[Pkg-javascript-commits] [dojo] 13/18: Imported Upstream version 1.6.1+dfsg

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

    Imported Upstream version 1.6.1+dfsg
---
 dijit/Calendar.js                                  |  329 ++--
 dijit/CheckedMenuItem.js                           |   10 +-
 dijit/ColorPalette.js                              |  116 +-
 dijit/Declaration.js                               |   42 +-
 dijit/Dialog.js                                    |  356 ++--
 dijit/DialogUnderlay.js                            |   21 +-
 dijit/Editor.js                                    |  146 +-
 dijit/InlineEditBox.js                             |   69 +-
 dijit/LICENSE                                      |    2 +-
 dijit/Menu.js                                      |   45 +-
 dijit/MenuBar.js                                   |    8 +-
 dijit/MenuBarItem.js                               |   10 +-
 dijit/MenuItem.js                                  |   30 +-
 dijit/MenuSeparator.js                             |   12 +-
 dijit/PopupMenuBarItem.js                          |    8 +-
 dijit/PopupMenuItem.js                             |    7 +-
 dijit/ProgressBar.js                               |   97 +-
 dijit/TitlePane.js                                 |  113 +-
 dijit/Toolbar.js                                   |   15 +-
 dijit/ToolbarSeparator.js                          |   14 +-
 dijit/Tooltip.js                                   |  158 +-
 dijit/TooltipDialog.js                             |   42 +-
 dijit/Tree.js                                      |  297 ++--
 dijit/_Calendar.js                                 |    7 +-
 dijit/_Contained.js                                |    5 +-
 dijit/_Container.js                                |    8 +-
 dijit/_CssStateMixin.js                            |   66 +-
 dijit/_DialogMixin.js                              |   26 +-
 dijit/_HasDropDown.js                              |  163 +-
 dijit/_KeyNavContainer.js                          |   31 +-
 dijit/_PaletteMixin.js                             |   48 +-
 dijit/_Templated.js                                |   62 +-
 dijit/_TimePicker.js                               |  202 +--
 dijit/_Widget.js                                   |  837 +---------
 dijit/_WidgetBase.js                               |  816 +++++++++
 dijit/_base.js                                     |   15 +-
 dijit/_base/focus.js                               |   22 +-
 dijit/_base/manager.js                             |   55 +-
 dijit/_base/place.js                               |   72 +-
 dijit/_base/popup.js                               |  157 +-
 dijit/_base/scroll.js                              |    8 +-
 dijit/_base/sniff.js                               |    6 +-
 dijit/_base/typematic.js                           |    6 +-
 dijit/_base/wai.js                                 |   35 +-
 dijit/_base/window.js                              |    8 +-
 dijit/_editor/RichText.js                          |  452 +++--
 dijit/_editor/_Plugin.js                           |  116 +-
 dijit/_editor/html.js                              |    6 +-
 dijit/_editor/nls/FontChoice.js                    |   34 +
 dijit/_editor/nls/LinkDialog.js                    |   34 +
 dijit/_editor/nls/ar/FontChoice.js                 |    7 +-
 dijit/_editor/nls/ar/LinkDialog.js                 |   10 +-
 dijit/_editor/nls/ar/commands.js                   |   21 +-
 dijit/_editor/nls/ca/FontChoice.js                 |    6 +-
 dijit/_editor/nls/ca/LinkDialog.js                 |    7 +-
 dijit/_editor/nls/ca/commands.js                   |    9 +-
 dijit/_editor/nls/commands.js                      |   34 +
 dijit/_editor/nls/cs/FontChoice.js                 |    5 +
 dijit/_editor/nls/cs/LinkDialog.js                 |    4 +
 dijit/_editor/nls/cs/commands.js                   |    9 +-
 dijit/_editor/nls/da/FontChoice.js                 |    7 +-
 dijit/_editor/nls/da/LinkDialog.js                 |    4 +
 dijit/_editor/nls/da/commands.js                   |    8 +-
 dijit/_editor/nls/de/FontChoice.js                 |    7 +-
 dijit/_editor/nls/de/LinkDialog.js                 |    4 +
 dijit/_editor/nls/de/commands.js                   |    4 +
 dijit/_editor/nls/el/FontChoice.js                 |    7 +-
 dijit/_editor/nls/el/LinkDialog.js                 |    4 +
 dijit/_editor/nls/el/commands.js                   |    4 +
 dijit/_editor/nls/es/FontChoice.js                 |    7 +-
 dijit/_editor/nls/es/LinkDialog.js                 |    8 +-
 dijit/_editor/nls/es/commands.js                   |    4 +
 dijit/_editor/nls/fi/FontChoice.js                 |    7 +-
 dijit/_editor/nls/fi/LinkDialog.js                 |    4 +
 dijit/_editor/nls/fi/commands.js                   |    4 +
 dijit/_editor/nls/fr/FontChoice.js                 |    7 +-
 dijit/_editor/nls/fr/LinkDialog.js                 |   13 +-
 dijit/_editor/nls/fr/commands.js                   |   13 +-
 dijit/_editor/nls/he/FontChoice.js                 |    7 +-
 dijit/_editor/nls/he/LinkDialog.js                 |    8 +-
 dijit/_editor/nls/he/commands.js                   |   11 +-
 dijit/_editor/nls/hu/FontChoice.js                 |    7 +-
 dijit/_editor/nls/hu/LinkDialog.js                 |    4 +
 dijit/_editor/nls/hu/commands.js                   |    5 +-
 dijit/_editor/nls/it/FontChoice.js                 |    8 +-
 dijit/_editor/nls/it/LinkDialog.js                 |    8 +-
 dijit/_editor/nls/it/commands.js                   |   18 +-
 dijit/_editor/nls/ja/FontChoice.js                 |    7 +-
 dijit/_editor/nls/ja/LinkDialog.js                 |    4 +
 dijit/_editor/nls/ja/commands.js                   |   23 +-
 dijit/_editor/nls/kk/FontChoice.js                 |   30 +
 dijit/_editor/nls/kk/LinkDialog.js                 |   16 +
 dijit/_editor/nls/kk/commands.js                   |   51 +
 dijit/_editor/nls/ko/FontChoice.js                 |    7 +-
 dijit/_editor/nls/ko/LinkDialog.js                 |   10 +-
 dijit/_editor/nls/ko/commands.js                   |   21 +-
 dijit/_editor/nls/nb/FontChoice.js                 |    7 +-
 dijit/_editor/nls/nb/LinkDialog.js                 |    4 +
 dijit/_editor/nls/nb/commands.js                   |    9 +-
 dijit/_editor/nls/nl/FontChoice.js                 |    7 +-
 dijit/_editor/nls/nl/LinkDialog.js                 |    4 +
 dijit/_editor/nls/nl/commands.js                   |    5 +-
 dijit/_editor/nls/pl/FontChoice.js                 |    7 +-
 dijit/_editor/nls/pl/LinkDialog.js                 |    4 +
 dijit/_editor/nls/pl/commands.js                   |    6 +-
 dijit/_editor/nls/pt-pt/FontChoice.js              |    7 +-
 dijit/_editor/nls/pt-pt/LinkDialog.js              |    4 +
 dijit/_editor/nls/pt-pt/commands.js                |    6 +-
 dijit/_editor/nls/pt/FontChoice.js                 |    5 +
 dijit/_editor/nls/pt/LinkDialog.js                 |    4 +
 dijit/_editor/nls/pt/commands.js                   |   17 +-
 dijit/_editor/nls/ro/FontChoice.js                 |    4 +
 dijit/_editor/nls/ro/LinkDialog.js                 |    8 +-
 dijit/_editor/nls/ro/commands.js                   |   43 +-
 dijit/_editor/nls/ru/FontChoice.js                 |    7 +-
 dijit/_editor/nls/ru/LinkDialog.js                 |    6 +-
 dijit/_editor/nls/ru/commands.js                   |    4 +
 dijit/_editor/nls/sk/FontChoice.js                 |    5 +
 dijit/_editor/nls/sk/LinkDialog.js                 |    4 +
 dijit/_editor/nls/sk/commands.js                   |    4 +
 dijit/_editor/nls/sl/FontChoice.js                 |   13 +-
 dijit/_editor/nls/sl/LinkDialog.js                 |    6 +-
 dijit/_editor/nls/sl/commands.js                   |   13 +-
 dijit/_editor/nls/sv/FontChoice.js                 |    7 +-
 dijit/_editor/nls/sv/LinkDialog.js                 |    4 +
 dijit/_editor/nls/sv/commands.js                   |    4 +
 dijit/_editor/nls/th/FontChoice.js                 |    5 +
 dijit/_editor/nls/th/LinkDialog.js                 |    6 +-
 dijit/_editor/nls/th/commands.js                   |    4 +
 dijit/_editor/nls/tr/FontChoice.js                 |    7 +-
 dijit/_editor/nls/tr/LinkDialog.js                 |    4 +
 dijit/_editor/nls/tr/commands.js                   |    4 +
 dijit/_editor/nls/zh-tw/FontChoice.js              |    7 +-
 dijit/_editor/nls/zh-tw/LinkDialog.js              |    4 +
 dijit/_editor/nls/zh-tw/commands.js                |   13 +-
 dijit/_editor/nls/zh/FontChoice.js                 |    7 +-
 dijit/_editor/nls/zh/LinkDialog.js                 |    8 +-
 dijit/_editor/nls/zh/commands.js                   |    4 +
 dijit/_editor/plugins/AlwaysShowToolbar.js         |   12 +-
 dijit/_editor/plugins/EnterKeyHandling.js          |  566 +++----
 dijit/_editor/plugins/FontChoice.js                |   47 +-
 dijit/_editor/plugins/FullScreen.js                |   24 +-
 dijit/_editor/plugins/LinkDialog.js                |   53 +-
 dijit/_editor/plugins/NewPage.js                   |   18 +-
 dijit/_editor/plugins/Print.js                     |   21 +-
 dijit/_editor/plugins/TabIndent.js                 |   15 +-
 dijit/_editor/plugins/TextColor.js                 |   15 +-
 dijit/_editor/plugins/ToggleDir.js                 |   12 +-
 dijit/_editor/plugins/ViewSource.js                |   73 +-
 dijit/_editor/range.js                             |    6 +-
 dijit/_editor/selection.js                         |   32 +-
 dijit/_tree/dndSource.js                           |    7 +-
 dijit/dijit-all.js                                 |   80 +-
 dijit/dijit.js                                     |   13 +-
 dijit/form/Button.js                               |   61 +-
 dijit/form/CheckBox.js                             |   31 +-
 dijit/form/ComboBox.js                             |  430 +++--
 dijit/form/ComboButton.js                          |    8 +-
 dijit/form/CurrencyTextBox.js                      |   23 +-
 dijit/form/DateTextBox.js                          |   14 +-
 dijit/form/DropDownButton.js                       |    7 +-
 dijit/form/FilteringSelect.js                      |   73 +-
 dijit/form/Form.js                                 |   20 +-
 dijit/form/HorizontalRule.js                       |   13 +-
 dijit/form/HorizontalRuleLabels.js                 |    6 +-
 dijit/form/HorizontalSlider.js                     |   76 +-
 dijit/form/MappedTextBox.js                        |    8 +-
 dijit/form/MultiSelect.js                          |   18 +-
 dijit/form/NumberSpinner.js                        |   11 +-
 dijit/form/NumberTextBox.js                        |   58 +-
 dijit/form/RadioButton.js                          |    7 +-
 dijit/form/RangeBoundTextBox.js                    |    8 +-
 dijit/form/Select.js                               |   76 +-
 dijit/form/SimpleTextarea.js                       |   23 +-
 dijit/form/Slider.js                               |   11 +-
 dijit/form/TextBox.js                              |  103 +-
 dijit/form/Textarea.js                             |   30 +-
 dijit/form/TimeTextBox.js                          |   45 +-
 dijit/form/ToggleButton.js                         |    8 +-
 dijit/form/ValidationTextBox.js                    |   89 +-
 dijit/form/VerticalRule.js                         |    7 +-
 dijit/form/VerticalRuleLabels.js                   |   10 +-
 dijit/form/VerticalSlider.js                       |   11 +-
 dijit/form/_DateTimeTextBox.js                     |  227 ++-
 dijit/form/_FormMixin.js                           |  221 ++-
 dijit/form/_FormSelectWidget.js                    |  170 +-
 dijit/form/_FormWidget.js                          |   80 +-
 dijit/form/_Spinner.js                             |   16 +-
 dijit/form/nls/ComboBox.js                         |   34 +
 dijit/form/nls/Textarea.js                         |   34 +
 dijit/form/nls/ar/ComboBox.js                      |    4 +
 dijit/form/nls/ar/Textarea.js                      |    4 +
 dijit/form/nls/ar/validate.js                      |    4 +
 dijit/form/nls/ca/ComboBox.js                      |    4 +
 dijit/form/nls/ca/Textarea.js                      |    4 +
 dijit/form/nls/ca/validate.js                      |    4 +
 dijit/form/nls/cs/ComboBox.js                      |    4 +
 dijit/form/nls/cs/Textarea.js                      |    4 +
 dijit/form/nls/cs/validate.js                      |    4 +
 dijit/form/nls/da/ComboBox.js                      |    4 +
 dijit/form/nls/da/Textarea.js                      |    4 +
 dijit/form/nls/da/validate.js                      |    6 +-
 dijit/form/nls/de/ComboBox.js                      |    4 +
 dijit/form/nls/de/Textarea.js                      |    4 +
 dijit/form/nls/de/validate.js                      |    4 +
 dijit/form/nls/el/ComboBox.js                      |    4 +
 dijit/form/nls/el/Textarea.js                      |    4 +
 dijit/form/nls/el/validate.js                      |    4 +
 dijit/form/nls/es/ComboBox.js                      |    4 +
 dijit/form/nls/es/Textarea.js                      |    4 +
 dijit/form/nls/es/validate.js                      |    4 +
 dijit/form/nls/fi/ComboBox.js                      |    4 +
 dijit/form/nls/fi/Textarea.js                      |    4 +
 dijit/form/nls/fi/validate.js                      |    4 +
 dijit/form/nls/fr/ComboBox.js                      |    4 +
 dijit/form/nls/fr/Textarea.js                      |    8 +-
 dijit/form/nls/fr/validate.js                      |    4 +
 dijit/form/nls/he/ComboBox.js                      |    4 +
 dijit/form/nls/he/Textarea.js                      |    4 +
 dijit/form/nls/he/validate.js                      |    4 +
 dijit/form/nls/hu/ComboBox.js                      |    4 +
 dijit/form/nls/hu/Textarea.js                      |    4 +
 dijit/form/nls/hu/validate.js                      |    4 +
 dijit/form/nls/it/ComboBox.js                      |    4 +
 dijit/form/nls/it/Textarea.js                      |    4 +
 dijit/form/nls/it/validate.js                      |    4 +
 dijit/form/nls/ja/ComboBox.js                      |    4 +
 dijit/form/nls/ja/Textarea.js                      |    4 +
 dijit/form/nls/ja/validate.js                      |    4 +
 dijit/form/nls/kk/ComboBox.js                      |    9 +
 dijit/form/nls/kk/Textarea.js                      |   12 +
 dijit/form/nls/kk/validate.js                      |   10 +
 dijit/form/nls/ko/ComboBox.js                      |    4 +
 dijit/form/nls/ko/Textarea.js                      |    4 +
 dijit/form/nls/ko/validate.js                      |    4 +
 dijit/form/nls/nb/ComboBox.js                      |    4 +
 dijit/form/nls/nb/Textarea.js                      |    4 +
 dijit/form/nls/nb/validate.js                      |    4 +
 dijit/form/nls/nl/ComboBox.js                      |    4 +
 dijit/form/nls/nl/Textarea.js                      |    4 +
 dijit/form/nls/nl/validate.js                      |    4 +
 dijit/form/nls/pl/ComboBox.js                      |    4 +
 dijit/form/nls/pl/Textarea.js                      |    8 +-
 dijit/form/nls/pl/validate.js                      |    4 +
 dijit/form/nls/pt-pt/ComboBox.js                   |    4 +
 dijit/form/nls/pt-pt/Textarea.js                   |    4 +
 dijit/form/nls/pt-pt/validate.js                   |    4 +
 dijit/form/nls/pt/ComboBox.js                      |    4 +
 dijit/form/nls/pt/Textarea.js                      |    4 +
 dijit/form/nls/pt/validate.js                      |    4 +
 dijit/form/nls/ro/ComboBox.js                      |    4 +
 dijit/form/nls/ro/Textarea.js                      |    4 +
 dijit/form/nls/ro/validate.js                      |    4 +
 dijit/form/nls/ru/ComboBox.js                      |    4 +
 dijit/form/nls/ru/Textarea.js                      |    4 +
 dijit/form/nls/ru/validate.js                      |    4 +
 dijit/form/nls/sk/ComboBox.js                      |    4 +
 dijit/form/nls/sk/Textarea.js                      |    4 +
 dijit/form/nls/sk/validate.js                      |    4 +
 dijit/form/nls/sl/ComboBox.js                      |    8 +-
 dijit/form/nls/sl/Textarea.js                      |    8 +-
 dijit/form/nls/sl/validate.js                      |    6 +-
 dijit/form/nls/sv/ComboBox.js                      |    4 +
 dijit/form/nls/sv/Textarea.js                      |    4 +
 dijit/form/nls/sv/validate.js                      |    4 +
 dijit/form/nls/th/ComboBox.js                      |    4 +
 dijit/form/nls/th/Textarea.js                      |    4 +
 dijit/form/nls/th/validate.js                      |    4 +
 dijit/form/nls/tr/ComboBox.js                      |    4 +
 dijit/form/nls/tr/Textarea.js                      |    4 +
 dijit/form/nls/tr/validate.js                      |    4 +
 dijit/form/nls/validate.js                         |   34 +
 dijit/form/nls/zh-tw/ComboBox.js                   |    4 +
 dijit/form/nls/zh-tw/Textarea.js                   |    4 +
 dijit/form/nls/zh-tw/validate.js                   |    4 +
 dijit/form/nls/zh/ComboBox.js                      |    4 +
 dijit/form/nls/zh/Textarea.js                      |    4 +
 dijit/form/nls/zh/validate.js                      |    4 +
 dijit/form/templates/Button.html                   |    4 +-
 dijit/form/templates/CheckBox.html                 |    2 +-
 dijit/form/templates/ComboBox.html                 |   18 -
 dijit/form/templates/ComboButton.html              |   16 +-
 dijit/form/templates/DropDownBox.html              |   16 +
 dijit/form/templates/DropDownButton.html           |    4 +-
 dijit/form/templates/HorizontalSlider.html         |   12 +-
 dijit/form/templates/Select.html                   |   14 +-
 dijit/form/templates/Spinner.html                  |   12 +-
 dijit/form/templates/TextBox.html                  |    2 +-
 dijit/form/templates/ValidationTextBox.html        |    4 +-
 dijit/form/templates/VerticalSlider.html           |   14 +-
 dijit/layout/AccordionContainer.js                 |  303 ++--
 dijit/layout/AccordionPane.js                      |    8 +-
 dijit/layout/BorderContainer.js                    |  407 ++---
 dijit/layout/ContentPane.js                        |  383 ++---
 dijit/layout/LayoutContainer.js                    |    8 +-
 dijit/layout/LinkPane.js                           |    9 +-
 dijit/layout/ScrollingTabController.js             |  163 +-
 dijit/layout/SplitContainer.js                     |    8 +-
 dijit/layout/StackContainer.js                     |   53 +-
 dijit/layout/StackController.js                    |   81 +-
 dijit/layout/TabContainer.js                       |    9 +-
 dijit/layout/TabController.js                      |   53 +-
 dijit/layout/_ContentPaneResizeMixin.js            |  250 +++
 dijit/layout/_LayoutWidget.js                      |   90 +-
 dijit/layout/_TabContainerBase.js                  |   23 +-
 dijit/layout/templates/AccordionButton.html        |   12 +-
 dijit/layout/templates/ScrollingTabController.html |   13 +-
 .../templates/_ScrollingTabControllerButton.html   |    6 +-
 dijit/layout/templates/_TabButton.html             |   14 +-
 dijit/lib/main.js                                  |   13 +
 dijit/nls/ar/common.js                             |    4 +
 dijit/nls/ar/loading.js                            |    4 +
 dijit/nls/ca/common.js                             |    4 +
 dijit/nls/ca/loading.js                            |    4 +
 dijit/nls/common.js                                |   34 +
 dijit/nls/cs/common.js                             |    4 +
 dijit/nls/cs/loading.js                            |    4 +
 dijit/nls/da/common.js                             |    4 +
 dijit/nls/da/loading.js                            |    4 +
 dijit/nls/de/common.js                             |    4 +
 dijit/nls/de/loading.js                            |    4 +
 dijit/nls/el/common.js                             |    4 +
 dijit/nls/el/loading.js                            |    4 +
 dijit/nls/es/common.js                             |    4 +
 dijit/nls/es/loading.js                            |    4 +
 dijit/nls/fi/common.js                             |    4 +
 dijit/nls/fi/loading.js                            |    4 +
 dijit/nls/fr/common.js                             |    4 +
 dijit/nls/fr/loading.js                            |    4 +
 dijit/nls/he/common.js                             |    4 +
 dijit/nls/he/loading.js                            |    4 +
 dijit/nls/hu/common.js                             |    4 +
 dijit/nls/hu/loading.js                            |    4 +
 dijit/nls/it/common.js                             |    4 +
 dijit/nls/it/loading.js                            |    4 +
 dijit/nls/ja/common.js                             |    4 +
 dijit/nls/ja/loading.js                            |    4 +
 dijit/nls/kk/common.js                             |   10 +
 dijit/nls/kk/loading.js                            |    8 +
 dijit/nls/ko/common.js                             |    4 +
 dijit/nls/ko/loading.js                            |    4 +
 dijit/nls/loading.js                               |   34 +
 dijit/nls/nb/common.js                             |    4 +
 dijit/nls/nb/loading.js                            |    4 +
 dijit/nls/nl/common.js                             |    4 +
 dijit/nls/nl/loading.js                            |    4 +
 dijit/nls/pl/common.js                             |    4 +
 dijit/nls/pl/loading.js                            |    4 +
 dijit/nls/pt-pt/common.js                          |    6 +-
 dijit/nls/pt-pt/loading.js                         |    6 +-
 dijit/nls/pt/common.js                             |    4 +
 dijit/nls/pt/loading.js                            |    4 +
 dijit/nls/ro/common.js                             |    4 +
 dijit/nls/ro/loading.js                            |    4 +
 dijit/nls/ru/common.js                             |    4 +
 dijit/nls/ru/loading.js                            |    4 +
 dijit/nls/sk/common.js                             |    4 +
 dijit/nls/sk/loading.js                            |    4 +
 dijit/nls/sl/common.js                             |    4 +
 dijit/nls/sl/loading.js                            |    7 +-
 dijit/nls/sv/common.js                             |    4 +
 dijit/nls/sv/loading.js                            |    4 +
 dijit/nls/th/common.js                             |    4 +
 dijit/nls/th/loading.js                            |    4 +
 dijit/nls/tr/common.js                             |    4 +
 dijit/nls/tr/loading.js                            |    4 +
 dijit/nls/zh-tw/common.js                          |    4 +
 dijit/nls/zh-tw/loading.js                         |    4 +
 dijit/nls/zh/common.js                             |    4 +
 dijit/nls/zh/loading.js                            |    4 +
 dijit/package.json                                 |   24 +
 dijit/robot.js                                     |    8 +-
 dijit/robotx.js                                    |   14 +-
 dijit/templates/Calendar.html                      |   16 +-
 dijit/templates/CheckedMenuItem.html               |    6 +-
 dijit/templates/ColorPalette.html                  |    1 -
 dijit/templates/Dialog.html                        |    4 +-
 dijit/templates/InlineEditBox.html                 |   14 +-
 dijit/templates/Menu.html                          |    2 +-
 dijit/templates/MenuBar.html                       |    2 +-
 dijit/templates/MenuBarItem.html                   |    2 +-
 dijit/templates/MenuItem.html                      |    6 +-
 dijit/templates/ProgressBar.html                   |    8 +-
 dijit/templates/TimePicker.html                    |    4 +-
 dijit/templates/TitlePane.html                     |    8 +-
 dijit/templates/Tooltip.html                       |    8 +-
 dijit/templates/TooltipDialog.html                 |    8 +-
 dijit/templates/Tree.html                          |    2 +-
 dijit/templates/TreeNode.html                      |   16 +-
 dijit/tests/Bidi.html                              |  374 +++++
 dijit/tests/Dialog.html                            |  422 +++++
 dijit/tests/NodeList-instantiate.html              |  157 ++
 dijit/tests/ProgressBar.html                       |  326 ++++
 dijit/tests/Tooltip-placement.html                 |  715 ++++++++
 dijit/tests/Tree.html                              |  249 ---
 dijit/tests/Tree_with_JRS.html                     |  119 --
 dijit/tests/Widget-placeAt.html                    |  152 --
 dijit/tests/_Container.html                        |   42 +-
 dijit/tests/_Templated-widgetsInTemplate.html      |  686 ++++----
 dijit/tests/_Templated-widgetsInTemplate1.x.html   |  488 ++++++
 dijit/tests/_Templated.html                        |   35 +-
 dijit/tests/_Widget-attr.html                      |  108 +-
 dijit/tests/_Widget-connect-performance.html       |   21 +-
 dijit/tests/_Widget-deferredConnect.html           |   18 +-
 dijit/tests/_Widget-lifecycle.html                 |   64 +-
 dijit/tests/_Widget-ondijitclick.html              |   57 +-
 dijit/tests/_Widget-placeAt.html                   |  171 ++
 dijit/tests/_Widget-subscribe.html                 |   30 +-
 dijit/tests/_altCalendar.html                      |    7 +-
 dijit/tests/_base/manager.html                     |   58 +-
 dijit/tests/_base/module.js                        |   16 +-
 dijit/tests/_base/place.html                       |    2 +-
 dijit/tests/_base/robot/CrossWindow.html           |   65 +
 dijit/tests/_base/robot/FocusManager.html          |    2 +
 dijit/tests/_base/robot/focus_mouse.html           |   64 +-
 dijit/tests/_base/robot/popup.html                 |  100 +-
 dijit/tests/_base/robot/typematic.html             |   38 +-
 dijit/tests/_base/tabindex.html                    |   84 +-
 dijit/tests/_base/test_CrossWindow.html            |   35 +-
 dijit/tests/_base/test_FocusManager.html           |    4 +-
 dijit/tests/_base/test_focusWidget.html            |   67 +-
 dijit/tests/_base/test_popup.html                  |   17 +-
 dijit/tests/_base/test_typematic.html              |    4 +-
 dijit/tests/_base/wai.html                         |   87 +-
 dijit/tests/_data/treeTest.json                    |   22 -
 dijit/tests/_loadTest.js                           |   11 +-
 dijit/tests/_testCommon.js                         |   36 +-
 dijit/tests/_testMatrix.php                        |    2 +-
 dijit/tests/bidi.html                              |  188 ---
 dijit/tests/editor/BackForwardState.html           |   14 +-
 dijit/tests/editor/EnterKeyHandling.html           |   41 +-
 dijit/tests/editor/_Editor.html                    |   51 -
 dijit/tests/editor/module.js                       |   30 +-
 dijit/tests/editor/nls_8859-2.html                 |   58 +-
 dijit/tests/editor/nls_sjis.html                   |   58 +-
 dijit/tests/editor/nls_utf8.html                   |   55 +-
 dijit/tests/editor/robot/BackForwardState.html     |   20 +-
 dijit/tests/editor/robot/CustomPlugin.html         |  106 ++
 dijit/tests/editor/robot/Editor_FontChoice.html    |  691 ++++----
 dijit/tests/editor/robot/Editor_FullScreen.html    | 1072 +++++-------
 dijit/tests/editor/robot/Editor_LinkDialog.html    | 1352 +++++++--------
 dijit/tests/editor/robot/Editor_NewPage.html       |  136 +-
 dijit/tests/editor/robot/Editor_ViewSource.html    |  778 ++++-----
 dijit/tests/editor/robot/Editor_a11y.html          |  138 +-
 dijit/tests/editor/robot/Editor_misc.html          |  261 ++-
 dijit/tests/editor/robot/Editor_mouse.html         |   92 +-
 dijit/tests/editor/robot/EnterKeyHandling.html     |  399 ++++-
 dijit/tests/editor/robot/TabIndent.html            |  151 ++
 dijit/tests/editor/robot/ToggleDir.html            |  117 ++
 dijit/tests/editor/robot/ToggleDir_rtl.html        |  117 ++
 dijit/tests/editor/test_CustomPlugin.html          |  115 +-
 dijit/tests/editor/test_Editor.html                |  110 +-
 dijit/tests/editor/test_FontChoice.html            |   28 +-
 dijit/tests/editor/test_FullScreen.html            |   64 +-
 dijit/tests/editor/test_LinkDialog.html            |   13 +-
 dijit/tests/editor/test_NewPage.html               |   18 +-
 dijit/tests/editor/test_Print.html                 |   14 +-
 dijit/tests/editor/test_RichText.html              |   60 -
 dijit/tests/editor/test_TabIndent.html             |   20 +-
 dijit/tests/editor/test_ToggleDir.html             |   20 +-
 dijit/tests/editor/test_ToggleDir_rtl.html         |   23 +-
 dijit/tests/editor/test_ViewSource.html            |   36 +-
 .../editor/{test_richtext.css => test_editor.css}  |    0
 dijit/tests/editor/test_resize.html                |   32 -
 dijit/tests/form/DateTextBox.html                  |   69 +
 dijit/tests/form/Form.html                         |  555 +++++--
 dijit/tests/form/FormInvalid.html                  |   54 -
 dijit/tests/form/TextBox_sizes.html                |  234 +--
 dijit/tests/form/_autoComplete.html                |  452 ++---
 dijit/tests/form/module.js                         |   81 +-
 dijit/tests/form/robot/Button_a11y.html            |   44 +-
 dijit/tests/form/robot/Button_mouse.html           |   71 +-
 dijit/tests/form/robot/CheckBox_a11y.html          |  361 ++++
 dijit/tests/form/robot/CheckBox_mouse.html         |  507 ++++++
 dijit/tests/form/robot/DateTextBox.html            | 1032 ++++++++++--
 dijit/tests/form/robot/Form.html                   |   72 -
 dijit/tests/form/robot/Form_onsubmit.html          |  186 +++
 dijit/tests/form/robot/Form_state.html             |  186 +++
 dijit/tests/form/robot/MultiSelect.html            |  263 +++
 dijit/tests/form/robot/Select.html                 |  195 ++-
 dijit/tests/form/robot/SimpleTextarea.html         |  137 ++
 dijit/tests/form/robot/Slider_mouse.html           |   73 +-
 dijit/tests/form/robot/Spinner_a11y.html           |  469 +++---
 dijit/tests/form/robot/Spinner_mouse.html          |   83 +-
 dijit/tests/form/robot/Textarea.html               |  253 +--
 dijit/tests/form/robot/TimeTextBox.html            |  227 ++-
 dijit/tests/form/robot/ValidationTextBox.html      | 1241 ++++++++++++++
 dijit/tests/form/robot/_autoComplete_a11y.html     |  593 ++++++-
 dijit/tests/form/robot/_autoComplete_mouse.html    |  337 ++--
 dijit/tests/form/robot/test_validate.html          | 1113 -------------
 dijit/tests/form/robot/validationMessages.html     |  424 ++---
 dijit/tests/form/test_Button.html                  |  371 ++---
 dijit/tests/form/test_CheckBox.html                |  239 +--
 dijit/tests/form/test_ComboBox_destroy.html        |   66 -
 dijit/tests/form/test_DateTextBox.html             |  116 +-
 dijit/tests/form/test_Form_onsubmit.html           |   77 +-
 dijit/tests/form/test_Form_state.html              |  114 ++
 dijit/tests/form/test_MultiSelect.html             |   44 +-
 dijit/tests/form/test_Select.html                  |  139 +-
 dijit/tests/form/test_SimpleTextarea.html          |   60 +-
 dijit/tests/form/test_Slider.html                  |  152 +-
 dijit/tests/form/test_Spinner.html                 |   92 +-
 dijit/tests/form/test_Textarea.html                |   46 +-
 dijit/tests/form/test_TimeTextBox.html             |  246 +--
 dijit/tests/form/test_validStatePerformance.html   |   94 +-
 dijit/tests/form/test_validate.html                |  287 ++--
 dijit/tests/form/test_validationState.html         |  102 --
 dijit/tests/form/test_verticalAlign.html           |  207 +++
 dijit/tests/general-module.js                      |   39 +-
 dijit/tests/helpers.js                             |   77 +-
 dijit/tests/i18n/calendar.html                     |   73 +-
 dijit/tests/i18n/currency.html                     |    4 +-
 dijit/tests/i18n/date.html                         |    4 +-
 dijit/tests/i18n/digit.html                        |    4 +-
 dijit/tests/i18n/module.js                         |   12 +-
 dijit/tests/i18n/number.html                       |    4 +-
 dijit/tests/i18n/test_i18n.js                      |  113 +-
 dijit/tests/i18n/textbox.html                      |    4 +-
 dijit/tests/i18n/time.html                         |  296 ++--
 dijit/tests/infrastructure-module.js               |   31 +-
 dijit/tests/layout/AccordionContainer.html         |  243 ++-
 dijit/tests/layout/BorderContainer.html            |  259 +++
 dijit/tests/layout/ContentPane-remote.html         |  663 ++++++++
 dijit/tests/layout/ContentPane.html                |  652 ++------
 dijit/tests/layout/ContentPaneLayout.html          |  292 +++-
 dijit/tests/layout/LayoutContainer.html            |  296 ++++
 dijit/tests/layout/TabContainer.html               |  585 ++++---
 dijit/tests/layout/TabContainerTitlePane.html      |  130 ++
 dijit/tests/layout/borderContainer.php             |   20 +-
 dijit/tests/layout/combotab.html                   |   10 +-
 dijit/tests/layout/doc0.html                       |    6 +-
 dijit/tests/layout/getResponse.php                 |    6 +-
 dijit/tests/layout/module.js                       |   34 +-
 dijit/tests/layout/multipleLayoutWidgets.php       |   10 +-
 dijit/tests/layout/nestedStack.html                |   89 +-
 .../layout/robot/AccordionContainer_a11y.html      |    9 +-
 .../layout/robot/AccordionContainer_mouse.html     |   10 +-
 dijit/tests/layout/robot/BorderContainer.html      |  202 +--
 .../layout/robot/BorderContainer_complex.html      |  295 ++++
 dijit/tests/layout/robot/BorderContainer_full.html |  110 ++
 .../tests/layout/robot/BorderContainer_nested.html |  148 ++
 dijit/tests/layout/robot/GUI.html                  |  303 ++++
 dijit/tests/layout/robot/StackContainer_mouse.html |  372 +++++
 dijit/tests/layout/robot/TabContainer_a11y.html    |  450 +++--
 dijit/tests/layout/robot/TabContainer_mouse.html   |   36 +
 .../tests/layout/robot/TabContainer_noLayout.html  |  435 +++++
 .../layout/robot/borderContainerTestFunctions.js   |   99 ++
 dijit/tests/layout/runTests.html                   |    9 +
 dijit/tests/layout/tab3.html                       |    8 +-
 dijit/tests/layout/tab3_noLayout.html              |    8 +-
 dijit/tests/layout/tab4.html                       |    8 +-
 dijit/tests/layout/test_AccordionContainer.html    |   73 +-
 .../layout/test_AccordionContainerDestroy.html     |   57 -
 dijit/tests/layout/test_BorderContainer.html       |  139 +-
 .../tests/layout/test_BorderContainer_complex.html |   67 +-
 .../layout/test_BorderContainer_experimental.html  |  248 +--
 dijit/tests/layout/test_BorderContainer_full.html  |   23 +-
 .../tests/layout/test_BorderContainer_nested.html  |  129 +-
 dijit/tests/layout/test_BorderContainer_prog.html  |   56 -
 dijit/tests/layout/test_ContentPane.html           |   56 +-
 dijit/tests/layout/test_ContentPane_prog.html      |   49 -
 dijit/tests/layout/test_Gui.html                   |  179 +-
 dijit/tests/layout/test_LayoutContainer.html       |  183 ---
 dijit/tests/layout/test_SplitContainer.html        |    4 +-
 dijit/tests/layout/test_StackContainer.html        |  103 +-
 dijit/tests/layout/test_StackContainer_code.html   |   72 -
 dijit/tests/layout/test_TabContainer.html          |  372 ++---
 dijit/tests/layout/test_TabContainerTitlePane.html |   82 -
 dijit/tests/layout/test_TabContainer_noLayout.html |  150 +-
 dijit/tests/layout/test_TabContainer_prog.html     |   61 -
 dijit/tests/layout/test_TabContainer_remote.html   |  116 --
 dijit/tests/layout/test_refreshOnShow.html         |   65 -
 dijit/tests/robot/BgIframe.html                    |  142 ++
 dijit/tests/robot/Calendar_a11y.html               |  232 ++-
 dijit/tests/robot/ColorPalette.html                |   42 +-
 dijit/tests/robot/Dialog_a11y.html                 |  355 ++--
 dijit/tests/robot/Dialog_focusDestroy.html         |   57 +
 dijit/tests/robot/Dialog_mouse.html                |   66 +-
 dijit/tests/robot/InlineEditBox.html               |  209 ++-
 dijit/tests/robot/Menu_a11y.html                   |    2 -
 dijit/tests/robot/Menu_iframe.html                 |  224 +++
 dijit/tests/robot/Menu_mouse.html                  |  177 +-
 dijit/tests/robot/TitlePane.html                   |   48 +
 dijit/tests/robot/Toolbar.html                     |   31 +
 dijit/tests/robot/TooltipDialog_mouse.html         |  219 ++-
 dijit/tests/robot/Tooltip_a11y.html                |    8 +
 dijit/tests/robot/Tooltip_mouse_quirks.html        |   55 +
 dijit/tests/robot/Tree_a11y.html                   |  772 ---------
 dijit/tests/robot/Tree_dnd.html                    |  340 ----
 dijit/tests/robot/Tree_dnd.js                      |  103 --
 dijit/tests/robot/Tree_dnd_multiParent.html        |  273 ---
 dijit/tests/robot/_Widget-ondijitclick_a11y.html   |   16 +-
 dijit/tests/test.html                              |   37 -
 dijit/tests/test_Calendar.html                     |   20 +-
 dijit/tests/test_ColorPalette.html                 |   30 +-
 dijit/tests/test_Declaration.html                  |  105 +-
 dijit/tests/test_Declaration_1.x.html              |  131 ++
 dijit/tests/test_Dialog.html                       |  190 +--
 dijit/tests/test_Dialog_focusDestroy.html          |   23 +-
 dijit/tests/test_InlineEditBox.html                |  127 +-
 dijit/tests/test_Menu.html                         |  300 ++--
 dijit/tests/test_Menu_iframe.html                  |   43 +-
 dijit/tests/test_ProgressBar.html                  |  172 --
 dijit/tests/test_TitlePane.html                    |  125 +-
 dijit/tests/test_Toolbar.html                      |  100 +-
 dijit/tests/test_Tooltip.html                      |   76 +-
 dijit/tests/test_TooltipDialog.html                |  161 +-
 dijit/tests/test_Tree.html                         |  174 --
 .../tests/test_Tree_Notification_API_Support.html  |  293 ----
 dijit/tests/test_bgIframe.html                     |   83 +-
 dijit/tests/test_instantiate.html                  |  118 --
 dijit/tests/tree/CustomLabel.html                  |   92 ++
 dijit/tests/tree/Tree.html                         |  353 ++++
 dijit/tests/tree/Tree_with_JRS.html                |  132 ++
 dijit/tests/tree/module.js                         |   18 +-
 dijit/tests/tree/robot/Tree_a11y.html              |  785 +++++++++
 dijit/tests/tree/robot/Tree_dnd.html               |  704 ++++++++
 dijit/tests/tree/robot/Tree_dnd.js                 |  131 ++
 dijit/tests/tree/robot/Tree_dnd_multiParent.html   |  272 +++
 dijit/tests/tree/robot/Tree_selector.html          |  243 +++
 dijit/tests/tree/robot/Tree_v1.html                |  267 +++
 dijit/tests/tree/runTests.html                     |    9 +
 dijit/tests/tree/test_CustomLabel.html             |   56 -
 dijit/tests/tree/test_Tree.html                    |  170 ++
 dijit/tests/tree/test_Tree_DnD.html                |   76 +-
 dijit/tests/tree/test_Tree_Programmatic.html       |   67 -
 dijit/tests/tree/test_Tree_Styling.html            |  113 --
 dijit/tests/tree/test_Tree_v1.html                 |   41 +-
 dijit/themes/a11y/colors3x4-rtl.png                |  Bin 282 -> 0 bytes
 dijit/themes/a11y/colors7x10-rtl.png               |  Bin 808 -> 0 bytes
 dijit/themes/claro/Calendar.css                    |  335 ++--
 dijit/themes/claro/Calendar.less                   |  273 +++
 dijit/themes/claro/Calendar_rtl.css                |   15 +-
 dijit/themes/claro/Calendar_rtl.less               |   19 +
 dijit/themes/claro/ColorPalette.css                |   23 +-
 dijit/themes/claro/ColorPalette.less               |   44 +
 dijit/themes/claro/Common.css                      |   98 +-
 dijit/themes/claro/Common.less                     |   76 +
 dijit/themes/claro/Dialog.css                      |  247 ++-
 dijit/themes/claro/Dialog.less                     |  203 +++
 dijit/themes/claro/Dialog_rtl.css                  |    9 +-
 dijit/themes/claro/Dialog_rtl.less                 |   13 +
 dijit/themes/claro/Editor.css                      |   50 +-
 dijit/themes/claro/Editor.less                     |   59 +
 dijit/themes/claro/Editor_rtl.css                  |    7 +-
 dijit/themes/claro/Editor_rtl.less                 |    9 +
 dijit/themes/claro/InlineEditBox.css               |   11 +-
 dijit/themes/claro/InlineEditBox.less              |   25 +
 dijit/themes/claro/Menu.css                        |  192 +--
 dijit/themes/claro/Menu.less                       |  188 +++
 dijit/themes/claro/Menu_rtl.css                    |    9 +-
 dijit/themes/claro/Menu_rtl.less                   |   11 +
 dijit/themes/claro/ProgressBar.css                 |   34 +-
 dijit/themes/claro/ProgressBar.less                |   56 +
 dijit/themes/claro/README                          |   64 +
 dijit/themes/claro/TimePicker.css                  |  143 +-
 dijit/themes/claro/TimePicker.less                 |  124 ++
 dijit/themes/claro/TimePicker_rtl.css              |    9 +-
 dijit/themes/claro/TimePicker_rtl.less             |   12 +
 dijit/themes/claro/TitlePane.css                   |   62 +-
 dijit/themes/claro/TitlePane.less                  |   74 +
 dijit/themes/claro/TitlePane_rtl.css               |    4 +-
 dijit/themes/claro/TitlePane_rtl.less              |    7 +
 dijit/themes/claro/Toolbar.css                     |  220 ++-
 dijit/themes/claro/Toolbar.less                    |  157 ++
 dijit/themes/claro/Toolbar_rtl.css                 |   30 +
 dijit/themes/claro/Toolbar_rtl.less                |   32 +
 dijit/themes/claro/Tree.css                        |  130 +-
 dijit/themes/claro/Tree.less                       |  133 ++
 dijit/themes/claro/claro.css                       |    1 -
 dijit/themes/claro/claro_rtl.css                   |    1 +
 dijit/themes/claro/compile.js                      |   55 +
 dijit/themes/claro/document.css                    |  130 +-
 dijit/themes/claro/document.less                   |   45 +
 dijit/themes/claro/form/Button.css                 |  162 +-
 dijit/themes/claro/form/Button.less                |  154 ++
 dijit/themes/claro/form/Button_rtl.css             |   23 +-
 dijit/themes/claro/form/Button_rtl.less            |   16 +
 dijit/themes/claro/form/Checkbox.css               |   68 +-
 dijit/themes/claro/form/Checkbox.less              |   79 +
 dijit/themes/claro/form/Common.css                 |  237 ++-
 dijit/themes/claro/form/Common.less                |  194 +++
 dijit/themes/claro/form/Common_rtl.css             |    6 +-
 dijit/themes/claro/form/Common_rtl.less            |   13 +
 dijit/themes/claro/form/NumberSpinner.css          |  141 +-
 dijit/themes/claro/form/NumberSpinner.less         |  150 ++
 dijit/themes/claro/form/RadioButton.css            |   81 +-
 dijit/themes/claro/form/RadioButton.less           |   84 +
 dijit/themes/claro/form/Select.css                 |  111 +-
 dijit/themes/claro/form/Select.less                |  124 ++
 dijit/themes/claro/form/Select_rtl.css             |    4 +-
 dijit/themes/claro/form/Select_rtl.less            |    6 +
 dijit/themes/claro/form/Slider.css                 |  377 ++---
 dijit/themes/claro/form/Slider.less                |  362 ++++
 dijit/themes/claro/form/Slider_rtl.css             |   25 +-
 dijit/themes/claro/form/Slider_rtl.less            |   33 +
 dijit/themes/claro/images/loading.gif              |  Bin 751 -> 0 bytes
 dijit/themes/claro/images/tooltip.png              |  Bin 1941 -> 1818 bytes
 dijit/themes/claro/images/tooltipGradient.png      |  Bin 0 -> 1030 bytes
 dijit/themes/claro/layout/AccordionContainer.css   |  136 +-
 dijit/themes/claro/layout/AccordionContainer.less  |  116 ++
 dijit/themes/claro/layout/BorderContainer.css      |  111 +-
 dijit/themes/claro/layout/BorderContainer.less     |  128 ++
 dijit/themes/claro/layout/ContentPane.css          |   18 +-
 dijit/themes/claro/layout/ContentPane.less         |   43 +
 dijit/themes/claro/layout/TabContainer.css         |  481 +++---
 dijit/themes/claro/layout/TabContainer.less        |  408 +++++
 dijit/themes/claro/layout/TabContainer_rtl.css     |   74 +-
 dijit/themes/claro/layout/TabContainer_rtl.less    |   81 +
 dijit/themes/claro/layout/images/tabBottom.png     |  Bin 753 -> 718 bytes
 dijit/themes/claro/layout/images/tabTop.png        |  Bin 748 -> 721 bytes
 dijit/themes/claro/variables.less                  |  189 +++
 dijit/themes/dijit.css                             |  207 ++-
 dijit/themes/dijit_rtl.css                         |   14 +-
 dijit/themes/nihilo/Calendar.css                   |   23 +-
 dijit/themes/nihilo/Calendar_rtl.css               |    2 +-
 dijit/themes/nihilo/ColorPalette.css               |    2 +-
 dijit/themes/nihilo/Dialog.css                     |   25 +-
 dijit/themes/nihilo/Menu.css                       |    8 +-
 dijit/themes/nihilo/Menu_rtl.css                   |    4 +-
 dijit/themes/nihilo/ProgressBar.css                |    2 +-
 dijit/themes/nihilo/TimePicker_rtl.css             |    2 +-
 dijit/themes/nihilo/TitlePane.css                  |    2 +-
 dijit/themes/nihilo/TitlePane_rtl.css              |    4 +-
 dijit/themes/nihilo/Toolbar.css                    |    6 +-
 dijit/themes/nihilo/Tree.css                       |    2 +-
 dijit/themes/nihilo/Tree_rtl.css                   |    2 +-
 dijit/themes/nihilo/form/Button.css                |    4 +-
 dijit/themes/nihilo/form/Button_rtl.css            |    2 +-
 dijit/themes/nihilo/form/Checkbox.css              |    2 +-
 dijit/themes/nihilo/form/Common.css                |    2 +-
 dijit/themes/nihilo/form/RadioButton.css           |    2 +-
 dijit/themes/nihilo/form/Select.css                |    8 +-
 dijit/themes/nihilo/form/Slider.css                |   10 +-
 dijit/themes/nihilo/form/Slider_rtl.css            |    4 +-
 .../nihilo/layout/AccordionContainer_rtl.css       |    2 +-
 dijit/themes/nihilo/layout/BorderContainer.css     |   10 +-
 dijit/themes/nihilo/layout/ContentPane.css         |    2 +-
 dijit/themes/nihilo/layout/SplitContainer.css      |    8 +-
 dijit/themes/nihilo/layout/TabContainer.css        |   45 +-
 dijit/themes/nihilo/layout/TabContainer_rtl.css    |    6 +-
 dijit/themes/soria/Calendar.css                    |   22 +
 dijit/themes/soria/Calendar_rtl.css                |    2 +-
 dijit/themes/soria/ColorPalette.css                |    2 +-
 dijit/themes/soria/Dialog.css                      |   25 +-
 dijit/themes/soria/Menu.css                        |    8 +-
 dijit/themes/soria/Menu_rtl.css                    |    2 +-
 dijit/themes/soria/ProgressBar.css                 |    2 +-
 dijit/themes/soria/TimePicker_rtl.css              |    2 +-
 dijit/themes/soria/TitlePane.css                   |    2 +-
 dijit/themes/soria/TitlePane_rtl.css               |    4 +-
 dijit/themes/soria/Toolbar.css                     |   12 +-
 dijit/themes/soria/Tree.css                        |    2 +-
 dijit/themes/soria/Tree_rtl.css                    |    2 +-
 dijit/themes/soria/form/Button.css                 |    2 +-
 dijit/themes/soria/form/Button_rtl.css             |    2 +-
 dijit/themes/soria/form/Checkbox.css               |    2 +-
 dijit/themes/soria/form/Common.css                 |    2 +-
 dijit/themes/soria/form/RadioButton.css            |    2 +-
 dijit/themes/soria/form/Select.css                 |    8 +-
 dijit/themes/soria/form/Slider.css                 |   10 +-
 dijit/themes/soria/form/Slider_rtl.css             |    4 +-
 .../themes/soria/layout/AccordionContainer_rtl.css |    2 +-
 dijit/themes/soria/layout/BorderContainer.css      |   10 +-
 dijit/themes/soria/layout/ContentPane.css          |    2 +-
 dijit/themes/soria/layout/SplitContainer.css       |    8 +-
 dijit/themes/soria/layout/TabContainer.css         |   35 +-
 dijit/themes/soria/layout/TabContainer_rtl.css     |    6 +-
 dijit/themes/themeTester-orig.html                 | 1235 ++++++++++++++
 dijit/themes/themeTester.html                      | 1033 ++++++------
 dijit/themes/tundra/Calendar.css                   |   24 +-
 dijit/themes/tundra/Calendar_rtl.css               |    2 +-
 dijit/themes/tundra/ColorPalette.css               |    2 +-
 dijit/themes/tundra/Dialog.css                     |   23 +-
 dijit/themes/tundra/Menu.css                       |    8 +-
 dijit/themes/tundra/Menu_rtl.css                   |    2 +-
 dijit/themes/tundra/ProgressBar.css                |    2 +-
 dijit/themes/tundra/TimePicker_rtl.css             |    2 +-
 dijit/themes/tundra/TitlePane.css                  |    6 +-
 dijit/themes/tundra/TitlePane_rtl.css              |    2 +-
 dijit/themes/tundra/Toolbar.css                    |   12 +-
 dijit/themes/tundra/form/Button.css                |    4 +-
 dijit/themes/tundra/form/Checkbox.css              |    2 +-
 dijit/themes/tundra/form/Common.css                |    2 +-
 dijit/themes/tundra/form/Select.css                |    8 +-
 dijit/themes/tundra/form/Slider.css                |   20 +-
 dijit/themes/tundra/form/Slider_rtl.css            |    8 +-
 dijit/themes/tundra/layout/BorderContainer.css     |    2 +-
 dijit/themes/tundra/layout/ContentPane.css         |    2 +-
 dijit/themes/tundra/layout/TabContainer.css        |   28 +-
 dijit/themes/tundra/layout/TabContainer_rtl.css    |    2 +-
 dijit/tree/ForestStoreModel.js                     |   52 +-
 dijit/tree/TreeStoreModel.js                       |   18 +-
 dijit/tree/_dndContainer.js                        |   44 +-
 dijit/tree/_dndSelector.js                         |  273 +--
 dijit/tree/dndSource.js                            |   64 +-
 dojo/AdapterRegistry.js                            |    9 +-
 dojo/DeferredList.js                               |    8 +-
 dojo/LICENSE                                       |    2 +-
 dojo/NodeList-data.js                              |  170 ++
 dojo/NodeList-fx.js                                |   38 +-
 dojo/NodeList-html.js                              |   16 +-
 dojo/NodeList-manipulate.js                        |   23 +-
 dojo/NodeList-traverse.js                          |   35 +-
 dojo/OpenAjax.js                                   |   40 +-
 dojo/Stateful.js                                   |   39 +-
 dojo/_base.js                                      |   20 +-
 dojo/_base/Color.js                                |    9 +-
 dojo/_base/Deferred.js                             |  109 +-
 dojo/_base/NodeList.js                             |   85 +-
 dojo/_base/_loader/bootstrap.js                    |   93 +-
 dojo/_base/_loader/hostenv_browser.js              |   50 +-
 dojo/_base/_loader/hostenv_ff_ext.js               |    4 +-
 dojo/_base/_loader/hostenv_rhino.js                |   18 +-
 dojo/_base/_loader/hostenv_spidermonkey.js         |   20 +-
 dojo/_base/_loader/loader.js                       |  267 ++-
 dojo/_base/_loader/loader_xd.js                    |   38 +-
 dojo/_base/array.js                                |   40 +-
 dojo/_base/browser.js                              |   34 +-
 dojo/_base/connect.js                              |  111 +-
 dojo/_base/declare.js                              |   30 +-
 dojo/_base/event.js                                |  127 +-
 dojo/_base/fx.js                                   |    9 +-
 dojo/_base/html.js                                 |  271 ++-
 dojo/_base/json.js                                 |   17 +-
 dojo/_base/lang.js                                 |   37 +-
 dojo/_base/query-sizzle.js                         |   39 +-
 dojo/_base/query.js                                |  365 ++--
 dojo/_base/window.js                               |   22 +-
 dojo/_base/xhr.js                                  |  123 +-
 dojo/_firebug/firebug.js                           |  108 +-
 dojo/back.js                                       |   67 +-
 dojo/behavior.js                                   |   91 +-
 dojo/cache.js                                      |   12 +-
 dojo/cldr/monetary.js                              |    6 +-
 dojo/cldr/nls/ar/buddhist.js                       |  115 ++
 dojo/cldr/nls/ar/currency.js                       |   30 +-
 dojo/cldr/nls/ar/gregorian.js                      |  389 ++---
 dojo/cldr/nls/ar/hebrew.js                         |  206 +--
 dojo/cldr/nls/ar/islamic-civil.js                  |  346 ++--
 dojo/cldr/nls/ar/islamic.js                        |  250 +--
 dojo/cldr/nls/ar/number.js                         |   43 +-
 dojo/cldr/nls/buddhist.js                          |  417 ++---
 dojo/cldr/nls/ca/currency.js                       |   28 +-
 dojo/cldr/nls/ca/gregorian.js                      |  388 ++---
 dojo/cldr/nls/ca/number.js                         |   41 +-
 dojo/cldr/nls/cs/currency.js                       |   28 +-
 dojo/cldr/nls/cs/gregorian.js                      |  331 ++--
 dojo/cldr/nls/cs/number.js                         |   41 +-
 dojo/cldr/nls/currency.js                          |   60 +-
 dojo/cldr/nls/da/buddhist.js                       |  141 ++
 dojo/cldr/nls/da/currency.js                       |   30 +-
 dojo/cldr/nls/da/gregorian.js                      |  391 ++---
 dojo/cldr/nls/da/islamic.js                        |   87 +
 dojo/cldr/nls/da/number.js                         |   41 +-
 dojo/cldr/nls/de/buddhist.js                       |  130 ++
 dojo/cldr/nls/de/currency.js                       |   32 +-
 dojo/cldr/nls/de/gregorian.js                      |  397 ++---
 dojo/cldr/nls/de/islamic.js                        |  172 ++
 dojo/cldr/nls/de/number.js                         |   41 +-
 dojo/cldr/nls/el/buddhist.js                       |  120 ++
 dojo/cldr/nls/el/currency.js                       |   28 +-
 dojo/cldr/nls/el/gregorian.js                      |  401 ++---
 dojo/cldr/nls/el/hebrew.js                         |   73 +
 dojo/cldr/nls/el/number.js                         |   37 +-
 dojo/cldr/nls/en-au/currency.js                    |   14 +-
 dojo/cldr/nls/en-au/gregorian.js                   |   32 +-
 dojo/cldr/nls/en-au/number.js                      |   11 +-
 dojo/cldr/nls/en-ca/currency.js                    |   14 +-
 dojo/cldr/nls/en-ca/gregorian.js                   |   38 +-
 dojo/cldr/nls/en-gb/buddhist.js                    |  101 ++
 dojo/cldr/nls/en-gb/gregorian.js                   |   44 +-
 dojo/cldr/nls/en-gb/islamic.js                     |  153 ++
 dojo/cldr/nls/en-gb/number.js                      |   11 +-
 dojo/cldr/nls/en/buddhist.js                       |  109 ++
 dojo/cldr/nls/en/currency.js                       |   32 +-
 dojo/cldr/nls/en/gregorian.js                      |  376 ++---
 dojo/cldr/nls/en/islamic.js                        |  166 ++
 dojo/cldr/nls/en/number.js                         |   42 +-
 dojo/cldr/nls/es/buddhist.js                       |  125 ++
 dojo/cldr/nls/es/currency.js                       |   28 +-
 dojo/cldr/nls/es/gregorian.js                      |  394 ++---
 dojo/cldr/nls/es/islamic.js                        |  179 ++
 dojo/cldr/nls/es/number.js                         |   39 +-
 dojo/cldr/nls/fi/buddhist.js                       |  166 ++
 dojo/cldr/nls/fi/currency.js                       |   42 +-
 dojo/cldr/nls/fi/gregorian.js                      |  396 ++---
 dojo/cldr/nls/fi/hebrew.js                         |  176 ++
 dojo/cldr/nls/fi/islamic.js                        |  155 ++
 dojo/cldr/nls/fi/number.js                         |   41 +-
 dojo/cldr/nls/fr-ch/gregorian.js                   |    9 +
 dojo/cldr/nls/fr-ch/number.js                      |    9 +
 dojo/cldr/nls/fr/currency.js                       |   44 +-
 dojo/cldr/nls/fr/gregorian.js                      |  408 ++---
 dojo/cldr/nls/fr/number.js                         |   41 +-
 dojo/cldr/nls/gregorian.js                         |  461 +++---
 dojo/cldr/nls/he/currency.js                       |   28 +-
 dojo/cldr/nls/he/gregorian.js                      |  356 ++--
 dojo/cldr/nls/he/hebrew.js                         |  200 +--
 dojo/cldr/nls/he/islamic.js                        |  188 +--
 dojo/cldr/nls/he/number.js                         |   41 +-
 dojo/cldr/nls/hebrew.js                            |  427 ++---
 dojo/cldr/nls/hu/currency.js                       |   32 +-
 dojo/cldr/nls/hu/gregorian.js                      |  368 +++--
 dojo/cldr/nls/hu/number.js                         |   39 +-
 dojo/cldr/nls/islamic.js                           |  414 ++---
 dojo/cldr/nls/it/currency.js                       |   28 +-
 dojo/cldr/nls/it/gregorian.js                      |  387 ++---
 dojo/cldr/nls/it/number.js                         |   21 +-
 dojo/cldr/nls/ja/currency.js                       |   34 +-
 dojo/cldr/nls/ja/gregorian.js                      |  370 ++---
 dojo/cldr/nls/ja/number.js                         |   21 +-
 dojo/cldr/nls/ko/currency.js                       |   28 +-
 dojo/cldr/nls/ko/gregorian.js                      |  403 ++---
 dojo/cldr/nls/ko/number.js                         |   41 +-
 dojo/cldr/nls/nb/currency.js                       |   44 +-
 dojo/cldr/nls/nb/gregorian.js                      |  386 ++---
 dojo/cldr/nls/nb/number.js                         |   41 +-
 dojo/cldr/nls/nl/currency.js                       |   28 +-
 dojo/cldr/nls/nl/gregorian.js                      |  437 ++---
 dojo/cldr/nls/nl/number.js                         |   41 +-
 dojo/cldr/nls/number.js                            |   89 +-
 dojo/cldr/nls/pl/currency.js                       |   28 +-
 dojo/cldr/nls/pl/gregorian.js                      |  402 ++---
 dojo/cldr/nls/pl/number.js                         |   41 +-
 dojo/cldr/nls/pt-pt/gregorian.js                   |  223 +--
 dojo/cldr/nls/pt-pt/number.js                      |   13 +-
 dojo/cldr/nls/pt/currency.js                       |   28 +-
 dojo/cldr/nls/pt/gregorian.js                      |  392 ++---
 dojo/cldr/nls/pt/number.js                         |   41 +-
 dojo/cldr/nls/ro/buddhist.js                       |  121 ++
 dojo/cldr/nls/ro/currency.js                       |   15 +
 dojo/cldr/nls/ro/gregorian.js                      |  251 +++
 dojo/cldr/nls/ro/number.js                         |   22 +
 dojo/cldr/nls/ru/currency.js                       |   30 +-
 dojo/cldr/nls/ru/gregorian.js                      |  384 ++---
 dojo/cldr/nls/ru/number.js                         |   39 +-
 dojo/cldr/nls/sk/currency.js                       |   28 +-
 dojo/cldr/nls/sk/gregorian.js                      |  372 ++---
 dojo/cldr/nls/sk/number.js                         |   15 +-
 dojo/cldr/nls/sl/currency.js                       |   32 +-
 dojo/cldr/nls/sl/gregorian.js                      |  355 ++--
 dojo/cldr/nls/sl/number.js                         |   41 +-
 dojo/cldr/nls/sv/currency.js                       |   34 +-
 dojo/cldr/nls/sv/gregorian.js                      |  404 ++---
 dojo/cldr/nls/sv/number.js                         |   41 +-
 dojo/cldr/nls/th/buddhist.js                       |  190 +--
 dojo/cldr/nls/th/currency.js                       |   30 +-
 dojo/cldr/nls/th/gregorian.js                      |  386 ++---
 dojo/cldr/nls/th/number.js                         |   41 +-
 dojo/cldr/nls/tr/currency.js                       |   32 +-
 dojo/cldr/nls/tr/gregorian.js                      |  396 ++---
 dojo/cldr/nls/tr/number.js                         |   41 +-
 dojo/cldr/nls/zh-hant/buddhist.js                  |  146 ++
 dojo/cldr/nls/zh-hant/currency.js                  |   16 +
 dojo/cldr/nls/zh-hant/gregorian.js                 |  228 +++
 dojo/cldr/nls/zh-hant/islamic.js                   |   87 +
 dojo/cldr/nls/zh-hant/number.js                    |    7 +
 dojo/cldr/nls/zh-hk/currency.js                    |   15 +
 dojo/cldr/nls/zh-hk/gregorian.js                   |   85 +
 dojo/cldr/nls/zh-hk/number.js                      |    7 +
 dojo/cldr/nls/zh-tw/currency.js                    |  359 +---
 dojo/cldr/nls/zh-tw/gregorian.js                   |  242 +--
 dojo/cldr/nls/zh/currency.js                       |   30 +-
 dojo/cldr/nls/zh/gregorian.js                      |  412 ++---
 dojo/cldr/nls/zh/number.js                         |   21 +-
 dojo/cldr/supplemental.js                          |   20 +-
 dojo/colors.js                                     |   12 +-
 dojo/cookie.js                                     |   19 +-
 dojo/currency.js                                   |   19 +-
 dojo/data/ItemFileReadStore.js                     |  200 +--
 dojo/data/ItemFileWriteStore.js                    |   88 +-
 dojo/data/ObjectStore.js                           |  477 ++++++
 dojo/data/api/Identity.js                          |   34 +-
 dojo/data/api/Notification.js                      |   36 +-
 dojo/data/api/Read.js                              |  164 +-
 dojo/data/api/Request.js                           |   15 +-
 dojo/data/api/Write.js                             |   44 +-
 dojo/data/util/filter.js                           |   12 +-
 dojo/data/util/simpleFetch.js                      |   29 +-
 dojo/data/util/sorter.js                           |   24 +-
 dojo/date.js                                       |   16 +-
 dojo/date/locale.js                                |   51 +-
 dojo/date/stamp.js                                 |   12 +-
 dojo/dnd/Avatar.js                                 |    9 +-
 dojo/dnd/Container.js                              |   17 +-
 dojo/dnd/Manager.js                                |   25 +-
 dojo/dnd/Moveable.js                               |   32 +-
 dojo/dnd/Mover.js                                  |   52 +-
 dojo/dnd/Selector.js                               |    8 +-
 dojo/dnd/Source.js                                 |   12 +-
 dojo/dnd/TimedMoveable.js                          |    9 +-
 dojo/dnd/autoscroll.js                             |   35 +-
 dojo/dnd/common.js                                 |    6 +-
 dojo/dnd/move.js                                   |  116 +-
 dojo/dojo.js                                       |   41 +-
 dojo/fx.js                                         |   37 +-
 dojo/fx/Toggler.js                                 |   17 +-
 dojo/fx/easing.js                                  |   62 +-
 dojo/gears.js                                      |    8 +-
 dojo/hash.js                                       |   42 +-
 dojo/html.js                                       |  102 +-
 dojo/i18n.js                                       |   29 +-
 dojo/io/iframe.js                                  |   72 +-
 dojo/io/script.js                                  |   26 +-
 dojo/jaxer.js                                      |    5 +-
 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/nls/ar/colors.js                              |    6 +-
 dojo/nls/ca/colors.js                              |    6 +-
 dojo/nls/colors.js                                 |   36 +-
 dojo/nls/cs/colors.js                              |    6 +-
 dojo/nls/da/colors.js                              |    6 +-
 dojo/nls/de/colors.js                              |    6 +-
 dojo/nls/el/colors.js                              |    6 +-
 dojo/nls/es/colors.js                              |    6 +-
 dojo/nls/fi/colors.js                              |  290 ++--
 dojo/nls/fr/colors.js                              |    6 +-
 dojo/nls/he/colors.js                              |    6 +-
 dojo/nls/hu/colors.js                              |    6 +-
 dojo/nls/it/colors.js                              |    6 +-
 dojo/nls/ja/colors.js                              |    6 +-
 dojo/nls/kk/colors.js                              |  159 ++
 dojo/nls/ko/colors.js                              |    6 +-
 dojo/nls/nb/colors.js                              |    6 +-
 dojo/nls/nl/colors.js                              |    6 +-
 dojo/nls/pl/colors.js                              |  110 +-
 dojo/nls/pt-pt/colors.js                           |   14 +-
 dojo/nls/pt/colors.js                              |   58 +-
 dojo/nls/ro/colors.js                              |    6 +-
 dojo/nls/ru/colors.js                              |    6 +-
 dojo/nls/sk/colors.js                              |    6 +-
 dojo/nls/sl/colors.js                              |  105 +-
 dojo/nls/sv/colors.js                              |    6 +-
 dojo/nls/th/colors.js                              |    6 +-
 dojo/nls/tr/colors.js                              |    6 +-
 dojo/nls/zh-tw/colors.js                           |    6 +-
 dojo/nls/zh/colors.js                              |  188 +--
 dojo/number.js                                     |   38 +-
 dojo/package.json                                  |   21 +
 dojo/parser.js                                     |  305 ++--
 dojo/regexp.js                                     |   16 +-
 dojo/resources/_modules.js                         |    2 +-
 dojo/robot.js                                      |    8 +-
 dojo/robotx.js                                     |   80 +-
 dojo/rpc/JsonService.js                            |    8 +-
 dojo/rpc/JsonpService.js                           |   15 +-
 dojo/rpc/RpcService.js                             |   13 +-
 dojo/store/Cache.js                                |  142 ++
 dojo/store/DataStore.js                            |  132 ++
 dojo/store/JsonRest.js                             |  136 ++
 dojo/store/Memory.js                               |  153 ++
 dojo/store/Observable.js                           |  164 ++
 dojo/store/README                                  |   10 +
 dojo/store/api/Store.js                            |  297 ++++
 dojo/store/util/QueryResults.js                    |   58 +
 dojo/store/util/SimpleQueryEngine.js               |  107 ++
 dojo/string.js                                     |   24 +-
 dojo/tests/AdapterRegistry.js                      |    8 +-
 dojo/tests/DeferredList.js                         |    8 +-
 dojo/tests/NodeList-data.html                      |  209 +++
 dojo/tests/NodeList-data.js                        |    4 +
 dojo/tests/NodeList-traverse.html                  |   57 +-
 dojo/tests/Stateful.js                             |   39 +-
 dojo/tests/_base.js                                |   14 +-
 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                          |    2 +-
 dojo/tests/_base/Deferred.js                       |   83 +-
 dojo/tests/_base/NodeList.html                     |   18 +-
 dojo/tests/_base/_loader/8976.html                 |    5 +-
 dojo/tests/_base/_loader/a.js                      |    3 +
 dojo/tests/_base/_loader/afterOnLoad.html          |    6 +-
 dojo/tests/_base/_loader/bootstrap.js              |   15 +-
 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/hostenv_browser.js        |    8 +-
 dojo/tests/_base/_loader/hostenv_rhino.js          |    2 +-
 dojo/tests/_base/_loader/hostenv_spidermonkey.js   |    2 +-
 dojo/tests/_base/_loader/loader.js                 |    2 +-
 dojo/tests/_base/_loader/modules.js                |   21 +
 dojo/tests/_base/_loader/modules/anon.js           |    6 +
 dojo/tests/_base/_loader/modules/data.js           |    4 +
 dojo/tests/_base/_loader/modules/factoryArity.js   |    2 +
 dojo/tests/_base/_loader/modules/full.js           |    7 +
 dojo/tests/_base/_loader/modules/wrapped.js        |    4 +
 dojo/tests/_base/_loader/scope/scope04.html        |    6 +-
 dojo/tests/_base/_loader/scope/scopeContained.html |    6 +-
 .../_base/_loader/scope/scopeContainedXd.html      |    6 +-
 dojo/tests/_base/_loader/scope/scopeDjConfig.html  |    6 +-
 dojo/tests/_base/_loader/scope/scopeSingle.html    |    6 +-
 .../tests/_base/_loader/scope/scopeSingleDaac.html |    6 +-
 dojo/tests/_base/array.js                          |    2 +-
 dojo/tests/_base/connect.js                        |   18 +-
 dojo/tests/_base/declare.js                        |    2 +-
 dojo/tests/_base/html.html                         |   61 +-
 dojo/tests/_base/html_rtl.html                     |  178 +-
 dojo/tests/_base/json.js                           |    2 +-
 dojo/tests/_base/lang.js                           |   10 +-
 dojo/tests/_base/query.html                        |    2 +-
 dojo/tests/_base/query.js                          |    4 +-
 dojo/tests/_base/runTests.html                     |    9 +
 dojo/tests/_base/scrollingIframe.js                |  104 ++
 dojo/tests/_base/scrollingQuirksIframe.html        |    6 +
 dojo/tests/_base/scrollingStrictIframe.html        |    6 +
 dojo/tests/_base/window.js                         |    2 +-
 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/baseonly.js                             |    7 +
 dojo/tests/behavior.html                           |    3 +-
 dojo/tests/cache.js                                |    2 +-
 dojo/tests/cldr.js                                 |    2 +-
 dojo/tests/colors.js                               |    2 +-
 dojo/tests/currency.js                             |   85 +-
 dojo/tests/data.js                                 |    9 +-
 dojo/tests/data/ItemFileReadStore.js               |    8 +-
 dojo/tests/data/ItemFileWriteStore.js              |  153 +-
 dojo/tests/data/ObjectStore.js                     |   98 ++
 dojo/tests/data/readOnlyItemFileTestTemplates.js   |  411 +++--
 dojo/tests/data/utils.js                           |    2 +-
 dojo/tests/date.js                                 |    8 +-
 dojo/tests/date/locale.js                          |   47 +-
 dojo/tests/date/stamp.js                           |    2 +-
 dojo/tests/dnd/test_box_constraints.html           |   12 +-
 dojo/tests/dnd/test_custom_constraints.html        |    6 +-
 .../tests/dnd/test_parent_constraints_margins.html |    1 -
 dojo/tests/hash.js                                 |    2 +-
 dojo/tests/html/test_set.html                      |  758 +++++----
 dojo/tests/i18n.js                                 |   55 +-
 dojo/tests/module.js                               |    4 +-
 dojo/tests/nls/ar/salutations.js                   |    4 +
 dojo/tests/nls/cs/salutations.js                   |    4 +
 dojo/tests/nls/de/salutations.js                   |    4 +
 dojo/tests/nls/el/salutations.js                   |    4 +
 dojo/tests/nls/en-au/salutations.js                |    4 +
 dojo/tests/nls/en-us-hawaii/salutations.js         |    4 +
 .../nls/en-us-new_york-brooklyn/salutations.js     |    4 +
 dojo/tests/nls/en-us-texas/salutations.js          |    4 +
 dojo/tests/nls/es/salutations.js                   |    4 +
 dojo/tests/nls/fa/salutations.js                   |    4 +
 dojo/tests/nls/fr/salutations.js                   |    4 +
 dojo/tests/nls/he/salutations.js                   |    4 +
 dojo/tests/nls/hi/salutations.js                   |    4 +
 dojo/tests/nls/it/salutations.js                   |    4 +
 dojo/tests/nls/ja/salutations.js                   |    4 +
 dojo/tests/nls/ko/salutations.js                   |    4 +
 dojo/tests/nls/pl/salutations.js                   |    4 +
 dojo/tests/nls/pt/salutations.js                   |    4 +
 dojo/tests/nls/ru/salutations.js                   |    4 +
 dojo/tests/nls/salutations.js                      |   30 +
 dojo/tests/nls/sw/salutations.js                   |    4 +
 dojo/tests/nls/th/salutations.js                   |    4 +
 dojo/tests/nls/tr/salutations.js                   |    4 +
 dojo/tests/nls/yi/salutations.js                   |    4 +
 dojo/tests/nls/zh-cn/salutations.js                |    4 +
 dojo/tests/nls/zh-tw/salutations.js                |    4 +
 dojo/tests/number.js                               |  259 +--
 dojo/tests/parser.html                             |  329 ++--
 dojo/tests/regexp.js                               |    2 +-
 dojo/tests/resources/test_css.html                 |    2 +-
 dojo/tests/rpc.js                                  |    8 +-
 dojo/tests/sie/all.js                              |   22 +
 dojo/tests/sie/smoke-v15.html                      |   29 +
 dojo/tests/sie/smoke.html                          |   31 +
 dojo/tests/smoke-dojo-sie.html                     |   11 +
 dojo/tests/store.js                                |    4 +
 dojo/tests/store/Cache.js                          |   83 +
 dojo/tests/store/DataStore.js                      |   54 +
 dojo/tests/store/JsonRest.js                       |   40 +
 dojo/tests/store/Memory.js                         |   99 ++
 dojo/tests/store/Observable.js                     |   92 ++
 dojo/tests/store/node1.1                           |    4 +
 dojo/tests/store/node1.2                           |    1 +
 dojo/tests/store/runTests.html                     |    9 +
 dojo/tests/store/treeTestRoot                      |   10 +
 dojo/tests/string.js                               |   14 +-
 dojo/tests/window/test_scroll.html                 |  195 +--
 dojo/uacss.js                                      |    8 +-
 dojo/window.js                                     |   20 +-
 dojox/LICENSE                                      |    2 +-
 dojox/NodeList/README                              |   33 +
 dojox/NodeList/delegate.js                         |   56 +
 dojox/NodeList/tests/delegate.html                 |   70 +
 dojox/analytics/Urchin.js                          |   34 +-
 dojox/analytics/_base.js                           |    2 +-
 dojox/analytics/plugins/consoleMessages.js         |    2 +-
 dojox/analytics/plugins/idle.js                    |    2 +-
 dojox/analytics/plugins/mouseOver.js               |   14 +-
 dojox/analytics/plugins/window.js                  |    4 +-
 dojox/analytics/profiles/analytics.profile.js      |    2 +-
 .../analytics/profiles/analyticsInBase.profile.js  |    2 +-
 dojox/atom/io/Connection.js                        |  102 +-
 dojox/atom/io/model.js                             |  348 ++--
 dojox/atom/tests/io/module.js                      |    4 +-
 dojox/atom/widget/FeedEntryEditor.js               |  166 +-
 dojox/atom/widget/FeedEntryViewer.js               |   16 +-
 dojox/atom/widget/FeedViewer.js                    |  206 +--
 dojox/atom/widget/nls/ar/FeedEntryViewer.js        |    4 +-
 dojox/atom/widget/nls/ar/PeopleEditor.js           |    3 +-
 dojox/atom/widget/nls/ca/FeedEntryViewer.js        |    2 +-
 dojox/atom/widget/nls/da/FeedEntryViewer.js        |    3 +-
 dojox/atom/widget/nls/fi/FeedEntryViewer.js        |    5 +-
 dojox/atom/widget/nls/fi/PeopleEditor.js           |    3 +-
 dojox/atom/widget/nls/he/FeedEntryViewer.js        |    3 +-
 dojox/atom/widget/nls/kk/FeedEntryEditor.js        |    7 +
 dojox/atom/widget/nls/kk/FeedEntryViewer.js        |   12 +
 dojox/atom/widget/nls/kk/FeedViewerEntry.js        |    4 +
 dojox/atom/widget/nls/kk/PeopleEditor.js           |    6 +
 dojox/atom/widget/nls/ko/FeedEntryViewer.js        |    6 +-
 dojox/atom/widget/nls/pl/FeedEntryEditor.js        |   11 +-
 dojox/atom/widget/nls/pl/FeedEntryViewer.js        |    7 +-
 dojox/atom/widget/nls/sl/PeopleEditor.js           |    2 +-
 dojox/atom/widget/nls/sv/PeopleEditor.js           |    2 +-
 dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js     |    4 +-
 dojox/atom/widget/nls/zh-tw/PeopleEditor.js        |    4 +-
 dojox/calc/FuncGen.js                              |  139 ++
 dojox/calc/GraphPro.js                             |  136 ++
 dojox/calc/Grapher.js                              |  623 +++++++
 dojox/calc/Readme.txt                              |  175 ++
 dojox/calc/Standard.js                             |  356 ++++
 dojox/calc/_Executor.js                            |  146 ++
 dojox/calc/_ExecutorIframe.html                    |  525 ++++++
 dojox/calc/resources/Common.css                    |  146 ++
 dojox/calc/resources/GraphPro.css                  |    7 +
 dojox/calc/resources/Standard.css                  |    7 +
 dojox/calc/templates/FuncGen.html                  |   17 +
 dojox/calc/templates/GraphPro.html                 |  165 ++
 dojox/calc/templates/Grapher.html                  |  117 ++
 dojox/calc/templates/Standard.html                 |  101 ++
 dojox/calc/tests/test_Executor.html                |  289 ++++
 dojox/calc/tests/test_GraphPro.html                |   42 +
 dojox/calc/tests/test_Standard.html                |   38 +
 dojox/calc/toFrac.js                               |  137 ++
 dojox/charting/Chart.js                            | 1108 +++++++++++++
 dojox/charting/Chart2D.js                          | 1032 +-----------
 dojox/charting/Element.js                          |  115 ++
 dojox/charting/Series.js                           |    2 +-
 dojox/charting/StoreSeries.js                      |   98 ++
 dojox/charting/Theme.js                            |   20 +-
 dojox/charting/action2d/Base.js                    |    4 +-
 dojox/charting/action2d/Tooltip.js                 |  184 +--
 dojox/charting/axis2d/Default.js                   |  149 +-
 dojox/charting/axis2d/Invisible.js                 |   22 +-
 dojox/charting/plot2d/Bubble.js                    |    5 +-
 dojox/charting/plot2d/Default.js                   |    5 +-
 dojox/charting/plot2d/Pie.js                       |  168 +-
 dojox/charting/plot2d/Scatter.js                   |    3 +-
 dojox/charting/plot2d/Spider.js                    |  640 ++++++++
 dojox/charting/plot2d/StackedBars.js               |    1 +
 dojox/charting/plot2d/StackedColumns.js            |    1 +
 dojox/charting/plot2d/_PlotEvents.js               |   18 +-
 dojox/charting/plot2d/common.js                    |   14 +-
 dojox/charting/plot3d/Bars.js                      |    4 +-
 dojox/charting/plot3d/Cylinders.js                 |    6 +-
 dojox/charting/resources/Legend.css                |   24 +
 dojox/charting/scaler/common.js                    |   10 +-
 dojox/charting/scaler/linear.js                    |    8 +-
 .../charting/tests/gradients/test_grad_bars1.html  |   14 +-
 .../charting/tests/gradients/test_grad_bars2.html  |   12 +-
 .../charting/tests/gradients/test_grad_bars3.html  |   12 +-
 .../charting/tests/gradients/test_grad_bars4.html  |   12 +-
 .../charting/tests/gradients/test_grad_bars5.html  |   12 +-
 .../tests/gradients/test_grad_bubble1.html         |    6 +-
 .../tests/gradients/test_grad_bubble2.html         |    6 +-
 .../tests/gradients/test_grad_bubble3.html         |    6 +-
 .../tests/gradients/test_grad_bubble4.html         |    6 +-
 .../tests/gradients/test_grad_bubble6.html         |    6 +-
 .../tests/gradients/test_grad_columns1.html        |   14 +-
 .../tests/gradients/test_grad_columns2.html        |   12 +-
 .../tests/gradients/test_grad_columns3.html        |   12 +-
 .../tests/gradients/test_grad_columns4.html        |   12 +-
 .../tests/gradients/test_grad_columns5.html        |   12 +-
 dojox/charting/tests/gradients/test_grad_pie1.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie2.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie3.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie4.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie7.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie8.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pie9.html |    5 +-
 dojox/charting/tests/gradients/test_grad_pieA.html |    5 +-
 .../tests/gradients/test_grad_scatter1.html        |    8 +-
 .../tests/gradients/test_grad_scatter2.html        |    6 +-
 .../tests/gradients/test_grad_scatterB.html        |    6 +-
 dojox/charting/tests/test_DataSeries.html          |   10 +-
 dojox/charting/tests/test_StoreSeries.html         |  225 +++
 dojox/charting/tests/test_anim2d.html              |   39 +-
 dojox/charting/tests/test_axes.html                |   13 +-
 dojox/charting/tests/test_axisZoomControl.html     |   12 +-
 dojox/charting/tests/test_bars.html                |    4 -
 dojox/charting/tests/test_chart2d.html             |  120 +-
 dojox/charting/tests/test_chart2d_dynamics.html    |   44 +-
 dojox/charting/tests/test_chart2d_updating.html    |   14 +-
 dojox/charting/tests/test_chartAxisTitle.html      |  164 ++
 dojox/charting/tests/test_chartTitle.html          |   93 ++
 dojox/charting/tests/test_cylinders.html           |    4 -
 dojox/charting/tests/test_event2d.html             |   82 +-
 dojox/charting/tests/test_fireEvent.html           |   16 +-
 dojox/charting/tests/test_label_shortening.html    |  145 ++
 dojox/charting/tests/test_labels2d.html            |   55 +-
 dojox/charting/tests/test_nulls.html               |   26 +-
 dojox/charting/tests/test_pie2d.html               |   33 +-
 dojox/charting/tests/test_pie_smart_label.html     |  133 ++
 dojox/charting/tests/test_plot_order.html          |    6 +-
 dojox/charting/tests/test_rotatedLabels.html       |    6 +-
 dojox/charting/tests/test_scaler.html              |    5 -
 dojox/charting/tests/test_selectableLegend.html    |  249 +++
 dojox/charting/tests/test_series_order.html        |    6 +-
 dojox/charting/tests/test_sparklines.html          |    4 +-
 dojox/charting/tests/test_spider2d.html            |  285 ++++
 dojox/charting/tests/test_tension.html             |    6 +-
 dojox/charting/tests/test_themes.html              |   30 +-
 dojox/charting/tests/test_widget2d.html            |   38 +-
 dojox/charting/tests/test_widget2d_deprecated.html |  104 ++
 dojox/charting/tests/test_win2d.html               |   19 +-
 dojox/charting/tests/theme_preview.html            |    7 +-
 dojox/charting/themes/Charged.js                   |   20 +-
 dojox/charting/themes/Claro.js                     |  108 ++
 dojox/charting/themes/Distinctive.js               |    4 +-
 dojox/charting/themes/ET/greys.js                  |   55 -
 dojox/charting/themes/Electric.js                  |   20 +-
 dojox/charting/themes/Harmony.js                   |    2 +-
 dojox/charting/themes/Midwest.js                   |    2 +-
 dojox/charting/themes/Minty.js                     |    2 +-
 dojox/charting/themes/Renkoo.js                    |   16 +-
 dojox/charting/themes/SageToLime.js                |    2 +-
 dojox/charting/themes/Tom.js                       |   16 +-
 dojox/charting/themes/Tufte.js                     |   16 +-
 dojox/charting/widget/Chart.js                     |  267 +++
 dojox/charting/widget/Chart2D.js                   |  265 +--
 dojox/charting/widget/Legend.js                    |   38 +-
 dojox/charting/widget/SelectableLegend.js          |  237 +++
 dojox/charting/widget/Sparkline.js                 |    6 +-
 dojox/collections/BinaryTree.js                    |   10 +-
 dojox/collections/Dictionary.js                    |    8 +-
 dojox/collections/SortedList.js                    |    2 +-
 dojox/collections/_base.js                         |   10 +-
 dojox/color/Colorspace.js                          |   52 +-
 dojox/color/Palette.js                             |   14 +-
 dojox/cometd/HttpChannels.js                       |    8 +-
 dojox/cometd/RestChannels.js                       |   74 +-
 dojox/cometd/_base.js                              |   26 +-
 dojox/cometd/ack.js                                |    6 +-
 dojox/cometd/callbackPollTransport.js              |    6 +-
 dojox/cometd/longPollTransportFormEncoded.js       |    4 +-
 dojox/cometd/longPollTransportJsonEncoded.js       |    4 +-
 dojox/cometd/tests/_base.js                        |    2 +-
 dojox/cometd/timesync.js                           |   20 +-
 dojox/css3/fx.js                                   |    2 +-
 dojox/data/AndOrReadStore.js                       |  197 ++-
 dojox/data/AndOrWriteStore.js                      |   88 +-
 dojox/data/AppStore.js                             |  121 +-
 dojox/data/AtomReadStore.js                        |   22 +-
 dojox/data/CdfStore.js                             |   30 +-
 dojox/data/ClientFilter.js                         |   41 +-
 dojox/data/CouchDBRestStore.js                     |    7 +-
 dojox/data/CssClassStore.js                        |   29 +-
 dojox/data/CssRuleStore.js                         |   84 +-
 dojox/data/CsvStore.js                             |  122 +-
 dojox/data/FileStore.js                            |   60 +-
 dojox/data/FlickrRestStore.js                      |    7 +-
 dojox/data/FlickrStore.js                          |  540 +++---
 dojox/data/GoogleFeedStore.js                      |   10 +-
 dojox/data/GoogleSearchStore.js                    |   22 +-
 dojox/data/HtmlStore.js                            |  116 +-
 dojox/data/HtmlTableStore.js                       |   85 +-
 dojox/data/JsonQueryRestStore.js                   |   11 +-
 dojox/data/JsonRestStore.js                        |    8 +-
 dojox/data/KeyValueStore.js                        |   91 +-
 dojox/data/OpenSearchStore.js                      |   46 +-
 dojox/data/OpmlStore.js                            |   98 +-
 dojox/data/PersevereStore.js                       |   16 +-
 dojox/data/PicasaStore.js                          |   56 +-
 dojox/data/QueryReadStore.js                       |   44 +-
 dojox/data/RailsStore.js                           |    9 +-
 dojox/data/S3Store.js                              |    7 +-
 dojox/data/ServiceStore.js                         |    5 +-
 dojox/data/SnapLogicStore.js                       |   50 +-
 dojox/data/StoreExplorer.js                        |   18 +-
 dojox/data/WikipediaStore.js                       |   10 +-
 dojox/data/XmlStore.js                             |   80 +-
 dojox/data/css.js                                  |   15 +-
 dojox/data/demos/stores/LazyLoadJSIStore.js        |   12 +-
 dojox/data/demos/widgets/FileView.js               |    2 +-
 dojox/data/demos/widgets/FlickrViewList.js         |    2 +-
 dojox/data/demos/widgets/PicasaView.js             |    2 +-
 dojox/data/dom.js                                  |   11 +-
 dojox/data/tests/ClientFilter.js                   |   24 +-
 dojox/data/tests/dom.js                            |    2 +-
 dojox/data/tests/module.js                         |    4 +-
 dojox/data/tests/performance/CsvStore.js           |   12 +-
 dojox/data/tests/stores/AndOrReadStore.js          |  436 ++---
 dojox/data/tests/stores/AndOrWriteStore.js         |  548 +++----
 dojox/data/tests/stores/AppStore.js                |   90 +-
 dojox/data/tests/stores/CssClassStore.js           |  136 +-
 dojox/data/tests/stores/CssRuleStore.js            |  112 +-
 dojox/data/tests/stores/CsvStore.js                |  192 +--
 dojox/data/tests/stores/FileStore.js               |   62 +-
 dojox/data/tests/stores/FlickrRestStore.js         |   86 +-
 dojox/data/tests/stores/FlickrStore.js             |   48 +-
 dojox/data/tests/stores/GoogleSearchStore.js       |    2 +-
 dojox/data/tests/stores/HtmlStore.js               |  104 +-
 dojox/data/tests/stores/HtmlTableStore.js          |   66 +-
 dojox/data/tests/stores/JsonQueryRestStore.js      |   40 +-
 dojox/data/tests/stores/JsonRestStore.js           |   50 +-
 dojox/data/tests/stores/KeyValueStore.js           |  150 +-
 dojox/data/tests/stores/OpenSearchStore.js         |   78 +-
 dojox/data/tests/stores/OpmlStore.js               |  142 +-
 dojox/data/tests/stores/PicasaStore.js             |   48 +-
 dojox/data/tests/stores/QueryReadStore.js          |   28 +-
 dojox/data/tests/stores/ServiceStore.js            |   24 +-
 dojox/data/tests/stores/SnapLogicStore.js          |   74 +-
 dojox/data/tests/stores/XmlStore.js                |  128 +-
 dojox/data/tests/stores/properties.js              |    2 +-
 dojox/data/util/JsonQuery.js                       |   23 +-
 dojox/date/buddhist.js                             |   12 +-
 dojox/date/buddhist/Date.js                        |   32 +-
 dojox/date/buddhist/locale.js                      |   53 +-
 dojox/date/hebrew.js                               |   16 +-
 dojox/date/hebrew/Date.js                          |   52 +-
 dojox/date/hebrew/locale.js                        |   78 +-
 dojox/date/hebrew/numerals.js                      |   14 +-
 dojox/date/islamic.js                              |   18 +-
 dojox/date/islamic/Date.js                         |   51 +-
 dojox/date/islamic/locale.js                       |   34 +-
 dojox/date/php.js                                  |    2 +-
 dojox/date/posix.js                                |   12 +-
 dojox/date/relative.js                             |    2 +-
 dojox/date/tests/buddhist/Date.js                  |   48 +-
 dojox/date/tests/hebrew/Date.js                    |  120 +-
 dojox/date/tests/islamic/Date.js                   |   18 +-
 dojox/date/tests/posix.js                          |    6 +-
 dojox/date/tests/relative.js                       |    8 +-
 dojox/date/tests/timezoneFormatting.js             |    2 +-
 dojox/date/timezone.js                             |   61 +-
 dojox/dnd/BoundingBoxController.js                 |    2 +-
 dojox/drawing/Drawing.js                           |   53 +-
 dojox/drawing/_base.js                             |    1 +
 dojox/drawing/annotations/Arrow.js                 |    2 +-
 dojox/drawing/annotations/BoxShadow.js             |   18 +-
 dojox/drawing/annotations/Label.js                 |   13 +-
 dojox/drawing/library/greek.js                     |   66 +
 dojox/drawing/manager/Anchors.js                   |   22 +-
 dojox/drawing/manager/Canvas.js                    |    6 +-
 dojox/drawing/manager/Mouse.js                     |   44 +-
 dojox/drawing/manager/Stencil.js                   |   53 +-
 dojox/drawing/manager/StencilUI.js                 |    2 +-
 dojox/drawing/manager/Undo.js                      |    4 +-
 dojox/drawing/manager/_registry.js                 |    6 +-
 dojox/drawing/manager/keys.js                      |   14 +-
 dojox/drawing/plugins/_Plugin.js                   |    2 +-
 dojox/drawing/plugins/drawing/GreekPalette.js      |  325 ++++
 dojox/drawing/plugins/drawing/Grid.js              |    2 +-
 dojox/drawing/plugins/drawing/Silverlight.js       |    6 +-
 dojox/drawing/plugins/tools/Pan.js                 |    4 +-
 dojox/drawing/resources/GreekPalette.css           |   57 +
 dojox/drawing/stencil/Ellipse.js                   |    2 +-
 dojox/drawing/stencil/Image.js                     |    2 +-
 dojox/drawing/stencil/Line.js                      |    4 +-
 dojox/drawing/stencil/Path.js                      |    4 +-
 dojox/drawing/stencil/Rect.js                      |    2 +-
 dojox/drawing/stencil/Text.js                      |   12 +-
 dojox/drawing/stencil/_Base.js                     |   11 +-
 dojox/drawing/tests/drawing.html                   |   10 +-
 dojox/drawing/tests/test_drawing.html              |   14 +-
 dojox/drawing/tests/test_drawing_toolbar.html      |   10 +-
 dojox/drawing/tests/test_paths.html                |   14 +-
 dojox/drawing/tools/Arrow.js                       |   15 +
 dojox/drawing/tools/Ellipse.js                     |    2 +-
 dojox/drawing/tools/Line.js                        |   12 +-
 dojox/drawing/tools/Path.js                        |   10 +-
 dojox/drawing/tools/TextBlock.js                   |  238 ++-
 dojox/drawing/tools/custom/Axes.js                 |    4 +-
 dojox/drawing/tools/custom/Vector.js               |   40 +-
 dojox/drawing/ui/Button.js                         |    6 +-
 dojox/drawing/ui/Toolbar.js                        |   27 +-
 dojox/drawing/ui/Tooltip.js                        |    4 +-
 dojox/drawing/ui/dom/Pan.js                        |    4 +-
 dojox/drawing/ui/dom/Toolbar.js                    |    4 +-
 dojox/drawing/util/common.js                       |   10 +-
 dojox/drawing/util/oo.js                           |    4 +-
 dojox/drawing/util/positioning.js                  |   21 +-
 dojox/drawing/util/typeset.js                      |   67 +
 dojox/dtl/_Templated.js                            |    4 +-
 dojox/dtl/_base.js                                 |    2 +-
 dojox/dtl/tests/context.js                         |    2 +-
 dojox/dtl/tests/dom/buffer.js                      |    2 +-
 dojox/dtl/tests/dom/tag.js                         |    2 +-
 dojox/dtl/tests/text/filter.js                     |    4 +-
 dojox/dtl/tests/text/tag.js                        |    2 +-
 dojox/dtl/utils/date.js                            |    2 +-
 dojox/editor/README                                |   75 +-
 dojox/editor/plugins/AutoSave.js                   |  409 +++++
 dojox/editor/plugins/AutoUrlLink.js                |  223 +++
 dojox/editor/plugins/Blockquote.js                 |   77 +-
 dojox/editor/plugins/Breadcrumb.js                 |   69 +-
 dojox/editor/plugins/CollapsibleToolbar.js         |   14 +-
 dojox/editor/plugins/EntityPalette.js              |   13 +-
 dojox/editor/plugins/FindReplace.js                |   65 +-
 dojox/editor/plugins/InsertAnchor.js               |   41 +-
 dojox/editor/plugins/InsertEntity.js               |   27 +-
 dojox/editor/plugins/LocalImage.js                 |  341 ++++
 dojox/editor/plugins/NormalizeIndentOutdent.js     |   89 +-
 dojox/editor/plugins/NormalizeStyle.js             |   57 +-
 dojox/editor/plugins/PageBreak.js                  |   23 +-
 dojox/editor/plugins/PasteFromWord.js              |   41 +-
 dojox/editor/plugins/PrettyPrint.js                |   19 +-
 dojox/editor/plugins/Preview.js                    |   20 +-
 dojox/editor/plugins/ResizeTableColumn.js          |  290 ++++
 dojox/editor/plugins/Save.js                       |   32 +-
 dojox/editor/plugins/ShowBlockNodes.js             |   32 +-
 dojox/editor/plugins/Smiley.js                     |   23 +-
 dojox/editor/plugins/SpellCheck.js                 | 1405 ++++++++++++++++
 dojox/editor/plugins/StatusBar.js                  |   14 +-
 dojox/editor/plugins/TablePlugins.js               |  282 +++-
 dojox/editor/plugins/TextColor.js                  |   29 +-
 dojox/editor/plugins/ToolbarLineBreak.js           |   16 +-
 dojox/editor/plugins/UploadImage.js                |   20 +-
 dojox/editor/plugins/_SmileyPalette.js             |   18 +-
 dojox/editor/plugins/_SpellCheckParser.js          |   63 +
 dojox/editor/plugins/nls/AutoSave.js               |   13 +
 dojox/editor/plugins/nls/LocalImage.js             |   10 +
 dojox/editor/plugins/nls/Smiley.js                 |    6 +-
 dojox/editor/plugins/nls/SpellCheck.js             |   16 +
 dojox/editor/plugins/nls/TableDialog.js            |    4 +-
 dojox/editor/plugins/nls/ar/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/ar/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ar/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/ar/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/ar/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/ar/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/ar/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ar/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/ar/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ar/PasteFromWord.js       |    7 +
 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              |   22 +
 dojox/editor/plugins/nls/ar/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/ar/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/ar/TextColor.js           |    5 +
 dojox/editor/plugins/nls/ar/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/ca/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/ca/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ca/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/ca/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/ca/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/ca/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/ca/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/ca/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/ca/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/ca/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/ca/Preview.js             |    4 +
 dojox/editor/plugins/nls/ca/Save.js                |    4 +
 dojox/editor/plugins/nls/ca/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/ca/Smiley.js              |   22 +
 dojox/editor/plugins/nls/ca/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/ca/TableDialog.js         |    2 +-
 dojox/editor/plugins/nls/ca/TextColor.js           |    5 +
 dojox/editor/plugins/nls/ca/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/cs/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/cs/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/cs/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/cs/FindReplace.js         |   22 +-
 dojox/editor/plugins/nls/cs/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/cs/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/cs/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/cs/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/cs/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/cs/TableDialog.js         |    2 +-
 dojox/editor/plugins/nls/cs/TextColor.js           |    5 +
 dojox/editor/plugins/nls/da/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/da/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/da/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/da/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/da/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/da/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/da/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/da/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/da/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/da/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/da/Preview.js             |    4 +
 dojox/editor/plugins/nls/da/Save.js                |    4 +
 dojox/editor/plugins/nls/da/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/da/Smiley.js              |   22 +
 dojox/editor/plugins/nls/da/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/da/TableDialog.js         |    3 +-
 dojox/editor/plugins/nls/da/TextColor.js           |    5 +
 dojox/editor/plugins/nls/da/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/de/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/de/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/de/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/de/FindReplace.js         |   17 +-
 dojox/editor/plugins/nls/de/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/de/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/de/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/de/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/de/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/de/TableDialog.js         |    2 +-
 dojox/editor/plugins/nls/de/TextColor.js           |    5 +
 dojox/editor/plugins/nls/el/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/el/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/el/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/el/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/el/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/el/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/el/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/el/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/el/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/el/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/el/Preview.js             |    4 +
 dojox/editor/plugins/nls/el/Save.js                |    4 +
 dojox/editor/plugins/nls/el/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/el/Smiley.js              |   22 +
 dojox/editor/plugins/nls/el/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/el/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/el/TextColor.js           |    5 +
 dojox/editor/plugins/nls/el/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/es/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/es/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/es/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/es/FindReplace.js         |   18 +-
 dojox/editor/plugins/nls/es/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/es/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/es/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/es/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/es/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/es/TableDialog.js         |    2 +
 dojox/editor/plugins/nls/es/TextColor.js           |    5 +
 dojox/editor/plugins/nls/fi/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/fi/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/fi/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/fi/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/fi/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/fi/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/fi/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/fi/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/fi/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/fi/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/fi/Preview.js             |    4 +
 dojox/editor/plugins/nls/fi/Save.js                |    4 +
 dojox/editor/plugins/nls/fi/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/fi/Smiley.js              |   22 +
 dojox/editor/plugins/nls/fi/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/fi/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/fi/TextColor.js           |    5 +
 dojox/editor/plugins/nls/fi/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/fr/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/fr/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/fr/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/fr/FindReplace.js         |   22 +-
 dojox/editor/plugins/nls/fr/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/fr/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/fr/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/fr/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/fr/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/fr/TableDialog.js         |   29 +-
 dojox/editor/plugins/nls/fr/TextColor.js           |    5 +
 dojox/editor/plugins/nls/he/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/he/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/he/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/he/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/he/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/he/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/he/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/he/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/he/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/he/PasteFromWord.js       |    7 +
 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              |   22 +
 dojox/editor/plugins/nls/he/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/he/TableDialog.js         |    5 +-
 dojox/editor/plugins/nls/he/TextColor.js           |    5 +
 dojox/editor/plugins/nls/he/latinEntities.js       |  256 +++
 dojox/editor/plugins/nls/hu/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/hu/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/hu/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/hu/FindReplace.js         |   23 +-
 dojox/editor/plugins/nls/hu/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/hu/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/hu/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/hu/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/hu/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/hu/TableDialog.js         |   22 +-
 dojox/editor/plugins/nls/hu/TextColor.js           |    5 +
 dojox/editor/plugins/nls/hu/latinEntities.js       |  152 +-
 dojox/editor/plugins/nls/it/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/it/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/it/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/it/FindReplace.js         |   19 +-
 dojox/editor/plugins/nls/it/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/it/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/it/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/it/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/it/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/it/TableDialog.js         |   18 +-
 dojox/editor/plugins/nls/it/TextColor.js           |    5 +
 dojox/editor/plugins/nls/ja/AutoSave.js            |   13 +
 dojox/editor/plugins/nls/ja/Blockquote.js          |    3 +
 dojox/editor/plugins/nls/ja/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/ja/FindReplace.js         |   18 +-
 dojox/editor/plugins/nls/ja/InsertAnchor.js        |    8 +
 dojox/editor/plugins/nls/ja/LocalImage.js          |   10 +
 dojox/editor/plugins/nls/ja/PasteFromWord.js       |    6 +
 dojox/editor/plugins/nls/ja/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/ja/SpellCheck.js          |   16 +
 dojox/editor/plugins/nls/ja/TableDialog.js         |   25 +-
 dojox/editor/plugins/nls/ja/TextColor.js           |    4 +
 dojox/editor/plugins/nls/kk/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/kk/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/kk/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/kk/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/kk/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/kk/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/kk/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/kk/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/kk/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/kk/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/kk/Preview.js             |    4 +
 dojox/editor/plugins/nls/kk/Save.js                |    4 +
 dojox/editor/plugins/nls/kk/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/kk/Smiley.js              |   22 +
 dojox/editor/plugins/nls/kk/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/kk/TableDialog.js         |   32 +
 dojox/editor/plugins/nls/kk/TextColor.js           |    5 +
 dojox/editor/plugins/nls/kk/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/ko/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/ko/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ko/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/ko/FindReplace.js         |   22 +-
 dojox/editor/plugins/nls/ko/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/ko/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/ko/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/ko/Smiley.js              |    9 +-
 dojox/editor/plugins/nls/ko/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/ko/TableDialog.js         |    2 +-
 dojox/editor/plugins/nls/ko/TextColor.js           |    5 +
 dojox/editor/plugins/nls/nb/AutoSave.js            |   13 +
 dojox/editor/plugins/nls/nb/Blockquote.js          |    3 +
 dojox/editor/plugins/nls/nb/Breadcrumb.js          |    9 +
 dojox/editor/plugins/nls/nb/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/nb/FindReplace.js         |   22 +
 dojox/editor/plugins/nls/nb/InsertAnchor.js        |    8 +
 dojox/editor/plugins/nls/nb/InsertEntity.js        |    3 +
 dojox/editor/plugins/nls/nb/LocalImage.js          |   10 +
 dojox/editor/plugins/nls/nb/PageBreak.js           |    3 +
 dojox/editor/plugins/nls/nb/PasteFromWord.js       |    6 +
 dojox/editor/plugins/nls/nb/Preview.js             |    3 +
 dojox/editor/plugins/nls/nb/Save.js                |    3 +
 dojox/editor/plugins/nls/nb/ShowBlockNodes.js      |    3 +
 dojox/editor/plugins/nls/nb/Smiley.js              |   21 +
 dojox/editor/plugins/nls/nb/SpellCheck.js          |   16 +
 dojox/editor/plugins/nls/nb/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/nb/TextColor.js           |    4 +
 dojox/editor/plugins/nls/nb/latinEntities.js       |  256 +++
 dojox/editor/plugins/nls/nl/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/nl/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/nl/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/nl/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/nl/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/nl/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/nl/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/nl/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/nl/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/nl/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/nl/Preview.js             |    4 +
 dojox/editor/plugins/nls/nl/Save.js                |    4 +
 dojox/editor/plugins/nls/nl/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/nl/Smiley.js              |   22 +
 dojox/editor/plugins/nls/nl/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/nl/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/nl/TextColor.js           |    5 +
 dojox/editor/plugins/nls/nl/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/pl/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/pl/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/pl/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/pl/FindReplace.js         |   19 +-
 dojox/editor/plugins/nls/pl/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/pl/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/pl/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/pl/Smiley.js              |   14 +-
 dojox/editor/plugins/nls/pl/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/pl/TableDialog.js         |    2 +-
 dojox/editor/plugins/nls/pl/TextColor.js           |    5 +
 dojox/editor/plugins/nls/pt-pt/AutoSave.js         |   14 +
 dojox/editor/plugins/nls/pt-pt/Blockquote.js       |    4 +
 dojox/editor/plugins/nls/pt-pt/Breadcrumb.js       |   10 +
 .../editor/plugins/nls/pt-pt/CollapsibleToolbar.js |    5 +
 dojox/editor/plugins/nls/pt-pt/FindReplace.js      |   23 +
 dojox/editor/plugins/nls/pt-pt/InsertAnchor.js     |    9 +
 dojox/editor/plugins/nls/pt-pt/InsertEntity.js     |    4 +
 dojox/editor/plugins/nls/pt-pt/LocalImage.js       |   11 +
 dojox/editor/plugins/nls/pt-pt/PageBreak.js        |    4 +
 dojox/editor/plugins/nls/pt-pt/PasteFromWord.js    |    7 +
 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           |   22 +
 dojox/editor/plugins/nls/pt-pt/SpellCheck.js       |   17 +
 dojox/editor/plugins/nls/pt-pt/TableDialog.js      |    1 +
 dojox/editor/plugins/nls/pt-pt/TextColor.js        |    5 +
 dojox/editor/plugins/nls/pt-pt/latinEntities.js    |  257 +++
 dojox/editor/plugins/nls/pt/AutoSave.js            |   13 +
 dojox/editor/plugins/nls/pt/Blockquote.js          |    3 +
 dojox/editor/plugins/nls/pt/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/pt/FindReplace.js         |   20 +-
 dojox/editor/plugins/nls/pt/InsertAnchor.js        |    8 +
 dojox/editor/plugins/nls/pt/LocalImage.js          |   10 +
 dojox/editor/plugins/nls/pt/PasteFromWord.js       |    6 +
 dojox/editor/plugins/nls/pt/Smiley.js              |    7 +-
 dojox/editor/plugins/nls/pt/SpellCheck.js          |   16 +
 dojox/editor/plugins/nls/pt/TableDialog.js         |    3 +-
 dojox/editor/plugins/nls/pt/TextColor.js           |    4 +
 dojox/editor/plugins/nls/pt/latinEntities.js       |    1 -
 dojox/editor/plugins/nls/ro/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/ro/FindReplace.js         |   12 +-
 dojox/editor/plugins/nls/ro/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/ro/Preview.js             |    2 +-
 dojox/editor/plugins/nls/ro/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/ro/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/ro/TableDialog.js         |   18 +-
 dojox/editor/plugins/nls/ro/latinEntities.js       |    6 +-
 dojox/editor/plugins/nls/ru/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/ru/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/ru/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/ru/FindReplace.js         |   19 +-
 dojox/editor/plugins/nls/ru/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/ru/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/ru/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/ru/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/ru/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/ru/TableDialog.js         |    2 +-
 dojox/editor/plugins/nls/ru/TextColor.js           |    5 +
 dojox/editor/plugins/nls/sk/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/sk/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/sk/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/sk/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/sk/FindReplace.js         |   22 +
 dojox/editor/plugins/nls/sk/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/sk/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/sk/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/sk/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/sk/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/sk/Preview.js             |    4 +
 dojox/editor/plugins/nls/sk/Save.js                |    4 +
 dojox/editor/plugins/nls/sk/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/sk/Smiley.js              |   22 +
 dojox/editor/plugins/nls/sk/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/sk/TableDialog.js         |   20 +-
 dojox/editor/plugins/nls/sk/TextColor.js           |    5 +
 dojox/editor/plugins/nls/sk/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/sl/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/sl/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/sl/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/sl/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/sl/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/sl/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/sl/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/sl/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/sl/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/sl/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/sl/Preview.js             |    4 +
 dojox/editor/plugins/nls/sl/Save.js                |    4 +
 dojox/editor/plugins/nls/sl/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/sl/Smiley.js              |   22 +
 dojox/editor/plugins/nls/sl/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/sl/TableDialog.js         |    4 +-
 dojox/editor/plugins/nls/sl/TextColor.js           |    5 +
 dojox/editor/plugins/nls/sl/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/sv/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/sv/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/sv/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/sv/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/sv/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/sv/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/sv/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/sv/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/sv/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/sv/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/sv/Preview.js             |    4 +
 dojox/editor/plugins/nls/sv/Save.js                |    4 +
 dojox/editor/plugins/nls/sv/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/sv/Smiley.js              |   22 +
 dojox/editor/plugins/nls/sv/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/sv/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/sv/TextColor.js           |    5 +
 dojox/editor/plugins/nls/sv/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/th/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/th/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/th/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/th/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/th/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/th/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/th/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/th/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/th/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/th/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/th/Preview.js             |    4 +
 dojox/editor/plugins/nls/th/Save.js                |    4 +
 dojox/editor/plugins/nls/th/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/th/Smiley.js              |   22 +
 dojox/editor/plugins/nls/th/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/th/TableDialog.js         |    4 +-
 dojox/editor/plugins/nls/th/TextColor.js           |    5 +
 dojox/editor/plugins/nls/th/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/tr/AutoSave.js            |   14 +
 dojox/editor/plugins/nls/tr/Blockquote.js          |    4 +
 dojox/editor/plugins/nls/tr/Breadcrumb.js          |   10 +
 dojox/editor/plugins/nls/tr/CollapsibleToolbar.js  |    5 +
 dojox/editor/plugins/nls/tr/FindReplace.js         |   23 +
 dojox/editor/plugins/nls/tr/InsertAnchor.js        |    9 +
 dojox/editor/plugins/nls/tr/InsertEntity.js        |    4 +
 dojox/editor/plugins/nls/tr/LocalImage.js          |   11 +
 dojox/editor/plugins/nls/tr/PageBreak.js           |    4 +
 dojox/editor/plugins/nls/tr/PasteFromWord.js       |    7 +
 dojox/editor/plugins/nls/tr/Preview.js             |    4 +
 dojox/editor/plugins/nls/tr/Save.js                |    4 +
 dojox/editor/plugins/nls/tr/ShowBlockNodes.js      |    4 +
 dojox/editor/plugins/nls/tr/Smiley.js              |   22 +
 dojox/editor/plugins/nls/tr/SpellCheck.js          |   17 +
 dojox/editor/plugins/nls/tr/TableDialog.js         |    3 +-
 dojox/editor/plugins/nls/tr/TextColor.js           |    5 +
 dojox/editor/plugins/nls/tr/latinEntities.js       |  257 +++
 dojox/editor/plugins/nls/zh-tw/AutoSave.js         |   13 +
 dojox/editor/plugins/nls/zh-tw/Blockquote.js       |    3 +
 .../editor/plugins/nls/zh-tw/CollapsibleToolbar.js |    4 +
 dojox/editor/plugins/nls/zh-tw/FindReplace.js      |   22 +-
 dojox/editor/plugins/nls/zh-tw/InsertAnchor.js     |    8 +
 dojox/editor/plugins/nls/zh-tw/LocalImage.js       |   10 +
 dojox/editor/plugins/nls/zh-tw/PasteFromWord.js    |    6 +
 dojox/editor/plugins/nls/zh-tw/Smiley.js           |    6 +-
 dojox/editor/plugins/nls/zh-tw/SpellCheck.js       |   16 +
 dojox/editor/plugins/nls/zh-tw/TableDialog.js      |    1 +
 dojox/editor/plugins/nls/zh-tw/TextColor.js        |    4 +
 dojox/editor/plugins/nls/zh/AutoSave.js            |   13 +
 dojox/editor/plugins/nls/zh/Blockquote.js          |    3 +
 dojox/editor/plugins/nls/zh/CollapsibleToolbar.js  |    4 +
 dojox/editor/plugins/nls/zh/FindReplace.js         |   30 +-
 dojox/editor/plugins/nls/zh/InsertAnchor.js        |    8 +
 dojox/editor/plugins/nls/zh/LocalImage.js          |   10 +
 dojox/editor/plugins/nls/zh/PasteFromWord.js       |    6 +
 dojox/editor/plugins/nls/zh/Smiley.js              |    6 +-
 dojox/editor/plugins/nls/zh/SpellCheck.js          |   16 +
 dojox/editor/plugins/nls/zh/TableDialog.js         |    1 +
 dojox/editor/plugins/nls/zh/TextColor.js           |    4 +
 dojox/editor/plugins/nls/zh/latinEntities.js       |  105 +-
 dojox/editor/plugins/resources/css/AutoSave.css    |   48 +
 dojox/editor/plugins/resources/css/LocalImage.css  |   13 +
 dojox/editor/plugins/resources/css/SpellCheck.css  |   51 +
 dojox/editor/plugins/resources/editorPlugins.css   |   53 +-
 dojox/editor/plugins/resources/icons/autoSave.png  |  Bin 0 -> 1953 bytes
 .../editor/plugins/resources/icons/spellcheck.gif  |  Bin 0 -> 879 bytes
 .../editor/plugins/resources/images/tableIcons.png |  Bin 704 -> 2961 bytes
 .../plugins/resources/images/tableIcons_rtl.png    |  Bin 0 -> 2896 bytes
 dojox/editor/plugins/resources/insertTable.html    |   35 +-
 dojox/editor/plugins/resources/modifyTable.html    |   46 +-
 dojox/editor/tests/PorterStemmer.php.disabled      |  474 ++++++
 dojox/editor/tests/editorAutoSave.html             |  172 ++
 dojox/editor/tests/editorAutoUrlLink.html          |  208 +++
 dojox/editor/tests/editorLocalImage.html           |   61 +
 dojox/editor/tests/editorPrettyPrint.html          |    2 +-
 dojox/editor/tests/editorResizeTableColumn.html    |   84 +
 dojox/editor/tests/editorSpellCheck.html           |   82 +
 dojox/editor/tests/editorTablePlugs.html           |   13 +-
 dojox/editor/tests/editorTextColor.html            |    4 +-
 dojox/editor/tests/sample.jpg                      |  Bin 0 -> 858 bytes
 dojox/editor/tests/spellCheck.php.disabled         |  152 ++
 dojox/editor/tests/testPluginsAll.html             |   15 +-
 dojox/editor/tests/wordlist.txt                    | 1619 ++++++++++++++++++
 dojox/embed/Flash.js                               |    3 -
 dojox/embed/Quicktime.js                           |   16 +-
 dojox/encoding/ascii85.js                          |   10 +-
 dojox/encoding/base64.js                           |   10 +-
 dojox/encoding/bits.js                             |    8 +-
 dojox/encoding/compression/lzw.js                  |   11 +-
 dojox/encoding/compression/splay.js                |    9 +-
 dojox/encoding/crypto/Blowfish.js                  |  125 +-
 dojox/encoding/crypto/RSAKey-ext.js                |   10 +-
 dojox/encoding/crypto/RSAKey.js                    |   10 +-
 dojox/encoding/crypto/SimpleAES.js                 |   61 +-
 dojox/encoding/crypto/_base.js                     |   14 +-
 dojox/encoding/digests/MD5.js                      |   11 +-
 dojox/encoding/digests/SHA1.js                     |   10 +-
 dojox/encoding/digests/_base.js                    |   18 +-
 dojox/encoding/easy64.js                           |   10 +-
 dojox/encoding/tests/digests/MD5.js                |    4 +-
 dojox/encoding/tests/digests/SHA1.js               |    4 +-
 dojox/flash/_base.js                               |  158 +-
 dojox/flash/tests/test_flash.js                    |   40 +-
 dojox/form/BusyButton.js                           |   14 +-
 dojox/form/CheckedMultiSelect.js                   |  119 +-
 dojox/form/DateTextBox.js                          |  104 +-
 dojox/form/FileInput.js                            |   14 +-
 dojox/form/FileInputAuto.js                        |   38 +-
 dojox/form/FilePickerTextBox.js                    |   20 +-
 dojox/form/FileUploader.js                         |  107 +-
 dojox/form/ListInput.js                            |  164 +-
 dojox/form/MultiComboBox.js                        |    4 +-
 dojox/form/PasswordValidator.js                    |   58 +-
 dojox/form/RangeSlider.js                          |   48 +-
 dojox/form/Rating.js                               |    2 +-
 dojox/form/TimeSpinner.js                          |    2 +-
 dojox/form/Uploader.js                             |  391 +++++
 dojox/form/_SelectStackMixin.js                    |   18 +-
 dojox/form/manager/_EnableMixin.js                 |    4 +-
 dojox/form/manager/_FormMixin.js                   |   25 +-
 dojox/form/manager/_Mixin.js                       |   14 +-
 dojox/form/manager/_NodeMixin.js                   |    2 +-
 dojox/form/nls/ar/PasswordValidator.js             |    2 +-
 dojox/form/nls/kk/PasswordValidator.js             |    5 +
 dojox/form/nls/ko/PasswordValidator.js             |    2 +-
 dojox/form/nls/nl/PasswordValidator.js             |    2 +-
 dojox/form/resources/FileInput.css                 |    2 +-
 dojox/form/resources/FilePickerTextBox.html        |    6 +-
 dojox/form/resources/HorizontalRangeSlider.html    |   10 +-
 dojox/form/resources/UploaderFileList.css          |   53 +
 dojox/form/resources/VerticalRangeSlider.html      |   10 +-
 dojox/form/tests/UploadFile.php.disabled           |  226 ++-
 dojox/form/tests/images/attach.png                 |  Bin 0 -> 19459 bytes
 dojox/form/tests/test_BusyButton.html              |    4 +-
 dojox/form/tests/test_CheckedMultiSelect.html      |  107 +-
 dojox/form/tests/test_FileInput.html               |    5 +
 dojox/form/tests/test_FileUploader.html            |    3 +
 dojox/form/tests/test_FileUploaderDialog.html      |   28 +-
 dojox/form/tests/test_FileUploaderForm.html        |   38 +-
 dojox/form/tests/test_ListInput.html               |    8 +-
 dojox/form/tests/test_MultiComboBox.html           |    4 +-
 dojox/form/tests/test_PasswordValidator.html       |   80 +-
 dojox/form/tests/test_RangeSlider.html             |    6 +-
 dojox/form/tests/test_SelectStack.html             |   12 +-
 dojox/form/tests/test_Uploader.html                |  173 ++
 dojox/form/tests/test_UploaderAll.html             |  216 +++
 dojox/form/uploader/Base.js                        |  120 ++
 dojox/form/uploader/FileList.js                    |  184 +++
 dojox/form/uploader/plugins/Flash.js               |  314 ++++
 dojox/form/uploader/plugins/HTML5.js               |  214 +++
 dojox/form/uploader/plugins/IFrame.js              |   60 +
 dojox/fx.js                                        |    2 +-
 dojox/fx/Shadow.js                                 |   28 +-
 dojox/fx/Timeline.js                               |   12 +-
 dojox/fx/_arg.js                                   |    4 +-
 dojox/fx/_base.js                                  |   50 +-
 dojox/fx/_core.js                                  |   16 +-
 dojox/fx/ext-dojo/NodeList-style.js                |    4 +-
 dojox/fx/ext-dojo/NodeList.js                      |    8 +-
 dojox/fx/ext-dojo/complex.js                       |   12 +-
 dojox/fx/ext-dojo/reverse.js                       |    2 +-
 dojox/fx/flip.js                                   |   75 +-
 dojox/fx/scroll.js                                 |   12 +-
 dojox/fx/style.js                                  |  100 +-
 dojox/gantt/GanttChart.js                          | 1265 ++++++++++++++
 dojox/gantt/GanttProjectItem.js                    |  967 +++++++++++
 dojox/gantt/GanttResourceItem.js                   |  456 +++++
 dojox/gantt/GanttTaskItem.js                       | 1357 +++++++++++++++
 dojox/gantt/TabMenu.js                             |  573 +++++++
 dojox/gantt/resources/gantt.css                    |  575 +++++++
 dojox/gantt/resources/images/am.png                |  Bin 0 -> 215 bytes
 dojox/gantt/resources/images/arrow.gif             |  Bin 0 -> 162 bytes
 dojox/gantt/resources/images/bg.png                |  Bin 0 -> 209 bytes
 dojox/gantt/resources/images/collapse.png          |  Bin 0 -> 306 bytes
 dojox/gantt/resources/images/expand.png            |  Bin 0 -> 319 bytes
 dojox/gantt/resources/images/load.png              |  Bin 0 -> 804 bytes
 dojox/gantt/resources/images/menuHighlight.png     |  Bin 0 -> 339 bytes
 dojox/gantt/resources/images/minus.gif             |  Bin 0 -> 121 bytes
 dojox/gantt/resources/images/ownerBar.png          |  Bin 0 -> 155 bytes
 dojox/gantt/resources/images/parentnode_bg.png     |  Bin 0 -> 145 bytes
 dojox/gantt/resources/images/parentnode_filled.png |  Bin 0 -> 145 bytes
 dojox/gantt/resources/images/plus.gif              |  Bin 0 -> 124 bytes
 dojox/gantt/resources/images/pm.png                |  Bin 0 -> 205 bytes
 dojox/gantt/resources/images/progress_bg.png       |  Bin 0 -> 186 bytes
 dojox/gantt/resources/images/progress_filled.png   |  Bin 0 -> 147 bytes
 dojox/gantt/resources/images/projProgressBg.png    |  Bin 0 -> 145 bytes
 .../gantt/resources/images/projProgressFilled.png  |  Bin 0 -> 145 bytes
 dojox/gantt/resources/images/rbg.png               |  Bin 0 -> 202 bytes
 dojox/gantt/resources/images/resourceBg.png        |  Bin 0 -> 202 bytes
 dojox/gantt/resources/images/resourceHeader.png    |  Bin 0 -> 177 bytes
 dojox/gantt/resources/images/rheader.png           |  Bin 0 -> 177 bytes
 dojox/gantt/resources/images/rowHighlight.png      |  Bin 0 -> 197 bytes
 dojox/gantt/resources/images/save.png              |  Bin 0 -> 913 bytes
 dojox/gantt/resources/images/taskArrow.gif         |  Bin 0 -> 162 bytes
 dojox/gantt/resources/images/taskBar.png           |  Bin 0 -> 155 bytes
 dojox/gantt/resources/images/taskProgressBg.png    |  Bin 0 -> 186 bytes
 .../gantt/resources/images/taskProgressFilled.png  |  Bin 0 -> 147 bytes
 dojox/gantt/resources/images/zoomin.png            |  Bin 0 -> 940 bytes
 dojox/gantt/resources/images/zoomintime.png        |  Bin 0 -> 843 bytes
 dojox/gantt/resources/images/zoomout.png           |  Bin 0 -> 772 bytes
 dojox/gantt/resources/images/zoomouttime.png       |  Bin 0 -> 802 bytes
 dojox/gantt/tests/saveGanttData.php                |    8 +
 dojox/gantt/tests/test_Gantt.html                  |  155 ++
 dojox/geo/charting/Map.js                          |    8 +-
 dojox/gfx.js                                       |   86 +-
 dojox/gfx/Moveable.js                              |    5 +-
 dojox/gfx/_base.js                                 |   67 +-
 dojox/gfx/arc.js                                   |   31 +-
 dojox/gfx/attach.js                                |   14 +-
 dojox/gfx/canvas.js                                |  222 ++-
 dojox/gfx/canvas_attach.js                         |    4 +-
 dojox/gfx/decompose.js                             |   28 +-
 dojox/gfx/fx.js                                    |  126 +-
 dojox/gfx/path.js                                  |    8 +-
 dojox/gfx/shape.js                                 |   26 +-
 dojox/gfx/silverlight.js                           | 1408 ++++++++--------
 dojox/gfx/silverlight_attach.js                    |   80 +-
 dojox/gfx/svg.js                                   |  195 +--
 dojox/gfx/svg_attach.js                            |  122 +-
 dojox/gfx/tests/decompose.js                       |    4 +-
 dojox/gfx/tests/test.roundrect.html                |   15 +-
 dojox/gfx/tests/test_bezier.html                   |   10 +-
 dojox/gfx/tests/test_destroy.html                  |   34 +-
 dojox/gfx/tests/test_fill.html                     |   12 +-
 dojox/gfx/tests/test_fx.html                       |    8 +-
 dojox/gfx/tests/test_fx_shapes.html                |   18 +-
 dojox/gfx/tests/test_gfx.html                      |   79 +-
 dojox/gfx/tests/test_gradient.html                 |   10 +-
 dojox/gfx/tests/test_group1.html                   |   10 +-
 dojox/gfx/tests/test_image1.html                   |    8 +-
 dojox/gfx/tests/test_image2.html                   |   10 +-
 dojox/gfx/tests/test_image3.html                   |   18 +-
 dojox/gfx/tests/test_image4.html                   |   13 +-
 dojox/gfx/tests/test_image5.html                   |   12 +-
 dojox/gfx/tests/test_linearGradient.html           |   10 +-
 dojox/gfx/tests/test_linestyle.html                |   10 +-
 dojox/gfx/tests/test_pattern.html                  |   12 +-
 dojox/gfx/tests/test_poly.html                     |    8 +-
 dojox/gfx/tests/test_refproj.html                  |   14 +-
 dojox/gfx/tests/test_resize.html                   |    8 +-
 dojox/gfx/tests/test_setPath.html                  |    8 +-
 dojox/gfx/tests/test_tbbox.html                    |   10 +-
 dojox/gfx/tests/test_text.html                     |   16 +-
 dojox/gfx/tests/test_textpath.html                 |   14 +-
 dojox/gfx/tests/test_transform.html                |   10 +-
 dojox/gfx/tests/test_utils.html                    |    3 +-
 dojox/gfx/tests/test_vectortext_draw.html          |   16 +-
 dojox/gfx/tests/test_vectortext_load.html          |   13 +-
 dojox/gfx/utils.js                                 |   14 +-
 dojox/gfx/vml.js                                   |  156 +-
 dojox/gfx/vml_attach.js                            |  116 +-
 dojox/gfx3d/lighting.js                            |    2 +-
 dojox/gfx3d/matrix.js                              |   20 +-
 dojox/gfx3d/object.js                              |  105 +-
 dojox/gfx3d/scheduler.js                           |   20 +-
 dojox/gfx3d/vector.js                              |    4 +-
 dojox/grid/DataGrid.js                             |   23 +-
 dojox/grid/EnhancedGrid.js                         |  253 ++-
 dojox/grid/LazyTreeGrid.js                         |  833 ++++++++++
 dojox/grid/LazyTreeGridStoreModel.js               |  105 ++
 dojox/grid/README                                  |   73 +-
 dojox/grid/TreeGrid.js                             |   50 +-
 dojox/grid/_Builder.js                             |   47 +-
 dojox/grid/_EditManager.js                         |    7 +-
 dojox/grid/_Events.js                              |    3 +-
 dojox/grid/_FocusManager.js                        |   56 +-
 dojox/grid/_Grid.js                                |   47 +-
 dojox/grid/_Layout.js                              |   19 +-
 dojox/grid/_RowManager.js                          |    2 +-
 dojox/grid/_RowSelector.js                         |    2 +-
 dojox/grid/_Scroller.js                            |   21 +-
 dojox/grid/_Selector.js                            |    8 +-
 dojox/grid/_TreeView.js                            |   10 +-
 dojox/grid/_View.js                                |   10 +-
 dojox/grid/_ViewManager.js                         |   14 +-
 dojox/grid/cells/dijit.js                          |   24 +-
 dojox/grid/cells/tree.js                           |    4 +-
 dojox/grid/enhanced/_Builder.js                    |  115 --
 dojox/grid/enhanced/_Events.js                     |  470 +-----
 dojox/grid/enhanced/_FocusManager.js               |  755 +++++++++
 dojox/grid/enhanced/_Plugin.js                     |  482 ++----
 dojox/grid/enhanced/_PluginManager.js              |  264 +++
 dojox/grid/enhanced/dnd/_DndBuilder.js             |   36 -
 dojox/grid/enhanced/dnd/_DndEvents.js              |   84 -
 dojox/grid/enhanced/dnd/_DndFocusManager.js        |  127 --
 dojox/grid/enhanced/dnd/_DndGrid.js                |   41 -
 dojox/grid/enhanced/dnd/_DndMover.js               |   40 -
 dojox/grid/enhanced/dnd/_DndMovingManager.js       |  988 -----------
 dojox/grid/enhanced/dnd/_DndRowSelector.js         |   30 -
 dojox/grid/enhanced/dnd/_DndSelectingManager.js    |  735 ---------
 dojox/grid/enhanced/nls/EnhancedGrid.js            |    5 +-
 dojox/grid/enhanced/nls/Filter.js                  |   85 +
 dojox/grid/enhanced/nls/Pagination.js              |   17 +
 dojox/grid/enhanced/nls/ar/EnhancedGrid.js         |    6 +-
 dojox/grid/enhanced/nls/ar/Filter.js               |   87 +
 dojox/grid/enhanced/nls/ar/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/ca/Filter.js               |   88 +
 dojox/grid/enhanced/nls/ca/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/cs/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/cs/Filter.js               |   87 +
 dojox/grid/enhanced/nls/cs/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/da/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/da/Filter.js               |   87 +
 dojox/grid/enhanced/nls/da/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/de/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/de/Filter.js               |   87 +
 dojox/grid/enhanced/nls/de/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/el/Filter.js               |   88 +
 dojox/grid/enhanced/nls/el/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/es/EnhancedGrid.js         |    6 +-
 dojox/grid/enhanced/nls/es/Filter.js               |   87 +
 dojox/grid/enhanced/nls/es/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/fi/EnhancedGrid.js         |    6 +-
 dojox/grid/enhanced/nls/fi/Filter.js               |   87 +
 dojox/grid/enhanced/nls/fi/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/fr/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/fr/Filter.js               |   87 +
 dojox/grid/enhanced/nls/fr/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/he/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/he/Filter.js               |   87 +
 dojox/grid/enhanced/nls/he/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/hr/EnhancedGrid.js         |   12 +
 dojox/grid/enhanced/nls/hr/Filter.js               |   87 +
 dojox/grid/enhanced/nls/hr/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/hu/EnhancedGrid.js         |    6 +-
 dojox/grid/enhanced/nls/hu/Filter.js               |   87 +
 dojox/grid/enhanced/nls/hu/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/it/EnhancedGrid.js         |   12 +-
 dojox/grid/enhanced/nls/it/Filter.js               |   87 +
 dojox/grid/enhanced/nls/it/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/ja/EnhancedGrid.js         |    9 +-
 dojox/grid/enhanced/nls/ja/Filter.js               |   85 +
 dojox/grid/enhanced/nls/ja/Pagination.js           |   17 +
 dojox/grid/enhanced/nls/kk/EnhancedGrid.js         |    8 +
 dojox/grid/enhanced/nls/kk/Filter.js               |   88 +
 dojox/grid/enhanced/nls/kk/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/ko/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/ko/Filter.js               |   87 +
 dojox/grid/enhanced/nls/ko/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/nb/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/nb/Filter.js               |   87 +
 dojox/grid/enhanced/nls/nb/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/nl/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/nl/Filter.js               |   87 +
 dojox/grid/enhanced/nls/nl/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/pl/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/pl/Filter.js               |   87 +
 dojox/grid/enhanced/nls/pl/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/pt-pt/Filter.js            |   88 +
 dojox/grid/enhanced/nls/pt-pt/Pagination.js        |   18 +
 dojox/grid/enhanced/nls/pt/Filter.js               |   86 +
 dojox/grid/enhanced/nls/pt/Pagination.js           |   17 +
 dojox/grid/enhanced/nls/ro/EnhancedGrid.js         |    5 +-
 dojox/grid/enhanced/nls/ro/Filter.js               |   87 +
 dojox/grid/enhanced/nls/ro/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/ru/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/ru/Filter.js               |   87 +
 dojox/grid/enhanced/nls/ru/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/sk/Filter.js               |   87 +
 dojox/grid/enhanced/nls/sk/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/sl/EnhancedGrid.js         |   10 +-
 dojox/grid/enhanced/nls/sl/Filter.js               |   87 +
 dojox/grid/enhanced/nls/sl/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/sv/EnhancedGrid.js         |   14 +-
 dojox/grid/enhanced/nls/sv/Filter.js               |   87 +
 dojox/grid/enhanced/nls/sv/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/th/Filter.js               |   88 +
 dojox/grid/enhanced/nls/th/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/tr/EnhancedGrid.js         |   12 +-
 dojox/grid/enhanced/nls/tr/Filter.js               |   87 +
 dojox/grid/enhanced/nls/tr/Pagination.js           |   18 +
 dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js      |    8 +-
 dojox/grid/enhanced/nls/zh-tw/Filter.js            |   87 +
 dojox/grid/enhanced/nls/zh-tw/Pagination.js        |   18 +
 dojox/grid/enhanced/nls/zh/EnhancedGrid.js         |    8 +-
 dojox/grid/enhanced/nls/zh/Filter.js               |   87 +
 dojox/grid/enhanced/nls/zh/Pagination.js           |   18 +
 dojox/grid/enhanced/plugins/AutoScroll.js          |  171 ++
 dojox/grid/enhanced/plugins/CellMerge.js           |  266 +++
 dojox/grid/enhanced/plugins/Cookie.js              |  345 ++++
 dojox/grid/enhanced/plugins/Dialog.js              |   34 +
 dojox/grid/enhanced/plugins/DnD.js                 | 1076 +++++++++++-
 dojox/grid/enhanced/plugins/Exporter.js            |  231 +++
 dojox/grid/enhanced/plugins/Filter.js              |  160 ++
 dojox/grid/enhanced/plugins/GridSource.js          |  148 ++
 dojox/grid/enhanced/plugins/IndirectSelection.js   |  871 +++++-----
 dojox/grid/enhanced/plugins/Menu.js                |  197 ++-
 dojox/grid/enhanced/plugins/NestedSorting.js       | 1735 ++++++--------------
 dojox/grid/enhanced/plugins/Pagination.js          | 1224 ++++++++++++++
 dojox/grid/enhanced/plugins/Printer.js             |  258 +++
 dojox/grid/enhanced/plugins/Rearrange.js           |  481 ++++++
 dojox/grid/enhanced/plugins/Search.js              |  109 ++
 dojox/grid/enhanced/plugins/Selector.js            | 1447 ++++++++++++++++
 dojox/grid/enhanced/plugins/_RowMapLayer.js        |  204 +++
 dojox/grid/enhanced/plugins/_SelectionPreserver.js |  127 ++
 dojox/grid/enhanced/plugins/_StoreLayer.js         |  383 +++++
 dojox/grid/enhanced/plugins/exporter/CSVWriter.js  |   79 +
 .../grid/enhanced/plugins/exporter/TableWriter.js  |  145 ++
 .../enhanced/plugins/exporter/_ExportWriter.js     |  267 +++
 .../enhanced/plugins/filter/ClearFilterConfirm.js  |   33 +
 dojox/grid/enhanced/plugins/filter/FilterBar.js    |  369 +++++
 .../grid/enhanced/plugins/filter/FilterBuilder.js  |   78 +
 .../enhanced/plugins/filter/FilterDefDialog.js     | 1229 ++++++++++++++
 dojox/grid/enhanced/plugins/filter/FilterLayer.js  |  404 +++++
 .../enhanced/plugins/filter/FilterStatusTip.js     |  139 ++
 .../grid/enhanced/plugins/filter/_ConditionExpr.js |  215 +++
 dojox/grid/enhanced/plugins/filter/_DataExprs.js   |   78 +
 dojox/grid/enhanced/plugins/filter/_FilterExpr.js  |  228 +++
 dojox/grid/enhanced/resources/Common.css           |   36 +
 dojox/grid/enhanced/resources/Common_rtl.css       |   15 +
 dojox/grid/enhanced/resources/DnD.css              |   78 +
 dojox/grid/enhanced/resources/DnD_rtl.css          |   12 +
 dojox/grid/enhanced/resources/EnhancedGrid.css     |  196 +--
 dojox/grid/enhanced/resources/EnhancedGrid_rtl.css |   35 +-
 dojox/grid/enhanced/resources/Filter.css           |  292 ++++
 dojox/grid/enhanced/resources/Filter_rtl.css       |   80 +
 dojox/grid/enhanced/resources/Pagination.css       |  138 ++
 dojox/grid/enhanced/resources/Pagination_rtl.css   |   68 +
 dojox/grid/enhanced/resources/Sorter.css           |  178 ++
 dojox/grid/enhanced/resources/Sorter_rtl.css       |   78 +
 dojox/grid/enhanced/resources/claro/Common.css     |   99 ++
 .../grid/enhanced/resources/claro/EnhancedGrid.css |    4 +
 dojox/grid/enhanced/resources/claro/Filter.css     |   59 +
 .../grid/enhanced/resources/claroEnhancedGrid.css  |  104 --
 .../enhanced/resources/images/nestedSortArrows.png |  Bin 955 -> 0 bytes
 .../enhanced/resources/images/sprite_icons.png     |  Bin 0 -> 2836 bytes
 dojox/grid/enhanced/resources/tundra/Common.css    |   40 +
 .../enhanced/resources/tundra/EnhancedGrid.css     |    5 +
 dojox/grid/enhanced/resources/tundra/Filter.css    |   38 +
 dojox/grid/enhanced/resources/tundra/Sorter.css    |   83 +
 .../grid/enhanced/resources/tundraEnhancedGrid.css |   86 -
 .../enhanced/templates/ClearFilterConfirmPane.html |    9 +
 dojox/grid/enhanced/templates/CriteriaBox.html     |   20 +
 dojox/grid/enhanced/templates/FilterBar.html       |   15 +
 .../enhanced/templates/FilterBoolValueBox.html     |   11 +
 dojox/grid/enhanced/templates/FilterDefPane.html   |   27 +
 .../grid/enhanced/templates/FilterStatusPane.html  |    9 +
 dojox/grid/enhanced/templates/Pagination.html      |   13 +
 dojox/grid/resources/Grid.css                      |    9 +-
 dojox/grid/resources/View.html                     |   16 +-
 dojox/grid/resources/_Grid.html                    |    6 +-
 dojox/grid/resources/claroGrid.css                 |   77 +-
 dojox/grid/resources/soriaGrid.css                 |    8 +
 dojox/grid/tests/databaseModel.js                  |   38 +-
 dojox/grid/tests/enhanced/support/common.css       |    8 +
 .../tests/enhanced/support/music-for-demo.part.csv |  309 ----
 dojox/grid/tests/enhanced/support/print_style1.css |   20 +
 dojox/grid/tests/enhanced/support/print_style2.css |    7 +
 .../tests/enhanced/support/test_layout_music.js    |  174 ++
 dojox/grid/tests/enhanced/support/test_repeat.js   |   90 +
 dojox/grid/tests/enhanced/support/test_ue.js       |   29 -
 .../tests/enhanced/support/test_write_store_dnd.js |   32 +
 .../enhanced/support/test_write_store_music.js     |  129 ++
 dojox/grid/tests/enhanced/test_enhanced_grid.html  |  181 --
 .../enhanced/test_enhanced_grid_cellmerge.html     |  242 +++
 .../tests/enhanced/test_enhanced_grid_claro.html   |   70 -
 .../tests/enhanced/test_enhanced_grid_cookie.html  |   88 +
 .../tests/enhanced/test_enhanced_grid_dnd.html     |  294 ++++
 .../tests/enhanced/test_enhanced_grid_filter.html  |  107 ++
 .../test_enhanced_grid_indirectSelection.html      |  105 ++
 .../test_enhanced_grid_leak_programmatic.html      |  185 +++
 .../enhanced/test_enhanced_grid_leak_scroll.html   |  175 ++
 .../test_enhanced_grid_leak_with_plugin.html       |  294 ++++
 .../tests/enhanced/test_enhanced_grid_menus.html   |   93 ++
 .../enhanced/test_enhanced_grid_nestedsorting.html |   74 +
 .../enhanced/test_enhanced_grid_pagination.html    |   73 +
 .../tests/enhanced/test_enhanced_grid_plugins.html |  875 ++++++++++
 .../enhanced/test_enhanced_grid_print_export.html  |  199 +++
 .../tests/enhanced/test_enhanced_grid_search.html  |  186 +++
 .../enhanced/test_enhanced_grid_selector.html      |  134 ++
 dojox/grid/tests/performance/_gridPerfFramework.js |   20 +-
 dojox/grid/tests/performance/module.js             |    8 +-
 dojox/grid/tests/robot/DataGrid_mouse.html         |    4 +-
 dojox/grid/tests/robot/structures.js               |   20 +-
 dojox/grid/tests/support/test_data.js              |    2 +-
 dojox/grid/tests/support/test_data_date.js         |    2 +-
 dojox/grid/tests/support/yahoo_search.js           |   14 +-
 dojox/grid/tests/test_change_structure.html        |    2 +-
 dojox/grid/tests/test_data_grid_edit.html          |    4 +-
 dojox/grid/tests/test_expand.html                  |   12 +-
 dojox/grid/tests/test_sizing.html                  |   20 +-
 dojox/grid/tests/test_treegrid.html                |    4 +-
 dojox/grid/tests/test_treegrid_lazyloading.html    |  154 ++
 dojox/grid/tests/test_treegrid_model.html          |    6 +-
 dojox/grid/tests/test_yahoo_search.html            |    2 +-
 dojox/grid/tests/yahooSearch.js                    |    4 +-
 dojox/highlight.js                                 |    2 +-
 dojox/highlight/_base.js                           |   28 +-
 dojox/highlight/languages/cpp.js                   |   14 +-
 dojox/highlight/languages/css.js                   |   26 +-
 dojox/highlight/languages/delphi.js                |   26 +-
 dojox/highlight/languages/django.js                |   12 +-
 dojox/highlight/languages/groovy.js                |   20 +-
 dojox/highlight/languages/html.js                  |    6 +-
 dojox/highlight/languages/java.js                  |   16 +-
 dojox/highlight/languages/pygments/_html.js        |    4 +-
 dojox/highlight/languages/pygments/css.js          |    4 +-
 dojox/highlight/languages/pygments/html.js         |    2 +-
 dojox/highlight/languages/pygments/javascript.js   |    8 +-
 dojox/highlight/languages/pygments/xml.js          |    2 +-
 dojox/highlight/languages/python.js                |   14 +-
 dojox/highlight/languages/sql.js                   |   22 +-
 dojox/highlight/tests/example-java-source.java     |   25 +
 dojox/highlight/tests/example-xml-data.xml         |   17 +
 dojox/highlight/tests/example-xml-resultdata.xml   |    1 +
 dojox/highlight/tests/example-xquery-source.xquery |   27 +
 dojox/highlight/tests/highlight.js                 |    2 +-
 dojox/highlight/tests/highlightRequires.js         |    7 +
 dojox/highlight/tests/module.js                    |    2 +-
 dojox/highlight/tests/pretty.css                   |  136 ++
 dojox/highlight/tests/test_highlightWidget.html    |   24 +
 dojox/highlight/widget/Code.js                     |   96 ++
 dojox/html/README                                  |    4 +-
 dojox/html/_base.js                                |   60 +-
 dojox/html/ellipsis.js                             |   45 +-
 dojox/html/entities.js                             |   62 +-
 dojox/html/ext-dojo/style.js                       |    2 +-
 dojox/html/format.js                               |  833 +++++-----
 dojox/html/metrics.js                              |    2 +-
 dojox/html/styles.js                               |  148 +-
 dojox/html/tests/entities.js                       |   14 +-
 dojox/html/tests/format.js                         |   38 +-
 dojox/html/tests/test_metrics_getTextBox.html      |   49 +
 dojox/image/Badge.js                               |   22 +-
 dojox/image/Gallery.js                             |   19 +-
 dojox/image/Lightbox.js                            |  127 +-
 dojox/image/LightboxNano.js                        |  129 +-
 dojox/image/Magnifier.js                           |    6 +-
 dojox/image/MagnifierLite.js                       |   14 +-
 dojox/image/SlideShow.js                           |  103 +-
 dojox/image/ThumbnailPicker.js                     |   45 +-
 dojox/image/_base.js                               |   32 +-
 dojox/image/resources/Lightbox.css                 |   29 +-
 dojox/image/tests/images/supertall.gif             |  Bin 0 -> 3916 bytes
 dojox/image/tests/images/superwide.gif             |  Bin 0 -> 4720 bytes
 dojox/image/tests/test_Lightbox.html               |   48 +-
 dojox/io/OAuth.js                                  |   18 +-
 dojox/io/httpParse.js                              |   18 +-
 dojox/io/proxy/xip.js                              |    6 +-
 dojox/io/proxy/xip_client.html                     |    2 +-
 dojox/io/proxy/xip_server.html                     |    2 +-
 dojox/io/scriptFrame.js                            |    2 +-
 dojox/io/tests/windowName.html                     |    2 +-
 dojox/io/tests/windowName.js                       |    8 +-
 dojox/io/tests/xhrPlugins.js                       |    8 +-
 dojox/io/windowName.js                             |   37 +-
 dojox/io/xhrMultiPart.js                           |    2 +-
 dojox/io/xhrPlugins.js                             |   32 +-
 dojox/io/xhrScriptPlugin.js                        |    6 +-
 dojox/io/xhrWindowNamePlugin.js                    |   20 +-
 dojox/jq.js                                        |   30 +-
 dojox/json/query.js                                |   74 +-
 dojox/json/ref.js                                  |   46 +-
 dojox/json/schema.js                               |   46 +-
 dojox/json/tests/query.js                          |   26 +-
 dojox/json/tests/schema.js                         |   18 +-
 dojox/jsonPath/query.js                            |   22 +-
 dojox/jsonPath/tests/jsonPath.js                   |   14 +-
 dojox/lang/aspect.js                               |    2 +-
 dojox/lang/docs.js                                 |    8 +-
 dojox/lang/functional/array.js                     |   10 +-
 dojox/lang/functional/curry.js                     |    8 +-
 dojox/lang/functional/fold.js                      |    6 +-
 dojox/lang/functional/lambda.js                    |   10 +-
 dojox/lang/functional/listcomp.js                  |   12 +-
 dojox/lang/functional/object.js                    |    6 +-
 dojox/lang/functional/reversed.js                  |   10 +-
 dojox/lang/functional/scan.js                      |   10 +-
 dojox/lang/functional/zip.js                       |   10 +-
 dojox/lang/observable.js                           |   62 +-
 dojox/lang/tests/declare-old.js                    |   44 +-
 dojox/lang/tests/docs.js                           |    8 +-
 dojox/lang/tests/observable.js                     |   12 +-
 dojox/lang/tests/typed.js                          |    6 +-
 dojox/lang/utils.js                                |    2 +-
 dojox/layout/ContentPane.js                        |    8 +-
 dojox/layout/DragPane.js                           |   24 +-
 dojox/layout/ExpandoPane.js                        |   38 +-
 dojox/layout/FloatingPane.js                       |   82 +-
 dojox/layout/GridContainer.js                      |    4 +-
 dojox/layout/GridContainerLite.js                  |   17 +-
 dojox/layout/RadioGroup.js                         |   27 +-
 dojox/layout/ResizeHandle.js                       |  100 +-
 dojox/layout/RotatorContainer.js                   |    8 +-
 dojox/layout/ScrollPane.js                         |   16 +-
 dojox/layout/TableContainer.js                     |   32 +-
 dojox/layout/ToggleSplitter.js                     |   75 +-
 dojox/layout/dnd/PlottedDnd.js                     |   60 +-
 dojox/layout/resources/FloatingPane.html           |    4 +-
 dojox/layout/resources/GridContainer.css           |    4 +-
 dojox/layout/tests/ContentPane.html                |   47 +-
 dojox/layout/tests/resources/script_dnd.js         |    6 +-
 dojox/layout/tests/test_DragPane.html              |   41 +-
 dojox/layout/tests/test_ExpandoPane.html           |   14 +-
 dojox/layout/tests/test_RadioGroup.html            |   50 +-
 dojox/layout/tests/test_TableContainer.html        |   39 +-
 dojox/math.js                                      |    8 +-
 dojox/math/BigInteger-ext.js                       |   10 +-
 dojox/math/BigInteger.js                           |   11 +-
 dojox/math/_base.js                                |   11 +-
 dojox/math/curves.js                               |   19 +-
 dojox/math/matrix.js                               |    7 +-
 dojox/math/random/Secure.js                        |    8 +-
 dojox/math/random/Simple.js                        |    6 +-
 dojox/math/random/prng4.js                         |    7 +-
 dojox/math/round.js                                |    7 +-
 dojox/math/stats.js                                |    7 +-
 dojox/math/tests/round.js                          |    2 +-
 dojox/math/tests/stats.js                          |    2 +-
 dojox/mdnd/AutoScroll.js                           |    6 +-
 dojox/mdnd/DropIndicator.js                        |    8 +-
 dojox/mdnd/Moveable.js                             |   40 +-
 dojox/mdnd/PureSource.js                           |   12 +-
 dojox/mdnd/dropMode/DefaultDropMode.js             |   24 +-
 dojox/mdnd/tests/robot/module.js                   |    2 +-
 dojox/mdnd/tests/unitTests/dropMode/FixtureLib.js  |    2 +-
 dojox/mobile/FixedSplitter.js                      |   97 ++
 dojox/mobile/FlippableView.js                      |  132 ++
 dojox/mobile/IconContainer.js                      |  307 ++++
 dojox/mobile/README                                |    8 +-
 dojox/mobile/ScrollableView.js                     |  118 ++
 dojox/mobile/TabBar.js                             |  205 +++
 dojox/mobile/TabContainer.js                       |  151 ++
 dojox/mobile/_ScrollableMixin.js                   |   51 +
 dojox/mobile/_base.js                              |  751 +++------
 dojox/mobile/app/AlertDialog.js                    |    4 +-
 dojox/mobile/app/ImageThumbView.js                 |  211 ++-
 dojox/mobile/app/List.js                           |  322 ++--
 dojox/mobile/app/SceneController.js                |  105 +-
 dojox/mobile/app/StageController.js                |   49 +-
 dojox/mobile/app/TextBox.js                        |   30 +-
 dojox/mobile/app/_FormWidget.js                    |   15 +-
 dojox/mobile/app/_Widget.js                        |   10 +-
 dojox/mobile/app/_base.js                          |   89 +-
 dojox/mobile/app/_event.js                         |    5 +-
 dojox/mobile/app/compat.js                         |    2 +-
 dojox/mobile/build/build.bat                       |    6 +-
 dojox/mobile/build/build.sh                        |    6 +-
 dojox/mobile/build/profiles/mobile-all.profile.js  |   36 -
 dojox/mobile/build/profiles/mobile.profile.js      |   40 -
 dojox/mobile/compat.js                             |  102 +-
 dojox/mobile/parser.js                             |   15 +-
 dojox/mobile/scrollable.js                         |  864 ++++++++++
 .../app/assistants/main-assistant.js               |  229 +--
 .../app/views/main/dividerTemplate.html            |    3 +
 .../complexListApp/app/views/main/main-scene.html  |   27 +-
 dojox/mobile/tests/complexListApp/styles/style.css |   40 +-
 .../dialogApp/app/assistants/main-assistant.js     |    6 +-
 .../flickr-image-thumb-view-assistant.js           |  119 +-
 .../app/assistants/flickr-image-view-assistant.js  |   28 +-
 .../assistants/flickr-search-group-assistant.js    |   16 +-
 .../app/assistants/flickr-search-text-assistant.js |   14 +-
 .../app/assistants/image-view-assistant.js         |   10 +-
 .../flickr-image-thumb-view-scene.html             |   16 +-
 dojox/mobile/tests/images/tab-icon-10.png          |  Bin 0 -> 349 bytes
 dojox/mobile/tests/images/tab-icon-10h.png         |  Bin 0 -> 369 bytes
 dojox/mobile/tests/images/tab-icon-11.png          |  Bin 0 -> 343 bytes
 dojox/mobile/tests/images/tab-icon-11h.png         |  Bin 0 -> 366 bytes
 dojox/mobile/tests/images/tab-icon-12.png          |  Bin 0 -> 622 bytes
 dojox/mobile/tests/images/tab-icon-12h.png         |  Bin 0 -> 623 bytes
 dojox/mobile/tests/images/tab-icon-13.png          |  Bin 0 -> 277 bytes
 dojox/mobile/tests/images/tab-icon-13h.png         |  Bin 0 -> 299 bytes
 dojox/mobile/tests/images/tab-icon-14.png          |  Bin 0 -> 623 bytes
 dojox/mobile/tests/images/tab-icon-14h.png         |  Bin 0 -> 652 bytes
 dojox/mobile/tests/images/tab-icon-15.png          |  Bin 0 -> 765 bytes
 dojox/mobile/tests/images/tab-icon-15h.png         |  Bin 0 -> 777 bytes
 dojox/mobile/tests/images/tab-icon-16.png          |  Bin 0 -> 597 bytes
 dojox/mobile/tests/images/tab-icon-16h.png         |  Bin 0 -> 600 bytes
 dojox/mobile/tests/images/tab-icon-17.png          |  Bin 0 -> 967 bytes
 dojox/mobile/tests/images/tab-icon-17h.png         |  Bin 0 -> 959 bytes
 dojox/mobile/tests/images/tab-icon-18.png          |  Bin 0 -> 827 bytes
 dojox/mobile/tests/images/tab-icon-18h.png         |  Bin 0 -> 834 bytes
 dojox/mobile/tests/images/tab-icons.png            |  Bin 0 -> 4215 bytes
 dojox/mobile/tests/index.html                      |   43 +-
 dojox/mobile/tests/items.json                      |    7 +
 .../multiSceneApp/app/assistants/main-assistant.js |    4 +-
 .../simpleApp/app/assistants/main-assistant.js     |    4 +-
 .../simpleListApp/app/assistants/main-assistant.js |    2 +-
 dojox/mobile/tests/test_Android-ButtonList.html    |    5 +-
 dojox/mobile/tests/test_Android-EdgeToEdge.html    |    2 +-
 .../tests/test_Android-EdgeToEdgeCategory.html     |    2 +-
 dojox/mobile/tests/test_Android-Heading.html       |   79 +
 dojox/mobile/tests/test_Android-Icon.html          |    3 +-
 dojox/mobile/tests/test_Android-RoundRectList.html |   18 +-
 dojox/mobile/tests/test_Android-Settings.html      |    5 +-
 dojox/mobile/tests/test_Android-Switch.html        |    4 +-
 dojox/mobile/tests/test_Android-TabBar.html        |   66 +
 dojox/mobile/tests/test_Android-TabContainer.html  |    9 +-
 .../tests/test_Android-VariableHeightList.html     |    2 +-
 dojox/mobile/tests/test_FixedSplitter-H2-prog.html |   38 +
 dojox/mobile/tests/test_FixedSplitter-H2.html      |   33 +
 dojox/mobile/tests/test_FixedSplitter-V2H2.html    |   39 +
 dojox/mobile/tests/test_FixedSplitter-V3.html      |   36 +
 .../mobile/tests/test_ScrollableMixin-custom.html  |  110 ++
 dojox/mobile/tests/test_ajax-html.html             |    2 +-
 dojox/mobile/tests/test_ajax-json.html             |    2 +-
 dojox/mobile/tests/test_anchor-label.html          |   12 +-
 dojox/mobile/tests/test_bookmarkable.html          |    2 +-
 dojox/mobile/tests/test_buttons.html               |    2 +-
 dojox/mobile/tests/test_css-sprite.html            |  171 ++
 .../tests/test_dynamic-ScrollableView-ah-af.html   |   85 +
 .../tests/test_dynamic-ScrollableView-vh-vf.html   |   76 +
 dojox/mobile/tests/test_dynamic-icons.html         |    5 +-
 dojox/mobile/tests/test_dynamic-items.html         |    2 +-
 dojox/mobile/tests/test_dynamic-view.html          |    2 +-
 .../tests/test_grouped-scrollable-views.html       |   66 +
 dojox/mobile/tests/test_grouped-views.html         |   63 +
 dojox/mobile/tests/test_hash-parameter.html        |    2 +-
 dojox/mobile/tests/test_iPad-Settings.html         |  238 +++
 dojox/mobile/tests/test_iPhone-Animation.html      |    4 +-
 dojox/mobile/tests/test_iPhone-Button.html         |    2 +-
 dojox/mobile/tests/test_iPhone-ButtonList.html     |    5 +-
 dojox/mobile/tests/test_iPhone-EdgeToEdge.html     |   10 +-
 .../tests/test_iPhone-EdgeToEdgeCategory.html      |    2 +-
 dojox/mobile/tests/test_iPhone-FlippableView.html  |   83 +
 dojox/mobile/tests/test_iPhone-Heading.html        |  105 +-
 dojox/mobile/tests/test_iPhone-Icon.html           |    3 +-
 dojox/mobile/tests/test_iPhone-IconMulti.html      |    9 +-
 dojox/mobile/tests/test_iPhone-IconSingle.html     |    9 +-
 .../mobile/tests/test_iPhone-IconSingleBelow.html  |    9 +-
 dojox/mobile/tests/test_iPhone-ResultList.html     |    2 +-
 dojox/mobile/tests/test_iPhone-RoundRect.html      |    2 +-
 dojox/mobile/tests/test_iPhone-RoundRectList.html  |   12 +-
 .../tests/test_iPhone-ScrollableView-demo.html     |  394 +++++
 .../mobile/tests/test_iPhone-ScrollableView-h.html |   53 +
 .../tests/test_iPhone-ScrollableView-hv-ah-af.html |  124 ++
 .../tests/test_iPhone-ScrollableView-hv-vh-vf.html |  124 ++
 .../tests/test_iPhone-ScrollableView-hv.html       |  123 ++
 .../tests/test_iPhone-ScrollableView-v-ah-af.html  |  139 ++
 .../tests/test_iPhone-ScrollableView-v-vh-af.html  |  140 ++
 .../tests/test_iPhone-ScrollableView-v-vh-vf.html  |  141 ++
 .../tests/test_iPhone-ScrollableView-v-vh.html     |  139 ++
 .../mobile/tests/test_iPhone-ScrollableView-v.html |  137 ++
 dojox/mobile/tests/test_iPhone-Settings.html       |   36 +-
 dojox/mobile/tests/test_iPhone-Switch.html         |    4 +-
 .../test_iPhone-TabBar-seg-grouped-scroll.html     |  185 +++
 .../tests/test_iPhone-TabBar-seg-grouped.html      |  178 ++
 dojox/mobile/tests/test_iPhone-TabBar-seg.html     |  162 ++
 dojox/mobile/tests/test_iPhone-TabBar.html         |   65 +
 dojox/mobile/tests/test_iPhone-TabContainer.html   |   25 +-
 .../tests/test_iPhone-VariableHeightList.html      |    2 +-
 .../mobile/tests/test_orientation-transition.html  |   55 +
 dojox/mobile/tests/test_progress-indicator.html    |    2 +-
 dojox/mobile/tests/test_scrollable-no-dojo-af.html |  115 ++
 .../tests/test_scrollable-no-dojo-ah-af.html       |  122 ++
 dojox/mobile/tests/test_scrollable-no-dojo-ah.html |  114 ++
 dojox/mobile/tests/test_scrollable-no-dojo.html    |   91 +
 .../tests/test_transition-to-dynamic-view.html     |   76 +
 dojox/mobile/tests/view3.html                      |   16 +-
 dojox/mobile/tests/view3.json                      |   14 +-
 dojox/mobile/themes/FixedSplitter.css              |   22 +
 dojox/mobile/themes/android/android-app-compat.css |   24 +
 dojox/mobile/themes/android/android-app.css        |  349 ++++
 dojox/mobile/themes/android/android-compat.css     |   12 +-
 dojox/mobile/themes/android/android.css            |  122 +-
 dojox/mobile/themes/android/compat/heading-bg.png  |  Bin 0 -> 181 bytes
 .../themes/android/images/thumb-overlay-large.png  |  Bin 0 -> 3697 bytes
 .../themes/android/images/thumb-overlay-small.png  |  Bin 0 -> 1549 bytes
 .../mobile/themes/android/images/thumb-overlay.png |  Bin 0 -> 2010 bytes
 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/downarrow-button.png  |  Bin 0 -> 935 bytes
 .../themes/domButtons/compat/plus-button.png       |  Bin 0 -> 918 bytes
 .../themes/domButtons/compat/search-button.gif     |  Bin 0 -> 910 bytes
 .../themes/domButtons/compat/search-button.png     |  Bin 0 -> 420 bytes
 .../themes/domButtons/compat/uparrow-button.png    |  Bin 0 -> 933 bytes
 .../themes/iphone/compat/ipad-arrow-button-bg.png  |  Bin 0 -> 181 bytes
 .../iphone/compat/ipad-arrow-button-head.png       |  Bin 0 -> 1212 bytes
 .../themes/iphone/compat/ipad-heading-bg.png       |  Bin 0 -> 195 bytes
 .../themes/iphone/images/thumb-overlay-large.png   |  Bin 0 -> 3697 bytes
 .../themes/iphone/images/thumb-overlay-small.png   |  Bin 0 -> 1549 bytes
 dojox/mobile/themes/iphone/ipad-compat.css         |   12 +
 dojox/mobile/themes/iphone/ipad.css                |   66 +
 dojox/mobile/themes/iphone/iphone-app.css          |  148 +-
 dojox/mobile/themes/iphone/iphone-compat.css       |   19 +-
 dojox/mobile/themes/iphone/iphone.css              |  143 +-
 dojox/rails/tests/plugd/trigger.js                 |   46 +-
 dojox/resources/_modules.js                        |  102 +-
 dojox/robot/recorder.js                            |   78 +-
 dojox/rpc/Client.js                                |    6 +-
 dojox/rpc/JsonRPC.js                               |    7 +-
 dojox/rpc/JsonRest.js                              |   53 +-
 dojox/rpc/OfflineRest.js                           |   31 +-
 dojox/rpc/ProxiedPath.js                           |    5 +-
 dojox/rpc/Rest.js                                  |   23 +-
 dojox/rpc/SMDLibrary/twitter.smd                   |   35 +
 dojox/rpc/Service.js                               |   17 +-
 dojox/rpc/test.txt                                 |    1 -
 dojox/rpc/tests/Geonames.js                        |   12 +-
 dojox/rpc/tests/Service.js                         |    4 +-
 dojox/rpc/tests/Wikipedia.js                       |    2 +-
 dojox/rpc/tests/Yahoo.js                           |    2 +-
 dojox/rpc/tests/stores/JsonRestStore.js            |   40 +-
 dojox/secure/DOM.js                                |   40 +-
 dojox/secure/capability.js                         |   26 +-
 dojox/secure/fromJson.js                           |  241 +++
 dojox/secure/sandbox.js                            |   78 +-
 dojox/secure/tests/DOM.js                          |   14 +-
 dojox/secure/tests/fromJson.js                     |  150 ++
 dojox/secure/tests/sandbox.js                      |   10 +-
 dojox/sketch/Annotation.js                         |   38 +-
 dojox/sketch/DoubleArrowAnnotation.js              |   16 +-
 dojox/sketch/Figure.js                             |   22 +-
 dojox/sketch/LeadAnnotation.js                     |   26 +-
 dojox/sketch/PreexistingAnnotation.js              |   32 +-
 dojox/sketch/SingleArrowAnnotation.js              |   16 +-
 dojox/sketch/Slider.js                             |    2 +-
 dojox/sketch/Toolbar.js                            |    2 +-
 dojox/sketch/UnderlineAnnotation.js                |   16 +-
 dojox/socket.js                                    |  224 +++
 dojox/socket/README                                |   15 +
 dojox/socket/Reconnect.js                          |   54 +
 dojox/sql.js                                       |    2 +-
 dojox/sql/_base.js                                 |   42 +-
 dojox/sql/_crypto.js                               |   24 +-
 dojox/string/BidiComplex.js                        |   72 +-
 dojox/string/Builder.js                            |   16 +-
 dojox/string/sprintf.js                            |   12 +-
 dojox/string/tests/BidiComplex.js                  |   28 +-
 dojox/string/tests/Builder.js                      |    2 +-
 dojox/testing/DocTest.js                           |   22 +-
 dojox/timing.js                                    |    2 +-
 dojox/timing/Sequence.js                           |   22 +-
 dojox/timing/Streamer.js                           |    6 +-
 dojox/timing/ThreadPool.js                         |   28 +-
 dojox/timing/_base.js                              |    6 +-
 dojox/timing/doLater.js                            |    8 +-
 dojox/uuid/Uuid.js                                 |   62 +-
 dojox/uuid/_base.js                                |   56 +-
 dojox/uuid/generateRandomUuid.js                   |   20 +-
 dojox/uuid/generateTimeBasedUuid.js                |   54 +-
 dojox/uuid/tests/uuid.js                           |    6 +-
 dojox/validate.js                                  |    2 +-
 dojox/validate/_base.js                            |   16 +-
 dojox/validate/br.js                               |   22 +-
 dojox/validate/ca.js                               |   10 +-
 dojox/validate/check.js                            |   50 +-
 dojox/validate/creditCard.js                       |   40 +-
 dojox/validate/isbn.js                             |    8 +-
 dojox/validate/regexp.js                           |   30 +-
 dojox/validate/tests/br.js                         |    8 +-
 dojox/validate/tests/creditcard.js                 |    8 +-
 dojox/validate/tests/module.js                     |    6 +-
 dojox/validate/tests/validate.js                   |   92 +-
 dojox/validate/web.js                              |    2 +-
 dojox/widget/AnalogGauge.js                        |   91 +-
 dojox/widget/BarGauge.js                           |   24 +-
 dojox/widget/Calendar.js                           |  129 +-
 dojox/widget/CalendarViews.js                      |   17 +-
 dojox/widget/ColorPicker.js                        |   74 +-
 dojox/widget/DataPresentation.js                   |   50 +-
 dojox/widget/Dialog.js                             |   78 +-
 dojox/widget/Dialog/Dialog.css                     |    7 +-
 dojox/widget/Dialog/Dialog.html                    |    2 +-
 dojox/widget/DialogSimple.js                       |   10 +
 dojox/widget/DocTester.js                          |    4 +-
 dojox/widget/DynamicTooltip.js                     |   12 +-
 dojox/widget/FeedPortlet.js                        |  151 +-
 dojox/widget/FilePicker.js                         |   16 +-
 dojox/widget/FisheyeList.js                        |   70 +-
 dojox/widget/FisheyeLite.js                        |    8 +-
 dojox/widget/Iterator.js                           |   20 +-
 dojox/widget/Loader.js                             |   44 +-
 dojox/widget/Pager.js                              |   26 +-
 dojox/widget/PlaceholderMenuItem.js                |   88 +-
 dojox/widget/Portlet.js                            |   63 +-
 dojox/widget/Portlet/Portlet.css                   |   23 +-
 dojox/widget/README                                |   80 +-
 dojox/widget/Roller.js                             |   48 +-
 dojox/widget/RollingList.js                        |   74 +-
 dojox/widget/SortList.js                           |   38 +-
 dojox/widget/Standby.js                            |  164 +-
 dojox/widget/TitleGroup.js                         |   87 +
 dojox/widget/TitleGroup/TitleGroup.css             |   28 +
 dojox/widget/Toaster.js                            |    4 +-
 dojox/widget/Wizard.js                             |   36 +-
 dojox/widget/Wizard/Wizard.css                     |   36 +-
 dojox/widget/gauge/AnalogArcIndicator.js           |    4 +-
 dojox/widget/gauge/AnalogArrowIndicator.js         |    2 +-
 dojox/widget/gauge/AnalogNeedleIndicator.js        |    2 +-
 dojox/widget/gauge/BarIndicator.js                 |    2 +-
 dojox/widget/gauge/_Gauge.js                       |   40 +-
 dojox/widget/nls/ar/ColorPicker.js                 |    2 +
 dojox/widget/nls/ar/FilePicker.js                  |    3 +-
 dojox/widget/nls/ar/Wizard.js                      |    1 +
 dojox/widget/nls/ca/ColorPicker.js                 |    5 +-
 dojox/widget/nls/cs/ColorPicker.js                 |    3 +-
 dojox/widget/nls/da/ColorPicker.js                 |    2 +
 dojox/widget/nls/de/ColorPicker.js                 |    2 +
 dojox/widget/nls/el/ColorPicker.js                 |    4 +-
 dojox/widget/nls/es/ColorPicker.js                 |    5 +
 dojox/widget/nls/fi/ColorPicker.js                 |    2 +
 dojox/widget/nls/fr/ColorPicker.js                 |    7 +-
 dojox/widget/nls/he/ColorPicker.js                 |    5 +-
 dojox/widget/nls/hu/ColorPicker.js                 |    2 +
 dojox/widget/nls/it/ColorPicker.js                 |    9 +-
 dojox/widget/nls/ja/ColorPicker.js                 |    5 +-
 dojox/widget/nls/kk/ColorPicker.js                 |   12 +
 dojox/widget/nls/kk/FilePicker.js                  |    6 +
 dojox/widget/nls/kk/Wizard.js                      |    6 +
 dojox/widget/nls/ko/ColorPicker.js                 |    5 +-
 dojox/widget/nls/nb/ColorPicker.js                 |    3 +-
 dojox/widget/nls/nl/ColorPicker.js                 |    4 +-
 dojox/widget/nls/nl/FilePicker.js                  |    1 +
 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/ColorPicker.js                 |    3 +-
 dojox/widget/nls/ru/ColorPicker.js                 |    4 +-
 dojox/widget/nls/sl/ColorPicker.js                 |    2 +
 dojox/widget/nls/sv/ColorPicker.js                 |    4 +-
 dojox/widget/nls/th/ColorPicker.js                 |    6 +-
 dojox/widget/nls/tr/ColorPicker.js                 |    4 +-
 dojox/widget/nls/zh-tw/ColorPicker.js              |    5 +-
 dojox/widget/nls/zh/ColorPicker.js                 |    5 +-
 dojox/widget/nls/zh/FilePicker.js                  |    2 +-
 dojox/widget/rotator/PanFade.js                    |  211 +++
 dojox/widget/tests/CalendarStackLayout.js          |    4 +-
 dojox/widget/tests/test_DataPresentation.html      |  206 +--
 dojox/widget/tests/test_Dialog.html                |   48 +-
 dojox/widget/tests/test_DynamicTooltip.html        |    8 +-
 dojox/widget/tests/test_PlaceholderMenuItem.html   |   19 +-
 .../widget/tests/test_PortletInGridContainer.html  |  329 ++--
 dojox/widget/tests/test_PortletInGridContainer.js  |   41 +-
 dojox/widget/tests/test_Standby.html               |   15 +-
 dojox/widget/tests/test_Standby_quirks.html        |    8 +-
 dojox/widget/tests/test_Standby_rtl.html           |    8 +-
 dojox/widget/tests/test_TitleGroup.html            |  106 ++
 dojox/widget/tests/test_Wizard.html                |  209 ++-
 dojox/widget/tests/withjs.html                     |    4 +
 dojox/wire/DataWire.js                             |    2 +-
 dojox/wire/Wire.js                                 |    4 +-
 dojox/wire/XmlWire.js                              |    2 +-
 dojox/wire/_base.js                                |    2 +-
 dojox/wire/demos/WidgetRepeater.js                 |    4 +-
 dojox/wire/ml/Action.js                            |    4 +-
 dojox/xml/DomParser.js                             |   66 +-
 dojox/xml/parser.js                                |    6 +-
 dojox/xml/tests/parser.js                          |    2 +-
 dojox/xml/widgetParser.js                          |   18 +-
 dojox/xmpp/ChatService.js                          |   10 +-
 dojox/xmpp/RosterService.js                        |   36 +-
 dojox/xmpp/TransportSession.js                     |   46 +-
 dojox/xmpp/UserService.js                          |    2 +-
 dojox/xmpp/bosh.js                                 |    4 +-
 dojox/xmpp/util.js                                 |   44 +-
 dojox/xmpp/widget/ChatSession.js                   |    2 +-
 dojox/xmpp/xmppSession.js                          |   68 +-
 util/LICENSE                                       |    2 +-
 util/buildscripts/LICENSE                          |    2 +-
 util/buildscripts/build.js                         |   16 +-
 util/buildscripts/build_release.sh                 |   24 +-
 util/buildscripts/cldr/alias.js                    |   64 +-
 util/buildscripts/cldr/arrayInherit.js             |   14 +-
 util/buildscripts/cldr/build.xml                   |   10 +-
 util/buildscripts/cldr/cldrUtil.js                 |    4 +-
 util/buildscripts/cldr/ldml/core.zip               |  Bin 3407639 -> 4073422 bytes
 util/buildscripts/cldr/specialLocale.js            |   32 +-
 util/buildscripts/cldr/wrap.js                     |   74 +
 util/buildscripts/copyright.txt                    |    2 +-
 util/buildscripts/jslib/buildUtil.js               |  224 ++-
 util/buildscripts/jslib/buildUtilXd.js             |    2 +-
 util/buildscripts/jslib/convertTestsToXDomain.js   |    2 +-
 util/buildscripts/jslib/fileUtil.js                |   90 +-
 util/buildscripts/jslib/i18nUtil.js                |   10 +-
 util/buildscripts/makeDojoJsWeb.js                 |    2 +-
 util/buildscripts/profiles/baseplus.profile.js     |    4 +-
 util/buildscripts/profiles/demos-all.profile.js    |    9 +-
 util/buildscripts/profiles/mobile-all.profile.js   |   36 +
 util/buildscripts/profiles/mobile.profile.js       |   41 +
 util/buildscripts/profiles/rhino.profile.js        |    2 +-
 util/buildscripts/profiles/standard.profile.js     |   26 +-
 util/buildscripts/tests/conditionalTest.js         |    2 +-
 util/buildscripts/webbuild/server/js/build.js      |    4 +-
 util/checkstyle/checkstyleUtil.js                  |   88 +-
 util/checkstyle/runCheckstyle.js                   |    4 +-
 util/docscripts/LICENSE                            |    2 +-
 util/docscripts/_browse.php                        |    2 +-
 util/docscripts/_browse2.php                       |  375 +++--
 util/docscripts/cheat.php                          |   10 +-
 util/docscripts/cheat/cheat.css                    |    2 +-
 util/docscripts/cheat/floatup.js                   |  112 ++
 util/docscripts/cheat/lib.js                       |   66 +-
 util/docscripts/generate.php                       |    6 +-
 util/docscripts/lib/parser2/dojo2.inc              |   61 +-
 util/docscripts/makeCix.php                        |   13 +-
 util/docscripts/parsefile.php                      |   95 ++
 util/doh/LICENSE                                   |    2 +-
 util/doh/_browserRunner.js                         |   43 +-
 util/doh/_rhinoRunner.js                           |    2 +-
 util/doh/robot.js                                  |   23 +-
 util/doh/robot/DOHRobot.jar                        |  Bin 43794 -> 45861 bytes
 util/doh/robot/DOHRobot.java                       |  111 +-
 util/doh/runner.html                               |   93 +-
 util/doh/runner.js                                 |  262 +--
 util/jsdoc/LICENSE                                 |    2 +-
 util/shrinksafe/tests/module.js                    |   16 +-
 2907 files changed, 135899 insertions(+), 55484 deletions(-)

diff --git a/dijit/Calendar.js b/dijit/Calendar.js
index becf3ca..6a11efd 100644
--- a/dijit/Calendar.js
+++ b/dijit/Calendar.js
@@ -1,12 +1,4 @@
-dojo.provide("dijit.Calendar");
-
-dojo.require("dojo.cldr.supplemental");
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._CssStateMixin");
+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) {
 
 dojo.declare(
 	"dijit.Calendar",
@@ -31,10 +23,12 @@ dojo.declare(
 		//	|	<div dojoType="dijit.Calendar"></div>
 
 		templateString: dojo.cache("dijit", "templates/Calendar.html"),
+		widgetsInTemplate: true,
 
 		// value: Date
-		//		The currently selected Date
-		value: new 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
@@ -49,23 +43,35 @@ dojo.declare(
 		//		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",
 
-		// Set node classes for various mouse events, see dijit._CssStateMixin for more details 
+		// Set node classes for various mouse events, see dijit._CssStateMixin for more details
 		cssStateNodes: {
 			"decrementMonth": "dijitCalendarArrow",
 			"incrementMonth": "dijitCalendarArrow",
 			"previousYearLabelNode": "dijitCalendarPreviousYear",
-			"nextYearLabelNode": "dijitCalendarNextYear"			
+			"nextYearLabelNode": "dijitCalendarNextYear"
 		},
 
-		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
-			tabIndex: "domNode"
- 		}),
+		_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.   Used attr('value', ...) instead.
+			//      Deprecated.   Use set('value', ...) instead.
 			// tags:
 			//      deprecated
 			dojo.deprecated("dijit.Calendar:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
@@ -74,9 +80,11 @@ dojo.declare(
 
 		_getValueAttr: function(){
 			// summary:
-			//		Support getter attr('value')
+			//		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); // return midnight, local time for back-compat
+			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
@@ -86,26 +94,43 @@ dojo.declare(
 			return value;
 		},
 
-		_setValueAttr: function(/*Date*/ value){
+		_setValueAttr: function(/*Date|Number*/ value, /*Boolean*/ priorityChange){
 			// summary:
-			//		Support setter attr("value", ...)
+			//		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(!this.value || this.dateFuncObj.compare(value, this.value)){
+			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);
-				value.setHours(1); // to avoid issues when DST shift occurs at midnight, see #8521, #9366
-				this.displayMonth = new this.dateClassObj(value);
-				if(!this.isDisabledDate(value, this.lang)){
-					this.value = value;
-					this.onChange(this.get('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
+						}
+					}
 				}
-				dojo.attr(this.domNode, "aria-label",
-					this.dateLocaleModule.format(value,
-						{selector:"date", formatLength:"full"}));
-				this._populateGrid();
+			}else{
+				// clear value, and repopulate grid (to deselect the previously selected day) without changing currentFocus
+				this._set("value", null);
+				this.set("currentFocus", this.currentFocus);
 			}
 		},
 
@@ -126,8 +151,10 @@ dojo.declare(
 			//      Fills in the calendar grid with each day (1-31)
 			// tags:
 			//      private
-			var month = this.displayMonth;
+
+			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)),
@@ -177,20 +204,24 @@ dojo.declare(
 				}
 
 				template.className = clazz + "Month dijitCalendarDateTemplate";
-				template.dijitDateValue = date.valueOf();
+				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);
 
-			// Fill in localized month name
+			// 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._setText(this.monthLabelNode, monthNames[month.getMonth()]);
-			// Repopulate month list based on current year (Hebrew calendar)
-			dojo.query(".dijitCalendarMonthLabelTemplate", this.domNode).forEach(function(node, i){
-				dojo.toggleClass(node, "dijitHidden", !(i in monthNames)); // hide leap months (Hebrew)
-				this._setText(node, monthNames[i]);
-			}, this);
+			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;
@@ -200,21 +231,6 @@ dojo.declare(
 				this._setText(this[name+"YearLabelNode"],
 					this.dateLocaleModule.format(d, {selector:'year', locale:this.lang}));
 			}, this);
-
-			// Set up repeating mouse behavior
-			var _this = this;
-			var typematic = function(nodeProp, dateProp, adj){
-//FIXME: leaks (collects) listeners if populateGrid is called multiple times.  Do this once?
-				_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);
 		},
 
 		goToToday: function(){
@@ -232,12 +248,14 @@ dojo.declare(
 		},
 
 		postMixInProperties: function(){
-			// parser.instantiate sometimes passes in NaN for IE.  Use default value in prototype instead.
+			// 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);
 		},
 
-		postCreate: function(){
+		buildRendering: function(){
 			this.inherited(arguments);
 			dojo.setSelectable(this.domNode, false);
 
@@ -262,23 +280,28 @@ dojo.declare(
 				this._setText(label, dayNames[(i + dayOffset) % 7]);
 			}, this);
 
-			var dateObj = new this.dateClassObj(this.value);
-			// Fill in spacer/month dropdown element with all the month names (invisible) so that the maximum width will affect layout
-			var monthNames = this.dateLocaleModule.getNames('months', 'wide', 'standAlone', this.lang, dateObj);
-			cloneClass(".dijitCalendarMonthLabelTemplate", monthNames.length-1);
-			dojo.query(".dijitCalendarMonthLabelTemplate", this.domNode).forEach(function(node, i){
-				dojo.attr(node, "month", i);
-				if(i in monthNames){ this._setText(node, monthNames[i]); }
-				dojo.place(node.cloneNode(true), this.monthLabelSpacer);
-			}, this);
+			var dateObj = new this.dateClassObj(this.currentFocus);
 
-			this.value = null;
-			this.set('value', dateObj);
-		},
+			this.monthDropDownButton.dropDown = new dijit.Calendar._MonthDropDown({
+				id: this.id + "_mdd",
+				onChange: dojo.hitch(this, "_onMonthSelect")
+			});
 
-		_onMenuHover: function(e){
-			dojo.stopEvent(e);
-			dojo.toggleClass(e.target, "dijitMenuItemHover");
+			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){
@@ -290,47 +313,63 @@ dojo.declare(
 			//      Number of months or years
 			// tags:
 			//      private
-			this.displayMonth = this.dateFuncObj.add(this.displayMonth, part, amount);
-			this._populateGrid();
+			this._setCurrentFocusAttr(this.dateFuncObj.add(this.currentFocus, part, amount));
 		},
 
-		_onMonthToggle: function(/*Event*/ evt){
+		_setCurrentFocusAttr: function(/*Date*/ date, /*Boolean*/ forceFocus){
 			// summary:
-			//      Handler for when user triggers or dismisses the month list
-			// tags:
-			//      protected
-			dojo.stopEvent(evt);
+			//		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
 
-			if(evt.type == "mousedown"){
-				var coords = dojo.position(this.monthLabelNode);
-//				coords.y -= dojo.position(this.domNode, true).y;
-				// Size the dropdown's width to match the label in the widget
-				// so that they are horizontally aligned
-				var dim = {
-					width: coords.w + "px",
-					top: -this.displayMonth.getMonth() * coords.h + "px"
-				};
-				if((dojo.isIE && dojo.isQuirks) || dojo.isIE < 7){
-					dim.left = -coords.w/2 + "px";
+			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");
 				}
-				dojo.style(this.monthDropDown, dim);
-				this._popupHandler = this.connect(document, "onmouseup", "_onMonthToggle");
-			}else{
-				this.disconnect(this._popupHandler);
-				delete this._popupHandler;
 			}
+		},
 
-			dojo.toggleClass(this.monthDropDown, "dijitHidden");
-			dojo.toggleClass(this.monthLabelNode, "dijitVisible");
+		focus: function(){
+			// summary:
+			//		Focus the calendar by focusing one of the calendar cells
+			this._setCurrentFocusAttr(this.currentFocus, true);
 		},
 
-		_onMonthSelect: function(/*Event*/ evt){
+		_onMonthSelect: function(/*Number*/ newMonth){
 			// summary:
-			//      Handler for when user selects a month from a list
+			//      Handler for when user selects a month from the drop down list
 			// tags:
 			//      protected
-			this._onMonthToggle(evt);
-			this.displayMonth.setMonth(dojo.attr(evt.target, "month"));
+
+			// 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();
 		},
 
@@ -343,7 +382,6 @@ dojo.declare(
 			for(var node = evt.target; node && !node.dijitDateValue; node = node.parentNode);
 			if(node && !dojo.hasClass(node, "dijitCalendarDisabledDate")){
 				this.set('value', node.dijitDateValue);
-				this.onValueSelected(this.get('value'));
 			}
 		},
 
@@ -376,11 +414,11 @@ dojo.declare(
 			
 			// if mouse out occurs moving from <td> to <span> inside <td>, ignore it
 			if(evt.relatedTarget && evt.relatedTarget.parentNode == this._currentNode){ return; }
-
-			dojo.removeClass(this._currentNode, "dijitCalendarHoveredDate");
+			var cls = "dijitCalendarHoveredDate";
 			if(dojo.hasClass(this._currentNode, "dijitCalendarActiveDate")) {
-				dojo.removeClass(this._currentNode, "dijitCalendarActiveDate");
+				cls += " dijitCalendarActiveDate";
 			}
+			dojo.removeClass(this._currentNode, cls);
 			this._currentNode = null;
 		},
 		
@@ -400,17 +438,22 @@ dojo.declare(
 		},
 
 //TODO: use typematic
-//TODO: skip disabled dates without ending up in a loop
-//TODO: could optimize by avoiding populate grid when month does not change
-		_onKeyPress: function(/*Event*/evt){
+		handleKey: function(/*Event*/ evt){
 			// summary:
-			//		Provides keyboard navigation of calendar
+			//		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.value;
+				newValue = this.currentFocus;
 			switch(evt.keyCode){
 				case dk.RIGHT_ARROW:
 					increment = 1;
@@ -429,7 +472,7 @@ dojo.declare(
 					increment = 1;
 					//fallthrough...
 				case dk.PAGE_UP:
-					interval = evt.ctrlKey ? "year" : "month";
+					interval = evt.ctrlKey || evt.altKey ? "year" : "month";
 					break;
 				case dk.END:
 					// go to the next month
@@ -438,31 +481,40 @@ dojo.declare(
 					interval = "day";
 					//fallthrough...
 				case dk.HOME:
-					newValue = new Date(newValue).setDate(1);
+					newValue = new this.dateClassObj(newValue);
+					newValue.setDate(1);
 					break;
 				case dk.ENTER:
-					this.onValueSelected(this.get('value'));
+				case dk.SPACE:
+					this.set("value", this.currentFocus);
 					break;
-				case dk.ESCAPE:
-					//TODO
 				default:
-					return;
+					return true;
 			}
-			dojo.stopEvent(evt);
 
 			if(interval){
 				newValue = this.dateFuncObj.add(newValue, interval, increment);
 			}
 
-			this.set("value", newValue);
+			this._setCurrentFocusAttr(newValue);
+
+			return false;
+		},
+
+		_onKeyPress: function(/*Event*/ evt){
+			// summary:
+			//		For handling keypress events on a stand alone calendar
+			if(!this.handleKey(evt)){
+				dojo.stopEvent(evt);
+			}
 		},
 
 		onValueSelected: function(/*Date*/ date){
 			// summary:
 			//		Notification that a date cell was selected.  It may be the same as the previous value.
 			// description:
-			//      Used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
-			//      to get notification when the user has clicked a date.
+			//      Formerly used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.DateTextBox`)
+			//      to get notification when the user has clicked a date.  Now onExecute() (above) is used.
 			// tags:
 			//      protected
 		},
@@ -478,7 +530,7 @@ dojo.declare(
 			//		support multiple (concurrently) selected dates
 			// tags:
 			//		protected extension
-			return !this.dateFuncObj.compare(dateObject, this.value, "date")
+			return this._isValidDate(this.value) && !this.dateFuncObj.compare(dateObject, this.value, "date")
 		},
 
 		isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
@@ -504,3 +556,38 @@ dojo.declare(
 		}
 	}
 );
+
+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: [],
+
+	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 dijit.Calendar;
+});
diff --git a/dijit/CheckedMenuItem.js b/dijit/CheckedMenuItem.js
index 09313a9..90154b9 100644
--- a/dijit/CheckedMenuItem.js
+++ b/dijit/CheckedMenuItem.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.CheckedMenuItem");
-
-dojo.require("dijit.MenuItem");
+define("dijit/CheckedMenuItem", ["dojo", "dijit", "text!dijit/templates/CheckedMenuItem.html", "dijit/MenuItem"], function(dojo, dijit) {
 
 dojo.declare("dijit.CheckedMenuItem",
 		dijit.MenuItem,
@@ -19,7 +17,7 @@ dojo.declare("dijit.CheckedMenuItem",
 			//		Sets the class and state for the check box.
 			dojo.toggleClass(this.domNode, "dijitCheckedMenuItemChecked", checked);
 			dijit.setWaiState(this.domNode, "checked", checked);
-			this.checked = checked;
+			this._set("checked", checked);
 		},
 
 		onChange: function(/*Boolean*/ checked){
@@ -41,3 +39,7 @@ dojo.declare("dijit.CheckedMenuItem",
 			this.inherited(arguments);
 		}
 	});
+
+
+return dijit.CheckedMenuItem;
+});
diff --git a/dijit/ColorPalette.js b/dijit/ColorPalette.js
index 7a389a0..0e60d61 100644
--- a/dijit/ColorPalette.js
+++ b/dijit/ColorPalette.js
@@ -1,13 +1,4 @@
-dojo.provide("dijit.ColorPalette");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojo.colors");
-dojo.require("dojo.i18n");
-
-dojo.require("dijit._PaletteMixin");
-
-dojo.requireLocalization("dojo", "colors");
+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],
@@ -26,7 +17,7 @@ dojo.declare("dijit.ColorPalette",
 	// |	picker.startup();
 
 
-	// palette: String
+	// palette: [const] String
 	//		Size of grid, either "7x10" or "3x4".
 	palette: "7x10",
 
@@ -48,62 +39,89 @@ dojo.declare("dijit.ColorPalette",
 			["gray", "red", "purple", "black"]]
 	},
 
-	// _imagePaths: [protected] Map
-	//		This is stores the path to the palette images
-	_imagePaths: {
-		"7x10": dojo.moduleUrl("dijit.themes", "a11y/colors7x10.png"),
-		"3x4": dojo.moduleUrl("dijit.themes", "a11y/colors3x4.png"),
-		"7x10-rtl": dojo.moduleUrl("dijit.themes", "a11y/colors7x10-rtl.png"),
-		"3x4-rtl": dojo.moduleUrl("dijit.themes", "a11y/colors3x4-rtl.png")
-	},
-
 	// templateString: String
 	//		The template of this widget.
 	templateString: dojo.cache("dijit", "templates/ColorPalette.html"),
 
 	baseClass: "dijitColorPalette",
 
-	dyeClass: 'dijit._Color',
-
 	buildRendering: function(){
 		// Instantiate the template, which makes a skeleton into which we'll insert a bunch of
 		// <img> nodes
-
 		this.inherited(arguments);
 
-		this.imageNode.setAttribute("src", this._imagePaths[this.palette + (this.isLeftToRight() ? "" : "-rtl")].toString());
-
-		var i18nColorNames = dojo.i18n.getLocalization("dojo", "colors", this.lang);
+		// 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],
-			i18nColorNames
+			dojo.i18n.getLocalization("dojo", "colors", this.lang),
+			dojo.declare(dijit._Color, {
+				hc: dojo.hasClass(dojo.body(), "dijit_a11y"),
+				palette: this.palette
+			})
 		);
 	}
 });
 
-dojo.declare("dijit._Color", dojo.Color,
+dojo.declare("dijit._Color", dojo.Color, {
 	// summary:
 	//		Object associated with each cell in a ColorPalette palette.
 	//		Implements dijit.Dye.
-	{
-		constructor: function(/*String*/alias){
-			this._alias = alias;
-			this.setColor(dojo.Color.named[alias]);
-		},
-
-		getValue: function(){
-			// summary:
-			//		Note that although dijit._Color is initialized with a value like "white" getValue() always
-			//		returns a hex value
-			return this.toHex();
-		},
-
-		fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){
-			dojo.create("img", {
-				src: blankGif,
-				"class": "dijitPaletteImg",
-				alt: this._alias
-			}, cell);
-		}
+
+	// Template for each cell in normal (non-high-contrast mode).  Each cell contains a wrapper
+	// node for showing the border (called dijitPaletteImg for back-compat), and dijitColorPaletteSwatch
+	// for showing the color.
+	template:
+		"<span class='dijitInline dijitPaletteImg'>" +
+			"<img src='${blankGif}' alt='${alt}' class='dijitColorPaletteSwatch' style='background-color: ${color}'/>" +
+		"</span>",
+
+	// Template for each cell in high contrast mode.  Each cell contains an image with the whole palette,
+	// but scrolled and clipped to show the correct color only
+	hcTemplate:
+		"<span class='dijitInline dijitPaletteImg' style='position: relative; overflow: hidden; height: 12px; width: 14px;'>" +
+			"<img src='${image}' alt='${alt}' style='position: absolute; left: ${left}px; top: ${top}px; ${size}'/>" +
+		"</span>",
+
+	// _imagePaths: [protected] Map
+	//		This is stores the path to the palette images used for high-contrast mode display
+	_imagePaths: {
+		"7x10": dojo.moduleUrl("dijit.themes", "a11y/colors7x10.png"),
+		"3x4": dojo.moduleUrl("dijit.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]);
+	},
+
+	getValue: function(){
+		// summary:
+		//		Note that although dijit._Color is initialized with a value like "white" getValue() always
+		//		returns a hex value
+		return this.toHex();
+	},
+
+	fillCell: function(/*DOMNode*/ cell, /*String*/ blankGif){
+		var html = dojo.string.substitute(this.hc ? this.hcTemplate : this.template, {
+			// substitution variables for normal mode
+			color: this.toHex(),
+			blankGif: blankGif,
+			alt: this._alias,
+			
+			// variables used for high contrast mode
+			image: this._imagePaths[this.palette].toString(),
+			left: this._col * -20 - 5,
+			top: this._row * -20 - 5,
+			size: this.palette == "7x10" ? "height: 145px; width: 206px" : "height: 64px; width: 86px"
+		});
+
+		dojo.place(html, cell);
 	}
-);
+});
+
+
+return dijit.ColorPalette;
+});
diff --git a/dijit/Declaration.js b/dijit/Declaration.js
index cfdd582..a62f6e0 100644
--- a/dijit/Declaration.js
+++ b/dijit/Declaration.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.Declaration");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+define("dijit/Declaration", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.Declaration",
@@ -14,35 +12,44 @@ dojo.declare(
 		//		Flag to parser to leave alone the script tags contained inside of me
 		_noScript: true,
 
-		// widgetClass: String
+		// stopParser: [private] Boolean
+		//		Flag to parser to not try and parse widgets declared inside of me
+		stopParser: true,
+
+		// widgetClass: [const] String
 		//		Name of class being declared, ex: "acme.myWidget"
 		widgetClass: "",
 
-		// propList: Object
+		// propList: [const] Object
 		//		Set of attributes for this widget along with default values, ex:
 		//		{delay: 100, title: "hello world"}
 		defaults: null,
 
-		// mixins: String[]
+		// mixins: [const] String[]
 		//		List containing the prototype for this widget, and also any mixins,
 		//		ex: ["dijit._Widget", "dijit._Container"]
 		mixins: [],
 
 		buildRendering: function(){
 			var src = this.srcNodeRef.parentNode.removeChild(this.srcNodeRef),
-				methods = dojo.query("> script[type^='dojo/method'][event]", src).orphan(),
-				postscriptConnects = dojo.query("> script[type^='dojo/method']", src).orphan(),
-				regularConnects = dojo.query("> script[type^='dojo/connect']", src).orphan(),
+				methods = dojo.query("> script[type^='dojo/method']", src).orphan(),
+				connects = dojo.query("> script[type^='dojo/connect']", src).orphan(),
 				srcType = src.nodeName;
 
 			var propList = this.defaults || {};
 
-			// For all methods defined like <script type="dojo/method" event="foo">,
-			// add that method to prototype
+			// For all methods defined like <script type="dojo/method" data-dojo-event="foo">,
+			// 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){
-				var evt = s.getAttribute("event"),
+				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event"),
 					func = dojo.parser._functionFromScript(s);
-				propList[evt] = func;
+				if(evt){
+					propList[evt] = func;
+				}else{
+					connects.push(s);
+				}
 			});
 
 			// map array of strings like [ "dijit.form.Button" ] to array of mixin objects
@@ -69,18 +76,21 @@ dojo.declare(
 			);
 
 			// Handle <script> blocks of form:
-			//		<script type="dojo/connect" event="foo">
+			//		<script type="dojo/connect" data-dojo-event="foo">
 			// and
 			//		<script type="dojo/method">
 			// (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_.
-			var connects = regularConnects.concat(postscriptConnects);
 			dojo.forEach(connects, function(s){
-				var evt = s.getAttribute("event") || "postscript",
+				var evt = s.getAttribute("event") || s.getAttribute("data-dojo-event") || "postscript",
 					func = dojo.parser._functionFromScript(s);
 				dojo.connect(wc.prototype, evt, func);
 			});
 		}
 	}
 );
+
+
+return dijit.Declaration;
+});
diff --git a/dijit/Dialog.js b/dijit/Dialog.js
index 7ac1b8e..1076e24 100644
--- a/dijit/Dialog.js
+++ b/dijit/Dialog.js
@@ -1,18 +1,6 @@
-dojo.provide("dijit.Dialog");
-
-dojo.require("dojo.dnd.move");
-dojo.require("dojo.dnd.TimedMoveable");
-dojo.require("dojo.fx");
-dojo.require("dojo.window");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._CssStateMixin");
-dojo.require("dijit.form._FormMixin");
-dojo.require("dijit._DialogMixin");
-dojo.require("dijit.DialogUnderlay");
-dojo.require("dijit.layout.ContentPane");
-dojo.requireLocalization("dijit", "common");
+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) {
+
+// dijit/TooltipDialog required for back-compat.  TODO: remove in 2.0
 
 /*=====
 dijit._underlay = function(kwArgs){
@@ -25,7 +13,6 @@ dijit._underlay = function(kwArgs){
 	//		or subclass thereof is shown.
 };
 =====*/
-
 dojo.declare(
 	"dijit._DialogBase",
 	[dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin, dijit._CssStateMixin],
@@ -62,7 +49,7 @@ dojo.declare(
 			"aria-describedby":""
 		}),
 
-		// open: Boolean
+		// open: [readonly] Boolean
 		//		True if Dialog is currently displayed on screen.
 		open: false,
 
@@ -82,12 +69,12 @@ dojo.declare(
 		//		False will disable autofocusing. Default: true
 		autofocus: true,
 
-		// _firstFocusItem: [private] [readonly] DomNode
+		// _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
+		// _lastFocusItem: [private readonly] DomNode
 		//		The pointer to which node has focus prior to our dialog.
 		//		Set by `dijit._DialogMixin._getFocusItems`.
 		_lastFocusItem: null,
@@ -139,14 +126,14 @@ dojo.declare(
 			// summary:
 			//		Called when data has been loaded from an href.
 			//		Unlike most other callbacks, this function can be connected to (via `dojo.connect`)
-			//		but should *not* be overriden.
+			//		but should *not* be overridden.
 			// tags:
 			//		callback
 
 			// 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){
+			if(this.autofocus && dijit._DialogLevelManager.isTop(this)){
 				this._getFocusItems(this.domNode);
 				dijit.focus(this._firstFocusItem);
 			}
@@ -177,7 +164,7 @@ dojo.declare(
 				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 });
-				dojo.subscribe("/dnd/move/stop",this,"_endDrag");
+				this._dndListener = dojo.subscribe("/dnd/move/stop",this,"_endDrag");
 			}else{
 				dojo.addClass(node,"dijitDialogFixed");
 			}
@@ -186,95 +173,6 @@ dojo.declare(
 				dialogId: this.id,
 				"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
 			};
-
-			this._fadeIn = dojo.fadeIn({
-				node: node,
-				duration: this.duration,
-				beforeBegin: dojo.hitch(this, function(){
-					var underlay = dijit._underlay;
-					if(!underlay){
-						underlay = dijit._underlay = new dijit.DialogUnderlay(this.underlayAttrs);
-					}else{
-						underlay.set(this.underlayAttrs);
-					}
-
-					var ds = dijit._dialogStack,
-						zIndex = 948 + ds.length*2;
-					if(ds.length == 1){	// first dialog
-						underlay.show();
-					}
-					dojo.style(dijit._underlay.domNode, 'zIndex', zIndex);
-					dojo.style(this.domNode, 'zIndex', zIndex + 1);
-				}),
-				onEnd: dojo.hitch(this, function(){
-					if(this.autofocus){
-						// 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);
-					}
-				})
-			 });
-
-			this._fadeOut = dojo.fadeOut({
-				node: node,
-				duration: this.duration,
-				onEnd: dojo.hitch(this, function(){
-					node.style.display = "none";
-
-					// Restore the previous dialog in the stack, or if this is the only dialog
-					// then restore to original page
-					var ds = dijit._dialogStack;
-					if(ds.length == 0){
-						dijit._underlay.hide();
-					}else{
-						dojo.style(dijit._underlay.domNode, 'zIndex', 948 + ds.length*2);
-						dijit._underlay.set(ds[ds.length-1].underlayAttrs);
-					}
-
-					// Restore focus to wherever it was before this dialog was displayed
-					if(this.refocus){
-						var focus = this._savedFocus;
-
-						// 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.
-						if(ds.length > 0){
-							var pd = ds[ds.length-1];
-							if(!dojo.isDescendant(focus.node, pd.domNode)){
-								pd._getFocusItems(pd.domNode);
-								focus = pd._firstFocusItem;
-							}
-						}
-
-						dijit.focus(focus);
-					}
-				})
-			 });
-		},
-
-		uninitialize: function(){
-			var wasPlaying = false;
-			if(this._fadeIn && this._fadeIn.status() == "playing"){
-				wasPlaying = true;
-				this._fadeIn.stop();
-			}
-			if(this._fadeOut && this._fadeOut.status() == "playing"){
-				wasPlaying = true;
-				this._fadeOut.stop();
-			}
-			
-			// 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((this.open || wasPlaying) && !dijit._underlay._destroyed){
-				dijit._underlay.hide();
-			}
-
-			if(this._moveable){
-				this._moveable.destroy();
-			}
-			this.inherited(arguments);
 		},
 
 		_size: function(){
@@ -300,7 +198,7 @@ dojo.declare(
 				});
 			}
 
-			var mb = dojo.marginBox(this.domNode);
+			var mb = dojo._getMarginSize(this.domNode);
 			var viewport = dojo.window.getBox();
 			if(mb.w >= viewport.w || mb.h >= viewport.h){
 				// Reduce size of dialog contents so that dialog fits in viewport
@@ -355,12 +253,6 @@ dojo.declare(
 			// tags:
 			//		private
 
-			var ds = dijit._dialogStack;
-			if(ds[ds.length-1] != this){
-				// console.debug(this.id + ': skipping because', this, 'is not the active dialog');
-				return;
-			}
-
 			if(evt.charOrCode){
 				var dk = dojo.keys;
 				var node = evt.target;
@@ -407,16 +299,23 @@ dojo.declare(
 		show: function(){
 			// summary:
 			//		Display the dialog
+			// returns: dojo.Deferred
+			//		Deferred object that resolves when the display animation is complete
+
 			if(this.open){ return; }
 
+			if(!this._started){
+				this.startup();
+			}
+
 			// first time we show the dialog, there's some initialization stuff to do
 			if(!this._alreadyInitialized){
 				this._setup();
 				this._alreadyInitialized=true;
 			}
 
-			if(this._fadeOut.status() == "playing"){
-				this._fadeOut.stop();
+			if(this._fadeOutDeferred){
+				this._fadeOutDeferred.cancel();
 			}
 
 			this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
@@ -431,43 +330,81 @@ dojo.declare(
 					this._oldViewport = viewport;
 				}
 			}));
-			this._modalconnects.push(dojo.connect(dojo.doc.documentElement, "onkeypress", this, "_onKey"));
+			this._modalconnects.push(dojo.connect(this.domNode, "onkeypress", this, "_onKey"));
 
 			dojo.style(this.domNode, {
 				opacity:0,
 				display:""
 			});
 
-			this.open = true;
+			this._set("open", true);
 			this._onShow(); // lazy load trigger
 
 			this._size();
 			this._position();
-			dijit._dialogStack.push(this);
-			this._fadeIn.play();
 
-			this._savedFocus = dijit.getFocus(this);
+			// fade-in Animation object, setup below
+			var fadeIn;
+
+			this._fadeInDeferred = new dojo.Deferred(dojo.hitch(this, function(){
+				fadeIn.stop();
+				delete this._fadeInDeferred;
+			}));
+
+			fadeIn = dojo.fadeIn({
+				node: this.domNode,
+				duration: this.duration,
+				beforeBegin: dojo.hitch(this, function(){
+					dijit._DialogLevelManager.show(this, this.underlayAttrs);
+				}),
+				onEnd: dojo.hitch(this, function(){
+					if(this.autofocus && dijit._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);
+					}
+					this._fadeInDeferred.callback(true);
+					delete this._fadeInDeferred;
+				})
+			}).play();
+			
+			return this._fadeInDeferred;
 		},
 
 		hide: function(){
 			// summary:
 			//		Hide the dialog
+			// returns: dojo.Deferred
+			//		Deferred object that resolves when the hide animation is complete
 
 			// if we haven't been initialized yet then we aren't showing and we can just return
-			// or if we aren't the active dialog, don't allow us to close yet
-			var ds = dijit._dialogStack;
-			if(!this._alreadyInitialized || this != ds[ds.length-1]){
+			if(!this._alreadyInitialized){
 				return;
 			}
-
-			if(this._fadeIn.status() == "playing"){
-				this._fadeIn.stop();
+			if(this._fadeInDeferred){
+				this._fadeInDeferred.cancel();
 			}
 
-			// throw away current active dialog from stack -- making the previous dialog or the node on the original page active
-			ds.pop();
+			// fade-in Animation object, setup below
+			var fadeOut;
 
-			this._fadeOut.play();
+			this._fadeOutDeferred = new dojo.Deferred(dojo.hitch(this, function(){
+				fadeOut.stop();
+				delete this._fadeOutDeferred;
+			}));
+
+			fadeOut = dojo.fadeOut({
+				node: this.domNode,
+				duration: this.duration,
+				onEnd: dojo.hitch(this, function(){
+					this.domNode.style.display = "none";
+					dijit._DialogLevelManager.hide(this);
+					this.onHide();
+					this._fadeOutDeferred.callback(true);
+					delete this._fadeOutDeferred;
+				})
+			 }).play();
 
 			if(this._scrollConnected){
 				this._scrollConnected = false;
@@ -478,9 +415,9 @@ dojo.declare(
 			if(this._relativePosition){
 				delete this._relativePosition;
 			}
-			this.open = false;
+			this._set("open", false);
 
-			this.onHide();
+			return this._fadeOutDeferred;
 		},
 
 		layout: function(){
@@ -497,10 +434,22 @@ dojo.declare(
 		},
 
 		destroy: function(){
-			dojo.forEach(this._modalconnects, dojo.disconnect);
-			if(this.refocus && this.open){
-				setTimeout(dojo.hitch(dijit,"focus",this._savedFocus), 25);
+			if(this._fadeInDeferred){
+				this._fadeInDeferred.cancel();
+			}
+			if(this._fadeOutDeferred){
+				this._fadeOutDeferred.cancel();
+			}
+			if(this._moveable){
+				this._moveable.destroy();
 			}
+			if(this._dndListener){
+				dojo.unsubscribe(this._dndListener);
+			}
+			dojo.forEach(this._modalconnects, dojo.disconnect);
+
+			dijit._DialogLevelManager.hide(this);
+
 			this.inherited(arguments);
 		}
 	}
@@ -512,8 +461,129 @@ dojo.declare(
 	{}
 );
 
-// Stack of currenctly displayed dialogs, layered on top of each other
-dijit._dialogStack = [];
+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.
+
+	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.
+
+		var ds = dijit._dialogStack;
+
+		// Save current focus
+		ds[ds.length-1].focus = dijit.getFocus(dialog);
+
+		// 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);
+
+		ds.push({dialog: dialog, underlayAttrs: underlayAttrs, zIndex: zIndex});
+	},
+
+	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.
+
+		var ds = dijit._dialogStack;
+
+		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
+				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 */
+				}
+			}
+		}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;
+	}
+};
 
-// For back-compat.  TODO: remove in 2.0
-dojo.require("dijit.TooltipDialog");
+// 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;
+});
diff --git a/dijit/DialogUnderlay.js b/dijit/DialogUnderlay.js
index 89c9d26..569fad0 100644
--- a/dijit/DialogUnderlay.js
+++ b/dijit/DialogUnderlay.js
@@ -1,9 +1,4 @@
-dojo.provide("dijit.DialogUnderlay");
-
-dojo.require("dojo.window");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+define("dijit/DialogUnderlay", ["dojo", "dijit", "dojo/window", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.DialogUnderlay",
@@ -41,10 +36,12 @@ dojo.declare(
 
 		_setDialogIdAttr: function(id){
 			dojo.attr(this.node, "id", id + "_underlay");
+			this._set("dialogId", id);
 		},
 
 		_setClassAttr: function(clazz){
 			this.node.className = "dijitDialogUnderlay " + clazz;
+			this._set("class", clazz);
 		},
 
 		postCreate: function(){
@@ -93,14 +90,12 @@ dojo.declare(
 			// summary:
 			//		Hides the dialog underlay
 			this.bgIframe.destroy();
+			delete this.bgIframe;
 			this.domNode.style.display = "none";
-		},
-
-		uninitialize: function(){
-			if(this.bgIframe){
-				this.bgIframe.destroy();
-			}
-			this.inherited(arguments);
 		}
 	}
 );
+
+
+return dijit.DialogUnderlay;
+});
diff --git a/dijit/Editor.js b/dijit/Editor.js
index ff894ee..c58e538 100644
--- a/dijit/Editor.js
+++ b/dijit/Editor.js
@@ -1,16 +1,4 @@
-dojo.provide("dijit.Editor");
-dojo.require("dijit._editor.RichText");
-
-dojo.require("dijit.Toolbar");
-dojo.require("dijit.ToolbarSeparator");
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit._editor.plugins.EnterKeyHandling");
-dojo.require("dijit._editor.range");
-dojo.require("dijit._Container");
-dojo.require("dojo.i18n");
-dojo.require("dijit.layout._LayoutWidget");
-dojo.require("dijit._editor.range");
-dojo.requireLocalization("dijit._editor", "commands");
+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",
@@ -28,7 +16,7 @@ dojo.declare(
 		//		a few limitations.  Note: this widget should not be used with the HTML
 		//		<TEXTAREA> tag -- see dijit._editor.RichText for details.
 
-		// plugins: Object[]
+		// plugins: [const] Object[]
 		//		A list of plugin names (as strings) or instances (as objects)
 		//		for this widget.
 		//
@@ -36,7 +24,7 @@ dojo.declare(
 		//	|	plugins="['bold',{name:'dijit._editor.plugins.FontChoice', command:'fontName', generic:true}]"
 		plugins: null,
 
-		// extraPlugins: Object[]
+		// extraPlugins: [const] Object[]
 		//		A list of extra plugin names which will be appended to plugins array
 		extraPlugins: null,
 
@@ -71,6 +59,18 @@ dojo.declare(
 			}
 		},
 
+		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.
+
+			// 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.inherited(arguments);
+		},
+	
 		postCreate: function(){
 			//for custom undo/redo, if enabled.
 			this._steps=this._steps.slice(0);
@@ -80,11 +80,6 @@ dojo.declare(
 				this.plugins=this.plugins.concat(this.extraPlugins);
 			}
 
-			// 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.inherited(arguments);
 
 			this.commands = dojo.i18n.getLocalization("dijit._editor", "commands", this.lang);
@@ -205,8 +200,8 @@ dojo.declare(
 			// except what's needed for the header (toolbars) and footer (breadcrumbs, etc).
 			// A class was added to the iframe container and some themes style it, so we have to
 			// calc off the added margins and padding too. See tracker: #10662
-			var areaHeight = (this._contentBox.h - 
-				(this.getHeaderHeight() + this.getFooterHeight() + 
+			var areaHeight = (this._contentBox.h -
+				(this.getHeaderHeight() + this.getFooterHeight() +
 				 dojo._getPadBorderExtents(this.iframe.parentNode).h +
 				 dojo._getMarginExtents(this.iframe.parentNode).h));
 			this.editingArea.style.height = areaHeight + "px";
@@ -233,9 +228,9 @@ dojo.declare(
 			var offsetLeft = b.offsetLeft;
 
 			//Check for vertical scroller click.
-			bodyDir = b.dir?b.dir.toLowerCase():""
+			bodyDir = b.dir ? b.dir.toLowerCase() : "";
 			if(bodyDir != "rtl"){
-				if(clientWidth < offsetWidth && e.x > clientWidth && e.x < offsetWidth){ 
+				if(clientWidth < offsetWidth && e.x > clientWidth && e.x < offsetWidth){
 					// Check the click was between width and offset width, if so, scroller
 					outsideClientArea = true;
 				}
@@ -254,7 +249,7 @@ dojo.declare(
 				}
 			}
 			if(!outsideClientArea){
-				delete this._cursorToStart; // Remove the force to cursor to start position. 
+				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);
@@ -285,11 +280,11 @@ dojo.declare(
 
 		// customUndo: Boolean
 		//		Whether we shall use custom undo/redo support instead of the native
-		//		browser support. By default, we only enable customUndo for IE, as it
-		//		has broken native undo/redo support. Note: the implementation does
-		//		support other browsers which have W3C DOM2 Range API implemented.
-		//		It was also enabled on WebKit, to fix undo/redo enablement. (#9613)
-		customUndo: dojo.isIE || dojo.isWebKit,
+		//		browser support. By default, we now use custom undo.  It works better
+		//		than native browser support and provides a consistent behavior across
+		//		browsers with a minimal performance hit.  We already had the hit on
+		//		the slowest browser, IE, anyway.
+		customUndo: true,
 
 		// editActionInterval: Integer
 		//		When using customUndo, not every keystroke will be saved as a step.
@@ -317,8 +312,11 @@ dojo.declare(
 				this._editTimer = setTimeout(dojo.hitch(this, this.endEditing), this._editInterval);
 			}
 		},
+
+		// TODO: declaring these in the prototype is meaningless, just create in the constructor/postCreate
 		_steps:[],
 		_undoedSteps:[],
+
 		execCommand: function(cmd){
 			// summary:
 			//		Main handler for executing any commands to the editor, like paste, bold, etc.
@@ -333,14 +331,15 @@ dojo.declare(
 					this._beginEditing();
 				}
 				var r;
+				var isClipboard = /copy|cut|paste/.test(cmd);
 				try{
-					r = this.inherited('execCommand', arguments);
-					if(dojo.isWebKit && cmd == 'paste' && !r){ //see #4598: safari does not support invoking paste from js
+					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 */ && /copy|cut|paste/.test(cmd)){
+					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'};
@@ -364,7 +363,7 @@ dojo.declare(
 			if(this.customUndo && (cmd == 'undo' || cmd == 'redo')){
 				return cmd == 'undo' ? (this._steps.length > 1) : (this._undoedSteps.length > 0);
 			}else{
-				return this.inherited('queryCommandEnabled',arguments);
+				return this.inherited(arguments);
 			}
 		},
 		_moveToBookmark: function(b){
@@ -377,7 +376,7 @@ dojo.declare(
 			var col = b.isCollapsed;
 			var r, sNode, eNode, sel;
 			if(mark){
-				if(dojo.isIE){
+				if(dojo.isIE < 9){
 					if(dojo.isArray(mark)){
 						//IE CONTROL, have to use the native bookmark.
 						bookmark = [];
@@ -456,7 +455,7 @@ dojo.declare(
 					ret = true;
 				}
 				delete this._undoRedoActive;
-			}	
+			}
 			return ret;
 		},
 		redo: function(){
@@ -505,7 +504,7 @@ dojo.declare(
 			var tmp=[];
 			if(b && b.mark){
 				var mark = b.mark;
-				if(dojo.isIE){
+				if(dojo.isIE < 9){
 					// Try to use the pseudo range API on IE for better accuracy.
 					var sel = dijit.range.getSelection(this.window);
 					if(!dojo.isArray(mark)){
@@ -551,7 +550,7 @@ dojo.declare(
 			if(this._steps.length === 0){
 				// You want to use the editor content without post filtering
 				// to make sure selection restores right for the 'initial' state.
-				// and undo is called.  So not using this.savedContent, as it was 'processed'
+				// 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()});
 			}
@@ -652,7 +651,7 @@ dojo.declare(
 			//		protected
 
 			//this._saveSelection();
-			this.inherited('_onBlur',arguments);
+			this.inherited(arguments);
 			this.endEditing(true);
 		},
 		_saveSelection: function(){
@@ -660,8 +659,9 @@ dojo.declare(
 			//		Save the currently selected text in _savedSelection attribute
 			// tags:
 			//		private
-			this._savedSelection=this._getBookmark();
-			//console.log('save selection',this._savedSelection,this);
+			try{
+				this._savedSelection=this._getBookmark();
+			}catch(e){ /* Squelch any errors that occur if selection save occurs due to being hidden simultaniously. */}
 		},
 		_restoreSelection: function(){
 			// summary:
@@ -691,38 +691,56 @@ dojo.declare(
 			this.inherited(arguments);
 		},
 
+		replaceValue: function(/*String*/ html){
+			// summary:
+			//		over-ride of replaceValue to support custom undo and stack maintainence.
+			// tags:
+			//		protected
+			if(!this.customUndo){
+				this.inherited(arguments);
+			}else{
+				if(this.isClosed){
+					this.setValue(html);
+				}else{
+					this.beginEditing();
+					if(!html){
+						html = " "
+					}
+					this.setValue(html);
+					this.endEditing();
+				}
+			}
+		},
+		
 		_setDisabledAttr: function(/*Boolean*/ value){
-			if(!this.disabled && value){
+			var disableFunc = dojo.hitch(this, function(){
+				if((!this.disabled && value) || (!this._buttonEnabledPlugins && value)){
 				// Disable editor: disable all enabled buttons and remember that list
-				this._buttonEnabledPlugins = dojo.filter(this._plugins, function(p){
-					if (p && p.button && !p.button.get("disabled")) {
-						p.button.set("disabled", true);
-						return true;
-					}
-					return false;
+					dojo.forEach(this._plugins, function(p){
+						p.set("disabled", true);
 				});
 			}else if(this.disabled && !value){
-				// Enable editor: we only want to enable the buttons that should be
-				// enabled (for example, the outdent button shouldn't be enabled if the current
-				// text can't be outdented).
-				dojo.forEach(this._buttonEnabledPlugins, function(p){
-					p.button.attr("disabled", false);
-					p.updateState && p.updateState();	// just in case something changed, like caret position
+					// Restore plugins to being active.
+					dojo.forEach(this._plugins, function(p){
+						p.set("disabled", false);
 				});
 			}
-			
+			});
+			this.setValueDeferred.addCallback(disableFunc);
 			this.inherited(arguments);
 		},
 		
 		_setStateClass: function(){
-			this.inherited(arguments);
+			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"));
-			}
+				// 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"));
+				}
+			}catch(e){ /* Squelch any errors caused by focus change if hidden during a state change */}
 		}
 	}
 );
@@ -752,3 +770,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 //	console.log('name',name,p);
 	o.plugin=p;
 });
+
+
+return dijit.Editor;
+});
diff --git a/dijit/InlineEditBox.js b/dijit/InlineEditBox.js
index 6413676..38a8e7b 100644
--- a/dijit/InlineEditBox.js
+++ b/dijit/InlineEditBox.js
@@ -1,13 +1,4 @@
-dojo.provide("dijit.InlineEditBox");
-
-dojo.require("dojo.i18n");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Container");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.TextBox");
-
-dojo.requireLocalization("dijit", "common");
+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) {
 
 dojo.declare("dijit.InlineEditBox",
 	dijit._Widget,
@@ -52,12 +43,12 @@ dojo.declare("dijit.InlineEditBox",
 	//		rather than plain text (ex: `dijit.Editor`)
 	renderAsHtml: false,
 
-	// editor: String
-	//		Class name for Editor widget
+	// editor: String|Function
+	//		Class name (or reference to the Class) for Editor widget
 	editor: "dijit.form.TextBox",
 
-	// editorWrapper: String
-	//		Class name for widget that wraps the editor widget, displaying save/cancel
+	// editorWrapper: String|Function
+	//		Class name (or reference to the Class) for widget that wraps the editor widget, displaying save/cancel
 	//		buttons.
 	editorWrapper: "dijit._InlineEditor",
 
@@ -65,6 +56,10 @@ dojo.declare("dijit.InlineEditBox",
 	//		Set of parameters for editor, like {required: true}
 	editorParams: {},
 
+	// disabled: Boolean
+	//		If true, clicking the InlineEditBox to edit it will have no effect.
+	disabled: false,
+
 	onChange: function(value){
 		// summary:
 		//		Set this handler to be notified of changes to value.
@@ -147,7 +142,6 @@ dojo.declare("dijit.InlineEditBox",
 		// summary:
 		//		Hook to make set("disabled", ...) work.
 		//		Set disabled state of widget.
-		this.disabled = disabled;
 		dijit.setWaiState(this.domNode, "disabled", disabled);
 		if(disabled){
 			this.displayNode.removeAttribute("tabIndex");
@@ -155,6 +149,7 @@ dojo.declare("dijit.InlineEditBox",
 			this.displayNode.setAttribute("tabIndex", 0);
 		}
 		dojo.toggleClass(this.displayNode, "dijitInlineEditBoxDisplayModeDisabled", disabled);
+		this._set("disabled", disabled);
 	},
 
 	_onMouseOver: function(){
@@ -212,7 +207,7 @@ dojo.declare("dijit.InlineEditBox",
 			var placeholder = dojo.create("span", null, this.domNode, "before");
 
 			// Create the editor wrapper (the thing that holds the editor widget and the save/cancel buttons)
-			var ewc = dojo.getObject(this.editorWrapper);
+			var ewc = typeof this.editorWrapper == "string" ? dojo.getObject(this.editorWrapper) : this.editorWrapper;
 			this.wrapperWidget = new ewc({
 				value: this.value,
 				buttonSave: this.buttonSave,
@@ -226,6 +221,9 @@ dojo.declare("dijit.InlineEditBox",
 				save: dojo.hitch(this, "save"),
 				cancel: dojo.hitch(this, "cancel")
 			}, placeholder);
+			if(!this._started){
+				this.startup();
+			}
 		}
 		var ww = this.wrapperWidget;
 
@@ -271,7 +269,7 @@ dojo.declare("dijit.InlineEditBox",
 	},
 
 	destroy: function(){
-		if(this.wrapperWidget){
+		if(this.wrapperWidget && !this.wrapperWidget._destroyed){
 			this.wrapperWidget.destroy();
 			delete this.wrapperWidget;
 		}
@@ -308,9 +306,6 @@ dojo.declare("dijit.InlineEditBox",
 		var value = ww.getValue();
 		this.set('value', value); // display changed, formatted value
 
-		// tell the world that we have changed
-		setTimeout(dojo.hitch(this, "onChange", value), 0); // setTimeout prevents browser freeze for long-running event handlers
-
 		this._showText(focus); // set focus as needed
 	},
 
@@ -328,11 +323,15 @@ 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.
 
-		this.value = val = dojo.trim(val);
-		if(!this.renderAsHtml){
-			val = val.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """).replace(/\n/g, "<br>");
+		val = dojo.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
 		}
-		this.displayNode.innerHTML = val || this.noValueIndicator;
 	},
 
 	getValue: function(){
@@ -388,9 +387,11 @@ dojo.declare(
 		}, this);
 	},
 
-	postCreate: function(){
+	buildRendering: function(){
+		this.inherited(arguments);
+
 		// Create edit widget in place in the template
-		var cls = dojo.getObject(this.editor);
+		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.
@@ -425,13 +426,21 @@ dojo.declare(
 			lang: this.lang
 		});
 		editorParams[ "displayedValue" in cls.prototype ? "displayedValue" : "value"] = this.value;
-		var ew = (this.editWidget = new cls(editorParams, this.editorPlaceholder));
+		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");
 
@@ -441,7 +450,7 @@ dojo.declare(
 			this.connect(ew, "onKeyPress", "_onKeyPress");
 		}else{
 			// If possible, enable/disable save button based on whether the user has changed the value
-			if("intermediateChanges" in cls.prototype){
+			if("intermediateChanges" in ew){
 				ew.set("intermediateChanges", true);
 				this.connect(ew, "onChange", "_onIntermediateChange");
 				this.saveButton.set("disabled", true);
@@ -560,3 +569,7 @@ dojo.declare(
 		}), 0);
 	}
 });
+
+
+return dijit.InlineEditBox;
+});
diff --git a/dijit/LICENSE b/dijit/LICENSE
index 4c93ded..aa6b39f 100644
--- a/dijit/LICENSE
+++ b/dijit/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2010, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/dijit/Menu.js b/dijit/Menu.js
index 299c8de..1e2e7e9 100644
--- a/dijit/Menu.js
+++ b/dijit/Menu.js
@@ -1,10 +1,6 @@
-dojo.provide("dijit.Menu");
+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) {
 
-dojo.require("dojo.window");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._KeyNavContainer");
-dojo.require("dijit._Templated");
+// "dijit/MenuItem", "dijit/PopupMenuItem", "dijit/CheckedMenuItem", "dijit/MenuSeparator" for Back-compat (TODO: remove in 2.0)
 
 dojo.declare("dijit._MenuBase",
 	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
@@ -282,8 +278,7 @@ dojo.declare("dijit._MenuBase",
 		//		menus (similar to TAB navigation) but the menu is not active
 		//		(ie no dropdown) until an item is clicked.
 		this.isActive = true;
-		dojo.addClass(this.domNode, "dijitMenuActive");
-		dojo.removeClass(this.domNode, "dijitMenuPassive");
+		dojo.replaceClass(this.domNode, "dijitMenuActive", "dijitMenuPassive");
 	},
 
 	onOpen: function(/*Event*/ e){
@@ -302,8 +297,7 @@ dojo.declare("dijit._MenuBase",
 		// 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.removeClass(this.domNode, "dijitMenuActive");
-		dojo.addClass(this.domNode, "dijitMenuPassive");
+		dojo.replaceClass(this.domNode, "dijitMenuPassive", "dijitMenuActive");
 	},
 
 	onClose: function(){
@@ -326,16 +320,25 @@ dojo.declare("dijit._MenuBase",
 		// tags:
 		//		private
 		this._stopPopupTimer();
-		if(this.focusedChild){ // unhighlight the focused item
-			this.focusedChild._setSelected(false);
-			this.focusedChild._onUnhover();
-			this.focusedChild = null;
-		}
+
+		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){
@@ -413,7 +416,7 @@ dojo.declare("dijit.Menu",
 			this.bindDomNode(dojo.body());
 		}else{
 			// TODO: should have _setTargetNodeIds() method to handle initialization and a possible
-			// later attr('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);
 		}
@@ -526,7 +529,7 @@ dojo.declare("dijit.Menu",
 						this._scheduleOpen(evt.target, iframe);	// no coords - open near target node
 					}
 				})
-			];	
+			];
 		});
 		binding.connects = cn ? doConnects(cn) : [];
 
@@ -692,9 +695,5 @@ dojo.declare("dijit.Menu",
 }
 );
 
-// Back-compat (TODO: remove in 2.0)
-dojo.require("dijit.MenuItem");
-dojo.require("dijit.PopupMenuItem");
-dojo.require("dijit.CheckedMenuItem");
-dojo.require("dijit.MenuSeparator");
-
+return dijit.Menu;
+});
diff --git a/dijit/MenuBar.js b/dijit/MenuBar.js
index 65a0833..20c8e0e 100644
--- a/dijit/MenuBar.js
+++ b/dijit/MenuBar.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.MenuBar");
-
-dojo.require("dijit.Menu");
+define("dijit/MenuBar", ["dojo", "dijit", "text!dijit/templates/MenuBar.html", "dijit/Menu"], function(dojo, dijit) {
 
 dojo.declare("dijit.MenuBar", dijit._MenuBase, {
 	// summary:
@@ -64,3 +62,7 @@ dojo.declare("dijit.MenuBar", dijit._MenuBase, {
 		}
 	}
 });
+
+
+return dijit.MenuBar;
+});
diff --git a/dijit/MenuBarItem.js b/dijit/MenuBarItem.js
index d32c2fd..c0c7b6f 100644
--- a/dijit/MenuBarItem.js
+++ b/dijit/MenuBarItem.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.MenuBarItem");
-
-dojo.require("dijit.MenuItem");
+define("dijit/MenuBarItem", ["dojo", "dijit", "text!dijit/templates/MenuBarItem.html", "dijit/MenuItem"], function(dojo, dijit) {
 
 dojo.declare("dijit._MenuBarItemMixin", null, {
 	templateString: dojo.cache("dijit", "templates/MenuBarItem.html"),
@@ -15,4 +13,8 @@ dojo.declare("dijit.MenuBarItem", [dijit.MenuItem, dijit._MenuBarItemMixin], {
 	// summary:
 	//		Item in a MenuBar that's clickable, and doesn't spawn a submenu when pressed (or hovered)
 
-});
\ No newline at end of file
+});
+
+
+return dijit.MenuBarItem;
+});
diff --git a/dijit/MenuItem.js b/dijit/MenuItem.js
index 044d0dc..0b99098 100644
--- a/dijit/MenuItem.js
+++ b/dijit/MenuItem.js
@@ -1,9 +1,4 @@
-dojo.provide("dijit.MenuItem");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Contained");
-dojo.require("dijit._CssStateMixin");
+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],
@@ -50,9 +45,8 @@ dojo.declare("dijit.MenuItem",
 			}
 		},
 
-		postCreate: function(){
+		buildRendering: function(){
 			this.inherited(arguments);
-			dojo.setSelectable(this.domNode, false);
 			var label = this.id+"_text";
 			dojo.attr(this.containerNode, "id", label);
 			if(this.accelKeyNode){
@@ -60,6 +54,7 @@ dojo.declare("dijit.MenuItem",
 				label += " " + this.id + "_accel";
 			}
 			dijit.setWaiState(this.domNode, "labelledby", label);
+			dojo.setSelectable(this.domNode, false);
 		},
 
 		_onHover: function(){
@@ -82,11 +77,10 @@ dojo.declare("dijit.MenuItem",
 			// then unselect it
 			this.getParent().onItemUnhover(this);
 
-			// _onUnhover() is called when the menu is hidden (collapsed), due to clicking
-			// a MenuItem and having it execut.  When that happens, FF and IE don't generate
-			// an onmouseout event for the MenuItem, so give _CssStateMixin some help
-			this._hovering = false;
-			this._setStateClass();
+			// When menu is hidden (collapsed) due to clicking a MenuItem and having it execute,
+			// FF and IE don't generate an onmouseout event for the MenuItem.
+			// So, help out _CssStateMixin in this case.
+			this._set("hovering", false);
 		},
 
 		_onClick: function(evt){
@@ -171,18 +165,24 @@ dojo.declare("dijit.MenuItem",
 			// summary:
 			//		Hook for attr('disabled', ...) to work.
 			//		Enable or disable this menu item.
-			this.disabled = value;
+
 			dijit.setWaiState(this.focusNode, 'disabled', value ? 'true' : 'false');
+			this._set("disabled", value);
 		},
 		_setAccelKeyAttr: function(/*String*/ value){
 			// summary:
 			//		Hook for attr('accelKey', ...) to work.
 			//		Set accelKey on this menu item.
-			this.accelKey=value;
 
 			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");
+			
+			this._set("accelKey", value);
 		}
 	});
+
+
+return dijit.MenuItem;
+});
diff --git a/dijit/MenuSeparator.js b/dijit/MenuSeparator.js
index 3acd1a9..5dbe665 100644
--- a/dijit/MenuSeparator.js
+++ b/dijit/MenuSeparator.js
@@ -1,8 +1,4 @@
-dojo.provide("dijit.MenuSeparator");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Contained");
+define("dijit/MenuSeparator", ["dojo", "dijit", "text!dijit/templates/MenuSeparator.html", "dijit/_Widget", "dijit/_Templated", "dijit/_Contained"], function(dojo, dijit) {
 
 dojo.declare("dijit.MenuSeparator",
 		[dijit._Widget, dijit._Templated, dijit._Contained],
@@ -12,7 +8,8 @@ dojo.declare("dijit.MenuSeparator",
 
 		templateString: dojo.cache("dijit", "templates/MenuSeparator.html"),
 
-		postCreate: function(){
+		buildRendering: function(){
+			this.inherited(arguments);
 			dojo.setSelectable(this.domNode, false);
 		},
 
@@ -26,3 +23,6 @@ dojo.declare("dijit.MenuSeparator",
 		}
 	});
 
+
+return dijit.MenuSeparator;
+});
diff --git a/dijit/PopupMenuBarItem.js b/dijit/PopupMenuBarItem.js
index e8fe6f9..dd63b08 100644
--- a/dijit/PopupMenuBarItem.js
+++ b/dijit/PopupMenuBarItem.js
@@ -1,10 +1,10 @@
-dojo.provide("dijit.PopupMenuBarItem");
-
-dojo.require("dijit.PopupMenuItem");
-dojo.require("dijit.MenuBarItem");
+define("dijit/PopupMenuBarItem", ["dojo", "dijit", "dijit/PopupMenuItem", "dijit/MenuBarItem"], function(dojo, dijit) {
 
 dojo.declare("dijit.PopupMenuBarItem", [dijit.PopupMenuItem, dijit._MenuBarItemMixin], {
 	// summary:
 	//		Item in a MenuBar like "File" or "Edit", that spawns a submenu when pressed (or hovered)
 });
 
+
+return dijit.PopupMenuBarItem;
+});
diff --git a/dijit/PopupMenuItem.js b/dijit/PopupMenuItem.js
index 3e65ed1..a231fe7 100644
--- a/dijit/PopupMenuItem.js
+++ b/dijit/PopupMenuItem.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.PopupMenuItem");
-
-dojo.require("dijit.MenuItem");
+define("dijit/PopupMenuItem", ["dojo", "dijit", "dijit/MenuItem"], function(dojo, dijit) {
 
 dojo.declare("dijit.PopupMenuItem",
 		dijit.MenuItem,
@@ -62,3 +60,6 @@ dojo.declare("dijit.PopupMenuItem",
 		}
 	});
 
+
+return dijit.PopupMenuItem;
+});
diff --git a/dijit/ProgressBar.js b/dijit/ProgressBar.js
index a90fff0..87a0bbe 100644
--- a/dijit/ProgressBar.js
+++ b/dijit/ProgressBar.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit.ProgressBar");
-
-dojo.require("dojo.fx");
-dojo.require("dojo.number");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+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], {
 	// summary:
@@ -14,20 +8,21 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 	// example:
 	// |	<div dojoType="ProgressBar"
 	// |		 places="0"
-	// |		 progress="..." maximum="...">
+	// |		 value="..." maximum="...">
 	// |	</div>
-	//
-	// description:
-	//		Note that the progress bar is updated via (a non-standard)
-	//		update() method, rather than via attr() like other widgets.
 
 	// progress: [const] String (Percentage or Number)
 	//		Number or percentage indicating amount of task completed.
-	// 		With "%": percentage value, 0% <= progress <= 100%, or
-	// 		without "%": absolute value, 0 <= progress <= maximum
-	// TODO: rename to value for 2.0
+	// 		Deprecated.   Use "value" instead.
 	progress: "0",
 
+	// value: String (Percentage or Number)
+	//		Number or percentage indicating amount of task completed.
+	// 		With "%": percentage value, 0% <= progress <= 100%, or
+	// 		without "%": absolute value, 0 <= progress <= maximum.
+	//		Infinity means that the progress bar is indeterminate.
+	value: "",
+
 	// maximum: [const] Float
 	//		Max sample number
 	maximum: 100,
@@ -39,8 +34,14 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 	// indeterminate: [const] Boolean
 	// 		If false: show progress value (number or percentage).
 	// 		If true: show that a process is underway but that the amount completed is unknown.
+	// 		Deprecated.   Use "value" instead.
 	indeterminate: false,
 
+	// label: String?
+	//		Label on progress bar.   Defaults to percentage for determinate progress bar and
+	//		blank for indeterminate progress bar.
+	label:"",
+
 	// name: String
 	//		this is the field name (for a form) if set. This needs to be set if you want to use
 	//		this widget in a dijit.form.Form widget (such as dijit.Dialog)
@@ -53,8 +54,14 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 	_indeterminateHighContrastImagePath:
 		dojo.moduleUrl("dijit", "themes/a11y/indeterminate_progress.gif"),
 
-	// public functions
-	postCreate: function(){
+	postMixInProperties: function(){
+		this.inherited(arguments);
+		if(!("value" in this.params)){
+			this.value = this.indeterminate ? Infinity : this.progress;
+		}
+	},
+
+	buildRendering: function(){
 		this.inherited(arguments);
 		this.indeterminateHighContrastImage.setAttribute("src",
 			this._indeterminateHighContrastImagePath.toString());
@@ -63,28 +70,28 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 
 	update: function(/*Object?*/attributes){
 		// summary:
-		//		Change attributes of ProgressBar, similar to attr(hash).
-		//
+		//		Internal method to change attributes of ProgressBar, similar to set(hash).  Users should call
+		//		set("value", ...) rather than calling this method directly.
 		// attributes:
 		//		May provide progress and/or maximum properties on this parameter;
 		//		see attribute specs for details.
-		//
 		// example:
 		//	|	myProgressBar.update({'indeterminate': true});
 		//	|	myProgressBar.update({'progress': 80});
+		//	|	myProgressBar.update({'indeterminate': true, label:"Loading ..." })
+		// tags:
+		//		private
 
 		// TODO: deprecate this method and use set() instead
 
 		dojo.mixin(this, attributes || {});
-		var tip = this.internalProgress;
-		var percent = 1, classFunc;
+		var tip = this.internalProgress, ap = this.domNode;
+		var percent = 1;
 		if(this.indeterminate){
-			classFunc = "addClass";
-			dijit.removeWaiState(tip, "valuenow");
-			dijit.removeWaiState(tip, "valuemin");
-			dijit.removeWaiState(tip, "valuemax");
+			dijit.removeWaiState(ap, "valuenow");
+			dijit.removeWaiState(ap, "valuemin");
+			dijit.removeWaiState(ap, "valuemax");
 		}else{
-			classFunc = "removeClass";
 			if(String(this.progress).indexOf("%") != -1){
 				percent = Math.min(parseFloat(this.progress)/100, 1);
 				this.progress = percent * this.maximum;
@@ -92,19 +99,21 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 				this.progress = Math.min(this.progress, this.maximum);
 				percent = this.progress / this.maximum;
 			}
-			var text = this.report(percent);
-			this.label.firstChild.nodeValue = text;
-			dijit.setWaiState(tip, "describedby", this.label.id);
-			dijit.setWaiState(tip, "valuenow", this.progress);
-			dijit.setWaiState(tip, "valuemin", 0);
-			dijit.setWaiState(tip, "valuemax", this.maximum);
+
+			dijit.setWaiState(ap, "describedby", this.labelNode.id);
+			dijit.setWaiState(ap, "valuenow", this.progress);
+			dijit.setWaiState(ap, "valuemin", 0);
+			dijit.setWaiState(ap, "valuemax", this.maximum);
 		}
-		dojo[classFunc](this.domNode, "dijitProgressBarIndeterminate");
+		this.labelNode.innerHTML = this.report(percent);
+
+		dojo.toggleClass(this.domNode, "dijitProgressBarIndeterminate", this.indeterminate);
 		tip.style.width = (percent * 100) + "%";
 		this.onChange();
 	},
 
 	_setValueAttr: function(v){
+		this._set("value", v);
 		if(v == Infinity){
 			this.update({indeterminate:true});
 		}else{
@@ -112,8 +121,15 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 		}
 	},
 
-	_getValueAttr: function(){
-		return this.progress;
+	_setLabelAttr: function(label){
+		this._set("label", label);
+		this.update();
+	},
+
+	_setIndeterminateAttr: function(indeterminate){
+		// Deprecated, use set("value", ...) instead
+		this.indeterminate = indeterminate;
+		this.update();
 	},
 
 	report: function(/*float*/percent){
@@ -123,13 +139,18 @@ dojo.declare("dijit.ProgressBar", [dijit._Widget, dijit._Templated], {
 		// tags:
 		//		extension
 
-		return dojo.number.format(percent, { type: "percent", places: this.places, locale: this.lang });
+		return this.label ? this.label :
+				(this.indeterminate ? " " : dojo.number.format(percent, { type: "percent", places: this.places, locale: this.lang }));
 	},
 
 	onChange: function(){
 		// summary:
 		//		Callback fired when progress updates.
 		// tags:
-		//		progress
+		//		extension
 	}
 });
+
+
+return dijit.ProgressBar;
+});
diff --git a/dijit/TitlePane.js b/dijit/TitlePane.js
index 46899eb..7605628 100644
--- a/dijit/TitlePane.js
+++ b/dijit/TitlePane.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit.TitlePane");
-
-dojo.require("dojo.fx");
-
-dojo.require("dijit._Templated");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit._CssStateMixin");
+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",
@@ -66,10 +60,13 @@ dojo.declare(
 		id:""
 	}),
 
+	buildRendering: function(){
+		this.inherited(arguments);
+		dojo.setSelectable(this.titleNode, false);
+	},
+
 	postCreate: function(){
-		if(!this.open){
-			this.hideNode.style.display = this.wipeNode.style.display = "none";
-		}
+		this.inherited(arguments);
 		
 		// Hover and focus effect on title bar, except for non-toggleable TitlePanes
 		// This should really be controlled from _setToggleableAttr() but _CssStateMixin
@@ -77,8 +74,6 @@ dojo.declare(
 		if(this.toggleable){
 			this._trackMouseState(this.titleBarNode, "dijitTitlePaneTitle");
 		}
-		this._setCss();
-		dojo.setSelectable(this.titleNode, false);
 
 		// setup open/close animations
 		var hideNode = this.hideNode, wipeNode = this.wipeNode;
@@ -96,40 +91,70 @@ dojo.declare(
 				hideNode.style.display="none";
 			}
 		});
-		this.inherited(arguments);
 	},
 
-	_setOpenAttr: function(/* Boolean */ open){
+	_setOpenAttr: function(/*Boolean*/ open, /*Boolean*/ animate){
 		// summary:
-		//		Hook to make attr("open", boolean) control the open/closed state of the pane.
+		//		Hook to make set("open", boolean) control the open/closed state of the pane.
 		// open: Boolean
 		//		True if you want to open the pane, false if you want to close it.
-		if(this.open !== open){ this.toggle(); }
-		dijit.setWaiState(this.containerNode,"hidden", this.open ? "false" : "true");
-		dijit.setWaiState(this.focusNode, "pressed", this.open ? "true" : "false");
+
+		dojo.forEach([this._wipeIn, this._wipeOut], function(animation){
+			if(animation && animation.status() == "playing"){
+				animation.stop();
+			}
+		});
+
+		if(animate){
+			var anim = this[open ? "_wipeIn" : "_wipeOut"];
+			anim.play();
+		}else{
+			this.hideNode.style.display = this.wipeNode.style.display = open ? "" : "none";
+		}
+
+		// load content (if this is the first time we are opening the TitlePane
+		// and content is specified as an href, or href was set when hidden)
+		if(this._started){
+			if(open){
+				this._onShow();
+			}else{
+				this.onHide();
+			}
+		}
+
+		this.arrowNodeInner.innerHTML = open ? "-" : "+";
+
+		dijit.setWaiState(this.containerNode,"hidden", open ? "false" : "true");
+		dijit.setWaiState(this.focusNode, "pressed", open ? "true" : "false");
+
+		this._set("open", open);
+
+		this._setCss();
 	},
 
-	_setToggleableAttr: function(/* Boolean */ canToggle){
+	_setToggleableAttr: function(/*Boolean*/ canToggle){
 		// summary:
-		//		Hook to make attr("canToggle", boolean) work.
+		//		Hook to make set("toggleable", boolean) work.
 		// canToggle: Boolean
 		//		True to allow user to open/close pane by clicking title bar.
-		this.toggleable = canToggle;
+
 		dijit.setWaiRole(this.focusNode, canToggle ? "button" : "heading");
 		if(canToggle){
-			// TODO: if canToggle is switched from true false shouldn't we remove this setting?
+			// 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);
-		}
-		else{
+		}else{
 			dojo.removeAttr(this.focusNode, "tabIndex");
 		}
+
+		this._set("toggleable", canToggle);
+
 		this._setCss();
 	},
 
-	_setContentAttr: function(content){
+	_setContentAttr: function(/*String|DomNode|Nodelist*/ content){
 		// summary:
-		//		Hook to make attr("content", ...) work.
+		//		Hook to make set("content", ...) work.
 		// 		Typically called when an href is loaded.  Our job is to make the animation smooth.
 
 		if(!this.open || !this._wipeOut || this._wipeOut.status() == "playing"){
@@ -161,29 +186,7 @@ dojo.declare(
 		// tags:
 		//		private
 
-		dojo.forEach([this._wipeIn, this._wipeOut], function(animation){
-			if(animation && animation.status() == "playing"){
-				animation.stop();
-			}
-		});
-
-		var anim = this[this.open ? "_wipeOut" : "_wipeIn"]
-		if(anim){
-			anim.play();
-		}else{
-			this.hideNode.style.display = this.open ? "" : "none";
-		}
-		this.open =! this.open;
-
-		// load content (if this is the first time we are opening the TitlePane
-		// and content is specified as an href, or href was set when hidden)
-		if(this.open){
-			this._onShow();
-		}else{
-			this.onHide();
-		}
-
-		this._setCss();
+		this._setOpenAttr(!this.open, true);
 	},
 
 	_setCss: function(){
@@ -193,12 +196,10 @@ dojo.declare(
 		//		private
 
 		var node = this.titleBarNode || this.focusNode;
-
-		if(this._titleBarClass){
-			dojo.removeClass(node, this._titleBarClass);
-		}
+		var oldCls = this._titleBarClass;
 		this._titleBarClass = "dijit" + (this.toggleable ? "" : "Fixed") + (this.open ? "Open" : "Closed");
-		dojo.addClass(node, this._titleBarClass);
+		dojo.replaceClass(node, this._titleBarClass, oldCls || "");
+
 		this.arrowNodeInner.innerHTML = this.open ? "-" : "+";
 	},
 
@@ -238,3 +239,7 @@ dojo.declare(
 		this.set("title", title);
 	}
 });
+
+
+return dijit.TitlePane;
+});
diff --git a/dijit/Toolbar.js b/dijit/Toolbar.js
index 8099b44..fb074f4 100644
--- a/dijit/Toolbar.js
+++ b/dijit/Toolbar.js
@@ -1,8 +1,6 @@
-dojo.provide("dijit.Toolbar");
+define("dijit/Toolbar", ["dojo", "dijit", "dijit/_Widget", "dijit/_KeyNavContainer", "dijit/_Templated", "dijit/ToolbarSeparator"], function(dojo, dijit) {
 
-dojo.require("dijit._Widget");
-dojo.require("dijit._KeyNavContainer");
-dojo.require("dijit._Templated");
+// Note: require of ToolbarSeparator is for back-compat, remove for 2.0
 
 dojo.declare("dijit.Toolbar",
 	[dijit._Widget, dijit._Templated, dijit._KeyNavContainer],
@@ -11,7 +9,7 @@ dojo.declare("dijit.Toolbar",
 	//		A Toolbar widget, used to hold things like `dijit.Editor` buttons
 
 	templateString:
-		'<div class="dijit" waiRole="toolbar" tabIndex="${tabIndex}" dojoAttachPoint="containerNode">' +
+		'<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>' +
@@ -20,11 +18,12 @@ dojo.declare("dijit.Toolbar",
 	baseClass: "dijitToolbar",
 
 	postCreate: function(){
+		this.inherited(arguments);
+
 		this.connectKeyNavHandlers(
 			this.isLeftToRight() ? [dojo.keys.LEFT_ARROW] : [dojo.keys.RIGHT_ARROW],
 			this.isLeftToRight() ? [dojo.keys.RIGHT_ARROW] : [dojo.keys.LEFT_ARROW]
 		);
-		this.inherited(arguments);
 	},
 
 	startup: function(){
@@ -37,5 +36,5 @@ dojo.declare("dijit.Toolbar",
 }
 );
 
-// For back-compat, remove for 2.0
-dojo.require("dijit.ToolbarSeparator");
+return dijit.Toolbar;
+});
diff --git a/dijit/ToolbarSeparator.js b/dijit/ToolbarSeparator.js
index 987bbee..65817ac 100644
--- a/dijit/ToolbarSeparator.js
+++ b/dijit/ToolbarSeparator.js
@@ -1,15 +1,15 @@
-dojo.provide("dijit.ToolbarSeparator");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+define("dijit/ToolbarSeparator", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare("dijit.ToolbarSeparator",
 		[ dijit._Widget, dijit._Templated ],
 		{
 		// summary:
 		//		A spacer between two `dijit.Toolbar` items
-		templateString: '<div class="dijitToolbarSeparator dijitInline" waiRole="presentation"></div>',
-		postCreate: function(){ dojo.setSelectable(this.domNode, false); },
+		templateString: '<div class="dijitToolbarSeparator dijitInline" role="presentation"></div>',
+		buildRendering: function(){
+			this.inherited(arguments);
+			dojo.setSelectable(this.domNode, false);
+		},
 		isFocusable: function(){
 			// summary:
 			//		This widget isn't focusable, so pass along that fact.
@@ -21,3 +21,5 @@ dojo.declare("dijit.ToolbarSeparator",
 	});
 
 
+return dijit.ToolbarSeparator;
+});
diff --git a/dijit/Tooltip.js b/dijit/Tooltip.js
index 17db535..04fb493 100644
--- a/dijit/Tooltip.js
+++ b/dijit/Tooltip.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.Tooltip");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+define("dijit/Tooltip", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit._MasterTooltip",
@@ -29,7 +26,6 @@ dojo.declare(
 			// 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") });
-
 		},
 
 		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position, /*Boolean*/ rtl){
@@ -41,6 +37,9 @@ dojo.declare(
 				return;
 			}
 
+			// reset width; it may have been set by orient() on a previous tooltip show()
+			this.domNode.width = "auto";
+
 			if(this.fadeOut.status() == "playing"){
 				// previous tooltip is being hidden; wait until the hide completes then show new one
 				this._onDeck=arguments;
@@ -57,12 +56,17 @@ dojo.declare(
 			this.aroundNode = aroundNode;
 		},
 
-		orient: function(/* DomNode */ node, /* String */ aroundCorner, /* String */ tooltipCorner){
+		orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ tooltipCorner, /*Object*/ spaceAvailable, /*Object*/ aroundNodeCoords){
 			// summary:
 			//		Private function to set CSS for tooltip node based on which position it's in.
-			//		This is called by the dijit popup code.
+			//		This is called by the dijit popup code.   It will also reduce the tooltip's
+			//		width to whatever width is available
 			// tags:
 			//		protected
+			this.connectorNode.style.top = ""; //reset to default
+			
+			//Adjust the spaceAvailable width, without changing the spaceAvailable object
+			var tooltipSpaceAvaliableWidth = spaceAvailable.w - this.connectorNode.offsetWidth;
 
 			node.className = "dijitTooltip " +
 				{
@@ -73,6 +77,52 @@ 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 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");
+					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 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);
+					this.connectorNode.style.top = aroundNodePlacement + "px";
+					this.connectorNode.style.bottom = "";
+				}else{
+					// Align center of connector with center of aroundNode, except don't let bottom
+					// of connector extend below bottom of tooltip content, or top of connector
+					// extend past top of tooltip content
+					this.connectorNode.style.bottom = Math.min(
+						Math.max(aroundNodeCoords.h/2 - tooltipConnectorHeight/2, 0),
+						mb.h - tooltipConnectorHeight) + "px";
+					this.connectorNode.style.top = "";
+				}
+			}else{
+				// reset the tooltip back to the defaults
+				this.connectorNode.style.top = "";
+				this.connectorNode.style.bottom = "";
+			}
+			
+			return Math.max(0, size.w - tooltipSpaceAvaliableWidth);
 		},
 
 		_onShow: function(){
@@ -89,6 +139,7 @@ dojo.declare(
 		hide: function(aroundNode){
 			// summary:
 			//		Hide the tooltip
+
 			if(this._onDeck && this._onDeck[1] == aroundNode){
 				// this hide request is for a show() that hasn't even started yet;
 				// just cancel the pending show()
@@ -155,69 +206,70 @@ dojo.declare(
 		//		the tooltip is displayed.
 		showDelay: 400,
 
-		// connectId: [const] String[]
-		//		Id's of domNodes to attach the tooltip to.
-		//		When user hovers over any of the specified dom nodes, the tooltip will appear.
-		//
-		//		Note: Currently connectId can only be specified on initialization, it cannot
-		//		be changed via attr('connectId', ...)
-		//
-		//		Note: in 2.0 this will be renamed to connectIds for less confusion.
+		// connectId: String|String[]
+		//		Id of domNode(s) to attach the tooltip to.
+		//		When user hovers over specified dom node, the tooltip will appear.
 		connectId: [],
 
 		// position: String[]
 		//		See description of `dijit.Tooltip.defaultPosition` for details on position parameter.
 		position: [],
 
-		constructor: function(){
-			// Map id's of nodes I'm connected to to a list of the this.connect() handles
-			this._nodeConnectionsById = {};
+		_setConnectIdAttr: function(/*String*/ newId){
+			// summary:
+			//		Connect to node(s) (specified by id)
+
+			// Remove connections to old nodes (if there are any)
+			dojo.forEach(this._connections || [], function(nested){
+				dojo.forEach(nested, dojo.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")
+				] : [];
+			}, this);
+	
+			this._set("connectId", newId);
+
+			this._connectIds = ary;	// save as array
 		},
 
-		_setConnectIdAttr: function(newIds){
-			for(var oldId in this._nodeConnectionsById){
-				this.removeTarget(oldId);
-			}
-			dojo.forEach(dojo.isArrayLike(newIds) ? newIds : [newIds], this.addTarget, this);
-		},
+		addTarget: function(/*DOMNODE || String*/ node){
+			// summary:
+			//		Attach tooltip to specified node if it's not already connected
 
-		_getConnectIdAttr: function(){
-			var ary = [];
-			for(var id in this._nodeConnectionsById){
-				ary.push(id);
-			}
-			return ary;
-		},
+			// TODO: remove in 2.0 and just use set("connectId", ...) interface
 
-		addTarget: function(/*DOMNODE || String*/ id){
-			// summary:
-			//		Attach tooltip to specified node, if it's not already connected
-			var node = dojo.byId(id);
-			if(!node){ return; }
-			if(node.id in this._nodeConnectionsById){ return; }//Already connected
-
-			this._nodeConnectionsById[node.id] = [
-				this.connect(node, "onmouseenter", "_onTargetMouseEnter"),
-				this.connect(node, "onmouseleave", "_onTargetMouseLeave"),
-				this.connect(node, "onfocus", "_onTargetFocus"),
-				this.connect(node, "onblur", "_onTargetBlur")
-			];
+			var id = node.id || node;
+			if(dojo.indexOf(this._connectIds, id) == -1){
+				this.set("connectId", this._connectIds.concat(id));
+			}
 		},
 
 		removeTarget: function(/*DOMNODE || String*/ node){
 			// summary:
 			//		Detach tooltip from specified node
 
-			// map from DOMNode back to plain id string
-			var id = node.id || node;
-
-			if(id in this._nodeConnectionsById){
-				dojo.forEach(this._nodeConnectionsById[id], this.disconnect, this);
-				delete this._nodeConnectionsById[id];
+			// 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);
+			if(idx >= 0){
+				// remove id (modifies original this._connectIds but that's OK in this case)
+				this._connectIds.splice(idx, 1);
+				this.set("connectId", this._connectIds);
 			}
 		},
 
-		postCreate: function(){
+		buildRendering: function(){
+			this.inherited(arguments);
 			dojo.addClass(this.domNode,"dijitTooltipData");
 		},
 
@@ -372,3 +424,7 @@ dojo.declare(
 //		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;
+});
diff --git a/dijit/TooltipDialog.js b/dijit/TooltipDialog.js
index 60ea483..7ca8e28 100644
--- a/dijit/TooltipDialog.js
+++ b/dijit/TooltipDialog.js
@@ -1,9 +1,4 @@
-dojo.provide("dijit.TooltipDialog");
-
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit._Templated");
-dojo.require("dijit.form._FormMixin");
-dojo.require("dijit._DialogMixin");
+define("dijit/TooltipDialog", ["dojo", "dijit", "text!dijit/templates/TooltipDialog.html", "dijit/layout/ContentPane", "dijit/_Templated", "dijit/form/_FormMixin", "dijit/_DialogMixin"], function(dojo, dijit) {
 
 dojo.declare(
 		"dijit.TooltipDialog",
@@ -45,10 +40,14 @@ dojo.declare(
 
 			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");
-				this.containerNode.title = this.title;
 			},
 
 			orient: function(/*DomNode*/ node, /*String*/ aroundCorner, /*String*/ corner){
@@ -58,13 +57,19 @@ dojo.declare(
 				//		directly.
 				// tags:
 				//		protected
-				var c = this._currentOrientClass;
-				if(c){
-					dojo.removeClass(this.domNode, c);
-				}
-				c = "dijitTooltipAB"+(corner.charAt(1) == 'L'?"Left":"Right")+" dijitTooltip"+(corner.charAt(0) == 'T' ? "Below" : "Above");
-				dojo.addClass(this.domNode, c);
-				this._currentOrientClass = c;
+				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
+				this._getFocusItems(this.containerNode);
+				dijit.focus(this._firstFocusItem);
 			},
 
 			onOpen: function(/*Object*/ pos){
@@ -76,11 +81,6 @@ dojo.declare(
 
 				this.orient(this.domNode,pos.aroundCorner, pos.corner);
 				this._onShow(); // lazy load trigger
-
-				if(this.autofocus){
-					this._getFocusItems(this.containerNode);
-					dijit.focus(this._firstFocusItem);
-				}
 			},
 
 			onClose: function(){
@@ -128,3 +128,7 @@ dojo.declare(
 			}
 		}
 	);
+
+
+return dijit.TooltipDialog;
+});
diff --git a/dijit/Tree.js b/dijit/Tree.js
index e402326..2dc6486 100644
--- a/dijit/Tree.js
+++ b/dijit/Tree.js
@@ -1,14 +1,4 @@
-dojo.provide("dijit.Tree");
-
-dojo.require("dojo.fx");
-dojo.require("dojo.DeferredList");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit._Contained");
-dojo.require("dijit._CssStateMixin");
-dojo.require("dojo.cookie");
+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) {
 
 dojo.declare(
 	"dijit._TreeNode",
@@ -20,7 +10,7 @@ dojo.declare(
 	// tags:
 	//		private
 
-	// item: dojo.data.Item
+	// item: [const] dojo.data.Item
 	//		the dojo.data entry this tree represents
 	item: null,
 
@@ -62,7 +52,7 @@ dojo.declare(
 		tooltip: {node: "rowNode", type: "attribute", attribute: "title"}
 	}),
 
-	postCreate: function(){
+	buildRendering: function(){
 		this.inherited(arguments);
 
 		// set expand icon for leaf
@@ -74,6 +64,9 @@ dojo.declare(
 		if(this.isExpandable){
 			dijit.setWaiState(this.labelNode, "expanded", this.isExpanded);
 		}
+
+		//aria-selected should be false on all selectable elements.
+		this.setSelected(false);
 	},
 
 	_setIndentAttr: function(indent){
@@ -82,7 +75,6 @@ dojo.declare(
 		// description:
 		//		0 for top level nodes, 1 for their children, 2 for their
 		//		grandchildren, etc.
-		this.indent = indent;
 
 		// Math.max() is to prevent negative padding on hidden root node (when indent == -1)
 		var pixels = (Math.max(indent, 0) * this.tree._nodePixelIndent) + "px";
@@ -93,6 +85,8 @@ dojo.declare(
 		dojo.forEach(this.getChildren(), function(child){
 			child.set("indent", indent+1);
 		});
+		
+		this._set("indent", indent);
 	},
 
 	markProcessing: function(){
@@ -146,14 +140,11 @@ dojo.declare(
 
 		var clsName = "_" + lower + "Class";
 		var nodeName = lower + "Node";
+		var oldCls = this[clsName];
 
-		if(this[clsName]){
-			dojo.removeClass(this[nodeName], this[clsName]);
- 		}
 		this[clsName] = this.tree["get" + upper + "Class"](item, this.isExpanded);
-		if(this[clsName]){
-			dojo.addClass(this[nodeName], this[clsName]);
- 		}
+		dojo.replaceClass(this[nodeName], this[clsName] || "", oldCls || "");
+ 
 		dojo.style(this[nodeName], this.tree["get" + upper + "Style"](item, this.isExpanded) || {});
  	},
 
@@ -183,8 +174,7 @@ dojo.declare(
 			idx = processing ? 0 : (this.isExpandable ?	(this.isExpanded ? 1 : 2) : 3);
 
 		// apply the appropriate class to the expando node
-		dojo.removeClass(this.expandoNode, styles);
-		dojo.addClass(this.expandoNode, styles[idx]);
+		dojo.replaceClass(this.expandoNode, styles[idx], styles);
 
 		// provide a non-image based indicator for images-off mode
 		this.expandoNodeText.innerHTML = _a11yStates[idx];
@@ -209,7 +199,9 @@ dojo.declare(
 		// set when the animation completes instead
 		this.isExpanded = true;
 		dijit.setWaiState(this.labelNode, "expanded", "true");
-		dijit.setWaiRole(this.containerNode, "group");
+		if(this.tree.showRoot || this !== this.tree.rootNode){
+			dijit.setWaiRole(this.containerNode, "group");
+		}
 		dojo.addClass(this.contentNode,'dijitTreeContentExpanded');
 		this._setExpando();
 		this._updateItemClasses(this.item);
@@ -371,6 +363,22 @@ dojo.declare(
 		return new dojo.DeferredList(defs);	// dojo.Deferred
 	},
 
+	getTreePath: function(){
+		var node = this;
+		var path = [];
+		while(node && node !== this.tree.rootNode){
+				path.unshift(node.item);
+				node = node.getParent();
+		}
+		path.unshift(this.tree.rootNode.item);
+
+		return path;
+	},
+
+	getIdentity: function() {
+		return this.tree.model.getIdentity(this.item);
+	},
+
 	removeChild: function(/* treeNode */ node){
 		this.inherited(arguments);
 
@@ -498,17 +506,25 @@ dojo.declare(
 	//		One ore more attributes that holds children of a tree node
 	childrenAttr: ["children"],
 
-	// path: String[] or Item[]
-	//		Full path from rootNode to selected node expressed as array of items or array of ids.
-	//		Since setting the path may be asynchronous (because ofwaiting on dojo.data), set("path", ...)
+	// paths: String[][] or Item[][]
+	//		Full paths from rootNode to selected nodes expressed as array of items or array of ids.
+	//		Since setting the paths may be asynchronous (because ofwaiting on dojo.data), set("paths", ...)
 	//		returns a Deferred to indicate when the set is complete.
+	paths: [],
+	
+	// path: String[] or Item[]
+	//      Backward compatible singular variant of paths.
 	path: [],
 
-	// selectedItem: [readonly] Item
-	//		The currently selected item in this tree.
-	//		This property can only be set (via set('selectedItem', ...)) when that item is already
+	// selectedItems: [readonly] Item[]
+	//		The currently selected items in this tree.
+	//		This property can only be set (via set('selectedItems', ...)) when that item is already
 	//		visible in the tree.   (I.e. the tree has already been expanded to show that node.)
-	//		Should generally use `path` attribute to set the selected item instead.
+	//		Should generally use `paths` attribute to set the selected items instead.
+	selectedItems: null,
+
+	// selectedItem: [readonly] Item
+	//      Backward compatible singular variant of selectedItems.
 	selectedItem: null,
 
 	// openOnClick: Boolean
@@ -526,13 +542,14 @@ dojo.declare(
 	persist: true,
 
 	// autoExpand: Boolean
-	//		Fully expand the tree on load.   Overrides `persist`
+	//		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".
-	dndController: null,
+	//      Default of "dijit.tree._dndSelector" handles selection only (no actual DnD).
+	dndController: "dijit.tree._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"],
@@ -750,6 +767,12 @@ dojo.declare(
 				}));
 				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.appendChild(rn.domNode);
 				var identity = this.model.getIdentity(item);
@@ -786,104 +809,103 @@ dojo.declare(
 	},
 
 	_setSelectedItemAttr: function(/*dojo.data.Item or id*/ item){
-		// summary:
-		//		Select a tree node related to passed item.
-		//		WARNING: if model use multi-parented items or desired tree node isn't already loaded
-		//		behavior is undefined. Use set('path', ...) instead.
-
-		var oldValue = this.get("selectedItem");
-		var identity = (!item || dojo.isString(item)) ? item : this.model.getIdentity(item);
-		if(identity == oldValue ? this.model.getIdentity(oldValue) : null){ return; }
-		var nodes = this._itemNodesMap[identity];
-		this._selectNode((nodes && nodes[0]) || null);	//select the first item
+		this.set('selectedItems', [item]);
 	},
 
-	_getSelectedItemAttr: function(){
+	_setSelectedItemsAttr: function(/*dojo.data.Items or ids*/ items){
 		// summary:
-		//		Return item related to selected tree node.
-		return this.selectedNode && this.selectedNode.item;
+		//		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);
+			});
+			var nodes = [];
+			dojo.forEach(identities, function(id){
+				nodes = nodes.concat(tree._itemNodesMap[id] || []);
+			});
+			this.set('selectedNodes', nodes);
+		}));
 	},
 
 	_setPathAttr: function(/*Item[] || String[]*/ path){
 		// summary:
-		//		Select the tree node identified by passed path.
-		// path:
-		//		Array of items or item id's
+		//      Singular variant of _setPathsAttr
+		if(path.length) {
+			return this.set("paths", [path]);
+		} 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.
+		// paths:
+		//		Array of arrays of items or item id's
 		// returns:
 		//		Deferred to indicate when the set is complete
+		var tree = this;
 
-		var d = new dojo.Deferred();
-
-		this._selectNode(null);
-		if(!path || !path.length){
-			d.resolve(true);
-			return d;
-		}
+		// 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();
+			
+			// normalize path to use identity
+			path = dojo.map(path, function(item){
+				return dojo.isString(item) ? item : tree.model.getIdentity(item);
+			});
 
-		// If this is called during initialization, defer running until Tree has finished loading
-		this._loadDeferred.addCallback(dojo.hitch(this, function(){
-			if(!this.rootNode){
-				d.reject(new Error("!this.rootNode"));
-				return;
-			}
-			if(path[0] !== this.rootNode.item && (dojo.isString(path[0]) && path[0] != this.model.getIdentity(this.rootNode.item))){
-				d.reject(new Error(this.id + ":path[0] doesn't match this.rootNode.item.  Maybe you are using the wrong tree."));
-				return;
+			if(path.length){
+				// Wait for the tree to load, if it hasn't already.
+				tree._loadDeferred.addCallback(function(){ selectPath(path, [tree.rootNode], d); });
+			}else{
+				d.errback("Empty path");
 			}
-			path.shift();
-
-			var node = this.rootNode;
-
-			function advance(){
-				// summary:
-				// 		Called when "node" has completed loading and expanding.   Pop the next item from the path
-				//		(which must be a child of "node") and advance to it, and then recurse.
-
-				// Set item and identity to next item in path (node is pointing to the item that was popped
-				// from the path _last_ time.
-				var item = path.shift(),
-					identity = dojo.isString(item) ? item : this.model.getIdentity(item);
-
-				// Change "node" from previous item in path to the item we just popped from path
-				dojo.some(this._itemNodesMap[identity], function(n){
-					if(n.getParent() == node){
-						node = n;
-						return true;
-					}
-					return false;
-				});
-
+			return d;
+		})).addCallback(setNodes);
+
+		function selectPath(path, nodes, def){
+			// Traverse path; the next path component should be among "nodes".
+			var nextPath = path.shift();
+			var nextNode = dojo.filter(nodes, function(node){
+				return node.getIdentity() == nextPath;
+			})[0];
+			if(!!nextNode){
 				if(path.length){
-					// Need to do more expanding
-					this._expandNode(node).addCallback(dojo.hitch(this, advance));
+					tree._expandNode(nextNode).addCallback(function(){ selectPath(path, nextNode.getChildren(), def); });
 				}else{
-					// Final destination node, select it
-					this._selectNode(node);
-					
-					// signal that path setting is finished
-					d.resolve(true);
+					//Successfully reached the end of this path
+					def.callback(nextNode);
 				}
+			} 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];}),
+				function(x){return x[1];}));
+		}
+	},
 
-			this._expandNode(node).addCallback(dojo.hitch(this, advance));
+	_setSelectedNodeAttr: function(node){
+		this.set('selectedNodes', [node]);
+	},
+	_setSelectedNodesAttr: function(nodes){
+		this._loadDeferred.addCallback( dojo.hitch(this, function(){
+			this.dndController.setSelection(nodes);
 		}));
-			
-		return d;
 	},
 
-	_getPathAttr: function(){
-		// summary:
-		//		Return an array of items that is the path to selected tree node.
-		if(!this.selectedNode){ return; }
-		var res = [];
-		var treeNode = this.selectedNode;
-		while(treeNode && treeNode !== this.rootNode){
-			res.unshift(treeNode.item);
-			treeNode = treeNode.getParent();
-		}
-		res.unshift(this.rootNode.item);
-		return res;
-	},
 
 	////////////// Data store related functions //////////////////////
 	// These just get passed to the model; they are here for back-compat
@@ -988,7 +1010,7 @@ dojo.declare(
 		if(!treeNode){ return; }
 
 		var key = e.charOrCode;
-		if(typeof key == "string"){	// handle printables (letter navigation)
+		if(typeof key == "string" && key != " "){	// handle printables (letter navigation)
 			// Check for key navigation.
 			if(!e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey){
 				this._onLetterKeyNav( { node: treeNode, key: key.toLowerCase() } );
@@ -1007,6 +1029,11 @@ dojo.declare(
 				// setup table mapping keys to events
 				map = {};
 				map[dk.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";
@@ -1022,10 +1049,10 @@ dojo.declare(
 		}
 	},
 
-	_onEnterKey: function(/*Object*/ message, /*Event*/ evt){
+	_onEnterKey: function(/*Object*/ message){
 		this._publish("execute", { item: message.item, node: message.node } );
-		this._selectNode(message.node);
-		this.onClick(message.item, message.node, evt);
+		this.dndController.userSelect(message.node, dojo.isCopyKey( message.evt ), message.evt.shiftKey);
+		this.onClick(message.item, message.node, message.evt);
 	},
 
 	_onDownArrow: function(/*Object*/ message){
@@ -1177,12 +1204,17 @@ 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);
+	},
 	_onClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
 		// summary:
 		//		Translates click events into commands for the controller to process
 
 		var domElement = e.target,
-			isExpandoClick = (domElement == nodeWidget.expandoNode || domElement == nodeWidget.expandoNodeText);
+			isExpandoClick = this.isExpandoNode(domElement, nodeWidget);
 
 		if( (this.openOnClick && nodeWidget.isExpandable) || isExpandoClick ){
 			// expando node was clicked, or label of a folder node was clicked; open it
@@ -1194,9 +1226,6 @@ dojo.declare(
 			this.onClick(nodeWidget.item, nodeWidget, e);
 			this.focusNode(nodeWidget);
 		}
-		if(!isExpandoClick){
-			this._selectNode(nodeWidget);
-		}
 		dojo.stopEvent(e);
 	},
 	_onDblClick: function(/*TreeNode*/ nodeWidget, /*Event*/ e){
@@ -1216,9 +1245,6 @@ dojo.declare(
 			this.onDblClick(nodeWidget.item, nodeWidget, e);
 			this.focusNode(nodeWidget);
 		}
-		if(!isExpandoClick){
-			this._selectNode(nodeWidget);
-		}
 		dojo.stopEvent(e);
 	},
 
@@ -1397,21 +1423,6 @@ dojo.declare(
 		dijit.focus(node.labelNode);
 	},
 
-	_selectNode: function(/*_tree.Node*/ node){
-		// summary:
-		//		Mark specified node as select, and unmark currently selected node.
-		// tags:
-		//		protected
-
-		if(this.selectedNode && !this.selectedNode._destroyed){
-			this.selectedNode.setSelected(false);
-		}
-		if(node){
-			node.setSelected(true);
-		}
-		this.selectedNode = node;
-	},
-
 	_onNodeFocus: function(/*dijit._Widget*/ node){
 		// summary:
 		//		Called when a TreeNode gets focus, either by user clicking
@@ -1490,13 +1501,16 @@ dojo.declare(
 
 		if(nodes){
 			dojo.forEach(nodes,function(node){
+				// Remove node from set of selected nodes (if it's selected)
+				this.dndController.removeTreeNode(node);
+
 				var parent = node.getParent();
 				if(parent){
 					// if node has not already been orphaned from a _onSetItem(parent, "children", ..) call...
 					parent.removeChild(node);
 				}
 				node.destroyRecursive();
-			});
+			}, this);
 			delete this._itemNodesMap[identity];
 		}
 	},
@@ -1569,13 +1583,12 @@ dojo.declare(
 	resize: function(changeSize){
 		if(changeSize){
 			dojo.marginBox(this.domNode, changeSize);
-			dojo.style(this.domNode, "overflow", "auto");	// for scrollbars
 		}
 
 		// 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.marginBox(this.tree.indentDetector).w;
+		this._nodePixelIndent = dojo._getMarginSize(this.tree.indentDetector).w;
 
 		if(this.tree.rootNode){
 			// If tree has already loaded, then reset indent for all the nodes
@@ -1596,5 +1609,7 @@ dojo.declare(
 });
 
 // For back-compat.  TODO: remove in 2.0
-dojo.require("dijit.tree.TreeStoreModel");
-dojo.require("dijit.tree.ForestStoreModel");
+
+
+return dijit.Tree;
+});
diff --git a/dijit/_Calendar.js b/dijit/_Calendar.js
index ce169f1..f4454f2 100644
--- a/dijit/_Calendar.js
+++ b/dijit/_Calendar.js
@@ -1,8 +1,11 @@
-dojo.provide("dijit._Calendar");
+define("dijit/_Calendar", ["dojo", "dijit", "dijit/Calendar"], function(dojo, dijit) {
 
-dojo.require("dijit.Calendar");
 dojo.deprecated("dijit._Calendar is deprecated", "dijit._Calendar moved to dijit.Calendar", 1.5);
 
 // dijit._Calendar had an underscore all this time merely because it did
 // not satisfy dijit's a11y policy.
 dijit._Calendar = dijit.Calendar;
+
+
+return dijit._Calendar;
+});
diff --git a/dijit/_Contained.js b/dijit/_Contained.js
index 8fd7b3d..25b2417 100644
--- a/dijit/_Contained.js
+++ b/dijit/_Contained.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._Contained");
+define("dijit/_Contained", ["dojo", "dijit"], function(dojo, dijit) {
 
 dojo.declare("dijit._Contained",
 		null,
@@ -63,3 +63,6 @@ dojo.declare("dijit._Contained",
 		}
 	);
 
+
+return dijit._Contained;
+});
diff --git a/dijit/_Container.js b/dijit/_Container.js
index 46c7ea9..57c8817 100644
--- a/dijit/_Container.js
+++ b/dijit/_Container.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._Container");
+define("dijit/_Container", ["dojo", "dijit"], function(dojo, dijit) {
 
 dojo.declare("dijit._Container",
 	null,
@@ -62,7 +62,7 @@ dojo.declare("dijit._Container",
 			//		not destroy it.  You can also pass in an integer indicating
 			//		the index within the container to remove
 
-			if(typeof widget == "number" && widget > 0){
+			if(typeof widget == "number"){
 				widget = this.getChildren()[widget];
 			}
 
@@ -130,3 +130,7 @@ dojo.declare("dijit._Container",
 		}
 	}
 );
+
+
+return dijit._Container;
+});
diff --git a/dijit/_CssStateMixin.js b/dijit/_CssStateMixin.js
index 545c650..b25a379 100644
--- a/dijit/_CssStateMixin.js
+++ b/dijit/_CssStateMixin.js
@@ -1,5 +1,4 @@
-dojo.provide("dijit._CssStateMixin");
-
+define("dijit/_CssStateMixin", ["dojo", "dijit"], function(dojo, dijit) {
 
 dojo.declare("dijit._CssStateMixin", [], {
 	// summary:
@@ -30,7 +29,19 @@ dojo.declare("dijit._CssStateMixin", [], {
 	//		is hovered, etc.
 	cssStateNodes: {},
 
-	postCreate: function(){
+	// hovering: [readonly] Boolean
+	//		True if cursor is over this widget
+	hovering: false,
+	
+	// active: [readonly] Boolean
+	//		True if mouse was pressed while over this widget, and hasn't been released yet
+	active: false,
+
+	_applyAttributes: function(){
+		// This code would typically be in postCreate(), but putting in _applyAttributes() for
+		// performance: so the class changes happen before DOM is inserted into the document.
+		// Change back to postCreate() in 2.0.  See #11635.
+
 		this.inherited(arguments);
 
 		// Automatically monitor mouse events (essentially :hover and :active) on this.domNode
@@ -39,15 +50,8 @@ dojo.declare("dijit._CssStateMixin", [], {
 		}, this);
 		
 		// Monitoring changes to disabled, readonly, etc. state, and update CSS class of root node
-		this.connect(this, "set", function(name, value){
-			if(arguments.length >= 2 && {disabled: true, readOnly: true, checked:true, selected:true}[name]){
-				this._setStateClass();
-			}
-		});
-
-		// The widget coming in/out of the focus change affects it's state
-		dojo.forEach(["_onFocus", "_onBlur"], function(ap){
-			this.connect(this, ap, "_setStateClass");
+		dojo.forEach(["disabled", "readOnly", "checked", "selected", "focused", "state", "hovering", "active"], function(attr){
+			this.watch(attr, dojo.hitch(this, "_setStateClass"));
 		}, this);
 
 		// Events on sub nodes within the widget
@@ -55,44 +59,42 @@ dojo.declare("dijit._CssStateMixin", [], {
 			this._trackMouseState(this[ap], this.cssStateNodes[ap]);
 		}
 		// Set state initially; there's probably no hover/active/focus state but widget might be
-		// disabled/readonly so we want to set CSS classes for those conditions.
+		// disabled/readonly/checked/selected so we want to set CSS classes for those conditions.
 		this._setStateClass();
 	},
 
 	_cssMouseEvent: function(/*Event*/ event){
 		// summary:
-		//	Sets _hovering and _active properties depending on mouse state,
-		//	then calls _setStateClass() to set appropriate CSS classes for this.domNode.
+		//	Sets hovering and active properties depending on mouse state,
+		//	which triggers _setStateClass() to set appropriate CSS classes for this.domNode.
 
 		if(!this.disabled){
 			switch(event.type){
 				case "mouseenter":
 				case "mouseover":	// generated on non-IE browsers even though we connected to mouseenter
-					this._hovering = true;
-					this._active = this._mouseDown;
+					this._set("hovering", true);
+					this._set("active", this._mouseDown);
 					break;
 
 				case "mouseleave":
 				case "mouseout":	// generated on non-IE browsers even though we connected to mouseleave
-					this._hovering = false;
-					this._active = false;
+					this._set("hovering", false);
+					this._set("active", false);
 					break;
 
 				case "mousedown" :
-					this._active = true;
+					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(){
-						this._active = false;
 						this._mouseDown = false;
-						this._setStateClass();
+						this._set("active", false);
 						this.disconnect(mouseUpConnector);
 					});
 					break;
 			}
-			this._setStateClass();
 		}
 	},
 
@@ -111,11 +113,12 @@ dojo.declare("dijit._CssStateMixin", [], {
 		//		The widget may have one or more of the following states, determined
 		//		by this.state, this.checked, this.valid, and this.selected:
 		//			- Error - ValidationTextBox sets this.state to "Error" if the current input value is invalid
+		//			- Incomplete - ValidationTextBox sets this.state to "Incomplete" if the current input value is not finished yet
 		//			- Checked - ex: a checkmark or a ToggleButton in a checked state, will have this.checked==true
 		//			- Selected - ex: currently selected tab will have this.selected==true
 		//
 		//		In addition, it may have one or more of the following states,
-		//		based on this.disabled and flags set in _onMouse (this._active, this._hovering, this._focused):
+		//		based on this.disabled and flags set in _onMouse (this.active, this.hovering) and from focus manager (this.focused):
 		//			- Disabled	- if the widget is disabled
 		//			- Active		- if the mouse (or space/enter key?) is being pressed down
 		//			- Focused		- if the widget has focus
@@ -148,9 +151,9 @@ dojo.declare("dijit._CssStateMixin", [], {
 		}else if(this.readOnly){
 			multiply("ReadOnly");
 		}else{
-			if(this._active){
+			if(this.active){
 				multiply("Active");
-			}else if(this._hovering){
+			}else if(this.hovering){
 				multiply("Hover");
 			}
 		}
@@ -243,10 +246,11 @@ dojo.declare("dijit._CssStateMixin", [], {
 
 		// Just in case widget is enabled/disabled while it has focus/hover/active state.
 		// Maybe this is overkill.
-		this.connect(this, "set", function(name, value){
-			if(name == "disabled" || name == "readOnly"){
-				setClass();
-			}
-		});
+		this.watch("disabled", setClass);
+		this.watch("readOnly", setClass);
 	}
 });
+
+
+return dijit._CssStateMixin;
+});
diff --git a/dijit/_DialogMixin.js b/dijit/_DialogMixin.js
index add8dc1..213a456 100644
--- a/dijit/_DialogMixin.js
+++ b/dijit/_DialogMixin.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit._DialogMixin");
-
-dojo.require("dijit._Widget");
+define("dijit/_DialogMixin", ["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit) {
 
 dojo.declare("dijit._DialogMixin", null,
 	{
@@ -54,22 +52,20 @@ dojo.declare("dijit._DialogMixin", null,
 			this.execute(this.get('value'));
 		},
 
-		_getFocusItems: function(/*Node*/ dialogNode){
+		_getFocusItems: function(){
 			// summary:
-			//		Find focusable Items each time a dialog is opened,
-			//		setting _firstFocusItem and _lastFocusItem
+			//		Finds focusable items in dialog,
+			//		and sets this._firstFocusItem and this._lastFocusItem
 			// tags:
 			//		protected
 
-			var elems = dijit._getTabNavigable(dojo.byId(dialogNode));
-			this._firstFocusItem = elems.lowest || elems.first || dialogNode;
+			var elems = dijit._getTabNavigable(this.containerNode);
+			this._firstFocusItem = elems.lowest || elems.first || this.closeButtonNode || this.domNode;
 			this._lastFocusItem = elems.last || elems.highest || this._firstFocusItem;
-			if(dojo.isMoz && this._firstFocusItem.tagName.toLowerCase() == "input" &&
-					dojo.getNodeProp(this._firstFocusItem, "type").toLowerCase() == "file"){
-				// FF doesn't behave well when first element is input type=file, set first focusable to dialog container
-				dojo.attr(dialogNode, "tabIndex", "0");
-				this._firstFocusItem = dialogNode;
-			}
 		}
 	}
-);
\ No newline at end of file
+);
+
+
+return dijit._DialogMixin;
+});
diff --git a/dijit/_HasDropDown.js b/dijit/_HasDropDown.js
index c964577..a6d8883 100644
--- a/dijit/_HasDropDown.js
+++ b/dijit/_HasDropDown.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit._HasDropDown");
-
-dojo.require("dijit._base.place");
-dojo.require("dijit._Widget");
+define("dijit/_HasDropDown", ["dojo", "dijit", "dijit/_Widget"], function(dojo, dijit) {
 
 dojo.declare("dijit._HasDropDown",
 	null,
@@ -51,8 +48,9 @@ dojo.declare("dijit._HasDropDown",
 		forceWidth: false,
 
 		// maxHeight: [protected] Integer
-		//		The max height for our dropdown.  Set to 0 for no max height.
-		//		any dropdown taller than this will have scrollbars
+		//		The max height for our dropdown.
+		//		Any dropdown taller than this will have scrollbars.
+		//		Set to 0 for no max height, or -1 to limit height to available space in viewport
 		maxHeight: 0,
 
 		// dropDownPosition: [const] String[]
@@ -82,6 +80,8 @@ dojo.declare("dijit._HasDropDown",
 
 			if(this.disabled || this.readOnly){ return; }
 
+			dojo.stopEvent(e);
+
 			this._docHandler = this.connect(dojo.doc, "onmouseup", "_onDropDownMouseUp");
 
 			this.toggleDropDown();
@@ -135,7 +135,7 @@ dojo.declare("dijit._HasDropDown",
 					}
 				}
 			}
-			if(this._opened && dropDown.focus){
+			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);
@@ -146,27 +146,14 @@ dojo.declare("dijit._HasDropDown",
 			// the drop down was already opened on mousedown/keydown; just need to call stopEvent()
 			if(this._stopClickEvents){
 				dojo.stopEvent(e);
-			}			
+			}
 		},
 
-		_setupDropdown: function(){
-			// summary:
-			//		set up nodes and connect our mouse and keypress events
+		buildRendering: function(){
+			this.inherited(arguments);
+
 			this._buttonNode = this._buttonNode || this.focusNode || this.domNode;
 			this._popupStateNode = this._popupStateNode || this.focusNode || this._buttonNode;
-			this._aroundNode = this._aroundNode || this.domNode;
-			this.connect(this._buttonNode, "onmousedown", "_onDropDownMouseDown");
-			this.connect(this._buttonNode, "onclick", "_onDropDownClick");
-			this.connect(this._buttonNode, "onkeydown", "_onDropDownKeydown");
-			this.connect(this._buttonNode, "onkeyup", "_onKey");
-
-			// If we have a _setStateClass function (which happens when
-			// we are a form widget), then we need to connect our open/close
-			// functions to it
-			if(this._setStateClass){
-				this.connect(this, "openDropDown", "_setStateClass");
-				this.connect(this, "closeDropDown", "_setStateClass");
-			}
 
 			// Add a class to the "dijitDownArrowButton" type class to _buttonNode so theme can set direction of arrow
 			// based on where drop down will normally appear
@@ -182,11 +169,18 @@ dojo.declare("dijit._HasDropDown",
 		},
 
 		postCreate: function(){
-			this._setupDropdown();
+			// summary:
+			//		set up nodes and connect our mouse and keypress events
+
 			this.inherited(arguments);
+
+			this.connect(this._buttonNode, "onmousedown", "_onDropDownMouseDown");
+			this.connect(this._buttonNode, "onclick", "_onDropDownClick");
+			this.connect(this.focusNode, "onkeypress", "_onKey");
+			this.connect(this.focusNode, "onkeyup", "_onKeyUp");
 		},
 
-		destroyDescendants: function(){
+		destroy: function(){
 			if(this.dropDown){
 				// Destroy the drop down, unless it's already been destroyed.  This can happen because
 				// the drop down is a direct child of <body> even though it's logically my child.
@@ -198,27 +192,43 @@ dojo.declare("dijit._HasDropDown",
 			this.inherited(arguments);
 		},
 
-		_onDropDownKeydown: function(/*Event*/ e){
-			if(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE){
-				e.preventDefault();	// stop IE screen jump
-			}
-		},
-
 		_onKey: function(/*Event*/ e){
 			// summary:
 			//		Callback when the user presses a key while focused on the button node
 
 			if(this.disabled || this.readOnly){ return; }
-			var d = this.dropDown;
+
+			var d = this.dropDown, target = e.target;
 			if(d && this._opened && d.handleKey){
-				if(d.handleKey(e) === false){ return; }
+				if(d.handleKey(e) === false){
+					/* false return code means that the drop down handled the key */
+					dojo.stopEvent(e);
+					return;
+				}
 			}
-			if(d && this._opened && e.keyCode == dojo.keys.ESCAPE){
-				this.toggleDropDown();
-			}else if(d && !this._opened && 
-					(e.keyCode == dojo.keys.DOWN_ARROW || e.keyCode == dojo.keys.ENTER || e.keyCode == dojo.keys.SPACE)){
+			if(d && this._opened && e.charOrCode == dojo.keys.ESCAPE){
+				this.closeDropDown();
+				dojo.stopEvent(e);
+			}else if(!this._opened &&
+					(e.charOrCode == dojo.keys.DOWN_ARROW ||
+						( (e.charOrCode == dojo.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'))))){
+				// Toggle the drop down, but wait until keyup so that the drop down doesn't
+				// get a stray keyup event, or in the case of key-repeat (because user held
+				// down key for too long), stray keydown events
+				this._toggleOnKeyUp = true;
+				dojo.stopEvent(e);
+			}
+		},
+
+		_onKeyUp: function(){
+			if(this._toggleOnKeyUp){
+				delete this._toggleOnKeyUp;
 				this.toggleDropDown();
-				if(d.focus){
+				var d = this.dropDown;	// drop down may not exist until toggleDropDown() call
+				if(d && d.focus){
 					setTimeout(dojo.hitch(d, "focus"), 1);
 				}
 			}
@@ -228,8 +238,14 @@ dojo.declare("dijit._HasDropDown",
 			// summary:
 			//		Called magically when focus has shifted away from this widget and it's dropdown
 
-			this.closeDropDown();
-			// don't focus on button.  the user has explicitly focused on something else.
+			// Don't focus on button if the user has explicitly focused on something else (happens
+			// when user clicks another control causing the current popup to close)..
+			// But if focus is inside of the drop down then reset focus to me, because IE doesn't like
+			// it when you display:none a node with focus.
+			var focusMe = dijit._curFocus && this.dropDown && dojo.isDescendant(dijit._curFocus, this.dropDown.domNode);
+
+			this.closeDropDown(focusMe);
+
 			this.inherited(arguments);
 		},
 
@@ -246,7 +262,8 @@ dojo.declare("dijit._HasDropDown",
 		loadDropDown: function(/* Function */ loadCallback){
 			// summary:
 			//		Loads the data for the dropdown, and at some point, calls
-			//		the given callback
+			//		the given callback.   This is basically a callback when the
+			//		user presses the down arrow button to open the drop down.
 			// tags:
 			//		protected
 
@@ -255,14 +272,13 @@ dojo.declare("dijit._HasDropDown",
 
 		toggleDropDown: function(){
 			// summary:
+			//		Callback when the user presses the down arrow button or presses
+			//		the down arrow key to open/close the drop down.
 			//		Toggle the drop-down widget; if it is up, close it, if not, open it
 			// tags:
 			//		protected
 
 			if(this.disabled || this.readOnly){ return; }
-			this.focus();
-			var dropDown = this.dropDown;
-			if(!dropDown){ return; }
 			if(!this._opened){
 				// If we aren't loaded, load it first so there isn't a flicker
 				if(!this.isLoaded()){
@@ -278,14 +294,17 @@ dojo.declare("dijit._HasDropDown",
 
 		openDropDown: function(){
 			// summary:
-			//		Opens the dropdown for this widget - it returns the
-			//		return value of dijit.popup.open
+			//		Opens the dropdown for this widget.   To be called only when this.dropDown
+			//		has been created and is ready to display (ie, it's data is loaded).
+			// returns:
+			//		return value of dijit.popup.open()
 			// tags:
 			//		protected
 
-			var dropDown = this.dropDown;
-			var ddNode = dropDown.domNode;
-			var self = this;
+			var dropDown = this.dropDown,
+				ddNode = dropDown.domNode,
+				aroundNode = this._aroundNode || this.domNode,
+				self = this;
 
 			// Prepare our popup's height and honor maxHeight if it exists.
 
@@ -293,8 +312,7 @@ dojo.declare("dijit._HasDropDown",
 			// ie, dependent on how much space is available (BK)
 
 			if(!this._preparedNode){
-				dijit.popup.moveOffScreen(ddNode);
-				this._preparedNode = true;			
+				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;
@@ -318,29 +336,44 @@ dojo.declare("dijit._HasDropDown",
 				}
 				dojo.style(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);
+					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
+				if(dropDown.startup && !dropDown._started){
+					dropDown.startup();
+				}
+
+				dijit.popup.moveOffScreen(dropDown);
 				// Get size of drop down, and determine if vertical scroll bar needed
-				var mb = dojo.marginBox(ddNode);
-				var overHeight = (this.maxHeight && mb.h > this.maxHeight);
+				var mb = dojo._getMarginSize(ddNode);
+				var overHeight = (maxHeight && mb.h > maxHeight);
 				dojo.style(ddNode, {
 					overflowX: "hidden",
 					overflowY: overHeight ? "auto" : "hidden"
 				});
 				if(overHeight){
-					mb.h = this.maxHeight;
+					mb.h = maxHeight;
 					if("w" in mb){
 						mb.w += 16;	// room for vertical scrollbar
 					}
 				}else{
 					delete mb.h;
 				}
-				delete mb.t;
-				delete mb.l;
 
 				// Adjust dropdown width to match or be larger than my width
 				if(this.forceWidth){
-					mb.w = this.domNode.offsetWidth;
+					mb.w = aroundNode.offsetWidth;
 				}else if(this.autoWidth){
-					mb.w = Math.max(mb.w, this.domNode.offsetWidth);
+					mb.w = Math.max(mb.w, aroundNode.offsetWidth);
 				}else{
 					delete mb.w;
 				}
@@ -356,7 +389,7 @@ dojo.declare("dijit._HasDropDown",
 			var retVal = dijit.popup.open({
 				parent: this,
 				popup: dropDown,
-				around: this._aroundNode,
+				around: aroundNode,
 				orient: dijit.getPopupAroundAlignment((this.dropDownPosition && this.dropDownPosition.length) ? this.dropDownPosition : ["below"],this.isLeftToRight()),
 				onExecute: function(){
 					self.closeDropDown(true);
@@ -368,13 +401,12 @@ dojo.declare("dijit._HasDropDown",
 					dojo.attr(self._popupStateNode, "popupActive", false);
 					dojo.removeClass(self._popupStateNode, "dijitHasDropDownOpen");
 					self._opened = false;
-					self.state = "";
 				}
 			});
 			dojo.attr(this._popupStateNode, "popupActive", "true");
 			dojo.addClass(self._popupStateNode, "dijitHasDropDownOpen");
 			this._opened=true;
-			this.state="Opened";
+
 			// TODO: set this.checked and call setStateClass(), to affect button look while drop down is shown
 			return retVal;
 		},
@@ -382,6 +414,8 @@ dojo.declare("dijit._HasDropDown",
 		closeDropDown: function(/*Boolean*/ focus){
 			// summary:
 			//		Closes the drop down on this widget
+			// focus:
+			//		If true, refocuses the button widget
 			// tags:
 			//		protected
 
@@ -389,9 +423,12 @@ dojo.declare("dijit._HasDropDown",
 				if(focus){ this.focus(); }
 				dijit.popup.close(this.dropDown);
 				this._opened = false;
-				this.state = "";
 			}
 		}
 
 	}
 );
+
+
+return dijit._HasDropDown;
+});
diff --git a/dijit/_KeyNavContainer.js b/dijit/_KeyNavContainer.js
index 1ca8311..c50d648 100644
--- a/dijit/_KeyNavContainer.js
+++ b/dijit/_KeyNavContainer.js
@@ -1,5 +1,4 @@
-dojo.provide("dijit._KeyNavContainer");
-dojo.require("dijit._Container");
+define("dijit/_KeyNavContainer", ["dojo", "dijit", "dijit/_Container"], function(dojo, dijit) {
 
 dojo.declare("dijit._KeyNavContainer",
 	dijit._Container,
@@ -42,6 +41,8 @@ dojo.declare("dijit._KeyNavContainer",
 			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");
 			this.connect(this.domNode, "onkeypress", "_onContainerKeypress");
 			this.connect(this.domNode, "onfocus", "_onContainerFocus");
 		},
@@ -78,6 +79,17 @@ dojo.declare("dijit._KeyNavContainer",
 			}
 		},
 
+		focusLastChild: function(){
+			// summary:
+			//		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);
+			}
+		},
+
 		focusNext: function(){
 			// summary:
 			//		Focus the next widget
@@ -111,15 +123,16 @@ dojo.declare("dijit._KeyNavContainer",
 			if(this.focusedChild && widget !== this.focusedChild){
 				this._onChildBlur(this.focusedChild);
 			}
+			widget.set("tabIndex", this.tabIndex);	// for IE focus outline to appear, must set tabIndex before focs
 			widget.focus(last ? "end" : "start");
-			this.focusedChild = widget;
+			this._set("focusedChild", widget);
 		},
 
 		_startupChild: function(/*dijit._Widget*/ widget){
 			// summary:
 			//		Setup for each child widget
 			// description:
-			//		Sets tabIndex=-1 on each child, so that the tab key will 
+			//		Sets tabIndex=-1 on each child, so that the tab key will
 			//		leave the container rather than visiting each child.
 			// tags:
 			//		private
@@ -200,6 +213,12 @@ dojo.declare("dijit._KeyNavContainer",
 			return this._getNextFocusableChild(null, 1);	// dijit._Widget
 		},
 
+		_getLastFocusableChild: function(){
+			// summary:
+			//		Returns last child that can be focused
+			return this._getNextFocusableChild(null, -1);	// dijit._Widget
+		},
+
 		_getNextFocusableChild: function(child, dir){
 			// summary:
 			//		Returns the next or previous focusable child, compared
@@ -227,3 +246,7 @@ dojo.declare("dijit._KeyNavContainer",
 		}
 	}
 );
+
+
+return dijit._KeyNavContainer;
+});
diff --git a/dijit/_PaletteMixin.js b/dijit/_PaletteMixin.js
index 86cfe01..a265a16 100644
--- a/dijit/_PaletteMixin.js
+++ b/dijit/_PaletteMixin.js
@@ -1,5 +1,4 @@
-dojo.provide("dijit._PaletteMixin");
-dojo.require("dijit._CssStateMixin");
+define("dijit/_PaletteMixin", ["dojo", "dijit", "dijit/_CssStateMixin"], function(dojo, dijit) {
 
 dojo.declare("dijit._PaletteMixin",
 	[dijit._CssStateMixin],
@@ -27,23 +26,23 @@ dojo.declare("dijit._PaletteMixin",
 	//		Index of the currently selected cell. Initially, none selected
 	_selectedCell: -1,
 
+/*=====
 	// _currentFocus: [private] DomNode
 	//		The currently focused cell (if the palette itself has focus), or otherwise
 	//		the cell to be focused when the palette itself gets focus.
 	//		Different from value, which represents the selected (i.e. clicked) cell.
-/*=====
 	_currentFocus: null,
 =====*/
 
+/*=====
 	// _xDim: [protected] Integer
 	//		This is the number of cells horizontally across.
-/*=====
 	_xDim: null,
 =====*/
 
+/*=====
 	// _yDim: [protected] Integer
 	//		This is the number of cells vertically down.
-/*=====
 	_yDim: null,
 =====*/
 
@@ -60,7 +59,7 @@ dojo.declare("dijit._PaletteMixin",
 	//	 dyeClass should implements dijit.Dye interface
 	dyeClass: '',
 
-	_preparePalette: function(choices, titles) {
+	_preparePalette: function(choices, titles, dyeClassObj) {
 		// summary:
 		//		Subclass must call _preparePalette() from postCreate(), passing in the tooltip
 		//		for each cell
@@ -68,18 +67,20 @@ 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;
 		
-		var dyeClassObj = dojo.getObject(this.dyeClass);
+		dyeClassObj = dyeClassObj || dojo.getObject(this.dyeClass);
 
 		for(var row=0; row < choices.length; row++){
 			var rowNode = dojo.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);
+					var cellObject = new dyeClassObj(value, row, col);
 					
 					var cellNode = dojo.create("td", {
 						"class": this.cellClass,
@@ -159,7 +160,7 @@ dojo.declare("dijit._PaletteMixin",
 		// tags:
 		//		private
 
-		var target = evt.currentTarget,	
+		var target = evt.currentTarget,
 			value = this._getDye(target).getValue();
 
 		// First focus the clicked cell, and then send onChange() notification.
@@ -169,8 +170,8 @@ dojo.declare("dijit._PaletteMixin",
 		// 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);		
+			dijit.focus(target);
+			this._setValueAttr(value, true);
 		}));
 
 		// workaround bug where hover class is not removed on popup because the popup is
@@ -214,8 +215,7 @@ dojo.declare("dijit._PaletteMixin",
 		//		Optional parameter used to tell the select whether or not to fire
 		//		onChange event.
 		
-		// clear old value and selected cell
-		this.value = null;
+		// clear old selected cell
 		if(this._selectedCell >= 0){
 			dojo.removeClass(this._cells[this._selectedCell].node, "dijitPaletteCellSelected");
 		}
@@ -226,18 +226,18 @@ dojo.declare("dijit._PaletteMixin",
 			for(var i = 0; i < this._cells.length; i++){
 				if(value == this._cells[i].dye.getValue()){
 					this._selectedCell = i;
-					this.value = value;
-
 					dojo.addClass(this._cells[i].node, "dijitPaletteCellSelected");
-
-					if(priorityChange || priorityChange === undefined){
-						this.onChange(value);
-					}
-
 					break;
 				}
 			}
 		}
+		
+		// record new value, or null if no matching cell
+		this._set("value", this._selectedCell >= 0 ? value : null);
+
+		if(priorityChange || priorityChange === undefined){
+			this.onChange(value);
+		}
 	},
 
 	onChange: function(value){
@@ -287,7 +287,7 @@ dojo.declare("dijit.Dye",
 		// summary:
 		//		Interface for the JS Object associated with a palette cell (i.e. DOMNode)
 
-		constructor: function(alias){
+		constructor: function(alias, row, col){
 			// summary:
 			//		Initialize according to value or alias like "white"
 			// alias: String
@@ -310,4 +310,8 @@ dojo.declare("dijit.Dye",
 		}
 	}
 );
-=====*/
\ No newline at end of file
+=====*/
+
+
+return dijit._PaletteMixin;
+});
diff --git a/dijit/_Templated.js b/dijit/_Templated.js
index 09d6b6d..80d6d99 100644
--- a/dijit/_Templated.js
+++ b/dijit/_Templated.js
@@ -1,9 +1,4 @@
-dojo.provide("dijit._Templated");
-
-dojo.require("dijit._Widget");
-dojo.require("dojo.string");
-dojo.require("dojo.parser");
-dojo.require("dojo.cache");
+define("dijit/_Templated", ["dojo", "dijit", "dijit/_Widget", "dojo/string", "dojo/parser", "dojo/cache"], function(dojo, dijit) {
 
 dojo.declare("dijit._Templated",
 	null,
@@ -45,15 +40,23 @@ dojo.declare("dijit._Templated",
 		//		'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){
@@ -78,7 +81,6 @@ dojo.declare("dijit._Templated",
 			}, this);
 		},
 
-		// method over-ride
 		buildRendering: function(){
 			// summary:
 			//		Construct the UI for this widget from a template, setting this.domNode.
@@ -104,33 +106,24 @@ dojo.declare("dijit._Templated",
 
 			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){
-				// 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";
-				}
-
 				// 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}
+					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
 				}));
 
-				// Restore the query.
-				if(qry){
-					parser._query = qry;
-					parser._attrName = attr;
-				}
-
 				this._supportingWidgets = dijit.findWidgets(node);
 
 				this._attachTemplateNodes(cw, function(n,p){
@@ -158,6 +151,8 @@ dojo.declare("dijit._Templated",
 		_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
@@ -180,11 +175,11 @@ dojo.declare("dijit._Templated",
 			var x = dojo.isArray(rootNode) ? 0 : -1;
 			for(; x<nodes.length; x++){
 				var baseNode = (x == -1) ? rootNode : nodes[x];
-				if(this.widgetsInTemplate && getAttrFunc(baseNode, "dojoType")){
+				if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){
 					continue;
 				}
 				// Process dojoAttachPoint
-				var attachPoint = getAttrFunc(baseNode, "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())){
@@ -198,7 +193,7 @@ dojo.declare("dijit._Templated",
 				}
 
 				// Process dojoAttachEvent
-				var attachEvent = getAttrFunc(baseNode, "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; ..."
@@ -218,12 +213,13 @@ dojo.declare("dijit._Templated",
 							if(!thisFunc){
 								thisFunc = event;
 							}
-							this.connect(baseNode, event, thisFunc);
+							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);
@@ -256,6 +252,10 @@ dojo.declare("dijit._Templated",
 			}, this);
 			this._attachPoints = [];
 
+			// And same for event handlers
+			dojo.forEach(this._attachEvents, this.disconnect, this);
+			this._attachEvents = [];
+			
 			this.inherited(arguments);
 		}
 	}
@@ -333,3 +333,7 @@ dojo.extend(dijit._Widget,{
 	waiRole: "",
 	waiState:""
 });
+
+
+return dijit._Templated;
+});
diff --git a/dijit/_TimePicker.js b/dijit/_TimePicker.js
index 60d0392..c55bc7a 100644
--- a/dijit/_TimePicker.js
+++ b/dijit/_TimePicker.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit._TimePicker");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dojo.date.locale");
+define("dijit/_TimePicker", ["dojo", "dijit", "text!dijit/templates/TimePicker.html", "dijit/form/_FormWidget", "dojo/date/locale"], function(dojo, dijit) {
 
 /*=====
 dojo.declare(
@@ -95,53 +92,38 @@ dojo.declare("dijit._TimePicker",
 =====*/
 		serialize: dojo.date.stamp.toISOString,
 
-		// _filterString: string
+/*=====
+		// filterString: string
 		//		The string to filter by
-		_filterString: "",
+		filterString: "",
+=====*/
 
 		setValue: function(/*Date*/ value){
 			// summary:
-			//		Deprecated.  Used attr('value') instead.
+			//		Deprecated.  Used set('value') instead.
 			// tags:
 			//		deprecated
 			dojo.deprecated("dijit._TimePicker:setValue() is deprecated.  Use set('value', ...) instead.", "", "2.0");
 			this.set('value', value);
 		},
+
 		_setValueAttr: function(/*Date*/ date){
 			// summary:
-			//		Hook so attr('value', ...) works.
+			//		Hook so set('value', ...) works.
 			// description:
 			//		Set the value of the TimePicker.
 			//		Redraws the TimePicker around the new date.
 			// tags:
 			//		protected
-			this.value = date;
+			this._set("value", date);
 			this._showText();
 		},
 
-		onOpen: function(best){
+		_setFilterStringAttr: function(val){
 			// summary:
-			//		This is called by the popup manager when a TimeTextBox is displayed on the screen
-			// best:
-			//		Whether it is being displayed above or below the `dijit.form.TimeTextBox`
-			// tags:
-			//		protected
-			if(this._beenOpened && this.domNode.parentNode){
-				// We've been opened before - so set our filter to to the
-				// currently-displayed value (or empty string if it's already
-				// valid)
-				var p = dijit.byId(this.domNode.parentNode.dijitPopupParent);
-				if(p){
-					var val = p.get('displayedValue');
-					if(val && !p.parse(val, p.constraints)){
-						this._filterString = val;
-					}else{
-						this._filterString = "";
-					}
-					this._showText();
-				}
-			}
-			this._beenOpened = true;
+			//		Called by TimeTextBox to filter the values shown in my list
+			this._set("filterString", val);
+			this._showText();
 		},
 
 		isDisabledDate: function(/*Date*/ dateObject, /*String?*/ locale){
@@ -152,7 +134,7 @@ dojo.declare("dijit._TimePicker",
 			return false; // Boolean
 		},
 
-		_getFilteredNodes: function(/*number*/ start, /*number*/ maxNum, /*Boolean*/ before){
+		_getFilteredNodes: function(/*number*/ start, /*number*/ maxNum, /*Boolean*/ before, /*DOMnode*/ lastNode){
 			// summary:
 			//		Returns an array of nodes with the filter applied.  At most maxNum nodes
 			//		will be returned - but fewer may be returned as well.  If the
@@ -160,15 +142,27 @@ dojo.declare("dijit._TimePicker",
 			//		before the given index
 			// tags:
 			//		private
-			var nodes = [], n, i = start, max = this._maxIncrement + Math.abs(i),
-				chk = before?-1:1, dec = before?1:0, inc = before?0:1;
+			var
+				nodes = [],
+				lastValue = lastNode ? lastNode.date : this._refDate,
+				n,
+				i = start,
+				max = this._maxIncrement + Math.abs(i),
+				chk = before ? -1 : 1,
+				dec = before ? 1 : 0,
+				inc = 1 - dec;
 			do{
 				i = i - dec;
 				n = this._createOption(i);
-				if(n){nodes.push(n);}
+				if(n){
+					if((before && n.date > lastValue) || (!before && n.date < lastValue)){
+						break; // don't wrap
+					}
+					nodes[before ? "unshift" : "push"](n);
+					lastValue = n.date;
+				}
 				i = i + inc;
 			}while(nodes.length < maxNum && (i*chk) < max);
-			if(before){ nodes.reverse(); }
 			return nodes;
 		},
 
@@ -177,22 +171,23 @@ dojo.declare("dijit._TimePicker",
 			//		Displays the relevant choices in the drop down list
 			// tags:
 			//		private
-			this.timeMenu.innerHTML = "";
 			var fromIso = dojo.date.stamp.fromISOString;
+			this.timeMenu.innerHTML = "";
 			this._clickableIncrementDate=fromIso(this.clickableIncrement);
 			this._visibleIncrementDate=fromIso(this.visibleIncrement);
 			this._visibleRangeDate=fromIso(this.visibleRange);
 			// get the value of the increments and the range in seconds (since 00:00:00) to find out how many divs to create
-			var sinceMidnight = function(/*Date*/ date){
+			var
+				sinceMidnight = function(/*Date*/ date){
 				return date.getHours() * 60 * 60 + date.getMinutes() * 60 + date.getSeconds();
-			};
-
-			var clickableIncrementSeconds = sinceMidnight(this._clickableIncrementDate);
-			var visibleIncrementSeconds = sinceMidnight(this._visibleIncrementDate);
-			var visibleRangeSeconds = sinceMidnight(this._visibleRangeDate);
+				},
+				clickableIncrementSeconds = sinceMidnight(this._clickableIncrementDate),
+				visibleIncrementSeconds = sinceMidnight(this._visibleIncrementDate),
+				visibleRangeSeconds = sinceMidnight(this._visibleRangeDate),
 
 			// round reference date to previous visible increment
-			var time = this.value.getTime();
+				time = (this.value || this.currentFocus).getTime();
+
 			this._refDate = new Date(time - time % (visibleIncrementSeconds*1000));
 			this._refDate.setFullYear(1970,0,1); // match parse defaults
 
@@ -208,62 +203,38 @@ dojo.declare("dijit._TimePicker",
 			// absolute max number of increments.
 			this._maxIncrement = (60 * 60 * 24) / clickableIncrementSeconds;
 
-			// find the nodes we should display based on our filter
-			var before = this._getFilteredNodes(0, this._totalIncrements >> 1, true);
-			var after = this._getFilteredNodes(0, this._totalIncrements >> 1, false);
-			if(before.length < this._totalIncrements >> 1){
-				before = before.slice(before.length / 2);
-				after = after.slice(0, after.length / 2);
-			}
+			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);
+		},
 
-			// TODO:
-			// I commented this out because it
-			// causes problems for a TimeTextBox in a Dialog, or as the editor of an InlineEditBox,
-			// because the timeMenu node isn't visible yet. -- Bill (Bug #????)
-			// dijit.focus(this.timeMenu);
+		constructor: function(){
+			this.constraints = {}; // create instance object
 		},
 
-		postCreate: function(){
-			// instantiate constraints
-			if(this.constraints === dijit._TimePicker.prototype.constraints){
-				this.constraints={};
-			}
+		postMixInProperties: function(){
+		        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, this.constraints);
+			dojo.mixin(this, constraints);
 
 			// dojo.date.locale needs the lang in the constraints as locale
-			if(!this.constraints.locale){
-				this.constraints.locale=this.lang;
+			if(!constraints.locale){
+				constraints.locale = this.lang;
 			}
+		},
 
+		postCreate: function(){
 			// assign typematic mouse listeners to the arrow buttons
 			this.connect(this.timeMenu, dojo.isIE ? "onmousewheel" : 'DOMMouseScroll', "_mouseWheeled");
-			var _this = this;
-			var typematic = function(){
-				_this._connects.push(
-					dijit.typematic.addMouseListener.apply(null, arguments)
-				);
-			};
-			typematic(this.upArrow,this,this._onArrowUp, 1.0, 50);
-			typematic(this.downArrow,this,this._onArrowDown, 1.0, 50);
-
-			// Connect some callback functions to the hover event of the arrows
-			var triggerFx = function(cb){
-				return function(cnt){
-					// don't run on the first firing
-					if(cnt > 0){cb.call(this, arguments);}
-				};
-			};
-			var hoverFx = function(node, cb){
-				return function(e){
-					dojo.stopEvent(e);
-					dijit.typematic.trigger(e, this, node, triggerFx(cb), node, 1.0, 50);
-				};
-			};
-			this.connect(this.upArrow, "onmouseover", hoverFx(this.upArrow, this._onArrowUp));
-			this.connect(this.downArrow, "onmouseover", hoverFx(this.downArrow, this._onArrowDown));
+			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.inherited(arguments);
 		},
@@ -274,9 +245,9 @@ dojo.declare("dijit._TimePicker",
 			// tags:
 			//		private
 
-			// in non-IE browser the "mouseenter" event will become "mouseover", 
+			// 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", 
+			dojo.toggleClass(e.currentTarget, e.currentTarget == this.upArrow ? "dijitUpArrowHover" : "dijitDownArrowHover",
 				e.type == "mouseenter" || e.type == "mouseover");
 		},
 
@@ -294,7 +265,7 @@ dojo.declare("dijit._TimePicker",
 				date.setFullYear(1970,0,1); // make sure each time is for the same date
 			}
 			var dateString = dojo.date.locale.format(date, this.constraints);
-			if(this._filterString && dateString.toLowerCase().indexOf(this._filterString) !== 0){
+			if(this.filterString && dateString.toLowerCase().indexOf(this.filterString) !== 0){
 				// Doesn't match the filter - return null
 				return null;
 			}
@@ -317,7 +288,7 @@ dojo.declare("dijit._TimePicker",
 				// set disabled
 				dojo.addClass(div, this.baseClass+"ItemDisabled");
 			}
-			if(!dojo.date.compare(this.value, date, this.constraints.selector)){
+			if(this.value && !dojo.date.compare(this.value, date, this.constraints.selector)){
 				div.selected = true;
 				dojo.addClass(div, this.baseClass+"ItemSelected");
 				if(dojo.hasClass(div, this.baseClass+"Marker")){
@@ -325,6 +296,10 @@ dojo.declare("dijit._TimePicker",
 				}else{
 					dojo.addClass(div, this.baseClass+"TickSelected");
 				}
+
+				// Initially highlight the current value.   User can change highlight by up/down arrow keys
+				// or mouse movement.
+				this._highlightOption(div, true);
 			}
 			return div;
 		},
@@ -338,23 +313,19 @@ dojo.declare("dijit._TimePicker",
 			if(!tdate || this.isDisabledDate(tdate)){ return; }
 			this._highlighted_option = null;
 			this.set('value', tdate);
-			this.onValueSelected(tdate);
+			this.onChange(tdate);
 		},
 
-		onValueSelected: function(/*Date*/ time){
+		onChange: function(/*Date*/ time){
 			// summary:
 			//		Notification that a time was selected.  It may be the same as the previous value.
-			// description:
-			//      Used by `dijit.form._DateTimeTextBox` (and thus `dijit.form.TimeTextBox`)
-			//      to get notification when the user has clicked a time.
 			// tags:
-			//      protected
+			//      public
 		},
 
-
 		_highlightOption: function(/*node*/ node, /*Boolean*/ highlight){
 			// summary:
-			//		Turns on/off hover effect on a node based on mouse out/over event
+			//		Turns on/off highlight effect on a node based on mouse out/over event
 			// tags:
 			//		private
 			if(!node){return;}
@@ -420,7 +391,7 @@ dojo.declare("dijit._TimePicker",
 			if(typeof count == "number" && count == -1){ return; } // typematic end
 			if(!this.timeMenu.childNodes.length){ return; }
 			var index = this.timeMenu.childNodes[0].index;
-			var divs = this._getFilteredNodes(index, 1, true);
+			var divs = this._getFilteredNodes(index, 1, true, this.timeMenu.childNodes[0]);
 			if(divs.length){
 				this.timeMenu.removeChild(this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
 				this.timeMenu.insertBefore(divs[0], this.timeMenu.childNodes[0]);
@@ -437,7 +408,7 @@ dojo.declare("dijit._TimePicker",
 			if(typeof count == "number" && count == -1){ return; } // typematic end
 			if(!this.timeMenu.childNodes.length){ return; }
 			var index = this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1].index + 1;
-			var divs = this._getFilteredNodes(index, 1, false);
+			var divs = this._getFilteredNodes(index, 1, false, this.timeMenu.childNodes[this.timeMenu.childNodes.length - 1]);
 			if(divs.length){
 				this.timeMenu.removeChild(this.timeMenu.childNodes[0]);
 				this.timeMenu.appendChild(divs[0]);
@@ -451,13 +422,7 @@ dojo.declare("dijit._TimePicker",
 			// tags:
 			//		protected
 			var dk = dojo.keys;
-			if(e.keyChar || e.charOrCode === dk.BACKSPACE || e.charOrCode == dk.DELETE){
-				// Set a timeout to kick off our filter
-				setTimeout(dojo.hitch(this, function(){
-					this._filterString = e.target.value.toLowerCase();
-					this._showText();
-				}),1);
-			}else if(e.charOrCode == dk.DOWN_ARROW || e.charOrCode == dk.UP_ARROW){
+			if(e.charOrCode == dk.DOWN_ARROW || e.charOrCode == dk.UP_ARROW){
 				dojo.stopEvent(e);
 				// Figure out which option to highlight now and then highlight it
 				if(this._highlighted_option && !this._highlighted_option.parentNode){
@@ -481,13 +446,26 @@ dojo.declare("dijit._TimePicker",
 				}
 				this._highlightOption(tgt, true);
 				this._keyboardSelected = tgt;
-			}else if(this._highlighted_option && (e.charOrCode == dk.ENTER || e.charOrCode === dk.TAB)){
+				return false;
+			}else if(e.charOrCode == dk.ENTER || e.charOrCode === dk.TAB){
+				// mouse hover followed by TAB is NO selection
+				if(!this._keyboardSelected && e.charOrCode === dk.TAB){
+					return true;	// true means don't call stopEvent()
+				}
+
 				// Accept the currently-highlighted option as the value
-				if(!this._keyboardSelected && e.charOrCode === dk.TAB){ return; } // mouse hover followed by TAB is NO selection
-				if(e.charOrCode == dk.ENTER){dojo.stopEvent(e);}
+				if(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 dijit._TimePicker;
+});
diff --git a/dijit/_Widget.js b/dijit/_Widget.js
index 5d7ba32..1f5941d 100644
--- a/dijit/_Widget.js
+++ b/dijit/_Widget.js
@@ -1,9 +1,7 @@
-dojo.provide("dijit._Widget");
+define("dijit/_Widget", ["dojo", "dijit", "dijit/_WidgetBase", "dijit/_base"], function(dojo, dijit) {
 
-//>>excludeStart("dijitBaseExclude", kwArgs.customDijitBase == "true");
-dojo.require( "dijit._base" );
-//>>excludeEnd("dijitBaseExclude");
 
+////////////////// DEFERRED CONNECTS ///////////////////
 
 // 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.
@@ -16,6 +14,8 @@ dojo.connect(dojo, "_connect",
 
 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>
@@ -41,156 +41,28 @@ if(dojo.isIE){
 
 (function(){
 
-var _attrReg = {},	// cached results from getSetterAttributes
-	getSetterAttributes = function(widget){
-		// summary:
-		//		Returns list of attributes with custom setters for specified widget
-		var dc = widget.declaredClass;
-		if(!_attrReg[dc]){
-			var r = [],
-				attrs,
-				proto = widget.constructor.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));
-				}
-			}
-			_attrReg[dc] = r;
-		}
-		return _attrReg[dc] || [];	// String[]
-	};
-
-dojo.declare("dijit._Widget", null, {
+dojo.declare("dijit._Widget", dijit._WidgetBase, {
 	// summary:
 	//		Base class for all Dijit widgets.
-
-	// id: [const] String
-	//		A unique, opaque ID string that can be assigned by users or by the
-	//		system. If the developer passes an ID which is known not to be
-	//		unique, the specified ID is ignored and the system-generated ID is
-	//		used instead.
-	id: "",
-
-	// lang: [const] String
-	//		Rarely used.  Overrides the default Dojo locale used to render this widget,
-	//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
-	//		Value must be among the list of locales specified during by the Dojo bootstrap,
-	//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
-	lang: "",
-
-	// 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: "",
-
-	// class: String
-	//		HTML class attribute
-	"class": "",
-
-	// style: String||Object
-	//		HTML style attributes as cssText string or name/value hash
-	style: "",
-
-	// title: String
-	//		HTML title attribute.
-	//
-	//		For form widgets this specifies a tooltip to display when hovering over
-	//		the widget (just like the native HTML title attribute).
-	//
-	//		For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
-	//		etc., it's used to specify the tab label, accordion pane title, etc.
-	title: "",
-
-	// tooltip: String
-	//		When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
-	//		this specifies the tooltip to appear when the mouse is hovered over that text.
-	tooltip: "",
-
-	// baseClass: [protected] String
-	//		Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
-	//		widget state.
-	baseClass: "",
-
-	// srcNodeRef: [readonly] DomNode
-	//		pointer to original DOM node
-	srcNodeRef: null,
-
-	// domNode: [readonly] DomNode
-	//		This is our visible representation of the widget! Other DOM
-	//		Nodes may by assigned to other properties, usually through the
-	//		template system's dojoAttachPoint syntax, but the domNode
-	//		property is the canonical "top level" node in widget UI.
-	domNode: null,
-
-	// containerNode: [readonly] DomNode
-	//		Designates where children of the source DOM node will be placed.
-	//		"Children" in this case refers to both DOM nodes and widgets.
-	//		For example, for myWidget:
 	//
-	//		|	<div dojoType=myWidget>
-	//		|		<b> here's a plain DOM node
-	//		|		<span dojoType=subWidget>and a widget</span>
-	//		|		<i> and another plain DOM node </i>
-	//		|	</div>
+	//		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)
+	//			- ondijitclick
+	//				Support new dojoAttachEvent="ondijitclick: ..." that is triggered by a mouse click or a SPACE/ENTER keypress
+	//			- focus related functions
+	//				In particular, the onFocus()/onBlur() callbacks.   Driven internally by
+	//				dijit/_base/focus.js.
+	//			- deprecated methods
+	//			- onShow(), onHide(), onClose()
 	//
-	//		containerNode would point to:
-	//
-	//		|		<b> here's a plain DOM node
-	//		|		<span dojoType=subWidget>and a widget</span>
-	//		|		<i> and another plain DOM node </i>
-	//
-	//		In templated widgets, "containerNode" is set via a
-	//		dojoAttachPoint assignment.
-	//
-	//		containerNode must be defined for any widget that accepts innerHTML
-	//		(like ContentPane or BorderContainer or even Button), and conversely
-	//		is null for widgets that don't, like TextBox.
-	containerNode: null,
-
-/*=====
-	// _started: Boolean
-	//		startup() has completed.
-	_started: false,
-=====*/
+	//		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)
+	
 
-	// attributeMap: [protected] Object
-	//		attributeMap sets up a "binding" between attributes (aka properties)
-	//		of the widget and the widget's DOM.
-	//		Changes to widget attributes listed in attributeMap will be
-	//		reflected into the DOM.
-	//
-	//		For example, calling attr('title', 'hello')
-	//		on a TitlePane will automatically cause the TitlePane's DOM to update
-	//		with the new title.
-	//
-	//		attributeMap is a hash where the key is an attribute of the widget,
-	//		and the value reflects a binding to a:
-	//
-	//		- DOM node attribute
-	// |		focus: {node: "focusNode", type: "attribute"}
-	// 		Maps this.focus to this.focusNode.focus
-	//
-	//		- DOM node innerHTML
-	//	|		title: { node: "titleNode", type: "innerHTML" }
-	//		Maps this.title to this.titleNode.innerHTML
-	//
-	//		- DOM node innerText
-	//	|		title: { node: "titleNode", type: "innerText" }
-	//		Maps this.title to this.titleNode.innerText
-	//
-	//		- DOM node CSS class
-	// |		myClass: { node: "domNode", type: "class" }
-	//		Maps this.myClass to this.domNode.className
-	//
-	//		If the value is an array, then each element in the array matches one of the
-	//		formats of the above list.
-	//
-	//		There are also some shorthands for backwards compatibility:
-	//		- string --> { node: string, type: "attribute" }, for example:
-	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
-	//		- "" --> { node: "domNode", type: "attribute" }
-	attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+	////////////////// DEFERRED CONNECTS ///////////////////
 
 	// _deferredConnects: [protected] Object
 	//		attributeMap addendum for event handlers that should be connected only on first use
@@ -342,58 +214,7 @@ dojo.declare("dijit._Widget", null, {
 	},
 	=====*/
 
-	// Constants used in templates
-
-	// _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(),
-
-	//////////// INITIALIZATION METHODS ///////////////////////////////////////
-
-	postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
-		// summary:
-		//		Kicks off widget instantiation.  See create() for details.
-		// tags:
-		//		private
-		this.create(params, srcNodeRef);
-	},
-
 	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
-		// summary:
-		//		Kick off the life-cycle of a widget
-		// params:
-		//		Hash of initialization parameters for widget, including
-		//		scalar values (like title, duration etc.) and functions,
-		//		typically callbacks like onClick.
-		// srcNodeRef:
-		//		If a srcNodeRef (DOM node) is specified:
-		//			- use srcNodeRef.innerHTML as my contents
-		//			- if this is a behavioral widget then apply behavior
-		//			  to that srcNodeRef
-		//			- otherwise, replace srcNodeRef with my generated DOM
-		//			  tree
-		// description:
-		//		Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
-		//		etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget
-		//		for a discussion of the widget creation lifecycle.
-		//
-		//		Of course, adventurous developers could override create entirely, but this should
-		//		only be done as a last resort.
-		// tags:
-		//		private
-
-		// store pointer to original DOM tree
-		this.srcNodeRef = dojo.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()
-		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 = [];
-
 		// 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
@@ -408,33 +229,9 @@ dojo.declare("dijit._Widget", null, {
 			}
 		}
 
-		//mixin our passed parameters
-		if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
-		if(params){
-			this.params = params;
-			dojo.mixin(this,params);
-		}
-		this.postMixInProperties();
-
-		// generate an id for the widget if one wasn't specified
-		// (be sure to do this before buildRendering() because that function might
-		// expect the id to be there.)
-		if(!this.id){
-			this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
-		}
-		dijit.registry.add(this);
-
-		this.buildRendering();
+		this.inherited(arguments);
 
 		if(this.domNode){
-			// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
-			this._applyAttributes();
-
-			var source = this.srcNodeRef;
-			if(source && source.parentNode){
-				source.parentNode.replaceChild(this.domNode, source);
-			}
-
 			// 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,
@@ -442,220 +239,39 @@ dojo.declare("dijit._Widget", null, {
 				this._onConnect(attr);
 			}
 		}
-
-		if(this.domNode){
-			this.domNode.setAttribute("widgetId", this.id);
-		}
-		this.postCreate();
-
-		// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
-		if(this.srcNodeRef && !this.srcNodeRef.parentNode){
-			delete this.srcNodeRef;
-		}
-
-		this._created = true;
 	},
 
-	_applyAttributes: function(){
+	_onConnect: function(/*String*/ event){
 		// summary:
-		//		Step during widget creation to copy all widget attributes to the
-		//		DOM as per attributeMap and _setXXXAttr functions.
-		// description:
-		//		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.
+		//		Called when someone connects to one of my handlers.
+		//		"Turn on" that handler if it isn't active yet.
 		//
-		//		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
+		//		This is also called for every single initialization parameter
+		//		so need to do nothing for parameters like "id".
 		// 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(getSetterAttributes(this), function(a){
-			if(!(a in this.attributeMap)){
-				condAttrApply(a, this);
-			}
-		}, this);
-	},
-
-	postMixInProperties: function(){
-		// summary:
-		//		Called after the parameters to the widget have been read-in,
-		//		but before the widget template is instantiated. Especially
-		//		useful to set properties that are referenced in the widget
-		//		template.
-		// tags:
-		//		protected
-	},
-
-	buildRendering: function(){
-		// summary:
-		//		Construct the UI for this widget, setting this.domNode
-		// description:
-		//		Most widgets will mixin `dijit._Templated`, which implements this
-		//		method.
-		// tags:
-		//		protected
-		this.domNode = this.srcNodeRef || dojo.create('div');
-	},
-
-	postCreate: function(){
-		// summary:
-		//		Processing after the DOM fragment is created
-		// description:
-		//		Called after the DOM fragment has been created, but not necessarily
-		//		added to the document.  Do not include any operations which rely on
-		//		node dimensions or placement.
-		// tags:
-		//		protected
-
-		// baseClass is a single class name or occasionally a space-separated list of names.
-		// Add those classes to the DOMNod.  If RTL mode then also add with Rtl suffix.		
-		if(this.baseClass){
-			var classes = this.baseClass.split(" ");
-			if(!this.isLeftToRight()){
-				classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; }));
-			}
-			dojo.addClass(this.domNode, classes);
-		}
-	},
-
-	startup: function(){
-		// summary:
-		//		Processing after the DOM fragment is added to the document
-		// description:
-		//		Called after a widget and its children have been created and added to the page,
-		//		and all related widgets have finished their create() cycle, up through postCreate().
-		//		This is useful for composite widgets that need to control or layout sub-widgets.
-		//		Many layout widgets can use this as a wiring phase.
-		this._started = true;
-	},
-
-	//////////// DESTROY FUNCTIONS ////////////////////////////////
-
-	destroyRecursive: function(/*Boolean?*/ preserveDom){
-		// summary:
-		// 		Destroy this widget and its descendants
-		// description:
-		//		This is the generic "destructor" function that all widget users
-		// 		should call to cleanly discard with a widget. Once a widget is
-		// 		destroyed, it is removed from the manager object.
-		// preserveDom:
-		//		If true, this method will leave the original DOM structure
-		//		alone of descendant Widgets. Note: This will NOT work with
-		//		dijit._Templated widgets.
-
-		this._beingDestroyed = true;
-		this.destroyDescendants(preserveDom);
-		this.destroy(preserveDom);
-	},
-
-	destroy: function(/*Boolean*/ preserveDom){
-		// summary:
-		// 		Destroy this widget, but not its descendants.
-		//		This method will, however, destroy internal widgets such as those used within a template.
-		// preserveDom: Boolean
-		//		If true, this method will leave the original DOM structure alone.
-		//		Note: This will not yet work with _Templated widgets
-
-		this._beingDestroyed = true;
-		this.uninitialize();
-		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);
-		});
-
-		// destroy widgets created as part of template, etc.
-		dfe(this._supportingWidgets || [], function(w){
-			if(w.destroyRecursive){
-				w.destroyRecursive();
-			}else if(w.destroy){
-				w.destroy();
-			}
-		});
-
-		this.destroyRendering(preserveDom);
-		dijit.registry.remove(this.id);
-		this._destroyed = true;
-	},
-
-	destroyRendering: function(/*Boolean?*/ preserveDom){
-		// summary:
-		//		Destroys the DOM nodes associated with this widget
-		// preserveDom:
-		//		If true, this method will leave the original DOM structure alone
-		//		during tear-down. Note: this will not work with _Templated
-		//		widgets yet.
-		// tags:
-		//		protected
-
-		if(this.bgIframe){
-			this.bgIframe.destroy(preserveDom);
-			delete this.bgIframe;
-		}
-
-		if(this.domNode){
-			if(preserveDom){
-				dojo.removeAttr(this.domNode, "widgetId");
-			}else{
-				dojo.destroy(this.domNode);
-			}
-			delete this.domNode;
-		}
-
-		if(this.srcNodeRef){
-			if(!preserveDom){
-				dojo.destroy(this.srcNodeRef);
-			}
-			delete this.srcNodeRef;
+		if(event in this._deferredConnects){
+			var mapNode = this[this._deferredConnects[event] || 'domNode'];
+			this.connect(mapNode, event.toLowerCase(), event);
+			delete this._deferredConnects[event];
 		}
 	},
 
-	destroyDescendants: function(/*Boolean?*/ preserveDom){
-		// summary:
-		//		Recursively destroy the children of this widget and their
-		//		descendants.
-		// preserveDom:
-		//		If true, the preserveDom attribute is passed to all descendant
-		//		widget's .destroy() method. Not for use with _Templated
-		//		widgets.
+	////////////////// FOCUS RELATED ///////////////////
+	// _onFocus() and _onBlur() are called by the focus manager
 
-		// get all direct descendants and destroy them recursively
-		dojo.forEach(this.getChildren(), function(widget){
-			if(widget.destroyRecursive){
-				widget.destroyRecursive(preserveDom);
-			}
-		});
-	},
+	// focused: [readonly] Boolean
+	//		This widget or a widget it contains has focus, or is "active" because
+	//		it was recently clicked.
+	focused: false,
 
-
-	uninitialize: function(){
+	isFocusable: function(){
 		// summary:
-		//		Stub function. Override to implement custom widget tear-down
-		//		behavior.
-		// tags:
-		//		protected
-		return false;
+		//		Return true if this widget can currently be focused
+		//		and false if not
+		return this.focus && (dojo.style(this.domNode, "display") != "none");
 	},
 
-	////////////////// MISCELLANEOUS METHODS ///////////////////
-
 	onFocus: function(){
 		// summary:
 		//		Called when the widget becomes "active" because
@@ -693,61 +309,7 @@ dojo.declare("dijit._Widget", null, {
 		this.onBlur();
 	},
 
-	_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];
-		}
-	},
-
-	_setClassAttr: function(/*String*/ value){
-		// summary:
-		//		Custom setter for the CSS "class" attribute
-		// tags:
-		//		protected
-		var mapNode = this[this.attributeMap["class"] || 'domNode'];
-		dojo.removeClass(mapNode, this["class"])
-		this["class"] = value;
-		dojo.addClass(mapNode, value);
-	},
-
-	_setStyleAttr: function(/*String||Object*/ value){
-		// summary:
-		//		Sets the style attribut of the widget according to value,
-		//		which is either a hash like {height: "5px", width: "3px"}
-		//		or a plain string
-		// description:
-		//		Determines which node to set the style on based on style setting
-		//		in attributeMap.
-		// tags:
-		//		protected
-
-		var mapNode = this[this.attributeMap.style || '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);
-		}else{
-			if(mapNode.style.cssText){
-				mapNode.style.cssText += "; " + value;
-			}else{
-				mapNode.style.cssText = value;
-			}
-		}
-
-		this.style = value;
-	},
+	////////////////// DEPRECATED METHODS ///////////////////
 
 	setAttribute: function(/*String*/ attr, /*anything*/ value){
 		// summary:
@@ -758,56 +320,6 @@ dojo.declare("dijit._Widget", null, {
 		this.set(attr, value);
 	},
 
-	_attrToDom: function(/*String*/ attr, /*String*/ value){
-		// summary:
-		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
-		//		the widget DOM, as specified in attributeMap.
-		//
-		// description:
-		//		Also sets this["attr"] to the new value.
-		//		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){
-
-			// Get target node and what we are doing to that node
-			var mapNode = this[command.node || command || "domNode"];	// DOM node
-			var type = command.type || "attribute";	// class, innerHTML, innerText, or attribute
-
-			switch(type){
-				case "attribute":
-					if(dojo.isFunction(value)){ // functions execute in the context of the widget
-						value = dojo.hitch(this, value);
-					}
-
-					// Get the name of the DOM node attribute; usually it's the same
-					// as the name of the attribute in the widget (attr), but can be overridden.
-					// Also maps handler names to lowercase, like onSubmit --> onsubmit
-					var attrName = command.attribute ? command.attribute :
-						(/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
-
-					dojo.attr(mapNode, attrName, value);
-					break;
-				case "innerText":
-					mapNode.innerHTML = "";
-					mapNode.appendChild(dojo.doc.createTextNode(value));
-					break;
-				case "innerHTML":
-					mapNode.innerHTML = value;
-					break;
-				case "class":
-					dojo.removeClass(mapNode, this[attr]);
-					dojo.addClass(mapNode, value);
-					break;
-			}
-		}, this);
-		this[attr] = value;
-	},
-
 	attr: function(/*String|Object*/name, /*Object?*/value){
 		// summary:
 		//		Set or get properties on a widget instance.
@@ -840,120 +352,7 @@ dojo.declare("dijit._Widget", null, {
 		}
 	},
 	
-	get: function(name){
-		// summary:
-		//		Get a property from a widget.
-		//	name:
-		//		The property to get.
-		// description:
-		//		Get a named property from a widget. The property may
-		//		potentially be retrieved via a getter method. If no getter is defined, this
-		// 		just retrieves the object's property.  
-		// 		For example, if the widget has 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;
-		var names = this._getAttrNames(name);
-		return this[names.g] ? this[names.g]() : this[name];
-	},
-	
-	set: function(name, value){
-		// summary:
-		//		Set a property on a widget
-		//	name:
-		//		The property to set. 
-		//	value:
-		//		The value to set in the property.
-		// description:
-		//		Sets named properties on a widget which may potentially be handled by a 
-		// 		setter in the widget.
-		// 		For example, if the widget has 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:
-		//	|	myWidget.set({
-		//	|		foo: "Howdy",
-		//	|		bar: 3
-		//	|	})
-		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
-
-		if(typeof name === "object"){
-			for(var x in name){
-				this.set(x, name[x]); 
-			}
-			return this;
-		}
-		var names = this._getAttrNames(name);
-		if(this[names.s]){
-			// use the explicit setter
-			var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
-		}else{
-			// if param is specified as DOM node attribute, copy it
-			if(name in this.attributeMap){
-				this._attrToDom(name, value);
-			}
-			var oldValue = this[name];
-			// FIXME: what about function assignments? Any way to connect() here?
-			this[name] = value;
-		}
-		return result || this;
-	},
-	
-	_attrPairNames: {},		// shared between all widgets
-	_getAttrNames: function(name){
-		// summary:
-		//		Helper function for get() and set().
-		//		Caches attribute name values so we don't do the string ops every time.
-		// tags:
-		//		private
-
-		var apn = this._attrPairNames;
-		if(apn[name]){ return apn[name]; }
-		var uc = name.charAt(0).toUpperCase() + name.substr(1);
-		return (apn[name] = {
-			n: name+"Node",
-			s: "_set"+uc+"Attr",
-			g: "_get"+uc+"Attr"
-		});
-	},
-
-	toString: function(){
-		// summary:
-		//		Returns a string that represents the widget
-		// description:
-		//		When a widget is cast to a string, this method will be used to generate the
-		//		output. Currently, it does not implement any sort of reversible
-		//		serialization.
-		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
-	},
-
-	getDescendants: 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[]
-	},
-
-	getChildren: function(){
-		// summary:
-		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
-		//		Does not return nested widgets, nor widgets that are part of this widget's template.
-		return this.containerNode ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[]
-	},
+	////////////////// ONDIJITCLICK SUPPORT ///////////////////
 
 	// nodesWithKeyClick: [private] String[]
 	//		List of nodes that correctly handle click events via native browser support,
@@ -971,7 +370,9 @@ dojo.declare("dijit._Widget", null, {
 		//		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
+		//		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.
@@ -987,12 +388,13 @@ dojo.declare("dijit._Widget", null, {
 
 		var d = dojo,
 			dc = d._connect,
-			handles = [];
+			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(dojo.indexOf(this.nodesWithKeyClick, obj.nodeName.toLowerCase()) == -1){ // is NOT input or button
+			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){
@@ -1001,13 +403,19 @@ dojo.declare("dijit._Widget", null, {
 							!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;
-							e.preventDefault();		// stop event to prevent scrolling on space key in IE
+							
+							// 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 &&
+							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;
@@ -1016,137 +424,12 @@ dojo.declare("dijit._Widget", null, {
 					})
 				);
 			}
-			event = "onclick";
 		}
-		handles.push(dc(obj, event, this, method));
 
-		this._connects.push(handles);
 		return handles;		// _Widget.Handle
 	},
 
-	disconnect: function(/* _Widget.Handle */ handles){
-		// 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;
-			}
-		}
-	},
-
-	subscribe: function(
-			/*String*/ topic,
-			/*String|Function*/ 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.
-		// example:
-		//	|	var btn = new dijit.form.Button();
-		//	|	// when /my/topic is published, this button changes its label to
-		//	|   // be the parameter of the topic.
-		//	|	btn.subscribe("/my/topic", function(v){
-		//	|		this.set("label", v);
-		//	|	});
-		var d = dojo,
-			handle = d.subscribe(topic, this, method);
-
-		// return handles for Any widget that may need them
-		this._subscribes.push(handle);
-		return 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;
-			}
-		}
-	},
-
-	isLeftToRight: function(){
-		// summary:
-		//		Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
-		// tags:
-		//		protected
-		return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean
-	},
-
-	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");
-	},
-
-	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
-		//		contains and addChild member.
-		//
-		// description:
-		//		A convenience function provided in all _Widgets, providing a simple
-		//		shorthand mechanism to put an existing (or newly created) Widget
-		//		somewhere in the dom, and allow chaining.
-		//
-		// reference:
-		//		The String id of a domNode, a domNode reference, or a reference to a Widget posessing
-		//		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",
-		//		"before", or "after".
-		//
-		//		If passed a _Widget reference, and that widget reference has an ".addChild" method,
-		//		it will be called passing this widget instance into that method, supplying the optional
-		//		position index passed.
-		//
-		// returns:
-		//		dijit._Widget
-		//		Provides a useful return of the newly created dijit._Widget instance so you
-		//		can "chain" this function by instantiating, placing, then saving the return value
-		//		to a variable.
-		//
-		// example:
-		// | 	// create a Button with no srcNodeRef, and place it in the body:
-		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
-		// | 	// now, 'button' is still the widget reference to the newly created button
-		// | 	dojo.connect(button, "onClick", function(e){ console.log('click'); });
-		//
-		// example:
-		// |	// create a button out of a node with id="src" and append it to id="wrapper":
-		// | 	var button = new dijit.form.Button({},"src").placeAt("wrapper");
-		//
-		// example:
-		// |	// place a new button as the first element of some div
-		// |	var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
-		//
-		// example:
-		// |	// create a contentpane and add it to a TabContainer
-		// |	var tc = dijit.byId("myTabs");
-		// |	new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
-
-		if(reference.declaredClass && reference.addChild){
-			reference.addChild(this, position);
-		}else{
-			dojo.place(this.domNode, reference, position);
-		}
-		return this;
-	},
+	////////////////// MISCELLANEOUS METHODS ///////////////////
 
 	_onShow: function(){
 		// summary:
@@ -1193,3 +476,7 @@ dojo.declare("dijit._Widget", null, {
 });
 
 })();
+
+
+return dijit._Widget;
+});
diff --git a/dijit/_WidgetBase.js b/dijit/_WidgetBase.js
new file mode 100644
index 0000000..634f1bc
--- /dev/null
+++ b/dijit/_WidgetBase.js
@@ -0,0 +1,816 @@
+define("dijit/_WidgetBase", ["dojo", "dijit", "dijit/_base/manager", "dojo/Stateful"], function(dojo, dijit) {
+
+(function(){
+
+dojo.declare("dijit._WidgetBase", dojo.Stateful, {
+	// summary:
+	//		Future base class for all Dijit widgets.
+	//		_Widget extends this class adding support for various features needed by desktop.
+
+	// id: [const] String
+	//		A unique, opaque ID string that can be assigned by users or by the
+	//		system. If the developer passes an ID which is known not to be
+	//		unique, the specified ID is ignored and the system-generated ID is
+	//		used instead.
+	id: "",
+
+	// lang: [const] String
+	//		Rarely used.  Overrides the default Dojo locale used to render this widget,
+	//		as defined by the [HTML LANG](http://www.w3.org/TR/html401/struct/dirlang.html#adef-lang) attribute.
+	//		Value must be among the list of locales specified during by the Dojo bootstrap,
+	//		formatted according to [RFC 3066](http://www.ietf.org/rfc/rfc3066.txt) (like en-us).
+	lang: "",
+
+	// 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: "",
+
+	// class: String
+	//		HTML class attribute
+	"class": "",
+
+	// style: String||Object
+	//		HTML style attributes as cssText string or name/value hash
+	style: "",
+
+	// title: String
+	//		HTML title attribute.
+	//
+	//		For form widgets this specifies a tooltip to display when hovering over
+	//		the widget (just like the native HTML title attribute).
+	//
+	//		For TitlePane or for when this widget is a child of a TabContainer, AccordionContainer,
+	//		etc., it's used to specify the tab label, accordion pane title, etc.
+	title: "",
+
+	// tooltip: String
+	//		When this widget's title attribute is used to for a tab label, accordion pane title, etc.,
+	//		this specifies the tooltip to appear when the mouse is hovered over that text.
+	tooltip: "",
+
+	// baseClass: [protected] String
+	//		Root CSS class of the widget (ex: dijitTextBox), used to construct CSS classes to indicate
+	//		widget state.
+	baseClass: "",
+
+	// srcNodeRef: [readonly] DomNode
+	//		pointer to original DOM node
+	srcNodeRef: null,
+
+	// domNode: [readonly] DomNode
+	//		This is our visible representation of the widget! Other DOM
+	//		Nodes may by assigned to other properties, usually through the
+	//		template system's dojoAttachPoint syntax, but the domNode
+	//		property is the canonical "top level" node in widget UI.
+	domNode: null,
+
+	// containerNode: [readonly] DomNode
+	//		Designates where children of the source DOM node will be placed.
+	//		"Children" in this case refers to both DOM nodes and widgets.
+	//		For example, for myWidget:
+	//
+	//		|	<div dojoType=myWidget>
+	//		|		<b> here's a plain DOM node
+	//		|		<span dojoType=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>
+	//		|		<i> and another plain DOM node </i>
+	//
+	//		In templated widgets, "containerNode" is set via a
+	//		dojoAttachPoint assignment.
+	//
+	//		containerNode must be defined for any widget that accepts innerHTML
+	//		(like ContentPane or BorderContainer or even Button), and conversely
+	//		is null for widgets that don't, like TextBox.
+	containerNode: null,
+
+/*=====
+	// _started: Boolean
+	//		startup() has completed.
+	_started: false,
+=====*/
+
+	// attributeMap: [protected] Object
+	//		attributeMap sets up a "binding" between attributes (aka properties)
+	//		of the widget and the widget's DOM.
+	//		Changes to widget attributes listed in attributeMap will be
+	//		reflected into the DOM.
+	//
+	//		For example, calling set('title', 'hello')
+	//		on a TitlePane will automatically cause the TitlePane's DOM to update
+	//		with the new title.
+	//
+	//		attributeMap is a hash where the key is an attribute of the widget,
+	//		and the value reflects a binding to a:
+	//
+	//		- DOM node attribute
+	// |		focus: {node: "focusNode", type: "attribute"}
+	// 		Maps this.focus to this.focusNode.focus
+	//
+	//		- DOM node innerHTML
+	//	|		title: { node: "titleNode", type: "innerHTML" }
+	//		Maps this.title to this.titleNode.innerHTML
+	//
+	//		- DOM node innerText
+	//	|		title: { node: "titleNode", type: "innerText" }
+	//		Maps this.title to this.titleNode.innerText
+	//
+	//		- DOM node CSS class
+	// |		myClass: { node: "domNode", type: "class" }
+	//		Maps this.myClass to this.domNode.className
+	//
+	//		If the value is an array, then each element in the array matches one of the
+	//		formats of the above list.
+	//
+	//		There are also some shorthands for backwards compatibility:
+	//		- string --> { node: string, type: "attribute" }, for example:
+	//	|	"focusNode" ---> { node: "focusNode", type: "attribute" }
+	//		- "" --> { node: "domNode", type: "attribute" }
+	attributeMap: {id:"", dir:"", lang:"", "class":"", style:"", title:""},
+
+	// _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(),
+
+	//////////// INITIALIZATION METHODS ///////////////////////////////////////
+
+	postscript: function(/*Object?*/params, /*DomNode|String*/srcNodeRef){
+		// summary:
+		//		Kicks off widget instantiation.  See create() for details.
+		// tags:
+		//		private
+		this.create(params, srcNodeRef);
+	},
+
+	create: function(/*Object?*/params, /*DomNode|String?*/srcNodeRef){
+		// summary:
+		//		Kick off the life-cycle of a widget
+		// params:
+		//		Hash of initialization parameters for widget, including
+		//		scalar values (like title, duration etc.) and functions,
+		//		typically callbacks like onClick.
+		// srcNodeRef:
+		//		If a srcNodeRef (DOM node) is specified:
+		//			- use srcNodeRef.innerHTML as my contents
+		//			- if this is a behavioral widget then apply behavior
+		//			  to that srcNodeRef
+		//			- otherwise, replace srcNodeRef with my generated DOM
+		//			  tree
+		// description:
+		//		Create calls a number of widget methods (postMixInProperties, buildRendering, postCreate,
+		//		etc.), some of which of you'll want to override. See http://docs.dojocampus.org/dijit/_Widget
+		//		for a discussion of the widget creation lifecycle.
+		//
+		//		Of course, adventurous developers could override create entirely, but this should
+		//		only be done as a last resort.
+		// tags:
+		//		private
+
+		// store pointer to original DOM tree
+		this.srcNodeRef = dojo.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()
+		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 = [];
+
+		// mix in our passed parameters
+		if(this.srcNodeRef && (typeof this.srcNodeRef.id == "string")){ this.id = this.srcNodeRef.id; }
+		if(params){
+			this.params = params;
+			dojo._mixin(this, params);
+		}
+		this.postMixInProperties();
+
+		// generate an id for the widget if one wasn't specified
+		// (be sure to do this before buildRendering() because that function might
+		// expect the id to be there.)
+		if(!this.id){
+			this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+		}
+		dijit.registry.add(this);
+
+		this.buildRendering();
+
+		if(this.domNode){
+			// Copy attributes listed in attributeMap into the [newly created] DOM for the widget.
+			// Also calls custom setters for all attributes with custom setters.
+			this._applyAttributes();
+
+			// If srcNodeRef was specified, then swap out original srcNode for this widget's DOM tree.
+			// For 2.0, move this after postCreate().  postCreate() shouldn't depend on the
+			// widget being attached to the DOM since it isn't when a widget is created programmatically like
+			// new MyWidget({}).   See #11635.
+			var source = this.srcNodeRef;
+			if(source && source.parentNode && this.domNode !== source){
+				source.parentNode.replaceChild(this.domNode, source);
+			}
+		}
+
+		if(this.domNode){
+			// Note: for 2.0 may want to rename widgetId to dojo._scopeName + "_widgetId",
+			// assuming that dojo._scopeName even exists in 2.0
+			this.domNode.setAttribute("widgetId", this.id);
+		}
+		this.postCreate();
+
+		// If srcNodeRef has been processed and removed from the DOM (e.g. TemplatedWidget) then delete it to allow GC.
+		if(this.srcNodeRef && !this.srcNodeRef.parentNode){
+			delete this.srcNodeRef;
+		}
+
+		this._created = true;
+	},
+
+	_applyAttributes: function(){
+		// summary:
+		//		Step during widget creation to copy all widget attributes to the
+		//		DOM as per attributeMap and _setXXXAttr functions.
+		// description:
+		//		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
+		// 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);
+			}
+		}, 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;
+			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));
+				}
+			}
+		}
+		return ctor._setterAttrs;	// String[]
+	},
+
+	postMixInProperties: function(){
+		// summary:
+		//		Called after the parameters to the widget have been read-in,
+		//		but before the widget template is instantiated. Especially
+		//		useful to set properties that are referenced in the widget
+		//		template.
+		// tags:
+		//		protected
+	},
+
+	buildRendering: function(){
+		// summary:
+		//		Construct the UI for this widget, setting this.domNode
+		// description:
+		//		Most widgets will mixin `dijit._Templated`, 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');
+		}
+
+		// baseClass is a single class name or occasionally a space-separated list of names.
+		// Add those classes to the DOMNode.  If RTL mode then also add with Rtl suffix.
+		// TODO: make baseClass custom setter
+		if(this.baseClass){
+			var classes = this.baseClass.split(" ");
+			if(!this.isLeftToRight()){
+				classes = classes.concat( dojo.map(classes, function(name){ return name+"Rtl"; }));
+			}
+			dojo.addClass(this.domNode, classes);
+		}
+	},
+
+	postCreate: function(){
+		// summary:
+		//		Processing after the DOM fragment is created
+		// description:
+		//		Called after the DOM fragment has been created, but not necessarily
+		//		added to the document.  Do not include any operations which rely on
+		//		node dimensions or placement.
+		// tags:
+		//		protected
+	},
+
+	startup: function(){
+		// summary:
+		//		Processing after the DOM fragment is added to the document
+		// description:
+		//		Called after a widget and its children have been created and added to the page,
+		//		and all related widgets have finished their create() cycle, up through postCreate().
+		//		This is useful for composite widgets that need to control or layout sub-widgets.
+		//		Many layout widgets can use this as a wiring phase.
+		this._started = true;
+	},
+
+	//////////// DESTROY FUNCTIONS ////////////////////////////////
+
+	destroyRecursive: function(/*Boolean?*/ preserveDom){
+		// summary:
+		// 		Destroy this widget and its descendants
+		// description:
+		//		This is the generic "destructor" function that all widget users
+		// 		should call to cleanly discard with a widget. Once a widget is
+		// 		destroyed, it is removed from the manager object.
+		// preserveDom:
+		//		If true, this method will leave the original DOM structure
+		//		alone of descendant Widgets. Note: This will NOT work with
+		//		dijit._Templated widgets.
+
+		this._beingDestroyed = true;
+		this.destroyDescendants(preserveDom);
+		this.destroy(preserveDom);
+	},
+
+	destroy: function(/*Boolean*/ preserveDom){
+		// summary:
+		// 		Destroy this widget, but not its descendants.
+		//		This method will, however, destroy internal widgets such as those used within a template.
+		// preserveDom: Boolean
+		//		If true, this method will leave the original DOM structure alone.
+		//		Note: This will not yet work with _Templated widgets
+
+		this._beingDestroyed = true;
+		this.uninitialize();
+		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);
+		});
+
+		// destroy widgets created as part of template, etc.
+		dfe(this._supportingWidgets || [], function(w){
+			if(w.destroyRecursive){
+				w.destroyRecursive();
+			}else if(w.destroy){
+				w.destroy();
+			}
+		});
+
+		this.destroyRendering(preserveDom);
+		dijit.registry.remove(this.id);
+		this._destroyed = true;
+	},
+
+	destroyRendering: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Destroys the DOM nodes associated with this widget
+		// preserveDom:
+		//		If true, this method will leave the original DOM structure alone
+		//		during tear-down. Note: this will not work with _Templated
+		//		widgets yet.
+		// tags:
+		//		protected
+
+		if(this.bgIframe){
+			this.bgIframe.destroy(preserveDom);
+			delete this.bgIframe;
+		}
+
+		if(this.domNode){
+			if(preserveDom){
+				dojo.removeAttr(this.domNode, "widgetId");
+			}else{
+				dojo.destroy(this.domNode);
+			}
+			delete this.domNode;
+		}
+
+		if(this.srcNodeRef){
+			if(!preserveDom){
+				dojo.destroy(this.srcNodeRef);
+			}
+			delete this.srcNodeRef;
+		}
+	},
+
+	destroyDescendants: function(/*Boolean?*/ preserveDom){
+		// summary:
+		//		Recursively destroy the children of this widget and their
+		//		descendants.
+		// preserveDom:
+		//		If true, the preserveDom attribute is passed to all descendant
+		//		widget's .destroy() method. Not for use with _Templated
+		//		widgets.
+
+		// get all direct descendants and destroy them recursively
+		dojo.forEach(this.getChildren(), function(widget){
+			if(widget.destroyRecursive){
+				widget.destroyRecursive(preserveDom);
+			}
+		});
+	},
+
+	uninitialize: function(){
+		// summary:
+		//		Stub function. Override to implement custom widget tear-down
+		//		behavior.
+		// tags:
+		//		protected
+		return false;
+	},
+
+	////////////////// 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,
+		//		which is either a hash like {height: "5px", width: "3px"}
+		//		or a plain string
+		// description:
+		//		Determines which node to set the style on based on style setting
+		//		in attributeMap.
+		// tags:
+		//		protected
+
+		var mapNode = this[this.attributeMap.style || '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);
+		}else{
+			if(mapNode.style.cssText){
+				mapNode.style.cssText += "; " + value;
+			}else{
+				mapNode.style.cssText = value;
+			}
+		}
+
+		this._set("style", value);
+	},
+
+	_attrToDom: function(/*String*/ attr, /*String*/ value){
+		// summary:
+		//		Reflect a widget attribute (title, tabIndex, duration etc.) to
+		//		the widget DOM, as specified in 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){
+
+			// Get target node and what we are doing to that node
+			var mapNode = this[command.node || command || "domNode"];	// DOM node
+			var type = command.type || "attribute";	// class, innerHTML, innerText, or attribute
+
+			switch(type){
+				case "attribute":
+					if(dojo.isFunction(value)){ // functions execute in the context of the widget
+						value = dojo.hitch(this, value);
+					}
+
+					// Get the name of the DOM node attribute; usually it's the same
+					// as the name of the attribute in the widget (attr), but can be overridden.
+					// Also maps handler names to lowercase, like onSubmit --> onsubmit
+					var attrName = command.attribute ? command.attribute :
+						(/^on[A-Z][a-zA-Z]*$/.test(attr) ? attr.toLowerCase() : attr);
+
+					dojo.attr(mapNode, attrName, value);
+					break;
+				case "innerText":
+					mapNode.innerHTML = "";
+					mapNode.appendChild(dojo.doc.createTextNode(value));
+					break;
+				case "innerHTML":
+					mapNode.innerHTML = value;
+					break;
+				case "class":
+					dojo.replaceClass(mapNode, value, this[attr]);
+					break;
+			}
+		}, this);
+	},
+
+	get: function(name){
+		// summary:
+		//		Get a property from a widget.
+		//	name:
+		//		The property to get.
+		// description:
+		//		Get a named property from a widget. The property may
+		//		potentially be retrieved via a getter method. If no getter is defined, this
+		// 		just retrieves the object's property.
+		// 		For example, if the widget has 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;
+		var names = this._getAttrNames(name);
+		return this[names.g] ? this[names.g]() : this[name];
+	},
+	
+	set: function(name, value){
+		// summary:
+		//		Set a property on a widget
+		//	name:
+		//		The property to set.
+		//	value:
+		//		The value to set in the property.
+		// description:
+		//		Sets named properties on a widget which may potentially be handled by a
+		// 		setter in the widget.
+		// 		For example, if the widget has 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:
+		//	|	myWidget.set({
+		//	|		foo: "Howdy",
+		//	|		bar: 3
+		//	|	})
+		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+
+		if(typeof name === "object"){
+			for(var x in name){
+				this.set(x, name[x]);
+			}
+			return this;
+		}
+		var names = this._getAttrNames(name);
+		if(this[names.s]){
+			// use the explicit setter
+			var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
+		}else{
+			// if param is specified as DOM node attribute, copy it
+			if(name in this.attributeMap){
+				this._attrToDom(name, value);
+			}
+			this._set(name, value);
+		}
+		return result || this;
+	},
+	
+	_attrPairNames: {},		// shared between all widgets
+	_getAttrNames: function(name){
+		// summary:
+		//		Helper function for get() and set().
+		//		Caches attribute name values so we don't do the string ops every time.
+		// tags:
+		//		private
+
+		var apn = this._attrPairNames;
+		if(apn[name]){ return apn[name]; }
+		var uc = name.charAt(0).toUpperCase() + name.substr(1);
+		return (apn[name] = {
+			n: name+"Node",
+			s: "_set"+uc+"Attr",
+			g: "_get"+uc+"Attr"
+		});
+	},
+
+	_set: function(/*String*/ name, /*anything*/ value){
+		// summary:
+		//		Helper function to set new value for specified attribute, and call handlers
+		//		registered with watch() if the value has changed.
+		var oldValue = this[name];
+		this[name] = value;
+		if(this._watchCallbacks && this._created && value !== oldValue){
+			this._watchCallbacks(name, oldValue, value);
+		}
+	},
+
+	toString: function(){
+		// summary:
+		//		Returns a string that represents the widget
+		// description:
+		//		When a widget is cast to a string, this method will be used to generate the
+		//		output. Currently, it does not implement any sort of reversible
+		//		serialization.
+		return '[Widget ' + this.declaredClass + ', ' + (this.id || 'NO ID') + ']'; // String
+	},
+
+	getDescendants: 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[]
+	},
+
+	getChildren: function(){
+		// summary:
+		//		Returns all the widgets contained by this, i.e., all widgets underneath this.containerNode.
+		//		Does not return nested widgets, nor widgets that are part of this widget's template.
+		return this.containerNode ? dijit.findWidgets(this.containerNode) : []; // dijit._Widget[]
+	},
+
+	connect: function(
+			/*Object|null*/ obj,
+			/*String|Function*/ event,
+			/*String|Function*/ method){
+		// summary:
+		//		Connects specified obj/event to specified method of this object
+		//		and registers for disconnect() on widget destroy.
+		// description:
+		//		Provide widget-specific analog to dojo.connect, except with the
+		//		implicit use of this widget as the target object.
+		//		Events connected with `this.connect` are disconnected upon
+		//		destruction.
+		// returns:
+		//		A handle that can be passed to `disconnect` in order to disconnect before
+		//		the widget is destroyed.
+		// example:
+		//	|	var btn = new dijit.form.Button();
+		//	|	// when foo.bar() is called, call the listener we're going to
+		//	|	// provide in the scope of btn
+		//	|	btn.connect(foo, "bar", function(){
+		//	|		console.debug(this.toString());
+		//	|	});
+		// tags:
+		//		protected
+
+		var handles = [dojo._connect(obj, event, this, method)];
+		this._connects.push(handles);
+		return handles;		// _Widget.Handle
+	},
+
+	disconnect: function(/* _Widget.Handle */ handles){
+		// 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;
+			}
+		}
+	},
+
+	subscribe: function(
+			/*String*/ topic,
+			/*String|Function*/ 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.
+		// example:
+		//	|	var btn = new dijit.form.Button();
+		//	|	// when /my/topic is published, this button changes its label to
+		//	|   // be the parameter of the topic.
+		//	|	btn.subscribe("/my/topic", function(v){
+		//	|		this.set("label", v);
+		//	|	});
+		var handle = dojo.subscribe(topic, this, method);
+
+		// return handles for Any widget that may need them
+		this._subscribes.push(handle);
+		return 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;
+			}
+		}
+	},
+
+	isLeftToRight: function(){
+		// summary:
+		//		Return this widget's explicit or implicit orientation (true for LTR, false for RTL)
+		// tags:
+		//		protected
+		return this.dir ? (this.dir == "ltr") : dojo._isBodyLtr(); //Boolean
+	},
+
+	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
+		//		contains and addChild member.
+		//
+		// description:
+		//		A convenience function provided in all _Widgets, providing a simple
+		//		shorthand mechanism to put an existing (or newly created) Widget
+		//		somewhere in the dom, and allow chaining.
+		//
+		// reference:
+		//		The String id of a domNode, a domNode reference, or a reference to a Widget posessing
+		//		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",
+		//		"before", or "after".
+		//
+		//		If passed a _Widget reference, and that widget reference has an ".addChild" method,
+		//		it will be called passing this widget instance into that method, supplying the optional
+		//		position index passed.
+		//
+		// returns:
+		//		dijit._Widget
+		//		Provides a useful return of the newly created dijit._Widget instance so you
+		//		can "chain" this function by instantiating, placing, then saving the return value
+		//		to a variable.
+		//
+		// example:
+		// | 	// create a Button with no srcNodeRef, and place it in the body:
+		// | 	var button = new dijit.form.Button({ label:"click" }).placeAt(dojo.body());
+		// | 	// now, 'button' is still the widget reference to the newly created button
+		// | 	dojo.connect(button, "onClick", function(e){ console.log('click'); });
+		//
+		// example:
+		// |	// create a button out of a node with id="src" and append it to id="wrapper":
+		// | 	var button = new dijit.form.Button({},"src").placeAt("wrapper");
+		//
+		// example:
+		// |	// place a new button as the first element of some div
+		// |	var button = new dijit.form.Button({ label:"click" }).placeAt("wrapper","first");
+		//
+		// example:
+		// |	// create a contentpane and add it to a TabContainer
+		// |	var tc = dijit.byId("myTabs");
+		// |	new dijit.layout.ContentPane({ href:"foo.html", title:"Wow!" }).placeAt(tc)
+
+		if(reference.declaredClass && reference.addChild){
+			reference.addChild(this, position);
+		}else{
+			dojo.place(this.domNode, reference, position);
+		}
+		return this;
+	}
+});
+
+})();
+
+
+return dijit._WidgetBase;
+});
diff --git a/dijit/_base.js b/dijit/_base.js
index c5f6673..b36827d 100644
--- a/dijit/_base.js
+++ b/dijit/_base.js
@@ -1,11 +1,6 @@
-dojo.provide("dijit._base");
+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) {
 
-dojo.require("dijit._base.focus");
-dojo.require("dijit._base.manager");
-dojo.require("dijit._base.place");
-dojo.require("dijit._base.popup");
-dojo.require("dijit._base.scroll");
-dojo.require("dijit._base.sniff");
-dojo.require("dijit._base.typematic");
-dojo.require("dijit._base.wai");
-dojo.require("dijit._base.window");
+
+
+return dijit._base;
+});
diff --git a/dijit/_base/focus.js b/dijit/_base/focus.js
index 231a7df..4f69e96 100644
--- a/dijit/_base/focus.js
+++ b/dijit/_base/focus.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit._base.focus");
-
-dojo.require("dojo.window");
-dojo.require("dijit._base.manager");	// for dijit.isTabNavigable()
+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.
@@ -57,6 +54,9 @@ dojo.mixin(dijit, {
 						}
 					}
 					bm = {isCollapsed:true};
+					if(sel.rangeCount){
+						bm.mark = sel.getRangeAt(0).cloneRange();
+					}
 				}else{
 					rg = sel.getRangeAt(0);
 					bm = {isCollapsed: false, mark: rg.cloneRange()};
@@ -304,7 +304,7 @@ dojo.mixin(dijit, {
 		var doc = dojo.isIE ? targetWindow.document.documentElement : targetWindow.document;
 		if(doc){
 			if(dojo.isIE){
-				doc.attachEvent('onmousedown', mousedownListener);
+				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....
@@ -322,13 +322,13 @@ dojo.mixin(dijit, {
 				doc.attachEvent('ondeactivate', deactivateListener);
 
 				return function(){
-					doc.detachEvent('onmousedown', mousedownListener);
+					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.addEventListener('mousedown', mousedownListener, true);
+				doc.body.addEventListener('mousedown', mousedownListener, true);
 				var focusListener = function(evt){
 					dijit._onFocusNode(effectiveNode || evt.target);
 				};
@@ -339,7 +339,7 @@ dojo.mixin(dijit, {
 				doc.addEventListener('blur', blurListener, true);
 
 				return function(){
-					doc.removeEventListener('mousedown', mousedownListener, true);
+					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)
@@ -480,6 +480,7 @@ dojo.mixin(dijit, {
 			widget = dijit.byId(oldStack[i]);
 			if(widget){
 				widget._focused = false;
+				widget.set("focused", false);
 				widget._hasBeenBlurred = true;
 				if(widget._onBlur){
 					widget._onBlur(by);
@@ -493,6 +494,7 @@ dojo.mixin(dijit, {
 			widget = dijit.byId(newStack[i]);
 			if(widget){
 				widget._focused = true;
+				widget.set("focused", true);
 				if(widget._onFocus){
 					widget._onFocus(by);
 				}
@@ -512,3 +514,7 @@ dojo.addOnLoad(function(){
 		})
 	}
 });
+
+
+return dijit;
+});
diff --git a/dijit/_base/manager.js b/dijit/_base/manager.js
index 57bd9a8..7c38332 100644
--- a/dijit/_base/manager.js
+++ b/dijit/_base/manager.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._base.manager");
+define("dijit/_base/manager", ["dojo", "dijit"], function(dojo, dijit) {
 
 dojo.declare("dijit.WidgetSet", null, {
 	// summary:
@@ -255,7 +255,10 @@ dojo.declare("dijit.WidgetSet", null, {
 				if(node.nodeType == 1){
 					var widgetId = node.getAttribute("widgetId");
 					if(widgetId){
-						outAry.push(hash[widgetId]);
+						var widget = hash[widgetId];
+						if(widget){	// may be null on page w/multiple dojo's loaded
+							outAry.push(widget);
+						}
 					}else{
 						getChildrenHelper(node);
 					}
@@ -345,29 +348,25 @@ dojo.declare("dijit.WidgetSet", null, {
 				return true;
 			case "iframe":
 				// If it's an editor <iframe> then it's tab navigable.
-				//TODO: feature detect "designMode" in elem.contentDocument?
-				if(dojo.isMoz){
-					try{
-						return elem.contentDocument.designMode == "on";
-					}catch(err){
-						return false;
+				var body;
+				try{
+					// non-IE
+					var contentDocument = elem.contentDocument;
+					if("designMode" in contentDocument && contentDocument.designMode == "on"){
+						return true;
 					}
-				}else if(dojo.isWebKit){
-					var doc = elem.contentDocument,
-						body = doc && doc.body;
-					return body && body.contentEditable == 'true';
-				}else{
+					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{
-						doc = elem.contentWindow.document;
-						body = doc && doc.body;
-						return body && body.firstChild && body.firstChild.contentEditable == 'true';
-					}catch(e){
+						body = elem.contentWindow.document.body;
+					}catch(e2){
 						return false;
 					}
 				}
+				return body.contentEditable == 'true' || (body.firstChild && body.firstChild.contentEditable == 'true');
 			default:
 				return elem.contentEditable == 'true';
 		}
@@ -403,7 +402,13 @@ dojo.declare("dijit.WidgetSet", null, {
 		//		  positive tabIndex value
 		//		* the last element in document order with the highest
 		//		  positive tabIndex value
-		var first, last, lowest, lowestTabindex, highest, highestTabindex;
+		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,
@@ -427,6 +432,10 @@ dojo.declare("dijit.WidgetSet", null, {
 							highest = child;
 						}
 					}
+					var rn = radioName(child);
+					if(dojo.attr(child, "checked") && rn) {
+						radioSelected[rn] = child;
+					}
 				}
 				if(child.nodeName.toUpperCase() != 'SELECT'){
 					walkTree(child);
@@ -434,7 +443,11 @@ dojo.declare("dijit.WidgetSet", null, {
 			});
 		};
 		if(shown(root)){ walkTree(root) }
-		return { first: first, last: last, lowest: lowest, highest: highest };
+		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:
@@ -466,3 +479,7 @@ dojo.declare("dijit.WidgetSet", null, {
 	dijit.defaultDuration = dojo.config["defaultDuration"] || 200;
 
 })();
+
+
+return dijit;
+});
diff --git a/dijit/_base/place.js b/dijit/_base/place.js
index c357682..1d39c62 100644
--- a/dijit/_base/place.js
+++ b/dijit/_base/place.js
@@ -1,8 +1,4 @@
-dojo.provide("dijit._base.place");
-
-dojo.require("dojo.window");
-dojo.require("dojo.AdapterRegistry");
-
+define("dijit/_base/place", ["dojo", "dijit", "dojo/window", "dojo/AdapterRegistry"], function(dojo, dijit) {
 
 dijit.getViewport = function(){
 	// summary:
@@ -63,16 +59,22 @@ dijit.placeOnScreen = function(
 	return dijit._place(node, choices);
 }
 
-dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ layoutNode){
+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)
+	// 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
@@ -89,12 +91,20 @@ dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ la
 	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 tooltips size changes based on position, due to triangle)
+		// a tooltip's size changes based on position, due to triangle)
 		if(layoutNode){
-			layoutNode(node, choice.aroundCorner, corner);
+			var res = layoutNode(node, choice.aroundCorner, corner, spaceAvailable, aroundNodeCoords);
+			overflow = typeof res == "undefined" ? 0 : res;
 		}
 
 		// get node's size
@@ -114,8 +124,9 @@ dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ la
 			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);
+			height = endY - startY;
+
+		overflow += (mb.w - width) + (mb.h - height);
 
 		if(best == null || overflow < best.overflow){
 			best = {
@@ -125,17 +136,32 @@ dijit._place = function(/*DomNode*/ node, /* Array */ choices, /* Function */ la
 				y: startY,
 				w: width,
 				h: height,
-				overflow: overflow
+				overflow: overflow,
+				spaceAvailable: spaceAvailable
 			};
 		}
+		
 		return !overflow;
 	});
 
-	node.style.left = best.x + "px";
-	node.style.top = best.y + "px";
+	// 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);
+		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;
 }
 
@@ -182,11 +208,7 @@ dijit.placeOnScreenAroundNode = function(
 
 	// get coordinates of aroundNode
 	aroundNode = dojo.byId(aroundNode);
-	var oldDisplay = aroundNode.style.display;
-	aroundNode.style.display="";
-	// #3172: use the slightly tighter border box instead of marginBox
 	var aroundNodePos = dojo.position(aroundNode, true);
-	aroundNode.style.display=oldDisplay;
 
 	// place the node around the calculated rectangle
 	return dijit._placeOnScreenAroundRect(node,
@@ -257,7 +279,7 @@ dijit._placeOnScreenAroundRect = function(
 		});
 	}
 
-	return dijit._place(node, choices, layoutNode);
+	return dijit._place(node, choices, layoutNode, {w: width, h: height});
 };
 
 dijit.placementRegistry= new dojo.AdapterRegistry();
@@ -317,11 +339,17 @@ dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToR
 			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)
@@ -332,3 +360,7 @@ dijit.getPopupAroundAlignment = function(/*Array*/ position, /*Boolean*/ leftToR
 	});
 	return align;
 };
+
+
+return dijit;
+});
diff --git a/dijit/_base/popup.js b/dijit/_base/popup.js
index 80b42fe..42f457b 100644
--- a/dijit/_base/popup.js
+++ b/dijit/_base/popup.js
@@ -1,8 +1,4 @@
-dojo.provide("dijit._base.popup");
-
-dojo.require("dijit._base.focus");
-dojo.require("dijit._base.place");
-dojo.require("dijit._base.window");
+define("dijit/_base/popup", ["dojo", "dijit", "dijit/_base/focus", "dijit/_base/place", "dijit/_base/window"], function(dojo, dijit) {
 
 /*=====
 dijit.popup.__OpenArgs = function(){
@@ -75,48 +71,77 @@ dijit.popup = {
 
 	_idGen: 1,
 
-	moveOffScreen: function(/*DomNode*/ node){
+	_createWrapper: function(/*Widget || DomNode*/ widget){
 		// summary:
-		//		Initialization for nodes that will be used as popups
-		//
-		// description:
-		//		Puts node inside a wrapper <div>, and
-		//		positions wrapper div off screen, but not display:none, so that
-		//		the widget doesn't appear in the page flow and/or cause a blank
-		//		area at the bottom of the viewport (making scrollbar longer), but
-		//		initialization of contained widgets works correctly
-
-		var wrapper = node.parentNode;
-
-		// Create a wrapper widget for when this node (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
-		if(!wrapper || !dojo.hasClass(wrapper, "dijitPopup")){
+		//		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:{
-					visibility:"hidden",
-					top: "-9999px"
-				}
+				style:{ display: "none"},
+				role: "presentation"
 			}, dojo.body());
-			dijit.setWaiRole(wrapper, "presentation");
 			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.
 
-		var s = node.style;
-		s.display = "";
-		s.visibility = "";
-		s.position = "";
-		s.top = "0px";
+		// Create wrapper if not already there
+		var wrapper = this._createWrapper(widget);
 
 		dojo.style(wrapper, {
 			visibility: "hidden",
-			// prevent transient scrollbar causing misalign (#5776), and initial flash in upper left (#10111)
-			top: "-9999px"
+			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.
@@ -153,14 +178,17 @@ dijit.popup = {
 			around = args.around,
 			id = (args.around && args.around.id) ? (args.around.id+"_dropdown") : ("popup_"+this._idGen++);
 
-
-		// The wrapper may have already been created, but in case it wasn't, create here
-		var wrapper = widget.domNode.parentNode;
-		if(!wrapper || !dojo.hasClass(wrapper, "dijitPopup")){
-			this.moveOffScreen(widget.domNode);
-			wrapper = widget.domNode.parentNode;
+		// 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: {
@@ -171,9 +199,9 @@ dijit.popup = {
 		});
 
 		if(dojo.isIE || dojo.isMoz){
-			var iframe = wrapper.childNodes[1];
-			if(!iframe){
-				iframe = new dijit.BackgroundIframe(wrapper);
+			if(!widget.bgIframe){
+				// setting widget.bgIframe triggers cleanup in _Widget.destroy()
+				widget.bgIframe = new dijit.BackgroundIframe(wrapper);
 			}
 		}
 
@@ -182,6 +210,7 @@ dijit.popup = {
 			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
 
@@ -216,8 +245,6 @@ dijit.popup = {
 		}));
 
 		stack.push({
-			wrapper: wrapper,
-			iframe: iframe,
 			widget: widget,
 			parent: args.parent,
 			onExecute: args.onExecute,
@@ -234,9 +261,10 @@ dijit.popup = {
 		return best;
 	},
 
-	close: function(/*dijit._Widget*/ popup){
+	close: function(/*dijit._Widget?*/ popup){
 		// summary:
-		//		Close specified popup and any popups that it parented
+		//		Close specified popup and any popups that it parented.
+		//		If no popup is specified, closes all popups.
 
 		var stack = this._stack;
 
@@ -245,10 +273,9 @@ dijit.popup = {
 		// 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(dojo.some(stack, function(elem){return elem.widget == popup;})){
+		while((popup && dojo.some(stack, function(elem){return elem.widget == popup;})) ||
+			(!popup && stack.length)){
 			var top = stack.pop(),
-				wrapper = top.wrapper,
-				iframe = top.iframe,
 				widget = top.widget,
 				onClose = top.onClose;
 
@@ -258,11 +285,9 @@ dijit.popup = {
 			}
 			dojo.forEach(top.handlers, dojo.disconnect);
 
-			// Move the widget plus it's wrapper off screen, unless it has already been destroyed in above onClose() etc.
+			// Hide the widget and it's wrapper unless it has already been destroyed in above onClose() etc.
 			if(widget && widget.domNode){
-				this.moveOffScreen(widget.domNode);
-			}else{
-				dojo.destroy(wrapper);
+				this.hide(widget);
 			}
                         
 			if(onClose){
@@ -272,9 +297,12 @@ dijit.popup = {
 	}
 };
 
+// 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(){
@@ -283,7 +311,7 @@ dijit._frames = new function(){
 			iframe = queue.pop();
 			iframe.style.display="";
 		}else{
-			if(dojo.isIE){
+			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;"
@@ -295,7 +323,7 @@ dijit._frames = new function(){
 				iframe.className = "dijitBackgroundIframe";
 				dojo.style(iframe, "opacity", 0.1);
 			}
-			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didnt work.
+			iframe.tabIndex = -1; // Magic to prevent iframe from getting focus on tab keypress - as style didn't work.
 			dijit.setWaiRole(iframe,"presentation");
 		}
 		return iframe;
@@ -308,7 +336,7 @@ dijit._frames = new function(){
 }();
 
 
-dijit.BackgroundIframe = function(/* DomNode */node){
+dijit.BackgroundIframe = function(/*DomNode*/ node){
 	// summary:
 	//		For IE/FF z-index schenanigans. id attribute is required.
 	//
@@ -319,9 +347,9 @@ dijit.BackgroundIframe = function(/* DomNode */node){
 
 	if(!node.id){ throw new Error("no id"); }
 	if(dojo.isIE || dojo.isMoz){
-		var iframe = dijit._frames.pop();
+		var iframe = (this.iframe = dijit._frames.pop());
 		node.appendChild(iframe);
-		if(dojo.isIE<7){
+		if(dojo.isIE<7 || dojo.isQuirks){
 			this.resize(node);
 			this._conn = dojo.connect(node, 'onresize', this, function(){
 				this.resize(node);
@@ -332,19 +360,15 @@ dijit.BackgroundIframe = function(/* DomNode */node){
 				height: '100%'
 			});
 		}
-		this.iframe = iframe;
 	}
 };
 
 dojo.extend(dijit.BackgroundIframe, {
 	resize: function(node){
 		// summary:
-		// 		resize the iframe so its the same size as node
-		// description:
-		//		this function is a no-op in all browsers except
-		//		IE6, which does not support 100% width/height 
-		//		of absolute positioned iframes
-		if(this.iframe && dojo.isIE<7){
+		// 		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'
@@ -364,3 +388,6 @@ dojo.extend(dijit.BackgroundIframe, {
 		}
 	}
 });
+
+return dijit.popup;
+});
diff --git a/dijit/_base/scroll.js b/dijit/_base/scroll.js
index 651d5d1..6a3508e 100644
--- a/dijit/_base/scroll.js
+++ b/dijit/_base/scroll.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit._base.scroll");
-
-dojo.require("dojo.window");
+define("dijit/_base/scroll", ["dojo", "dijit", "dojo/window"], function(dojo, dijit) {
 
 dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 	// summary:
@@ -9,3 +7,7 @@ dijit.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 	
 	dojo.window.scrollIntoView(node, pos);
 };
+
+
+return dijit.scrollIntoView;
+});
diff --git a/dijit/_base/sniff.js b/dijit/_base/sniff.js
index e6db29c..9524e85 100644
--- a/dijit/_base/sniff.js
+++ b/dijit/_base/sniff.js
@@ -1,3 +1,5 @@
+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.
@@ -5,6 +7,6 @@
 //		Simply doing a require on this module will
 //		establish this CSS.  Modified version of Morris' CSS hack.
 
-dojo.provide("dijit._base.sniff");
 
-dojo.require("dojo.uacss");
+return dijit;
+});
diff --git a/dijit/_base/typematic.js b/dijit/_base/typematic.js
index 6702705..2054683 100644
--- a/dijit/_base/typematic.js
+++ b/dijit/_base/typematic.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._base.typematic");
+define("dijit/_base/typematic", ["dojo", "dijit"], function(dojo, dijit) {
 
 dijit.typematic = {
 	// summary:
@@ -177,3 +177,7 @@ dijit.typematic = {
 			this.addMouseListener(mouseNode, _this, callback, subsequentDelay, initialDelay, minDelay));
 	}
 };
+
+
+return dijit.typematic;
+});
diff --git a/dijit/_base/wai.js b/dijit/_base/wai.js
index 16c8289..c631934 100644
--- a/dijit/_base/wai.js
+++ b/dijit/_base/wai.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._base.wai");
+define("dijit/_base/wai", ["dojo", "dijit"], function(dojo, dijit) {
 
 dijit.wai = {
 	onload: function(){
@@ -45,26 +45,24 @@ if(dojo.isIE || dojo.isMoz){	// NOTE: checking in Safari messes things up
 }
 
 dojo.mixin(dijit, {
-	_XhtmlRoles: /banner|contentinfo|definition|main|navigation|search|note|secondary|seealso/,
-
-	hasWaiRole: function(/*Element*/ elem, /*String*/ role){
+	hasWaiRole: function(/*Element*/ elem, /*String?*/ role){
 		// summary:
-		//		Determines if an element has a particular non-XHTML role.
+		//		Determines if an element has a particular role.
 		// returns:
-		//		True if elem has the specific non-XHTML role attribute and false if not.
+		//		True if elem has the specific role attribute and false if not.
 		// 		For backwards compatibility if role parameter not provided,
-		// 		returns true if has non XHTML role
+		// 		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 non-XHTML role for an element (which should be a wai role).
+		//		Gets the role for an element (which should be a wai role).
 		// returns:
-		//		The non-XHTML role of elem or an empty string if elem
+		//		The role of elem or an empty string if elem
 		//		does not have a role.
-		 return dojo.trim((dojo.attr(elem, "role") || "").replace(this._XhtmlRoles,"").replace("wairole:",""));
+		 return dojo.trim((dojo.attr(elem, "role") || "").replace("wairole:",""));
 	},
 
 	setWaiRole: function(/*Element*/ elem, /*String*/ role){
@@ -72,24 +70,13 @@ dojo.mixin(dijit, {
 		//		Sets the role on an element.
 		// description:
 		//		Replace existing role attribute with new role.
-		//		If elem already has an XHTML role, append this role to XHTML role
-		//		and remove other ARIA roles.
 
-		var curRole = dojo.attr(elem, "role") || "";
-		if(!this._XhtmlRoles.test(curRole)){
 			dojo.attr(elem, "role", role);
-		}else{
-			if((" "+ curRole +" ").indexOf(" " + role + " ") < 0){
-				var clearXhtml = dojo.trim(curRole.replace(this._XhtmlRoles, ""));
-				var cleanRole = dojo.trim(curRole.replace(clearXhtml, ""));
-				dojo.attr(elem, "role", cleanRole + (cleanRole ? ' ' : '') + role);
-			}
-		}
 	},
 
 	removeWaiRole: function(/*Element*/ elem, /*String*/ role){
 		// summary:
-		//		Removes the specified non-XHTML role from an element.
+		//		Removes the specified role from an element.
 		// 		Removes role attribute if no specific role provided (for backwards compat.)
 
 		var roleValue = dojo.attr(elem, "role");
@@ -144,3 +131,7 @@ dojo.mixin(dijit, {
 		elem.removeAttribute("aria-"+state);
 	}
 });
+
+
+return dijit;
+});
diff --git a/dijit/_base/window.js b/dijit/_base/window.js
index 1ec6db4..0bf2322 100644
--- a/dijit/_base/window.js
+++ b/dijit/_base/window.js
@@ -1,7 +1,9 @@
-dojo.provide("dijit._base.window");
-
-dojo.require("dojo.window");
+define("dijit/_base/window", ["dojo", "dijit", "dojo/window"], function(dojo, dijit) {
 
 dijit.getDocumentWindow = function(doc){
 	return dojo.window.get(doc);
 };
+
+
+return dijit;
+});
diff --git a/dijit/_editor/RichText.js b/dijit/_editor/RichText.js
index 6b2c293..a5c19ec 100644
--- a/dijit/_editor/RichText.js
+++ b/dijit/_editor/RichText.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit._editor.RichText");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._CssStateMixin");
-dojo.require("dijit._editor.selection");
-dojo.require("dijit._editor.range");
-dojo.require("dijit._editor.html");
+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.
@@ -15,7 +9,7 @@ if(!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"]){
 	if(dojo._postLoad){
 		(function(){
 			var savetextarea = dojo.doc.createElement('textarea');
-			savetextarea.id = dijit._scopeName + "._editor.RichText.savedContent";
+			savetextarea.id = dijit._scopeName + "._editor.RichText.value";
 			dojo.style(savetextarea, {
 				display:'none',
 				position:'absolute',
@@ -28,7 +22,7 @@ if(!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"]){
 	}else{
 		//dojo.body() is not available before onLoad is fired
 		try{
-			dojo.doc.write('<textarea id="' + dijit._scopeName + '._editor.RichText.savedContent" ' +
+			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){ }
 	}
@@ -85,22 +79,6 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this.events = [].concat(this.events);
 
 		this._keyHandlers = {};
-		this.contentPreFilters.push(dojo.hitch(this, "_preFixUrlAttributes"));
-		if(dojo.isMoz){
-			this.contentPreFilters.push(this._normalizeFontStyle);
-			this.contentPostFilters.push(this._removeMozBogus);
-		}
-		if(dojo.isWebKit){
-			// Try to clean up WebKit bogus artifacts.  The inserted classes
-			// made by WebKit sometimes messes things up.
-			this.contentPreFilters.push(this._removeWebkitBogus);
-			this.contentPostFilters.push(this._removeWebkitBogus);
-		}
-		if(dojo.isIE){
-			// IE generates <strong> and <em> but we want to normalize to <b> and <i>
-			this.contentPostFilters.push(this._normalizeFontStyle);
-		}
-		//this.contentDomPostFilters.push(this._postDomFixUrlAttributes);
 
 		if(params && dojo.isString(params.value)){
 			this.value = params.value;
@@ -129,10 +107,6 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	//		semicolon (";") separated list of css files for the editing area
 	styleSheets: "",
 
-	// _content: [private] String
-	//		temporary content storage
-	_content: "",
-
 	// height: String
 	//		Set height to fix the editor at a specific height, with scrolling.
 	//		By default, this is 300px.  If you want to have the editor always
@@ -156,8 +130,14 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	//		so they can be saved into a single <textarea> node.  See "name" attribute.
 	_SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",
 
-	// onLoadDeferred: [protected] dojo.Deferred
-	//		Deferred which is fired when the editor finishes loading
+	// _NAME_CONTENT_SEP: [private] String
+	//		USed to separate name from content.  Just a colon isn't safe.
+	_NAME_CONTENT_SEP: "@@**%%:%%**@@",
+
+	// onLoadDeferred: [readonly] dojo.Deferred
+	//		Deferred which is fired when the editor finishes loading.
+	//		Call myEditor.onLoadDeferred.then(callback) it to be informed
+	//		when the rich-text area initialization is finalized.
 	onLoadDeferred: null,
 
 	// isTabIndent: Boolean
@@ -175,6 +155,23 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			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 = [this._normalizeFontStyle].concat(this.contentPreFilters);
+			this.contentPostFilters = [this._removeMozBogus].concat(this.contentPostFilters);
+		}
+		if(dojo.isWebKit){
+			// 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){
+			// IE generates <strong> and <em> but we want to normalize to <b> and <i>
+			this.contentPostFilters = [this._normalizeFontStyle].concat(this.contentPostFilters);
+		}
 		this.inherited(arguments);
 
 		dojo.publish(dijit._scopeName + "._editor.RichText::init", [this]);
@@ -225,7 +222,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 	// events: [private] String[]
 	//		 events which should be connected to the underlying editing area
-	events: ["onKeyPress", "onKeyDown", "onKeyUp", "onClick"],
+	events: ["onKeyPress", "onKeyDown", "onKeyUp"], // onClick handled specially
 
 	// captureEvents: [deprecated] String[]
 	//		 Events which should be connected to the underlying editing
@@ -243,18 +240,19 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		Handle that here.
 		// tags:
 		//		private
-		if(this._editorCommandsLocalized){
+		if(dijit._editor._editorCommandsLocalized){
+			// Use the already generate cache of mappings.  
+			this._local2NativeFormatNames = dijit._editor._local2NativeFormatNames;
+			this._native2LocalFormatNames = dijit._editor._native2LocalFormatNames;
 			return;
 		}
-		this._editorCommandsLocalized = true;
-
+		dijit._editor._editorCommandsLocalized = true;
+		dijit._editor._local2NativeFormatNames = {};
+		dijit._editor._native2LocalFormatNames = {};
+		this._local2NativeFormatNames = dijit._editor._local2NativeFormatNames;
+		this._native2LocalFormatNames = dijit._editor._native2LocalFormatNames;
 		//in IE, names for blockformat is locale dependent, so we cache the values here
 
-		//if the normal way fails, we try the hard way to get the list
-
-		//do not use _cacheLocalBlockFormatNames here, as it will
-		//trigger security warning in IE7
-
 		//put p after div, so if IE returns Normal, we show it as paragraph
 		//We can distinguish p and div if IE returns Normal, however, in order to detect that,
 		//we have to call this.document.selection.createRange().parentElement() or such, which
@@ -263,31 +261,36 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		var localhtml = "", format, i=0;
 		while((format=formats[i++])){
 			//append a <br> after each element to separate the elements more reliably
-			if(format.charAt(1) != 'l'){
+			if(format.charAt(1) !== 'l'){
 				localhtml += "<"+format+"><span>content</span></"+format+"><br/>";
 			}else{
 				localhtml += "<"+format+"><li>content</li></"+format+"><br/>";
 			}
 		}
-		//queryCommandValue returns empty if we hide editNode, so move it out of screen temporary
-		var div = dojo.doc.createElement('div');
-		dojo.style(div, {
-			position: "absolute",
-			top: "-2000px"
+		// 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);
+
+		// 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 node = div.firstChild;
+			while(node){
+				try{
+					dijit._editor.selection.selectElement(node.firstChild);
+					var nativename = node.tagName.toLowerCase();
+					this._local2NativeFormatNames[nativename] = document.queryCommandValue("formatblock");
+					this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
+					node = node.nextSibling.nextSibling;
+					//console.log("Mapped: ", nativename, " to: ", this._local2NativeFormatNames[nativename]);
+				}catch(e) { /*Sqelch the occasional IE9 error */ }
+			}
+			div.parentNode.removeChild(div);
+			div.innerHTML = "";
 		});
-		dojo.doc.body.appendChild(div);
-		div.innerHTML = localhtml;
-		var node = div.firstChild;
-		while(node){
-			dijit._editor.selection.selectElement(node.firstChild);
-			dojo.withGlobal(this.window, "selectElement", dijit._editor.selection, [node.firstChild]);
-			var nativename = node.tagName.toLowerCase();
-			this._local2NativeFormatNames[nativename] = document.queryCommandValue("formatblock");
-			//this.queryCommandValue("formatblock");
-			this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
-			node = node.nextSibling.nextSibling;
-		}
-		dojo.body().removeChild(div);
+		setTimeout(inject, 0);
 	},
 
 	open: function(/*DomNode?*/ element){
@@ -297,10 +300,6 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// description:
 		//		Sets up the editing area asynchronously. This will result in
 		//		the creation and replacement with an iframe.
-		//
-		//		A dojo.Deferred object is created at this.onLoadDeferred, and
-		//		users may attach to it to be informed when the rich-text area
-		//		initialization is finalized.
 		// tags:
 		//		private
 
@@ -311,7 +310,6 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		if(!this.isClosed){ this.close(); }
 		dojo.publish(dijit._scopeName + "._editor.RichText::open", [ this ]);
 
-		this._content = "";
 		if(arguments.length == 1 && element.nodeName){ // else unchanged
 			this.domNode = element;
 		}
@@ -363,8 +361,17 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			}
 
 			if(ta.form){
+				var resetValue = ta.value;
+				this.reset = function(){
+					var current = this.getValue();
+					if(current != resetValue){
+						this.replaceValue(resetValue);
+					}
+				};
 				dojo.connect(ta.form, "onsubmit", 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
 					ta.value = this.getValue();
 				});
 			}
@@ -377,7 +384,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this._oldHeight = content.h;
 		this._oldWidth = content.w;
 
-		this.savedContent = html;
+		this.value = html;
 
 		// If we're a list item we have to put in a blank line to force the
 		// bullet to nicely align at the top of text
@@ -393,26 +400,41 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this.footer = dn.ownerDocument.createElement("div");
 		dn.appendChild(this.footer);
 
+		if(!this.name){
+			this.name = this.id + "_AUTOGEN";
+		}
+
 		// User has pressed back/forward button so we lost the text in the editor, but it's saved
 		// in a hidden <textarea> (which contains the data for all the editors on this page),
 		// so get editor value from there
 		if(this.name !== "" && (!dojo.config["useXDomain"] || dojo.config["allowXdRichTextSave"])){
-			var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.savedContent");
-			if(saveTextarea.value !== ""){
+			var saveTextarea = dojo.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(":");
+					var data = dat.split(this._NAME_CONTENT_SEP);
 					if(data[0] == this.name){
 						html = data[1];
-						datas.splice(i, 1);	// TODO: this has no effect
+						datas = datas.splice(i, 1);
+						saveTextarea.value = datas.join(this._SEPARATOR);
 						break;
 					}
 				}
 			}
 
-			// TODO: this is troublesome if this editor has been destroyed, should have global handler.
-			// TODO: need to clear <textarea> in global handler
-			dojo.addOnUnload(dojo.hitch(this, "_saveContent"));
+			if(!dijit._editor._globalSaveHandler){
+				dijit._editor._globalSaveHandler = {};
+				dojo.addOnUnload(function() {
+					var id;
+					for(id in dijit._editor._globalSaveHandler){
+						var f = dijit._editor._globalSaveHandler[id];
+						if(dojo.isFunction(f)){
+							f();
+						}
+					}
+				});
+			}
+			dijit._editor._globalSaveHandler[this.id] = dojo.hitch(this, "_saveContent");
 		}
 
 		this.isClosed = false;
@@ -456,6 +478,15 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		ifr.setAttribute('src', s);
 		this.editingArea.appendChild(ifr);
 
+		if(dojo.isSafari <= 4){
+			var src = ifr.getAttribute("src");
+			if(!src || src.indexOf("javascript") == -1){
+				// Safari 4 and earlier sometimes act oddly
+				// So we have to set it again.
+				setTimeout(function(){ifr.setAttribute('src', s);},0);
+			}
+		}
+
 		// TODO: this is a guess at the default line-height, kinda works
 		if(dn.nodeName == "LI"){
 			dn.lastChild.style.marginTop = "-1.2em";
@@ -479,7 +510,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// The contents inside of <body>.  The real contents are set later via a call to setValue().
 		var html = "";
 		var setBodyId = true;
-		if(dojo.isIE || (!this.height && !dojo.isMoz)){
+		if(dojo.isIE || dojo.isWebKit || (!this.height && !dojo.isMoz)){
 			// 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>";
@@ -509,8 +540,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 		var userStyle = "";
 		var self = this;
-		this.style.replace(/(^|;)\s*(line-|font-?)[^;]+/ig, function(match){ 
-			match = match.replace(/^;/ig,"") + ';'; 
+		this.style.replace(/(^|;)\s*(line-|font-?)[^;]+/ig, function(match){
+			match = match.replace(/^;/ig,"") + ';';
 			var s = match.split(":")[0];
 			if(s){
 				s = dojo.trim(s);
@@ -529,7 +560,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				}
 				dojo.style(self.domNode, sC, "");
 			}
-			userStyle += match + ';'; 
+			userStyle += match + ';';
 		});
 
 
@@ -547,7 +578,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			"\t\tmargin: -1px 0 0 0;\n", // remove extraneous vertical scrollbar on safari and firefox
 
 			// Set the html/body sizing.  Webkit always needs this, other browsers
-			// only set it when height is defined (not auto-expanding), otherwise 
+			// 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":""),
@@ -571,9 +602,10 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			// But in fixed height mode we want both x/y scrollers.  Also, if it's using wrapping div and in auto-expand
 			// (Mainly IE) we need to kill the y scroller on body and html.
 			(!setBodyId && !this.height ? "\tbody,html {overflow-y: hidden;}\n" : ""),
-			"\t#dijitEditorBody{overflow-x: auto; overflow-y:" + (this.height ? "auto;" : "hidden;") + "}\n",
+			"\t#dijitEditorBody{overflow-x: auto; overflow-y:" + (this.height ? "auto;" : "hidden;") + " outline: 0px;}\n",
 			"\tli > ul:-moz-first-node, li > ol:-moz-first-node{ padding-top: 1.2em; }\n",
-			"\tli{ min-height: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" : ""), 
 			"</style>\n",
 			this._applyEditingAreaStyleSheets(),"\n",
 			"</head>\n<body ",
@@ -624,7 +656,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 
 		this.editingAreaStyleSheets.push(url);
-		this.onLoadDeferred.addCallback(dojo.hitch(function(){
+		this.onLoadDeferred.addCallback(dojo.hitch(this, function(){
 			if(this.document.createStyleSheet){ //IE
 				this.document.createStyleSheet(url);
 			}else{ //other browser
@@ -661,9 +693,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 	_mozSettingProps: {'styleWithCSS':false},
 	_setDisabledAttr: function(/*Boolean*/ value){
-		this.disabled = value;
-		if(!this.isLoaded){ return; } // this method requires init to be complete
 		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(preventIEfocus){ this.editNode.unselectable = "on"; }
@@ -711,15 +743,14 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			this.window.__registeredWindow = true;
 			this._iframeRegHandle = dijit.registerIframe(this.iframe);
 		}
-		if(!dojo.isIE && (this.height || dojo.isMoz)){
+		if(!dojo.isIE && !dojo.isWebKit && (this.height || dojo.isMoz)){
 			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
-				var tabStop = (this.tabStop = dojo.doc.createElement('<div tabIndex=-1>'));
-				this.editingArea.appendChild(tabStop);
+				this.tabStop = dojo.create('div', { tabIndex: -1 }, this.editingArea);
 				this.iframe.onfocus = function(){ _this.editNode.setActive(); };
 			}
 		}
@@ -732,6 +763,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			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
 			this.connect(this.document, "onmousedown", "_onIEMouseDown"); // #4996 fix focus
 
@@ -742,22 +775,30 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			this.editNode.style.zoom = 1.0;
 		}else{
 			this.connect(this.document, "onmousedown", function(){
-				// Clear the moveToStart focus, as mouse 
+				// Clear the moveToStart focus, as mouse
 				// down will set cursor point.  Required to properly
 				// work with selection/position driven plugins and clicks in
 				// the window. refs: #10678
 				delete this._cursorToStart;
-			}); 
+			});
 		}
-
+		
 		if(dojo.isWebKit){
 			//WebKit sometimes doesn't fire right on selections, so the toolbar
 			//doesn't update right.  Therefore, help it out a bit with an additional
 			//listener.  A mouse up will typically indicate a display change, so fire this
 			//and get the toolbar to adapt.  Reference: #9532
 			this._webkitListener = this.connect(this.document, "onmouseup", "onDisplayChanged");
+			this.connect(this.document, "onmousedown", function(e){
+				var t = e.target;
+				if(t && (t === this.document.body || t === this.document)){
+					// Since WebKit uses the inner DIV, we need to check and set position.
+					// See: #12024 as to why the change was made.
+					setTimeout(dojo.hitch(this, "placeCursorAtEnd"), 0);
+				}
+			});
 		}
-
+		
 		if(dojo.isIE){
 			// Try to make sure 'hidden' elements aren't visible in edit mode (like browsers other than IE
 			// do).  See #9103
@@ -773,8 +814,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// Note that setValue() call will only work after isLoaded is set to true (above)
 
 		// 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.
+		// 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(){
 			this.setValue(html);
 			if(this.onLoadDeferred){
@@ -787,14 +828,13 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				dojo.addOnLoad(dojo.hitch(this, function(){ setTimeout(dojo.hitch(this, "focus"), this.updateInterval); }));
 			}
 			// Save off the initial content now
-			this.savedContent = this.getValue(true);
+			this.value = this.getValue(true);
 		});
 		if(this.setValueDeferred){
 			this.setValueDeferred.addCallback(setContent);
 		}else{
 			setContent();
 		}
-
 	},
 
 	onKeyDown: function(/* Event */ e){
@@ -872,7 +912,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				dojo.attr(this.document.body, "spellcheck", !disabled);
 			}));
 		}
-		this.disableSpellCheck = disabled;
+		this._set("disableSpellCheck", disabled);
 	},
 
 	onKeyPress: function(e){
@@ -962,13 +1002,14 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// console.info('_onBlur')
 
 		this.inherited(arguments);
-		var _c=this.getValue(true);
 
-		if(_c!=this.savedContent){
-			this.onChange(_c);
-			this.savedContent=_c;
+		var newValue = this.getValue(true);
+		if(newValue != this.value){
+			this.onChange(newValue);
 		}
+		this._set("value", newValue);
 	},
+
 	_onFocus: function(/*Event*/ e){
 		// summary:
 		//		Called from focus manager when focus has moved into this editor
@@ -984,7 +1025,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 	},
 
-	// TODO: why is this needed - should we deprecate this ?
+	// TODO: remove in 2.0
 	blur: function(){
 		// summary:
 		//		Remove focus from this instance.
@@ -1004,7 +1045,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			this.focusOnLoad = true;
 			return;
 		}
-		if(this._cursorToStart){ 
+		if(this._cursorToStart){
 			delete this._cursorToStart;
 			if(this.editNode.childNodes){
 				this.placeCursorAtStart(); // this calls focus() so return
@@ -1046,6 +1087,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			this._updateHandler = dojo.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.
 	},
 	onNormalizedDisplayChanged: function(){
 		// summary:
@@ -1107,14 +1151,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		var mozilla = 1 << 1;
 		var webkit = 1 << 2;
 		var opera = 1 << 3;
-		var webkit420 = 1 << 4;
 
 		function isSupportedBy(browsers){
 			return {
 				ie: Boolean(browsers & ie),
 				mozilla: Boolean(browsers & mozilla),
 				webkit: Boolean(browsers & webkit),
-				webkit420: Boolean(browsers & webkit420),
 				opera: Boolean(browsers & opera)
 			};
 		}
@@ -1136,7 +1178,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			case "insertorderedlist": case "insertunorderedlist":
 			case "indent": case "outdent": case "formatblock":
 			case "inserthtml": case "undo": case "redo": case "strikethrough": case "tabindent":
-				supportedBy = isSupportedBy(mozilla | ie | opera | webkit420);
+				supportedBy = isSupportedBy(mozilla | ie | opera | webkit);
 				break;
 
 			case "blockdirltr": case "blockdirrtl":
@@ -1145,7 +1187,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				supportedBy = isSupportedBy(ie);
 				break;
 			case "cut": case "copy": case "paste":
-				supportedBy = isSupportedBy( ie | mozilla | webkit420);
+				supportedBy = isSupportedBy( ie | mozilla | webkit);
 				break;
 
 			case "inserttable":
@@ -1164,7 +1206,6 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		return (dojo.isIE && supportedBy.ie) ||
 			(dojo.isMoz && supportedBy.mozilla) ||
 			(dojo.isWebKit && supportedBy.webkit) ||
-			(dojo.isWebKit > 420 && supportedBy.webkit420) ||
 			(dojo.isOpera && supportedBy.opera);	// Boolean return true if the command is supported, false otherwise
 	},
 
@@ -1186,7 +1227,6 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 
 		command = this._normalizeCommand(command, argument);
 
-
 		if(argument !== undefined){
 			if(command == "heading"){
 				throw new Error("unimplemented");
@@ -1229,8 +1269,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}
 		//see #4109
 		if(dojo.isWebKit){
-			if(command == "copy"){
-				command = "cut";
+			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;
 			}
@@ -1391,7 +1434,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 	getValue: function(/*Boolean?*/ nonDestructive){
 		// summary:
 		//		Return the current content of the editing area (post filters
-		//		are applied).  Users should call attr('value') instead.
+		//		are applied).  Users should call get('value') instead.
 		//	nonDestructive:
 		//		defaults to false. Should the post-filtering be run over a copy
 		//		of the live DOM? Most users should pass "true" here unless they
@@ -1435,6 +1478,9 @@ 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>";
+			}
 
 			// Use   to avoid webkit problems where editor is disabled until the user clicks it
 			if(!html && dojo.isWebKit){
@@ -1443,7 +1489,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			node.innerHTML = html;
 			this._preDomFilterContent(node);
 		}
+
 		this.onDisplayChanged();
+		this._set("value", this.getValue(true));
 	},
 
 	replaceValue: function(/*String*/ html){
@@ -1462,9 +1510,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		}else if(this.window && this.window.getSelection){ // Moz
 			html = this._preFilterContent(html);
 			this.execCommand("selectall");
-			if(!html){ 
+			if(!html){
 				this._cursorToStart = true;
-				html = " "; 
+				html = " ";
 			}
 			this.execCommand("inserthtml", html);
 			this._preDomFilterContent(this.editNode);
@@ -1475,6 +1523,8 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 			//so for now, use setValue for IE too
 			this.setValue(html);
 		}
+
+		this._set("value", this.getValue(true));
 	},
 
 	_preFilterContent: function(/*String*/ html){
@@ -1583,11 +1633,11 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// tags:
 		//		private
 
-		var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.savedContent");
+		var saveTextarea = dojo.byId(dijit._scopeName + "._editor.RichText.value");
 		if(saveTextarea.value){
 			saveTextarea.value += this._SEPARATOR;
 		}
-		saveTextarea.value += this.name + ":" + this.getValue(true);
+		saveTextarea.value += this.name + this._NAME_CONTENT_SEP + this.getValue(true);
 	},
 
 
@@ -1623,7 +1673,7 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		return dijit._editor.getChildrenHtml(dom);
 	},
 
-	close: function(/*Boolean*/ save){
+	close: function(/*Boolean?*/ save){
 		// summary:
 		//		Kills the editor and optionally writes back the modified contents to the
 		//		element from which it originated.
@@ -1632,11 +1682,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		// tags:
 		//		private
 
-		if(this.isClosed){return false; }
+		if(this.isClosed){ return; }
 
 		if(!arguments.length){ save = true; }
-		this._content = this.getValue();
-		var changed = (this.savedContent != this._content);
+		if(save){
+			this._set("value", this.getValue(true));
+		}
 
 		// line height is squashed for iframes
 		// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; }
@@ -1668,23 +1719,12 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 				s.overflow = this.__overflow;
 				this.__overflow = null;
 			}
-			this.textarea.value = save ? this._content : this.savedContent;
+			this.textarea.value = this.value;
 			dojo.destroy(this.domNode);
 			this.domNode = this.textarea;
 		}else{
-			// if(save){
-			// why we treat moz differently? comment out to fix #1061
-			//		if(dojo.isMoz){
-			//			var nc = dojo.doc.createElement("span");
-			//			this.domNode.appendChild(nc);
-			//			nc.innerHTML = this.editNode.innerHTML;
-			//		}else{
-			//			this.domNode.innerHTML = this._content;
-			//		}
-			// }
-
 			// Note that this destroys the iframe
-			this.domNode.innerHTML = save ? this._content : this.savedContent;
+			this.domNode.innerHTML = this.value;
 		}
 		delete this.iframe;
 
@@ -1703,13 +1743,14 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		this.document = null;
 		this.editingArea = null;
 		this.editorObject = null;
-
-		return changed; // Boolean: whether the content has been modified
 	},
 
 	destroy: function(){
 		if(!this.isClosed){ this.close(false); }
 		this.inherited(arguments);
+		if(dijit._editor._globalSaveHandler){
+			delete dijit._editor._globalSaveHandler[this.id];
+		}
 	},
 
 	_removeMozBogus: function(/* String */ html){
@@ -1726,6 +1767,9 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		private
 		html = html.replace(/\sclass="webkit-block-placeholder"/gi, '');
 		html = html.replace(/\sclass="apple-style-span"/gi, '');
+		// For some reason copy/paste sometime adds extra meta tags for charset on
+		// webkit (chrome) on mac.They need to be removed.  See: #12007"
+		html = html.replace(/<meta charset=\"utf-8\" \/>/gi, '');
 		return html; // String
 	},
 	_normalizeFontStyle: function(/* String */ html){
@@ -1874,6 +1918,58 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		return rv;
 	},
 
+	_boldImpl: function(argument){
+		// summary:
+		//		This function implements an over-ride of the bold command.
+		// argument:
+		//		Not used, operates by selection.
+		// tags:
+		//		protected
+		if(dojo.isIE){
+			this._adaptIESelection()
+		}
+		return this.document.execCommand("bold", false, argument);
+	},
+	
+	_italicImpl: function(argument){
+		// summary:
+		//		This function implements an over-ride of the italic command.
+		// argument:
+		//		Not used, operates by selection.
+		// tags:
+		//		protected
+		if(dojo.isIE){
+			this._adaptIESelection()
+		}
+		return this.document.execCommand("italic", false, argument);
+	},
+
+	_underlineImpl: function(argument){
+		// summary:
+		//		This function implements an over-ride of the underline command.
+		// argument:
+		//		Not used, operates by selection.
+		// tags:
+		//		protected
+		if(dojo.isIE){
+			this._adaptIESelection()
+		}
+		return this.document.execCommand("underline", false, argument);
+	},
+	
+	_strikethroughImpl: function(argument){
+		// summary:
+		//		This function implements an over-ride of the strikethrough command.
+		// argument:
+		//		Not used, operates by selection.
+		// tags:
+		//		protected
+		if(dojo.isIE){
+			this._adaptIESelection()
+		}
+		return this.document.execCommand("strikethrough", false, argument);
+	},
+
 	getHeaderHeight: function(){
 		// summary:
 		//		A function for obtaining the height of the header node
@@ -1893,14 +1989,94 @@ dojo.declare("dijit._editor.RichText", [dijit._Widget, dijit._CssStateMixin], {
 		//		The node to process the children of;
 		var h = 0;
 		if(node && node.childNodes){
-			// IE didn't compute it right when position was obtained on the node directly is some cases, 
+			// IE didn't compute it right when position was obtained on the node directly is some cases,
 			// so we have to walk over all the children manually.
-			var i; 
-			for(i = 0; i < node.childNodes.length; i++){ 
-				var size = dojo.position(node.childNodes[i]); 
-				h += size.h;   
-			} 
+			var i;
+			for(i = 0; i < node.childNodes.length; i++){
+				var size = dojo.position(node.childNodes[i]);
+				h += size.h;
+			}
 		}
 		return h; // Number
+	},
+	
+	_isNodeEmpty: function(node, startOffset){
+		// summary:
+		//		Function to test if a node is devoid of real content.
+		// node:
+		//		The node to check.
+		// tags:
+		//		private.
+		if(node.nodeType == 1/*element*/){
+			if(node.childNodes.length > 0){
+				return this._isNodeEmpty(node.childNodes[0], startOffset);
+	}
+			return true;
+		}else if(node.nodeType == 3/*text*/){
+			return (node.nodeValue.substring(startOffset) == "");
+		}
+		return false;
+	},
+	
+	_removeStartingRangeFromRange: function(node, range){
+		// summary:
+		//		Function to adjust selection range by removing the current
+		//		start node.
+		// node:
+		//		The node to remove from the starting range.
+		// range:
+		//		The range to adapt.
+		// tags:
+		//		private
+		if(node.nextSibling){
+			range.setStart(node.nextSibling,0);
+		}else{
+			var parent = node.parentNode;
+			while(parent && parent.nextSibling == null){
+				//move up the tree until we find a parent that has another node, that node will be the next node
+				parent = parent.parentNode;
+			}
+			if(parent){
+				range.setStart(parent.nextSibling,0);
+			}
+		}
+		return range;
+	},
+	
+	_adaptIESelection: function(){
+		// summary:
+		//		Function to adapt the IE range by removing leading 'newlines'
+		//		Needed to fix issue with bold/italics/underline not working if
+		//		range included leading 'newlines'.
+		//		In IE, if a user starts a selection at the very end of a line,
+		//		then the native browser commands will fail to execute correctly.
+		//		To work around the issue,  we can remove all empty nodes from
+		//		the start of the range selection.
+		var selection = dijit.range.getSelection(this.window);
+		if(selection && selection.rangeCount && !selection.isCollapsed){
+			var range = selection.getRangeAt(0);
+			var firstNode = range.startContainer;
+			var startOffset = range.startOffset;
+
+			while(firstNode.nodeType == 3/*text*/ && startOffset >= firstNode.length && firstNode.nextSibling){
+				//traverse the text nodes until we get to the one that is actually highlighted
+				startOffset = startOffset - firstNode.length;
+				firstNode = firstNode.nextSibling;
+			}
+
+			//Remove the starting ranges until the range does not start with an empty node.
+			var lastNode=null;
+			while(this._isNodeEmpty(firstNode, startOffset) && firstNode != lastNode){
+				lastNode =firstNode; //this will break the loop in case we can't find the next sibling
+				range = this._removeStartingRangeFromRange(firstNode, range); //move the start container to the next node in the range
+				firstNode = range.startContainer;
+				startOffset = 0; //start at the beginning of the new starting range
+			}
+			selection.removeAllRanges();// this will work as long as users cannot select multiple ranges. I have not been able to do that in the editor.
+			selection.addRange(range);
+		}
 	}
 });
+
+return dijit._editor.RichText;
+});
diff --git a/dijit/_editor/_Plugin.js b/dijit/_editor/_Plugin.js
index 49a5225..64d948c 100644
--- a/dijit/_editor/_Plugin.js
+++ b/dijit/_editor/_Plugin.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit._editor._Plugin");
-dojo.require("dijit._Widget");
-dojo.require("dijit.form.Button");
+define("dijit/_editor/_Plugin", ["dojo", "dijit", "dijit/_Widget", "dijit/form/Button"], function(dojo, dijit) {
 
 dojo.declare("dijit._editor._Plugin", null, {
 	// summary
@@ -11,6 +9,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 		this.params = args || {};
 		dojo.mixin(this, this.params);
 		this._connects=[];
+		this._attrPairNames = {};
 	},
 
 	// editor: [const] dijit.Editor
@@ -42,6 +41,11 @@ dojo.declare("dijit._editor._Plugin", null, {
 	//		This is used to instantiate the button, unless `button` itself is specified directly.
 	buttonClass: dijit.form.Button,
 
+	// disabled: Boolean
+	//		Flag to indicate if this plugin has been disabled and should do nothing
+	//		helps control button state, among other things.  Set via the setter api.
+	disabled: false,
+
 	getLabel: function(/*String*/key){
 		// summary:
 		//		Returns the label to use for the button
@@ -73,6 +77,9 @@ dojo.declare("dijit._editor._Plugin", null, {
 				this.button = new this.buttonClass(props);
 			}
 		}
+		if(this.get("disabled") && this.button){
+			this.button.set("disabled", this.get("disabled"));
+		}
 	},
 
 	destroy: function(){
@@ -110,9 +117,10 @@ dojo.declare("dijit._editor._Plugin", null, {
 			c = this.command,
 			checked, enabled;
 		if(!e || !e.isLoaded || !c.length){ return; }
+		var disabled = this.get("disabled");
 		if(this.button){
 			try{
-				enabled = e.queryCommandEnabled(c);
+				enabled = !disabled && e.queryCommandEnabled(c);
 				if(this.enabled !== enabled){
 					this.enabled = enabled;
 					this.button.set('disabled', !enabled);
@@ -150,7 +158,7 @@ dojo.declare("dijit._editor._Plugin", null, {
 				);
 			}else{
 				// hide button because editor doesn't support command (due to browser limitations)
-				this.button.domNode.style.display = "none";			
+				this.button.domNode.style.display = "none";
 			}
 		}
 
@@ -168,5 +176,103 @@ dojo.declare("dijit._editor._Plugin", null, {
 			toolbar.addChild(this.button);
 		}
 		// console.debug("adding", this.button, "to:", toolbar);
+	},
+	
+	set: function(/* attribute */ name, /* anything */ value){
+		// summary:
+		//		Set a property on a plugin
+		//	name:
+		//		The property to set.
+		//	value:
+		//		The value to set in the property.
+		// description:
+		//		Sets named properties on a plugin which may potentially be handled by a
+		// 		setter in the plugin.
+		// 		For example, if the plugin has a properties "foo"
+		//		and "bar" and a method named "_setFooAttr", calling:
+		//	|	plugin.set("foo", "Howdy!");
+		//		would be equivalent to writing:
+		//	|	plugin._setFooAttr("Howdy!");
+		//		and:
+		//	|	plugin.set("bar", 3);
+		//		would be equivalent to writing:
+		//	|	plugin.bar = 3;
+		//
+		//	set() may also be called with a hash of name/value pairs, ex:
+		//	|	plugin.set({
+		//	|		foo: "Howdy",
+		//	|		bar: 3
+		//	|	})
+		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
+		if(typeof name === "object"){
+			for(var x in name){
+				this.set(x, name[x]);
+	}
+			return this;
+		}
+		var names = this._getAttrNames(name);
+		if(this[names.s]){
+			// use the explicit setter
+			var result = this[names.s].apply(this, Array.prototype.slice.call(arguments, 1));
+		}else{
+			this._set(name, value);
+		}
+		return result || this;
+	},
+
+	get: function(name){
+		// summary:
+		//		Get a property from a plugin.
+		//	name:
+		//		The property to get.
+		// description:
+		//		Get a named property from a plugin. The property may
+		//		potentially be retrieved via a getter method. If no getter is defined, this
+		// 		just retrieves the object's property.
+		// 		For example, if the plugin has a properties "foo"
+		//		and "bar" and a method named "_getFooAttr", calling:
+		//	|	plugin.get("foo");
+		//		would be equivalent to writing:
+		//	|	plugin._getFooAttr();
+		//		and:
+		//	|	plugin.get("bar");
+		//		would be equivalent to writing:
+		//	|	plugin.bar;
+		var names = this._getAttrNames(name);
+		return this[names.g] ? this[names.g]() : this[name];
+	},
+
+	_setDisabledAttr: function(disabled){
+		// summary:
+		//		Function to set the plugin state and call updateState to make sure the
+		//		button is updated appropriately.
+		this.disabled = disabled;
+		this.updateState();
+	},
+	
+	_getAttrNames: function(name){
+		// summary:
+		//		Helper function for get() and set().
+		//		Caches attribute name values so we don't do the string ops every time.
+		// tags:
+		//		private
+
+		var apn = this._attrPairNames;
+		if(apn[name]){ return apn[name]; }
+		var uc = name.charAt(0).toUpperCase() + name.substr(1);
+		return (apn[name] = {
+			s: "_set"+uc+"Attr",
+			g: "_get"+uc+"Attr"
+		});
+	},
+	
+	_set: function(/*String*/ name, /*anything*/ value){
+		// summary:
+		//		Helper function to set new value for specified attribute
+		var oldValue = this[name];
+		this[name] = value;
 	}
 });
+
+return dijit._editor._Plugin;
+});
\ No newline at end of file
diff --git a/dijit/_editor/html.js b/dijit/_editor/html.js
index d683413..71cd981 100755
--- a/dijit/_editor/html.js
+++ b/dijit/_editor/html.js
@@ -1,4 +1,5 @@
-dojo.provide("dijit._editor.html");
+define("dijit/_editor/html", ["dojo", "dijit"], function(dojo, dijit) {
+dojo.getObject("_editor", true, dijit);
 
 dijit._editor.escapeXml=function(/*String*/str, /*Boolean?*/noSingleQuotes){
 	// summary:
@@ -178,3 +179,6 @@ dijit._editor.getChildrenHtml = function(/* DomNode */dom){
 	}
 	return out; // String
 };
+
+return dijit._editor;
+});
diff --git a/dijit/_editor/nls/FontChoice.js b/dijit/_editor/nls/FontChoice.js
index 1855400..f1cc889 100644
--- a/dijit/_editor/nls/FontChoice.js
+++ b/dijit/_editor/nls/FontChoice.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	fontSize: "Size",
 	fontName: "Font",
@@ -24,3 +26,35 @@
 	6: "x-large",
 	7: "xx-large"
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/_editor/nls/LinkDialog.js b/dijit/_editor/nls/LinkDialog.js
index ad13eb6..b188243 100644
--- a/dijit/_editor/nls/LinkDialog.js
+++ b/dijit/_editor/nls/LinkDialog.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	createLinkTitle: "Link Properties",
 	insertImageTitle: "Image Properties",
@@ -10,3 +12,35 @@
 	topWindow: "Topmost Window",
 	newWindow: "New Window"
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/_editor/nls/ar/FontChoice.js b/dijit/_editor/nls/ar/FontChoice.js
index 621c142..a2ee528 100644
--- a/dijit/_editor/nls/ar/FontChoice.js
+++ b/dijit/_editor/nls/ar/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "الحجم",
 	fontName: "طاقم طباعة",
@@ -9,6 +11,7 @@
 	cursive: "كتابة بحروف متصلة",
 	fantasy: "خيالي",
 
+	noFormat: "‏لا شيء‏",
 	p: "فقرة",
 	h1: "عنوان",
 	h2: "عنوان فرعي",
@@ -22,4 +25,6 @@
 	5: "كبير",
 	6: "كبير جدا",
 	7: "كبير جدا جدا"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ar/LinkDialog.js b/dijit/_editor/nls/ar/LinkDialog.js
index 9483616..ad64eb3 100644
--- a/dijit/_editor/nls/ar/LinkDialog.js
+++ b/dijit/_editor/nls/ar/LinkDialog.js
@@ -1,13 +1,17 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "خصائص الوصلة",
 	insertImageTitle: "خصائص الصورة",
-	url: "عنوان URL:",
+	url: "‏عنوان URL:‏",
 	text: "الوصف:",
-	target: "الهدف: ",
+	target: "الهدف:",
 	set: "تحديد",
 	currentWindow: "النافذة الحالية",
 	parentWindow: "النافذة الرئيسية",
 	topWindow: "النافذة العلوية",
-	newWindow: "نافذة جديدة"
+	newWindow: "‏نافذة جديدة‏"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ar/commands.js b/dijit/_editor/nls/ar/commands.js
index 3bb35e7..0713041 100644
--- a/dijit/_editor/nls/ar/commands.js
+++ b/dijit/_editor/nls/ar/commands.js
@@ -1,9 +1,11 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'عري~ض',
 	'copy': 'نسخ',
 	'cut': 'قص',
 	'delete': 'حذف',
-	'indent': '‏ازاحة للداخل‏',
+	'indent': 'ازاحة للداخل',
 	'insertHorizontalRule': 'مسطرة أفقية',
 	'insertOrderedList': '‏كشف مرقم‏',
 	'insertUnorderedList': 'كشف نقطي',
@@ -16,7 +18,7 @@
 	'paste': 'لصق',
 	'redo': '‏اعادة‏',
 	'removeFormat': 'ازالة النسق',
-	'selectAll': 'اختيار كل',
+	'selectAll': '‏اختيار كل‏',
 	'strikethrough': 'تشطيب',
 	'subscript': 'رمز سفلي',
 	'superscript': 'رمز علوي',
@@ -37,13 +39,16 @@
 	'formatBlock': 'نمط الفقرة',
 	'fontSize': 'حجم طاقم الطباعة',
 	'fontName': 'اسم طاقم الطباعة',
-	'tabIndent': 'ازاحة للداخل باستخدام Tab',
-	"fullScreen": "تبديل الشاشة الكاملة",
-	"viewSource": "\u202bمشاهدة مصدر HTML\u202c",
-	"print": "‏طباعة‏",
+	'tabIndent': 'ازاحة علامة الجدولة للداخل',
+	"fullScreen": "تبديل  الشاشة الكاملة",
+	"viewSource": "مشاهدة مصدر HTML",
+	"print": "طباعة",
 	"newPage": "صفحة جديدة",
 	/* Error messages */
-	'systemShortcut': 'التصرف "${0}" يكون متاحا فقط في برنامج الاستعراض الخاص بك باستخدام المسار المختصر للوحة المفاتيح. استخدم ${1}.',
-	'ctrlKey':'ctrl+${0}'
+	'systemShortcut': 'يكون التصرف "${0}" متاحا فقط ببرنامج الاستعراض الخاص بك باستخدام المسار المختصر للوحة المفاتيح.  استخدم ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ca/FontChoice.js b/dijit/_editor/nls/ca/FontChoice.js
index b430f31..bf116e7 100644
--- a/dijit/_editor/nls/ca/FontChoice.js
+++ b/dijit/_editor/nls/ca/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Mida",
 	fontName: "Tipus de lletra",
@@ -9,6 +11,7 @@
 	cursive: "Cursiva",
 	fantasy: "Fantasia",
 
+	noFormat: "Cap",
 	p: "Paràgraf",
 	h1: "Títol",
 	h2: "Subtítol",
@@ -23,4 +26,5 @@
 	6: "x-gran",
 	7: "xx-gran"
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ca/LinkDialog.js b/dijit/_editor/nls/ca/LinkDialog.js
index 900c52e..3c22820 100644
--- a/dijit/_editor/nls/ca/LinkDialog.js
+++ b/dijit/_editor/nls/ca/LinkDialog.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Propietats de l\'enllaç",
 	insertImageTitle: "Propietats de la imatge",
 	url: "URL:",
-	text: "Descipció:",
+	text: "Descripció:",
 	target: "Destinació:",
 	set: "Defineix",
 	currentWindow: "Finestra actual",
@@ -10,4 +12,5 @@
 	topWindow: "Finestra superior",
 	newWindow: "Finestra nova"
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ca/commands.js b/dijit/_editor/nls/ca/commands.js
index 8a94eae..7ee2ae1 100644
--- a/dijit/_editor/nls/ca/commands.js
+++ b/dijit/_editor/nls/ca/commands.js
@@ -1,16 +1,18 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Negreta',
 	'copy': 'Copia',
 	'cut': 'Retalla',
 	'delete': 'Suprimeix',
 	'indent': 'Sagnat',
-	'insertHorizontalRule': 'Regle horitzontal',
+	'insertHorizontalRule': 'Regla horitzontal',
 	'insertOrderedList': 'Llista numerada',
 	'insertUnorderedList': 'Llista de vinyetes',
 	'italic': 'Cursiva',
 	'justifyCenter': 'Centra',
 	'justifyFull': 'Justifica',
-	'justifyLeft': 'Alinea a la esquerra',
+	'justifyLeft': 'Alinea a l\'esquerra',
 	'justifyRight': 'Alinea a la dreta',
 	'outdent': 'Sagna a l\'esquerra',
 	'paste': 'Enganxa',
@@ -46,4 +48,5 @@
 	'systemShortcut': 'L\'acció "${0}" és l\'única disponible al navegador utilitzant una drecera del teclat. Utilitzeu ${1}.',
 	'ctrlKey':'control+${0}'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/commands.js b/dijit/_editor/nls/commands.js
index 25d7c29..dfdbd39 100644
--- a/dijit/_editor/nls/commands.js
+++ b/dijit/_editor/nls/commands.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 ({
 	'bold': 'Bold',
 	'copy': 'Copy',
@@ -47,3 +49,35 @@
 	'ctrlKey':'ctrl+${0}',
 	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/_editor/nls/cs/FontChoice.js b/dijit/_editor/nls/cs/FontChoice.js
index fa836c8..722f035 100644
--- a/dijit/_editor/nls/cs/FontChoice.js
+++ b/dijit/_editor/nls/cs/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Velikost",
 	fontName: "Písmo",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "Žádný",
 	p: "Odstavec",
 	h1: "Nadpis",
 	h2: "Podnadpis",
@@ -23,3 +26,5 @@
 	6: "velmi velké",
 	7: "extra velké"
 })
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/cs/LinkDialog.js b/dijit/_editor/nls/cs/LinkDialog.js
index e24ac48..7a6acc3 100644
--- a/dijit/_editor/nls/cs/LinkDialog.js
+++ b/dijit/_editor/nls/cs/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Vlastnosti odkazu",
 	insertImageTitle: "Vlastnosti obrázku",
@@ -11,3 +13,5 @@
 	newWindow: "Nové okno"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/cs/commands.js b/dijit/_editor/nls/cs/commands.js
index 7e52895..5d56608 100644
--- a/dijit/_editor/nls/cs/commands.js
+++ b/dijit/_editor/nls/cs/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Tučné',
 	'copy': 'Kopírovat',
@@ -38,11 +40,12 @@
 	'fontSize': 'Velikost písma',
 	'fontName': 'Název písma',
 	'tabIndent': 'Odsazení tabulátoru',
-	"fullScreen": "Přepnout režim celé obrazovky",
-	"viewSource": "Zobrazit zdroj ve formátu HTML",
+	"fullScreen": "Přepnout celou obrazovku",
+	"viewSource": "Zobrazit zdroj HTML",
 	"print": "Tisk",
 	"newPage": "Nová stránka",
 	/* Error messages */
 	'systemShortcut': 'Akce "${0}" je v prohlížeči dostupná pouze prostřednictvím klávesové zkratky. Použijte klávesovou zkratku ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/da/FontChoice.js b/dijit/_editor/nls/da/FontChoice.js
index 1994287..ab382e4 100644
--- a/dijit/_editor/nls/da/FontChoice.js
+++ b/dijit/_editor/nls/da/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Størrelse",
 	fontName: "Skrifttype",
@@ -9,6 +11,7 @@
 	cursive: "kursiv",
 	fantasy: "fantasy",
 
+	noFormat: "Ingen",
 	p: "Afsnit",
 	h1: "Overskrift",
 	h2: "Underoverskrift",
@@ -22,4 +25,6 @@
 	5: "large",
 	6: "x-large",
 	7: "xx-large"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/da/LinkDialog.js b/dijit/_editor/nls/da/LinkDialog.js
index 60ccf05..2b405ea 100644
--- a/dijit/_editor/nls/da/LinkDialog.js
+++ b/dijit/_editor/nls/da/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Linkegenskaber",
 	insertImageTitle: "Billedegenskaber",
@@ -11,3 +13,5 @@
 	newWindow: "Nyt vindue"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/da/commands.js b/dijit/_editor/nls/da/commands.js
index 58ef957..0d21af9 100644
--- a/dijit/_editor/nls/da/commands.js
+++ b/dijit/_editor/nls/da/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Fed',
 	'copy': 'Kopiér',
@@ -43,7 +45,7 @@
 	"print": "Udskriv",
 	"newPage": "Ny side",
 	/* Error messages */
-	'systemShortcut': 'Funktionen "${0}" kan kun bruges i din browser med en tastaturgenvej. Brug ${1}.',
-	'ctrlKey':'Ctrl+${0}'
+	'systemShortcut': 'Funktionen "${0}" kan kun bruges i din browser med en tastaturgenvej. Brug ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/de/FontChoice.js b/dijit/_editor/nls/de/FontChoice.js
index 0f45e8f..db1d989 100644
--- a/dijit/_editor/nls/de/FontChoice.js
+++ b/dijit/_editor/nls/de/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Größe",
 	fontName: "Schriftart",
@@ -9,6 +11,7 @@
 	cursive: "Kursiv",
 	fantasy: "Fantasie",
 
+	noFormat: "Keine Angabe",
 	p: "Absatz",
 	h1: "Überschrift",
 	h2: "Unterüberschrift",
@@ -22,4 +25,6 @@
 	5: "L",
 	6: "XL",
 	7: "XXL"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/de/LinkDialog.js b/dijit/_editor/nls/de/LinkDialog.js
index 266add8..cf5209d 100644
--- a/dijit/_editor/nls/de/LinkDialog.js
+++ b/dijit/_editor/nls/de/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Linkeigenschaften",
 	insertImageTitle: "Grafikeigenschaften",
@@ -11,3 +13,5 @@
 	newWindow: "Neues Fenster"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/de/commands.js b/dijit/_editor/nls/de/commands.js
index 3191e18..5f68329 100755
--- a/dijit/_editor/nls/de/commands.js
+++ b/dijit/_editor/nls/de/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Fett',
 	'copy': 'Kopieren',
@@ -47,3 +49,5 @@
 	'ctrlKey':'Strg+${0}'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/el/FontChoice.js b/dijit/_editor/nls/el/FontChoice.js
index e9fee55..c58d50a 100644
--- a/dijit/_editor/nls/el/FontChoice.js
+++ b/dijit/_editor/nls/el/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Μέγεθος",
 	fontName: "Γραμματοσειρά",
@@ -9,6 +11,7 @@
 	cursive: "πλάγιοι",
 	fantasy: "φαντασίας",
 
+	noFormat: "Χωρίς",
 	p: "Παράγραφος",
 	h1: "Επικεφαλίδα",
 	h2: "Δευτερεύουσα επικεφαλίδα",
@@ -22,4 +25,6 @@
 	5: "μεγάλα",
 	6: "x-μεγάλα",
 	7: "xx-μεγάλα"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/el/LinkDialog.js b/dijit/_editor/nls/el/LinkDialog.js
index 9cbc6f0..330fb96 100644
--- a/dijit/_editor/nls/el/LinkDialog.js
+++ b/dijit/_editor/nls/el/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Ιδιότητες σύνδεσης",
 	insertImageTitle: "Ιδιότητες εικόνας",
@@ -11,3 +13,5 @@
 	newWindow: "Νέο παράθυρο"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/el/commands.js b/dijit/_editor/nls/el/commands.js
index a23feac..26574f5 100644
--- a/dijit/_editor/nls/el/commands.js
+++ b/dijit/_editor/nls/el/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Έντονα',
 	'copy': 'Αντιγραφή',
@@ -46,3 +48,5 @@
 	'systemShortcut': 'Σε αυτό το πρόγραμμα πλοήγησης, η ενέργεια "${0}" είναι διαθέσιμη μόνο με τη χρήση μιας συντόμευσης πληκτρολογίου. Χρησιμοποιήστε τη συντόμευση ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/es/FontChoice.js b/dijit/_editor/nls/es/FontChoice.js
index 8592dc9..8e2f83f 100644
--- a/dijit/_editor/nls/es/FontChoice.js
+++ b/dijit/_editor/nls/es/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Tamaño",
 	fontName: "Font",
@@ -9,6 +11,7 @@
 	cursive: "cursiva",
 	fantasy: "fantasía",
 
+	noFormat: "Ninguno",
 	p: "Párrafo",
 	h1: "Cabecera",
 	h2: "Subcabecera",
@@ -22,4 +25,6 @@
 	5: "grande",
 	6: "x-grande",
 	7: "xx-grande"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/es/LinkDialog.js b/dijit/_editor/nls/es/LinkDialog.js
index 27d996c..986d4f2 100644
--- a/dijit/_editor/nls/es/LinkDialog.js
+++ b/dijit/_editor/nls/es/LinkDialog.js
@@ -1,9 +1,11 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Propiedades del enlace",
 	insertImageTitle: "Propiedades de la imagen",
 	url: "URL:",
-	text: "Descripción: ",
-	target: "Destino: ",
+	text: "Descripción:",
+	target: "Destino:",
 	set: "Establecer",
 	currentWindow: "Ventana actual",
 	parentWindow: "Ventana padre",
@@ -11,3 +13,5 @@
 	newWindow: "Nueva ventana"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/es/commands.js b/dijit/_editor/nls/es/commands.js
index 9e540f9..e6b16f2 100644
--- a/dijit/_editor/nls/es/commands.js
+++ b/dijit/_editor/nls/es/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Negrita',
 	'copy': 'Copiar',
@@ -47,3 +49,5 @@
 	'ctrlKey':'control+${0}'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/fi/FontChoice.js b/dijit/_editor/nls/fi/FontChoice.js
index ad48fc0..06e0c64 100644
--- a/dijit/_editor/nls/fi/FontChoice.js
+++ b/dijit/_editor/nls/fi/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Koko",
 	fontName: "Fontti",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "Ei mitään",
 	p: "Kappale",
 	h1: "Otsikko",
 	h2: "Alatason otsikko",
@@ -22,4 +25,6 @@
 	5: "large",
 	6: "x-large",
 	7: "xx-large"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/fi/LinkDialog.js b/dijit/_editor/nls/fi/LinkDialog.js
index 75bf456..db5626c 100644
--- a/dijit/_editor/nls/fi/LinkDialog.js
+++ b/dijit/_editor/nls/fi/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Linkin ominaisuudet",
 	insertImageTitle: "Kuvan ominaisuudet",
@@ -11,3 +13,5 @@
 	newWindow: "Uusi ikkuna"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/fi/commands.js b/dijit/_editor/nls/fi/commands.js
index 6db52cb..517afd1 100644
--- a/dijit/_editor/nls/fi/commands.js
+++ b/dijit/_editor/nls/fi/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Lihavointi',
 	'copy': 'Kopioi',
@@ -46,3 +48,5 @@
 	'systemShortcut': 'Toiminto "${0}" on käytettävissä selaimessa vain näppäimistön pikatoiminnolla. Käytä seuraavaa: ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/fr/FontChoice.js b/dijit/_editor/nls/fr/FontChoice.js
index c96716d..bf77dd7 100644
--- a/dijit/_editor/nls/fr/FontChoice.js
+++ b/dijit/_editor/nls/fr/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Taille",
 	fontName: "Police",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantaisie",
 
+	noFormat: "Néant",
 	p: "Paragraphe",
 	h1: "En-tête",
 	h2: "Sous-en-tête",
@@ -22,4 +25,6 @@
 	5: "l",
 	6: "xl",
 	7: "xxl"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/fr/LinkDialog.js b/dijit/_editor/nls/fr/LinkDialog.js
index 5949bc9..8ae89c1 100644
--- a/dijit/_editor/nls/fr/LinkDialog.js
+++ b/dijit/_editor/nls/fr/LinkDialog.js
@@ -1,13 +1,16 @@
+define(
+//begin v1.x content
 ({
-	createLinkTitle: "Propriétés des liens",
-	insertImageTitle: "Propriétés des images",
+	createLinkTitle: "Propriétés du lien",
+	insertImageTitle: "Propriétés de l'image",
 	url: "URL :",
 	text: "Description :",
 	target: "Cible :",
 	set: "Définir",
-	currentWindow: "Fenêtre en cours",
+	currentWindow: "Fenêtre actuelle",
 	parentWindow: "Fenêtre parent",
-	topWindow: "Première fenêtre",
+	topWindow: "Fenêtre supérieure",
 	newWindow: "Nouvelle fenêtre"
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/fr/commands.js b/dijit/_editor/nls/fr/commands.js
index 98f2697..587a727 100644
--- a/dijit/_editor/nls/fr/commands.js
+++ b/dijit/_editor/nls/fr/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Gras',
 	'copy': 'Copier',
@@ -31,18 +33,19 @@
 	'deleteTable': 'Supprimer le tableau',
 	'tableProp': 'Propriété du tableau',
 	'htmlToggle': 'Source HTML',
-	'foreColor': 'Couleur avant-plan',
-	'hiliteColor': 'Couleur arrière-plan',
+	'foreColor': 'Couleur d\'avant-plan',
+	'hiliteColor': 'Couleur d\'arrière-plan',
 	'plainFormatBlock': 'Style de paragraphe',
 	'formatBlock': 'Style de paragraphe',
 	'fontSize': 'Taille de police',
 	'fontName': 'Nom de police',
 	'tabIndent': 'Retrait de tabulation',
-	"fullScreen": "Basculer vers le mode plein écran",
+	"fullScreen": "Basculer en plein écran",
 	"viewSource": "Afficher la source HTML",
 	"print": "Imprimer",
 	"newPage": "Nouvelle page",
 	/* Error messages */
-	'systemShortcut': 'Action "${0}" uniquement disponible dans votre navigateur via un raccourci clavier. Utilisez ${1}.'
+	'systemShortcut': 'L\'action "${0}" est disponible dans votre navigateur uniquement, par le biais d\'un raccourci-clavier. Utilisez ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/he/FontChoice.js b/dijit/_editor/nls/he/FontChoice.js
index bcffb70..72363d6 100644
--- a/dijit/_editor/nls/he/FontChoice.js
+++ b/dijit/_editor/nls/he/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "גודל",
 	fontName: "גופן",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "ללא ",
 	p: "פיסקה",
 	h1: "כותרת",
 	h2: "תת-כותרת",
@@ -22,4 +25,6 @@
 	5: "גדול",
 	6: "גדול מאוד",
 	7: "גדול ביותר"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/he/LinkDialog.js b/dijit/_editor/nls/he/LinkDialog.js
index 5566e91..1a16944 100644
--- a/dijit/_editor/nls/he/LinkDialog.js
+++ b/dijit/_editor/nls/he/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "תכונות קישור",
 	insertImageTitle: "תכונות תמונה",
@@ -5,9 +7,11 @@
 	text: "תיאור:",
 	target: "יעד:",
 	set: "הגדרה",
-	currentWindow: "חלון נוכחי ",
+	currentWindow: "חלון נוכחי",
 	parentWindow: "חלון אב",
-	topWindow: "חלון עליון ",
+	topWindow: "חלון עליון",
 	newWindow: "חלון חדש"
 })
+//end v1.x content
+);
 
diff --git a/dijit/_editor/nls/he/commands.js b/dijit/_editor/nls/he/commands.js
index b872a60..69d2a74 100644
--- a/dijit/_editor/nls/he/commands.js
+++ b/dijit/_editor/nls/he/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'מודגש',
 	'copy': 'עותק',
@@ -38,13 +40,14 @@
 	'fontSize': 'גופן יחסי',
 	'fontName': 'שם גופן',
 	'tabIndent': 'כניסת טאב',
-	"fullScreen": "מיתוג מסך מלא ",
-	"viewSource": "הצגת מקור HTML ",
+	"fullScreen": "מיתוג מסך מלא",
+	"viewSource": "הצגת מקור HTML",
 	"print": "הדפסה",
-	"newPage": "דף חדש ",
+	"newPage": "דף חדש",
 	/* Error messages */
 	'systemShortcut': 'הפעולה "${0}" זמינה בדפדפן רק באמצעות קיצור דרך במקלדת. השתמשו בקיצור ${1}.',
 	'ctrlKey':'ctrl+${0}‎',
 	'appleKey':'\u2318${0}‎' // "command" or open-apple key on Macintosh
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/hu/FontChoice.js b/dijit/_editor/nls/hu/FontChoice.js
index e925dec..e37ab40 100644
--- a/dijit/_editor/nls/hu/FontChoice.js
+++ b/dijit/_editor/nls/hu/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Méret",
 	fontName: "Betűtípus",
@@ -9,6 +11,7 @@
 	cursive: "kurzív",
 	fantasy: "fantázia",
 
+	noFormat: "Nincs",
 	p: "Bekezdés",
 	h1: "Címsor",
 	h2: "Alcím",
@@ -22,4 +25,6 @@
 	5: "nagy",
 	6: "x-nagy",
 	7: "xx-nagy"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/hu/LinkDialog.js b/dijit/_editor/nls/hu/LinkDialog.js
index dcc5a06..4e73312 100644
--- a/dijit/_editor/nls/hu/LinkDialog.js
+++ b/dijit/_editor/nls/hu/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Hivatkozás tulajdonságai",
 	insertImageTitle: "Kép tulajdonságai",
@@ -11,3 +13,5 @@
 	newWindow: "Új ablak"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/hu/commands.js b/dijit/_editor/nls/hu/commands.js
index cffd776..6afb026 100644
--- a/dijit/_editor/nls/hu/commands.js
+++ b/dijit/_editor/nls/hu/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Félkövér',
 	'copy': 'Másolás',
@@ -45,4 +47,5 @@
 	/* Error messages */
 	'systemShortcut': 'A(z) "${0}" művelet a böngészőben csak billentyűparancs használatával érhető el. Használja a következőt: ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/it/FontChoice.js b/dijit/_editor/nls/it/FontChoice.js
index 4f818ce..29c9dfa 100644
--- a/dijit/_editor/nls/it/FontChoice.js
+++ b/dijit/_editor/nls/it/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Dimensione",
 	fontName: "Carattere",
@@ -9,6 +11,7 @@
 	cursive: "corsivo",
 	fantasy: "fantasy",
 
+	noFormat: "Nessuna",
 	p: "Paragrafo",
 	h1: "Intestazione",
 	h2: "Sottointestazione",
@@ -22,4 +25,7 @@
 	5: "large",
 	6: "x-large",
 	7: "xx-large"
-})
\ No newline at end of file
+})
+
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/it/LinkDialog.js b/dijit/_editor/nls/it/LinkDialog.js
index 9af2670..b659615 100644
--- a/dijit/_editor/nls/it/LinkDialog.js
+++ b/dijit/_editor/nls/it/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Proprietà collegamento",
 	insertImageTitle: "Proprietà immagine",
@@ -6,8 +8,10 @@
 	target: "Destinazione:",
 	set: "Imposta",
 	currentWindow: "Finestra corrente",
-	parentWindow: "Finestra padre",
-	topWindow: "Finestra superiore",
+	parentWindow: "Finestra parent",
+	topWindow: "Finestra in primo piano",
 	newWindow: "Nuova finestra"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/it/commands.js b/dijit/_editor/nls/it/commands.js
index 711acf2..1aa2df5 100644
--- a/dijit/_editor/nls/it/commands.js
+++ b/dijit/_editor/nls/it/commands.js
@@ -1,9 +1,11 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Grassetto',
 	'copy': 'Copia',
 	'cut': 'Taglia',
 	'delete': 'Elimina',
-	'indent': 'Rientro',
+	'indent': 'Rientra',
 	'insertHorizontalRule': 'Righello orizzontale',
 	'insertOrderedList': 'Elenco numerato',
 	'insertUnorderedList': 'Elenco puntato',
@@ -12,7 +14,7 @@
 	'justifyFull': 'Giustifica',
 	'justifyLeft': 'Allinea a sinistra',
 	'justifyRight': 'Allinea a destra',
-	'outdent': 'Annulla rientro',
+	'outdent': 'Rimuovi rientro',
 	'paste': 'Incolla',
 	'redo': 'Ripristina',
 	'removeFormat': 'Rimuovi formato',
@@ -20,14 +22,14 @@
 	'strikethrough': 'Barrato',
 	'subscript': 'Pedice',
 	'superscript': 'Apice',
-	'underline': 'Sottolinea',
+	'underline': 'Sottolineato',
 	'undo': 'Annulla',
 	'unlink': 'Rimuovi collegamento',
 	'createLink': 'Crea collegamento',
-	'toggleDir': 'Attiva/Disattiva direzione',
+	'toggleDir': 'Inverti direzione',
 	'insertImage': 'Inserisci immagine',
 	'insertTable': 'Inserisci/Modifica tabella',
-	'toggleTableBorder': 'Attiva/Disattiva bordo tabella',
+	'toggleTableBorder': 'Mostra/Nascondi margine tabella',
 	'deleteTable': 'Elimina tabella',
 	'tableProp': 'Proprietà tabella',
 	'htmlToggle': 'Origine HTML',
@@ -37,12 +39,14 @@
 	'formatBlock': 'Stile paragrafo',
 	'fontSize': 'Dimensione carattere',
 	'fontName': 'Nome carattere',
-	'tabIndent': 'Rientro tabulazione',
+	'tabIndent': 'Rientranza tabulazione',
 	"fullScreen": "Attiva/Disattiva schermo intero",
 	"viewSource": "Visualizza origine HTML",
 	"print": "Stampa",
 	"newPage": "Nuova pagina",
 	/* Error messages */
-	'systemShortcut': 'La azione "${0}" è disponibile solo nel browser tramite un tasto di scelta rapida. Utilizzare ${1}.'
+	'systemShortcut': 'Azione "${0}" disponibile sul proprio browser solo mediante i tasti di scelta rapida della tastiera. Utilizzare ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ja/FontChoice.js b/dijit/_editor/nls/ja/FontChoice.js
index d7e62f3..45d6178 100644
--- a/dijit/_editor/nls/ja/FontChoice.js
+++ b/dijit/_editor/nls/ja/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "サイズ",
 	fontName: "フォント",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "なし",
 	p: "段落",
 	h1: "見出し",
 	h2: "副見出し",
@@ -22,4 +25,6 @@
 	5: "大",
 	6: "特大",
 	7: "超特大"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ja/LinkDialog.js b/dijit/_editor/nls/ja/LinkDialog.js
index b9f2ab1..df9c07d 100644
--- a/dijit/_editor/nls/ja/LinkDialog.js
+++ b/dijit/_editor/nls/ja/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "リンク・プロパティー",
 	insertImageTitle: "イメージ・プロパティー",
@@ -11,3 +13,5 @@
 	newWindow: "新規ウィンドウ"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ja/commands.js b/dijit/_editor/nls/ja/commands.js
index e1b5471..4e8f1a9 100644
--- a/dijit/_editor/nls/ja/commands.js
+++ b/dijit/_editor/nls/ja/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': '太字',
 	'copy': 'コピー',
@@ -7,7 +9,7 @@
 	'insertHorizontalRule': '水平罫線',
 	'insertOrderedList': '番号付きリスト',
 	'insertUnorderedList': '黒丸付きリスト',
-	'italic': '斜体',
+	'italic': 'イタリック',
 	'justifyCenter': '中央揃え',
 	'justifyFull': '両端揃え',
 	'justifyLeft': '左揃え',
@@ -15,7 +17,7 @@
 	'outdent': 'アウトデント',
 	'paste': '貼り付け',
 	'redo': 'やり直し',
-	'removeFormat': '形式の除去',
+	'removeFormat': '書式のクリア',
 	'selectAll': 'すべて選択',
 	'strikethrough': '取り消し線',
 	'subscript': '下付き文字',
@@ -27,21 +29,24 @@
 	'toggleDir': '方向の切り替え',
 	'insertImage': 'イメージの挿入',
 	'insertTable': 'テーブルの挿入/編集',
-	'toggleTableBorder': 'テーブルボーダーの切り替え',
+	'toggleTableBorder': 'テーブル・ボーダーの切り替え',
 	'deleteTable': 'テーブルの削除',
-	'tableProp': 'テーブルプロパティ',
+	'tableProp': 'テーブル・プロパティー',
 	'htmlToggle': 'HTML ソース',
 	'foreColor': '前景色',
-	'hiliteColor': '背景色',
+	'hiliteColor': 'マーカー',
 	'plainFormatBlock': '段落スタイル',
 	'formatBlock': '段落スタイル',
-	'fontSize': 'フォントサイズ',
+	'fontSize': 'フォント・サイズ',
 	'fontName': 'フォント名',
-	'tabIndent': 'タブインデント',
+	'tabIndent': 'タブ・インデント',
 	"fullScreen": "全画面表示に切り替え",
 	"viewSource": "HTML ソースの表示",
 	"print": "印刷",
-	"newPage": "新しいページ",
+	"newPage": "新規ページ",
 	/* Error messages */
-	'systemShortcut': '"${0}" アクションを使用できるのは、ブラウザーでキーボードショートカットを使用する場合のみです。 ${1} を使用してください。'
+	'systemShortcut': '"${0}" アクションを使用できるのは、ブラウザーでキーボード・ショートカットを使用する場合のみです。${1} を使用してください。',
+	'ctrlKey':'Ctrl+${0}'
 })
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/kk/FontChoice.js b/dijit/_editor/nls/kk/FontChoice.js
new file mode 100644
index 0000000..37a1944
--- /dev/null
+++ b/dijit/_editor/nls/kk/FontChoice.js
@@ -0,0 +1,30 @@
+define(
+//begin v1.x content
+({
+	fontSize: "Өлшемі",
+	fontName: "Қаріп",
+	formatBlock: "Пішім",
+
+	serif: "serif",
+	"sans-serif": "sans-serif",
+	monospace: "monospace",
+	cursive: "көлбеу",
+	fantasy: "қиял-ғажайып",
+
+	noFormat: "Ешбір",
+	p: "Еже",
+	h1: "Үстіңгі деректеме",
+	h2: "Ішкі тақырып",
+	h3: "Ішкі-ішкі тақырып",
+	pre: "Алдын ала пішімделген",
+
+	1: "xx-кіші",
+	2: "x-кіші",
+	3: "кіші",
+	4: "орташа",
+	5: "үлкен",
+	6: "x-үлкен",
+	7: "xx-үлкен"
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/kk/LinkDialog.js b/dijit/_editor/nls/kk/LinkDialog.js
new file mode 100644
index 0000000..bbf9688
--- /dev/null
+++ b/dijit/_editor/nls/kk/LinkDialog.js
@@ -0,0 +1,16 @@
+define(
+//begin v1.x content
+({
+	createLinkTitle: "Сілтеме сипаттары",
+	insertImageTitle: "Сурет сипаттары",
+	url: "URL мекенжайы:",
+	text: "Сипаттама:",
+	target: "Мақсат:",
+	set: "Орнату",
+	currentWindow: "Ағымдағы терезе",
+	parentWindow: "Басты терезе",
+	topWindow: "Ең жоғарғы терезе",
+	newWindow: "Жаңа терезе"
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/kk/commands.js b/dijit/_editor/nls/kk/commands.js
new file mode 100644
index 0000000..b03c438
--- /dev/null
+++ b/dijit/_editor/nls/kk/commands.js
@@ -0,0 +1,51 @@
+define(
+//begin v1.x content
+({
+	'bold': 'Қалың',
+	'copy': 'Көшіру',
+	'cut': 'Қиып алу',
+	'delete': 'Жою',
+	'indent': 'Шегіндіру',
+	'insertHorizontalRule': 'Көлденең сызғыш',
+	'insertOrderedList': 'Нөмірленген тізім',
+	'insertUnorderedList': 'Таңбалауыш тізім',
+	'italic': 'Көлбеу',
+	'justifyCenter': 'Ортасы бойынша туралау',
+	'justifyFull': 'Туралау',
+	'justifyLeft': 'Сол жақ бойынша туралау',
+	'justifyRight': 'Оң жақ бойынша туралау',
+	'outdent': 'Шығыңқы',
+	'paste': 'Қою',
+	'redo': 'Қайтару',
+	'removeFormat': 'Пішімді алып тастау',
+	'selectAll': 'Барлығын таңдау',
+	'strikethrough': 'Сызылған',
+	'subscript': 'Жоласты',
+	'superscript': 'Жолүсті',
+	'underline': 'Асты сызылған',
+	'undo': 'Болдырмау ',
+	'unlink': 'Сілтемені жою',
+	'createLink': 'Сілтеме жасау',
+	'toggleDir': 'Бағытты қосу',
+	'insertImage': 'Сурет кірістіру',
+	'insertTable': 'Кестені кірістіру/өңдеу',
+	'toggleTableBorder': 'Кесте жиегін қосу',
+	'deleteTable': 'Кестені жою',
+	'tableProp': 'Кесте сипаты',
+	'htmlToggle': 'HTML көзі',
+	'foreColor': 'Алды түсі',
+	'hiliteColor': 'Өң түсі',
+	'plainFormatBlock': 'Еже мәнері',
+	'formatBlock': 'Еже мәнері',
+	'fontSize': 'Қаріп өлшемі',
+	'fontName': 'Қаріп атауы',
+	'tabIndent': 'Қойынды шегінісі',
+	"fullScreen": "Толық экранды қосу",
+	"viewSource": "HTML көзін қарау",
+	"print": "Басып шығару",
+	"newPage": "Жаңа бет",
+	/* Error messages */
+	'systemShortcut': '"${0}" әрекеті шолғышта тек пернелер тіркесімі арқылы қол жетімді. ${1} пайдаланыңыз.'
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ko/FontChoice.js b/dijit/_editor/nls/ko/FontChoice.js
index 7fe52f3..b1ecdfd 100644
--- a/dijit/_editor/nls/ko/FontChoice.js
+++ b/dijit/_editor/nls/ko/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "크기",
 	fontName: "글꼴",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "없음",
 	p: "단락",
 	h1: "제목",
 	h2: "부제목",
@@ -22,4 +25,6 @@
 	5: "크게",
 	6: "조금 크게",
 	7: "가장 크게"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ko/LinkDialog.js b/dijit/_editor/nls/ko/LinkDialog.js
index ea87569..f9a42da 100644
--- a/dijit/_editor/nls/ko/LinkDialog.js
+++ b/dijit/_editor/nls/ko/LinkDialog.js
@@ -1,9 +1,11 @@
+define(
+//begin v1.x content
 ({
-	createLinkTitle: "링크 특성",
-	insertImageTitle: "이미지 특성",
+	createLinkTitle: "링크 등록 정보",
+	insertImageTitle: "이미지 등록 정보",
 	url: "URL:",
 	text: "설명:",
-	target: "대상:",
+	target: "대상",
 	set: "설정",
 	currentWindow: "현재 창",
 	parentWindow: "상위 창",
@@ -11,3 +13,5 @@
 	newWindow: "새 창"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ko/commands.js b/dijit/_editor/nls/ko/commands.js
index d278c4b..062e8c4 100644
--- a/dijit/_editor/nls/ko/commands.js
+++ b/dijit/_editor/nls/ko/commands.js
@@ -1,5 +1,7 @@
+define(
+//begin v1.x content
 ({
-	'bold': '굵은체',
+	'bold': '굵게',
 	'copy': '복사',
 	'cut': '잘라내기',
 	'delete': '삭제',
@@ -7,7 +9,7 @@
 	'insertHorizontalRule': '수평 자',
 	'insertOrderedList': '번호 목록',
 	'insertUnorderedList': '글머리표 목록',
-	'italic': '기울임체',
+	'italic': '기울임꼴',
 	'justifyCenter': '가운데 맞춤',
 	'justifyFull': '양쪽 맞춤',
 	'justifyLeft': '왼쪽 맞춤',
@@ -24,25 +26,26 @@
 	'undo': '실행 취소',
 	'unlink': '링크 제거',
 	'createLink': '링크 작성',
-	'toggleDir': '토글 방향',
+	'toggleDir': '방향 토글',
 	'insertImage': '이미지 삽입',
 	'insertTable': '테이블 삽입/편집',
-	'toggleTableBorder': '토글 테이블 테두리',
+	'toggleTableBorder': '테이블 외곽선 토글',
 	'deleteTable': '테이블 삭제',
 	'tableProp': '테이블 특성',
 	'htmlToggle': 'HTML 소스',
 	'foreColor': '전경색',
 	'hiliteColor': '배경색',
-	'plainFormatBlock': '단락 스타일',
-	'formatBlock': '단락 스타일',
+	'plainFormatBlock': '단락 양식',
+	'formatBlock': '단락 양식',
 	'fontSize': '글꼴 크기',
 	'fontName': '글꼴 이름',
 	'tabIndent': '탭 들여쓰기',
-	"fullScreen": "토글 전체 화면",
+	"fullScreen": "전체 화면 토글",
 	"viewSource": "HTML 소스 보기",
 	"print": "인쇄",
 	"newPage": "새 페이지",
 	/* Error messages */
-	'systemShortcut': '"${0}" 조치는 브라우저에서 키보드 단축키를 이용해서만 사용할 수 있습니다. ${1}을(를) 사용하십시오.'
+	'systemShortcut': '"${0}" 조치는 브라우저에서 키보드 단축키를 통해서만 사용 가능합니다. ${1}을(를) 사용하십시오.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/nb/FontChoice.js b/dijit/_editor/nls/nb/FontChoice.js
index 84b00a9..358233f 100644
--- a/dijit/_editor/nls/nb/FontChoice.js
+++ b/dijit/_editor/nls/nb/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Størrelse",
 	fontName: "Skrift",
@@ -9,6 +11,7 @@
 	cursive: "kursiv",
 	fantasy: "fantasi",
 
+	noFormat: "Ingen",
 	p: "Avsnitt",
 	h1: "Overskrift",
 	h2: "Undertittel",
@@ -22,4 +25,6 @@
 	5: "stor",
 	6: "x-stor",
 	7: "xx-stor"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/nb/LinkDialog.js b/dijit/_editor/nls/nb/LinkDialog.js
index e7f0f8d..ad1dd86 100644
--- a/dijit/_editor/nls/nb/LinkDialog.js
+++ b/dijit/_editor/nls/nb/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Koblingsegenskaper",
 	insertImageTitle: "Bildeegenskaper",
@@ -11,3 +13,5 @@
 	newWindow: "Nytt vindu"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/nb/commands.js b/dijit/_editor/nls/nb/commands.js
index 7b47e4f..5bad6a5 100644
--- a/dijit/_editor/nls/nb/commands.js
+++ b/dijit/_editor/nls/nb/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Fet',
 	'copy': 'Kopier',
@@ -43,6 +45,9 @@
 	"print": "Skriv ut",
 	"newPage": "Ny side",
 	/* Error messages */
-	'systemShortcut': 'Handlingen "${0}" er bare tilgjengelig i nettleseren ved hjelp av en tastatursnarvei. Bruk ${1}.'
+	'systemShortcut': 'Handlingen "${0}" er bare tilgjengelig i nettleseren ved hjelp av en tastatursnarvei. Bruk ${1}.',
+	'ctrlKey':'ctrl+${0}',
+	'appleKey':'\u2318${0}' // "command" or open-apple key on Macintosh
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/nl/FontChoice.js b/dijit/_editor/nls/nl/FontChoice.js
index db9a8ba..a422387 100644
--- a/dijit/_editor/nls/nl/FontChoice.js
+++ b/dijit/_editor/nls/nl/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Grootte",
 	fontName: "Lettertype",
@@ -9,6 +11,7 @@
 	cursive: "cursief",
 	fantasy: "fantasy",
 
+	noFormat: "Geen",
 	p: "Alinea",
 	h1: "Kop",
 	h2: "Subkop",
@@ -22,4 +25,6 @@
 	5: "groot",
 	6: "x-groot",
 	7: "xx-groot"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/nl/LinkDialog.js b/dijit/_editor/nls/nl/LinkDialog.js
index 38840ee..786058b 100644
--- a/dijit/_editor/nls/nl/LinkDialog.js
+++ b/dijit/_editor/nls/nl/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Linkeigenschappen",
 	insertImageTitle: "Afbeeldingseigenschappen",
@@ -11,3 +13,5 @@
 	newWindow: "Nieuw venster"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/nl/commands.js b/dijit/_editor/nls/nl/commands.js
index 01366f7..d2527d3 100644
--- a/dijit/_editor/nls/nl/commands.js
+++ b/dijit/_editor/nls/nl/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Vet',
 	'copy': 'Kopiëren',
@@ -45,4 +47,5 @@
 	/* Error messages */
 	'systemShortcut': 'De actie "${0}" is alleen beschikbaar in uw browser via een sneltoetscombinatie. Gebruik ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pl/FontChoice.js b/dijit/_editor/nls/pl/FontChoice.js
index 8a1546c..49ac3e4 100644
--- a/dijit/_editor/nls/pl/FontChoice.js
+++ b/dijit/_editor/nls/pl/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Wielkość",
 	fontName: "Czcionka",
@@ -9,6 +11,7 @@
 	cursive: "kursywa",
 	fantasy: "fantazyjna",
 
+	noFormat: "Brak",
 	p: "Akapit",
 	h1: "Nagłówek",
 	h2: "Nagłówek 2-go poziomu",
@@ -22,4 +25,6 @@
 	5: "duża",
 	6: "większa",
 	7: "największa"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pl/LinkDialog.js b/dijit/_editor/nls/pl/LinkDialog.js
index 138d55f..0cd9bb5 100644
--- a/dijit/_editor/nls/pl/LinkDialog.js
+++ b/dijit/_editor/nls/pl/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Właściwości odsyłacza",
 	insertImageTitle: "Właściwości obrazu",
@@ -11,3 +13,5 @@
 	newWindow: "Nowe okno"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pl/commands.js b/dijit/_editor/nls/pl/commands.js
index 8b388b4..ab20734 100644
--- a/dijit/_editor/nls/pl/commands.js
+++ b/dijit/_editor/nls/pl/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Pogrubienie',
 	'copy': 'Kopiuj',
@@ -30,7 +32,7 @@
 	'toggleTableBorder': 'Przełącz ramkę tabeli',
 	'deleteTable': 'Usuń tabelę',
 	'tableProp': 'Właściwość tabeli',
-	'htmlToggle': 'Źródło HTML',
+	'htmlToggle': 'Kod źródłowy HTML',
 	'foreColor': 'Kolor pierwszego planu',
 	'hiliteColor': 'Kolor tła',
 	'plainFormatBlock': 'Styl akapitu',
@@ -47,3 +49,5 @@
 	'ctrlKey':'Ctrl+${0}'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pt-pt/FontChoice.js b/dijit/_editor/nls/pt-pt/FontChoice.js
index f038d84..c867ff6 100644
--- a/dijit/_editor/nls/pt-pt/FontChoice.js
+++ b/dijit/_editor/nls/pt-pt/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Tamanho",
 	fontName: "Tipo de letra",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "Nenhum",
 	p: "Parágrafo",
 	h1: "Título",
 	h2: "Sub-título",
@@ -22,4 +25,6 @@
 	5: "large",
 	6: "xl",
 	7: "xxl"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pt-pt/LinkDialog.js b/dijit/_editor/nls/pt-pt/LinkDialog.js
index 70f0f52..51d7455 100644
--- a/dijit/_editor/nls/pt-pt/LinkDialog.js
+++ b/dijit/_editor/nls/pt-pt/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Propriedades da ligação",
 	insertImageTitle: "Propriedades da imagem",
@@ -11,3 +13,5 @@
 	newWindow: "Nova janela"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pt-pt/commands.js b/dijit/_editor/nls/pt-pt/commands.js
index 30080d2..539d96a 100644
--- a/dijit/_editor/nls/pt-pt/commands.js
+++ b/dijit/_editor/nls/pt-pt/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Negrito',
 	'copy': 'Copiar',
@@ -30,7 +32,7 @@
 	'toggleTableBorder': 'Alternar contorno da tabela',
 	'deleteTable': 'Eliminar tabela',
 	'tableProp': 'Propriedades da tabela',
-	'htmlToggle': 'Origem HTML',
+	'htmlToggle': 'Código-fonte de HTML',
 	'foreColor': 'Cor de primeiro plano',
 	'hiliteColor': 'Cor de segundo plano',
 	'plainFormatBlock': 'Estilo de parágrafo',
@@ -46,3 +48,5 @@
 	'systemShortcut': 'A acção "${0}" apenas está disponível no navegador utilizando um atalho de teclado. Utilize ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pt/FontChoice.js b/dijit/_editor/nls/pt/FontChoice.js
index ee93dcc..94c2ba0 100644
--- a/dijit/_editor/nls/pt/FontChoice.js
+++ b/dijit/_editor/nls/pt/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Tamanho",
 	fontName: "Fonte",
@@ -9,6 +11,7 @@
 	cursive: "cursiva",
 	fantasy: "fantasy",
 
+	noFormat: "Nenhuma",
 	p: "Parágrafo",
 	h1: "Título",
 	h2: "Subtítulo",
@@ -23,3 +26,5 @@
 	6: "extra-grande",
 	7: "extra-extra-grande"
 })
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pt/LinkDialog.js b/dijit/_editor/nls/pt/LinkDialog.js
index 4e09587..f303014 100644
--- a/dijit/_editor/nls/pt/LinkDialog.js
+++ b/dijit/_editor/nls/pt/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Propriedades de Link",
 	insertImageTitle: "Propriedades de Imagem",
@@ -11,3 +13,5 @@
 	newWindow: "Nova Janela"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/pt/commands.js b/dijit/_editor/nls/pt/commands.js
index e0e6d75..e613736 100644
--- a/dijit/_editor/nls/pt/commands.js
+++ b/dijit/_editor/nls/pt/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Negrito',
 	'copy': 'Copiar',
@@ -10,9 +12,9 @@
 	'italic': 'Itálico',
 	'justifyCenter': 'Alinhar pelo Centro',
 	'justifyFull': 'Justificar',
-	'justifyLeft': 'Alinhar pela Esquerda',
-	'justifyRight': 'Alinhar pela Direita',
-	'outdent': 'Não-chanfrado',
+	'justifyLeft': 'Alinhar à Esquerda',
+	'justifyRight': 'Alinhar à Direita',
+	'outdent': 'Não chanfrado',
 	'paste': 'Colar',
 	'redo': 'Refazer',
 	'removeFormat': 'Remover Formato',
@@ -32,7 +34,7 @@
 	'tableProp': 'Propriedade da Tabela',
 	'htmlToggle': 'Origem HTML',
 	'foreColor': 'Cor do Primeiro Plano',
-	'hiliteColor': 'Cor de segundo plano',
+	'hiliteColor': 'Cor do Segundo Plano',
 	'plainFormatBlock': 'Estilo de Parágrafo',
 	'formatBlock': 'Estilo de Parágrafo',
 	'fontSize': 'Tamanho da Fonte',
@@ -40,9 +42,10 @@
 	'tabIndent': 'Recuo de Guia',
 	"fullScreen": "Comutar Tela Cheia",
 	"viewSource": "Visualizar Origem HTML",
-	"print": "Impressão",
+	"print": "Imprimir",
 	"newPage": "Nova Página",
 	/* Error messages */
-	'systemShortcut': 'A ação "${0}" está disponível em seu navegador apenas usando um atalho do teclado. Use ${1}.'
+	'systemShortcut': 'A ação "${0}" está disponível em seu navegador apenas usando um atalho de teclado. Use ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ro/FontChoice.js b/dijit/_editor/nls/ro/FontChoice.js
index 1badfb3..3e9621a 100644
--- a/dijit/_editor/nls/ro/FontChoice.js
+++ b/dijit/_editor/nls/ro/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Dimensiune",
 	fontName: "Font",
@@ -25,3 +27,5 @@
 	7: "xxl (xx-large)"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ro/LinkDialog.js b/dijit/_editor/nls/ro/LinkDialog.js
index edb7add..847d296 100644
--- a/dijit/_editor/nls/ro/LinkDialog.js
+++ b/dijit/_editor/nls/ro/LinkDialog.js
@@ -1,13 +1,17 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Proprietăţi legătură",
 	insertImageTitle: "Proprietăţi imagine",
 	url: "URL:",
 	text: "Descriere:",
-	target: "Ţintă:",
+	target: "Destinaţie:",
 	set: "Setare",
 	currentWindow: "Fereastra curentă",
 	parentWindow: "Fereastra părinte",
 	topWindow: "Fereastra cea mai de sus",
-	newWindow: "Fereastră nouă"
+	newWindow: "Fereastra nouă"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ro/commands.js b/dijit/_editor/nls/ro/commands.js
index a6a383a..724f340 100644
--- a/dijit/_editor/nls/ro/commands.js
+++ b/dijit/_editor/nls/ro/commands.js
@@ -1,23 +1,25 @@
+define(
+//begin v1.x content
 ({
-	'bold': 'Aldine',
+	'bold': 'Aldin',
 	'copy': 'Copiere',
 	'cut': 'Tăiere',
 	'delete': 'Ştergere',
-	'indent': 'Indentare',
-	'insertHorizontalRule': 'Regulă orizontală',
+	'indent': 'Micşorare indent',
+	'insertHorizontalRule': 'Linie delimitatoare',
 	'insertOrderedList': 'Listă numerotată',
-	'insertUnorderedList': 'Listă cu marcaje',
-	'italic': 'Cursive',
-	'justifyCenter': 'Aliniere pe centru',
-	'justifyFull': 'Aliniere',
-	'justifyLeft': 'Aliniere la stânga',
-	'justifyRight': 'Aliniere la dreapta',
-	'outdent': 'Outdentare',
+	'insertUnorderedList': 'Listă cu marcator',
+	'italic': 'Cursiv',
+	'justifyCenter': 'Aliniere centru',
+	'justifyFull': 'Aliniere stânga-dreapta',
+	'justifyLeft': 'Aliniere stânga',
+	'justifyRight': 'Aliniere dreapta',
+	'outdent': 'Mărire indent',
 	'paste': 'Lipire',
-	'redo': 'Repetare acţiune',
+	'redo': 'Refacere acţiune',
 	'removeFormat': 'Înlăturare format',
-	'selectAll': 'Selectare toate',
-	'strikethrough': 'Suprascriere linie',
+	'selectAll': 'Selectează tot',
+	'strikethrough': 'Tăiere text cu o linie',
 	'subscript': 'Scriere indice inferior',
 	'superscript': 'Scriere indice superior',
 	'underline': 'Subliniere',
@@ -29,20 +31,21 @@
 	'insertTable': 'Inserare/Editare tabelă',
 	'toggleTableBorder': 'Comutare bordură tabelă',
 	'deleteTable': 'Ştergere tabelă',
-	'tableProp': 'Proprietăţi tabelă',
+	'tableProp': 'Proprietate tabelă',
 	'htmlToggle': 'Sursă HTML',
-	'foreColor': 'Culoare prim plan',
-	'hiliteColor': 'Culoare fundal',
+	'foreColor': 'Culoare de prim-plan',
+	'hiliteColor': 'Culoare de fundal',
 	'plainFormatBlock': 'Stil paragraf',
 	'formatBlock': 'Stil paragraf',
 	'fontSize': 'Dimensiune font',
 	'fontName': 'Nume font',
-	'tabIndent': 'Indentare cu tab',
+	'tabIndent': 'Indentare Tab',
 	"fullScreen": "Comutare ecran complet",
-	"viewSource": "Vizualizare sursă HTML",
+	"viewSource": "Vizualizara sursă HTML",
 	"print": "Tipărire",
 	"newPage": "Pagină nouă",
 	/* Error messages */
-	'systemShortcut': 'Acţiunea "${0}" este disponibilă în browser folosind o scurtătură de la tastatură. Folosiţi ${1}.'
+	'systemShortcut': 'Acţiunea "${0}" este disponibilă în browser doar utilizând o comandă rapidă de la tastatură. Utilizaţi ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ru/FontChoice.js b/dijit/_editor/nls/ru/FontChoice.js
index daf517f..414f995 100644
--- a/dijit/_editor/nls/ru/FontChoice.js
+++ b/dijit/_editor/nls/ru/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Размер",
 	fontName: "Шрифт",
@@ -9,6 +11,7 @@
 	cursive: "курсив",
 	fantasy: "артистический",
 
+	noFormat: "Нет",
 	p: "Абзац",
 	h1: "Заголовок",
 	h2: "Подзаголовок",
@@ -22,4 +25,6 @@
 	5: "большой",
 	6: "очень большой",
 	7: "самый большой"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ru/LinkDialog.js b/dijit/_editor/nls/ru/LinkDialog.js
index d985008..5f8eff8 100644
--- a/dijit/_editor/nls/ru/LinkDialog.js
+++ b/dijit/_editor/nls/ru/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Свойства ссылки",
 	insertImageTitle: "Свойства изображения",
@@ -7,7 +9,9 @@
 	set: "Задать",
 	currentWindow: "Текущее окно",
 	parentWindow: "Родительское окно",
-	topWindow: "Окно верхнего уровня",
+	topWindow: "Верхнее окно",
 	newWindow: "Новое окно"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/ru/commands.js b/dijit/_editor/nls/ru/commands.js
index f609cee..90f5d15 100644
--- a/dijit/_editor/nls/ru/commands.js
+++ b/dijit/_editor/nls/ru/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Полужирный',
 	'copy': 'Копировать',
@@ -46,3 +48,5 @@
 	'systemShortcut': 'Действие "${0}" можно выполнить в браузере только путем нажатия клавиш ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sk/FontChoice.js b/dijit/_editor/nls/sk/FontChoice.js
index 7bf92c8..4734c19 100644
--- a/dijit/_editor/nls/sk/FontChoice.js
+++ b/dijit/_editor/nls/sk/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Veľkosť",
 	fontName: "Písmo",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "Žiadny",
 	p: "Odsek",
 	h1: "Hlavička",
 	h2: "Podhlavička",
@@ -23,4 +26,6 @@
 	6: "x-large",
 	7: "xx-large"
 })
+//end v1.x content
+);
 
diff --git a/dijit/_editor/nls/sk/LinkDialog.js b/dijit/_editor/nls/sk/LinkDialog.js
index 9c8e0ba..ca57a1b 100644
--- a/dijit/_editor/nls/sk/LinkDialog.js
+++ b/dijit/_editor/nls/sk/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Pripojiť vlastnosti",
 	insertImageTitle: "Vlastnosti obrázka ",
@@ -11,3 +13,5 @@
 	newWindow: "Nové okno "
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sk/commands.js b/dijit/_editor/nls/sk/commands.js
index 03105d5..f4af3b3 100644
--- a/dijit/_editor/nls/sk/commands.js
+++ b/dijit/_editor/nls/sk/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Tučné písmo',
 	'copy': 'Kopírovať',
@@ -46,3 +48,5 @@
 	'systemShortcut': 'Akcia "${0}" je vo vašom prehliadači dostupná len s použitím klávesovej skratky. Použite ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sl/FontChoice.js b/dijit/_editor/nls/sl/FontChoice.js
index ff41d9c..f54975d 100644
--- a/dijit/_editor/nls/sl/FontChoice.js
+++ b/dijit/_editor/nls/sl/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Velikost",
 	fontName: "Pisava",
@@ -9,11 +11,12 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "Brez",
 	p: "Odstavek",
-	h1: "Naslov",
-	h2: "Podnaslov",
-	h3: "Pod podnaslov",
-	pre: "Vnaprej oblikovano",
+	h1: "Naslovni slog",
+	h2: "Podnaslovni slog",
+	h3: "Pod-podnaslovni slog",
+	pre: "Vnaprej oblikovan",
 
 	1: "xx-majhno",
 	2: "x-majhno",
@@ -24,3 +27,5 @@
 	7: "xx-veliko"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sl/LinkDialog.js b/dijit/_editor/nls/sl/LinkDialog.js
index 26e536c..7118f40 100644
--- a/dijit/_editor/nls/sl/LinkDialog.js
+++ b/dijit/_editor/nls/sl/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Lastnosti povezave",
 	insertImageTitle: "Lastnosti slike",
@@ -7,7 +9,9 @@
 	set: "Nastavi",
 	currentWindow: "Trenutno okno",
 	parentWindow: "Nadrejeno okno",
-	topWindow: "Najvišje okno",
+	topWindow: "Okno na vrhu",
 	newWindow: "Novo okno"
 })
+//end v1.x content
+);
 
diff --git a/dijit/_editor/nls/sl/commands.js b/dijit/_editor/nls/sl/commands.js
index bbdded1..f7e6877 100644
--- a/dijit/_editor/nls/sl/commands.js
+++ b/dijit/_editor/nls/sl/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Krepko',
 	'copy': 'Prekopiraj',
@@ -9,13 +11,13 @@
 	'insertUnorderedList': 'Naštevni seznam',
 	'italic': 'Ležeče',
 	'justifyCenter': 'Poravnaj na sredino',
-	'justifyFull': 'Obojestranska poravnava',
+	'justifyFull': 'Poravnaj obojestransko',
 	'justifyLeft': 'Poravnaj levo',
 	'justifyRight': 'Poravnaj desno',
-	'outdent': 'Viseč odstavek',
+	'outdent': 'Primakni',
 	'paste': 'Prilepi',
 	'redo': 'Znova uveljavi',
-	'removeFormat': 'Odstrani obliko zapisa',
+	'removeFormat': 'Odstrani oblikovanje',
 	'selectAll': 'Izberi vse',
 	'strikethrough': 'Prečrtano',
 	'subscript': 'Podpisano',
@@ -24,7 +26,7 @@
 	'undo': 'Razveljavi',
 	'unlink': 'Odstrani povezavo',
 	'createLink': 'Ustvari povezavo',
-	'toggleDir': 'Preklopi na usmeritev',
+	'toggleDir': 'Preklopi smer',
 	'insertImage': 'Vstavi sliko',
 	'insertTable': 'Vstavi/uredi tabelo',
 	'toggleTableBorder': 'Preklopi na rob tabele',
@@ -45,4 +47,5 @@
 	/* Error messages */
 	'systemShortcut': 'Dejanje "${0}" lahko v vašem brskalniku uporabite samo z bližnjico na tipkovnici. Uporabite ${1}.'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sv/FontChoice.js b/dijit/_editor/nls/sv/FontChoice.js
index cbfc0f2..4c92983 100644
--- a/dijit/_editor/nls/sv/FontChoice.js
+++ b/dijit/_editor/nls/sv/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Storlek",
 	fontName: "Teckensnitt",
@@ -9,6 +11,7 @@
 	cursive: "kursivt",
 	fantasy: "fantasy",
 
+	noFormat: "Ingen",
 	p: "Stycke",
 	h1: "Rubrik",
 	h2: "Underrubrik",
@@ -22,4 +25,6 @@
 	5: "stort",
 	6: "extra stort",
 	7: "extra extra stort"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sv/LinkDialog.js b/dijit/_editor/nls/sv/LinkDialog.js
index 8ac889d..9475026 100644
--- a/dijit/_editor/nls/sv/LinkDialog.js
+++ b/dijit/_editor/nls/sv/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Länkegenskaper",
 	insertImageTitle: "Bildegenskaper",
@@ -11,3 +13,5 @@
 	newWindow: "nytt fönster"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/sv/commands.js b/dijit/_editor/nls/sv/commands.js
index 5bca9c7..51a9b80 100644
--- a/dijit/_editor/nls/sv/commands.js
+++ b/dijit/_editor/nls/sv/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Fetstil',
 	'copy': 'Kopiera',
@@ -48,3 +50,5 @@
 	'appleKey':'\u2318+${0}' // "command" or open-apple key on Macintosh
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/th/FontChoice.js b/dijit/_editor/nls/th/FontChoice.js
index e90d262..9d48a6d 100644
--- a/dijit/_editor/nls/th/FontChoice.js
+++ b/dijit/_editor/nls/th/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "ขนาด",
 	fontName: "ฟอนต์",
@@ -9,6 +11,7 @@
 	cursive: "cursive",
 	fantasy: "fantasy",
 
+	noFormat: "ไม่มี",
 	p: "ย่อหน้า",
 	h1: "ส่วนหัว",
 	h2: "ส่วนหัวย่อย",
@@ -24,3 +27,5 @@
 	7: "xx-large"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/th/LinkDialog.js b/dijit/_editor/nls/th/LinkDialog.js
index 0e29ed5..515e441 100644
--- a/dijit/_editor/nls/th/LinkDialog.js
+++ b/dijit/_editor/nls/th/LinkDialog.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "คุณสมบัติลิงก์",
 	insertImageTitle: "คุณสมบัติอิมเมจ",
 	url: "URL:",
-	text: "รายละเอียด",
+	text: "รายละเอียด:",
 	target: "เป้าหมาย:",
 	set: "ตั้งค่า",
 	currentWindow: "หน้าต่างปัจจุบัน",
@@ -11,3 +13,5 @@
 	newWindow: "หน้าต่างใหม่"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/th/commands.js b/dijit/_editor/nls/th/commands.js
index e2cee6f..290e913 100644
--- a/dijit/_editor/nls/th/commands.js
+++ b/dijit/_editor/nls/th/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'ตัวหนา',
 	'copy': 'คัดลอก',
@@ -46,3 +48,5 @@
 	'systemShortcut': 'การดำเนินการ"${0}" ใช้งานได้เฉพาะกับเบราว์เซอร์ของคุณโดยใช้แป้นพิมพ์ลัด ใช้ ${1}'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/tr/FontChoice.js b/dijit/_editor/nls/tr/FontChoice.js
index 0860cdc..b97cad3 100644
--- a/dijit/_editor/nls/tr/FontChoice.js
+++ b/dijit/_editor/nls/tr/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "Boyut",
 	fontName: "Yazı Tipi",
@@ -9,6 +11,7 @@
 	cursive: "el yazısı",
 	fantasy: "fantazi",
 
+	noFormat: "Yok",
 	p: "Paragraf",
 	h1: "Başlık",
 	h2: "Alt Başlık",
@@ -22,4 +25,6 @@
 	5: "büyük",
 	6: "x-büyük",
 	7: "xx-büyük"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/tr/LinkDialog.js b/dijit/_editor/nls/tr/LinkDialog.js
index b10cff6..66b04e4 100644
--- a/dijit/_editor/nls/tr/LinkDialog.js
+++ b/dijit/_editor/nls/tr/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "Bağlantı Özellikleri",
 	insertImageTitle: "Resim Özellikleri",
@@ -11,3 +13,5 @@
 	newWindow: "Yeni Pencere"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/tr/commands.js b/dijit/_editor/nls/tr/commands.js
index 3423ed8..8b26396 100644
--- a/dijit/_editor/nls/tr/commands.js
+++ b/dijit/_editor/nls/tr/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': 'Kalın',
 	'copy': 'Kopyala',
@@ -46,3 +48,5 @@
 	'systemShortcut': '"${0}" işlemi yalnızca tarayıcınızda bir klavye kısayoluyla birlikte kullanılabilir. Şunu kullanın: ${1}.'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/zh-tw/FontChoice.js b/dijit/_editor/nls/zh-tw/FontChoice.js
index e77c569..f368836 100644
--- a/dijit/_editor/nls/zh-tw/FontChoice.js
+++ b/dijit/_editor/nls/zh-tw/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "大小",
 	fontName: "字型",
@@ -9,6 +11,7 @@
 	cursive: "Cursive",
 	fantasy: "Fantasy",
 
+	noFormat: "無",
 	p: "段落",
 	h1: "標題",
 	h2: "子標題",
@@ -22,4 +25,6 @@
 	5: "大",
 	6: "較大",
 	7: "最大"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/zh-tw/LinkDialog.js b/dijit/_editor/nls/zh-tw/LinkDialog.js
index d766166..446327a 100644
--- a/dijit/_editor/nls/zh-tw/LinkDialog.js
+++ b/dijit/_editor/nls/zh-tw/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "鏈結內容",
 	insertImageTitle: "影像內容",
@@ -11,3 +13,5 @@
 	newWindow: "新視窗"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/zh-tw/commands.js b/dijit/_editor/nls/zh-tw/commands.js
index 7e2ba3d..7efdda1 100644
--- a/dijit/_editor/nls/zh-tw/commands.js
+++ b/dijit/_editor/nls/zh-tw/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': '粗體',
 	'copy': '複製',
@@ -17,7 +19,7 @@
 	'redo': '重做',
 	'removeFormat': '移除格式',
 	'selectAll': '全選',
-	'strikethrough': '加刪除線',
+	'strikethrough': '刪除線',
 	'subscript': '下標',
 	'superscript': '上標',
 	'underline': '底線',
@@ -37,12 +39,13 @@
 	'formatBlock': '段落樣式',
 	'fontSize': '字型大小',
 	'fontName': '字型名稱',
-	'tabIndent': '定位點縮排',
+	'tabIndent': '標籤縮排',
 	"fullScreen": "切換全螢幕",
 	"viewSource": "檢視 HTML 原始檔",
 	"print": "列印",
-	"newPage": "新建頁面",
+	"newPage": "新頁面",
 	/* Error messages */
-	'systemShortcut': '"${0}" 動作只能在瀏覽器中透過使用鍵盤快速鍵來使用。請使用 ${1}。'
+	'systemShortcut': '"${0}" 動作在您的瀏覽器中,只能使用鍵盤快速鍵。請使用 ${1}。'
 })
-
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/zh/FontChoice.js b/dijit/_editor/nls/zh/FontChoice.js
index cc056a7..fe3f8e9 100644
--- a/dijit/_editor/nls/zh/FontChoice.js
+++ b/dijit/_editor/nls/zh/FontChoice.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	fontSize: "大小",
 	fontName: "字体",
@@ -9,6 +11,7 @@
 	cursive: "草书",
 	fantasy: "虚线",
 
+	noFormat: "无",
 	p: "段落",
 	h1: "标题",
 	h2: "子标题",
@@ -22,4 +25,6 @@
 	5: "L 号",
 	6: "XL 号",
 	7: "XXL 号"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/zh/LinkDialog.js b/dijit/_editor/nls/zh/LinkDialog.js
index bb24f31..e408cf0 100644
--- a/dijit/_editor/nls/zh/LinkDialog.js
+++ b/dijit/_editor/nls/zh/LinkDialog.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	createLinkTitle: "链接属性",
 	insertImageTitle: "图像属性",
@@ -7,7 +9,9 @@
 	set: "设置",
 	currentWindow: "当前窗口",
 	parentWindow: "父窗口",
-	topWindow: "最顶部窗口",
-	newWindow: "新窗口"
+	topWindow: "顶层窗口",
+	newWindow: "新建窗口"
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/nls/zh/commands.js b/dijit/_editor/nls/zh/commands.js
index 1618b6d..46bee0b 100644
--- a/dijit/_editor/nls/zh/commands.js
+++ b/dijit/_editor/nls/zh/commands.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	'bold': '粗体',
 	'copy': '复制',
@@ -46,3 +48,5 @@
 	'systemShortcut': '只能在浏览器中通过键盘快捷方式执行“${0}”操作。使用 ${1}。'
 })
 
+//end v1.x content
+);
diff --git a/dijit/_editor/plugins/AlwaysShowToolbar.js b/dijit/_editor/plugins/AlwaysShowToolbar.js
index 0a5d1a6..a8e9868 100644
--- a/dijit/_editor/plugins/AlwaysShowToolbar.js
+++ b/dijit/_editor/plugins/AlwaysShowToolbar.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._editor.plugins.AlwaysShowToolbar");
+define("dijit/_editor/plugins/AlwaysShowToolbar", ["dojo", "dijit", "dijit/_editor/_Plugin"], function(dojo, dijit) {
 
 dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 	{
@@ -50,7 +50,7 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		if(!e.isLoaded){ return; }
 		if(e.height){ return; }
 
-		var height = dojo.marginBox(e.editNode).h;
+		var height = dojo._getMarginSize(e.editNode).h;
 		if(dojo.isOpera){
 			height = e.editNode.scrollHeight;
 		}
@@ -60,7 +60,7 @@ 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.marginBox(e.document.body).h;
+			height = dojo._getMarginSize(e.document.body).h;
 		}
 
 		if(height == 0){
@@ -110,7 +110,7 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		if(scrollPos > this._scrollThreshold && scrollPos < this._scrollThreshold+this._lastHeight){
 			// dojo.debug(scrollPos);
 			if(!this._fixEnabled){
-				var tdnbox = dojo.marginBox(tdn);
+				var tdnbox = dojo._getMarginSize(tdn);
 				this.editor.iframe.style.marginTop = tdnbox.h+"px";
 
 				if(isIE6){
@@ -175,3 +175,7 @@ dojo.declare("dijit._editor.plugins.AlwaysShowToolbar", dijit._editor._Plugin,
 		}
 	}
 });
+
+
+return dijit._editor.plugins.AlwaysShowToolbar;
+});
diff --git a/dijit/_editor/plugins/EnterKeyHandling.js b/dijit/_editor/plugins/EnterKeyHandling.js
index f8d8e57..410fc9d 100644
--- a/dijit/_editor/plugins/EnterKeyHandling.js
+++ b/dijit/_editor/plugins/EnterKeyHandling.js
@@ -1,16 +1,11 @@
-dojo.provide("dijit._editor.plugins.EnterKeyHandling");
-
-dojo.require("dojo.window");
+define("dijit/_editor/plugins/EnterKeyHandling", ["dojo", "dijit", "dojo/window", "dijit/_editor/_Plugin", "dijit/_editor/range"], function(dojo, dijit) {
 
 dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 	// summary:
-	//		This plugin tries to make all browsers behave consistently w.r.t
-	//		displaying paragraphs, specifically dealing with when the user presses
-	//		the ENTER key.
-	//
-	//		It deals mainly with how the text appears on the screen (specifically
-	//		address the double-spaced line problem on IE), but also has some code
-	//		to normalize what attr('value') returns.
+	//		This plugin tries to make all browsers behave consistently with regard to
+	//		how ENTER behaves in the editor window.  It traps the ENTER key and alters
+	//		the way DOM is constructed in certain cases to try to commonize the generated
+	//		DOM and behaviors across browsers.
 	//
 	// description:
 	//		This plugin has three modes:
@@ -19,17 +14,27 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 	//			* blockModeForEnter=DIV
 	//			* blockModeForEnter=P
 	//
-	//		In blockModeForEnter=P, the ENTER key semantically means "start a new
-	//		paragraph", whereas shift-ENTER means  "new line in the current paragraph".
-	//		For example:
+	//		In blockModeForEnter=P, the ENTER key starts a new
+	//		paragraph, and shift-ENTER starts a new line in the current paragraph.
+	//		For example, the input:
 	//
 	//		|	first paragraph <shift-ENTER>
 	//		|	second line of first paragraph <ENTER>
-	//		|
 	//		|	second paragraph
 	//
-	//		In the other two modes, the ENTER key means to go to a new line in the
-	//		current paragraph, and users [visually] create a new paragraph by pressing ENTER twice.
+	//		will generate:
+	//
+	//		|	<p>
+	//		|		first paragraph
+	//		|		<br/>
+	//		|		second line of first paragraph
+	//		|	</p>
+	//		|	<p>
+	//		|		second paragraph
+	//		|	</p>
+	//
+	//		In BR and DIV mode, the ENTER key conceptually goes to a new line in the
+	//		current paragraph, and users conceptually create a new paragraph by pressing ENTER twice.
 	//		For example, if the user enters text into an editor like this:
 	//
 	//		|		one <ENTER>
@@ -40,113 +45,69 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 	//		|		five <ENTER>
 	//		|		six <ENTER>
 	//
-	//		It will appear on the screen as two paragraphs of three lines each.
-	//
-	//		blockNodeForEnter=BR
-	//		--------------------
-	//		On IE, typing the above keystrokes in the editor will internally produce DOM of:
-	//
-	//		|		<p>one</p>
-	//		|		<p>two</p>
-	//		|		<p>three</p>
-	//		|		<p></p>
-	//		|		<p>four</p>
-	//		|		<p>five</p>
-	//		|		<p>six</p>
-	//
-	//		However, blockNodeForEnter=BR makes the Editor on IE display like other browsers, by
-	//		changing the CSS for the <p> node to not have top/bottom margins,
-	//		thus eliminating the double-spaced appearance.
-	//
-	//		Also, attr('value') when used w/blockNodeForEnter=br on IE will return:
+	//		It will appear on the screen as two 'paragraphs' of three lines each.  Markupwise, this generates:
 	//
-	//		|	<p> one <br> two <br> three </p>
-	//		|	<p> four <br> five <br> six </p>
+	//		BR:
+	//		|		one<br/>
+	//		|		two<br/>
+	//		|		three<br/>
+	//		|		<br/>
+	//		|		four<br/>
+	//		|		five<br/>
+	//		|		six<br/>
 	//
-	//		This output normalization implemented by a filter when the
-	//		editor writes out it's data, to convert consecutive <p>
-	//		nodes into a single <p> node with internal <br> separators.
-	//
-	//		There's also a pre-filter to mirror the post-filter.
-	//		It converts a single <p> with <br> line breaks
-	//		into separate <p> nodes, and creates empty <p> nodes for spacing
-	//		between paragraphs.
-	//
-	//		On FF typing the above keystrokes will internally generate:
-	//
-	//		|		one <br> two <br> three <br> <br> four <br> five <br> six <br>
-	//
-	//		And on Safari it will generate:
-	//
-	//		|		"one"
+	//		DIV:
+	//		|		<div>one</div>
 	//		|		<div>two</div>
 	//		|		<div>three</div>
-	//		|		<div><br></div>
+	//		|		<div> </div>
 	//		|		<div>four</div>
 	//		|		<div>five</div>
 	//		|		<div>six</div>
-	//
-	//		Thus, Safari and FF already look correct although semantically their content is a bit strange.
-	//		On Safari or Firefox blockNodeForEnter=BR uses the builtin editor command "insertBrOnReturn",
-	//		but that doesn't seem to do anything.
-	//		Thus, attr('value') on safari/FF returns the browser-specific HTML listed above,
-	//		rather than the semantically meaningful value that IE returns: <p>one<br>two</p> <p>three<br>four</p>.
-	//
-	//		(Note: originally based on http://bugs.dojotoolkit.org/ticket/2859)
-	//
-	//		blockNodeForEnter=P
-	//		-------------------
-	//		Plugin will monitor keystrokes and update the editor's content on the fly,
-	//		so that the ENTER key will create a new <p> on FF and Safari (it already
-	//		works that way by default on IE).
-	//
-	//		blockNodeForEnter=DIV
-	//		---------------------
-	//		Follows the same code path as blockNodeForEnter=P but inserting a <div>
-	//		on ENTER key.  Although it produces strange internal DOM, like this:
-	//
-	//		|	<div>paragraph one</div>
-	//		|	<div>paragraph one, line 2</div>
-	//		|	<div> </div>
-	//		|	<div>paragraph two</div>
-	//
-	//		it does provide a consistent look on all browsers, and the on-the-fly DOM updating
-	//		can be useful for collaborative editing.
 
 	// blockNodeForEnter: String
 	//		This property decides the behavior of Enter key. It can be either P,
 	//		DIV, BR, or empty (which means disable this feature). Anything else
-	//		will trigger errors.
+	//		will trigger errors.  The default is 'BR'
 	//
 	//		See class description for more details.
 	blockNodeForEnter: 'BR',
 
 	constructor: function(args){
 		if(args){
+			if("blockNodeForEnter" in args){
+				args.blockNodeForEnter = args.blockNodeForEnter.toUpperCase();
+			}
 			dojo.mixin(this,args);
 		}
 	},
 
 	setEditor: function(editor){
 		// Overrides _Plugin.setEditor().
+		if(this.editor === editor) { return; }
 		this.editor = editor;
 		if(this.blockNodeForEnter == 'BR'){
-			if(dojo.isIE){
-				editor.contentDomPreFilters.push(dojo.hitch(this, "regularPsToSingleLinePs"));
-				editor.contentDomPostFilters.push(dojo.hitch(this, "singleLinePsToRegularPs"));
-				editor.onLoadDeferred.addCallback(dojo.hitch(this, "_fixNewLineBehaviorForIE"));
-			}else{
+			// 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){
-					try{
-						this.editor.document.execCommand("insertBrOnReturn", false, true);
-					}catch(e){}
+				this.connect(editor.document, "onkeypress", function(e){
+					if(e.charOrCode == dojo.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);
+						ne.shiftKey = true;
+						if(!this.handleEnterKey(ne)){
+							dojo.stopEvent(e);
+						}
+					}
+				});
 					return d;
 				}));
-			}
 		}else if(this.blockNodeForEnter){
 			// add enter key handler
 			// FIXME: need to port to the new event code!!
-			dojo['require']('dijit._editor.range');
 			var h = dojo.hitch(this,this.handleEnterKey);
 			editor.addKeyHandler(13, 0, 0, h); //enter
 			editor.addKeyHandler(13, 0, 1, h); //shift+enter
@@ -222,12 +183,12 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		// tags:
 		//		private
 
-		var selection, range, newrange, doc=this.editor.document,br;
+		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);
 			if(header){
-				if(!e.shiftKey && header.tagName == 'LI'){
+				if(header.tagName == 'LI'){
 					return true; // let browser handle
 				}
 				selection = dijit.range.getSelection(this.editor.window);
@@ -238,36 +199,118 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					range = selection.getRangeAt(0);
 				}
 				if(dijit.range.atBeginningOfContainer(header, range.startContainer, range.startOffset)){
-					if(e.shiftKey){
 						br=doc.createElement('br');
 						newrange = dijit.range.create(this.editor.window);
 						header.insertBefore(br,header.firstChild);
 						newrange.setStartBefore(br.nextSibling);
 						selection.removeAllRanges();
 						selection.addRange(newrange);
-					}else{
-						dojo.place(br, header, "before");
-					}
 				}else if(dijit.range.atEndOfContainer(header, range.startContainer, range.startOffset)){
 					newrange = dijit.range.create(this.editor.window);
 					br=doc.createElement('br');
-					if(e.shiftKey){
 						header.appendChild(br);
 						header.appendChild(doc.createTextNode('\xA0'));
 						newrange.setStart(header.lastChild,0);
-					}else{
-						dojo.place(br, header, "after");
-						newrange.setStartAfter(header);
-					}
-
 					selection.removeAllRanges();
 					selection.addRange(newrange);
 				}else{
+					rs = range.startContainer;
+					if(rs && rs.nodeType == 3){
+						// Text node, we have to split it.
+						txt = rs.nodeValue;
+						dojo.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){
+								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);
+							newrange.setStart(endNode,0);
+							selection.removeAllRanges();
+							selection.addRange(newrange);
+						});
+						return false;
+					}
 					return true; // let browser handle
 				}
 			}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>');
+				selection = dijit.range.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);
+							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(){
+								var endEmpty = false;
+							
+								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));
+								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");
+								}else{
+									startNode = rs;
+								}
+								dojo.place(brNode, startNode, "after");
+								dojo.place(endNode, brNode, "after");
+								dojo.destroy(rs);
+								newrange = dijit.range.create(dojo.gobal);
+								newrange.setStart(endNode,0);
+								newrange.setEnd(endNode, endNode.length);
+								selection.removeAllRanges();
+								selection.addRange(newrange);
+								if(endEmpty && !dojo.isWebKit){
+									dijit._editor.selection.remove();
+								}else{
+									dijit._editor.selection.collapse(true);
+								}
+							}));
+						}else{
+							dojo.withGlobal(this.editor.window, dojo.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);
+								newrange.setStart(endNode,0);
+								newrange.setEnd(endNode, endNode.length);
+								selection.removeAllRanges();
+								selection.addRange(newrange);
+								dijit._editor.selection.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>');
+				}
 			}
 			return false;
 		}
@@ -331,7 +374,15 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		var newblock = doc.createElement(this.blockNodeForEnter);
 		newblock.innerHTML=this.bogusHtmlContent;
 		this.removeTrailingBr(block.blockNode);
-		if(dijit.range.atEndOfContainer(block.blockNode, range.endContainer, range.endOffset)){
+		var endOffset = range.endOffset;
+		var node = range.endContainer;
+		if(node.length < endOffset){
+			//We are not checking the right node, try to locate the correct one
+			var ret = this._adjustNodeAndOffset(node, endOffset);
+			node = ret.node;
+			endOffset = ret.offset;
+		}
+		if(dijit.range.atEndOfContainer(block.blockNode, node, endOffset)){
 			if(block.blockNode === block.blockContainer){
 				block.blockNode.appendChild(newblock);
 			}else{
@@ -377,13 +428,22 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 			}
 			
 			// Okay, we probably have to split.
-			var rs = range.startContainer;
-			if(rs && rs.nodeType == 3){
+			rs = range.startContainer;
+			var firstNodeMoved;
+			if(rs && rs.nodeType == 3){ 
 				// Text node, we have to split it.
 				var nodeToMove, tNode;
-				var txt = rs.nodeValue;
-				var startNode = doc.createTextNode(txt.substring(0, range.startOffset));
-				var endNode = doc.createTextNode(txt.substring(range.startOffset, txt.length));
+				endOffset = range.endOffset;
+				if(rs.length < endOffset){
+					//We are not splitting the right node, try to locate the correct one
+					ret = this._adjustNodeAndOffset(rs, endOffset);
+					rs = ret.node;
+					endOffset = ret.offset;
+				}
+				
+				txt = rs.nodeValue;
+				startNode = doc.createTextNode(txt.substring(0, endOffset));
+				endNode = doc.createTextNode(txt.substring(endOffset, txt.length));
 
 				// Place the split, then remove original nodes.
 				dojo.place(startNode, rs, "before");
@@ -397,7 +457,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 				while(parentC !== block.blockNode){
 					var tg = parentC.tagName;
 					var newTg = doc.createElement(tg);
-					// Clone over any 'style' data. 
+					// Clone over any 'style' data.
 					if(parentC.style){
 						if(newTg.style){
 							if(parentC.style.cssText){
@@ -405,7 +465,19 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 							}
 						}
 					}
-
+					// If font also need to clone over any font data. 
+					if(parentC.tagName === "FONT"){
+						if(parentC.color){
+							newTg.color = parentC.color;
+						}
+						if(parentC.face){
+							newTg.face = parentC.face;
+						}
+						if(parentC.size){  // this check was necessary on IE
+							newTg.size = parentC.size;
+						}
+					}
+					
 					nodeToMove = endNode;
 					while(nodeToMove){
 						tNode = nodeToMove.nextSibling;
@@ -426,6 +498,7 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 					// before moving the contents.
 					newblock.innerHTML = "";
 				}
+				firstNodeMoved = nodeToMove;
 				while(nodeToMove){
 					tNode = nodeToMove.nextSibling;
 					newblock.appendChild(nodeToMove);
@@ -435,20 +508,64 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 			
 			//lets move caret to the newly created block
 			newrange = dijit.range.create(this.editor.window);
-			newrange.setStart(newblock, 0);
-			selection.removeAllRanges();
-			selection.addRange(newrange);
-			if(this.editor.height){
-				dijit.scrollIntoView(newblock);
-			}
-			if(dojo.isMoz){
-				// press enter in middle of P may leave a trailing <br/>, let's remove it later
-				this._pressedEnterInBlock = block.blockNode;
+			var nodeForCursor;
+			var innerMostFirstNodeMoved = firstNodeMoved;
+			if(this.blockNodeForEnter !== 'BR'){
+				while(innerMostFirstNodeMoved){
+					nodeForCursor = innerMostFirstNodeMoved;
+					tNode = innerMostFirstNodeMoved.firstChild;
+					innerMostFirstNodeMoved = tNode;
+				}
+				if(nodeForCursor && nodeForCursor.parentNode){
+					newblock = nodeForCursor.parentNode;
+					newrange.setStart(newblock, 0);
+					selection.removeAllRanges();
+					selection.addRange(newrange);
+					if(this.editor.height){
+						dijit.scrollIntoView(newblock);
+					}
+					if(dojo.isMoz){
+						// press enter in middle of P may leave a trailing <br/>, let's remove it later
+						this._pressedEnterInBlock = block.blockNode;
+					}					
+				}else{
+					_letBrowserHandle = true;
+				}
+			}else{
+				newrange.setStart(newblock, 0);
+				selection.removeAllRanges();
+				selection.addRange(newrange);
+				if(this.editor.height){
+					dijit.scrollIntoView(newblock);
+				}
+				if(dojo.isMoz){
+					// press enter in middle of P may leave a trailing <br/>, let's remove it later
+					this._pressedEnterInBlock = block.blockNode;
+				}
 			}
 		}
 		return _letBrowserHandle;
 	},
 
+	_adjustNodeAndOffset: function(/*DomNode*/node, /*Int*/offset){
+		// summary:
+		//              In the case there are multiple text nodes in a row the offset may not be within the node.  If the offset is larger than the node length, it will attempt to find
+		//              the next text sibling until it locates the text node in which the offset refers to
+		// node:
+		//              The node to check.
+		// offset:
+		//              The position to find within the text node
+		// tags:
+		//              private.
+		while(node.length < offset && node.nextSibling && node.nextSibling.nodeType==3){
+			//Adjust the offset and node in the case of multiple text nodes in a row
+			offset = offset - node.length;
+			node = node.nextSibling;
+		}
+		var ret = {"node": node, "offset": offset};
+		return ret;
+	},
+
 	removeTrailingBr: function(container){
 		// summary:
 		//		If last child of container is a <br>, then remove it.
@@ -468,205 +585,8 @@ dojo.declare("dijit._editor.plugins.EnterKeyHandling", dijit._editor._Plugin, {
 		if(!para.childNodes.length){
 			para.innerHTML=this.bogusHtmlContent;
 		}
-	},
-	_fixNewLineBehaviorForIE: function(d){
-		// summary:
-		//		Insert CSS so <p> nodes don't have spacing around them,
-		//		thus hiding the fact that ENTER key on IE is creating new
-		//		paragraphs
-
-		// cannot use !important since there may be custom user styling;
-		var doc = this.editor.document;
-		if(doc.__INSERTED_EDITIOR_NEWLINE_CSS === undefined){
-			var style = dojo.create("style", {type: "text/css"}, doc.getElementsByTagName("head")[0]);
-			style.styleSheet.cssText = "p{margin:0;}"; // cannot use !important since there may be custom user styling;
-			this.editor.document.__INSERTED_EDITIOR_NEWLINE_CSS = true;
-		}
-		return d;
-	},
-	regularPsToSingleLinePs: function(element, noWhiteSpaceInEmptyP){
-		// summary:
-		//		Converts a <p> node containing <br>'s into multiple <p> nodes.
-		// description:
-		//		See singleLinePsToRegularPs().   This method does the
-		//		opposite thing, and is used as a pre-filter when loading the
-		//		editor, to mirror the effects of the post-filter at end of edit.
-		// tags:
-		//		private
-		function wrapLinesInPs(el){
-		  // move "lines" of top-level text nodes into ps
-			function wrapNodes(nodes){
-				// nodes are assumed to all be siblings
-				var newP = nodes[0].ownerDocument.createElement('p'); // FIXME: not very idiomatic
-				nodes[0].parentNode.insertBefore(newP, nodes[0]);
-				dojo.forEach(nodes, function(node){
-					newP.appendChild(node);
-				});
-			}
-
-			var currentNodeIndex = 0;
-			var nodesInLine = [];
-			var currentNode;
-			while(currentNodeIndex < el.childNodes.length){
-				currentNode = el.childNodes[currentNodeIndex];
-				if( currentNode.nodeType==3 ||	// text node
-					(currentNode.nodeType==1 && currentNode.nodeName!='BR' && dojo.style(currentNode, "display")!="block")
-				){
-					nodesInLine.push(currentNode);
-				}else{
-					// hit line delimiter; process nodesInLine if there are any
-					var nextCurrentNode = currentNode.nextSibling;
-					if(nodesInLine.length){
-						wrapNodes(nodesInLine);
-						currentNodeIndex = (currentNodeIndex+1)-nodesInLine.length;
-						if(currentNode.nodeName=="BR"){
-							dojo.destroy(currentNode);
-						}
-					}
-					nodesInLine = [];
-				}
-				currentNodeIndex++;
-			}
-			if(nodesInLine.length){ wrapNodes(nodesInLine); }
-		}
-
-		function splitP(el){
-			// split a paragraph into seperate paragraphs at BRs
-			var currentNode = null;
-			var trailingNodes = [];
-			var lastNodeIndex = el.childNodes.length-1;
-			for(var i=lastNodeIndex; i>=0; i--){
-				currentNode = el.childNodes[i];
-				if(currentNode.nodeName=="BR"){
-					var newP = currentNode.ownerDocument.createElement('p');
-					dojo.place(newP, el, "after");
-					if(trailingNodes.length==0 && i != lastNodeIndex){
-						newP.innerHTML = " "
-					}
-					dojo.forEach(trailingNodes, function(node){
-						newP.appendChild(node);
-					});
-					dojo.destroy(currentNode);
-					trailingNodes = [];
-				}else{
-					trailingNodes.unshift(currentNode);
-				}
-			}
-		}
-
-		var pList = [];
-		var ps = element.getElementsByTagName('p');
-		dojo.forEach(ps, function(p){ pList.push(p); });
-		dojo.forEach(pList, function(p){
-			var prevSib = p.previousSibling;
-			if(	(prevSib) && (prevSib.nodeType == 1) && 
-				(prevSib.nodeName == 'P' || dojo.style(prevSib, 'display') != 'block')
-			){
-				var newP = p.parentNode.insertBefore(this.document.createElement('p'), p);
-				// this is essential to prevent IE from losing the P.
-				// if it's going to be innerHTML'd later we need
-				// to add the   to _really_ force the issue
-				newP.innerHTML = noWhiteSpaceInEmptyP ? "" : " ";
-			}
-			splitP(p);
-		},this.editor);
-		wrapLinesInPs(element);
-		return element;
-	},
-
-	singleLinePsToRegularPs: function(element){
-		// summary:
-		//		Called as post-filter.
-		//		Apparently collapses adjacent <p> nodes into a single <p>
-		//		nodes with <br> separating each line.
-		//
-		// example:
-		//		Given this input:
-		//	|	<p>line 1</p>
-		//	|	<p>line 2</p>
-		//	|	<ol>
-		//	|		<li>item 1
-		//	|		<li>item 2
-		//	|	</ol>
-		//	|	<p>line 3</p>
-		//	|	<p>line 4</p>
-		//
-		//		Will convert to:
-		//	|	<p>line 1<br>line 2</p>
-		//	|	<ol>
-		//	|		<li>item 1
-		//	|		<li>item 2
-		//	|	</ol>
-		//	|	<p>line 3<br>line 4</p>
-		//
-		//		Not sure why this situation would even come up after the pre-filter and
-		//		the enter-key-handling code.
-		//
-		// tags:
-		//		private
-
-		function getParagraphParents(node){
-			// summary:
-			//		Used to get list of all nodes that contain paragraphs.
-			//		Seems like that would just be the very top node itself, but apparently not.
-			var ps = node.getElementsByTagName('p');
-			var parents = [];
-			for(var i=0; i<ps.length; i++){
-				var p = ps[i];
-				var knownParent = false;
-				for(var k=0; k < parents.length; k++){
-					if(parents[k] === p.parentNode){
-						knownParent = true;
-						break;
-					}
-				}
-				if(!knownParent){
-					parents.push(p.parentNode);
-				}
-			}
-			return parents;
-		}
-
-		function isParagraphDelimiter(node){
-			return (!node.childNodes.length || node.innerHTML==" ");
-		}
-
-		var paragraphContainers = getParagraphParents(element);
-		for(var i=0; i<paragraphContainers.length; i++){
-			var container = paragraphContainers[i];
-			var firstPInBlock = null;
-			var node = container.firstChild;
-			var deleteNode = null;
-			while(node){
-				if(node.nodeType != 1 || node.tagName != 'P' ||
-						(node.getAttributeNode('style') || {/*no style*/}).specified){
-					firstPInBlock = null;
-				}else if(isParagraphDelimiter(node)){
-					deleteNode = node;
-					firstPInBlock = null;
-				}else{
-					if(firstPInBlock == null){
-						firstPInBlock = node;
-					}else{
-						if( (!firstPInBlock.lastChild || firstPInBlock.lastChild.nodeName != 'BR') &&
-							(node.firstChild) &&
-							(node.firstChild.nodeName != 'BR')
-						){
-							firstPInBlock.appendChild(this.editor.document.createElement('br'));
-						}
-						while(node.firstChild){
-							firstPInBlock.appendChild(node.firstChild);
-						}
-						deleteNode = node;
-					}
-				}
-				node = node.nextSibling;
-				if(deleteNode){
-					dojo.destroy(deleteNode);
-					deleteNode = null;
-				}
-			}
-		}
-		return element;
 	}
 });
+
+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 cc47175..058606f 100644
--- a/dijit/_editor/plugins/FontChoice.js
+++ b/dijit/_editor/plugins/FontChoice.js
@@ -1,13 +1,4 @@
-dojo.provide("dijit._editor.plugins.FontChoice");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit._editor.range");
-dojo.require("dijit._editor.selection");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dojo.data.ItemFileReadStore");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dijit._editor", "FontChoice");
+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],{
@@ -34,13 +25,13 @@ 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 " +
+			"<input dojoType='dijit.form.FilteringSelect' required='false' labelType='html' labelAttr='label' searchAttr='name' " +
 					"tabIndex='-1' id='${selectId}' dojoAttachPoint='select' value=''/>" +
 		"</span>",
 
 	postMixInProperties: function(){
 		// summary:
-		//		Over-ride to misin specific properties.
+		//		Over-ride to set specific properties.
 		this.inherited(arguments);
 
 		this.strings = dojo.i18n.getLocalization("dijit._editor", "FontChoice");
@@ -264,7 +255,7 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 		//		The 'insert value' associated with a name
 		// name: String
 		//		The text name of the value
-		if(this.plainText){
+		if(this.plainText || value == "noFormat"){
 			return name;
 		}else{
 			return "<" + value + ">" + name + "</" + value + ">";
@@ -287,14 +278,14 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 					end = range.endContainer;
 
 					// find containing nodes of start/end.
-					while(start && start !== editor.editNode && 
-						  start !== editor.document.body && 
+					while(start && start !== editor.editNode &&
+						  start !== editor.document.body &&
 						  start.nodeType !== 1){
 						start = start.parentNode;
 					}
 
-					while(end && end !== editor.editNode && 
-						  end !== editor.document.body && 
+					while(end && end !== editor.editNode &&
+						  end !== editor.document.body &&
 						  end.nodeType !== 1){
 						end = end.parentNode;
 					}
@@ -348,7 +339,7 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 							node = node.parentNode;
 						}
 
-						//Also look for all child nodes in the selection that may need to be 
+						//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); }
@@ -384,7 +375,7 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 		if(editor.customUndo){
 			// So of course IE doesn't work right with paste-overs.
 			// We have to do this manually, which is okay since IE already uses
-			// customUndo and we turned it on for WebKit.  WebKit pasted funny, 
+			// 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");
@@ -393,11 +384,11 @@ dojo.declare("dijit._editor.plugins._FormatBlockDropDown", dijit._editor.plugins
 		}else{
 			// Everyone else works fine this way, a paste-over and is native
 			// undo friendly.
-			dojo.withGlobal(editor.window, 
+			dojo.withGlobal(editor.window,
 				 "selectElementChildren", dijit._editor.selection, [node]);
-			var html = 	dojo.withGlobal(editor.window, 
+			var html = 	dojo.withGlobal(editor.window,
 				 "getSelectedHtml", dijit._editor.selection, [null]);
-			dojo.withGlobal(editor.window, 
+			dojo.withGlobal(editor.window,
 				 "selectElement", dijit._editor.selection, [node]);
 			editor.execCommand("inserthtml", html||"");
 		}
@@ -482,10 +473,6 @@ dojo.declare("dijit._editor.plugins.FontChoice", dijit._editor._Plugin,{
 			}else{
 				this.editor.execCommand(this.command, choice);
 			}
-			
-			// Enable custom undo for webkit, needed for noFormat to work properly
-			// and still undo.
-			this.editor.customUndo = this.editor.customUndo || dojo.isWebKit;
 		});
 	},
 
@@ -501,7 +488,11 @@ 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);
+			if(disabled){ return; }
 			var value;
 			try{
 				value = _e.queryCommandValue(_c) || "";
@@ -571,3 +562,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+
+return dijit._editor.plugins.FontChoice;
+});
diff --git a/dijit/_editor/plugins/FullScreen.js b/dijit/_editor/plugins/FullScreen.js
index c4203a3..0e5d4e8 100755
--- a/dijit/_editor/plugins/FullScreen.js
+++ b/dijit/_editor/plugins/FullScreen.js
@@ -1,12 +1,4 @@
-dojo.provide("dijit._editor.plugins.FullScreen");
-
-dojo.require("dojo.window");
-dojo.require("dojo.i18n");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-
-dojo.requireLocalization("dijit._editor", "commands");
+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,{
 	// summary:
@@ -175,7 +167,7 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 		this.isFullscreen = full;
 
 		if(full){
-			//Parent classes can royally screw up this plugin, so we 
+			//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");
@@ -384,7 +376,7 @@ 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(dojo.hitch(this, function(){ed.resize({h: mb.h});}), 0);
 					}
 				}
 				dojo.window.scrollIntoView(self.editor.toolbar.domNode);
@@ -392,6 +384,12 @@ dojo.declare("dijit._editor.plugins.FullScreen",dijit._editor._Plugin,{
 		}
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
+
 	destroy: function(){
 		// summary:
 		//		Over-ride to ensure the resize handle gets cleaned up.
@@ -424,3 +422,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+
+return dijit._editor.plugins.FullScreen;
+});
diff --git a/dijit/_editor/plugins/LinkDialog.js b/dijit/_editor/plugins/LinkDialog.js
index c1099d6..75dfcf5 100644
--- a/dijit/_editor/plugins/LinkDialog.js
+++ b/dijit/_editor/plugins/LinkDialog.js
@@ -1,17 +1,4 @@
-dojo.provide("dijit._editor.plugins.LinkDialog");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.ValidationTextBox");
-dojo.require("dijit.form.Select");
-dojo.require("dijit._editor.range");
-dojo.require("dojo.i18n");
-dojo.require("dojo.string");
-dojo.requireLocalization("dijit", "common");
-dojo.requireLocalization("dijit._editor", "LinkDialog");
+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, {
 	// summary:
@@ -32,11 +19,11 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 	// urlRegExp: [protected] String
 	//		Used for validating input as correct URL.  While file:// urls are not terribly
 	//		useful, they are technically valid.
-	urlRegExp: "((https?|ftps?|file)\\://|\./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6] [...]
+	urlRegExp: "((https?|ftps?|file)\\://|\./|/|)(/[a-zA-Z]{1,1}:/|)(((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)*(?:[a-zA-Z](?:[-\\da-zA-Z]{0,80}[\\da-zA-Z])?)\\.?)|(((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])|(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]|(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]|(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6] [...]
 
 	// emailRegExp: [protected] String
 	//		Used for validating input as correct email address.  Taken from dojox.validate
-	emailRegExp:  "<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+" /*username*/ + "@" +  
+	emailRegExp:  "<?(mailto\\:)([!#-'*+\\-\\/-9=?A-Z^-~]+[.])*[!#-'*+\\-\\/-9=?A-Z^-~]+" /*username*/ + "@" +
         "((?:(?:[\\da-zA-Z](?:[-\\da-zA-Z]{0,61}[\\da-zA-Z])?)\\.)+(?:[a-zA-Z](?:[-\\da-zA-Z]{0,6}[\\da-zA-Z])?)\\.?)|localhost|^[^-][a-zA-Z0-9_-]*>?",	// host.
 
 	// htmlTemplate: [protected] String
@@ -64,12 +51,12 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		"<label for='${id}_urlInput'>${url}</label>",
 		"</td><td>",
 		"<input dojoType='dijit.form.ValidationTextBox' required='true' " +
-		"id='${id}_urlInput' name='urlInput' intermediateChanges='true'>",
+		"id='${id}_urlInput' name='urlInput' 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'>",
+		"name='textInput' intermediateChanges='true'/>",
 		"</td></tr><tr><td>",
 		"<label for='${id}_targetSelect'>${target}</label>",
 		"</td><td>",
@@ -203,15 +190,18 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 	_setContent: function(staticPanel){
 		// summary:
 		//		Helper for _initButton above.   Not sure why it's a separate method.
-		this.dropDown.set('content', staticPanel);
+		this.dropDown.set({
+			parserScope: "dojo",		// make parser search for dojoType/data-dojo-type even if page is multi-version
+			content: staticPanel
+		});
 	},
 
 	_checkValues: function(args){
 		// summary:
 		//		Function to check the values in args and 'fix' them up as needed.
 		// args: Object
-		//		Content being set.		
-		// tags: 
+		//		Content being set.
+		// tags:
 		//		protected
 		if(args && args.urlInput){
 			args.urlInput = args.urlInput.replace(/"/g, """);
@@ -226,7 +216,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 		//		private
 		//TODO: prevent closing popup if the text is empty
 		this._onCloseDialog();
-		if(dojo.isIE){ //see #4151
+		if(dojo.isIE < 9){ //see #4151
 			var sel = dijit.range.getSelection(this.editor.window);
 			var range = sel.getRangeAt(0);
 			var a = range.endContainer;
@@ -257,7 +247,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 			}
 		}
 		// make sure values are properly escaped, etc.
-		args = this._checkValues(args); 
+		args = this._checkValues(args);
 		this.editor.execCommand('inserthtml',
 			dojo.string.substitute(this.htmlTemplate, args));
 	},
@@ -292,7 +282,7 @@ 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){
+		if(dojo.isIE < 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);
@@ -336,6 +326,7 @@ dojo.declare("dijit._editor.plugins.LinkDialog", dijit._editor._Plugin, {
 					 "selectElement",
 					 dijit._editor.selection, [t]);
 				this.editor.onDisplayChanged();
+				
 				setTimeout(dojo.hitch(this, function(){
 					// Focus shift outside the event handler.
 					// IE doesn't like focus changes in event handles.
@@ -363,12 +354,12 @@ 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' 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'>",
+		"name='textInput' intermediateChanges='true'/>",
 		"</td></tr><tr><td>",
 		"</td><td>",
 		"</td></tr><tr><td colspan='2'>",
@@ -445,11 +436,11 @@ dojo.declare("dijit._editor.plugins.ImgLinkDialog", [dijit._editor.plugins.LinkD
 
 	_checkValues: function(args){
 		// summary:
-		//		Function to check the values in args and 'fix' them up as needed 
+		//		Function to check the values in args and 'fix' them up as needed
 		//		(special characters in the url or alt text)
 		// args: Object
-		//		Content being set.		
-		// tags: 
+		//		Content being set.
+		// tags:
 		//		protected
 		if(args && args.urlInput){
 			args.urlInput = args.urlInput.replace(/"/g, """);
@@ -500,3 +491,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 			break;
 	}
 });
+
+
+return dijit._editor.plugins.LinkDialog;
+});
diff --git a/dijit/_editor/plugins/NewPage.js b/dijit/_editor/plugins/NewPage.js
index 7d0ea3f..c4486f4 100644
--- a/dijit/_editor/plugins/NewPage.js
+++ b/dijit/_editor/plugins/NewPage.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit._editor.plugins.NewPage");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dijit._editor", "commands");
+define("dijit/_editor/plugins/NewPage", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
 
 dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
 	// summary:
@@ -41,6 +35,12 @@ dojo.declare("dijit._editor.plugins.NewPage",dijit._editor._Plugin,{
 		this._initButton();
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
+
 	_newPage: function(){
 		// summary:
 		//		Function to set the content to blank.
@@ -63,3 +63,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+
+return dijit._editor.plugins.NewPage;
+});
diff --git a/dijit/_editor/plugins/Print.js b/dijit/_editor/plugins/Print.js
index 4853e7a..4ac105e 100755
--- a/dijit/_editor/plugins/Print.js
+++ b/dijit/_editor/plugins/Print.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit._editor.plugins.Print");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dijit._editor", "commands");
+define("dijit/_editor/plugins/Print", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/Button", "dojo/i18n", "i18n!dijit/_editor/nls/commands"], function(dojo, dijit) {
 
 dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
 	// summary:
@@ -46,6 +40,16 @@ dojo.declare("dijit._editor.plugins.Print",dijit._editor._Plugin,{
 		);
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		var disabled = this.get("disabled");
+		if(!this.editor.iframe.contentWindow["print"]){
+			disabled = true;
+		}
+		this.button.set("disabled", disabled);
+	},
+
 	_print: function(){
 		// summary:
 		//		Function to trigger printing of the editor document
@@ -104,3 +108,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	}
 });
 
+
+return dijit._editor.plugins.Print;
+});
diff --git a/dijit/_editor/plugins/TabIndent.js b/dijit/_editor/plugins/TabIndent.js
index ff850b0..ef49134 100644
--- a/dijit/_editor/plugins/TabIndent.js
+++ b/dijit/_editor/plugins/TabIndent.js
@@ -1,8 +1,7 @@
-dojo.provide("dijit._editor.plugins.TabIndent");
+define("dijit/_editor/plugins/TabIndent", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/ToggleButton"], function(dojo, dijit) {
+
 dojo.experimental("dijit._editor.plugins.TabIndent");
 
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.ToggleButton");
 
 dojo.declare("dijit._editor.plugins.TabIndent",
 	dijit._editor._Plugin,
@@ -36,7 +35,11 @@ dojo.declare("dijit._editor.plugins.TabIndent",
 		updateState: function(){
 			// Overrides _Plugin.updateState().
 			// Ctrl-m in the editor will switch tabIndent mode on/off, so we need to react to that.
-
+			var disabled = this.get("disabled");
+			this.button.set("disabled", disabled);
+			if(disabled){
+				return;
+			}
 			this.button.set('checked', this.editor.isTabIndent, false);
 		}
 	}
@@ -50,3 +53,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dijit._editor.plugins.TabIndent({command: o.args.name});
 	}
 });
+
+
+return dijit._editor.plugins.TabIndent;
+});
diff --git a/dijit/_editor/plugins/TextColor.js b/dijit/_editor/plugins/TextColor.js
index 288204e..8ba6ef7 100644
--- a/dijit/_editor/plugins/TextColor.js
+++ b/dijit/_editor/plugins/TextColor.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit._editor.plugins.TextColor");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.ColorPalette");
+define("dijit/_editor/plugins/TextColor", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/ColorPalette"], function(dojo, dijit) {
 
 dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 	// summary:
@@ -41,6 +38,10 @@ dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 		}
 		
 		if(this.button){
+			var disabled = this.get("disabled");
+			this.button.set("disabled", disabled);
+			if(disabled){ return; }
+			
 			var value;
 			try{
 				value = _e.queryCommandValue(_c)|| "";
@@ -58,7 +59,7 @@ dojo.declare("dijit._editor.plugins.TextColor", dijit._editor._Plugin, {
 		}
 
 		if(typeof value == "string"){
-			//if RGB value, convert to hex value	
+			//if RGB value, convert to hex value
 			if(value.indexOf("rgb")> -1){
 				value = dojo.colorFromRgb(value).toHex();
 			}
@@ -88,3 +89,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
 			});
 	}
 });
+
+
+return dijit._editor.plugins.TextColor;
+});
diff --git a/dijit/_editor/plugins/ToggleDir.js b/dijit/_editor/plugins/ToggleDir.js
index cde17f2..ba8aa67 100644
--- a/dijit/_editor/plugins/ToggleDir.js
+++ b/dijit/_editor/plugins/ToggleDir.js
@@ -1,4 +1,5 @@
-dojo.provide("dijit._editor.plugins.ToggleDir");
+define("dijit/_editor/plugins/ToggleDir", ["dojo", "dijit", "dijit/_editor/_Plugin", "dijit/form/ToggleButton"], function(dojo, dijit) {
+
 dojo.experimental("dijit._editor.plugins.ToggleDir");
 
 dojo.require("dijit._editor._Plugin");
@@ -36,8 +37,9 @@ dojo.declare("dijit._editor.plugins.ToggleDir",
 		},
 
 		updateState: function(){
-			// Override _Plugin.updateState() to do nothing, since we don't need to react to changes in the
-			// editor like arrow keys etc.
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			this.button.set("disabled", this.get("disabled"));
 		},
 
 		_setRtl: function(rtl){
@@ -62,3 +64,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dijit._editor.plugins.ToggleDir({command: o.args.name});
 	}
 });
+
+
+return dijit._editor.plugins.ToggleDir;
+});
diff --git a/dijit/_editor/plugins/ViewSource.js b/dijit/_editor/plugins/ViewSource.js
index fa54501..6b0c6c4 100755
--- a/dijit/_editor/plugins/ViewSource.js
+++ b/dijit/_editor/plugins/ViewSource.js
@@ -1,12 +1,4 @@
-dojo.provide("dijit._editor.plugins.ViewSource");
-
-dojo.require("dojo.window");
-dojo.require("dojo.i18n");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-
-dojo.requireLocalization("dijit._editor", "commands");
+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,{
 	// summary:
@@ -144,35 +136,10 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 				html = this._filter(html);
 				ed.set("value", html);
 				this._pluginList = [];
-				this._disabledPlugins = dojo.filter(edPlugins, function(p){
+				dojo.forEach(edPlugins, function(p){
 					// Turn off any plugins not controlled by queryCommandenabled.
-					if(p && p.button && !p.button.get("disabled") &&
-						!(p instanceof dijit._editor.plugins.ViewSource)){
-						p._vs_updateState = p.updateState;
-						p.updateState = function(){
-							return false;
-						};
-						p.button.set("disabled", true);
-						if(p.command){
-							// FF has a weird behavior when spellcheck is off,
-							// queryCommandValue() returns true on the doc, and as such
-							// toggles 'on' some actions.  So, we need to explictly 
-							// toggle them off.  TODO:  Add a disable API to _Plugin.js
-							// It would aleviate the need for this.
-							switch(p.command){
-								case "bold":
-								case "italic":
-								case "underline":
-								case "strikethrough":
-								case "superscript":
-								case "subscript":
-									p.button.set("checked", false);
-									break;
-								default:
-									break;
-							}
-						}
-						return true;
+					if(!(p instanceof dijit._editor.plugins.ViewSource)){
+						p.set("disabled", true)
 					}
 				});
 
@@ -185,7 +152,7 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 				}
 
 				this.sourceArea.value = html;
-				var is = dojo.marginBox(ed.iframe.parentNode);
+				var is = dojo._getMarginSize(ed.iframe.parentNode);
 
 				dojo.marginBox(this.sourceArea, {
 					w: is.w,
@@ -233,6 +200,13 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 
 				//Trigger a check for command enablement/disablement.
 				this.editor.onNormalizedDisplayChanged();
+
+				this.editor.__oldGetValue = this.editor.getValue;
+				this.editor.getValue = dojo.hitch(this, function() {
+					var txt = this.sourceArea.value;
+					txt = this._filter(txt);
+					return txt;
+				});
 			}else{
 				// First check that we were in source view before doing anything.
 				// corner case for being called with a value of false and we hadn't
@@ -243,6 +217,11 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 				dojo.disconnect(this._resizeHandle);
 				delete this._resizeHandle;
 
+				if(this.editor.__oldGetValue){
+					this.editor.getValue = this.editor.__oldGetValue;
+					delete this.editor.__oldGetValue;
+				}
+
 				// Restore all the plugin buttons state.
 				ed.queryCommandEnabled = ed._sourceQueryCommandEnabled;
 				if(!this._readOnly){
@@ -253,15 +232,11 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 					ed.endEditing();
 				}
 
-				dojo.forEach(this._disabledPlugins, function(p){
+				dojo.forEach(edPlugins, function(p){
 					// Turn back on any plugins we turned off.
-					p.button.set("disabled", false);
-					if(p._vs_updateState){
-						p.updateState = p._vs_updateState;
-					}
+					p.set("disabled", false);
 				});
 
-				this._disabledPlugins = null;
 				dojo.style(this.sourceArea, "display", "none");
 				dojo.style(ed.iframe, "display", "block");
 				delete ed._sourceQueryCommandEnabled;
@@ -286,6 +261,12 @@ dojo.declare("dijit._editor.plugins.ViewSource",dijit._editor._Plugin,{
 		}
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
+
 	_resize: function(){
 		// summary:
 		//		Internal function to resize the source view
@@ -555,3 +536,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+
+return dijit._editor.plugins.ViewSource;
+});
diff --git a/dijit/_editor/range.js b/dijit/_editor/range.js
index 873bb2d..abc35cd 100644
--- a/dijit/_editor/range.js
+++ b/dijit/_editor/range.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit._editor.range");
+define("dijit/_editor/range", ["dojo", "dijit"], function(dojo, dijit) {
 
 dijit.range={};
 
@@ -527,3 +527,7 @@ dojo.declare("dijit.range.W3CRange",null, {
 }
 });
 } //if(!dijit.range._w3c)
+
+
+return dijit.range;
+});
diff --git a/dijit/_editor/selection.js b/dijit/_editor/selection.js
index 37ea03d..cabd7e8 100644
--- a/dijit/_editor/selection.js
+++ b/dijit/_editor/selection.js
@@ -1,4 +1,6 @@
-dojo.provide("dijit._editor.selection");
+define("dijit/_editor/selection", ["dojo", "dijit"], function(dojo, dijit) {
+
+dojo.getObject("_editor.selection", true, dijit);
 
 // FIXME:
 //		all of these methods branch internally for IE. This is probably
@@ -9,7 +11,7 @@ dojo.mixin(dijit._editor.selection, {
 	getType: function(){
 		// summary:
 		//		Get the selection type (like dojo.doc.select.type in IE).
-		if(dojo.isIE){
+		if(dojo.isIE < 9){
 			return dojo.doc.selection.type.toLowerCase();
 		}else{
 			var stype = "text";
@@ -36,7 +38,7 @@ 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){
+		if(dojo.isIE < 9){
 			if(dijit._editor.selection.getType() == 'control'){
 				return null;
 			}
@@ -53,7 +55,7 @@ dojo.mixin(dijit._editor.selection, {
 	getSelectedHtml: function(){
 		// summary:
 		//		Return the html text of the current selection or null if unavailable
-		if(dojo.isIE){
+		if(dojo.isIE < 9){
 			if(dijit._editor.selection.getType() == 'control'){
 				return null;
 			}
@@ -82,7 +84,7 @@ 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){
+			if(dojo.isIE < 9){
 				var range = dojo.doc.selection.createRange();
 				if(range && range.item){
 					return dojo.doc.selection.createRange().item(0);
@@ -102,7 +104,7 @@ dojo.mixin(dijit._editor.selection, {
 			var p = this.getSelectedElement();
 			if(p){ return p.parentNode; }
 		}else{
-			if(dojo.isIE){
+			if(dojo.isIE < 9){
 				var r = dojo.doc.selection.createRange();
 				r.collapse(true);
 				return r.parentElement();
@@ -202,7 +204,7 @@ dojo.mixin(dijit._editor.selection, {
 		// summary:
 		//		Function to delete the currently selected content from the document.
 		var sel = dojo.doc.selection;
-		if(dojo.isIE){
+		if(dojo.isIE < 9){
 			if(sel.type.toLowerCase() != "none"){
 				sel.clear();
 			}
@@ -226,7 +228,7 @@ dojo.mixin(dijit._editor.selection, {
 		var doc = dojo.doc;
 		var range;
 		element = dojo.byId(element);
-		if(doc.selection && dojo.isIE && dojo.body().createTextRange){ // IE
+		if(doc.selection && dojo.isIE < 9 && dojo.body().createTextRange){ // IE
 			range = element.ownerDocument.body.createTextRange();
 			range.moveToElementText(element);
 			if(!nochangefocus){
@@ -265,9 +267,14 @@ dojo.mixin(dijit._editor.selection, {
 		var doc = dojo.doc;
 		var win = dojo.global;
 		element = dojo.byId(element);
-		if(dojo.isIE && dojo.body().createTextRange){
+		if(dojo.isIE < 9 && dojo.body().createTextRange){
 			try{
-				range = dojo.body().createControlRange();
+				var tg = element.tagName ? element.tagName.toLowerCase() : "";
+				if(tg === "img" || tg === "table"){
+					range = dojo.body().createControlRange();
+				}else{
+					range = dojo.body().createRange();
+				}
 				range.addElement(element);
 				if(!nochangefocus){
 					range.select();
@@ -322,7 +329,7 @@ dojo.mixin(dijit._editor.selection, {
 				}
 			}else if(doc.selection){
 				// Probably IE, so we can't use the range object as the pseudo
-				// range doesn't implement the boundry checking, we have to 
+				// range doesn't implement the boundry checking, we have to
 				// use IE specific crud.
 				range = doc.selection.createRange();
 				try{
@@ -348,3 +355,6 @@ dojo.mixin(dijit._editor.selection, {
 	}
 
 });
+
+return dijit._editor.selection;
+});
diff --git a/dijit/_tree/dndSource.js b/dijit/_tree/dndSource.js
index a9c93d8..f55d1d0 100644
--- a/dijit/_tree/dndSource.js
+++ b/dijit/_tree/dndSource.js
@@ -1,7 +1,10 @@
-dojo.provide("dijit._tree.dndSource");
-dojo.require("dijit.tree.dndSource");
+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;
+});
diff --git a/dijit/dijit-all.js b/dijit/dijit-all.js
index 10be88a..1276f47 100644
--- a/dijit/dijit-all.js
+++ b/dijit/dijit-all.js
@@ -1,5 +1,6 @@
+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 [...]
+
 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");
-dojo.provide("dijit.dijit-all");
 
 /*=====
 dijit["dijit-all"] = {
@@ -8,78 +9,5 @@ dijit["dijit-all"] = {
 };
 =====*/
 
-dojo.require("dijit.dijit");
-
-dojo.require("dijit.ColorPalette");
-dojo.require("dijit.Declaration");
-
-dojo.require("dijit.Dialog");
-dojo.require("dijit.DialogUnderlay");
-dojo.require("dijit.TooltipDialog");
-
-// Editor
-dojo.require("dijit.Editor");
-dojo.require("dijit._editor.plugins.FontChoice");
-dojo.require("dijit._editor.plugins.LinkDialog");
-
-dojo.require("dijit.Menu");
-dojo.require("dijit.MenuItem");
-dojo.require("dijit.PopupMenuItem");
-dojo.require("dijit.MenuBar");
-dojo.require("dijit.MenuBarItem");
-dojo.require("dijit.PopupMenuBarItem");
-dojo.require("dijit.MenuSeparator");
-
-dojo.require("dijit.ProgressBar");
-dojo.require("dijit.TitlePane");
-dojo.require("dijit.Toolbar");
-dojo.require("dijit.Tooltip");
-dojo.require("dijit.Tree");
-dojo.require("dijit.InlineEditBox");
-
-// Form widgets
-dojo.require("dijit.form.Form");
-
-// Button widgets
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.DropDownButton");
-dojo.require("dijit.form.ComboButton");
-dojo.require("dijit.form.ToggleButton");
-dojo.require("dijit.form.CheckBox");
-dojo.require("dijit.form.RadioButton");
-
-// TextBox widgets
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.ValidationTextBox");
-dojo.require("dijit.form.CurrencyTextBox");
-dojo.require("dijit.form.DateTextBox");
-dojo.require("dijit.form.NumberSpinner");
-dojo.require("dijit.form.NumberTextBox");
-
-// Select widgets
-dojo.require("dijit.form.ComboBox");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dijit.form.MultiSelect");
-dojo.require("dijit.form.Select");
-
-// Slider widgets
-dojo.require("dijit.form.HorizontalSlider");
-dojo.require("dijit.form.VerticalSlider");
-dojo.require("dijit.form.HorizontalRule");
-dojo.require("dijit.form.VerticalRule");
-dojo.require("dijit.form.HorizontalRuleLabels");
-dojo.require("dijit.form.VerticalRuleLabels");
-
-// Textarea widgets
-dojo.require("dijit.form.SimpleTextarea");
-dojo.require("dijit.form.Textarea");
-
-// Layout widgets
-dojo.require("dijit.layout.AccordionContainer");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit.layout.BorderContainer");
-dojo.require("dijit.layout.LayoutContainer"); //deprecated
-dojo.require("dijit.layout.LinkPane");
-dojo.require("dijit.layout.SplitContainer"); //deprecated
-dojo.require("dijit.layout.StackContainer");
-dojo.require("dijit.layout.TabContainer");
+return dijit;
+});
diff --git a/dijit/dijit.js b/dijit/dijit.js
index 056141f..9f44e61 100644
--- a/dijit/dijit.js
+++ b/dijit/dijit.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit.dijit");
+define("dijit/dijit", ["dojo", "dijit", "dijit/_base", "dojo/parser", "dijit/_Widget", "dijit/_Templated", "dijit/_Container", "dijit/layout/_LayoutWidget", "dijit/form/_FormWidget"], function(dojo, dijit) {
 
 /*=====
 dijit.dijit = {
@@ -15,12 +15,9 @@ dijit.dijit = {
 =====*/
 
 // All the stuff in _base (these are the function that are guaranteed available without an explicit dojo.require)
-dojo.require("dijit._base");
 
 // And some other stuff that we tend to pull in all the time anyway
-dojo.require("dojo.parser");
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit.layout._LayoutWidget");
-dojo.require("dijit.form._FormWidget");
+
+
+return dijit;
+});
diff --git a/dijit/form/Button.js b/dijit/form/Button.js
index 1fd7bca..e6c134f 100644
--- a/dijit/form/Button.js
+++ b/dijit/form/Button.js
@@ -1,8 +1,4 @@
-dojo.provide("dijit.form.Button");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dijit._Container");
-dojo.require("dijit._HasDropDown");
+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,
@@ -49,11 +45,9 @@ dojo.declare("dijit.form.Button",
 	templateString: dojo.cache("dijit.form", "templates/Button.html"),
 
 	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
-		value: "valueNode",
-		iconClass: { node: "iconNode", type: "class" }
+		value: "valueNode"
 	}),
 
-
 	_onClick: function(/*Event*/ e){
 		// summary:
 		//		Internal function to handle click actions
@@ -83,25 +77,26 @@ dojo.declare("dijit.form.Button",
 		}
 	},
 
+	buildRendering: function(){
+		this.inherited(arguments);
+		dojo.setSelectable(this.focusNode, false);
+	},
+
 	_fillContent: function(/*DomNode*/ source){
 		// Overrides _Templated._fillContent().
 		// If button label is specified as srcNodeRef.innerHTML rather than
 		// this.params.label, handle it here.
+		// TODO: remove the method in 2.0, parser will do it all for me
 		if(source && (!this.params || !("label" in this.params))){
 			this.set('label', source.innerHTML);
 		}
 	},
 
-	postCreate: function(){
-		dojo.setSelectable(this.focusNode, false);
-		this.inherited(arguments);
-	},
-
 	_setShowLabelAttr: function(val){
 		if(this.containerNode){
 			dojo.toggleClass(this.containerNode, "dijitDisplayNone", !val);
 		}
-		this.showLabel = val;
+		this._set("showLabel", val);
 	},
 
 	onClick: function(/*Event*/ e){
@@ -127,13 +122,24 @@ dojo.declare("dijit.form.Button",
 
 	_setLabelAttr: function(/*String*/ content){
 		// summary:
-		//		Hook for attr('label', ...) to work.
+		//		Hook for set('label', ...) to work.
 		// description:
 		//		Set the label (text) of the button; takes an HTML string.
-		this.containerNode.innerHTML = this.label = content;
+		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);
 	}
 });
 
@@ -179,12 +185,14 @@ dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container,
 
 		// 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){
+		if(!this.dropDown && this.dropDownContainer){
 			var dropDownNode = dojo.query("[widgetId]", this.dropDownContainer)[0];
 			this.dropDown = dijit.byNode(dropDownNode);
 			delete this.dropDownContainer;
 		}
-		dijit.popup.moveOffScreen(this.dropDown.domNode);
+		if(this.dropDown){
+			dijit.popup.hide(this.dropDown);
+		}
 
 		this.inherited(arguments);
 	},
@@ -193,7 +201,7 @@ dojo.declare("dijit.form.DropDownButton", [dijit.form.Button, dijit._Container,
 		// 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.href || dropDown.isLoaded);
+		return (!!dropDown && (!dropDown.href || dropDown.isLoaded));
 	},
 
 	loadDropDown: function(){
@@ -283,8 +291,9 @@ dojo.declare("dijit.form.ComboButton", dijit.form.DropDownButton, {
 		//		otherwise on arrow node
 		// position:
 		//		"start" or "end"
-		
-		dijit.focus(position == "start" ? this.titleNode : this._popupStateNode);
+		if(!this.disabled){
+			dijit.focus(position == "start" ? this.titleNode : this._popupStateNode);
+		}
 	}
 });
 
@@ -310,8 +319,8 @@ dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
 		this.set('checked', !this.checked);
 	},
 
-	_setCheckedAttr: function(/*Boolean*/ value, /* Boolean? */ priorityChange){
-		this.checked = value;
+	_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);
@@ -319,7 +328,7 @@ dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
 
 	setChecked: function(/*Boolean*/ checked){
 		// summary:
-		//		Deprecated.   Use set('checked', true/false) instead.
+		//		Deprecated.  Use set('checked', true/false) instead.
 		dojo.deprecated("setChecked("+checked+") is deprecated. Use set('checked',"+checked+") instead.", "", "2.0");
 		this.set('checked', checked);
 	},
@@ -334,3 +343,7 @@ dojo.declare("dijit.form.ToggleButton", dijit.form.Button, {
 		this.set('checked', this.params.checked || false);
 	}
 });
+
+
+return dijit.form.Button;
+});
diff --git a/dijit/form/CheckBox.js b/dijit/form/CheckBox.js
index 23e580e..a530e26 100644
--- a/dijit/form/CheckBox.js
+++ b/dijit/form/CheckBox.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.CheckBox");
-
-dojo.require("dijit.form.ToggleButton");
+define("dijit/form/CheckBox", ["dojo", "dijit", "text!dijit/form/templates/CheckBox.html", "dijit/form/ToggleButton"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form.CheckBox",
@@ -29,20 +27,20 @@ dojo.declare(
 
 		// type: [private] String
 		//		type attribute on <input> node.
-		//		Overrides `dijit.form.Button.type`.   Users should not change this value.
+		//		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, attr('value') will return either the string or false depending on
+		//		However, get('value') will return either the string or false depending on
 		//		whether or not the checkbox is checked.
 		//
-		//		attr('value', string) will check the checkbox and change the value to the
+		//		set('value', string) will check the checkbox and change the value to the
 		//		specified string
 		//
-		//		attr('value', boolean) will change the checked state.
+		//		set('value', boolean) will change the checked state.
 		value: "on",
 
 		// readOnly: Boolean
@@ -51,22 +49,22 @@ dojo.declare(
 		//		Similar to disabled except readOnly form values are submitted.
 		readOnly: false,
 		
-		// the attributeMap should inherit from dijit.form._FormWidget.prototype.attributeMap 
+		// 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.readOnly = value;
+			this._set("readOnly", value);
 			dojo.attr(this.focusNode, 'readOnly', value);
 			dijit.setWaiState(this.focusNode, "readonly", value);
 		},
 
-		_setValueAttr: function(/*String or Boolean*/ newValue, /*Boolean*/ priorityChange){
+		_setValueAttr: function(/*String|Boolean*/ newValue, /*Boolean*/ priorityChange){
 			// summary:
 			//		Handler for value= attribute to constructor, and also calls to
-			//		attr('value', val).
+			//		set('value', val).
 			// description:
 			//		During initialization, just saves as attribute to the <input type=checkbox>.
 			//
@@ -76,7 +74,7 @@ dojo.declare(
 			//		specified as "value" when the CheckBox was constructed (ex: <input
 			//		dojoType="dijit.CheckBox" value="chicken">)
 			if(typeof newValue == "string"){
-				this.value = newValue;
+				this._set("value", newValue);
 				dojo.attr(this.focusNode, 'value', newValue);
 				newValue = true;
 			}
@@ -86,7 +84,7 @@ dojo.declare(
 		},
 		_getValueAttr: function(){
 			// summary:
-			//		Hook so attr('value') works.
+			//		Hook so get('value') works.
 			// description:
 			//		If the CheckBox is checked, returns the value attribute.
 			//		Otherwise returns false.
@@ -123,7 +121,7 @@ dojo.declare(
 			this.set('checked', this.params.checked || false);
 
 			// Handle unlikely event that the <input type=checkbox> value attribute has changed
-			this.value = this.params.value || "on";
+			this._set("value", this.params.value || "on");
 			dojo.attr(this.focusNode, 'value', this.value);
 		},
 
@@ -146,6 +144,7 @@ dojo.declare(
 			//		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);
@@ -190,3 +189,7 @@ dojo.declare(
 		}
 	}
 );
+
+
+return dijit.form.CheckBox;
+});
diff --git a/dijit/form/ComboBox.js b/dijit/form/ComboBox.js
index 6073827..a0464ed 100644
--- a/dijit/form/ComboBox.js
+++ b/dijit/form/ComboBox.js
@@ -1,19 +1,8 @@
-dojo.provide("dijit.form.ComboBox");
-
-dojo.require("dojo.window");
-dojo.require("dojo.regexp");
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
-dojo.require("dijit._CssStateMixin");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dijit.form.ValidationTextBox");
-
-dojo.requireLocalization("dijit.form", "ComboBox");
+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",
-	null,
+	dijit._HasDropDown,
 	{
 		// summary:
 		//		Implements the base functionality for `dijit.form.ComboBox`/`dijit.form.FilteringSelect`
@@ -32,14 +21,14 @@ dojo.declare(
 		//		Specifies number of search results per page (before hitting "next" button)
 		pageSize: Infinity,
 
-		// store: Object
+		// 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} }
+		//	|	{ sort: [{attribute:"name",descending: true}] }
 		//		To override the default queryOptions so that deep=false, do:
 		//	|	{ queryOptions: {ignoreCase: true, deep: false} }
 		fetchProperties:{},
@@ -92,7 +81,7 @@ dojo.declare(
 		//		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.
+		//		etc.  Use it in conjunction with highlightMatch.
 		//		dojo.data query expression pattern.
 		//		`${0}` will be substituted for the user text.
 		//		`*` is used for wildcards.
@@ -103,21 +92,32 @@ dojo.declare(
 		//		Set true if the ComboBox/FilteringSelect should ignore case when matching possible items
 		ignoreCase: true,
 
-		// hasDownArrow: [const] Boolean
+		// 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/ComboBox.html"),
+		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: {
-			"downArrowNode": "dijitDownArrowButton"
+			"_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;
@@ -134,7 +134,7 @@ dojo.declare(
 				tr.move("character",0);
 				ntr.move("character",0);
 				try{
-					// If control doesnt have focus, you get an exception.
+					// 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);
@@ -155,7 +155,7 @@ dojo.declare(
 			// Additional code to set disabled state of ComboBox node.
 			// Overrides _FormValueWidget._setDisabledAttr() or ValidationTextBox._setDisabledAttr().
 			this.inherited(arguments);
-			dijit.setWaiState(this.comboNode, "disabled", value);
+			dijit.setWaiState(this.domNode, "disabled", value);
 		},
 
 		_abortQuery: function(){
@@ -175,29 +175,39 @@ dojo.declare(
 			//		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._onKeyPress({charOrCode: 229}); // fake IME key to cause a search
+					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);
 		},
 
-		_onKeyPress: function(/*Event*/ 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 == dojo.keys.SHIFT){
 				return; // throw out weird key combinations and spurious events
 			}
+			
 			var doSearch = false;
-			var searchFunction = "_startSearchFromInput";
-			var pw = this._popupWidget;
+			var pw = this.dropDown;
 			var dk = dojo.keys;
 			var highlighted = null;
 			this._prev_key_backspace = false;
 			this._abortQuery();
-			if(this._isShowingNow){
-				pw.handleKey(key);
+
+			// _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){
@@ -205,10 +215,9 @@ dojo.declare(
 				case dk.DOWN_ARROW:
 				case dk.PAGE_UP:
 				case dk.UP_ARROW:
-					if(!this._isShowingNow){
-						doSearch = true;
-						searchFunction = "_startSearchAll";
-					}else{
+					// 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);
@@ -235,8 +244,12 @@ dojo.declare(
 						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:
@@ -252,29 +265,24 @@ dojo.declare(
 					if(highlighted){
 						this._selectOption();
 					}
-					if(this._isShowingNow){
+					if(this._opened){
 						this._lastQuery = null; // in case results come back later
-						this._hideResultList();
+						this.closeDropDown();
 					}
 					break;
 
 				case ' ':
 					if(highlighted){
+						// user is effectively clicking a choice in the drop down menu
 						dojo.stopEvent(evt);
 						this._selectOption();
-						this._hideResultList();
+						this.closeDropDown();
 					}else{
+						// user typed a space into the input box, treat as normal character
 						doSearch = true;
 					}
 					break;
 
-				case dk.ESCAPE:
-					if(this._isShowingNow){
-						dojo.stopEvent(evt);
-						this._hideResultList();
-					}
-					break;
-
 				case dk.DELETE:
 				case dk.BACKSPACE:
 					this._prev_key_backspace = true;
@@ -284,15 +292,14 @@ dojo.declare(
 				default:
 					// Non char keys (F1-F12 etc..)  shouldn't open list.
 					// Ascii characters and IME input (Chinese, Japanese etc.) should.
-					// On IE and safari, IME input produces keycode == 229, and we simulate
-					// it on firefox by attaching to compositionend event (see compositionend method)
+					//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, searchFunction),1);
+				this.searchTimer = setTimeout(dojo.hitch(this, "_startSearchFromInput"),1);
 			}
 		},
 
@@ -328,6 +335,12 @@ dojo.declare(
 		},
 
 		_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 ||
@@ -335,13 +348,13 @@ dojo.declare(
 			){
 				return;
 			}
-			this._popupWidget.clearResultList();
-			if(!results.length && !this._maxOptions){ // this condition needs to match !this._isvalid set in FilteringSelect::_openResultList
-				this._hideResultList();
+			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
@@ -349,7 +362,7 @@ dojo.declare(
 			// highlighted.
 
 			dataObject._maxOptions = this._maxOptions;
-			var nodes = this._popupWidget.createOptions(
+			var nodes = this.dropDown.createOptions(
 				results,
 				dataObject,
 				dojo.hitch(this, "_getMenuLabelFromItem")
@@ -363,12 +376,14 @@ dojo.declare(
 			//		shouting the next choice
 			if(dataObject.direction){
 				if(1 == dataObject.direction){
-					this._popupWidget.highlightFirstOption();
+					this.dropDown.highlightFirstOption();
 				}else if(-1 == dataObject.direction){
-					this._popupWidget.highlightLastOption();
+					this.dropDown.highlightLastOption();
+				}
+				if(wasSelected){
+					this._announceOption(this.dropDown.getHighlightedOption());
 				}
-				this._announceOption(this._popupWidget.getHighlightedOption());
-			}else if(this.autoComplete && !this._prev_key_backspace /*&& !dataObject.direction*/
+			}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
@@ -379,62 +394,42 @@ dojo.declare(
 		},
 
 		_showResultList: function(){
-			this._hideResultList();
+			// 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("");
 
-			// Position the list and if it's too big to fit on the screen then
-			// size it to the maximum possible height
-			// Our dear friend IE doesnt take max-height so we need to
-			// calculate that on our own every time
-
-			// TODO: want to redo this, see
-			//		http://trac.dojotoolkit.org/ticket/3272
-			//	and
-			//		http://trac.dojotoolkit.org/ticket/4108
-
-
-			// natural size of the list has changed, so erase old
-			// width/height settings, which were hardcoded in a previous
-			// call to this function (via dojo.marginBox() call)
-			dojo.style(this._popupWidget.domNode, {width: "", height: ""});
-
-			var best = this.open();
-			// #3212:
-			//		only set auto scroll bars if necessary prevents issues with
-			//		scroll bars appearing when they shouldn't when node is made
-			//		wider (fractional pixels cause this)
-			var popupbox = dojo.marginBox(this._popupWidget.domNode);
-			this._popupWidget.domNode.style.overflow =
-				((best.h == popupbox.h) && (best.w == popupbox.w)) ? "hidden" : "auto";
-			// #4134:
-			//		borrow TextArea scrollbar test so content isn't covered by
-			//		scrollbar and horizontal scrollbar doesn't appear
-			var newwidth = best.w;
-			if(best.h < this._popupWidget.domNode.scrollHeight){
-				newwidth += 16;
-			}
-			dojo.marginBox(this._popupWidget.domNode, {
-				h: best.h,
-				w: Math.max(newwidth, this.domNode.offsetWidth)
-			});
+			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.
 			
-			// If we increased the width of drop down to match the width of ComboBox.domNode,
-			// then need to reposition the drop down (wrapper) so (all of) the drop down still
-			// appears underneath the ComboBox.domNode
-			if(newwidth < this.domNode.offsetWidth){
-				this._popupWidget.domNode.parentNode.style.left = dojo.position(this.domNode, true).x + "px";
-			}
+			this._startSearchAll();
+		},
 
-			dijit.setWaiState(this.comboNode, "expanded", "true");
+		isLoaded: function(){
+			// signal to _HasDropDown that it needs to call loadDropDown() to load the
+			// drop down asynchronously before displaying it
+			return false;
 		},
 
-		_hideResultList: function(){
+		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._isShowingNow){
-				dijit.popup.close(this._popupWidget);
-				this._isShowingNow=false;
-				dijit.setWaiState(this.comboNode, "expanded", "false");
+			if(this._opened){
+				this.inherited(arguments);
+				dijit.setWaiState(this.domNode, "expanded", "false");
 				dijit.removeWaiState(this.focusNode,"activedescendant");
 			}
 		},
@@ -446,7 +441,7 @@ dojo.declare(
 			//		if value is now more choices or previous choices, revert
 			//		the value
 			var newvalue = this.get('displayedValue');
-			var pw = this._popupWidget;
+			var pw = this.dropDown;
 			if(pw && (
 				newvalue == pw._messages["previousMessage"] ||
 				newvalue == pw._messages["nextMessage"]
@@ -468,23 +463,25 @@ dojo.declare(
 		_onBlur: function(){
 			// summary:
 			//		Called magically when focus has shifted away from this widget and it's drop down
-			this._hideResultList();
+			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.
+			//		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
-			//              attr('item', value)
+			//		Users shouldn't call this function; they should be calling
+			//		set('item', value)
 			// tags:
-			//              private
-			if(!displayedValue){ displayedValue = this.labelFunc(item, this.store); }
-			this.value = this._getValueField() != this.searchAttr? this.store.getIdentity(item) : displayedValue;
-			this.item = item;
-			dijit.form.ComboBox.superclass._setValueAttr.call(this, this.value, priorityChange, displayedValue);
+			//		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){
@@ -498,13 +495,13 @@ dojo.declare(
 			}
 			// pull the text value from the item attached to the DOM node
 			var newValue;
-			if(node == this._popupWidget.nextButton ||
-				node == this._popupWidget.previousButton){
+			if(node == this.dropDown.nextButton ||
+				node == this.dropDown.previousButton){
 				newValue = node.innerHTML;
 				this.item = undefined;
 				this.value = '';
 			}else{
-				newValue = this.labelFunc(node.item, this.store);
+				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)
@@ -521,28 +518,11 @@ dojo.declare(
 			if(evt){
 				this._announceOption(evt.target);
 			}
-			this._hideResultList();
+			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
 		},
 
-		_onArrowMouseDown: function(evt){
-			// summary:
-			//		Callback when arrow is clicked
-			if(this.disabled || this.readOnly){
-				return;
-			}
-			dojo.stopEvent(evt);
-			this.focus();
-			if(this._isShowingNow){
-				this._hideResultList();
-			}else{
-				// forces full population of results, if they click
-				// on the arrow it means they want to see more options
-				this._startSearchAll();
-			}
-		},
-
 		_startSearchAll: function(){
 			this._startSearch('');
 		},
@@ -556,9 +536,13 @@ dojo.declare(
 		},
 
 		_startSearch: function(/*String*/ key){
-			if(!this._popupWidget){
-				var popupId = this.id + "_popup";
-				this._popupWidget = new dijit.form._ComboBoxMenu({
+			// 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
@@ -587,7 +571,7 @@ dojo.declare(
 					onError: function(errText){
 						_this._fetchHandle = null;
 						console.error('dijit.form.ComboBox: ' + errText);
-						dojo.hitch(_this, "_hideResultList")();
+						_this.closeDropDown();
 					},
 					start: 0,
 					count: this.pageSize
@@ -602,8 +586,9 @@ dojo.declare(
 					//		reader knows which menu option to shout
 					dataObject.direction = direction;
 					this._fetchHandle = this.store.fetch(dataObject);
+					this.focus();
 				};
-				this._nextSearch = this._popupWidget.onPage = dojo.hitch(this, nextSearch, this._fetchHandle);
+				this._nextSearch = this.dropDown.onPage = dojo.hitch(this, nextSearch, this._fetchHandle);
 			}, query, this), this.searchDelay);
 		},
 
@@ -612,29 +597,12 @@ dojo.declare(
 		},
 
 		_getValueField: function(){
-			// summmary:
+			// 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;
 		},
 
-		/////////////// Event handlers /////////////////////
-
-		// FIXME: For 2.0, rename to "_compositionEnd"
-		compositionend: function(/*Event*/ evt){
-			// summary:
-			//		When inputting characters using an input method, such as
-			//		Asian languages, it will generate this event instead of
-			//		onKeyDown event.
-			//		Note: this event is only triggered in FF (not in IE/safari)
-			// tags:
-			//		private
-
-			// 229 is the code produced by IE and safari while pressing keys during
-			// IME input mode
-			this._onKeyPress({charOrCode: 229});
-		},
-
 		//////////// INITIALIZATION METHODS ///////////////////////////////////////
 
 		constructor: function(){
@@ -658,13 +626,14 @@ dojo.declare(
 				// 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.store.fetchSelectedItem();
+					var item = (this.item = this.store.fetchSelectedItem());
 					if(item){
 						var valueField = this._getValueField();
-						this.value = valueField != this.searchAttr? this.store.getValue(item, valueField) : this.labelFunc(item, this.store);
+						this.value = this.store.getValue(item, valueField);
 					}
 				}
 			}
+
 			this.inherited(arguments);
 		},
 
@@ -674,32 +643,24 @@ dojo.declare(
 			// tags:
 			//		protected
 
-			if(!this.hasDownArrow){
-				this.downArrowNode.style.display = "none";
-			}
-
 			// 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");
-				var cn=this.comboNode;
-				dijit.setWaiState(cn, "labelledby", label[0].id);
+				dijit.setWaiState(this.domNode, "labelledby", label[0].id);
 
 			}
 			this.inherited(arguments);
 		},
 
-		uninitialize: function(){
-			if(this._popupWidget && !this._popupWidget._destroyed){
-				this._hideResultList();
-				this._popupWidget.destroy();
-			}
-			this.inherited(arguments);
+		_setHasDownArrowAttr: function(val){
+			this.hasDownArrow = val;
+			this._buttonNode.style.display = val ? "" : "none";
 		},
 
 		_getMenuLabelFromItem: function(/*Item*/ item){
-			var label = this.labelAttr? this.store.getValue(item, this.labelAttr) : this.labelFunc(item, this.store);
-			var labelType = this.labelType;
+			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));
@@ -708,24 +669,27 @@ dojo.declare(
 			return {html: labelType == "html", label: label};
 		},
 
-		doHighlight: function(/*String*/label, /*String*/find){
+		doHighlight: function(/*String*/ label, /*String*/ find){
 			// summary:
 			//		Highlights the string entered by the user in the menu.  By default this
-			//		highlights the first occurence found. Override this method
-			//		to implement your custom highlighing.
+			//		highlights the first occurrence found. Override this method
+			//		to implement your custom highlighting.
 			// tags:
 			//		protected
 
-			// Add greedy when this.highlightMatch == "all"
-			var modifiers = "i"+(this.highlightMatch == "all"?"g":"");
-			var escapedLabel = this._escapeHtml(label);
+			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
-			var ret = escapedLabel.replace(new RegExp("(^|\\s)("+ find +")", modifiers),
-					'$1<span class="dijitComboBoxHighlightMatch">$2</span>');
-			return ret;// returns String, (almost) valid HTML (entities encoded)
+			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){
+		_escapeHtml: function(/*String*/ str){
 			// TODO Should become dojo.html.entities(), when exists use instead
 			// summary:
 			//		Adds escape sequences for special characters in XML: &<>"'
@@ -734,19 +698,6 @@ dojo.declare(
 			return str; // string
 		},
 
-		open: function(){
-			// summary:
-			//		Opens the drop down menu.  TODO: rename to _open.
-			// tags:
-			//		private
-			this._isShowingNow=true;
-			return dijit.popup.open({
-				popup: this._popupWidget,
-				around: this.domNode,
-				parent: this
-			});
-		},
-
 		reset: function(){
 			// Overrides the _FormWidget.reset().
 			// Additionally reset the .item (to clean up).
@@ -756,15 +707,15 @@ dojo.declare(
 
 		labelFunc: function(/*item*/ item, /*dojo.data.store*/ store){
 			// summary:
-			//              Computes the label to display based on the dojo.data store item.
+			//		Computes the label to display based on the dojo.data store item.
 			// returns:
-			//              The label that the ComboBox should display
+			//		The label that the ComboBox should display
 			// tags:
-			//              private
+			//		private
 
 			// Use toString() because XMLStore returns an XMLItem whereas this
 			// method is expected to return a String (#9354)
-			return store.getValue(item, this.searchAttr).toString(); // String
+			return store.getValue(item, this.labelAttr || this.searchAttr).toString(); // String
 		}
 	}
 );
@@ -778,9 +729,9 @@ dojo.declare(
 		// tags:
 		//		private
 
-		templateString: "<ul class='dijitReset dijitMenu' dojoAttachEvent='onmousedown:_onMouseDown,onmouseup:_onMouseUp,onmouseover:_onMouseOver,onmouseout:_onMouseOut' tabIndex='-1' style='overflow: \"auto\"; overflow-x: \"hidden\";'>"
-				+"<li class='dijitMenuItem dijitMenuPreviousButton' dojoAttachPoint='previousButton' waiRole='option'></li>"
-				+"<li class='dijitMenuItem dijitMenuNextButton' dojoAttachPoint='nextButton' waiRole='option'></li>"
+		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
@@ -790,8 +741,16 @@ dojo.declare(
 		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){
@@ -814,13 +773,6 @@ dojo.declare(
 			//		callback
 		},
 
-		postCreate: function(){
-			// fill in template with i18n messages
-			this.previousButton.innerHTML = this._messages["previousMessage"];
-			this.nextButton.innerHTML = this._messages["nextMessage"];
-			this.inherited(arguments);
-		},
-
 		onClose: function(){
 			// summary:
 			//		Callback from dijit.popup code to this widget, notifying it that it closed
@@ -834,9 +786,11 @@ dojo.declare(
 			//		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);
-			var menuitem = dojo.doc.createElement("li");
-			dijit.setWaiRole(menuitem, "option");
 			if(labelObject.html){
 				menuitem.innerHTML = labelObject.label;
 			}else{
@@ -873,8 +827,6 @@ dojo.declare(
 			//		iterate over cache nondestructively
 			dojo.forEach(results, function(item, i){
 				var menuitem = this._createOption(item, labelFunc);
-				menuitem.className = "dijitReset dijitMenuItem" +
-					(this.isLeftToRight() ? "" : " dijitMenuItemRtl");
 				dojo.attr(menuitem, "id", this.id + i);
 				this.domNode.insertBefore(menuitem, this.nextButton);
 			}, this);
@@ -907,6 +859,7 @@ dojo.declare(
 			while(this.domNode.childNodes.length>2){
 				this.domNode.removeChild(this.domNode.childNodes[this.domNode.childNodes.length-2]);
 			}
+			this._blurOptionNode();
 		},
 
 		_onMouseDown: function(/*Event*/ evt){
@@ -915,10 +868,14 @@ dojo.declare(
 
 		_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;
@@ -1085,20 +1042,25 @@ dojo.declare(
 			return (ho && ho.parentNode) ? ho : null;
 		},
 
-		handleKey: function(key){
-			switch(key){
+		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();
-					break;
+					return false;
 				case dojo.keys.PAGE_DOWN:
 					this.pageDown();
-					break;
+					return false;
 				case dojo.keys.UP_ARROW:
 					this._highlightPrevOption();
-					break;
+					return false;
 				case dojo.keys.PAGE_UP:
 					this.pageUp();
-					break;
+					return false;
+				default:
+					return true;
 			}
 		}
 	}
@@ -1126,10 +1088,10 @@ dojo.declare(
 
 		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange, /*String?*/ displayedValue){
 			// summary:
-			//		Hook so attr('value', value) works.
+			//		Hook so set('value', value) works.
 			// description:
 			//		Sets the value of the select.
-			this.item = null; // value not looked up in store
+			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);
 		}
@@ -1173,13 +1135,13 @@ dojo.declare("dijit.form._ComboBoxDataStore", null, {
 
 	},
 
-	getValue: function(	/* item */ item,
-						/* attribute-name-string */ attribute,
-						/* value? */ defaultValue){
+	getValue: function(	/*item*/ item,
+						/*attribute-name-string*/ attribute,
+						/*value?*/ defaultValue){
 		return (attribute == "value") ? item.value : (item.innerText || item.textContent || '');
 	},
 
-	isItemLoaded: function(/* anything */ something){
+	isItemLoaded: function(/*anything*/ something){
 		return true;
 	},
 
@@ -1187,9 +1149,9 @@ dojo.declare("dijit.form._ComboBoxDataStore", null, {
 		return {"dojo.data.api.Read": true, "dojo.data.api.Identity": true};
 	},
 
-	_fetchItems: function(	/* Object */ args,
-							/* Function */ findCallback,
-							/* Function */ errorCallback){
+	_fetchItems: function(	/*Object*/ args,
+							/*Function*/ findCallback,
+							/*Function*/ errorCallback){
 		// summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		if(!args.query){ args.query = {}; }
@@ -1205,19 +1167,19 @@ dojo.declare("dijit.form._ComboBoxDataStore", null, {
 		findCallback(items, args);
 	},
 
-	close: function(/*dojo.data.api.Request || args || null */ request){
+	close: function(/*dojo.data.api.Request || args || null*/ request){
 		return;
 	},
 
-	getLabel: function(/* item */ item){
+	getLabel: function(/*item*/ item){
 		return item.innerHTML;
 	},
 
-	getIdentity: function(/* item */ item){
+	getIdentity: function(/*item*/ item){
 		return dojo.attr(item, "value");
 	},
 
-	fetchItemByIdentity: function(/* Object */ args){
+	fetchItemByIdentity: function(/*Object*/ args){
 		// summary:
 		//		Given the identity of an item, this method returns the item that has
 		//		that identity through the onItem callback.
@@ -1246,3 +1208,7 @@ dojo.declare("dijit.form._ComboBoxDataStore", null, {
 });
 //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/ComboButton.js b/dijit/form/ComboButton.js
index fc98c1b..0ece056 100644
--- a/dijit/form/ComboButton.js
+++ b/dijit/form/ComboButton.js
@@ -1,2 +1,6 @@
-dojo.provide("dijit.form.ComboButton");
-dojo.require("dijit.form.Button");
+define("dijit/form/ComboButton", ["dojo", "dijit", "dijit/form/Button"], function(dojo, dijit) {
+
+
+
+return dijit.form.ComboButton;
+});
diff --git a/dijit/form/CurrencyTextBox.js b/dijit/form/CurrencyTextBox.js
index 6cec892..315513a 100644
--- a/dijit/form/CurrencyTextBox.js
+++ b/dijit/form/CurrencyTextBox.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form.CurrencyTextBox");
-
-dojo.require("dojo.currency");
-dojo.require("dijit.form.NumberTextBox");
+define("dijit/form/CurrencyTextBox", ["dojo", "dijit", "dojo/currency", "dijit/form/NumberTextBox"], function(dojo, dijit) {
 
 /*=====
 dojo.declare(
@@ -40,11 +37,11 @@ dojo.declare(
 		//		the [ISO4217](http://en.wikipedia.org/wiki/ISO_4217) currency code, a three letter sequence like "USD"
 		currency: "",
 
+		/*=====
 		// constraints: dijit.form.CurrencyTextBox.__Constraints
 		//		Despite the name, this parameter specifies both constraints on the input
 		//		(including minimum/maximum allowed values) as well as
-		//		formatting options.   See `dijit.form.CurrencyTextBox.__Constraints` for details.
-		/*=====
+		//		formatting options.  See `dijit.form.CurrencyTextBox.__Constraints` for details.
 		constraints: {},
 		======*/
 		
@@ -61,19 +58,21 @@ dojo.declare(
 		// Override NumberTextBox._formatter to deal with currencies, ex: converts "123.45" to "$123.45"
 		_formatter: dojo.currency.format,
 
-		parse: function(/* String */ value, /* Object */ constraints){
+		_parser: dojo.currency.parse,
+
+		parse: function(/*String*/ value, /*Object*/ constraints){
 			// summary:
 			// 		Parses string value as a Currency, according to the constraints object
 			// tags:
 			// 		protected extension
-			var v = dojo.currency.parse(value, constraints);
+			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
-				return this.inherited(arguments, [ value, dojo.mixin({}, constraints, this.editOptions) ]);
+				v = dojo.hitch(dojo.mixin({}, this, { _parser: dijit.form.NumberTextBox.prototype._parser }), "inherited")(arguments);
 			}
 			return v;
 		},
 
-		_setConstraintsAttr: function(/* Object */ constraints){
+		_setConstraintsAttr: function(/*Object*/ constraints){
 			if(!constraints.currency && this.currency){
 				constraints.currency = this.currency;
 			}
@@ -81,3 +80,7 @@ dojo.declare(
 		}
 	}
 );
+
+
+return dijit.form.CurrencyTextBox;
+});
diff --git a/dijit/form/DateTextBox.js b/dijit/form/DateTextBox.js
index e03e9e7..b6da6f3 100644
--- a/dijit/form/DateTextBox.js
+++ b/dijit/form/DateTextBox.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form.DateTextBox");
-
-dojo.require("dijit.Calendar");
-dojo.require("dijit.form._DateTimeTextBox");
+define("dijit/form/DateTextBox", ["dojo", "dijit", "dijit/Calendar", "dijit/form/_DateTimeTextBox"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form.DateTextBox",
@@ -16,13 +13,18 @@ dojo.declare(
 		//		Example:
 		// |	<input dojotype='dijit.form.DateTextBox' value='2009-01-20'>
 
-		baseClass: "dijitTextBox dijitDateTextBox",
+		baseClass: "dijitTextBox dijitComboBox dijitDateTextBox",
 		popupClass: "dijit.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 `dojo.date.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 533532f..2580ffc 100644
--- a/dijit/form/DropDownButton.js
+++ b/dijit/form/DropDownButton.js
@@ -1,3 +1,6 @@
-dojo.provide("dijit.form.DropDownButton");
-dojo.require("dijit.form.Button");
+define("dijit/form/DropDownButton", ["dojo", "dijit", "dijit/form/Button"], function(dojo, dijit) {
 
+
+
+return dijit.form.DropDownButton;
+});
diff --git a/dijit/form/FilteringSelect.js b/dijit/form/FilteringSelect.js
index 42b5d77..749babc 100644
--- a/dijit/form/FilteringSelect.js
+++ b/dijit/form/FilteringSelect.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.FilteringSelect");
-
-dojo.require("dijit.form.ComboBox");
+define("dijit/form/FilteringSelect", ["dojo", "dijit", "dijit/form/ComboBox"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form.FilteringSelect",
@@ -32,17 +30,19 @@ dojo.declare(
 		//			- List can be specified either as a static list or via a javascript
 		//				function (that can get the list from a server)
 
-		_isvalid: true,
-
 		// required: Boolean
 		//		True (default) if user is required to enter a value into this field.
 		required: true,
 
 		_lastDisplayedValue: "",
 
+		_isValidSubset: function(){
+			return this._opened;
+		},
+
 		isValid: function(){
 			// Overrides ValidationTextBox.isValid()
-			return this._isvalid || (!this.required && this.get('displayedValue') == ""); // #5974
+			return this.item || (!this.required && this.get('displayedValue') == ""); // #5974
 		},
 
 		_refreshState: function(){
@@ -51,12 +51,12 @@ dojo.declare(
 			}
 		},
 
-		_callbackSetLabel: function(	/*Array*/ result,
+		_callbackSetLabel: function(
+						/*Array*/ result,
 						/*Object*/ dataObject,
 						/*Boolean?*/ priorityChange){
 			// summary:
-			//		Callback function that dynamically sets the label of the
-			//		ComboBox
+			//		Callback from dojo.data after lookup of user entered value finishes
 
 			// setValue does a synchronous lookup,
 			// so it calls _callbackSetLabel directly,
@@ -66,35 +66,38 @@ dojo.declare(
 				return;
 			}
 			if(!result.length){
-				//#3268: do nothing on bad input
+				//#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._isvalid = false;
+				this._set("item", null);
 				this.validate(this._focused);
-				this.item = null;
 			}else{
 				this.set('item', result[0], priorityChange);
 			}
 		},
 
 		_openResultList: function(/*Object*/ results, /*Object*/ dataObject){
+			// 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){
 				return;
 			}
+			dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
+
 			if(this.item === undefined){ // item == undefined for keyboard search
-				this._isvalid = results.length != 0 || this._maxOptions != 0; // result.length==0 && maxOptions != 0 implies the nextChoices item selected but then the datastore returned 0 more entries
+				// If the search returned no items that means that the user typed
+				// in something invalid (and they can't make it valid by typing more characters),
+				// so flag the FilteringSelect as being in an invalid state
 				this.validate(true);
 			}
-			dijit.form.ComboBoxMixin.prototype._openResultList.apply(this, arguments);
 		},
 
 		_getValueAttr: function(){
 			// summary:
-			//		Hook for attr('value') to work.
+			//		Hook for get('value') to work.
 
 			// don't get the textbox value but rather the previously set hidden value.
 			// Use this.valueNode.value which isn't always set for other MappedTextBox widgets until blur
@@ -108,7 +111,7 @@ dojo.declare(
 
 		_setValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
 			// summary:
-			//		Hook so attr('value', value) works.
+			//		Hook so set('value', value) works.
 			// description:
 			//		Sets the value of the select.
 			//		Also sets the label to the corresponding value by reverse lookup.
@@ -136,10 +139,9 @@ dojo.declare(
 			//		that gets submitted, based on a dojo.data store item.
 			// description:
 			//		Users shouldn't call this function; they should be calling
-			//		attr('item', value)
+			//		set('item', value)
 			// tags:
 			//		private
-			this._isvalid = true;
 			this.inherited(arguments);
 			this.valueNode.value = this.value;
 			this._lastDisplayedValue = this.textbox.value;
@@ -151,30 +153,38 @@ dojo.declare(
 
 		_setDisplayedValueAttr: function(/*String*/ label, /*Boolean?*/ priorityChange){
 			// summary:
-			//		Hook so attr('displayedValue', label) works.
+			//		Hook so set('displayedValue', label) works.
 			// description:
 			//		Sets textbox to display label. Also performs reverse lookup
-			//		to set the hidden value.
+			//		to set the hidden value.  label should corresponding to item.searchAttr.
 
-			// When this is called during initialization it'll ping the datastore
-			// for reverse lookup, and when that completes (after an XHR request)
-			// will call setValueAttr()... but that shouldn't trigger an onChange()
-			// event, even when it happens after creation has finished
+			if(label == null){ label = ''; }
+
+			// This is called at initialization along with every custom setter.
+			// Usually (or always?) the call can be ignored.   If it needs to be
+			// processed then at least make sure that the XHR request doesn't trigger an onChange()
+			// event, even if it returns after creation has finished
 			if(!this._created){
+				if(!("displayedValue" in this.params)){
+					return;
+				}
 				priorityChange = false;
 			}
 
+			// Do a reverse lookup to map the specified displayedValue to the hidden value.
+			// Note that if there's a custom labelFunc() this code
 			if(this.store){
-				this._hideResultList();
+				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);
-				// if the label is not valid, the callback will never set it,
-				// so the last valid value will get the warning textbox set the
+				// 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
 				// sense to the user
 				this.textbox.value = label;
 				this._lastDisplayedValue = label;
+				this._set("displayedValue", label);	// for watch("displayedValue") notification
 				var _this = this;
 				var fetch = {
 					query: query,
@@ -197,13 +207,12 @@ dojo.declare(
 			}
 		},
 
-		postMixInProperties: function(){
-			this.inherited(arguments);
-			this._isvalid = !this.required;
-		},
-
 		undo: function(){
 			this.set('displayedValue', this._lastDisplayedValue);
 		}
 	}
 );
+
+
+return dijit.form.FilteringSelect;
+});
diff --git a/dijit/form/Form.js b/dijit/form/Form.js
index c04b3cf..87a5156 100644
--- a/dijit/form/Form.js
+++ b/dijit/form/Form.js
@@ -1,12 +1,8 @@
-dojo.provide("dijit.form.Form");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit.form._FormMixin");
+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._Widget, dijit._Templated, dijit.form._FormMixin, dijit.layout._ContentPaneResizeMixin],
 	{
 		// summary:
 		//		Widget corresponding to HTML form tag, for validation and serialization
@@ -90,7 +86,7 @@ dojo.declare(
 
 		postCreate: function(){
 			// IE tries to hide encType
-			// TODO: this code should be in parser, not here.
+			// 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")){
@@ -111,8 +107,8 @@ dojo.declare(
 				preventDefault: function(){ // not IE
 							this.returnValue = false;
 						},
-				stopPropagation: function(){}, 
-				currentTarget: e ? e.target : this.domNode, 
+				stopPropagation: function(){},
+				currentTarget: e ? e.target : this.domNode,
 				target: e ? e.target : this.domNode
 			};
 			// if return value is not exactly false, and haven't called preventDefault(), then reset
@@ -151,7 +147,7 @@ dojo.declare(
 			}
 		},
 
-		onSubmit: function(/*Event?*/e){
+		onSubmit: function(/*Event?*/ e){
 			// summary:
 			//		Callback when user submits the form.
 			// description:
@@ -175,3 +171,7 @@ dojo.declare(
 		}
 	}
 );
+
+
+return dijit.form.Form;
+});
diff --git a/dijit/form/HorizontalRule.js b/dijit/form/HorizontalRule.js
index 79312aa..89db758 100644
--- a/dijit/form/HorizontalRule.js
+++ b/dijit/form/HorizontalRule.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form.HorizontalRule");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+define("dijit/form/HorizontalRule", ["dojo", "dijit", "dijit/_Widget", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
 {
@@ -35,7 +32,9 @@ dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
 	//		VerticalRule will override this...
 	_isHorizontal: true,
 
-	postCreate: function(){
+	buildRendering: function(){
+		this.inherited(arguments);
+
 		var innerHTML;
 		if(this.count == 1){
 			innerHTML = this._genHTML(50, 0);
@@ -59,3 +58,7 @@ dojo.declare("dijit.form.HorizontalRule", [dijit._Widget, dijit._Templated],
 		this.domNode.innerHTML = innerHTML;
 	}
 });
+
+
+return dijit.form.HorizontalRule;
+});
diff --git a/dijit/form/HorizontalRuleLabels.js b/dijit/form/HorizontalRuleLabels.js
index e6f3c47..db71049 100644
--- a/dijit/form/HorizontalRuleLabels.js
+++ b/dijit/form/HorizontalRuleLabels.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.HorizontalRuleLabels");
-
-dojo.require("dijit.form.HorizontalRule");
+define("dijit/form/HorizontalRuleLabels", ["dojo", "dijit", "dijit/form/HorizontalRule"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.HorizontalRuleLabels", dijit.form.HorizontalRule,
 {
@@ -86,3 +84,5 @@ 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 2d5c66d..19e661c 100644
--- a/dijit/form/HorizontalSlider.js
+++ b/dijit/form/HorizontalSlider.js
@@ -1,11 +1,4 @@
-dojo.provide("dijit.form.HorizontalSlider");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dijit._Container");
-dojo.require("dojo.dnd.move");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.number");
-dojo.require("dojo._base.fx");
+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) {
 
 dojo.declare(
 	"dijit.form.HorizontalSlider",
@@ -19,22 +12,22 @@ dojo.declare(
 	// Overrides FormValueWidget.value to indicate numeric value
 	value: 0,
 
-	// showButtons: Boolean
+	// showButtons: [const] Boolean
 	//		Show increment/decrement buttons at the ends of the slider?
 	showButtons: true,
 
-	// minimum:: Integer
+	// minimum:: [const] Integer
 	//		The minimum value the slider can be set to.
 	minimum: 0,
 
-	// maximum: Integer
+	// maximum: [const] Integer
 	//		The maximum value the slider can be set to.
 	maximum: 100,
 
 	// discreteValues: Integer
 	//		If specified, indicates that the slider handle has only 'discreteValues' possible positions,
-	//      and that after dragging the handle, it will snap to the nearest possible position.
-	//      Thus, the slider has only 'discreteValues' possible values.
+	//		and that after dragging the handle, it will snap to the nearest possible position.
+	//		Thus, the slider has only 'discreteValues' possible values.
 	//
 	//		For example, if minimum=10, maxiumum=30, and discreteValues=3, then the slider handle has
 	//		three possible positions, representing values 10, 20, or 30.
@@ -42,13 +35,13 @@ dojo.declare(
 	//		If discreteValues is not specified or if it's value is higher than the number of pixels
 	//		in the slider bar, then the slider handle can be moved freely, and the slider's value will be
 	//		computed/reported based on pixel position (in this case it will likely be fractional,
-	//      such as 123.456789).
+	//		such as 123.456789).
 	discreteValues: Infinity,
 
 	// pageIncrement: Integer
 	//		If discreteValues is also specified, this indicates the amount of clicks (ie, snap positions)
-	//      that the slider handle is moved via pageup/pagedown keys.
-	//	If discreteValues is not specified, it indicates the number of pixels.
+	//		that the slider handle is moved via pageup/pagedown keys.
+	//		If discreteValues is not specified, it indicates the number of pixels.
 	pageIncrement: 2,
 
 	// clickSelect: Boolean
@@ -60,7 +53,7 @@ dojo.declare(
 	//		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.)
+	// Flag to _Templated  (TODO: why is this here?  I see no widgets in the template.)
 	widgetsInTemplate: true,
 
 	attributeMap: dojo.delegate(dijit.form._FormWidget.prototype.attributeMap, {
@@ -143,7 +136,7 @@ dojo.declare(
 		this._movable.onMouseDown(e);
 	},
 
-	_setPixelValue: function(/*Number*/ pixelValue, /*Number*/ maxPixels, /*Boolean, optional*/ priorityChange){
+	_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;
@@ -154,10 +147,11 @@ dojo.declare(
 		this._setValueAttr((this.maximum-this.minimum)*wholeIncrements/count + this.minimum, priorityChange);
 	},
 
-	_setValueAttr: function(/*Number*/ value, /*Boolean, optional*/ priorityChange){
+	_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
 		// summary:
-		//		Hook so attr('value', value) works.
-		this.valueNode.value = this.value = value;
+		//		Hook so set('value', value) works.
+		this._set("value", value);
+		this.valueNode.value = value;
 		dijit.setWaiState(this.focusNode, "valuenow", value);
 		this.inherited(arguments);
 		var percent = (value - this.minimum) / (this.maximum - this.minimum);
@@ -181,14 +175,13 @@ dojo.declare(
 				properties: props
 			})
 			this._inProgressAnim.play();
-		}
-		else{
+		}else{
 			progressBar.style[this._progressPixelSize] = (percent*100) + "%";
 			remainingBar.style[this._progressPixelSize] = ((1-percent)*100) + "%";
 		}
 	},
 
-	_bumpValue: function(signedChange, /*Boolean, optional*/ priorityChange){
+	_bumpValue: function(signedChange, /*Boolean?*/ priorityChange){
 		if(this.disabled || this.readOnly){ return; }
 		var s = dojo.getComputedStyle(this.sliderBarContainer);
 		var c = dojo._getContentBox(this.sliderBarContainer, s);
@@ -260,10 +253,28 @@ dojo.declare(
 		}
 	},
 
-	postCreate: function(){
+	buildRendering: function(){
+		this.inherited(arguments);
 		if(this.showButtons){
 			this.incrementButton.style.display="";
 			this.decrementButton.style.display="";
+		}
+
+		// find any associated label element and add to slider focusnode.
+		var label = dojo.query('label[for="'+this.id+'"]');
+		if(label.length){
+			label[0].id = (this.id+"_label");
+			dijit.setWaiState(this.focusNode, "labelledby", label[0].id);
+		}
+
+		dijit.setWaiState(this.focusNode, "valuemin", this.minimum);
+		dijit.setWaiState(this.focusNode, "valuemax", this.maximum);
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+
+		if(this.showButtons){
 			this._connects.push(dijit.typematic.addMouseListener(
 				this.decrementButton, this, "_typematicCallback", 25, 500));
 			this._connects.push(dijit.typematic.addMouseListener(
@@ -275,18 +286,8 @@ dojo.declare(
 		var mover = dojo.declare(dijit.form._SliderMover, {
 			widget: this
 		});
-
 		this._movable = new dojo.dnd.Moveable(this.sliderHandle, {mover: mover});
-		// find any associated label element and add to slider focusnode.
-		var label=dojo.query('label[for="'+this.id+'"]');
-		if(label.length){
-			label[0].id = (this.id+"_label");
-			dijit.setWaiState(this.focusNode, "labelledby", label[0].id);
-		}
-		dijit.setWaiState(this.focusNode, "valuemin", this.minimum);
-		dijit.setWaiState(this.focusNode, "valuemax", this.maximum);
 
-		this.inherited(arguments);
 		this._layoutHackIE7();
 	},
 
@@ -311,7 +312,8 @@ dojo.declare("dijit.form._SliderMover",
 			widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
 			widget._isReversed_ = widget._isReversed();
 		}
-		var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
+		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);
 	},
 
@@ -324,3 +326,5 @@ dojo.declare("dijit.form._SliderMover",
 });
 
 
+return dijit.form.HorizontalSlider;
+});
diff --git a/dijit/form/MappedTextBox.js b/dijit/form/MappedTextBox.js
index 6b76b8d..16e5fbf 100644
--- a/dijit/form/MappedTextBox.js
+++ b/dijit/form/MappedTextBox.js
@@ -1,2 +1,6 @@
-dojo.provide("dijit.form.MappedTextBox");
-dojo.require("dijit.form.ValidationTextBox");
+define("dijit/form/MappedTextBox", ["dojo", "dijit", "dijit/form/ValidationTextBox"], function(dojo, dijit) {
+
+
+
+return dijit.form.MappedTextBox;
+});
diff --git a/dijit/form/MultiSelect.js b/dijit/form/MultiSelect.js
index 77d4975..ed36a72 100644
--- a/dijit/form/MultiSelect.js
+++ b/dijit/form/MultiSelect.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.MultiSelect");
-
-dojo.require("dijit.form._FormWidget");
+define("dijit/form/MultiSelect", ["dojo", "dijit", "dijit/form/_FormWidget"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 	// summary:
@@ -28,7 +26,7 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 		this._setValueAttr(this._resetValue, true);
 	},
 
-	addSelected: function(/* dijit.form.MultiSelect */ select){
+	addSelected: function(/*dijit.form.MultiSelect*/ select){
 		// summary:
 		//		Move the selected nodes of a passed Select widget
 		//		instance to this Select widget.
@@ -60,7 +58,7 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 
 	_getValueAttr: function(){
 		// summary:
-		//		Hook so attr('value') works.
+		//		Hook so get('value') works.
 		// description:
 		//		Returns an array of the selected options' values.
 		return this.getSelected().map(function(n){
@@ -70,9 +68,9 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 
 	multiple: true, // for Form
 
-	_setValueAttr: function(/* Array */values){
+	_setValueAttr: function(/*Array*/ values){
 		// summary:
-		//		Hook so attr('value', values) works.
+		//		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){
@@ -96,7 +94,7 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 	},
 
 	// for layout widgets:
-	resize: function(/* Object */size){
+	resize: function(/*Object*/ size){
 		if(size){
 			dojo.marginBox(this.domNode, size);
 		}
@@ -106,3 +104,7 @@ dojo.declare("dijit.form.MultiSelect", dijit.form._FormValueWidget, {
 		this._onChange();
 	}
 });
+
+
+return dijit.form.MultiSelect;
+});
diff --git a/dijit/form/NumberSpinner.js b/dijit/form/NumberSpinner.js
index 2638509..7fd3e12 100644
--- a/dijit/form/NumberSpinner.js
+++ b/dijit/form/NumberSpinner.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form.NumberSpinner");
-
-dojo.require("dijit.form._Spinner");
-dojo.require("dijit.form.NumberTextBox");
+define("dijit/form/NumberSpinner", ["dojo", "dijit", "dijit/form/_Spinner", "dijit/form/NumberTextBox"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.NumberSpinner",
 	[dijit.form._Spinner, dijit.form.NumberTextBoxMixin],
@@ -18,7 +15,7 @@ dojo.declare("dijit.form.NumberSpinner",
 	// example:
 	//	| new dijit.form.NumberSpinner({ constraints:{ max:300, min:100 }}, "someInput");
 
-	adjust: function(/* Object */val, /* Number*/delta){
+	adjust: function(/*Object*/ val, /*Number*/ delta){
 		// summary:
 		//		Change Number val by the given amount
 		// tags:
@@ -58,3 +55,7 @@ dojo.declare("dijit.form.NumberSpinner",
 		}
 	}
 });
+
+
+return dijit.form.NumberSpinner;
+});
diff --git a/dijit/form/NumberTextBox.js b/dijit/form/NumberTextBox.js
index ab95619..ea7a005 100644
--- a/dijit/form/NumberTextBox.js
+++ b/dijit/form/NumberTextBox.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form.NumberTextBox");
-
-dojo.require("dijit.form.ValidationTextBox");
-dojo.require("dojo.number");
+define("dijit/form/NumberTextBox", ["dojo", "dijit", "dijit/form/ValidationTextBox", "dojo/number"], function(dojo, dijit) {
 
 /*=====
 dojo.declare(
@@ -17,8 +14,7 @@ dojo.declare(
 	//	|		{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,
-	//		but after the field is blurred the value is displayed with 3 decimal places:
+	//		To specify a field where 0 to 3 decimal places are allowed on input:
 	//	|		{places:'0,3'}
 });
 =====*/
@@ -40,7 +36,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		//		Despite the name, this parameter specifies both constraints on the input
 		//		(including minimum/maximum allowed values) as well as
 		//		formatting options like places (the number of digits to display after
-		//		the decimal point).   See `dijit.form.NumberTextBox.__Constraints` for details.
+		//		the decimal point).  See `dijit.form.NumberTextBox.__Constraints` for details.
 		constraints: {},
 		======*/
 
@@ -48,10 +44,10 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		//		The value of this NumberTextBox as a Javascript Number (i.e., not a String).
 		//		If the displayed value is blank, the value is NaN, and if the user types in
 		//		an gibberish value (like "hello world"), the value is undefined
-		//		(i.e. attr('value') returns undefined).
+		//		(i.e. get('value') returns undefined).
 		//
-		//		Symmetrically, attr('value', NaN) will clear the displayed value,
-		//		whereas attr('value', undefined) will have no effect.
+		//		Symmetrically, set('value', NaN) will clear the displayed value,
+		//		whereas set('value', undefined) will have no effect.
 		value: NaN,
 
 		// editOptions: [protected] Object
@@ -63,7 +59,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		/*=====
 		_formatter: function(value, options){
 			// summary:
-			//		_formatter() is called by format().   It's the base routine for formatting a number,
+			//		_formatter() is called by format().  It's the base routine for formatting a number,
 			//		as a string, for example converting 12345 into "12,345".
 			// value: Number
 			//		The number to be converted into a string.
@@ -77,7 +73,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		 =====*/
 		_formatter: dojo.number.format,
 
-		_setConstraintsAttr: function(/* Object */ constraints){
+		_setConstraintsAttr: function(/*Object*/ constraints){
 			var places = typeof constraints.places == "number"? constraints.places : 0;
 			if(places){ places++; } // decimal rounding errors take away another digit of precision
 			if(typeof constraints.max != "number"){
@@ -124,7 +120,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 		},
 
 		/*=====
-		parse: function(value, constraints){
+		_parser: function(value, constraints){
 			// summary:
 			//		Parses the string value as a Number, according to constraints.
 			// value: String
@@ -137,7 +133,20 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			return 123.45;		// Number
 		},
 		=====*/
-		parse: dojo.number.parse,
+		_parser: dojo.number.parse,
+
+		parse: function(/*String*/ value, /*dojo.number.__FormatOptions*/ constraints){
+			// summary:
+			//		Replacable 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)){
+				v = this._parser(value, constraints); // parse w/o editOptions: not technically needed but is nice for the user
+			}
+			return v;
+		},
 
 		_getDisplayedValueAttr: function(){
 			var v = this.inherited(arguments);
@@ -151,10 +160,10 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			//		Otherwise it dispatches to the superclass's filter() method.
 			//
 			//		See `dijit.form.TextBox.filter` for more details.
-			return (value === null || value === '' || value === undefined) ? NaN : this.inherited(arguments); // attr('value', null||''||undefined) should fire onChange(NaN)
+			return (value === null || value === '' || value === undefined) ? NaN : this.inherited(arguments); // set('value', null||''||undefined) should fire onChange(NaN)
 		},
 
-		serialize: function(/*Number*/ value, /*Object?*/options){
+		serialize: function(/*Number*/ value, /*Object?*/ options){
 			// summary:
 			//		Convert value (a Number) into a canonical string (ie, how the number literal is written in javascript/java/C/etc.)
 			// tags:
@@ -162,9 +171,14 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 			return (typeof value != "number" || isNaN(value)) ? '' : this.inherited(arguments);
 		},
 
-		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange, /*String?*/formattedValue){
+		_setBlurValue: function(){
+			var val = dojo.hitch(dojo.mixin({}, this, { _focused: true }), "get")('value'); // parse with editOptions
+			this._setValueAttr(val, true);
+		},
+
+		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
 			// summary:
-			//		Hook so attr('value', ...) works.
+			//		Hook so set('value', ...) works.
 			if(value !== undefined && formattedValue === undefined){
 				formattedValue = String(value);
 				if(typeof value == "number"){
@@ -185,7 +199,7 @@ dojo.declare("dijit.form.NumberTextBoxMixin",
 
 		_getValueAttr: function(){
 			// summary:
-			//		Hook so attr('value') works.
+			//		Hook so get('value') works.
 			//		Returns Number, NaN for '', or undefined for unparsable text
 			var v = this.inherited(arguments); // returns Number for all values accepted by parse() or NaN for all other displayed values
 
@@ -244,5 +258,11 @@ dojo.declare("dijit.form.NumberTextBox",
 		//				but reappears after the field is blurred.
 		//			4. Formatting and constraints regarding the number of places (digits after the decimal point)
 		//				allowed on input, and number of places displayed when blurred (see `constraints` parameter).
+
+		baseClass: "dijitTextBox dijitNumberTextBox"
 	}
 );
+
+
+return dijit.form.NumberTextBox;
+});
diff --git a/dijit/form/RadioButton.js b/dijit/form/RadioButton.js
index ad1e033..0eedc17 100644
--- a/dijit/form/RadioButton.js
+++ b/dijit/form/RadioButton.js
@@ -1,4 +1,7 @@
-dojo.provide("dijit.form.RadioButton");
-dojo.require("dijit.form.CheckBox");
+define("dijit/form/RadioButton", ["dojo", "dijit", "dijit/form/CheckBox"], function(dojo, dijit) {
 
 // TODO: for 2.0, move the RadioButton code into this file
+
+
+return dijit.form.RadioButton;
+});
diff --git a/dijit/form/RangeBoundTextBox.js b/dijit/form/RangeBoundTextBox.js
index e0667f7..e27de43 100644
--- a/dijit/form/RangeBoundTextBox.js
+++ b/dijit/form/RangeBoundTextBox.js
@@ -1,2 +1,6 @@
-dojo.provide("dijit.form.RangeBoundTextBox");
-dojo.require("dijit.form.ValidationTextBox");
+define("dijit/form/RangeBoundTextBox", ["dojo", "dijit", "dijit/form/ValidationTextBox"], function(dojo, dijit) {
+
+
+
+return dijit.form.RangeBoundTextBox;
+});
diff --git a/dijit/form/Select.js b/dijit/form/Select.js
index b2b2e22..38e8884 100644
--- a/dijit/form/Select.js
+++ b/dijit/form/Select.js
@@ -1,11 +1,4 @@
-dojo.provide("dijit.form.Select");
-
-dojo.require("dijit.form._FormSelectWidget");
-dojo.require("dijit._HasDropDown");
-dojo.require("dijit.Menu");
-dojo.require("dijit.Tooltip");
-
-dojo.requireLocalization("dijit.form", "validate");
+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, {
 	// summary:
@@ -27,6 +20,16 @@ dojo.declare("dijit.form._SelectMenu", dijit.Menu, {
 		dijit.setWaiRole(n,"presentation");
 		n.appendChild(o);
 	},
+
+	postCreate: function(){
+		// summary:
+		//              stop mousemove from selecting text on IE to be consistent with other browsers
+
+		this.inherited(arguments);
+
+		this.connect(this.domNode, "onmousemove", dojo.stopEvent);
+	},
+
 	resize: function(/*Object*/ mb){
 		// summary:
 		//		Overridden so that we are able to handle resizing our
@@ -69,13 +72,17 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 	//		Shows current state (ie, validation result) of input (Normal, Warning, or Error)
 	state: "",
 
+	// message: String
+	//		Currently displayed error/prompt message
+	message: "",
+
 	//	tooltipPosition: String[]
 	//		See description of dijit.Tooltip.defaultPosition for details on this parameter.
 	tooltipPosition: [],
 
 	// emptyLabel: string
 	//		What to display in an "empty" dropdown
-	emptyLabel: "",
+	emptyLabel: " ",
 
 	// _isLoaded: Boolean
 	//		Whether or not we have been loaded
@@ -89,11 +96,11 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		// 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;
-			this.value = this.options[si != -1 ? si : 0].value;
+			var si = this.srcNodeRef.selectedIndex || 0; // || 0 needed for when srcNodeRef is not a SELECT
+			this.value = this.options[si >= 0 ? si : 0].value;
 		}
-
 		// Create the dropDown widget
 		this.dropDown = new dijit.form._SelectMenu({id: this.id + "_menu"});
 		dojo.addClass(this.dropDown.domNode, this.baseClass + "Menu");
@@ -103,7 +110,7 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		// summary:
 		//		For the given option, return the menu item that should be
 		//		used to display it.  This can be overridden as needed
-		if(!option.value){
+		if(!option.value && !option.label){
 			// We are a separator (no label set for it)
 			return new dijit.MenuSeparator();
 		}else{
@@ -111,7 +118,7 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 			var click = dojo.hitch(this, "_setValueAttr", option);
 			var item = new dijit.MenuItem({
 				option: option,
-				label: option.label,
+				label: option.label || this.emptyLabel,
 				onClick: click,
 				disabled: option.disabled || false
 			});
@@ -165,7 +172,6 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 			this._updateSelection();
 		}
 
-		var len = this.options.length;
 		this._isLoaded = false;
 		this._childrenLoaded = true;
 
@@ -183,10 +189,9 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 	_setDisplay: function(/*String*/ newDisplay){
 		// summary:
 		//		sets the display for the given value (or values)
-		this.containerNode.innerHTML = '<span class="dijitReset dijitInline ' + this.baseClass + 'Label">' +
-					(newDisplay || this.emptyLabel || " ") +
-					'</span>';
-		dijit.setWaiState(this.focusNode, "valuetext", (newDisplay || this.emptyLabel || " ") );
+		var lbl = newDisplay || this.emptyLabel;
+		this.containerNode.innerHTML = '<span class="dijitReset dijitInline ' + this.baseClass + 'Label">' + lbl + '</span>';
+		dijit.setWaiState(this.focusNode, "valuetext", lbl);
 	},
 
 	validate: function(/*Boolean*/ isFocused){
@@ -198,12 +203,11 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		//		set the value.
 		
 		var isValid = this.isValid(isFocused);
-		this.state = isValid ? "" : "Error";
-		this._setStateClass();
+		this._set("state", isValid ? "" : "Error");
 		dijit.setWaiState(this.focusNode, "invalid", isValid ? "false" : "true");
 		var message = isValid ? "" : this._missingMsg;
-		if(this._message !== message){
-			this._message = message;
+		if(this.message !== message){
+			this._set("message", message);
 			dijit.hideTooltip(this.domNode);
 			if(message){
 				dijit.showTooltip(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
@@ -214,9 +218,9 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 
 	isValid: function(/*Boolean*/ isFocused){
 		// summary:
-		//		Whether or not this is a valid value.   The only way a Select
+		//		Whether or not this is a valid value.  The only way a Select
 		//		can be invalid is when it's required but nothing is selected.
-		return (!this.required || !(/^\s*$/.test(this.value)));
+		return (!this.required || this.value === 0 || !(/^\s*$/.test(this.value || ""))); // handle value is null or undefined
 	},
 
 	reset: function(){
@@ -224,9 +228,8 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		//		Overridden so that the state will be cleared.
 		this.inherited(arguments);
 		dijit.hideTooltip(this.domNode);
-		this.state = "";
-		this._setStateClass();
-		delete this._message;
+		this._set("state", "");
+		this._set("message", "")
 	},
 
 	postMixInProperties: function(){
@@ -238,10 +241,17 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 	},
 
 	postCreate: function(){
+		// summary:
+		//		stop mousemove from selecting text on IE to be consistent with other browsers
+
 		this.inherited(arguments);
-		if(this.tableNode.style.width){
-			dojo.addClass(this.domNode, this.baseClass + "FixedWidth");
-		}
+
+		this.connect(this.domNode, "onmousemove", dojo.stopEvent);
+	},
+
+	_setStyleAttr: function(/*String||Object*/ value){
+		this.inherited(arguments);
+		dojo.toggleClass(this.domNode, this.baseClass + "FixedWidth", !!this.tableNode.style.width);
 	},
 
 	isLoaded: function(){
@@ -276,3 +286,7 @@ dojo.declare("dijit.form.Select", [dijit.form._FormSelectWidget, dijit._HasDropD
 		this.inherited(arguments);
 	}
 });
+
+
+return dijit.form.Select;
+});
diff --git a/dijit/form/SimpleTextarea.js b/dijit/form/SimpleTextarea.js
index abcdcaf..bec0449 100644
--- a/dijit/form/SimpleTextarea.js
+++ b/dijit/form/SimpleTextarea.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.SimpleTextarea");
-
-dojo.require("dijit.form.TextBox");
+define("dijit/form/SimpleTextarea", ["dojo", "dijit", "dijit/form/TextBox"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.SimpleTextarea",
 	dijit.form.TextBox,
@@ -34,12 +32,20 @@ dojo.declare("dijit.form.SimpleTextarea",
 
 	postMixInProperties: function(){
 		// Copy value from srcNodeRef, unless user specified a value explicitly (or there is no srcNodeRef)
+		// TODO: parser will handle this in 2.0
 		if(!this.value && this.srcNodeRef){
 			this.value = this.srcNodeRef.value;
 		}
 		this.inherited(arguments);
 	},
 
+	buildRendering: function(){
+		this.inherited(arguments);
+		if(dojo.isIE && this.cols){ // attribute selectors is not supported in IE6
+			dojo.addClass(this.textbox, "dijitTextAreaCols");
+		}
+	},
+
 	filter: function(/*String*/ value){
 		// Override TextBox.filter to deal with newlines... specifically (IIRC) this is for IE which writes newlines
 		// as \r\n instead of just \n
@@ -49,13 +55,6 @@ dojo.declare("dijit.form.SimpleTextarea",
 		return this.inherited(arguments);
 	},
 
-	postCreate: function(){
-		this.inherited(arguments);
-		if(dojo.isIE && this.cols){ // attribute selectors is not supported in IE6
-			dojo.addClass(this.textbox, "dijitTextAreaCols");
-		}
-	},
-
 	_previousValue: "",
 	_onInput: function(/*Event?*/ e){
 		// Override TextBox._onInput() to enforce maxLength restriction
@@ -89,3 +88,7 @@ dojo.declare("dijit.form.SimpleTextarea",
 		this.inherited(arguments);
 	}
 });
+
+
+return dijit.form.SimpleTextarea;
+});
diff --git a/dijit/form/Slider.js b/dijit/form/Slider.js
index 090b7d8..57522c2 100644
--- a/dijit/form/Slider.js
+++ b/dijit/form/Slider.js
@@ -1,12 +1,9 @@
-dojo.provide("dijit.form.Slider");
+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) {
 
 dojo.deprecated("Call require() for HorizontalSlider / VerticalRule, explicitly rather than 'dijit.form.Slider' itself", "", "2.0");
 
 // For back-compat, remove for 2.0
-dojo.require("dijit.form.HorizontalSlider");
-dojo.require("dijit.form.VerticalSlider");
-dojo.require("dijit.form.HorizontalRule");
-dojo.require("dijit.form.VerticalRule");
-dojo.require("dijit.form.HorizontalRuleLabels");
-dojo.require("dijit.form.VerticalRuleLabels");
 
+
+return dijit.form.Slider;
+});
diff --git a/dijit/form/TextBox.js b/dijit/form/TextBox.js
index bd2fe3f..ed26dfa 100644
--- a/dijit/form/TextBox.js
+++ b/dijit/form/TextBox.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.TextBox");
-
-dojo.require("dijit.form._FormWidget");
+define("dijit/form/TextBox", ["dojo", "dijit", "text!dijit/form/templates/TextBox.html", "dijit/form/_FormWidget"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form.TextBox",
@@ -25,15 +23,15 @@ dojo.declare(
 		//		Converts the first character of each word to uppercase if true.
 		propercase: false,
 
-		//	maxLength: String
+		// maxLength: String
 		//		HTML INPUT tag maxLength declaration.
 		maxLength: "",
 
-		//	selectOnClick: [const] Boolean
+		// selectOnClick: [const] Boolean
 		//		If true, all text will be selected when focused with mouse
 		selectOnClick: false,
 
-		//	placeHolder: String
+		// 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: "",
@@ -51,14 +49,14 @@ dojo.declare(
 		
 		postMixInProperties: function(){
 			var type = this.type.toLowerCase();
-			if(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 == dijit.form.TextBox.prototype.templateString)){
 				this.templateString = this._singleNodeTemplate;
 			}
 			this.inherited(arguments);
 		},
 
 		_setPlaceHolderAttr: function(v){
-			this.placeHolder = v;
+			this._set("placeHolder", v);
 			if(!this._phspan){
 				this._attachPoints.push('_phspan');
 				/* dijitInputField class gives placeHolder same padding as the input field
@@ -81,7 +79,7 @@ dojo.declare(
 
 		_getValueAttr: function(){
 			// summary:
-			//		Hook so attr('value') works as we like.
+			//		Hook so get('value') works as we like.
 			// description:
 			//		For `dijit.form.TextBox` this basically returns the value of the <input>.
 			//
@@ -94,7 +92,7 @@ dojo.declare(
 
 		_setValueAttr: function(value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
 			// summary:
-			//		Hook so attr('value', ...) works.
+			//		Hook so set('value', ...) works.
 			//
 			// description:
 			//		Sets the value of the widget to "value" which can be of
@@ -125,6 +123,7 @@ dojo.declare(
 			}
 			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._updatePlaceHolder();
@@ -137,7 +136,7 @@ dojo.declare(
 		//		(ex: Kentucky) and the serialized value (ex: KY) are different,
 		//		this represents the displayed value.
 		//
-		//		Setting 'displayedValue' through attr('displayedValue', ...)
+		//		Setting 'displayedValue' through set('displayedValue', ...)
 		//		updates 'value', and vice-versa.  Otherwise 'value' is updated
 		//		from 'displayedValue' periodically, like onBlur etc.
 		//
@@ -148,7 +147,7 @@ dojo.declare(
 
 		getDisplayedValue: function(){
 			// summary:
-			//		Deprecated.   Use set('displayedValue') instead.
+			//		Deprecated.  Use get('displayedValue') instead.
 			// tags:
 			//		deprecated
 			dojo.deprecated(this.declaredClass+"::getDisplayedValue() is deprecated. Use set('displayedValue') instead.", "", "2.0");
@@ -157,7 +156,7 @@ dojo.declare(
 
 		_getDisplayedValueAttr: function(){
 			// summary:
-			//		Hook so attr('displayedValue') works.
+			//		Hook so get('displayedValue') works.
 			// description:
 			//		Returns the displayed value (what the user sees on the screen),
 			// 		after filtering (ie, trimming spaces etc.).
@@ -166,21 +165,24 @@ dojo.declare(
 			//		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){
+		setDisplayedValue: function(/*String*/ value){
 			// summary:
-			//		Deprecated.   Use set('displayedValue', ...) instead.
+			//		Deprecated.  Use set('displayedValue', ...) instead.
 			// tags:
 			//		deprecated
 			dojo.deprecated(this.declaredClass+"::setDisplayedValue() is deprecated. Use set('displayedValue', ...) instead.", "", "2.0");
 			this.set('displayedValue', value);
 		},
 
-		_setDisplayedValueAttr: function(/*String*/value){
+		_setDisplayedValueAttr: function(/*String*/ value){
 			// summary:
-			//		Hook so attr('displayedValue', ...) works.
+			//		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,
@@ -188,11 +190,18 @@ dojo.declare(
 
 			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);
+
+			// 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){
+		format: function(/*String*/ value, /*Object*/ constraints){
 			// summary:
 			//		Replacable function to convert a value to a properly formatted string.
 			// tags:
@@ -200,7 +209,7 @@ dojo.declare(
 			return ((value == null || value == undefined) ? "" : (value.toString ? value.toString() : value));
 		},
 
-		parse: function(/* String */ value, /* Object */ constraints){
+		parse: function(/*String*/ value, /*Object*/ constraints){
 			// summary:
 			//		Replacable function to convert a formatted string to a value
 			// tags:
@@ -234,12 +243,15 @@ dojo.declare(
 				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(){
-			// 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
 			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;
@@ -252,16 +264,22 @@ dojo.declare(
 						}
 					}
 				}
+				}), 0);
 			}
-			this.textbox.setAttribute("value", this.textbox.value); // DOM and JS values shuld be the same
+
+			// 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", this._onInput);
+				this.connect(this.textbox, "oninput", "_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);
+				this.connect(this.textbox, "onkeydown", "_onInput");
+				this.connect(this.textbox, "onkeyup", "_onInput");
+				this.connect(this.textbox, "onpaste", "_onInput");
+				this.connect(this.textbox, "oncut", "_onInput");
 			}
 		},
 
@@ -273,8 +291,8 @@ dojo.declare(
 			// 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.
+			//			- 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()
@@ -352,8 +370,11 @@ dojo.declare(
 
 			this._updatePlaceHolder();
 			
-			this._refreshState();
+			// 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(){
@@ -365,7 +386,7 @@ dojo.declare(
 	}
 );
 
-dijit.selectInputText = function(/*DomNode*/element, /*Number?*/ start, /*Number?*/ stop){
+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).
 
@@ -378,14 +399,12 @@ dijit.selectInputText = function(/*DomNode*/element, /*Number?*/ start, /*Number
 	dijit.focus(element);
 	if(_document["selection"] && dojo.body()["createTextRange"]){ // IE
 		if(element.createTextRange){
-			var range = element.createTextRange();
-			with(range){
-				collapse(true);
-				moveStart("character", -99999); // move to 0
-				moveStart("character", start); // delta from 0 is the correct position
-				moveEnd("character", stop-start);
-				select();
-			}
+			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){
@@ -393,3 +412,7 @@ dijit.selectInputText = function(/*DomNode*/element, /*Number?*/ start, /*Number
 		}
 	}
 };
+
+
+return dijit.form.TextBox;
+});
diff --git a/dijit/form/Textarea.js b/dijit/form/Textarea.js
index 172f206..37a61e1 100644
--- a/dijit/form/Textarea.js
+++ b/dijit/form/Textarea.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.Textarea");
-
-dojo.require("dijit.form.SimpleTextarea");
+define("dijit/form/Textarea", ["dojo", "dijit", "dijit/form/SimpleTextarea"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form.Textarea",
@@ -20,6 +18,10 @@ dojo.declare(
 	// |	<textarea dojoType="dijit.form.TextArea">...</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: "",
 
@@ -32,9 +34,9 @@ dojo.declare(
 			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 && !(dojo.isSafari < 4)){ // Safari 4.0 && Chrome
+		}else if(dojo.isWebKit){
 			newH += dojo._getBorderExtents(textarea).h;
-		}else{ // Safari 3.x and Opera 9.6
+		}else{ // Opera 9.6 (TODO: test if this is still needed)
 			newH += dojo._getPadBorderExtents(textarea).h;
 		}
 		return newH;
@@ -127,13 +129,19 @@ dojo.declare(
 		this.resize();
 	},
 
-	postCreate: function(){
+	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' });
-		this.connect(this.textbox, "onscroll", this._onInput);
-		this.connect(this.textbox, "onresize", this._onInput);
-		this.connect(this.textbox, "onfocus", this._onInput); // useful when a previous estimate was off a bit
+	},
+
+	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);
 	},
 
@@ -144,3 +152,7 @@ dojo.declare(
 		this.inherited(arguments);
 	}
 });
+
+
+return dijit.form.Textarea;
+});
diff --git a/dijit/form/TimeTextBox.js b/dijit/form/TimeTextBox.js
index 8f9d807..35a4711 100644
--- a/dijit/form/TimeTextBox.js
+++ b/dijit/form/TimeTextBox.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form.TimeTextBox");
-
-dojo.require("dijit._TimePicker");
-dojo.require("dijit.form._DateTimeTextBox");
+define("dijit/form/TimeTextBox", ["dojo", "dijit", "dijit/_TimePicker", "dijit/form/_DateTimeTextBox"], function(dojo, dijit) {
 
 /*=====
 dojo.declare(
@@ -17,7 +14,7 @@ dojo.declare(
 		// summary:
 		//		A validating, serializable, range-bound time text box with a drop down time picker
 
-		baseClass: "dijitTextBox dijitTimeTextBox",
+		baseClass: "dijitTextBox dijitComboBox dijitTimeTextBox",
 		popupClass: "dijit._TimePicker",
 		_selector: "time",
 
@@ -37,7 +34,43 @@ dojo.declare(
 		//
 		//		Example:
 		// |	<input dojotype='dijit.form.TimeTextBox' value='T12:34:00'>
-		value: new Date("")		// value.toString()="NaN"
+		value: new Date(""),		// value.toString()="NaN"
 		//FIXME: in markup, you have no control over daylight savings
+
+		_onKey: function(evt){
+			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:
+					// 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(){
+						// 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>
+						if(this._opened){
+							this.closeDropDown();
+						}
+						this.openDropDown();
+					}), 0);
+			}
+		}
 	}
 );
+
+return dijit.form.TimeTextBox;
+});
\ No newline at end of file
diff --git a/dijit/form/ToggleButton.js b/dijit/form/ToggleButton.js
index c687449..45400fa 100644
--- a/dijit/form/ToggleButton.js
+++ b/dijit/form/ToggleButton.js
@@ -1,2 +1,6 @@
-dojo.provide("dijit.form.ToggleButton");
-dojo.require("dijit.form.Button");
+define("dijit/form/ToggleButton", ["dojo", "dijit", "dijit/form/Button"], function(dojo, dijit) {
+
+
+
+return dijit.form.ToggleButton;
+});
diff --git a/dijit/form/ValidationTextBox.js b/dijit/form/ValidationTextBox.js
index d4f60de..e00a9a6 100644
--- a/dijit/form/ValidationTextBox.js
+++ b/dijit/form/ValidationTextBox.js
@@ -1,11 +1,4 @@
-dojo.provide("dijit.form.ValidationTextBox");
-
-dojo.require("dojo.i18n");
-
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.Tooltip");
-
-dojo.requireLocalization("dijit.form", "validate");
+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) {
 
 /*=====
 	dijit.form.ValidationTextBox.__Constraints = function(){
@@ -36,6 +29,7 @@ dojo.declare(
 
 		// promptMessage: String
 		//		If defined, display this hint string immediately on focus to the textbox, if empty.
+		//		Also displays if the textbox value is Incomplete (not yet valid but will be with additional input).
 		//		Think of this like a tooltip that tells the user what to do, not an error message
 		//		that tells the user what they've done wrong.
 		//
@@ -54,6 +48,12 @@ dojo.declare(
 		// 		Set to "" to use the invalidMessage instead.
 		missingMessage: "$_unset_$",
 
+		// message: String
+		//		Currently error/prompt message.
+		//		When using the default tooltip implementation, this will only be
+		//		displayed when the field is focused.
+		message: "",
+
 		// constraints: dijit.form.ValidationTextBox.__Constraints
 		//		user-defined object needed to pass parameters to the validator functions
 		constraints: {},
@@ -63,7 +63,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.
@@ -73,7 +73,7 @@ dojo.declare(
 		},
 
 		// state: [readonly] String
-		//		Shows current state (ie, validation result) of input (Normal, Warning, or Error)
+		//		Shows current state (ie, validation result) of input (""=Normal, Incomplete, or Error)
 		state: "",
 
 		// tooltipPosition: String[]
@@ -82,12 +82,12 @@ dojo.declare(
 
 		_setValueAttr: function(){
 			// summary:
-			//		Hook so attr('value', ...) works.
+			//		Hook so set('value', ...) works.
 			this.inherited(arguments);
 			this.validate(this._focused);
 		},
 
-		validator: function(/*anything*/value, /*dijit.form.ValidationTextBox.__Constraints*/constraints){
+		validator: function(/*anything*/ value, /*dijit.form.ValidationTextBox.__Constraints*/ constraints){
 			// summary:
 			//		Overridable function used to validate the text input against the regular expression.
 			// tags:
@@ -116,7 +116,7 @@ dojo.declare(
 		_isEmpty: function(value){
 			// summary:
 			//		Checks for whitespace
-			return /^\s*$/.test(value); // Boolean
+			return (this.trim ? /^\s*$/ : /^$/).test(value); // Boolean
 		},
 
 		getErrorMessage: function(/*Boolean*/ isFocused){
@@ -147,37 +147,32 @@ dojo.declare(
 			var isValid = this.disabled || this.isValid(isFocused);
 			if(isValid){ this._maskValidSubsetError = true; }
 			var isEmpty = this._isEmpty(this.textbox.value);
-			var isValidSubset = !isValid && !isEmpty && isFocused && this._isValidSubset();
-			this.state = ((isValid || ((!this._hasBeenBlurred || isFocused) && isEmpty) || isValidSubset) && this._maskValidSubsetError) ? "" : "Error";
-			if(this.state == "Error"){ this._maskValidSubsetError = isFocused; } // we want the error to show up afer a blur and refocus
-			this._setStateClass();
+			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");
-			if(isFocused){
-				if(this.state == "Error"){
-					message = this.getErrorMessage(true);
-				}else{
-					message = this.getPromptMessage(true); // show the prompt whever there's no error
-				}
-				this._maskValidSubsetError = true; // since we're focused, always mask warnings
+
+			if(this.state == "Error"){
+				this._maskValidSubsetError = isFocused && isValidSubset; // we want the error to show up after a blur and refocus
+				message = this.getErrorMessage(isFocused);
+			}else if(this.state == "Incomplete"){
+				message = this.getPromptMessage(isFocused); // show the prompt whenever the value is not yet complete
+				this._maskValidSubsetError = !this._hasBeenBlurred || isFocused; // no Incomplete warnings while focused
+			}else if(isEmpty){
+				message = this.getPromptMessage(isFocused); // show the prompt whenever there's no error and no text
 			}
-			this.displayMessage(message);
+			this.set("message", message);
+
 			return isValid;
 		},
 
-		// _message: String
-		//		Currently displayed message
-		_message: "",
-
 		displayMessage: function(/*String*/ message){
 			// summary:
 			//		Overridable method to display validation errors/hints.
 			//		By default uses a tooltip.
 			// tags:
 			//		extension
-			if(this._message == message){ return; }
-			this._message = message;
 			dijit.hideTooltip(this.domNode);
-			if(message){
+			if(message && this._focused){
 				dijit.showTooltip(message, this.domNode, this.tooltipPosition, !this.isLeftToRight());
 			}
 		},
@@ -194,11 +189,11 @@ dojo.declare(
 			this.constraints = {};
 		},
 
-		_setConstraintsAttr: function(/* Object */ constraints){
+		_setConstraintsAttr: function(/*Object*/ constraints){
 			if(!constraints.locale && this.lang){
 				constraints.locale = this.lang;
 			}
-			this.constraints = constraints;
+			this._set("constraints", constraints);
 			this._computePartialRE();
 		},
 
@@ -255,11 +250,16 @@ dojo.declare(
 		},
 
 		_setRequiredAttr: function(/*Boolean*/ value){
-			this.required = value;
+			this._set("required", value);
 			dijit.setWaiState(this.focusNode, "required", value);
 			this._refreshState();
 		},
 
+		_setMessageAttr: function(/*String*/ message){
+			this._set("message", message);
+			this.displayMessage(message);
+		},
+
 		reset:function(){
 			// Overrides dijit.form.TextBox.reset() by also
 			// hiding errors about partial matches
@@ -268,7 +268,10 @@ dojo.declare(
 		},
 
 		_onBlur: function(){
+			// the message still exists but for back-compat, and to erase the tooltip
+			// (if the message is being displayed as a tooltip), call displayMessage('')
 			this.displayMessage('');
+
 			this.inherited(arguments);
 		}
 	}
@@ -299,9 +302,9 @@ dojo.declare(
 			this.nameAttrSetting = "";
 		},
 
-		serialize: function(/*anything*/val, /*Object?*/options){
+		serialize: function(/*anything*/ val, /*Object?*/ options){
 			// summary:
-			//		Overridable function used to convert the attr('value') result to a canonical
+			//		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:
@@ -333,10 +336,10 @@ dojo.declare(
 			// (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 + "'" : "") + ">", this.textbox, "after");
+			this.valueNode = dojo.place("<input type='hidden'" + (this.name ? " name='" + this.name.replace(/'/g, """) + "'" : "") + "/>", this.textbox, "after");
 		},
 
-		reset:function(){
+		reset: function(){
 			// Overrides `dijit.form.ValidationTextBox.reset` to
 			// reset the hidden textbox value to ''
 			this.valueNode.value = '';
@@ -440,7 +443,7 @@ dojo.declare(
 			}
 		},
 
-		_setConstraintsAttr: function(/* Object */ constraints){
+		_setConstraintsAttr: function(/*Object*/ constraints){
 			this.inherited(arguments);
 			if(this.focusNode){ // not set when called from postMixInProperties
 				if(this.constraints.min !== undefined){
@@ -458,10 +461,14 @@ dojo.declare(
 
 		_setValueAttr: function(/*Number*/ value, /*Boolean?*/ priorityChange){
 			// summary:
-			//		Hook so attr('value', ...) works.
+			//		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 2173220..e51c6b5 100644
--- a/dijit/form/VerticalRule.js
+++ b/dijit/form/VerticalRule.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.VerticalRule");
-
-dojo.require("dijit.form.HorizontalRule");
+define("dijit/form/VerticalRule", ["dojo", "dijit", "dijit/form/HorizontalRule"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
 {
@@ -23,3 +21,6 @@ dojo.declare("dijit.form.VerticalRule", dijit.form.HorizontalRule,
 
 });
 
+
+return dijit.form.VerticalRule;
+});
diff --git a/dijit/form/VerticalRuleLabels.js b/dijit/form/VerticalRuleLabels.js
index d74bf65..4dbbb30 100644
--- a/dijit/form/VerticalRuleLabels.js
+++ b/dijit/form/VerticalRuleLabels.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.VerticalRuleLabels");
-
-dojo.require("dijit.form.HorizontalRuleLabels");
+define("dijit/form/VerticalRuleLabels", ["dojo", "dijit", "dijit/form/HorizontalRuleLabels"], function(dojo, dijit) {
 
 dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
 {
@@ -19,4 +17,8 @@ dojo.declare("dijit.form.VerticalRuleLabels", dijit.form.HorizontalRuleLabels,
 
 	// needed to prevent labels from being reversed in RTL mode
 	_isHorizontal: false
-});
\ No newline at end of file
+});
+
+
+return dijit.form.VerticalRuleLabels;
+});
diff --git a/dijit/form/VerticalSlider.js b/dijit/form/VerticalSlider.js
index 517f702..3b526b1 100644
--- a/dijit/form/VerticalSlider.js
+++ b/dijit/form/VerticalSlider.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form.VerticalSlider");
-
-dojo.require("dijit.form.HorizontalSlider");
+define("dijit/form/VerticalSlider", ["dojo", "dijit", "text!dijit/form/templates/VerticalSlider.html", "dijit/form/HorizontalSlider"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form.VerticalSlider",
@@ -18,8 +16,8 @@ dojo.declare(
 	_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
+	//		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(){
@@ -30,3 +28,6 @@ dojo.declare(
 	}
 });
 
+
+return dijit.form.VerticalSlider;
+});
diff --git a/dijit/form/_DateTimeTextBox.js b/dijit/form/_DateTimeTextBox.js
index eb81515..406549b 100644
--- a/dijit/form/_DateTimeTextBox.js
+++ b/dijit/form/_DateTimeTextBox.js
@@ -1,9 +1,4 @@
-dojo.provide("dijit.form._DateTimeTextBox");
-
-dojo.require("dojo.date");
-dojo.require("dojo.date.locale");
-dojo.require("dojo.date.stamp");
-dojo.require("dijit.form.ValidationTextBox");
+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
 
@@ -22,17 +17,27 @@ dojo.declare(
 
 dojo.declare(
 	"dijit.form._DateTimeTextBox",
-	dijit.form.RangeBoundTextBox,
+	[ dijit.form.RangeBoundTextBox, dijit._HasDropDown ],
 	{
 		// summary:
 		//		Base class for validating, serializable, range-bound date or time text box.
 
+		templateString: dojo.cache("dijit.form", "templates/DropDownBox.html"),
+
+		// hasDownArrow: [const] Boolean
+		//		Set this textbox to display a down arrow button, to open the drop down list.
+		hasDownArrow: true,
+
+		// openOnClick: [const] Boolean
+		//		Set to true to open drop down upon clicking anywhere on the textbox.
+		openOnClick: true,
+
+		/*=====
 		// constraints: dijit.form._DateTimeTextBox.__Constraints
 		//		Despite the name, this parameter specifies both constraints on the input
 		//		(including starting/ending dates/times allowed) as well as
 		//		formatting options like whether the date is displayed in long (ex: December 25, 2005)
-		//		or short (ex: 12/25/2005) format.   See `dijit.form._DateTimeTextBox.__Constraints` for details.
-		/*=====
+		//		or short (ex: 12/25/2005) format.  See `dijit.form._DateTimeTextBox.__Constraints` for details.
 		constraints: {},
 		======*/
 
@@ -41,12 +46,19 @@ dojo.declare(
 		regExpGen: dojo.date.locale.regexp,
 
 		// datePackage: String
-		//	JavaScript namespace to find calendar routines.  Uses Gregorian calendar routines
-		//	at dojo.date, by default.
+		//		JavaScript namespace to find calendar routines.	 Uses Gregorian calendar routines
+		//		at dojo.date, by default.
 		datePackage: "dojo.date",
 
 		// Override _FormWidget.compare() to work for dates/times
-		compare: dojo.date.compare,
+		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));
+		},
+
+		// flag to _HasDropDown to make drop down Calendar width == <input> width
+		forceWidth: true,
 
 		format: function(/*Date*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
 			// summary:
@@ -57,7 +69,7 @@ dojo.declare(
 			return this.dateLocaleModule.format(value, constraints);
 		},
 
-		parse: function(/*String*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
+		"parse": function(/*String*/ value, /*dojo.date.locale.__FormatOptions*/ constraints){
 			// summary:
 			//		Parses as string as a Date, according to constraints
 			// tags:
@@ -67,20 +79,25 @@ dojo.declare(
 		},
 
 		// Overrides ValidationTextBox.serialize() to serialize a date in canonical ISO format.
-		serialize: function(/*anything*/val, /*Object?*/options){
+		serialize: function(/*anything*/ val, /*Object?*/ options){
 			if(val.toGregorian){
 				val = val.toGregorian();
 			}
 			return dojo.date.stamp.toISOString(val, options);
 		},
 
+		// dropDownDefaultValue: Date
+		//		The default value to focus in the popupClass widget when the textbox value is empty.
+		dropDownDefaultValue : new Date(),
+
 		// value: Date
 		//		The value of this widget as a JavaScript Date object.  Use get("value") / set("value", val) to manipulate.
 		//		When passed to the parser in markup, must be specified according to `dojo.date.stamp.fromISOString`
 		value: new Date(""),	// value.toString()="NaN"
+
 		_blankValue: null,	// used by filter() when the textbox is blank
 
-		//	popupClass: [protected extension] String
+		// popupClass: [protected extension] String
 		//		Name of the popup widget class used to select a date/time.
 		//		Subclasses should specify this.
 		popupClass: "", // default is no popup = text only
@@ -92,7 +109,7 @@ dojo.declare(
 		//		Subclass must specify this.
 		_selector: "",
 
-		constructor: function(/*Object*/args){
+		constructor: function(/*Object*/ args){
 			var dateClass = args.datePackage ? args.datePackage + ".Date" : "Date";
 			this.dateClassObj = dojo.getObject(dateClass, false);
 			this.value = new this.dateClassObj("");
@@ -100,120 +117,109 @@ dojo.declare(
 			this.datePackage = args.datePackage || this.datePackage;
 			this.dateLocaleModule = dojo.getObject(this.datePackage + ".locale", false);
 			this.regExpGen = this.dateLocaleModule.regexp;
+			this._invalidDate = dijit.form._DateTimeTextBox.prototype.value.toString();
 		},
 
-		_setConstraintsAttr: function(/* Object */ constraints){
+		buildRendering: function(){
+			this.inherited(arguments);
+
+			if(!this.hasDownArrow){
+				this._buttonNode.style.display = "none";
+			}
+
+			// If openOnClick is true, we basically just want to treat the whole widget as the
+			// button.  We need to do that also if the actual drop down button will be hidden,
+			// so that there's a mouse method for opening the drop down.
+			if(this.openOnClick || !this.hasDownArrow){
+				this._buttonNode = this.domNode;
+				this.baseClass += " dijitComboBoxOpenOnClick";
+			}
+		},
+
+		_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;
 			if(typeof constraints.min == "string"){ constraints.min = fromISO(constraints.min); }
  			if(typeof constraints.max == "string"){ constraints.max = fromISO(constraints.max); }
-			this.inherited(arguments, [constraints]);
+			this.inherited(arguments);
 		},
 
-		_onFocus: function(/*Event*/ evt){
+		_isInvalidDate: function(/*Date*/ value){
 			// summary:
-			//		open the popup
-			this._open();
-			this.inherited(arguments);
+			//		Runs various tests on the value, checking for invalid conditions
+			// tags:
+			//		private
+			return !value || isNaN(value) || typeof value != "object" || value.toString() == this._invalidDate;
 		},
 
-		_setValueAttr: function(/*Date*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
+		_setValueAttr: function(/*Date|String*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
 			// summary:
-			//		Sets the date on this textbox.  Note that `value` must be like a Javascript Date object.
+			//		Sets the date on this textbox. Note: value can be a JavaScript Date literal or a string to be parsed.
 			if(value !== undefined){
-				if(!value || value.toString() == dijit.form._DateTimeTextBox.prototype.value.toString()){
+				if(typeof value == "string"){
+					value = dojo.date.stamp.fromISOString(value);
+				}
+				if(this._isInvalidDate(value)){
 					value = null;
 				}
 				if(value instanceof Date && !(this.dateClassObj instanceof Date)){
 					value = new this.dateClassObj(value);
 				}
 			}
-			this.inherited(arguments, [value, priorityChange, formattedValue]);
-			if(this._picker){
-				// #3948: fix blank date on popup only
-				if(!value){value = new this.dateClassObj();}
-				this._picker.set('value', value);
+			this.inherited(arguments);
+			if(this.dropDown){
+				this.dropDown.set('value', value, false);
 			}
 		},
 
-		_open: function(){
-			// summary:
-			//		opens the TimePicker, and sets the onValueSelected value
-
-			if(this.disabled || this.readOnly || !this.popupClass){return;}
-
-			var textBox = this;
+		_set: function(attr, value){
+			// Avoid spurious watch() notifications when value is changed to new Date object w/the same value
+			if(attr == "value" && this.value instanceof Date && this.compare(value, this.value) == 0){
+				return;
+			}
+			this.inherited(arguments);
+		},
 
-			if(!this._picker){
-				var PopupProto = dojo.getObject(this.popupClass, false);
-				this._picker = new PopupProto({
-					onValueSelected: function(value){
-						if(textBox._tabbingAway){
-							delete textBox._tabbingAway;
-						}else{
-							textBox.focus(); // focus the textbox before the popup closes to avoid reopening the popup
+		_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()
 						}
-						setTimeout(dojo.hitch(textBox, "_close"), 1); // allow focus time to take
+			this.dropDownDefaultValue = val;
+		},
 
+		openDropDown: function(/*Function*/ callback){
+			// rebuild drop down every time, so that constraints get copied (#6002)
+			if(this.dropDown){
+				this.dropDown.destroy();
+			}
+			var PopupProto = dojo.getObject(this.popupClass, false),
+				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,
-					value: this.get('value') || new this.dateClassObj(),
+				value: value,
+				currentFocus: !this._isInvalidDate(value) ? value : this.dropDownDefaultValue,
 					constraints: textBox.constraints,
+				filterString: textBox.filterString, // for TimeTextBox, to filter times shown
 
 					datePackage: textBox.datePackage,
 
 					isDisabledDate: function(/*Date*/ date){
 						// summary:
 						// 	disables dates outside of the min/max of the _DateTimeTextBox
-						var compare = dojo.date.compare;
-						var constraints = textBox.constraints;
-						return constraints && (
-							(constraints.min && compare(constraints.min, date, textBox._selector) > 0) ||
-							(constraints.max && compare(constraints.max, date, textBox._selector) < 0)
-						);
+						return !textBox.rangeCheck(date, textBox.constraints);
 					}
 				});
-			}
-			if(!this._opened){
-				// Open drop down.  Align left sides of input box and drop down, even in RTL mode,
-				// otherwise positioning thrown off when the drop down width is changed in marginBox call below (#10676)
-				dijit.popup.open({
-					parent: this,
-					popup: this._picker,
-					orient: {'BL':'TL', 'TL':'BL'},
-					around: this.domNode,
-					onCancel: dojo.hitch(this, this._close),
-					onClose: function(){ textBox._opened=false; }
-				});
-				this._opened=true;
-			}
-
-			dojo.marginBox(this._picker.domNode,{ w:this.domNode.offsetWidth });
-		},
-
-		_close: function(){
-			if(this._opened){
-				dijit.popup.close(this._picker);
-				this._opened=false;
-			}
-		},
 
-		_onBlur: function(){
-			// summary:
-			//		Called magically when focus has shifted away from this widget and it's dropdown
-			this._close();
-			if(this._picker){
-				// teardown so that constraints will be rebuilt next time (redundant reference: #6002)
-				this._picker.destroy();
-				delete this._picker;
-			}
 			this.inherited(arguments);
-			// don't focus on <input>.  the user has explicitly focused on something else.
 		},
 
 		_getDisplayedValueAttr: function(){
@@ -222,49 +228,10 @@ dojo.declare(
 
 		_setDisplayedValueAttr: function(/*String*/ value, /*Boolean?*/ priorityChange){
 			this._setValueAttr(this.parse(value, this.constraints), priorityChange, value);
-		},
-
-		destroy: function(){
-			if(this._picker){
-				this._picker.destroy();
-				delete this._picker;
-			}
-			this.inherited(arguments);
-		},
-
-		postCreate: function(){
-			this.inherited(arguments);
-			this.connect(this.focusNode, 'onkeypress', this._onKeyPress);
-			this.connect(this.focusNode, 'onclick', this._open);
-		},
-
-		_onKeyPress: function(/*Event*/ e){
-			// summary:
-			//		Handler for keypress events
-
-			var p = this._picker, dk = dojo.keys;
-			// Handle the key in the picker, if it has a handler.  If the handler
-			// returns false, then don't handle any other keys.
-			if(p && this._opened && p.handleKey){
-				if(p.handleKey(e) === false){ return; }
-			}
-			if(this._opened && e.charOrCode == dk.ESCAPE && !(e.shiftKey || e.ctrlKey || e.altKey || e.metaKey)){
-				this._close();
-				dojo.stopEvent(e);
-			}else if(!this._opened && e.charOrCode == dk.DOWN_ARROW){
-				this._open();
-				dojo.stopEvent(e);
-			}else if(e.charOrCode === dk.TAB){
-				this._tabbingAway = true;
-			}else if(this._opened && (e.keyChar || e.charOrCode === dk.BACKSPACE || e.charOrCode == dk.DELETE)){
-				// Replace the element - but do it after a delay to allow for
-				// filtering to occur
-				setTimeout(dojo.hitch(this, function(){
-					if(this._picker && this._opened){
-						dijit.placeOnScreenAroundElement(p.domNode.parentNode, this.domNode, {'BL':'TL', 'TL':'BL'}, p.orient ? dojo.hitch(p, "orient") : null);
-					}
-				}), 1);
-			}
 		}
 	}
 );
+
+
+return dijit.form._DateTimeTextBox;
+});
diff --git a/dijit/form/_FormMixin.js b/dijit/form/_FormMixin.js
index e2e74c0..a32be2a 100644
--- a/dijit/form/_FormMixin.js
+++ b/dijit/form/_FormMixin.js
@@ -1,9 +1,6 @@
-dojo.provide("dijit.form._FormMixin");
+define("dijit/form/_FormMixin", ["dojo", "dijit", "dojo/window"], function(dojo, dijit) {
 
-dojo.require("dojo.window");
-
-dojo.declare("dijit.form._FormMixin", null,
-	{
+dojo.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)
@@ -14,10 +11,10 @@ dojo.declare("dijit.form._FormMixin", null,
 	//		form widgets
 
 /*=====
-    // value: Object
+	// 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).
@@ -28,6 +25,12 @@ dojo.declare("dijit.form._FormMixin", null,
 	//	|	{ 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
@@ -46,11 +49,11 @@ dojo.declare("dijit.form._FormMixin", null,
 		validate: function(){
 			// summary:
 			//		returns if the form is valid - same as isValid - but
-			//			provides a few additional (ui-specific) features.
-			//			1 - it will highlight any sub-widgets that are not
-			//				valid
-			//			2 - it will call focus() on the first invalid
-			//				sub-widget
+			//		provides a few additional (ui-specific) features.
+			//		1 - it will highlight any sub-widgets that are not
+			//			valid
+			//		2 - it will call focus() on the first invalid
+			//			sub-widget
 			var didFocus = false;
 			return dojo.every(dojo.map(this.getDescendants(), function(widget){
 				// Need to set this so that "required" widgets get their
@@ -71,9 +74,9 @@ dojo.declare("dijit.form._FormMixin", null,
 			dojo.deprecated(this.declaredClass+"::setValues() is deprecated. Use set('value', val) instead.", "", "2.0");
 			return this.set('value', val);
 		},
-		_setValueAttr: function(/*object*/obj){
+		_setValueAttr: function(/*Object*/ obj){
 			// summary:
-			//		Fill in form values from according to an Object (in the format returned by attr('value'))
+			//		Fill in form values from according to an Object (in the format returned by get('value'))
 
 			// generate map from name --> [list of widgets with that name]
 			var map = { };
@@ -151,7 +154,7 @@ dojo.declare("dijit.form._FormMixin", null,
 					return;		// like "continue"
 				}
 
-				// TODO: widget values (just call attr('value', ...) on the widget)
+				// TODO: widget values (just call set('value', ...) on the widget)
 
 				// TODO: maybe should call dojo.getNodeProp() instead
 				switch(element.type){
@@ -183,6 +186,9 @@ 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(){
@@ -191,17 +197,18 @@ dojo.declare("dijit.form._FormMixin", null,
 		},
 		_getValueAttr: function(){
 			// summary:
-			// 		Returns Object representing form values.
+			// 		Returns Object representing form values.   See description of `value` for details.
 			// description:
-			//		Returns name/value hash for each form element.
-			//		If there are multiple elements w/the same name, value is an array,
-			//		unless they are radio buttons in which case value is a scalar since only
-			//		one can be checked at a time.
+
+			// The value is updated into this.value every time a child has an onChange event,
+			// so in the common case this function could just return this.value.   However,
+			// that wouldn't work when:
 			//
-			//		If the name is a dot separated list (like a.b.c.d), creates a nested structure.
-			//		Only works on widget form elements.
-			// example:
-			//		| { name: "John Smith", interests: ["sports", "movies"] }
+			// 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()
+			//
+			// 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 = { };
@@ -209,7 +216,7 @@ dojo.declare("dijit.form._FormMixin", null,
 				var name = widget.name;
 				if(!name || widget.disabled){ return; }
 
-				// Single value widget (checkbox, radio, or plain <input> type widget
+				// Single value widget (checkbox, radio, or plain <input> type widget)
 				var value = widget.get('value');
 
 				// Store widget's value(s) as a scalar, except for checkboxes which are automatically arrays
@@ -312,96 +319,134 @@ dojo.declare("dijit.form._FormMixin", null,
 			return obj;
 		},
 
-		// TODO: ComboBox might need time to process a recently input value.  This should be async?
 	 	isValid: function(){
 	 		// summary:
-	 		//		Returns true if all of the widgets are valid
-
-	 		// This also populate this._invalidWidgets[] array with list of invalid widgets...
-	 		// TODO: put that into separate function?   It's confusing to have that as a side effect
-	 		// of a method named isValid().
+	 		//		Returns true if all of the widgets are valid.
+			//		Deprecated, will be removed in 2.0.  Use get("state") instead.
 
-			this._invalidWidgets = dojo.filter(this.getDescendants(), function(widget){
-				return !widget.disabled && widget.isValid && !widget.isValid();
-	 		});
-			return !this._invalidWidgets.length;
+			return this.state == "";
 		},
 
-
 		onValidStateChange: function(isValid){
 			// summary:
 			//		Stub function to connect to if you want to do something
 			//		(like disable/enable a submit button) when the valid
 			//		state changes on the form as a whole.
+			//
+			//		Deprecated.  Will be removed in 2.0.  Use watch("state", ...) instead.
 		},
 
-		_widgetChange: function(widget){
+		_getState: function(){
 			// summary:
-			//		Connected to a widget's onChange function - update our
-			//		valid state, if needed.
-			var isValid = this._lastValidState;
-			if(!widget || this._lastValidState === undefined){
-				// We have passed a null widget, or we haven't been validated
-				// yet - let's re-check all our children
-				// This happens when we connect (or reconnect) our children
-				isValid = this.isValid();
-				if(this._lastValidState === undefined){
-					// Set this so that we don't fire an onValidStateChange
-					// the first time
-					this._lastValidState = isValid;
-				}
-			}else if(widget.isValid){
-				this._invalidWidgets = dojo.filter(this._invalidWidgets || [], function(w){
-					return (w != widget);
-				}, this);
-				if(!widget.isValid() && !widget.get("disabled")){
-					this._invalidWidgets.push(widget);
-				}
-				isValid = (this._invalidWidgets.length === 0);
-			}
-			if(isValid !== this._lastValidState){
-				this._lastValidState = isValid;
-				this.onValidStateChange(isValid);
-			}
+			//		Compute what this.state should be based on state of children
+			var states = dojo.map(this._descendants, function(w){
+				return w.get("state") || "";
+			});
+
+			return dojo.indexOf(states, "Error") >= 0 ? "Error" :
+				dojo.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(); });
 		},
 
-		connectChildren: function(){
+		connectChildren: function(/*Boolean*/ inStartup){
 			// summary:
-			//		Connects to the onChange function of all children to
-			//		track valid state changes.  You can call this function
-			//		directly, ex. in the event that you programmatically
-			//		add a widget to the form *after* the form has been
+			//		Setup connections to monitor changes to children's value, error state, and disabled state,
+			//		in order to update Form.value and Form.state.
+			//
+			//		You can call this function directly, ex. in the event that you
+			//		programmatically add a widget to the form *after* the form has been
 			//		initialized.
-			dojo.forEach(this._changeConnections, dojo.hitch(this, "disconnect"));
+
 			var _this = this;
 
-			// we connect to validate - so that it better reflects the states
-			// of the widgets - also, we only connect if it has a validate
-			// function (to avoid too many unneeded connections)
-			var conns = (this._changeConnections = []);
-			dojo.forEach(dojo.filter(this.getDescendants(),
+			// Remove old connections, if any
+			this.disconnectChildren();
+
+			this._descendants = this.getDescendants();
+
+			// (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");
+			set("value", this.get("value"));
+			set("state", this._getState());
+
+			// Monitor changes to error state and disabled state in order to update
+			// Form.state
+			var conns = (this._childConnections = []),
+				watches = (this._childWatches = []);
+			dojo.forEach(dojo.filter(this._descendants,
 				function(item){ return item.validate; }
 			),
 			function(widget){
-				// We are interested in whenever the widget is validated - or
-				// whenever the disabled attribute on that widget is changed
-				conns.push(_this.connect(widget, "validate",
-									dojo.hitch(_this, "_widgetChange", widget)));
-				conns.push(_this.connect(widget, "_setDisabledAttr",
-									dojo.hitch(_this, "_widgetChange", 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){
+						_this.set("state", _this._getState());
+					}));
+				});
 			});
 
-			// Call the widget change function to update the valid state, in
-			// case something is different now.
-			this._widgetChange(null);
+			// And monitor calls to child.onChange so we can update this.value
+			var onChange = function(){
+				// summary:
+				//		Called when child's value or disabled state changes
+				
+				// Use setTimeout() to collapse value changes in multiple children into a single
+				// update to my value.   Multiple updates will occur on:
+				//	1. Form.set()
+				//	2. Form.reset()
+				//	3. user selecting a radio button (which will de-select another radio button,
+				//		 causing two onChange events)
+				if(_this._onChangeDelayTimer){
+					clearTimeout(_this._onChangeDelayTimer);
+				}
+				_this._onChangeDelayTimer = setTimeout(function(){
+					delete _this._onChangeDelayTimer;
+					_this._set("value", _this.get("value"));
+				}, 10);
+			};
+			dojo.forEach(
+				dojo.filter(this._descendants, function(item){ return item.onChange; } ),
+				function(widget){
+					// When a child widget's value changes,
+					// the efficient thing to do is to just update that one attribute in this.value,
+					// but that gets a little complicated when a checkbox is checked/unchecked
+					// since this.value["checkboxName"] contains an array of all the checkboxes w/the same name.
+					// Doing simple thing for now.
+					conns.push(_this.connect(widget, "onChange", onChange));
+
+					// Disabling/enabling a child widget should remove it's value from this.value.
+					// Again, this code could be more efficient, doing simple thing for now.
+					watches.push(widget.watch("disabled", onChange));
+				}
+			);
 		},
 
 		startup: function(){
 			this.inherited(arguments);
-			// Initialize our valid state tracking.  Needs to be done in startup
-			// because it's not guaranteed that our children are initialized
-			// yet.
-			this._changeConnections = [];
-			this.connectChildren();
+
+			// Initialize value and valid/invalid state tracking.  Needs to be done in startup()
+			// so that children are initialized.
+			this.connectChildren(true);
+
+			// Make state change call onValidStateChange(), will be removed in 2.0
+			this.watch("state", function(attr, oldVal, newVal){ this.onValidStateChange(newVal == ""); });
+		},
+
+		destroy: function(){
+			this.disconnectChildren();
+			this.inherited(arguments);
 		}
+
 	});
+
+
+return dijit.form._FormMixin;
+});
diff --git a/dijit/form/_FormSelectWidget.js b/dijit/form/_FormSelectWidget.js
index 13edee1..92fbb87 100644
--- a/dijit/form/_FormSelectWidget.js
+++ b/dijit/form/_FormSelectWidget.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.form._FormSelectWidget");
-
-dojo.require("dijit.form._FormWidget");
-dojo.require("dojo.data.util.sorter");
+define("dijit/form/_FormSelectWidget", ["dojo", "dijit", "dijit/form/_FormWidget", "dojo/data/util/sorter"], function(dojo, dijit) {
 
 /*=====
 dijit.form.__SelectOption = function(){
@@ -10,7 +7,7 @@ dijit.form.__SelectOption = function(){
 	//		place a separator at that location
 	// label: String
 	//		The label for our option.  It can contain html tags.
-	//  selected: Boolean
+	// selected: Boolean
 	//		Whether or not we are a selected option
 	// disabled: Boolean
 	//		Whether or not this specific option is disabled
@@ -28,13 +25,13 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	//		This also provides the mechanism for reading the elements from
 	//		a store, if desired.
 
-	// multiple: Boolean
+	// multiple: [const] Boolean
 	//		Whether or not we are multi-valued
 	multiple: false,
 
 	// options: dijit.form.__SelectOption[]
 	//		The set of options for our select item.  Roughly corresponds to
-	//      the html <option> tag.
+	//		the html <option> tag.
 	options: null,
 
 	// store: dojo.data.api.Identity
@@ -56,20 +53,20 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	//		iterated over (i.e. to filter even futher what you want to add)
 	onFetch: null,
 
-	// sortByLabel: boolean
+	// sortByLabel: Boolean
 	//		Flag to sort the options returned from a store by the label of
 	//		the store.
 	sortByLabel: true,
 
 
-	// loadChildrenOnOpen: boolean
+	// loadChildrenOnOpen: Boolean
 	//		By default loadChildren is called when the items are fetched from the
 	//		store.  This property allows delaying loadChildren (and the creation
-	//		of the options/menuitems) until the user opens the click the button.
-	//		dropdown
+	//		of the options/menuitems) until the user clicks the button to open the
+	//		dropdown.
 	loadChildrenOnOpen: false,
 
-	getOptions: function(/* anything */ valueOrIdx){
+	getOptions: function(/*anything*/ valueOrIdx){
 		// summary:
 		//		Returns a given option (or options).
 		// valueOrIdx:
@@ -135,7 +132,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		return null; // null
 	},
 
-	addOption: function(/* dijit.form.__SelectOption, dijit.form.__SelectOption[] */ option){
+	addOption: function(/*dijit.form.__SelectOption|dijit.form.__SelectOption[]*/ option){
 		// summary:
 		//		Adds an option or options to the end of the select.  If value
 		//		of the option is empty or missing, a separator is created instead.
@@ -150,7 +147,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		this._loadChildren();
 	},
 
-	removeOption: function(/* string, dijit.form.__SelectOption, number, or array */ valueOrIdx){
+	removeOption: function(/*String|dijit.form.__SelectOption|Number|Array*/ valueOrIdx){
 		// summary:
 		//		Removes the given option or options.  You can remove by string
 		//		(in which case the value is removed), number (in which case the
@@ -165,7 +162,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 			// that case, we don't want to blow up...
 			if(i){
 				this.options = dojo.filter(this.options, function(node, idx){
-					return (node.value !== i.value);
+					return (node.value !== i.value || node.label !== i.label);
 				});
 				this._removeOptionItem(i);
 			}
@@ -173,7 +170,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		this._loadChildren();
 	},
 
-	updateOption: function(/* dijit.form.__SelectOption, dijit.form.__SelectOption[] */ newOption){
+	updateOption: function(/*dijit.form.__SelectOption|dijit.form.__SelectOption[]*/ newOption){
 		// summary:
 		//		Updates the values of the given option.  The option to update
 		//		is matched based on the value of the entered option.  Passing
@@ -189,9 +186,9 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		this._loadChildren();
 	},
 
-	setStore: function(/* dojo.data.api.Identity */ store,
-						/* anything? */ selectedValue,
-						/* Object? */ fetchArgs){
+	setStore: function(/*dojo.data.api.Identity*/ store,
+						/*anything?*/ selectedValue,
+						/*Object?*/ fetchArgs){
 		// summary:
 		//		Sets the store you would like to use with this select widget.
 		//		The selected value is the value of the new store to set.  This
@@ -218,7 +215,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 					dojo.connect(store, "onSet", this, "_onSetItem")
 				];
 			}
-			this.store = store;
+			this._set("store", store);
 		}
 
 		// Turn off change notifications while we make all these changes
@@ -231,48 +228,52 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 
 		// Add our new options
 		if(store){
-			var cb = function(items){
-				if(this.sortByLabel && !fetchArgs.sort && items.length){
-					items.sort(dojo.data.util.sorter.createSortFunction([{
-						attribute: store.getLabelAttributes(items[0])[0]
-					}], store));
-				}
-
-				if(fetchArgs.onFetch){
-					items = fetchArgs.onFetch(items);
-				}
-				// TODO: Add these guys as a batch, instead of separately
-				dojo.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{
-					this._pseudoLoadChildren(items);
-				}
-				this._fetchedWith = opts;
-				this._lastValueReported = this.multiple ? [] : null;
-				this._onChangeActive = true;
-				this.onSetStore();
-				this._handleOnChange(this.value);
-			};
-			var opts = dojo.mixin({onComplete:cb, scope: this}, fetchArgs);
 			this._loadingStore = true;
-			store.fetch(opts);
+			store.fetch(dojo.delegate(fetchArgs, {
+				onComplete: function(items, opts){
+					if(this.sortByLabel && !fetchArgs.sort && items.length){
+						items.sort(dojo.data.util.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){
+						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{
+						this._pseudoLoadChildren(items);
+					}
+					this._fetchedWith = opts;
+					this._lastValueReported = this.multiple ? [] : null;
+					this._onChangeActive = true;
+					this.onSetStore();
+					this._handleOnChange(this.value);
+				},
+				scope: this
+			}));
 		}else{
 			delete this._fetchedWith;
 		}
 		return oStore;	// dojo.data.api.Identity
 	},
 
-	_setValueAttr: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
+	// TODO: implement set() and watch() for store and query, although not sure how to handle
+	// setting them individually rather than together (as in setStore() above)
+
+	_setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
 		// summary:
 		//		set the value of the widget.
 		//		If a string is passed, then we set our value from looking it up.
@@ -308,7 +309,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		var val = dojo.map(newValue, function(i){ return i.value; }),
 			disp = dojo.map(newValue, function(i){ return i.label; });
 
-		this.value = this.multiple ? val : val[0];
+		this._set("value", this.multiple ? val : val[0]);
 		this._setDisplay(this.multiple ? disp : disp[0]);
 		this._updateSelection();
 		this._handleOnChange(this.value, priorityChange);
@@ -332,23 +333,10 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		return this.multiple ? ret : ret[0];
 	},
 
-	_getValueDeprecated: false, // remove when _FormWidget:getValue is removed
-	getValue: function(){
-		// summary:
-		//		get the value of the widget.
-		return this._lastValue;
-	},
-
-	undo: function(){
-		// summary:
-		//		restore the value to the last value passed to onChange
-		this._setValueAttr(this._lastValueReported, false);
-	},
-
 	_loadChildren: function(){
 		// summary:
 		//		Loads the children represented by this widget's options.
-		//		reset the menu to make it "populatable on the next click
+		//		reset the menu to make it populatable on the next click
 		if(this._loadingStore){ return; }
 		dojo.forEach(this._getChildren(), function(child){
 			child.destroyRecursive();
@@ -363,7 +351,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	_updateSelection: function(){
 		// summary:
 		//		Sets the "selected" class on the item for styling purposes
-		this.value = this._getValueFromOpts();
+		this._set("value", this._getValueFromOpts());
 		var val = this.value;
 		if(!dojo.isArray(val)){
 			val = [val];
@@ -377,7 +365,6 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 				dijit.setWaiState(child.domNode, "selected", isSelected);
 			}, this);
 		}
-		this._handleOnChange(this.value);
 	},
 
 	_getValueFromOpts: function(){
@@ -408,17 +395,17 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 	},
 
 	// Internal functions to call when we have store notifications come in
-	_onNewItem: function(/* item */ item, /* Object? */ parentInfo){
+	_onNewItem: function(/*item*/ item, /*Object?*/ parentInfo){
 		if(!parentInfo || !parentInfo.parent){
 			// Only add it if we are top-level
 			this._addOptionForItem(item);
 		}
 	},
-	_onDeleteItem: function(/* item */ item){
+	_onDeleteItem: function(/*item*/ item){
 		var store = this.store;
 		this.removeOption(store.getIdentity(item));
 	},
-	_onSetItem: function(/* item */ item){
+	_onSetItem: function(/*item*/ item){
 		this.updateOption(this._getOptionObjForItem(item));
 	},
 
@@ -433,7 +420,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		return {value: value, label: label, item:item}; // dijit.form.__SelectOption
 	},
 
-	_addOptionForItem: function(/* item */ item){
+	_addOptionForItem: function(/*item*/ item){
 		// summary:
 		//		Creates (and adds) the option for the given item
 		var store = this.store;
@@ -449,13 +436,18 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		this.addOption(newOpt);
 	},
 
-	constructor: function(/* Object */ keywordArgs){
+	constructor: function(/*Object*/ keywordArgs){
 		// summary:
 		//		Saves off our value, if we have an initial one set so we
 		//		can use it if we have a store as well (see startup())
 		this._oValue = (keywordArgs || {}).value || null;
 	},
 
+	buildRendering: function(){
+		this.inherited(arguments);
+		dojo.setSelectable(this.focusNode, false);
+	},
+
 	_fillContent: function(){
 		// summary:
 		//		Loads our options and sets up our dropdown correctly.  We
@@ -468,16 +460,21 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 							if(node.getAttribute("type") === "separator"){
 								return { value: "", label: "", selected: false, disabled: false };
 							}
-							return { value: node.getAttribute("value"),
+							return {
+								value: (node.getAttribute("data-" + dojo._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?)
+								// decide before 1.6
 										selected: node.getAttribute("selected") || false,
-										disabled: node.getAttribute("disabled") || false };
+								disabled: node.getAttribute("disabled") || false
+							};
 						}, this) : [];
 		}
 		if(!this.value){
-			this.value = this._getValueFromOpts();
+			this._set("value", this._getValueFromOpts());
 		}else if(this.multiple && typeof this.value == "string"){
-			this.value = this.value.split(",");
+			this_set("value", this.value.split(","));
 		}
 	},
 
@@ -485,7 +482,6 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		// summary:
 		//		sets up our event handling that we need for functioning
 		//		as a select
-		dojo.setSelectable(this.focusNode, false);
 		this.inherited(arguments);
 
 		// Make our event connections for updating state
@@ -521,7 +517,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		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
@@ -529,7 +525,7 @@ 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.
@@ -555,7 +551,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.
@@ -570,3 +566,7 @@ dojo.declare("dijit.form._FormSelectWidget", dijit.form._FormValueWidget, {
 		//		from that store are available
 	}
 });
+
+
+return dijit.form._FormSelectWidget;
+});
diff --git a/dijit/form/_FormWidget.js b/dijit/form/_FormWidget.js
index d1f3074..06fbe5a 100644
--- a/dijit/form/_FormWidget.js
+++ b/dijit/form/_FormWidget.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit.form._FormWidget");
-
-dojo.require("dojo.window");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._CssStateMixin");
+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],
 	{
@@ -19,7 +13,7 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 	//
 	//		They also share some common methods.
 
-	// name: String
+	// name: [const] String
 	//		Name used when submitting form; same as "name" attribute or plain HTML elements
 	name: "",
 
@@ -76,7 +70,7 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 	},
 
 	_setDisabledAttr: function(/*Boolean*/ value){
-		this.disabled = value;
+		this._set("disabled", value);
 		dojo.attr(this.focusNode, 'disabled', value);
 		if(this.valueNode){
 			dojo.attr(this.valueNode, 'disabled', value);
@@ -86,8 +80,8 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 		if(value){
 			// reset these, because after the domNode is disabled, we can no longer receive
 			// mouse related events, see #4200
-			this._hovering = false;
-			this._active = false;
+			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";
@@ -97,17 +91,19 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 				if(dojo.isWebKit || dijit.hasDefaultTabStop(node)){	// see #11064 about webkit bug
 					node.setAttribute('tabIndex', "-1");
 				}else{
-					node.removeAttribute('tabIndex');				
+					node.removeAttribute('tabIndex');
 				}
 			}, this);
 		}else{
-			this.focusNode.setAttribute('tabIndex', this.tabIndex);
+			if(this.tabIndex != ""){
+				this.focusNode.setAttribute('tabIndex', this.tabIndex);
+			}
 		}
 	},
 
 	setDisabled: function(/*Boolean*/ disabled){
 		// summary:
-		//		Deprecated.   Use set('disabled', ...) instead.
+		//		Deprecated.  Use set('disabled', ...) instead.
 		dojo.deprecated("setDisabled("+disabled+") is deprecated. Use set('disabled',"+disabled+") instead.", "", "2.0");
 		this.set('disabled', disabled);
 	},
@@ -121,21 +117,23 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 
 	isFocusable: function(){
 		// summary:
-		//		Tells if this widget is focusable or not.   Used internally by dijit.
+		//		Tells if this widget is focusable or not.  Used internally by dijit.
 		// tags:
 		//		protected
-		return !this.disabled && !this.readOnly && this.focusNode && (dojo.style(this.domNode, "display") != "none");
+		return !this.disabled && this.focusNode && (dojo.style(this.domNode, "display") != "none");
 	},
 
 	focus: function(){
 		// summary:
 		//		Put focus on this widget
-		dijit.focus(this.focusNode);
+		if(!this.disabled){
+			dijit.focus(this.focusNode);
+		}
 	},
 
-	compare: function(/*anything*/val1, /*anything*/val2){
+	compare: function(/*anything*/ val1, /*anything*/ val2){
 		// summary:
-		//		Compare 2 values (as returned by attr('value') for this widget).
+		//		Compare 2 values (as returned by get('value') for this widget).
 		// tags:
 		//		protected
 		if(typeof val1 == "number" && typeof val2 == "number"){
@@ -162,27 +160,28 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 	//		when the initial value is set.
 	_onChangeActive: false,
 
-	_handleOnChange: function(/*anything*/ newValue, /* Boolean? */ priorityChange){
+	_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==true,
+		//		but on mouse up, it's priorityChange==true.  If intermediateChanges==false,
 		//		onChange is only called form priorityChange=true events.
 		// tags:
 		//		private
-		this._lastValue = newValue;
 		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;
 		}
-		if((this.intermediateChanges || priorityChange || priorityChange === undefined) &&
-			((typeof newValue != typeof this._lastValueReported) ||
-				this.compare(newValue, this._lastValueReported) != 0)){
+		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);
@@ -214,14 +213,14 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 
 	setValue: function(/*String*/ value){
 		// summary:
-		//		Deprecated.   Use set('value', ...) instead.
+		//		Deprecated.  Use set('value', ...) instead.
 		dojo.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.
+		//		Deprecated.  Use get('value') instead.
 		dojo.deprecated(this.declaredClass+"::getValue() is deprecated. Use get('value') instead.", "", "2.0");
 		return this.get('value');
 	},
@@ -231,7 +230,7 @@ dojo.declare("dijit.form._FormWidget", [dijit._Widget, dijit._Templated, dijit._
 		// 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 && this.isFocusable()){ // !e.ctrlKey to ignore right-click on mac
+		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(){
@@ -255,7 +254,7 @@ dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
 
 	// 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.
+	// 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
@@ -273,39 +272,40 @@ dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
 	}),
 
 	_setReadOnlyAttr: function(/*Boolean*/ value){
-		this.readOnly = 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){ // IE won't stop the event with keypress
+		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._resetValue = this.value;
+			this._lastValueReported = this._resetValue = this.value;
 		}
 	},
 
-	_setValueAttr: function(/*anything*/ newValue, /*Boolean, optional*/ priorityChange){
+	_setValueAttr: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
 		// summary:
-		//		Hook so attr('value', value) works.
+		//		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.value = newValue;
 		this._handleOnChange(newValue, priorityChange);
 	},
 
-	_getValueAttr: function(){
+	_handleOnChange: function(/*anything*/ newValue, /*Boolean?*/ priorityChange){
 		// summary:
-		//		Hook so attr('value') works.
-		return this._lastValue;
+		//		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(){
@@ -359,3 +359,7 @@ dojo.declare("dijit.form._FormValueWidget", dijit.form._FormWidget,
 		}
 	}
 });
+
+
+return dijit.form._FormWidget;
+});
diff --git a/dijit/form/_Spinner.js b/dijit/form/_Spinner.js
index 527d79c..dc29fd3 100644
--- a/dijit/form/_Spinner.js
+++ b/dijit/form/_Spinner.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.form._Spinner");
-
-dojo.require("dijit.form.ValidationTextBox");
+define("dijit/form/_Spinner", ["dojo", "dijit", "text!dijit/form/templates/Spinner.html", "dijit/form/ValidationTextBox"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.form._Spinner",
@@ -17,7 +15,7 @@ dojo.declare(
 		defaultTimeout: 500,
 
 		// minimumTimeout: Number
-		//       minimum number of milliseconds that typematic event fires when held key or button is held
+		//		minimum number of milliseconds that typematic event fires when held key or button is held
 		minimumTimeout: 10,
 
 		// timeoutChangeRate: Number
@@ -27,11 +25,11 @@ dojo.declare(
 		timeoutChangeRate: 0.90,
 
 		// smallDelta: Number
-		//	  Adjust the value by this much when spinning using the arrow keys/buttons
+		//		Adjust the value by this much when spinning using the arrow keys/buttons
 		smallDelta: 1,
 
 		// largeDelta: Number
-		//	  Adjust the value by this much when spinning using the PgUp/Dn keys
+		//		Adjust the value by this much when spinning using the PgUp/Dn keys
 		largeDelta: 10,
 
 		templateString: dojo.cache("dijit.form", "templates/Spinner.html"),
@@ -45,7 +43,7 @@ dojo.declare(
 			"downArrowNode": "dijitDownArrowButton"
 		},
 
-		adjust: function(/* Object */ val, /*Number*/ delta){
+		adjust: function(/*Object*/ val, /*Number*/ 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.
@@ -115,3 +113,7 @@ dojo.declare(
 			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));
 		}
 });
+
+
+return dijit.form._Spinner;
+});
diff --git a/dijit/form/nls/ComboBox.js b/dijit/form/nls/ComboBox.js
index 7843596..da6e189 100644
--- a/dijit/form/nls/ComboBox.js
+++ b/dijit/form/nls/ComboBox.js
@@ -1,4 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 		previousMessage: "Previous choices",
 		nextMessage: "More choices"
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/form/nls/Textarea.js b/dijit/form/nls/Textarea.js
index 87867f0..f845b63 100644
--- a/dijit/form/nls/Textarea.js
+++ b/dijit/form/nls/Textarea.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 /* 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
@@ -5,3 +7,35 @@
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+,
+"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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/form/nls/ar/ComboBox.js b/dijit/form/nls/ar/ComboBox.js
index 4ebc65a..1be1bd9 100644
--- a/dijit/form/nls/ar/ComboBox.js
+++ b/dijit/form/nls/ar/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "الاختيارات السابقة",
 		nextMessage: "مزيد من الاختيارات"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ar/Textarea.js b/dijit/form/nls/ar/Textarea.js
index 5a679b7..3987f40 100644
--- a/dijit/form/nls/ar/Textarea.js
+++ b/dijit/form/nls/ar/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'مساحة التحرير',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'اطار مساحة التحرير'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ar/validate.js b/dijit/form/nls/ar/validate.js
index f146dd2..4c88bdb 100644
--- a/dijit/form/nls/ar/validate.js
+++ b/dijit/form/nls/ar/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "القيمة التي تم ادخالها غير صحيحة.",
 	missingMessage: "يجب ادخال هذه القيمة.",
 	rangeMessage: "هذه القيمة ليس بالمدى الصحيح."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ca/ComboBox.js b/dijit/form/nls/ca/ComboBox.js
index 02456e5..24b685e 100644
--- a/dijit/form/nls/ca/ComboBox.js
+++ b/dijit/form/nls/ca/ComboBox.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Opcions anteriors",
 		nextMessage: "Més opcions"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/ca/Textarea.js b/dijit/form/nls/ca/Textarea.js
index b8a7429..7b4f9d6 100644
--- a/dijit/form/nls/ca/Textarea.js
+++ b/dijit/form/nls/ca/Textarea.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 /* used by both the editor and textarea widgets to provide information to screen reader users */
 ({
 	iframeEditTitle: 'àrea d\'edició',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
@@ -6,3 +8,5 @@
 									 //  parent element of the editing area
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/ca/validate.js b/dijit/form/nls/ca/validate.js
index fb301c0..7629f97 100644
--- a/dijit/form/nls/ca/validate.js
+++ b/dijit/form/nls/ca/validate.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "El valor introduït no és vàlid",
 	missingMessage: "Aquest valor és necessari",
 	rangeMessage: "Aquest valor és fora de l'interval"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/cs/ComboBox.js b/dijit/form/nls/cs/ComboBox.js
index 9d0eaad..e86b1b0 100644
--- a/dijit/form/nls/cs/ComboBox.js
+++ b/dijit/form/nls/cs/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Předchozí volby",
 		nextMessage: "Další volby"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/cs/Textarea.js b/dijit/form/nls/cs/Textarea.js
index db754be..5896983 100644
--- a/dijit/form/nls/cs/Textarea.js
+++ b/dijit/form/nls/cs/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'oblast úprav',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'rámec oblasti úprav'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/cs/validate.js b/dijit/form/nls/cs/validate.js
index fc95d3a..6dd8c95 100644
--- a/dijit/form/nls/cs/validate.js
+++ b/dijit/form/nls/cs/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Zadaná hodnota není platná.",
 	missingMessage: "Tato hodnota je vyžadována.",
 	rangeMessage: "Tato hodnota je mimo rozsah."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/da/ComboBox.js b/dijit/form/nls/da/ComboBox.js
index 520cfdf..9bbacaf 100644
--- a/dijit/form/nls/da/ComboBox.js
+++ b/dijit/form/nls/da/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Forrige valg",
 		nextMessage: "Flere valg"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/da/Textarea.js b/dijit/form/nls/da/Textarea.js
index 9237b1c..6faa493 100644
--- a/dijit/form/nls/da/Textarea.js
+++ b/dijit/form/nls/da/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'redigeringsområde',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'ramme om redigeringsområde'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/da/validate.js b/dijit/form/nls/da/validate.js
index 1707a09..9307b48 100644
--- a/dijit/form/nls/da/validate.js
+++ b/dijit/form/nls/da/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
-	invalidMessage: "Den angivne værdi er ugyldig.",
+	invalidMessage: "Den angivne værdi er ikke gyldig.",
 	missingMessage: "Værdien er påkrævet.",
 	rangeMessage: "Værdien er uden for intervallet."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/de/ComboBox.js b/dijit/form/nls/de/ComboBox.js
index ac984af..0e2dd48 100644
--- a/dijit/form/nls/de/ComboBox.js
+++ b/dijit/form/nls/de/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Vorherige Auswahl",
 		nextMessage: "Weitere Auswahlmöglichkeiten"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/de/Textarea.js b/dijit/form/nls/de/Textarea.js
index 9421712..ed22a38 100644
--- a/dijit/form/nls/de/Textarea.js
+++ b/dijit/form/nls/de/Textarea.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 /* used by both the editor and textarea widgets to provide information to screen reader users */
 ({
 	iframeEditTitle: 'Editierbereich',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
@@ -5,3 +7,5 @@
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/de/validate.js b/dijit/form/nls/de/validate.js
index 07670e3..79346f8 100755
--- a/dijit/form/nls/de/validate.js
+++ b/dijit/form/nls/de/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Der eingegebene Wert ist ungültig. ",
 	missingMessage: "Dieser Wert ist erforderlich.",
 	rangeMessage: "Dieser Wert liegt außerhalb des gültigen Bereichs. "
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/el/ComboBox.js b/dijit/form/nls/el/ComboBox.js
index 2d13c2c..06871ad 100644
--- a/dijit/form/nls/el/ComboBox.js
+++ b/dijit/form/nls/el/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Προηγούμενες επιλογές",
 		nextMessage: "Περισσότερες επιλογές"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/el/Textarea.js b/dijit/form/nls/el/Textarea.js
index da96a69..11814ae 100644
--- a/dijit/form/nls/el/Textarea.js
+++ b/dijit/form/nls/el/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'περιοχή επεξεργασίας',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'πλαίσιο περιοχής επεξεργασίας'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/el/validate.js b/dijit/form/nls/el/validate.js
index 25eedb6..8b61b80 100644
--- a/dijit/form/nls/el/validate.js
+++ b/dijit/form/nls/el/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Η τιμή που καταχωρήσατε δεν είναι έγκυρη.",
 	missingMessage: "Η τιμή αυτή πρέπει απαραίτητα να καθοριστεί.",
 	rangeMessage: "Η τιμή αυτή δεν ανήκει στο εύρος έγκυρων τιμών."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/es/ComboBox.js b/dijit/form/nls/es/ComboBox.js
index 0cc1343..2d7705a 100644
--- a/dijit/form/nls/es/ComboBox.js
+++ b/dijit/form/nls/es/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Opciones anteriores",
 		nextMessage: "Más opciones"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/es/Textarea.js b/dijit/form/nls/es/Textarea.js
index e6dd4fe..b4f8e92 100644
--- a/dijit/form/nls/es/Textarea.js
+++ b/dijit/form/nls/es/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'área de edición',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'marco del área de edición'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/es/validate.js b/dijit/form/nls/es/validate.js
index a07f31c..e880327 100644
--- a/dijit/form/nls/es/validate.js
+++ b/dijit/form/nls/es/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "El valor especificado no es válido.",
 	missingMessage: "Este valor es necesario.",
 	rangeMessage: "Este valor está fuera del intervalo."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/fi/ComboBox.js b/dijit/form/nls/fi/ComboBox.js
index 88c460b..4ad1f81 100644
--- a/dijit/form/nls/fi/ComboBox.js
+++ b/dijit/form/nls/fi/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Edelliset valinnat",
 		nextMessage: "Lisää valintoja"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/fi/Textarea.js b/dijit/form/nls/fi/Textarea.js
index 28e675b..d43eb74 100644
--- a/dijit/form/nls/fi/Textarea.js
+++ b/dijit/form/nls/fi/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'muokkausalue',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'muokkausalueen kehys'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/fi/validate.js b/dijit/form/nls/fi/validate.js
index b08e2b1..2bf7676 100644
--- a/dijit/form/nls/fi/validate.js
+++ b/dijit/form/nls/fi/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Annettu arvo ei kelpaa.",
 	missingMessage: "Tämä arvo on pakollinen.",
 	rangeMessage: "Tämä arvo on sallitun alueen ulkopuolella."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/fr/ComboBox.js b/dijit/form/nls/fr/ComboBox.js
index ddba994..04f4184 100644
--- a/dijit/form/nls/fr/ComboBox.js
+++ b/dijit/form/nls/fr/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Choix précédents",
 		nextMessage: "Plus de choix"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/fr/Textarea.js b/dijit/form/nls/fr/Textarea.js
index 8c8390d..3d8c993 100644
--- a/dijit/form/nls/fr/Textarea.js
+++ b/dijit/form/nls/fr/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
-	iframeEditTitle: 'zone d\'édition',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: 'cadre de la zone d\'édition'  // secondary title for editable IFRAME when focus is on outer container
+	iframeEditTitle: "zone d'édition",  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: "cadre de la zone d'édition"  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/fr/validate.js b/dijit/form/nls/fr/validate.js
index 73cbba3..20981aa 100644
--- a/dijit/form/nls/fr/validate.js
+++ b/dijit/form/nls/fr/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "La valeur indiquée n'est pas correcte.",
 	missingMessage: "Cette valeur est requise.",
 	rangeMessage: "Cette valeur n'est pas comprise dans la plage autorisée."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/he/ComboBox.js b/dijit/form/nls/he/ComboBox.js
index a4f9d32..754b0f6 100644
--- a/dijit/form/nls/he/ComboBox.js
+++ b/dijit/form/nls/he/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "האפשרויות הקודמות",
 		nextMessage: "אפשרויות נוספות"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/he/Textarea.js b/dijit/form/nls/he/Textarea.js
index 3c4b349..35ac734 100644
--- a/dijit/form/nls/he/Textarea.js
+++ b/dijit/form/nls/he/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'אזור עריכה',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'מסגרת אזור עריכה'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/he/validate.js b/dijit/form/nls/he/validate.js
index 343d904..1be970a 100644
--- a/dijit/form/nls/he/validate.js
+++ b/dijit/form/nls/he/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "הערך שצוין אינו חוקי.",
 	missingMessage: "זהו ערך דרוש.",
 	rangeMessage: "הערך מחוץ לטווח."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/hu/ComboBox.js b/dijit/form/nls/hu/ComboBox.js
index 8109a9e..05f5149 100644
--- a/dijit/form/nls/hu/ComboBox.js
+++ b/dijit/form/nls/hu/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Előző menüpontok",
 		nextMessage: "További menüpontok"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/hu/Textarea.js b/dijit/form/nls/hu/Textarea.js
index 2167170..e8f3b8e 100644
--- a/dijit/form/nls/hu/Textarea.js
+++ b/dijit/form/nls/hu/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'szerkesztési terület',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'szerkesztési terület keret'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/hu/validate.js b/dijit/form/nls/hu/validate.js
index 4addd49..a2a9e15 100644
--- a/dijit/form/nls/hu/validate.js
+++ b/dijit/form/nls/hu/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "A megadott érték érvénytelen.",
 	missingMessage: "Meg kell adni egy értéket.",
 	rangeMessage: "Az érték kívül van a megengedett tartományon."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/it/ComboBox.js b/dijit/form/nls/it/ComboBox.js
index 6a27e72..4d0a32e 100644
--- a/dijit/form/nls/it/ComboBox.js
+++ b/dijit/form/nls/it/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Scelte precedenti",
 		nextMessage: "Altre scelte"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/it/Textarea.js b/dijit/form/nls/it/Textarea.js
index 2f9bd4a..5b05d18 100644
--- a/dijit/form/nls/it/Textarea.js
+++ b/dijit/form/nls/it/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'modifica area',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'modifica frame area'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/it/validate.js b/dijit/form/nls/it/validate.js
index 8931cf0..d299f4b 100644
--- a/dijit/form/nls/it/validate.js
+++ b/dijit/form/nls/it/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Il valore immesso non è valido.",
 	missingMessage: "Questo valore è obbligatorio.",
 	rangeMessage: "Questo valore non è compreso nell'intervallo."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ja/ComboBox.js b/dijit/form/nls/ja/ComboBox.js
index f362cd2..9ffe040 100644
--- a/dijit/form/nls/ja/ComboBox.js
+++ b/dijit/form/nls/ja/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "以前の選択項目",
 		nextMessage: "追加の選択項目"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ja/Textarea.js b/dijit/form/nls/ja/Textarea.js
index b27aa7d..08a93a0 100644
--- a/dijit/form/nls/ja/Textarea.js
+++ b/dijit/form/nls/ja/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: '編集域',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '編集域フレーム'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ja/validate.js b/dijit/form/nls/ja/validate.js
index 28bd9b0..21b323c 100644
--- a/dijit/form/nls/ja/validate.js
+++ b/dijit/form/nls/ja/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "入力した値は無効です。",
 	missingMessage: "この値は必須です。",
 	rangeMessage: "この値は範囲外です。"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/kk/ComboBox.js b/dijit/form/nls/kk/ComboBox.js
new file mode 100644
index 0000000..e287206
--- /dev/null
+++ b/dijit/form/nls/kk/ComboBox.js
@@ -0,0 +1,9 @@
+define(
+//begin v1.x content
+({
+		previousMessage: "Алдыңғы нұсқалар",
+		nextMessage: "Басқа нұсқалар"
+})
+//end v1.x content
+);
+
diff --git a/dijit/form/nls/kk/Textarea.js b/dijit/form/nls/kk/Textarea.js
new file mode 100644
index 0000000..2f28cd5
--- /dev/null
+++ b/dijit/form/nls/kk/Textarea.js
@@ -0,0 +1,12 @@
+define(
+//begin v1.x content
+/* used by both the editor and textarea widgets to provide information to screen reader users */
+({
+	iframeEditTitle: 'өңдеу аумағы',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'өңдеу аумағының жақтауы'  // secondary title for editable IFRAME when focus is on outer container
+									 //  to let user know that focus has moved out of editing area and to the
+									 //  parent element of the editing area
+})
+//end v1.x content
+);
+
diff --git a/dijit/form/nls/kk/validate.js b/dijit/form/nls/kk/validate.js
new file mode 100644
index 0000000..16973a8
--- /dev/null
+++ b/dijit/form/nls/kk/validate.js
@@ -0,0 +1,10 @@
+define(
+//begin v1.x content
+({
+	invalidMessage: "Енгізілген мән жарамды емес.",
+	missingMessage: "Бұл мән міндетті.",
+	rangeMessage: "Бұл мән ауқымнан тыс."
+})
+//end v1.x content
+);
+
diff --git a/dijit/form/nls/ko/ComboBox.js b/dijit/form/nls/ko/ComboBox.js
index 7d8b668..f2ee413 100644
--- a/dijit/form/nls/ko/ComboBox.js
+++ b/dijit/form/nls/ko/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "이전 선택사항",
 		nextMessage: "기타 선택사항"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ko/Textarea.js b/dijit/form/nls/ko/Textarea.js
index e6b1266..de203c1 100644
--- a/dijit/form/nls/ko/Textarea.js
+++ b/dijit/form/nls/ko/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: '편집 영역',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '편집 영역 프레임'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ko/validate.js b/dijit/form/nls/ko/validate.js
index d23627d..eaa460f 100644
--- a/dijit/form/nls/ko/validate.js
+++ b/dijit/form/nls/ko/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "입력된 값이 올바르지 않습니다.",
 	missingMessage: "이 값은 필수입니다.",
 	rangeMessage: "이 값은 범위를 벗어납니다."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/nb/ComboBox.js b/dijit/form/nls/nb/ComboBox.js
index 3c65d2e..a9c25d8 100644
--- a/dijit/form/nls/nb/ComboBox.js
+++ b/dijit/form/nls/nb/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Tidligere valg",
 		nextMessage: "Flere valg"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/nb/Textarea.js b/dijit/form/nls/nb/Textarea.js
index 894c98e..3026a3d 100644
--- a/dijit/form/nls/nb/Textarea.js
+++ b/dijit/form/nls/nb/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'redigeringsområde',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'ramme for redigeringsområde'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/nb/validate.js b/dijit/form/nls/nb/validate.js
index 6257674..db548a8 100644
--- a/dijit/form/nls/nb/validate.js
+++ b/dijit/form/nls/nb/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Den angitte verdien er ikke gyldig.",
 	missingMessage: "Denne verdien er obligatorisk.",
 	rangeMessage: "Denne verdien er utenfor gyldig område."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/nl/ComboBox.js b/dijit/form/nls/nl/ComboBox.js
index 3c9369f..2c1d351 100644
--- a/dijit/form/nls/nl/ComboBox.js
+++ b/dijit/form/nls/nl/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Eerdere opties",
 		nextMessage: "Meer opties"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/nl/Textarea.js b/dijit/form/nls/nl/Textarea.js
index 1f98573..b24553f 100644
--- a/dijit/form/nls/nl/Textarea.js
+++ b/dijit/form/nls/nl/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'veld bewerken',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'veldkader bewerken'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/nl/validate.js b/dijit/form/nls/nl/validate.js
index d83a8b4..513b7a3 100644
--- a/dijit/form/nls/nl/validate.js
+++ b/dijit/form/nls/nl/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "De opgegeven waarde is ongeldig.",
 	missingMessage: "Deze waarde is verplicht.",
 	rangeMessage: "Deze waarde is niet toegestaan."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pl/ComboBox.js b/dijit/form/nls/pl/ComboBox.js
index 2e7bf87..842b14d 100644
--- a/dijit/form/nls/pl/ComboBox.js
+++ b/dijit/form/nls/pl/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Poprzednie wybory",
 		nextMessage: "Więcej wyborów"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pl/Textarea.js b/dijit/form/nls/pl/Textarea.js
index 129d7d0..d1d4b94 100644
--- a/dijit/form/nls/pl/Textarea.js
+++ b/dijit/form/nls/pl/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
-	iframeEditTitle: 'Obszar edycji',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: 'Ramka obszaru edycji'  // secondary title for editable IFRAME when focus is on outer container
+	iframeEditTitle: 'edycja obszaru',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'edycja ramki obszaru'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pl/validate.js b/dijit/form/nls/pl/validate.js
index 46f0bfb..fcf3f09 100644
--- a/dijit/form/nls/pl/validate.js
+++ b/dijit/form/nls/pl/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Wprowadzona wartość jest niepoprawna.",
 	missingMessage: "Ta wartość jest wymagana.",
 	rangeMessage: "Ta wartość jest spoza zakresu."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pt-pt/ComboBox.js b/dijit/form/nls/pt-pt/ComboBox.js
index f03c359..dbd0c4c 100644
--- a/dijit/form/nls/pt-pt/ComboBox.js
+++ b/dijit/form/nls/pt-pt/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Opções anteriores",
 		nextMessage: "Mais opções"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pt-pt/Textarea.js b/dijit/form/nls/pt-pt/Textarea.js
index f40fc3d..3686878 100644
--- a/dijit/form/nls/pt-pt/Textarea.js
+++ b/dijit/form/nls/pt-pt/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'área de edição',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'painel da área de edição'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pt-pt/validate.js b/dijit/form/nls/pt-pt/validate.js
index 8fbb734..cd99891 100644
--- a/dijit/form/nls/pt-pt/validate.js
+++ b/dijit/form/nls/pt-pt/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "O valor introduzido não é válido.",
 	missingMessage: "Este valor é requerido.",
 	rangeMessage: "Este valor encontra-se fora do intervalo."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pt/ComboBox.js b/dijit/form/nls/pt/ComboBox.js
index f03c359..dbd0c4c 100644
--- a/dijit/form/nls/pt/ComboBox.js
+++ b/dijit/form/nls/pt/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Opções anteriores",
 		nextMessage: "Mais opções"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pt/Textarea.js b/dijit/form/nls/pt/Textarea.js
index 1a6077e..7eb9f8b 100644
--- a/dijit/form/nls/pt/Textarea.js
+++ b/dijit/form/nls/pt/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'editar área',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'editar quadro da área'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/pt/validate.js b/dijit/form/nls/pt/validate.js
index 46ffabb..beb20fa 100644
--- a/dijit/form/nls/pt/validate.js
+++ b/dijit/form/nls/pt/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "O valor inserido não é válido.",
 	missingMessage: "Este valor é necessário.",
 	rangeMessage: "Este valor está fora do intervalo. "
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ro/ComboBox.js b/dijit/form/nls/ro/ComboBox.js
index 303c832..2783f4d 100644
--- a/dijit/form/nls/ro/ComboBox.js
+++ b/dijit/form/nls/ro/ComboBox.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Alegeri anterioare",
 		nextMessage: "Mai multe alegeri"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/ro/Textarea.js b/dijit/form/nls/ro/Textarea.js
index 98a19c6..1f29ba1 100644
--- a/dijit/form/nls/ro/Textarea.js
+++ b/dijit/form/nls/ro/Textarea.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 /* used by both the editor and textarea widgets to provide information to screen reader users */
 ({
 	iframeEditTitle: 'zonă de editare',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
@@ -6,3 +8,5 @@
 									 //  parent element of the editing area
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/ro/validate.js b/dijit/form/nls/ro/validate.js
index 17132f7..83c7997 100644
--- a/dijit/form/nls/ro/validate.js
+++ b/dijit/form/nls/ro/validate.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Valoarea introdusă nu este validă.",
 	missingMessage: "Această valoare este necesară.",
 	rangeMessage: "Această valoare este în afara intervalului. "
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/ru/ComboBox.js b/dijit/form/nls/ru/ComboBox.js
index 8ef55f7..f042314 100644
--- a/dijit/form/nls/ru/ComboBox.js
+++ b/dijit/form/nls/ru/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Предыдущие варианты",
 		nextMessage: "Следующие варианты"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ru/Textarea.js b/dijit/form/nls/ru/Textarea.js
index 56b7fc2..8e7f05a 100644
--- a/dijit/form/nls/ru/Textarea.js
+++ b/dijit/form/nls/ru/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'область редактирования',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'фрейм области редактирования'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/ru/validate.js b/dijit/form/nls/ru/validate.js
index 93bbaaa..0ac668d 100644
--- a/dijit/form/nls/ru/validate.js
+++ b/dijit/form/nls/ru/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Указано недопустимое значение.",
 	missingMessage: "Это обязательное значение.",
 	rangeMessage: "Это значение вне диапазона."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/sk/ComboBox.js b/dijit/form/nls/sk/ComboBox.js
index e003b1b..f6bfe11 100644
--- a/dijit/form/nls/sk/ComboBox.js
+++ b/dijit/form/nls/sk/ComboBox.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Predchádzajúce voľby",
 		nextMessage: "Ďalšie voľby"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/sk/Textarea.js b/dijit/form/nls/sk/Textarea.js
index 8a6c633..4a3e584 100644
--- a/dijit/form/nls/sk/Textarea.js
+++ b/dijit/form/nls/sk/Textarea.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 /* used by both the editor and textarea widgets to provide information to screen reader users */
 ({
 	iframeEditTitle: 'upraviť oblasť',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
@@ -6,3 +8,5 @@
 									 //  parent element of the editing area
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/sk/validate.js b/dijit/form/nls/sk/validate.js
index a5e1f4c..47fa3a4 100644
--- a/dijit/form/nls/sk/validate.js
+++ b/dijit/form/nls/sk/validate.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Zadaná hodnota nie je platná.",
 	missingMessage: "Táto hodnota je vyžadovaná.",
 	rangeMessage: "Táto hodnota je mimo rozsah."
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/sl/ComboBox.js b/dijit/form/nls/sl/ComboBox.js
index 5537951..187ba78 100644
--- a/dijit/form/nls/sl/ComboBox.js
+++ b/dijit/form/nls/sl/ComboBox.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
-		previousMessage: "Prejšnje možnosti",
-		nextMessage: "Dodatne možnosti"
+		previousMessage: "Prejšnje izbire",
+		nextMessage: "Dodatne izbire"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/sl/Textarea.js b/dijit/form/nls/sl/Textarea.js
index 26ffbda..1e023cb 100644
--- a/dijit/form/nls/sl/Textarea.js
+++ b/dijit/form/nls/sl/Textarea.js
@@ -1,8 +1,12 @@
+define(
+//begin v1.x content
 /* used by both the editor and textarea widgets to provide information to screen reader users */
 ({
-	iframeEditTitle: 'urejanje področja',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
-	iframeFocusTitle: 'urejanje področja okvirja'  // secondary title for editable IFRAME when focus is on outer container
+	iframeEditTitle: 'urejevalno področje',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
+	iframeFocusTitle: 'okvir urejevalnega področja'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/sl/validate.js b/dijit/form/nls/sl/validate.js
index eda6ec8..88b79ae 100644
--- a/dijit/form/nls/sl/validate.js
+++ b/dijit/form/nls/sl/validate.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Vnesena vrednost ni veljavna.",
 	missingMessage: "Ta vrednost je zahtevana.",
-	rangeMessage: "Ta vrednost je zunaj obsega. "
+	rangeMessage: "Ta vrednost je izven območja."
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/sv/ComboBox.js b/dijit/form/nls/sv/ComboBox.js
index cc822ce..6abcf1f 100644
--- a/dijit/form/nls/sv/ComboBox.js
+++ b/dijit/form/nls/sv/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Föregående alternativ",
 		nextMessage: "Fler alternativ"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/sv/Textarea.js b/dijit/form/nls/sv/Textarea.js
index 52263a0..8ad63d6 100644
--- a/dijit/form/nls/sv/Textarea.js
+++ b/dijit/form/nls/sv/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'redigeringsområde',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'redigeringsområdesram'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/sv/validate.js b/dijit/form/nls/sv/validate.js
index 2e0346f..0ebf0ef 100644
--- a/dijit/form/nls/sv/validate.js
+++ b/dijit/form/nls/sv/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Det angivna värdet är ogiltigt.",
 	missingMessage: "Värdet är obligatoriskt.",
 	rangeMessage: "Värdet är utanför intervallet."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/th/ComboBox.js b/dijit/form/nls/th/ComboBox.js
index bbcae92..48b5daa 100644
--- a/dijit/form/nls/th/ComboBox.js
+++ b/dijit/form/nls/th/ComboBox.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "การเลือกก่อนหน้า",
 		nextMessage: "การเลือกเพิ่มเติม"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/th/Textarea.js b/dijit/form/nls/th/Textarea.js
index 2c51dfc..4907e45 100644
--- a/dijit/form/nls/th/Textarea.js
+++ b/dijit/form/nls/th/Textarea.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 /* used by both the editor and textarea widgets to provide information to screen reader users */
 ({
 	iframeEditTitle: 'แก้ไขพื้นที่',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
@@ -6,3 +8,5 @@
 									 //  parent element of the editing area
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/th/validate.js b/dijit/form/nls/th/validate.js
index 68ce684..8cc7e32 100644
--- a/dijit/form/nls/th/validate.js
+++ b/dijit/form/nls/th/validate.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "ค่าที่ป้อนไม่ถูกต้อง",
 	missingMessage: "จำเป็นต้องมีค่านี้",
 	rangeMessage: "ค่านี้เกินช่วง"
 })
 
+//end v1.x content
+);
diff --git a/dijit/form/nls/tr/ComboBox.js b/dijit/form/nls/tr/ComboBox.js
index 5a1453e..85a78d2 100644
--- a/dijit/form/nls/tr/ComboBox.js
+++ b/dijit/form/nls/tr/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "Önceki seçenekler",
 		nextMessage: "Diğer seçenekler"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/tr/Textarea.js b/dijit/form/nls/tr/Textarea.js
index 22982eb..21b70fa 100644
--- a/dijit/form/nls/tr/Textarea.js
+++ b/dijit/form/nls/tr/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: 'düzenleme alanı',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: 'düzenleme alanı çerçevesi'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/tr/validate.js b/dijit/form/nls/tr/validate.js
index 7c1f178..e51e2aa 100644
--- a/dijit/form/nls/tr/validate.js
+++ b/dijit/form/nls/tr/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "Girilen değer geçersiz.",
 	missingMessage: "Bu değer gerekli.",
 	rangeMessage: "Bu değer aralık dışında."
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/validate.js b/dijit/form/nls/validate.js
index d63a297..544440b 100644
--- a/dijit/form/nls/validate.js
+++ b/dijit/form/nls/validate.js
@@ -1,5 +1,39 @@
+define({ root:
+//begin v1.x content
 ({
 	invalidMessage: "The value entered is not valid.",
 	missingMessage: "This value is required.",
 	rangeMessage: "This value is out of range."
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/form/nls/zh-tw/ComboBox.js b/dijit/form/nls/zh-tw/ComboBox.js
index 35266ae..c918f01 100644
--- a/dijit/form/nls/zh-tw/ComboBox.js
+++ b/dijit/form/nls/zh-tw/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "前一個選擇項",
 		nextMessage: "其他選擇項"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/zh-tw/Textarea.js b/dijit/form/nls/zh-tw/Textarea.js
index e7b0dec..5a034c7 100644
--- a/dijit/form/nls/zh-tw/Textarea.js
+++ b/dijit/form/nls/zh-tw/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: '編輯區',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '編輯區框'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/zh-tw/validate.js b/dijit/form/nls/zh-tw/validate.js
index 7ab6fb3..05f004e 100644
--- a/dijit/form/nls/zh-tw/validate.js
+++ b/dijit/form/nls/zh-tw/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "輸入的值無效。",
 	missingMessage: "必須提供此值。",
 	rangeMessage: "此值超出範圍。"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/zh/ComboBox.js b/dijit/form/nls/zh/ComboBox.js
index 532cf89..a16792a 100644
--- a/dijit/form/nls/zh/ComboBox.js
+++ b/dijit/form/nls/zh/ComboBox.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 		previousMessage: "先前选项",
 		nextMessage: "更多选项"
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/zh/Textarea.js b/dijit/form/nls/zh/Textarea.js
index e6c5be1..39bda72 100644
--- a/dijit/form/nls/zh/Textarea.js
+++ b/dijit/form/nls/zh/Textarea.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	iframeEditTitle: '编辑区',  // primary title for editable IFRAME, for screen readers when focus is in the editing area
 	iframeFocusTitle: '编辑区框架'  // secondary title for editable IFRAME when focus is on outer container
 									 //  to let user know that focus has moved out of editing area and to the
 									 //  parent element of the editing area
 })
+//end v1.x content
+);
diff --git a/dijit/form/nls/zh/validate.js b/dijit/form/nls/zh/validate.js
index 05b770b..075ce0c 100644
--- a/dijit/form/nls/zh/validate.js
+++ b/dijit/form/nls/zh/validate.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	invalidMessage: "输入的值无效。",
 	missingMessage: "此值是必需值。",
 	rangeMessage: "此值超出范围。"
 })
+//end v1.x content
+);
diff --git a/dijit/form/templates/Button.html b/dijit/form/templates/Button.html
index e60858c..950331d 100644
--- a/dijit/form/templates/Button.html
+++ b/dijit/form/templates/Button.html
@@ -3,7 +3,7 @@
 		dojoAttachEvent="ondijitclick:_onButtonClick"
 		><span class="dijitReset dijitStretch dijitButtonContents"
 			dojoAttachPoint="titleNode,focusNode"
-			waiRole="button" waiState="labelledby-${id}_label"
+			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"
@@ -12,6 +12,6 @@
 			></span
 		></span
 	></span
-	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen"
+	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
 		dojoAttachPoint="valueNode"
 /></span>
\ No newline at end of file
diff --git a/dijit/form/templates/CheckBox.html b/dijit/form/templates/CheckBox.html
index 908a5d9..88e94f7 100644
--- a/dijit/form/templates/CheckBox.html
+++ b/dijit/form/templates/CheckBox.html
@@ -1,4 +1,4 @@
-<div class="dijit dijitReset dijitInline" waiRole="presentation"
+<div class="dijit dijitReset dijitInline" role="presentation"
 	><input
 	 	${!nameAttrSetting} type="${type}" ${checkedAttrSetting}
 		class="dijitReset dijitCheckBoxInput"
diff --git a/dijit/form/templates/ComboBox.html b/dijit/form/templates/ComboBox.html
deleted file mode 100644
index 905e69b..0000000
--- a/dijit/form/templates/ComboBox.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<div class="dijit dijitReset dijitInlineTable dijitLeft"
-	id="widget_${id}"
-	dojoAttachPoint="comboNode" waiRole="combobox"
-	><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer'
-		dojoAttachPoint="downArrowNode" waiRole="presentation"
-		dojoAttachEvent="onmousedown:_onArrowMouseDown"
-		><input class="dijitReset dijitInputField dijitArrowButtonInner" value="▼ " type="text" tabIndex="-1" readOnly waiRole="presentation"
-			${_buttonInputDisabled}
-	/></div
-	><div class='dijitReset dijitValidationContainer'
-		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ " type="text" tabIndex="-1" readOnly waiRole="presentation"
-	/></div
-	><div class="dijitReset dijitInputField dijitInputContainer"
-		><input class='dijitReset dijitInputInner' ${!nameAttrSetting} type="text" autocomplete="off"
-			dojoAttachEvent="onkeypress:_onKeyPress,compositionend"
-			dojoAttachPoint="textbox,focusNode" waiRole="textbox" waiState="haspopup-true,autocomplete-list"
-	/></div
-></div>
diff --git a/dijit/form/templates/ComboButton.html b/dijit/form/templates/ComboButton.html
index 1c3949c..dcd5158 100644
--- a/dijit/form/templates/ComboButton.html
+++ b/dijit/form/templates/ComboButton.html
@@ -1,21 +1,21 @@
 <table class="dijit dijitReset dijitInline dijitLeft"
-	cellspacing='0' cellpadding='0' waiRole="presentation"
-	><tbody waiRole="presentation"><tr waiRole="presentation"
+	cellspacing='0' cellpadding='0' role="presentation"
+	><tbody role="presentation"><tr role="presentation"
 		><td class="dijitReset dijitStretch dijitButtonNode" dojoAttachPoint="buttonNode" dojoAttachEvent="ondijitclick:_onButtonClick,onkeypress:_onButtonKeyPress"
 		><div id="${id}_button" class="dijitReset dijitButtonContents"
 			dojoAttachPoint="titleNode"
-			waiRole="button" waiState="labelledby-${id}_label"
-			><div class="dijitReset dijitInline dijitIcon" dojoAttachPoint="iconNode" waiRole="presentation"></div
-			><div class="dijitReset dijitInline dijitButtonText" id="${id}_label" dojoAttachPoint="containerNode" waiRole="presentation"></div
+			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
 		></td
 		><td id="${id}_arrow" class='dijitReset dijitRight dijitButtonNode dijitArrowButton'
 			dojoAttachPoint="_popupStateNode,focusNode,_buttonNode"
 			dojoAttachEvent="onkeypress:_onArrowKeyPress"
 			title="${optionsTitle}"
-			waiRole="button" waiState="haspopup-true"
-			><div class="dijitReset dijitArrowButtonInner" waiRole="presentation"></div
-			><div class="dijitReset dijitArrowButtonChar" waiRole="presentation">▼</div
+			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"
diff --git a/dijit/form/templates/DropDownBox.html b/dijit/form/templates/DropDownBox.html
new file mode 100644
index 0000000..ece3ae9
--- /dev/null
+++ b/dijit/form/templates/DropDownBox.html
@@ -0,0 +1,16 @@
+<div class="dijit dijitReset dijitInlineTable dijitLeft"
+	id="widget_${id}"
+	role="combobox"
+	><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton dijitArrowButtonContainer'
+		dojoAttachPoint="_buttonNode, _popupStateNode" role="presentation"
+		><input class="dijitReset dijitInputField dijitArrowButtonInner" value="▼ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
+			${_buttonInputDisabled}
+	/></div
+	><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' ${!nameAttrSetting} type="text" autocomplete="off"
+			dojoAttachPoint="textbox,focusNode" role="textbox" aria-haspopup="true"
+	/></div
+></div>
diff --git a/dijit/form/templates/DropDownButton.html b/dijit/form/templates/DropDownButton.html
index d350ff4..fde165d 100644
--- a/dijit/form/templates/DropDownButton.html
+++ b/dijit/form/templates/DropDownButton.html
@@ -3,7 +3,7 @@
 		dojoAttachEvent="ondijitclick:_onButtonClick" dojoAttachPoint="_buttonNode"
 		><span class="dijitReset dijitStretch dijitButtonContents"
 			dojoAttachPoint="focusNode,titleNode,_arrowWrapperNode"
-			waiRole="button" waiState="haspopup-true,labelledby-${id}_label"
+			role="button" aria-haspopup="true" aria-labelledby="${id}_label"
 			><span class="dijitReset dijitInline dijitIcon"
 				dojoAttachPoint="iconNode"
 			></span
@@ -15,6 +15,6 @@
 			><span class="dijitReset dijitInline dijitArrowButtonChar">▼</span
 		></span
 	></span
-	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen"
+	><input ${!nameAttrSetting} type="${type}" value="${value}" class="dijitOffScreen" tabIndex="-1"
 		dojoAttachPoint="valueNode"
 /></span>
diff --git a/dijit/form/templates/HorizontalSlider.html b/dijit/form/templates/HorizontalSlider.html
index 2fff79e..3117f68 100644
--- a/dijit/form/templates/HorizontalSlider.html
+++ b/dijit/form/templates/HorizontalSlider.html
@@ -6,27 +6,27 @@
 	></tr
 	><tr class="dijitReset"
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
-			><div class="dijitSliderDecrementIconH" tabIndex="-1" style="display:none" dojoAttachPoint="decrementButton"><span class="dijitSliderButtonInner">-</span></div
+			><div class="dijitSliderDecrementIconH" style="display:none" dojoAttachPoint="decrementButton"><span class="dijitSliderButtonInner">-</span></div
 		></td
 		><td class="dijitReset"
 			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderLeftBumper" dojoAttachEvent="onmousedown:_onClkDecBumper"></div
 		></td
 		><td class="dijitReset"
 			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
-			/><div class="dijitReset dijitSliderBarContainerH" waiRole="presentation" dojoAttachPoint="sliderBarContainer"
-				><div waiRole="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onmousedown:_onBarClick"
+			/><div class="dijitReset dijitSliderBarContainerH" role="presentation" dojoAttachPoint="sliderBarContainer"
+				><div role="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onmousedown:_onBarClick"
 					><div class="dijitSliderMoveable dijitSliderMoveableH"
-						><div dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleH" dojoAttachEvent="onmousedown:_onHandleClick" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"></div
+						><div dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleH" dojoAttachEvent="onmousedown:_onHandleClick" role="slider" valuemin="${minimum}" valuemax="${maximum}"></div
 					></div
 				></div
-				><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onBarClick"></div
+				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onBarClick"></div
 			></div
 		></td
 		><td class="dijitReset"
 			><div class="dijitSliderBar dijitSliderBumper dijitSliderBumperH dijitSliderRightBumper" dojoAttachEvent="onmousedown:_onClkIncBumper"></div
 		></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerH"
-			><div class="dijitSliderIncrementIconH" tabIndex="-1" style="display:none" dojoAttachPoint="incrementButton"><span class="dijitSliderButtonInner">+</span></div
+			><div class="dijitSliderIncrementIconH" style="display:none" dojoAttachPoint="incrementButton"><span class="dijitSliderButtonInner">+</span></div
 		></td
 	></tr
 	><tr class="dijitReset"
diff --git a/dijit/form/templates/Select.html b/dijit/form/templates/Select.html
index 1e59b59..f671701 100644
--- a/dijit/form/templates/Select.html
+++ b/dijit/form/templates/Select.html
@@ -1,14 +1,14 @@
 <table class="dijit dijitReset dijitInline dijitLeft"
 	dojoAttachPoint="_buttonNode,tableNode,focusNode" cellspacing='0' cellpadding='0'
-	waiRole="combobox" waiState="haspopup-true"
-	><tbody waiRole="presentation"><tr waiRole="presentation"
-		><td class="dijitReset dijitStretch dijitButtonContents dijitButtonNode" waiRole="presentation"
+	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}" waiState="hidden-true"
+			><input type="hidden" ${!nameAttrSetting} dojoAttachPoint="valueNode" value="${value}" aria-hidden="true"
 		/></td><td class="dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton"
-				dojoAttachPoint="titleNode" waiRole="presentation"
-			><div class="dijitReset dijitArrowButtonInner" waiRole="presentation"></div
-			><div class="dijitReset dijitArrowButtonChar" waiRole="presentation">▼</div
+				dojoAttachPoint="titleNode" role="presentation"
+			><div class="dijitReset dijitArrowButtonInner" role="presentation"></div
+			><div class="dijitReset dijitArrowButtonChar" role="presentation">▼</div
 		></td
 	></tr></tbody
 ></table>
diff --git a/dijit/form/templates/Spinner.html b/dijit/form/templates/Spinner.html
index 75fe79f..34f1b1d 100644
--- a/dijit/form/templates/Spinner.html
+++ b/dijit/form/templates/Spinner.html
@@ -1,27 +1,27 @@
 <div class="dijit dijitReset dijitInlineTable dijitLeft"
-	id="widget_${id}" waiRole="presentation"
+	id="widget_${id}" role="presentation"
 	><div class="dijitReset dijitButtonNode dijitSpinnerButtonContainer"
-		><input class="dijitReset dijitInputField dijitSpinnerButtonInner" type="text" tabIndex="-1" readOnly waiRole="presentation"
+		><input class="dijitReset dijitInputField dijitSpinnerButtonInner" type="text" tabIndex="-1" readonly="readonly" role="presentation"
 		/><div class="dijitReset dijitLeft dijitButtonNode dijitArrowButton dijitUpArrowButton"
 			dojoAttachPoint="upArrowNode"
 			><div class="dijitArrowButtonInner"
-				><input class="dijitReset dijitInputField" value="▲" type="text" tabIndex="-1" readOnly waiRole="presentation"
+				><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"
 			><div class="dijitArrowButtonInner"
-				><input class="dijitReset dijitInputField" value="▼" type="text" tabIndex="-1" readOnly waiRole="presentation"
+				><input class="dijitReset dijitInputField" value="▼" type="text" tabIndex="-1" readonly="readonly" role="presentation"
 					${_buttonInputDisabled}
 			/></div
 		></div
 	></div
 	><div class='dijitReset dijitValidationContainer'
-		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ " type="text" tabIndex="-1" readOnly waiRole="presentation"
+		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ" type="text" tabIndex="-1" readonly="readonly" role="presentation"
 	/></div
 	><div class="dijitReset dijitInputField dijitInputContainer"
 		><input class='dijitReset dijitInputInner' dojoAttachPoint="textbox,focusNode" type="${type}" dojoAttachEvent="onkeypress:_onKeyPress"
-			waiRole="spinbutton" autocomplete="off" ${!nameAttrSetting}
+			role="spinbutton" autocomplete="off" ${!nameAttrSetting}
 	/></div
 ></div>
diff --git a/dijit/form/templates/TextBox.html b/dijit/form/templates/TextBox.html
index c57d876..3b3a602 100644
--- a/dijit/form/templates/TextBox.html
+++ b/dijit/form/templates/TextBox.html
@@ -1,4 +1,4 @@
-<div class="dijit dijitReset dijitInline dijitLeft" id="widget_${id}" waiRole="presentation"
+<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"
 			${!nameAttrSetting} type='${type}'
diff --git a/dijit/form/templates/ValidationTextBox.html b/dijit/form/templates/ValidationTextBox.html
index 64b0683..f1e80ba 100644
--- a/dijit/form/templates/ValidationTextBox.html
+++ b/dijit/form/templates/ValidationTextBox.html
@@ -1,7 +1,7 @@
 <div class="dijit dijitReset dijitInlineTable dijitLeft"
-	id="widget_${id}" waiRole="presentation"
+	id="widget_${id}" role="presentation"
 	><div class='dijitReset dijitValidationContainer'
-		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ " type="text" tabIndex="-1" readOnly waiRole="presentation"
+		><input class="dijitReset dijitInputField dijitValidationIcon dijitValidationInner" value="Χ " type="text" tabIndex="-1" readonly="readonly" role="presentation"
 	/></div
 	><div class="dijitReset dijitInputField dijitInputContainer"
 		><input class="dijitReset dijitInputInner" dojoAttachPoint='textbox,focusNode' autocomplete="off"
diff --git a/dijit/form/templates/VerticalSlider.html b/dijit/form/templates/VerticalSlider.html
index 751912c..989ca29 100644
--- a/dijit/form/templates/VerticalSlider.html
+++ b/dijit/form/templates/VerticalSlider.html
@@ -2,7 +2,7 @@
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
-			><div class="dijitSliderIncrementIconV" tabIndex="-1" style="display:none" dojoAttachPoint="decrementButton"><span class="dijitSliderButtonInner">+</span></div
+			><div class="dijitSliderIncrementIconV" style="display:none" dojoAttachPoint="decrementButton"><span class="dijitSliderButtonInner">+</span></div
 		></td
 		><td class="dijitReset"></td
 	></tr
@@ -15,13 +15,13 @@
 	></tr
 	><tr class="dijitReset"
 		><td dojoAttachPoint="leftDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationL dijitSliderDecorationV"></td
-		><td class="dijitReset" style="height:100%;"
+		><td class="dijitReset dijitSliderDecorationC" style="height:100%;"
 			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
-			/><center class="dijitReset dijitSliderBarContainerV" waiRole="presentation" dojoAttachPoint="sliderBarContainer"
-				><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onmousedown:_onBarClick"><!--#5629--></div
-				><div waiRole="presentation" dojoAttachPoint="progressBar" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onmousedown:_onBarClick"
+			/><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"
 					><div class="dijitSliderMoveable dijitSliderMoveableV" style="vertical-align:top;"
-						><div dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleV" dojoAttachEvent="onmousedown:_onHandleClick" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"></div
+						><div dojoAttachPoint="sliderHandle,focusNode" class="dijitSliderImageHandle dijitSliderImageHandleV" dojoAttachEvent="onmousedown:_onHandleClick" role="slider" valuemin="${minimum}" valuemax="${maximum}"></div
 					></div
 				></div
 			></center
@@ -38,7 +38,7 @@
 	><tr class="dijitReset"
 		><td class="dijitReset"></td
 		><td class="dijitReset dijitSliderButtonContainer dijitSliderButtonContainerV"
-			><div class="dijitSliderDecrementIconV" tabIndex="-1" style="display:none" dojoAttachPoint="incrementButton"><span class="dijitSliderButtonInner">-</span></div
+			><div class="dijitSliderDecrementIconV" style="display:none" dojoAttachPoint="incrementButton"><span class="dijitSliderButtonInner">-</span></div
 		></td
 		><td class="dijitReset"></td
 	></tr
diff --git a/dijit/layout/AccordionContainer.js b/dijit/layout/AccordionContainer.js
index 86f5386..23a16fc 100644
--- a/dijit/layout/AccordionContainer.js
+++ b/dijit/layout/AccordionContainer.js
@@ -1,14 +1,27 @@
-dojo.provide("dijit.layout.AccordionContainer");
-
-dojo.require("dojo.fx");
-
-dojo.require("dijit._Container");
-dojo.require("dijit._Templated");
-dojo.require("dijit._CssStateMixin");
-dojo.require("dijit.layout.StackContainer");
-dojo.require("dijit.layout.ContentPane");
-
-dojo.require("dijit.layout.AccordionPane");	// for back compat, remove for 2.0
+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",
@@ -34,17 +47,18 @@ dojo.declare(
 		//		The name of the widget used to display the title of each pane
 		buttonWidget: "dijit.layout._AccordionButton",
 
+/*=====
 		// _verticalSpace: Number
 		//		Pixels of space available for the open pane
 		//		(my content box size minus the cumulative size of all the title bars)
 		_verticalSpace: 0,
-
+=====*/
 		baseClass: "dijitAccordionContainer",
 
-		postCreate: function(){
-			this.domNode.style.overflow = "hidden";
+		buildRendering: function(){
 			this.inherited(arguments);
-			dijit.setWaiRole(this.domNode, "tablist");
+			this.domNode.style.overflow = "hidden";		// TODO: put this in dijit.css
+			dijit.setWaiRole(this.domNode, "tablist");	// TODO: put this in template
 		},
 
 		startup: function(){
@@ -58,20 +72,6 @@ dojo.declare(
 			}
 		},
 
-		_getTargetHeight: function(/* Node */ node){
-			// summary:
-			//		For the given node, returns the height that should be
-			//		set to achieve our vertical space (subtract any padding
-			//		we may have).
-			//
-			//		This is used by the animations.
-			//
-			//		TODO: I don't think this works correctly in IE quirks when an elements
-			//		style.height including padding and borders
-			var cs = dojo.getComputedStyle(node);
-			return Math.max(this._verticalSpace - dojo._getPadBorderExtents(node, cs).h - dojo._getMarginExtents(node, cs).h, 0);
-		},
-
 		layout: function(){
 			// Implement _LayoutWidget.layout() virtual method.
 			// Set the height of the open pane based on what room remains.
@@ -80,25 +80,31 @@ dojo.declare(
 			
 			if(!openPane){ return;}
 
-			var openPaneContainer = openPane._wrapperWidget.domNode,
-				openPaneContainerMargin = dojo._getMarginExtents(openPaneContainer),
-				openPaneContainerPadBorder = dojo._getPadBorderExtents(openPaneContainer),
+			// 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),
+				wrapperContainerNode = openPane._wrapperWidget.containerNode,
+				wrapperContainerNodeMargin = dojo._getMarginExtents(wrapperContainerNode),
+				wrapperContainerNodePadBorder = dojo._getPadBorderExtents(wrapperContainerNode),
 				mySize = this._contentBox;
 
 			// get cumulative height of all the unselected title bars
 			var totalCollapsedHeight = 0;
 			dojo.forEach(this.getChildren(), function(child){
 	            if(child != openPane){
-					totalCollapsedHeight += dojo.marginBox(child._wrapperWidget.domNode).h;
+					totalCollapsedHeight += dojo._getMarginSize(child._wrapperWidget.domNode).h;
 				}
 			});
-			this._verticalSpace = mySize.h - totalCollapsedHeight - openPaneContainerMargin.h 
-			 	- openPaneContainerPadBorder.h - openPane._buttonWidget.getTitleHeight();
+			this._verticalSpace = mySize.h - totalCollapsedHeight - wrapperDomNodeMargin.h
+			 	- wrapperDomNodePadBorder.h - wrapperContainerNodeMargin.h - wrapperContainerNodePadBorder.h
+				- openPane._buttonWidget.getTitleHeight();
 
 			// Memo size to make displayed child
 			this._containerContentBox = {
 				h: this._verticalSpace,
-				w: this._contentBox.w - openPaneContainerMargin.w - openPaneContainerPadBorder.w
+				w: this._contentBox.w - wrapperDomNodeMargin.w - wrapperDomNodePadBorder.w
+					- wrapperContainerNodeMargin.w - wrapperContainerNodePadBorder.w
 			};
 
 			if(openPane){
@@ -122,7 +128,7 @@ dojo.declare(
 			this.inherited(arguments);
 		},
 
-		addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){	
+		addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
 			if(this._started){
 				// Adding a child to a started Accordion is complicated because children have
 				// wrapper widgets.  Default code path (calling this.inherited()) would add
@@ -138,7 +144,7 @@ dojo.declare(
 				// Then stick the wrapper widget around the child widget
 				this._setupChild(child);
 
-				// Code below copied from StackContainer	
+				// Code below copied from StackContainer
 				dojo.publish(this.id+"-addChild", [child, insertIndex]);
 				this.layout();
 				if(!this.selectedChildWidget){
@@ -154,9 +160,15 @@ dojo.declare(
 		removeChild: function(child){
 			// Overrides _LayoutWidget.removeChild().
 
-			// destroy wrapper widget first, before StackContainer.getChildren() call
-			child._wrapperWidget.destroy();
-			delete child._wrapperWidget;
+			// Destroy wrapper widget first, before StackContainer.getChildren() call.
+			// Replace wrapper widget with true child widget (ContentPane etc.).
+			// This step only happens if the AccordionContainer has been started; otherwise there's no wrapper.
+			if(child._wrapperWidget){
+				dojo.place(child.domNode, child._wrapperWidget.domNode, "after");
+				child._wrapperWidget.destroy();
+				delete child._wrapperWidget;
+			}
+
 			dojo.removeClass(child.domNode, "dijitHidden");
 
 			this.inherited(arguments);
@@ -170,23 +182,53 @@ dojo.declare(
 		},
 
 		destroy: function(){
+			if(this._animation){
+				this._animation.stop();
+			}
 			dojo.forEach(this.getChildren(), function(child){
-				child._wrapperWidget.destroy();
+				// If AccordionContainer has been started, then each child has a wrapper widget which
+				// also needs to be destroyed.
+				if(child._wrapperWidget){
+					child._wrapperWidget.destroy();
+				}else{
+					child.destroyRecursive();
+				}
 			});
 			this.inherited(arguments);
 		},
 
-		_transition: function(/*dijit._Widget?*/newWidget, /*dijit._Widget?*/oldWidget, /*Boolean*/ animate){
+		_showChild: function(child){
+			// Override StackContainer._showChild() to set visibility of _wrapperWidget.containerNode
+			child._wrapperWidget.containerNode.style.display="block";
+			return this.inherited(arguments);
+		},
+
+		_hideChild: function(child){
+			// Override StackContainer._showChild() to set visibility of _wrapperWidget.containerNode
+			child._wrapperWidget.containerNode.style.display="none";
+			this.inherited(arguments);
+		},
+
+		_transition: function(/*dijit._Widget?*/ newWidget, /*dijit._Widget?*/ oldWidget, /*Boolean*/ animate){
 			// Overrides StackContainer._transition() to provide sliding of title bars etc.
 
-//TODO: should be able to replace this with calls to slideIn/slideOut
-			if(this._inTransition){ return; }
-			var animations = [];
-			var paneHeight = this._verticalSpace;
+			if(dojo.isIE < 8){
+				// workaround animation bugs by not animating; not worth supporting animation for IE6 & 7
+				animate = false;
+			}
+
+			if(this._animation){
+				// there's an in-progress animation.  speedily end it so we can do the newly requested one
+				this._animation.stop(true);
+				delete this._animation;
+			}
+
+			var self = this;
+
 			if(newWidget){
 				newWidget._wrapperWidget.set("selected", true);
 
-				this._showChild(newWidget);	// prepare widget to be slid in
+				var d = this._showChild(newWidget);	// prepare widget to be slid in
 
 				// Size the new widget, in case this is the first time it's being shown,
 				// or I have been resized since the last time it was shown.
@@ -194,74 +236,51 @@ dojo.declare(
 				if(this.doLayout && newWidget.resize){
 					newWidget.resize(this._containerContentBox);
 				}
-
-				var newContents = newWidget.domNode;
-				dojo.addClass(newContents, "dijitVisible");
-				dojo.removeClass(newContents, "dijitHidden");
-				
-				if(animate){
-					var newContentsOverflow = newContents.style.overflow;
-					newContents.style.overflow = "hidden";
-					animations.push(dojo.animateProperty({
-						node: newContents,
-						duration: this.duration,
-						properties: {
-							height: { start: 1, end: this._getTargetHeight(newContents) }
-						},
-						onEnd: function(){
-							newContents.style.overflow = newContentsOverflow;
-
-							// Kick IE to workaround layout bug, see #11415
-							if(dojo.isIE){
-								setTimeout(function(){
-									dojo.removeClass(newContents.parentNode, "dijitAccordionInnerContainerFocused");
-									setTimeout(function(){
-										dojo.addClass(newContents.parentNode, "dijitAccordionInnerContainerFocused");
-									}, 0);
-								}, 0);
-							}
-						}
-					}));
-				}
 			}
+
 			if(oldWidget){
 				oldWidget._wrapperWidget.set("selected", false);
-				var oldContents = oldWidget.domNode;
-				if(animate){
-					var oldContentsOverflow = oldContents.style.overflow;
-					oldContents.style.overflow = "hidden";
-					animations.push(dojo.animateProperty({
-						node: oldContents,
-						duration: this.duration,
-						properties: {
-							height: { start: this._getTargetHeight(oldContents), end: 1 }
-						},
-						onEnd: function(){
-							dojo.addClass(oldContents, "dijitHidden");
-							dojo.removeClass(oldContents, "dijitVisible");
-							oldContents.style.overflow = oldContentsOverflow;
-							if(oldWidget.onHide){
-								oldWidget.onHide();
-							}
-						}
-					}));
-				}else{
-					dojo.addClass(oldContents, "dijitHidden");
-					dojo.removeClass(oldContents, "dijitVisible");
-					if(oldWidget.onHide){
-						oldWidget.onHide();
-					}
+				if(!animate){
+					this._hideChild(oldWidget);
 				}
 			}
 
 			if(animate){
-				this._inTransition = true;
-				var combined = dojo.fx.combine(animations);
-				combined.onEnd = dojo.hitch(this, function(){
-					delete this._inTransition;
+				var newContents = newWidget._wrapperWidget.containerNode,
+					oldContents = oldWidget._wrapperWidget.containerNode;
+
+				// During the animation we will be showing two dijitAccordionChildWrapper nodes at once,
+				// 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),
+					animationHeightOverhead = wrapperContainerNodeMargin.h + wrapperContainerNodePadBorder.h;
+
+				oldContents.style.height = (self._verticalSpace - animationHeightOverhead) + "px";
+
+				this._animation = new dojo.Animation({
+					node: newContents,
+					duration: this.duration,
+					curve: [1, this._verticalSpace - animationHeightOverhead - 1],
+					onAnimate: function(value){
+						value = Math.floor(value);	// avoid fractional values
+						newContents.style.height = value + "px";
+						oldContents.style.height = (self._verticalSpace - animationHeightOverhead - value) + "px";
+					},
+					onEnd: function(){
+						delete self._animation;
+						newContents.style.height = "auto";
+						oldWidget._wrapperWidget.containerNode.style.display = "none";
+						oldContents.style.height = "auto";
+						self._hideChild(oldWidget);
+					}
 				});
-				combined.play();
-			}			
+				this._animation.onStop = this._animation.onEnd;
+				this._animation.play();
+			}
+
+			return d;	// If child has an href, promise that fires when the widget has finished loading
 		},
 
 		// note: we are treating the container as controller here
@@ -272,10 +291,7 @@ dojo.declare(
 			//		This is called from a handler on AccordionContainer.domNode
 			//		(setup in StackContainer), and is also called directly from
 			//		the click handler for accordion labels
-			if(this._inTransition || this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
-				if(this._inTransition){
-					dojo.stopEvent(e);
-				}
+			if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
 				return;
 			}
 			var k = dojo.keys,
@@ -300,16 +316,17 @@ dojo.declare("dijit.layout._AccordionInnerContainer",
 		//		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,
 =====*/
 
@@ -319,7 +336,15 @@ dojo.declare("dijit.layout._AccordionInnerContainer",
 		isContainer: true,
 		isLayoutContainer: true,
 
-		buildRendering: function(){			
+		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");
 			
@@ -337,22 +362,32 @@ dojo.declare("dijit.layout._AccordionInnerContainer",
 				parent: this.parent
 			})).placeAt(this.domNode);
 			
-			// and then the actual content widget (changing it from prior-sibling to last-child)
-			dojo.place(this.contentWidget.domNode, 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);
-			this.connect(this.contentWidget, 'set', function(name, value){
-				var mappedName = {title: "label", tooltip: "title", iconClass: "iconClass"}[name];
-				if(mappedName){
-					this.button.set(mappedName, value);
-				}
-			}, this);
+
+			// 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.selected = isSelected;
+			this._set("selected", isSelected);
 			this.button.set("selected", isSelected);
 			if(isSelected){
 				var cw = this.contentWidget;
@@ -367,7 +402,9 @@ dojo.declare("dijit.layout._AccordionInnerContainer",
 
 		destroy: function(){
 			this.button.destroyRecursive();
-			
+
+			dojo.forEach(this._contentWidgetWatches || [], function(w){ w.unwatch(); });
+
 			delete this.contentWidget._buttonWidget;
 			delete this.contentWidget._wrapperWidget;
 
@@ -406,18 +443,18 @@ dojo.declare("dijit.layout._AccordionButton",
 		return this.parent;
 	},
 
-	postCreate: function(){
+	buildRendering: function(){
 		this.inherited(arguments);
-		dojo.setSelectable(this.domNode, false);
-		var titleTextNodeId = dojo.attr(this.domNode,'id').replace(' ','_');
+		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.marginBox(this.domNode).h;	// Integer
+		return dojo._getMarginSize(this.domNode).h;	// Integer
 	},
 
 	// TODO: maybe the parent should set these methods directly rather than forcing the code
@@ -426,10 +463,8 @@ dojo.declare("dijit.layout._AccordionButton",
 		// summary:
 		//		Callback when someone clicks my title.
 		var parent = this.getParent();
-		if(!parent._inTransition){
 			parent.selectChild(this.contentWidget, true);
 			dijit.focus(this.focusNode);
-		}
 	},
 
 	_onTitleKeyPress: function(/*Event*/ evt){
@@ -437,9 +472,13 @@ dojo.declare("dijit.layout._AccordionButton",
 	},
 
 	_setSelectedAttr: function(/*Boolean*/ isSelected){
-		this.selected = isSelected;
+		this._set("selected", isSelected);
 		dijit.setWaiState(this.focusNode, "expanded", isSelected);
 		dijit.setWaiState(this.focusNode, "selected", isSelected);
 		this.focusNode.setAttribute("tabIndex", isSelected ? "0" : "-1");
 	}
 });
+
+
+return dijit.layout.AccordionContainer;
+});
diff --git a/dijit/layout/AccordionPane.js b/dijit/layout/AccordionPane.js
index e44fca1..aceef97 100644
--- a/dijit/layout/AccordionPane.js
+++ b/dijit/layout/AccordionPane.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.layout.AccordionPane");
-
-dojo.require("dijit.layout.ContentPane");
+define("dijit/layout/AccordionPane", ["dojo", "dijit", "dijit/layout/ContentPane"], function(dojo, dijit) {
 
 dojo.declare("dijit.layout.AccordionPane", dijit.layout.ContentPane, {
 	// summary:
@@ -17,3 +15,7 @@ dojo.declare("dijit.layout.AccordionPane", dijit.layout.ContentPane, {
 		//		called when this pane is selected
 	}
 });
+
+
+return dijit.layout.AccordionPane;
+});
diff --git a/dijit/layout/BorderContainer.js b/dijit/layout/BorderContainer.js
index f2b8368..74db0e1 100644
--- a/dijit/layout/BorderContainer.js
+++ b/dijit/layout/BorderContainer.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.layout.BorderContainer");
-
-dojo.require("dijit.layout._LayoutWidget");
-dojo.require("dojo.cookie");
+define("dijit/layout/BorderContainer", ["dojo", "dijit", "dijit/layout/_LayoutWidget", "dojo/cookie", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.layout.BorderContainer",
@@ -18,19 +15,21 @@ dojo.declare(
 	//		include optional splitters (splitter="true") to make them resizable by the user.  The remaining
 	//		space is designated for the center region.
 	//
-	//		NOTE: Splitters must not be more than 50 pixels in width.
-	//
 	//		The outer size must be specified on the BorderContainer node.  Width must be specified for the sides
 	//		and height for the top and bottom, respectively.  No dimensions should be specified on the center;
 	//		it will fill the remaining space.  Regions named "leading" and "trailing" may be used just like
 	//		"left" and "right" except that they will be reversed in right-to-left environments.
 	//
+	//		For complex layouts, multiple children can be specified for a single region.   In this case, the
+	//		layoutPriority flag on the children determines which child is closer to the edge (low layoutPriority)
+	//		and which child is closer to the center (high layoutPriority).   layoutPriority can also be used
+	//		instead of the design attribute to conrol layout precedence of horizontal vs. vertical panes.
 	// example:
 	// |	<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false"
 	// |            style="width: 400px; height: 300px;">
-	// |		<div dojoType="ContentPane" region="top">header text</div>
-	// |		<div dojoType="ContentPane" region="right" splitter="true" style="width: 200px;">table of contents</div>
-	// |		<div dojoType="ContentPane" region="center">client area</div>
+	// |		<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>
 
 	// design: String
@@ -40,13 +39,13 @@ dojo.declare(
 	//			- "sidebar" where the left and right sides extend from top to bottom.
 	design: "headline",
 
-	// gutters: Boolean
+	// gutters: [const] Boolean
 	//		Give each pane a border and margin.
 	//		Margin determined by domNode.paddingLeft.
 	//		When false, only resizable panes have a gutter (i.e. draggable splitter) for resizing.
 	gutters: true,
 
-	// liveSplitters: Boolean
+	// liveSplitters: [const] Boolean
 	//		Specifies whether splitters resize as you drag (true) or only upon mouseup (false)
 	liveSplitters: true,
 
@@ -69,13 +68,6 @@ dojo.declare(
 		this.inherited(arguments);
 	},
 
-	postCreate: function(){
-		this.inherited(arguments);
-
-		this._splitters = {};
-		this._splitterThickness = {};
-	},
-
 	startup: function(){
 		if(this._started){ return; }
 		dojo.forEach(this.getChildren(), this._setupChild, this);
@@ -95,14 +87,10 @@ dojo.declare(
 			if(region == "leading"){ region = ltr ? "left" : "right"; }
 			if(region == "trailing"){ region = ltr ? "right" : "left"; }
 
-			//FIXME: redundant?
-			this["_"+region] = child.domNode;
-			this["_"+region+"Widget"] = child;
-
 			// Create draggable splitter for resizing pane,
 			// or alternately if splitter=false but BorderContainer.gutters=true then
 			// insert dummy div just for spacing
-			if((child.splitter || this.gutters) && !this._splitters[region]){
+			if(region != "center" && (child.splitter || this.gutters) && !child._splitterWidget){
 				var _Splitter = dojo.getObject(child.splitter ? this._splitterClass : "dijit.layout._Gutter");
 				var splitter = new _Splitter({
 					id: child.id + "_splitter",
@@ -112,24 +100,19 @@ dojo.declare(
 					live: this.liveSplitters
 				});
 				splitter.isSplitter = true;
-				this._splitters[region] = splitter.domNode;
-				dojo.place(this._splitters[region], child.domNode, "after");
+				child._splitterWidget = splitter;
+
+				dojo.place(splitter.domNode, child.domNode, "after");
 
-				// Splitters arent added as Contained children, so we need to call startup explicitly
+				// Splitters aren't added as Contained children, so we need to call startup explicitly
 				splitter.startup();
 			}
-			child.region = region;
+			child.region = region;	// TODO: technically wrong since it overwrites "trailing" with "left" etc.
 		}
 	},
 
-	_computeSplitterThickness: function(region){
-		this._splitterThickness[region] = this._splitterThickness[region] ||
-			dojo.marginBox(this._splitters[region])[(/top|bottom/.test(region) ? 'h' : 'w')];
-	},
-
 	layout: function(){
 		// Implement _LayoutWidget.layout() virtual method.
-		for(var region in this._splitters){ this._computeSplitterThickness(region); }
 		this._layoutChildren();
 	},
 
@@ -143,20 +126,29 @@ dojo.declare(
 
 	removeChild: function(/*dijit._Widget*/ child){
 		// Override _LayoutWidget.removeChild().
+
 		var region = child.region;
-		var splitter = this._splitters[region];
+		var splitter = child._splitterWidget
 		if(splitter){
-			dijit.byNode(splitter).destroy();
-			delete this._splitters[region];
-			delete this._splitterThickness[region];
+			splitter.destroy();
+			delete child._splitterWidget;
 		}
 		this.inherited(arguments);
-		delete this["_"+region];
-		delete this["_" +region+"Widget"];
+		
 		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, {
+			top: "auto",
+			bottom: "auto",
+			left: "auto",
+			right: "auto",
+			position: "static"
+		});
+		dojo.style(child.domNode, region == "top" || region == "bottom" ? "width" : "height", "auto");
 	},
 
 	getChildren: function(){
@@ -166,11 +158,15 @@ dojo.declare(
 		});
 	},
 
+	// TODO: remove in 2.0
 	getSplitter: function(/*String*/region){
 		// summary:
 		//		Returns the widget responsible for rendering the splitter associated with region
-		var splitter = this._splitters[region];
-		return splitter ? dijit.byNode(splitter) : null;
+		// tags:
+		//		deprecated
+		return dojo.filter(this.getChildren(), function(child){
+			return child.region == region;
+		})[0]._splitterWidget;
 	},
 
 	resize: function(newSize, currentSize){
@@ -191,7 +187,7 @@ dojo.declare(
 		this.inherited(arguments);
 	},
 
-	_layoutChildren: function(/*String?*/changedRegion, /*Number?*/ changedRegionSize){
+	_layoutChildren: function(/*String?*/ changedChildId, /*Number?*/ changedChildSize){
 		// summary:
 		//		This is the main routine for setting size/position of each child.
 		// description:
@@ -201,11 +197,10 @@ dojo.declare(
 		//		With changedRegion specified (as "left", "top", "bottom", or "right"),
 		//		it changes that region's width/height to changedRegionSize and
 		//		then resizes other regions that were affected.
-		// changedRegion:
-		//		The region should be changed because splitter was dragged.
-		//		"left", "right", "top", or "bottom".
-		// changedRegionSize:
-		//		The new width/height (in pixels) to make changedRegion
+		// changedChildId:
+		//		Id of the child which should be resized because splitter was dragged.
+		// changedChildSize:
+		//		The new width/height (in pixels) to make specified child
 
 		if(!this._borderBox || !this._borderBox.h){
 			// We are currently hidden, or we haven't been sized by our parent yet.
@@ -213,196 +208,63 @@ dojo.declare(
 			return;
 		}
 
-		var sidebarLayout = (this.design == "sidebar");
-		var topHeight = 0, bottomHeight = 0, leftWidth = 0, rightWidth = 0;
-		var topStyle = {}, leftStyle = {}, rightStyle = {}, bottomStyle = {},
-			centerStyle = (this._center && this._center.style) || {};
-
-		var changedSide = /left|right/.test(changedRegion);
-
-		var layoutSides = !changedRegion || (!changedSide && !sidebarLayout);
-		var layoutTopBottom = !changedRegion || (changedSide && sidebarLayout);
-
-		// Ask browser for width/height of side panes.
-		// Would be nice to cache this but height can change according to width
-		// (because words wrap around).  I don't think width will ever change though
-		// (except when the user drags a splitter).
-		if(this._top){
-			topStyle = (changedRegion == "top" || layoutTopBottom) && this._top.style;
-			topHeight = changedRegion == "top" ? changedRegionSize : dojo.marginBox(this._top).h;
-		}
-		if(this._left){
-			leftStyle = (changedRegion == "left" || layoutSides) && this._left.style;
-			leftWidth = changedRegion == "left" ? changedRegionSize : dojo.marginBox(this._left).w;
-		}
-		if(this._right){
-			rightStyle = (changedRegion == "right" || layoutSides) && this._right.style;
-			rightWidth = changedRegion == "right" ? changedRegionSize : dojo.marginBox(this._right).w;
-		}
-		if(this._bottom){
-			bottomStyle = (changedRegion == "bottom" || layoutTopBottom) && this._bottom.style;
-			bottomHeight = changedRegion == "bottom" ? changedRegionSize : dojo.marginBox(this._bottom).h;
-		}
-
-		var splitters = this._splitters;
-		var topSplitter = splitters.top, bottomSplitter = splitters.bottom,
-			leftSplitter = splitters.left, rightSplitter = splitters.right;
-		var splitterThickness = this._splitterThickness;
-		var topSplitterThickness = splitterThickness.top || 0,
-			leftSplitterThickness = splitterThickness.left || 0,
-			rightSplitterThickness = splitterThickness.right || 0,
-			bottomSplitterThickness = splitterThickness.bottom || 0;
-
-		// Check for race condition where CSS hasn't finished loading, so
-		// the splitter width == the viewport width (#5824)
-		if(leftSplitterThickness > 50 || rightSplitterThickness > 50){
-			setTimeout(dojo.hitch(this, function(){
-				// Results are invalid.  Clear them out.
-				this._splitterThickness = {};
-
-				for(var region in this._splitters){
-					this._computeSplitterThickness(region);
+		// 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){
+			return {
+				pane: child,
+				weight: [
+					child.region == "center" ? Infinity : 0,
+					child.layoutPriority,
+					(this.design == "sidebar" ? 1 : -1) * (/top|bottom/.test(child.region) ? 1 : -1),
+					idx
+				]
+			};
+		}, this);
+		wrappers.sort(function(a, b){
+			var aw = a.weight, bw = b.weight;
+			for(var i=0; i<aw.length; i++){
+				if(aw[i] != bw[i]){
+					return aw[i] - bw[i];
 				}
-				this._layoutChildren();
-			}), 50);
-			return false;
-		}
-
-		var pe = this.pe;
-
-		var splitterBounds = {
-			left: (sidebarLayout ? leftWidth + leftSplitterThickness: 0) + pe.l + "px",
-			right: (sidebarLayout ? rightWidth + rightSplitterThickness: 0) + pe.r + "px"
-		};
-
-		if(topSplitter){
-			dojo.mixin(topSplitter.style, splitterBounds);
-			topSplitter.style.top = topHeight + pe.t + "px";
-		}
-
-		if(bottomSplitter){
-			dojo.mixin(bottomSplitter.style, splitterBounds);
-			bottomSplitter.style.bottom = bottomHeight + pe.b + "px";
-		}
-
-		splitterBounds = {
-			top: (sidebarLayout ? 0 : topHeight + topSplitterThickness) + pe.t + "px",
-			bottom: (sidebarLayout ? 0 : bottomHeight + bottomSplitterThickness) + pe.b + "px"
-		};
-
-		if(leftSplitter){
-			dojo.mixin(leftSplitter.style, splitterBounds);
-			leftSplitter.style.left = leftWidth + pe.l + "px";
-		}
-
-		if(rightSplitter){
-			dojo.mixin(rightSplitter.style, splitterBounds);
-			rightSplitter.style.right = rightWidth + pe.r +	"px";
-		}
-
-		dojo.mixin(centerStyle, {
-			top: pe.t + topHeight + topSplitterThickness + "px",
-			left: pe.l + leftWidth + leftSplitterThickness + "px",
-			right: pe.r + rightWidth + rightSplitterThickness + "px",
-			bottom: pe.b + bottomHeight + bottomSplitterThickness + "px"
+			}
+			return 0;
 		});
 
-		var bounds = {
-			top: sidebarLayout ? pe.t + "px" : centerStyle.top,
-			bottom: sidebarLayout ? pe.b + "px" : centerStyle.bottom
-		};
-		dojo.mixin(leftStyle, bounds);
-		dojo.mixin(rightStyle, bounds);
-		leftStyle.left = pe.l + "px"; rightStyle.right = pe.r + "px"; topStyle.top = pe.t + "px"; bottomStyle.bottom = pe.b + "px";
-		if(sidebarLayout){
-			topStyle.left = bottomStyle.left = leftWidth + leftSplitterThickness + pe.l + "px";
-			topStyle.right = bottomStyle.right = rightWidth + rightSplitterThickness + pe.r + "px";
-		}else{
-			topStyle.left = bottomStyle.left = pe.l + "px";
-			topStyle.right = bottomStyle.right = pe.r + "px";
-		}
-
-		// More calculations about sizes of panes
-		var containerHeight = this._borderBox.h - pe.t - pe.b,
-			middleHeight = containerHeight - ( topHeight + topSplitterThickness + bottomHeight + bottomSplitterThickness),
-			sidebarHeight = sidebarLayout ? containerHeight : middleHeight;
-
-		var containerWidth = this._borderBox.w - pe.l - pe.r,
-			middleWidth = containerWidth - (leftWidth + leftSplitterThickness + rightWidth + rightSplitterThickness),
-			sidebarWidth = sidebarLayout ? middleWidth : containerWidth;
+		// Make new list, combining the externally specified children with splitters and gutters
+		var childrenAndSplitters = [];
+		dojo.forEach(wrappers, function(wrapper){
+			var pane = wrapper.pane;
+			childrenAndSplitters.push(pane);
+			if(pane._splitterWidget){
+				childrenAndSplitters.push(pane._splitterWidget);
+			}
+		});
 
-		// New margin-box size of each pane
+		// Compute the box in which to lay out my children
 		var dim = {
-			top:	{ w: sidebarWidth, h: topHeight },
-			bottom: { w: sidebarWidth, h: bottomHeight },
-			left:	{ w: leftWidth, h: sidebarHeight },
-			right:	{ w: rightWidth, h: sidebarHeight },
-			center:	{ h: middleHeight, w: middleWidth }
+			l: this.pe.l,
+			t: this.pe.t,
+			w: this._borderBox.w - this.pe.w,
+			h: this._borderBox.h - this.pe.h
 		};
 
-		if(changedRegion){
-			// Respond to splitter drag event by changing changedRegion's width or height
-			var child = this["_" + changedRegion + "Widget"],
-				mb = {};
-				mb[ /top|bottom/.test(changedRegion) ? "h" : "w"] = changedRegionSize;
-			child.resize ? child.resize(mb, dim[child.region]) : dojo.marginBox(child.domNode, mb);
-		}
+		// Layout the children, possibly changing size due to a splitter drag
+		dijit.layout.layoutChildren(this.domNode, dim, childrenAndSplitters,
+			changedChildId, changedChildSize);
+	},
 
-		// Nodes in IE<8 don't respond to t/l/b/r, and TEXTAREA doesn't respond in any browser
-		var janky = dojo.isIE < 8 || (dojo.isIE && dojo.isQuirks) || dojo.some(this.getChildren(), function(child){
-			return child.domNode.tagName == "TEXTAREA" || child.domNode.tagName == "INPUT";
+	destroyRecursive: function(){
+		// Destroy splitters first, while getChildren() still works
+		dojo.forEach(this.getChildren(), function(child){
+			var splitter = child._splitterWidget;
+			if(splitter){
+				splitter.destroy();
+			}
+			delete child._splitterWidget;
 		});
-		if(janky){
-			// Set the size of the children the old fashioned way, by setting
-			// CSS width and height
 
-			var resizeWidget = function(widget, changes, result){
-				if(widget){
-					(widget.resize ? widget.resize(changes, result) : dojo.marginBox(widget.domNode, changes));
-				}
-			};
-
-			if(leftSplitter){ leftSplitter.style.height = sidebarHeight; }
-			if(rightSplitter){ rightSplitter.style.height = sidebarHeight; }
-			resizeWidget(this._leftWidget, {h: sidebarHeight}, dim.left);
-			resizeWidget(this._rightWidget, {h: sidebarHeight}, dim.right);
-
-			if(topSplitter){ topSplitter.style.width = sidebarWidth; }
-			if(bottomSplitter){ bottomSplitter.style.width = sidebarWidth; }
-			resizeWidget(this._topWidget, {w: sidebarWidth}, dim.top);
-			resizeWidget(this._bottomWidget, {w: sidebarWidth}, dim.bottom);
-
-			resizeWidget(this._centerWidget, dim.center);
-		}else{
-			// Calculate which panes need a notification that their size has been changed
-			// (we've already set style.top/bottom/left/right on those other panes).
-			var notifySides = !changedRegion || (/top|bottom/.test(changedRegion) && this.design != "sidebar"),
-				notifyTopBottom = !changedRegion || (/left|right/.test(changedRegion) && this.design == "sidebar"),
-				notifyList = {
-					center: true,
-					left: notifySides,
-					right: notifySides,
-					top: notifyTopBottom,
-					bottom: notifyTopBottom
-				};
-			
-			// Send notification to those panes that have changed size
-			dojo.forEach(this.getChildren(), function(child){
-				if(child.resize && notifyList[child.region]){
-					child.resize(null, dim[child.region]);
-				}
-			}, this);
-		}
-	},
-
-	destroy: function(){
-		for(var region in this._splitters){
-			var splitter = this._splitters[region];
-			dijit.byNode(splitter).destroy();
-			dojo.destroy(splitter);
-		}
-		delete this._splitters;
-		delete this._splitterThickness;
+		// Then destroy the real children, and myself
 		this.inherited(arguments);
 	}
 });
@@ -417,6 +279,12 @@ dojo.extend(dijit._Widget, {
 	//		See the `dijit.layout.BorderContainer` description for details.
 	region: '',
 
+	// layoutPriority: [const] Number
+	//		Parameter for children of `dijit.layout.BorderContainer`.
+	//		Children with a higher layoutPriority will be placed closer to the BorderContainer center,
+	//		between children with a lower layoutPriority.
+	layoutPriority: 0,
+
 	// splitter: [const] Boolean
 	//		Parameter for child of `dijit.layout.BorderContainer` where region != "center".
 	//		If true, enables user to resize the widget by putting a draggable splitter between
@@ -434,8 +302,6 @@ dojo.extend(dijit._Widget, {
 	maxSize: Infinity
 });
 
-dojo.require("dijit._Templated");
-
 dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 {
 	// summary:
@@ -455,7 +321,7 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 	//		Pointer to the pane associated with this splitter
 	child: null,
 
-	// region: String
+	// region: [const] String
 	//		Region of pane associated with this splitter.
 	//		"top", "bottom", "left", "right".
 	region: null,
@@ -466,18 +332,21 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 	//		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" waiRole="separator"><div class="dijitSplitterThumb"></div></div>',
+	templateString: '<div class="dijitSplitter" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_startDrag,onmouseenter:_onMouse,onmouseleave:_onMouse" tabIndex="0" role="separator"><div class="dijitSplitterThumb"></div></div>',
 
-	postCreate: function(){
+	postMixInProperties: function(){
 		this.inherited(arguments);
-		this.horizontal = /top|bottom/.test(this.region);
-		dojo.addClass(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V"));
-//		dojo.addClass(this.child.domNode, "dijitSplitterPane");
-//		dojo.setSelectable(this.domNode, false); //TODO is this necessary?
 
+		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);
@@ -489,23 +358,14 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 
 	_computeMaxSize: function(){
 		// summary:
-		//		Compute the maximum size that my corresponding pane can be set to
+		//		Return the maximum size that my corresponding pane can be set to
 
 		var dim = this.horizontal ? 'h' : 'w',
-			thickness = this.container._splitterThickness[this.region];
-			
-		// Get DOMNode of opposite pane, if an opposite pane exists.
-		// Ex: if I am the _Splitter for the left pane, then get the right pane.
-		var flip = {left:'right', right:'left', top:'bottom', bottom:'top', leading:'trailing', trailing:'leading'},
-			oppNode = this.container["_" + flip[this.region]];
-		
-		// I can expand up to the edge of the opposite pane, or if there's no opposite pane, then to
-		// edge of BorderContainer
-		var available = dojo.contentBox(this.container.domNode)[dim] -
-				(oppNode ? dojo.marginBox(oppNode)[dim] : 0) -
-				20 - thickness * 2;
+			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, available);
+		return Math.min(this.child.maxSize, childSize + spaceAvailable);
 	},
 
 	_startDrag: function(e){
@@ -524,28 +384,26 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 			dojo.addClass(this.domNode, "dijitSplitterShadow");
 			dojo.place(this.fake, this.domNode, "after");
 		}
-		dojo.addClass(this.domNode, "dijitSplitterActive");
-		dojo.addClass(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V") + "Active");
+		dojo.addClass(this.domNode, "dijitSplitterActive dijitSplitter" + (this.horizontal ? "H" : "V") + "Active");
 		if(this.fake){
-			dojo.removeClass(this.fake, "dijitSplitterHover");
-			dojo.removeClass(this.fake, "dijitSplitter" + (this.horizontal ? "H" : "V") + "Hover");
+			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,
-			max = this._computeMaxSize(),
-			min = this.child.minSize || 20,
 			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,
-			splitterStart = parseInt(this.domNode.style[region], 10),
+			splitterAttr = region == "top" || region == "bottom" ? "top" : "left",	// style attribute of splitter to adjust
+			splitterStart = parseInt(splitterStyle[splitterAttr], 10),
 			resize = this._resize,
-			childNode = this.child.domNode,
-			layoutFunc = dojo.hitch(this.container, this.container._layoutChildren),
+			layoutFunc = dojo.hitch(this.container, "_layoutChildren", this.child.id),
 			de = dojo.doc;
 
 		this._handlers = (this._handlers || []).concat([
@@ -555,9 +413,10 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 					boundChildSize = Math.max(Math.min(childSize, max), min);
 
 				if(resize || forceResize){
-					layoutFunc(region, boundChildSize);
+					layoutFunc(boundChildSize);
 				}
-				splitterStyle[region] = factor * delta + splitterStart + (boundChildSize - childSize) + "px";
+				// 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),
@@ -578,9 +437,8 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 				dojo.removeClass(this.cover, "dijitSplitterCoverActive");
 			}
 			if(this.fake){ dojo.destroy(this.fake); }
-			dojo.removeClass(this.domNode, "dijitSplitterActive");
-			dojo.removeClass(this.domNode, "dijitSplitter" + (this.horizontal ? "H" : "V") + "Active");
-			dojo.removeClass(this.domNode, "dijitSplitterShadow");
+			dojo.removeClass(this.domNode, "dijitSplitterActive dijitSplitter"
+				+ (this.horizontal ? "H" : "V") + "Active dijitSplitterShadow");
 			this._drag(e); //TODO: redundant with onmousemove?
 			this._drag(e, true);
 		}finally{
@@ -614,8 +472,8 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 //				this.inherited(arguments);
 				return;
 		}
-		var childSize = dojo.marginBox(this.child.domNode)[ horizontal ? 'h' : 'w' ] + this._factor * tick;
-		this.container._layoutChildren(this.region, Math.max(Math.min(childSize, this._computeMaxSize()), this.child.minSize));
+		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);
 	},
 
@@ -629,7 +487,7 @@ dojo.declare("dijit.layout._Splitter", [ dijit._Widget, dijit._Templated ],
 	}
 });
 
-dojo.declare("dijit.layout._Gutter", [dijit._Widget, dijit._Templated ],
+dojo.declare("dijit.layout._Gutter", [dijit._Widget, dijit._Templated],
 {
 	// summary:
 	// 		Just a spacer div to separate side pane from center pane.
@@ -640,10 +498,19 @@ dojo.declare("dijit.layout._Gutter", [dijit._Widget, dijit._Templated ],
 	// tags:
 	//		private
 
-	templateString: '<div class="dijitGutter" waiRole="presentation"></div>',
+	templateString: '<div class="dijitGutter" role="presentation"></div>',
 
-	postCreate: function(){
+	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"));
 	}
 });
+
+
+return dijit.layout.BorderContainer;
+});
diff --git a/dijit/layout/ContentPane.js b/dijit/layout/ContentPane.js
index 197853d..a7569c5 100644
--- a/dijit/layout/ContentPane.js
+++ b/dijit/layout/ContentPane.js
@@ -1,36 +1,34 @@
-dojo.provide("dijit.layout.ContentPane");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Contained");
-dojo.require("dijit.layout._LayoutWidget");	// for dijit.layout.marginBox2contentBox()
-
-dojo.require("dojo.parser");
-dojo.require("dojo.string");
-dojo.require("dojo.html");
-dojo.requireLocalization("dijit", "loading");
+define("dijit/layout/ContentPane", ["dojo", "dijit", "dijit/_Widget", "dijit/layout/_ContentPaneResizeMixin", "dojo/string", "dojo/html", "i18n!dijit/nls/loading"], function(dojo, dijit) {
 
 dojo.declare(
-	"dijit.layout.ContentPane", dijit._Widget,
+	"dijit.layout.ContentPane", [dijit._Widget, dijit.layout._ContentPaneResizeMixin],
 {
 	// summary:
-	//		A widget that acts as a container for mixed HTML and widgets, and includes an Ajax interface
+	//		A widget containing an HTML fragment, specified inline
+	//		or by uri.  Fragment may include widgets.
+	//
 	// description:
-	//		A widget that can be used as a stand alone widget
-	//		or as a base class for other widgets.
+	//		This widget embeds a document fragment in the page, specified
+	//		either by uri, javascript generated markup or DOM reference.
+	//		Any widgets within this content are instantiated and managed,
+	//		but laid out according to the HTML structure.  Unlike IFRAME,
+	//		ContentPane embeds a document fragment as would be found
+	//		inside the BODY tag of a full HTML document.  It should not
+	//		contain the HTML, HEAD, or BODY tags.
+	//		For more advanced functionality with scripts and
+	//		stylesheets, see dojox.layout.ContentPane.  This widget may be
+	//		used stand alone or as a base class for other widgets.
+	//		ContentPane is useful as a child of other layout containers
+	//		such as BorderContainer or TabContainer, but note that those
+	//		widgets can contain any widget as a child.
 	//
-	//		Handles replacement of document fragment using either external uri or javascript
-	//		generated markup or DOM content, instantiating widgets within that content.
-	//		Don't confuse it with an iframe, it only needs/wants document fragments.
-	//		It's useful as a child of LayoutContainer, SplitContainer, or TabContainer.
-	//		But note that those classes can contain any widget as a child.
 	// example:
 	//		Some quick samples:
-	//		To change the innerHTML use .set('content', '<b>new content</b>')
+	//		To change the innerHTML: cp.set('content', '<b>new content</b>')
 	//
-	//		Or you can send it a NodeList, .set('content', dojo.query('div [class=selected]', userSelection))
-	//		please note that the nodes in NodeList will copied, not moved
+	//		Or you can send it a NodeList: cp.set('content', dojo.query('div [class=selected]', userSelection))
 	//
-	//		To do a ajax update use .set('href', url)
+	//		To do an ajax update: cp.set('href', url)
 
 	// href: String
 	//		The href of the content that displays now.
@@ -42,7 +40,7 @@ dojo.declare(
 /*=====
 	// content: String || DomNode || NodeList || dijit._Widget
 	//		The innerHTML of the ContentPane.
-	//		Note that the initialization parameter / argument to attr("content", ...)
+	//		Note that the initialization parameter / argument to set("content", ...)
 	//		can be a String, DomNode, Nodelist, or _Widget.
 	content: "",
 =====*/
@@ -56,6 +54,13 @@ dojo.declare(
 	//		Parse content and create the widgets, if any.
 	parseOnLoad: true,
 
+	// parserScope: String
+	//		Flag passed to parser.  Root for attribute names to search for.   If scopeName is dojo,
+	//		will search for data-dojo-type (or dojoType).  For backwards compatibility
+	//		reasons defaults to dojo._scopeName (which is "dojo" except when
+	//		multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+	parserScope: dojo._scopeName,
+
 	// preventCache: Boolean
 	//		Prevent caching of data from href's by appending a timestamp to the href.
 	preventCache: false,
@@ -79,7 +84,7 @@ dojo.declare(
 	// isLoaded: [readonly] Boolean
 	//		True if the ContentPane has data in it, either specified
 	//		during initialization (via href or inline content), or set
-	//		via attr('content', ...) / attr('href', ...)
+	//		via set('content', ...) / set('href', ...)
 	//
 	//		False if it doesn't have any content, or if ContentPane is
 	//		still in the process of downloading href.
@@ -87,35 +92,19 @@ dojo.declare(
 
 	baseClass: "dijitContentPane",
 
-	// doLayout: Boolean
-	//		- false - don't adjust size of children
-	//		- true - if there is a single visible child widget, set it's size to
-	//				however big the ContentPane is
-	doLayout: true,
-
 	// ioArgs: Object
 	//		Parameters to pass to xhrGet() request, for example:
 	// |	<div dojoType="dijit.layout.ContentPane" href="./bar" ioArgs="{timeout: 500}">
 	ioArgs: {},
 
-	// 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,
-
 	// onLoadDeferred: [readonly] dojo.Deferred
-	//		This is the `dojo.Deferred` returned by attr('href', ...) and refresh().
+	//		This is the `dojo.Deferred` returned by set('href', ...) and refresh().
 	//		Calling onLoadDeferred.addCallback() or addErrback() registers your
-	//		callback to be called only once, when the prior attr('href', ...) call or
+	//		callback to be called only once, when the prior set('href', ...) call or
 	//		the initial href parameter to the constructor finishes loading.
 	//
-	//		This is different than an onLoad() handler which gets called any time any href is loaded.
+	//		This is different than an onLoad() handler which gets called any time any href
+	//		or content is loaded.
 	onLoadDeferred: null,
 
 	// Override _Widget's attributeMap because we don't want the title attribute (used to specify
@@ -125,99 +114,71 @@ dojo.declare(
 		title: []
 	}),
 
+	// Flag to parser that I'll parse my contents, so it shouldn't.
+	stopParser: true,
+
+	// template: [private] Boolean
+	//		Flag from the parser that this ContentPane is inside a template
+	//		so the contents are pre-parsed.
+	// (TODO: this declaration can be commented out in 2.0)
+	template: false,
+
+	create: function(params, srcNodeRef){
+		// Convert a srcNodeRef argument into a content parameter, so that the original contents are
+		// processed in the same way as contents set via set("content", ...), calling the parser etc.
+		// Avoid modifying original params object since that breaks NodeList instantiation, see #11906.
+		if((!params || !params.template) && srcNodeRef && !("href" in params) && !("content" in params)){
+			var df = dojo.doc.createDocumentFragment();
+			srcNodeRef = dojo.byId(srcNodeRef)
+			while(srcNodeRef.firstChild){
+				df.appendChild(srcNodeRef.firstChild);
+			}
+			params = dojo.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);
-
-		// Detect if we were initialized with data
-		if(!this.href && this.srcNodeRef && this.srcNodeRef.innerHTML){
-			this.isLoaded = true;
-		}
 	},
 
 	buildRendering: function(){
-		// Overrides Widget.buildRendering().
-		// Since we have no template we need to set this.containerNode ourselves.
-		// For subclasses of ContentPane do have a template, does nothing.
 		this.inherited(arguments);
+
+		// Since we have no template we need to set this.containerNode ourselves, to make getChildren() work.
+		// For subclasses of ContentPane that do have a template, does nothing.
 		if(!this.containerNode){
-			// make getDescendants() work
 			this.containerNode = this.domNode;
 		}
-	},
 
-	postCreate: function(){
 		// remove the title attribute so it doesn't show up when hovering
-		// over a node
+		// 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");
 		}
-
-		dojo.addClass(this.domNode, this.baseClass);
 	},
 
-	startup: function(){
+	_startChildren: function(){
 		// summary:
-		//		See `dijit.layout._LayoutWidget.startup` for description.
-		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
-		//		the same API.
-		if(this._started){ return; }
-
-		var parent = dijit._Contained.prototype.getParent.call(this);
-		this._childOfLayoutWidget = parent && parent.isLayoutContainer;
-
-		// I need to call resize() on my child/children (when I become visible), unless
-		// I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then.
-		this._needLayout = !this._childOfLayoutWidget;
-
-		if(this.isLoaded){
-			dojo.forEach(this.getChildren(), function(child){
-				child.startup();
-			});
-		}
-
-		if(this._isShown() || this.preload){
-			this._onShow();
-		}
+		//		Call startup() on all children including non _Widget ones like dojo.dnd.Source objects
 
+		// This starts all the widgets
 		this.inherited(arguments);
-	},
-
-	_checkIfSingleChild: function(){
-		// summary:
-		//		Test if we have exactly one visible widget as a child,
-		//		and if so assume that we are a container for that widget,
-		//		and should propogate 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){
-				return node.tagName !== "SCRIPT"; // or a regexp for hidden elements like script|area|map|etc..
-			}),
-			childWidgetNodes = childNodes.filter(function(node){
-				return dojo.hasAttr(node, "dojoType") || dojo.hasAttr(node, "widgetId");
-			}),
-			candidateWidgets = dojo.filter(childWidgetNodes.map(dijit.byNode), function(widget){
-				return widget && widget.domNode && widget.resize;
-			});
-
-		if(
-			// all child nodes are widgets
-			childNodes.length == childWidgetNodes.length &&
 
-			// all but one are invisible (like dojo.data)
-			candidateWidgets.length == 1
-		){
-			this._singleChild = candidateWidgets[0];
-		}else{
-			delete this._singleChild;
+		// 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)){
+					obj.startup();
+					obj._started = true;
+				}
+			}, this);
 		}
-
-		// 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);
 	},
 
 	setHref: function(/*String|Uri*/ href){
@@ -228,23 +189,25 @@ dojo.declare(
 	},
 	_setHrefAttr: function(/*String|Uri*/ href){
 		// summary:
-		//		Hook so attr("href", ...) works.
+		//		Hook so set("href", ...) works.
 		// description:
 		//		Reset the (external defined) content of this pane and replace with new url
 		//		Note: It delays the download until widget is shown if preload is false.
 		//	href:
 		//		url to the page you want to get, must be within the same domain as your mainpage
 
-		// Cancel any in-flight requests (an attr('href') will cancel any in-flight attr('href', ...))
+		// 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.href = href;
+		this._set("href", href);
 
 		// _setHrefAttr() is called during creation and by the user, after creation.
-		// only in the second case do we actually load the URL; otherwise it's done in startup()
-		if(this._created && (this.preload || this._isShown())){
+		// Assuming preload == false, only in the second case do we actually load the URL;
+		// otherwise it's done in startup(), and only if this widget is shown.
+		if(this.preload || (this._created && this._isShown())){
 			this._load();
 		}else{
 			// Set flag to indicate that href needs to be loaded the next time the
@@ -263,7 +226,7 @@ dojo.declare(
 	},
 	_setContentAttr: function(/*String|DomNode|Nodelist*/data){
 		// summary:
-		//		Hook to make attr("content", ...) work.
+		//		Hook to make set("content", ...) work.
 		//		Replaces old content with data content, include style classes from old content
 		//	data:
 		//		the new Content may be String, DomNode or NodeList
@@ -273,24 +236,30 @@ dojo.declare(
 
 		// clear href so we can't run refresh and clear content
 		// refresh should only work if we downloaded the content
-		this.href = "";
+		this._set("href", "");
 
-		// Cancel any in-flight requests (an attr('content') will cancel any in-flight attr('href', ...))
+		// Cancel any in-flight requests (a set('content', ...) will cancel any in-flight set('href', ...))
 		this.cancel();
 
 		// Even though user is just setting content directly, still need to define an onLoadDeferred
 		// because the _onLoadHandler() handler is still getting called from setContent()
 		this.onLoadDeferred = new dojo.Deferred(dojo.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>)
+			// or as initialization parameter (ie: new ContentPane({content: ...})
+			this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad"));
+		}
 
 		this._setContent(data || "");
 
-		this._isDownloaded = false; // mark that content is from a attr('content') not an attr('href')
+		this._isDownloaded = false; // mark that content is from a set('content') not a set('href')
 
 		return this.onLoadDeferred; 	// dojo.Deferred
 	},
 	_getContentAttr: function(){
 		// summary:
-		//		Hook to make attr("content") work
+		//		Hook to make get("content") work
 		return this.containerNode.innerHTML;
 	},
 
@@ -323,69 +292,6 @@ dojo.declare(
 		this.inherited(arguments);
 	},
 
-	resize: function(changeSize, resultSize){
-		// summary:
-		//		See `dijit.layout._LayoutWidget.resize` for description.
-		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
-		//		the same API.
-
-		// For the TabContainer --> BorderContainer --> ContentPane case, _onShow() is
-		// never called, so resize() is our trigger to do the initial href download.
-		if(!this._wasShown){
-			this._onShow();
-		}
-
-		this._resizeCalled = true;
-
-		// Set margin box size, unless it wasn't specified, in which case use current size.
-		if(changeSize){
-			dojo.marginBox(this.domNode, changeSize);
-		}
-
-		// Compute content box size of containerNode in case we [later] need to size our single child.
-		var cn = this.containerNode;
-		if(cn === this.domNode){
-			// If changeSize or resultSize was passed to this method and this.containerNode ==
-			// this.domNode then we can compute the content-box size without querying the node,
-			// which is more reliable (similar to LayoutWidget.resize) (see for example #9449).
-			var mb = resultSize || {};
-			dojo.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
-			}
-			this._contentBox = dijit.layout.marginBox2contentBox(cn, mb);
-		}else{
-			this._contentBox = dojo.contentBox(cn);
-		}
-
-		// Make my children layout, or size my single child widget
-		this._layoutChildren();
-	},
-
-	_isShown: function(){
-		// summary:
-		//		Returns true if the content is currently shown.
-		// description:
-		//		If I am a child of a layout widget then it actually returns true if I've ever been visible,
-		//		not whether I'm currently visible, since that's much faster than tracing up the DOM/widget
-		//		tree every call, and at least solves the performance problem on page load by deferring loading
-		//		hidden ContentPanes until they are first shown
-
-		if(this._childOfLayoutWidget){
-			// If we are TitlePane, etc - we return that only *IF* we've been resized
-			if(this._resizeCalled && "open" in this){
-				return this.open;
-			}
-			return this._resizeCalled;
-		}else if("open" in this){
-			return this.open;		// for TitlePane, etc.
-		}else{
-			// TODO: with _childOfLayoutWidget check maybe this branch no longer necessary?
-			var node = this.domNode;
-			return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden");
-		}
-	},
-
 	_onShow: function(){
 		// summary:
 		//		Called when the ContentPane is made visible
@@ -397,26 +303,15 @@ dojo.declare(
 		//		Does necessary processing, including href download and layout/resize of
 		//		child widget(s)
 
+		this.inherited(arguments);
+
 		if(this.href){
 			if(!this._xhrDfd && // if there's an href that isn't already being loaded
 				(!this.isLoaded || this._hrefChanged || this.refreshOnShow)
 			){
-				this.refresh();
-			}
-		}else{
-			// If we are the child of a layout widget then the layout widget will call resize() on
-			// us, and then we will size our child/children.   Otherwise, we need to do it now.
-			if(!this._childOfLayoutWidget && this._needLayout){
-				// If a layout has been scheduled for when we become visible, do it now
-				this._layoutChildren();
+				return this.refresh();	// If child has an href, promise that fires when the load is complete
 			}
 		}
-
-		this.inherited(arguments);
-
-		// Need to keep track of whether ContentPane has been shown (which is different than
-		// whether or not it's currently visible).
-		this._wasShown = true;
 	},
 
 	refresh: function(){
@@ -431,8 +326,9 @@ dojo.declare(
 		this.cancel();
 
 		this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel"));
+		this.onLoadDeferred.addCallback(dojo.hitch(this, "onLoad"));
 		this._load();
-		return this.onLoadDeferred;
+		return this.onLoadDeferred;		// If child has an href, promise that fires when refresh is complete
 	},
 
 	_load: function(){
@@ -482,10 +378,9 @@ dojo.declare(
 	_onLoadHandler: function(data){
 		// summary:
 		//		This is called whenever new content is being loaded
-		this.isLoaded = true;
+		this._set("isLoaded", true);
 		try{
 			this.onLoadDeferred.callback(data);
-			this.onLoad(data);
 		}catch(e){
 			console.error('Error '+this.widgetId+' running custom onLoad code: ' + e.message);
 		}
@@ -494,7 +389,7 @@ dojo.declare(
 	_onUnloadHandler: function(){
 		// summary:
 		//		This is called whenever the content is being unloaded
-		this.isLoaded = false;
+		this._set("isLoaded", false);
 		try{
 			this.onUnload();
 		}catch(e){
@@ -540,7 +435,7 @@ dojo.declare(
 		delete this._singleChild;
 	},
 
-	_setContent: function(cont, isFakeContent){
+	_setContent: function(/*String|DocumentFragment*/ cont, /*Boolean*/ isFakeContent){
 		// summary:
 		//		Insert the content into the container node
 
@@ -575,31 +470,31 @@ dojo.declare(
 			cleanContent: this.cleanContent,
 			extractContent: this.extractContent,
 			parseContent: this.parseOnLoad,
+			parserScope: this.parserScope,
+			startup: false,
 			dir: this.dir,
 			lang: this.lang
 		}, this._contentSetterParams || {});
 
-		dojo.mixin(setter, setterParams);
-
-		setter.set( (dojo.isObject(cont) && cont.domNode) ? cont.domNode : cont );
+		setter.set( (dojo.isObject(cont) && cont.domNode) ? cont.domNode : cont, setterParams );
 
 		// setter params must be pulled afresh from the ContentPane each time
 		delete this._contentSetterParams;
 
-		if(!isFakeContent){
-			// Startup each top level child widget (and they will start their children, recursively)
-			dojo.forEach(this.getChildren(), function(child){
-				// The parser has already called startup on all widgets *without* a getParent() method
-				if(!this.parseOnLoad || child.getParent){
-					child.startup();
-				}
-			}, this);
+		if(this.doLayout){
+			this._checkIfSingleChild();
+		}
 
-			// Call resize() on each of my child layout widgets,
-			// or resize() on my single child layout widget...
-			// either now (if I'm currently visible)
-			// or when I become visible
-			this._scheduleLayout();
+		if(!isFakeContent){
+			if(this._started){
+				// Startup each top level child widget (and they will start their children, recursively)
+				this._startChildren();
+	
+				// Call resize() on each of my child layout widgets,
+				// or resize() on my single child layout widget...
+				// either now (if I'm currently visible) or when I become visible
+				this._scheduleLayout();
+			}
 
 			this._onLoadHandler(cont);
 		}
@@ -609,7 +504,7 @@ dojo.declare(
 		this.onLoadDeferred.errback(err);
 
 		// shows user the string that is returned by on[type]Error
-		// overide on[type]Error and return your own string to customize
+		// override on[type]Error and return your own string to customize
 		var errText = this['on' + type + 'Error'].call(this, err);
 		if(consoleText){
 			console.error(consoleText, err);
@@ -618,48 +513,6 @@ dojo.declare(
 		}
 	},
 
-	_scheduleLayout: function(){
-		// summary:
-		//		Call resize() on each of my child layout widgets, either now
-		//		(if I'm currently visible) or when I become visible
-		if(this._isShown()){
-			this._layoutChildren();
-		}else{
-			this._needLayout = true;
-		}
-	},
-
-	_layoutChildren: function(){
-		// summary:
-		//		Since I am a Container widget, each of my children expects me to
-		//		call resize() or layout() on them.
-		// description:
-		//		Should be called on initialization and also whenever we get new content
-		//		(from an href, or from attr('content', ...))... but deferred until
-		//		the ContentPane is visible
-
-		if(this.doLayout){
-			this._checkIfSingleChild();
-		}
-
-		if(this._singleChild && this._singleChild.resize){
-			var cb = this._contentBox || dojo.contentBox(this.containerNode);
-
-			// note: if widget has padding this._contentBox will have l and t set,
-			// but don't pass them to resize() or it will doubly-offset the child
-			this._singleChild.resize({w: cb.w, h: cb.h});
-		}else{
-			// All my child widgets are independently sized (rather than matching my size),
-			// but I still need to call resize() on each child to make it layout.
-			dojo.forEach(this.getChildren(), function(widget){
-				if(widget.resize){
-					widget.resize();
-				}
-			});
-		}
-		delete this._needLayout;
-	},
-
 	// EVENT's, should be overide-able
 	onLoad: function(data){
 		// summary:
@@ -721,3 +574,7 @@ dojo.declare(
 		//		callback
 	}
 });
+
+
+return dijit.layout.ContentPane;
+});
diff --git a/dijit/layout/LayoutContainer.js b/dijit/layout/LayoutContainer.js
index 7d63538..2056e3f 100644
--- a/dijit/layout/LayoutContainer.js
+++ b/dijit/layout/LayoutContainer.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.layout.LayoutContainer");
-
-dojo.require("dijit.layout._LayoutWidget");
+define("dijit/layout/LayoutContainer", ["dojo", "dijit", "dijit/layout/_LayoutWidget"], function(dojo, dijit) {
 
 dojo.declare("dijit.layout.LayoutContainer",
 	dijit.layout._LayoutWidget,
@@ -73,3 +71,7 @@ dojo.extend(dijit._Widget, {
 	//		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 b5c4634..3f92b5f 100644
--- a/dijit/layout/LinkPane.js
+++ b/dijit/layout/LinkPane.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.layout.LinkPane");
-
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit._Templated");
+define("dijit/layout/LinkPane", ["dojo", "dijit", "dijit/layout/ContentPane", "dijit/_Templated"], function(dojo, dijit) {
 
 dojo.declare("dijit.layout.LinkPane",
 	[dijit.layout.ContentPane, dijit._Templated],
@@ -38,3 +35,7 @@ dojo.declare("dijit.layout.LinkPane",
 		// copied
 	}
 });
+
+
+return dijit.layout.LinkPane;
+});
diff --git a/dijit/layout/ScrollingTabController.js b/dijit/layout/ScrollingTabController.js
index b7ab54e..0d8dbaa 100644
--- a/dijit/layout/ScrollingTabController.js
+++ b/dijit/layout/ScrollingTabController.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.layout.ScrollingTabController");
-
-dojo.require("dijit.layout.TabController");
-dojo.require("dijit.Menu");
+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,
@@ -16,7 +13,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 
 	templateString: dojo.cache("dijit.layout", "templates/ScrollingTabController.html"),
 
-	// useMenu:[const] Boolean
+	// useMenu: [const] Boolean
 	//		True if a menu should be used to select tabs when they are too
 	//		wide to fit the TabContainer, false otherwise.
 	useMenu: true,
@@ -26,7 +23,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 	//		wide to fit the TabContainer, false otherwise.
 	useSlider: true,
 
-	// tabStripClass: String
+	// tabStripClass: [const] String
 	//		The css class to apply to the tab strip, if it is visible.
 	tabStripClass: "",
 
@@ -42,7 +39,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		"class": "containerNode"
 	}),
 
-	postCreate: function(){
+	buildRendering: function(){
 		this.inherited(arguments);
 		var n = this.domNode;
 
@@ -72,41 +69,18 @@ dojo.declare("dijit.layout.ScrollingTabController",
 
 	onAddChild: function(page, insertIndex){
 		this.inherited(arguments);
-		var menuItem;
-		if(this.useMenu){
-			var containerId = this.containerId;
-			menuItem = new dijit.MenuItem({
-				id: page.id + "_stcMi",
-				label: page.title,
-				dir: page.dir,
-				lang: page.lang,
-				onClick: dojo.hitch(this, function(){
-					var container = dijit.byId(containerId);
-					container.selectChild(page);
-				})
-			});
-			this._menuChildren[page.id] = menuItem;
-			this._menu.addChild(menuItem, insertIndex);
-		}
 
-		// update the menuItem label when the button label is updated
-		this.pane2handles[page.id].push(
-			this.connect(this.pane2button[page.id], "set", function(name, value){
-				if(this._postStartup){
-					if(name == "label"){
-						if(menuItem){
-							menuItem.set(name, value);
-						}
-	
-						// The changed label will have changed the width of the
-						// buttons, so do a resize
-						if(this._dim){
-							this.resize(this._dim);
-						}
+		// 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){
+			this.pane2watches[page.id].push(
+				this.pane2button[page.id].watch(attr, dojo.hitch(this, function(name, oldValue, newValue){
+					if(this._postStartup && this._dim){
+						this.resize(this._dim);
 					}
-				}
-			})
-		);
+				}))
+			);
+		}, this);
 
 		// Increment the width of the wrapper when a tab is added
 		// This makes sure that the buttons never wrap.
@@ -123,13 +97,6 @@ dojo.declare("dijit.layout.ScrollingTabController",
 			this._selectedTab = null;
 		}
 
-		// delete menu entry corresponding to pane that was removed from TabContainer
-		if(this.useMenu && page && page.id && this._menuChildren[page.id]){
-			this._menu.removeChild(this._menuChildren[page.id]);
-			this._menuChildren[page.id].destroy();
-			delete this._menuChildren[page.id];
-		}
-
 		this.inherited(arguments);
 	},
 
@@ -137,7 +104,6 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		// summary:
 		//		Creates the buttons used to scroll to view tabs that
 		//		may not be visible if the TabContainer is too narrow.
-		this._menuChildren = {};
 
 		// Make a list of the buttons to display when the tab labels become
 		// wider than the TabContainer, and hide the other buttons.
@@ -146,26 +112,13 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		this._buttons = dojo.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.marginBox(btn).w;
+				this._btnWidth += dojo._getMarginSize(btn).w;
 				return true;
 			}else{
 				dojo.style(btn, "display", "none");
 				return false;
 			}
 		}, this);
-
-		if(this.useMenu){
-			// Create the menu that is used to select tabs.
-			this._menu = new dijit.Menu({
-				id: this.id + "_menu",
-				dir: this.dir,
-				lang: this.lang,
-				targetNodeIds: [this._menuBtn.domNode],
-				leftClickToOpen: true,
-				refocus: false	// selecting a menu item sets focus to a TabButton
-			});
-			this._supportingWidgets.push(this._menu);
-		}
 	},
 
 	_getTabsWidth: function(){
@@ -235,6 +188,10 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		this._setButtonClass(this._getScroll());
 		
 		this._postResize = true;
+
+		// Return my size so layoutChildren() can use it.
+		// Also avoids IE9 layout glitch on browser resize when scroll buttons present
+		return {h: this._contentBox.h, w: dim.w};
 	},
 
 	_getScroll: function(){
@@ -337,7 +294,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		return pos;
 	},
 
-	createSmoothScroll : function(x){
+	createSmoothScroll: function(x){
 		// summary:
 		//		Creates a dojo._Animation object that smoothly scrolls the tab list
 		//		either to a fixed horizontal pixel value, or to the selected tab.
@@ -383,7 +340,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		return anim; // dojo._Animation
 	},
 
-	_getBtnNode: function(e){
+	_getBtnNode: function(/*Event*/ e){
 		// summary:
 		//		Gets a button DOM node from a mouse click event.
 		// e:
@@ -395,7 +352,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		return n;
 	},
 
-	doSlideRight: function(e){
+	doSlideRight: function(/*Event*/ e){
 		// summary:
 		//		Scrolls the menu to the right.
 		// e:
@@ -403,7 +360,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		this.doSlide(1, this._getBtnNode(e));
 	},
 
-	doSlideLeft: function(e){
+	doSlideLeft: function(/*Event*/ e){
 		// summary:
 		//		Scrolls the menu to the left.
 		// e:
@@ -411,7 +368,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		this.doSlide(-1,this._getBtnNode(e));
 	},
 
-	doSlide: function(direction, node){
+	doSlide: function(/*Number*/ direction, /*DomNode*/ node){
 		// summary:
 		//		Scrolls the tab list to the left or right by 75% of the widget width.
 		// direction:
@@ -430,7 +387,7 @@ dojo.declare("dijit.layout.ScrollingTabController",
 		this.createSmoothScroll(to).play();
 	},
 
-	_setButtonClass: function(scroll){
+	_setButtonClass: function(/*Number*/ scroll){
 		// summary:
 		//		Disables the left scroll button if the tabs are scrolled all the way to the left,
 		//		or the right scroll button in the opposite case.
@@ -443,15 +400,71 @@ dojo.declare("dijit.layout.ScrollingTabController",
 	}
 });
 
-dojo.declare("dijit.layout._ScrollingTabControllerButton",
-	dijit.form.Button,
-	{
-		baseClass: "dijitTab tabStripButton",
 
-		templateString: dojo.cache("dijit.layout","templates/_ScrollingTabControllerButton.html"),
+dojo.declare("dijit.layout._ScrollingTabControllerButtonMixin", null, {
+	baseClass: "dijitTab tabStripButton",
+
+	templateString: dojo.cache("dijit.layout","templates/_ScrollingTabControllerButton.html"),
 
 		// Override inherited tabIndex: 0 from dijit.form.Button, because user shouldn't be
 		// able to tab to the left/right/menu buttons
-		tabIndex: "-1"
+	tabIndex: "",
+
+	// Similarly, override FormWidget.isFocusable() because clicking a button shouldn't focus it
+	// either (this override avoids focus() call in FormWidget.js)
+	isFocusable: function(){ return false; }
+});
+
+dojo.declare("dijit.layout._ScrollingTabControllerButton",
+	[dijit.form.Button, dijit.layout._ScrollingTabControllerButtonMixin]);
+
+dojo.declare(
+	"dijit.layout._ScrollingTabControllerMenuButton",
+	[dijit.form.Button, dijit._HasDropDown, dijit.layout._ScrollingTabControllerButtonMixin],
+{
+	// id of the TabContainer itself
+	containerId: "",
+
+	// -1 so user can't tab into the button, but so that button can still be focused programatically.
+	// Because need to move focus to the button (or somewhere) before the menu is hidden or IE6 will crash.
+	tabIndex: "-1",
+
+	isLoaded: function(){
+		// recreate menu every time, in case the TabContainer's list of children (or their icons/labels) have changed
+		return false;
+	},
+
+	loadDropDown: function(callback){
+		this.dropDown = new dijit.Menu({
+			id: this.containerId + "_menu",
+			dir: this.dir,
+			lang: this.lang
+		});
+		var container = dijit.byId(this.containerId);
+		dojo.forEach(container.getChildren(), function(page){
+			var menuItem = new dijit.MenuItem({
+				id: page.id + "_stcMi",
+				label: page.title,
+				iconClass: page.iconClass,
+				dir: page.dir,
+				lang: page.lang,
+				onClick: function(){
+					container.selectChild(page);
+				}
+			});
+			this.dropDown.addChild(menuItem);
+		}, this);
+		callback();
+	},
+
+	closeDropDown: function(/*Boolean*/ focus){
+		this.inherited(arguments);
+		if(this.dropDown){
+			this.dropDown.destroyRecursive();
+			delete this.dropDown;
+		}
 	}
-);
+});
+
+return dijit.layout.ScrollingTabController;
+});
diff --git a/dijit/layout/SplitContainer.js b/dijit/layout/SplitContainer.js
index 4641eda..a4aa12f 100644
--- a/dijit/layout/SplitContainer.js
+++ b/dijit/layout/SplitContainer.js
@@ -1,12 +1,10 @@
-dojo.provide("dijit.layout.SplitContainer");
+define("dijit/layout/SplitContainer", ["dojo", "dijit", "dojo/cookie", "dijit/layout/_LayoutWidget"], function(dojo, dijit) {
 
 //
 // FIXME: make it prettier
 // FIXME: active dragging upwards doesn't always shift other bars (direction calculation is wrong in this case)
 //
 
-dojo.require("dojo.cookie");
-dojo.require("dijit.layout._LayoutWidget");
 
 dojo.declare("dijit.layout.SplitContainer",
 	dijit.layout._LayoutWidget,
@@ -575,3 +573,7 @@ dojo.extend(dijit._Widget, {
 	//		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 6c0bb26..c9db4f0 100644
--- a/dijit/layout/StackContainer.js
+++ b/dijit/layout/StackContainer.js
@@ -1,9 +1,4 @@
-dojo.provide("dijit.layout.StackContainer");
-
-dojo.require("dijit._Templated");
-dojo.require("dijit.layout._LayoutWidget");
-dojo.requireLocalization("dijit", "common");
-dojo.require("dojo.cookie");
+define("dijit/layout/StackContainer", ["dojo", "dijit", "dijit/_Templated", "dijit/layout/_LayoutWidget", "i18n!dijit/nls/common", "dojo/cookie", "dijit/layout/StackController"], function(dojo, dijit) {
 
 dojo.declare(
 	"dijit.layout.StackContainer",
@@ -38,10 +33,14 @@ dojo.declare(
 	selectedChildWidget: null,
 =====*/
 
-	postCreate: function(){
+	buildRendering: function(){
 		this.inherited(arguments);
 		dojo.addClass(this.domNode, "dijitLayoutContainer");
 		dijit.setWaiRole(this.containerNode, "tabpanel");
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
 		this.connect(this.domNode, "onkeypress", this._onKeyPress);
 	},
 
@@ -97,8 +96,7 @@ dojo.declare(
 
 		this.inherited(arguments);
 
-		dojo.removeClass(child.domNode, "dijitVisible");
-		dojo.addClass(child.domNode, "dijitHidden");
+		dojo.replaceClass(child.domNode, "dijitHidden", "dijitVisible");
 
 		// remove the title attribute so it doesn't show up when i hover
 		// over a node
@@ -171,17 +169,19 @@ dojo.declare(
 
 		if(this.selectedChildWidget != page){
 			// Deselect old page and select new one
-			this._transition(page, this.selectedChildWidget, animate);
-			this.selectedChildWidget = page;
+			var d = this._transition(page, this.selectedChildWidget, animate);
+			this._set("selectedChildWidget", page);
 			dojo.publish(this.id+"-selectChild", [page]);
 
 			if(this.persist){
 				dojo.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){
+	_transition: function(/*dijit._Widget*/ newWidget, /*dijit._Widget*/ oldWidget, /*Boolean*/ animate){
 		// summary:
 		//		Hide the old widget and display the new widget.
 		//		Subclasses should override this.
@@ -190,7 +190,7 @@ dojo.declare(
 		if(oldWidget){
 			this._hideChild(oldWidget);
 		}
-		this._showChild(newWidget);
+		var d = this._showChild(newWidget);
 
 		// Size the new widget, in case this is the first time it's being shown,
 		// or I have been resized since the last time it was shown.
@@ -204,6 +204,8 @@ dojo.declare(
 				newWidget.resize();
 			}
 		}
+
+		return d;	// If child has an href, promise that fires when the child's href finishes loading
 	},
 
 	_adjacent: function(/*Boolean*/ forward){
@@ -218,13 +220,13 @@ dojo.declare(
 	forward: function(){
 		// summary:
 		//		Advance to next page.
-		this.selectChild(this._adjacent(true), true);
+		return this.selectChild(this._adjacent(true), true);
 	},
 
 	back: function(){
 		// summary:
 		//		Go back to previous page.
-		this.selectChild(this._adjacent(false), true);
+		return this.selectChild(this._adjacent(false), true);
 	},
 
 	_onKeyPress: function(e){
@@ -242,24 +244,24 @@ dojo.declare(
 		// summary:
 		//		Show the specified child by changing it's CSS, and call _onShow()/onShow() so
 		//		it can do any updates it needs regarding loading href's etc.
+		// returns:
+		//		Promise that fires when page has finished showing, or true if there's no href
 		var children = this.getChildren();
 		page.isFirstChild = (page == children[0]);
 		page.isLastChild = (page == children[children.length-1]);
-		page.selected = true;
+		page._set("selected", true);
 
-		dojo.removeClass(page.domNode, "dijitHidden");
-		dojo.addClass(page.domNode, "dijitVisible");
+		dojo.replaceClass(page.domNode, "dijitVisible", "dijitHidden");
 
-		page._onShow();
+		return page._onShow() || true;
 	},
 
 	_hideChild: function(/*dijit._Widget*/ page){
 		// summary:
 		//		Hide the specified child by changing it's CSS, and call _onHide() so
 		//		it's notified.
-		page.selected=false;
-		dojo.removeClass(page.domNode, "dijitVisible");
-		dojo.addClass(page.domNode, "dijitHidden");
+		page._set("selected", false);
+		dojo.replaceClass(page.domNode, "dijitHidden", "dijitVisible");
 
 		page.onHide();
 	},
@@ -278,7 +280,7 @@ dojo.declare(
 		}
 	},
 
-	destroyDescendants: function(/*Boolean*/preserveDom){
+	destroyDescendants: function(/*Boolean*/ preserveDom){
 		dojo.forEach(this.getChildren(), function(child){
 			this.removeChild(child);
 			child.destroyRecursive(preserveDom);
@@ -287,7 +289,6 @@ dojo.declare(
 });
 
 // For back-compat, remove for 2.0
-dojo.require("dijit.layout.StackController");
 
 
 // These arguments can be specified for the children of a StackContainer.
@@ -316,3 +317,7 @@ dojo.extend(dijit._Widget, {
 	//		icon specified in iconClass
 	showTitle: true
 });
+
+
+return dijit.layout.StackContainer;
+});
diff --git a/dijit/layout/StackController.js b/dijit/layout/StackController.js
index c8bc1a6..c6fdb81 100644
--- a/dijit/layout/StackController.js
+++ b/dijit/layout/StackController.js
@@ -1,10 +1,4 @@
-dojo.provide("dijit.layout.StackController");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._Container");
-dojo.require("dijit.form.ToggleButton");
-dojo.requireLocalization("dijit", "common");
+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",
@@ -16,7 +10,7 @@ dojo.declare(
 			//		Monitors the specified StackContainer, and whenever a page is
 			//		added, deleted, or selected, updates itself accordingly.
 
-			templateString: "<span wairole='tablist' dojoAttachEvent='onkeypress' class='dijitStackController'></span>",
+			templateString: "<span role='tablist' dojoAttachEvent='onkeypress' class='dijitStackController'></span>",
 
 			// containerId: [const] String
 			//		The id of the page container that I point to
@@ -26,11 +20,19 @@ dojo.declare(
 			//		The name of the button widget to create to correspond to each page
 			buttonWidget: "dijit.layout._StackButton",
 
-			postCreate: function(){
-				dijit.setWaiRole(this.domNode, "tablist");
-
+			constructor: function(){
 				this.pane2button = {};		// mapping from pane id to buttons
-				this.pane2handles = {};		// mapping from pane id to this.connect() handles
+				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");
@@ -80,22 +82,25 @@ dojo.declare(
 					title: page.tooltip
 				});
 				dijit.setWaiState(button.focusNode,"selected", "false");
-				this.pane2handles[page.id] = [
-					this.connect(page, 'set', function(name, value){
-						var buttonAttr = {
-							title: 'label',
-							showTitle: 'showLabel',
-							iconClass: 'iconClass',
-							closable: 'closeButton',
-							tooltip: 'title'
-						}[name];
-						if(buttonAttr){
-							button.set(buttonAttr, value);
-						}
-					}),
+
+
+				// 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
@@ -118,8 +123,13 @@ dojo.declare(
 				//		private
 
 				if(this._currentChild === page){ this._currentChild = null; }
-				dojo.forEach(this.pane2handles[page.id], this.disconnect, this);
-				delete this.pane2handles[page.id];
+
+				// 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);
@@ -221,6 +231,14 @@ dojo.declare(
 						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);
@@ -240,7 +258,7 @@ dojo.declare(
 								}
 							}
 					}
-					// handle page navigation
+					// handle next/previous page navigation (left/right arrow, etc.)
 					if(forward !== null){
 						this.adjacent(forward).onClick();
 						dojo.stopEvent(e);
@@ -274,9 +292,9 @@ dojo.declare("dijit.layout._StackButton",
 		// Probably we should be calling this.startupKeyNavChildren() instead.
 		tabIndex: "-1",
 
-		postCreate: function(/*Event*/ evt){
-			dijit.setWaiRole((this.focusNode || this.domNode), "tab");
+		buildRendering: function(/*Event*/ evt){
 			this.inherited(arguments);
+			dijit.setWaiRole((this.focusNode || this.domNode), "tab");
 		},
 
 		onClick: function(/*Event*/ evt){
@@ -298,3 +316,6 @@ dojo.declare("dijit.layout._StackButton",
 		}
 	});
 
+
+return dijit.layout.StackController;
+});
diff --git a/dijit/layout/TabContainer.js b/dijit/layout/TabContainer.js
index cefa134..cc90e60 100644
--- a/dijit/layout/TabContainer.js
+++ b/dijit/layout/TabContainer.js
@@ -1,8 +1,4 @@
-dojo.provide("dijit.layout.TabContainer");
-
-dojo.require("dijit.layout._TabContainerBase");
-dojo.require("dijit.layout.TabController");
-dojo.require("dijit.layout.ScrollingTabController");
+define("dijit/layout/TabContainer", ["dojo", "dijit", "dijit/layout/_TabContainerBase", "dijit/layout/TabController", "dijit/layout/ScrollingTabController"], function(dojo, dijit) {
 
 dojo.declare("dijit.layout.TabContainer",
 	dijit.layout._TabContainerBase,
@@ -64,3 +60,6 @@ dojo.declare("dijit.layout.TabContainer",
 		}
 });
 
+
+return dijit.layout.TabContainer;
+});
diff --git a/dijit/layout/TabController.js b/dijit/layout/TabController.js
index 0ae654c..9517184 100644
--- a/dijit/layout/TabController.js
+++ b/dijit/layout/TabController.js
@@ -1,12 +1,7 @@
-dojo.provide("dijit.layout.TabController");
-
-dojo.require("dijit.layout.StackController");
+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.require("dijit.Menu");
-dojo.require("dijit.MenuItem");
 
-dojo.requireLocalization("dijit", "common");
 
 dojo.declare("dijit.layout.TabController",
 	dijit.layout.StackController,
@@ -21,7 +16,7 @@ dojo.declare("dijit.layout.TabController",
 	// tags:
 	//		private
 
-	templateString: "<div wairole='tablist' dojoAttachEvent='onkeypress:onkeypress'></div>",
+	templateString: "<div role='tablist' dojoAttachEvent='onkeypress:onkeypress'></div>",
 
 	// tabPosition: String
 	//		Defines where tabs go relative to the content.
@@ -77,26 +72,10 @@ dojo.declare("dijit.layout._TabButton",
 	// Don't scroll the whole tab container into view when the button is focused.
 	scrollOnFocus: false,
 
-	postMixInProperties: function(){
-		// Override blank iconClass from Button to do tab height adjustment on IE6,
-		// to make sure that tabs with and w/out close icons are same height
-		if(!this.iconClass){
-			this.iconClass = "dijitTabButtonIcon";
-		}
-	},
-
-	postCreate: function(){
+	buildRendering: function(){
 		this.inherited(arguments);
-		dojo.setSelectable(this.containerNode, false);
 
-		// If a custom icon class has not been set for the
-		// tab icon, set its width to one pixel. This ensures
-		// that the height styling of the tab is maintained,
-		// as it is based on the height of the icon.
-		// TODO: I still think we can just set dijitTabButtonIcon to 1px in CSS <Bill>
-		if(this.iconNode.className == "dijitTabButtonIcon"){
-			dojo.style(this.iconNode, "width", "1px");
-		}
+		dojo.setSelectable(this.containerNode, false);
 	},
 
 	startup: function(){
@@ -110,8 +89,10 @@ dojo.declare("dijit.layout._TabButton",
 		}, 1);
 	},
 
-	_setCloseButtonAttr: function(disp){
-		this.closeButton = disp;
+	_setCloseButtonAttr: function(/*Boolean*/ disp){
+		// summary:
+		//		Hide/show close button
+		this._set("closeButton", disp);
 		dojo.toggleClass(this.innerDiv, "dijitClosable", disp);
 		this.closeNode.style.display = disp ? "" : "none";
 		if(disp){
@@ -143,16 +124,16 @@ dojo.declare("dijit.layout._TabButton",
 	},
 	_setLabelAttr: function(/*String*/ content){
 		// summary:
-		//		Hook for attr('label', ...) to work.
+		//		Hook for set('label', ...) to work.
 		// description:
 		//		takes an HTML string.
-		//		Inherited ToggleButton implementation will Set the label (text) of the button; 
+		//		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 || '');
-			}
-		},
+		this.inherited(arguments);
+		if(this.showLabel == false && !this.params.title){
+			this.iconNode.alt = dojo.trim(this.containerNode.innerText || this.containerNode.textContent || '');
+		}
+	},
 
 	destroy: function(){
 		if(this._closeMenu){
@@ -162,3 +143,7 @@ dojo.declare("dijit.layout._TabButton",
 		this.inherited(arguments);
 	}
 });
+
+
+return dijit.layout.TabController;
+});
diff --git a/dijit/layout/_ContentPaneResizeMixin.js b/dijit/layout/_ContentPaneResizeMixin.js
new file mode 100644
index 0000000..7db832d
--- /dev/null
+++ b/dijit/layout/_ContentPaneResizeMixin.js
@@ -0,0 +1,250 @@
+define("dijit/layout/_ContentPaneResizeMixin", ["dojo", "dijit", "dijit/_Contained", "dijit/layout/_LayoutWidget"], function(dojo, dijit) {
+
+dojo.declare("dijit.layout._ContentPaneResizeMixin", null, {
+	// summary:
+	//		Resize() functionality of ContentPane.   If there's a single layout widget
+	//		child then it will call resize() with the same dimensions as the ContentPane.
+	//		Otherwise just calls resize on each child.
+	//
+	//		Also implements basic startup() functionality, where starting the parent
+	//		will start the children
+
+	// doLayout: Boolean
+	//		- false - don't adjust size of children
+	//		- true - if there is a single visible child widget, set it's size to
+	//				however big the ContentPane is
+	doLayout: true,
+
+	// 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.
+		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
+		//		the same API.
+
+		if(this._started){ return; }
+
+		var parent = dijit._Contained.prototype.getParent.call(this);
+		this._childOfLayoutWidget = parent && parent.isLayoutContainer;
+
+		// I need to call resize() on my child/children (when I become visible), unless
+		// I'm the child of a layout widget in which case my parent will call resize() on me and I'll do it then.
+		this._needLayout = !this._childOfLayoutWidget;
+
+		this.inherited(arguments);
+
+		this._startChildren();
+
+		if(this._isShown()){
+			this._onShow();
+		}
+
+		if(!this._childOfLayoutWidget){
+			// If my parent isn't a layout container, since my style *may be* width=height=100%
+			// or something similar (either set directly or via a CSS class),
+			// monitor when my size changes so that I can re-layout.
+			// For browsers where I can't directly monitor when my size changes,
+			// monitor when the viewport changes size, which *may* indicate a size change for me.
+			this.connect(dojo.isIE ? this.domNode : dojo.global, 'onresize', function(){
+				// Using function(){} closure to ensure no arguments to resize.
+				this._needLayout = !this._childOfLayoutWidget;
+				this.resize();
+			});
+		}
+	},
+
+	_checkIfSingleChild: function(){
+		// summary:
+		//		Test if we have exactly one visible widget as a child,
+		//		and if so assume that we are a container for that widget,
+		//		and should propagate startup() and resize() calls to it.
+		//		Skips over things like data stores since they aren't visible.
+
+		var childNodes = dojo.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");
+			}),
+			candidateWidgets = dojo.filter(childWidgetNodes.map(dijit.byNode), function(widget){
+				return widget && widget.domNode && widget.resize;
+			});
+
+		if(
+			// all child nodes are widgets
+			childNodes.length == childWidgetNodes.length &&
+
+			// all but one are invisible (like dojo.data)
+			candidateWidgets.length == 1
+		){
+			this._singleChild = candidateWidgets[0];
+		}else{
+			delete this._singleChild;
+		}
+
+		// So we can set overflow: hidden to avoid a safari bug w/scrollbars showing up (#9449)
+		dojo.toggleClass(this.containerNode, this.baseClass + "SingleChild", !!this._singleChild);
+	},
+
+	resize: function(changeSize, resultSize){
+		// summary:
+		//		See `dijit.layout._LayoutWidget.resize` for description.
+		//		Although ContentPane doesn't extend _LayoutWidget, it does implement
+		//		the same API.
+
+		// For the TabContainer --> BorderContainer --> ContentPane case, _onShow() is
+		// never called, so resize() is our trigger to do the initial href download (see [20099]).
+		// However, don't load href for closed TitlePanes.
+		if(!this._wasShown && this.open !== false){
+			this._onShow();
+		}
+
+		this._resizeCalled = true;
+
+		this._scheduleLayout(changeSize, resultSize);
+	},
+
+	_scheduleLayout: function(changeSize, resultSize){
+		// summary:
+		//		Resize myself, and call resize() on each of my child layout widgets, either now
+		//		(if I'm currently visible) or when I become visible
+		if(this._isShown()){
+			this._layout(changeSize, resultSize);
+		}else{
+			this._needLayout = true;
+			this._changeSize = changeSize;
+			this._resultSize = resultSize;
+		}
+	},
+
+	_layout: function(changeSize, resultSize){
+		// summary:
+		//		Resize myself according to optional changeSize/resultSize parameters, like a layout widget.
+		//		Also, since I am a Container widget, each of my children expects me to
+		//		call resize() or layout() on them.
+		//
+		//		Should be called on initialization and also whenever we get new content
+		//		(from an href, or from set('content', ...))... but deferred until
+		//		the ContentPane is visible
+
+		// Set margin box size, unless it wasn't specified, in which case use current size.
+		if(changeSize){
+			dojo.marginBox(this.domNode, changeSize);
+		}
+
+		// Compute content box size of containerNode in case we [later] need to size our single child.
+		var cn = this.containerNode;
+		if(cn === this.domNode){
+			// If changeSize or resultSize was passed to this method and this.containerNode ==
+			// this.domNode then we can compute the content-box size without querying the node,
+			// which is more reliable (similar to LayoutWidget.resize) (see for example #9449).
+			var mb = resultSize || {};
+			dojo.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
+			}
+			this._contentBox = dijit.layout.marginBox2contentBox(cn, mb);
+		}else{
+			this._contentBox = dojo.contentBox(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.
+		if(this.doLayout){
+			this._checkIfSingleChild();
+		}
+
+		if(this._singleChild && this._singleChild.resize){
+			var cb = this._contentBox || dojo.contentBox(this.containerNode);
+
+			// note: if widget has padding this._contentBox will have l and t set,
+			// but don't pass them to resize() or it will doubly-offset the child
+			this._singleChild.resize({w: cb.w, h: cb.h});
+		}else{
+			// All my child widgets are independently sized (rather than matching my size),
+			// but I still need to call resize() on each child to make it layout.
+			dojo.forEach(this.getChildren(), function(widget){
+				if(widget.resize){
+					widget.resize();
+				}
+			});
+		}
+	},
+
+	_isShown: function(){
+		// summary:
+		//		Returns true if the content is currently shown.
+		// description:
+		//		If I am a child of a layout widget then it actually returns true if I've ever been visible,
+		//		not whether I'm currently visible, since that's much faster than tracing up the DOM/widget
+		//		tree every call, and at least solves the performance problem on page load by deferring loading
+		//		hidden ContentPanes until they are first shown
+
+		if(this._childOfLayoutWidget){
+			// If we are TitlePane, etc - we return that only *IF* we've been resized
+			if(this._resizeCalled && "open" in this){
+				return this.open;
+			}
+			return this._resizeCalled;
+		}else if("open" in this){
+			return this.open;		// for TitlePane, etc.
+		}else{
+			var node = this.domNode, parent = this.domNode.parentNode;
+			return (node.style.display != 'none') && (node.style.visibility != 'hidden') && !dojo.hasClass(node, "dijitHidden") &&
+					parent && parent.style && (parent.style.display != 'none');
+		}
+	},
+
+	_onShow: function(){
+		// summary:
+		//		Called when the ContentPane is made visible
+		// description:
+		//		For a plain ContentPane, this is called on initialization, from startup().
+		//		If the ContentPane is a hidden pane of a TabContainer etc., then it's
+		//		called whenever the pane is made visible.
+		//
+		//		Does layout/resize of child widget(s)
+
+		if(this._needLayout){
+			// If a layout has been scheduled for when we become visible, do it now
+			this._layout(this._changeSize, this._resultSize);
+		}
+
+		this.inherited(arguments);
+
+		// Need to keep track of whether ContentPane has been shown (which is different than
+		// whether or not it's currently visible).
+		this._wasShown = true;
+	}
+});
+
+
+return dijit.layout._ContentPaneResizeMixin;
+});
diff --git a/dijit/layout/_LayoutWidget.js b/dijit/layout/_LayoutWidget.js
index 5444070..6436681 100644
--- a/dijit/layout/_LayoutWidget.js
+++ b/dijit/layout/_LayoutWidget.js
@@ -1,8 +1,4 @@
-dojo.provide("dijit.layout._LayoutWidget");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Container");
-dojo.require("dijit._Contained");
+define("dijit/layout/_LayoutWidget", ["dojo", "dijit", "dijit/_Widget", "dijit/_Container", "dijit/_Contained"], function(dojo, dijit) {
 
 dojo.declare("dijit.layout._LayoutWidget",
 	[dijit._Widget, dijit._Container, dijit._Contained],
@@ -22,10 +18,9 @@ dojo.declare("dijit.layout._LayoutWidget",
 		//		children widgets, setting their size, when they become visible.
 		isLayoutContainer: true,
 
-		postCreate: function(){
-			dojo.addClass(this.domNode, "dijitContainer");
-
+		buildRendering: function(){
 			this.inherited(arguments);
+			dojo.addClass(this.domNode, "dijitContainer");
 		},
 
 		startup: function(){
@@ -159,10 +154,9 @@ dojo.declare("dijit.layout._LayoutWidget",
 			// tags:
 			//		protected extension
 
-			dojo.addClass(child.domNode, this.baseClass+"-child");
-			if(child.baseClass){
-				dojo.addClass(child.domNode, this.baseClass+"-"+child.baseClass);
-			}
+			var cls = this.baseClass + "-child "
+				+ (child.baseClass ? this.baseClass + "-" + child.baseClass : "");
+			dojo.addClass(child.domNode, cls);
 		},
 
 		addChild: function(/*dijit._Widget*/ child, /*Integer?*/ insertIndex){
@@ -175,10 +169,11 @@ dojo.declare("dijit.layout._LayoutWidget",
 
 		removeChild: function(/*dijit._Widget*/ child){
 			// Overrides _Container.removeChild() to remove class added by _setupChild()
-			dojo.removeClass(child.domNode, this.baseClass+"-child");
-			if(child.baseClass){
-				dojo.removeClass(child.domNode, this.baseClass+"-"+child.baseClass);
-			}
+			var cls = this.baseClass + "-child"
+					+ (child.baseClass ?
+						" " + this.baseClass + "-" + child.baseClass : "");
+			dojo.removeClass(child.domNode, cls);
+			
 			this.inherited(arguments);
 		}
 	}
@@ -207,15 +202,22 @@ dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
 
 	var size = function(widget, dim){
 		// size the child
-		widget.resize ? widget.resize(dim) : dojo.marginBox(widget.domNode, dim);
-
-		// record child's size, but favor our own numbers when we have them.
-		// the browser lies sometimes
-		dojo.mixin(widget, dojo.marginBox(widget.domNode));
-		dojo.mixin(widget, dim);
+		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);
+		}
 	};
 
-	dijit.layout.layoutChildren = function(/*DomNode*/ container, /*Object*/ dim, /*Object[]*/ children){
+	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:
@@ -223,7 +225,16 @@ dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
 		// dim:
 		//		{l, t, w, h} object specifying dimensions of container into which to place children
 		// children:
-		//		an array like [ {domNode: foo, layoutAlign: "bottom" }, {domNode: bar, layoutAlign: "client"} ]
+		//		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);
@@ -232,27 +243,37 @@ dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
 
 		// 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.
-		children = dojo.filter(children, function(item){ return item.layoutAlign != "client"; })
-			.concat(dojo.filter(children, function(item){ return item.layoutAlign == "client"; }));
+		// 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.layoutAlign;
+				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.bottom = elmStyle.right = "auto";
+			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"){
-				size(child, { w: dim.w });
+				sizeSetting.w = dim.w;
+				size(child, sizeSetting);
 				dim.h -= child.h;
 				if(pos == "top"){
 					dim.t += child.h;
@@ -260,17 +281,22 @@ dijit.layout.marginBox2contentBox = function(/*DomNode*/ node, /*Object*/ mb){
 					elmStyle.top = dim.t + dim.h + "px";
 				}
 			}else if(pos == "left" || pos == "right"){
-				size(child, { h: dim.h });
+				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"){
+			}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 f8bc174..820f592 100644
--- a/dijit/layout/_TabContainerBase.js
+++ b/dijit/layout/_TabContainerBase.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.layout._TabContainerBase");
-
-dojo.require("dijit.layout.StackContainer");
-dojo.require("dijit._Templated");
+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],
@@ -21,12 +18,12 @@ dojo.declare("dijit.layout._TabContainerBase",
 
 	baseClass: "dijitTabContainer",
 
-	// tabStrip: Boolean
+	// tabStrip: [const] Boolean
 	//		Defines whether the tablist gets an extra class for layouting, putting a border/shading
-	//		around the set of tabs.
+	//		around the set of tabs.   Not supported by claro theme.
 	tabStrip: false,
 
-	// nested: Boolean
+	// nested: [const] Boolean
 	//		If true, use styling for a TabContainer nested inside another TabContainer.
 	//		For tundra etc., makes tabs look like links, and hides the outer
 	//		border since the outer TabContainer already has a border.
@@ -43,7 +40,7 @@ dojo.declare("dijit.layout._TabContainerBase",
 		this.inherited(arguments);
 	},
 
-	postCreate: function(){
+	buildRendering: function(){
 		this.inherited(arguments);
 
 		// Create the tab list that will have a tab (a.k.a. tab button) for each tab panel
@@ -110,7 +107,12 @@ dojo.declare("dijit.layout._TabContainerBase",
 		}else{
 			// just layout the tab controller, so it can position left/right buttons etc.
 			if(this.tablist.resize){
-				this.tablist.resize({w: dojo.contentBox(this.domNode).w});
+				//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;
+				s.width="";
+				this.tablist.resize({w: width});
 			}
 
 			// and call resize() on the selected pane just to tell it that it's been made visible
@@ -128,3 +130,6 @@ dojo.declare("dijit.layout._TabContainerBase",
 	}
 });
 
+
+return dijit.layout._TabContainerBase;
+});
diff --git a/dijit/layout/templates/AccordionButton.html b/dijit/layout/templates/AccordionButton.html
index ca8c413..8c0effc 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'
-			class='dijitAccordionTitleFocus' wairole="tab" waiState="expanded-false"
-		><span class='dijitInline dijitAccordionArrow' waiRole="presentation"></span
-		><span class='arrowTextUp' waiRole="presentation">+</span
-		><span class='arrowTextDown' waiRole="presentation">-</span
-		><img src="${_blankGif}" alt="" class="dijitIcon" dojoAttachPoint='iconNode' style="vertical-align: middle" waiRole="presentation"/>
-		<span waiRole="presentation" dojoAttachPoint='titleTextNode' class='dijitAccordionText'></span>
+			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>
 	</div>
 </div>
diff --git a/dijit/layout/templates/ScrollingTabController.html b/dijit/layout/templates/ScrollingTabController.html
index 313f76b..28ad6b6 100644
--- a/dijit/layout/templates/ScrollingTabController.html
+++ b/dijit/layout/templates/ScrollingTabController.html
@@ -1,18 +1,19 @@
 <div class="dijitTabListContainer-${tabPosition}" style="visibility:hidden">
-	<div dojoType="dijit.layout._ScrollingTabControllerButton"
+	<div dojoType="dijit.layout._ScrollingTabControllerMenuButton"
 			class="tabStripButton-${tabPosition}"
-			id="${id}_menuBtn" iconClass="dijitTabStripMenuIcon"
-			dojoAttachPoint="_menuBtn" showLabel=false>▼</div>
+			id="${id}_menuBtn" containerId="${containerId}" iconClass="dijitTabStripMenuIcon"
+			dropDownPosition="below-alt, above-alt"
+			dojoAttachPoint="_menuBtn" showLabel="false">▼</div>
 	<div dojoType="dijit.layout._ScrollingTabControllerButton"
 			class="tabStripButton-${tabPosition}"
 			id="${id}_leftBtn" iconClass="dijitTabStripSlideLeftIcon"
-			dojoAttachPoint="_leftBtn" dojoAttachEvent="onClick: doSlideLeft" showLabel=false>◀</div>
+			dojoAttachPoint="_leftBtn" dojoAttachEvent="onClick: doSlideLeft" showLabel="false">◀</div>
 	<div dojoType="dijit.layout._ScrollingTabControllerButton"
 			class="tabStripButton-${tabPosition}"
 			id="${id}_rightBtn" iconClass="dijitTabStripSlideRightIcon"
-			dojoAttachPoint="_rightBtn" dojoAttachEvent="onClick: doSlideRight" showLabel=false>▶</div>
+			dojoAttachPoint="_rightBtn" dojoAttachEvent="onClick: doSlideRight" showLabel="false">▶</div>
 	<div class='dijitTabListWrapper' dojoAttachPoint='tablistWrapper'>
-		<div wairole='tablist' dojoAttachEvent='onkeypress:onkeypress'
+		<div role='tablist' dojoAttachEvent='onkeypress:onkeypress'
 				dojoAttachPoint='containerNode' class='nowrapTabStrip'></div>
 	</div>
 </div>
\ No newline at end of file
diff --git a/dijit/layout/templates/_ScrollingTabControllerButton.html b/dijit/layout/templates/_ScrollingTabControllerButton.html
index 2846c18..0c4b8f6 100644
--- a/dijit/layout/templates/_ScrollingTabControllerButton.html
+++ b/dijit/layout/templates/_ScrollingTabControllerButton.html
@@ -1,7 +1,7 @@
 <div dojoAttachEvent="onclick:_onButtonClick">
-	<div waiRole="presentation" class="dijitTabInnerDiv" dojoattachpoint="innerDiv,focusNode">
-		<div waiRole="presentation" class="dijitTabContent dijitButtonContents" dojoattachpoint="tabContent">
-			<img waiRole="presentation" alt="" src="${_blankGif}" class="dijitTabStripIcon" dojoAttachPoint="iconNode"/>
+	<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>
 	</div>
diff --git a/dijit/layout/templates/_TabButton.html b/dijit/layout/templates/_TabButton.html
index 42b968c..53ce137 100644
--- a/dijit/layout/templates/_TabButton.html
+++ b/dijit/layout/templates/_TabButton.html
@@ -1,12 +1,12 @@
-<div waiRole="presentation" dojoAttachPoint="titleNode" dojoAttachEvent='onclick:onClick'>
-    <div waiRole="presentation" class='dijitTabInnerDiv' dojoAttachPoint='innerDiv'>
-        <div waiRole="presentation" class='dijitTabContent' dojoAttachPoint='tabContent'>
-        	<div waiRole="presentation" dojoAttachPoint='focusNode'>
-		        <img src="${_blankGif}" alt="" class="dijitIcon" dojoAttachPoint='iconNode' />
+<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' waiRole="presentation">
-		            <span dojoAttachPoint='closeText' class='dijitTabCloseText'>x</span
+		        		dojoAttachEvent='onclick: onClickCloseButton' role="presentation">
+		            <span dojoAttachPoint='closeText' class='dijitTabCloseText'>[x]</span
 		        ></span>
 			</div>
         </div>
diff --git a/dijit/lib/main.js b/dijit/lib/main.js
new file mode 100644
index 0000000..70fd6d4
--- /dev/null
+++ b/dijit/lib/main.js
@@ -0,0 +1,13 @@
+// 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/nls/ar/common.js b/dijit/nls/ar/common.js
index fd6eb5b..16d3947 100644
--- a/dijit/nls/ar/common.js
+++ b/dijit/nls/ar/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "حسنا",
 	buttonCancel: "الغاء",
 	buttonSave: "حفظ",
 	itemClose: "اغلاق"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ar/loading.js b/dijit/nls/ar/loading.js
index e910036..2d87a15 100644
--- a/dijit/nls/ar/loading.js
+++ b/dijit/nls/ar/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "جاري التحميل...",
 	errorState: "عفوا، حدث خطأ"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ca/common.js b/dijit/nls/ca/common.js
index 6c556d8..08ab8bb 100644
--- a/dijit/nls/ca/common.js
+++ b/dijit/nls/ca/common.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "D'acord",
 	buttonCancel: "Cancel·la",
@@ -5,3 +7,5 @@
 	itemClose: "Tanca"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/ca/loading.js b/dijit/nls/ca/loading.js
index 4399fa2..470a995 100644
--- a/dijit/nls/ca/loading.js
+++ b/dijit/nls/ca/loading.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "S'està carregant...",
 	errorState: "Ens sap greu. S'ha produït un error."
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/common.js b/dijit/nls/common.js
index 4625cca..e31c31e 100644
--- a/dijit/nls/common.js
+++ b/dijit/nls/common.js
@@ -1,6 +1,40 @@
+define({ root:
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Cancel",
 	buttonSave: "Save",
 	itemClose: "Close"
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/nls/cs/common.js b/dijit/nls/cs/common.js
index 6ca9673..415a6a3 100644
--- a/dijit/nls/cs/common.js
+++ b/dijit/nls/cs/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Storno",
 	buttonSave: "Uložit",
 	itemClose: "Zavřít"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/cs/loading.js b/dijit/nls/cs/loading.js
index bcd5e96..47c5253 100644
--- a/dijit/nls/cs/loading.js
+++ b/dijit/nls/cs/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Probíhá načítání...",
 	errorState: "Omlouváme se, došlo k chybě"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/da/common.js b/dijit/nls/da/common.js
index ca4787f..ec2795c 100644
--- a/dijit/nls/da/common.js
+++ b/dijit/nls/da/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annullér",
 	buttonSave: "Gem",
 	itemClose: "Luk"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/da/loading.js b/dijit/nls/da/loading.js
index f00490e..306023d 100644
--- a/dijit/nls/da/loading.js
+++ b/dijit/nls/da/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Indlæser...",
 	errorState: "Der er opstået en fejl"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/de/common.js b/dijit/nls/de/common.js
index 9830c21..7a374dd 100755
--- a/dijit/nls/de/common.js
+++ b/dijit/nls/de/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Abbrechen",
 	buttonSave: "Speichern",
 	itemClose: "Schließen"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/de/loading.js b/dijit/nls/de/loading.js
index 3945c4f..435a9fc 100644
--- a/dijit/nls/de/loading.js
+++ b/dijit/nls/de/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Wird geladen...",
 	errorState: "Es ist ein Fehler aufgetreten."
 })
+//end v1.x content
+);
diff --git a/dijit/nls/el/common.js b/dijit/nls/el/common.js
index 48a8e18..a5b3bde 100644
--- a/dijit/nls/el/common.js
+++ b/dijit/nls/el/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "ΟΚ",
 	buttonCancel: "Ακύρωση",
 	buttonSave: "Αποθήκευση",
 	itemClose: "Κλείσιμο"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/el/loading.js b/dijit/nls/el/loading.js
index 06640e7..14efe3a 100644
--- a/dijit/nls/el/loading.js
+++ b/dijit/nls/el/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Φόρτωση...",
 	errorState: "Σας ζητούμε συγνώμη, παρουσιάστηκε σφάλμα"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/es/common.js b/dijit/nls/es/common.js
index 5bf0cc4..55e30eb 100644
--- a/dijit/nls/es/common.js
+++ b/dijit/nls/es/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "Aceptar",
 	buttonCancel: "Cancelar",
 	buttonSave: "Guardar",
 	itemClose: "Cerrar"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/es/loading.js b/dijit/nls/es/loading.js
index 5dd2144..d5e51af 100644
--- a/dijit/nls/es/loading.js
+++ b/dijit/nls/es/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Cargando...",
 	errorState: "Lo siento, se ha producido un error"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/fi/common.js b/dijit/nls/fi/common.js
index 3b7e0c4..23450a5 100644
--- a/dijit/nls/fi/common.js
+++ b/dijit/nls/fi/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Peruuta",
 	buttonSave: "Tallenna",
 	itemClose: "Sulje"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/fi/loading.js b/dijit/nls/fi/loading.js
index d30e1b0..786cfb8 100644
--- a/dijit/nls/fi/loading.js
+++ b/dijit/nls/fi/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Lataus on meneillään...",
 	errorState: "On ilmennyt virhe."
 })
+//end v1.x content
+);
diff --git a/dijit/nls/fr/common.js b/dijit/nls/fr/common.js
index 3a45bcb..0d54bc8 100644
--- a/dijit/nls/fr/common.js
+++ b/dijit/nls/fr/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annuler",
 	buttonSave: "Sauvegarder",
 	itemClose: "Fermer"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/fr/loading.js b/dijit/nls/fr/loading.js
index 116c5ad..9f263c7 100644
--- a/dijit/nls/fr/loading.js
+++ b/dijit/nls/fr/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Chargement...",
 	errorState: "Une erreur est survenue"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/he/common.js b/dijit/nls/he/common.js
index 884a6d1..387db73 100644
--- a/dijit/nls/he/common.js
+++ b/dijit/nls/he/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "אישור",
 	buttonCancel: "ביטול",
 	buttonSave: "שמירה",
 	itemClose: "סגירה"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/he/loading.js b/dijit/nls/he/loading.js
index 1977ce4..c4e13a0 100644
--- a/dijit/nls/he/loading.js
+++ b/dijit/nls/he/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "טעינה...‏",
 	errorState: "אירעה שגיאה"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/hu/common.js b/dijit/nls/hu/common.js
index d20276c..82f7ecd 100644
--- a/dijit/nls/hu/common.js
+++ b/dijit/nls/hu/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Mégse",
 	buttonSave: "Mentés",
 	itemClose: "Bezárás"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/hu/loading.js b/dijit/nls/hu/loading.js
index 8128f82..63d758b 100644
--- a/dijit/nls/hu/loading.js
+++ b/dijit/nls/hu/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Betöltés...",
 	errorState: "Sajnálom, hiba történt"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/it/common.js b/dijit/nls/it/common.js
index ba275de..5d62045 100644
--- a/dijit/nls/it/common.js
+++ b/dijit/nls/it/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annulla",
 	buttonSave: "Salva",
 	itemClose: "Chiudi"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/it/loading.js b/dijit/nls/it/loading.js
index 6970086..a41d6fb 100644
--- a/dijit/nls/it/loading.js
+++ b/dijit/nls/it/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Caricamento in corso...",
 	errorState: "Si è verificato un errore"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ja/common.js b/dijit/nls/ja/common.js
index 32c4436..b364461 100644
--- a/dijit/nls/ja/common.js
+++ b/dijit/nls/ja/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "キャンセル",
 	buttonSave: "保存",
 	itemClose: "閉じる"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ja/loading.js b/dijit/nls/ja/loading.js
index b353f63..741c58e 100644
--- a/dijit/nls/ja/loading.js
+++ b/dijit/nls/ja/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "ロード中...",
 	errorState: "エラーが発生しました。"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/kk/common.js b/dijit/nls/kk/common.js
new file mode 100644
index 0000000..5675fd7
--- /dev/null
+++ b/dijit/nls/kk/common.js
@@ -0,0 +1,10 @@
+define(
+//begin v1.x content
+({
+	buttonOk: "OK",
+	buttonCancel: "Болдырмау",
+	buttonSave: "Сақтау",
+	itemClose: "Жабу"
+})
+//end v1.x content
+);
diff --git a/dijit/nls/kk/loading.js b/dijit/nls/kk/loading.js
new file mode 100644
index 0000000..038534c
--- /dev/null
+++ b/dijit/nls/kk/loading.js
@@ -0,0 +1,8 @@
+define(
+//begin v1.x content
+({
+	loadingState: "Жүктелуде...",
+	errorState: "Кешіріңіз, қате орын алды"
+})
+//end v1.x content
+);
diff --git a/dijit/nls/ko/common.js b/dijit/nls/ko/common.js
index d04333e..172e23a 100644
--- a/dijit/nls/ko/common.js
+++ b/dijit/nls/ko/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "확인",
 	buttonCancel: "취소",
 	buttonSave: "저장",
 	itemClose: "닫기"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ko/loading.js b/dijit/nls/ko/loading.js
index 5e9a2a6..905249c 100644
--- a/dijit/nls/ko/loading.js
+++ b/dijit/nls/ko/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "로드 중...",
 	errorState: "죄송합니다. 오류가 발생했습니다."
 })
+//end v1.x content
+);
diff --git a/dijit/nls/loading.js b/dijit/nls/loading.js
index fe85bad..b46fc40 100644
--- a/dijit/nls/loading.js
+++ b/dijit/nls/loading.js
@@ -1,4 +1,38 @@
+define({ root:
+//begin v1.x content
 ({
 	loadingState: "Loading...",
 	errorState: "Sorry, an error occurred"
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dijit/nls/nb/common.js b/dijit/nls/nb/common.js
index 3768a74..4b87fb8 100644
--- a/dijit/nls/nb/common.js
+++ b/dijit/nls/nb/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Avbryt",
 	buttonSave: "Lagre",
 	itemClose: "Lukk"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/nb/loading.js b/dijit/nls/nb/loading.js
index 13d5722..90b399b 100644
--- a/dijit/nls/nb/loading.js
+++ b/dijit/nls/nb/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Laster inn...",
 	errorState: "Det oppsto en feil"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/nl/common.js b/dijit/nls/nl/common.js
index 93f39f9..bbd4080 100644
--- a/dijit/nls/nl/common.js
+++ b/dijit/nls/nl/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Annuleren",
 	buttonSave: "Opslaan",
 	itemClose: "Sluiten"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/nl/loading.js b/dijit/nls/nl/loading.js
index f8dc69f..4fdcedb 100644
--- a/dijit/nls/nl/loading.js
+++ b/dijit/nls/nl/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Bezig met laden...",
 	errorState: "Er is een fout opgetreden"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/pl/common.js b/dijit/nls/pl/common.js
index 85a8629..c7a6f35 100644
--- a/dijit/nls/pl/common.js
+++ b/dijit/nls/pl/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Anuluj",
 	buttonSave: "Zapisz",
 	itemClose: "Zamknij"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/pl/loading.js b/dijit/nls/pl/loading.js
index 8b70948..5c3e45b 100644
--- a/dijit/nls/pl/loading.js
+++ b/dijit/nls/pl/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Ładowanie...",
 	errorState: "Niestety, wystąpił błąd"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/pt-pt/common.js b/dijit/nls/pt-pt/common.js
index b043944..a7fa342 100644
--- a/dijit/nls/pt-pt/common.js
+++ b/dijit/nls/pt-pt/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Cancelar",
 	buttonSave: "Guardar",
 	itemClose: "Fechar"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/nls/pt-pt/loading.js b/dijit/nls/pt-pt/loading.js
index 07be3ca..45ad394 100644
--- a/dijit/nls/pt-pt/loading.js
+++ b/dijit/nls/pt-pt/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "A carregar...",
 	errorState: "Lamentamos, mas ocorreu um erro"
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dijit/nls/pt/common.js b/dijit/nls/pt/common.js
index 9b0576a..301e314 100644
--- a/dijit/nls/pt/common.js
+++ b/dijit/nls/pt/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Cancelar",
 	buttonSave: "Salvar",
 	itemClose: "Fechar"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/pt/loading.js b/dijit/nls/pt/loading.js
index 418f8ee..3f61ef8 100644
--- a/dijit/nls/pt/loading.js
+++ b/dijit/nls/pt/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Carregando...",
 	errorState: "Desculpe, ocorreu um erro"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ro/common.js b/dijit/nls/ro/common.js
index 9468897..4763ce0 100644
--- a/dijit/nls/ro/common.js
+++ b/dijit/nls/ro/common.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Anulare",
@@ -5,3 +7,5 @@
 	itemClose: "Închidere"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/ro/loading.js b/dijit/nls/ro/loading.js
index 6a956f4..7dd766b 100644
--- a/dijit/nls/ro/loading.js
+++ b/dijit/nls/ro/loading.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Încărcare...",
 	errorState: "Ne pare rău, a apărut o eroare "
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/ru/common.js b/dijit/nls/ru/common.js
index 10d71ab..870e21c 100644
--- a/dijit/nls/ru/common.js
+++ b/dijit/nls/ru/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "ОК",
 	buttonCancel: "Отмена",
 	buttonSave: "Сохранить",
 	itemClose: "Закрыть"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/ru/loading.js b/dijit/nls/ru/loading.js
index d7d7dc9..20465d2 100644
--- a/dijit/nls/ru/loading.js
+++ b/dijit/nls/ru/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Загрузка...",
 	errorState: "Извините, возникла ошибка"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/sk/common.js b/dijit/nls/sk/common.js
index bc2fe93..76748df 100644
--- a/dijit/nls/sk/common.js
+++ b/dijit/nls/sk/common.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Zrušiť",
@@ -5,3 +7,5 @@
 	itemClose: "Zatvoriť"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/sk/loading.js b/dijit/nls/sk/loading.js
index e7853dd..8630175 100644
--- a/dijit/nls/sk/loading.js
+++ b/dijit/nls/sk/loading.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Zavádzanie...",
 	errorState: "Nastala chyba"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/sl/common.js b/dijit/nls/sl/common.js
index fdd260b..751e4fe 100644
--- a/dijit/nls/sl/common.js
+++ b/dijit/nls/sl/common.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "V redu",
 	buttonCancel: "Prekliči",
@@ -5,3 +7,5 @@
 	itemClose: "Zapri"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/sl/loading.js b/dijit/nls/sl/loading.js
index 86bd4db..0ba8233 100644
--- a/dijit/nls/sl/loading.js
+++ b/dijit/nls/sl/loading.js
@@ -1,5 +1,8 @@
+define(
+//begin v1.x content
 ({
-	loadingState: "Nalaganje...",
+	loadingState: "Nalaganje ...",
 	errorState: "Oprostite, prišlo je do napake."
 })
-
+//end v1.x content
+);
diff --git a/dijit/nls/sv/common.js b/dijit/nls/sv/common.js
index 1ad8253..57b368f 100644
--- a/dijit/nls/sv/common.js
+++ b/dijit/nls/sv/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "OK",
 	buttonCancel: "Avbryt",
 	buttonSave: "Spara",
 	itemClose: "Stäng"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/sv/loading.js b/dijit/nls/sv/loading.js
index cc47058..baa5d5a 100644
--- a/dijit/nls/sv/loading.js
+++ b/dijit/nls/sv/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Läser in...",
 	errorState: "Det uppstod ett fel."
 })
+//end v1.x content
+);
diff --git a/dijit/nls/th/common.js b/dijit/nls/th/common.js
index aefd2de..4fa0ef6 100644
--- a/dijit/nls/th/common.js
+++ b/dijit/nls/th/common.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "ตกลง",
 	buttonCancel: "ยกเลิก",
@@ -5,3 +7,5 @@
 	itemClose: "ปิด"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/th/loading.js b/dijit/nls/th/loading.js
index 695bac2..6b99a61 100644
--- a/dijit/nls/th/loading.js
+++ b/dijit/nls/th/loading.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "กำลังโหลด...",
 	errorState: "ขออภัย เกิดข้อผิดพลาด"
 })
 
+//end v1.x content
+);
diff --git a/dijit/nls/tr/common.js b/dijit/nls/tr/common.js
index 21990ee..8a1d058 100644
--- a/dijit/nls/tr/common.js
+++ b/dijit/nls/tr/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "Tamam",
 	buttonCancel: "İptal",
 	buttonSave: "Kaydet",
 	itemClose: "Kapat"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/tr/loading.js b/dijit/nls/tr/loading.js
index f714438..53685e3 100644
--- a/dijit/nls/tr/loading.js
+++ b/dijit/nls/tr/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "Yükleniyor...",
 	errorState: "Üzgünüz, bir hata oluştu"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/zh-tw/common.js b/dijit/nls/zh-tw/common.js
index 8db6f95..46eca0d 100644
--- a/dijit/nls/zh-tw/common.js
+++ b/dijit/nls/zh-tw/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "確定",
 	buttonCancel: "取消",
 	buttonSave: "儲存",
 	itemClose: "關閉"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/zh-tw/loading.js b/dijit/nls/zh-tw/loading.js
index 177bc82..e581a01 100644
--- a/dijit/nls/zh-tw/loading.js
+++ b/dijit/nls/zh-tw/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "載入中...",
 	errorState: "抱歉,發生錯誤"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/zh/common.js b/dijit/nls/zh/common.js
index 5a7aeb2..b70ed72 100644
--- a/dijit/nls/zh/common.js
+++ b/dijit/nls/zh/common.js
@@ -1,6 +1,10 @@
+define(
+//begin v1.x content
 ({
 	buttonOk: "确定",
 	buttonCancel: "取消",
 	buttonSave: "保存",
 	itemClose: "关闭"
 })
+//end v1.x content
+);
diff --git a/dijit/nls/zh/loading.js b/dijit/nls/zh/loading.js
index a367413..a8ae8e6 100644
--- a/dijit/nls/zh/loading.js
+++ b/dijit/nls/zh/loading.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 ({
 	loadingState: "正在加载...",
 	errorState: "对不起,发生了错误"
 })
+//end v1.x content
+);
diff --git a/dijit/package.json b/dijit/package.json
new file mode 100644
index 0000000..9ca9423
--- /dev/null
+++ b/dijit/package.json
@@ -0,0 +1,24 @@
+{
+  "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
diff --git a/dijit/robot.js b/dijit/robot.js
index 83338db..56b8b9e 100644
--- a/dijit/robot.js
+++ b/dijit/robot.js
@@ -1,2 +1,6 @@
-dojo.provide("dijit.robot");
-dojo.require("dojo.robot");
+define("dijit/robot", ["dojo", "dijit", "dojo/robot"], function(dojo, dijit) {
+
+
+
+return dijit;
+});
diff --git a/dijit/robotx.js b/dijit/robotx.js
index 8fb1eec..e25ed95 100644
--- a/dijit/robotx.js
+++ b/dijit/robotx.js
@@ -1,6 +1,8 @@
-dojo.provide("dijit.robotx");
-dojo.require("dijit.robot");
-dojo.require("dojo.robotx");
+define("dijit/robotx", ["dojo", "dijit", "dijit/robot", "dojo/robotx"], function(dojo, dijit_) {
+
+//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");
 (function(){
 var __updateDocument = doh.robot._updateDocument;
@@ -10,9 +12,13 @@ dojo.mixin(doh.robot,{
 		__updateDocument();
 		var win = dojo.global;
 		if(win["dijit"]){
-			dijit = win.dijit;
+			window.dijit = win.dijit; // window reference needed for IE
 		}
 	}
 });
 
 })();
+
+
+return dijit_;
+});
diff --git a/dijit/templates/Calendar.html b/dijit/templates/Calendar.html
index 680c495..15294bd 100644
--- a/dijit/templates/Calendar.html
+++ b/dijit/templates/Calendar.html
@@ -1,21 +1,17 @@
-<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" dojoAttachEvent="onkeypress: _onKeyPress">
+<table cellspacing="0" cellpadding="0" class="dijitCalendarContainer" role="grid" dojoAttachEvent="onkeypress: _onKeyPress" aria-labelledby="${id}_year">
 	<thead>
 		<tr class="dijitReset dijitCalendarMonthContainer" valign="top">
 			<th class='dijitReset dijitCalendarArrow' dojoAttachPoint="decrementMonth">
-				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarDecrease" waiRole="presentation"/>
+				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarDecrease" role="presentation"/>
 				<span dojoAttachPoint="decreaseArrowNode" class="dijitA11ySideArrow">-</span>
 			</th>
 			<th class='dijitReset' colspan="5">
-				<div class="dijitVisible">
-					<div class="dijitPopup dijitMenu dijitMenuPassive dijitHidden" dojoAttachPoint="monthDropDown" dojoAttachEvent="onmouseup: _onMonthSelect, onmouseover: _onMenuHover, onmouseout: _onMenuHover">
-						<div class="dijitCalendarMonthLabelTemplate dijitCalendarMonthLabel"></div>
-					</div>
+				<div dojoType="dijit.form.DropDownButton" dojoAttachPoint="monthDropDownButton"
+					id="${id}_mddb" tabIndex="-1">
 				</div>
-				<div dojoAttachPoint="monthLabelSpacer" class="dijitSpacer"></div>
-				<div dojoAttachPoint="monthLabelNode" class="dijitCalendarMonthLabel dijitInline dijitVisible" dojoAttachEvent="onmousedown: _onMonthToggle"></div>
 			</th>
 			<th class='dijitReset dijitCalendarArrow' dojoAttachPoint="incrementMonth">
-				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarIncrease" waiRole="presentation"/>
+				<img src="${_blankGif}" alt="" class="dijitCalendarIncrementControl dijitCalendarIncrease" role="presentation"/>
 				<span dojoAttachPoint="increaseArrowNode" class="dijitA11ySideArrow">+</span>
 			</th>
 		</tr>
@@ -33,7 +29,7 @@
 			<td class='dijitReset' valign="top" colspan="7">
 				<h3 class="dijitCalendarYearLabel">
 					<span dojoAttachPoint="previousYearLabelNode" class="dijitInline dijitCalendarPreviousYear"></span>
-					<span dojoAttachPoint="currentYearLabelNode" class="dijitInline dijitCalendarSelectedYear"></span>
+					<span dojoAttachPoint="currentYearLabelNode" class="dijitInline dijitCalendarSelectedYear" id="${id}_year"></span>
 					<span dojoAttachPoint="nextYearLabelNode" class="dijitInline dijitCalendarNextYear"></span>
 				</h3>
 			</td>
diff --git a/dijit/templates/CheckedMenuItem.html b/dijit/templates/CheckedMenuItem.html
index a0b6146..1edfebf 100644
--- a/dijit/templates/CheckedMenuItem.html
+++ b/dijit/templates/CheckedMenuItem.html
@@ -1,10 +1,10 @@
-<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" waiRole="menuitemcheckbox" tabIndex="-1"
+<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" role="menuitemcheckbox" tabIndex="-1"
 		dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
-	<td class="dijitReset dijitMenuItemIconCell" waiRole="presentation">
+	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
 		<img src="${_blankGif}" alt="" class="dijitMenuItemIcon dijitCheckedMenuItemIcon" dojoAttachPoint="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" waiRole="presentation"> </td>
+	<td class="dijitReset dijitMenuArrowCell" role="presentation"> </td>
 </tr>
diff --git a/dijit/templates/ColorPalette.html b/dijit/templates/ColorPalette.html
index aa35a15..125bd88 100644
--- a/dijit/templates/ColorPalette.html
+++ b/dijit/templates/ColorPalette.html
@@ -1,5 +1,4 @@
 <div class="dijitInline dijitColorPalette">
-	<img class="dijitColorPaletteUnder" dojoAttachPoint="imageNode" waiRole="presentation" alt=""/>
 	<table class="dijitPaletteTable" cellSpacing="0" cellPadding="0">
 		<tbody dojoAttachPoint="gridNode"></tbody>
 	</table>
diff --git a/dijit/templates/Dialog.html b/dijit/templates/Dialog.html
index 26357cd..2c263a8 100644
--- a/dijit/templates/Dialog.html
+++ b/dijit/templates/Dialog.html
@@ -1,7 +1,7 @@
-<div class="dijitDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+<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="onclick: onCancel" title="${buttonCancel}">
+	<span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="ondijitclick: onCancel" title="${buttonCancel}" role="button" tabIndex="-1">
 		<span dojoAttachPoint="closeText" class="closeText" title="${buttonCancel}">x</span>
 	</span>
 	</div>
diff --git a/dijit/templates/InlineEditBox.html b/dijit/templates/InlineEditBox.html
index 5d0a609..75451e3 100644
--- a/dijit/templates/InlineEditBox.html
+++ b/dijit/templates/InlineEditBox.html
@@ -1,8 +1,10 @@
-<span dojoAttachPoint="editNode" waiRole="presentation" style="position: absolute; visibility:hidden" class="dijitReset dijitInline"
-	dojoAttachEvent="onkeypress: _onKeyPress"
-	><span dojoAttachPoint="editorPlaceholder"></span
-	><span dojoAttachPoint="buttonContainer"
-		><button class='saveButton' dojoAttachPoint="saveButton" dojoType="dijit.form.Button" dojoAttachEvent="onClick:save" label="${buttonSave}"></button
-		><button class='cancelButton' dojoAttachPoint="cancelButton" dojoType="dijit.form.Button" dojoAttachEvent="onClick:cancel" label="${buttonCancel}"></button
+<span data-dojo-attach-point="editNode" role="presentation" style="position: absolute; visibility:hidden" class="dijitReset dijitInline"
+	data-dojo-attach-event="onkeypress: _onKeyPress"
+	><span data-dojo-attach-point="editorPlaceholder"></span
+	><span data-dojo-attach-point="buttonContainer"
+		><button data-dojo-type="dijit.form.Button" data-dojo-props="label: '${buttonSave}', 'class': 'saveButton'"
+			data-dojo-attach-point="saveButton" data-dojo-attach-event="onClick:save"></button
+		><button data-dojo-type="dijit.form.Button"  data-dojo-props="label: '${buttonCancel}', 'class': 'cancelButton'"
+			data-dojo-attach-point="cancelButton" data-dojo-attach-event="onClick:cancel"></button
 	></span
 ></span>
diff --git a/dijit/templates/Menu.html b/dijit/templates/Menu.html
index eac5faa..b0a7cab 100644
--- a/dijit/templates/Menu.html
+++ b/dijit/templates/Menu.html
@@ -1,3 +1,3 @@
-<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" waiRole="menu" tabIndex="${tabIndex}" dojoAttachEvent="onkeypress:_onKeyPress" cellspacing=0>
+<table class="dijit dijitMenu dijitMenuPassive dijitReset dijitMenuTable" role="menu" tabIndex="${tabIndex}" dojoAttachEvent="onkeypress:_onKeyPress" cellspacing="0">
 	<tbody class="dijitReset" dojoAttachPoint="containerNode"></tbody>
 </table>
diff --git a/dijit/templates/MenuBar.html b/dijit/templates/MenuBar.html
index 4c6ad33..f94db38 100644
--- a/dijit/templates/MenuBar.html
+++ b/dijit/templates/MenuBar.html
@@ -1 +1 @@
-<div class="dijitMenuBar dijitMenuPassive" dojoAttachPoint="containerNode"  waiRole="menubar" tabIndex="${tabIndex}" dojoAttachEvent="onkeypress: _onKeyPress"></div>
+<div class="dijitMenuBar dijitMenuPassive" dojoAttachPoint="containerNode"  role="menubar" tabIndex="${tabIndex}" dojoAttachEvent="onkeypress: _onKeyPress"></div>
diff --git a/dijit/templates/MenuBarItem.html b/dijit/templates/MenuBarItem.html
index 8a89132..4705ad2 100644
--- a/dijit/templates/MenuBarItem.html
+++ b/dijit/templates/MenuBarItem.html
@@ -1,4 +1,4 @@
-<div class="dijitReset dijitInline dijitMenuItem dijitMenuItemLabel" dojoAttachPoint="focusNode" waiRole="menuitem" tabIndex="-1"
+<div class="dijitReset dijitInline dijitMenuItem dijitMenuItemLabel" dojoAttachPoint="focusNode" role="menuitem" tabIndex="-1"
 		dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
 	<span dojoAttachPoint="containerNode"></span>
 </div>
diff --git a/dijit/templates/MenuItem.html b/dijit/templates/MenuItem.html
index e13c3fb..abde6bc 100644
--- a/dijit/templates/MenuItem.html
+++ b/dijit/templates/MenuItem.html
@@ -1,11 +1,11 @@
-<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" waiRole="menuitem" tabIndex="-1"
+<tr class="dijitReset dijitMenuItem" dojoAttachPoint="focusNode" role="menuitem" tabIndex="-1"
 		dojoAttachEvent="onmouseenter:_onHover,onmouseleave:_onUnhover,ondijitclick:_onClick">
-	<td class="dijitReset dijitMenuItemIconCell" waiRole="presentation">
+	<td class="dijitReset dijitMenuItemIconCell" role="presentation">
 		<img src="${_blankGif}" alt="" class="dijitIcon dijitMenuItemIcon" dojoAttachPoint="iconNode"/>
 	</td>
 	<td class="dijitReset dijitMenuItemLabel" colspan="2" dojoAttachPoint="containerNode"></td>
 	<td class="dijitReset dijitMenuItemAccelKey" style="display: none" dojoAttachPoint="accelKeyNode"></td>
-	<td class="dijitReset dijitMenuArrowCell" waiRole="presentation">
+	<td class="dijitReset dijitMenuArrowCell" role="presentation">
 		<div dojoAttachPoint="arrowWrapper" style="visibility: hidden">
 			<img src="${_blankGif}" alt="" class="dijitMenuExpand"/>
 			<span class="dijitMenuExpandA11y">+</span>
diff --git a/dijit/templates/ProgressBar.html b/dijit/templates/ProgressBar.html
index 7eeb733..33c7ee7 100644
--- a/dijit/templates/ProgressBar.html
+++ b/dijit/templates/ProgressBar.html
@@ -1,8 +1,8 @@
-<div class="dijitProgressBar dijitProgressBarEmpty"
-	><div waiRole="progressbar" dojoAttachPoint="internalProgress" class="dijitProgressBarFull"
-		><div class="dijitProgressBarTile"></div
+<div class="dijitProgressBar dijitProgressBarEmpty" role="progressbar"
+	><div  dojoAttachPoint="internalProgress" class="dijitProgressBarFull"
+		><div class="dijitProgressBarTile" role="presentation"></div
 		><span style="visibility:hidden"> </span
 	></div
-	><div dojoAttachPoint="label" class="dijitProgressBarLabel" id="${id}_label"> </div
+	><div dojoAttachPoint="labelNode" class="dijitProgressBarLabel" id="${id}_label"></div
 	><img dojoAttachPoint="indeterminateHighContrastImage" class="dijitProgressBarIndeterminateHighContrastImage" alt=""
 /></div>
diff --git a/dijit/templates/TimePicker.html b/dijit/templates/TimePicker.html
index e94d957..66d5491 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" wairole="presentation" role="presentation"> </div
+		><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" wairole="presentation" role="presentation"> </div
+		><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 c272d65..82823d7 100644
--- a/dijit/templates/TitlePane.html
+++ b/dijit/templates/TitlePane.html
@@ -2,14 +2,14 @@
 	<div dojoAttachEvent="onclick:_onTitleClick, onkeypress:_onTitleKey"
 			class="dijitTitlePaneTitle" dojoAttachPoint="titleBarNode">
 		<div class="dijitTitlePaneTitleFocus" dojoAttachPoint="focusNode">
-			<img src="${_blankGif}" alt="" dojoAttachPoint="arrowNode" class="dijitArrowNode" waiRole="presentation"
+			<img src="${_blankGif}" alt="" dojoAttachPoint="arrowNode" class="dijitArrowNode" role="presentation"
 			/><span dojoAttachPoint="arrowNodeInner" class="dijitArrowNodeInner"></span
 			><span dojoAttachPoint="titleNode" class="dijitTitlePaneTextNode"></span>
 		</div>
 	</div>
-	<div class="dijitTitlePaneContentOuter" dojoAttachPoint="hideNode" waiRole="presentation">
-		<div class="dijitReset" dojoAttachPoint="wipeNode" waiRole="presentation">
-			<div class="dijitTitlePaneContentInner" dojoAttachPoint="containerNode" waiRole="region" tabindex="-1" id="${id}_pane">
+	<div class="dijitTitlePaneContentOuter" dojoAttachPoint="hideNode" role="presentation">
+		<div class="dijitReset" dojoAttachPoint="wipeNode" role="presentation">
+			<div class="dijitTitlePaneContentInner" dojoAttachPoint="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 8739648..506ec74 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" waiRole='alert'></div>
-	<div class="dijitTooltipConnector"></div>
-</div>
+<div class="dijitTooltip dijitTooltipLeft" id="dojoTooltip"
+	><div class="dijitTooltipContainer dijitTooltipContents" dojoAttachPoint="containerNode" role='alert'></div
+	><div class="dijitTooltipConnector" dojoAttachPoint="connectorNode"></div
+></div>
diff --git a/dijit/templates/TooltipDialog.html b/dijit/templates/TooltipDialog.html
index d8cbaee..2f1bba2 100644
--- a/dijit/templates/TooltipDialog.html
+++ b/dijit/templates/TooltipDialog.html
@@ -1,6 +1,6 @@
-<div waiRole="presentation">
-	<div class="dijitTooltipContainer" waiRole="presentation">
-		<div class ="dijitTooltipContents dijitTooltipFocusNode" dojoAttachPoint="containerNode" tabindex="-1" waiRole="dialog"></div>
+<div role="presentation" tabIndex="-1">
+	<div class="dijitTooltipContainer" role="presentation">
+		<div class ="dijitTooltipContents dijitTooltipFocusNode" dojoAttachPoint="containerNode" role="dialog"></div>
 	</div>
-	<div class="dijitTooltipConnector" waiRole="presentation"></div>
+	<div class="dijitTooltipConnector" role="presentation"></div>
 </div>
diff --git a/dijit/templates/Tree.html b/dijit/templates/Tree.html
index ee331d1..e5112b0 100644
--- a/dijit/templates/Tree.html
+++ b/dijit/templates/Tree.html
@@ -1,4 +1,4 @@
-<div class="dijitTree dijitTreeContainer" waiRole="tree"
+<div class="dijitTree dijitTreeContainer" role="tree"
 	dojoAttachEvent="onkeypress:_onKeyPress">
 	<div class="dijitInline dijitTreeIndent" style="position: absolute; top: -9999px" dojoAttachPoint="indentDetector"></div>
 </div>
diff --git a/dijit/templates/TreeNode.html b/dijit/templates/TreeNode.html
index 47df19a..a9ac539 100644
--- a/dijit/templates/TreeNode.html
+++ b/dijit/templates/TreeNode.html
@@ -1,13 +1,13 @@
-<div class="dijitTreeNode" waiRole="presentation"
-	><div dojoAttachPoint="rowNode" class="dijitTreeRow" waiRole="presentation" dojoAttachEvent="onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onclick:_onClick, ondblclick:_onDblClick"
-		><img src="${_blankGif}" alt="" dojoAttachPoint="expandoNode" class="dijitTreeExpando" waiRole="presentation"
-		/><span dojoAttachPoint="expandoNodeText" class="dijitExpandoText" waiRole="presentation"
+<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"
 		></span
 		><span dojoAttachPoint="contentNode"
-			class="dijitTreeContent" waiRole="presentation">
-			<img src="${_blankGif}" alt="" dojoAttachPoint="iconNode" class="dijitIcon dijitTreeIcon" waiRole="presentation"
-			/><span dojoAttachPoint="labelNode" class="dijitTreeLabel" wairole="treeitem" tabindex="-1" waiState="selected-false" dojoAttachEvent="onfocus:_onLabelFocus"></span>
+			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>
 		</span
 	></div>
-	<div dojoAttachPoint="containerNode" class="dijitTreeContainer" waiRole="presentation" style="display: none;"></div>
+	<div dojoAttachPoint="containerNode" class="dijitTreeContainer" role="presentation" style="display: none;"></div>
 </div>
diff --git a/dijit/tests/Bidi.html b/dijit/tests/Bidi.html
new file mode 100755
index 0000000..06cdfee
--- /dev/null
+++ b/dijit/tests/Bidi.html
@@ -0,0 +1,374 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+	<title>Multi-directional document test</title>
+
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="extraLocale: ['en','ar','he'], isDebug: true"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dojo.data.ItemFileReadStore");
+
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.Tree");
+		dojo.require("dijit.tree.ForestStoreModel");
+
+		dojo.require("dijit.Menu");
+		dojo.require("dijit.MenuItem");
+		dojo.require("dijit.PopupMenuItem");
+
+		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.DropDownButton");
+		dojo.require("dijit.form.ComboButton");
+		dojo.require("dijit.form.ToggleButton");
+
+		dojo.require("dijit.ColorPalette");
+		dojo.require("dijit.Toolbar");
+		dojo.require("dijit.TooltipDialog");
+
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.DateTextBox");
+		dojo.require("dijit.form.NumberSpinner");
+		dojo.require("dijit.form.ComboBox");
+
+		dojo.require("dijit.layout.TabContainer");
+		dojo.require("dijit.layout.ContentPane");
+
+		dojo.require("dojo.parser");
+
+		dojo.require("doh.runner");
+
+		function checkLeft(/*Widget*/ left, /*Widget*/ right){
+			if(left.domNode) left = left.domNode;
+			if(right.domNode) right = right.domNode;
+
+			var lp = dojo.position(left, true),
+				rp = dojo.position(right, true);
+
+			doh.t(lp.x+lp.w-0.1 <= rp.x,
+				left.id + " to left of " + right.id + dojo.toJson(lp) + dojo.toJson(rp)
+			);
+		}
+
+		dojo.addOnLoad(function(){
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("Test bidi toolbar", [
+				{
+					name: "toolbar checkLeft",
+					runTest: function(){
+						//Check that the order of the menu buttons is correct
+						checkLeft(dijit.byId("ltr_ToolbarCutButton"), dijit.byId("ltr_ToolbarDropDown"));
+						checkLeft(dijit.byId("ltr_ToolbarDropDown"), dijit.byId("ltr_ToolbarColorDropDown"));
+						checkLeft(dijit.byId("ltr_ToolbarColorDropDown"), dijit.byId("ltr_ToolbarComboButton"));
+						checkLeft(dijit.byId("rtl_ToolbarComboButton"), dijit.byId("rtl_ToolbarColorDropDown"));
+						checkLeft(dijit.byId("rtl_ToolbarColorDropDown"), dijit.byId("rtl_ToolbarDropDown"));
+						checkLeft(dijit.byId("rtl_ToolbarDropDown"), dijit.byId("rtl_ToolbarCutButton"));
+					}
+				},
+				{
+					name: "ltr_ToolbarDropDown",
+					runTest: function(){
+						dijit.byId("ltr_ToolbarDropDown").openDropDown();
+
+						checkLeft(dojo.byId("ltr_l1"), dijit.byId("ltr_i1"));
+						checkLeft(dojo.byId("ltr_l2"), dijit.byId("ltr_i2"));
+						checkLeft(dojo.byId("ltr_l3"), dijit.byId("ltr_i3"));
+
+						doh.is("ltr", dojo.byId("widget_ltr_i1").dir);
+						doh.is("ltr", dojo.byId("widget_ltr_i2").dir);
+						doh.is("ltr", dojo.byId("widget_ltr_i3").dir);
+						doh.is("ltr", dijit.byId("ltr_button").dir);
+					}
+				},
+				{
+					name: "rtl_ToolbarDropDown",
+					runTest: function(){
+						dijit.byId("rtl_ToolbarDropDown").openDropDown();
+
+						checkLeft(dijit.byId("rtl_i1"), dojo.byId("rtl_l1"));
+						checkLeft(dijit.byId("rtl_i2"), dojo.byId("rtl_l2"));
+						checkLeft(dijit.byId("rtl_i3"), dojo.byId("rtl_l3"));
+
+						doh.is("rtl", dojo.byId("widget_rtl_i1").dir);
+						doh.is("rtl", dojo.byId("widget_rtl_i2").dir);
+						doh.is("rtl", dojo.byId("widget_rtl_i3").dir);
+						doh.is("rtl", dijit.byId("rtl_button").dir);
+					}
+				},
+				{
+					name: "ltr_ToolbarColorDropDown",
+					runTest: function(){
+						dijit.byId("ltr_ToolbarColorDropDown").openDropDown();
+
+						var white = dojo.query("img[alt='white']", dojo.byId("ltr_colorPalette"))[0];
+						var plum = dojo.query("img[alt='plum']", dojo.byId("ltr_colorPalette"))[0];
+						checkLeft(white, plum);
+					}
+				},
+				{
+					name: "rtl_ToolbarColorDropDown",
+					runTest: function(){
+						dijit.byId("rtl_ToolbarColorDropDown").openDropDown();
+
+						var white = dojo.query("img[alt='white']", dojo.byId("rtl_colorPalette"))[0];
+						var plum = dojo.query("img[alt='plum']", dojo.byId("rtl_colorPalette"))[0];
+						checkLeft(plum, white);
+					}
+				},
+				{
+					name: "ltr_ToolbarMenuDropDown",
+					runTest: function(){
+						dijit.byId("ltr_ToolbarComboButton").openDropDown();
+
+						var icon = dijit.byId("ltr_mi1").iconNode;
+						var label = dijit.byId("ltr_mi1").containerNode;
+						checkLeft(icon, label);
+					}
+				},
+				{
+					name: "ltr_Toolbar_nested_menu",
+					runTest: function(){
+						dijit.byId("ltr_popup_mi1")._onClick({preventDefault: function(){}, stopPropagation: function(){}});
+
+						var icon = dijit.byId("ltr_popup_mi1").iconNode;
+						var label = dijit.byId("ltr_popup_mi1").containerNode;
+						checkLeft(icon, label);
+					}
+				},
+				{
+					name: "rtl_ToolbarMenuDropDown",
+					runTest: function(){
+						dijit.byId("rtl_ToolbarComboButton").openDropDown();
+
+						var icon = dijit.byId("rtl_mi1").iconNode;
+						var label = dijit.byId("rtl_mi1").containerNode;
+						checkLeft(label, icon);
+					}
+				},
+				{
+					name: "rtl_Toolbar_nested_menu",
+					runTest: function(){
+						dijit.byId("rtl_popup_mi1")._onClick({preventDefault: function(){}, stopPropagation: function(){}});
+
+						var icon = dijit.byId("rtl_popup_mi1").iconNode;
+						var label = dijit.byId("rtl_popup_mi1").containerNode;
+						checkLeft(label, icon);
+					}
+				}
+			]);
+
+			doh.register("Test bidi tab container", [
+				{
+					name: "ltr TabContainer",
+					runTest: function(){
+						// Check that the order of the tabs is correct
+						checkLeft(dijit.byId("ltr_tc_tablist_ltr_tc_cp"), dijit.byId("ltr_tc_tablist_ltr_tc_tree"));
+
+						// Check the fields on each of the first tabs
+						doh.is("ltr", dijit.byId("ltr_tc_cp").dir);
+
+						var combo = dojo.query("input[value='dijit']", dojo.byId("ltr_tc_cp"))[0];
+						var arrow = dojo.query(".dijitButtonNode", dojo.byId("ltr_tc_cp"))[0];
+						checkLeft(combo, arrow);
+					}
+				},
+				{
+					name: "rtl TabContainer",
+					runTest: function(){
+						// Check that the order of the tabs is correct
+						checkLeft(dijit.byId("rtl_tc_tablist_rtl_tc_tree"), dijit.byId("rtl_tc_tablist_rtl_tc_cp"));
+
+						// Check the fields on each of the first tabs
+						doh.is("rtl", dijit.byId("rtl_tc_cp").dir);
+
+						combo = dojo.query("input[value='dijit']", dojo.byId("rtl_tc_cp"))[0];
+						arrow = dojo.query(".dijitButtonNode", dojo.byId("rtl_tc_cp"))[0];
+						checkLeft(arrow, combo);
+					}
+				}
+			]);
+
+			doh.register("Tree", [
+				{
+					name: "ltr_tree",
+					runTest: function(){
+						dijit.byId("ltr_tc").selectChild("ltr_tc_tree");
+
+						var rowNodes = dojo.query(".dijitTreeRow", dojo.byId("ltr_tc_tree"));
+
+						dojo.forEach(rowNodes, function(rowNode){
+							var expando = dojo.query(".dijitTreeExpando", rowNode)[0];
+							var label = dojo.query(".dijitTreeContent", rowNode)[0];
+							checkLeft(expando, label);
+						});
+					}
+				},
+				{
+					name: "rtl_tree",
+					runTest: function(){
+						dijit.byId("rtl_tc").selectChild("rtl_tc_tree");
+
+						var rowNodes = dojo.query(".dijitTreeRow", dojo.byId("rtl_tc_tree"));
+
+						dojo.forEach(rowNodes, function(rowNode){
+							var expando = dojo.query(".dijitTreeExpando", rowNode)[0];
+							var label = dojo.query(".dijitTreeContent", rowNode)[0];
+							checkLeft(label, expando);
+						});
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Multi-directional document test</h1>
+
+	<div data-dojo-id="continentStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"_data/countries.json"'></div>
+	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
+		rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
+
+	<div id="right" dir="rtl" lang="ar-eg" style="float: right; width: 500px;">
+		<h2>RTL</h2>
+
+		<div data-dojo-type="dijit.Toolbar"
+				><div id="rtl_ToolbarCutButton" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
+				><div id="rtl_ToolbarDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
+					<span>שיח</span>
+					<div data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information"'>
+						<table>
+							<tr>
+								<td><label id="rtl_l1">שם:</label></td>
+								<td><input id="rtl_i1" data-dojo-type="dijit.form.TextBox"/></td>
+							</tr>
+							<tr>
+								<td><label id="rtl_l2">תאריך:</label></td>
+								<td><input id="rtl_i2" data-dojo-type="dijit.form.DateTextBox"/></td>
+							</tr>
+							<tr>
+								<td><label id="rtl_l3">גיל:</label></td>
+								<td><input id="rtl_i3" data-dojo-type="dijit.form.NumberSpinner"/></td>
+							</tr>
+							<tr>
+								<td colspan="2" style="text-align:center;">
+									<button id="rtl_button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", name:"submit"'>כניסה</button>
+								</td>
+							</tr>
+						</table>
+					</div
+				></div
+				><div id="rtl_ToolbarColorDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
+					<span>لوحة الألوان</span>
+					<div id="rtl_colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display:none;", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
+				</div
+				><div id="rtl_ToolbarComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true'>
+					<span>القائمة</span>
+					<div data-dojo-type="dijit.Menu" data-dojo-props='style:"display:none;"'>
+						<div id="rtl_mi1" data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave"'>حفظ</div>
+						<div data-dojo-type="dijit.MenuItem">حفظ ك</div>
+						<div id="rtl_popup_mi1" data-dojo-type="dijit.PopupMenuItem">
+							<span>فرعية</span>
+							<div data-dojo-type="dijit.Menu">
+								<div data-dojo-type="dijit.MenuItem">Submenu Item One</div>
+								<div data-dojo-type="dijit.MenuItem">Submenu Item Two</div>
+								<div data-dojo-type="dijit.PopupMenuItem">
+									<span>Deeper Submenu</span>
+									<div data-dojo-type="dijit.Menu">
+										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item One</div>
+										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item Two</div>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div
+		></div>
+		<div id="rtl_tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 450px; height: 300px; margin-top: 1em;"'>
+			<div id="rtl_tc_cp" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"رابط", closable:true, href:"layout/doc0.html"'></div>
+			<div id="rtl_tc_tree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true, title:"עץ", closable:true'></div>
+		</div>
+	</div>
+
+	<div id="left" dir="ltr" lang="en-us" style="width: 500px; float: left;">
+		<h2>LTR</h2>
+
+		<div data-dojo-type="dijit.Toolbar"
+				><div id="ltr_ToolbarCutButton" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
+				><div id="ltr_ToolbarDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
+					<span>TooltipDialog</span>
+					<div data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information"'>
+						<table>
+							<tr>
+								<td><label id="ltr_l1">Name:</label></td>
+								<td><input id="ltr_i1" data-dojo-type="dijit.form.TextBox"/></td>
+							</tr>
+							<tr>
+								<td><label id="ltr_l2">Date:</label></td>
+								<td><input id="ltr_i2" data-dojo-type="dijit.form.DateTextBox"/></td>
+							</tr>
+							<tr>
+								<td><label id="ltr_l3">Age:</label></td>
+								<td><input id="ltr_i3" data-dojo-type="dijit.form.NumberSpinner"/></td>
+							</tr>
+							<tr>
+								<td colspan="2" style="text-align:center;">
+									<button id="ltr_button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", name:"submit"'>Login</button></td>
+							</tr>
+						</table>
+					</div
+				></div
+				><div id="ltr_ToolbarColorDropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
+					<span>ColorPalette</span>
+					<div id="ltr_colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display:none;", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
+				</div
+				><div id="ltr_ToolbarComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true'>
+					<span>Menu</span>
+					<div data-dojo-type="dijit.Menu" data-dojo-props='style:"display none;"'>
+						<div id="ltr_mi1" data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave"'>Save</div>
+						<div data-dojo-type="dijit.MenuItem">Save As</div>
+						<div id="ltr_popup_mi1" data-dojo-type="dijit.PopupMenuItem">
+							<span>Enabled Submenu</span>
+							<div data-dojo-type="dijit.Menu">
+								<div data-dojo-type="dijit.MenuItem">Submenu Item One</div>
+								<div data-dojo-type="dijit.MenuItem">Submenu Item Two</div>
+								<div data-dojo-type="dijit.PopupMenuItem">
+									<span>Deeper Submenu</span>
+									<div data-dojo-type="dijit.Menu">
+										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item One</div>
+										<div data-dojo-type="dijit.MenuItem">Sub-sub-menu Item Two</div>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div
+		></div>
+
+		<div id="ltr_tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 450px; height: 300px; margin-top: 1em;"'>
+			<div id="ltr_tc_cp" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Href", closable:true, href:"layout/doc0.html"'></div>
+			<div id="ltr_tc_tree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true, title:"Tree", closable:true'></div>
+		</div>
+
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/Dialog.html b/dijit/tests/Dialog.html
new file mode 100644
index 0000000..09be048
--- /dev/null
+++ b/dijit/tests/Dialog.html
@@ -0,0 +1,422 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Dialog Widget Automated (non-robot) Tests</title>
+
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<!-- 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>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.Dialog");
+
+		dojo.addOnLoad(function(){
+			// Non robot tests to see if nested dialogs work correctly
+			// when obscured dialogs are destroyed/hidden, on race conditions of
+			// multiple dialogs fading in/out at once, etc.
+			doh.register("out-of-order dialog hide/destroy", [
+				{
+					name: "open first dialog",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg1;
+
+						// Start focus on a button on the page (although we aren't going
+						// to click the button)
+						dojo.byId("button").focus();
+
+						// Create and show first dialog
+						dlg1 = new dijit.Dialog({
+							id: "dlg1",
+							title: "dialog 1",
+							content:
+								"<input id='dlg1_inputA'><br>" +
+								"<input id='dlg1_inputB'><br>" +
+								"<input id='dlg1_inputC'><br>" +
+								"<input id='dlg1_inputD'><br>" +
+								"<input id='dlg1_inputE'><br>" +
+								"<input id='dlg1_inputF'><br>" +
+								"<input id='dlg1_inputG'><br>" +
+								"<input id='dlg1_inputH'><br>"
+						});
+						dlg1.show().then(d.getTestCallback(function(){
+							doh.t(isVisible(dlg1), "dialog 1 is visible");
+
+							var dialog1Z = dojo.style(dlg1.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+
+							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");
+
+							// For back-compat, startup() should be called on children even if Dialog.startup()
+							// isn't called explicitly.							
+							doh.t(dlg1._started, "dlg1 started");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "open second dialog",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg1 = dijit.byId("dlg1"),
+							dlg2;
+
+						// Create and show second dialog
+						dlg2 = new dijit.Dialog({
+							id: "dlg2",
+							title: "dialog 2",
+							content:
+								"<input id='dlg2_inputA'><br>" +
+								"<input id='dlg2_inputB'><br>" +
+								"<input id='dlg2_inputC'><br>" +
+								"<input id='dlg2_inputD'><br>" +
+								"<input id='dlg2_inputE'><br>" +
+								"<input id='dlg2_inputF'><br>"
+						});
+						dlg2.show().then(d.getTestCallback(function(){
+							doh.t(isVisible(dlg2), "dialog 2 is visible");
+
+							var dialog1Z = dojo.style(dlg1.domNode, "zIndex"),
+								dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+
+							doh.t(underlayZ > dialog1Z, "underlay (zIndex=" + underlayZ +
+								") above dialog1 (zIndex=" + dialog1Z + ")");
+							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
+								") above underlay (zIndex=" + underlayZ + ")");
+
+							doh.is("dlg2_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "destroy first dialog",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg1 = dijit.byId("dlg1"),
+							dlg2 = dijit.byId("dlg2");
+
+						dlg1.destroy();
+
+						setTimeout(d.getTestCallback(function(){
+							doh.t(isVisible(dlg2), "dialog 2 is still visible");
+							doh.t(isVisible(dojo.global.dijit._underlay), "underlay is still visible");
+
+							doh.is("dlg2_inputA", dojo.global.dijit._curFocus.id, "dialog 2 still has focus");
+
+							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+
+							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
+								") above underlay (zIndex=" + underlayZ + ")");
+
+						}), 2000);
+
+						return d;
+					}
+				},
+				{
+					name: "open third dialog",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg2 = dijit.byId("dlg2"),
+							dlg3;
+
+						// Create and show third dialog
+						dlg3 = new dijit.Dialog({
+							id: "dlg3",
+							title: "dialog 3",
+							content:
+								"<input id='dlg3_inputA'><br>" +
+								"<input id='dlg3_inputB'><br>" +
+								"<input id='dlg3_inputC'><br>" +
+								"<input id='dlg3_inputD'><br>"
+
+						});
+						dlg3.show().then(d.getTestCallback(function(){
+							doh.t(isVisible(dlg3), "dialog 3 is visible");
+
+							// Even though a dialog was deleted, the zIndex of the dialog 3
+							// should be above dialog 2.    This test is to make sure we don't
+							// merely use _dialogStack.length to compute zIndex
+							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
+								dialog3Z = dojo.style(dlg3.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							doh.t(underlayZ > dialog2Z, "underlay (zIndex=" + underlayZ +
+								") above dialog2 (zIndex=" + dialog2Z + ")");
+							doh.t(dialog3Z > underlayZ, "dialog3 (zIndex=" + dialog3Z +
+								") above underlay (zIndex=" + underlayZ + ")");
+
+							doh.is("dlg3_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "open fourth dialog",
+					timeout: 30000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg3 = dijit.byId("dlg3"),
+							dlg4;
+
+						// Create and show fourth dialog
+						dlg4 = new dijit.Dialog({
+							id: "dlg4",
+							title: "dialog 4",
+							content:
+								"<input id='dlg4_inputA'><br>" +
+								"<input id='dlg4_inputB'>"
+						});
+						dlg4.show().then(d.getTestCallback(function(){
+							doh.t(isVisible(dlg4), "dialog 4 is visible");
+
+							var dialog3Z = dojo.style(dlg3.domNode, "zIndex"),
+								dialog4Z = dojo.style(dlg4.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							doh.t(underlayZ > dialog3Z, "underlay (zIndex=" + underlayZ +
+								") above dialog3 (zIndex=" + dialog3Z + ")");
+							doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
+								") above underlay (zIndex=" + underlayZ + ")");
+
+							doh.is("dlg4_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "hide third dialog",
+					timeout: 40000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg3 = dijit.byId("dlg3"),
+							dlg4 = dijit.byId("dlg4");
+
+						dlg3.hide().then(d.getTestCallback(function(){
+							doh.t(isVisible(dlg4), "dialog 4 is still visible");
+							doh.t(isVisible(dojo.global.dijit._underlay), "underlay is still visible");
+
+							doh.is("dlg4_inputA", dojo.global.dijit._curFocus.id, "dialog 4 still has focus");
+
+							var dialog4Z = dojo.style(dlg4.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+
+							doh.t(dialog4Z > underlayZ, "dialog4 (zIndex=" + dialog4Z +
+								") above underlay (zIndex=" + underlayZ + ")");
+
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "close fourth dialog",
+					timeout: 30000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg2 = dijit.byId("dlg2"),
+							dlg3 = dijit.byId("dlg3"),
+							dlg4 = dijit.byId("dlg4");
+
+						// Closing fourth dialog should move focus to second dialog,
+						// since we already destroyed the third dialog
+						dlg4.hide().then(d.getTestCallback(function(){
+							doh.t(isHidden(dlg4), "dialog 4 is hidden");
+							doh.t(isHidden(dlg3), "dialog 3 is hidden");
+							doh.t(isVisible(dlg2), "dialog 2 is visible");
+
+							var dialog2Z = dojo.style(dlg2.domNode, "zIndex"),
+								underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+							doh.t(dialog2Z > underlayZ, "dialog2 (zIndex=" + dialog2Z +
+								") above underlay (zIndex=" + underlayZ + ")");
+
+							doh.is("dlg2_inputA", dojo.global.dijit._curFocus.id, "focus is on the first field");
+						}));
+
+						return d;
+					}
+				},
+				{
+					name: "close second dialog",
+					timeout: 30000,
+					runTest: function(){
+						var d = new doh.Deferred(),
+							dlg2 = dijit.byId("dlg2");
+
+						// Since we already destroyed first dialog, closing second dialog should hide underlay and
+						// revert focus to the main page
+						dlg2.hide().then(d.getTestCallback(function(){
+							doh.t(isHidden(dlg2), "dialog 4 is hidden");
+							doh.t(isHidden(dojo.global.dijit._underlay), "underlay hidden");
+
+							doh.is("button", dojo.global.dijit._curFocus.id, "focus is on the main page");
+						}));
+
+						return d;
+					}
+				}
+			]);
+
+			var dlgA, dlgB;
+			doh.register("concurrent hide show", {
+				name: "concurrent hide show",
+				timeout: 20000,
+				setUp: function(){
+					// Create and show first dialog
+					dlgA = new dijit.Dialog({
+						id: "dlgA",
+						title: "Dialog A",
+						content:
+							"<button type='button'>OK</button>"
+					});
+					dlgB = new dijit.Dialog({
+						id: "dlgB",
+						title: "dialog B",
+						content:
+							"<button type='button'>OK</button>"
+					});
+					dlgA.show();
+					
+				},
+				runTest: function(){
+					var d = new doh.Deferred(),
+						cnt=0;
+
+					handle = setInterval(d.getTestErrback(function(){
+						var hidden = cnt%2 ? dlgA : dlgB,
+							shown = cnt%2 ? dlgB : dlgA;
+						
+						if(cnt > 10){
+							clearInterval(handle);
+							handle = null;
+							d.callback(true);
+							return;
+						}
+						
+						doh.t(isVisible(shown), shown.title + " visible");
+						doh.t(isHidden(hidden), hidden.title + " hidden");
+						doh.t(isVisible(dojo.global.dijit._underlay), "underlay visible");
+
+						var shownZ = dojo.style(shown.domNode, "zIndex"),
+							underlayZ = dojo.style(dojo.global.dijit._underlay.domNode, "zIndex");
+						doh.t(shownZ > underlayZ, "visible dialog (zIndex=" + shownZ +
+							") above underlay (zIndex=" + underlayZ + ")");
+
+						hidden.show();
+						shown.hide();
+
+						cnt++;
+					}), 1000);
+					
+					return d;
+				},
+				tearDown: function(){
+					dlgA.hide();
+					dlgB.hide();
+					if(handle){
+						clearInterval(handle);
+					}
+				}
+			});
+
+			var slow, fast;
+			doh.register("fast double show", [
+				function create(){
+					console.log("creating slow, fast");
+					var d = new doh.Deferred();
+					slow = new dijit.Dialog({
+						id: "slow",
+						title: "Dialog C",
+						content:
+							"Hello world " +
+							"<button type='button' id='slowOK' onfocus='dojo.global.slowFocused=true;'>OK</button>" +
+							"<button type='button' id='slowCancel'>Cancel</button>",
+						duration: 500
+					});
+					fast = new dijit.Dialog({
+						id: "fast",
+						title: "dialog D",
+						content:
+							"<button type='button'>OK</button>",
+						duration: 100
+					});
+					
+				},
+				{
+					name: "show Dialog C then show Dialog D before Dialog C fade-in completes",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						slow.show();
+						
+						setTimeout(d.getTestErrback(function(){
+							fast.show();
+						}), 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)
+						return d;
+					}
+				},
+
+				{
+					name: "close dialogD",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						fast.hide();
+						
+						setTimeout(d.getTestCallback(function(){
+							doh.is("slowOK", dojo.global.dijit._curFocus.id, "focused to dialog C");
+							doh.t(dojo.global.slowFocused, "onfocus handler working");
+						}), fast.duration * 2)
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">Dijit Dialog Automated (non-robot) tests</h1>
+	<button id="button">focus point</button>
+</body>
+</html>
+
+
diff --git a/dijit/tests/NodeList-instantiate.html b/dijit/tests/NodeList-instantiate.html
new file mode 100644
index 0000000..ae72995
--- /dev/null
+++ b/dijit/tests/NodeList-instantiate.html
@@ -0,0 +1,157 @@
+<html>
+	<head>
+		<title>dojo.NodeList.instantiate() tests</title>
+
+		<style type="text/css">
+			@import "../themes/claro/document.css";
+			@import "css/dijitTests.css";
+			#container { height:200px; }
+		</style>
+
+		<!-- required: a default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../dojo/dojo.js"
+			djConfig="isDebug: true"></script>
+
+		<!-- not needed, for testing alternate themes -->
+		<script type="text/javascript" src="_testCommon.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("doh.runner");
+			dojo.require("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dijit._Widget");
+			dojo.require("dijit.form.Button");
+			dojo.require("dijit.layout.TabContainer");
+			dojo.require("dijit.layout.ContentPane");
+
+	    	dojo.addOnLoad(function() {	
+
+				// declare a simple widget to use as a base test:
+				dojo.declare("test._Widget",dijit._Widget,{
+					message:"",
+					postCreate:function(){
+						this.inherited(arguments);
+						this.connect(this.domNode,"onclick","workit");
+						dojo.style(this.domNode,{
+							cursor:"pointer",
+							color:"#333"
+						});
+						this.domNode.innerHTML += this.message +" ("+this.id +")";
+						console.log('created',this.id);
+					},
+					workit:function(){
+						dojo.place(this.domNode,this.domNode.parentNode,"end");
+					}
+				});
+		
+				doh.register("Instantiate", [
+					function testWidget(){
+						dojo.query("#list1 li").instantiate(test._Widget,{}).connect("onclick",console.log);
+	
+						var li = dijit.byId("test__Widget_0");
+						doh.t(li, "test__Widget_0 exists");
+						doh.is("pointer", dojo.style("test__Widget_0", "cursor"));
+						doh.is("inner (test__Widget_0)", li.domNode.innerHTML);
+					},
+					
+					function testWidget2(){
+						dojo.query("#list2 li").instantiate(test._Widget,{ message:"woot" });
+	
+						li = dijit.byId("test__Widget_12");
+						doh.t(li, "test__Widget_12 exists");
+						doh.is("pointer", dojo.style("test__Widget_12", "cursor"));
+						doh.is("innerwoot (test__Widget_12)", li.domNode.innerHTML);
+					},
+	
+					function TabContainer(){
+						// make a tab container from some div, and all it's children div's
+						dojo.query("#container")
+							.forEach(function(n){
+								dojo.query("div",n)
+									// create contentpanes from the children and style them
+									.instantiate(dijit.layout.ContentPane,{})
+									.forEach(function(wn,idx){
+										dojo.mixin(dijit.byNode(wn),{ title:"tab" + (idx + 1) })
+									})
+								;
+							})
+							.instantiate(dijit.layout.TabContainer,{})
+						;
+						// should we add auto-startup calling?
+						dijit.byId("container").startup();
+	
+						var tc = dijit.byId("container");
+						doh.t(tc, "Tab container exists");
+						
+						var tabs = tc.tablist.getChildren();
+						doh.is(3, tabs.length);
+						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); })
+					},
+	
+					function Buttons(){
+						// bunches of buttons, use you imagination on how to relate them to something
+						dojo.query("#buttonTest").forEach(function(n){
+							dojo.query("button",n).instantiate(dijit.form.Button,{
+								onClick:function(){
+									this.containerNode.innerHTML = this.label + " was clicked";
+								}
+							});
+						});
+	
+						var b1 = dijit.byId("b1");
+						doh.t(b1, "button 1 exists");
+						doh.is("button 1", b1.label);
+						
+						var b2 = dijit.byId("b2");
+						doh.t(b2, "button 2 exists");
+						doh.is("button 2", b2.label);
+						
+						var b3 = dijit.byId("b3");
+						doh.t(b3, "button 3 exists");
+						doh.is("button 3", b3.label);
+						
+						var b4 = dijit.byId("b4");
+						doh.t(b4, "button 4 exists");
+						doh.is("button 4", b4.label);
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro">
+
+		<h1>dojo.NodeList.instantiate() tests</h1>
+
+		<h2>Some simple widgets:</h2>
+		<ul id="list1"
+			><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li
+		></ul>
+		<ul id="list2"
+			><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li
+		></ul>
+
+		<h2>A TabContainer:</h2>
+		<div id="container"
+			><div>pane1</div
+			><div>pane2</div
+			><div>pane3</div
+		></div>
+
+		<h2>Some Buttons</h2>
+		<div id="buttonTest"
+			><button id="b1">button 1</button
+			><button id="b2">button 2</button
+			><button id="b3">button 3</button
+			><button id="b4">button 4</button
+		></div>
+
+	</body>
+</html>
diff --git a/dijit/tests/ProgressBar.html b/dijit/tests/ProgressBar.html
new file mode 100644
index 0000000..aa10a5b
--- /dev/null
+++ b/dijit/tests/ProgressBar.html
@@ -0,0 +1,326 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>Dojo Toolkit - ProgressBar test</title>
+
+	<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"/>
+
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "css/dijitTests.css";
+		body {
+			margin: 1em;
+		}
+		.smallred .dijitProgressBarTile {
+			background:red;
+		}
+		.smallred .dijitProgressBarLabel {
+			display:none;
+		}
+		#html5ish, #html5ish2 { width:500px; }
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="isDebug: true"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.ProgressBar");
+		dojo.require("dojo.parser");	// scan page for widgets
+		dojo.require("dojo.string");
+		dojo.require("doh.runner");
+
+		dojo.addOnLoad(function go(){
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("other setup", function(){
+				// Stuff from the original test file.   Not sure if this is needed now that
+				// the test is automated.
+
+				// note that programmatic instantiation doesn't pull any parameters from the srcNodeRef, not even id
+				var theBar = new dijit.ProgressBar({id: "testBar", width: 400, maximum: 256, duration: 2000,
+					report:function(percent){
+						return dojo.string.substitute("${0} out of ${1} max chars", [this.get('value'), this.maximum]);
+					}
+				}, dojo.byId("testBar"));
+	
+				dojo.byId("test").value="";
+				dojo.byId("progressValue").value = dijit.byId("setTestBar").value;
+				dojo.byId("maximum").value = dijit.byId("setTestBar").maximum;
+				dojo.connect(dojo.byId("test"), "onkeyup", null, keyUpHandler);
+				dojo.connect(dojo.byId("set"), "onclick", null, setParameters);
+				dojo.connect(dojo.byId("startTimer"), "onclick", null,
+					function(){ remoteProgress(dijit.byId("timerBar")); } );
+					
+				// test 7
+				new dijit.ProgressBar({
+					style:"width:400px",
+					indeterminate:true
+				}, "pi");
+			});
+
+			doh.register("ProgressBar",[
+				{
+					name: "set valid value",
+					runTest: function(){
+						var progressBar = dijit.byId("setTestBar");
+						progressBar.set({maximum: 100, value: 58});
+						
+						doh.is("58", progressBar.progress);
+						doh.is("58%", dojo.byId("setTestBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+
+						var width = visualProgress.style.width;
+						width = width.substring(0, width.length-1);
+						doh.t(57 < width <= 58); //IE thinks the width is 57.99
+					}
+				},
+				{
+					name: "set value too high",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var progressBar = dijit.byId("setTestBar");
+						progressBar.set({maximum: 100, value: 101});
+
+						doh.is("100", progressBar.progress);
+						doh.is("100%", dojo.byId("setTestBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", visualProgress.style.width);
+					}
+				},
+				{
+					name: "set zero value",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var progressBar = dijit.byId("setTestBar");
+						progressBar.set({maximum: 100, value: 0});
+
+						doh.is("0", progressBar.progress);
+						doh.is("0%", dojo.byId("setTestBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("0%", visualProgress.style.width);
+					}
+				},
+				{
+					name: "set max value",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var progressBar = dijit.byId("setTestBar");
+						progressBar.set({maximum: 100, value: 100});
+
+						doh.is("100", progressBar.progress);
+						doh.is("100%", dojo.byId("setTestBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", visualProgress.style.width);
+					}
+				},
+				{
+					name: "report callback",
+					runTest: function(){
+						var progressBar = dijit.byId("testBar");
+						progressBar.set({value: 79});
+						doh.is("79", progressBar.progress);
+						doh.is("79 out of 256 max chars", dojo.byId("testBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						width = visualProgress.style.width;
+						doh.is("30.8", width.substring(0,4));
+					}
+				},
+				{
+					name: "default maximum",
+					runTest: function(){
+						var progressBar = dijit.byId("implied1");
+						doh.is("50", progressBar.progress);
+						doh.is("50%", dojo.byId("implied1_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("50%", visualProgress.style.width);
+							
+						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];
+						doh.is("50%", visualProgress.style.width);
+					}
+				},
+				{
+					name: "set indeterminate, no label",
+					runTest: function(){
+						var progressBar = dijit.byId("indeterminateBar");
+						progressBar.set({indeterminate: true, label: ''});
+
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", visualProgress.style.width);
+						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
+					}
+				},
+				{
+					name: "set determinate, no label",
+					runTest: function(){
+						var progressBar = dijit.byId("indeterminateBar");
+						progressBar.set({indeterminate: false, label: ''});	
+						doh.is("50%", dojo.byId("indeterminateBar_label").innerHTML);
+
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("50%", visualProgress.style.width);
+						doh.f(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "doesn't have class dijitProgressBarIndeterminate");
+					}
+				},
+				{
+					name: "set indeterminate, custom label",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						var progressBar = dijit.byId("indeterminateBar");
+						progressBar.set({indeterminate: true, label: 'Loading...'});
+
+						doh.is("Loading...", dojo.byId("indeterminateBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", visualProgress.style.width);						
+						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
+					}
+				},
+				{
+					name: "set determinate, custom label",
+					runTest: function(){
+						var progressBar = dijit.byId("indeterminateBar");
+						progressBar.set({indeterminate: false, label: 'Loading...'});
+						
+						doh.is("Loading...", dojo.byId("indeterminateBar_label").innerHTML);
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("50%", visualProgress.style.width);
+						doh.f(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "doesn't have class dijitProgressBarIndeterminate");
+					}
+				},
+				{
+					name: "programmatic indeterminate",
+					runTest: function(){
+						var progressBar = dijit.byId("pi");
+						var visualProgress = dojo.query("div.dijitProgressBarFull", progressBar.domNode)[0];
+						doh.is("100%", visualProgress.style.width);
+							
+						doh.t(dojo.hasClass(progressBar.domNode, "dijitProgressBarIndeterminate"), "has class dijitProgressBarIndeterminate");
+						
+						var progressBar = dijit.byId("timerBar");
+						doh.t(80 < progressBar.progress <= 100, "Timer progress was " + progressBar.progress);
+					}
+				}
+			]);
+			
+			doh.run();
+		});
+
+		// An example of polling on a separate (heartbeat) server thread.  This is useful when the progress
+		// is entirely server bound and there is no existing interaction with the server to determine status.
+
+		// We don't have a server to run against, but a simple heartbeat implementation might look something
+		// like this:
+
+		// function getProgressReport(){
+		//	var dataSource = "http://dojotoolkit.org";
+		//	return dojo.xhrGet({url: dataSource, handleAs: "json", content: {key: "progress"}});
+		// }
+
+		// Instead, we'll just tick off intervals of 10
+
+		var fakeProgress = 0;
+		function getProgressReport(){
+			var deferred = new dojo.Deferred();
+			fakeProgress = Math.min(fakeProgress + 10, 100);
+			deferred.callback(fakeProgress+"%");
+			return deferred;
+		}
+
+		function remoteProgress(bar){
+			var _timer = setInterval(function(){
+				var report = getProgressReport();
+				report.addCallback(function(response){
+					bar.set({value: response});
+					if(response == "100%"){
+						clearInterval(_timer);
+						_timer = null;
+						return;
+					}
+				});
+			}, 3000); // on 3 second intervals
+		}
+
+		function setParameters(){
+			dijit.byId("setTestBar").set({maximum: dojo.byId("maximum").value, value: dojo.byId("progressValue").value});
+		}
+
+		function keyUpHandler(){
+			dijit.byId("testBar").set({value:dojo.byId("test").value.length});
+			dijit.byId("testBarInt").set({value:dojo.byId("test").value.length});
+			dijit.byId("smallTestBar").set({value:dojo.byId("test").value.length});
+		}
+	</script>
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Dijit ProgressBar Tests</h1>
+
+	<h3>Test 1</h3>
+	Progress Value <input type="text" name="progressValue" id="progressValue" />
+	<br>
+	Max Progress Value <input type="text" name="maximum" id="maximum" />
+	<br>
+	<input type="button" name="set" id="set" value="set!" />
+	<br>
+	<div id="setTestBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px",
+		maximum:200, value:"20" '></div>
+
+	<h3>Test 2</h3>
+	Write here: <input type="text" value="" name="test" maxLength="256" id="test" style="width:300"/>
+	<br />
+	<br />
+	<div id="testBar" style='width:300px'></div>
+	<br />
+	Small, without text and background image:
+	<br />
+	<div id="smallTestBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px; height:10px", "class":"smallred", maximum:256'></div>
+	<br />
+	Show decimal place:
+	<div id="testBarInt" data-dojo-type="dijit.ProgressBar" data-dojo-props='places:1, style:"width:400px",
+		maximum:256'></div>
+
+	<h3>Test 3</h3>
+	No explicit maximum (both 50%)
+	<div id="implied1" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px",
+		value:"50" '></div>
+	<br />
+	<div id="implied2" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px",
+		value:"50%" '></div>
+
+	<h3>Test 4</h3>
+	<input type="button" name="startTimer" id="startTimer" value="Start Timer" />
+	<div id="timerBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", maximum:100, value:"0" '></div>
+
+	<h3>Test 5 - indeterminate progess</h3>
+	<input id="indeterminateButton1" type="button" value="Make Indeterminate (default blank label)"
+		onclick="dijit.byId('indeterminateBar').set({indeterminate: true, label: ''});" />
+	<input id="labelButton1" type="button" value="Make Determinate (default percentage label)"
+		onclick="dijit.byId('indeterminateBar').set({indeterminate: false, label: ''});" />
+	<input id="indeterminateButton2" type="button" value="Make Indeterminate With Label"
+		onclick="dijit.byId('indeterminateBar').set({indeterminate: true, label: 'Loading...'});" />
+	<input  id="labelButton2" type="button" value="Make Determinate With Label"
+		onclick="dijit.byId('indeterminateBar').set({indeterminate: false, label: 'Loading...'});" />
+	
+	<div id="indeterminateBar" data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", value:"50" '></div>
+
+	<h3>Test 6 - programatic indeterminate</h3>
+	<div id="pi"></div>
+
+</body>
+</html>
diff --git a/dijit/tests/Tooltip-placement.html b/dijit/tests/Tooltip-placement.html
new file mode 100644
index 0000000..d49e872
--- /dev/null
+++ b/dijit/tests/Tooltip-placement.html
@@ -0,0 +1,715 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Tooltip Placement Test</title>
+
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "css/dijitTests.css";
+		
+		div {font-size:9px}
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="isDebug: true"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.ValidationTextBox");
+		
+		dojo.addOnLoad(function(){
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("other setup", function(){
+				dijit._MasterTooltip.prototype.duration = 0.05; // speed up tooltip fading
+				var view = dojo.window.getBox();
+				var width = view.w;
+				var height = view.h;
+				
+				if(width < 600){
+					//Make the larger tooltips smaller so they fit on the page and pass all tests
+					dijit.byId("test2").promptMessage="really really really really really really really really really really really really really really really really really really really really";
+					dijit.byId("test5").promptMessage="really really really really really really really really really really really really really really really really really really really really";
+					dijit.byId("test12").promptMessage="really really really really really really really really really really really really really really really really really really really really";
+					dijit.byId("test17").promptMessage="really really really really really really really really really really really really really really really really really really really really";
+					dijit.byId("test19").promptMessage="really really really really really really really really really really really really really really really really really really really really";
+				}else if(width > 1200){
+					//Make a shorter tooltip longer in order to span the whole width
+					dijit.byId("test1").promptMessage="really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a"
+					dijit.byId("test4").promptMessage="really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a"
+					dijit.byId("test10").promptMessage="really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a"
+					dijit.byId("test20").promptMessage="really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a"
+				}
+				
+				if(height < 600){
+					//Make the taller tooltips shorter
+					for(var i=1;i<22;i++) {
+						if(i==7){
+							//skip
+						}else{
+							dijit.byId("test"+i+"_tall_skinny").promptMessage="<br><br><br><br>a";
+						}
+					}
+				}
+				
+				dijit.byId("test1").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test1_tall_skinny").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test2").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test2_tall_skinny").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test3").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test3_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test4").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test4_tall_skinny").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test5").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test5_tall_skinny").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test6").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test6_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test7").set("style", "width:"+width*(1.1)+"px");
+				dijit.byId("test8").set("style", "width:"+width*(0.2)+"px");
+				dijit.byId("test8_tall_skinny").set("style", "width:"+width*(0.2)+"px");
+				dijit.byId("test9").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test9_tall_skinny").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test10").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test10_tall_skinny").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test11").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test11_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test12").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test12_tall_skinny").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test13").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test13_tall_skinny").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test14").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test14_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test15").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test15_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test16").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test16_tall_skinny").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test17").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test17_tall_skinny").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test18").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test18_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test19").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test19_tall_skinny").set("style", "width:"+width*(0.3)+"px");
+				dijit.byId("test20").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test20_tall_skinny").set("style", "width:"+width*(0.6)+"px");
+				dijit.byId("test21").set("style", "width:"+width*(0.9)+"px");
+				dijit.byId("test21_tall_skinny").set("style", "width:"+width*(0.9)+"px");
+			});
+
+			//Verify the following is true:
+			//	1. The tooltip is displayed to the right or the left of the textbox
+			//	2. The tooltip arrow is next to the textbox
+			//	3. The user can view the entire tooltip on the screen OR the tooltip is displayed on the side with the largest width available
+			//	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]);
+				
+				var xDiff = textboxPos.x - tooltipContainerPos.x - tooltipContainerPos.w;
+				var toTheLeft = xDiff >= -0.5 && xDiff < 2;
+
+				xDiff = tooltipContainerPos.x - textboxPos.x - textboxPos.w;
+				var toTheRight = xDiff >= -0.5 && xDiff < 2;
+
+				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 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(toTheLeft){
+						doh.t(tooltipContainerPos.w + 3/*space in between arrow and textbox*/ >= textboxPos.x, "The entire width was not utilized to the left");					
+					}else{
+						doh.t(tooltipContainerPos.w + 3/*space in between arrow and textbox*/ >= view.w - tooltipContainerPos.x, "The entire width was not utilized to the right");
+					}
+				}
+			
+				//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);
+				if(!canViewEntireTooltip && !isIE6 && !dojo.isOpera){
+					if(toTheLeft){
+						//verify there is more space on the left than the right
+						doh.t(textboxPos.x >= (view.w - textboxPos.x - textboxPos.w), "There is not more space on the left than the right");
+					}else{
+						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");
+				}
+			}
+			
+			//Verify the tooltip arrow is next to the textbox
+			function verifyTooltipArrowPosition(textbox){
+				var textboxPos = dojo.position(textbox.domNode);
+				var tooltipConnectorPos = dojo.position(dojo.query(".dijitTooltipConnector")[0]);
+				
+				var 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
+				doh.t(yAxisValid, "Y axis is invalid. yDiff was: "+yDiff);
+			}
+			
+			//Verify the following is true:
+			//	1. The tooltip arrow is next to the textbox
+			//	2. The text fits inside the tooltip
+			function testNoWrapOrLargeWords(textbox){
+				verifyTooltipArrowPosition(textbox);
+				
+				//Verify the text fits inside the tooltip
+				var tooltipContainer = dojo.query(".dijitTooltipContainer")[0];
+				tooltipContainer.style.overflow = "auto";
+				var scrollWidth = tooltipContainer.scrollWidth;
+				tooltipContainer.style.overflow = "visible"; //change it back
+				
+				var tooltipWidth = dojo.position(tooltipContainer).w;
+				doh.t(tooltipWidth >= scrollWidth);
+			}
+		
+			function testAboveBelow(textbox, verifyConnectorPosition){
+				var textboxPos = dojo.position(textbox.domNode);
+				var tooltipConnectorPos = dojo.position(dojo.query(".dijitTooltipConnector")[0]);
+				var tooltipContainerPos = dojo.position(dojo.query(".dijitTooltip")[0]);
+
+				if(verifyConnectorPosition){
+					var xAxisValid = textboxPos.x <= tooltipConnectorPos.x && tooltipConnectorPos.x <= (textboxPos.x + textboxPos.w);
+					doh.t(xAxisValid, "X axis is invalid");
+				}
+			
+				//verify the tooltip is above or below the textbox
+				var yDiff = textboxPos.y - tooltipContainerPos.y - tooltipContainerPos.h;
+				var above = yDiff >= -0.5 && yDiff < 1;
+	
+				yDiff = tooltipContainerPos.y - textboxPos.y - textboxPos.h;
+				var below = yDiff >= -0.5 && yDiff < 1;
+			
+				doh.t(above || below);
+			}
+
+			var widget, handler;
+
+			// init tests for each group
+			var tooltip_left_right_tall_skinny = [{
+				name: "test1_tall_skinny",
+				timeout: 4000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					widget = dijit.byId("test1_tall_skinny");
+
+					dojo.byId("aboveBelowButton").focus();
+					widget.set('value', null);
+
+					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+						testRightOrLeft(widget, false);
+					}));
+					dijit.byId("test7").focusNode.focus(); //hack for IE6.  test1 is not getting focus in IE6 if we don't focus something else first
+					widget.focusNode.focus();
+				
+					return d;
+				},
+				tearDown: function(){
+					dojo.disconnect(handler);
+				}
+			}];
+			var tooltip_left_right = [{
+				name: "test1",
+				timeout: 4000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					widget = dijit.byId("test1");
+
+					dojo.byId("aboveBelowButton").focus();
+					widget.set('value', null);
+
+					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+						testRightOrLeft(widget, true);
+					}));
+					dijit.byId("test7").focusNode.focus(); //hack for IE6.  test1 is not getting focus in IE6 if we don't focus something else first
+					widget.focusNode.focus();
+				
+					return d;
+				},
+				tearDown: function(){
+					dojo.disconnect(handler);
+				}
+			}];
+			var tooltip_left_right_small = [{
+				name: "test1_lrs",
+				timeout: 6000,
+				runTest: function(){
+					var d = new doh.Deferred();
+				
+					var widget = dijit.byId("test1");
+					widget.set('value', null);
+				
+					dijit.byId("test7").focusNode.focus();
+				
+					setTimeout(function(){ widget.focusNode.focus();}, 500);
+
+					setTimeout(d.getTestCallback(function(){
+						testRightOrLeft(widget, false);
+					}), 1000);
+					return d;
+				}
+			}];
+			var tooltip_above_below_small = [{
+				name: "test1_abs",
+				timeout: 3000,
+				runTest: function(){
+					var d = new doh.Deferred();
+		
+					var widget = dijit.byId("test1");
+					dojo.byId("aboveBelowButton").focus();
+					dojo.byId("aboveBelowButton").click();
+					widget.focusNode.focus();
+
+					setTimeout(d.getTestCallback(function(){
+						testAboveBelow(widget, true);
+					}), 1000);
+					return d;
+				}
+			}];
+			var tooltip_above_below = [{
+				name: "test1_ab",
+				timeout: 5000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					widget = dijit.byId("test1");
+
+					widget.set('value', "a");
+
+					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+						testAboveBelow(widget, true);
+					}));
+
+					widget.focusNode.focus();
+
+					return d;
+				},
+				tearDown: function(){
+					dojo.disconnect(handler);
+				}
+			}];
+			var tooltip_above_below_tall_skinny = [{
+				name: "test1_ab_tall_skinny",
+				timeout: 5000,
+				runTest: function(){
+					var d = new doh.Deferred();
+					widget = dijit.byId("test1_tall_skinny");
+
+					widget.set('value', "a");
+
+					handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+						testAboveBelow(widget, true);
+					}));
+
+					widget.focusNode.focus();
+
+					return d;
+				},
+				tearDown: function(){
+					dojo.disconnect(handler);
+				}
+			}];
+
+			// rest of tests
+			for(var i=2; i<=21; i++){
+				if(i==7){ continue; }
+				tooltip_left_right_tall_skinny.push({
+					name: "test"+i+"_tall_skinny",
+					widget: "test"+i+"_tall_skinny",
+					timeout: 3000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						widget = dijit.byId(this.widget);
+
+						widget.set('value', null);
+
+						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+							testRightOrLeft(widget, false);
+						}));
+						dojo.window.scrollIntoView(widget.focusNode);
+						widget.focusNode.focus();
+					
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
+				tooltip_left_right.push({
+					name: "test"+i,
+					widget: "test"+i,
+					timeout: 3000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						widget = dijit.byId(this.widget);
+
+						widget.set('value', null);
+
+						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+							var id = widget.id;
+							if(id=="test3" || id=="test6" || id=="test8" || id=="test9" || id=="test13" || id=="test16" || id=="test21"){
+								//These are the nowrap tests and therefore we should only verify the arrow is pointing to the textbox
+								testNoWrapOrLargeWords(widget);
+							}else{
+								testRightOrLeft(widget, true);
+							}
+						}));
+						dojo.window.scrollIntoView(widget.focusNode);
+						widget.focusNode.focus();
+					
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
+				tooltip_left_right_small.push({
+					name: "test"+i+"_lrs",
+					widget: "test"+i,
+					timeout: 3000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						widget = dijit.byId(this.widget);
+
+						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+							testRightOrLeft(widget, false);
+						}));
+						widget.focusNode.focus();
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
+				tooltip_above_below_small.push({
+					name: "test"+i+"_abs",
+					widget: "test"+i,
+					timeout: 3000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						widget = dijit.byId(this.widget);
+
+						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+							testAboveBelow(widget, true);
+						}));
+						widget.focusNode.focus();
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
+				tooltip_above_below.push({
+					name: "test"+i+"_ab",
+					widget: "test"+i,
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						widget = dijit.byId(this.widget);
+
+						widget.set('value', "a");
+
+						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+							var id = widget.id;
+							if(id=="test3" || id=="test6" || id=="test8" || id=="test9" || id=="test13" || id=="test16" || id=="test21"){
+								//These are the nowrap tests and therefore we should only verify the arrow is pointing to the textbox (in most cases it's off the screen)
+								testAboveBelow(widget, false);
+							}else{
+								testAboveBelow(widget, true);
+							}
+						}));
+
+						widget.focusNode.focus();
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
+				tooltip_above_below_tall_skinny.push({
+					name: "test"+i+"_ab_tall_skinny",
+					widget: "test"+i+"_tall_skinny",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						widget = dijit.byId(this.widget);
+
+						widget.set('value', "a");
+
+						handler = dojo.connect(dijit._MasterTooltip.prototype, "_onShow", d.getTestCallback(function(){
+							testAboveBelow(widget, true);
+						}));
+
+						widget.focusNode.focus();
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handler);
+					}
+				});
+			}
+
+			doh.register("tooltip_left_right_tall_skinny", tooltip_left_right_tall_skinny);
+			doh.register("tooltip_left_right", tooltip_left_right);
+			doh.register("tooltip_left_right_small", tooltip_left_right_small);
+			doh.register("tooltip_above_below_small", tooltip_above_below_small);
+			doh.register("tooltip_above_below", tooltip_above_below);
+			doh.register("tooltip_above_below_tall_skinny", tooltip_above_below_tall_skinny);
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+<table>
+
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test1" name="test1" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>	
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test1_tall_skinny" name="test1_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test2" name="test2" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really reallyreally really really really really really r [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test2_tall_skinny" name="test2_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test3" name="test3" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallylonggermanwordreallyreallyreallyreallyreallyreallyreallylongword big', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test3_tall_skinny" name="test3_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test4" name="test4" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test4_tall_skinny" name="test4_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test5" name="test5" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really really  [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test5_tall_skinny" name="test5_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test6" name="test6" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<div style=\'white-space: nowrap\'>really really really really big</div>', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test6_tall_skinny" name="test6_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test7" name="test7" data-dojo-type="dijit.form.ValidationTextBox"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test8" name="test8" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<div style=\'white-space: nowrap\'>really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a</div> [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test8_tall_skinny" name="test8_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td>
+		<button id="aboveBelowButton" onclick="dijit.Tooltip.defaultPosition=['above', 'below']; dojo.byId('current').innerHTML='Current: ' + dijit.Tooltip.defaultPosition;">above, below</button>
+		<button 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>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<br><br>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test9" name="test9" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongword', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test9_tall_skinny" name="test9_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test10" name="test10" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test10_tall_skinny" name="test10_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test11" name="test11" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'a a a a a a a a a a a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test11_tall_skinny" name="test11_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test12" name="test12" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really real [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test12_tall_skinny" name="test12_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test13" name="test13" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<div style=\'white-space: nowrap\'>really really really really really really really really really really really really really really really really really big</div>', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test13_tall_skinny" name="test13_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test14" name="test14" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reallyreally really really really really really really really really really [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test14_tall_skinny" name="test14_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test15" name="test15" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test15_tall_skinny" name="test15_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<br>
+	</td>
+	</tr>	
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test16" name="test16" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongword big word really big word', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test16_tall_skinny" name="test16_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test17" name="test17" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really reallyreally really really really really really really really really really really really really really really really reall [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test17_tall_skinny" name="test17_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test18" name="test18" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'a a a a a a a a a a a a a a a a a a a a a a<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:right;">
+		<input type="text" id="test18_tall_skinny" name="test18_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test19" name="test19" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really really real [...]
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test19_tall_skinny" name="test19_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test20" name="test20" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'really really really really really really really really really really really really really really really really really really really<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test20_tall_skinny" name="test20_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test21" name="test21" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'reallyreallyreallyreallyreallyreallylongword<br><br><br><br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+	<tr>
+	<td style="text-align:left;">
+		<input type="text" id="test21_tall_skinny" name="test21_tall_skinny" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="regExp:'ab', promptMessage:'<br><br><br><br><br><br><br><br><br><br><br>a', required:true, missingMessage:'!'"/>
+	</td>
+	</tr>
+</table>
+</body>
+</html>
diff --git a/dijit/tests/Tree.html b/dijit/tests/Tree.html
deleted file mode 100644
index 9b0de99..0000000
--- a/dijit/tests/Tree.html
+++ /dev/null
@@ -1,249 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>dijit.Tree Automatic Tests</title>
-
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../../dojo/resources/dnd.css";
-		@import "../../dojo/tests/dnd/dndDefault.css";
-		@import "css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-	<script type="text/javascript" src="helpers.js"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-		dojo.require("dijit.tree.dndSource");
-
-		dojo.addOnLoad(function(){
-			doh.register("Tree tests",
-				[
-					function create(){
-						var d = new doh.Deferred;
-			 			myStore = new dojo.data.ItemFileWriteStore({url:'_data/countries.json'});
-			 			doh.t(myStore, "store created");
-
-						myModel = new dijit.tree.ForestStoreModel({
-							store: myStore,
-							query: {type:'continent'},
-							rootId: "earth",
-							rootLabel: "Earth",
-							childrenAttrs: ["children"]
-						});
-						doh.t(myModel, "model created");
-
-						myTree = new dijit.Tree({
-							id: "myTree",
-							model: myModel,
-							persist: false,		// persist==true is too hard to test
-							dndController: "dijit.tree.dndSource"
-						});
-						doh.t(myTree, "tree created");
-
-						dojo.byId("container").appendChild(myTree.domNode);
-						myTree.startup();
-
-						setTimeout(d.getTestCallback(function(){
-							// Give the tree time to load, and the do checks that it
-							// loaded correctly
-							doh.t(myTree.rootNode, "root node exists");
-							doh.t(myTree.rootNode.isExpanded, "root node is expanded");
-
-							var children = myTree.rootNode.getChildren();
-							doh.is(6, children.length, "six children");
-							doh.is("Africa", children[0].label, "first child");
-							doh.f(children[0].isExpanded, "first child not expanded");
-							doh.is("South America", children[5].label, "last child");
-
-							// Last child has special CSS for drawing the grid lines
-							doh.f(dojo.hasClass(children[3].domNode, "dijitTreeIsLast"), "middle node doesn't have dijitTreeIsLast");
-							doh.t(dojo.hasClass(children[5].domNode, "dijitTreeIsLast"), "last node has dijitTreeIsLast");
-						}), 750);
-						return d;
-					},
-
-					function createWithPath(){
-						var d = new doh.Deferred;
-						myTree2 = new dijit.Tree({
-							id: "myTree2",
-							model: myModel,
-							persist: false,		// persist==true is too hard to test
-							dndController: "dijit.tree.dndSource",
-							path: ["earth", "EU", "IT"]
-						});
-						doh.t(myTree2, "myTree2 created");
-
-						dojo.byId("container2").appendChild(myTree2.domNode);
-						myTree2.startup();
-
-						setTimeout(d.getTestCallback(function(){
-							// Give the tree time to load, and the do checks that it
-							// loaded correctly
-
-							doh.t(myTree2.rootNode, "root node exists");
-							doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
-							doh.t(myTree2.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
-							doh.is(myTree2.rootNode.getChildren()[3].getChildren()[3], myTree2.selectedNode, "selected correct node");
-						}), 750);
-						return d;
-					},
-
-					function copyPath(){
-						var d = new doh.Deferred;
-
-						myTree.set("path", myTree2.get("path")).then(d.getTestCallback(function(){
-							doh.t(myTree.rootNode.isExpanded, "root node is expanded");
-							doh.t(myTree.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
-							doh.is(myTree.rootNode.getChildren()[3].getChildren()[3], myTree.selectedNode, "selected correct node");
-						}));
-
-						return d;
-					},
-
-					{
-						name: "copyPathByIds",
-						timeout: 5000,
-						runTest: function(){
-							var d = new doh.Deferred;
-
-							myTree.set("path", ["earth", "NA", "CA", "Ottawa"]).then(d.getTestErrback(function(){
-								var path = dojo.map(myTree.get("path"), function(item){ return myTree.model.getIdentity(item); });
-								doh.is(["earth", "NA", "CA", "Ottawa"], path, "path got set on myTree");
-
-								myTree2.set("path", path).then(d.getTestCallback(function(){
-									doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
-									doh.t(myTree2.rootNode.getChildren()[4].isExpanded, "north america node is expanded");
-									doh.t(myTree2.rootNode.getChildren()[4].getChildren()[1].isExpanded, "canada node is expanded");
-									doh.is(myTree2.rootNode.getChildren()[4].getChildren()[1].getChildren()[0], myTree2.selectedNode, "selected correct node");
-								}));
-							}));
-
-							return d;
-						}
-					},
-
-					function itemUpdate(){
-						// Test that Tree noticed when data store items change, and updates accordingly
-
-						var item = myTree.rootNode.getChildren()[3].item;
-						myStore.setValue(item, "name", "EU");
-
-						doh.is("EU", innerText(myTree.rootNode.getChildren()[3].labelNode), "label changed");
-					},
-
-					function topLevelItemDelete(){
-						// Delete a top level item.   ForestStoreModel needs to realize that the top level
-						// children have changed and notify Tree
-
-						// Remove "South America"
-						var item = myTree.rootNode.getChildren()[5].item;
-						myStore.deleteItem(item);
-
-						var children = myTree.rootNode.getChildren();
-						doh.is(5, children.length, "five children");
-						doh.is("North America", children[4].label, "last child");
-						doh.t(dojo.hasClass(children[4].domNode, "dijitTreeIsLast"),
-								"North america has become the last node so it gets the CSS class for that");
-					},
-
-					function openANode(){
-						var d = new doh.Deferred;
-
-						var asia = myTree.rootNode.getChildren()[1];
-
-						doh.is(0, asia.getChildren().length, "no children loaded yet");
-
-						myTree._onExpandoClick({node: asia});
-
-						setTimeout(d.getTestCallback(function(){
-							// Give the tree time to load the children, and the do checks that it
-							// loaded correctly
-
-							var children = asia.getChildren();
-							doh.is(4, children.length, "four children");
-							doh.is("China", children[0].label, "first child");
-							doh.is("Mongolia", children[3].label, "last child");
-						}), 750);
-						return d;
-					},
-
-					function selectAnItem(){
-						myTree.set('selectedItem','CN');
-						doh.is('CN',myTree.model.getIdentity(myTree.get('selectedItem')));
-					},
-
-					function nestedItemDelete(){
-						// Delete a nested item
-
-						// Remove "China"
-						var asia = myTree.rootNode.getChildren()[1],
-							china = asia.getChildren()[0];
-						myStore.deleteItem(china.item);
-
-						var children = asia.getChildren();
-						doh.is(3, children.length, "three children");
-					},
-
-					function topLevelItemInsert(){
-						// Create a new top level item as last child.
-						// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
-
-						myStore.newItem({
-							id: 'PA',
-							name:'Pacifica',
-							type:'continent',
-			        		children: []
-						});
-
-						var children = myTree.rootNode.getChildren();
-						doh.is(6, children.length, "six children");
-						doh.is("Pacifica", children[5].label, "last child");
-						doh.f(dojo.hasClass(children[4].domNode, "dijitTreeIsLast"),
-							"North America no longer last child");
-						doh.t(dojo.hasClass(children[5].domNode, "dijitTreeIsLast"),
-							"Pacifica is last child");
-					},
-
-
-					function destroyTree(){
-						// Just running this to make sure we don't get an exception
-						console.log("destroying tree");
-						myTree.destroy();
- 						myTree2.destroy();
-					}
-
-				]
-			);
-
-			doh.run();
-		});
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit.Tree automated tests</h1>
-	<div id="container"> <!--  tree will go here --></div>
-	<div id="container2"> <!--  tree2 will go here --></div>
-</body>
-</html>
-
-
-
-
diff --git a/dijit/tests/Tree_with_JRS.html b/dijit/tests/Tree_with_JRS.html
deleted file mode 100644
index 5e1db3b..0000000
--- a/dijit/tests/Tree_with_JRS.html
+++ /dev/null
@@ -1,119 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>dijit.Tree Automatic Tests</title>
-
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../../dojo/resources/dnd.css";
-		@import "../../dojo/tests/dnd/dndDefault.css";
-		@import "css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-	
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-	
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-	<script type="text/javascript" src="helpers.js"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("doh.runner");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojox.data.JsonRestStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-		dojo.require("dijit.tree.dndSource");
-
-		dojo.addOnLoad(function(){
-			doh.register("Tree tests",
-				[
-					function create(){
-						var d = new doh.Deferred;
-			 			myStore = new dojox.data.JsonRestStore({target:"tree/", labelAttribute:"name"});
-
-			 			doh.t(myStore, "store created");
-
-						myModel = new dijit.tree.ForestStoreModel({
-							store: myStore,
-							deferItemLoadingUntilExpand: true,
-							query: "treeTestRoot",
-							childrenAttrs: ["children"]
-						});
-						doh.t(myModel, "model created");
-
-						myTree = new dijit.Tree({
-							id: "myTree",
-							model: myModel,
-							"label": "Example",
-							persist: false,		// persist==true is too hard to test
-							dndController: "dijit.tree.dndSource" 
-						});
-						doh.t(myTree, "tree created");
-
-						dojo.byId("container").appendChild(myTree.domNode);
-						myTree.startup();
-
-						setTimeout(d.getTestCallback(function(){
-							// Give the tree time to load, and the do checks that it
-							// loaded correctly
-							doh.t(myTree.rootNode, "root node exists");
-							doh.t(myTree.rootNode.isExpanded, "root node is expanded");
-
-							var children = myTree.rootNode.getChildren();
-							doh.is(5, children.length, "six children");
-							doh.is("node1", children[0].label, "first child");
-							doh.f(children[0].isExpanded, "first child not expanded");
-						}), 500);
-						return d;
-					},
-
-					{
-						runTest: function openANode(){
-							var d = new doh.Deferred;
-							
-							var first = myTree.rootNode.getChildren()[0];
-							
-							myTree._onExpandoClick({
-								node: first
-							});
-							setTimeout(function(){
-								var firstFirst = first.getChildren()[0];
-								myTree._onExpandoClick({
-									node: firstFirst
-								});
-								
-								setTimeout(d.getTestCallback(function(){
-									// Give the tree time to load the children, and the do checks that it
-									// loaded correctly
-									
-									var children = firstFirst.getChildren();
-									doh.is(2, children.length, "two children");
-									doh.is("node1.1.1", children[0].label, "first child");
-								}), 500);
-							}, 500);
-							return d;
-						},
-						timeout: 2000
-					}
-				]
-			);
-
-			doh.run();
-		});
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit.Tree automated tests</h1>
-	<div id="container"> <!--  tree will go here --></div>
-	<div id="container2"> <!--  tree2 will go here --></div>
-</body>
-</html>
diff --git a/dijit/tests/Widget-placeAt.html b/dijit/tests/Widget-placeAt.html
deleted file mode 100644
index df4a961..0000000
--- a/dijit/tests/Widget-placeAt.html
+++ /dev/null
@@ -1,152 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-
-	<title>_Widget.placeAt tests</title>
-
-	<!-- test decoration styles -->
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../../dijit/tests/css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-	<!-- required: load the dojo base -->
-	<script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true" ></script>
-	<!-- for theme-switching, only for dijit -->
-	<script type="text/javascript" src="../../dijit/tests/_testCommon.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("doh.runner");
-
-		// load componenets need for this test
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.BorderContainer");
-
-		// run all the tests onload
-		dojo.addOnLoad(function(){
-
-			var pane1, pane2, tc;
-
-			doh.register("dijit.tests.placeAt",
-				[
-					function placeAsDOMNodeChild(){
-						// create a tabcontainer
-						tc = new dijit.layout.TabContainer({
-							style: "height:200px; width:200px"
-						}, "tabContainerThinger").placeAt("container");
-
-						doh.is(dojo.byId("container"), tc.domNode.parentNode, "TabContainer is child of container");
-					},
-
-					function placeAsWidgetChild(){
-						// add the child to the tabcontainer now:
-						pane1 = new dijit.layout.ContentPane({ title:"empty" }).placeAt(tc);
-
-						doh.is(pane1, tc.getChildren()[0], "pane1 is child of TabContainer");
-					},
-
-					function placeAsWidgetChildOrdered(){
-						// add this child (created second) as the first tab:
-						pane2 = new dijit.layout.ContentPane({ title:"first" }).placeAt(tc, 0);
-
-						doh.is(pane2, tc.getChildren()[0], "pane2 is new first child of TabContainer");
-						doh.is(pane1, tc.getChildren()[1], "pane1 is now second child of TabContainer");
-					},
-
-					function startup(){
-						// just starting the TabContainer so we can do some more tests
-						tc.startup();
-						tc.selectChild(pane2);
-					},
-
-					function placeAsFirst(){
-						pane2.set("content","button should appear BEFORE this text");
-
-						// create a button, and add it to pane2 before the above text
-						var button = new dijit.form.Button({
-							label:"alert",
-							onClick: function(){
-								alert('woot');
-							}
-						}).placeAt(pane2.containerNode, "first");
-
-						doh.is(button.domNode, pane2.containerNode.firstChild, "button is first child");
-						doh.is(3, button.domNode.nextSibling.nodeType, "button went before other content");
-					},
-
-					function placeBefore(){
-						// and a button, this time we'll place it before the tabcontainer's dom
-						var otherButton = new dijit.form.Button({
-							label:"destroy tabContainer",
-							onClick:function(){
-								tc.destroyRecursive();
-							}
-						}).placeAt(tc.domNode, "before");
-
-						doh.is(tc.domNode, otherButton.domNode.nextSibling, "otherButton is before tab container");
-					}
-				]
-			);
-			doh.register("dijit.tests.placeAt BorderContainer",
-				[
-					function addPanes(){
-						// Add top and left pane
-						dijit.byId("addStuff").onClick();
-
-						var bc = dijit.byId("bc1");
-						doh.is("<p>wowzers</p>", bc._left.innerHTML.toLowerCase(), "left pane");
-						doh.is("<div>some html text</div>", bc._top.innerHTML.toLowerCase(), "top pane");
-					}
-				]
-			);
-			doh.run();
-		});
-	</script>
-</head>
-<body class="claro">
-	<h1 class="testTitle">_Widget.placeAt tests</h1>
-
-	<div id="container">
-
-	</div>
-
-	<h2>Node2</h2>
-	<p>This is where the tab srcNodeRef is, but it gets moved above us into the id="container" div.  (Should be there already.)</p>
-	<div id="otherContainer">
-		<div id="tabContainerThinger"></div>
-	</div>
-
-	<h2>BorderContainer sample</h2>
-	<div id="bc1" dojoType="dijit.layout.BorderContainer" style="width:600px; height:400px">
-		<div dojoType="dijit.layout.ContentPane" region="center">
-			<button id="addStuff" dojoType="dijit.form.Button">
-				Add Stuff
-				<script type="dojo/method" event="onClick">
-					this.set("disabled", true);
-					var bc = dijit.byId("bc1");
-
-					// add a left pane and add content
-					new dijit.layout.ContentPane({
-						region:"left",
-						style:"width:100px"
-					}).placeAt(bc).set("content","<p>wowzers</p>");
-
-					// add a top pane, and add content
-					new dijit.layout.ContentPane({
-						region:"top",
-						style:"height:100px"
-					}).placeAt(bc).set("content","<div>some HTML text</div>");
-
-				</script>
-			</button>
-		</div>
-	</div>
-
-</body>
-</html>
diff --git a/dijit/tests/_Container.html b/dijit/tests/_Container.html
index a6b1d68..2a3d5e6 100644
--- a/dijit/tests/_Container.html
+++ b/dijit/tests/_Container.html
@@ -1,28 +1,33 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Container</title>
 
-	<script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit._Widget");
 		dojo.require("dijit._Container");
 		dojo.require("dijit._Contained");
 
-		dojo.declare("dijit.TestContainer",
-			[dijit._Widget, dijit._Container], { }
-		);
-
-		dojo.declare("dijit.TestContained",
-			[dijit._Widget, dijit._Contained], {}
-		);
-
 		dojo.require("dojo.parser");
 
 		dojo.addOnLoad(function(){
+			dojo.declare("dijit.TestContainer",
+				[dijit._Widget, dijit._Container], { }
+			);
+	
+			dojo.declare("dijit.TestContained",
+				[dijit._Widget, dijit._Contained], {}
+			);
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
 			doh.register("dijit._Container",
 				[
 					{
@@ -90,6 +95,7 @@
 					}
 				]
 			);
+
 			doh.run();
 		});
 
@@ -97,13 +103,13 @@
 </head>
 <body class="claro">
 
-	<div id="container" dojoType="dijit.TestContainer">
-		<div id="zero" dojoType="dijit.TestContained"></div>
-		<div id="one" dojoType="dijit.TestContained"></div>
-		<div id="two" dojoType="dijit.TestContained"></div>
-		<div id="three" dojoType="dijit._Widget"></div>
+	<div id="container" data-dojo-type="dijit.TestContainer">
+		<div id="zero" data-dojo-type="dijit.TestContained"></div>
+		<div id="one" data-dojo-type="dijit.TestContained"></div>
+		<div id="two" data-dojo-type="dijit.TestContained"></div>
+		<div id="three" data-dojo-type="dijit._Widget"></div>
 	</div>
-	<div id="outside" dojoType="dijit._Widget"></div>
-	<div id="outsideCont" dojoType="dijit.TestContained"></div>
+	<div id="outside" data-dojo-type="dijit._Widget"></div>
+	<div id="outsideCont" data-dojo-type="dijit.TestContained"></div>
 </body>
 </html>
diff --git a/dijit/tests/_Templated-widgetsInTemplate.html b/dijit/tests/_Templated-widgetsInTemplate.html
index 867c0c5..613b758 100644
--- a/dijit/tests/_Templated-widgetsInTemplate.html
+++ b/dijit/tests/_Templated-widgetsInTemplate.html
@@ -1,11 +1,21 @@
+<!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"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			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");
@@ -16,27 +26,222 @@
 			dojo.require("dijit.layout._LayoutWidget");
 
 			dojo.addOnLoad(function(){
-				var testW;
-				doh.register("t",
+				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: "dojoAttachPoint",
+							name: "data-dojo-attach-point",
 							runTest: function(t){
 								var testW = dijit.byId("test1Widget");
-								t.t(testW.normalNode, "normalNode");
-								t.f(isNaN(testW.normalNode.nodeType), "normalNode.nodeType");
-								t.t(testW.buttonWidget instanceof dijit.form.Button, "buttonWidget is Button");
-								t.t(testW.checkboxWidget instanceof dijit.form.CheckBox, "checkboxWidget is CheckBox");
-								t.t(testW.progressBarWidget instanceof dijit.ProgressBar, "progressBarWidget is ProgressBar");
-								testW = dijit.byId("test2Widget");
-								t.t(testW.containerNode, "containerNode");
-								t.f(isNaN(testW.containerNode.nodeType), "containerNode nodeType");
-								t.is(undefined,testW.buttonWidget, "buttonWidget undefined");
-								t.t(testW.checkboxWidget instanceof dijit.form.CheckBox, "checkboxWidget is still CheckBox");
+								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: "dojoAttachEvent",
+							name: "data-dojo-attach-event",
 							runTest: function(t){
 								var testW = dijit.byId("test1Widget");
 								testW.buttonWidget._counter=0;
@@ -45,9 +250,9 @@
 								testW.checkboxWidget.onClick(testW.checkboxWidget);
 								testW.progressBarWidget._counter=0;
 								testW.progressBarWidget.onChange(testW.progressBarWidget);
-								t.is(1,testW.buttonWidget._counter, "buttonWidget._counter");
-								t.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter");
-								t.is(1,testW.progressBarWidget._counter, "progressBarWidget._counter");
+								doh.is(1,testW.buttonWidget._counter, "buttonWidget._counter");
+								doh.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter");
+								doh.is(1,testW.progressBarWidget._counter, "progressBarWidget._counter");
 							}
 						},
 						{
@@ -58,7 +263,6 @@
 							runTest: function(t){
 								var testW = dijit.byId("test3Widget");
 
-
 /*** performance tests
 								var start = new Date();
 								for(var i=0; i<1000; i++)
@@ -70,22 +274,22 @@
 								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");
+								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();
-								t.is(7, desc.length, "number of descendants (including nested ones)");
-								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.nested");
-								t.is(desc[4].id, "3.nested2");
-								t.is(desc[5].id, "3.4");
-								t.is(desc[6].id, "3.5");
+								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");
 							}
 						},
 						{
@@ -96,9 +300,11 @@
 							}
 						},
 						{
-							// Check that programmatic widget with layout widgets in template is correctly created and rendered
+							// 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);
 							}
 						},
@@ -115,13 +321,23 @@
 								// Check that generated HTML in DOM is same
 								var declNeutralHtml = declW.domNode.innerHTML.replace(/_\d+/g, "");
 								var progNeutralHtml = progW.domNode.innerHTML.replace(/_\d+/g, "");
-								t.is(declNeutralHtml, progNeutralHtml, "progNeutralHtml");
+								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);
-								t.is(declBox.h, progBox.h, "progBox.h");
-								t.is(declBox.w, progBox.w, "progBox.w");
+								doh.is(declBox.h, progBox.h, "progBox.h");
+								doh.is(declBox.w, progBox.w, "progBox.w");
 							}
 						},
 						{
@@ -135,6 +351,8 @@
 							// 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);
 							}
 						},
@@ -151,323 +369,131 @@
 							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>
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../themes/tundra/tundra.css";
-	</style>
 	</head>
 	<body class="claro">
 		<h1>testing widgetsInTemplate support</h1>
-		<xmp id="Test1Template" style="display:none;">
+		<textarea id="Test1Template" style="display:none;">
 			<div>
-				<div dojoAttachPoint="normalNode" >normal node</div>
-				<button dojoAttachPoint="buttonWidget" dojoAttachEvent="onClick:onClick" dojoType="dijit.form.Button">button #1</button>
-				<div dojoAttachPoint="checkboxWidget" dojoAttachEvent="onClick:onClick" dojoType="dijit.form.CheckBox"></div> checkbox #1
-				<div dojoAttachPoint="progressBarWidget" dojoAttachEvent="onChange:onClick" style="width:400px"
-					maximum="200" progress="20" dojoType="dijit.ProgressBar"></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>
-		</xmp>
-		<script>
-			dojo.declare('Test1Widget',
-				[dijit._Widget, dijit._Templated],
-			{
-				widgetsInTemplate: true,
-		//		isContainer: true,
-
-				templateString: dojo.byId('Test1Template').textContent || dojo.byId('Test1Template').innerText,
-				onClick: function(e){
-					if(e.target){
-						alert('onClick widgetId='+e.target.id);
-					}else{
-						if(e._counter == undefined){
-							e._counter = 1;
-						}else{
-							e._counter++;
-						}
-					}
-				}
-			});
-		</script>
-	<!-- can use widget immediately in markup - no parsing occurs until document loaded and scripts run -->
-	<div dojoType="Test1Widget" id="test1Widget" ></div>
+		</textarea>
 
-	<!-- TODO: this is a strange test; the containerNode shouldn't have any contents as they will be overwritten -->
-	<xmp id="Test2Template" style="display:none;">
-		<div>
-			<div dojoAttachPoint="containerNode" >
-				<div dojoAttachPoint="checkboxWidget" dojoType="dijit.form.CheckBox"></div>
-				checkbox #2
+		<div data-dojo-type="Test1Widget" data-dojo-props="id: 'test1Widget'"></div>
+	
+	
+		<textarea id="Test3Template" style="display:none;">
+			<div>
+				<div data-dojo-attach-point="checkboxWidget" data-dojo-type="dijit.form.CheckBox"></div> checkbox #3
+				<div data-dojo-attach-point="containerNode"></div>
 			</div>
-		</div>
-	</xmp>
-		<script>
-			dojo.declare('Test2Widget',
-				[dijit._Widget, dijit._Templated],
-			{
-				widgetsInTemplate: true,
-
-				templateString: dojo.byId('Test2Template').textContent || dojo.byId('Test2Template').innerText
-			});
-		</script>
-	<div dojoType="Test2Widget" id="test2Widget" ><button dojoAttachPoint="buttonWidget" dojoType="dijit.form.Button">button #2</button></div>
-
+		</textarea>
 
-	<xmp id="Test3Template" style="display:none;">
-		<div>
-			<div dojoAttachPoint="checkboxWidget" dojoType="dijit.form.CheckBox"></div> checkbox #3
-			<div dojoAttachPoint="containerNode" ></div>
-		</div>
-	</xmp>
-		<script>
-			dojo.declare('Test3Widget',
-				[dijit._Widget, dijit._Templated],
-			{
-				widgetsInTemplate: true,
-
-				templateString: dojo.byId('Test3Template').textContent || dojo.byId('Test3Template').innerText
-			});
-		</script>
-	<div dojoType="Test3Widget" id="test3Widget" >
-		<span>hello world</span>
-		<b style="border: 1px solid blue;">this is my
-			<button dojoType="dijit.form.Button" id="3.1">first button</button>
-		</b>
-		<button dojoType="dijit.form.Button" id="3.2">another button</button>
-		<i>and some more</i>
-		<div style="border: 1px solid red;">
-			<div dojoType="dijit.layout.ContentPane" style="border: 1px solid gray;" id="3.3">
-				<button dojoType="dijit.form.Button" id="3.nested">a nested button</button>
-				<button dojoType="dijit.form.Button" id="3.nested2">another nested button</button>
+		<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>
-			<button dojoType="dijit.form.Button" id="3.4">yet another button</button>
-			<button dojoType="dijit.form.Button" id="3.5">yet yet another button</button>
 		</div>
-	</div>
 
-	<!-- Test templated widget containing layout widgets in template -->
-	<xmp id="Test4Template" style="display:none;">
-		<div>
-			<div dojoType="dijit.layout.TabContainer" dojoAttachPoint="tabCont" style="height: 5em;">
-				<div dojoType="dijit.layout.ContentPane" dojoAttachPoint="tab1" title="Tab 1">
-					pane 1
-				</div>
-				<div dojoType="dijit.layout.ContentPane" dojoAttachPoint="tab2" title="Tab 2">
-					pane 2
+		<!-- Test templated widget containing layout widgets in template -->
+		<textarea id="Test4Template" style="display:none;">
+			<div>
+				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="style: {height: '5em', width: '100em'}" data-dojo-attach-point="tabCont">
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'Tab 1'" data-dojo-attach-point="tab1">
+						pane 1
+					</div>
+					<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title: 'Tab 2'" data-dojo-attach-point="tab2">
+						pane 2
+					</div>
 				</div>
 			</div>
-		</div>
-	</xmp>
-	<script>
-		dojo.declare('Test4Widget',
-			[dijit._Widget, dijit._Templated],
-		{
-			widgetsInTemplate: true,
-
-			templateString: dojo.byId('Test4Template').textContent || dojo.byId('Test4Template').innerText
-		});
+		</textarea>
 
-		var test4WidgetProgrammatic;
-		dojo.addOnLoad(function(){
-			test4WidgetProgrammatic = new Test4Widget({dir: "ltr"}).placeAt("test4Widget", "after");
-			test4WidgetProgrammatic.startup();
-		});
-
-		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;
-			t.t(tabBox && tabBox.w > 0 && tabBox.h > 0, "tabBox && tabBox.w > 0 && tabBox.h > 0");
-			t.t(paneBox && paneBox.w > 0 && paneBox.h > 0, "paneBox && paneBox.w > 0 && paneBox.h");
-			// Check that everything got started
-			t.t(testW._started, "testW._started");
-			t.t(testW.tabCont._started, "tabCont._started");
-			t.t(testW.tab1._started, "tab1._started");
-			t.t(testW.tab2._started, "tab2._started");
-		}
-	</script>
-	<div dojoType="Test4Widget" id="test4Widget" ></div>
-
-	<!-- Test templated widget containing container and nested widgets in template -->
-	<xmp id="Test5Template" style="display:none;">
-		<div>
-			<div dojoType="TestLayoutWidget" dojoAttachPoint="layout">
-				<div dojoType="TestCtndWidget" dojoAttachPoint="layChild1"></div>
-				<div dojoType="TestCtndWidget" dojoAttachPoint="layChild2"></div>
-			</div>
-			<div dojoType="TestCtnrWidget" dojoAttachPoint="container">
-				<div dojoType="TestCtndWidget" dojoAttachPoint="contained1"></div>
-				<div dojoType="TestCtndWidget" dojoAttachPoint="contained2"></div>
-			</div>
-			<div dojoType="TestStubWidget" dojoAttachPoint="stub1"></div>
-			<div dojoType="TestNonCtnrWidget" dojoAttachPoint="nonContainer">
-				<div dojoType="TestStubWidget" dojoAttachPoint="nonContained1"></div>
-				<div dojoType="TestStubWidget" dojoAttachPoint="nonContained2"></div>
-			</div>
-			<div dojoType="TestCtnrWidget" dojoAttachPoint="threeLevel">
-				<div dojoType="TestNonCtnrWidget" dojoAttachPoint="secondLevel">
-					<div dojoType="TestStubWidget" dojoAttachPoint="bottomLevel"></div>
+		<div data-dojo-type="Test4Widget" data-dojo-props="id: 'test4Widget'"></div>
+	
+		<!-- Test templated widget containing container and nested widgets in template -->
+		<textarea id="Test5Template" style="display:none;">
+			<div>
+				<div data-dojo-type="TestLayoutWidget" data-dojo-attach-point="layout">
+					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild1"></div>
+					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="layChild2"></div>
 				</div>
-			</div>
-			<div dojoType="TestNonCtnrWidget" dojoAttachPoint="anotherThree">
-				<div dojoType="TestCtnrWidget" dojoAttachPoint="anotherSecond">
-					<div dojoType="TestCtndWidget" dojoAttachPoint="anotherBottom"></div>
+				<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="container">
+					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained1"></div>
+					<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="contained2"></div>
+				</div>
+				<div data-dojo-type="TestStubWidget" data-dojo-attach-point="stub1"></div>
+				<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="nonContainer">
+					<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained1"></div>
+					<div data-dojo-type="TestStubWidget" data-dojo-attach-point="nonContained2"></div>
+				</div>
+				<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="threeLevel">
+					<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="secondLevel">
+						<div data-dojo-type="TestStubWidget" data-dojo-attach-point="bottomLevel"></div>
+					</div>
+				</div>
+				<div data-dojo-type="TestNonCtnrWidget" data-dojo-attach-point="anotherThree">
+					<div data-dojo-type="TestCtnrWidget" data-dojo-attach-point="anotherSecond">
+						<div data-dojo-type="TestCtndWidget" data-dojo-attach-point="anotherBottom"></div>
+					</div>
 				</div>
 			</div>
-		</div>
-	</xmp>
-	<script>
-		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 dojoAttachPoint=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').textContent || dojo.byId('Test5Template').innerText,
-			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;
-			}
-		});
-
-		var test5WidgetProgrammatic;
-		dojo.addOnLoad(function(){
-			test5WidgetProgrammatic = new Test5Widget().placeAt("test5Widget", "after");
-			test5WidgetProgrammatic.startup();
-		});
+		</textarea>
 
-		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){
-				t.t(w._started, "w._started: " + w);
-				t.is(undefined, w._doubleStarted, "w._doubleStarted: " + w);
-			});
-		}
-
-		function validateTest5WidgetDestroy(t, testW) {
-			var savedWidgets = getTestWidgets(testW);
-			testW.destroy();
-			dojo.forEach(savedWidgets, function(w, idx){
-				t.t(w._destroyed, "w._destroyed: " + w);
-				t.is(undefined, w._doubleDestroyed, "w._doubleDestroyed: " + w);
-			});
-		}
-	</script>
-	<div dojoType="Test5Widget" id="test5Widget" ></div>
+		<div data-dojo-type="Test5Widget" data-dojo-props="id: 'test5Widget'"></div>
 
+		<div data-dojo-type="Missing" data-dojo-props="id: 'missing'"></div>
 	</body>
 </html>
-
diff --git a/dijit/tests/_Templated-widgetsInTemplate1.x.html b/dijit/tests/_Templated-widgetsInTemplate1.x.html
new file mode 100644
index 0000000..59c9571
--- /dev/null
+++ b/dijit/tests/_Templated-widgetsInTemplate1.x.html
@@ -0,0 +1,488 @@
+<html>
+	<head>
+		<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"
+			djConfig="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(){
+				var testW;
+
+				dojo.declare('Test1Widget',
+					[dijit._Widget, dijit._Templated],
+				{
+					widgetsInTemplate: true,
+	
+					templateString: dojo.byId('Test1Template').textContent || dojo.byId('Test1Template').innerText,
+					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('Test2Widget',
+					[dijit._Widget, dijit._Templated],
+				{
+					widgetsInTemplate: true,
+	
+					templateString: dojo.byId('Test2Template').textContent || dojo.byId('Test2Template').innerText
+				});
+
+				dojo.declare('Test4Widget',
+					[dijit._Widget, dijit._Templated],
+				{
+					widgetsInTemplate: true,
+		
+					templateString: dojo.byId('Test4Template').textContent || dojo.byId('Test4Template').innerText
+				});
+		
+				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;
+					t.t(tabBox && tabBox.w > 0 && tabBox.h > 0, "tabBox && tabBox.w > 0 && tabBox.h > 0");
+					t.t(paneBox && paneBox.w > 0 && paneBox.h > 0, "paneBox && paneBox.w > 0 && paneBox.h");
+					// Check that everything got started
+					t.t(testW._started, "testW._started");
+					t.t(testW.tabCont._started, "tabCont._started");
+					t.t(testW.tab1._started, "tab1._started");
+					t.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 dojoAttachPoint=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').textContent || dojo.byId('Test5Template').innerText,
+					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;
+					}
+				});
+		
+				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){
+						t.t(w._started, "w._started: " + w);
+						t.is(undefined, w._doubleStarted, "w._doubleStarted: " + w);
+					});
+				}
+		
+				function validateTest5WidgetDestroy(t, testW) {
+					var savedWidgets = getTestWidgets(testW);
+					testW.destroy();
+					dojo.forEach(savedWidgets, function(w, idx){
+						t.t(w._destroyed, "w._destroyed: " + w);
+						t.is(undefined, w._doubleDestroyed, "w._doubleDestroyed: " + w);
+					});
+				}
+
+				dojo.declare("Missing", [dijit._Widget, dijit._Templated], {
+					templateString: '<div>' +
+										'<div dojoType="dijit.layout.ContentPane">' +
+											'<div dojoType="dijit.form.Button" id="missingButtonId" ' +
+											'dojoAttachPoint="missingButton">Missing...</div>' +
+										'</div>' +
+									'</div>',
+					widgetsInTemplate: true
+				});
+	
+				doh.register("parse", function(){
+					dojo.parser.parse();
+				});
+
+				doh.register("_Templated-widgetsInTemplate1.x",
+					[
+						{
+							name: "dojoAttachPoint",
+							runTest: function(t){
+								var testW = dijit.byId("test1Widget");
+								t.t(testW.normalNode, "normalNode");
+								t.f(isNaN(testW.normalNode.nodeType), "normalNode.nodeType");
+								t.t(testW.buttonWidget instanceof dijit.form.Button, "buttonWidget is Button");
+								t.t(testW.checkboxWidget instanceof dijit.form.CheckBox, "checkboxWidget is CheckBox");
+								t.t(testW.progressBarWidget instanceof dijit.ProgressBar, "progressBarWidget is ProgressBar");
+								testW = dijit.byId("test2Widget");
+								t.t(testW.containerNode, "containerNode");
+								t.f(isNaN(testW.containerNode.nodeType), "containerNode nodeType");
+								t.is(undefined,testW.buttonWidget, "buttonWidget undefined");
+								t.t(testW.checkboxWidget instanceof dijit.form.CheckBox, "checkboxWidget is still CheckBox");
+							}
+						},
+						{
+							name: "dojoAttachEvent",
+							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);
+								t.is(1,testW.buttonWidget._counter, "buttonWidget._counter");
+								t.is(1,testW.checkboxWidget._counter, "checkboxWidget._counter");
+								t.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();
+								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 desc = testW.getDescendants();
+								t.is(7, desc.length, "number of descendants (including nested ones)");
+								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.nested");
+								t.is(desc[4].id, "3.nested2");
+								t.is(desc[5].id, "3.4");
+								t.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 programmatic 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, "");
+								t.is(declNeutralHtml, progNeutralHtml, "progNeutralHtml");
+
+								// Check that dimensions are same
+								var declBox = dojo.contentBox(declW.domNode);
+								var progBox = dojo.contentBox(progW.domNode);
+								t.is(declBox.h, progBox.h, "progBox.h");
+								t.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");
+							}
+						}
+					]
+				);
+				doh.run();
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<h1>testing widgetsInTemplate support</h1>
+		<xmp id="Test1Template" style="display:none;">
+			<div>
+				<div dojoAttachPoint="normalNode" >normal node</div>
+				<button dojoAttachPoint="buttonWidget" dojoAttachEvent="onClick:onClick" dojoType="dijit.form.Button">button #1</button>
+				<div dojoAttachPoint="checkboxWidget" dojoAttachEvent="onClick:onClick" dojoType="dijit.form.CheckBox"></div> checkbox #1
+				<div dojoAttachPoint="progressBarWidget" dojoAttachEvent="onChange:onClick" style="width:400px"
+					maximum="200" progress="20" dojoType="dijit.ProgressBar"></div>
+			</div>
+		</xmp>
+	<div dojoType="Test1Widget" id="test1Widget" ></div>
+
+	<!-- TODO: this is a strange test; the containerNode shouldn't have any contents as they will be overwritten -->
+	<xmp id="Test2Template" style="display:none;">
+		<div>
+			<div dojoAttachPoint="containerNode" >
+				<div dojoAttachPoint="checkboxWidget" dojoType="dijit.form.CheckBox"></div>
+				checkbox #2
+			</div>
+		</div>
+	</xmp>
+	<div dojoType="Test2Widget" id="test2Widget" ><button dojoAttachPoint="buttonWidget" dojoType="dijit.form.Button">button #2</button></div>
+
+
+	<xmp id="Test3Template" style="display:none;">
+		<div>
+			<div dojoAttachPoint="checkboxWidget" dojoType="dijit.form.CheckBox"></div> checkbox #3
+			<div dojoAttachPoint="containerNode" ></div>
+		</div>
+	</xmp>
+		<script>
+			dojo.declare('Test3Widget',
+				[dijit._Widget, dijit._Templated],
+			{
+				widgetsInTemplate: true,
+
+				templateString: dojo.byId('Test3Template').textContent || dojo.byId('Test3Template').innerText
+			});
+		</script>
+	<div dojoType="Test3Widget" id="test3Widget" >
+		<span>hello world</span>
+		<b style="border: 1px solid blue;">this is my
+			<button dojoType="dijit.form.Button" id="3.1">first button</button>
+		</b>
+		<button dojoType="dijit.form.Button" id="3.2">another button</button>
+		<i>and some more</i>
+		<div style="border: 1px solid red;">
+			<div dojoType="dijit.layout.ContentPane" style="border: 1px solid gray;" id="3.3">
+				<button dojoType="dijit.form.Button" id="3.nested">a nested button</button>
+				<button dojoType="dijit.form.Button" id="3.nested2">another nested button</button>
+			</div>
+			<button dojoType="dijit.form.Button" id="3.4">yet another button</button>
+			<button dojoType="dijit.form.Button" id="3.5">yet yet another button</button>
+		</div>
+	</div>
+
+	<!-- Test templated widget containing layout widgets in template -->
+	<xmp id="Test4Template" style="display:none;">
+		<div>
+			<div dojoType="dijit.layout.TabContainer" dojoAttachPoint="tabCont" style="height: 5em;">
+				<div dojoType="dijit.layout.ContentPane" dojoAttachPoint="tab1" title="Tab 1">
+					pane 1
+				</div>
+				<div dojoType="dijit.layout.ContentPane" dojoAttachPoint="tab2" title="Tab 2">
+					pane 2
+				</div>
+			</div>
+		</div>
+	</xmp>
+	<div dojoType="Test4Widget" id="test4Widget" ></div>
+
+	<!-- Test templated widget containing container and nested widgets in template -->
+	<xmp id="Test5Template" style="display:none;">
+		<div>
+			<div dojoType="TestLayoutWidget" dojoAttachPoint="layout">
+				<div dojoType="TestCtndWidget" dojoAttachPoint="layChild1"></div>
+				<div dojoType="TestCtndWidget" dojoAttachPoint="layChild2"></div>
+			</div>
+			<div dojoType="TestCtnrWidget" dojoAttachPoint="container">
+				<div dojoType="TestCtndWidget" dojoAttachPoint="contained1"></div>
+				<div dojoType="TestCtndWidget" dojoAttachPoint="contained2"></div>
+			</div>
+			<div dojoType="TestStubWidget" dojoAttachPoint="stub1"></div>
+			<div dojoType="TestNonCtnrWidget" dojoAttachPoint="nonContainer">
+				<div dojoType="TestStubWidget" dojoAttachPoint="nonContained1"></div>
+				<div dojoType="TestStubWidget" dojoAttachPoint="nonContained2"></div>
+			</div>
+			<div dojoType="TestCtnrWidget" dojoAttachPoint="threeLevel">
+				<div dojoType="TestNonCtnrWidget" dojoAttachPoint="secondLevel">
+					<div dojoType="TestStubWidget" dojoAttachPoint="bottomLevel"></div>
+				</div>
+			</div>
+			<div dojoType="TestNonCtnrWidget" dojoAttachPoint="anotherThree">
+				<div dojoType="TestCtnrWidget" dojoAttachPoint="anotherSecond">
+					<div dojoType="TestCtndWidget" dojoAttachPoint="anotherBottom"></div>
+				</div>
+			</div>
+		</div>
+	</xmp>
+	<div dojoType="Test5Widget" id="test5Widget" ></div>
+
+	<div dojoType="Missing" id="missing"></div>
+	</body>
+</html>
+
diff --git a/dijit/tests/_Templated.html b/dijit/tests/_Templated.html
index 055fd15..4989674 100644
--- a/dijit/tests/_Templated.html
+++ b/dijit/tests/_Templated.html
@@ -1,11 +1,15 @@
+<!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"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			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");
 
@@ -22,7 +26,7 @@
 				dojo.declare("SimpleTemplate", [dijit._Widget, dijit._Templated], {
 					attributeMap: {},
 					id: "test1",
-					templateString: "<button><span>hello < world</span></button>"
+					templateString: "<button type='button'><span>hello < world</span></button>"
 				});
 
 				// Template with variables
@@ -52,7 +56,7 @@
 					templateString: "<tr><td>${text}</td></tr>"
 				});
 
-				// Illegal subsitition variable name
+				// Illegal substitution variable name
 				dojo.declare("IllegalSubstitution", [dijit._Widget, dijit._Templated], {
 					templateString: "<tr><td>${fake}</td></tr>"
 				});
@@ -62,7 +66,7 @@
 					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><input dojoAttachPoint="inputNode" value="input"/></span>' +
 										"<span dojoAttachPoint='containerNode'></span>" +
 									"</div>"
 				});
@@ -73,19 +77,27 @@
 					onfocus: function(){ this.focusCalled=true; },
 					focus2: function(){ this.focus2Called=true; },
 					templateString: "<table style='border: 1px solid blue'><tr>" +
-										"<td><button dojoAttachPoint='left' dojoAttachEvent='onclick: click, onfocus'>left</button></td>" +
-										"<td><button dojoAttachPoint='right' dojoAttachEvent='onclick: click, onfocus: focus2'>right</button></td>" +
+										"<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);
-							t.is('<button widgetid=\"test1\"><span>hello < world</span></button>', wrapper.innerHTML.toLowerCase());
+							
+							// 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){
@@ -175,9 +187,9 @@
 							dojo.declare("ParentThing", [dijit._Widget, dijit._Templated], {
 								widgetsInTemplate:true,
 								templateString: "<div>" +
-													"<span dojoType='SubThing'>a</span>" +
-													"<div dojoType='dijit.layout.LayoutContainer'>" +
-														"<span dojoType='SubThing'>b</span>" +
+													"<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(){
@@ -206,9 +218,6 @@
 				doh.run();
 			});
 		</script>
-	<style type="text/css">
-		@import "../themes/tundra/tundra.css";
-	</style>
 	</head>
 	<body>
 		<h1>_Templated test</h1>
diff --git a/dijit/tests/_Widget-attr.html b/dijit/tests/_Widget-attr.html
index 287db8d..ec9435d 100644
--- a/dijit/tests/_Widget-attr.html
+++ b/dijit/tests/_Widget-attr.html
@@ -4,68 +4,73 @@
 <head>
 	<title>Widget.get()/set() unit test</title>
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		djConfig="isDebug: true"></script>
 	<script type="text/javascript" src="_testCommon.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit");
 
-		dojo.declare("Baz",
-			[ dijit._Widget, dijit._Templated ],
-			{
-				templateString: "<div><div dojoAttachPoint='nameNode'></div><span>${attr1}</span></div>",
-
-				attributeMap: {
-					name: {node: "nameNode", type: "innerHTML" }
-				},
-
-				name: "howdy!",
-
-				attr1: 0,
-				_setAttr1Attr: function(value){
-					this.domNode.lastChild.innerHTML = value;
-					this.attr1 = value;
+		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!",
+	
+					attr1: 0,
+					_setAttr1Attr: function(value){
+						this.domNode.lastChild.innerHTML = value;
+						this.attr1 = value;
+					},
+	
+					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
 				},
-
-				attr2: 0,
-				_getAttr2Attr: function(){
+				set: function(name, value){
+					// default setter
 				}
-			}
-		);
-		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>"
-		});
-
-		dojo.addOnLoad(function(){
-			doh.register("dijit.attr",
+			});
+	
+			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();
@@ -144,6 +149,7 @@
 					}
 				]
 			);
+
 			doh.run();
 		});
 
diff --git a/dijit/tests/_Widget-connect-performance.html b/dijit/tests/_Widget-connect-performance.html
index 17e5297..699e079 100644
--- a/dijit/tests/_Widget-connect-performance.html
+++ b/dijit/tests/_Widget-connect-performance.html
@@ -1,21 +1,26 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Test Dijit Internal Event: "ondijitclick"</title>
 
-	<script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit._Widget");
 		dojo.require("dojo.parser");
 
-		dojo.declare("dijit.MyWidget", dijit._Widget, {
-			_eventHandler: function(){}
-		});
-
 		dojo.addOnLoad(function(){
+			dojo.declare("dijit.MyWidget", dijit._Widget, {
+				_eventHandler: function(){}
+			});
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
 			var connects = [];
 			doh.register("_widgetConnect",
 				[
@@ -65,6 +70,6 @@
 </head>
 <body class="claro">
 	<div id="externalNode"></div>
-	<div id="widget1" dojoType="dijit.MyWidget"></div>
+	<div id="widget1" data-dojo-type="dijit.MyWidget"></div>
 </body>
 </html>
diff --git a/dijit/tests/_Widget-deferredConnect.html b/dijit/tests/_Widget-deferredConnect.html
index 271378b..7722e91 100644
--- a/dijit/tests/_Widget-deferredConnect.html
+++ b/dijit/tests/_Widget-deferredConnect.html
@@ -1,16 +1,16 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>_Widget deferred connection test</title>
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../themes/tundra/tundra.css";
+		@import "../themes/claro/document.css";
+		@import "../themes/claro/claro.css";
 		@import "css/dijitTests.css";
 	</style>
 
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script>
 		dojo.require("dijit.form.Button");
 
@@ -59,8 +59,8 @@
 	<!--
 		"overrode" button specifies an onmousemove handler on initialization.
 	-->
-	<button id="overrode" dojoType="dijit.form.Button"
-		onMouseMove="if(!overrodeMouseMoved){ console.log('\'overrode\' button: mouse moved'); } overrodeMouseMoved = true;">
+	<button id="overrode" data-dojo-type="dijit.form.Button"
+		data-dojo-props='onMouseMove:function(){ if(!overrodeMouseMoved){ console.log("\"overrode\" button: mouse moved"); } overrodeMouseMoved = true; }'>
 		overrode
 	</button>
 
@@ -69,11 +69,11 @@
 		This should trigger an additional dojo.connect() call from Button.focusNode.onmousemove
 		to the Button.onMouseMove empty function.
 	-->
-	<button id="connect" dojoType="dijit.form.Button">
+	<button id="connect" data-dojo-type="dijit.form.Button">
 		connected
 	</button>
 
-	<button id="both" dojoType="dijit.form.Button" onMouseMove="bothHandler">
+	<button id="both" data-dojo-type="dijit.form.Button" data-dojo-props='onMouseMove:bothHandler'>
 		both
 	</button>
 </body>
diff --git a/dijit/tests/_Widget-lifecycle.html b/dijit/tests/_Widget-lifecycle.html
index 794df16..c70e776 100644
--- a/dijit/tests/_Widget-lifecycle.html
+++ b/dijit/tests/_Widget-lifecycle.html
@@ -5,33 +5,33 @@
 
 	<title>_Widget.destroy() unit test</title>
 
-	<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"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit._Widget");
 
-		var obj = {
-			foo: function(){
-				// summary: empty function that we connect to
-			}
-		};
-
-		// Number of times foo was called while TestWidget existed
-		var calls = 0;
-
-		dojo.declare("dijit.TestWidget", dijit._Widget, {
-			postCreate: function(){
-				// Rather odd call to this.connect() For testing the connections are dropped on destroy()
-				this.connect(obj, "foo", function(){
-					calls++;
-				});
-			}
-		});
-
-		var w;
-
 		dojo.addOnLoad(function(){
-			doh.register("dijit._Widget",
+			var obj = {
+				foo: function(){
+					// summary: empty function that we connect to
+				}
+			};
+	
+			// Number of times foo was called while TestWidget existed
+			var calls = 0;
+	
+			dojo.declare("dijit.TestWidget", dijit._Widget, {
+				postCreate: function(){
+					// Rather odd call to this.connect() For testing the connections are dropped on destroy()
+					this.connect(obj, "foo", function(){
+						calls++;
+					});
+				}
+			});
+	
+			var w;
+
+			doh.register("dijit._Widget-lifecycle",
 				[
 					{
 						name: "create",
@@ -82,6 +82,26 @@
 
 				]
 			);
+
+			doh.register("setter calls on creation", function(){
+				// Make sure setters are called even for anonymous classes (#12122),
+				// and even when there's no value explicitly specified in the parameters
+				var fooSetterCalled,
+					Widget1 = dojo.declare([dijit._Widget], {}),
+				    Widget2 = dojo.declare([dijit._Widget], {
+						foo: 345,
+				        _setFooAttr: function(val){
+							fooSetterCalled = val;
+				            this.foo = val;
+				        }
+				    });
+				
+				new Widget1();
+				new Widget2();
+				
+				doh.is(345, fooSetterCalled, "fooSetterCalled");
+			});
+	
 			doh.run();
 		});
 
diff --git a/dijit/tests/_Widget-ondijitclick.html b/dijit/tests/_Widget-ondijitclick.html
index eaf6e9e..e3ad564 100644
--- a/dijit/tests/_Widget-ondijitclick.html
+++ b/dijit/tests/_Widget-ondijitclick.html
@@ -1,30 +1,35 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Test Dijit Internal Event: "ondijitclick"</title>
 
-	<script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit._Widget");
 		dojo.require("dojo.parser");
 
-		dojo.declare("dijit.WidgetWithOndijitclick",
-			dijit._Widget,
-			{
-				clickCount: 0,
-				onClick: function(){
-				},
-				_onClick: function() {
-					console.log(this.id + ": ondijitclick");
-					this.onClick();
-				},
-				postCreate: function() {
-					this.connect(this.domNode, "ondijitclick", "_onClick");
+		dojo.addOnLoad(function(){
+			dojo.declare("dijit.WidgetWithOndijitclick",
+				dijit._Widget,
+				{
+					clickCount: 0,
+					onClick: function(){
+					},
+					_onClick: function() {
+						console.log(this.id + ": ondijitclick");
+						this.onClick();
+					},
+					postCreate: function() {
+						this.connect(this.domNode, "ondijitclick", "_onClick");
+					}
 				}
-			}
-		);
+			);
+
+			dojo.parser.parse();
+		});
 	</script>
 	<style>
 		div {
@@ -46,14 +51,14 @@
 		whether catch clicks on key-down or key-up so this tests to make sure we are doing
 		the right one.)
 	</p>
-	<div id="first" dojoType="dijit.WidgetWithOndijitclick" tabIndex=0
-			onClick="dojo.byId('plainbutton').focus();">
+	<div id="first" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='
+			onClick:function(){ dojo.byId("plainbutton").focus(); }'>
 		click me using space or enter, to focus button below
 	</div>
 	<button id="plainbutton" onclick="console.log('plain button clicked'); window.clicked = true;" type="button" >plain button</button>
 
-	<div id="second" dojoType="dijit.WidgetWithOndijitclick" tabIndex=0
-			onClick="dojo.byId('textarea').focus();">
+	<div id="second" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='
+			onClick:function(){ dojo.byId("textarea").focus(); }'>
 		click me using space or enter, to focus textarea below
 	</div>
 	<textarea id="textarea">hello world</textarea>
@@ -63,14 +68,14 @@
 			onClick="dojo.byId('third').focus();">
 		click me using space or enter, to focus ondijitclick widget below
 	</button>
-	<div id="third" dojoType="dijit.WidgetWithOndijitclick" tabIndex=0 style="margin-top: 0px;"
-			onfocus="console.log('onfocus on third'); window.onDijitClickFocus = true;"
-			onClick="console.log('onclick on third'); window.spuriousOnDijitClick = true;">
+	<div id="third" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='style:"margin-top: 0px;",
+			onFocus:function(){ console.log("onfocus on third"); window.onDijitClickFocus = true; },
+			onClick:function(){ console.log("onclick on third"); window.spuriousOnDijitClick = true; }'>
 		clicking the button above shouldn't cause my ondijitclick handler to fire
 	</div>
 	<br>
-	<div id="fourth" dojoType="dijit.WidgetWithOndijitclick" tabIndex=0 style="margin-top: 0px;"
-			onClick='alert("make sure can close this alert via keyboard");'>
+	<div id="fourth" tabIndex="0" data-dojo-type="dijit.WidgetWithOndijitclick" data-dojo-props='style:"margin-top: 0px;",
+			onClick:function(){ alert("make sure can close this alert via keyboard"); }'>
 		Manual Test: Click me using space or enter to launch a JavaScript alert() from element using ondijitclick
 	</div>
 </body>
diff --git a/dijit/tests/_Widget-placeAt.html b/dijit/tests/_Widget-placeAt.html
new file mode 100644
index 0000000..a03feba
--- /dev/null
+++ b/dijit/tests/_Widget-placeAt.html
@@ -0,0 +1,171 @@
+<!DOCTYPE html>
+<html>
+<head>
+
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
+	<title>_Widget.placeAt tests</title>
+
+	<!-- test decoration styles -->
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "../../dijit/tests/css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: load the dojo base -->
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug:true" ></script>
+	<!-- for theme-switching, only for dijit -->
+	<script type="text/javascript" src="../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+
+		// load components need for this test
+		dojo.require("dojo.parser");
+		dojo.require("dijit.form.Button");
+		dojo.require("dijit.layout.TabContainer");
+		dojo.require("dijit.layout.ContentPane");
+		dojo.require("dijit.layout.BorderContainer");
+
+		// run all the tests onload
+		dojo.addOnLoad(function(){
+
+			var pane1, pane2, tc;
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("dijit.tests.placeAt",
+				[
+					function placeAsDOMNodeChild(){
+						// create a TabContainer
+						tc = new dijit.layout.TabContainer({
+							style: "height:200px; width:200px"
+						}, "tabContainerThinger").placeAt("container");
+
+						doh.is(dojo.byId("container"), tc.domNode.parentNode, "TabContainer is child of container");
+					},
+
+					function placeAsWidgetChild(){
+						// add the child to the TabContainer now:
+						pane1 = new dijit.layout.ContentPane({ title:"empty" }).placeAt(tc);
+
+						doh.is(pane1, tc.getChildren()[0], "pane1 is child of TabContainer");
+					},
+
+					function placeAsWidgetChildOrdered(){
+						// add this child (created second) as the first tab:
+						pane2 = new dijit.layout.ContentPane({ title:"first" }).placeAt(tc, 0);
+
+						doh.is(pane2, tc.getChildren()[0], "pane2 is new first child of TabContainer");
+						doh.is(pane1, tc.getChildren()[1], "pane1 is now second child of TabContainer");
+					},
+
+					function startup(){
+						// just starting the TabContainer so we can do some more tests
+						tc.startup();
+						tc.selectChild(pane2);
+					},
+
+					function placeAsFirst(){
+						pane2.set("content","button should appear BEFORE this text");
+
+						// create a button, and add it to pane2 before the above text
+						var button = new dijit.form.Button({
+							label:"alert",
+							onClick: function(){
+								alert('woot');
+							}
+						}).placeAt(pane2.containerNode, "first");
+
+						doh.is(button.domNode, pane2.containerNode.firstChild, "button is first child");
+						doh.is(3, button.domNode.nextSibling.nodeType, "button went before other content");
+					},
+
+					function placeBefore(){
+						// and a button, this time we'll place it before the TabContainer's dom
+						var otherButton = new dijit.form.Button({
+							label:"destroy TabContainer",
+							onClick:function(){
+								tc.destroyRecursive();
+							}
+						}).placeAt(tc.domNode, "before");
+
+						doh.is(tc.domNode, otherButton.domNode.nextSibling, "otherButton is before tab container");
+					}
+				]
+			);
+			doh.register("dijit.tests.placeAt BorderContainer",
+				[
+					function addPanes(){
+						// Add top and left pane
+						dijit.byId("addStuff").onClick();
+
+						var bc = dijit.byId("bc1"),
+							children = bc.getChildren();
+							
+						doh.is(3, children.length);
+						
+						var bcPos = dojo.position(bc.domNode),
+							center = dijit.byId("center"),
+							centerPos = dojo.position(center.domNode),
+							left = dojo.filter(children, function(child){ return child.region == "left";})[0],
+							leftPos = dojo.position(left.domNode),
+							top =  dojo.filter(children, function(child){ return child.region == "top";})[0];
+
+						doh.t(leftPos.x >= bcPos.x, "left in BorderContainer");
+						doh.t(centerPos.x >= leftPos.x + leftPos.w, "left vs. center horizontal");
+						doh.is("<p>wowzers</p>", left.domNode.innerHTML.toLowerCase(), "left pane");
+						doh.is("<div>some html text</div>", top.domNode.innerHTML.toLowerCase(), "top pane");
+					}
+				]
+			);
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">_Widget.placeAt tests</h1>
+
+	<div id="container">
+
+	</div>
+
+	<h2>Node2</h2>
+	<p>This is where the tab srcNodeRef is, but it gets moved above us into the id="container" div.  (Should be there already.)</p>
+	<div id="otherContainer">
+		<div id="tabContainerThinger"></div>
+	</div>
+
+	<h2>BorderContainer sample</h2>
+	<div id="bc1" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"width:600px; height:400px"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"center", region:"center"'>
+			<button id="addStuff" data-dojo-type="dijit.form.Button">
+				Add Stuff
+				<script type="dojo/method" data-dojo-event="onClick">
+					this.set("disabled", true);
+					var bc = dijit.byId("bc1");
+
+					// add a left pane and add content
+					new dijit.layout.ContentPane({
+						region:"left",
+						style:"width:100px"
+					}).placeAt(bc).set("content","<p>wowzers</p>");
+
+					// add a top pane, and add content
+					new dijit.layout.ContentPane({
+						region:"top",
+						style:"height:100px"
+					}).placeAt(bc).set("content","<div>some HTML text</div>");
+
+				</script>
+			</button>
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/_Widget-subscribe.html b/dijit/tests/_Widget-subscribe.html
index 269d74b..1d1ac5f 100644
--- a/dijit/tests/_Widget-subscribe.html
+++ b/dijit/tests/_Widget-subscribe.html
@@ -1,26 +1,31 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Test Dijit Subscribe</title>
 
-	<script type="text/javascript" src="../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../dojo/dojo.js" data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit._Widget");
 		dojo.require("dojo.parser");
 
-		var numCallsInternal = 0;
-		var numCallsExternal = 0;
-		var externalString = "";
-		var internalSubscribe = null;
+		dojo.addOnLoad(function(){
+			var numCallsInternal = 0;
+			var numCallsExternal = 0;
+			var externalString = "";
+			var internalSubscribe = null;
+	
+			dojo.declare("dijit.MyWidget", dijit._Widget, {
+				_subscribeHandlerInternal: function(){ numCallsInternal++; }
+			});
 
-		dojo.declare("dijit.MyWidget", dijit._Widget, {
-			_subscribeHandlerInternal: function(){ numCallsInternal++; }
-		});
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
 
-		dojo.addOnLoad(function(){
 			doh.register("_widgetSubscribe",
 				[
 					{
@@ -85,12 +90,13 @@
 					}
 				]
 			);
+
 			doh.run();
 		});
 
 	</script>
 </head>
 <body class="claro">
-	<div id="widget1" dojoType="dijit.MyWidget"></div>
+	<div id="widget1" data-dojo-type="dijit.MyWidget"></div>
 </body>
 </html>
diff --git a/dijit/tests/_altCalendar.html b/dijit/tests/_altCalendar.html
index d4b6730..8740d8d 100644
--- a/dijit/tests/_altCalendar.html
+++ b/dijit/tests/_altCalendar.html
@@ -12,13 +12,8 @@
 				<span dojoAttachPoint="increaseArrowNode" class="dijitA11ySideArrow">+</span>
 			</span></th>
 			<th class='dijitReset' colspan="6">
-				<div class="dijitVisible">
-					<div class="dijitPopup dijitMenu dijitMenuPassive dijitHidden" dojoAttachPoint="monthDropDown" dojoAttachEvent="onmouseup: _onMonthSelect, onmouseover: _onMenuHover, onmouseout: _onMenuHover">
-						<div class="dijitCalendarMonthLabelTemplate dijitCalendarMonthLabel"></div>
-					</div>
+				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-attach-point="monthDropDownButton">
 				</div>
-				<div dojoAttachPoint="monthLabelSpacer" class="dijitSpacer"></div>
-				<div dojoAttachPoint="monthLabelNode" class="dijitCalendarMonthLabel dijitInline dijitVisible" dojoAttachEvent="onmousedown: _onMonthToggle"></div>
 			</th>
 		</tr>
 		<tr>
diff --git a/dijit/tests/_base/manager.html b/dijit/tests/_base/manager.html
index 9a79d59..a01d101 100644
--- a/dijit/tests/_base/manager.html
+++ b/dijit/tests/_base/manager.html
@@ -1,39 +1,44 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit manager unit test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit");
 
-		dojo.declare("foo", dijit._Widget, {
-			name: "",
-			attr1: 0,
-			attr2: 0
-		});
-
-		dojo.declare("bar", dijit._Widget, {
-			name: "",
-			attr1: 0,
-			attr2: 0
-		});
-
-		dojo.declare("Baz", dijit._Widget, {
-			name: "",
-			attr1: 1,
-			attr2: 1
-		});
-
 		dojo.addOnLoad(function(){
+			dojo.declare("foo", dijit._Widget, {
+				name: "",
+				attr1: 0,
+				attr2: 0
+			});
+	
+			dojo.declare("bar", dijit._Widget, {
+				name: "",
+				attr1: 0,
+				attr2: 0
+			});
+	
+			dojo.declare("Baz", dijit._Widget, {
+				name: "",
+				attr1: 1,
+				attr2: 1
+			});
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
 			doh.register("dijit._base.manager",
 				[
 					function forEachTest(t){
@@ -238,6 +243,7 @@
 					}
 				]
 			);
+
 			doh.run();
 		});
 
@@ -245,14 +251,14 @@
 </head>
 <body>
 	<h1>Dijit Manager Unit Test</h1>
-	<div dojoType="foo" id="one" name="bob" attr1="10" attr2="10"></div>
-	<div dojoType="foo" id="two" name="is" attr1="5" attr2="10"></div>
-	<div dojoType="bar" id="three" name="your" attr1="5" attr2="5">
+	<div id="one" data-dojo-type="foo" data-dojo-props='name:"bob", attr1:10, attr2:10'></div>
+	<div id="two" data-dojo-type="foo" data-dojo-props='name:"is", attr1:5, attr2:10'></div>
+	<div id="three" data-dojo-type="bar" data-dojo-props='name:"your", attr1:5, attr2:5'>
 		<div id="three.one">
 			<div id="three.one.one"></div>
 		</div>
 	</div>
-	<div dojoType="bar" id="four" name="uncle" attr1="10" attr2="5"></div>
+	<div id="four" data-dojo-type="bar" data-dojo-props='name:"uncle", attr1:10, attr2:5'></div>
 	<div id="not-a-widget"></div>
 </body>
 </html>
diff --git a/dijit/tests/_base/module.js b/dijit/tests/_base/module.js
index 07a8c17..222b5b7 100644
--- a/dijit/tests/_base/module.js
+++ b/dijit/tests/_base/module.js
@@ -4,14 +4,16 @@ try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?"),
 		test_robot = true;
 
-	doh.registerUrl("dijit.tests._base.manager", dojo.moduleUrl("dijit", "tests/_base/manager.html"), 99999999);
-	doh.registerUrl("dijit.tests._base.tabindex", dojo.moduleUrl("dijit", "tests/_base/tabindex.html"), 99999999);
-	doh.registerUrl("dijit.tests._base.wai", dojo.moduleUrl("dijit", "tests/_base/wai.html"), 99999999);
-	doh.registerUrl("dijit.tests._base.place", dojo.moduleUrl("dijit", "tests/_base/place.html"), 99999999);
+	doh.registerUrl("dijit.tests._base.manager", dojo.moduleUrl("dijit", "tests/_base/manager.html"), 999999);
+	doh.registerUrl("dijit.tests._base.tabindex", dojo.moduleUrl("dijit", "tests/_base/tabindex.html"), 999999);
+	doh.registerUrl("dijit.tests._base.wai", dojo.moduleUrl("dijit", "tests/_base/wai.html"), 999999);
+	doh.registerUrl("dijit.tests._base.place", dojo.moduleUrl("dijit", "tests/_base/place.html"), 999999);
 	if(test_robot){
-		doh.registerUrl("dijit.tests._base.robot.FocusManager", dojo.moduleUrl("dijit","tests/_base/robot/FocusManager.html"), 99999999);
-		doh.registerUrl("dijit.tests._base.robot.focus_mouse", dojo.moduleUrl("dijit","tests/_base/robot/focus_mouse.html"), 99999999);
-		doh.registerUrl("dijit.tests._base.robot.typematic", dojo.moduleUrl("dijit","tests/_base/robot/typematic.html"), 99999999);
+		doh.registerUrl("dijit.tests._base.robot.popup", dojo.moduleUrl("dijit", "tests/_base/robot/popup.html"), 999999);
+		doh.registerUrl("dijit.tests._base.robot.CrossWindow", dojo.moduleUrl("dijit","tests/_base/robot/CrossWindow.html"), 999999);
+		doh.registerUrl("dijit.tests._base.robot.FocusManager", dojo.moduleUrl("dijit","tests/_base/robot/FocusManager.html"), 999999);
+		doh.registerUrl("dijit.tests._base.robot.focus_mouse", dojo.moduleUrl("dijit","tests/_base/robot/focus_mouse.html"), 999999);
+		doh.registerUrl("dijit.tests._base.robot.typematic", dojo.moduleUrl("dijit","tests/_base/robot/typematic.html"), 999999);
 	}
 
 }catch(e){
diff --git a/dijit/tests/_base/place.html b/dijit/tests/_base/place.html
index 60e9888..83c7b0a 100644
--- a/dijit/tests/_base/place.html
+++ b/dijit/tests/_base/place.html
@@ -4,7 +4,7 @@
 <head>
 	<title>Dijit.place unit test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		body {
diff --git a/dijit/tests/_base/robot/CrossWindow.html b/dijit/tests/_base/robot/CrossWindow.html
new file mode 100644
index 0000000..b682467
--- /dev/null
+++ b/dijit/tests/_base/robot/CrossWindow.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 CrossWindow 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_CrossWindow.html');
+
+				doh.register("CrossWindow", [
+					{
+						name: "Create widget on main window",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var widget = dijit.byId("simple_0");
+								doh.t(widget, "The first widget was not created");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "Pop up new window",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("popupLink", 100, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var widget = dijit.byId("simple3");
+								doh.t(widget, "The 3rd widget was not created");
+								doh.is("mainpage", widget.domNode.ownerDocument.body.id);
+								doh.is("Templated in IE Popup Test", widget.domNode.ownerDocument.title);
+
+								widget = dijit.byId("simple2");
+								doh.t(widget, "The 2nd widget was not created");
+								doh.is("popup", widget.domNode.ownerDocument.body.id);
+								doh.is("IE Cross Window", widget.domNode.ownerDocument.title);
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/_base/robot/FocusManager.html b/dijit/tests/_base/robot/FocusManager.html
index d0875c7..c1b56df 100644
--- a/dijit/tests/_base/robot/FocusManager.html
+++ b/dijit/tests/_base/robot/FocusManager.html
@@ -117,6 +117,7 @@
 						name: "Test select text, clear, and restore",
 						timeout: 8000,
 						runTest: function(){
+							if(!dojo.isIE){ // IE only supports selecting form elements and the whole body from a plain non-Editor page, see the MSDN article on createTextRange
 							var d = new doh.Deferred();
 
 							//Select the text in the p tag.
@@ -153,6 +154,7 @@
 								d.errback(e);
 							}
 							return d;
+							}
 						}
 					}
 				]);
diff --git a/dijit/tests/_base/robot/focus_mouse.html b/dijit/tests/_base/robot/focus_mouse.html
index 5fadfcc..40fbbbc 100644
--- a/dijit/tests/_base/robot/focus_mouse.html
+++ b/dijit/tests/_base/robot/focus_mouse.html
@@ -22,19 +22,34 @@
 				function resetEvents(){
 					focusEvents = {};
 					blurEvents = {};
+					focusedState = {};
+					focusedWatchLog = {};
 				}
 				resetEvents();
 
 				doh.register("Dijit focus manager tests", [
 
 					function setUp(){
-						dojo.forEach(["form", "fieldset1", "fieldset2", "select", "editor"], function(id){
-							dojo.connect(dijit.byId(id), "_onFocus", function(){
+						dojo.forEach(["form", "fieldset1", "fieldset2", "select", "editor", "spinner"], function(id){
+							var w = dijit.byId(id);
+
+							// old API is to connect to onFocus/onBlur (remove in 2.0)
+							dojo.connect(w, "onFocus", function(){
 								focusEvents[id] = true;
 							});
-							dojo.connect(dijit.byId(id), "_onBlur", function(){
+							dojo.connect(w, "onBlur", function(){
 								blurEvents[id] = true;
 							});
+
+							// new API is to watch "focused" attribute
+							w.watch("focused", function(name, oldValue, newValue){
+								// keep track of current state
+								focusedState[name] = newValue;
+
+								// keep log of every watch notification
+								var nvs = newValue ? "focused" : "blurred";
+								focusedWatchLog[w.id] = !focusedWatchLog[w.id] ? nvs : focusedWatchLog[w.id] + ", " + nvs;
+							});
 						});
 					},
 
@@ -59,6 +74,9 @@
 								// And that the dijit.form.Form widget is marked as
 								// being "in focus"
 								doh.t(focusEvents["form"], "form focused");
+								
+								// And that it got one watch event
+								doh.is("focused", focusedWatchLog["form"], "watch callback");
 							}), 500);
 
 							return d;
@@ -72,10 +90,7 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-
-							dijit.byId("select").focus();
-
-							doh.robot.sequence(d.getTestCallback(function(){
+							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);
@@ -92,9 +107,17 @@
 								doh.f(blurEvents["form"], "form wasn't blurred");
 								doh.t(focusEvents["fieldset1"], "fieldset1 focused");
 								doh.t(focusEvents["select"], "select focused");
-							}), 500);
+								
+								doh.f(focusedWatchLog["form"], "form watch callback (no new notification)");
+								doh.is("focused", focusedWatchLog["fieldset1"], "fieldset watch callback");
+								doh.is("focused", focusedWatchLog["select"], "select watch callback");
+							}));
+							dijit.byId("select").focus();
 
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handle);
 						}
 					},
 					{
@@ -120,6 +143,11 @@
 								doh.f(blurEvents["form"], "form wasn't blurred");
 								doh.t(blurEvents["fieldset1"], "fieldset no longer focused");
 								doh.t(focusEvents["editor"], "editor focused");
+
+								doh.f(focusedWatchLog["form"], "form watch callback (no new notification)");
+								doh.is("blurred", focusedWatchLog["fieldset1"], "fieldset watch callback, no longer focused");
+								doh.is("blurred", focusedWatchLog["select"], "select watch callback, no longer focused");
+								doh.is("focused", focusedWatchLog["editor"], "editor watch callback");
 							}), 500);
 
 							return d;
@@ -147,19 +175,24 @@
 								doh.is("form", stack[0], "grandparent of spinner");
 								doh.is("fieldset2", stack[1], "parent of spinner");
 								doh.is("spinner", stack[2], "spinner itself (last in stack)");
+
+								// check watch callbacks
+								doh.f(focusedWatchLog["form"], "grandparent of spinner stayed focused, so no new watch event (watch)");
+								doh.is("focused", focusedWatchLog["fieldset2"], "parent of spinner (watch)");
+								doh.is("focused", focusedWatchLog["spinner"], "spinner (watch)");
 							}), 500);
 
 							return d;
 						}
-					},
-
+					}/*,
+					// FIXME: this test is invalid because focus is not designed to change on mouse click to the first item in the menu
 					{
 						name: "combo button menu",
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var button = dojo.query("#button .dijitDownArrowButton")[0];
+							var button = dijit.byId('button').focusNode;
 							doh.t(button, "found drop down button");
 
 							doh.robot.mouseMoveAt(button);
@@ -167,7 +200,7 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Focus goes to an first item in the drop down menu
-								doh.is(dojo.byId("mi1"), dojo.global.dijit._curFocus);
+								doh.is(dojo.byId("mi1").id, dojo.global.dijit._curFocus.id);
 
 								// The focus stack should show the ComboBox plus all parent widgets
 								var stack = dojo.global.dijit._activeStack;
@@ -178,11 +211,14 @@
 								doh.is("button", stack[2], "combobutton");
 								doh.is("menu", stack[3], "menu");
 								doh.is("mi1", stack[4], "menuitem");
-							}), 1000);
+							}), 500);
 
 							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handle);
 						}
-					}
+					}*/
 
 /*
 					// Commented out because
diff --git a/dijit/tests/_base/robot/popup.html b/dijit/tests/_base/robot/popup.html
index f123897..393a0d9 100644
--- a/dijit/tests/_base/robot/popup.html
+++ b/dijit/tests/_base/robot/popup.html
@@ -21,8 +21,7 @@
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_popup.html');
 
-			doh.register("simple open and close",
-				[
+				doh.register("simple open and close", [
 					function initialConditions(t){
 						// If the popup code has cached any iframes, make sure they are hidden
 						dojo.query("iframe").forEach(function(node){
@@ -70,26 +69,11 @@
 						around.closePopup();
 
 						// Make sure the popup is hidden
-						// (in a future release this might change to display:none etc but currently it's visibility:hidden)
-						doh.is("hidden", popup.domNode.style.visibility, "popup is hidden");
-
-						// If the popup code has cached the iframe for later use, make sure it's hidden
-						dojo.query("iframe").forEach(function(node){
-							doh.is("none", node.style.display, "background iframe is hidden");
-						});
+						doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
 					}
 				]);
 
-			doh.register("nested open and close",
-				[
-					function initialConditions(t){
-						// If the popup code has cached any iframes, make sure they are hidden
-						dojo.query("iframe").forEach(function(node){
-							console.log("found iframe", node);
-							doh.is("none", node.style.display, "background iframe is hidden");
-						});
-					},
-
+				doh.register("nested open and close", [
 					// Open first level
 					function openAround(){
 						var d = new doh.Deferred();
@@ -105,7 +89,7 @@
 
 							if(dojo.isIE <= 6){
 								// Test the BackgroundIFrame
-								var iframes = dojo.query("iframe");
+								var iframes = dojo.query("iframe", popup.domNode.parentNode);
 								doh.is(1, iframes.length, "one background iframe on IE6");
 
 								var popupCoords = dojo.position(popup.domNode),
@@ -136,11 +120,14 @@
 
 							if(dojo.isIE <= 6){
 								// Test the BackgroundIFrame
-								var iframes = dojo.query("iframe");
-								doh.is(2, iframes.length, "two background iframe on IE6");
+								var iframes = dojo.query("iframe", popup.domNode.parentNode);
+								doh.is(1, iframes.length, "one background iframe for popup");
+
+								iframes = dojo.query("iframe", nestedPopup.domNode.parentNode);
+								doh.is(1, iframes.length, "another background iframe for nested popup");
 
 								var popupCoords = dojo.position(nestedPopup.domNode),
-									iframeCoords = dojo.position(iframes[1]);
+									iframeCoords = dojo.position(iframes[0]);
 								doh.is(popupCoords.x, iframeCoords.x, "x is same: " + popupCoords.x);
 								doh.is(popupCoords.y, iframeCoords.y, "y is same: " + popupCoords.y);
 								doh.is(popupCoords.w, iframeCoords.w, "w is same: " + popupCoords.w);
@@ -166,16 +153,69 @@
 
 						// Make sure the popups are both hidden
 						// (in a future release this might change to display:none etc but currently it's visibility:hidden)
-						doh.is("hidden", popup.domNode.style.visibility, "popup is hidden");
-						doh.is("hidden", nestedPopup.domNode.style.visibility, "nested popup is hidden");
-
-						// If the popup code has cached the iframes for later use, make sure they are hidden
-						dojo.query("iframe").forEach(function(node){
-							doh.is("none", node.style.display, "background iframe is hidden");
-						});
+						doh.is("none", popup.domNode.parentNode.style.display, "popup is hidden");
+						doh.is("none", nestedPopup.domNode.parentNode.style.display, "nested popup is hidden");
 					}
 				]);
 
+				// Make sure there are no hidden tab stops when popups are closed.
+				// This test doesn't work on safari (due to safari bugs) although there aren't any hidden tab stops.
+				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)
+
 				// TODO: test x/y placement
 
 				// Test that onCancel goes back one level.
diff --git a/dijit/tests/_base/robot/typematic.html b/dijit/tests/_base/robot/typematic.html
index b91a62d..a2da8b5 100644
--- a/dijit/tests/_base/robot/typematic.html
+++ b/dijit/tests/_base/robot/typematic.html
@@ -23,42 +23,50 @@
 						name: "keyboard",
 						timeout: 9000,
 						runTest: function(){
-							var input = dojo.byId("typematicInput");
+							var
+								d = new doh.Deferred(),
+								input = dojo.byId("typematicInput"),
+								v;
 							input.value = "";
 							input.focus();
-							var d = new doh.Deferred();
 
 							doh.robot.keyDown(dojo.keys.CTRL, 1000);
 							doh.robot.keyDown(dojo.keys.F11, 200);
-							doh.robot.keyUp(dojo.keys.F11, 2000);
-							doh.robot.keyUp(dojo.keys.CTRL, 200);
+							doh.robot.sequence(function(){
+								v = input.value; // get value before releasing key to reduce timing dependence on the robot
+							}, 2000);
+							doh.robot.keyUp(dojo.keys.F11, 100);
+							doh.robot.keyUp(dojo.keys.CTRL, 100);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								var v = input.value;
 								// allow off by 1
-								doh.t(v=="aaaaaaaaa"||v=="aaaaaaaaaa"||v=="aaaaaaaaaaa", "a letters typed");
-							}), 500);
+								doh.t(v=="aaaaaaaaa"||v=="aaaaaaaaaa"||v=="aaaaaaaaaaa", "a letters typed " + v);
+							}), 100);
 
 							return d;
 						}
 					},
 					{
 						name: "mouse",
-						timeout: 9000,
+						timeout: 5000,
 						runTest: function(){
-							var input = dojo.byId("typematicInput");
+							var
+								d = new doh.Deferred(),
+								input = dojo.byId("typematicInput"),
+								v;
 							input.value = "";
-							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("typematicButton", 1000, 1000);
+							doh.robot.mouseMoveAt("typematicButton", 500, 1);
 							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseRelease({left: true}, 1000);
+							doh.robot.sequence(function(){
+								v = input.value; // get value before releasing button to reduce timing dependence on the robot
+							}, 1000);
+							doh.robot.mouseRelease({left: true}, 100);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								var v = input.value;
 								// allow off by 1
-								doh.t(v=="bbbbbb"||v=="bbbbbbb"||v=="bbbbbbbb", "b letters typed");
-							}), 500);
+								doh.t(v=="bbbbbb"||v=="bbbbbbb"||v=="bbbbbbbb", "b letters typed " + v);
+							}), 100);
 
 							return d;
 						}
diff --git a/dijit/tests/_base/tabindex.html b/dijit/tests/_base/tabindex.html
index f4ad8bf..9fcea43 100644
--- a/dijit/tests/_base/tabindex.html
+++ b/dijit/tests/_base/tabindex.html
@@ -1,23 +1,28 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit tabindex related functions unit test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
-		@import "../../themes/tundra/tundra.css";
+		@import "../../themes/claro/claro.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.Editor");
 
 		dojo.addOnLoad(function(){
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
 			doh.register("dijit.tabindex",
 				[
 					function isTabNavigable(t){
@@ -126,6 +131,7 @@
 					}
 				]
 			);
+
 			doh.run();
 		});
 
@@ -140,25 +146,25 @@
 		<div id="div"></div>
 	</div>
 	<div id="a-without-href-container">
-		<a id="a-without-href" name="named-link-anchor"></a>
+		<a id="a-without-href"></a>
 	</div>
 	<div id="a-with-href-container">
-		<a id="a-with-href" href="#named-link-anchor"></a>
+		<a id="a-with-href" href="#a-without-href"></a>
 	</div>
 
-	<div><img src="../images/flatScreen.gif" alt="picture of a flat-screen monitor" usemap="#area-map"></div>
+	<div><img src="../images/flatScreen.gif" alt="picture of a flat-screen monitor" usemap="#area-map"/></div>
 	<map id="area-map" name="area-map">
-		<area id="area" href="#" alt="example area" shape="rect" coords="0,0,8,8">
+		<area id="area" href="#" alt="example area" shape="rect" coords="0,0,8,8"/>
 	</map>
 
 	<div id="button-container">
 		<button id="button"></button>
 	</div>
 	<div id="input-container">
-		<input id="input">
+		<input id="input"/>
 	</div>
 	<div id="object-container">
-		<object id="object"></object>
+		<object id="object" type="text/javascript"></object>
 	</div>
 	<div id="select-container">
 		<select id="select"></select>
@@ -168,9 +174,9 @@
 	</div>
 
 	<div id="skip-disabled">
-		<input id="disabled-input1" disabled="disabled">
-		<input id="not-disabled-input">
-		<input id="disabled-input2" disabled="disabled">
+		<input id="disabled-input1" disabled="disabled"/>
+		<input id="not-disabled-input"/>
+		<input id="disabled-input2" disabled="disabled"/>
 	</div>
 
 	<div id="zero-tabindex-div-container">
@@ -182,7 +188,7 @@
 	</div>
 
 	<div id="zero-tabindex-input-container">
-		<input id="zero-tabindex-input" tabindex="0">
+		<input id="zero-tabindex-input" tabindex="0"/>
 	</div>
 
 	<div id="iframe-container">
@@ -190,58 +196,58 @@
 	</div>
 
 	<div id="editor-container">
-		<div id="editor" dojoType="dijit.Editor"></div>
+		<div id="editor" data-dojo-type="dijit.Editor"></div>
 	</div>
 
 	<div id="positive-tabindex-mixed-with-no-tabindex">
-		<input id="no-tabindex-input1">
-		<input id="no-tabindex-input2">
-		<input id="positive-tabindex-input1a" tabindex="1">
-		<input id="positive-tabindex-input1b" tabindex="1">
-		<input id="positive-tabindex-input2a" tabindex="2">
-		<input id="positive-tabindex-input2b" tabindex="2">
+		<input id="no-tabindex-input1"/>
+		<input id="no-tabindex-input2"/>
+		<input id="positive-tabindex-input1a" tabindex="1"/>
+		<input id="positive-tabindex-input1b" tabindex="1"/>
+		<input id="positive-tabindex-input2a" tabindex="2"/>
+		<input id="positive-tabindex-input2b" tabindex="2"/>
 	</div>
 
 	<div id="positive-tabindex">
-		<input id="positive-tabindex-input3a" tabindex="3">
-		<input id="positive-tabindex-input3b" tabindex="3">
-		<input id="positive-tabindex-input4a" tabindex="4">
-		<input id="positive-tabindex-input4b" tabindex="4">
+		<input id="positive-tabindex-input3a" tabindex="3"/>
+		<input id="positive-tabindex-input3b" tabindex="3"/>
+		<input id="positive-tabindex-input4a" tabindex="4"/>
+		<input id="positive-tabindex-input4b" tabindex="4"/>
 	</div>
 
 	<div id="skip-minus-one">
-		<input id="minus-one-input1" tabindex="-1">
-		<input id="not-minus-one-input">
-		<input id="minus-one-input2" tabindex="-1">
+		<input id="minus-one-input1" tabindex="-1"/>
+		<input id="not-minus-one-input"/>
+		<input id="minus-one-input2" tabindex="-1"/>
 	</div>
 
 	<div id="descend">
-		<input disabled="disabled">
+		<input disabled="disabled"/>
 		<div>
-			<input disabled="disabled">
+			<input disabled="disabled"/>
 			<div>
-				<input disabled="disabled">
+				<input disabled="disabled"/>
 			</div>
 		</div>
 		<div>
-			<input disabled="disabled">
+			<input disabled="disabled"/>
 			<div>
-				<input disabled="disabled">
+				<input disabled="disabled"/>
 			</div>
 			<div>
-				<input id="child-input1">
+				<input id="child-input1"/>
 			</div>
 			<div>
-				<input id="child-input2">
+				<input id="child-input2"/>
 			</div>
 		</div>
 		<div>
 			<div>
-				<input disabled="disabled">
+				<input disabled="disabled"/>
 			</div>
-			<input disabled="disabled">
+			<input disabled="disabled"/>
 		</div>
-		<input disabled="disabled">
+		<input disabled="disabled"/>
 	</div>
 
 	<div id="outer-inner-container">
diff --git a/dijit/tests/_base/test_CrossWindow.html b/dijit/tests/_base/test_CrossWindow.html
index fe1fd74..d014c26 100644
--- a/dijit/tests/_base/test_CrossWindow.html
+++ b/dijit/tests/_base/test_CrossWindow.html
@@ -29,27 +29,24 @@
 			onPopClose = function(){
 				console.log("setting context back to main window...");
 				dojo.setContext(dojo.global, globalDocument);
-				console.log("Now building the wdiget in the main window...");
+				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({}, div);
+				new widgetClass({id:"simple3"}, div);
 				console.log("There should now be two widgets at the top of the page.");
 			}
 
 			onPopLoad = function(){
-				popwin.onunload = onPopClose;
-
-				console.log("popwin:", popwin);
-				console.log("popwin.onunload :", popwin.onunload );
-
 				globalDocument = dojo.doc;
 				dojo.setContext(dojo.global, popwin.document);
 
+				if(dijit.byId('simple2')){ dijit.byId('simple2').destroy(); }
 				console.log("rendering one widget in popup...");
 
 				var div = dojo.doc.createElement("div");
 				dojo.byId("main").appendChild(div);
-				new widgetClass({}, div);
+				new widgetClass({id:"simple2"}, div);
 
 				console.log("The widget should have appeared in the popup window.");
 
@@ -64,7 +61,7 @@
 				var newfcolor = '$FF0000';
 				var word = "";
 				var HTMLstring=	'<HTML><HEAD><TITLE>IE Cross Window</TITLE></HEAD>\n' +
-								'<BODY id="popup" bgColor="'+newbcolor+'" onload = function(){popup.opener.onPopLoad();}>\n'+
+								'<BODY id="popup" bgColor="'+newbcolor+'">\n'+
 								'<div><div id="main"></div></div>\n'+
 								'</BODY></HTML>';
 
@@ -76,10 +73,10 @@
 				// The onload event for IE is written into the above body tag.
 				// This is the onload for Firefox
 				if(dojo.isMoz){
-					popup.onload = onPopLoad
+					popup.onload = onPopLoad;
 				}else{
 					setTimeout(function(){
-						onPopLoad()
+						onPopLoad();
 					}, 200);
 				}
 
@@ -95,8 +92,8 @@
 				var div = dojo.doc.createElement("div");
 				dojo.byId("main").appendChild(div);
 
-				for(var i =0; i<amt; i++){
-					new widgetClass({}, div);
+				for(var i = 0; i < amt; i++){
+					new widgetClass({id:"simple_"+i}, div);
 				}
 				console.log("Time to render ", amt, " widgets:",  (new Date() - start) );
 			}
@@ -105,16 +102,11 @@
 				widgetClass = dojo.declare(
 					"Simple",
 					[dijit._Widget, dijit._Templated], {
-						templateString: '<div> - Widget created -</div>'
+						templateString: '<div> Widget created: ${id} </div>'
 					}
 				);
 
 				speedTest();
-
-				console.log("Opening popup window...");
-				setTimeout(function(){
-					popwin = openPopup();
-				}, 0);
 			});
 		</script>
 	</head>
@@ -126,9 +118,12 @@
 			<a href="http://trac.dojotoolkit.org/ticket/6791">#6791</a>.
 		</p>
 		<p>
-			You must allow popup before running this test.
+			You must allow popups before running this test.
 			Check console for results.
 		</p>
 		<div id="main"></div>
+		<iframe name="mywin" src="about:blank"></iframe>
+		
+		<a id="popupLink" href="nowhere.html" onclick="popwin = openPopup();return false;">run popup test</a>
 	</body>
 </html>
diff --git a/dijit/tests/_base/test_FocusManager.html b/dijit/tests/_base/test_FocusManager.html
index 1bfe546..48eeece 100644
--- a/dijit/tests/_base/test_FocusManager.html
+++ b/dijit/tests/_base/test_FocusManager.html
@@ -4,8 +4,8 @@
 <head>
 	<title>dijit.focus Test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../themes/tundra/tundra.css";
+		@import "../../themes/claro/document.css";
+		@import "../../themes/claro/claro.css";
 		@import "../css/dijitTests.css";
 	</style>
 
diff --git a/dijit/tests/_base/test_focusWidget.html b/dijit/tests/_base/test_focusWidget.html
index 658d114..10f1a80 100644
--- a/dijit/tests/_base/test_focusWidget.html
+++ b/dijit/tests/_base/test_focusWidget.html
@@ -1,16 +1,16 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.focus Test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../themes/tundra/tundra.css";
+		@import "../../themes/claro/document.css";
+		@import "../../themes/claro/claro.css";
 		@import "../css/dijitTests.css";
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.DateTextBox");
@@ -30,11 +30,9 @@
 				queue.push(arguments);
 				return;
 			}
-			with(widget.domNode.style){
-				borderStyle="solid";
-				outlineStyle="solid";
-
-			}
+			var s = widget.domNode.style;
+			s.borderStyle="solid";
+			s.outlineStyle="solid";
 			animation = dojo.animateProperty({
 				node: widget.domNode,
 				duration: 50,
@@ -73,6 +71,13 @@
 				}
 			});
 			dojo.subscribe("focusNode", function(node){ console.log("focused on node " + (node?(node.id||node.tagName):"nothing"));});
+
+			// Focus notification also comes through watch() on each widget
+			dijit.registry.forEach(function(widget){
+				widget.watch("focused", function(name, oldValue, newValue){
+					console.log(this.id + "." + name + ": " + oldValue + " ---> " + newValue);
+				});
+			}, this);
 		});
 	</script>
 	<style>
@@ -92,48 +97,48 @@
 		Also, check the console log for focus and blur events on widgets.
 	</p>
 
-	<label for="fieldset1">a form ContentPane widget:</label><br>
-	<form dojoType="dijit.layout.ContentPane" id="form">
-		<label for="first">simple input: </label><input id=first><br>
+	<label>a form ContentPane widget:</label><br>
+	<form id="form" data-dojo-type="dijit.layout.ContentPane" >
+		<label for="first">simple input: </label><input id="first"/><br>
 
-		<label for="fieldset1">a fieldset ContentPane widget:</label><br>
-		<fieldset id=fieldset1 dojoType="dijit.layout.ContentPane">
+		<label>a fieldset ContentPane widget:</label><br>
+		<fieldset id=fieldset1 data-dojo-type="dijit.layout.ContentPane">
 			<label for="select">a ComboBox widget:</label>
-			<select id=select dojoType="dijit.form.ComboBox">
+			<select id=select data-dojo-type="dijit.form.ComboBox">
 				<option>this</option>
 				<option>is</option>
 				<option>a</option>
 				<option>list</option>
 			</select>
 			<label for="plain">a plain input:</label>
-			<input id=plain value=plain>
+			<input id=plain value=plain/>
 		</fieldset>
-		<div dojoType="dijit.Editor" id=editor>
+		<div id=editor data-dojo-type="dijit.Editor" >
 			Hello world, this is an <i>editor</i>
 		</div>
 		<br>
-		<label for="fieldset1">another fieldset ContentPane:</label><br>
-		<fieldset id=fieldset2 dojoType="dijit.layout.ContentPane">
+		<label>another fieldset ContentPane:</label><br>
+		<fieldset id=fieldset2 data-dojo-type="dijit.layout.ContentPane">
 			<label for="date">a DateTextBox widget:</label>
-			<input id=date dojoType="dijit.form.DateTextBox"><br>
+			<input id=date data-dojo-type="dijit.form.DateTextBox"/><br>
 
 			<label for="textarea">a plain textarea:</label><br>
 			<textarea id=textarea>hello there!</textarea><br>
 
 			<label for="spinner">a Spinner widget:</label>
-			<input id=spinner dojoType="dijit.form.NumberSpinner" value=100><br>
+			<input id=spinner data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='value:100'/><br>
 
-			<label for="button">a Combobutton widget:</label>
-			<div id=button dojoType="dijit.form.ComboButton" tabIndex=0>
+			<label>a Combobutton widget:</label>
+			<div id=button data-dojo-type="dijit.form.ComboButton" data-dojo-props='tabIndex:"0"'>
 				<span>push me</span>
-				<div id=menu dojoType="dijit.Menu">
-					<div id=mi1 dojoType="dijit.MenuItem">menu item 1</div>
-					<div id=mi2 dojoType="dijit.MenuItem">menu item 2</div>
-					<div id=popupMenuItem dojoType="dijit.PopupMenuItem">
+				<div id=menu data-dojo-type="dijit.Menu">
+					<div id=mi1 data-dojo-type="dijit.MenuItem">menu item 1</div>
+					<div id=mi2 data-dojo-type="dijit.MenuItem">menu item 2</div>
+					<div id=popupMenuItem data-dojo-type="dijit.PopupMenuItem">
 						<span>submenu</span>
-						<div id=submenu dojoType="dijit.Menu">
-							<div id=smi1 dojoType="dijit.MenuItem">submenu item 1</div>
-							<div id=smi2 dojoType="dijit.MenuItem">submenu item 2</div>
+						<div id=submenu data-dojo-type="dijit.Menu">
+							<div id=smi1 data-dojo-type="dijit.MenuItem">submenu item 1</div>
+							<div id=smi2 data-dojo-type="dijit.MenuItem">submenu item 2</div>
 						</div>
 					</div>
 				</div>
diff --git a/dijit/tests/_base/test_popup.html b/dijit/tests/_base/test_popup.html
index 39827df..b356280 100644
--- a/dijit/tests/_base/test_popup.html
+++ b/dijit/tests/_base/test_popup.html
@@ -4,7 +4,7 @@
 <head>
 	<title>Dijit.popup and BackgroundIFrame unit test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../../themes/dijit.css";
 		@import "../css/dijitTests.css";
 
@@ -117,11 +117,11 @@
 
 			// Create a button that displays a simple drop down
 			choiceDropDown = new SimpleChoiceWidget();
-			choiceDropDownButton = new SimpleDropDownButton({
+			(choiceDropDownButton = new SimpleDropDownButton({
 				id: "choiceDropDownButton",
 				label: "show choice drop down",
 				popup: choiceDropDown
-			}).placeAt(dojo.body());
+			})).placeAt(dojo.byId("widgets"));
 
 			dojo.declare("DialogWithPopupWidget",  [dijit._Widget, dijit._Templated], {
 				// summary:
@@ -173,7 +173,7 @@
 						id: "choiceFromDialog"
 					})
 				})
-			}).placeAt(dojo.body());
+			}).placeAt(dojo.byId("widgets"));
 
 			dojo.declare("NestedPopupOpener",  [dijit._Widget, dijit._Templated], {
 				// summary:
@@ -231,7 +231,7 @@
 				id: "showNestedMenuButton",
 				label: "show nested drop down",
 				popup: nestedOpener
-			}).placeAt(dojo.body());
+			}).placeAt(dojo.byId("widgets"));
 
 			// Create a button that displays a dialog that displays a nested drop down
 			dialogNestedChoice1 = new SimpleChoiceWidget({
@@ -257,14 +257,15 @@
 				id: "showComplexDialogButton",
 				label: "show dialog w/nested menu",
 				popup: dialogWithNestedPopup
-			}).placeAt(dojo.body());
+			}).placeAt(dojo.byId("widgets"));
 
 		});
-
 	</script>
 </head>
 <body>
 	<h1>dijit.popup and BackgroundIFrame Unit Test</h1>
-	<button>simple button</button>
+	<input id="inputAtStart">
+	<span id="widgets"></span>
+	<input id="inputAtEnd">
 </body>
 </html>
diff --git a/dijit/tests/_base/test_typematic.html b/dijit/tests/_base/test_typematic.html
index e72baac..83848c6 100644
--- a/dijit/tests/_base/test_typematic.html
+++ b/dijit/tests/_base/test_typematic.html
@@ -4,8 +4,8 @@
 <head>
 	<title>Typematic Test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../themes/tundra/tundra.css";
+		@import "../../themes/claro/document.css";
+		@import "../../themes/claro/claro.css";
 		@import "../css/dijitTests.css";
 	</style>
 
diff --git a/dijit/tests/_base/wai.html b/dijit/tests/_base/wai.html
index 8a4860a..9275e80 100644
--- a/dijit/tests/_base/wai.html
+++ b/dijit/tests/_base/wai.html
@@ -34,47 +34,6 @@
 						doh.assertEqual("menuitem", dijit.getWaiRole(elem));
 					},
 
-					function getOnlyXHTMLRole(){
-						var elem=dojo.byId("navigation-role");
-						doh.assertFalse(dijit.hasWaiRole(elem, "contentinfo"));
-						doh.assertEqual("", dijit.getWaiRole(elem));
-					},
-
-					function getWaiRoleFromMultiple(){
-						var elem=dojo.byId("multiple-role-wairole");
-						doh.assertTrue(dijit.hasWaiRole(elem, "menuitem"));
-						doh.assertEqual("menuitem", dijit.getWaiRole(elem));
-					},
-
-					function getUnprefixedFromMultiple(){
-						var elem=dojo.byId("multiple-role");
-						doh.assertTrue(dijit.hasWaiRole(elem, "menuitem"));
-						doh.assertEqual("menuitem", dijit.getWaiRole(elem));
-					},
-
-					function getReverseWairoleFromMultiple(){
-						var elem=dojo.byId("reverse-order-wairole");
-						doh.assertTrue(dijit.hasWaiRole(elem, "menuitem"));
-						doh.assertEqual("menuitem", dijit.getWaiRole(elem));
-					},
-
-					function getReverseUnprefixedFromMultiple(){
-						var elem=dojo.byId("reverse-order-noprefix");
-						doh.assertTrue(dijit.hasWaiRole(elem, "menuitem"));
-						doh.assertEqual("menuitem", dijit.getWaiRole(elem));
-					},
-
-					function hasWaiRoleMixedRole(){
-						var elem=dojo.byId("multiple-role");
-						doh.assertTrue(dijit.hasWaiRole(elem, "menuitem"));
-					},
-
-					function hasWaiRoleXHTMLRole(){
-						var elem=dojo.byId("navigation-role");
-						doh.assertFalse(dijit.hasWaiRole(elem));
-					},
-
-
 					function setWaiRole(){
 						var div = document.createElement("div");
 						dijit.setWaiRole(div, "menuitem");
@@ -82,12 +41,14 @@
 					},
 
 					function setWaiRoleToExistingXHTML() {
+						/* replacing XHTML role w/wai role */
 						var elem=dojo.byId("navigation-role");
 						dijit.setWaiRole(elem, "treeitem");
-						doh.assertEqual("contentinfo treeitem", elem.getAttribute("role"));
+						doh.assertEqual("treeitem", elem.getAttribute("role"));
 					},
 
 					function setWaiRoleToExistingWaiRole() {
+						/* replacing wai role w/another wai role */
 						var div= document.createElement("div");
 						dijit.setWaiRole(div, "menuitem");
 						doh.assertTrue(dijit.hasWaiRole(div, "menuitem"));
@@ -95,14 +56,6 @@
 						doh.assertEqual("treeitem", div.getAttribute("role"));
 					},
 
-					function setWaiRoleToExistingWaiAndXHTMLRole() {
-						var div= dojo.byId("navigation-role");
-						dijit.setWaiRole(div, "menuitem");
-						doh.assertTrue(dijit.hasWaiRole(div, "menuitem"));
-						dijit.setWaiRole(div, "treeitem");
-						doh.assertEqual("contentinfo treeitem", div.getAttribute("role"));
-					},
-
 					function removeAllWaiRole(){
 						var div = document.createElement("div");
 						dijit.setWaiRole(div, "menuitem");
@@ -116,35 +69,6 @@
 						}
 					},
 
-					function removeAllRoleMultiple(){
-						var elem=dojo.byId("multiple-role");
-						dijit.removeWaiRole(elem);
-						if(elem.hasAttribute){
-							doh.assertFalse(elem.hasAttribute("role"));
-						}else{
-							doh.assertTrue(elem.getAttribute("role") == null
-								|| elem.getAttribute("role") == "");
-						}
-					},
-
-					function removeSingleRoleMultiple(){
-						var div= dojo.byId("navigation-role");
-						dijit.setWaiRole(div, "menuitem");
-						doh.assertTrue(dijit.hasWaiRole(div, "menuitem"));
-						dijit.removeWaiRole(div, "menuitem");
-						doh.assertFalse(dijit.hasWaiRole(div, "menuitem"));
-						doh.assertEqual("contentinfo", div.getAttribute("role"));
-					},
-
-					function removeSingleReversedRoleMultiple(){
-						var div= document.createElement("div");
-						dijit.setWaiRole(div, "menuitem");
-						var curRole = dojo.attr(div, "role");
-						dojo.attr(div, "role", curRole += " contentinfo");
-						dijit.removeWaiRole(div, "menuitem");
-						doh.assertEqual("contentinfo", div.getAttribute("role"));
-					},
-
 					function getWaiStateOnElementWithNoState(){
 						var elem = dojo.byId("no-role-or-states");
 						doh.assertFalse(dijit.hasWaiState(elem, "checked"));
@@ -184,11 +108,6 @@
 	<div id="unprefixed-role" role="menuitem"></div>
 	<div id="navigation-role" role="contentinfo"></div>
 	<div id="single-role" role="contentinfo"></div>
-	<div id="multiple-role-wairole" role="contentinfo wairole:menuitem"></div>
-	<div id="multiple-role" role="contentinfo menuitem"></div>
-	<div id="reverse-order-wairole" role="wairole:menuitem contentinfo"></div>
-	<div id="reverse-order-noprefix" role="menuitem contentinfo"></div>
 	<div id="checked" aria-checked="true"></div>
-
 </body>
 </html>
diff --git a/dijit/tests/_data/treeTest.json b/dijit/tests/_data/treeTest.json
deleted file mode 100644
index a6ad3d0..0000000
--- a/dijit/tests/_data/treeTest.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-	identifier: 'id',
-	label: 'name',
-	items: [
-		{ id: 'root', name:'root', someProperty:'root property', children: [
-			{_reference:'node1'},
-			{_reference:'node2'},
-			{_reference:'node3'},
-			{_reference:'node4'},
-			{_reference:'node5'}
-		]},
-			{ id: 'node1', name:'node1', someProperty:'somePropertyA', children: [
-				{_reference:'node1.1'}, {_reference:'node1.2'}
-			]},
-				{ id: 'node1.1',name:'node1.1', someProperty:'somePropertyA1'},
-				{ id: 'node1.2',name:'node1.2', someProperty:'somePropertyA2'},
-			{ id: 'node2', name:'node2', someProperty:'somePropertyB'},
-			{ id: 'node3', name:'node3', someProperty:'somePropertyC'},
-			{ id: 'node4', name:'node4', someProperty:'somePropertyA'},
-			{ id: 'node5', name:'node5', someProperty:'somePropertyB'}
-	]
-}
diff --git a/dijit/tests/_loadTest.js b/dijit/tests/_loadTest.js
index 917d6a6..8d5d2bf 100644
--- a/dijit/tests/_loadTest.js
+++ b/dijit/tests/_loadTest.js
@@ -1,4 +1,4 @@
-document.write(function(){
+(function(){
 var file;
 var head = document.documentElement.firstChild;
 while(head && head.tagName != "HEAD"){
@@ -36,7 +36,7 @@ if(baseHref){
 	text = text.replace(/(<HEAD\b([^>]|\s)*>)/i, "$1" + "<BASE href='" + baseHref + "'><\/BASE>");
 }
 // strip DOCTYPE and HTML tag
-text = text.replace(/^(.|\s)*?<html\b\S*\s*(([^>]|\s)*)\s*>((.|\s)*)<\/html\b([^>]|\s)*>(.|\s)*?$/i,
+text = text.replace(/^(.|\s)*?<html\b(([^>]|\s)*)>((.|\s)*)/i,
 	function(s,a1,htmlAttrs,a3,content){
 		// add attributes from target file's HTML tag - may not be necessary but we'll do it anyway for completeness
 		htmlAttrs = htmlAttrs.replace(/((\w+)\s*=\s*(['"]?)(.*?)(\3)?(\s+|$))/g,
@@ -44,7 +44,7 @@ text = text.replace(/^(.|\s)*?<html\b\S*\s*(([^>]|\s)*)\s*>((.|\s)*)<\/html\b([^
 				document.documentElement.setAttribute(attr, val);
 				return "";
 			});
-		return content;
+		return content.replace(/<\/html\b([^>]|\s)*>(.|\s)*?$/i, "");
 	});
 if(/MSIE/.test(navigator.userAgent)){ // need to load scripts serially
 	document._oldgetElementsByTagName_ = document.getElementsByTagName;
@@ -72,6 +72,7 @@ if(/MSIE/.test(navigator.userAgent)){ // need to load scripts serially
 			).replace(/(<script\s[^>]*)\bsrc\s*=\s*([^>]*>)/ig,
 		function(s,pre,post){
 			if(s.search(/\sdefer\b/i) > 0){ return s; }
+			//if(s.search(/\bxpopup.js\b/i) > 0){ return pre+">"; } // firewall popup blocker:  uncomment if you get out of stack space message
 			var file = post.substr(0, post.search(/\s|>/)).replace(/['"]/g, "");
 			var scriptText = readFile(baseHref+file);
 			if(!scriptText){
@@ -83,5 +84,5 @@ if(/MSIE/.test(navigator.userAgent)){ // need to load scripts serially
 		document._oldwrite_(text);
 	};
 }
-return text;
-}());
+document.write(text);
+})();
diff --git a/dijit/tests/_testCommon.js b/dijit/tests/_testCommon.js
index e7cf772..bb6ca81 100644
--- a/dijit/tests/_testCommon.js
+++ b/dijit/tests/_testCommon.js
@@ -17,9 +17,11 @@
 
 (function(){
 	var d = dojo,
+		dir = "",
 		theme = false,
 		testMode = null,
-		defTheme = "claro";
+		defTheme = "claro",
+		vars={};
 
 	if(window.location.href.indexOf("?") > -1){
 		var str = window.location.href.substr(window.location.href.indexOf("?")+1).split(/#/);
@@ -27,7 +29,7 @@
 		for(var i=0; i<ary.length; i++){
 			var split = ary[i].split("="),
 				key = split[0],
-				value = split[1].replace(/[^\w]/g, "");	// replace() to prevent XSS attack
+				value = (split[1]||'').replace(/[^\w]/g, "");	// replace() to prevent XSS attack
 			switch(key){
 				case "locale":
 					// locale string | null
@@ -36,6 +38,7 @@
 				case "dir":
 					// rtl | null
 					document.getElementsByTagName("html")[0].dir = value;
+					dir = value;
 					break;
 				case "theme":
 					// tundra | soria | nihilo | claro | null
@@ -44,21 +47,25 @@
 				case "a11y":
 					if(value){ testMode = "dijit_a11y"; }
 			}
+			vars[key] = value;
 		}
 	}
+	d._getVar = function(k, def){
+		return vars[k] || def;
+	}
 
 	// 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
 	// until the CSS has finished loading.
-	if(theme || testMode){
+	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+'">');
+			document.write('<link rel="stylesheet" type="text/css" href="'+themeCss+'"/>');
+			document.write('<link rel="stylesheet" type="text/css" href="'+themeCssRtl+'"/>');
 		}
 
 		if(dojo.config.parseOnLoad){
@@ -84,6 +91,25 @@
 			}
 			if(testMode){ d.addClass(b, testMode); }
 
+			// 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(){
diff --git a/dijit/tests/_testMatrix.php b/dijit/tests/_testMatrix.php
index dfd7507..27654fd 100644
--- a/dijit/tests/_testMatrix.php
+++ b/dijit/tests/_testMatrix.php
@@ -6,7 +6,7 @@
 	<title>Dojo Toolkit - Every Dijit Test + Theme</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 	</style>
 
diff --git a/dijit/tests/bidi.html b/dijit/tests/bidi.html
deleted file mode 100755
index 0f78cee..0000000
--- a/dijit/tests/bidi.html
+++ /dev/null
@@ -1,188 +0,0 @@
-<!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>Multi-directional document test</title>
-
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, extraLocale: ['en','ar','he'], isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("dojo.data.ItemFileReadStore");
-
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.MenuItem");
-		dojo.require("dijit.PopupMenuItem");
-
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.DropDownButton");
-		dojo.require("dijit.form.ComboButton");
-		dojo.require("dijit.form.ToggleButton");
-
-		dojo.require("dijit.ColorPalette");
-		dojo.require("dijit.Toolbar");
-		dojo.require("dijit.TooltipDialog");
-
-		dojo.require("dijit.form.TextBox");
-		dojo.require("dijit.form.DateTextBox");
-		dojo.require("dijit.form.NumberSpinner");
-		dojo.require("dijit.form.ComboBox");
-
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.layout.ContentPane");
-
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Multi-directional document test</h1>
-
-	<div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
-		url="_data/countries.json"></div>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel"
-		store="continentStore" query="{type:'continent'}"
-		rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
-
-	<div id="right" dir="rtl" lang="ar-eg" style="float: right; width: 500px;">
-		<h2>RTL</h2>
-
-		<div dojoType="dijit.Toolbar"
-				><div dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconCut" showLabel="false">Cut</div
-				><div dojoType="dijit.form.DropDownButton" iconClass="plusIcon" showLabel="true">
-					<span>שיח</span>
-					<div dojoType="dijit.TooltipDialog" title="Enter Login information">
-						<table>
-							<tr>
-								<td><label for="user">שם:</label></td>
-								<td><input dojoType=dijit.form.TextBox></td>
-							</tr>
-							<tr>
-								<td><label for="pwd">תאריך:</label></td>
-								<td><input dojoType=dijit.form.DateTextBox></td>
-							</tr>
-							<tr>
-								<td><label for="pwd">גיל:</label></td>
-								<td><input dojoType=dijit.form.NumberSpinner></td>
-							</tr>
-							<tr>
-								<td colspan="2" align="center">
-									<button dojoType=dijit.form.Button type="submit" name="submit">כניסה</button></td>
-							</tr>
-						</table>
-					</div
-				></div
-				><div dojoType="dijit.form.DropDownButton" iconClass="dijitEditorIcon dijitEditorIconBackColor" showLabel="true">
-					<span>لوحة الألوان</span>
-					<div dojoType="dijit.ColorPalette" style="display: none" palette="7x10" onChange="console.log(this.value);"></div>
-				</div
-				><div dojoType="dijit.form.ComboButton" optionsTitle='save options' iconClass="plusIcon" showLabel="true">
-					<span>القائمة</span>
-					<div dojoType="dijit.Menu" style="display: none;">
-						<div dojoType="dijit.MenuItem"  iconClass="dijitEditorIcon dijitEditorIconSave">حفظ</div>
-						<div dojoType="dijit.MenuItem">حفظ ك</div>
-						<div dojoType="dijit.PopupMenuItem">
-							<span>فرعية</span>
-							<div dojoType="dijit.Menu">
-								<div dojoType="dijit.MenuItem">Submenu Item One</div>
-								<div dojoType="dijit.MenuItem">Submenu Item Two</div>
-								<div dojoType="dijit.PopupMenuItem">
-									<span>Deeper Submenu</span>
-									<div dojoType="dijit.Menu">
-										<div dojoType="dijit.MenuItem">Sub-sub-menu Item One</div>
-										<div dojoType="dijit.MenuItem">Sub-sub-menu Item Two</div>
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div
-		></div>
-		<div dojoType="dijit.layout.TabContainer" style="width: 450px; height: 300px; margin-top: 1em;">
-			<div dojoType="dijit.layout.ContentPane" title="رابط" closable="true" href="layout/doc0.html"></div>
-			<div dojoType="dijit.Tree" model="continentModel" openOnClick="true" title="עץ" closable="true"></div>
-		</div>
-	</div>
-
-	<div id="left" dir="ltr" lang="en-us" style="width: 500px; float: left;">
-		<h2>LTR</h2>
-
-		<div dojoType="dijit.Toolbar"
-				><div dojoType="dijit.form.Button" iconClass="dijitEditorIcon dijitEditorIconCut" showLabel="false">Cut</div
-				><div dojoType="dijit.form.DropDownButton" iconClass="plusIcon" showLabel="true">
-					<span>TooltipDialog</span>
-					<div dojoType="dijit.TooltipDialog" title="Enter Login information">
-						<table>
-							<tr>
-								<td><label for="user">Name:</label></td>
-								<td><input dojoType=dijit.form.TextBox></td>
-							</tr>
-							<tr>
-								<td><label for="pwd">Date:</label></td>
-								<td><input dojoType=dijit.form.DateTextBox></td>
-							</tr>
-							<tr>
-								<td><label for="pwd">Age:</label></td>
-								<td><input dojoType=dijit.form.NumberSpinner></td>
-							</tr>
-							<tr>
-								<td colspan="2" align="center">
-									<button dojoType=dijit.form.Button type="submit" name="submit">Login</button></td>
-							</tr>
-						</table>
-					</div
-				></div
-				><div dojoType="dijit.form.DropDownButton" iconClass="dijitEditorIcon dijitEditorIconBackColor" showLabel="true">
-					<span>ColorPalette</span>
-					<div dojoType="dijit.ColorPalette" style="display: none" palette="7x10" onChange="console.log(this.value);"></div>
-				</div
-				><div dojoType="dijit.form.ComboButton" optionsTitle='save options' iconClass="plusIcon" showLabel="true">
-					<span>Menu</span>
-					<div dojoType="dijit.Menu" style="display: none;">
-						<div dojoType="dijit.MenuItem"  iconClass="dijitEditorIcon dijitEditorIconSave">Save</div>
-						<div dojoType="dijit.MenuItem">Save As</div>
-						<div dojoType="dijit.PopupMenuItem">
-							<span>Enabled Submenu</span>
-							<div dojoType="dijit.Menu">
-								<div dojoType="dijit.MenuItem">Submenu Item One</div>
-								<div dojoType="dijit.MenuItem">Submenu Item Two</div>
-								<div dojoType="dijit.PopupMenuItem">
-									<span>Deeper Submenu</span>
-									<div dojoType="dijit.Menu">
-										<div dojoType="dijit.MenuItem">Sub-sub-menu Item One</div>
-										<div dojoType="dijit.MenuItem">Sub-sub-menu Item Two</div>
-									</div>
-								</div>
-							</div>
-						</div>
-					</div>
-				</div
-		></div>
-
-		<div dojoType="dijit.layout.TabContainer" style="width: 450px; height: 300px; margin-top: 1em;">
-			<div dojoType="dijit.layout.ContentPane" title="Href" closable="true" href="layout/doc0.html"></div>
-			<div dojoType="dijit.Tree" model="continentModel" openOnClick="true" title="Tree" closable="true"></div>
-		</div>
-
-	</div>
-
-</body>
-</html>
diff --git a/dijit/tests/editor/BackForwardState.html b/dijit/tests/editor/BackForwardState.html
index 5879497..079a30c 100644
--- a/dijit/tests/editor/BackForwardState.html
+++ b/dijit/tests/editor/BackForwardState.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Back/Forward Button Test</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -40,7 +40,7 @@
 	</ol>
 	<p><a href="BackForwardStateHelper.html" id="away">Navigate to another page</a></p>
 
-	<div dojoType="dijit.Editor" id="editor0" name="editor0" name="editor0" height="100" plugins="[]">editor0 original contents</div>
-	<div dojoType="dijit.Editor" id="editor1" name="editor1" name="editor1" height="100" plugins="[]">editor1 original contents</div>
+	<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>
 </body>
 </html>
diff --git a/dijit/tests/editor/EnterKeyHandling.html b/dijit/tests/editor/EnterKeyHandling.html
index 4049565..849c039 100644
--- a/dijit/tests/editor/EnterKeyHandling.html
+++ b/dijit/tests/editor/EnterKeyHandling.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -38,45 +38,46 @@
 	<h1>Test file for Editor EnterKeyHandling plugin</h1>
 
 	<h2>blockNodeforEnter='BR'</h2>
-	<div dojoType="dijit.Editor" id="br"
-			plugins="[{name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'BR'}, 'viewsource']"
-		><p>para 1<br>line 2</p>
+	<div id="br" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"BR"}, "viewsource"]
+		'><p>para 1<br>line 2</p>
 		<p>para 2<br>line 2</p>
  	</div>
 
  	<h2>blockNodeforEnter='DIV'</h2>
-	<div dojoType="dijit.Editor" id="div"
-			plugins="[{name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'DIV'}, 'viewsource']"
-		><p>para 1<br>line 2</p>
+	<div id="div" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]
+		'><p>para 1<br>line 2</p>
 		<p>para 2<br>line 2</p>
  	</div>
 
  	<h2>blockNodeforEnter='DIV' split test</h2>
-	<div dojoType="dijit.Editor" id="div2"
-			plugins="[{name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'DIV'}, 'viewsource']">
+	<div id="div2" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
 		<div> </div>
 		<div id="lineOne">this is a line of text.  It <b id="boldLine0">is</b> intended to be split up by pressing enter.</div>
 		<div> </div>
  	</div>
 
  	<h2>blockNodeforEnter='DIV' split test style clone</h2>
-	<div dojoType="dijit.Editor" id="div3"
-			plugins="[{name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'DIV'}, 'viewsource']">
+	<div id="div3" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
 		<div> </div>
 		<div id="lineOne">this is a line of text.  It <b id="boldLine1" style="font-size: 4em">is</b> intended to be split up by pressing enter.</div>
 		<div> </div>
  	</div>
 
+ 	<h2>blockNodeforEnter='DIV' split test font clone</h2>
+	<div id="div4" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"DIV"}, "viewsource"]'>
+		<div> </div>
+		<div id="lineOne">this is a line of text.  It <font id="fontLine1" size="5">is</font> intended to be split up by pressing enter.</div>
+		<div> </div>
+ 	</div>
+
  	<h2>blockNodeforEnter='P'</h2>
-	<div dojoType="dijit.Editor" id="p"
-			plugins="[{name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'P'}, 'viewsource']"
-		><p>para 1<br>line 2</p>
+	<div id="p" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"P"}, "viewsource"]
+		'><p>para 1<br>line 2</p>
 		<p>para 2<br>line 2</p>
  	</div>
  	
 	<h2>blockNodeforEnter='P' split test</h2>
-	<div dojoType="dijit.Editor" id="p2"
-			plugins="[{name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'P'}, 'viewsource']">
+	<div id="p2" data-dojo-type="dijit.Editor" data-dojo-props='plugins:[{name:"dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter:"P"}, "viewsource"]'>
 		<p> </p>
 		<p id="lineOne">this is a line of text.  It <b id="boldLine2">is</b> intended to be split up by pressing enter.</p>
 		<p> </p>
diff --git a/dijit/tests/editor/_Editor.html b/dijit/tests/editor/_Editor.html
deleted file mode 100644
index 3a4299f..0000000
--- a/dijit/tests/editor/_Editor.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>Editor Test</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-
-	<script type="text/javascript">
-		dojo.require("dojo.window");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.AlwaysShowToolbar");
-		dojo.require("dijit._editor.plugins.FontChoice");  // 'fontName','fontSize','formatBlock'
-		dojo.require("dijit._editor.plugins.TextColor");
-		dojo.require("dijit._editor.plugins.LinkDialog");
-		if(!window.parent.dijit.robot){
-			dojo.require("dijit.robot"); // test kludge, we just want the robot's cool scrollIntoView for the bold text test below and not the applet
-		}else{
-			doh=window.parent.doh;
-		}
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-</head>
-
-<body class="claro">
-<div>some content
-<div>more contentmargin:50px;border:50px solid red; padding:50px;
-<iframe src="test_Editor.html" id="iframe" style="width:100px; height:50px; overflow:hidden;">
-</iframe>
-<input type="button" dojoType="dijit.form.Button" onClick="var frame=dojo.byId('iframe');dojo.withGlobal(frame.contentWindow, function(){frame.contentWindow.dojo.window.scrollIntoView(frame.contentWindow.dijit.byId('editor1').toolbar.getChildren()[7].domNode);});alert('expected Bold, got: '+frame.contentWindow.dijit.byId('editor1').toolbar.getChildren()[7].titleNode.getAttribute('title'))">Scroll bold into view</input>
-<input type="button" dojoType="dijit.form.Button" onClick="var frame=dojo.byId('iframe');doh.robot.scrollIntoView(dojo.query(dojo.isIE?'strong':'b',frame.contentWindow.dijit.byId('editor1').document.body)[0]);">Scroll bold text into view</input>
-<input type="button" dojoType="dijit.form.Button" onClick="var frame=dojo.byId('iframe');dojo.withGlobal(frame.contentWindow, function(){frame.contentWindow.dojo.window.scrollIntoView(frame.contentWindow.dijit.byId('editor1').toolbar.getChildren()[8].domNode);});alert('expected Italic, got: '+frame.contentWindow.dijit.byId('editor1').toolbar.getChildren()[8].titleNode.getAttribute('title'))">Scroll italics into view</input>
-</div>
-</div>
-</body>
-</html>
diff --git a/dijit/tests/editor/module.js b/dijit/tests/editor/module.js
index 40468f7..89e8728 100755
--- a/dijit/tests/editor/module.js
+++ b/dijit/tests/editor/module.js
@@ -3,22 +3,32 @@ dojo.provide("dijit.tests.editor.module");
 try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
+	//inline doh tests
+	doh.registerUrl("dijit.tests.editor.nls_8859-2", dojo.moduleUrl("dijit","tests/editor/nls_8859-2.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.nls_sjis", dojo.moduleUrl("dijit","tests/editor/nls_sjis.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.nls_utf8", dojo.moduleUrl("dijit","tests/editor/nls_utf8.html"+userArgs), 999999);
+	
 	// Base editor functionality
-	doh.registerUrl("dijit.tests.editor.robot.Editor_mouse", dojo.moduleUrl("dijit","tests/editor/robot/Editor_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.Editor_a11y", dojo.moduleUrl("dijit","tests/editor/robot/Editor_a11y.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.Misc", dojo.moduleUrl("dijit","tests/editor/robot/Editor_misc.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.editor.robot.Editor_mouse", dojo.moduleUrl("dijit","tests/editor/robot/Editor_mouse.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.Editor_a11y", dojo.moduleUrl("dijit","tests/editor/robot/Editor_a11y.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.Misc", dojo.moduleUrl("dijit","tests/editor/robot/Editor_misc.html"+userArgs), 999999);
 
 	// Plugins
-	doh.registerUrl("dijit.tests.editor.robot.EnterKeyHandling", dojo.moduleUrl("dijit","tests/editor/robot/EnterKeyHandling.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.FullScreen", dojo.moduleUrl("dijit","tests/editor/robot/Editor_FullScreen.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.ViewSource", dojo.moduleUrl("dijit","tests/editor/robot/Editor_ViewSource.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.NewPage", dojo.moduleUrl("dijit","tests/editor/robot/Editor_NewPage.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.LinkDialog", dojo.moduleUrl("dijit","tests/editor/robot/Editor_LinkDialog.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.editor.robot.FontChoice", dojo.moduleUrl("dijit","tests/editor/robot/Editor_FontChoice.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.editor.robot.CustomPlugin", dojo.moduleUrl("dijit","tests/editor/robot/CustomPlugin.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.EnterKeyHandling", dojo.moduleUrl("dijit","tests/editor/robot/EnterKeyHandling.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.FullScreen", dojo.moduleUrl("dijit","tests/editor/robot/Editor_FullScreen.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.ViewSource", dojo.moduleUrl("dijit","tests/editor/robot/Editor_ViewSource.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.NewPage", dojo.moduleUrl("dijit","tests/editor/robot/Editor_NewPage.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.LinkDialog", dojo.moduleUrl("dijit","tests/editor/robot/Editor_LinkDialog.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.FontChoice", dojo.moduleUrl("dijit","tests/editor/robot/Editor_FontChoice.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.ToggleDir", dojo.moduleUrl("dijit","tests/editor/robot/ToggleDir.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.ToggleDir_rtl", dojo.moduleUrl("dijit","tests/editor/robot/ToggleDir_rtl.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.editor.robot.TabIndent", dojo.moduleUrl("dijit","tests/editor/robot/TabIndent.html"+userArgs), 999999);
+	
 	if(!dojo.isWebKit){
 		// The back button on webkit is URL for the browser itself, restarting the entire test suite,
 		// rather than just for the iframe holding the test file (BackForwardState.html and BackForwardStateHelper.html)
-		doh.registerUrl("dijit.tests.editor.robot.BackForwardState", dojo.moduleUrl("dijit","tests/editor/robot/BackForwardState.html"+userArgs), 99999999);
+		doh.registerUrl("dijit.tests.editor.robot.BackForwardState", dojo.moduleUrl("dijit","tests/editor/robot/BackForwardState.html"+userArgs), 999999);
 	}
 
 }catch(e){
diff --git a/dijit/tests/editor/nls_8859-2.html b/dijit/tests/editor/nls_8859-2.html
index da9996a..e4d9a4a 100644
--- a/dijit/tests/editor/nls_8859-2.html
+++ b/dijit/tests/editor/nls_8859-2.html
@@ -1,42 +1,76 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 	<title>Editor Test</title>
-	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-2">
+	<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-2"/>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
+	<script type="text/javascript" src="../_testCommon.js"></script>
+		
 	<script type="text/javascript">
+		dojo.require("doh.runner");
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");
+		
+		dojo.addOnLoad(function(){
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+
+			 doh.register("test value", [
+				{
+					name: "test value",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						
+						setTimeout(d.getTestCallback(function(){
+							var value = dijit.byId('editor').get('value');
+							doh.is("�󱶳�����ӣ�������", value );
+							
+							dijit.byId('editor').set('value', '\u65e5\u672c\u8a9e');
+							value = dijit.byId('editor').get('value');
+							doh.is("\u65e5\u672c\u8a9e", value );
+
+							dijit.byId('editor').set('value', '�󱶳�����ӣ�������');
+						}), 2000);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
 	</script>
 </head>
 <body class="claro">
 <form method="post">
 <p>
-Plain text: �󱶳�����ӣ�������
+Plain text: �󱶳�����ӣ�������
 </p>
 
 <p>
 Same text should show up in the Editor:
 </p>
-<div name="field" id="editor" dojoType="dijit.Editor">
-�󱶳�����ӣ�������
-</div>
+<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='name:"field"'>�󱶳�����ӣ�������</div>
 <input type="submit" value="Save" />
-<button type=button onclick="console.log(dijit.byId('editor').attr('value'))">getValue</button>
-<button type=button onclick="dijit.byId('editor').attr('value', '\u65e5\u672c\u8a9e')">set value to &#x65e5;&#x672c;&#x8a9e;</button>
+<button type=button onclick="console.log(dijit.byId('editor').get('value'))">getValue</button>
+<button type=button onclick="dijit.byId('editor').set('value', '\u65e5\u672c\u8a9e')">set value to &#x65e5;&#x672c;&#x8a9e;</button>
 
 </form>
 </body>
diff --git a/dijit/tests/editor/nls_sjis.html b/dijit/tests/editor/nls_sjis.html
index f0e291a..7983040 100644
--- a/dijit/tests/editor/nls_sjis.html
+++ b/dijit/tests/editor/nls_sjis.html
@@ -1,42 +1,76 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 	<title>Editor Test</title>
-	<meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS">
+	<meta http-equiv="Content-Type" content="text/html; charset=Shift-JIS"/>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
+	<script type="text/javascript" src="../_testCommon.js"></script>
+		
 	<script type="text/javascript">
+		dojo.require("doh.runner");
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");
+		
+		dojo.addOnLoad(function(){
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+
+			 doh.register("test value", [
+				{
+					name: "test value",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						
+						setTimeout(d.getTestCallback(function(){
+							var value = dijit.byId('editor').get('value');
+							doh.is("���{��", value );
+							
+							dijit.byId('editor').set('value', '����ɂ���');
+							value = dijit.byId('editor').get('value');
+							doh.is("����ɂ���", value );
+
+							dijit.byId('editor').set('value', '���{��');
+						}), 2000);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
 	</script>
 </head>
 <body class="claro">
 <form method="get">
 <p>
-Plain text: ��{��
+Plain text: ���{��
 </p>
 
 <p>
 Same text should show up in the Editor:
 </p>
-<div name="field" id="editor" dojoType="dijit.Editor">
-  ��{��
-</div>
+<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='name:"field"'>���{��</div>
 <input type="submit" value="Save" />
-<button type=button onclick="console.log(dijit.byId('editor').attr('value'))">getValue</button>
-<button type=button onclick="dijit.byId('editor').attr('value', '����ɂ���')">set value to ����ɂ���</button>
+<button type=button onclick="console.log(dijit.byId('editor').get('value'))">getValue</button>
+<button type=button onclick="dijit.byId('editor').set('value', '����ɂ���')">set value to ����ɂ���</button>
 
 </form>
 </body>
diff --git a/dijit/tests/editor/nls_utf8.html b/dijit/tests/editor/nls_utf8.html
index 1dff50f..62487c9 100644
--- a/dijit/tests/editor/nls_utf8.html
+++ b/dijit/tests/editor/nls_utf8.html
@@ -1,25 +1,60 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 	<title>Editor Test</title>
-	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
+
+	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
+		dojo.require("doh.runner");
 		dojo.require("dijit.dijit");
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");
+		
+		dojo.addOnLoad(function(){
+			 
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			 doh.register("test value", [
+				{
+					name: "test value",
+					timeout: 10000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						
+						setTimeout(d.getTestCallback(function(){
+							var value = dijit.byId('editor').get('value');
+							doh.is("日本語", value );
+							
+							dijit.byId('editor').set('value', 'こんにちは');
+							value = dijit.byId('editor').get('value');
+							doh.is("こんにちは", value );
+							
+							dijit.byId('editor').set('value', '日本語');
+						}), 2000);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
 	</script>
 </head>
 <body class="claro">
@@ -31,12 +66,10 @@ Plain text: 日本語
 <p>
 Same text should show up in the Editor:
 </p>
-<div name="field" id="editor" name="text" dojoType="dijit.Editor">
-  日本語
-</div>
+<div id="editor" data-dojo-type="dijit.Editor" data-dojo-props='name:"field"'>日本語</div>
 <input type="submit" value="Save" />
-<button type=button onclick="console.log(dijit.byId('editor').attr('value'))">getValue</button>
-<button type=button onclick="dijit.byId('editor').attr('value', 'こんにちは')">set value to こんにちは</button>
+<button type=button onclick="console.log(dijit.byId('editor').get('value'))">getValue</button>
+<button type=button onclick="dijit.byId('editor').set('value', 'こんにちは')">set value to こんにちは</button>
 
 </form>
 </body>
diff --git a/dijit/tests/editor/robot/BackForwardState.html b/dijit/tests/editor/robot/BackForwardState.html
index 67334e3..962f912 100644
--- a/dijit/tests/editor/robot/BackForwardState.html
+++ b/dijit/tests/editor/robot/BackForwardState.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
 
 			// This page tests that the editor's value won't be lost if the user
@@ -27,6 +28,15 @@
 
 				doh.register("back button restore", [
 					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){return w.onLoadDeferred;})
+						    );
+						}
+					},
+					{
 						name: "set editor value",
 						timeout: 10000,
 						runTest: function(){
@@ -69,7 +79,6 @@
 							doh.is("Back/forward test helper page", (dojo.query("h1")[0]||{}).innerHTML);
 						}
 					},
-
 					{
 						name: "go back to original page",
 						timeout: 10000,
@@ -83,6 +92,15 @@
 							});
 						}
 					},
+					{
+						name: "wait for editors to load again",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){return w.onLoadDeferred;})
+						    );
+						}
+					},
 
 					{
 						name: "check that editor values restored",
diff --git a/dijit/tests/editor/robot/CustomPlugin.html b/dijit/tests/editor/robot/CustomPlugin.html
new file mode 100644
index 0000000..6a0febc
--- /dev/null
+++ b/dijit/tests/editor/robot/CustomPlugin.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot CustomPlugin 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("dojo.DeferredList");
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_CustomPlugin.html');
+
+				doh.register("isVisible", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					function initialConditions(){
+						var pluginIcon = dojo.query(".customIcon")[0];
+						doh.t(isVisible(pluginIcon), "isVisible(pluginIcon)");
+					}
+				]);
+
+					
+				doh.register("testCustomPlugin", [
+					{
+						name: "toggleOn",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".customIcon")[0], 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)");
+									}
+								});
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleOff",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//doh.robot.keyPress(dojo.keys.ENTER, 1000, {});
+							doh.robot.mouseMoveAt(dojo.query(".customIcon")[0], 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)");
+									}
+								});
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/editor/robot/Editor_FontChoice.html b/dijit/tests/editor/robot/Editor_FontChoice.html
index ca81c5c..72c81e2 100755
--- a/dijit/tests/editor/robot/Editor_FontChoice.html
+++ b/dijit/tests/editor/robot/Editor_FontChoice.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
@@ -37,8 +38,21 @@
 					}
 					doh.f(true, "didn't find plugin " + command);
 				}
+
+				
+				doh.register("init", {
+					name: "wait for editors to load",
+					timeout: 5000,
+					runTest: function(){
+					    return new dojo.DeferredList(
+					        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+					    );
+					}
+				});
+
 				// Verify that the formatBlock, fontSize, and fontName
 				// plugins correctly display the format / font-size / font-name of the selected text.
+
 				doh.register("FontChoice: verify current format/font-size/font-name",
 					dojo.map(
 						[
@@ -69,44 +83,41 @@
 								runTest: function(){
 									var d = new doh.Deferred();
 		
-									try{
-										// Focus on the editor window
-										dojo.window.scrollIntoView(editor.domNode);
-										editor.focus();
-										doh.robot.mouseMoveAt(editor.iframe, 1000);
-										doh.robot.mouseClick({left:true}, 1000);
-		
-										doh.robot.sequence(function() {
-											// Find node w/specified id
-											var node = dojo.withGlobal(editor.window, function() { return dojo.byId(params.id); });
-											doh.is(params.id, node && node.id, "found " + params.id);
+									// Focus on the editor window
+									dojo.window.scrollIntoView(editor.domNode);
+									editor.focus();
+									doh.robot.mouseMoveAt(editor.iframe, 1000);
+									doh.robot.mouseClick({left:true}, 1000);
+	
+									doh.robot.sequence(d.getTestErrback(function() {
+										// Find node w/specified 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() {
+											dijit._editor.selection.selectElementChildren(node);
+											dijit._editor.selection.collapse(true);
+										});
+									}),1000);
+					                doh.robot.sequence(d.getTestErrback(function(){
+										// Make sure states update.
+										editor.onDisplayChanged();
+									}), 1000);
+									doh.robot.sequence(d.getTestCallback(function(){
+										if(params.format){
+											doh.is(params.format, getPlugin("formatBlock").button.get("value"), "format " + params.format + " identified.");
+										}
+										if(params.size){
+											doh.is(params.size, getPlugin("fontSize").button.get("value"), "font size " + params.size + " identified.");
+										}
+										if(params.name){
+											doh.is(params.name, getPlugin("fontName").button.get("value"), "font name" + params.name + " identified.");
+										}
+									}), 2000);
 
-											// Select the text, collapse to the start of it
-											// Using "dojo.global.dojo" to access the inner dojo, in test_FontChoice.html
-											// (not the one in this file), since that's the one that dijit is referencing.
-											dojo.global.dojo.withGlobal(editor.window, function() {
-												dijit._editor.selection.selectElementChildren(node);
-												dijit._editor.selection.collapse(true);
-											});
-										},1000);
-						                doh.robot.sequence(function(){
-											// Make sure states update.
-											editor.onDisplayChanged();
-										}, 1000);
-										doh.robot.sequence(d.getTestCallback(function(){
-											if(params.format){
-												doh.assertEqual(params.format, getPlugin("formatBlock").button.get("value"), "format " + params.format + " identified.");
-											}
-											if(params.size){
-												doh.assertEqual(params.size, getPlugin("fontSize").button.get("value"), "font size " + params.size + " identified.");
-											}
-											if(params.name){
-												doh.assertEqual(params.name, getPlugin("fontName").button.get("value"), "font name" + params.name + " identified.");
-											}
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
 									return d;
 								},
 								tearDown: function(){
@@ -139,40 +150,40 @@
 								},
 								runTest: function(){
 									var d = new doh.Deferred();
-									try{
-										// Focus on the editor window
-										dojo.window.scrollIntoView(editor.domNode);
-										editor.focus();
-										doh.robot.mouseMoveAt(editor.iframe, 1000);
-										doh.robot.mouseClick({left:true}, 1000);
-		
-										doh.robot.sequence(d.getTestErrback(function(){
-											// Find node
-											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() {
-												// Select the text, collapse to the start of it
-												dijit._editor.selection.selectElementChildren(p);
-												dijit._editor.selection.collapse(true);
-												
-												// Set the format / font-size / font-name plugin to the new value
-												// TODO: use mouse/keyboard to set the value
-												fcPlugin.button.set("value", params.to);
-											});
-										}),1000);
-						                doh.robot.sequence(function(){
-											// Make sure states update.
-											editor.onDisplayChanged();
-										}, 1000);
-										doh.robot.sequence(d.getTestCallback(function(){
-											doh.assertEqual(params.to, fcPlugin.button.get("value"), "verify converted");
-
-											// TODO: check that it actually changed the format / font-size / font-name (in the editor contents)
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
+
+									// Focus on the editor window
+									dojo.window.scrollIntoView(editor.domNode);
+									editor.focus();
+									doh.robot.mouseMoveAt(editor.iframe, 1000);
+									doh.robot.mouseClick({left:true}, 1000);
+	
+									doh.robot.sequence(d.getTestErrback(function(){
+										// Find node
+										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() {
+											// Select the text, collapse to the start of it
+											dijit._editor.selection.selectElementChildren(p);
+											// Disable collapse.  Webkit changed behavior so it now requires
+											// a selection.
+											if(!dojo.isWebKit){ dijit._editor.selection.collapse(true) };
+											
+											// Set the format / font-size / font-name plugin to the new value
+											// TODO: use mouse/keyboard to set the value
+											fcPlugin.button.set("value", params.to);
+										});
+									}),1000);
+					                doh.robot.sequence(d.getTestErrback(function(){
+										// Make sure states update.
+										editor.onDisplayChanged();
+									}), 1000);
+									doh.robot.sequence(d.getTestCallback(function(){
+										doh.is(params.to, fcPlugin.button.get("value"), "verify converted");
+
+										// TODO: check that it actually changed the format / font-size / font-name (in the editor contents)
+									}), 2000);
+
 									return d;
 								},
 								tearDown: function(){
@@ -194,74 +205,72 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 1000);
-								doh.robot.mouseClick({left:true}, 1000);
 
-								// Verify the formatBlock plugin was found
-								doh.assertTrue(fcPlugin !== null, "formatBlock was found");
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000);
+							doh.robot.mouseClick({left:true}, 1000);
 
-								doh.robot.sequence(d.getTestErrback(function(){
-									var p = dojo.withGlobal(editor.window, function() { return dojo.byId("text"); });
-									doh.is("text", p && p.id, "found text");
+							// Verify the formatBlock plugin was found
+							doh.t(fcPlugin !== null, "formatBlock was found");
 
-									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);
-
-										// Set the format / font-size / font-name plugin to the new value
-										// TODO: use mouse/keyboard to set the value
-										fcPlugin.button.set("value", "h3");
-									});
-								}),1000);
-								doh.robot.sequence(function(){
-									// Make sure states update.
-									editor.onDisplayChanged();
-								}, 1000);
-								doh.robot.sequence(function(){
-									doh.assertEqual("h3", fcPlugin.button.get("value"), "Verify first P converted to H3.");
-									// TODO: check that it actually changed the format (in the editor contents)
-								}, 2000);
-
-								// 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"); });
-									doh.is("text1", p && p.id, "found text1");
-
-									dojo.global.dojo.withGlobal(editor.window, function() {
-										// Select the text, collapse to the start of it
-										dijit._editor.selection.selectElementChildren(p);
-										dijit._editor.selection.collapse(true);
-
-										// Set the format / font-size / font-name plugin to the new value
-										// TODO: use mouse/keyboard to set the value
-										fcPlugin.button.set("value", "h3");
-									});
-								}),1000);
-								doh.robot.sequence(function(){
-									// Make sure states update.
-									editor.onDisplayChanged();
-								}, 1000);
-								doh.robot.sequence(function(){
-									// state should have updated, so, now set value.
+							doh.robot.sequence(d.getTestErrback(function(){
+								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() {
+									// Select the text, collapse to the start of it
+									dijit._editor.selection.selectElementChildren(p);
+									dijit._editor.selection.collapse(true);
+
+									// Set the format / font-size / font-name plugin to the new value
 									// TODO: use mouse/keyboard to set the value
 									fcPlugin.button.set("value", "h3");
-								},1000);
-								doh.robot.sequence(function(){
-									// Make sure states update.
-									editor.onDisplayChanged();
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.assertEqual("h3", fcPlugin.button.get("value"), "Verify second P converted to H3.");
-									// TODO: check that it actually changed the format (in the editor contents)
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+								});
+							}),1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Make sure states update.
+								editor.onDisplayChanged();
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is("h3", fcPlugin.button.get("value"), "Verify first P converted to H3.");
+								// TODO: check that it actually changed the format (in the editor contents)
+							}), 2000);
+
+							// 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"); });
+								doh.is("text1", p && p.id, "found text1");
+
+								dojo.global.dojo.withGlobal(editor.window, function() {
+									// Select the text, collapse to the start of it
+									dijit._editor.selection.selectElementChildren(p);
+									dijit._editor.selection.collapse(true);
+
+									// Set the format / font-size / font-name plugin to the new value
+									// TODO: use mouse/keyboard to set the value
+									fcPlugin.button.set("value", "h3");
+								});
+							}),1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Make sure states update.
+								editor.onDisplayChanged();
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// state should have updated, so, now set value.
+								// TODO: use mouse/keyboard to set the value
+								fcPlugin.button.set("value", "h3");
+							}),1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Make sure states update.
+								editor.onDisplayChanged();
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("h3", fcPlugin.button.get("value"), "Verify second P converted to H3.");
+								// TODO: check that it actually changed the format (in the editor contents)
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -281,45 +290,43 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 1000);
-								doh.robot.mouseClick({left:true}, 1000);
-
-								// Verify the formatBlock plugin was found
-								doh.assertTrue(fcPlugin !== null, "formatBlock was found");
-
-								doh.robot.sequence(d.getTestErrback(function(){
-									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() {
-										// Select the text, collapse to the start of it
-										dijit._editor.selection.selectElementChildren(p);
-										dijit._editor.selection.collapse(true);
-									});
-								}),1000);
-								doh.robot.sequence(function(){
-									// Make sure states update.
-									editor.onDisplayChanged();
-								}, 1000);
-								doh.robot.sequence(function(){
-									fcPlugin.button.set("value", "noFormat");
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Make sure states update.
-									// If change occurred, then the value should 
-									// still be noFormat.
-									editor.onDisplayChanged();
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-                                    doh.assertEqual("noFormat", fcPlugin.button.get("value"), 
-										"Validating current cursor point format is noFormat");
-								}), 1000);
-							 }catch(e){
-								 d.errback(e);
-							 }
+
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000);
+							doh.robot.mouseClick({left:true}, 1000);
+
+							// Verify the formatBlock plugin was found
+							doh.t(fcPlugin !== null, "formatBlock was found");
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								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() {
+									// Select the text, collapse to the start of it
+									dijit._editor.selection.selectElementChildren(p);
+									dijit._editor.selection.collapse(true);
+								});
+							}),1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Make sure states update.
+								editor.onDisplayChanged();
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								fcPlugin.button.set("value", "noFormat");
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Make sure states update.
+								// If change occurred, then the value should 
+								// still be noFormat.
+								editor.onDisplayChanged();
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+                                doh.is("noFormat", fcPlugin.button.get("value"), 
+									"Validating current cursor point format is noFormat");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -336,59 +343,57 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 1000);
-								doh.robot.mouseClick({left:true}, 1000);
-
-								// Verify the formatBlock plugin was found
-								doh.assertTrue(fcPlugin !== null, "formatBlock was found");
-
-								doh.robot.sequence(d.getTestErrback(function(){
-									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() {
-										// Select the text, collapse to the start of it
-										dijit._editor.selection.selectElementChildren(p);
-										dijit._editor.selection.collapse(true);
-									});
-								}),1000);
-								doh.robot.sequence(function(){
-									// Make sure states update.
-									editor.onDisplayChanged();
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Select the children of the block and try to flatten the formatting.
-
-									var selection = dojo.withDoc(editor.document, function() { return dojo.byId("selectionContainer"); });
-									dojo.global.dojo.withGlobal(editor.window, function() {
-										dojo.window.scrollIntoView(selection);
-										dijit._editor.selection.selectElementChildren(selection);
-									});
-									fcPlugin.button.set("value", "noFormat");
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check that the elements are all gone.
-									var selection = dojo.withDoc(editor.document, function() { return dojo.byId("selectionContainer"); });
-									doh.assertTrue(selection.childNodes.length > 0, "Checking that there are still child nodes.");
-
-									var i;
-									var nodes = selection.childNodes;
-									for(i = 0; i < nodes.length; i++){
-										var n = nodes[i];
-										if(n.nodeType == 1){
-											var tag = n.nodeName? n.nodeName.toLowerCase() : "";
-											doh.assertTrue(tag != "p");
-											doh.assertTrue(tag != "h3");
-											doh.assertTrue(tag != "pre");
-										}
+
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000);
+							doh.robot.mouseClick({left:true}, 1000);
+
+							// Verify the formatBlock plugin was found
+							doh.t(fcPlugin !== null, "formatBlock was found");
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								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() {
+									// Select the text, collapse to the start of it
+									dijit._editor.selection.selectElementChildren(p);
+									dijit._editor.selection.collapse(true);
+								});
+							}),1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Make sure states update.
+								editor.onDisplayChanged();
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Select the children of the block and try to flatten the formatting.
+
+								var selection = dojo.withDoc(editor.document, function() { return dojo.byId("selectionContainer"); });
+								dojo.global.dojo.withGlobal(editor.window, function() {
+									dojo.window.scrollIntoView(selection);
+									dijit._editor.selection.selectElementChildren(selection);
+								});
+								fcPlugin.button.set("value", "noFormat");
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check that the elements are all gone.
+								var selection = dojo.withDoc(editor.document, function() { return dojo.byId("selectionContainer"); });
+								doh.t(selection.childNodes.length > 0, "Checking that there are still child nodes.");
+
+								var i;
+								var nodes = selection.childNodes;
+								for(i = 0; i < nodes.length; i++){
+									var n = nodes[i];
+									if(n.nodeType == 1){
+										var tag = n.nodeName? n.nodeName.toLowerCase() : "";
+										doh.t(tag != "p");
+										doh.t(tag != "h3");
+										doh.t(tag != "pre");
 									}
-								}), 1000);
-							}catch(e){
-								d.errback(e);
-							}
+								}
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -418,48 +423,46 @@
 							//		This test goes through all the registered FontChoice plugins
 							//		and verifies that they're all using plain text labels in the dropdown.
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								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++){
-										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;
-													}
+
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							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++){
+									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!"));
-													}
+											}
+											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);
+										}catch(e){
+											d.errback(e);
 										}
-										store.fetch({query: {name: "*"}, onComplete: onComplete, onError: onError});
+									};
+									var onError = function(err){
+										d.errback(err);
 									}
-								}, 1000);
-							}catch(e){
-								d.errback(e);
-							}
+									store.fetch({query: {name: "*"}, onComplete: onComplete, onError: onError});
+								}
+							}, 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -486,52 +489,50 @@
 							//		This test goes through the font choice plugin registered as generic font names and validates
 							//		the font names in the values are the generic map.
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 1000);
-								doh.robot.mouseClick({left:true}, 1000);
-								doh.robot.sequence(function(){
-									var i, passed = true;
-									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."));
+
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000);
+							doh.robot.mouseClick({left:true}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var i, passed = true;
+								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;
 											}
-										}catch(e){
-											d.errback(e);
 										}
-									};
-									var onError = function(err){
-										d.errback(err);
+										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);
 									}
-									store.fetch({query: {value: "*"}, onComplete: onComplete, onError: onError});
-								}, 1000);
-							}catch(e){
-								d.errback(e);
-							}
+								};
+								var onError = function(err){
+									d.errback(err);
+								}
+								store.fetch({query: {value: "*"}, onComplete: onComplete, onError: onError});
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -558,50 +559,48 @@
 							//		This test goes through the font choice plugin registered as custom font names and validates
 							//		the font names in the values are the provided names.
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 1000);
-								doh.robot.mouseClick({left:true}, 1000);
-								doh.robot.sequence(function(){
-									var i, passed = true;
-									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."));
+
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000);
+							doh.robot.mouseClick({left:true}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var i, passed = true;
+								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;
 											}
-										}catch(e){
-											d.errback(e);
 										}
-									};
-									var onError = function(err){
-										d.errback(err);
+										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);
 									}
-									store.fetch({query: {value: "*"}, onComplete: onComplete, onError: onError});
-								}, 1000);
-							}catch(e){
-								d.errback(e);
-							}
+								};
+								var onError = function(err){
+									d.errback(err);
+								}
+								store.fetch({query: {value: "*"}, onComplete: onComplete, onError: onError});
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
diff --git a/dijit/tests/editor/robot/Editor_FullScreen.html b/dijit/tests/editor/robot/Editor_FullScreen.html
index c3cfcbd..4ead3ea 100644
--- a/dijit/tests/editor/robot/Editor_FullScreen.html
+++ b/dijit/tests/editor/robot/Editor_FullScreen.html
@@ -16,779 +16,601 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_FullScreen.html');
 
-				var editor0;
-				var fsPlugin;
+				function getPlugin(/*Editor*/ editor){
+					// summary:
+					//		Return full screen plugin for specified editor
+					var edPlugins = editor._plugins, i;
+					for(i = 0; i < edPlugins.length; i++){
+						var p = edPlugins[i], fsPlugin;
+						if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
+							p.button.set("checked", false);
+							return p;				
+						}
+					}
+					doh.t(false, "didn't find plugin");
+				}
+
+				doh.register("load", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					}
+				]);
 
-				doh.register("FullScreen_tests", [
+				doh.register("General", [
+					function setUp(){
+						editor = dijit.byId("editor0");
+						fsPlugin = getPlugin(editor);
+					},
 					{
 						name: "Keyboard: Go to Fullscreen (CTRL-SHIFT-F11)",
 						timeout: 20000,
-						setUp: function(){
-							editor0 = dijit.byId("editor0");
-							var edPlugins = editor0._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								editor0.focus();
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-								doh.robot.keyPress(dojo.keys.F11, 500, {ctrl:true,shift:true});
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									doh.assertTrue(fsPlugin.isFullscreen);
-									var vp = dojo.window.getBox();
-									var edPos = dojo.position(editor0.domNode);
-									doh.assertEqual("absolute", dojo.style(editor0.domNode, "position"));
-									doh.assertEqual("0", dojo.style(editor0.domNode, "top"), "Top position check");
-									doh.assertEqual("0", dojo.style(editor0.domNode, "left"), "Left position check");
-
-									//There may be a difference of a pixel or two, so check that the editor is real close
-									//to the viewport size.
-									doh.assertTrue(edPos.h >= vp.h && edPos.h < (vp.h + 5), "Height check");
-									doh.assertTrue(edPos.w >= vp.w && edPos.w < (vp.w + 5), "Width check");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							doh.robot.keyPress(dojo.keys.F11, 500, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(fsPlugin.isFullscreen, "isFullScreen");
+								var vp = dojo.window.getBox();
+								var edPos = dojo.position(editor.domNode);
+								doh.is("absolute", dojo.style(editor.domNode, "position"));
+								doh.is("0", dojo.style(editor.domNode, "top"), "Top position check");
+								doh.is("0", dojo.style(editor.domNode, "left"), "Left position check");
+
+								//There may be a difference of a pixel or two, so check that the editor is real close
+								//to the viewport size.
+								doh.t(edPos.h >= vp.h && edPos.h < (vp.h + 5), "Height check");
+								doh.t(edPos.w >= vp.w && edPos.w < (vp.w + 5), "Width check");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 						}
 					},
 					{
 						name: "Keyboard: Go to fullscreen and back",
 						timeout: 20000,
-						setUp: function(){
-							editor0 = dijit.byId("editor0");
-							var edPlugins = editor0._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								editor0.focus();
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-								doh.robot.keyPress(dojo.keys.F11, 500, {ctrl:true,shift:true});
-								doh.robot.keyPress(dojo.keys.F11, 1000, {ctrl:true,shift:true});
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
 
-								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									doh.assertFalse(fsPlugin.isFullscreen);
-									var edPos = dojo.position(editor0.domNode);
-									doh.assertTrue( "absolute" !== dojo.style(editor0.domNode, "position"));
+							doh.robot.keyPress(dojo.keys.F11, 500, {ctrl:true,shift:true});
+							doh.robot.keyPress(dojo.keys.F11, 1000, {ctrl:true,shift:true});
 
-									//There may be a difference of a pixel or two depending on how the browser sizes
-									//so check that the editor is real close to the expected size defined in the test doc.
-									doh.assertTrue(edPos.h >= 400 && (edPos.h < 405), "Restored height check.");
-									doh.assertTrue(edPos.w >= 800 && (edPos.w < 805), "Restored width check.");
-								}), 2000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.f(fsPlugin.isFullscreen, "isFullScreen");
+								var edPos = dojo.position(editor.domNode);
+								doh.isNot("absolute", dojo.style(editor.domNode, "position"));
 
+								//There may be a difference of a pixel or two depending on how the browser sizes
+								//so check that the editor is real close to the expected size defined in the test doc.
+								doh.t(edPos.h >= 400 && (edPos.h < 405), "Restored height check.");
+								doh.t(edPos.w >= 800 && (edPos.w < 805), "Restored width check.");
+							}), 2000);
 
-							}catch(e){
-								d.errback(e);
-							}
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 						}
 					},
 					{
 						name: "Mouse Click: Go to Fullscreen",
 						timeout: 20000,
-						setUp: function(){
-							editor0 = dijit.byId("editor0");
-							var edPlugins = editor0._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								editor0.focus();
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-								doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left: true}, 750);
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									doh.assertTrue(fsPlugin.isFullscreen);
-									var vp = dojo.window.getBox();
-									var edPos = dojo.position(editor0.domNode);
-									doh.assertEqual("absolute", dojo.style(editor0.domNode, "position"));
-									doh.assertEqual("0", dojo.style(editor0.domNode, "top"), "Top position check");
-									doh.assertEqual("0", dojo.style(editor0.domNode, "left"), "Left position check");
-
-									//There may be a difference of a pixel or two, so check that the editor is real close
-									//to the viewport size.
-									doh.assertTrue(edPos.h >= vp.h && edPos.h < (vp.h + 5), "Height check");
-									doh.assertTrue(edPos.w >= vp.w && edPos.w < (vp.w + 5), "Width check");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(fsPlugin.isFullscreen, "isFullScreen");
+								var vp = dojo.window.getBox();
+								var edPos = dojo.position(editor.domNode);
+								doh.is("absolute", dojo.style(editor.domNode, "position"));
+								doh.is("0", dojo.style(editor.domNode, "top"), "Top position check");
+								doh.is("0", dojo.style(editor.domNode, "left"), "Left position check");
+
+								//There may be a difference of a pixel or two, so check that the editor is real close
+								//to the viewport size.
+								doh.t(edPos.h >= vp.h && edPos.h < (vp.h + 5), "Height check");
+								doh.t(edPos.w >= vp.w && edPos.w < (vp.w + 5), "Width check");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 						}
 					},
 					{
 						name: "Mouse Click: Go to fullscreen and back",
 						timeout: 20000,
-						setUp: function(){
-							editor0 = dijit.byId("editor0");
-							var edPlugins = editor0._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								editor0.focus();
-								doh.assertTrue(fsPlugin != null);
-								//Click it, then click it again!
-								doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left: true}, 750);
-								doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left: true}, 750);
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									doh.assertFalse(fsPlugin.isFullscreen);
-									var edPos = dojo.position(editor0.domNode);
-									doh.assertTrue( "absolute" !== dojo.style(editor0.domNode, "position"));
-
-									//There may be a difference of a pixel or two depending on how the browser sizes
-									//so check that the editor is real close to the expected size defined in the test doc.
-									doh.assertTrue(edPos.h >= 400 && (edPos.h < 405), "Restored height check.");
-									doh.assertTrue(edPos.w >= 800 && (edPos.w < 805), "Restored width check.");
-								}), 2000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+							doh.t(fsPlugin != null);
+							//Click it, then click it again!
+							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.f(fsPlugin.isFullscreen, "isFullScreen");
+								var edPos = dojo.position(editor.domNode);
+								doh.isNot("absolute", dojo.style(editor.domNode, "position"));
+
+								//There may be a difference of a pixel or two depending on how the browser sizes
+								//so check that the editor is real close to the expected size defined in the test doc.
+								doh.t(edPos.h >= 400 && (edPos.h < 405), "Restored height check.");
+								doh.t(edPos.w >= 800 && (edPos.w < 805), "Restored width check.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 						}
+					}
+				]);
+
+				doh.register("BorderContainer", [
+					function setUp(){
+						editor = dijit.byId("editor1");
+						fsPlugin = getPlugin(editor);
+						container = dijit.byId("bc");
 					},
+
 					{
 						name: "BorderContainer:  Go Fullscreen, Reduce BorderContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor1");
-							container = dijit.byId("bc");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 400, h: 400});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = origContainerSize.w - curContainerSize.w;
-									var containerHdiff = origContainerSize.h - curContainerSize.h;
-									var eWdiff= origEditorSize.w - curEditorSize.w;
-									var eHdiff= origEditorSize.h - curEditorSize.h;
-									
-									doh.assertTrue(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 400, h: 400});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = origContainerSize.w - curContainerSize.w;
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
 					},
 					{
 						name: "BorderContainer:  Go Fullscreen, Increase BorderContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor1");
-							container = dijit.byId("bc");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 800, h: 800});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = -(origContainerSize.w - curContainerSize.w);
-									var containerHdiff = -(origContainerSize.h - curContainerSize.h);
-									var eWdiff= -(origEditorSize.w - curEditorSize.w);
-									var eHdiff= -(origEditorSize.h - curEditorSize.h);
-									
-									doh.assertTrue(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 800, h: 800});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = -(origContainerSize.w - curContainerSize.w);
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
+					}
+				]);
+
+				doh.register("TabContainer", [
+					function setUp(){
+						editor = dijit.byId("editor2");
+						fsPlugin = getPlugin(editor);
+						container = dijit.byId("tc");
 					},
+
 					{
 						name: "TabContainer:  Go Fullscreen, Reduce TabContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor2");
-							container = dijit.byId("tc");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 400, h: 400});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = origContainerSize.w - curContainerSize.w;
-									var containerHdiff = origContainerSize.h - curContainerSize.h;
-									var eWdiff= origEditorSize.w - curEditorSize.w;
-									var eHdiff= origEditorSize.h - curEditorSize.h;
-									
-									doh.assertTrue(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 400, h: 400});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = origContainerSize.w - curContainerSize.w;
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
 					},
 					{
 						name: "TabContainer:  Go Fullscreen, Increase TabContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor2");
-							container = dijit.byId("tc");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 800, h: 800});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = -(origContainerSize.w - curContainerSize.w);
-									var containerHdiff = -(origContainerSize.h - curContainerSize.h);
-									var eWdiff= -(origEditorSize.w - curEditorSize.w);
-									var eHdiff= -(origEditorSize.h - curEditorSize.h);
-									
-									doh.assertTrue(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 800, h: 800});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = -(origContainerSize.w - curContainerSize.w);
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
+					}
+				]);
+
+				doh.register("AccordionContainer", [
+					function setUp(){
+						editor = dijit.byId("editor3");
+						fsPlugin = getPlugin(editor);
+						container = dijit.byId("ac");
 					},
+
 					{
 						name: "AccordionContainer:  Go Fullscreen, Reduce AccordionContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor3");
-							container = dijit.byId("ac");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 400, h: 400});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = origContainerSize.w - curContainerSize.w;
-									var containerHdiff = origContainerSize.h - curContainerSize.h;
-									var eWdiff= origEditorSize.w - curEditorSize.w;
-									var eHdiff= origEditorSize.h - curEditorSize.h;
-									
-									doh.assertTrue(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 400, h: 400});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = origContainerSize.w - curContainerSize.w;
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
 					},
 					{
 						name: "AccordionContainer:  Go Fullscreen, Increase AccordionContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor3");
-							container = dijit.byId("ac");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 800, h: 800});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = -(origContainerSize.w - curContainerSize.w);
-									var containerHdiff = -(origContainerSize.h - curContainerSize.h);
-									var eWdiff= -(origEditorSize.w - curEditorSize.w);
-									var eHdiff= -(origEditorSize.h - curEditorSize.h);
-									
-									doh.assertTrue(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 800, h: 800});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = -(origContainerSize.w - curContainerSize.w);
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
+					}
+				]);
+
+				doh.register("StackContainer", [
+					function setUp(){
+						editor = dijit.byId("editor4");
+						fsPlugin = getPlugin(editor);
+						container = dijit.byId("sc");
 					},
+
 					{
 						name: "StackContainer:  Go Fullscreen, Reduce StackContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor4");
-							container = dijit.byId("sc");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 400, h: 400});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = origContainerSize.w - curContainerSize.w;
-									var containerHdiff = origContainerSize.h - curContainerSize.h;
-									var eWdiff= origEditorSize.w - curEditorSize.w;
-									var eHdiff= origEditorSize.h - curEditorSize.h;
-									
-									doh.assertTrue(origEditorSize.w > curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h > curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 400, h: 400});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = origContainerSize.w - curContainerSize.w;
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
 					},
 					{
 						name: "StackContainer:  Go Fullscreen, Increase StackContainer, Exit FullScreen, Validate Resize",
 						timeout: 20000,
-						setUp: function(){
-							editor = dijit.byId("editor4");
-							container = dijit.byId("sc");
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.FullScreen"){
-									fsPlugin = p;
-									break;
-								}
-							}
-							if(fsPlugin) {fsPlugin.button.set("checked", false);}
-						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-
-								var origEditorSize = dojo.marginBox(editor.domNode);
-								var origContainerSize = dojo.marginBox(container.domNode);
-								os = {w: origContainerSize.w, h: origContainerSize.h}
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(fsPlugin != null);
-
-								doh.robot.sequence(function(){
-									// Engage FullScreen Mode
-									fsPlugin.button.set("checked", true);
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Resize the container
-									container.resize({w: 800, h: 800});
-								}, 1000);
-								doh.robot.sequence(function(){
-									// Disengage FullScreen Mode
-									fsPlugin.button.set("checked", false);
-								}, 1000);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now validate the editor resized when it returned since
-									// the Container was resized.
-									var curEditorSize = dojo.marginBox(editor.domNode);
-									var curContainerSize = dojo.marginBox(container.domNode);
-									var containerWdiff = -(origContainerSize.w - curContainerSize.w);
-									var containerHdiff = -(origContainerSize.h - curContainerSize.h);
-									var eWdiff= -(origEditorSize.w - curEditorSize.w);
-									var eHdiff= -(origEditorSize.h - curEditorSize.h);
-									
-									doh.assertTrue(origEditorSize.w < curEditorSize.w, "Validating new width is less that the original size");
-									doh.assertTrue(origEditorSize.h < curEditorSize.h, "Validating new height is less that the original size");
-									doh.assertTrue((eWdiff < (containerWdiff + 5)) && (eWdiff > (containerWdiff - 5)), "Doing a rouch check that the editor width resized roughly to the Container difference");
-									doh.assertTrue((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
-								}), 1000);
-
-
-							}catch(e){
-								d.errback(e);
-							}
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							var origEditorSize = dojo.marginBox(editor.domNode);
+							var origContainerSize = dojo.marginBox(container.domNode);
+							os = {w: origContainerSize.w, h: origContainerSize.h}
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Engage FullScreen Mode
+								fsPlugin.button.set("checked", true);
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Resize the container
+								container.resize({w: 800, h: 800});
+							}), 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Disengage FullScreen Mode
+								fsPlugin.button.set("checked", false);
+							}), 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now validate the editor resized when it returned since
+								// the Container was resized.
+								var curEditorSize = dojo.marginBox(editor.domNode);
+								var curContainerSize = dojo.marginBox(container.domNode);
+								var containerWdiff = -(origContainerSize.w - curContainerSize.w);
+								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");
+								doh.t((eHdiff < (containerHdiff + 5)) && (eHdiff > (containerHdiff - 5)), "Doing a rouch check that the editor height resized roughly to the Container difference");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							 if(fsPlugin) {fsPlugin.button.set("checked", false);}
+							 fsPlugin.button.set("checked", false);
 							 if(container && os){container.resize(os);}
 						}
 					}
diff --git a/dijit/tests/editor/robot/Editor_LinkDialog.html b/dijit/tests/editor/robot/Editor_LinkDialog.html
index 9a91ca7..c23fe20 100644
--- a/dijit/tests/editor/robot/Editor_LinkDialog.html
+++ b/dijit/tests/editor/robot/Editor_LinkDialog.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
@@ -27,59 +28,70 @@
 				var value;
 				var node;
 
+				doh.register("Setup", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+							// TODO: test if this is working
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					}
+				]);
+
 				doh.register("LinkDialog_tests", [
+					function setUp(){
+						editor = dijit.byId("editor");
+						ldPlugin = null;
+						var edPlugins = editor._plugins, i;
+						for(i = 0; i < edPlugins.length; i++){
+							var p = edPlugins[i];
+							if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
+								ldPlugin = p;
+								break;
+							}
+						}
+						doh.t(ldPlugin != null, "found link dialog.");
+					},
+
 					{
 						name: "Anchor Tag: Create a new link",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								var url, desc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									url.set("value", "http://example.com/");
-									desc.set("value", "This is my example link.");
-								},2000);
-								doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertTrue(new RegExp("href=(\"|\')http://example.com/(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertFalse(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("target=(\"|\')_self(\"|\')").test(newVal), "Verifying target has been inserted.");
-									doh.assertTrue(new RegExp(">This is my example link.<").test(newVal), "Verifying description has been inserted.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							var url, desc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url.set("value", "http://example.com/");
+								desc.set("value", "This is my example link.");
+							}),2000);
+
+							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.t(new RegExp("href=(\"|\')http://example.com/(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.), newVal =" + newVal);
+								doh.t(new RegExp("target=(\"|\')_self(\"|\')").test(newVal), "Verifying target has been inserted.");
+								doh.t(new RegExp(">This is my example link.<").test(newVal), "Verifying description has been inserted.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -90,57 +102,40 @@
 						name: "Anchor Tag: Create a new link with alternate target",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, target, desc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "http://example.com/");
-									desc.set("value", "This is my example link.");
-									target.set("value", "_blank");
-								},2000);
-								doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("href=(\"|\')http://example.com/(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertTrue(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
-									doh.assertTrue(new RegExp(">This is my example link.<").test(newVal), "Verifying description has been inserted.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, target, desc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "http://example.com/");
+								desc.set("value", "This is my example link.");
+								target.set("value", "_blank");
+							}),2000);
+							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("href=(\"|\')http://example.com/(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.t(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
+								doh.t(new RegExp(">This is my example link.<").test(newVal), "Verifying description has been inserted.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -151,57 +146,40 @@
 						name: "Anchor Tag: Test auto insertion of http:// for urls.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc, target;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "example.com/");
-									desc.set("value", "This is my example link.");
-									target.set("value", "_blank");
-								},2000);
-								doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("href=(\"|\')http://example.com/(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertTrue(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
-									doh.assertTrue(new RegExp(">This is my example link.<").test(newVal), "Verifying description has been inserted.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "example.com/");
+								desc.set("value", "This is my example link.");
+								target.set("value", "_blank");
+							}),2000);
+							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("href=(\"|\')http://example.com/(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.t(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
+								doh.t(new RegExp(">This is my example link.<").test(newVal), "Verifying description has been inserted.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -212,57 +190,40 @@
 						name: "Anchor Tag: Test insertion 'relative' urls.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc, target;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "./myDirectory/myfile.html");
-									desc.set("value", "This is my example relative link.");
-									target.set("value", "_blank");
-								},2000);
-								doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("href=(\"|\')./myDirectory/myfile.html(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertTrue(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
-									doh.assertTrue(new RegExp(">This is my example relative link.<").test(newVal), "Verifying description has been inserted.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "./myDirectory/myfile.html");
+								desc.set("value", "This is my example relative link.");
+								target.set("value", "_blank");
+							}),2000);
+							doh.robot.mouseMoveAt(function(){return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode;}, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("href=(\"|\')./myDirectory/myfile.html(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.t(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
+								doh.t(new RegExp(">This is my example relative link.<").test(newVal), "Verifying description has been inserted.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -273,16 +234,6 @@
 						name: "Anchor Tag: Update existing anchor tag",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleLink");
 							});
@@ -290,53 +241,46 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.sequence(function(){
-									// Okay, select the text of the hyperlink so we can then perform an edit on it.
-									editor._sCall("selectElement", [node]);
-								},500);
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								var url, desc, target, oldUrl, oldDesc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-
-									oldUrl = url.get("value");
-									oldDesc = desc.get("value");
-
-									url.set("value", oldUrl + "_2");
-									desc.set("value", oldDesc + "_2");
-									target.set("value", "_blank");
-								}, 2000);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertTrue(new RegExp("href=(\"|\')"+ oldUrl + "_2" + "(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertFalse(new RegExp("href=(\"|\')"+ oldUrl + "(\"|\')").test(newVal), "Verifying old URL is gone.");
-									doh.assertFalse(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
-									doh.assertFalse(new RegExp("target=(\"|\')_self(\"|\')").test(newVal), "Verifying old target is removed.");
-									doh.assertTrue(new RegExp(">" + oldDesc + "_2<").test(newVal), "Verifying description has been inserted.");
-									doh.assertFalse(new RegExp(">" + oldDesc + "<").test(newVal), "Verifying old desc is gone.");
-								}), 2000);
-							}catch(e){
-									d.errback(e);
-							}
+
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Okay, select the text of the hyperlink so we can then perform an edit on it.
+								editor._sCall("selectElement", [node]);
+							}),500);
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							var url, desc, target, oldUrl, oldDesc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+
+								oldUrl = url.get("value");
+								oldDesc = desc.get("value");
+
+								url.set("value", oldUrl + "_2");
+								desc.set("value", oldDesc + "_2");
+								target.set("value", "_blank");
+							}), 2000);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.t(new RegExp("href=(\"|\')"+ oldUrl + "_2" + "(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.f(new RegExp("href=(\"|\')"+ oldUrl + "(\"|\')").test(newVal), "Verifying old URL is gone.");
+								doh.f(new RegExp("<li><a").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("target=(\"|\')_blank(\"|\')").test(newVal), "Verifying target has been inserted.");
+								doh.f(new RegExp("target=(\"|\')_self(\"|\')").test(newVal), "Verifying old target is removed.");
+								doh.t(new RegExp(">" + oldDesc + "_2<").test(newVal), "Verifying description has been inserted.");
+								doh.f(new RegExp(">" + oldDesc + "<").test(newVal), "Verifying old desc is gone.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -347,16 +291,6 @@
 						name: "Anchor Tag: Blank description invalid.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleLink");
 							});
@@ -364,47 +298,40 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.sequence(function(){
-									// Okay, select the text of the hyperlink so we can then perform an edit on it.
-									editor._sCall("selectElement", [node]);
-								},500);
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								var url, desc, target, oldDesc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									oldDesc = desc.get("value");
-									desc.set("value", "");
-									target.set("value", "_blank");
-								}, 2000);
-								doh.robot.sequence(function(){
-									// Verify setting the content is disabled.
-									var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
-									doh.assertTrue(setButton.get("disabled"));
-								}, 500);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal === value, "Verify the contents have not changed.");
-								}), 2000);
-							}catch(e){
-									d.errback(e);
-							}
+
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Okay, select the text of the hyperlink so we can then perform an edit on it.
+								editor._sCall("selectElement", [node]);
+							}),500);
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							var url, desc, target, oldDesc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								oldDesc = desc.get("value");
+								desc.set("value", "");
+								target.set("value", "_blank");
+							}), 2000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Verify setting the content is disabled.
+								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								doh.t(setButton.get("disabled"));
+							}), 500);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.t(newVal === value, "Verify the contents have not changed.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -415,60 +342,43 @@
 						name: "Anchor Tag: Test invalid url.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc, target;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "http://this is not/valid/bad.html");
-									desc.set("value", "This is my example relative link.");
-									target.set("value", "_blank");
-									url.validate();
-								},2000);
-								doh.robot.sequence(function(){
-									var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
-									doh.assertTrue(setButton.get("disabled"));
-								}, 500);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.mouseMoveAt(editor.iframe, 500, null, 0, 0);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal === value, "Verify the contents have not changed.");
-									doh.assertFalse(url.isValid());
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "http://this is not/valid/bad.html");
+								desc.set("value", "This is my example relative link.");
+								target.set("value", "_blank");
+								url.validate();
+							}),2000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								doh.t(setButton.get("disabled"), "set button disabled");
+							}), 500);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.is(value, newVal, "Verify the contents have not changed.");
+								doh.f(url.isValid(), "url.isValid");
+							}), 2000);
 							return d;
 						},
 						tearDown: function(){
@@ -479,59 +389,43 @@
 						name: "Anchor Tag: Test mailto url.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc, target;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "mailto:johndoe at example.com");
-									desc.set("value", "Send a message to John.");
-									target.set("value", "_blank");
-									url.isValid();
-								},2000);
-								doh.robot.sequence(function(){
-									var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
-									doh.assertTrue(!setButton.get("disabled"));
-								}, 500);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.mouseMoveAt(editor.iframe, 500, null, 0, 0);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue((newVal.indexOf("mailto:johndoe at example.com") > -1), "Verify the contents have the mailto url present.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "mailto:johndoe at example.com");
+								desc.set("value", "Send a message to John.");
+								target.set("value", "_blank");
+								url.isValid();
+							}),2000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								doh.t(!setButton.get("disabled"));
+							}), 500);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.t((newVal.indexOf("mailto:johndoe at example.com") > -1), "Verify the contents have the mailto url present, newVal=" + newVal);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -542,59 +436,43 @@
 						name: "Anchor Tag: Test mailto url prepend.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc, target;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "johndoe at example.com");
-									desc.set("value", "Send a message to John.");
-									target.set("value", "_blank");
-									url.isValid();
-								},2000);
-								doh.robot.sequence(function(){
-									var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
-									doh.assertTrue(!setButton.get("disabled"));
-								}, 500);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.mouseMoveAt(editor.iframe, 500, null, 0, 0);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue((newVal.indexOf("mailto:johndoe at example.com") > -1), "Verify the contents have the mailto url present.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "johndoe at example.com");
+								desc.set("value", "Send a message to John.");
+								target.set("value", "_blank");
+								url.isValid();
+							}),2000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								doh.t(!setButton.get("disabled"));
+							}), 500);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.t((newVal.indexOf("mailto:johndoe at example.com") > -1), "Verify the contents have the mailto url present, newVal=" + newVal);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -605,59 +483,43 @@
 						name: "Anchor Tag: Test invalid mailto url.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc, target;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
-									url.set("value", "mailto:john doe at example.com");
-									desc.set("value", "Send a message to John.");
-									target.set("value", "_blank");
-									url.isValid();
-								},2000);
-								doh.robot.sequence(function(){
-									var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
-									doh.assertTrue(setButton.get("disabled"));
-								}, 500);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.mouseMoveAt(editor.iframe, 500, null, 0, 0);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal === value, "Verify the contents have not changed.");
-									doh.assertFalse(url.isValid());
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc, target;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								target = dijit.byId(ldPlugin._uniqueId + "_targetSelect");
+								url.set("value", "mailto:john doe at example.com");
+								desc.set("value", "Send a message to John.");
+								target.set("value", "_blank");
+								url.isValid();
+							}),2000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								doh.t(setButton.get("disabled"));
+							}), 500);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_cancelButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt(editor.iframe, 500, 0, 0, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								var newVal = editor.get("value");
+								doh.t(newVal === value, "Verify the contents have not changed.");
+								doh.f(url.isValid());
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -668,16 +530,6 @@
 						name: "Anchor Tag: Double-Click opens TooltipDialog.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.LinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleLink");
 							});
@@ -685,108 +537,99 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.sequence(d.getTestErrback(function(){
-									doh.assertTrue(ldPlugin && ldPlugin.dropDown && ldPlugin.dropDown.domNode, "found TooltipDialog");
-									doh.assertTrue(isHidden(ldPlugin.dropDown.domNode),  "tooltip dialog is hidden");
-								}));
-
-								// Double click
-								doh.robot.mouseMoveAt(node, 500);
-								doh.robot.mouseClick({left:true}, 100);
-								doh.robot.mouseClick({left:true}, 100);
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.assertTrue(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.assertTrue(new RegExp("http://www.example.com/example.html").test(val), "Verifying the contents contained link url");
-										}else{
-											doh.assertTrue(false, "Failed to enclosing textbox widget.");
-										}
+
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.t(ldPlugin && ldPlugin.dropDown && ldPlugin.dropDown.domNode, "found TooltipDialog");
+								doh.t(isHidden(ldPlugin.dropDown.domNode),  "tooltip dialog is hidden");
+							}));
+
+							// Double click
+							doh.robot.mouseMoveAt(node, 500, 1);
+							doh.robot.mouseClick({left:true}, 100);
+							doh.robot.mouseClick({left:true}, 100);
+
+							doh.robot.sequence(d.getTestCallback(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.assertTrue(false, "Failed to get focus.");	
+										doh.t(false, "Failed to enclosing textbox widget.");
 									}
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+								}else{
+									doh.t(false, "Failed to get focus.");	
+								}
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
+							ldPlugin.dropDown.onCancel();
 							if(editor){editor.set("value", value);}
 						}
 					}
 				]);
 
 				doh.register("ImgDialog_tests", [
+					function setUp(){
+						editor = dijit.byId("editor");
+						ldPlugin = null;
+						var edPlugins = editor._plugins, i;
+						for(i = 0; i < edPlugins.length; i++){
+							var p = edPlugins[i];
+							if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
+								ldPlugin = p;
+								break;
+							}
+						}
+						doh.t(ldPlugin != null, "found image dialog.");
+						value = editor.get("value");
+					},
+
 					{
 						name: "Image Tag: Create a new image",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the image dialog.");
-								var value = editor.get("value");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									url.set("value", "./sample2.jpg");
-									desc.set("value", "This is my example image 2.");
-								},2000);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("src=(\"|\').*/sample2.jpg(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertTrue(new RegExp("alt=(\"|\')This is my example image 2.(\"|\')").test(newVal), "Verifying alt description has been inserted.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url.set("value", "./sample2.jpg");
+								desc.set("value", "This is my example image 2.");
+							}),2000);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.): " + newVal);
+								doh.t(new RegExp("src=(\"|\').*/sample2.jpg(\"|\')").test(newVal), "Verifying URL has been inserted: " + newVal);
+								doh.t(new RegExp("alt=(\"|\')This is my example image 2.(\"|\')").test(newVal), "Verifying alt description has been inserted: " + newVal);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -797,54 +640,37 @@
 						name: "Image Tag: Verify http:// is prepended",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							value = editor.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the image dialog.");
-								var value = editor.get("value");
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								var url, desc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									url.set("value", "example.com/example.jpg");
-									desc.set("value", "This is my example image.");
-								},2000);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("src=(\"|\')http://example.com/example.jpg(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertTrue(new RegExp("alt=(\"|\')This is my example image.(\"|\')").test(newVal), "Verifying alt description has been inserted.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var url, desc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								url.set("value", "example.com/example.jpg");
+								desc.set("value", "This is my example image.");
+							}),2000);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("src=(\"|\')http://example.com/example.jpg(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.t(new RegExp("alt=(\"|\')This is my example image.(\"|\')").test(newVal), "Verifying alt description has been inserted.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -855,16 +681,6 @@
 						name: "Image Tag: Update existing image tag",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleImage");
 							});
@@ -873,43 +689,35 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.sequence(function(){editor._sCall("selectElement", [node]);}, 500);
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								var url, desc, oldDesc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									oldDesc = desc.get("value");
-									url.set("value", "./sample2.jpg");
-									desc.set("value", oldDesc + "_2");
-								}, 2000);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("src=(\"|\')"+ ".*/sample2.jpg" + "(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertFalse(new RegExp("src=(\"|\')"+ ".*/sample.jpg" + "(\"|\')").test(newVal), "Verifying old URL is gone.");
-									doh.assertTrue(new RegExp("alt=(\"|\")" + oldDesc + "_2" + "(\"|\')").test(newVal), "Verifying description has been inserted.");
-									doh.assertFalse(new RegExp("alt=(\"|\")" + oldDesc + "(\"|\')").test(newVal), "Verifying old desc is gone.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestErrback(function(){editor._sCall("selectElement", [node]);}), 500);
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							var url, desc, oldDesc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								oldDesc = desc.get("value");
+								url.set("value", "./sample2.jpg");
+								desc.set("value", oldDesc + "_2");
+							}), 2000);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
+								doh.t(new RegExp("src=(\"|\')"+ ".*/sample2.jpg" + "(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.f(new RegExp("src=(\"|\')"+ ".*/sample.jpg" + "(\"|\')").test(newVal), "Verifying old URL is gone.");
+								doh.t(new RegExp("alt=(\"|\")" + oldDesc + "_2" + "(\"|\')").test(newVal), "Verifying description has been inserted.");
+								doh.f(new RegExp("alt=(\"|\")" + oldDesc + "(\"|\')").test(newVal), "Verifying old desc is gone.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -920,16 +728,6 @@
 						name: "Image Tag: Blank description valid.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleImage");
 							});
@@ -938,48 +736,40 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.sequence(function(){editor._sCall("selectElement", [node]);}, 500);
-								doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								var url, desc, oldDesc;
-								doh.robot.sequence(function(){
-									url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
-									desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
-									oldDesc = desc.get("value");
-									url.set("value", "./sample2.jpg");
-									desc.set("value", "");
-								}, 2000);
-								doh.robot.sequence(function(){
-									// Verify setting the content is disabled.
-									var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
-									doh.assertFalse(setButton.get("disabled"));
-								}, 500);
-								doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									// Now check the state!
-									var newVal = editor.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									doh.assertFalse(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.)");
-									doh.assertTrue(new RegExp("src=(\"|\')"+ ".*/sample2.jpg" + "(\"|\')").test(newVal), "Verifying URL has been inserted.");
-									doh.assertFalse(new RegExp("src=(\"|\')"+ ".*/sample.jpg" + "(\"|\')").test(newVal), "Verifying old URL is gone.");
-									doh.assertTrue(new RegExp("alt=(\"|\")(\"|\')").test(newVal), "Verifying description has been cleared.");
-									doh.assertFalse(new RegExp("alt=(\"|\")" + oldDesc + "(\"|\')").test(newVal), "Verifying old desc is gone.");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestErrback(function(){editor._sCall("selectElement", [node]);}), 500);
+							doh.robot.mouseMoveAt(ldPlugin.button.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							var url, desc, oldDesc;
+							doh.robot.sequence(d.getTestErrback(function(){
+								url = dijit.byId(ldPlugin._uniqueId + "_urlInput");
+								desc = dijit.byId(ldPlugin._uniqueId + "_textInput");
+								oldDesc = desc.get("value");
+								url.set("value", "./sample2.jpg");
+								desc.set("value", "");
+							}), 2000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								// Verify setting the content is disabled.
+								var setButton = dijit.byId(ldPlugin._uniqueId + "_setButton");
+								doh.f(setButton.get("disabled"));
+							}), 500);
+							doh.robot.mouseMoveAt(function(){ return dijit.byId(ldPlugin._uniqueId + "_setButton").domNode; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								doh.f(new RegExp("<li><img").test(newVal), "Verifying insert did not occur in the top li (IE test for selection restore.), newVal=" + newVal);
+								doh.t(new RegExp("src=(\"|\')"+ ".*/sample2.jpg" + "(\"|\')").test(newVal), "Verifying URL has been inserted.");
+								doh.f(new RegExp("src=(\"|\')"+ ".*/sample.jpg" + "(\"|\')").test(newVal), "Verifying old URL is gone.");
+								doh.t(new RegExp("alt=(\"|\")(\"|\')").test(newVal), "Verifying description has been cleared.");
+								doh.f(new RegExp("alt=(\"|\")" + oldDesc + "(\"|\')").test(newVal), "Verifying old desc is gone.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -990,16 +780,6 @@
 						name: "Image Tag: Single click selects image.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleImage");
 							});
@@ -1008,29 +788,21 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.mouseMoveAt(node, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									var selectedElement = editor._sCall("getSelectedElement", [null]);
-									doh.assertTrue(selectedElement != null);
-									var tag = selectedElement.tagName? selectedElement.tagName.toLowerCase() : "";
-									doh.assertTrue(tag === "img");
-									doh.assertTrue(selectedElement.getAttribute("id") === "exampleImage");
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.mouseMoveAt(node, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								var selectedElement = editor._sCall("getSelectedElement", [null]);
+								doh.t(selectedElement != null);
+								var tag = selectedElement.tagName? selectedElement.tagName.toLowerCase() : "";
+								doh.t(tag === "img");
+								doh.t(selectedElement.getAttribute("id") === "exampleImage");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -1041,16 +813,6 @@
 						name: "Image Tag: Double-Click opens TooltipDialog.",
 						timeout: 20000,
 						setUp: function(){
-							editor = dijit.byId("editor");
-							ldPlugin = null;
-							var edPlugins = editor._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.ImgLinkDialog"){
-									ldPlugin = p;
-									break;
-								}
-							}
 							dojo.withGlobal(editor.window, function(){
 								node = dojo.byId("exampleImage");
 							});
@@ -1058,54 +820,44 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								// Focus on the editor window
-								dojo.window.scrollIntoView(editor.domNode);
-								editor.focus();
-								doh.robot.mouseMoveAt(editor.iframe, 500);
-								doh.robot.mouseClick({left:true}, 500);
-								
-
-								// Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(ldPlugin !== null, "Verifying the link dialog.");
-								var value = editor.get("value");
-
-								doh.robot.sequence(d.getTestErrback(function(){
-									doh.assertTrue(ldPlugin && ldPlugin.dropDown && ldPlugin.dropDown.domNode, "found TooltipDialog");
-									doh.assertTrue(isHidden(ldPlugin.dropDown.domNode),  "tooltip dialog is hidden");
-								}));
-
-								// Double click
-								doh.robot.mouseMoveAt(node, 500);
-								doh.robot.mouseClick({left:true}, 100);
-								doh.robot.mouseClick({left:true}, 100);
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.assertTrue(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.assertTrue(new RegExp(".*/sample.jpg").test(val), "Verifying the contents contained image name");
-										}else{
-											doh.assertTrue(false, "Failed to enclosing textbox widget.");
-										}
-									}else{
-										doh.assertTrue(false, "Failed to get focus.");	
-									}
-								}), 2000);
-							}catch(e){
-								d.errback(e);
-							}
+
+							// Focus on the editor window
+							editor.focus();
+							doh.robot.mouseMoveAt(editor.iframe, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.t(ldPlugin && ldPlugin.dropDown && ldPlugin.dropDown.domNode, "found TooltipDialog");
+								doh.t(isHidden(ldPlugin.dropDown.domNode),  "tooltip dialog is hidden");
+							}));
+
+							// Double click
+							doh.robot.mouseMoveAt(node, 500, 1);
+							doh.robot.mouseClick({left:true}, 100);
+							doh.robot.mouseClick({left:true}, 100);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(ldPlugin.dropDown.domNode),  "tooltip dialog is visible");
+
+								var f = dijit.getFocus();
+								doh.t(f.node, "got focus");
+
+								var w = dijit.getEnclosingWidget(f.node);
+								doh.t(w, "found enclosing widget");
+
+								var val = w.get("value");
+								doh.t(new RegExp(".*/sample.jpg").test(val), "Verifying the contents contained image name");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
+							ldPlugin.dropDown.onCancel();
 							if(editor){editor.set("value", value);}
 						}
 					}
 				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/editor/robot/Editor_NewPage.html b/dijit/tests/editor/robot/Editor_NewPage.html
index 569f65b..33e2c68 100755
--- a/dijit/tests/editor/robot/Editor_NewPage.html
+++ b/dijit/tests/editor/robot/Editor_NewPage.html
@@ -16,108 +16,104 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_NewPage.html');
 
-				var editor0;
-				var npPlugin;
-				var value;
+				function getPlugin(/*Editor*/ editor){
+					// summary:
+					//		Return new page plugin for specified editor
+					var edPlugins = editor._plugins, i;
+					for(i = 0; i < edPlugins.length; i++){
+						var p = edPlugins[i], fsPlugin;
+						if(p.declaredClass === "dijit._editor.plugins.NewPage"){
+							p.button.set("checked", false);
+							return p;				
+						}
+					}
+					doh.t(false, "didn't find plugin");
+				}
 
 				doh.register("NewPage_tests", [
 					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
 						name: "Mouse: Click new page clears editor",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor0");
-							var edPlugins = editor0._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.NewPage"){
-									npPlugin = p;
-									break;
-								}
-							}
-							value = editor0.get("value");
+							editor = dijit.byId("editor0");
+							npPlugin = getPlugin(editor);
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								editor0.focus();
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(npPlugin != null);
-								var value = editor0.get("value");
-								doh.robot.mouseMoveAt(npPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var newVal = editor0.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									newVal = dojo.trim(newVal);
-									newVal = newVal.replace("/>", ">");
-									newVal = newVal.replace(" >", ">");
-									newVal = newVal.toLowerCase();
-									doh.assertEqual("<br>", newVal, "Validate the contents are a single br");
-								}), 1000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							value = editor.get("value");
+							doh.robot.mouseMoveAt(npPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								newVal = dojo.trim(newVal);
+								newVal = newVal.replace("/>", ">");
+								newVal = newVal.replace(" >", ">");
+								newVal = newVal.toLowerCase();
+								doh.is("<br>", newVal, "Validate the contents are a single br");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							if(editor0){editor0.set("value", value);}
+							editor.set("value", value);
+
 						}
 					},
 					{
 						name: "Mouse: Click new page sets editor with default content.",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("editor1");
-							var edPlugins = editor0._plugins, i;
-							for(i = 0; i < edPlugins.length; i++){
-								var p = edPlugins[i];
-								if(p.declaredClass === "dijit._editor.plugins.NewPage"){
-									npPlugin = p;
-									break;
-								}
-							}
-							value = editor0.get("value");
+							editor = dijit.byId("editor1");
+							npPlugin = getPlugin(editor);
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								editor0.focus();
-
-								//Find the fullscreen plugin, we'll need it.
-								doh.assertTrue(npPlugin != null);
-								var value = editor0.get("value");
-								doh.robot.mouseMoveAt(npPlugin.button.domNode, 500);
-								doh.robot.mouseClick({left:true}, 500);
-
-								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var newVal = editor0.get("value");
-									doh.assertTrue(newVal !== value, "Verify the contents have changed.");
-									newVal = dojo.trim(newVal);
-									doh.assertEqual("<p>This page intentionally left blank</p>", newVal, "Validate the contents are the defined default content");
-								}), 1000);
-							}catch(e){
-								d.errback(e);
-							}
+							// Focus on the editor window
+							dojo.window.scrollIntoView(editor.domNode);
+							editor.focus();
+
+							value = editor.get("value");
+							doh.robot.mouseMoveAt(npPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var newVal = editor.get("value");
+								doh.isNot(value, newVal, "Verify the contents have changed.");
+								newVal = dojo.trim(newVal);
+								doh.is("<p>This page intentionally left blank</p>", newVal, "Validate the contents are the defined default content");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
-							if(editor0){editor0.set("value", value);}
+							editor.set("value", value);
+
 						}
 					}
 				]);
diff --git a/dijit/tests/editor/robot/Editor_ViewSource.html b/dijit/tests/editor/robot/Editor_ViewSource.html
index 254ed07..a2db279 100755
--- a/dijit/tests/editor/robot/Editor_ViewSource.html
+++ b/dijit/tests/editor/robot/Editor_ViewSource.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
@@ -28,6 +29,15 @@
 
 				doh.register("ViewSource_Tests", [
 					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
 						name: "Keyboard: Go to view source (CTRL-SHIFT-F12)",
 						timeout: 20000,
 						setUp: function(){
@@ -42,34 +52,28 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							editor0.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor0.focus();
-
-										//Find the ViewSource plugin, we'll need it.
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											doh.assertTrue(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
-											doh.assertEqual("none", dojo.style(editor0.iframe, "display"), "Verifying iframe is invisible");
-											doh.assertEqual("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
-											doh.assertEqual(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
-										}), 3000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor0.focus();
+							}), 500);
+
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
+								doh.is("none", dojo.style(editor0.iframe, "display"), "Verifying iframe is invisible");
+								doh.is("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+							}), 3000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -93,32 +97,28 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking that the view source plugin was found.");
 							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							setTimeout(function(){
-								try{
-									//Focus on the editor window
-									editor0.focus();
-
-									//Find the view source plugin, we'll need it.
-									doh.assertTrue(vsPlugin != null, "Checking that the view source plugin was found.");
-									doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
-									doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-
-									doh.robot.sequence(d.getTestCallback(function(){
-										//Now check the state!
-										doh.assertFalse(vsPlugin._sourceShown, "Verifying the plugin states the source is not shown.");
-										doh.assertEqual("block", dojo.style(editor0.iframe, "display"), "Verifying iframe is visible");
-										doh.assertEqual("none", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is invisible");
-										doh.assertEqual(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
-									}), 2000);
-								}catch(e){
-									d.errback(e);
-								}
-							}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor0.focus();
+							}), 1000);
+
+							//Find the view source plugin, we'll need it.
+							doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.f(vsPlugin._sourceShown, "Verifying the plugin states the source is not shown.");
+								doh.is("block", dojo.style(editor0.iframe, "display"), "Verifying iframe is visible");
+								doh.is("none", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is invisible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -138,31 +138,26 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking that the view source plugin was found.");
 							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							setTimeout(function(){
-								try{
-									//Focus on the editor window
-									editor0.focus();
-
-									doh.assertTrue(vsPlugin != null);
-									doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
-									doh.robot.mouseClick({left: true}, 750);
-
-									doh.robot.sequence(d.getTestCallback(function(){
-										//Now check the state!
-										doh.assertTrue(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
-										doh.assertEqual("none", dojo.style(editor0.iframe, "display"), "Verifying iframe is invisible");
-										doh.assertEqual("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
-										doh.assertEqual(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
-									}), 1000);
-								}catch(e){
-									d.errback(e);
-								}
-							}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor0.focus();
+							}), 1000);
+
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
+								doh.is("none", dojo.style(editor0.iframe, "display"), "Verifying iframe is invisible");
+								doh.is("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+							}), 1000);
 
 							return d;
 						},
@@ -185,33 +180,28 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null);
 							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							setTimeout(function(){
-								try{
-									//Focus on the editor window
-									editor0.focus();
-
-									doh.assertTrue(vsPlugin != null);
-									doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
-									doh.robot.mouseClick({left: true}, 750);
-									doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
-									doh.robot.mouseClick({left: true}, 750);
-
-									doh.robot.sequence(d.getTestCallback(function(){
-										//Now check the state!
-										doh.assertTrue(!vsPlugin._sourceShown, "Verifying the plugin believes the source is not shown.");
-										doh.assertEqual("block", dojo.style(editor0.iframe, "display"), "Verifying iframe is visible");
-										doh.assertEqual("none", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is invisible");
-										doh.assertEqual(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
-									}), 1000);
-								}catch(e){
-									d.errback(e);
-								}
-							}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor0.focus();
+							}), 500);
+
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(!vsPlugin._sourceShown, "Verifying the plugin believes the source is not shown.");
+								doh.is("block", dojo.style(editor0.iframe, "display"), "Verifying iframe is visible");
+								doh.is("none", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is invisible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+							}), 1000);
 
 							return d;
 						},
@@ -239,36 +229,32 @@
 									break;
 								}
 							}
+							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);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							setTimeout(function(){
-								try{
-									//Focus on the editor window
-									editor1.focus();
-
-									doh.assertTrue(vsPlugin != null, "Checking for viewSource plugin.");
-									doh.assertTrue(fsPlugin != null, "Checking for fullScreen plugin.");
-									doh.robot.mouseMoveAt(fsPlugin.button.domNode, 1000);
-									doh.robot.mouseClick({left: true}, 500);
-									doh.robot.mouseMoveAt(vsPlugin.button.domNode, 1000);
-									doh.robot.mouseClick({left: true}, 500);
-
-									doh.robot.sequence(d.getTestCallback(function(){
-										//Now check the state!
-										doh.assertTrue(fsPlugin.isFullscreen, "Verifying the plugin believes the editor is in full screen mode.");
-										doh.assertTrue(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
-										doh.assertEqual("none", dojo.style(editor1.iframe, "display"), "Verifying iframe is invisible");
-										doh.assertEqual("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
-										doh.assertEqual(vsPlugin.sourceArea.nextSibling, editor1.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
-									}), 2000);
-								}catch(e){
-									d.errback(e);
-								}
-							}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor1.focus();
+							}), 1000);
+
+							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(fsPlugin.isFullscreen, "Verifying the plugin believes the editor is in full screen mode.");
+								doh.t(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
+								doh.is("none", dojo.style(editor1.iframe, "display"), "Verifying iframe is invisible");
+								doh.is("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor1.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -296,42 +282,38 @@
 									break;
 								}
 							}
+							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);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							setTimeout(function(){
-								try{
-									//Focus on the editor window
-									dojo.window.scrollIntoView(editor1.domNode);
-									editor1.focus();
-
-									doh.assertTrue(vsPlugin != null, "Checking for viewSource plugin.");
-									doh.assertTrue(fsPlugin != null, "Checking for fullScreen plugin.");
-
-									//Toggle fs on, the source on.
-									doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
-									doh.robot.mouseClick({left: true}, 750);
-									doh.robot.mouseMoveAt(vsPlugin.button.domNode, 1000);
-									doh.robot.mouseClick({left: true}, 1000);
-									doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
-									doh.robot.mouseClick({left: true}, 1000);
-									doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
-									doh.robot.mouseClick({left: true}, 1000);
-									doh.robot.sequence(d.getTestCallback(function(){
-										//Now check the state!
-										doh.assertTrue(!fsPlugin.isFullscreen, "Verifying the plugin believes the editor is not in full screen mode.");
-										doh.assertTrue(!vsPlugin._sourceShown, "Verifying the plugin believes the source is not shown.");
-										doh.assertEqual("block", dojo.style(editor1.iframe, "display"), "Verifying iframe is visible");
-										doh.assertEqual("none", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is invisible");
-										doh.assertEqual(vsPlugin.sourceArea.nextSibling, editor1.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
-									}), 1000);
-								}catch(e){
-									d.errback(e);
-								}
-							}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor1.domNode);
+								editor1.focus();
+							}), 1000);
+
+							//Toggle fs on, the source on.
+							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 1000);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.mouseMoveAt(fsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(!fsPlugin.isFullscreen, "Verifying the plugin believes the editor is not in full screen mode.");
+								doh.t(!vsPlugin._sourceShown, "Verifying the plugin believes the source is not shown.");
+								doh.is("block", dojo.style(editor1.iframe, "display"), "Verifying iframe is visible");
+								doh.is("none", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is invisible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor1.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -356,49 +338,45 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							editor0.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								var oldValue = editor0.get("value");
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor0.focus();
-										dojo.window.scrollIntoView(editor0.domNode);
-
-										var simpleScript0 = '<scr' + 'ipt type="text/javascript">var foo = "Hack!"</scr' + 'ipt>';
-										var simpleScript1 = '<scr' + 'ipt type="text/javascript" src="http://example.com/hack.js"></scr' + 'ipt>';
-
-										//Type in some script stuff.
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-										doh.robot.sequence(function(){
-											var val = "\n\n" +
-												simpleScript0 +
-												"\n\n" +
-												simpleScript1 +
-												"\n" +
-												vsPlugin.sourceArea.value;
-											vsPlugin.sourceArea.value = val;
-										}, 1000);
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											var val = editor0.get("value");
-											doh.assertEqual(-1, val.indexOf("Hack!"), "Validating inline script tag was stripped");
-											doh.assertEqual(-1, val.indexOf("hack.js"), "Validating import script tag was stripped");
-											editor0.set("value", oldValue);
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+
+							var oldValue = editor0.get("value");
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							var simpleScript0 = '<scr' + 'ipt type="text/javascript">var foo = "Hack!"</scr' + 'ipt>';
+							var simpleScript1 = '<scr' + 'ipt type="text/javascript" src="http://example.com/hack.js"></scr' + 'ipt>';
+
+							//Type in some script stuff.
+
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestErrback(function(){
+								vsPlugin.sourceArea.value = "\n\n" +
+										simpleScript0 +
+										"\n\n" +
+										simpleScript1 +
+										"\n" +
+										vsPlugin.sourceArea.value;
+							}), 1000);
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor0.get("value");
+								doh.is(-1, val.indexOf("Hack!"), "Validating inline script tag was stripped");
+								doh.is(-1, val.indexOf("hack.js"), "Validating import script tag was stripped");
+								editor0.set("value", oldValue);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -422,42 +400,38 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							editor0.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								var oldValue = editor0.get("value");
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor0.focus();
-										dojo.window.scrollIntoView(editor0.domNode);
-
-										var complexScript = '< scr' + 'IPt type="text/javascript"            \n>\n   var foo = "Hack!"  \n</SCr' + 'ipt  >';
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-										doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
-										doh.robot.sequence(function(){
-											var val = "\n\n" +
-												complexScript +
-												"\n\n" +
-												vsPlugin.sourceArea.value;
-											vsPlugin.sourceArea.value = val;
-										}, 1000);
-										doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											var val = editor0.get("value");
-											doh.assertEqual(-1, val.indexOf("< scrIPt "), "Validating script tag was stripped");
-											editor0.set("value", oldValue);
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+
+							var oldValue = editor0.get("value");
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							var complexScript = '< scr' + 'IPt type="text/javascript"            \n>\n   var foo = "Hack!"  \n</SCr' + 'ipt  >';
+							doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestErrback(function(){
+								vsPlugin.sourceArea.value = "\n\n" +
+										complexScript +
+										"\n\n" +
+										vsPlugin.sourceArea.value;
+							}), 1000);
+							doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor0.get("value");
+								doh.is(-1, val.indexOf("< scrIPt "), "Validating script tag was stripped");
+								editor0.set("value", oldValue);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -481,45 +455,40 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							editor0.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								var oldValue = editor0.get("value");
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor0.focus();
-										dojo.window.scrollIntoView(editor0.domNode);
-
-										var simpleComment = '<!--  Hello, this is a comment! -->';
-
-										//Type in some script stuff.
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-										doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
-										doh.robot.sequence(function(){
-											var val = "\n\n" +
-												simpleComment +
-												"\n\n" +
-												vsPlugin.sourceArea.value;
-											vsPlugin.sourceArea.value = val;
-										}, 1000);
-										doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
-
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											var val = editor0.get("value");
-											doh.assertEqual(-1, val.indexOf("Hello, this is a comment!"), "Validating comment block was stripped");
-											editor0.set("value", oldValue);
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+							var oldValue = editor0.get("value");
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							var simpleComment = '<!--  Hello, this is a comment! -->';
+
+							//Type in some script stuff.
+							doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestErrback(function(){
+								vsPlugin.sourceArea.value = "\n\n" +
+										simpleComment +
+										"\n\n" +
+										vsPlugin.sourceArea.value;
+							}), 1000);
+							doh.robot.keyPress(dojo.keys.F12, 500, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor0.get("value");
+								doh.is(-1, val.indexOf("Hello, this is a comment!"), "Validating comment block was stripped");
+								editor0.set("value", oldValue);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -543,45 +512,41 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							editor0.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								var oldValue = editor0.get("value");
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor0.focus();
-										dojo.window.scrollIntoView(editor0.domNode);
-
-										//Type in some script stuff.
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-										doh.robot.sequence(function(){
-											var val = "\n\n" +
-												"<!--\n" +
-												"Hello, this is a comment!\n" +
-												"-->\n" +
-												"\n\n" +
-												vsPlugin.sourceArea.value;
-											vsPlugin.sourceArea.value = val;
-										}, 1000);
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											var val = editor0.get("value");
-											doh.assertEqual(-1, val.indexOf("Hello, this is a comment!"), "Validating multiline comment block was stripped");
-											editor0.set("value", oldValue);
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+
+							var oldValue = editor0.get("value");
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							//Type in some script stuff.
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestErrback(function(){
+								vsPlugin.sourceArea.value = "\n\n" +
+										"<!--\n" +
+										"Hello, this is a comment!\n" +
+										"-->\n" +
+										"\n\n" +
+										vsPlugin.sourceArea.value;
+							}), 1000);
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor0.get("value");
+								doh.is(-1, val.indexOf("Hello, this is a comment!"), "Validating multiline comment block was stripped");
+								editor0.set("value", oldValue);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -607,44 +572,42 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							 var d = new doh.Deferred();
-							 editor0.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
+
 								var oldValue = editor0.get("value");
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor0.focus();
-
-										var simpleiFrame = '<iframe src="http://example.com/hack.html" width=0 height=0 style="display: none;"></iframe>';
-
-										//Type in some script stuff.
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-										doh.robot.sequence(function(){
-											var val = "\n\n" +
-												simpleiFrame +
-												"\n\n" +
-												vsPlugin.sourceArea.value;
-											vsPlugin.sourceArea.value = val;
-										}, 1000);
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											var val = editor0.get("value");
-											doh.assertEqual(-1, val.indexOf("<iframe"), "Validating iframe tag was stripped stripped");
-											editor0.set("value", oldValue);
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							var simpleIFrame = '<iframe src="http://example.com/hack.html" width=0 height=0 style="display: none;"></iframe>';
+
+							//Type in some script stuff.
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestErrback(function(){
+								vsPlugin.sourceArea.value = "\n\n" +
+									simpleIFrame +
+									"\n\n" +
+									vsPlugin.sourceArea.value;
+							}), 1000);
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor0.get("value");
+								doh.is(-1, val.indexOf("<iframe"), "Validating iframe tag was stripped stripped");
+								editor0.set("value", oldValue);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -668,62 +631,57 @@
 									break;
 								}
 							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
 							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							editor3.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								var oldValue = editor3.get("value");
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										editor3.focus();
-										dojo.window.scrollIntoView(editor3.domNode);
-
-										var simpleScript0 = '<scr' + 'ipt type="text/javascript">var foo = "Hack!"</scr' + 'ipt>';
-										var simpleScript1 = '<scr' + 'ipt type="text/javascript" src="http://example.com/hack.js"></scr' + 'ipt>';
-										var simpleiFrame = '<iframe src="http://example.com/hack.html" width=0 height=0 style="display: none;"></iframe>';
-										var simpleComment = '<!--  Hello, this is a comment! -->';
-
-										//Type in some script stuff.
-										doh.assertTrue(vsPlugin != null, "Checking for VS plugin.");
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-
-										doh.robot.sequence(function(){
-											var val = "\n\n" +
-												"<div>\n" +
-												simpleScript0 +
-												"\n\n" +
-												simpleScript1 +
-												"\n" +
-												"</div>" +
-												"\n\n" +
-												simpleiFrame +
-												"\n\n" +
-												simpleComment +
-												"\n\n" +
-												vsPlugin.sourceArea.value;
-											vsPlugin.sourceArea.value = val;
-										}, 1000);
-										doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											var val = editor3.get("value");
-											// IE strips scripts anyway, need to look more at this sometime.
-											// It's not the plugin doing it.
-											doh.assertTrue((0 <= val.indexOf("Hack!")) || dojo.isIE, "Validating inline script tag was left");
-											doh.assertTrue((0 <= val.indexOf("hack.js") || dojo.isIE), "Validating import script tag was left");
-											doh.assertTrue(0 <= val.indexOf("<iframe"), "Validating iframe tag was left");
-											doh.assertTrue(0 <= val.indexOf("Hello, this is a comment!"), "Validating comment was left");
-											editor3.set("value", oldValue);
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+							var oldValue = editor3.get("value");
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor3.domNode);
+								editor3.focus();
+							}), 500);
+
+							var simpleScript0 = '<scr' + 'ipt type="text/javascript">var foo = "Hack!"</scr' + 'ipt>';
+							var simpleScript1 = '<scr' + 'ipt type="text/javascript" src="http://example.com/hack.js"></scr' + 'ipt>';
+							var simpleiFrame = '<iframe src="http://example.com/hack.html" width=0 height=0 style="display: none;"></iframe>';
+							var simpleComment = '<!--  Hello, this is a comment! -->';
+
+							//Type in some script stuff.
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								vsPlugin.sourceArea.value = "\n\n" +
+										"<div>\n" +
+										simpleScript0 +
+										"\n\n" +
+										simpleScript1 +
+										"\n" +
+										"</div>" +
+										"\n\n" +
+										simpleiFrame +
+										"\n\n" +
+										simpleComment +
+										"\n\n" +
+										vsPlugin.sourceArea.value;
+							}), 1000);
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor3.get("value");
+								// IE strips scripts anyway, need to look more at this sometime.
+								// It's not the plugin doing it.
+								doh.t((0 <= val.indexOf("Hack!")) || dojo.isIE, "Validating inline script tag was left");
+								doh.t((0 <= val.indexOf("hack.js") || dojo.isIE), "Validating import script tag was left");
+								doh.t(0 <= val.indexOf("<iframe"), "Validating iframe tag was left");
+								doh.t(0 <= val.indexOf("Hello, this is a comment!"), "Validating comment was left");
+								editor3.set("value", oldValue);
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -751,26 +709,23 @@
 						},
 						runTest: function(){
 							 var d = new doh.Deferred();
-							 editor2.onLoadDeferred.addCallback(function(){
-								//Timing gets wonky here, so we need to do this on a timeout
-								//so the browser has time  to shift focus.
-								editor2.focus();
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
 								dojo.window.scrollIntoView(editor2.domNode);
-								setTimeout(function(){
-									try{
-										//Focus on the editor window
-										doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
-										doh.robot.mouseClick({left: true}, 750);
-
-										doh.robot.sequence(d.getTestCallback(function(){
-											//Now check the state!
-											doh.assertEqual(true, dojo.attr(vsPlugin.sourceArea, "readOnly"), "Verify the source area is read only.");
-										}), 2000);
-									}catch(e){
-										d.errback(e);
-									}
-								}, 500);
-							});
+								editor2.focus();
+							}), 500);
+
+							doh.robot.mouseMoveAt(vsPlugin.button.domNode, 500);
+							doh.robot.mouseClick({left: true}, 750);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.is(true, dojo.attr(vsPlugin.sourceArea, "readOnly"), "Verify the source area is read only.");
+							}), 2000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -778,6 +733,57 @@
 							 fsPlugin = null;
 							 vsPlugin = null;
 						}
+					},
+					{
+						name: "ViewSource:  GetValue",
+						timeout: 20000,
+						setUp: function(){
+							editor0 = dijit.byId("editor0");
+							value = editor0.get("value");
+							var edPlugins = editor0._plugins, i;
+							for(i = 0; i < edPlugins.length; i++){
+								var p = edPlugins[i];
+								if(p.declaredClass === "dijit._editor.plugins.ViewSource"){
+									vsPlugin = p;
+								}
+								if(vsPlugin){
+									break;
+								}
+							}
+							doh.t(vsPlugin != null, "Checking for VS plugin.");
+							if(vsPlugin) { vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//Timing gets wonky here, so we need to do this on a timeout
+							//so the browser has time  to shift focus.
+							doh.robot.sequence(d.getTestErrback(function(){
+								//Focus on the editor window
+								dojo.window.scrollIntoView(editor0.domNode);
+								editor0.focus();
+							}), 500);
+
+							doh.robot.keyPress(dojo.keys.F12, 1000, {ctrl:true,shift:true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(vsPlugin._sourceShown, "Verifying the plugin believes the source is shown.");
+								doh.is("none", dojo.style(editor0.iframe, "display"), "Verifying iframe is invisible");
+								doh.is("block", dojo.style(vsPlugin.sourceArea, "display"), "Verifying source view node is visible");
+								doh.is(vsPlugin.sourceArea.nextSibling, editor0.iframe, "Verifying source view node's next sibling is the hidden iframe node.");
+								vsPlugin.sourceArea.value = "FOO";
+								doh.is("FOO", editor0.get("value"), "Verifying the source area returns foo when getValue is called.");
+							}), 3000);
+
+							return d;
+						},
+						tearDown: function(){
+							if(vsPlugin) {vsPlugin.button.focus(); vsPlugin.button.set("checked", false);}
+							editor0.set("value", value); 
+							fsPlugin = null;
+							vsPlugin = null;
+						}
 					}
 				]);
 				doh.run();
diff --git a/dijit/tests/editor/robot/Editor_a11y.html b/dijit/tests/editor/robot/Editor_a11y.html
index 7adb0de..0eddfa4 100644
--- a/dijit/tests/editor/robot/Editor_a11y.html
+++ b/dijit/tests/editor/robot/Editor_a11y.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
@@ -24,7 +25,8 @@
 				// the same.   Would be nice if we didn't need this, the normalization should
 				// probably happen as pre and post filters on the editor
 				return str.
-					replace('<br />', '').		// FF.  Because of EnterKeyHandling plugin?
+					replace(' />', '/>').
+					replace('<br/>', '').		// FF.  Because of EnterKeyHandling plugin?
 					replace(/^<p>/, '').replace(/<\/p>$/, '').		// Safari.  Because of EnterKeyHandling plugin?
 					replace(new RegExp(String.fromCharCode(160), "g"), " ");	// Safari: nbsp (char code 160) to normal space (char code 32)
 			}
@@ -32,52 +34,71 @@
 			dojo.addOnLoad(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)
+				// 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 editor0, editor1;
+				var editor0,
+					editor1, editor1oldValue, editor1newValue, editor1onChange = "no onchange event yet";
 
-				doh.register("setup", function setup(){
-					editor0 = dijit.byId("editor0");
-					editor1 = dijit.byId("editor1");
-				});
+				doh.register("setup", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					function setUp(){
+						editor0 = dijit.byId("editor0");
+						editor1 = dijit.byId("editor1");					
+						editor1.watch("value", function(attr, oldVal, newVal){
+							editor1oldValue = normalize(oldVal);
+							editor1newValue = normalize(newVal);
+						});
+						editor1.onChange = function(newValue){
+							editor1onChange = normalize(newValue);
+						};
+					}
+				]);
 
 				doh.register("keyboard shortcuts", [
 					{
 						name: "bold/italic",
-						timeout: 10000,
+						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							dojo.window.scrollIntoView(editor1.domNode);
 
 							// Set contents of editor1
-							doh.robot.sequence(function(){
+							doh.robot.sequence(d.getTestErrback(function(){
 								editor1.focus();
-							}, 500);
+							}), 500);
 							doh.robot.keyPress("a", 500, metaKey);	// select all
-							doh.robot.typeKeys("hello ", 500);		// and erase (by typing something new)
+							doh.robot.typeKeys("hello ", 500, 750);		// and erase (by typing something new)
 							doh.robot.keyPress("b", 500, metaKey);	// start bold
-							doh.robot.typeKeys("bold", 500);
+							doh.robot.typeKeys("bold", 500, 600);
 							doh.robot.keyPress("b", 500, metaKey);	// stop bold
-							doh.robot.typeKeys(" and ", 500);
+							doh.robot.typeKeys(" and ", 500, 750);
 							doh.robot.keyPress("i", 500, metaKey);	// start italic
-							doh.robot.typeKeys("exciting", 500);
+							doh.robot.typeKeys("exciting", 500, 1200);
 							doh.robot.keyPress("i", 500, metaKey);	// stop italic
-							doh.robot.typeKeys(" new world.", 500);
+							doh.robot.typeKeys(" new world.", 500, 1650);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								var val = normalize(editor1.get('value'));
 								doh.is("hello <b>bold</b> and <i>exciting</i> new world.", val);
-							}), 1500);
+							}), 500);
 
 							return d;
 						}
 					}
 				]);
 
-				// Check that toolbar buttons are highlighted/not highlighted (etc.) based on
+				// Check that toolbar buttons are depressed/not depressed (etc.) based on
 				// where caret is in document
 				doh.register("toolbar state", [
 					{
@@ -91,13 +112,30 @@
 							// strange things happen if you alter an editor's value while it is focused,
 							// so temporarily move to the toolbar while setting content
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});	// go to toolbar
-							doh.robot.sequence(function(){
-								editor1.set("value", "toolbar <b>state</b> <i>test</i>.")
-							}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor1.set("value", "toolbar <b>state</b> <i>test</i>.");
+
+								// set() should fire watch() callbacks but not call onChange()
+								doh.is("toolbar <b>state</b> <i>test</i>.", editor1newValue, "value set successfully");
+								doh.is("no onchange event yet", editor1onChange, "onChange not called");
+							}), 500);
 							doh.robot.keyPress(dojo.keys.TAB, 500);	// goes to content
+							doh.robot.sequence(d.getTestCallback(function(){
+								// just to signal that we are done
+							}));
 
+							return d;
+						}
+					},
+					{
+						name: "no buttons depressed",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
 
-							doh.robot.keyPress(dojo.keys.HOME, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor1.placeCursorAtStart();
+							}), 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								var toolbar = editor1.toolbar;
@@ -116,15 +154,14 @@
 						}
 					},
 					{
-						name: "bold higlighted",
+						name: "bold button depressed",
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							doh.robot.sequence(function(){
+							doh.robot.sequence(d.getTestErrback(function(){
 								editor1.placeCursorAtStart();
-							}, 500);
-							var i;
-							for(i = 0; i < 9; i++){
+							}), 500);
+							for(var i = 0; i < 9; i++){
 								// Move to second letter of second word.
 								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
 							}
@@ -145,16 +182,15 @@
 						}
 					},
 					{
-						name: "italic higlighted",
+						name: "italic button depressed",
 						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
+							doh.robot.sequence(d.getTestErrback(function(){
 								editor1.placeCursorAtStart();
-							}, 500);
-							var i;
-							for(i = 0; i < 15; i++){
+							}), 500);
+							for(var i = 0; i < 15; i++){
 								// Move to second letter of third word.
 								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
 							}
@@ -179,27 +215,33 @@
 				doh.register("toolbar navigation", [
 					{
 						name: "bold",
-						timeout: 10000,
+						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							dojo.window.scrollIntoView(editor1.domNode);
 
-							doh.robot.sequence(function(){
+							// Write "hello" in editor and also make sure there's something in the system
+							// clipboard, so that the paste button in the toolbar is guaranteed to be enabled.
+							// (otherwise the two RIGHT_ARROW commands below will overshoot the bold button
+							// and end up on the italic button)
+							doh.robot.sequence(d.getTestErrback(function(){
 								editor1.focus();
-							}, 500);
-							doh.robot.keyPress("a", 500, metaKey);	// select all
-							doh.robot.typeKeys("hello ", 500);		// and erase (by typing something new)
+							}), 500);
+							doh.robot.keyPress("a", 1000, metaKey);	// select all
+							doh.robot.keyPress("c", 500, dojo.isMac ? {meta: true} : {ctrl: true});	// copy into clipboard
+							doh.robot.typeKeys("hello ", 500, 900);		// and erase (by typing something new)
 
 							// Go to toolbar and turn on bold.
 							// We only have to right-arrow twice because it skips the vertical divider bars
 							// and also skips cut and copy (they are disabled b/c nothing is selected)
 							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000);
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
 							doh.robot.keyPress(dojo.keys.SPACE, 500);
 
-							doh.robot.typeKeys("world", 500);
+							// Focus and caret should be back after "hello ", type "world" in bold
+							doh.robot.typeKeys("world", 1000, 750);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Get the value and try to do some normalization to make all browsers look
@@ -207,7 +249,7 @@
 								// probably happen as pre and post filters on the editor
 								var val = normalize(editor1.get('value'));
 								doh.is("hello <b>world</b>", val);
-							}), 1000);
+							}), 500);
 
 							return d;
 						}
@@ -224,9 +266,9 @@
 							dojo.window.scrollIntoView(editor1.domNode);
 
 							// Focus on link before editor
-							doh.robot.sequence(function(){
+							doh.robot.sequence(d.getTestErrback(function(){
 								dojo.byId("focusBefore").focus();
-							}, 500);
+							}), 500);
 
 							// Go to toolbar of editor1
 							doh.robot.keyPress(dojo.keys.TAB, 500);
@@ -251,10 +293,17 @@
 							// Go to content of editor1
 							doh.robot.keyPress(dojo.keys.TAB, 500);
 
-							doh.robot.sequence(d.getTestCallback(function(){
+							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("editor1_iframe", dojo.global.dijit._curFocus.id, "focused on editor content");
 							}), 500);
 
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.typeKeys("tabbing test", 500, 1800);		// and replace with "tabbing test"
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// just here to make deferred fire
+							}), 500);
+
 							return d;
 						}
 					},
@@ -269,6 +318,9 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is("focusAfter", dojo.global.dijit._curFocus.id, "focused after editor1");
+								
+								doh.is("tabbing test", editor1newValue, "watch()");
+								doh.is("tabbing test", editor1onChange, "onChange");
 							}), 500);
 
 							return d;
diff --git a/dijit/tests/editor/robot/Editor_misc.html b/dijit/tests/editor/robot/Editor_misc.html
index c032845..11b4c65 100755
--- a/dijit/tests/editor/robot/Editor_misc.html
+++ b/dijit/tests/editor/robot/Editor_misc.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
@@ -24,8 +25,65 @@
 				var editor0;
 				var height;
 				var value;
+				var editor1;
+				var editor1OrigionalBackgroundColor;
 				doh.register("Miscellaneous_tests", [
 					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
+						name: "addStylesheet",
+						timeout: 3000,
+						setUp: function(){
+							editor1 = dijit.byId("editor1");
+							editor1.setValue("<h1>header one</h1>");
+							var editorTextNode = editor1.editNode.firstChild;
+							editor1OrigionalBackgroundColor = dojo.getComputedStyle(editorTextNode).backgroundColor;
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.window.scrollIntoView(editor1.domNode);
+							editor1.addStyleSheet('test_editor.css');
+
+							setTimeout(d.getTestCallback(function(){
+								var editorTextNode = editor1.editNode.firstChild;
+								var backgroundColor = dojo.getComputedStyle(editorTextNode).backgroundColor;
+								var borderStyle = dojo.getComputedStyle(editorTextNode).borderBottomStyle;
+								var borderWidth = dojo.getComputedStyle(editorTextNode).borderBottomWidth;
+								doh.is("header one", editorTextNode.innerHTML);
+								doh.t(backgroundColor==="rgb(255, 0, 0)" || backgroundColor==="red" || backgroundColor==="#ff0000", "backgroundColor " + backgroundColor);
+								doh.is("solid", borderStyle);
+								doh.is("1px", borderWidth);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "removeStylesheet",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+								editor1.removeStyleSheet('test_editor.css')
+
+							setTimeout(d.getTestCallback(function(){
+								var editorNodeText = editor1.editNode.firstChild;
+								var backgroundColor = dojo.getComputedStyle(editorNodeText).backgroundColor;
+								doh.is("header one", editorNodeText.innerHTML);
+								doh.is(editor1OrigionalBackgroundColor, backgroundColor, "backgroundColor");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
 						name: "Test AutoExpanding Edtor",
 						timeout: 20000,
 						setUp: function(){
@@ -35,27 +93,25 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
-								doh.robot.mouseClick({left:true}, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
-								doh.robot.keyPress(dojo.keys.ENTER, 500);
- 								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var newHeight = dojo.style(editor0.domNode, "height");
-									doh.assertTrue(height < newHeight);
-								}), 1000);
-							}catch(e){
-								d.errback(e);
-							}
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var newHeight = dojo.style(editor0.domNode, "height");
+								doh.t(height < newHeight, "height decreased from " + height + " to " + newHeight);
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -64,28 +120,61 @@
 					},
 					{
 						name: "Test font-size style migrated to editor body",
+						runTest: function(){
+							editor0 = dijit.byId("fontSizedEditor");
+							var bStyle = editor0.document.body.style["fontSize"];
+							doh.t(bStyle != null, "bStyle set");
+							doh.is("30pt", bStyle.toLowerCase());
+						}
+					},
+					{
+						name: "Test prefilters do process initial content",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("fontSizedEditor");
+							editor0 = dijit.byId("filteredEditor");
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
+							doh.robot.mouseClick({left:true}, 500);
+
+								doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var val = editor0.get("value");
+								doh.t(val.indexOf("DOJO") >= 0, "dojo in val " + val);
+								doh.t(val.indexOf("notdojo") < 0, "notdojo not in val " + val);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "Test placeCurorAtStart (br tag) moves input before br, not inside.",
+						timeout: 20000,
+						setUp: function(){
+							editor0 = dijit.byId("brEditor");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
-								doh.robot.mouseClick({left:true}, 500);
-
- 								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var bStyle = editor0.document.body.style["fontSize"];
-									doh.assertTrue(bStyle != null);
-									doh.assertTrue(bStyle.toLowerCase() === "30pt");
-								}), 500);
-							}catch(e){
-								d.errback(e);
-							}
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
+							doh.robot.mouseClick({left:true}, 500);
+								doh.robot.sequence(d.getTestErrback(function(){
+								editor0.placeCursorAtStart();
+							}), 500);
+							doh.robot.typeKeys("abc", 500);
+								doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var content = editor0.get("value").replace(/[\s]/g, "");
+								doh.t(content.indexOf("abc<br") >= 0, "looked for 'abc<br', found: " + content);
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -93,57 +182,50 @@
 						}
 					},
 					{
-						name: "Test prefilters do process initial content",
+						name: "Test custom editor content (programmatic creation).",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("filteredEditor");
+							editor0 = dijit.byId("programmatic3");
+							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
-								doh.robot.mouseClick({left:true}, 500);
-
- 								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var val = editor0.get("value");
-									doh.assertTrue(val.indexOf("DOJO") >= 0);
-									doh.assertTrue(val.indexOf("notdojo") < 0)
-								}), 500);
-							}catch(e){
-								d.errback(e);
-							}
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
+							doh.robot.mouseClick({left:true}, 500);
+								doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								var content = editor0.get("value");
+								doh.t(content.indexOf("Custom Initial Content.") >= 0);
+							}), 1000);
+
 							return d;
+						},
+						tearDown: function(){
+							if(editor0){editor0.set("value", value);}
 						}
 					},
 					{
-						name: "Test placeCurorAtStart (br tag) moves input before br, not inside.",
+						name: "Verify custom filters passed in constructor are not lost",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("brEditor");
+							editor0 = dijit.byId("programmatic4");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								//Focus on the editor window
-								dojo.window.scrollIntoView(editor0.domNode);
-								doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
-								doh.robot.mouseClick({left:true}, 500);
- 								doh.robot.sequence(function(){
-									editor0.placeCursorAtStart();
-								}, 500);
-								doh.robot.typeKeys("abc", 500);
- 								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var content = editor0.get("value");
-									doh.assertTrue(content.indexOf("abc<br") >= 0);
-								}), 1000);
-							}catch(e){
-								d.errback(e);
-							}
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								doh.t(editor0.contentPreFilters.length > 1);
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
@@ -151,27 +233,32 @@
 						}
 					},
 					{
-						name: "Test custom editor content (programmatic creation).",
+						name: "Test replaceValue.",
 						timeout: 20000,
 						setUp: function(){
-							editor0 = dijit.byId("programmatic3");
+							editor0 = dijit.byId("programmatic4");
 							value = editor0.get("value");
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
-							try{
-								//Focus on the editor window
+
+							//Focus on the editor window
+							dojo.window.scrollIntoView(editor0.domNode);
+							dojo.style(editor0.domNode, "display", "none");
+							editor0.replaceValue("New Value");
+							dojo.style(editor0.domNode, "display", "none");
+							doh.robot.sequence(d.getTestCallback(function(){
+								//Now check the state!
+								dojo.style(editor0.domNode, "display", "");
 								dojo.window.scrollIntoView(editor0.domNode);
-								doh.robot.mouseMoveAt(editor0.iframe, 500, null, 10, 10);
-								doh.robot.mouseClick({left:true}, 500);
- 								doh.robot.sequence(d.getTestCallback(function(){
-									//Now check the state!
-									var content = editor0.get("value");
-									doh.assertTrue(content.indexOf("Custom Initial Content.") >= 0);
-								}), 1000);
-							}catch(e){
-								d.errback(e);
-							}
+								var newValue = editor0.get("value");
+								editor0.undo();
+								var curValue = editor0.get("value");
+								doh.t(newValue.indexOf(value) < 0, "Verifying content changed with no trace of old content.");
+								doh.t(curValue != newValue, "Verify that undo undid the change.");
+								doh.t(curValue == value, "Verify original value was restored.");
+							}), 1000);
+
 							return d;
 						},
 						tearDown: function(){
diff --git a/dijit/tests/editor/robot/Editor_mouse.html b/dijit/tests/editor/robot/Editor_mouse.html
index 191e1d2..07b0cad 100644
--- a/dijit/tests/editor/robot/Editor_mouse.html
+++ b/dijit/tests/editor/robot/Editor_mouse.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dojo.window");
 			dojo.require("dijit.robotx");
 
@@ -24,7 +25,8 @@
 				// the same.   Would be nice if we didn't need this, the normalization should
 				// probably happen as pre and post filters on the editor
 				return str.
-					replace(/<br \/>$/, '').		// FF.  Because of EnterKeyHandling plugin?
+					replace(/\s*\/>/g, "/>").
+					replace(/<br\/>$/, '').		// FF.  Because of EnterKeyHandling plugin?
 					replace(/^<p>/, '').replace(/<\/p>$/, '').		// Safari.  Because of EnterKeyHandling plugin?
 					replace(new RegExp(String.fromCharCode(160), "g"), " ");	// Safari: nbsp (char code 160) to normal space (char code 32)
 			}
@@ -38,10 +40,21 @@
 
 				var editor0, editor1;
 
-				doh.register("setup", function setup(){
-					editor0 = dijit.byId("editor0");
-					editor1 = dijit.byId("editor1");
-				});
+				doh.register("setup", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					function setVars(){
+						editor0 = dijit.byId("editor0");
+						editor1 = dijit.byId("editor1");
+					}
+				]);
 
 				doh.register("toolbar buttons", [
 					{
@@ -57,38 +70,38 @@
 							dojo.window.scrollIntoView(editor1.domNode);
 
 							// Focus the editor
-							doh.robot.mouseMoveAt(editor1.editNode, 500);
+							doh.robot.mouseMoveAt(editor1.editNode, 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 							// select all
 							doh.robot.sequence(function(){
 								editor1.execCommand("SelectAll");
-							},500);
+							}, 500);
 
-							doh.robot.typeKeys("hello ", 1000);		// and erase (by typing something new)
+							doh.robot.typeKeys("hello ", 1000, 1000);		// and erase (by typing something new)
 
 							// turn on bold
-							doh.robot.mouseMoveAt(boldButton.domNode, 500);
+							doh.robot.mouseMoveAt(boldButton.domNode, 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("world", 1000);
+							doh.robot.typeKeys("world", 1000, 1000);
 
 							// turn off bold
-							doh.robot.mouseMoveAt(boldButton.domNode, 500);
+							doh.robot.mouseMoveAt(boldButton.domNode, 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys(". ", 1000);
+							doh.robot.typeKeys(". ", 1000, 400);
 
 							// turn on italic
-							doh.robot.mouseMoveAt(italicButton.domNode, 500);
+							doh.robot.mouseMoveAt(italicButton.domNode, 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("how are you", 1000);
+							doh.robot.typeKeys("how are you", 1000, 2000);
 
 							// turn off italic
-							doh.robot.mouseMoveAt(italicButton.domNode, 500);
+							doh.robot.mouseMoveAt(italicButton.domNode, 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 
-							doh.robot.typeKeys("?", 1000);
+							doh.robot.typeKeys("?", 1000, 200);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Get the value and try to do some normalization to make all browsers look
@@ -96,38 +109,61 @@
 								// probably happen as pre and post filters on the editor
 								var val = normalize(editor1.get("value"));
 								doh.is("hello <b>world</b>. <i>how are you</i>?", val);
-							}), 5000);
+							}), 1000);
 
 							return d;
 						}
 					},
 					{
 						name: "delete bold tag",
-						timeout: 20000,
+						timeout: 5000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							
+
 							// Find the bolded "world" word in the editor
-							var bold=dojo.query('b',editor1.editNode);
+							var bold=dojo.query('b', editor1.editNode);
 							if(!bold.length){
-								bold=dojo.query('strong',editor1.editNode)
+								bold=dojo.query('strong', editor1.editNode)
 							}
-							
+
 							// Double-click "world" to select it
-							doh.robot.mouseMoveAt(bold[0],500,100,5,5);
+							doh.robot.mouseMoveAt(bold[0], 500, 1, 5, 5);
 							doh.robot.mouseClick({left: true}, 500);
 							doh.robot.mouseClick({left: true}, 50);
 
 							// Delete "world" and the space before it
-							doh.robot.keyPress(dojo.keys.DELETE,500);
-							if(!dojo.isSafari&&!dojo.isChrome){
+							doh.robot.keyPress(dojo.keys.DELETE, 500);
+							if(!dojo.isSafari && !(dojo.isChrome && dojo.isMac)){
 								// they delete the space too?
-								doh.robot.keyPress(dojo.keys.BACKSPACE,500);
+								doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
 							}
-	
+
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is("hello. <i>how are you</i>?", normalize(editor1.get("value")));
-							}),500);
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("selection", [
+					{
+						name: "mouseup but no click event",
+						timeout: 10000,
+						runTest: function(){
+							var cutButton = editor1.toolbar.getChildren()[3].domNode;
+							doh.t(dojo.hasClass(cutButton, "dijitButtonDisabled"), "Cut should be disabled " + cutButton.className);
+
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(editor1.editNode, 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(editor1.editNode, 500, 500, -10, 0); // move off of editNode
+							doh.robot.mouseRelease({left: true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dojo.hasClass(cutButton, "dijitButtonDisabled"), "Cut should not be disabled " + cutButton.className);
+							}), 1000);
 
 							return d;
 						}
diff --git a/dijit/tests/editor/robot/EnterKeyHandling.html b/dijit/tests/editor/robot/EnterKeyHandling.html
index 882d92d..4891afc 100644
--- a/dijit/tests/editor/robot/EnterKeyHandling.html
+++ b/dijit/tests/editor/robot/EnterKeyHandling.html
@@ -16,6 +16,7 @@
 		<script type="text/javascript" src="../../helpers.js"></script>
 
 		<script type="text/javascript">
+			dojo.require("dojo.DeferredList");
 			dojo.require("dijit.robotx");
 
 			function dom2string(root){
@@ -57,97 +58,137 @@
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../EnterKeyHandling.html');
 
+				var metaKey = dojo.isMac? {meta: true} : {ctrl: true};
+				
 				// Tests for BR mode
-				if(dojo.isIE){
-					doh.register("blockNodeForEnter=BR / IE tests", [
-						{
-							name: "initial input",
-							timeout: 4000,
-							runTest: function(){
-								// The initial input was <p>para 1<br>line 2</p>  <p>para 2<br>line 2</p>,
-								// but the pre-filter should internally convert it to have a <p> for each line
-								// of text.
-								doh.is('<p>para 1</p><p>line 2</p><p> </p><p>para 2</p><p>line 2</p>',
-										dom2string(dijit.byId("br").editNode),
-										"innerHTML of editor (should have converted each line of text to a separate <p>)");
-
-								// getValue() should call the post-filter which recombines the separate <p> nodes into bigger
+				doh.register("blockNodeForEnter=BR", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
+						name: "type in some text",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var br = dijit.byId("br");
+							br.set("value", "");
+							br.focus();
+							
+							doh.robot.mouseMoveAt(br.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+							
+							// tab to the MenuBar... then focus should automatically shift to "File" menu,
+							for(var i=0; i<4; i++){
+								doh.robot.typeKeys("ab345", 500);
+								doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							}
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// get('value') should call the post-filter which recombines the separate <p> nodes into bigger
 								// paragraphs.
-								doh.is('<p>para 1<br />line 2</p><p>para 2<br />line 2</p>',
-										dijit.byId("br").get('value'),
+								var value = br.get('value');
+								value = value.replace(/ /g, "");
+								value = value.replace(/ /g, "");
+								value = value.replace(/\xA0/g, "");
+								doh.is('ab345<br/>ab345<br/>ab345<br/>ab345<br/>',
+										value,
 										"get('value')");
+							}), 1000);
 
-								// Make sure that the post-filter didn't corrupt the data inside the editor
-								doh.is('<p>para 1</p><p>line 2</p><p> </p><p>para 2</p><p>line 2</p>',
-										dom2string(dijit.byId("br").editNode),
-										'innerHTML of editor DOM after getValue() call');
+							return d;
+						}
+					},
+					{
+						name: "copy and paste",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
 
-								// Make sure that the margin:0 style was applied to the <p> nodes
-								var sampleP = dijit.byId("br").editNode.childNodes[0];
-								doh.is('P', sampleP.tagName, "found a P node");
-								doh.is(0, dojo.style(sampleP, "margin-top"));
-								doh.is(0, dojo.style(sampleP, "margin-bottom"));
-							}
-						},
-						/*******
-						Not currently working, see #9462
-						{
-							name: "text nodes at top level",
-							timeout: 4000,
-							runTest: function(){
-
-								var br = dijit.byId("br");
-
-								br.set("value", "<p>ab345<br>ab345<br>ab345<br>ab345<br></p>");
-
-								// Pre-filter should internally convert it to have a <p> for each line
-								// of text.
-								console.log(br.get("value"));
-								doh.is('<p>ab345</p><p>ab345</p><p>ab345</p><p>ab345</p>',
-										dom2string(dijit.byId("br").editNode),
-										"innerHTML of editor (should have converted each line of text to a separate <p>)");
-								// getValue() should call the post-filter which recombines the separate <p> nodes into bigger
+							var br = dijit.byId("br");
+							br.set("value", "");
+							br.focus();
+							
+							doh.robot.mouseMoveAt(br.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+								
+							doh.robot.typeKeys("testingCopyAndPaste", 500);
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.keyPress("c", 500, metaKey);	// copy
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {shift: false});
+							doh.robot.sequence(d.getTestCallback(function(){
+								// get('value') should call the post-filter which recombines the separate <p> nodes into bigger
 								// paragraphs.
-								doh.is('<p>ab345<br/>ab345<br/>ab345<br/>ab345</p>',
-										dijit.byId("br").get('value'),
-										"get('value')");
-							}
-						},
-						********/
-						{
-							name: "type in some text",
-							timeout: 10000,
-							runTest: function(){
-								var d = new doh.Deferred();
-
-								var br = dijit.byId("br");
-								br.set("value", "");
-								br.focus();
-
-								// tab to the MenuBar... then focus should automatically shift to "File" menu,
-								for(var i=0; i<4; i++){
-									doh.robot.typeKeys("ab345", 500);
-									i<3 && doh.robot.keyPress(dojo.keys.ENTER, 100, {});
+								var value = br.get('value');
+								value = value.replace(/ /g, "");
+								value = value.replace(/\xA0/g, "");
+								
+								// Safari may end with a trailing/extra br, so we need to remove it.
+								if(/<br\/><br\/>$/.test(value)){
+									value = value.substring(0, value.length - 5);
 								}
+								doh.is('testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste<br/>',
+										value,
+										"get('value')");
+							}), 1000);
+							return d;
+						}
+					},					
+					{
+						name: "copy and paste split",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
 
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('<p>ab345</p><p>ab345</p><p>ab345</p><p>ab345</p>',
-											dom2string(br.editNode),
-											"innerHTML of editor (should have converted each line of text to a separate <p>)");
-
-									// get('value') should call the post-filter which recombines the separate <p> nodes into bigger
-									// paragraphs.
-									doh.is('<p>ab345<br />ab345<br />ab345<br />ab345</p>',
-											br.get('value'),
-											"get('value')");
-								}), 500);
+							var br = dijit.byId("br");
+							br.set("value", "");
+							br.focus();
+							
+							doh.robot.mouseMoveAt(br.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+								
+							doh.robot.typeKeys("testingCopyAndPaste", 500);
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.keyPress("c", 500, metaKey);	// copy
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								// get('value') should call the post-filter which recombines the separate <p> nodes into bigger
+								// paragraphs.
+								var value = br.get('value');
+								value = value.replace(/ /g, "");
 
-								return d;
-							}
+								// Safari may end with a trailing/extra br, so we need to remove it.
+								if(/aste<br\/>$/.test(value)){
+									value = value.substring(0, value.length - 5);
+								}
+								doh.is('testingCopyAndPastetestingCopyAndPastetestingCopyAndP<br/>aste',
+										value,
+										"get('value')");
+							}), 1000);
+							return d;
 						}
-					]);
-				}
-
+					}
+				]);
+				
 				doh.register("Split tests", [
 					{
 						name: "Test div line split",
@@ -170,7 +211,7 @@
 							}, 500);
 							
 							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz) {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);
 
@@ -178,8 +219,8 @@
 								// Do tests here.
 								var val = editor.get("value");
 								// Check that it split the is into two and that the bold and div were properly split.
-								doh.assertTrue(val.indexOf("It <b id=\"boldLine0\">i</b></div>") > 0);
-								doh.assertTrue(val.indexOf("<div><b>s</b>") > 0);
+								doh.t(val.indexOf("It <b id=\"boldLine0\">i</b></div>") > 0, "start");
+								doh.t(val.indexOf("<div><b>s</b>") > 0, "end");
 							}), 500);
 
 							return d;
@@ -207,7 +248,44 @@
 							}, 500);
 							
 							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz) {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);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Do tests here.
+								var val = editor.get("value");
+								// Check that it split the is into two and that the bold and div were properly split.
+								val = val.toLowerCase();
+								doh.t(/it <b\s+id="boldline1"\s+style\s*=\s*"\s*font-size:\s*4em;?\s*">i<\/b><\/div>/.test(val), "start");
+								doh.t(/<div><b\s+style\s*=\s*"\s*font-size:\s*4em;?\s*">s<\/b>/.test(val), "end");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "Test div line split font clone",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							// The initial input was a div with a line of text with a font tag in the middle.
+							// we want to focus on the font and enter there, splitting it.
+							var editor = dijit.byId("div4");
+							dojo.window.scrollIntoView(editor.iframe);
+							var node = dojo.withGlobal(editor.window, function(){
+								return dojo.byId("fontLine1");
+							});
+							
+							doh.robot.mouseMoveAt(editor.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(function(){
+                                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, {}); }
 							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500);
 
@@ -216,13 +294,84 @@
 								var val = editor.get("value");
 								// Check that it split the is into two and that the bold and div were properly split.
 								val = val.toLowerCase();
-								doh.assertTrue(/it <b\s+id="boldline1"\s+style\s*=\s*"\s*font-size:\s*4em;?\s*">i<\/b><\/div>/.test(val));
-								doh.assertTrue(/<div><b\s+style\s*=\s*"\s*font-size:\s*4em;?\s*">s<\/b>/.test(val));
+								doh.assertTrue(/it <font\s+id="fontline1"\s+size\s*=\s*"\s*5?\s*">i<\/font><\/div>/.test(val),"font not set on first line");
+								doh.assertTrue(/<div><font\s+size\s*=\s*"\s*5?\s*">s<\/font>/.test(val),"font not set on split line");
 							}), 500);
 
 							return d;
 						}
+					},					
+					{
+						name: "copy and paste DIV",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
 
+							var editor = dijit.byId("div3");
+							dojo.window.scrollIntoView(editor.iframe);
+							editor.set("value", "");
+							editor.focus();
+							
+							doh.robot.mouseMoveAt(editor.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+								
+							doh.robot.typeKeys("testingCopyAndPaste", 500);
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.keyPress("c", 500, metaKey);	// copy
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							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,
+										value,
+										"get('value')");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "copy and paste DIV split",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var editor = dijit.byId("div3");
+							dojo.window.scrollIntoView(editor.iframe);
+							editor.set("value", "");
+							editor.focus();
+							
+							doh.robot.mouseMoveAt(editor.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+								
+							doh.robot.typeKeys("testingCopyAndPaste", 500);
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.keyPress("c", 500, metaKey);	// copy
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								// get('value') should call the post-filter which recombines the separate <p> nodes into bigger
+								// 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,
+									value,
+									"get('value')");
+							}), 1000);
+							return d;
+						}
 					},
 					{
 						name: "Test p line split",
@@ -245,7 +394,7 @@
 							}, 500);
 							
 							//Keyboard kill the selection and shift position between i and s.
-							if(!dojo.isMoz) {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);
 
@@ -253,12 +402,82 @@
 								// Do tests here.
 								var val = editor.get("value");
 								// Check that it split the is into two and that the bold and div were properly split.
-								doh.assertTrue(val.indexOf("It <b id=\"boldLine2\">i</b></p>") > 0);
-								doh.assertTrue(val.indexOf("<p><b>s</b>") > 0);
+								doh.t(val.indexOf("It <b id=\"boldLine2\">i</b></p>") > 0, "start");
+								doh.t(val.indexOf("<p><b>s</b>") > 0, "end");
 							}), 500);
 
 							return d;
 						}
+					},
+					{
+						name: "copy and paste P",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var editor = dijit.byId("p2");
+							dojo.window.scrollIntoView(editor.iframe);
+							editor.set("value", "");
+							editor.focus();
+							
+							doh.robot.mouseMoveAt(editor.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+								
+							doh.robot.typeKeys("testingCopyAndPaste", 500);
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.keyPress("c", 500, metaKey);	// copy
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								var value = editor.get('value');
+								value = value.replace(/\xA0/g, "");
+								doh.is('<p>testingCopyAndPastetestingCopyAndPastetestingCopyAndPaste</p><p></p>',
+									value,
+									"get('value')");
+							}), 1000);
+							return d;
+						}
+					},					
+					{
+						name: "copy and paste P split",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var editor = dijit.byId("p2");
+							dojo.window.scrollIntoView(editor.iframe);
+							editor.set("value", "");
+							editor.focus();
+							
+							doh.robot.mouseMoveAt(editor.iframe, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500, {});
+								
+							doh.robot.typeKeys("testingCopyAndPaste", 500);
+							doh.robot.keyPress("a", 500, metaKey);	// select all
+							doh.robot.keyPress("c", 500, metaKey);	// copy
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress("v", 500, metaKey);	// paste
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								// get('value') should call the post-filter which recombines the separate <p> nodes into bigger
+								// paragraphs.
+								var value = editor.get('value');
+								value = value.replace(/\xA0/g, "");
+								doh.is('<p>testingCopyAndPastetestingCopyAndPastetestingCopyAndP</p><p>aste</p>',
+										value,
+										"get('value')");
+							}), 1000);
+							return d;
+						}
 					}
 				]);
 
diff --git a/dijit/tests/editor/robot/TabIndent.html b/dijit/tests/editor/robot/TabIndent.html
new file mode 100644
index 0000000..06dc319
--- /dev/null
+++ b/dijit/tests/editor/robot/TabIndent.html
@@ -0,0 +1,151 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot TabIndent 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("dojo.DeferredList");
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_TabIndent.html');
+					
+				var metaKey = {ctrl: true}
+					
+				doh.register("testTabIndent", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
+						name: "toggleDir_toggleOn",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var editor = dijit.byId("tiTest");
+							
+							doh.robot.sequence(d.getTestErrback(function(){
+								editor.setValue("<ol><li>a list item.</li><li>a list item2.</li></ol>");
+							}),500);
+							
+							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconTabIndent")[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); //make sure the last thing in the list is selected
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("<ol><li>a list item.</li><ol><li>a list item2.</li></ol></ol>", editor.getValue());
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleDir_shiftTab",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var editor = dijit.byId("tiTest");
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var editorValue = editor.getValue();
+								var valid = editorValue === "<ol><li>a list item.</li><li>a list item2.<br /></li></ol>"; //chrome
+								valid = valid || editorValue === "<ol><li>a list item.</li><li>a list item2.<br/></li></ol>"; //safari
+								valid = valid || editorValue === "<ol><li>a list item.</li><li>a list item2.</li></ol>"; //everone else
+								doh.t(valid);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleDir_toggleOff",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var editor = dijit.byId("tiTest");
+							var origValue;
+							doh.robot.sequence(d.getTestErrback(function(){ origValue = editor.getValue(); }), 1000); 
+							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconTabIndent")[0], 1000);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(editor.editNode, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//verify the editor lost focus and therefore the value did not change
+								doh.is(origValue, editor.getValue());
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleDir_toggleOn_ctrlM",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var editor = dijit.byId("tiTest");
+
+							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyPress("m", 500, {ctrl: true});
+							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); //make sure the last thing in the list is selected
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("<ol><li>a list item.</li><ol><li>a list item2.</li></ol></ol>", editor.getValue());
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleDir_toggleOff_ctrlM",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var editor = dijit.byId("tiTest");
+							var origValue;
+							doh.robot.sequence(d.getTestErrback(function(){ origValue = editor.getValue(); }), 1000); 
+							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyPress("m", 500, {ctrl: true});
+							doh.robot.mouseMoveAt(function(){ return editor.editNode }, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								//verify the editor lost focus and therefore the value did not change
+								doh.is(origValue, editor.getValue());
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/editor/robot/ToggleDir.html b/dijit/tests/editor/robot/ToggleDir.html
new file mode 100644
index 0000000..b7e27d3
--- /dev/null
+++ b/dijit/tests/editor/robot/ToggleDir.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot ToggleDir 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("dojo.DeferredList");
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_ToggleDir.html');
+					
+				var metaKey = {ctrl: true}
+					
+				doh.register("testToggleDir", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
+						name: "toggleDir_toggleOn",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconToggleDir")[0], 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("ed0", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							if(!dojo.isOpera){
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {shift: true});
+							}
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var editor = dijit.byId("ed0");
+								if(!dojo.isOpera){ /*This test is not valid in opera because the rtl test ends up being the same as the ltr test, therefore, there is no way to disnguish between the two.*/
+									var selection = dijit.range.getSelection(editor.window);
+									if(selection && selection.rangeCount){				
+										var range = selection.getRangeAt(0);
+										var firstNode = range.startContainer;
+										var startOffset = range.startOffset;
+										var selectedText = firstNode.nodeValue.charAt(startOffset);
+										doh.is(".", selectedText);
+									}else{
+										doh.t(false);
+									}
+								}
+								
+								var editDoc = editor.editorObject.contentWindow.document.documentElement;
+			                    editDoc = editDoc.getElementsByTagName("body")[0];
+			                    doh.is("rtl", editDoc.dir);
+							
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleDir_toggleOff",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconToggleDir")[0], 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("ed0", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							if(!dojo.isOpera){
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {shift: true});
+							}
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var editor = dijit.byId("ed0");
+								if(!dojo.isOpera){
+									var selection = dijit.range.getSelection(editor.window);
+									if(selection && selection.rangeCount){				
+										var range = selection.getRangeAt(0);
+										var firstNode = range.startContainer;
+										var startOffset = range.startOffset;
+										var selectedText = firstNode.nodeValue.charAt(startOffset);
+										doh.is(".", selectedText);
+									}else{
+										doh.t(false);
+									}
+								}
+								var editDoc = editor.editorObject.contentWindow.document.documentElement;
+			                    editDoc = editDoc.getElementsByTagName("body")[0];
+			                    doh.is("ltr", editDoc.dir);
+							}), 1000);
+							return d;
+						}
+					}					
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/editor/robot/ToggleDir_rtl.html b/dijit/tests/editor/robot/ToggleDir_rtl.html
new file mode 100644
index 0000000..a85277b
--- /dev/null
+++ b/dijit/tests/editor/robot/ToggleDir_rtl.html
@@ -0,0 +1,117 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot ToggleDir_rtl 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("dojo.DeferredList");
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_ToggleDir_rtl.html');
+					
+				var metaKey = {ctrl: true}
+					
+				doh.register("testToggleDir", [
+					{
+						name: "wait for editors to load",
+						timeout: 5000,
+						runTest: function(){
+						    return new dojo.DeferredList(
+						        dijit.registry.filter(function(w){ return w.onLoadDeferred; }).map(function(w){ return w.onLoadDeferred; })
+						    );
+						}
+					},
+					{
+						name: "toggleDir_toggleOn",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconToggleDir")[0], 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("ed0", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							if(!dojo.isOpera){
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {shift: true});
+							}
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var editor = dijit.byId("ed0");
+								if(!dojo.isOpera){ /*This test is not valid in opera because the rtl test ends up being the same as the ltr test, therefore, there is no way to disnguish between the two.*/
+									var selection = dijit.range.getSelection(editor.window);
+									if(selection && selection.rangeCount){				
+										var range = selection.getRangeAt(0);
+										var firstNode = range.startContainer;
+										var startOffset = range.startOffset;
+										var selectedText = firstNode.nodeValue.charAt(startOffset);
+										doh.is(".", selectedText);
+									}else{
+										doh.t(false);
+									}
+								}
+								
+								var editDoc = editor.editorObject.contentWindow.document.documentElement;
+			                    editDoc = editDoc.getElementsByTagName("body")[0];
+			                    doh.is("ltr", editDoc.dir);
+							
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "toggleDir_toggleOff",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dojo.query(".dijitEditorIconToggleDir")[0], 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.mouseMoveAt("ed0", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+							if(!dojo.isOpera){
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {shift: true});
+							}
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var editor = dijit.byId("ed0");
+								if(!dojo.isOpera){
+									var selection = dijit.range.getSelection(editor.window);
+									if(selection && selection.rangeCount){				
+										var range = selection.getRangeAt(0);
+										var firstNode = range.startContainer;
+										var startOffset = range.startOffset;
+										var selectedText = firstNode.nodeValue.charAt(startOffset);
+										doh.is(".", selectedText);
+									}else{
+										doh.t(false);
+									}
+								}
+								var editDoc = editor.editorObject.contentWindow.document.documentElement;
+			                    editDoc = editDoc.getElementsByTagName("body")[0];
+			                    doh.is("rtl", editDoc.dir);
+							}), 1000);
+							return d;
+						}
+					}					
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/editor/test_CustomPlugin.html b/dijit/tests/editor/test_CustomPlugin.html
index dec73f3..7b82f02 100644
--- a/dijit/tests/editor/test_CustomPlugin.html
+++ b/dijit/tests/editor/test_CustomPlugin.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Custom Plugin Test/Tutorial</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -34,64 +34,71 @@
 		dojo.require("dijit.Editor");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-		dojo.require("dijit._Widget");
-		dojo.require("dijit._Templated");
 		dojo.require("dijit._editor._Plugin");
 		dojo.require("dojo.string");
 
-		dojo.declare("MyPlugin",
-			dijit._editor._Plugin,
-			{
-				buttonClass: dijit.form.ToggleButton,
-				useDefaultCommand: false,
-
-				_initButton: function(){
-					this.command = "htmlToggle";
-					this.editor.commands[this.command] = "View HTML source"; // note: should be localized
-					this.iconClassPrefix = "customIcon";
-					this.inherited(arguments);
-					delete this.command; // kludge so setEditor doesn't make the button invisible
-					this.connect(this.button, "onClick", this._toggleSource);
-				},
-
-				destroy: function(f){
-					this.inherited(arguments);
-					if(this.sourceArea){ dojo.destroy(this.sourceArea); }
-				},
-
-				_toggleSource: function(){
-					this.source = !this.source;
-					if(!this.sourceArea){
-						this.sourceArea = dojo.doc.createElement('textarea');
-						this.sourceArea.style.position = 'absolute';
-						dojo.place(this.sourceArea, this.editor.domNode, "last");
-					}
-					if(this.source){
-						this.sourceArea.value = this.editor.getValue();
-						dojo.marginBox(this.sourceArea, dojo.marginBox(this.editor.editingArea));
-					}else{
-						this.editor.setValue(this.sourceArea.value);
-						this.sourceArea.style.top = "-999px";
+		dojo.addOnLoad(function(){
+			dojo.declare("MyPlugin",
+				dijit._editor._Plugin,
+				{
+					buttonClass: dijit.form.ToggleButton,
+					useDefaultCommand: false,
+	
+					_initButton: function(){
+						this.command = "htmlToggle";
+						this.editor.commands[this.command] = "View HTML source"; // note: should be localized
+						this.iconClassPrefix = "customIcon";
+						this.inherited(arguments);
+						delete this.command; // kludge so setEditor doesn't make the button invisible
+						this.connect(this.button, "onClick", this._toggleSource);
+					},
+	
+					destroy: function(f){
+						this.inherited(arguments);
+						if(this.sourceArea){ dojo.destroy(this.sourceArea); }
+					},
+	
+					_toggleSource: function(){
+						this.source = !this.source;
+						if(!this.sourceArea){
+							this.sourceArea = dojo.doc.createElement('textarea');
+							this.sourceArea.style.position = 'absolute';
+							dojo.place(this.sourceArea, this.editor.domNode, "last");
+						}
+						if(this.source){
+							this.sourceArea.value = this.editor.getValue();
+							dojo.style(this.sourceArea, "borderWidth", dojo.style(this.editor.editingArea, "borderStyle") == "none" ? "0" : dojo.style(this.editor.editingArea, "borderWidth"));
+							dojo.marginBox(this.sourceArea, dojo.marginBox(this.editor.editingArea));
+							if(dojo.isIE){
+								//work around IE oddity with offsetParent mismatch
+								var p = dojo.position(this.editor.editingArea);
+								dojo.style(this.sourceArea, { left: p.x, top: p.y });
+							}
+						}else{
+							this.editor.setValue(this.sourceArea.value);
+							this.sourceArea.style.top = "-999px";
+						}
+	
+						this.button.set('label', this.source ? "View WYSIWYG" : this.editor.commands["htmlToggle"]); // note: should be localized
 					}
-
-					this.editor.set('disabled', this.source); // conditionally disable toolbar -- FIXME. Doesn't work.
-					this.button.set('label', this.source ? "View WYSIWYG" : this.editor.commands[this.command]); // note: should be localized
 				}
-			}
-		);
-
-		/* the following code registers my plugin */
-		dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
-			if(o.plugin){ return; }
-			if(o.args.name == "MyPlugin"){
-				return new MyPlugin({});
-			}
+			);
+	
+			/* the following code registers my plugin */
+			dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+				if(o.plugin){ return; }
+				if(o.args.name == "MyPlugin"){
+					return new MyPlugin({});
+				}
+			});
+			
+			dojo.parser.parse();
 		});
 	</script>
 </head>
 <body class="claro">
-	<div dojoType="dijit.Editor" id="editor1" extraPlugins="['MyPlugin']"><p>
+	<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["MyPlugin"]'><p>
 	This editor should have my custom plugin
 	</p></div>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/dijit/tests/editor/test_Editor.html b/dijit/tests/editor/test_Editor.html
index b1fe5b9..c6f09c4 100644
--- a/dijit/tests/editor/test_Editor.html
+++ b/dijit/tests/editor/test_Editor.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -30,33 +30,38 @@
 		dojo.require("dijit._editor.plugins.LinkDialog");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-		// 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], {
-			setEditor: function(editor){
-				this.editor = editor;
-				this.editor.contentPreFilters.push(function(val){
-					if(val){
-						val = val.replace("notdojo", "DOJO");
-					}
-					return val;
-				});
-			}
-		});
-
 		dojo.addOnLoad(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], {
+				setEditor: function(editor){
+					this.editor = editor;
+					this.editor.contentPreFilters.push(function(val){
+						if(val){
+							val = val.replace("notdojo", "DOJO");
+						}
+						return val;
+					});
+				}
+			});
+
+			dojo.parser.parse();
+
 			var progEditor = new dijit.Editor({
 				value: "Custom Initial Content."
 			}, "programmatic3");
 
+			var progEditor = new dijit.Editor({
+				contentPreFilters: [function(txt) { return txt; }]		
+			}, "programmatic4");
 		});
 
 	</script>
 </head>
 
 <body class="claro">
-	<div dojoType="dijit.Editor" id="automated" height="1.5em" plugins="[]" focusOnLoad="true" style="border:0px;"
-	>Automated Test - all check boxes should be checked<script type='dojo/method' event='onFocus'>
+	<div data-dojo-type="dijit.Editor" data-dojo-props="plugins:[], focusOnLoad:true, height:'1.5em', style:'border:0px;'" id="automated"
+	>Automated Test - all check boxes should be checked<script type='dojo/method' data-dojo-event='onFocus'>
 			if(!document.getElementById('onFocusFired').checked){
 				document.getElementById('onFocusFired').checked=true;
 				document.getElementById('initialValueOK').checked = (dijit.byId('automated').getValue() == 'Automated Test - all check boxes should be checked');
@@ -66,7 +71,7 @@
 				setTimeout(dojo.hitch(dijit.byId('editor0'),"focus",0));
 			}
 		</script
-		><script type='dojo/method' event='onBlur'>
+		><script type='dojo/method' data-dojo-event='onBlur'>
 			if(!document.getElementById('onBlurFired').checked){
 				document.getElementById('onBlurFired').checked=true;
 				dijit.byId('automated').set('disabled', true);
@@ -76,45 +81,45 @@
 				} catch(e) { document.getElementById('disabledOK').checked = true; }}, 0);
 			}
 		</script
-		><script type='dojo/method' event='onChange'>
+		><script type='dojo/method' data-dojo-event='onChange'>
 			if(document.getElementById('onChangeOKnow').checked && !document.getElementById('onChangeFired').checked){
 				document.getElementById('onChangeFired').checked=true;
 			}
 		</script
 	></div>
-	Focus:<input type="checkbox" id="onFocusFired" disabled autoComplete="off">
-	Value:<input type="checkbox" id="initialValueOK" disabled autoComplete="off">
-	<input type="checkbox" id="onChangeOKnow" disabled autoComplete="off" style="display:none;">
-	Change:<input type="checkbox" id="onChangeFired" disabled autoComplete="off">
-	Blur:<input type="checkbox" id="onBlurFired" disabled autoComplete="off">
-	Disabled:<input type="checkbox" id="disabledOK" disabled autoComplete="off">
+	Focus:<input type="checkbox" id="onFocusFired" disabled />
+	Value:<input type="checkbox" id="initialValueOK" disabled />
+	<input type="checkbox" id="onChangeOKnow" disabled style="display:none;"/>
+	Change:<input type="checkbox" id="onChangeFired" disabled />
+	Blur:<input type="checkbox" id="onBlurFired" disabled />
+	Disabled:<input type="checkbox" id="disabledOK" disabled />
 	<br>
 	<br>
 
-	<h1 class="testTitle"><label for="editor1">Editor + Plugins Test</label></h1>
+	<h1 class="testTitle">Editor + Plugins Test</h1>
 
 	<h2>No plugins, initially empty</h2>
-	<div dojoType="dijit.Editor" id="editor0" height="100" plugins="[]"></div>
+	<div data-dojo-type="dijit.Editor" data-dojo-props="plugins:[], height:'100'" id="editor0"></div>
 
 	<h2>Created from div</h2>
-	<input id="focusBefore" value="input before editor1">
-	<div dojoType="dijit.Editor" id="editor1" disableSpellCheck="true"
-		onChange="console.log('editor1 onChange handler: ' + arguments[0])"
+	<input id="focusBefore" value="input before editor1"/>
+	<div data-dojo-type="dijit.Editor" data-dojo-props="onChange:function(v){console.log('editor1 onChange handler: ' + v)}, disableSpellCheck:true" id="editor1"
 	><p>This instance is created from a div directly with default toolbar and plugins</p>
 	The following HTML should appear as source: <INPUT TYPE="IMAGE" SRC="javascript:alert('no scripting attacks')">
 	</div>
-	<input id="focusAfter" value="input after editor1">
+	<input id="focusAfter" value="input after editor1"/>
 	<button onClick="dijit.byId('editor1').destroy()">destroy</button>
 	<button onClick="dijit.byId('editor1').set('disableSpellCheck', !dijit.byId('editor1').get('disableSpellCheck'))">toggle spell check</button>
 	<button onclick="console.log(dijit.byId('editor1').get('value'))">getValue</button>
+	<button id="addStyleSheet" onclick="dijit.byId('editor1').addStyleSheet('test_editor.css')">add stylesheet</button>
+	<button id="removeStyleSheet" onclick="dijit.byId('editor1').removeStyleSheet('test_editor.css')">remove stylesheet</button>
 	<hr/>
 
 	<h2>Created from div, auto-expanding</h2>
-	<h3><label for="thud">label for editor:</label></h3>
-	<div dojoType="dijit.Editor" height="" minHeight="75px"
-		onChange="console.log('thud onChange handler: ' + arguments[0])"
-		extraPlugins="['dijit._editor.plugins.AlwaysShowToolbar']"
-		styleSheets="../../../dojo/resources/dojo.css" id="thud">
+	<h3><label>label for editor:</label></h3>
+	<div data-dojo-type="dijit.Editor" 
+		data-dojo-props="onChange:function(v){console.log('thud onChange handler: ' + v)}, extraPlugins:['dijit._editor.plugins.AlwaysShowToolbar'], styleSheets:'../../themes/claro/document.css', minHeight:'75px', height:''"
+		id="thud">
 		Extra text
 		<p>
 			This editor is created from a div with AlwaysShowToolbar plugin (do not forget to set height="").
@@ -133,10 +138,10 @@
 	<hr/>
 
 	<h2>Optional toolbar buttons</h2>
-	<h3><label for="blah">blah entry</label></h3>
-	<div dojoType="dijit.Editor"
-		plugins="['bold','italic','|','createLink','foreColor','hiliteColor',{name:'dijit._editor.plugins.FontChoice', command:'fontName', generic:true},'fontSize','formatBlock','insertImage','insertHorizontalRule']"
-		styleSheets="../../../dojo/resources/dojo.css" id="blah">
+	<h3><label>blah entry</label></h3>
+	<div data-dojo-type="dijit.Editor"
+		data-dojo-props="plugins:['bold','italic','|','createLink','foreColor','hiliteColor',{name:'dijit._editor.plugins.FontChoice', command:'fontName', generic:true},'fontSize','formatBlock','insertImage','insertHorizontalRule'], styleSheets:'../../themes/claro/document.css'"
+		id="blah">
 		This instance includes optional toolbar buttons which pull in additional ui (dijit) code.
 		Note the dojo.require() statements required to pull in the associated editor plugins to make
 		this work.
@@ -157,10 +162,10 @@
 	<hr/>
 
 	<h2>Plugins specified</h2>
-	<h3><label for="blah2">Another blah entry</label></h3>
-	<div dojoType="dijit.Editor"
-		plugins="['bold','italic','|',{name:'dijit._editor.plugins.FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond','Apple Chancery','Hiragino Mincho Pro']}, {name:'dijit._editor.plugins.FontChoice', command:'fontSize', custom:[3,4,5]}, {name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'DIV'}]"
-		styleSheets="../../../dojo/resources/dojo.css" id="blah2">
+	<h3><label>Another blah entry</label></h3>
+	<div data-dojo-type="dijit.Editor"
+		data-dojo-props="plugins:['bold','italic','|',{name:'dijit._editor.plugins.FontChoice', command:'fontName', custom:['Verdana','Myriad','Garamond','Apple Chancery','Hiragino Mincho Pro']}, {name:'dijit._editor.plugins.FontChoice', command:'fontSize', custom:[3,4,5]}, {name:'dijit._editor.plugins.EnterKeyHandling', blockNodeForEnter:'DIV'}], styleSheets:'../../themes/claro/document.css'"
+		id="blah2">
 		This instance demos how to:
 		<ol>
 			<li>specify which plugins to load (see the plugins property): this instance loads FontChoice plugin, among others;</li>
@@ -171,17 +176,17 @@
 	<hr/>
 
 	<h2>Font sizing via style</h2> 
-	<div dojoType="dijit.Editor" style="text-align:left; font-size:30pt" id="fontSizedEditor"> 
+	<div data-dojo-type="dijit.Editor" data-dojo-props="style:'text-align:left; font-size:30pt'" id="fontSizedEditor"> 
 		Hello World! 
 	</div> 
 
 	<h2>Checking pre-filter application</h2> 
-	<div dojoType="dijit.Editor" id="filteredEditor" extraPlugins="[{name: 'dijit.tests.editor.TestFilter'}]"> 
+	<div data-dojo-type="dijit.Editor" data-dojo-props="extraPlugins:[{name: 'dijit.tests.editor.TestFilter'}]" id="filteredEditor"> 
 		notdojo 
 	</div> 
 
 	<h2>Checking editor starting with br</h2> 
-	<div dojoType="dijit.Editor" id="brEditor"> 
+	<div data-dojo-type="dijit.Editor" id="brEditor"> 
 		<br>
 		some stuff
 		<br>
@@ -204,5 +209,8 @@
 
 	<br><br>    
 	<div id="programmatic3">This div will become a programmatic editor in addOnLoad with creation-defined default content.</div>
+	<br><br>
+	<div id="programmatic4">This div will become a programmatic editor in addOnLoad with creation-defined and custom filters.</div>
+
 </body>
 </html>
diff --git a/dijit/tests/editor/test_FontChoice.html b/dijit/tests/editor/test_FontChoice.html
index bb302a3..82c41e9 100755
--- a/dijit/tests/editor/test_FontChoice.html
+++ b/dijit/tests/editor/test_FontChoice.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: FontChoice Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -30,8 +30,8 @@
 	<br>
 	<br>
 	<p>Editor with default drop down lists:</p>
-	<div dojoType="dijit.Editor"
-		extraPlugins="['fontName', 'fontSize', 'formatBlock', 'viewSource']" style="background-color: white; width: 100% height: 400px;" id="editor0">
+	<div id="editor0" data-dojo-type="dijit.Editor"
+		data-dojo-props='extraPlugins:["fontName", "fontSize", "formatBlock", "viewSource"], height: "400px", style:"background-color: white; width: 100%;"'>
 		<h1>Font Choice Plugin details</h1>
 		<ol>
 			<li>The Fontchoice plugin provides three dropdown menus for manipulating font information, such as
@@ -101,8 +101,8 @@
 	<br>
 	<br>
 	<p>Editor w/ plain text dropdown values:</p>
-	<div dojoType="dijit.Editor"
-		extraPlugins="[{name: 'fontName', plainText: true}, {name: 'fontSize', plainText: true}, {name: 'formatBlock', plainText: true}, 'viewSource']" style="background-color: white; width: 100%; height: 400px;" id="editor1">
+	<div id="editor1" data-dojo-type="dijit.Editor"
+		data-dojo-props='extraPlugins:[{name: "fontName", plainText: true}, {name: "fontSize", plainText: true}, {name: "formatBlock", plainText: true}, "viewSource"], style:"background-color: white; width: 100%;", height: "400px"'>
 		<h1>Font Choice Plugin details</h1>
 		<ol>
 			<li>This instance of the FontChoice plugin just turns off formatted content in the dropdowns.  Everything should be the same font and size.</li>
@@ -119,8 +119,8 @@
 	<br>
 	<br>
 	<p>Editor w/ generic (web font names) font selector, traditional font name selector, font size selector, and format block selector:</p>
-	<div dojoType="dijit.Editor" id="generic" height="10em"
-		plugins="['bold', 'italic', 'underline', {name: 'dijit._editor.plugins.FontChoice', command: 'fontName', generic: true}, 'fontName', 'fontSize', 'formatBlock']">hello world</div>
+	<div id="generic" data-dojo-type="dijit.Editor" data-dojo-props='height:"10em",
+		plugins:["bold", "italic", "underline", {name: "dijit._editor.plugins.FontChoice", command: "fontName", generic: true}, "fontName", "fontSize", "formatBlock"]'>hello world</div>
 	<br>
 	<br>
 	<div>Content after the editor.</div>
@@ -130,10 +130,10 @@
 	<br>
 	<br>
 	<p>Editor w/ custom font drop down list:</p>
-	<div dojoType="dijit.Editor" id="custom" height="10em"
-		plugins="['bold', 'italic', 'underline', {name: 'dijit._editor.plugins.FontChoice', command: 'fontName', custom:['Verdana','Myriad','Garamond']}]">
+	<div id="custom" data-dojo-type="dijit.Editor" data-dojo-props='height:"10em",
+		plugins:["bold", "italic", "underline", {name: "dijit._editor.plugins.FontChoice", command: "fontName", custom:["Verdana","Myriad","Garamond"]}]'>
 			This editor should let you set the fonts to
-			<font face="Verdana">Verdana</font>, <font face="Myriad">Myriad</font>, and <font face="Garamond">Garamond</font>.
+			<span style="font-family:Verdana;">Verdana</span>, <span style="font-family:Myriad;">Myriad</span>, and <span style="font-family:Garamond;">Garamond</span>.
 	</div>
 	<br>
 	<br>
diff --git a/dijit/tests/editor/test_FullScreen.html b/dijit/tests/editor/test_FullScreen.html
index c2cb827..2e852f8 100755
--- a/dijit/tests/editor/test_FullScreen.html
+++ b/dijit/tests/editor/test_FullScreen.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: FullScreen Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -34,8 +34,8 @@
 	<div>Content before the editor.</div>
 	<br>
 	<br>
-	<div dojoType="dijit.Editor"
-		extraPlugins="['fullscreen']" style="background-color: white; width: 800px; height: 400px;" id="editor0">
+	<div id="editor0" data-dojo-type="dijit.Editor"
+		data-dojo-props='extraPlugins:["fullscreen"], style:"background-color: white; width: 800px; height: 400px;" '>
 		<h1>Full Screen Plugin details</h1>
 		<ol>
 			<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -64,13 +64,13 @@
 	<div>Content after the editor.</div>
 	<br>
 	<h1>BorderContainer with center region containing editor.</h1>
-	<div dojoType="dijit.layout.BorderContainer" id="bc" style="width: 600px; height: 500px;">
-		<div dojoType="dijit.layout.ContentPane" region="left" style="width: 50px;">left</div>
-		<div dojoType="dijit.layout.ContentPane" region="top" style="height: 50px;">top</div>
-		<div dojoType="dijit.layout.ContentPane" region="right" style="width: 50px;">right</div>
-		<div dojoType="dijit.layout.ContentPane" region="bottom" style="height: 50px;">bottom</div>
-		<div dojoType="dijit.layout.ContentPane" region="center">
-			<div dojoType="dijit.Editor" extraPlugins="['fullscreen','viewsource']" id="editor1" height="100%">
+	<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"width: 600px; height: 500px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width: 50px;"'>left</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"height: 50px;"'>top</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", style:"width: 50px;"'>right</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"height: 50px;"'>bottom</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
+			<div id="editor1" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -98,9 +98,9 @@
 	</div>
 	<br>
 	<h1>TabContainer with tab containing editor.</h1>
-	<div dojoType="dijit.layout.TabContainer" id="tc" style="width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;">
-		<div dojoType="dijit.layout.ContentPane" title="Editor Tab">
-			<div dojoType="dijit.Editor" extraPlugins="['fullscreen','viewsource']" id="editor2" height="100%">
+	<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor Tab"'>
+			<div id="editor2" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -125,18 +125,18 @@
 				</ol>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Tab 1">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Tab 1"'>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Tab 2">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Tab 2"'>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Tab 3">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Tab 3"'>
 		</div>
 	</div>
 	<br>
 	<h1>AccordionContainer with pane containing editor.</h1>
-	<div dojoType="dijit.layout.AccordionContainer" id="ac" style="width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;">
-		<div dojoType="dijit.layout.ContentPane" title="Editor Pane">
-			<div dojoType="dijit.Editor" extraPlugins="['fullscreen','viewsource']" id="editor3" height="100%">
+	<div id="ac" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor Pane"'>
+			<div id="editor3" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -161,18 +161,18 @@
 				</ol>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Pane 1">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 1"'>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Pane 2">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 2"'>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Pane 3">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 3"'>
 		</div>
 	</div>
 	<br>
 	<h1>StackContainer with pane containing editor.</h1>
-	<div dojoType="dijit.layout.StackContainer" id="sc" style="width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;">
-		<div dojoType="dijit.layout.ContentPane" title="Editor Pane">
-			<div dojoType="dijit.Editor" extraPlugins="['fullscreen','viewsource']" id="editor4" height="100%">
+	<div id="sc" data-dojo-type="dijit.layout.StackContainer" data-dojo-props='style:"width: 600px; height: 500px; border-style: solid; border-width: 1px; padding: 0px; margin: 0px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor Pane"'>
+			<div id="editor4" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["fullscreen","viewsource"], height:"100%"'>
 				<h1>Full Screen Plugin details</h1>
 				<ol>
 					<li>The Fullscreen plugin provides an extra button on the toolbar to allow switching the
@@ -197,11 +197,11 @@
 				</ol>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Pane 1">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 1"'>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Pane 2">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 2"'>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="Blank Pane 3">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Blank Pane 3"'>
 		</div>
 	</div>
 </body>
diff --git a/dijit/tests/editor/test_LinkDialog.html b/dijit/tests/editor/test_LinkDialog.html
index 02b8e0e..66f2a5c 100755
--- a/dijit/tests/editor/test_LinkDialog.html
+++ b/dijit/tests/editor/test_LinkDialog.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: LinkDialog Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -25,8 +25,7 @@
 </head>
 <body class="claro">
 	<div style="border: 1px dotted black;">
-		<div dojoType="dijit.Editor" id="editor"
-			extraPlugins="['createLink', 'insertImage', 'viewSource']">
+		<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
diff --git a/dijit/tests/editor/test_NewPage.html b/dijit/tests/editor/test_NewPage.html
index 96d0af4..371bc9b 100755
--- a/dijit/tests/editor/test_NewPage.html
+++ b/dijit/tests/editor/test_NewPage.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: New Page Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -28,8 +28,8 @@
 	<div>Content before the editor.</div>
 	<br>
 	<br>
-	<div dojoType="dijit.Editor"
-		extraPlugins="['newpage']" style="background-color: white; width: 800px;" height="400px" id="editor0">
+	<div id="editor0" data-dojo-type="dijit.Editor"
+		data-dojo-props='extraPlugins:["newpage"], style:"background-color: white; width: 800px;", height:"400px" '>
 		<h1>New Page Plugin details</h1>
 		<ol>
 			<li>The new page plugin is a small plugin that adds the capability of making a 'new page'.  In other words
@@ -43,8 +43,8 @@
 	</div>
 	<br>
 	<br>
-	<div dojoType="dijit.Editor"
-		extraPlugins="[{name: 'newpage', content: '<p>This page intentionally left blank</p>'}]" style="background-color: white; width: 800px;" height="400px" id="editor1">
+	<div id="editor1" data-dojo-type="dijit.Editor"
+		data-dojo-props='extraPlugins:[{name: "newpage", content: "<p>This page intentionally left blank</p>"}], style:"background-color: white; width: 800px;", height:"400px" '>
 		<h1>New Page Plugin details</h1>
 		<ol>
 			<li>The new page plugin is a small plugin that adds the capability of making a 'new page'.  In other words
diff --git a/dijit/tests/editor/test_Print.html b/dijit/tests/editor/test_Print.html
index c2d6a89..f5ff6df 100755
--- a/dijit/tests/editor/test_Print.html
+++ b/dijit/tests/editor/test_Print.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: Print  Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -28,8 +28,8 @@
 	<div>Content before the editor.</div>
 	<br>
 	<br>
-	<div dojoType="dijit.Editor"
-		extraPlugins="['print']" style="background-color: white; width: 800px; height: 400px;" id="editor0">
+	<div id="editor0" data-dojo-type="dijit.Editor"
+		data-dojo-props='extraPlugins:["print"], style:"background-color: white; width: 800px;", height: "400px"'>
 		<h1>Print Plugin details</h1>
 		<ol>
 			<li>The print plugin is a small plugin that adds the capability of printing the document in the editor</li>
diff --git a/dijit/tests/editor/test_RichText.html b/dijit/tests/editor/test_RichText.html
deleted file mode 100644
index 51b1948..0000000
--- a/dijit/tests/editor/test_RichText.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-
-	<title>Rich Text System Test</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-	</style>
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript" src="../../_editor/selection.js"></script>
-	<script type="text/javascript" src="../../_editor/RichText.js"></script>
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit._editor.RichText");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-
-</head>
-<body>
-
-	<h1 class="testTitle">Rich Text Test</h1>
-
-	<div style="border: 1px dotted black;">
-		<h3>thud</h3>
-		<textarea dojoType="dijit._editor.RichText" id="editor1"
-			styleSheets="../../../dojo/resources/dojo.css">
-			<h1>header one</h1>
-			<ul>
-				<li>Right click on the client area of the page (ctrl-click for Macintosh). Menu should open.</li>
-				<li>Right click on each of the form controls above. Menu should open.</li>
-				<li>Right click near the righthand window border. Menu should open to the left of the pointer.</li>
-				<li>Right click near the bottom window border. Menu should open above the pointer.</li>
-			</ul>
-		</textarea>
-		<button onclick="dijit.byId('editor1').addStyleSheet('test_richtext.css')">add stylesheet</button>
-		<button onclick="dijit.byId('editor1').removeStyleSheet('test_richtext.css')">remove stylesheet</button>
-	</div>
-
-	<div style="border: 1px dotted black;">
-		<h3>blah</h3>
-		<div dojoType="dijit._editor.RichText"
-			styleSheets="../../dojo/resources/dojo.css">
-			<ul>
-				<li>Right click on the client area of the page (ctrl-click for Macintosh). Menu should open.</li>
-				<li>Right click on each of the form controls above. Menu should open.</li>
-				<li>Right click near the righthand window border. Menu should open to the left of the pointer.</li>
-				<li>Right click near the bottom window border. Menu should open above the pointer.</li>
-			</ul>
-		</div>
-		<h3>..after</h3>
-	</div>
-
-</body>
-</html>
diff --git a/dijit/tests/editor/test_TabIndent.html b/dijit/tests/editor/test_TabIndent.html
index dcf22b5..ad32fb7 100644
--- a/dijit/tests/editor/test_TabIndent.html
+++ b/dijit/tests/editor/test_TabIndent.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor TabIndent Plugin Test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 	<script type="text/javascript">
@@ -23,12 +23,12 @@
 </head>
 <body class="claro">
 	<p>Paragraph with focusable <span tabindex="0" style="color:blue">item </span>before editor. </p>
-	<label for="tiTest">Test TabIndent Plugin</label>
+	<label>Test TabIndent Plugin</label>
 	<div style="border: 1px dotted black;">
 	
-		<div id="tiTest" dojoType="dijit.Editor"
-			extraPlugins="['tabIndent','|','dijit._editor.plugins.TabIndent','|',{name:'dijit._editor.plugins.TabIndent'}]">
-			<p>
+		<div id="tiTest" data-dojo-type="dijit.Editor"
+			data-dojo-props='extraPlugins:["tabIndent"]'>
+			<div>
 				<ol>
 				<li>the tabIndent plugin allows the use of the tab and shift-tab keys to
 indent list items.</li>
@@ -36,7 +36,7 @@ indent list items.</li>
 				<li>and another</li>
 				<li>still one more</li>
 				</ol>
-			</p>
+			</div>
 			<p>
 				Ctrl-M also turns tab indent on/off.
 				(The buttons should change checked status when the user types
diff --git a/dijit/tests/editor/test_ToggleDir.html b/dijit/tests/editor/test_ToggleDir.html
index 6200b7a..b9004d0 100644
--- a/dijit/tests/editor/test_ToggleDir.html
+++ b/dijit/tests/editor/test_ToggleDir.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: ToggleDir Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -25,13 +25,9 @@
 </head>
 <body class="claro">
 	<div style="border: 1px dotted black;">
-		<div dojoType="dijit.Editor"
-			extraPlugins="['toggleDir','|','dijit._editor.plugins.ToggleDir','|',{name:'dijit._editor.plugins.ToggleDir'}]">
-			<ol>
-				<li>the toggleDir plugin provides an extra button on the toolbar to switch text direction (BiDi) of the
-					edited document.  Useful when right-to-left languages like Hebrew and Arabic are combined with
-					left-to-right languages like English.</li>
-			</ol>
+		<div id="ed0" data-dojo-type="dijit.Editor" data-dojo-props='extraPlugins:["dijit._editor.plugins.ToggleDir"]'>
+			<ol><li>the toggleDir plugin provides an extra button to switch text direction (BiDi). Useful when right-to-left 
+					languages are used with left-to-right languages.</li></ol>
 		</div>
 	</div>
 </body>
diff --git a/dijit/tests/editor/test_ToggleDir_rtl.html b/dijit/tests/editor/test_ToggleDir_rtl.html
index 66483bb..ab8de26 100755
--- a/dijit/tests/editor/test_ToggleDir_rtl.html
+++ b/dijit/tests/editor/test_ToggleDir_rtl.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<!DOCTYPE html>
+<html style="overflow:hidden"> <!-- hide the scroll bars on ie6, to work around a doh robot bug-->
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: ToggleDir Plugin (page in RTL)</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
@@ -24,14 +24,11 @@
 	</script>
 </head>
 <body class="claro" dir="rtl">
+<div style="position:absolute;left:0px;" id=dummy>Text</div>
 	<div style="border: 1px dotted black;">
-		<div dojoType="dijit.Editor"
-			extraPlugins="['toggleDir','|','dijit._editor.plugins.ToggleDir','|',{name:'dijit._editor.plugins.ToggleDir'}]">
-			<ol>
-				<li>the toggleDir plugin provides an extra button on the toolbar to switch text direction (BiDi) of the
-					edited document.  Useful when right-to-left languages like Hebrew and Arabic are combined with
-					left-to-right languages like English.</li>
-			</ol>
+		<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 
+					languages are used with left-to-right languages.</li></ol>
 		</div>
 	</div>
 </body>
diff --git a/dijit/tests/editor/test_ViewSource.html b/dijit/tests/editor/test_ViewSource.html
index 14e6790..0da4f18 100755
--- a/dijit/tests/editor/test_ViewSource.html
+++ b/dijit/tests/editor/test_ViewSource.html
@@ -1,17 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Editor Test: ViewSource Plugin</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!--<script type="text/javascript" src="../_testCommon.js"></script>-->
 
@@ -29,8 +29,8 @@
 	<br>
 	<br>
 	<div>
-		<div dojoType="dijit.Editor"
-			extraPlugins="['viewsource']" style="background-color: white; width: 800px;" height="400px" id="editor0">
+		<div id="editor0" data-dojo-type="dijit.Editor"
+			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
@@ -56,12 +56,12 @@
 					toggled off.</li>
 			</ol>
 		</div>
-	<div>
+	</div>
 	<br>
 	<br>
 	<div>
-		<div dojoType="dijit.Editor"
-			extraPlugins="['fullscreen','viewsource']" style="background-color: white; width: 800px;" height="300px" id="editor1">
+		<div id="editor1" data-dojo-type="dijit.Editor"
+			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>
@@ -73,12 +73,12 @@
 					view source mode on and scales appropriately.</li>
 			</ol>
 		</div>
-	<div>
+	</div>
 	<br>
 	<br>
 	<div>
-		<div dojoType="dijit.Editor"
-			extraPlugins="['fullscreen',{name: 'viewsource', readOnly: true}]" style="background-color: white; width: 800px;" height="300px" id="editor2">
+		<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" '>
 			<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>
@@ -89,13 +89,13 @@
 				<li>Verify that while in View Source mode, the source cannot be edited.</li>
 			</ol>
 		</div>
-	<div>
+	</div>
 	<br>
 	<br>
 	<div>
-		<div dojoType="dijit.Editor"
-			extraPlugins="['fullscreen',{name: 'viewsource', stripScripts: false, stripComments: false, stripIFrames: false}]"
-			style="background-color: white; width: 800px;" height="300px" id="editor3">
+		<div id="editor3" data-dojo-type="dijit.Editor"
+			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>
 				<li>The ViewSource plugin supports disabling the script stripping, comment stripping, etc.  This can be dangerous, but sometimes it is desirable.</li>
@@ -106,7 +106,7 @@
 				<li>Verify that typed in script tags, comments, and iframes are left in the content when view switched.</li>
 			</ol>
 		</div>
-	<div>
+	</div>
 	<br>
 	<br>
 	<div>Content after the editors.</div>
diff --git a/dijit/tests/editor/test_richtext.css b/dijit/tests/editor/test_editor.css
similarity index 100%
rename from dijit/tests/editor/test_richtext.css
rename to dijit/tests/editor/test_editor.css
diff --git a/dijit/tests/editor/test_resize.html b/dijit/tests/editor/test_resize.html
deleted file mode 100755
index 97db52d..0000000
--- a/dijit/tests/editor/test_resize.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Editor in a BorderContainer</title>
-
-	<link rel="stylesheet" href="../../themes/tundra/tundra.css">
-
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.layout.BorderContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.Editor");
-		dojo.require("dijit._editor.plugins.AlwaysShowToolbar");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-</head>
-<body class="claro">
-	<h1>Editor in a BorderContainer</h1>
-	<p>Tests that a BorderContainer can correctly size the Editor (by calling Editor.resize()).</p>
-	<div dojoType="dijit.layout.BorderContainer" style="height: 400px;border:1px solid black;">
-		<div dojoType="dijit.layout.ContentPane" region="top" splitter="true" style="height: 100px">
-			Top pane
-		</div>
-		<div dojoType="dijit.Editor" id="editor1" region="center" height="100%">
-			Editor (center pane)
-		</div>
-	</div>
-</body>
-</html>
diff --git a/dijit/tests/form/DateTextBox.html b/dijit/tests/form/DateTextBox.html
new file mode 100644
index 0000000..197e9d2
--- /dev/null
+++ b/dijit/tests/form/DateTextBox.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>DateTextBox DOH Test</title>
+
+	<style>
+		@import "../../../dojo/resources/dojo.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true"></script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<!-- only needed for alternate theme testing: do NOT use in your code! -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+
+	<script type="text/javascript">
+		dojo.require('doh.runner');
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.DateTextBox");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+		dojo.addOnLoad(function(){
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("tests",
+				function noYear(){
+					var widget = dijit.byId("noyear");
+					doh.t(widget.isValid(false), "isValid");
+					doh.is(2011, widget.get('value').getFullYear(), "programmatic value");
+					doh.is(2011, widget.value.getFullYear(), "JS value");
+				}
+			);
+
+			doh.run();
+
+		});
+	</script>
+
+</head>
+<body class="claro">
+	<h1 class="testTitle">dijit.form.DateTextBox automated tests (non-robot)</h1>
+	
+	<label for="noyear">Pick a day in 3Q 2011</label>
+	<input data-dojo-type="dijit.form.DateTextBox" id="noyear", data-dojo-props='
+		required:"true",
+		constraints:{datePattern:"MMMM dd",
+			min:new Date(2011,9,1),
+			max:new Date(2011,11,31)
+		},
+		parse:function(){
+			var d = this.inherited("parse", arguments);
+			if(d instanceof Date)d.setFullYear(2011);
+			return d;
+		},
+		value:new Date(2011,10,25)'
+	/>
+</body>
+</html>
diff --git a/dijit/tests/form/Form.html b/dijit/tests/form/Form.html
index c82c1ff..075fa0a 100644
--- a/dijit/tests/form/Form.html
+++ b/dijit/tests/form/Form.html
@@ -1,20 +1,23 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Form unit test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
+		TD { border:2px outset; padding:2px; }
+		TH { border:2px solid; font-weight: bold; padding:1px; }
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -22,9 +25,9 @@
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dojo.date");
+		dojo.require("dojo.parser");
 		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");
@@ -67,14 +70,15 @@
 							foo: {bar: {baz: {quux: d("2007-12-30")} } },
 							available: {from: d("2005-01-02"), to: d("2006-01-02")},
 							plop: {combo: "one"},
-							cb2: ["2", "3"],
-							r2: "2",
+							cb: ["2", "3"],
+							r: "2",
 							ms1: ["VA", "WA"],
 							h1: "hidden",
 							t1: "line 1\nline 2",
 							st1: "simple line 1\nsimple line 2",
 							richtext: "<h1>original</h1><p>This is the default content</p>",
 							filename: "",
+							requiredWidget: "",
 							readOnlyWidget: "Should be returned",
 							duplicate: ["first", "second", "third"]
 						};
@@ -84,42 +88,33 @@
 							foo: {bar: {baz: {quux: d("2005-01-01")} } },
 							available: {from: d("2005-11-02"), to: d("2006-11-02")},
 							plop: {combo: "three"},
-							cb2: ["4"],
-							r2: "1",
+							cb: ["4"],
+							r: "1",
 							ms1: ["FL", "CA"],
 							h1: "still hidden",
 							t1: "new line 1\nnew line 2",
 							st1: "new simple line 1\nnew simple line 2",
 							richtext: "<h1>changed</h1><p>This is the changed content set by set('value', ...')</p>",
 							filename: "",
+							requiredWidget: "abc",
 							readOnlyWidget: "Should be returned",
 							duplicate: ["1", "2", "3"]
 						};
-		var particalchanged = {
+		var partialChange = {
 							foo: {bar: {baz: {quux: d("2006-01-01")} } },
 							available: {from: d("2006-11-02"), to: d("2007-11-02")},
 							plop: {combo: "two"},
-							cb2: ["2"]
+							cb: ["2"]
 		};
-		// we reset the form to these values
-		var reset =	{
-							foo: {bar: {baz: {quux: d("2007-12-30")} } },
-							available: {from: d("2005-01-02"), to: d("2006-01-02")},
-							plop: {combo: "one"},
-							cb2: ["2", "3"],
-							r2: "2",
-							ms1: ["VA", "WA"],
-							h1: "hidden",
-							t1: "line 1\nline 2",
-							st1: "simple line 1\nsimple line 2",
-							richtext: "<h1>changed</h1><p>This is the changed content set by set('value', ...')</p>", // not a form element, so not reset
-							filename: "",
-							readOnlyWidget: "Should be returned",
-							duplicate: ["first", "second", "third"]
-						};
 
 		dojo.addOnLoad(function(){
 
+			doh.register("parse", function(){
+				dojo.parser.parse();
+
+				formWidget = dijit.byId("myForm");
+			});
+
 			// should be able to query for all of the inputs, including hidden ones
 			doh.register("query input by checked state", [
 				{
@@ -128,9 +123,9 @@
 						var queried=dojo.query("input[checked]");
 						doh.t(queried.length>0,"dojo.query could not find checked widgets.");
 						doh.is(3,queried.length,"expected: 3 checked widgets, got: "+queried.length);
-						doh.is(dojo.byId('dijit_form_CheckBox_1'),queried[0],"Expected 2nd checkbox.");
-						doh.is(dojo.byId('dijit_form_CheckBox_2'),queried[1],"Expected 3rd checkbox.");
-						doh.is(dojo.byId('dijit_form_RadioButton_1'),queried[2],"Expected 2nd radio button.");
+						doh.is(dojo.byId('cb_2'),queried[0],"Expected 2nd checkbox.");
+						doh.is(dojo.byId('cb_3'),queried[1],"Expected 3rd checkbox.");
+						doh.is(dojo.byId('r_2'),queried[2],"Expected 2nd radio button.");
 					}
 				}
 			]);
@@ -140,8 +135,8 @@
 					[
 						"foo.bar.baz.quux","available.from","available.to", // DateTextBox
 						"plop.combo", // ComboBox
-						"cb2", // CheckBox
-						"r2", // RadioButton
+						"cb", // CheckBox
+						"r", // RadioButton
 						//"ms1", // MultiSelect
 						"h1", // plain hidden input
 						//"t1", "st1", // TextArea
@@ -163,15 +158,14 @@
 			);
 
 			var resetready=false;
-			var formWidget = dijit.byId("myForm");
 			var testSubmittedValues = function(deferred, testValues, formValues){
 				deferred.getTestCallback(function(){
 					doh.is(testValues.foo.bar.baz.quux.json(), formValues['foo.bar.baz.quux']);
 					doh.is(testValues.available.from.json(), formValues['available.from']);
 					doh.is(testValues.available.to.json(), formValues['available.to']);
 					doh.is(testValues.plop.combo, formValues['plop.combo']);
-					doh.is(testValues.cb2, formValues.cb2);
-					doh.is(testValues.r2, formValues.r2);
+					doh.is(testValues.cb, formValues.cb);
+					doh.is(testValues.r, formValues.r);
 					doh.is(testValues.ms1, formValues.ms1);
 					doh.is(testValues.h1, formValues.h1);
 					doh.is(testValues.t1, formValues.t1);
@@ -180,7 +174,7 @@
 					doh.is(testValues.readOnlyWidget, formValues.readOnlyWidget);
 				})();
 			};
-			doh.register("dijit.form.Form",
+			doh.register("general tests",
 				[
 					{
 						name: "setUp",
@@ -212,66 +206,399 @@
 					},
 					{
 						name:"testSubmit",
-					        timeout:10000,
+					        timeout:5000,
 					        runTest:function(){
 							var d=new doh.Deferred();
 							submittedValues = function(values){
 								testSubmittedValues(d, original, values);
-								submittedValues = defaultSubmitHandler;
 							};
-							formWidget.containerNode.submit();
+							setTimeout(function(){ formWidget.containerNode.submit(); }, 1000);
 							return d;
+						},
+						tearDown: function(){
+							submittedValues = defaultSubmitHandler;
 						}
 					},
 					function setValues(){
 						formWidget.set('value', changed);
 						doh.is( dojo.toJson(changed), dojo.toJson(formWidget.get('value')) );
 
-						formWidget.set('value', particalchanged);
-						doh.is( dojo.toJson(dojo.mixin(changed,particalchanged)), dojo.toJson(formWidget.get('value')) );
+						formWidget.set('value', partialChange);
+						doh.is( dojo.toJson(dojo.mixin(changed,partialChange)), dojo.toJson(formWidget.get('value')) );
 					},
 					function nameAttributeSurvived(){  // ticket:4753
 						var radios = dojo.query("INPUT[type=radio]", "radio-cells").forEach(
 							function(r) {
-								doh.is( r.name, "r2" );
+								doh.is( r.name, "r" );
 							});
 					},
 					{
 					        name:"postSubmit",
-					        timeout:10000,
+					        timeout:5000,
 					        runTest:function(){
 							var d=new doh.Deferred();
 							submittedValues = function(values){
-								testSubmittedValues(d, dojo.mixin(changed,particalchanged), values);
-								submittedValues = defaultSubmitHandler;
+								testSubmittedValues(d, dojo.mixin(changed,partialChange), values);
 							};
-							formWidget.containerNode.submit();
+							setTimeout(function(){ formWidget.containerNode.submit(); }, 1000);
 							return d;
+						},
+						tearDown: function(){
+							submittedValues = defaultSubmitHandler;
 						}
 					},
 					function resetTest(){
 						formWidget._onResetReturn = false;
 						formWidget.reset();
-						doh.isNot( dojo.toJson(reset), dojo.toJson(formWidget.get('value')), "reset stopped");
+						doh.isNot( dojo.toJson(original), dojo.toJson(formWidget.get('value')), "onReset false");
 						formWidget._onResetReturn = true;
 						formWidget.reset();
 						delete formWidget._onResetReturn;
-						doh.is( dojo.toJson(reset), dojo.toJson(formWidget.get('value')), "reset permitted" );
-					},
-					function testValidate(){
-						doh.is(formWidget.validate(), true);
-					},
-					function resetEditor(){ // reset editor so that refresh will pass all tests
-						dijit.byId('editor').set('value', original.richtext);
-						// FF3 sticks in some tabs and newlines that mess up the equality check
-						// Need better way to compare two HTML trees but for now do this.
-						var values = formWidget.get('value');
-						values.richtext = values.richtext.replace(/[\n\t]/, "", "g");
-						doh.is( dojo.toJson(original), dojo.toJson(values) );
+						doh.is( dojo.toJson(original), dojo.toJson(formWidget.get('value')), "onReset true" );
 					}
 				]
 			);
 
+			false && doh.register("watch('value')", [
+				// Setup watch("value", ...)
+				function setUp(){
+					var d = new doh.Deferred();
+
+					// Setup globals to reflect return from watch("value"), ...
+					calls = 0;
+					oldVal = null;
+					newVal = null;
+
+					handle = formWidget.watch("value", function(name, oldV, newV){
+						calls++;
+						oldVal = oldV;
+						newVal = newV;
+					});
+				},
+
+				// Change the DateTextBox values through Form.set("value", ...)
+				// and see if Form.watch("value", ...) does the right thing					
+				function formSet(){
+					var d = new doh.Deferred();
+
+					formWidget.set("value", {
+						foo: {bar: {baz: {quux: "1967-10-20"} } },
+						available: {from: "1967-11-09"}
+					});
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "exactly one watch(value) call");
+						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);
+					
+					return d;
+				},
+
+				// Change the DateTextBox value directly
+				// and see if Form.watch("value", ...) does the right thing					
+				function directSet(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("dtb1").set("value", "1981-10-12");
+					
+					setTimeout(d.getTestCallback(function(){
+						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);
+					
+					return d;
+				},
+
+				// Change the CheckBox values through Form.set("value", ...)
+				// and see if Form.watch("value", ...) does the right thing					
+				function checkboxSet(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					formWidget.set("value", {cb: [1,4]});
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "exactly one watch(value) call");
+
+						doh.is(2, oldVal.cb.length, "number of checkboxes previously checked");
+						doh.is(2, oldVal.cb[0], "old checkboxes, first checked");
+						doh.is(3, oldVal.cb[1], "old checkboxes, second checked");
+
+						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);
+					
+					return d;
+				},
+
+				// Uncheck a CheckBox directly
+				// and see if Form.watch("value", ...) does the right thing					
+				function directCheckBoxUncheck(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("cb_1").set("checked", false);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "exactly one watch(value) call");
+
+						doh.is(2, oldVal.cb.length, "number of checkboxes previously checked");
+						doh.is(1, oldVal.cb[0], "old checkboxes, first checked");
+						doh.is(4, oldVal.cb[1], "old checkboxes, second checked");
+
+						doh.is(1, newVal.cb.length, "number of checkboxes currently checked");
+						doh.is(4, newVal.cb[0], "new checkboxes, first checked");
+					}), 50);
+					
+					return d;
+				},
+
+				// Check a CheckBox directly
+				// and see if Form.watch("value", ...) does the right thing					
+				function directCheckBoxCheck(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("cb_2").set("checked", true);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "exactly one watch(value) call");
+
+						doh.is(1, oldVal.cb.length, "number of checkboxes previously checked");
+						doh.is(4, oldVal.cb[0], "old checkboxes, first checked");
+
+						// the new array should be [2,4] not [4,2] because the order the checkboxes
+						// were checked shouldn't matter; the value needs to be canonical
+						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);
+					
+					return d;
+				},
+
+				// Change the selected RadioButton through Form.set("value", ...)
+				// and see if Form.watch("value", ...) does the right thing					
+				function radioSet(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					formWidget.set("value", {r: 3});
+					
+					setTimeout(d.getTestCallback(function(){
+						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);
+
+					return d;
+				},
+
+				// Change the selected RadioButton directly
+				// and see if Form.watch("value", ...) does the right thing					
+				function radioDirectSet(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("r_1").set("checked", true);
+
+					setTimeout(d.getTestCallback(function(){
+						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);
+					
+					return d;
+				},
+
+				// Disabling a widget should remove it from the value
+				function disableWidget(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("dtb1").set("disabled", true);
+					
+					setTimeout(d.getTestCallback(function(){
+						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);
+					
+					return d;
+				},
+
+				// Enabling a widget should add it back to the value
+				function enableWidget(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("dtb1").set("disabled", false);
+					
+					setTimeout(d.getTestCallback(function(){
+						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);
+					
+					return d;
+				},
+
+				function tearDown(){
+					handle.unwatch();
+				}
+			]);
+
+			doh.register("watch('state')", [
+				// fill in something in required field so that form is valid
+				function makeValid(){
+					doh.f(formWidget.isValid(), "form isn't valid (due to required but empty)");
+					dijit.byId("rw").set("value", "abc");
+					doh.t(formWidget.isValid(), "form is now valid");
+				},
+
+				// Setup watch("state", ...)
+				function setUp(){
+					// Setup globals to reflect return from watch("value"), ...
+					calls = 0;
+					oldVal = null;
+					newVal = null;
+
+					handle = formWidget.watch("state", function(name, oldV, newV){
+						calls++;
+						oldVal = oldV;
+						newVal = newV;
+					});
+
+					validState = true;
+					dojo.connect(formWidget, "onValidStateChange", function(val){
+						validState = val;
+					});
+				},
+
+				// Start typing a value into the DateTextBox while it's focused.
+				// The incomplete value should trigger a change of the Form to Incomplete state even though
+				// user is still focused
+				function partialInput(){
+					var d = new doh.Deferred();
+
+					// Simulate the typing and validation checking since this isn't a robot test
+					dojo.byId("dtb1").focus();
+					dojo.byId("dtb1").value = "12/";
+					dijit.byId("dtb1").validate(true);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "one watch(state) calls");
+						doh.is("", oldVal, "old state");
+						doh.is("Incomplete", newVal, "new state");
+					}), 50);
+					
+					return d;
+				},
+
+				// Finishing the input will change state back to ""
+				function finishInput(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+
+					// Simulate the typing and validation checking since this isn't a robot test
+					dojo.byId("dtb1").value = "12/31/2012";
+					dijit.byId("dtb1").validate(true);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "another watch(state) calls");
+						doh.is("Incomplete", oldVal, "old state");
+						doh.is("", newVal, "new state");
+					}), 50);
+					
+					return d;
+				},
+
+				// An error value should trigger the Form.state change, even before blur		
+				function errorInput(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+
+					// Simulate the typing and validation checking since this isn't a robot test
+					dojo.byId("dtb1").value = "12/a";
+					dijit.byId("dtb1").validate(true);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "another watch(state) call");
+						doh.is("", oldVal, "old state");
+						doh.is("Error", newVal, "new state");
+						doh.f(validState, "onValidStateChange(false) called")
+					}), 50);
+					
+					return d;
+				},
+
+				// Disabling the widget in error state should make the form valid
+				function disableErrorWidget(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("dtb1").set("disabled", true);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "one watch(state) call");
+						doh.is("Error", oldVal, "old state");
+						doh.is("", newVal, "new state");
+						doh.t(formWidget.isValid(), "isValid");
+					}), 50);
+					
+					return d;
+				},
+
+				// Enabling the widget in error state should make the form invalid again
+				function enableErrorWidget(){
+					var d = new doh.Deferred();
+
+					calls = 0;
+					dijit.byId("dtb1").set("disabled", false);
+					
+					setTimeout(d.getTestCallback(function(){
+						doh.is(1, calls, "one watch(state) call");
+						doh.is("", oldVal, "old state");
+						doh.is("Error", newVal, "new state");
+						doh.f(formWidget.isValid(), "isValid");
+					}), 50);
+					
+					return d;
+				},
+
+				function tearDown(){
+					handle.unwatch();
+				}
+			]);
+
+			doh.register("validate()", function validate(){
+				formWidget.set("value", original);
+
+				// make the second and third DateTextBoxes invalid
+				dojo.byId("dtb2").value = "12/a";
+				dijit.byId("dtb2").validate(true);
+				dojo.byId("dtb3").value = "12/a";
+				dijit.byId("dtb3").validate(true);
+
+				// Since the required but empty ValidationTextBox has never been focused,
+				// it's not yet marked in an error state
+				doh.f(dojo.hasClass(dojo.byId("widget_rw"), "dijitValidationTextBoxError"), "required but empty not yet marked as error");
+
+				// validate() should focus the first DateTextBox and highlight
+				// the two invalid DateTextBoxes and the required but empty ValidationTextBox.
+				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.run();
 		});
 
@@ -287,12 +614,11 @@
 	<!--    to test form submission, you'll need to create an action handler similar to
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi
 		http://www.tipjar.com/cgi-bin/test -->
-	<form dojoType="dijit.form.Form" id="myForm"
-		encType="multipart/form-data" action="../formAction.html" method="" target="_formSubmitIframe">
-		<script type="dojo/method" event="onReset">
+	<form id="myForm" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe"'>
+		<script type="dojo/method" data-dojo-event="onReset">
 			return ("_onResetReturn" in this)? this._onResetReturn : confirm('Press OK to reset widget values');
 		</script>
-		<script type="dojo/method" event="onSubmit">
+		<script type="dojo/method" data-dojo-event="onSubmit">
 			console.debug('Attempting to submit form w/values:\n',
 				dojo.toJson(this.get('value'),true)
 			);
@@ -305,7 +631,7 @@
 			return true;
 		</script>
 		<p>Just HTML text</p>
-		<table style="border: 1px solid #9f9f9f;" cellspacing="10">
+		<table style="border: 1px solid #9f9f9f;">
 			<thead>
 				<tr>
 					<th>Description</th>
@@ -334,36 +660,30 @@
 					<td>DateTextBox inside contentpane</td>
 					<td>foo.bar.baz.quux</td>
 					<td>
-						<div dojoType="dijit.layout.ContentPane">
-						<input type="text" name="foo.bar.baz.quux" dojoType="dijit.form.DateTextBox" value="2007-12-30" />
+						<div data-dojo-type="dijit.layout.ContentPane">
+						<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id:"dtb1", name:"foo.bar.baz.quux", value:"2007-12-30" '/>
 						</div>
 					</td>
 				</tr>
 				<tr>
-					<td>Layoutcontainer</td>
-					<td>
-						<div dojoType="dijit.layout.LayoutContainer"></div>
-					</td>
-				</tr>
-				<tr>
-					<td>DateTextBox 1</td>
+					<td>DateTextBox 2</td>
 					<td>available.from</td>
 					<td>
-						<input type="text" name="available.from" dojoType="dijit.form.DateTextBox" value="2005-01-02" />
+						<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id:"dtb2", name:"available.from", value:"2005-01-02" '/>
 					</td>
 				</tr>
 				<tr>
-					<td>DateTextBox 2</td>
+					<td>DateTextBox 3</td>
 					<td>available.to</td>
 					<td>
-						<input type="text" name="available.to" dojoType="dijit.form.DateTextBox" value="2006-01-02" />
+						<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id:"dtb3", name:"available.to", value:"2006-01-02" '/>
 					</td>
 				</tr>
 				<tr>
 					<td>ComboBox</td>
 					<td>plop.combo</td>
 					<td>
-						<select name="plop.combo" dojoType="dijit.form.ComboBox">
+						<select data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plop.combo" '>
 							<option value="one">one</option>
 							<option value="two">two</option>
 							<option value="three">three</option>
@@ -398,12 +718,12 @@
 
 				<tr>
 					<td>CheckBox widget</td>
-					<td>cb2</td>
+					<td>cb</td>
 					<td>
-						<input dojoType="dijit.form.CheckBox" type="checkbox" name="cb2" value="1" /> 1
-						<input dojoType="dijit.form.CheckBox" type="checkbox" name="cb2" value="2" checked="checked" /> 2
-						<input dojoType="dijit.form.CheckBox" type="checkbox" name="cb2" value="3" checked="checked" /> 3
-						<input dojoType="dijit.form.CheckBox" type="checkbox" name="cb2" value="4" /> 4
+						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_1", name:"cb", value:"1" '/> 1
+						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_2", name:"cb", value:"2", checked:true '/> 2
+						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_3", name:"cb", value:"3", checked:true '/> 3
+						<input data-dojo-type="dijit.form.CheckBox" data-dojo-props='id: "cb_4", name:"cb", value:"4" '/> 4
 					</td>
 				</tr>
 
@@ -421,12 +741,12 @@
 				-->
 
 				<tr>
-				<td>Radio widget</td><td>r2</td>
+				<td>Radio widget</td><td>r</td>
 				<td id="radio-cells">
-				<input dojoType="dijit.form.RadioButton" type="radio" name="r2" value="1" /> 1
-				<input dojoType="dijit.form.RadioButton" type="radio" name="r2" value="2" checked="checked" /> 2
-				<input dojoType="dijit.form.RadioButton" type="radio" name="r2" value="3"/> 3
-				<input dojoType="dijit.form.RadioButton" type="radio" name="r2" value="4" /> 4
+				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_1", name:"r", value:"1" '/> 1
+				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_2", name:"r", value:"2", checked:true '/> 2
+				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_3", name:"r", value:"3"'/> 3
+				<input data-dojo-type="dijit.form.RadioButton" data-dojo-props='id:"r_4", name:"r", value:"4" '/> 4
 				<input type="button" onclick="dojo.query('INPUT[type=radio]','radio-cells').forEach(function(n){dijit.getEnclosingWidget(n).set('checked',false);});return true;" value="Unset all radio buttons"/>
 				</td>
 				</tr>
@@ -434,13 +754,13 @@
 				<tr>
 					<td>Multi-select</td><td>ms1</td>
 					<td>
-						<select id="ms1" multiple="true" name="ms1"
-							dojoType="dijit.form.MultiSelect"
-							style="height:100px; width:175px; border:5px solid #ededed;">
+						<select id="ms1" multiple data-dojo-type="dijit.form.MultiSelect"
+							data-dojo-props='name:"ms1",
+							style:{height:"100px", width:"175px", border:"5px solid #ededed"}'>
 
 							<option value="TN">Tennessee</option>
-							<option value="VA" selected="true">Virginia</option>
-							<option value="WA" selected="true">Washington</option>
+							<option value="VA" selected>Virginia</option>
+							<option value="WA" selected>Washington</option>
 							<option value="FL">Florida</option>
 							<option value="CA">California</option>
 
@@ -452,7 +772,7 @@
 					<td>Hidden input</td>
 					<td>h1</td>
 					<td>
-						<input id="h1" name="h1" dojoType="dijit.form.TextBox" type="hidden" value="hidden">
+						<input id="h1" data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"h1", type:"hidden", value:"hidden"'/>
 					</td>
 				</tr>
 
@@ -460,8 +780,8 @@
 					<td>Auto-sizing textarea</td>
 					<td>t1</td>
 					<td>
-						<textarea id="t1" name="t1"
-	dojoType="dijit.form.Textarea">line 1
+						<textarea id="t1" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"t1"
+	'>line 1
 line 2</textarea>
 					</td>
 				</tr>
@@ -470,7 +790,7 @@ line 2</textarea>
 					<td>Fixed size textarea</td>
 					<td>st1</td>
 					<td>
-						<textarea id="st1" name="st1" dojoType="dijit.form.SimpleTextarea" rows=5 cols=50>
+						<textarea id="st1" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"st1", rows:"5", cols:"50"'>
 simple line 1
 simple line 2</textarea>
 					</td>
@@ -480,7 +800,7 @@ simple line 2</textarea>
 					<td>Editor widget</td>
 					<td>richtext</td>
 					<td>
-						<div dojoType="dijit.Editor" id="editor" name="richtext" pluginsConfig="[{items:['bold','italic']}]"><h1>original</h1><p>This is the default content</p></div>
+						<textarea id="editor" name="richtext" data-dojo-type="dijit.Editor" data-dojo-props='plugins:["bold", "italic"]'><h1>original</h1><p>This is the default content</p></textarea>
 					</td>
 				</tr>
 
@@ -488,64 +808,71 @@ simple line 2</textarea>
 					<td>File upload</td>
 					<td>filename</td>
 					<td>
-						<input dojoType="dijit.form.TextBox" name="filename" type="file">
+						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"filename", type:"file"'/>
+					</td>
+				</tr>
+				<tr>
+					<td>Required Widget</td>
+					<td>requiredWidget</td>
+					<td>
+						<input data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='id: "rw", name:"requiredWidget", required:true, value:""'/>
 					</td>
 				</tr>
 				<tr>
 					<td>Disabled Widget</td>
 					<td>disabledWidget</td>
 					<td>
-						<input dojoType="dijit.form.TextBox" name="disabledWidget" disabled="disabled" value="Should not be returned">
+						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"disabledWidget", disabled:true, value:"Should not be returned"'/>
 					</td>
 				</tr>
 				<tr>
 					<td>Disabled Required Widget</td>
 					<td>disabledRequiredWidget</td>
 					<td>
-						<input dojoType="dijit.form.ValidationTextBox" name="disabledRequiredWidget" disabled="disabled" required="true" value="">
+						<input data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='id: "drw", name:"disabledRequiredWidget", disabled:true, required:true, value:""'/>
 					</td>
 				</tr>
 				<tr>
 					<td>Read-only Widget</td>
 					<td>readOnlyWidget</td>
 					<td>
-						<input dojoType="dijit.form.TextBox" name="readOnlyWidget" readOnly value="Should be returned">
+						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"readOnlyWidget", readOnly:true, value:"Should be returned"'/>
 					</td>
 				</tr>
 				<tr>
 					<td>Duplicate named TextBox 1</td>
 					<td>duplicate</td>
 					<td>
-						<input dojoType="dijit.form.TextBox" name="duplicate" value="first">
+						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"duplicate", value:"first"'/>
 					</td>
 				</tr>
 				<tr>
 					<td>Duplicate named TextBox 2</td>
 					<td>duplicate</td>
 					<td>
-						<input dojoType="dijit.form.TextBox" name="duplicate" value="second">
+						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"duplicate", value:"second"'/>
 					</td>
 				</tr>
 				<tr>
 					<td>Duplicate named TextBox 3</td>
 					<td>duplicate</td>
 					<td>
-						<input dojoType="dijit.form.TextBox" name="duplicate" value="third">
+						<input data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"duplicate", value:"third"'/>
 					</td>
 				</tr>
 			</tbody>
 		</table>
 
-		<button dojoType="dijit.form.Button" onClick="getValues();">Get Values from form!</button>
-		<button dojoType="dijit.form.Button" onClick="setValues();">Set Values to form!</button>
-		<button dojoType="dijit.form.Button" onClick="validate();">Validate form!</button>
-		<button dojoType="dijit.form.Button" type="submit" value="Submit">Submit</button>
-		<button dojoType="dijit.form.Button" type="reset">HTML Reset</button>
-		<button dojoType="dijit.form.Button" type="button" onClick="dijit.byId('myForm').reset()">reset()</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ getValues(); }'>Get Values from form!</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ setValues(); }'>Set Values to form!</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ validate(); }'>Validate form!</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", value:"Submit"'>Submit</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset"'>HTML Reset</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ dijit.byId("myForm").reset() }'>reset()</button>
 	</form>
-<button dojoType="dijit.form.Button" type="button"
-onclick="dijit.byId('myForm').submit()">Submit programmatically</button>
+<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button",
+onClick:function(){ dijit.byId("myForm").submit() }'>Submit programmatically</button>
 
-<iframe name="_formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
+<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
 </body>
 </html>
diff --git a/dijit/tests/form/FormInvalid.html b/dijit/tests/form/FormInvalid.html
deleted file mode 100644
index 90f2309..0000000
--- a/dijit/tests/form/FormInvalid.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-    <head>
-        <title>Form unit test</title>
-        <style type="text/css">
-            @import "../../../dojo/resources/dojo.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" djConfig="isDebug: true, parseOnLoad: true">
-        </script>
-        <!-- only needed for alternate theme testing: -->
-        <script type="text/javascript" src="../_testCommon.js">
-        </script>
-        <script type="text/javascript">
-            dojo.require("dojo.date");
-            dojo.require("dijit.dijit"); // optimize: load dijit layer
-            dojo.require("dijit.form.Form");
-            dojo.require("dijit.form.ValidationTextBox");
-            dojo.require("dijit.form.Button");
-
-            function foo(isValid){
-                var form = dijit.byId("myForm1");
-                var btn = dijit.byId("submitBtn");
-                btn.set("disabled", !isValid);
-            }
-
-            dojo.addOnLoad(function(){
-                var form = dijit.byId("myForm1");
-                dojo.connect(form, "onValidStateChange", null, foo);
-                dijit.byId("submitBtn").set("disabled", true);
-            })
-        </script>
-    </head>
-    <body class="claro">
-        <h1 class="testTitle">Form Widget Unit Test</h1>
-        <form dojoType="dijit.form.Form" id="myForm1" onSubmit="dojo.stopEvent(arguments[0])">
-            <h3>This form's submit button should become enabled ONLY when all fields are valid</h3>
-            <p>
-            	This is a test case for <a href="http://bugs.dojotoolkit.org/ticket/8966">#8966</a>.
-            </p>
-            <input dojoType="dijit.form.ValidationTextBox" required="true" name="field1" id="field1" />Foo*
-            <br/>
-            <input dojoType="dijit.form.ValidationTextBox" required="true" name="field2" id="field2" />Bar*
-            <br/>
-            <button dojoType="dijit.form.Button" id="submitBtn" type="submit">
-                Submit
-            </button>
-			<br/><em>*Required</em>
-        </form>
-    </body>
-</html>
diff --git a/dijit/tests/form/TextBox_sizes.html b/dijit/tests/form/TextBox_sizes.html
index ef0bea7..1ddb1fc 100644
--- a/dijit/tests/form/TextBox_sizes.html
+++ b/dijit/tests/form/TextBox_sizes.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 dir="ltr">
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.form.TextBox size tests</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../../themes/dijit.css";
 		@import "../../themes/dijit_rtl.css";
 		@import "../../themes/tundra/Common.css";
@@ -36,9 +36,10 @@
 		@import "../../themes/nihilo/form/Common_rtl.css";
 
 		#table TD {
-			padding: 1px;
 			background-color: pink;
 			font-size: 100%;
+			padding: 0px;
+			margin: 0px;
 		}
 		TABLE#table, #table TD, #table .dijit {
 			border-color: black !important;
@@ -56,16 +57,26 @@
 		.unPadded .dijitInputField {
 			padding: 0px !important;
 		}
+		#table {
+			padding: 0px;
+			border:1px solid black;
+			background-color: pink;
+		}
+		#table .layout {
+			padding: 1px;
+			border: 1px solid black;
+		}
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.TextBox");
 		dojo.require("dijit.form.NumberTextBox");
+		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.FilteringSelect");
 		dojo.require("dijit.form.NumberSpinner");
 		dojo.require("dijit.form.Button");
@@ -134,35 +145,32 @@
 			var validation = dijit.byId("validation");
 			var combobox = dijit.byId("combobox");
 			var spinner = dijit.byId("spinner");
-			var table = dojo.byId("table");
-
-			var compareToTextBox = function(attr){
-				try{
-					var textboxPos = dojo.position(textbox.domNode);
-					var validationPos = dojo.position(validation.domNode);
-					var comboboxPos = dojo.position(combobox.domNode);
-					var spinnerPos = dojo.position(spinner.domNode);
-					doh.t(Math.round(textboxPos[attr]) == Math.round(validationPos[attr]) &&
-						Math.round(textboxPos[attr]) == Math.round(comboboxPos[attr]) &&
-						Math.round(textboxPos[attr]) == Math.round(spinnerPos[attr]),
-						"Expected same " + attr + ":" + textboxPos[attr] + '/' + validationPos[attr] + '/' + comboboxPos[attr] + '/' + spinnerPos[attr]
-					);
-				}catch(e){
-					throw e; // prevent consoles from including entire function text in output
-				}
-			};
 
-			var compareToTextBoxParent = function(attr){
+			var compareToTextBox = function(attr, isParent){
 				try{
-					var textboxPos = dojo.position(textbox.domNode.parentNode);
-					var validationPos = dojo.position(validation.domNode.parentNode);
-					var comboboxPos = dojo.position(combobox.domNode.parentNode);
-					var spinnerPos = dojo.position(spinner.domNode.parentNode);
-					doh.t(Math.round(textboxPos[attr]) == Math.round(validationPos[attr]) &&
-						Math.round(textboxPos[attr]) == Math.round(comboboxPos[attr]) &&
-						Math.round(textboxPos[attr]) == Math.round(spinnerPos[attr]),
-						"Expected same parent " + attr + ":" + textboxPos[attr] + '/' + validationPos[attr] + '/' + comboboxPos[attr] + '/' + spinnerPos[attr]
-					);
+				var
+					attrMap = {
+						h: 'offsetHeight',
+						w: 'offsetWidth'
+					},
+					textboxNode = isParent ? textbox.domNode.parentNode : textbox.domNode,
+					validationNode = isParent ? validation.domNode.parentNode : validation.domNode,
+					comboboxNode = isParent ? combobox.domNode.parentNode : combobox.domNode,
+					spinnerNode = isParent ? spinner.domNode.parentNode : spinner.domNode,
+					textboxPos = dojo.position(textboxNode),
+					validationPos = dojo.position(validationNode),
+					comboboxPos = dojo.position(comboboxNode),
+					spinnerPos = dojo.position(spinnerNode);
+					// IE9 sometimes reports getBoundingClientRect.bottom incorrectly for TD so also check offset*
+					doh.t(Math.round(textboxPos[attr]) == Math.round(validationPos[attr])
+						|| (attrMap[attr] && textboxNode[attrMap[attr]] > 0 && textboxNode[attrMap[attr]] == validationNode[attrMap[attr]]),
+						"validationPos " + attr + " " + textboxPos[attr] + " vs " + validationPos[attr]);
+					doh.t(Math.round(textboxPos[attr]) == Math.round(comboboxPos[attr])
+						|| (attrMap[attr] && textboxNode[attrMap[attr]] > 0 && textboxNode[attrMap[attr]] == comboboxNode[attrMap[attr]]),
+						"comboboxPos " + attr + " " + textboxPos[attr] + " vs " + comboboxPos[attr]);
+					doh.t(Math.round(textboxPos[attr]) == Math.round(spinnerPos[attr])
+						|| (attrMap[attr] && textboxNode[attrMap[attr]] > 0 && textboxNode[attrMap[attr]] == spinnerNode[attrMap[attr]]),
+						"spinnerPos " + attr + " " + textboxPos[attr] + " vs " + spinnerPos[attr]);
 				}catch(e){
 					throw e; // prevent consoles from including entire function text in output
 				}
@@ -175,7 +183,7 @@
 				},
 				{
 						name: "y",
-						runTest: function(){ compareToTextBoxParent("h"); }
+						runTest: function(){ compareToTextBox("h", true); }
 				},
 				{
 						name: "h",
@@ -229,9 +237,9 @@
 							var paddingTop = Math.abs(inputPos.y - paddedBoxPos.y);
 							var paddingBottom = Math.abs(inputPos.h - paddedBoxPos.h) - paddingTop;
 							var pad = undefined;
-							if(dojo.hasClass(table, "padded")){
+							if(dojo.hasClass(testtable, "padded")){
 								pad = 10;
-							}else if(dojo.hasClass(table, "unPadded")){
+							}else if(dojo.hasClass(testtable, "unPadded")){
 								pad = 0;
 							}else{
 								return;
@@ -260,7 +268,8 @@
 						name: "button: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							if(widgetName == "dijitTextBox" || widgetName == "dijitValidationTextBox"){ return; }
+							if(widgetName == "dijitTextBox" || widgetName == "dijitValidationTextBox" ||
+								widgetName == "dijitNumberTextBox" || widgetName == "dijitCurrencyTextBox"){ return; }
 							var paddedBoxPos = dojo.position(widget.focusNode.parentNode);
 							var buttonNode = dojo.query(".dijitValidationContainer", widget.domNode)[0].previousSibling;
 							var buttonPos = dojo.position(buttonNode);
@@ -297,7 +306,7 @@
 					timeout: 1000,
 					runTest: function(){
 						var inputPos = dojo.position(combobox.focusNode.parentNode);
-						var arrowPos = dojo.position(combobox.downArrowNode);
+						var arrowPos = dojo.position(combobox._buttonNode);
 						doh.t(Math.abs(inputPos.h-arrowPos.h) <= 1, "ComboBox button height (" + arrowPos.h + ") is same as input height (" + inputPos.h + ")");
 					}
 				},
@@ -329,9 +338,9 @@
 							var paddingTop = Math.abs(inputPos.y - paddedBoxPos.y);
 							var paddingBottom = Math.abs(inputPos.h - paddedBoxPos.h) - paddingTop;
 							var pad = undefined;
-							if(dojo.hasClass(table, "padded")){
+							if(dojo.hasClass(testtable, "padded")){
 								pad = 10;
-							}else if(dojo.hasClass(table, "unPadded")){
+							}else if(dojo.hasClass(testtable, "unPadded")){
 								pad = 0;
 							}else{
 								return;
@@ -367,7 +376,7 @@
 							var offset = Math.min(Math.abs(paddedBoxPos.x + paddedBoxPos.w - validationPos.x), Math.abs(validationPos.x + validationPos.w - paddedBoxPos.x));
 
 							// IE 6 float bug(s) causes a known 3px margin between input field & validation icon 
-							// Fix could be .dj_ie .dijitInputField { float:right; /* get rid of 3px margin */ }
+							// Fix could be .dj_ie .dijitInputField { float:right; }
 							// But this breaks even more the tests, dojo.position() bug?
 							if(dojo.isIE < 7 || dojo.isQuirks)
 								doh.t(offset <= 3, "padded textbox horizontally just left or right (" + offset + ") of validation node: valiation node x/w = " + validationPos.x+"/"+validationPos.w + ", pad box x/w = " + paddedBoxPos.x+"/"+paddedBoxPos.w);
@@ -379,7 +388,8 @@
 						name: "button: " + widgetName,
 						timeout: 1000,
 						runTest: function(){
-							if(widget.state != "Error" || widgetName == "dijitValidationTextBox"){ return; }
+							if(widget.state != "Error" || widgetName == "dijitValidationTextBox" ||
+								widgetName == "dijitNumberTextBox" || widgetName == "dijitCurrencyTextBox"){ return; }
 							var validationNode = dojo.query(".dijitValidationContainer", widget.domNode)[0];
 							var buttonNode = dojo.query(".dijitValidationContainer", widget.domNode)[0].previousSibling;
 							var validationPos = dojo.position(validationNode);
@@ -399,76 +409,97 @@
 
 	<h1 class="testTitle">dijit.form.TextBox size tests</h1>
 
-	<table class="padded" id="table" rules="all" cellpadding="0" cellspacing="0" border="2" frame="border" style="font-family:monospace;font-size:12pt;">
+	<table class="padded" id="table" style="font-family:monospace;font-size:12pt;">
 		<tr>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
-			<td></td>
 			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
-			<td>TextBox</td>
-			<td></td>
-			<td><input dojoType="dijit.form.TextBox" type="text" id="textbox" value="text"></td>
-			<td></td>
+			<td class="layout">TextBox</td>
+			<td class="layout"><input id="textbox" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", value:"text"'/></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
-			<td>NumberTextBox</td>
-			<td></td>
-			<td><input dojoType="dijit.form.NumberTextBox" type="text" id="validation" value="54" required="true"></td>
-			<td></td>
+			<td class="layout">NumberTextBox</td>
+			<td class="layout"><input id="validation" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='type:"text", value:54, required:true'/></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
-			<td>FilteringSelect</td>
-			<td></td>
-			<td><select dojoType="dijit.form.FilteringSelect" id="combobox" required="true">
+			<td class="layout">FilteringSelect</td>
+			<td class="layout"><select id="combobox" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='required:true'>
 				<option value="KY">Kentucky</option>
 			</select></td>
-			<td></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
-			<td>NumberSpinner</td>
-			<td></td>
-			<td><div dojoType="dijit.form.NumberSpinner" type="text" id="spinner" value="45" required="true"></div></td>
-			<td></td>
+			<td class="layout">NumberSpinner</td>
+			<td class="layout"><div id="spinner" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='type:"text", value:45, required:true'></div></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
-			<td>INPUT type=file</td>
-			<td></td>
-			<td><input dojoType="dijit.form.TextBox" type="file" id="file"></td>
-			<td></td>
+			<td class="layout">INPUT type=file</td>
+			<td class="layout"><input id="file" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"file" '/></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 		<tr>
 			<td style="font-size:1px;overflow:hidden;"> </td>
-			<td></td>
-			<td></td>
-			<td></td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
+			<td style="font-size:1px;overflow:hidden;"> </td>
 		</tr>
 	</table><br>
-	<table style="display:block;">
-	<tr><td style="text-align:right;">Font family:
-	<select dojoType="dijit.form.ComboBox" id="fontFamily" style="font-size:14pt;" value="">
-		<script type="dojo/method" event="onChange" args="fontFamily">
-			var table = dojo.byId('table');
-			table.style.fontFamily = fontFamily;
+	<script type="text/javascript">
+		testtable = dojo.byId('table');
+
+		function fontFamilyOnChange(fontFamily){
+			testtable.style.fontFamily = fontFamily;
 			if(dojo.isIE){
-				dojo.query('INPUT', table).forEach(function(node){
+				dojo.query('INPUT', testtable).forEach(function(node){
 					node.style.fontFamily = fontFamily;
 				});
 			}
-		</script>
+		}
+
+		function directionOnChange(direction){
+			dojo.query('.dijitTextBox', testtable).forEach(function(node){
+				node.style.direction = direction;
+				node.parentNode.style.direction = direction;
+				dojo.forEach(node.className.split(' '), function(cls){
+					if(cls.indexOf('Rtl') > 0){
+						dojo.removeClass(node, cls);
+					}
+				});
+				if(direction == "rtl"){
+					dojo.forEach(node.className.split(' '), function(cls){
+						if(cls.indexOf('Box') > 0){
+							cls = cls.substr(0, cls.indexOf('Box')+3) + "Rtl" + cls.substr(cls.indexOf('Box')+3);
+						}else{
+							cls = cls + "Rtl";
+						}
+						dojo.addClass(node, cls);
+					});
+				}
+			});
+		}
+
+		function themeOnChange(theme){
+			if(theme == "a11y"){
+				theme="dijit_a11y";
+			}
+			dojo.body().className = theme + ((this.isRealA11y && theme != "dijit_a11y") ? " dijit_a11y" : "");
+		}
+	</script>
+	<table style="display:block;">
+	<tr><td class="layout" style="text-align:right;">Font family:
+	<select id="fontFamily" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{fontSize:"14pt"}, value:"", onChange:fontFamilyOnChange'>
 		<option>monospace</option>
 		<option selected>Courier</option>
 		<option>Helvetica</option>
 		<option>Times</option>
 		<option>system,fixed</option>
 	</select></td></tr>
-	<tr><td style="text-align:right;">Font size:
-	<select dojoType="dijit.form.ComboBox" id="fontSize" style="font-size:14pt;" value="">
-		<script type="dojo/method" event="onChange" args="fontSize">
-			var table = dojo.byId('table');
-			table.style.fontSize = fontSize;
-		</script>
+	<tr><td class="layout" style="text-align:right;">Font size:
+	<select id="fontSize" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{fontSize:"14pt"}, value:"", onChange:function(val){ testtable.style.fontSize = val; }'>
 		<option>small</option>
 		<option>medium</option>
 		<option>xx-large</option>
@@ -478,48 +509,19 @@
 		<option>1em</option>
 		<option>200%</option>
 	</select></td></tr>
-	<tr><td style="text-align:right;">Padding:
-	<select dojoType="dijit.form.FilteringSelect" id="padding" style="font-size:14pt;" required="false" value="">
-		<script type="dojo/method" event="onChange" args="padding">
-			dojo.byId('table').className = padding;
-		</script>
+	<tr><td class="layout" style="text-align:right;">Padding:
+	<select id="padding" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:{fontSize:"14pt"}, required:false, value:"", onChange:function(val){ testtable.className = val; }'>
 		<option value="default">default</option>
 		<option value="padded">padded</option>
 		<option value="unPadded">unPadded</option>
 	</select></td></tr>
-	<tr><td style="text-align:right;">Direction:
-	<select dojoType="dijit.form.FilteringSelect" id="direction" style="font-size:14pt;" required="false" value="">
-		<script type="dojo/method" event="onChange" args="direction">
-			var table = dojo.byId('table');
-			dojo.query('.dijitTextBox', table).forEach(function(node){
-				node.style.direction = direction;
-				node.parentNode.style.direction = direction;
-				dojo.forEach(node.className.split(' '), function(cls){
-					if(cls.indexOf('Rtl') > 0){
-						dojo.removeClass(node, cls);
-					}
-				});
-				if(direction == "rtl"){
-					dojo.forEach(node.className.split(' '), function(cls){
-						if(cls.indexOf('Box') > 0){
-							cls = cls.substr(0, cls.indexOf('Box')+3) + "Rtl" + cls.substr(cls.indexOf('Box')+3);
-						}else{
-							cls = cls + "Rtl";
-						}
-						dojo.addClass(node, cls);
-					});
-				}
-			});
-		</script>
+	<tr><td class="layout" style="text-align:right;">Direction:
+	<select id="direction" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:{fontSize:"14pt"}, required:false, value:"", onChange:directionOnChange'>
 		<option value="ltr">left-to-right</option>
 		<option value="rtl">right-to-left</option>
 	</select></td></tr>
-	<tr><td style="text-align:right;">Theme:
-	<select dojoType="dijit.form.FilteringSelect" id="theme" style="font-size:14pt;" required="false" value="">
-		<script type="dojo/method" event="onChange" args="theme">
-			if(theme == "a11y"){ theme="dijit_a11y"; }
-			dojo.body().className = theme + ((this.isRealA11y && theme != "dijit_a11y") ? " dijit_a11y" : "");
-		</script>
+	<tr><td class="layout" style="text-align:right;">Theme:
+	<select id="theme" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:{fontSize:"14pt"}, required:false, value:"", onChange:themeOnChange'>
 		<option value="tundra">tundra</option>
 		<option value="soria">soria</option>
 		<option value="nihilo">nihilo</option>
@@ -527,6 +529,6 @@
 		<option value="a11y">a11y</option>
 	</select></td></tr>
 	</table>
-	<button dojoType="dijit.form.Button" onclick="doh.run()">Run tests</button>
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ doh.run(); }'>Run tests</button>
 </body>
 </html>
diff --git a/dijit/tests/form/_autoComplete.html b/dijit/tests/form/_autoComplete.html
index e02dedc..365a8c5 100644
--- a/dijit/tests/form/_autoComplete.html
+++ b/dijit/tests/form/_autoComplete.html
@@ -1,21 +1,21 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.form.ComboBox Unit Test</title>
 
 	<style>
-		@import "../../../dojo/resources/dojo.css";
+		@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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: false"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -63,19 +63,9 @@
 
 		function init(){
 			var testClass = dojo.getObject(testWidget);
-			// substitute testWidget for each dojoType=$testWidget
-			dojo.query('[dojoType="$testWidget"]').forEach(function(node){
-				node.setAttribute('dojoType', testWidget);
-			});
-			// substitute value=$-id-val by locating <select id="id"><option value="val">val</option></select>
-			dojo.query('*[value|="$"]').forEach(function(node){
-				var attrs = node.getAttribute('value').split("-");
-				var id = attrs[1];
-				var val = attrs[2];
-				if(testWidget == "dijit.form.ComboBox"){
-					val = dojo.query("> option[value='"+val+"']", id)[0].innerHTML;
-				}
-				node.setAttribute('value', val);
+			// substitute testWidget for each data-dojo-type=$testWidget
+			dojo.query('[data-dojo-type="$testWidget"]').forEach(function(node){
+				node.setAttribute('data-dojo-type', testWidget);
 			});
 			dojo.parser.parse(dojo.body());
 			store = new dojo.data.ItemFileReadStore({url: dojo.moduleUrl("dijit.tests._data", "states.json")});
@@ -112,6 +102,25 @@
 			widget.set('disabled',!widget.disabled);
 			button.innerHTML= widget.disabled ? "Enable" : "Disable";
 		}
+
+		function getValue() {
+			var f = document.getElementById("form1");
+			var s = "";
+			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; }
+				s += elem.name + ": " + elem.value + "\n";
+			}
+			return s;
+		}
+
+		// formSubmitted flag is for benefit of DOH test harneess
+		formSubmitted = false;
+		function onFormSubmit(){
+			formSubmitted = true;
+			console.log(getValue());
+			return false;
+		}
 	</script>
 </head>
 
@@ -119,25 +128,27 @@
 
 	<h1 class="testTitle" id="title"></h1>
 	<script>dojo.byId('title').appendChild(document.createTextNode(testWidget+" Unit Test"))</script>
-	<form id="form1" action="#" method="GET">
+	<form id="form1" action="#" method="GET" onsubmit="return onFormSubmit();">
+		
+		<!--
+			Need a submit button like this (rather than onsubmit handler on <form>) to get
+			IE to submit when the ENTER key is pressed.
+			
+			And (at least on IE8) when ComboBox_a11y.html is run via runTests.html,
+			it only seems to work if the button is at the top of the form, not at the bottom.
+		-->
+		<button type="reset">reset</button>
+		<button type="submit">fake submit</button><br/>
+		<hr>
 
 		<p>Option tags, autoComplete=false, selectOnClick=true, default value of California, pageSize=30, custom labelFunc method</p>
-		<label for="setvaluetest">US State test 1</label> (200% Courier font):
-		<select id="setvaluetest"
-				name="state1"
-				dojoType="$testWidget"
-				style="width:50%;font-size:200%;font-family:Courier;"
-				autoComplete="false"
-				selectOnClick="true"
-				onBlur="dojo.byId('b1').value=dijit.byId('setvaluetest').value"
-				pageSize="30"
-		>
-			<script type="dojo/method" event="onChange">
+		<label for="setvaluetest">US State test 1 (200% Courier font):</label>
+		<script type="text/javascript">
+			function setValueTestOnChange(newValue){
 				if(this.lastlabelFuncMsg){
 					console.info(this.lastlabelFuncMsg);
 					this.lastlabelFuncMsg = '';
 				}
-				var newValue = arguments[0];
 				dojo.byId('oc1').value = newValue;
 				var itemLabel;
 				if(this.item === null){
@@ -151,17 +162,11 @@
 					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.labelFunc(this.item, this.store);
-					if(this.textbox.value != itemLabel){
-						console.error(this.id + ' has an inconsistent item value, item label = ' + itemLabel + ', onChange value = ' + newValue + ', widget value = ' + this.value + ', displayed Value = ' + this.textbox.value);
-						this.itemError = true;
-					}
+					itemLabel = this.store.getValue(this.item, this.searchAttr).toString();
 				}
 				dojo.byId('i1').value = itemLabel;
-			</script>
-			<script type="dojo/method" event="labelFunc">
-				var item = arguments[0];
-				var store = arguments[1];
+			}
+			function setValueTestLabelFunc(item, store){
 				var label = store.getValue(item, this.searchAttr);
 				var value = store.getValue(item, 'value');
 				if(!this.labelFuncCount){ this.labelFuncCount = 0; }
@@ -171,7 +176,19 @@
 				this.labelFuncCounts[value]++;
 				this.lastlabelFuncMsg = 'my labelfunc ' + label + ' (' + value + '), count = ' + this.labelFuncCounts[value];
 				return label + ' (' + value + ')';
-			</script>
+			}
+		</script>
+		<select id="setvaluetest" data-dojo-type="$testWidget"
+				data-dojo-props='name:"state1",
+				style:{width:"50%", fontSize:"200%", fontFamily:"Courier"},
+				autoComplete:false,
+				selectOnClick:true,
+				onBlur:function(){ dojo.byId("b1").value=dijit.byId("setvaluetest").value },
+				onClick:function(){ console.log("onclick"); },
+				pageSize:30,
+				labelFunc:setValueTestLabelFunc,
+				onChange:setValueTestOnChange
+		'>
 			<option value="AL">Alabama</option>
 			<option value="AK">Alaska</option>
 			<option value="AS">American Samoa</option>
@@ -234,108 +251,99 @@
 			<option value="WI">Wisconsin</option>
 			<option value="WY">Wyoming</option>
 		</select>
-		<br>onChange:<input id="oc1" disabled value="not fired yet!" autocomplete="off">
-		<br>value:<input id="v1" disabled value="not fired yet!" autocomplete="off">
-		<br>blur:<input id="b1" disabled value="not fired yet!" autocomplete="off">
-		<br>this.item:<input id="i1" disabled value="no onChange yet!" autocomplete="off">
-		<input type="button" id="sv1_1" value="Set displayed value to Kentucky" onClick="dijit.byId('setvaluetest').set('displayedValue', 'Kentucky')">
-	        <input type="button" id="sv1_2" value="Set displayed value to Canada" onClick="dijit.byId('setvaluetest').set('displayedValue', 'Canada')">
-	        <input type="button" id="sv1_3" value="Set value to null" onClick="dijit.byId('setvaluetest').set('value', null)">
-	        <input type="button" id="sv1_4" value="Get value" onClick="dojo.byId('v1').value=dijit.byId('setvaluetest').get('value')">
+		<br>onChange:<input id="oc1" disabled value="not fired yet!" autocomplete="off"/>
+		<br>value:<input id="v1" disabled value="not fired yet!" autocomplete="off"/>
+		<br>blur:<input id="b1" disabled value="not fired yet!" autocomplete="off"/>
+		<br>this.item:<input id="i1" disabled value="no onChange yet!" autocomplete="off"/>
+		<input type="button" id="sv1_1" value="Set displayed value to Kentucky" onClick="dijit.byId('setvaluetest').set('displayedValue', 'Kentucky')"/>
+	        <input type="button" id="sv1_2" value="Set displayed value to Canada" onClick="dijit.byId('setvaluetest').set('displayedValue', 'Canada')"/>
+	        <input type="button" id="sv1_3" value="Set value to null" onClick="dijit.byId('setvaluetest').set('value', null)"/>
+	        <input type="button" id="sv1_4" value="Get value" onClick="dojo.byId('v1').value=dijit.byId('setvaluetest').get('value')"/>
 
 		<hr>
 
-		<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
-			url="../_data/states.json"></div>
-		<div dojoType="dijit.tests._data.SlowStore" jsId="slowStateStore"
-			url="../_data/states.json"></div>
+		<div data-dojo-id="stateStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
+		<div data-dojo-id="slowStateStore" data-dojo-type="dijit.tests._data.SlowStore" data-dojo-props='url:"../_data/states.json"'></div>
 
-		<div dojoType="dojo.data.ItemFileReadStore" jsId="dijitStore"
-			url="../_data/dijits.json"></div>
+		<div data-dojo-id="dijitStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/dijits.json"'></div>
 
 		<p>Data store, autoComplete=true:</p>
-		<label for="datatest">US State test 2</label> (8pt font):
-		<input dojoType="$testWidget"
-				value="$-setvaluetest-CA"
-				store="stateStore"
-				searchAttr="name"
-				style="width: 200px; font-size: 8pt;"
-				name="state2"
-				onChange="setVal2"
-				id="datatest"
-		>
-		<br>onChange:<input id="value2" disabled value="not fired yet!" autocomplete="off">
+		<label for="datatest">US State test 2 (8pt font):</label>
+		<input id="datatest" data-dojo-type="$testWidget"
+				data-dojo-props='value: (testWidget == "dijit.form.ComboBox") ? "California" : "CA",
+				store:stateStore,
+				searchAttr:"name",
+				style:{width:"200px", fontSize:"8pt"},
+				name:"state2",
+				onChange:setVal2
+				'/>
+		<br>onChange:<input id="value2" disabled value="not fired yet!" autocomplete="off"/>
 		<hr>
 		<p>Artificially slowed-down data store, autoComplete=true:</p>
-		<label for="slow">US State test slow</label>:
-		<input dojoType="$testWidget"
-				value="$-setvaluetest-CA"
-				store="slowStateStore"
-				searchAttr="name"
-				name="stateSlow"
-				onChange="dojo.byId('ocSlow').value=arguments[0]"
-				id="slow"
-		>
-		<br>onChange:<input id="ocSlow" disabled value="not fired yet!" autocomplete="off">
-		<button id="slowDestroy" onclick="dijit.byId('slow').destroy();return false">Destroy widget to test in-flight query cancel</button>
+		<label for="slow">US State test slow:</label>
+		<input id="slow" data-dojo-type="$testWidget"
+				data-dojo-props='value: (testWidget == "dijit.form.ComboBox") ? "California" : "CA",
+				store:slowStateStore,
+				searchAttr:"name",
+				name:"stateSlow",
+				onChange:function(val){ dojo.byId("ocSlow").value = val; }
+				'/>
+		<br>onChange:<input id="ocSlow" disabled value="not fired yet!" autocomplete="off"/>
+		<button id="slowDestroy" type="button" onclick="dijit.byId('slow').destroy();return false">Destroy widget to test in-flight query cancel</button>
 		<hr>
 
-		<label for="datatestDijit">Dijit List test #1</label> (150% font):
-		<input dojoType="$testWidget"
-				value="dijit.Editor"
-				store="dijitStore"
-				searchAttr="className"
-				style="width: 200px; font-size: 150%;"
-				name="dijitList1"
-				id="datatestDijit"
-		>
+		<label for="datatestDijit">Dijit List test #1 (150% font):</label>
+		<input id="datatestDijit" data-dojo-type="$testWidget"
+				data-dojo-props='value:"dijit.Editor",
+				store:dijitStore,
+				searchAttr:"className",
+				style:{width:"200px",fontSize:"150%"},
+				name:"dijitList1"
+				'/>
 		<span>Hey look, this one is kind of useful.</span>
 		<hr>
 
 		<p>Initially disabled, url, autoComplete=false:</p>
-		<label for="combo3">US State test 3: </label>
-	 	<input id="combo3"
-	 			dojoType="$testWidget"
-	 			value="$-setvaluetest-CA"
-				store="stateStore"
-				searchAttr="name"
-				style="width: 300px;"
-				name="state3"
-				autoComplete="false"
-				onChange="setVal3"
-				disabled
-		>
-		<br>onChange:<input id="value3" disabled value="not fired yet!" autocomplete="off">
+		<label for="combo3">US State test 3:</label>
+	 	<input id="combo3" data-dojo-type="$testWidget"
+	 			data-dojo-props='value:(testWidget == "dijit.form.ComboBox") ? "California" : "CA",
+				store:stateStore,
+				searchAttr:"name",
+				style:{width:"300px"},
+				name:"state3",
+				autoComplete:false,
+				onChange:setVal3,
+				disabled:true
+		'/>
+		<br>onChange:<input id="value3" disabled value="not fired yet!" autocomplete="off"/>
 		<div>
-			<button id="combo3_disable" onclick='toggleDisabled("combo3_disable", "combo3"); return false;' tabIndex="-1">Enable</button>
+			<button id="combo3_disable" type="button" onclick='toggleDisabled("combo3_disable", "combo3"); return false;' tabIndex="-1">Enable</button>
 		</div>
 		<hr>
 		<p>Data store, autoComplete=false required=true and highlightMatch="none"</p>
-		<label for="combobox4">US State test 4: </label>
-		<input dojoType="$testWidget"
-				value=""
-				store="stateStore"
-				searchAttr="name"
-				style="width: 300px;"
-				name="state4"
-				onChange="setVal4"
-				autoComplete="false"
-				id="combobox4"
-				required="true"
-				highlightMatch="none"
-		>
-		<br>onChange:<input id="value4" disabled value="not fired yet!" autocomplete="off">
+		<label for="combobox4">US State test 4:</label>
+		<input id="combobox4" data-dojo-type="$testWidget"
+				data-dojo-props='value:"",
+				store:stateStore,
+				searchAttr:"name",
+				style:{width:"300px"},
+				name:"state4",
+				onChange:setVal4,
+				autoComplete:false,
+				required:true,
+				highlightMatch:"none"
+		'/>
+		<br>onChange:<input id="value4" disabled value="not fired yet!" autocomplete="off"/>
 		<hr>
 		<p>test that title used as label is preserved on input</p>
-		<select id="preservetitletest"
-				name="titletest"
-				dojoType="$testWidget"
-				style="width:50%;font-family:Courier;"
-				autoComplete="false"
-				selectOnClick="true"
-				pageSize="5"
-				title="New England States"
-		>
+		<select id="preservetitletest" data-dojo-type="$testWidget"
+				data-dojo-props='name:"titletest",
+				style:{width:"50%", fontFamily:"Courier"},
+				autoComplete:false,
+				selectOnClick:true,
+				pageSize:5,
+				title:"New England States"
+		'>
 			<option value="ct">Connecticut</option>
 			<option value="me">Maine</option>
 			<option value="ma">Massachusetts</option>
@@ -344,38 +352,34 @@
 		</select>
 		<hr>
 		<p>No arrow, data store which searches and highlights matches anywhere in the string</p>
-	 	<input dojoType="$testWidget"
-				id="arrowless"
-	 			value="$-setvaluetest-CA"
-				store="stateStore"
-				searchAttr="name"
-				queryExpr="*${0}*"
-				name="state5"
-				autoComplete="false"
-				hasDownArrow="false"
-				highlightMatch="all"
-		>
+	 	<input id="arrowless" data-dojo-type="$testWidget"
+				data-dojo-props='value: (testWidget == "dijit.form.ComboBox") ? "California" : "CA",
+				store:stateStore,
+				searchAttr:"name",
+				queryExpr:"*${0}*",
+				name:"state5",
+				autoComplete:false,
+				hasDownArrow:false,
+				highlightMatch:"all"
+		'/>
 		<hr>
 		<p>Created programmatically</p>
-		<input id="progCombo">
+		<input id="progCombo"/>
 		<hr>
 		<p>Created programmatically with an initial query.  (Limits list to items with type = country.)</p>
-		<input id="progCombo2">
+		<input id="progCombo2"/>
 		<hr>
 		<p>Created programmatically with an ItemFileReadStore and a descending sort.  (Limits list to items with type = country.)</p>
-		<input id="progCombo3">
+		<input id="progCombo3"/>
 		<hr>
 		<p>With option tags, autoComplete=true, pageSize=30, and a descending sort.</p>
-		<select
-				name="descending"
-				id="descending"
-				dojoType="$testWidget"
-				style="width:50%;font-size:200%;font-family:Courier;"
-				autoComplete="true"
-				onChange="dojo.byId('oc1').value=arguments[0]"
-				pageSize="30"
-				fetchProperties="{sort:[{attribute: 'name', descending: true}]}"
-		>
+		<select id="descending" data-dojo-type="$testWidget"
+				data-dojo-props='name:"descending",
+				style:{width:"50%",fontSize:"200%",fontFamily:"Courier"},
+				autoComplete:true,
+				pageSize:30,
+				fetchProperties:{sort:[{attribute: "name", descending: true}]}
+		'>
 			<option value="AL">Alabama</option>
 			<option value="AK">Alaska</option>
 			<option value="AS">American Samoa</option>
@@ -448,10 +452,9 @@
 		   <li>3 * 5</li>
 		</ul>
 		<label for="specialchars">Special chars:</label>
-		<select dojoType="$testWidget"
-			name="specialchars"
-			id="specialchars"
-		>
+		<select id="specialchars" data-dojo-type="$testWidget"
+			data-dojo-props='name:"specialchars"
+			'>
 			<option value="sticks" selected>sticks & stones</option>
 			<option value="rags">rags --> riches</option>
 			<option value="more">more\less</option>
@@ -461,7 +464,7 @@
 		<p>Japanese</p>
 		<p>Try typing &#x6771;&#x533A; (East), &#x897F;&#x533A; (West), &#x5317;&#x533A; (North), &#x5357;&#x533A; (South) and a few choices will pop up.</p>
 		<label for="japanese">Japanese list:</label>
-		<select name="japanese" id="japanese" dojoType="$testWidget" style="width: 300px;" autoComplete="true" required="true" value="">
+		<select id="japanese" data-dojo-type="$testWidget" data-dojo-props='name:"japanese", style:{width:"300px"}, autoComplete:true, required:true, value:""'>
 			<option value="nanboku">&#x5357;&#x5317; (Nanboku)</option>
 			<option value="touzai">&#x6771;&#x897F; (Touzai)</option>
 			<option value="toukyou">&#x6771;&#x4EAC; (Tokyo)</option>
@@ -471,57 +474,57 @@
 			<option value="kitaku">&#x5317;&#x533A; (North)</option>
 		</select>
 		<hr>
-		<p>Custom labelFunc (value in textbox should be lower case when onChange is called), autoComplete=true, prompt message when field is blank:</p>
+		<p>Custom labelFunc (labels in lowercase), autoComplete=true, prompt message when field is blank:</p>
 		<label for="labelFunc">custom label function</label>
-		<input
-				id="labelFunc"
-				dojoType="$testWidget"
-				value="$-setvaluetest-OR"
-				labelFunc="myLabelFunc"
-				store="stateStore"
-				name="labelFunc"
-				autoComplete="true"
-				labelAttr="label"
-				labelType="html"
-				promptMessage="Please enter a state"
-				invalidMessage="Invalid state name."
-		>
-		<input type="button" onclick="dijit.byId('labelFunc').set('readOnly',false);" value="Remove readOnly">
-		<input type="button" onclick="dijit.byId('labelFunc').set('readOnly',true);" value="Set readOnly">
-		<input type="button" onclick="dijit.byId('labelFunc').set('disabled',false);" value="Remove disabled">
-		<input type="button" onclick="dijit.byId('labelFunc').set('disabled',true);" value="Set disabled">
+		<input id="labelFunc" data-dojo-type="$testWidget"
+				data-dojo-props='value: (testWidget == "dijit.form.ComboBox") ? "Oregon" : "OR",
+				labelFunc:myLabelFunc,
+				store:stateStore,
+				name:"labelFunc",
+				autoComplete:true,
+				labelAttr:"label",
+				labelType:"html",
+				promptMessage:"Please enter a state",
+				invalidMessage:"Invalid state name."
+		'/>
+		<input type="button" onclick="dijit.byId('labelFunc').set('readOnly',false);" value="Remove readOnly"/>
+		<input type="button" onclick="dijit.byId('labelFunc').set('readOnly',true);" value="Set readOnly"/>
+		<input type="button" onclick="dijit.byId('labelFunc').set('disabled',false);" value="Remove disabled"/>
+		<input type="button" onclick="dijit.byId('labelFunc').set('disabled',true);" value="Set disabled"/>
 		<hr>
-		<input type="button" value="Create one in a window" onclick="var win=window.open(window.location);">
-		<input type="submit">
-		<script>
-			// so robot can get to it easily
-			document.displayData=function() {
-				var f = document.getElementById("form1");
-				var s = "";
-				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; }
-					s += elem.name + ": " + elem.value + "\n";
-				}
-				return s;
-			}
-		</script>
-		<button name="button" onclick="alert(document.displayData()); return false;">view data</button>
+
+		<p>Rich text label</p>
+		<label for="richtexttest">Rich text labels in drop down:</label>
+		<select id="richtexttest" data-dojo-type="$testWidget"
+				data-dojo-props='name:"richtexttest",
+				autoComplete:false,
+				selectOnClick:true,
+				value:"h1",
+				labelType:"html",
+				labelFunc:function(node){ var txt = node.innerHTML; return "<"+txt+">"+txt+"</"+txt+">"; }
+		'>
+			<option value="h1">h1</option>
+			<option value="h2">h2</option>
+			<option value="p">p</option>
+			<option value="pre">pre</option>
+		</select>
+		<hr>
+
+		<input type="button" value="Create one in a window" onclick="var win=window.open(window.location);"/>
 
 	</form>
 	
 	<hr>
 	<p>test placeholder</p>
-	<select id="placeholdertest"
-			name="placetest"
-			dojoType="$testWidget"
-			style="width:50%;font-family:Courier;"
-			autoComplete="false"
-			selectOnClick="true"
-			pageSize="5"
-			placeHolder="Select a New England State"
-			value=""
-	>
+	<select id="placeholdertest" data-dojo-type="$testWidget"
+			data-dojo-props='name:"placetest",
+			style:{width:"50%",fontFamily:"Courier"},
+			autoComplete:false,
+			selectOnClick:true,
+			pageSize:5,
+			placeHolder:"Select a New England State",
+			value:""
+	'>
 		<option value="ct">Connecticut</option>
 		<option value="me">Maine</option>
 		<option value="ma">Massachusetts</option>
@@ -538,9 +541,62 @@
 	  <option>IE bleed through</option>
 	  <option>problem</option>
 	</select>
+	
+	Destroy test:<div id="destroyDiv"
+		><select id="combo_01" data-dojo-type="$testWidget" 
+				data-dojo-props='name:"state", 
+				disabled:true,
+				style:{width:"300px"},
+				autoComplete:false'>
+			<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>
+		</select
+	></div>
+
+	<br>
+	<fieldset style="position:relative;border:1px solid black;display:inline;">
+		<span style="position:absolute;">Highlight test</span>
+		<div style="border:0;margin:1.5em;">
+			<span style='white-space:nowrap;'>
+			ignoreCase:<select onchange="dijit.byId('highlight').set('ignoreCase', this.value=='true')">
+				<option value="true" selected>true</option>
+				<option value="false">false</option>
+			</select>
+			highlightMatch:<select onchange="dijit.byId('highlight').set('highlightMatch', this.value)">
+				<option value="first" selected>first</option>
+				<option value="all">all</option>
+				<option value="none">none</option>
+			</select>
+			queryExpr:<select onchange="dijit.byId('highlight').set('queryExpr', this.value)">
+				<option value="${0}*" selected>${0}*</option>
+				<option value="*${0}*">*${0}*</option>
+				<option value="*${0}">*${0}</option>
+			</select>
+			</span>
+			<br>
+			<span style='white-space:nowrap;'>
+			Highlight test:<select id="highlight" data-dojo-type="$testWidget"
+					data-dojo-props='ignoreCase:true,
+					highlightMatch:"first",
+					autoComplete:false,
+					required:false,
+					labelType:"text",
+					onBlur:function(){ this.set("value",null) },
+					value:""'>
+				<option value="AA">AA</option>
+				<option value="Aa">Aa</option>
+				<option value="aA">aA</option>
+				<option value="aa">aa</option>
+			</select>
+			</span>
+		</div>
+	</fieldset>
 
 	<div id="debugbox"></div>
-	<!-- maintain state of combo box if user presses back/forward button -->
-	<form name="_dojo_form" style="display:none" disabled="true"><textarea name="stabile" cols="80" rows="10"></textarea></form>
 </body>
 </html>
diff --git a/dijit/tests/form/module.js b/dijit/tests/form/module.js
index 2fc3f2e..f98c692 100644
--- a/dijit/tests/form/module.js
+++ b/dijit/tests/form/module.js
@@ -3,53 +3,64 @@ dojo.provide("dijit.tests.form.module");
 try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
-	doh.registerUrl("dijit.tests.form.robot.Button_mouse", dojo.moduleUrl("dijit","tests/form/robot/Button_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.Button_a11y", dojo.moduleUrl("dijit","tests/form/robot/Button_a11y.html"+userArgs), 99999999);
+	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.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.robot.test_validate", dojo.moduleUrl("dijit","tests/form/robot/test_validate.html"+userArgs), 99999999);
+	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.robot.DateTextBox", dojo.moduleUrl("dijit","tests/form/robot/DateTextBox.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.TimeTextBox", dojo.moduleUrl("dijit","tests/form/robot/TimeTextBox.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.form.robot.DateTextBox", dojo.moduleUrl("dijit","tests/form/robot/DateTextBox.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.form.robot.TimeTextBox", dojo.moduleUrl("dijit","tests/form/robot/TimeTextBox.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.form.Form", dojo.moduleUrl("dijit", "tests/form/Form.html"), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.Form", dojo.moduleUrl("dijit","tests/form/robot/Form.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.form.Form", dojo.moduleUrl("dijit", "tests/form/Form.html"), 999999);
+	doh.registerUrl("dijit.tests.form.robot.FormState", dojo.moduleUrl("dijit","tests/form/robot/Form_state.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.form.robot.Form_onsubmit", dojo.moduleUrl("dijit","tests/form/robot/Form_onsubmit.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.form.Select", dojo.moduleUrl("dijit", "tests/form/test_Select.html?mode=test"), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.Select", dojo.moduleUrl("dijit", "tests/form/robot/Select.html"), 99999999);
+	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.robot.ComboBox_mouse", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_mouse.html"+(userArgs+"&testWidget=dijit.form.ComboBox").replace(/^&/,"?")), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.ComboBox_a11y", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_a11y.html"+(userArgs+"&testWidget=dijit.form.ComboBox").replace(/^&/,"?")), 99999999);
+	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(/^&/,"?")), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.FilteringSelect_a11y", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_a11y.html"+(userArgs+"&testWidget=dijit.form.FilteringSelect").replace(/^&/,"?")), 99999999);
+	doh.registerUrl("dijit.tests.form.robot.FilteringSelect_mouse", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_mouse.html"+(userArgs+"&testWidget=dijit.form.FilteringSelect").replace(/^&/,"?")), 999999);
+	doh.registerUrl("dijit.tests.form.robot.FilteringSelect_a11y", dojo.moduleUrl("dijit","tests/form/robot/_autoComplete_a11y.html"+(userArgs+"&testWidget=dijit.form.FilteringSelect").replace(/^&/,"?")), 999999);
 
-	doh.registerUrl("dijit.tests.form.robot.Slider_mouse", dojo.moduleUrl("dijit","tests/form/robot/Slider_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.Slider_a11y", dojo.moduleUrl("dijit","tests/form/robot/Slider_a11y.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.form.robot.MultiSelect", dojo.moduleUrl("dijit","tests/form/robot/MultiSelect.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.form.robot.Spinner_mouse", dojo.moduleUrl("dijit","tests/form/robot/Spinner_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.form.robot.Spinner_a11y", dojo.moduleUrl("dijit","tests/form/robot/Spinner_a11y.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.form.robot.SimpleTextarea", dojo.moduleUrl("dijit","tests/form/robot/SimpleTextarea.html"+userArgs), 999999);
+	
+	doh.registerUrl("dijit.tests.form.robot.Slider_mouse", dojo.moduleUrl("dijit","tests/form/robot/Slider_mouse.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.form.robot.Slider_a11y", dojo.moduleUrl("dijit","tests/form/robot/Slider_a11y.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.form.CheckBox", dojo.moduleUrl("dijit", "tests/form/test_CheckBox.html"), 99999999);
+	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.robot.Textarea", dojo.moduleUrl("dijit","tests/form/robot/Textarea.html"+userArgs), 99999999);
+	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), 99999999);
+	doh.registerUrl("dijit.tests.form.robot.validationMessages", dojo.moduleUrl("dijit","tests/form/robot/validationMessages.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=tundra&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=tundra&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=tundra&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=claro&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=claro&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=claro&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=soria&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=soria&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=soria&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=nihilo&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=nihilo&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=nihilo&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?a11y=1&dir=ltr"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?a11y=1&dir=rtl"), 99999999);
-	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&a11y=1&dir=ltr"), 99999999);
+	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_sizes.tundra.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=tundra&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=tundra&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.tundra.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=tundra&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=claro&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=claro&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.claro.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=claro&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=soria&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=soria&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.soria.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=soria&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=nihilo&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?theme=nihilo&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.nihilo.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&theme=nihilo&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.ltr", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?a11y=1&dir=ltr"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.rtl", dojo.moduleUrl("dijit", "tests/form/TextBox_sizes.html?a11y=1&dir=rtl"), 999999);
+	doh.registerUrl("dijit.tests.form.TextBox_sizes.a11y.quirks", dojo.moduleUrl("dijit", "tests/quirks.html?file=form/TextBox_sizes.html&a11y=1&dir=ltr"), 999999);
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dijit/tests/form/robot/Button_a11y.html b/dijit/tests/form/robot/Button_a11y.html
index 7b743ae..c0a21f1 100644
--- a/dijit/tests/form/robot/Button_a11y.html
+++ b/dijit/tests/form/robot/Button_a11y.html
@@ -68,7 +68,7 @@
 
 							doh.is("1465", dijit.getEnclosingWidget(dojo.global.dijit._curFocus).id, "focus starting on 1465");
 
-							dijit.byId("1467").set("disabled", true);
+							dijit.byId("1466").set("disabled", true);
 
 							// tab over disabled "View" button to "Create" combo-button
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
@@ -370,15 +370,21 @@
 
 				doh.register("dijit.form.ToggleButton", [
 					{
-						name: "change value",
+						name: "uncheck",
 						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							var checked = dijit.byId("toggle1").get("checked");
-							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
 							doh.t(checked, "toggle1 initially checked");
 
+							var watchOld, watchNew;
+							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
+							dijit.byId("toggle1").watch("checked", function(name, o, n){
+								watchOld = o;
+								watchNew = n;
+							});
+
 							doh.robot.sequence(function(){
 								dijit.byId("toggle1").focus();
 							});
@@ -386,10 +392,42 @@
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(checked, "toggle1 unchecked");
+								doh.t(watchOld, "watch: previous == checked");
+								doh.f(watchNew, "watch: new == unchecked");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "check",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var checked = dijit.byId("toggle1").get("checked");
+							doh.f(checked, "toggle1 unchecked");
+
+							var watchOld, watchNew;
+							dijit.byId("toggle1").set("onChange", function(v){ checked = v; });
+							dijit.byId("toggle1").watch("checked", function(name, o, n){
+								watchOld = o;
+								watchNew = n;
+							});
+
+							doh.robot.sequence(function(){
+								dijit.byId("toggle1").focus();
+							});
+							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(checked, "toggle1 checked");
+								doh.f(watchOld, "watch: previous == unchecked");
+								doh.t(watchNew, "watch: new == checked");
 							}), 1000);
 							return d;
 						}
 					}
+
 				]);
 
 				dojo.forEach(["SPACE", "ENTER"], function(key){
diff --git a/dijit/tests/form/robot/Button_mouse.html b/dijit/tests/form/robot/Button_mouse.html
index 0333284..7cb35cd 100644
--- a/dijit/tests/form/robot/Button_mouse.html
+++ b/dijit/tests/form/robot/Button_mouse.html
@@ -28,9 +28,9 @@
 							var d = new doh.Deferred();
 
 							var clicked = false;
-							dijit.byId("1467").set("onClick", function(){ clicked = true; });
+							dijit.byId("1466").set("onClick", function(){ clicked = true; });
 
-							doh.robot.mouseMoveAt("1467", 500);
+							doh.robot.mouseMoveAt("1466", 500);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -281,13 +281,13 @@
 					{
 						name: "icon",
 						runTest: function(){
-							doh.f(dojo.hasClass(dijit.byId("1467").iconNode, "plusIcon"), "doesn't plus icon class");
-							dijit.byId("1467").set("iconClass", "plusIcon");
-							doh.t(dojo.hasClass(dijit.byId("1467").iconNode, "plusIcon"), "has plus icon class");
+							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");
 
 							// switching icon erases old one
-							dijit.byId("1467").set("iconClass", "noteIcon");
-							doh.f(dojo.hasClass(dijit.byId("1467").iconNode, "plusIcon"), "doesn't plus icon class");
+							dijit.byId("1466").set("iconClass", "noteIcon");
+							doh.f(dojo.hasClass(dijit.byId("1466").iconNode, "plusIcon"), "doesn't plus icon class");
 						}
 					},
 
@@ -325,18 +325,23 @@
 					}
 				]);
 
+				var nameBox, valueBox;
+				function setUp(){
+					nameBox = dojo.byId("buttonName");
+					valueBox = dojo.byId("buttonValue");
+					dojo.window.scrollIntoView(valueBox);
+					nameBox.value = 'INIT';
+					valueBox.value = 'INIT';
+				}
 				doh.register("submit", [
 					{
 						name: "plain",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
-							doh.robot.mouseMoveAt('Plain', 500);
+							doh.robot.mouseMoveAt('Plain', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -350,14 +355,11 @@
 					{
 						name: "combo left",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
-							doh.robot.mouseMoveAt('Combo', 500);
+							doh.robot.mouseMoveAt('Combo', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -371,16 +373,13 @@
 					{
 						name: "combo right",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
 							var downArrowNode = dojo.query(".dijitDownArrowButton", dojo.byId("Combo"))[0];
 
-							doh.robot.mouseMoveAt(downArrowNode, 500);
+							doh.robot.mouseMoveAt(downArrowNode, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -394,14 +393,11 @@
 					{
 						name: "combo menu",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
-							doh.robot.mouseMoveAt("ComboMenuItem", 1000);
+							doh.robot.mouseMoveAt("ComboMenuItem", 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -415,14 +411,11 @@
 					{
 						name: "drop down",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
-							doh.robot.mouseMoveAt('DropDown', 500);
+							doh.robot.mouseMoveAt('DropDown', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -436,14 +429,11 @@
 					{
 						name: "drop down menu",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
-							doh.robot.mouseMoveAt("DropDownMenuItem", 1000);
+							doh.robot.mouseMoveAt("DropDownMenuItem", 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -457,14 +447,11 @@
 					{
 						name: "disabled",
 						timeout: 5000,
+						setUp: setUp,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var nameBox = dojo.byId("buttonName");
-							var valueBox = dojo.byId("buttonValue");
-							nameBox.value = 'INIT';
-							valueBox.value = 'INIT';
 
-							doh.robot.mouseMoveAt('Disabled', 500);
+							doh.robot.mouseMoveAt('Disabled', 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
diff --git a/dijit/tests/form/robot/CheckBox_a11y.html b/dijit/tests/form/robot/CheckBox_a11y.html
new file mode 100644
index 0000000..e7e809e
--- /dev/null
+++ b/dijit/tests/form/robot/CheckBox_a11y.html
@@ -0,0 +1,361 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Checkbox a11y Test</title>
+
+		<style>
+			@import "../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: true, 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_Checkbox.html');
+
+				doh.register("Checkbox a11y",[
+					{
+						timeout:5000,
+						name:"uncheck cb0 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							dijit.byId("cb1").focus();
+							doh.robot.keyPress(dojo.keys.TAB, 500, {
+								shift: true
+							});
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dojo.byId('cb0').checked, "cb0 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:5000,
+						name:"check cb1 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('cb1').checked, "cb1 was not checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:7000,
+						name:"uncheck cb2 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('cb2').checked, "cb2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:7000,
+						name:"cb4 readonly a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('cb4').checked, "cb4 was not checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:9000,
+						name:"cb6 uncheck a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('cb6').checked, "cb6 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"cb6 check a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.SPACE, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('cb6').checked, "cb6 was not checked");
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("Radio button a11y",[
+					{
+						timeout:6000,
+						name:"weather enabled a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							dijit.byId("g1rb2").focus();
+							doh.robot.sequence(function(){
+								dijit.byId("g1rb3").set("disabled",false);
+							}, 1000); 
+							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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:6000,
+						name:"change value to county a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							dijit.byId("g2rb1").focus();
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+							doh.robot.keyPress(dojo.keys.SPACE, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:4000,
+						name:"change value to top 40 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:11000,
+						name:"enable b1 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('b1').checked, "b1 was not checked");
+								doh.f(dijit.byId('b2').checked, "b2 was checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.f(dijit.byId('c2').checked, "c2 was checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable b2 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.f(dijit.byId('c2').checked, "c2 was checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:5000,
+						name:"enable c1 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.SPACE, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.t(dijit.byId('c1').checked, "c1 was not checked");
+								doh.f(dijit.byId('c2').checked, "c2 was checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable c2 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.t(dijit.byId('c2').checked, "c2 was not checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:6000,
+						name:"enable d2 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 1000);
+							doh.robot.keyPress(dojo.keys.SPACE, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.t(dijit.byId('c2').checked, "c2 was not checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.t(dijit.byId('d2').checked, "d2 was not checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable d1 a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.t(dijit.byId('c2').checked, "c2 was not checked");
+								doh.t(dijit.byId('d1').checked, "d1 was not checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:5000,
+						name:"enable coffee a11y",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('g4rb1').checked, "tea was checked");
+								doh.t(dijit.byId('g4rb2').checked, "coffee was not checked");
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("CheckBox watch",
+					[
+						function w(){
+							var cb = dijit.byId('cb2');
+							cb.set("checked", true);
+
+							var oldWatch, newWatch;
+							cb.watch("checked", function(name, o, n){
+								oldWatch = o;
+								newWatch = n;
+							});
+
+							cb.set("checked", false);
+							doh.t(oldWatch, "old value was checked");
+							doh.f(newWatch, "new value is unchecked");
+
+							cb.set("checked", true);
+							doh.f(oldWatch, "old value was unchecked");
+							doh.t(newWatch, "new value is checked");
+						}
+					]
+				);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/CheckBox_mouse.html b/dijit/tests/form/robot/CheckBox_mouse.html
new file mode 100644
index 0000000..6043f5d
--- /dev/null
+++ b/dijit/tests/form/robot/CheckBox_mouse.html
@@ -0,0 +1,507 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Checkbox mouse Test</title>
+
+		<style>
+			@import "../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+
+		<script type="text/javascript" src="../../helpers.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+			dojo.require("dijit.form.CheckBox");
+
+			// These are the values assigned to the widgets in the page's HTML
+			var originalGet = {
+				cb1: [],
+				cb2: ["on"],
+				cb4: ["on"],
+				cb5: [],
+				cb6: ["on"],
+				cb7: [],
+				'g[1]': "talk",
+				g2: null
+			};
+
+			var originalSubmit = {
+				cb2: "on",
+				cb4: "on",
+				cb6: "on",
+				'g[1]': "talk"
+			};
+
+			// attempt to change these values
+			var change = {
+				cb1: ["foo"],
+				cb2: [],
+				cb3: ["on"],
+				cb4: [],
+				cb5: ["on"],
+				cb6: ["foo"],
+				'g[1]': "weather",
+				g2: "country"
+			};
+
+			// changed values
+			var changedGet = {
+				cb1: ["foo"],
+				cb2: [],
+				cb4: [],
+				cb5: ["on"],
+				cb6: [],
+				cb7: [],
+				'g[1]': null,
+				g2: "country"
+			};
+
+			var changedSubmit = {
+				cb1: "foo",
+				cb5: "on",
+				g2: "country"
+			};
+		
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_Checkbox.html');
+
+				// should be able to query for all of the inputs, including hidden ones
+				doh.register("query input by checked state", [
+					{
+						name: "query checked",
+						runTest: function(){
+							var queried=dojo.query("input[checked]", dojo.byId('myForm'));
+							doh.is(5,queried.length,"expected: 5 checked widgets, got: "+queried.length);
+						}
+					}
+				]);
+
+				doh.register("query input by name", [
+					{
+						name: "query name",
+						runTest: function(){
+							var queried=dojo.query("input[name]", dojo.byId('myForm'));
+							doh.is(13,queried.length,"expected: 13 named widgets, got: "+queried.length);
+						}
+					}
+				]);
+
+				var formWidget = dijit.byId("myForm");
+
+				var submitForm = function(name, testValues){
+					return {
+						name: name,
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							submittedValues = function(formValues){
+								d.getTestCallback(function(){
+									for(var i in originalGet){ doh.is(testValues[i], formValues[i], i); }
+								})();
+							};
+							formWidget.submit();
+							return d;
+						},
+						tearDown: function(){
+							submittedValues = defaultSubmitHandler;
+						}
+					};
+				};
+
+				doh.register("CheckBox values", [
+					function getValues(){
+						doh.is( dojo.toJson(originalGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')) );
+					},
+					{
+						timeout:3000,
+						name:"setValues",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ submitForm("original submit", originalSubmit); }, 500); 
+							doh.robot.sequence(function(){ dijit.byId("myForm").set('value', change); }, 500); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is( dojo.toJson(changedGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')) );
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"resetValues",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ submitForm("changed submit", changedSubmit); }, 500); 
+							doh.robot.sequence(function(){ dijit.byId("myForm").reset(); }, 500); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is( dojo.toJson(originalGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')), "reset to original values" );
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"readOnly",
+						runTest:function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ submitForm("reset submit", originalSubmit); }, 500); 
+							doh.robot.mouseMoveAt("cb4", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is( dojo.toJson(originalGet), dojo.global.dojo.toJson(dijit.byId("myForm").get('value')), "still have original values" );
+								submitForm("resubmit", originalSubmit);
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("CheckBox onChange",
+					[
+						function fireOnChange(){
+							var d = new doh.Deferred();
+							var cb = dijit.byId('cb2');
+							var lastOnChange = dojo.byId('oncheckedoutput').innerHTML;
+							cb.set('checked', !cb.get('checked'));
+							setTimeout(d.getTestCallback(function(){
+								doh.isNot(lastOnChange, dojo.byId('oncheckedoutput').innerHTML);
+							}), 500);
+							return d;
+						},
+
+						function skipOnChange(){
+							var d = new doh.Deferred();
+							var cb = dijit.byId('cb2');
+							var lastOnChange = dojo.byId('oncheckedoutput').innerHTML;
+							cb.set('checked', !cb.get('checked'), false);
+							setTimeout(d.getTestCallback(function(){
+								doh.is(lastOnChange, dojo.byId('oncheckedoutput').innerHTML);
+							}), 500);
+							return d;
+						}
+					]
+				);
+				
+				doh.register("Radio button onChange",[
+					function checkInitialValues(){
+						doh.f(dijit.byId('g1rb1').checked, "news was checked");
+						doh.t(dijit.byId('g1rb2').checked, "talk was not checked");
+						doh.f(dijit.byId('g1rb3').checked, "weather was checked");
+						doh.f(dijit.byId('g2rb1').checked, "top 40 was checked");
+						doh.f(dijit.byId('g2rb2').checked, "oldies was checked");
+						doh.f(dijit.byId('g2rb3').checked, "country was checked");
+						doh.f(dojo.byId('g3rb1').checked, "rock was checked");
+						doh.f(dojo.byId('g3rb2').checked, "jazz was checked");
+						doh.t(dojo.byId('g3rb3').checked, "classical was not checked");
+						doh.t(dijit.byId('g4rb1').checked, "tea was not checked");
+						doh.f(dijit.byId('g4rb2').checked, "coffee was checked");
+					},
+					{
+						timeout:3000,
+						name:"change value to news",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g1rb1", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('g1rb1').checked, "news was not checked");
+								doh.f(dijit.byId('g1rb2').checked, "talk was checked");
+								doh.f(dijit.byId('g1rb3').checked, "weather was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"weather disabled",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g1rb3", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('g1rb1').checked, "news was not checked");
+								doh.f(dijit.byId('g1rb2').checked, "talk was checked");
+								doh.f(dijit.byId('g1rb3').checked, "weather was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:4000,
+						name:"weather enabled",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("enableWeatherButton", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("g1rb3", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"change value to county",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g2rb3", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"change value to top 40",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g2rb1", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"change value to oldies",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g2rb2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('g2rb3').checked, "country was checked");
+								doh.t(dijit.byId('g2rb2').checked, "oldies was not checked");
+								doh.f(dijit.byId('g2rb1').checked, "top 40 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"change value to rock",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g3rb1", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dojo.byId('g3rb1').checked, "rock was not checked");
+								doh.f(dojo.byId('g3rb2').checked, "jazz was checked");
+								doh.f(dojo.byId('g3rb3').checked, "classical was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"disabled jazz",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g3rb2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dojo.byId('g3rb1').checked, "rock was not checked");
+								doh.f(dojo.byId('g3rb2').checked, "jazz was checked");
+								doh.f(dojo.byId('g3rb3').checked, "classical was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable b1",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("b1", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId('b1').checked, "b1 was not checked");
+								doh.f(dijit.byId('b2').checked, "b2 was checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.f(dijit.byId('c2').checked, "c2 was checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable b2",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("b2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.f(dijit.byId('c2').checked, "c2 was checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable c1",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("c1", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.t(dijit.byId('c1').checked, "c1 was not checked");
+								doh.f(dijit.byId('c2').checked, "c2 was checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable c2",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("c2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.t(dijit.byId('c2').checked, "c2 was not checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable d2",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("d2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.t(dijit.byId('c2').checked, "c2 was not checked");
+								doh.f(dijit.byId('d1').checked, "d1 was checked");
+								doh.t(dijit.byId('d2').checked, "d2 was not checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable d1",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("d1", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('b1').checked, "b1 was checked");
+								doh.t(dijit.byId('b2').checked, "b2 was not checked");
+								doh.f(dijit.byId('c1').checked, "c1 was checked");
+								doh.t(dijit.byId('c2').checked, "c2 was not checked");
+								doh.t(dijit.byId('d1').checked, "d1 was not checked");
+								doh.f(dijit.byId('d2').checked, "d2 was checked");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						timeout:3000,
+						name:"enable coffee",
+						runTest:function(){
+							var d = new doh.Deferred();
+ 
+							doh.robot.mouseMoveAt("g4rb2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId('g4rb1').checked, "tea was checked");
+								doh.t(dijit.byId('g4rb2').checked, "coffee was not checked");
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/DateTextBox.html b/dijit/tests/form/robot/DateTextBox.html
index 1bc5ccd..5ea63d4 100644
--- a/dijit/tests/form/robot/DateTextBox.html
+++ b/dijit/tests/form/robot/DateTextBox.html
@@ -22,22 +22,28 @@
 				doh.robot.initRobot('../test_DateTextBox.html');
 
 				// refs to DateTextBox widgets
-				var american, german;
+				var american, german, localLong;
 
-				// log of calls to onChange handler
-				var changes = [];
+				// log of calls to onChange handler, and watch(value)
+				var changes = [], watches = [];
 
 				doh.register("setup",
 					function setUp(){
 						// refs to DateTextBox widgets
 				    	american = dijit.byId('american');
 				    	german = dijit.byId('german');
+						localLong = dijit.byId('localLong');
+				    	pattern = dijit.byId('pattern');
 
 				    	// setup onChange handler to monitor onChange calls on american textbox
 						dojo.connect(american, 'onChange', function(val){
 							console.log('onchange w/value: ', val);
 							changes.push(val);
 						});
+						
+						american.watch("value", function(attr, oldV, newV){
+							watches.push(newV);
+						});
 				    }
 				);
 
@@ -80,73 +86,583 @@
 						american.set('displayedValue', '12/1/2008');
 						doh.f(american.isValid(), 'marked as invalid since out of range');
 						doh.is('12/1/2008', american.get('displayedValue'), 'displayed value of american');
+					},
+
+					function noInitialValue(){
+				    		var fromDate = dijit.byId('fromDate');
+						doh.is('', fromDate.get('displayedValue'), 'initially blank');
+						doh.is(dijit.form.DateTextBox.prototype.value, fromDate.value, 'default value');
+						var d = new doh.Deferred();
+						var today = new Date();
+						fromDate.set('value', today, true);
+						doh.robot.sequence(d.getTestCallback(function(){
+				    			var toDate = dijit.byId('toDate');
+							doh.is(today.toDateString(), fromDate.value.toDateString(), 'changed value');
+							doh.is(today.toDateString(), toDate.constraints.min.toDateString(), 'onChange');
+						}), 500);
+						return d;
+					}
+				]);
+
+
+				doh.register("localization", [
+					function initialGerman(){
+						doh.is(0, dojo.date.compare(new Date(2006,10,29), german.get('value')), 'wire value of german: ' + german.get('value'));
+						doh.is('29.11.2006', german.get('displayedValue'), 'displayed value of german');
+					},
+
+					function setValueGerman(){
+						german.set('value', new Date(2004,9,20));
+						doh.is(0, dojo.date.compare(new Date(2004,9,20), german.get('value')),
+								'wire value of german is: ' + german.get('value') +
+								' but should be: ' + new Date(2004,9,20));
+						doh.is('20.10.2004', german.get('displayedValue'), 'displayed value of german');
+						doh.t(german.isValid(), 'marked as valid');
+					},
+
+					function setDisplayedValueGerman(){
+						german.set('displayedValue', '12.11.2006');
+						doh.is(0, dojo.date.compare(new Date(2006, 10, 12), german.get('value')), 'wire value of german');
+						doh.is('12.11.2006', german.get('displayedValue'), 'displayed value of german');
+						doh.t(german.isValid(), 'marked as valid');
+					},
+
+					{
+						name: "labels",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							german.set('value', new Date(2006, 9, 15));	// 10/15/2006
+
+							doh.robot.mouseMoveAt(german.domNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var calendar = dijit.byId("german_popup");
+
+								// calendar exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// Month label
+								doh.is("Oktober", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]));
+
+								// Day labels
+								var dayLabels = dojo.query(".dijitCalendarDayLabelTemplate", calendar.domNode);
+								doh.is(7, dayLabels.length, "7 day labels");
+								doh.is("M", innerText(dayLabels[0]), "day 0");
+								doh.is("D", innerText(dayLabels[1]), "day 1");
+								doh.is("M", innerText(dayLabels[2]), "day 2");
+								doh.is("D", innerText(dayLabels[3]), "day 3");
+								doh.is("F", innerText(dayLabels[4]), "day 4");
+								doh.is("S", innerText(dayLabels[5]), "day 5");
+								doh.is("S", innerText(dayLabels[6]), "day 6");
+							}), 1000);
+
+							return d;
+						}
 					}
 				]);
 
-				doh.register("direct input", {
+				doh.register("keyboard: direct input", {
 					name: "direct input",
-					timeout: 60000,
+					timeout: 6000,
 					setUp: function(){
 						// clear the field
-						american.set('value', null);
+						changes = [];
+						watches = [];
+						american.set('value', null, false);
 					},
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.robot.sequence(function(){
-							// monitor onchange events
-							changes = [];
-							american.focus();
-						}, 500);
-						doh.robot.typeKeys('1/3/2005', 500, 1600);
+
+						doh.is(1, watches.length, 'one watch(value) event from the set("value")');
+
+						american.focus();
+
+						doh.robot.typeKeys('1/3/2005', 1000, 1600);
 						doh.robot.keyPress(dojo.keys.TAB, 500, {});
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+						doh.robot.sequence(d.getTestCallback(function(){
 							var value = american.get('value');
 							doh.is(0, dojo.date.compare(new Date(2005, 0, 3), value), 'actual value is ' + value);
 							doh.is(1, changes.length, 'one onchange event');	// #9018
+							doh.is(2, watches.length, 'one watch(value) event from the onblur');
 							doh.is(0, dojo.date.compare(new Date(2005, 0, 3), changes[0]),
 									'value reported by onchange: ' + changes[0] +
 									', should be ' + new Date(2005, 0, 3));
-						})), 1000);
+							doh.is(0, dojo.date.compare(new Date(2005, 0, 3), watches[1]),
+									'value reported by watch(value): ' + watches[1] +
+									', should be ' + new Date(2005, 0, 3));
+						}), 1000);
 						return d;
 					}
 				});
 
-				doh.register("drop down", [
+				doh.register("keyboard: drop down", [
+					function setUp(){
+						// set to may 10
+						changes = [];
+						american.set('displayedValue', "", false);
+						watches = [];	// put after set() so we can ignore the watch() published by set()
+					},
+
+					{
+						name: "initial popup display",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								calendar;
+
+							american.focus();
+
+							doh.robot.typeKeys("5/10/2005", 1000, 1800);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 700, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								calendar = dijit.byId("american_popup");
+
+								// calendar exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// calendar is on the right month
+								doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
+
+								// and the right year
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+								doh.is(1, selectedYearButtons.length, "current year is shown");
+								doh.is("2005", innerText(selectedYearButtons[0]), "current year is 2005");
+
+								// and the currently selected date is right too
+								var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
+								doh.is(1, selectedDays.length, "one day selected");
+								doh.is("10", innerText(selectedDays[0]), "correct day is selected");
+
+								// focus moved to the calendar
+								doh.is(10, innerText(dojo.global.dijit._curFocus), "focus on selected calendar cell")
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "forward two days",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// selected day not changed (because no ENTER/SPACE)
+								var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
+								doh.is(1, selectedDays.length, "one day selected");
+								doh.is(10, innerText(selectedDays[0]), "correct day is selected");
+
+								// focus still on the calendar, moved forward 2 days
+								doh.is(12, innerText(dojo.global.dijit._curFocus), "focus")
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "back a day",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// focus still on the calendar, moved back 1 day
+								doh.is(11, innerText(dojo.global.dijit._curFocus), "focus")
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "forward four weeks",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 750, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 750, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 750, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 750, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// should have advanced to next month
+								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(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "back three weeks",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 750, {});
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 750, {});
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 750, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// should have scrolled back to previous month
+								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(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "forward two months",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 750, {});
+							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 750, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// focused day still the same
+								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+
+								// month changed
+								doh.is("July", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "month changed");
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "back a month",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.PAGE_UP, 750, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// focused day still the same
+								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+
+								// month changed
+								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "month changed");
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "forward two years",
+						timeout: 6000,
+						runTest: function(){
+							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.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								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")
+
+								// same month
+								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "same month");
+
+								// year changed
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+								doh.is(1, selectedYearButtons.length, "current year is shown");
+								doh.is("2007", innerText(selectedYearButtons[0]), "year changed");
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "back a year",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.PAGE_UP, 750, {ctrl: true});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// focused day still the same
+								doh.is(18, innerText(dojo.global.dijit._curFocus), "focus")
+
+								// same month
+								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "same month");
+
+								// year changed
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+								doh.is(1, selectedYearButtons.length, "current year is shown");
+								doh.is("2006", innerText(selectedYearButtons[0]), "year changed");
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "first day of month",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.HOME, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// focused on first day of month
+								doh.is(1, innerText(dojo.global.dijit._curFocus), "focus")
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "last day of month",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var calendar = dijit.byId("american_popup");
+
+							doh.robot.keyPress(dojo.keys.END, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// focused on last day of month
+								doh.is(30, innerText(dojo.global.dijit._curFocus), "focus")
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "select a date",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// select
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is('6/30/2006', american.get('displayedValue'), 'displayed value of american');
+
+								var expectedVal = new Date(2006, 5, 30);	// 6/30/2006
+								doh.is(0, dojo.date.compare(expectedVal, american.get('value')), 'wire value of american: ' + american.get('value'));
+
+								doh.is(1, changes.length, "onchange event fired");
+								doh.is(1, watches.length, "watch(value) event fired");
+								doh.is(0, dojo.date.compare(expectedVal, changes[0]), 'onchange of american: ' + changes[0]);
+								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>")
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "tab away",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
+							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")
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+
+// TODO: add key-repeat tests
+
+				doh.register("mouse: drop down", [
 					function setUp(){
 						// clear the field
-						american.set('value', new Date(2005, 4, 10));
+						changes = [];
+						american.set('displayedValue', "", false);
+						watches = [];	// do it here to ignore watch() notification for above set() call
 					},
 
 					{
 						name: "initial popup display",
-						timeout: 60000,
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is(0, changes.length, "no onchange events yet #1");
+								doh.is(0, watches.length, "no watch(value) events yet #1");
+							}), 500);
+
+							doh.robot.mouseMoveAt(american.focusNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var calendar = dijit.byId("american_popup");
+
+								// drop down automatically opened on click
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								doh.is(0, changes.length, "no onchange events yet #2");
+								doh.is(0, watches.length, "no watch(value) events yet #2");
+							}), 1000);
+
+							return d;
+						}
+					},
+					
+					{
+						name: "close and reopen",
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							doh.robot.sequence(function(){
-								changes = [];
-								american.focus();
-							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var calendar = dojo.byId("american_popup");
+							// Close drop down and then type a value
+							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							doh.robot.typeKeys("5/10/2005", 500, 1800);
+							
+							// And open dropdown again (manually)
+							doh.robot.mouseMoveAt(american._buttonNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var calendar = dijit.byId("american_popup");
 
-								// Calendar exists and is shown
+								// calendar exists and is shown
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// Calendar is on the right month
-								doh.is("May", innerText(dijit.byNode(calendar).monthLabelNode), "calendar starts on month selected in input box");
+								// calendar is on the right month
+								doh.is("May", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
 
-								// And the right year
+								// and the right year
 								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
 								doh.is(1, selectedYearButtons.length, "current year is shown");
 								doh.is("2005", innerText(selectedYearButtons[0]), "current year is 2005");
 
-								// And the currently selected date is right too
+								// and the currently selected date is right too
 								var selectedDays = dojo.query(".dijitCalendarSelectedDate", calendar.domNode);
 								doh.is(1, selectedDays.length, "one day selected");
 								doh.is("10", innerText(selectedDays[0]), "correct day is selected");
-							})), 1000);
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
 
 							return d;
 						}
@@ -154,25 +670,28 @@
 
 					{
 						name: "advance a month",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var calendar = dojo.byId("american_popup"),
+							var calendar = dijit.byId("american_popup"),
 								nextMonthButtons = dojo.query(".dijitCalendarIncrease", calendar.domNode);
 
 							doh.is(1, nextMonthButtons.length, "found next month button");
 
-							doh.robot.mouseMoveAt(nextMonthButtons[0], 500);
+							doh.robot.mouseMoveAt(nextMonthButtons[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								// Calendar still exists and is shown
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// Calendar moved to the next month
-								doh.is("June", innerText(dijit.byNode(calendar).monthLabelNode), "moved from may to june");
-							})), 1000);
+								// calendar moved to the next month
+								doh.is("June", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from may to june");
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
 
 							return d;
 						}
@@ -180,29 +699,30 @@
 
 					{
 						name: "advance a month with the menu dropdown",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							var calendar = dojo.byId("american_popup"),
-								calendarWidget = dijit.byNode(calendar);
+							var calendar = dijit.byId("american_popup");
 
-							doh.t("monthLabelNode" in calendarWidget, "found month label");
-							doh.t(calendarWidget.monthDropDown, "month dropdown exists");
-							doh.f(isVisible(calendarWidget.monthDropDown), "month dropdown is not visible");
+							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.robot.mouseMoveAt(calendarWidget.monthLabelNode, 500);
-							doh.robot.mousePress({left:true}, 500);
-							var july = dojo.query("[month=6]", calendarWidget.monthDropDown)[0];
-							doh.robot.mouseMoveAt(july, 500);
-							doh.robot.mouseRelease({left:true}, 500);
+							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];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								// Calendar still exists and is shown
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// Calendar moved to the next month
-								doh.is("July", innerText(calendarWidget.monthLabelNode), "moved from june to july");
+								// calendar moved to the next month
+								doh.is("July", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from june to july");
 								var rows = dojo.query("TR.dijitCalendarWeekTemplate", calendar.domNode),
 									firstRowDays = dojo.query("TD", rows[0]);
 								doh.is(7, firstRowDays.length, "7 days in first row");
@@ -210,8 +730,9 @@
 								doh.is("26", innerText(firstRowDays[0]), "first day is june 26");
 								doh.is("1", innerText(firstRowDays[5]), "sixth day is june 1");
 
-								calendarWidget._adjustDisplay("month", -1);
-							})), 1000);
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
 
 							return d;
 						}
@@ -219,28 +740,31 @@
 
 					{
 						name: "advance a year",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var calendar = dojo.byId("american_popup"),
+							var calendar = dijit.byId("american_popup"),
 								nextYearButtons = dojo.query(".dijitCalendarNextYear", calendar.domNode);
 
 							doh.is(1, nextYearButtons.length, "found next year button");
 
-							doh.robot.mouseMoveAt(nextYearButtons[0], 500);
+							doh.robot.mouseMoveAt(nextYearButtons[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								// Calendar still exists and is shown
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// Calendar moved to the next year
+								// calendar moved to the next year
 								var yearNodes = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
 								doh.is(1, yearNodes.length, "found year node");
 								doh.is("2006", innerText(yearNodes[0]), "moved from 2005 to 2006");
-							})), 1000);
+
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 1000);
 
 							return d;
 						}
@@ -248,24 +772,26 @@
 
 					{
 						name: "check disabled dates",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							// Move forward another year, to see disabled days (this date text box is valid only to 2006)
-							var calendar = dojo.byId("american_popup"),
+							var calendar = dijit.byId("american_popup"),
 								nextYearButtons = dojo.query(".dijitCalendarNextYear", calendar.domNode);
 
 							doh.is(1, nextYearButtons.length, "found next year button");
 
-							doh.robot.mouseMoveAt(nextYearButtons[0], 500);
+							doh.robot.mouseMoveAt(nextYearButtons[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.robot.sequence(d.getTestCallback(function(){
 								dojo.query(".dijitCalendarDateTemplate", calendar.domNode).forEach(function(node){
 									doh.t(dojo.hasClass(node, 'dijitCalendarDisabledDate'), 'every day in 2007 is disabled');
 								});
-							})), 1000);
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 500);
 
 							return d;
 						}
@@ -273,24 +799,26 @@
 
 					{
 						name: "check enabled dates",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							// Move back another year, dates should be enabled again
-							var calendar = dojo.byId("american_popup"),
+							// Move back a year, dates should be enabled again
+							var calendar = dijit.byId("american_popup"),
 								previousYearButtons = dojo.query(".dijitCalendarPreviousYear", calendar.domNode);
 
 							doh.is(1, previousYearButtons.length, "found previous year button");
 
-							doh.robot.mouseMoveAt(previousYearButtons[0], 500);
+							doh.robot.mouseMoveAt(previousYearButtons[0], 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.robot.sequence(d.getTestCallback(function(){
 								dojo.query(".dijitCalendarDateTemplate", calendar.domNode).forEach(function(node){
 									doh.f(dojo.hasClass(node, 'dijitCalendarDisabledDate'), "every day in 2006 is enabled");
 								});
-							})), 1000);
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 500);
 
 							return d;
 						}
@@ -298,42 +826,45 @@
 
 					{
 						name: "check calendar display",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
-							var calendar = dojo.byId("american_popup"),
+							var calendar = dijit.byId("american_popup"),
 								rows = dojo.query("TR.dijitCalendarWeekTemplate", calendar.domNode);
 
 							doh.is(6, rows.length, "six weeks shown");
 							var firstRowDays = dojo.query("TD", rows[0]);
 							doh.is(7, firstRowDays.length, "7 days in first row");
 							doh.t(dojo.hasClass(firstRowDays[0], "dijitCalendarPreviousMonth"), "previous month class applied");
-							doh.is("28", innerText(firstRowDays[0]), "first day is may 28");
-							doh.is("1", innerText(firstRowDays[4]), "fifth day is june 1");
+							doh.is("25", innerText(firstRowDays[0]), "first day is june 25");
+							doh.is("1", innerText(firstRowDays[6]), "seventh day is july 1");
 
-							dojo.query("TD", rows[5]).forEach(function(node){
-								doh.t(dojo.hasClass(node, 'dijitCalendarNextMonth'), "last row is for next month");
-							});
+							var lastRowDays = dojo.query("TD", rows[5]);
+							doh.t(dojo.hasClass(lastRowDays[3], 'dijitCalendarNextMonth'), "last row is for next month");
+							doh.is(0, changes.length, "no onchange events yet");
+							doh.is(0, watches.length, "no watch(value) events yet");
 						}
 					},
 
 					{
 						name: "hover a date",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var calendar = dojo.byId("american_popup"),
+							var calendar = dijit.byId("american_popup"),
 								rows = dojo.query("TR.dijitCalendarWeekTemplate", calendar.domNode),
 								thirdRowDays = dojo.query("TD", rows[2]),
-								day = thirdRowDays[4];
+								day = thirdRowDays[6];
 
-							// Hover June 15
-							doh.is("15", innerText(day), "found june 15");
-							doh.robot.mouseMoveAt(day, 500);
+							// hover June 15
+							doh.is("15", innerText(day), "found july 15");
+							doh.robot.mouseMoveAt(day, 0, 1);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(dojo.hasClass(day, 'dijitCalendarHoveredDate'), "hovered date has hover class");
-							})), 500);
+								doh.is(0, changes.length, "no onchange events yet");
+								doh.is(0, watches.length, "no watch(value) events yet");
+							}), 500);
 
 							return d;
 						}
@@ -341,24 +872,24 @@
 
 					{
 						name: "select a date",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.is(0, changes.length, "no onchange events yet");
-
-							// Select June 15
+							// select June 15
 							doh.robot.mouseClick({left:true}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('6/15/2006', american.get('displayedValue'), 'displayed value of american');
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is('7/15/2006', american.get('displayedValue'), 'displayed value of american');
 
-								var expectedVal = new Date(2006, 5, 15);	// 6/15/2006
+								var expectedVal = new Date(2006, 6, 15);	// 7/15/2006
 								doh.is(0, dojo.date.compare(expectedVal, american.get('value')), 'wire value of american: ' + american.get('value'));
 
 								doh.is(1, changes.length, "onchange event fired");
+								doh.is(1, watches.length, "watch(value) event fired");
 								doh.is(0, dojo.date.compare(expectedVal, changes[0]), 'onchange of american: ' + changes[0]);
-							})), 1000);
+								doh.is(0, dojo.date.compare(expectedVal, watches[0]), 'watch(value) of american: ' + watches[0]);
+							}), 1000);
 
 							return d;
 						}
@@ -366,73 +897,302 @@
 
 					{
 						name: "tab away",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is(1, changes.length, "no new onchange events");	// #9018
-							})), 1000);
+								doh.is(1, watches.length, "no new watch(value) events");
+							}), 1000);
 							return d;
 						}
 					}
 				]);
 
-				doh.register("localization", [
-					function initialGerman(){
-						doh.is(0, dojo.date.compare(new Date(2006,10,29), german.get('value')), 'wire value of german: ' + german.get('value'));
-						doh.is('29.11.2006', german.get('displayedValue'), 'displayed value of german');
+				// Tests that drop down displays correct year/month, and that correct cell is focused,
+				// based on this.value and this.dropDownDefaultValue
+				doh.register("focused popup value", [
+					{
+						name: "today",
+						timeout: 6000,
+						setUp: function(){
+							german.closeDropDown();
+							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(){
+								var today = new Date();
+	
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", german.dropDown.domNode);
+								doh.is(today.getFullYear(), innerText(selectedYearButtons[0]), "current year is selected");
+	
+								var selectedDates = dojo.query(".dijitCalendarSelectedDate", german.dropDown.domNode);
+								doh.is(0, selectedDates.length, "no selected date");
+							}), 500);
+
+							return d;
+						},
+						tearDown: function(){
+							german.closeDropDown();
+						}
 					},
+					{
+						name: "dropDownDefaultValue",
+						timeout: 6000,
+						setUp: function(){
+							german.closeDropDown();
+							german.set('value', null);
+							german.set("dropDownDefaultValue", new Date(2000,11,21));
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
 
-					function setValueGerman(){
-						german.set('value', new Date(2004,9,20));
-						doh.is(0, dojo.date.compare(new Date(2004,9,20), german.get('value')),
-								'wire value of german is: ' + german.get('value') +
-								' but should be: ' + new Date(2004,9,20));
-						doh.is('20.10.2004', german.get('displayedValue'), 'displayed value of german');
-						doh.t(german.isValid(), 'marked as valid');
+							german.focus();
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", german.dropDown.domNode);
+								doh.is("2000", innerText(selectedYearButtons[0]), "specified default year is selected");
+	
+								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");
+							}), 500);
+
+							return d;
+						},
+						tearDown: function(){
+							german.closeDropDown();
+						}
 					},
 
-					function setDisplayedValueGerman(){
-						german.set('displayedValue', '12.11.2006');
-						doh.is(0, dojo.date.compare(new Date(2006, 10, 12), german.get('value')), 'wire value of german');
-						doh.is('12.11.2006', german.get('displayedValue'), 'displayed value of german');
-						doh.t(german.isValid(), 'marked as valid');
+					// Testing that value overrides dropDownDefaultValue
+					{
+						name: "textbox value",
+						timeout: 6000,
+						setUp: function(){
+							german.closeDropDown();
+							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(){
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", german.dropDown.domNode);
+								doh.is("1900", innerText(selectedYearButtons[0]), "textbox year is selected");
+	
+								var selectedDates = dojo.query(".dijitCalendarSelectedDate", german.dropDown.domNode);
+								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");
+							}), 500);
+
+							return d;
+						},
+						tearDown: function(){
+							german.closeDropDown();
+						}
+					}
+				]);
+
+				// Testing that canceling an edit doesn't select anything
+				doh.register("cancel", [
+					{
+						name: "no value",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.f(pattern.get("value"), "initially blank");
+
+							// open the drop down
+							doh.robot.mouseMoveAt("pattern", 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								var calendar = dijit.byId("pattern_popup");
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+							}), 500);
+
+							// close the drop down
+							doh.robot.mouseMoveAt("pattern", 500, 1, pattern.domNode.offsetWidth + 20, pattern.domNode.offsetHeight/2);
+							doh.robot.mouseClick({left:true}, 500);			
+							doh.robot.sequence(d.getTestCallback(function(){
+								var calendar = dijit.byId("pattern_popup");
+								doh.f(calendar && isVisible(calendar), "calendar popup destroyed or hidden");
+								doh.f(pattern.get("value"), "no value set into DateTextBox")
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("month drop down edge case", [
+					function setUp(){
+						american.set('value', new Date(2010, 11, 31), false);
 					},
 
 					{
-						name: "calendar",
-						timeout: 60000,
+						name: "initial popup display",
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
-							doh.robot.sequence(function(){
-								german.set('value', new Date(2006, 9, 15));	// 10/15/2006
-								german.focus();
-							}, 500);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								var calendar = dojo.byId("german_popup");
+							doh.robot.mouseMoveAt(american.focusNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var calendar = dijit.byId("american_popup");
 
-								// Calendar exists and is shown
+								// calendar exists and is shown
 								doh.t(calendar, "calendar popup exists");
 								doh.t(isVisible(calendar), "calendar is visible");
 
-								// Month label
-								doh.is("Oktober", innerText(dijit.byNode(calendar).monthLabelNode));
+								// calendar is on the right month
+								doh.is("December", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "calendar starts on month selected in input box");
 
-								// Day labels
-								var dayLabels = dojo.query(".dijitCalendarDayLabelTemplate", calendar.domNode);
-								doh.is(7, dayLabels.length, "7 day labels");
-								doh.is("M", innerText(dayLabels[0]), "day 0");
-								doh.is("D", innerText(dayLabels[1]), "day 1");
-								doh.is("M", innerText(dayLabels[2]), "day 2");
-								doh.is("D", innerText(dayLabels[3]), "day 3");
-								doh.is("F", innerText(dayLabels[4]), "day 4");
-								doh.is("S", innerText(dayLabels[5]), "day 5");
-								doh.is("S", innerText(dayLabels[6]), "day 6");
-							})), 1000);
+								// and the right year
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+								doh.is(1, selectedYearButtons.length, "current year is shown");
+								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
+
+								// and the currently focused date is the 31'st
+								doh.is("31", innerText(dojo.global.dijit._curFocus), "correct day is focused");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					// Switching to February to test that movement works even though there is no Feb 31st.
+					{
+						name: "switch to february",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							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.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];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// calendar moved to feb 2010
+								doh.is("February", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from December to February");
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+								doh.is(1, selectedYearButtons.length, "current year is shown");
+								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
+							}), 500);
+
+							return d;
+						}
+					},
+
+					// Switching to December to make sure that drop down isn't cut off
+					{
+						name: "switch back to december",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							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.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];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// calendar still exists and is shown
+								doh.t(calendar, "calendar popup exists");
+								doh.t(isVisible(calendar), "calendar is visible");
+
+								// calendar moved to dec 2010
+								doh.is("December", innerText(dojo.query(".dijitCalendarCurrentMonthLabel", calendar.domNode)[0]), "moved from june to july");
+								var selectedYearButtons = dojo.query(".dijitCalendarSelectedYear", calendar.domNode);
+								doh.is(1, selectedYearButtons.length, "current year is shown");
+								doh.is("2010", innerText(selectedYearButtons[0]), "current year");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "cancel",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+							}), 5);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("openOnClick=false", [
+					{
+						name: "click on input",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(localLong.focusNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestErrback(function(){
+								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");
+							}), 1000);
+
+							doh.robot.mouseMoveAt(localLong._buttonNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var calendar = dijit.byId("localLong_popup");
+
+								// calendar isn't displayed
+								doh.t(calendar && isVisible(calendar), "calendar is visible");
+							}), 1000);
 
 							return d;
 						}
diff --git a/dijit/tests/form/robot/Form.html b/dijit/tests/form/robot/Form.html
deleted file mode 100644
index 1186e65..0000000
--- a/dijit/tests/form/robot/Form.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>doh.robot Button 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('../FormInvalid.html');
-
-				doh.register("dijit.form.Form", [
-					{
-						name: "initial",
-						timeout: 15000,
-						runTest: function(){
-							// Submit button is initially disabled
-							doh.t(dijit.byId("submitBtn").get("disabled"));
-						}
-					},
-					{
-						name: "filling in first field doesn't change disabled state",
-						timeout: 15000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.sequence(function(){
-								dijit.byId("field1").focus();
-							});
-							doh.robot.typeKeys("hello", 500, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(dijit.byId("submitBtn").get("disabled"));
-							}), 500);
-							return d;
-						}
-					},
-					{
-						name: "filling in second field enables form",
-						timeout: 15000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.sequence(function(){
-								dijit.byId("field2").focus();
-							}, 500);
-							doh.robot.typeKeys("world", 500, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(dijit.byId("submitBtn").get("disabled"));
-							}), 500);
-							return d;
-						}
-					}
-				]);
-
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/form/robot/Form_onsubmit.html b/dijit/tests/form/robot/Form_onsubmit.html
new file mode 100644
index 0000000..47a83a4
--- /dev/null
+++ b/dijit/tests/form/robot/Form_onsubmit.html
@@ -0,0 +1,186 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Form_onsubmit 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_Form_onsubmit.html');
+
+				doh.register("onsubmit", [
+					{
+						name: "submit1",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("submit1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("", dijit.byId("textbox").get('value'));
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "submit2",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//reset the submit textbox
+							dijit.byId("textbox").set('value',"");
+														
+							doh.robot.mouseMoveAt("submit2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("", dijit.byId("textbox").get('value'));
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "submit3",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							//reset the submit textbox
+							dijit.byId("textbox").set('value',"");
+
+							doh.robot.mouseMoveAt("submit3", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("one", dijit.byId("textbox").get('value'));
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "submit4",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//reset the submit textbox
+							dijit.byId("textbox").set('value',"");
+							
+							doh.robot.mouseMoveAt("submit4", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("one", dijit.byId("textbox").get('value'));
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "testReset1",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("combo1", 500, 0);
+							doh.robot.mouseClick({left:true}, 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, {});
+							doh.robot.mouseMoveAt("reset1", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("two", dijit.byId("combo1").value);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "testReset2",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("combo2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							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.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.mouseMoveAt("reset2", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("three", dijit.byId("combo2").value);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "testReset3",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("combo3", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.mouseMoveAt("reset3", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("one", dijit.byId("combo3").value);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "testReset4",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("combo4", 500, 0);
+							doh.robot.mouseClick({left:true}, 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.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.mouseMoveAt("reset4", 500, 0);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("one", dijit.byId("combo4").value);
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/Form_state.html b/dijit/tests/form/robot/Form_state.html
new file mode 100644
index 0000000..0ab8501
--- /dev/null
+++ b/dijit/tests/form/robot/Form_state.html
@@ -0,0 +1,186 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Form Valid/Invalid State 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");
+
+			// 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');
+
+				doh.register("FormValidationState", [
+					{
+						name: "formLoadInvalid",
+						runTest: function(){
+							doh.t(dijit.byId("submitButton").get("disabled"));
+						}
+					},
+					{
+						name: "initialFormInvalid",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ dojo.byId("notes").focus(); });
+							doh.robot.typeKeys("my notes", 1, 1200);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "initialFormInvalid2",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ dojo.byId("name").focus(); });
+							doh.robot.typeKeys("my name", 1, 1000);
+
+							doh.robot.sequence(function(){
+								dojo.byId("birth").focus();
+								dijit.byId('birth').set('value', null);
+							}, 500); 
+							doh.robot.typeKeys("1/1/2010", 1, 1200);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "initialFormValid",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.byId("reset").focus();
+							dojo.byId("reset").click();
+
+							setTimeout(d.getTestCallback(function(){
+								doh.f(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "initialFormValid2",
+						timeout: 8000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){
+								dojo.byId("birth").focus();
+								dijit.byId('birth').set('value', null); 
+							});
+							doh.robot.typeKeys("1/1/2010", 1, 1200);
+
+							doh.robot.sequence(function(){
+								dojo.byId("disable").focus();
+								dojo.byId("disable").click();
+							}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "initialFormInvalid3",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.byId("enable").focus();
+							dojo.byId("enable").click();
+
+							setTimeout(d.getTestCallback(function(){
+								doh.t(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "moreFieldsInvalid",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.byId("reset").focus();
+							dojo.byId("reset").click();
+
+							dojo.byId("addMoreFields").focus();
+							dijit.byId("addMoreFields").onClick();
+
+							setTimeout(d.getTestCallback(function(){
+								doh.t(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "moreFieldsValid",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ dojo.byId("lastName").focus(); });
+							doh.robot.typeKeys("my last name", 1, 1800);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "moreFieldsInvalid2",
+						timeout: 8000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){
+								dojo.byId("color").focus();
+								dijit.byId('color').set('value', null); 
+							});
+							doh.robot.keyPress(dojo.keys.TAB, 1, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(dijit.byId("submitButton").get("disabled"));
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/MultiSelect.html b/dijit/tests/form/robot/MultiSelect.html
new file mode 100644
index 0000000..d2b60c9
--- /dev/null
+++ b/dijit/tests/form/robot/MultiSelect.html
@@ -0,0 +1,263 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot MultiSelect 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");
+
+			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) {
+						//it must be in the newSelectedList
+						var found=false;
+						dojo.forEach(newSelected, function(ns){
+							if(option.value===ns) {
+								found=true;
+							}
+						});
+						doh.t(found);
+					} else {
+						//it better be in the origional selected list
+						var found=false;
+						dojo.forEach(selected, function(s){
+							if(option.value===s) {
+								found=true;
+							}
+						});
+						doh.t(found);
+					}
+				});
+			}
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_MultiSelect.html');
+
+				doh.register("dijit.form.MultiSelect", [
+					{
+						name: "tabInSelect",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var changed = false;
+							dijit.byId("select").set("onChange", function(e){changed = true; });
+
+							dojo.global.scrollTo(0,0);
+							doh.robot.mouseMove(30,30);
+							doh.robot.mouseClick({left:true}, 1000); //tabbing in doesn't work in FF unless we first click on the page first
+
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {}); //Arrowing down will select the element for IE, FF, Safari, & chrome
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {}); //Space is needed to select the element in opera
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(changed);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "switchRight",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ 
+								dijit.byId('select').set('value', ['16']);
+							}, 500);
+
+							doh.robot.mouseMoveAt("right", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var selectedValue2 = "";
+							doh.robot.sequence(function(){ selectedValue2 = dijit.byId('select2').get('value');}, 1000); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("16", selectedValue2[0]);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "switchLeft",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.sequence(function(){ 
+								dijit.byId('select2').set('value', ['3','7','19','47']);
+							}, 500);
+
+							doh.robot.mouseMoveAt("left", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+
+							var selectedValue = "";
+							doh.robot.sequence(function(){ selectedValue = dijit.byId('select').get('value');}, 1000); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("3", selectedValue[0]);
+								doh.is("7", selectedValue[1]);
+								doh.is("19", selectedValue[2]);
+								doh.is("47", selectedValue[3]);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "invertSelected",
+						timeout: 8000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//select a block in the first list
+							doh.robot.sequence(function(){ 
+								dijit.byId('select').set('value', ['18','14','12','10']);
+							}, 500);
+
+							//get the selected list
+							var allOptions = "";
+							var selected = "";
+							var newSelected = "";
+							doh.robot.sequence(function(){ 
+								selected = dijit.byId('select').get('value'); 
+								allOptions = dijit.byId('select').domNode.options;
+							}, 1000); 
+
+							doh.robot.mouseMoveAt("i1", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(function(){ 
+								newSelected = dijit.byId('select').get('value'); 
+							}, 1000); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								testInverted(allOptions, selected, newSelected);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "invertSelected2",
+						timeout: 8000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//select random options
+							doh.robot.sequence(function(){ 
+								dijit.byId('select').set('value', ['2','8','14','20','22','32']);
+							}, 500);
+
+							//get the selected list
+							var allOptions = "";
+							var selected = "";
+							var newSelected = "";
+							doh.robot.sequence(function(){ 
+								selected = dijit.byId('select').get('value'); 
+								allOptions = dijit.byId('select').domNode.options;
+							}, 1000); 
+
+							doh.robot.mouseMoveAt("i1", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(function(){ 
+								newSelected = dijit.byId('select').get('value'); 
+							}, 1000); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								testInverted(allOptions, selected, newSelected);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "invertSelected3",
+						timeout: 8000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//Select the first thing in the list and then invert it
+							//select random options
+							doh.robot.sequence(function(){ 
+								dijit.byId('select3').set('value', ['TN']);
+							}, 500);
+
+							//get the selected list
+							var allOptions = "";
+							var selected = "";
+							var newSelected = "";
+							doh.robot.sequence(function(){ 
+								selected = dijit.byId('select3').get('value'); 
+								allOptions = dijit.byId('select3').domNode.options;
+							}, 1000); 
+
+							doh.robot.mouseMoveAt("i3", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(function(){ 
+								newSelected = dijit.byId('select3').get('value'); 
+							}, 1000); 
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								testInverted(allOptions, selected, newSelected);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "setValue",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//Select only one thing in the list to make sure we don't start with the values that we are going to select
+							doh.robot.sequence(function(){ 
+								dijit.byId('select3').set('value', ['CA']);
+							}, 500);
+
+							doh.robot.mouseMoveAt("s1", 1000);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var selected = dijit.byId('select3').get('value');
+								doh.is(2, selected.length);
+								doh.is(selected[0], 'VA');
+								doh.is(selected[1], 'WA');
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "formSubmit",
+						timeout: 1500,
+						runTest: function(){
+							var d=new doh.Deferred();
+							dijit.byId('select3').set('value', ['TN','FL']);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+									var vals = dojo.fromJson(dojo.formToJson("test"));
+									doh.is("TN,FL", vals.select3);
+							}), 500);
+							return d;
+						}
+					}
+
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/Select.html b/dijit/tests/form/robot/Select.html
index 0fd6bdb..5e871af 100644
--- a/dijit/tests/form/robot/Select.html
+++ b/dijit/tests/form/robot/Select.html
@@ -23,7 +23,7 @@
 
 				// refs to parts of s1 Select
 				var s1, s1menu, Tenessee, Virginia, Washington,	// s1 select
-					s8a, s8a_menu, s8b, s8b_menu;				// long list selects
+					s8a, s8a_menu, s8b, s8b_menu, s3, s3_menu;				// long list selects
 
 				// log of calls to onChange handler
 				var changes = [];
@@ -39,18 +39,28 @@
 						s8a_menu = dijit.byId('s8a_menu');
 						s8b = dijit.byId('s8b');
 						s8b_menu = dijit.byId('s8b_menu');
+						s3 = dijit.byId('s3');
+						s3_menu = dijit.byId('s3_menu');
+
+						// preload menus since first load can take a while
+						var doNothing = function(){};
+						s1.loadDropDown(doNothing);
+						dijit.byId('s5').loadDropDown(doNothing);
+						dijit.byId('s6').loadDropDown(doNothing);
+						s8a.loadDropDown(doNothing);
+						s8b.loadDropDown(doNothing);
 				    }
 				);
 
 				doh.register("mouse", [
 					{
 						name: "two clicks to select",
-						timeout: 60000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							// click to open drop down
-							doh.robot.mouseMoveAt(s1.domNode, 500);
+							doh.robot.mouseMoveAt(s1.domNode, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "drop down menu displayed after click");
@@ -62,23 +72,23 @@
 
 								Washington = dojo.query("tr", s1_menu.domNode)[2];
 								doh.t(Washington, "Washington is another menu choice");
-							}), 500);
+							}), 1000);
 
 							// select an option in the drop down
 							doh.robot.mouseMoveAt(function(){
 								// function wrapper because Washington isn't defined until about sequence() runs
 								return Washington;
-							}, 500);
+							}, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden(s1_menu), "clicking choice hides menu");
 								
 								doh.is("Washington", innerText(s1.containerNode), "select shows selected option");
 								doh.is("WA", s1.get("value"), "get(value) after selecting Washington");
-							}), 500);
+							}), 1000);
 
 							// click to open drop down again
-							doh.robot.mouseMoveAt(s1.domNode, 500);
+							doh.robot.mouseMoveAt(s1.domNode, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "drop down menu displayed after third click");
@@ -86,14 +96,14 @@
 								var selectedOptions = dojo.query(".dijitSelectSelectedOption .dijitMenuItemLabel", s1_menu.domNode);
 								doh.is(1, selectedOptions.length, "one selected option");
 								doh.is("Washington", innerText(selectedOptions[0]), "Washington highlighted");
-							}), 500);
+							}), 1000);
 
 							// clicking away should close the drop down
 							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");
-							}), 500);
+							}), 1000);
 
 							return d;
 						}
@@ -101,7 +111,7 @@
 
 					{
 						name: "mouse down, slide, mouse up",
-						timeout: 60000,
+						timeout: 15000,
 						setUp: function(){
 							s1.set("value", "VA");
 						},
@@ -109,7 +119,7 @@
 							var d = new doh.Deferred();
 
 							// mouse-down to open drop down
-							doh.robot.mouseMoveAt(s1.domNode, 500);
+							doh.robot.mouseMoveAt(s1.domNode, 0, 1);
 							doh.robot.mousePress({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "drop down menu displayed after mouse down");
@@ -121,23 +131,23 @@
 
 								Washington = dojo.query("tr", s1_menu.domNode)[2];
 								doh.t(Washington, "Washington is another menu choice");
-							}), 500);
+							}), 1000);
 
 							// select an option in the drop down
 							doh.robot.mouseMoveAt(function(){
-								// function wrapper because Washington isn't defined until about sequence() runs
+								// function wrapper because Washington isn't defined until above sequence() runs
 								return Washington;
-							}, 500);
+							}, 0, 1);
 							doh.robot.mouseRelease({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden(s1_menu), "clicking choice hides menu");
 								
 								doh.is("Washington", innerText(s1.containerNode), "select shows selected option");
 								doh.is("WA", s1.get("value"), "get(value) after selecting Washington");
-							}), 500);
+							}), 1000);
 
 							// mouse down to open drop down again
-							doh.robot.mouseMoveAt(s1.domNode, 500);
+							doh.robot.mouseMoveAt(s1.domNode, 0, 1);
 							doh.robot.mousePress({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s1_menu), "drop down menu displayed after second mouse down");
@@ -145,7 +155,7 @@
 								var selectedOptions = dojo.query(".dijitSelectSelectedOption .dijitMenuItemLabel", s1_menu.domNode);
 								doh.is(1, selectedOptions.length, "one selected option");
 								doh.is("Washington", innerText(selectedOptions[0]), "Washington highlighted");
-							}), 500);
+							}), 1000);
 
 							// mouse up away from node should leave drop down open
 							doh.robot.mouseMove(10, 10, 500)
@@ -158,19 +168,19 @@
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden(s1_menu), "clicking on blank screen hides menu");
-							}), 500);
+							}), 1000);
 
 							return d;
 						}
 					},
 					{
 						name: "maxHeight",
-						timeout: 60000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							// open drop down
-							doh.robot.mouseMoveAt(s8a.domNode, 500);
+							doh.robot.mouseMoveAt(s8a.domNode, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s8a_menu.domNode), "drop down menu displayed after mouse down");
@@ -178,14 +188,14 @@
 								var pos = dojo.position(s8a_menu.domNode);
 								doh.t(pos.h >= 200, "height at least 200: " + pos.h);
 								doh.t(pos.h < 220, "height including borders not much more than 200: " + pos.h);
-							}), 500);
+							}), 1000);
 
 							// close drop down
-							doh.robot.mouseMove(10, 10, 500)
+							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");
-							}), 500);
+							}), 1000);
 
 							return d;
 						}
@@ -195,12 +205,13 @@
 					// the select itself.  In this case, mouse up should leave the menu open						
 					{
 						name: "menu overlaps select",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
-							var d = new doh.Deferred();
+							var d = new doh.Deferred(),
+								overlapping = false;
 
 							// open drop down
-							doh.robot.mouseMoveAt(s8b.domNode, 500);
+							doh.robot.mouseMoveAt(s8b.domNode, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible(s8b_menu.domNode), "drop down menu displayed after mouse click");
@@ -208,15 +219,19 @@
 								var select = dojo.position(s8b.domNode),
 									menu = dojo.position(s8b_menu.domNode);
 								doh.t(menu.h >= 220, "menu has big height: " + menu.h);
-								doh.t(menu.y < select.y && menu.y+menu.h > select.y+select.h,
-									"menu overlaps select, select = " + dojo.toJson(select) + ", menu = " + dojo.toJson(menu));
-							}), 500);
+
+								// Sometimes the menu overlaps and (at least on chrome/win) sometimes it doesn't.
+								// Not sure why the behavior changes but not treating it as a bug.
+								overlapping = menu.y < select.y && menu.y+menu.h > select.y+select.h;
+							}), 1000);
 
 							// clicking again should select the option from the menu
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden(s8b_menu), "clicking again selects something from menu");
-							}), 500);
+								if(overlapping){
+									doh.t(isHidden(s8b_menu), "clicking again selects something from menu");
+								}
+							}), 1000);
 
 							return d;
 						}
@@ -227,7 +242,7 @@
 				doh.register("keyboard", [
 					{
 						name: "tabIndex",
-						timeout: 60000,
+						timeout: 10000,
 						setUp: function(){
 							dojo.byId("htmlSelect2").focus();
 							dijit.byId("s2").set("disabled", true);
@@ -239,19 +254,19 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("s1", dojo.global.dijit._curFocus.id)
-							}), 500);
+							}), 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)
-							}), 500);
+							}), 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)
-							}), 500);
+							}), 1000);
 
 							return d;
 						},
@@ -261,7 +276,7 @@
 					},
 					{
 						name: "selecting",
-						timeout: 60000,
+						timeout: 15000,
 						setUp: function(){
 							dojo.byId("htmlSelect2").focus();
 						},
@@ -272,7 +287,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("s1", dojo.global.dijit._curFocus.id)
-							}), 500);
+							}), 1000);
 
 							// down arrow to open drop down and focus first item
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
@@ -280,7 +295,7 @@
 								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")
-							}), 500);
+							}), 1000);
 
 							// down arrow to next menu choice
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
@@ -288,14 +303,14 @@
 								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")
-							}), 500);
+							}), 1000);
 
 							// ENTER to select option
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden(s1_menu), "drop down menu closes after ENTER key");
 								doh.is("VA", s1.get("value"));
-							}), 500);
+							}), 1000);
 
 							return d;
 						},
@@ -305,7 +320,7 @@
 					},
 					{
 						name: "ESC to close menu",
-						timeout: 60000,
+						timeout: 10000,
 						setUp: function(){
 							dojo.byId("htmlSelect2").focus();
 						},
@@ -316,7 +331,7 @@
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("s1", dojo.global.dijit._curFocus.id)
-							}), 500);
+							}), 1000);
 
 							// down arrow to open drop down and focus first item
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
@@ -324,14 +339,14 @@
 								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")
-							}), 500);
+							}), 1000);
 
 							// ESC to close menu
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden(s1_menu), "drop down menu closes after ENTER key");
 								doh.is("VA", s1.get("value"), "value hasn't changed");
-							}), 500);
+							}), 1000);
 
 							return d;
 						},
@@ -344,13 +359,13 @@
 				doh.register("display", [
 					{
 						name: "empty drop down",
-						timeout: 60000,
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
 							// Open widget w/no choices
 							var s6 = dijit.byId("s6");
-							doh.robot.mouseMoveAt(s6.domNode, 500);
+							doh.robot.mouseMoveAt(s6.domNode, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								var menu = dijit.byId("s6_menu"),
@@ -368,7 +383,7 @@
 					// even when a narrow entry is selected.
 					{
 						name: "width",
-						timeout: 60000,
+						timeout: 10000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -381,17 +396,17 @@
 
 							// Open drop down menu and make sure it's wider than the select
 							// (to display "no move" and "no copy" choices)
-							doh.robot.mouseMoveAt(s5.domNode, 500);
+							doh.robot.mouseMoveAt(s5.domNode, 0, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								menuSize = dojo.position(s5_menu.domNode);
 								doh.t(menuSize.w > s5origSize.w, "menu (" + menuSize.w + ") wider than select (" + s5origSize.w + ")");
-							}), 500);
+							}), 1000);
 
 							// Select last entry in the drop down.   Should make the select wider.
 							doh.robot.mouseMoveAt(function(){
 								return dojo.query("tr", s5_menu.domNode)[4];
-							}, 500);
+							}, 500, 1);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								var s5newSize = dojo.position(s5.domNode);
@@ -403,6 +418,86 @@
 					}
 				]);
 
+				doh.register("required", [
+					function initial_value(){
+						doh.t(!s3.get('value'), "initial blank value");
+						doh.t(!s3.options[0].value, "blank option");
+						doh.t(s3.get('required'), "required");
+						doh.f(s3.isValid(), "should not be valid");
+					},
+					{
+						name: "select blank option",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Open drop down menu
+							doh.robot.mouseMoveAt(s3.domNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							// Select blank option
+							doh.robot.mouseMoveAt(function(){
+								return dojo.query("tr", s3_menu.domNode)[0];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isHidden(s3_menu), "drop down menu closes after selection");
+								doh.t(!s3.get('value'), "blank value");
+								doh.t(!s3.options[0].value, "blank option");
+								doh.f(s3.isValid(), "should not be valid");
+							}), 1000);
+				
+							return d;
+						}
+					},
+					{
+						name: "select option w/ blank present",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Open drop down menu
+							doh.robot.mouseMoveAt(s3.domNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							// Select 4th option
+							doh.robot.mouseMoveAt(function(){
+								return dojo.query("tr", s3_menu.domNode)[4];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isHidden(s3_menu), "drop down menu closes after selection");
+								doh.is("AZ", s3.get('value'), "Arizona");
+								doh.f(!s3.options[0].value, "no blank option");
+								doh.t(s3.isValid(), "should be valid");
+							}), 1000);
+				
+							return d;
+						}
+					},
+					{
+						name: "select option w/o blank present",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Open drop down menu
+							doh.robot.mouseMoveAt(s3.domNode, 0, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							// Select 4th option
+							doh.robot.mouseMoveAt(function(){
+								return dojo.query("tr", s3_menu.domNode)[4];
+							}, 1000, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isHidden(s3_menu), "drop down menu closes after selection");
+								doh.is("AR", s3.get('value'), "Arkansas");
+								doh.t(s3.isValid(), "should be valid");
+							}), 1000);
+				
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/SimpleTextarea.html b/dijit/tests/form/robot/SimpleTextarea.html
new file mode 100644
index 0000000..9874104
--- /dev/null
+++ b/dijit/tests/form/robot/SimpleTextarea.html
@@ -0,0 +1,137 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot SimpleTextArea 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_SimpleTextarea.html');
+
+				doh.register("dijit.form.SimpleTextarea", [
+					{
+						name: "tab",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							dojo.global.scrollTo(0,0);
+							doh.robot.mouseMove(10,10);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.sequence(function(){ dijit.byId('ta1').set('value', null) }, 1000); 
+							doh.robot.typeKeys("hi", 500, 500);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("hi", dojo.byId('oc1').value);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "onchange",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var changed = false;
+							dijit.byId("ta1").set("onChange", function(e){console.log(e); changed = true; });
+
+							doh.robot.mouseMoveAt("ta1", 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.typeKeys("hello", 500, 1000);
+							
+							//blur to trigger onChange
+							doh.robot.mouseMoveAt("ta2", 500); 
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(changed, "onchange event was not fired");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "maxlength",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var changed = false;
+							dijit.byId("ta1").set("maxLength", "5");
+
+							doh.robot.mouseMoveAt("ta1", 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.typeKeys("mississippi", 500, 2000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("missi", dojo.byId('ta1').value);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "testReset",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("resetButton", 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("shichashaw, textarea text baw.", dojo.trim(dojo.byId('ta1').value));
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "testGetValue",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("getValueButton", 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(dojo.byId('gv1').value, dojo.byId('ta1').value);
+							}), 1000);
+							return d;
+						}
+					}
+					,
+					{
+						name: "testNull",
+						timeout: 15000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("setNullButton", 500);
+							doh.robot.mouseClick({left:true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("", dojo.byId('ta1').value);
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/Slider_mouse.html b/dijit/tests/form/robot/Slider_mouse.html
index 4f7e3fd..d7bec43 100644
--- a/dijit/tests/form/robot/Slider_mouse.html
+++ b/dijit/tests/form/robot/Slider_mouse.html
@@ -118,9 +118,9 @@
 					var slider = dijit.byId(arrowSliders[0]);
 					slider.set('value', 50);
 					var d = new doh.Deferred();
-					doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+					doh.robot.sequence(d.getTestCallback(function(){
 						doh.is(50, parseFloat(dojo.byId(onChange[slider.id]).value));
-					})), 500);
+					}), 500);
 					return d;
 				},
 				function setToNull(){
@@ -128,9 +128,9 @@
 					var slider = dijit.byId(arrowSliders[0]);
 					slider.set('value', null);
 					var d = new doh.Deferred();
-					doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+					doh.robot.sequence(d.getTestCallback(function(){
 						doh.is(0, parseFloat(dojo.byId(onChange[slider.id]).value));
-					})), 500);
+					}), 500);
 					return d;
 				}
 			]);
@@ -248,85 +248,66 @@
 			doh.register("general tests", [
 				{
 					name: "slider1",
-					setUp: function(){
-						dijit.byId("slider1").set('value',10);
-					},
-					timeout: 4000, // this is the animated slider so there is a 500ms delay
+					timeout: 5000, // this is the animated slider so there is a 500ms delay
 					runTest: function(){
 						var d = new doh.Deferred();
 						var slider = dijit.byId("slider1");
+						slider.set('value', 10);
 						dojo.window.scrollIntoView(slider.domNode);
-						doh.robot.mouseMoveAt(slider.focusNode, 500);
+						doh.robot.mouseMoveAt(slider.focusNode, 1, 0);
 						doh.robot.mousePress({left: true}, 500);
 						// drag to 20% marker
-						doh.robot.mouseMoveAt(dojo.query("div[style*='20%']", dojo.byId('dijit_form_HorizontalRule_0'))[0], 500);
+						var marker = dojo.query("div[style*='20%']", dojo.byId('dijit_form_HorizontalRule_0'))[0];
+						doh.robot.mouseMoveAt(marker, 500, 0);
 						doh.robot.mouseRelease({left: true}, 500);
-						doh.robot.sequence(function(){
+						doh.robot.sequence(d.getTestCallback(function(){
 							var value = slider.get('value');
-							if(value >= 19 && value <= 21){
-								d.callback(true);
-							}else{
-								d.errback("slider1 failed. Expected ~20, got " + value);
-							}
-						}, 1400);
+							doh.t(value >= 19 && value <= 21, "Expected 20-ish, got "+value);
+						}), 1000);
 						return d;
-					},
-					tearDown: function(){
-						dijit.byId("slider1").set('value',20);
 					}
 				},
 
 				{
 					name: "slider2",
-					timeout: 3500,
-					setUp: function(){
-						dijit.byId("slider2").set('value',10);
-					},
+					timeout: 5000,
 					runTest: function(){
 						var d = new doh.Deferred();
 						var slider = dijit.byId("slider2");
+						slider.set('value', 10);
 						dojo.window.scrollIntoView(slider.domNode);
-						doh.robot.mouseMoveAt(slider.focusNode, 500);
+						doh.robot.mouseMoveAt(slider.focusNode, 1, 0);
 						doh.robot.mousePress({left: true}, 500);
 						// drag to 20% marker (Slider is in descending order so it's 100-20=80%)
 						var marker = dojo.query("div[style*='80%']", dojo.byId('dijit_form_VerticalRule_1'))[0];
-						doh.robot.mouseMoveAt(marker, 500, 100, 0, 0);
+						doh.robot.mouseMoveAt(marker, 500, 0);
 						doh.robot.mouseRelease({left: true}, 500);
-						doh.robot.sequence(function(){
+						doh.robot.sequence(d.getTestCallback(function(){
 							var value = slider.get('value');
-							if(value == 20){
-								d.callback(true);
-							}else{
-								d.errback("slider2 failed. Expected 20, got "+value);
-							}
-						}, 900);
+							doh.is(20, value);
+						}), 1000);
 						return d;
 					}
 				},
 
 				{
 					name: "slider3",
-					timeout: 3500,
-					setUp: function(){
-						dijit.byId("programaticSlider").set('value',1000);
-					},
+					timeout: 5000,
 					runTest: function(){
 						var d = new doh.Deferred();
 						var slider = dijit.byId("programaticSlider");
+						slider.set('value', 1000);
 						dojo.window.scrollIntoView(slider.domNode);
-						doh.robot.mouseMoveAt(slider.focusNode, 500);
+						doh.robot.mouseMoveAt(slider.focusNode, 1, 0);
 						doh.robot.mousePress({left: true}, 500);
 						// drag to the top
-						doh.robot.mouseMoveAt(dojo.query("div[style*='0%']", dojo.byId('dijit_form_VerticalRule_2'))[0], 500, 100, 0, 0);
+						var marker = dojo.query("div[style*='0%']", dojo.byId('dijit_form_VerticalRule_2'))[0];
+						doh.robot.mouseMoveAt(marker, 500, 0);
 						doh.robot.mouseRelease({left: true}, 500);
-						doh.robot.sequence(function(){
+						doh.robot.sequence(d.getTestCallback(function(){
 							var value = slider.get('value');
-							if(value == 3000){
-								d.callback(true);
-							}else{
-								d.errback("slider3 failed. Expected 3000, got "+value);
-							}
-						}, 900);
+							doh.is(3000, value);
+						}), 1000);
 						return d;
 					}
 				}
diff --git a/dijit/tests/form/robot/Spinner_a11y.html b/dijit/tests/form/robot/Spinner_a11y.html
index ed5fb1e..155a6c7 100644
--- a/dijit/tests/form/robot/Spinner_a11y.html
+++ b/dijit/tests/form/robot/Spinner_a11y.html
@@ -102,10 +102,8 @@
 					// END
 					if(inSpinner.constraints.max){
 						inSpinner.set('value', inSpinner.constraints.max);
-						newVal = inSpinner.get('value');
-					}else{
-						newVal = inSpinner.get('value');
 					}
+					newVal = inSpinner.get('value');
 					eVals.push({stroke: "END", expected: newVal});
 
 					// reset <inSpinner> back to its initial value, and return
@@ -113,29 +111,53 @@
 					return eVals;
 				}
 
+				// 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();
+					}
+				};
+
 				// common robot TAB-focus test function.
 				var a11yTabFocus = function(inSpinnerId){
 					var d = new doh.Deferred();
 					var spinner = dijit.byId(inSpinnerId);
-					// insure a known focus starting point within document before key presses.
-					spinner.focus();
-					// Shift-tab away, tab to, tab away, shift-tab back.
-					doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
-					doh.robot.keyPress(dojo.keys.TAB, 1000);
-					doh.robot.keyPress(dojo.keys.TAB, 1000);
-					doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
-
-					// TODO: this doesn't seem thorough... after TAB or shift TAB
-					// should be checking that we ended up at the right place, i.e.
-					// make sure that we don't have extra tab stops within the Spinner itself.
-
-					var checkGotFocus = function(){
-						spinner.disconnect(focusConnect);
-						spinner.disconnect(blurConnect);
-						doh.assertEqual(3, focusCountZ, "# of times focused (" + spinner.id + ")");
-						doh.assertEqual(2, blurCountZ, "# of times lost focus (" + spinner.id + ")");
-					};
-					doh.robot.sequence(d.getTestCallback(checkGotFocus), 1000, 1000);
+					focusThenRun(spinner, function(){
+						var handler = spinner.connect(spinner, '_onBlur', function(){
+							spinner.disconnect(handler);
+							setTimeout(function(){
+								handler = spinner.connect(spinner, '_onFocus', function(){
+									spinner.disconnect(handler);
+									setTimeout(function(){
+										handler = spinner.connect(spinner, '_onBlur', function(){
+											spinner.disconnect(handler);
+											setTimeout(function(){
+												handler = spinner.connect(spinner, '_onFocus', function(){
+													spinner.disconnect(handler);
+													setTimeout(d.getTestCallback(function(){
+														spinner.disconnect(focusConnect);
+														spinner.disconnect(blurConnect);
+														doh.is(3, focusCountZ, "# of times focused (" + spinner.id + ")");
+														doh.is(2, blurCountZ, "# of times lost focus (" + spinner.id + ")");
+													}), 1);
+												});
+												doh.robot.keyPress(dojo.keys.TAB, 1, {shift:true}); // refocus
+											}, 1);
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 1); // reblur
+									}, 1);
+								});
+								doh.robot.keyPress(dojo.keys.TAB, 1); // refocus
+							}, 1);
+						});
+						doh.robot.keyPress(dojo.keys.TAB, 1, {shift:true}); // blur
+					});
 					return d;
 				}
 
@@ -145,36 +167,36 @@
 					var spinner = dijit.byId(inSpinnerId);
 					var initVal = spinner.get('value');
 
-					spinner.focus();
-
-					doh.robot.keyPress(dojo.keys.HOME, 1000);
-					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.PAGE_UP, 200);
-					doh.robot.keyPress(dojo.keys.PAGE_UP, 200);
-					doh.robot.keyPress(dojo.keys.PAGE_DOWN, 200);
-					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
-					doh.robot.keyPress(dojo.keys.END, 200);
-					var testPresses = function(){
-						spinner.disconnect(noteConnect);
-						spinner.set('value', initVal);
-						for(var i = 0; i < results.length; i++){
-							var aResult = results[i];
-							if(!(isNaN(aResult.expected) && isNaN(aResult.actual))) {
-								doh.is(aResult.expected, aResult.actual, aResult.stroke);
+					focusThenRun(spinner, function(){
+						doh.robot.keyPress(dojo.keys.HOME, 1);
+						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.PAGE_UP, 200);
+						doh.robot.keyPress(dojo.keys.PAGE_UP, 200);
+						doh.robot.keyPress(dojo.keys.PAGE_DOWN, 200);
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200);
+						doh.robot.keyPress(dojo.keys.END, 200);
+						var testPresses = function(){
+							spinner.disconnect(noteConnect);
+							spinner.set('value', initVal);
+							for(var i = 0; i < results.length; i++){
+								var aResult = results[i];
+								if(!(isNaN(aResult.expected) && isNaN(aResult.actual))) {
+									doh.is(aResult.expected, aResult.actual, aResult.stroke);
+								}
 							}
-						}
-					};
-					doh.robot.sequence(d.getTestCallback(testPresses), 1000, 1000);
+						};
+						doh.robot.sequence(d.getTestCallback(testPresses), 1000, 1000);
+					});
 					return d;
 				}
 
 				doh.register("setUp",{
 					name: "setUp",
-					timeout: 15000,
+					timeout: 5000,
 					setUp:function(){
 						spin1 = dijit.byId('integerspinner1');
 						spin2 = dijit.byId('integerspinner2');
@@ -184,7 +206,7 @@
 					},
 					runTest: function(){
 						// assert onChange not fired
-						doh.is("not fired yet!", dojo.byId('oc1').value);
+						doh.is("not fired yet!", dojo.byId('oc1').value, "onChange should not have fired");
 
 						// make sure initial values are what we expect
 						doh.is(1, spin1.smallDelta);
@@ -214,99 +236,90 @@
 				doh.register("a11y", [
 					{
 						name: "spinner2_typematic",
-						timeout: 15000,
-						setUp:function(){
-							spin2.set('value', 900);
-							spin2.focus();
-						},
+						timeout: 9000,
 						runTest: function(){
 							// test typematic
 							var d=new doh.Deferred();
-							doh.robot.keyDown(dojo.keys.DOWN_ARROW, 1000);
-							doh.robot.keyUp(dojo.keys.DOWN_ARROW, 5000);
-							doh.robot.sequence(function(){
-								if(spin2.get('value')<=800){
-									d.callback(true);
-								}else{
-									d.errback(new Error('Error in typematic test. Expected <=800, got '+spin2.get('value')));
-								}
-							}, 1000);
+							spin2.set('value', 900);
+							focusThenRun(spin2, function(){
+								doh.robot.keyDown(dojo.keys.DOWN_ARROW, 1);
+								doh.robot.keyUp(dojo.keys.DOWN_ARROW, 5000);
+								doh.robot.sequence(d.getTestCallback(function(){
+									var v = spin2.get('value');
+									doh.t(v <= 800, 'Error in typematic test. Expected <=800, got '+v);
+								}), 1000);
+							});
 							return d;
 						}
 					},
 
 					{
 						name: "spinner2_max",
-						timeout: 15000,
-						setUp:function(){
-							spin2.set('value', 1549);
-							spin2.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							// test max with arrow key
 							var d=new doh.Deferred();
-							// press once: should move up
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(1550, spin2.get('value'));
-								doh.is("1550", spin2.focusNode.value);
-								doh.is(true, spin2.isValid());
-								// press again: shouldn't move
-								doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is(1550, spin2.get('value'));
-									doh.is("1550", spin2.focusNode.value);
-									doh.is(true, spin2.isValid());
+							spin2.set('value', 1549);
+							focusThenRun(spin2, function(){
+								// press once: should move up
+								doh.robot.keyPress(dojo.keys.UP_ARROW, 1);
+								doh.robot.sequence(d.getTestErrback(function(){
+									doh.is(1550, spin2.get('value'), "value 1: " + spin2.get('value'));
+									doh.is("1550", spin2.focusNode.value, "displayed value 1: " + spin2.focusNode.value);
+									doh.t(spin2.isValid(), "invalid 1");
+									// press again: shouldn't move
+									doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
+									doh.robot.sequence(d.getTestCallback(function(){
+										doh.is(1550, spin2.get('value'), "value 2: " + spin2.get('value'));
+										doh.is("1550", spin2.focusNode.value, "displayed value 2: " + spin2.focusNode.value);
+										doh.t(spin2.isValid(), "invalid 2");
+									}), 500);
 								}), 500);
-							}), 500);
-
+							});
 							return d;
 						}
 					},
 
 					{
 						name: "spinner2_min",
-						timeout: 15000,
-						setUp:function(){
-							spin2.set('value', 10);
-							spin2.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							// test min with arrow key
 							var d=new doh.Deferred();
-							// press once: should move up
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(9, spin2.get('value'));
-								doh.is("9", spin2.focusNode.value);
-								doh.is(true, spin2.isValid());
-								// press again: shouldn't move
-								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is(9, spin2.get('value'));
-									doh.is("9", spin2.focusNode.value);
-									doh.is(true, spin2.isValid());
+							spin2.set('value', 10);
+							focusThenRun(spin2, function(){
+								// press once: should move up
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1);
+								doh.robot.sequence(d.getTestErrback(function(){
+									doh.is(9, spin2.get('value'), "value 1: " + spin2.get('value'));
+									doh.is("9", spin2.focusNode.value, "displayed value 1: " + spin2.focusNode.value);
+									doh.t(spin2.isValid(), "invalid 1");
+									// press again: shouldn't move
+									doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+									doh.robot.sequence(d.getTestCallback(function(){
+										doh.is(9, spin2.get('value'), "value 2: " + spin2.get('value'));
+										doh.is("9", spin2.focusNode.value, "displayed value 2: " + spin2.focusNode.value);
+										doh.t(spin2.isValid(), "invalid 2");
+									}), 500);
 								}), 500);
-							}), 500);
-
+							});
 							return d;
 						}
 					},
 
 					{
 						name: "spinner2_invalid",
-						timeout: 15000,
-						setUp:function(){
-							spin2.focusNode.value="";
-							spin2.focus();
-						},
+						timeout: 3000,
 						runTest: function(){
 							// assert invalid works
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("0.5", 1000, 600);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(false, spin2.isValid());
-							}), 500);
+							spin2.focusNode.value="";
+							focusThenRun(spin2, function(){
+								doh.robot.typeKeys("0.5", 1, 600);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.f(spin2.isValid(), "valid");
+								}), 500);
+							});
 							return d;
 						}
 					}
@@ -420,7 +433,7 @@
 					// don't test integerspinner1 since shift-tab from there goes to address bar and the robot doesn't like that at all
 					{
 						name:"integertextbox3TabFocus",
-						timeout:9000,
+						timeout:3000,
 						setUp:function(){
 							tabFocusSetup("integertextbox3");
 						},
@@ -430,7 +443,7 @@
 					},
 					{ // test integerspinner2 second since the previous test group already had it focused
 						name:"integerspinner2TabFocus",
-						timeout:9000,
+						timeout:3000,
 						setUp:function(){
 							tabFocusSetup("integerspinner2");
 						},
@@ -440,7 +453,7 @@
 					},
 					{
 						name:"realspinner1TabFocus",
-						timeout:9000,
+						timeout:3000,
 						setUp:function(){
 							tabFocusSetup("realspinner1");
 						},
@@ -500,64 +513,73 @@
 				[
 					{
 						name: "spinnerMinOnly large exp",
-						timeout: 15000,
-						setUp:function(){
-							spin4.focusNode.value="";
-							spin4.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("0.5e99", 1000, 1200);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(spin4.isValid(false), "large exponential is invalid");
-								doh.f(spin4.isInRange(false), "large exponential is out of range");
-								doh.is(spin4.getErrorMessage(true), spin4.rangeMessage, "large exponential showing out of range message");
-								doh.is("5e+98", spin4.get('displayedValue'), "large exponential reformatted to standard form");
-							}), 1000);
+							spin4.focusNode.value="";
+							focusThenRun(spin4, function(){
+								var handler = spin4.connect(spin4, '_onBlur',
+									function(){
+										spin4.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.f(spin4.isValid(false), "large exponential is invalid");
+											doh.f(spin4.isInRange(false), "large exponential is out of range");
+											doh.is(spin4.getErrorMessage(true), spin4.rangeMessage, "large exponential showing out of range message");
+											doh.is("5e+98", spin4.get('displayedValue'), "large exponential reformatted to standard form");
+										}), 150);
+									});
+								doh.robot.typeKeys("0.5e99", 1, 1200);
+								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							});
 							return d;
 						}
 					},
 					{
 						name: "spinnerMinOnly adjust small exp",
-						timeout: 15000,
-						setUp:function(){
-							spin4.focusNode.value="";
-							spin4.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("0.5e9", 1000, 1000);
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(spin4.isValid(false), "small exponential is valid");
-								doh.t(spin4.isInRange(false), "small exponential is in range");
-								doh.is(500000000.1, spin4.get('value'), "small exponential converted to whole number");
-								doh.is("500,000,000.1", spin4.get('displayedValue'), "small exponential converted to whole number with formatting");
-							}), 1000);
+							spin4.focusNode.value="";
+							focusThenRun(spin4, function(){
+								var handler = spin4.connect(spin4, '_onBlur',
+									function(){
+										spin4.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.t(spin4.isValid(false), "small exponential is valid");
+											doh.t(spin4.isInRange(false), "small exponential is in range");
+											doh.is(500000000.1, spin4.get('value'), "small exponential converted to whole number");
+											doh.is("500,000,000.1", spin4.get('displayedValue'), "small exponential converted to whole number with formatting");
+										}), 150);
+									});
+								doh.robot.typeKeys("0.5e9", 1, 1000);
+								doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
+								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							});
 							return d;
 						}
 					},
 					{
 						name: "spinnerMinOnly adjust max exp",
-						timeout: 15000,
-						setUp:function(){
-							spin4.focusNode.value="";
-							spin4.focus();
-						},
+						timeout: 9000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("0.5e99", 1000, 1200);
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // convert to max
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(spin4.isValid(false), "large exponential converted to max is valid");
-								doh.t(spin4.isInRange(false), "max value is in range");
-								doh.is(89999999999999.9, spin4.get('value'), "max value (-.1)");
-								doh.is("89,999,999,999,999.9", spin4.get('displayedValue'), "max value (-.1) with formatting");
-							}), 1000);
+							spin4.focusNode.value="";
+							focusThenRun(spin4, function(){
+								var handler = spin4.connect(spin4, '_onBlur',
+									function(){
+										spin4.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.t(spin4.isValid(false), "large exponential converted to max is valid");
+											doh.t(spin4.isInRange(false), "max value is in range");
+											doh.is(89999999999999.9, spin4.get('value'), "max value (-.1)");
+											doh.is("89,999,999,999,999.9", spin4.get('displayedValue'), "max value (-.1) with formatting");
+										}), 150);
+									});
+								doh.robot.typeKeys("0.5e99", 1, 1200);
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // convert to max
+								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							});
 							return d;
 						}
 					}
@@ -568,86 +590,90 @@
 				[
 					{
 						name: "HOME key, out of range",
-						timeout: 15000,
-						setUp:function(){
-							spin4.focusNode.value="";
-							spin4.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("0.5e99", 1000, 1200);
-							doh.robot.keyPress(dojo.keys.HOME, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(spin4.isValid(true), "HOME changed large exponential to valid min, value is instead: "+spin4.focusNode.value);
-								doh.t(spin4.isInRange(true), "HOME changed large exponential to in range");
-								doh.is(-10.9, spin4.get('value'), "HOME changed large exponential to min value");
-								doh.is("-10.9", spin4.get('displayedValue'), "HOME changed large exponential to min display");
-							}), 500);
+							spin4.focusNode.value="";
+							focusThenRun(spin4, function(){
+								doh.robot.typeKeys("0.5e99", 1, 1200);
+								doh.robot.keyPress(dojo.keys.HOME, 500);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.t(spin4.isValid(true), "HOME changed large exponential to valid min, value is instead: "+spin4.focusNode.value);
+									doh.t(spin4.isInRange(true), "HOME changed large exponential to in range");
+									doh.is(-10.9, spin4.get('value'), "HOME changed large exponential to min value");
+									doh.is("-10.9", spin4.get('displayedValue'), "HOME changed large exponential to min display");
+								}), 500);
+							});
 							return d;
 						}
 					},
 					{
 						name: "HOME key, invalid",
-						timeout: 15000,
-						setUp:function(){
-							spin4.focusNode.value="";
-							spin4.focus();
-						},
+						timeout: 9000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys(".5e9a", 1000, 1000);
-							doh.robot.keyPress(dojo.keys.HOME, 500);
-							if(dojo.isMac){
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {meta:true});
-							}
-							doh.robot.typeKeys("1", 500, 200);
-							doh.robot.keyPress(dojo.keys.END, 500);
-							if(dojo.isMac){
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {meta:true});
-							}
-							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(spin4.isValid(true), "edited exponential is now valid");
-								doh.is(1.5e+9, spin4.get('value'), "edited exponential");
-							}), 500);
+							spin4.focusNode.value="";
+							focusThenRun(spin4, function(){
+								doh.robot.typeKeys(".5e9a", 1, 1000);
+								doh.robot.keyPress(dojo.keys.HOME, 500);
+								if(dojo.isMac){
+									doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {meta:true});
+								}
+								doh.robot.typeKeys("1", 500, 200);
+								doh.robot.keyPress(dojo.keys.END, 500);
+								if(dojo.isMac){
+									doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {meta:true});
+								}
+								doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.t(spin4.isValid(true), "edited exponential is now valid");
+									doh.is(1.5e+9, spin4.get('value'), "edited exponential");
+								}), 500);
+							});
 							return d;
 						}
 					},
 					{
 						name: "out-of-range formatting",
-						timeout: 15000,
-						setUp:function(){
-							spin3.focusNode.value="";
-							spin3.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("156.0", 1000, 1000);
-							doh.robot.keyPress(dojo.keys.TAB, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(spin3.isValid(), "out-of-range is invalid");
-								doh.is('156.0', spin3.get('displayedValue'), "fraction not removed from out-of-range");
-								doh.is(156, spin3.get('value'), "out-of-range number returns number");
-							}), 1000);
+							spin3.focusNode.value="";
+							focusThenRun(spin3, function(){
+								var handler = spin3.connect(spin3, '_onBlur',
+									function(){
+										spin3.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.f(spin3.isValid(), "out-of-range is invalid");
+											doh.is('156.0', spin3.get('displayedValue'), "fraction not removed from out-of-range");
+											doh.is(156, spin3.get('value'), "out-of-range number returns number");
+										}), 150);
+									});
+								doh.robot.typeKeys("156.0", 1, 1000);
+								doh.robot.keyPress(dojo.keys.TAB, 500);
+							});
 							return d;
 						}
 					},
 					{
 						name: "improper fraction",
-						timeout: 15000,
-						setUp:function(){
-							spin4.focusNode.value="";
-							spin4.focus();
-						},
+						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
-							doh.robot.typeKeys("99", 1000, 400);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.f(spin4.isValid(), "missing fraction is invalid");
-								doh.is('99', spin4.get('displayedValue'), "fraction not added to unparsable number");
-								doh.t(isNaN(spin4.get('value')), "unparsable number causes no value");
-							}), 1000);
+							spin4.focusNode.value="";
+							focusThenRun(spin4, function(){
+								var handler = spin4.connect(spin4, '_onBlur',
+									function(){
+										spin4.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.f(spin4.isValid(), "missing fraction is invalid");
+											doh.is('99', spin4.get('displayedValue'), "fraction not added to unparsable number");
+											doh.t(isNaN(spin4.get('value')), "unparsable number causes no value");
+										}), 150);
+									});
+								doh.robot.typeKeys("99", 1, 400);
+								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							});
 							return d;
 						}
 					}
@@ -657,19 +683,24 @@
 				[
 					{
 						name: "simple",
-						timeout: 15000,
+						timeout: 5000,
 						runTest: function(){
 							var d=new doh.Deferred();
 							var spinner = dijit.byId("integertextbox3");
 							spinner.set('value', '');
-							spinner.focus();
-							doh.robot.typeKeys("1.2339", 1000, 1200);
-							doh.robot.keyPress(dojo.keys.TAB, 500);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(spinner.isValid(false), "no error when rounding");
-								doh.is(1.234, spinner.get('value'), "value is rounded");
-								doh.is("1.234", spinner.get('displayedValue'), "rounded value correctly displayed");
-							}), 1000);
+							focusThenRun(spinner, function(){
+								var handler = spinner.connect(spinner, '_onBlur',
+									function(){
+										spinner.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.t(spinner.isValid(false), "no error when rounding");
+											doh.is(1.234, spinner.get('value'), "value is rounded");
+											doh.is("1.234", spinner.get('displayedValue'), "rounded value correctly displayed");
+										}), 150);
+									});
+								doh.robot.typeKeys("1.2339", 1, 1200);
+								doh.robot.keyPress(dojo.keys.TAB, 500);
+							});
 							return d;
 						}
 					}
diff --git a/dijit/tests/form/robot/Spinner_mouse.html b/dijit/tests/form/robot/Spinner_mouse.html
index ed40d26..0547f3c 100644
--- a/dijit/tests/form/robot/Spinner_mouse.html
+++ b/dijit/tests/form/robot/Spinner_mouse.html
@@ -84,7 +84,7 @@
 						runTest: function(){
 							// assert invalid works
 							var d=new doh.Deferred();
-							doh.robot.mouseMoveAt(spin1.focusNode, 500);
+							doh.robot.mouseMoveAt(spin1.focusNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(function(){
 								spin1.focusNode.value="";
@@ -114,7 +114,7 @@
 						runTest: function(){
 							// assert invalid works
 							var d=new doh.Deferred();
-							doh.robot.mouseMoveAt(spin3.focusNode, 500);
+							doh.robot.mouseMoveAt(spin3.focusNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							doh.robot.sequence(function(){
 								spin3.focusNode.value="";
@@ -149,19 +149,17 @@
 						runTest: function(){
 							// test typematic
 							var d=new doh.Deferred();
-							doh.robot.mouseMoveAt(spin1.downArrowNode, 500);
-							doh.robot.mousePress({left:true,  middle:false,  right:false}, 500);
+							doh.robot.mouseMoveAt(spin1.focusNode, 1, 0); // scroll both buttons into view
+							doh.robot.mouseMoveAt(spin1.downArrowNode, 1, 0);
+							doh.robot.mousePress({left:true,  middle:false,  right:false}, 1000);
 							doh.robot.mouseRelease({left:true,  middle:false,  right:false}, 5000); // going too fast overwhelms the CPU and starves the robot thread
 							doh.robot.mousePress({left:true,  middle:false,  right:false}, 500);
 							doh.robot.mouseRelease({left:true,  middle:false,  right:false}, 5000);
-							doh.robot.sequence(function(){
+							doh.robot.sequence(d.getTestCallback(function(){
 								var v = spin1.get('value');
-								if(v <= 875){
-									d.callback(true);
-								}else{
-									d.errback(new Error('Error in typematic test. Expected <= 875, got ' + v));
-								}
-							}, 1000);
+								// also test after user clicks away
+								doh.t(v <= 875, "Error in typematic test. Expected <= 875, got " + v);
+							}), 500);
 							return d;
 						}
 					},
@@ -176,9 +174,10 @@
 							// test max with arrow button
 							var d=new doh.Deferred();
 							// press once: should move up
-							doh.robot.mouseMoveAt(spin1.upArrowNode, 500);
+							doh.robot.mouseMoveAt(spin1.focusNode, 1, 0); // scroll both buttons into view
+							doh.robot.mouseMoveAt(spin1.upArrowNode, 1, 0);
 							doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
-							doh.robot.mouseMoveAt('sv1_4', 500);
+							doh.robot.mouseMoveAt('sv1_4', 1, 0);
 							doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is(1550, spin1.get('value'));
@@ -186,9 +185,9 @@
 								doh.is("1550", dojo.byId('oc1').value);
 								doh.is(true, spin1.isValid());
 								// press again: shouldn't move
-								doh.robot.mouseMoveAt(spin1.upArrowNode, 500);
+								doh.robot.mouseMoveAt(spin1.upArrowNode, 1, 0);
 								doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
-								doh.robot.mouseMoveAt('sv1_4', 500);
+								doh.robot.mouseMoveAt('sv1_4', 1, 0);
 								doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is(1550, spin1.get('value'));
@@ -212,9 +211,10 @@
 							// test min with arrow button
 							var d=new doh.Deferred();
 							// press once: should move up
-							doh.robot.mouseMoveAt(spin1.downArrowNode, 500);
+							doh.robot.mouseMoveAt(spin1.focusNode, 1, 0); // scroll both buttons into view
+							doh.robot.mouseMoveAt(spin1.downArrowNode, 1, 0);
 							doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
-							doh.robot.mouseMoveAt('sv1_4', 500);
+							doh.robot.mouseMoveAt('sv1_4', 1, 0);
 							doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is(0, spin1.get('value'));
@@ -222,9 +222,9 @@
 								doh.is("0", dojo.byId('oc1').value);
 								doh.is(true, spin1.isValid());
 								// press again: can move since no min
-								doh.robot.mouseMoveAt(spin1.downArrowNode, 500);
+								doh.robot.mouseMoveAt(spin1.downArrowNode, 1, 0);
 								doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
-								doh.robot.mouseMoveAt('sv1_4', 500);
+								doh.robot.mouseMoveAt('sv1_4', 1, 0);
 								doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 								doh.robot.sequence(d.getTestCallback(function(){
 									doh.is(-1, spin1.get('value'));
@@ -251,19 +251,16 @@
 							// note that Spinner spins backwards!
 							delta=-doh.robot.mouseWheelSize;
 							var d=new doh.Deferred();
-							doh.robot.mouseMoveAt(spin1.domNode, 1000);
+							doh.robot.mouseMoveAt(spin1.domNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							// wheel up 10 times
 							// this should increase the value by 10
 							// takes 100ms/click
 							doh.robot.mouseWheel(-10, 1000, 1000);
-							doh.robot.sequence(function(){
+							doh.robot.sequence(d.getTestCallback(function(){
 								var v=spin1.get('value');
-								if(v==(900+10*delta)){
-									d.callback(true);
-								}else{
-									d.errback(new Error("spinner 1: wrong value, expected "+(900+10*delta)+", got "+spin1.get('value')));							}
-							}, 1000);
+								doh.is(v, (900+10*delta), "spinner 1: wrong value, expected "+(900+10*delta)+", got "+v);
+							}), 1000);
 							return d;
 						}
 					},
@@ -278,19 +275,16 @@
 							// test custom delta with mouse wheel
 							// it should increment 10 per mouse wheel
 							var d=new doh.Deferred();
-							doh.robot.mouseMoveAt(spin2.domNode, 1000);
+							doh.robot.mouseMoveAt(spin2.domNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							// wheel down 9 times
 							// this should decrease the value by 90
 							// takes 100ms/click
 							doh.robot.mouseWheel(9, 1000, 900);
-							doh.robot.sequence(function(){
-								if(spin2.get('value')==(1000-90*delta)){
-									d.callback(true);
-								}else{
-									d.errback(new Error("spinner 2: wrong value, expected "+(1000-90*delta)+", got "+spin2.get('value')));
-								}
-							}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								var v = spin2.get('value');
+								doh.is(v, (1000-90*delta), "spinner 2: wrong value, expected "+(1000-90*delta)+", got "+v);
+							}), 1000);
 							return d;
 						}
 					},
@@ -305,19 +299,16 @@
 							// test real number spinner with mouse wheel
 							// it should increment 0.1 per mouse wheel
 							var d=new doh.Deferred();
-							doh.robot.mouseMoveAt(spin3.domNode, 1000);
+							doh.robot.mouseMoveAt(spin3.domNode, 1, 0);
 							doh.robot.mouseClick({left:true}, 500);
 							// wheel up 10
 							// this should increase the value by 1.0
 							// takes 100ms/click
 							doh.robot.mouseWheel(-10, 1000, 1000);
-							doh.robot.sequence(function(){
-								if(spin3.get('value')==(1.0+1.0*delta)){
-									d.callback(true);
-								}else{
-									d.errback(new Error("spinner 3: wrong value, expected "+(1.0+1.0*delta)+", got "+spin3.get('value')));
-								}
-							}, 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);
+							}), 1000);
 							return d;
 						}
 					},
@@ -332,7 +323,7 @@
 							// test max with arrow key
 							var d=new doh.Deferred();
 							// press once: should move up
-							doh.robot.mouseMoveAt(spin3.focusNode, 500);
+							doh.robot.mouseMoveAt(spin3.focusNode, 1, 0);
 							doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 							// wheel up 1; this will increase the value by delta
 							doh.robot.mouseWheel(-1, 500, 1);
@@ -341,7 +332,7 @@
 								doh.is("155.0", spin3.focusNode.value);
 								doh.is(true, spin3.isValid());
 								// press again: shouldn't move
-								doh.robot.mouseMoveAt(spin3.focusNode, 500);
+								doh.robot.mouseMoveAt(spin3.focusNode, 1, 0);
 								doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 								// wheel up 1; this will increase the value by delta
 								doh.robot.mouseWheel(-1, 500, 1);
@@ -366,7 +357,7 @@
 							// test min with arrow key
 							var d=new doh.Deferred();
 							// press once: should move up
-							doh.robot.mouseMoveAt(spin3.focusNode, 500);
+							doh.robot.mouseMoveAt(spin3.focusNode, 1, 0);
 							doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
 							doh.robot.mouseWheel(1, 500, 1);
@@ -375,7 +366,7 @@
 								doh.is("-10.9", spin3.focusNode.value);
 								doh.is(true, spin3.isValid());
 								// press again: shouldn't move
-								doh.robot.mouseMoveAt(spin3.focusNode, 500);
+								doh.robot.mouseMoveAt(spin3.focusNode, 1, 0);
 								doh.robot.mouseClick({left:true,  middle:false,  right:false}, 500);
 								doh.robot.mouseWheel(1, 500, 1);
 								doh.robot.sequence(d.getTestCallback(function(){
diff --git a/dijit/tests/form/robot/Textarea.html b/dijit/tests/form/robot/Textarea.html
index a48b392..c161edf 100644
--- a/dijit/tests/form/robot/Textarea.html
+++ b/dijit/tests/form/robot/Textarea.html
@@ -19,110 +19,152 @@
 			dojo.addOnLoad(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){
+						var handler = widget.connect(widget, '_onFocus', function(){
+							widget.disconnect(handler);
+							setTimeout(fcn, 1);
+						});
+						widget.focus();
+					}else{
+						fcn();
+					}
+				};
+
+				doh.register("init", function init(){
+					// Wait for Textarea widgets to size themselves... it's done on a setTimeout(func, 0)
+					var d = new doh.Deferred();
+					setTimeout(function(){
+						d.callback(true);
+					}, 100);
+					return d;
+				});
+
 				doh.register("height tests", [
 					{
 						name: "initial height",
 						runTest: function(){
-							doh.t(dojo.marginBox("largeTextArea").h > dojo.marginBox("blank").h);
+							var blank = dojo.marginBox("blank").h,
+							large = dojo.marginBox("largeTextArea").h;
+							doh.t(large > blank, "blank: " + blank + ", large: " + large);
 						}
 					},
 					{
 						name: "expansion/contraction by newline",
 						timeout: 10000,
 						runTest: function(){
-							var d = new doh.Deferred();
-							
-							var height1 = dojo.marginBox("blank").h;
-
-							dijit.byId("blank").focus();
-
-							// Test expand on newline
-							doh.robot.typeKeys('Row of text.', 500, 500);
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								var height2 = dojo.marginBox("blank").h;
-								doh.t(height2 > height1, "height went from " + height1 + " to " + height2);
-							}), 500);
-
-							// Test shrink on delete of newline
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
-							doh.robot.sequence(d.getTestCallback(function(){
-								var height2 = dojo.marginBox("blank").h;
-								doh.t(height2 > height1, "height went from " + height1 + " to " + height2);
-							}), 500);
+							var
+								d = new doh.Deferred(),
+								w = dijit.byId("blank"),
+								height1 = dojo.marginBox(w.domNode).h,
+								height2, height3;
+
+							focusThenRun(w, function(){
+								// Test expand on newline
+								doh.robot.typeKeys('Row of text.', 1, 2000);
+								doh.robot.keyPress(dojo.keys.ENTER, 100, {});
+								doh.robot.keyPress(dojo.keys.ENTER, 100, {});
+								doh.robot.sequence(function(){
+									height2 = dojo.marginBox(w.domNode).h;
+								}, 1000);
+
+								// Test shrink on delete of newline
+								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 200, {});
+								doh.robot.keyPress(dojo.keys.DELETE, 200, {});
+								doh.robot.sequence(d.getTestCallback(function(){
+									height3 = dojo.marginBox(w.domNode).h;
+									doh.t(height2 > height1, "height ("+height2+") should have increased from " + height1);
+									doh.t(height3 < height2, "height ("+height3+") should have decreased from " + height2);
+								}), 1000);
+							});
 
 							return d;
 						}
 					},
 					{
 						name: "expansion/contraction by word wrap",
-						timeout: 30000,
+						timeout: 50000,
 						runTest: function(){
-							var d = new doh.Deferred();
-
-							var height1 = dojo.marginBox("blank").h,
+							var
+								d = new doh.Deferred(),
+								w = dijit.byId("blank"),
+								height1 = dojo.marginBox(w.domNode).h,
 								height2,
-								height3;
-
-							dijit.byId("blank").focus();
-
-
-							// Test expand by wordwrap
-							var text = 'The quick brown fox jumped over the lazy dog.';
-							for(var i=0; i<5; i++){
-								doh.robot.typeKeys(text, 500, 500);
-							}
-							doh.robot.sequence(d.getTestErrback(function(){
-								height2 = dojo.marginBox("blank").h;
-								doh.t(height2 > height1, "height went from " + height1 + " to " + height2);
-								console.log("height went from " + height1 + " to " + height2);
-							}), 7000);
-
-							// Test shrink on delete (backspace) of text.   delete seems to delete the next character
-							// rather than the previous character, hence the LEFT_ARROW.
-							for(var i=0; i<text.length*5; i++){
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 30, {});
-								doh.robot.keyPress(dojo.keys.DELETE, 30, {});
-							}
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								height3 = dojo.marginBox("blank").h;
-								doh.t(height3 < height2, "height went from " + height2 + " to " + height3);
-							}), 500);
+								height3,
+								handler,
+								pos,
+								i = 0,
+								text = 'The quick brown fox jumped over the lazy dog.',
+								typing = true;
+
+							w.set('intermediateChanges', true);
+							focusThenRun(w, function(){
+								// Test expand by wordwrap
+								text = text+text+text+text;
+								// onChange handler enables very fast typing and deleting, but not too fast
+								handler = w.connect(w, 'onChange', function(nv){
+									if(typing){
+										pos = nv.indexOf(text);
+										if(pos <= 0){
+											doh.robot.typeKeys(text.substr(i++,1), 1, 0);
+											return;
+										} // still typing
+										height2 = dojo.marginBox(w.domNode).h;
+										typing = false;
+										// Test shrink on delete (backspace) of text.   delete seems to delete the next character
+										// rather than the previous character, hence the LEFT_ARROW.
+										doh.robot.keyPress(dojo.keys.LEFT_ARROW, 0, {});
+										doh.robot.keyPress(dojo.keys.DELETE, 0, {});
+									}else{
+										if(nv.length > pos){
+											doh.robot.keyPress(dojo.keys.LEFT_ARROW, 0, {});
+											doh.robot.keyPress(dojo.keys.DELETE, 0, {});
+											return; // still deleting
+										}
+										w.disconnect(handler);
+										doh.robot.sequence(d.getTestCallback(function(){
+											doh.t(height2 > height1, "height ("+height2+") should have increased from " + height1);
+											height3 = dojo.marginBox(w.domNode).h;
+											doh.t(height3 < height2, "height ("+height3+") should have decreased from " + height2);
+										}), 1);
+									}
+								});
+								doh.robot.typeKeys(text.substr(i++,1), 1, 0);
+							});
 
 							return d;
 						}
 					},
 					{
 						name: "expansion/contraction by cut/paste",
-						timeout: 30000,
+						timeout: 5000,
 						runTest: function(){
-							var d = new doh.Deferred();
-
-							var modifier = dojo.isMac ? {meta: true} : {ctrl: true};
-
-							var height1 = dojo.marginBox("blank").h,
+							var
+								d = new doh.Deferred(),
+								modifier = dojo.isMac ? {meta: true} : {ctrl: true},
+								w = dijit.byId("blank"),
+								height1 = dojo.marginBox(w.domNode).h,
 								height2,
 								height3;
 
-							dijit.byId("blank").focus();
-
-							// Cut text, height should decrease
-							doh.robot.keyPress("a", 500, modifier);
-							doh.robot.keyPress("x", 500, modifier);
-							doh.robot.sequence(d.getTestErrback(function(){
-								height2 = dojo.marginBox("blank").h;
-								doh.t(height2 < height1, "height went from " + height1 + " to " + height2);
-								console.log("height went from " + height1 + " to " + height2);
-							}), 500);
-
-							// Paste text, height should increase
-							doh.robot.keyPress("v", 500, modifier);
-							doh.robot.keyPress("v", 500, modifier);
-							doh.robot.sequence(d.getTestCallback(function(){
-								height3 = dojo.marginBox("blank").h;
-								doh.t(height3 > height2, "height went from " + height2 + " to " + height3);
-							}), 500);
+							focusThenRun(w, function(){
+								// 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);
+
+								// Paste text, height should increase
+								doh.robot.keyPress("v", 500, modifier);
+								doh.robot.keyPress("v", 500, modifier);
+								doh.robot.sequence(d.getTestCallback(function(){
+									height3 = dojo.marginBox(w.domNode).h;
+									doh.t(height2 < height1, "height went from " + height1 + " to " + height2);
+									doh.t(height3 > height2, "height went from " + height2 + " to " + height3);
+								}), 1000);
+							});
 
 							return d;
 						}
@@ -135,35 +177,36 @@
 						name: "maxLength",
 						timeout: 10000,
 						runTest: function(){
-							var d = new doh.Deferred();
-							
-							var ta = dijit.byId("simple");
-							
-							ta.focus();
-
-							// Limit is 50, and there's text there already, so not all of
-							// these characters will fit; some should be rejected.
-							doh.robot.typeKeys('0123456789', 500, 500);	
-							doh.robot.sequence(d.getTestErrback(function(){
-								var value = ta.get("value");
-								doh.is(50, value.length, "should have stopped at 50, value is " + value);
-							}), 500);
-
-							// Erase a character
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DELETE, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
-								value = ta.get("value");
-								doh.is(49, value.length, "erased a char, value is " + value);
-							}), 500);
-
-							// And try to type a new character, there should be room now,
-							// but just for one character
-							doh.robot.typeKeys('AB', 500, 500);	
-							doh.robot.sequence(d.getTestCallback(function(){
-								value = ta.get("value");
-								doh.is(50, value.length, "tried to type 2 chars but only 1 should fit, value is " + value);
-							}), 500);
+							var
+								d = new doh.Deferred(),
+								ta = dijit.byId("simple"),
+								value1, value2, value3;
+
+							focusThenRun(ta, function(){
+								// Limit is 50, and there's text there already, so not all of
+								// these characters will fit; some should be rejected.
+								doh.robot.typeKeys('0123456789', 1, 2000);
+								doh.robot.sequence(function(){
+									value1 = ta.get("value");
+								}, 500);
+
+								// Erase a character
+								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 100, {});
+								doh.robot.keyPress(dojo.keys.DELETE, 500, {});
+								doh.robot.sequence(function(){
+									value2 = ta.get("value");
+								}, 500);
+
+								// And try to type a new character, there should be room now,
+								// but just for one character
+								doh.robot.typeKeys('AB', 500, 400);
+								doh.robot.sequence(d.getTestCallback(function(){
+									value3 = ta.get("value");
+									doh.is(50, value1.length, "should have stopped at 50, value is " + value1);
+									doh.is(49, value2.length, "erased a char, value is " + value2);
+									doh.is(50, value3.length, "tried to type 2 chars but only 1 should fit, value is " + value3);
+								}), 500);
+							});
 
 							return d;
 						}
diff --git a/dijit/tests/form/robot/TimeTextBox.html b/dijit/tests/form/robot/TimeTextBox.html
index bffc26c..f46ef96 100644
--- a/dijit/tests/form/robot/TimeTextBox.html
+++ b/dijit/tests/form/robot/TimeTextBox.html
@@ -21,31 +21,135 @@
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_TimeTextBox.html');
 
-				doh.register("TimeTextBox", [
+				doh.register("keyboard", [
 					{
-						name: "keyboard",
-						timeout: 60000,
+						name: "select",
+						timeout: 6000,
 						runTest: function(){
 							var d = new doh.Deferred(),
 								w = dijit.byId('q1');
+							dojo.global.formValue = null;
 	
-							// focus field, thus opening drop down		
+							// focus field... drop down shouldn't open yet
 							w.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+							}), 500);
+
+							// open drop down
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(popup && isVisible(popup), "popup visible");
+							}), 500);
 	
 							// advance from 5:45PM to 6PM, and select
 							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 							
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+
+								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
+								doh.is(val, "T18:00:00", "6PM was selected");
+
+								doh.is(null, dojo.global.formValue, "no form submit");
+							}), 500);
+
+							// ENTER key while drop down is closed should submit the form
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.isNot(null, dojo.global.formValue, "form was submitted");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "select original value",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								w = dijit.byId('q1');
+	
+							dojo.global.formValue = null;
+
+							// focus field... drop down shouldn't open yet
+							w.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+							}), 500);
+
+							// open drop down
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(popup && isVisible(popup), "popup visible");
+							}), 500);
+	
+							// select the initial value
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+
+								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
+								doh.is(val, "T18:00:00", "6PM was selected (again)");
+
+								doh.is(null, dojo.global.formValue, "no form submit");
+							}), 500);
+
+							// ENTER key while drop down is closed should submit the form
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.isNot(null, dojo.global.formValue, "form was submitted");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "cancel",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								w = dijit.byId('q1');
+
+							dojo.global.formValue = null;
+
+							// focus field... drop down shouldn't open yet
+							w.focus();
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+							}), 500);
+
+							// open drop down
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(popup && isVisible(popup), "popup visible");
+							}), 500);
+	
+							// close drop down
+							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+
 								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
-								doh.is(val, "T18:00:00", "should be 6PM");
-							})), 500);
+								doh.is(val, "T18:00:00", "same value as before");
+							}), 500);
 							return d;
 						}
 					},
 					{
 						name: "partial input",
-						timeout: 60000,
+						timeout: 6000,
 						setUp: function(){
 							// clear the field
 							var w = dijit.byId('q2');
@@ -55,25 +159,114 @@
 							var d = new doh.Deferred(),
 								w = dijit.byId('q2');
 	
-							// focus field, thus opening drop down		
+							// focus field... drop down shouldn't open yet
 							w.focus();
-	
-							// close drop down
-							doh.robot.keyPress(dojo.keys.ESCAPE, 1500, {});
-							
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q2_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+							}), 1000);
+		
 							// do partial input
-							doh.robot.typeKeys('12:', 1000, 600);
+							doh.robot.typeKeys('12', 500, 400);
 
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.robot.sequence(d.getTestErrback(function(){
+								// partial input shouldn't be flagged as an error, because probably
+								// the user just hasn't finished typing yet
 								doh.f(w.isValid(), 'fully invalid');
 								doh.t(w._isValidSubset(), 'partially valid');
-								doh.f(this.state == "Error", 'no error shown');
-							})), 500);
+								doh.isNot("Error", w.state, 'no error shown');
+
+								// typing caused drop down to open							
+								var popup = dijit.byId('q2_popup');
+								doh.t(popup && isVisible(popup), "popup visible");
+
+								// drop down list should be filtered to times starting with 12:,
+								// and they should appear in chronological order
+								var popup = dijit.byId("q2_popup"),
+									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]));
+								doh.is("12:30 AM", innerText(children[2]));
+								doh.is("12:45 AM", innerText(children[3]));
+								doh.is("12:00 PM", innerText(children[4]));
+								doh.is("12:15 PM", innerText(children[5]));
+								doh.is("12:30 PM", innerText(children[6]));
+								doh.is("12:45 PM", innerText(children[7]));
+							}), 1000);
+
+							// tab away to close drop down
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.sequence(d.getTestCallback(function(){
+								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");
+							}), 1000);
+
 							return d;
 						}
 					}
 				]);
 
+				var handler, q5;
+				doh.register("mouse", [
+					{
+						name: "select",
+						timeout: 6000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								w = dijit.byId('q1'),
+								toClick;
+	
+							// click field, thus opening drop down
+							doh.robot.mouseMoveAt(w.domNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+	
+							doh.robot.sequence(d.getTestErrback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(popup && isVisible(popup), "popup visible");
+								toClick = dojo.query(".dijitTimePickerItemInner:contains(6:45)", popup.domNode);
+								doh.is(1, toClick.length, "found 6:45 in drop down");
+							}), 500);
+
+							// click 6:45, thus selecting it and closing drop down
+							doh.robot.mouseMoveAt(function(){return toClick[0]; }, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var popup = dijit.byId('q1_popup');
+								doh.t(!popup || isHidden(popup), "popup hidden");
+								var val = dojo.date.stamp.toISOString(w.get('value'), {selector: "time"});	
+								doh.is(val, "T18:45:00", "should be 6:45PM");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "constraints propagation",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							q5 = dijit.byId('q5');
+							handler = q5.connect(q5.focusNode, 'onmouseup', d.getTestCallback(function(){
+								// drop down list should be filtered to 1 hour and 15 minute increments
+								var popup = dijit.byId("q5_popup"),
+									children = dojo.query(".dijitTimePickerItem", popup.domNode);
+								doh.is(4, children.length, "# of items in drop down");
+							}));
+							// click field, thus opening drop down
+							doh.robot.mouseMoveAt(q5.focusNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							return d;
+						},
+						tearDown: function(){
+							q5.disconnect(handler);
+							q5.closeDropDown();
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/form/robot/ValidationTextBox.html b/dijit/tests/form/robot/ValidationTextBox.html
new file mode 100644
index 0000000..07c5e24
--- /dev/null
+++ b/dijit/tests/form/robot/ValidationTextBox.html
@@ -0,0 +1,1241 @@
+<!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>doh.robot Validation 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">
+			dojo.require("dijit.robotx");
+
+			function fixNbsp(val){
+				return typeof val == "string" ? val.replace(/\xA0/g, " ") : val;
+			}
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_validate.html');
+
+				// Test initial conditions
+				doh.register("initial conditions", {
+					name: "initial conditions",
+					runTest: function(){
+						var form1 = dojo.byId("form1");
+						
+						doh.is("Testing Testing", form1.firstname.value, "firstname");
+						doh.is("not fired yet!", dojo.byId("oc1").value, "firstname onchange");
+
+						doh.is("TESTING TESTING", form1.lastname.value, "lastname");
+						
+						doh.is("", form1.age.value, "age");
+						doh.is("not fired yet!", dojo.byId("oc3").value, "age onchange");
+						
+						doh.is("", form1.occupation.value, "occupation");
+						
+						doh.is("3000", form1.elevation.value, "elevation");
+						doh.is("3,000", dojo.byId("q05").value, "elevation display value");
+						doh.is("not fired yet!", dojo.byId("oc5").value, "elevation onchange");
+						
+						doh.is("54775.53", form1.income1.value, "income1");
+						doh.is("$54,775.53", dojo.byId("q08").value, "income1 display value");
+						doh.is("not fired yet!", dojo.byId("oc8").value, "income1 onchange");
+
+						doh.is("54775.53", form1.income2.value, "income2");
+						doh.is("€54,775.53", dojo.byId("q08eur").value, "income2 display value");
+
+						doh.is("someTestString", form1.phone.value, "phone");
+						doh.is("", form1.password.value, "password");
+						doh.is("", form1.ticket1651.value, "ticket1651");
+						doh.is("cannot type here", form1.readOnly.value, "readonly");
+						doh.is("cannot type here", form1.disabled.value, "disabled");
+					}
+				});
+
+				var watchHandle, onChangeHandle;
+
+				function setTest(testName, textbox, setDict, watchExpected, unchangedExpected, isValid, onChangeExpected){
+					// summary:
+					//		Generate test to call set("value", ...) and check response
+					// textbox: String
+					//		id of TextBox widget
+					// setDict: Dictionary
+					//		Value to pass to textbox.set(), such as {value: "123"} or {displayedValue: "1,234"}.
+					// watchExpected: Dictionary
+					//		Expected changes in state of TextBox, such as
+					//			{value: 1234, displayedValue: "1,234"}
+					//		Checks that watch() returns these values.
+					//		Also checks that textbox is actually displaying displayedValue
+					// unchangedExpected: Dictionary
+					//		Attributes of textbox that shouldn't change/be reported by watch(), and their values
+					//			{value: 1234, displayedValue: "1,234"}
+					//		Checks that watch() returns these values.
+					//		Also checks that textbox is actually displaying displayedValue
+					// isValid: Boolean
+					//		Checks return of textbox.isValid().   TODO: this should be watchable.
+					// onChangeExpected:
+					//		Check that onChange reports this value
+
+
+					return {
+						name: testName,
+						timeout: 1000,
+						runTest: function(){
+
+							textbox = dijit.byId(textbox);
+		
+							// expectedState is a combination of the attributes that we expect to change
+							// and the attributes that we expect not to change
+							var expectedState = dojo.delegate(watchExpected, unchangedExpected);
+
+							// save all notifications from watch()		
+							var watchActual = {};
+							watchHandle = textbox.watch(function(attr, oldVal, newVal){
+									console.log(textbox.id + ": " + attr + ": " + oldVal + " --> " + newVal);
+									watchActual[attr] = fixNbsp(newVal);
+								});
+
+							// and monitor onChange() calls too
+							var onChangeActual;
+							if(onChangeExpected){
+								onChangeHandle = dojo.connect(textbox, "onChange", function(newVal){
+									onChangeActual = fixNbsp(newVal);
+								});
+							}
+
+							// do the set
+							textbox.set(setDict);
+							
+							doh.is(expectedState.displayedValue, fixNbsp(textbox.focusNode.value), "focusNode.value");
+		
+							doh.is(isValid, textbox.isValid(), "isValid()");
+		
+							var d = new doh.Deferred();
+		
+							doh.robot.sequence(d.getTestCallback(function(){
+								// test that onChange() was called correctly
+								if(onChangeExpected){
+									doh.is(onChangeExpected, onChangeActual, "onChange()");
+								}
+								
+								// check that watch() callbacks were called
+								for(attr in watchExpected){
+									doh.t(attr in watchActual, "watch(" + attr + ") fired");
+									doh.is(watchExpected[attr], watchActual[attr], "watch(" + attr + ")")
+									doh.is(typeof watchExpected[attr], typeof watchActual[attr], "typeof watch(" + attr + ")")
+								}
+		
+								// check that direct get(...) calls are also working, for both the attributes
+								// that were supposed to change and the attributes that weren't supposed to change
+								for(attr in expectedState){
+									doh.is(expectedState[attr], fixNbsp(textbox.get(attr)), "get(" + attr + ")")
+									doh.is(typeof expectedState[attr], typeof textbox.get(attr), "typeof get(" + attr + ")")
+								}
+
+								// check that watch() didn't report attributes as changed when they didn't change
+								for(attr in unchangedExpected){
+									doh.f(attr in watchActual, attr + " shouldn't have been reported as changed by watch " + 
+										watchActual[attr]);
+								}
+							}), 50);		
+		
+							return d;
+						},
+						tearDown: function(){
+							watchHandle.unwatch();
+							watchHandle = null;
+							if(onChangeHandle){
+								dojo.disconnect(onChangeHandle);
+								onChangeHandle = null;
+							}
+						}
+					};
+				}
+
+				doh.register("set('value')", [
+					// test valid and invalid settings of value
+					setTest("valid_max", 'q03', {value: 120}, {value: 120, displayedValue: "120"}, {}, true),
+					setTest("out_of_range_max",'q03', {value: 121}, {value: 121, displayedValue: "121", state: "Error"}, {}, false),
+					setTest("valid_min", 'q03', {value: 0}, {value: 0, displayedValue: "0", state: ""}, {}, true),
+					setTest("out_of_range_min", 'q03', {value: -1}, {value: -1, displayedValue: "-1", state: "Error"}, {}, false),
+					setTest("invalid", 'q03', {value: 'two'}, {value: undefined, displayedValue: 'two'}, {}, false),
+					setTest("null_required", 'q03', {required: true, value: null},
+							{required: true, value: NaN, displayedValue: ''}, {state: "Error"}, false),	
+					setTest("null_notrequired", 'q03', {required: false, value: null}, {}, {displayedValue: ''}, true),
+
+					// test formatting of value vs. displayed value
+					setTest("number format", 'q05', {value: 1234}, {value: 1234, displayedValue: "1,234"}, {}, true),
+					setTest("currency format", 'q08', {value: 1234}, {value: 1234, displayedValue: "$1,234.00"}, {}, true)
+				]);
+
+				doh.register("set('displayedValue')", [
+					// test formatting of value vs. displayed value, in reverse
+					setTest("number format", 'q05', {displayedValue: "4,321"}, {value: 4321, displayedValue: "4,321"}, {}, true),
+					setTest("european currency format", 'q08eurde', {displayedValue: "4.321,98"},
+						{value: 4321.98, displayedValue: "4.321,98 €"}, {}, true)
+				]);
+
+				doh.register("intermediatechanges", {
+					name: "valid",
+					textbox: "q01",
+					timeout: 9000,
+					setUp: function(){
+						this.textbox = dijit.byId(this.textbox);
+						this.textbox.set('value', '');
+						this.textbox.focusNode.focus();
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						var onChange = dojo.byId('oc1');
+						doh.robot.typeKeys('Testing', 1000, 1400);
+						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							// test that value changed while typing since intermediateChanges = true
+							doh.is('Testing', this.textbox.focusNode.value, "focusNode value");
+							doh.is('Testing', this.textbox.get('value'), "attr value");
+							doh.is('Testing', onChange.value, "onChange.value");
+						})), 1000);
+						return d;
+					}
+				});
+
+				doh.register("allcaps", {
+					name: "valid",
+					textbox: "q02",
+					timeout: 9000,
+					setUp: function(){
+						this.textbox = dijit.byId(this.textbox);
+						this.textbox.set('value', '');
+						this.textbox.focusNode.focus();
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						doh.robot.typeKeys('Testing', 1000, 1400);
+						doh.robot.sequence(function(){
+							dojo.byId("q01").focus();
+						}, 500);
+						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.is('TESTING', this.textbox.focusNode.value, "focusNode.value");
+							doh.is('TESTING', this.textbox.get('value'), "get('value')");
+						})), 1000);
+						return d;
+					}
+				});
+
+				doh.register("maxlength", [
+					{
+						name: "3chars",
+						textbox: "fav",
+						timeout: 9000,
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							doh.robot.typeKeys('100', 1000, 600);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								// test that value changed while typing since intermediateChanges = true
+								doh.is('100', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(100, this.textbox.get('value'), "get('value')");
+							})), 1000);
+							return d;
+						}
+					},
+
+					{
+						name: "4chars",
+						textbox: "fav",
+						timeout: 9000,
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							doh.robot.typeKeys('1001', 1000, 800);
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								// test that value changed while typing since intermediateChanges = true
+								doh.is('100', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(100, this.textbox.get('value'), "get('value')");
+								doh.robot.typeKeys('1', 500, 200);
+								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+									doh.is('100', this.textbox.focusNode.value, "focusNode.value");
+									doh.is(100, this.textbox.get('value'), "get('value')");
+								})), 500);
+							})), 1000);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("errorStyle", [
+					{
+						name: "beforeFocus",
+						textbox: "q04",
+						runTest: function(){
+							this.textbox = dijit.byId(this.textbox);
+							doh.is('Incomplete', this.textbox.get('state'));
+							doh.is(false, this.textbox.isValid(), "isValid()");
+						}
+					},
+
+					{
+						name: "focus",
+						textbox: "q04",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.focusNode.focus();
+							doh.robot.sequence(dojo.hitch(this, function(){
+								dojo.byId("q01").focus();
+							}), 1000);	// time for promptMessage to appear on q04 (IE6 takes a while due to iframe)
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('Error', this.textbox.get('state'));
+								doh.is(false, this.textbox.isValid(), "isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+
+					{
+						name: "valid",
+						textbox: "q04",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.focusNode.focus();
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is('Error', this.textbox.get('state'));
+								doh.is(false, this.textbox.isValid(), "isValid()");
+								doh.robot.typeKeys('a', 500, 200);
+								doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+									doh.is('a', this.textbox.get('value'), "get('value')");
+									doh.is('', this.textbox.get('state'), "state 1");
+									doh.is(true, this.textbox.isValid(), "isValid() 1");
+									dojo.byId("q01").focus();
+									doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+										doh.is('', this.textbox.get('state'), "state 2");
+										doh.is(true, this.textbox.isValid(), "isValid() 2");
+									})), 1000);
+								})), 500);
+							})), 1000);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("commaformat", [
+					{
+						name: "beforeFocus",
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', 3000);
+						},
+						runTest: function(){
+							this.textbox = dijit.byId(this.textbox);
+							doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
+							doh.is('3000', this.textbox.get('value'), "get('value')");
+							doh.is(true, this.textbox.isValid(), "isValid()");
+						}
+					},
+
+					{
+						name: "focus",
+						timeout: 9000,
+						textbox: "q05",
+						runTest: function(){
+							var d = new doh.Deferred();
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.focusNode.focus();
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								// comma should disappear on click, value shouldn't change
+								doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('3000', this.textbox.get('value'), "get('value')");
+								doh.is(true, this.textbox.isValid(), "isValid()");
+							})), 500);
+							return d;
+						}
+					},
+
+					{
+						name: "type_valid_nocomma",
+						timeout: 9000,
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc5');
+							doh.robot.typeKeys('3000', 1000, 800);
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is('3000', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('3000', this.textbox.get('value'), "get('value')");
+								doh.is(true, this.textbox.isValid(), "isValid()");
+								doh.is('NaN', onChange.value);
+								dojo.byId("q01").focus();
+								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+									doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
+									doh.is('3000', this.textbox.get('value'), "get('value')");
+									doh.is(true, this.textbox.isValid(), "isValid()");
+									doh.is('3000', onChange.value);
+								})), 1000);
+							})), 1000);
+							return d;
+						}
+					},
+
+					{
+						name: "type_valid_comma",
+						timeout: 9000,
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc5');
+							doh.robot.typeKeys('3,000', 1000, 1000);
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('3000', this.textbox.get('value'), "get('value')");
+								doh.is(true, this.textbox.isValid(), "isValid()");
+								doh.is('NaN', onChange.value);
+								dojo.byId("q01").focus();
+								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+									doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
+									doh.is('3000', this.textbox.get('value'), "get('value')");
+									doh.is(true, this.textbox.isValid(), "isValid()");
+									doh.is('3000', onChange.value);
+								})), 1000);
+							})), 1000);
+							return d;
+						}
+					},
+
+					{
+						name: "type_invalid_comma",
+						timeout: 9000,
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc5');
+							doh.robot.typeKeys('300,0', 1000, 1000);
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is('300,0', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(undefined, this.textbox.get('value'), "get('value')");
+								doh.is(false, this.textbox.isValid(), "isValid()");
+								doh.is('NaN', onChange.value);
+								dojo.byId("q01").focus();
+								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+									doh.is('300,0', this.textbox.focusNode.value, "focusNode.value");
+									doh.is(undefined, this.textbox.get('value'), "get('value')");
+									doh.is(false, this.textbox.isValid(), "isValid()");
+									doh.is('undefined', onChange.value);
+								})), 1000);
+							})), 1000);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("currencyFormat", [
+					{
+						name: "beforeFocus",
+						textbox: "q08",
+						runTest: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set("value", 54775.53);
+							doh.is('$54,775.53', this.textbox.focusNode.value, "focusNode.value");
+							doh.is('54775.53', this.textbox.get('value'), "get('value')");
+							doh.is(true, this.textbox.isValid(), "isValid()");
+						}
+					},
+
+					{
+						name: "focus",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								// comma should disappear on click, value shouldn't change
+								doh.is('54775.53', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('54775.53', this.textbox.get('value'), "get('value')");
+								doh.is(true, this.textbox.isValid(), "isValid()");
+							})), 500);
+							return d;
+						}
+					},
+
+					{
+						name: "type_valid_number",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('10000.01', 1000, 1600);
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is('10000.01', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('10000.01', this.textbox.get('value'), "get('value')");
+								doh.is(true, this.textbox.isValid(), "isValid()");
+								doh.is('NaN', onChange.value);
+								dojo.byId("q01").focus();
+								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+									doh.is('$10,000.01', this.textbox.focusNode.value, "focusNode.value");
+									doh.is('10000.01', this.textbox.get('value'), "get('value')");
+									doh.is(true, this.textbox.isValid(), "isValid()");
+									doh.is('10000.01', onChange.value);
+								})), 1000);
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "type_valid_dollarsign",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var textbox = this.textbox;
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('$20000.01', 1000, 1800);
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is('$20000.01', textbox.focusNode.value, "focusNode.value");
+								doh.is(20000.01, textbox.get('value'), "get('value')");
+								doh.is(true, textbox.isValid(), "isValid()");
+								doh.is('NaN', onChange.value);
+								var handler = textbox.connect(textbox, 'onChange',
+									function(){
+										textbox.disconnect(handler);
+										setTimeout(d.getTestCallback(function(){
+											doh.is('$20,000.01', textbox.focusNode.value, "blurred focusNode.value");
+											doh.is(20000.01, textbox.get('value'), "blurred get('value')");
+											doh.is(true, textbox.isValid(), "blurred isValid()");
+											doh.is('20000.01', onChange.value);
+										}), 1);
+									});
+								dojo.byId("q01").focus();
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "missing required decimal",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('123', 1000, 600);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('123', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(undefined, this.textbox.get('value'), "get('value')");
+								doh.f(this.textbox.isValid(), "!isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "too few decimal digits",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('123.0', 1000, 1000);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('123.0', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(undefined, this.textbox.get('value'), "get('value')");
+								doh.f(this.textbox.isValid(), "!isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "too many decimal digits",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('123.000', 1000, 1400);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('123.000', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(undefined, this.textbox.get('value'), "get('value')");
+								doh.f(this.textbox.isValid(), "!isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "negative decimal",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('-123.00', 1000, 1400);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('-123.00', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(-123, this.textbox.get('value'), "get('value')");
+								doh.t(this.textbox.isValid(), "isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "negative currency",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('($123.00)', 1000, 1600);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('($123.00)', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(-123, this.textbox.get('value'), "get('value')");
+								doh.t(this.textbox.isValid(), "isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "convert negative decimal to negative currency",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('-123.45', 1000, 1400);
+
+							var textbox = this.textbox;
+							var handler = textbox.connect(textbox, '_onBlur',
+								function(){
+									textbox.disconnect(handler);
+									setTimeout(d.getTestCallback(function(){
+										doh.is('($123.45)', textbox.focusNode.value, "focusNode.value");
+										doh.is(-123.45, textbox.get('value'), "get('value')");
+										doh.t(textbox.isValid(), "isValid()");
+									}), 150);
+								});
+							doh.robot.keyPress(dojo.keys.TAB, 100, {});
+							return d;
+						}
+					},
+					{
+						name: "convert negative negative currency to negative decimal",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('($123.45)', 1000, 1800);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('-123.45', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(-123.45, this.textbox.get('value'), "get('value')");
+								doh.t(this.textbox.isValid(), "isValid()");
+							})), 1000);
+							return d;
+						}
+					},
+					{
+						name: "exponent not allowed",
+						timeout: 9000,
+						textbox: "q08",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var onChange = dojo.byId('oc8');
+							doh.robot.typeKeys('1.23e0', 1000, 1200);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('1.23e0', this.textbox.focusNode.value, "focusNode.value");
+								doh.is(undefined, this.textbox.get('value'), "get('value')");
+								doh.f(this.textbox.isValid(), "!isValid()");
+							})), 1000);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("euroformat", {
+					name: "type_1",
+					timeout: 9000,
+					textbox: "q08eur",
+					setUp: function(){
+						this.textbox = dijit.byId(this.textbox);
+						this.textbox.set('value', '');
+						this.textbox.focusNode.focus();
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						doh.robot.typeKeys('1', 1000, 200);
+						doh.robot.sequence(dojo.hitch(this, function(){
+							dijit.byId('q01').focusNode.focus();
+						}), 500);
+						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.is('€1.00', this.textbox.focusNode.value, "focusNode.value");
+							doh.is('1', this.textbox.get('value'), "get('value')");
+							doh.is(true, this.textbox.isValid(), "isValid()");
+						})), 1000);
+						return d;
+					}
+				});
+
+				doh.register("regexp", [
+					{
+						name: "valid",
+						timeout: 9000,
+						textbox: "q22",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							doh.robot.typeKeys('a', 1000, 200);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('a', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('a', this.textbox.get('value'), "get('value')");
+								doh.is(true, this.textbox.isValid(), "isValid()");
+							})), 500);
+							return d;
+						}
+					},
+
+					{
+						name: "invalid",
+						timeout: 9000,
+						textbox: "q22",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.focusNode.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							doh.robot.typeKeys('a ', 1000, 400);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('a ', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('a ', this.textbox.get('value'), "get('value')");
+								doh.is(false, this.textbox.isValid(), "isValid()");
+							})), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("password", {
+					name: "type",
+					timeout: 9000,
+					textbox: "q23",
+					setUp: function(){
+						this.textbox = dijit.byId(this.textbox);
+						this.textbox.set('value', '');
+						this.textbox.focusNode.focus();
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						doh.robot.typeKeys('abcdef', 1000, 1200);
+						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+							doh.is('abcdef', this.textbox.focusNode.value, "focusNode.value");
+							doh.is('abcdef', this.textbox.get('value'), "get('value')");
+						})), 1000);
+						return d;
+					}
+				});
+
+				doh.register("readonly", [
+					{
+						name: "readonly",
+						timeout: 9000,
+						textbox: "q24",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							dojo.byId("mname").focus();
+						},
+						runTest: function(){
+							doh.t(this.textbox.isFocusable(), "readOnly is focusable");
+							var d = new doh.Deferred();
+
+							// Tab into element (readonly *can* be focused, although disabled can't)
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+
+							// typing on a disabled element should have no effect
+							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('cannot type here', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('cannot type here', this.textbox.get('value'), "get('value')");
+							})), 1000);
+							return d;
+						}
+					},
+
+					{
+						name: "write",
+						timeout: 9000,
+						textbox: "q24",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('value', '');
+							this.textbox.set('readOnly', false);
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							//  Click to focus
+							doh.robot.mouseMoveAt(this.textbox.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.typeKeys('abc', 1000, 600);
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is('abc', this.textbox.focusNode.value, "focusNode.value");
+								doh.is('abc', this.textbox.get('value'), "get('value')");
+							})), 1000);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("disabled", [
+					{
+						name: "click doesn't focus",
+						timeout: 9000,
+						setUp: function(){
+							this.textbox = dijit.byId("q24");
+							dojo.byId("mname").focus();
+							this.textbox.set('disabled', true);
+						},
+						runTest: function(){
+							doh.f(this.textbox.isFocusable(), "disabled is not focusable");
+							var d = new doh.Deferred();
+
+							//  Clicking shouldn't have any effect since it's disabled
+							doh.robot.mouseMoveAt(this.textbox.focusNode, 500, 1);
+							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");
+							})), 500);
+							return d;
+						}
+					},
+
+					{
+						name: "tab jumps over",
+						timeout: 9000,
+
+						setUp: function(){
+							var textbox = dijit.byId("q24");
+							dojo.byId("mname").focus();
+							textbox.set('disabled', true);
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.keyPress(dojo.keys.TAB, 500);
+
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.is("q26", dojo.global.dijit._curFocus.id,
+										"tabbed past input, to the button after it");
+							})), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("selectOnClick", [
+					{
+						name: "1 click does highlight",
+						timeout: 9000,
+						setUp: function(){
+							dijit.byId("q02").focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred(),
+								textbox = dijit.byId("q01");
+
+							textbox.set('value', 'Testing');
+							doh.robot.mouseMoveAt(textbox.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.typeKeys("abc", 1000, 600);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Abc", textbox.get('value'), "was highlighted");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "2 clicks doesn't highlight",
+						timeout: 9000,
+						setUp: function(){
+							dijit.byId("q02").focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred(),
+								textbox = dijit.byId("q01");
+
+							textbox.set('value', 'Testing');
+							doh.robot.mouseMoveAt(textbox.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseClick({left: true}, 1000);
+							var oldValue = textbox.get('value');
+							doh.robot.typeKeys("abc", 500, 600);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.isNot(oldValue, textbox.get('value'), "didn't change at all");
+								doh.isNot("Abc", textbox.get('value'), "was highlighted");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "TAB focus still highlights a selectOnFocus textbox",
+						timeout: 9000,
+						setUp: function(){
+							dijit.byId("q02").focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred(),
+								textbox = dijit.byId("q01");
+
+							textbox.set('value', 'Testing');
+							doh.robot.mouseMoveAt(textbox.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
+							doh.robot.typeKeys("abc", 500, 600);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Abc", textbox.get('value'), "was not highlighted");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "click doesn't highlight after TAB focus",
+						timeout: 9000,
+						setUp: function(){
+							dijit.byId("q02").focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred(),
+								textbox = dijit.byId("q01");
+
+							textbox.set('value', 'Testing');
+							doh.robot.mouseMoveAt(textbox.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000);
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
+							doh.robot.mouseClick({left: true}, 1000);
+							var oldValue = textbox.get('value');
+							doh.robot.typeKeys("abc", 500, 600);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.isNot(oldValue, textbox.get('value'), "didn't change at all");
+								doh.isNot("Abc", textbox.get('value'), "was highlighted");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "mouse selection still works",
+						timeout: 9000,
+						setUp: function(){
+							dijit.byId("q02").focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred(),
+								textbox = dijit.byId("q01");
+
+							textbox.set('value', 'MMMMMMM');
+							doh.robot.mouseMoveAt(textbox.focusNode, 500, 1, 3, 6);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500, 10, 6);
+							doh.robot.mouseRelease({left: true}, 500);
+							doh.robot.typeKeys("abc", 500, 600);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("AbcMMMMMM", textbox.get('value'), "could not select text");
+							}), 500);
+							return d;
+						}
+					}
+				]);
+
+				doh.register("set constraints", [
+					{
+						name: "number",
+						timeout: 9000,
+						runTest: function(){
+							var textWidget = dijit.byId("q05");
+							textWidget.set('value', 12345);
+							doh.is("12,345", textWidget.get('displayedValue'), "default value");
+							textWidget.set('constraints', {places:2});
+							doh.is("12,345.00", textWidget.get('displayedValue'), "decimal value");
+						}
+					},
+					{
+						name: "currency",
+						timeout: 9000,
+						runTest: function(){
+							var textWidget = dijit.byId("q08eurde");
+							textWidget.set('value', 12345.25);
+							doh.is("12.345,25\xa0€", textWidget.get('displayedValue'), "EUR value");
+							textWidget.set('constraints', {currency:'USD', locale:'en-us'});
+							doh.is("$12,345.25", textWidget.get('displayedValue'), "USD value");
+						}
+					}
+				]);
+
+				doh.register("placeholder", [
+					{
+						name: "textbox",
+						runTest: function(){
+							var textWidget = dijit.byId("q26");
+							doh.is('', textWidget.get('value'),'initial value is empty');
+							doh.is('placeholder is here', textWidget._phspan.innerHTML, '_phspan.innerHTML');
+							textWidget.set('value','abc');
+							doh.is('abc', textWidget.get('value'));
+							textWidget.set('placeHolder','new placholder');
+							doh.is('abc', textWidget.get('value'));
+							textWidget.set('value','');
+							doh.is('new placholder', textWidget._phspan.innerHTML, '_phspan.innerHTML 1');
+							doh.is('', textWidget.get('value'));
+						}
+					},
+					{
+						name: "focus/blur textbox",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred(), textWidget = dijit.byId("q26");
+							textWidget.set('placeHolder','placeholder is here');
+							textWidget.set('value','');
+							
+							//  Clicking into the input should hide _phspan
+							doh.robot.mouseMoveAt(textWidget.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is("", textWidget.get('value'), "get('value')");
+								doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
+								
+								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("", textWidget.get('value'), "get('value')");
+									doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display 1");
+								}), 1000);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "type in textbox",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred(), textWidget = dijit.byId("q26");
+							textWidget.set('placeHolder','placeholder is here');
+							textWidget.set('value','');
+							
+							//  Clicking into the input should hide _phspan
+							doh.robot.mouseMoveAt(textWidget.focusNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.is("", textWidget.get('value'), "get('value')");
+								doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 1");
+								
+								doh.robot.typeKeys('new', 0, 600);
+								doh.robot.sequence(d.getTestCallback(function(){
+									doh.is("new", textWidget.get('value'), "get('value')");
+									doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 2");
+								}), 500);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "reset textbox",
+						timeout: 9000,
+						runTest: function(){
+							var textWidget = dijit.byId("q26"), d = new doh.Deferred();
+							textWidget.focus();
+							textWidget.set('placeHolder','placeholder is here');
+							textWidget.set('value','');
+							
+							doh.is("", textWidget.get('value'), "get('value') 1");
+							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
+							
+							textWidget.set('value','abc');
+							textWidget.reset();
+							
+							doh.is("", textWidget.get('value'), "get('value') 2");
+							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 1");
+							
+							var handler = textWidget.connect(textWidget, '_onBlur',
+								function(){
+									textWidget.disconnect(handler);
+									textWidget.set('value','xyz');
+									textWidget.reset();
+									setTimeout(d.getTestCallback(function(){
+										doh.is("", textWidget.get('value'), "get('value')");
+										doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display 2");
+									}), 150);
+								});
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							
+							return d;
+						}
+					},
+					{
+						name: "set textbox value",
+						runTest: function(){
+							var textWidget = dijit.byId("q26");
+							textWidget.set('placeHolder','placeholder is here');
+							textWidget.set('value','value');
+							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
+						}
+					}
+				]);
+
+				doh.register("#11889", [
+					{
+						name: "non-focused places:5",
+						timeout: 2000,
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('constraints', { places: 5 });
+							this.textbox.set('editOptions', { places: "2,4" });
+						},
+						runTest: function(){
+							this.textbox.set('value', 1.625);
+							doh.is(1.625, this.textbox.get('value'), 'numeric value is unchanged');
+							doh.is('1.62500', this.textbox.get('displayedValue'), 'formatted displayed value');
+							doh.t(true, this.textbox.isValid(false), 'nonfocused is valid');
+						}
+					},
+					{
+						name: "focused places:2,4. blur to places:5",
+						timeout: 2000,
+						textbox: "q05",
+						setUp: function(){
+							this.textbox = dijit.byId(this.textbox);
+							this.textbox.set('constraints', { places: 5 });
+							this.textbox.set('editOptions', { places: "2,4" });
+							this.textbox.focus();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+							var textbox = this.textbox;
+							textbox.set('value', 1.125);
+
+							doh.is(1.125, textbox.get('value'), 'numeric value is unchanged');
+							doh.is('1.125', textbox.get('displayedValue'), 'formatted displayed value');
+							doh.t(true, textbox.isValid(true), 'focused is valid');
+
+							var handler = textbox.connect(textbox, '_onBlur',
+								function(){
+									textbox.disconnect(handler);
+									setTimeout(d.getTestCallback(function(){
+										doh.is(1.125, textbox.get('value'), 'numeric value is unchanged');
+										doh.is('1.12500', textbox.get('displayedValue'), 'formatted displayed value');
+										doh.t(true, textbox.isValid(false), 'nonfocused is valid');
+									}), 150);
+								});
+							dojo.byId("q01").focus();
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/form/robot/_autoComplete_a11y.html b/dijit/tests/form/robot/_autoComplete_a11y.html
index a389c1e..8a438df 100644
--- a/dijit/tests/form/robot/_autoComplete_a11y.html
+++ b/dijit/tests/form/robot/_autoComplete_a11y.html
@@ -36,36 +36,41 @@
 			var arrowlessComboBoxes=['arrowless'];
 
 			var robot_typeValue = function(combo, text, value, expectedText){
-				if(!value) value = text;
-				if(!expectedText) expectedText = text;
+				if(value===undefined) value = text;
+				if(expectedText===undefined) expectedText = text;
 				var d = new doh.Deferred();
+
+				// setup watch() on "value" and "displayedValue"
+				var dv, v;					
+				var h1 = combo.watch("displayedValue", function(name, oldVal, newVal){ dv = newVal; });
+				var h2 = combo.watch("value", function(name, oldVal, newVal){ v = newVal; });
+
 				combo.focusNode.focus();
 				combo.itemError = false;
 				doh.robot.sequence(function(){ combo.set("value", null); }, 500);
 				doh.robot.typeKeys(text.replace(/^(.).*$/, "$1"), 500);
 				doh.robot.typeKeys(text.replace(/^./, ""), 1500);
 				doh.robot.keyPress(dojo.keys.ENTER, 1500);
-				doh.robot.sequence(function(){
-					if(combo.get("value") == value && combo.focusNode.value == expectedText && !combo._isShowingNow && !combo.itemError){
-						d.callback(true);
-					}else{
-						if(combo._isShowingNow){
-							// menu could arrive after Enter keypress if it is not thrown out
-							// TODO: is this still needed?   I've got explicit tests in the "race condition"
-							// section to make sure this doesn't happen, and it doesn't seem to be.
-							combo._hideResultList();
-							d.errback(combo.id+" had a menu that did not close after an Enter keypress.");
-						}else{
-							d.errback(combo.id+" was supposed to have a value of "+value+" (actually "+combo.get("value")+"). Text is "+combo.focusNode.value+" (expected "+expectedText+")");
-						}
-					}
-				}, 2000);
+
+				doh.robot.sequence(d.getTestCallback(function(){
+					// general tests
+					doh.is(value, combo.get("value"), "combo.get(value)");
+					doh.is(expectedText, combo.focusNode.value, "expectedText");
+					doh.f(combo._opened, "not opened");
+					doh.f(combo.itemError, "no itemError");
+					
+					// watch() tests
+					doh.is(expectedText, dv, "watch of displayedValue");
+					doh.is(value, v, "watch of value");
+					h1.unwatch();
+					h2.unwatch();
+				}), 2000);
 				return d;
 			};
 
 			var findMenuItem = function(combo, text){
-				var node = combo._popupWidget.domNode.firstChild;
-				while(((node.innerText || node.textContent).indexOf(text)<0) && node.nextSibling){
+				var node = combo.dropDown.domNode.firstChild;
+				while(innerText(node).indexOf(text) < 0 && node.nextSibling){
 					node = node.nextSibling;
 				}
 				return node;
@@ -77,6 +82,12 @@
 				if(!expectedText) expectedText = text;
 				var d = new doh.Deferred();
 
+				// setup watch() on "value", "displayedValue", "item"
+				var dv, v, i;					
+				var h1 = combo.watch("displayedValue", function(name, oldVal, newVal){ dv = newVal; });
+				var h2 = combo.watch("value", function(name, oldVal, newVal){ v = newVal; });
+				var h3 = combo.watch("item", function(name, oldVal, newVal){ i = newVal; });
+
 				combo.focusNode.focus();
 				combo.itemError = false;
 				doh.robot.sequence(function(){ combo.set("value", null); }, 1000);
@@ -85,8 +96,8 @@
 				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
 				var repeat = function(){
 					var node = findMenuItem(combo, text);
-					var isMoreChoices = node == combo._popupWidget.nextButton;
-					var selected = combo._popupWidget.getHighlightedOption() || combo._popupWidget.domNode.firstChild;
+					var isMoreChoices = node == combo.dropDown.nextButton;
+					var selected = combo.dropDown.getHighlightedOption() || combo.dropDown.domNode.firstChild;
 					while(selected != node){
 						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
 						selected = selected.nextSibling;
@@ -96,13 +107,20 @@
 						// can go faster since the data will have loaded by now
 						doh.robot.sequence(repeat, 1000);
 					}else{
-						doh.robot.sequence(function(){
-							if(combo.get("value") == value && combo.focusNode.value == expectedText && !combo.itemError){
-								d.callback(true);
-							}else{
-								d.errback(combo.id+" was supposed to have a value of "+value+" (actually "+combo.get("value")+"). Text is "+combo.focusNode.value+" (expected "+expectedText+")");
-							}
-						}, 500);
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is(value, combo.get("value"), "combo.get(value)");
+							doh.is(expectedText, combo.focusNode.value, "expectedText");
+							doh.f(combo._opened, "not opened");
+							doh.f(combo.itemError, "no itemError");
+							
+							// 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");
+							h1.unwatch();
+							h2.unwatch();
+							h3.unwatch();
+						}), 500);
 					}
 
 				};
@@ -111,33 +129,6 @@
 				return d;
 			};
 
-			// Enter an invalid value into the ComboBox/FilteringSelect, and test
-			// that FilteringSelect flags it as an error (but ComboBox allows it)
-			var errorTest = function(){
-				robot_typeValue((this.combo = dijit.byId(this.combo)), "zxcxarax");
-				var d = new doh.Deferred();
-				doh.robot.sequence(dojo.hitch(this, function(){
-					if(isComboBox){
-						if(this.combo.isValid() && this.combo.get("value") == "zxcxarax" && !this.combo.itemError){
-							d.callback(true);
-						}else{
-							d.errback(new Error("Good value flagged as bad in ComboBox"));
-						}
-					}else{
-						if(!this.combo.isValid() && this.combo.get("value") == "" && !this.combo.itemError){
-							d.callback(true);
-						}else{
-							if(this.combo.isValid()){
-								d.errback(new Error("Bad value permitted in FilteringSelect. Value is: "+this.combo.get("value")+", text is:"+this.combo.focusNode.value));
-							}else{
-								d.errback(new Error("Expected value of '', got "+this.combo.get("value")));
-							}
-						}
-					}
-				}), 2000);
-				return d;
-			};
-
 			// Wait for data stores to finish loading before starting tests
 			doh.register("wait for data store load",
 				dojo.map(["store", "store2", "stateStore", "dijitStore"], function(name){
@@ -167,8 +158,8 @@
 					runTest:function(){
 						// Spot check of initial conditions of widgets and DOM nodes
 
-						doh.is("California (CA)", dijit.byId("setvaluetest").get("displayedValue"), "state1 displayed value");
-						doh.is(isComboBox ? "California (CA)" : "CA", dijit.byId("setvaluetest").get("value"), "state1 value");
+						doh.is("California", dijit.byId("setvaluetest").get("displayedValue"), "state1 displayed value");
+						doh.is(isComboBox ? "California" : "CA", dijit.byId("setvaluetest").get("value"), "state1 value");
 						doh.is("not fired yet!", dojo.byId("oc1").value, "state1 onChange hasn't fired");
 
 						// Test that dojo.query() finds hidden field, see #8660
@@ -194,6 +185,7 @@
 					}
 				}
 			);
+
 			var comboIds=['setvaluetest','datatest','combo3','combobox4','arrowless','descending'];
 			for(var i=0; i<comboIds.length; i++){
 				doh.register("query input by name",{
@@ -217,6 +209,11 @@
 					runTest:function(){
 						var d = new doh.Deferred(),
 							combo = dijit.byId("setvaluetest");
+						
+						var dv, v;	
+						combo.watch("displayedValue", function(name, oldVal, newVal){ dv = newVal; });
+						combo.watch("value", function(name, oldVal, newVal){ v = newVal; });
+
 						combo.set('displayedValue', 'Kentucky');
 						doh.robot.sequence(d.getTestCallback(function(){
 							var oc1=dojo.byId('oc1');
@@ -225,6 +222,8 @@
 							if(!isComboBox){
 								doh.t(combo.isValid(), "isValid()");
 							}
+							doh.is(isComboBox ? "Kentucky" : "KY", v, "watch of value")
+							doh.is("Kentucky", dv, "watch of displayedValue")
 						}), 900);
 						return d;
 					}
@@ -274,7 +273,7 @@
 					}
 				}
 
-				// TODO: test some other get("value") calls
+				// TODO: test some other set("value") calls
 			]);
 
 			doh.register("direct input", [
@@ -284,7 +283,7 @@
 					name:"valid value",
 					combo:"setvaluetest",
 					runTest:function(){
-						return robot_typeValue(dijit.byId(this.combo), "California", isComboBox? undefined : "CA", isComboBox? undefined : "California (CA)");
+						return robot_typeValue(dijit.byId(this.combo), "California", isComboBox? undefined : "CA", isComboBox? undefined : "California");
 					}
 				},
 
@@ -294,7 +293,25 @@
 					name:"invalid value",
 					combo:"setvaluetest",
 					runTest:function(){
-						return (dojo.hitch(this, errorTest))();
+						return robot_typeValue((this.combo = dijit.byId(this.combo)), "zxcxarax", isComboBox?"zxcxarax":"");
+					}
+				},
+				
+				// Check on the invalid value from the previous test
+				{
+					timeout:60000,
+					name:"invalid value 2",
+					combo:"setvaluetest",
+					runTest:function(){
+						this.combo = dijit.byId(this.combo);
+						if(isComboBox){
+							doh.is("zxcxarax", this.combo.get("value"), "Expected value of zxcxarax, got "+this.combo.get("value")+", text is:"+this.combo.focusNode.value);
+							doh.t(this.combo.isValid(), "Bad value not permitted in ComboBox. Value is: "+this.combo.get("value")+", text is:"+this.combo.focusNode.value);
+						}else{
+							doh.is("", this.combo.get("value"), "Expected value of '', got "+this.combo.get("value")+", text is:"+this.combo.focusNode.value);
+							doh.t(!this.combo.isValid(), "Bad value permitted in FilteringSelect. Value is: "+this.combo.get("value")+", text is:"+this.combo.focusNode.value);
+						}
+						doh.t(!this.combo.itemError, "Should not have an itemError");
 					},
 					tearDown:function(){
 						this.combo.set("value", isComboBox?"Alaska":"AK");
@@ -302,6 +319,48 @@
 				}
 			]);
 
+			// Test that enter key submits the form, but only when the drop down is closed
+			doh.register("enter key", {
+				timeout:60000,
+				name:"submit",
+				runTest:function(){
+					dojo.global.formSubmitted = false;
+					var d = new doh.Deferred();
+					var combo = dijit.byId("setvaluetest");	
+					combo.focus();
+
+					// Initial conditions:
+					doh.robot.sequence(d.getTestErrback(function(){
+						var popup = dijit.byId('setvaluetest_popup');
+						doh.t(!popup || isHidden(popup), "popup hidden");
+					}), 500);
+
+					// Down arrow opens the drop down
+					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+					doh.robot.sequence(d.getTestErrback(function(){
+						var popup = dijit.byId('setvaluetest_popup');
+						doh.t(popup && isVisible(popup), "popup visible");
+					}), 500);
+
+					// Enter key should select value and close drop down but not submit form
+					doh.robot.keyPress(dojo.keys.ENTER, 500);
+					doh.robot.sequence(d.getTestErrback(function(){
+						var popup = dijit.byId('setvaluetest_popup');
+						doh.t(!popup || isHidden(popup), "popup hidden");
+						doh.f(dojo.global.formSubmitted, "form not submitted yet")
+					}), 500);
+
+					// Enter key again should submit form
+					doh.robot.keyPress(dojo.keys.ENTER, 500);
+					doh.robot.sequence(d.getTestCallback(function(){
+						var popup = dijit.byId('setvaluetest_popup');
+						doh.t(!popup || isHidden(popup), "popup hidden");
+						doh.t(dojo.global.formSubmitted, "form submitted")
+					}), 500);
+
+					return d;
+				}
+			});
 
 			doh.register("drop down navigation / keyboard", [
 				// Select a value from the drop down using the keyboard,
@@ -311,7 +370,7 @@
 					name:"setvaluetest_a11y",
 					combo:"setvaluetest",
 					runTest:function(){
-						return robot_a11ySelectValue(dijit.byId(this.combo), "Texas", isComboBox? "Texas (TX)" : "TX", "Texas (TX)");
+						return robot_a11ySelectValue(dijit.byId(this.combo), "Texas", isComboBox? "Texas" : "TX", "Texas");
 					}
 				}
 			]);
@@ -529,6 +588,7 @@
 					runTest: function(){
 						var d = new doh.Deferred();
 						var combo = dijit.byId("slow");
+						combo.set('displayedValue', null, false);
 
 						combo.focusNode.focus();
 						// this test is very timing-sensitive
@@ -558,14 +618,14 @@
 							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");
-						}), 1000);
+						}), 1000, 500);
 
 						return d;
 					}
 				},
 
 				// Test that drop down doesn't show up after ENTER keypress, and also that
-				// searchDelay is preventing intemediate queries.
+				// searchDelay is preventing intermediate queries.
 				{
 					timeout:60000,
 					name:"pressing enter before search returns",
@@ -576,6 +636,7 @@
 						var d = new doh.Deferred();
 						var combo = dijit.byId("slow");
 
+						dojo.global.formSubmitted = false;
 						combo.focusNode.focus();
 						doh.robot.sequence(function(){ combo.set("value", null); }, 1000, 100); // wait for focus
 
@@ -593,7 +654,12 @@
 								doh.is(6, len, "query was issued for 'Co' but canceled");
 								doh.is("cancel ", log[1].type + " " + log[1].query.name);
 								doh.is("cancel Co*", log[3].type + " " + log[3].query.name);
+								doh.is("start Co", log[4].type + " " + log[4].query.name);	// trying to lookup ID for item named "co"
 								doh.is("end Co", log[5].type + " " + log[5].query.name);
+								
+								// also, form should not have submitted because the FilteringSelect
+								// is still trying to fill in it's item value
+								doh.f(dojo.global.formSubmitted, "form not submitted");
 							}else{ // this will look more like the IF block above once #6022 is committed
 								doh.is(2, len, "query was issued for 'Co' but canceled");
 								doh.is("cancel Co*", log[1].type + " " + log[1].query.name);
@@ -603,7 +669,7 @@
 							doh.t(!list || isHidden(list), "drop down is *not* visible");
 
 							doh.is("Co", combo.get('displayedValue'), "auto-complete didn't fire");
-						}), 2000);
+						}), 1200, 500);
 
 						return d;
 					}
@@ -728,14 +794,14 @@
 				}
 			]);
 
+			// Labelfunc tests.   See also initial tests on "setvaluetest" ComboBox.
 			doh.register("labelFunc", [
 				{
 					timeout:60000,
-					name:"labelFunc_a11y",
+					name:"labelFunc_keyboardSelect",
 					combo:"labelFunc",
 					runTest:function(){
-						// labelFunc makes Texas texas
-						return robot_a11ySelectValue((this.combo = dijit.byId(this.combo)), "Texas", isComboBox? "texas" : "TX", "texas");
+						return robot_a11ySelectValue((this.combo = dijit.byId(this.combo)), "texas", isComboBox? "Texas" : "TX", "Texas");
 					},
 					tearDown:function(){
 						this.combo.set("value", isComboBox? "Texas" : "TX");
@@ -747,7 +813,36 @@
 					name:"labelFunc_type",
 					combo:"labelFunc",
 					runTest:function(){
-						var d = robot_typeValue((this.combo = dijit.byId(this.combo)), "Alabama", isComboBox? "alabama" : "AL", "alabama");
+						var d = robot_typeValue((this.combo = dijit.byId(this.combo)), "Alabama", isComboBox? "Alabama" : "AL", "Alabama");
+						return d;
+					}
+				},
+
+				{
+					timeout:60000,
+					name: "richtext",
+					runTest: function(){
+						var d = new doh.Deferred(),
+							w = dijit.byId("richtexttest");
+
+						// testing that input has right data
+						doh.is("h1", w.focusNode.value, "initial focus value");
+						w.set("value", "h2");
+						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(){
+							var list = dojo.byId("richtexttest_popup");
+							doh.t(list, "drop down exists");
+							doh.t(isVisible(list), "drop down is visible");
+
+							var entries = dojo.query("li", list).filter(isVisible);
+							doh.is("<h1>h1</h1>", dojo.trim(entries[0].innerHTML).toLowerCase(), "list #1 is rich text");
+						}), 500);
+
 						return d;
 					}
 				}
@@ -866,10 +961,10 @@
 						// Show list, should be in reverse order
 						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
 						for(var i=0; i < 14; i++){
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200); // down arrow and wrap twice
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 250); // down arrow and wrap twice
 						}
 						for(i=0; i < 4; i++){
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 200); // up arrow and wrap at most once
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 250); // up arrow and wrap at most once
 						}
 						doh.robot.keyPress(dojo.keys.ENTER, 500); // select current item
 						doh.robot.sequence(d.getTestCallback(function(){
@@ -892,7 +987,7 @@
 						// Show list, should be in reverse order
 						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
 						for(var i=0; i < 14; i++){
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200); // down arrow and wrap twice
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 250); // down arrow and wrap twice
 						}
 						for(i=0; i < 5; i++){
 							doh.robot.keyPress(dojo.keys.UP_ARROW, 200); // up arrow and wrap at most once
@@ -920,7 +1015,7 @@
 						// Show list, should be in reverse order
 						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);
 						for(var i=0; i < 5; i++){
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 200); // down arrow to More choices
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 250); // down arrow to More choices
 						}
 						doh.robot.keyPress(dojo.keys.ENTER, 500); // select More choices
 						doh.robot.keyPress(dojo.keys.UP_ARROW, 1000); // up arrow to Previous choices
@@ -934,6 +1029,360 @@
 				}
 			]);
 
+			var pageSize, combo;
+			// Test more choices
+			doh.register("Select More choices", [
+				{
+					timeout:10000,
+					name:"no auto-complete",
+					setUp: function(){
+						combo = dijit.byId("setvaluetest");
+						pageSize = combo.get('pageSize');
+						combo.set('pageSize', 1);
+						combo.set('displayedValue', null, false);
+						combo.focusNode.focus();
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						// select more choices and press Enter
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1500); // open dropdown
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // select Alabama
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // select more choices
+						doh.robot.keyPress(dojo.keys.ENTER, 500);
+
+						doh.robot.sequence(d.getTestCallback(function(){
+							// Check that drop down list has disappeared
+							var list = dojo.byId("setvaluetest_popup");
+							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");
+
+							// Since the user down arrowed thru the choices, the value should be the current selection
+							doh.is('Alaska', combo.focusNode.value);
+							if(!isComboBox){
+								doh.t(combo.isValid(true), "FilteringSelect should be valid");
+							}
+						}), 1000, 500);
+
+						return d;
+					},
+					tearDown: function(){
+						combo.set('pageSize', pageSize);
+						combo.closeDropDown();
+					}
+				},
+				{
+					timeout:10000,
+					name:"auto-complete",
+					setUp: function(){
+						combo = dijit.byId("datatest");
+						pageSize = combo.get('pageSize');
+						combo.set('pageSize', 1);
+						combo.set('displayedValue', null, false);
+						combo.focusNode.focus();
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						// select more choices and press Enter
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1500); // open dropdown
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // select Alabama
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500); // select more choices
+						doh.robot.keyPress(dojo.keys.ENTER, 500);
+
+						doh.robot.sequence(d.getTestCallback(function(){
+							// Check that drop down list has disappeared
+							var list = dojo.byId("datatest_popup");
+							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");
+
+							// Since the user down arrowed thru the choices, the value should be the current selection
+							doh.is('Alaska', combo.focusNode.value);
+							if(!isComboBox){
+								doh.t(combo.isValid(true), "FilteringSelect should be valid");
+							}
+						}), 1000, 500);
+
+						return d;
+					},
+					tearDown: function(){
+						combo.set('pageSize', pageSize);
+						combo.closeDropDown();
+					}
+				}
+			]);
+
+			doh.register("onChange", [
+				{
+					timeout:6000,
+					name:"11062",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(){
+							status = "called";
+						});
+						combo.focusNode.focus();
+						doh.robot.keyPress(dojo.keys.TAB, 500); // blur
+
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							doh.is("not called", status, "onChange should not have been called");
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.0",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value = isComboBox ? 'Kentucky' : 'KY';
+						combo._lastValueReported = combo._lastValue = value;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value, true);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("not called", status, "onChange should not have been called");
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.1",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value1 = isComboBox ? 'Kentucky' : 'KY';
+						var value2 = isComboBox ? 'Texas' : 'TX';
+						combo._lastValueReported = combo._lastValue = value1;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value2, false);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("not called", status, "onChange should not have been called");
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.2",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value1 = isComboBox ? 'Kentucky' : 'KY';
+						var value2 = isComboBox ? 'Texas' : 'TX';
+						combo._lastValueReported = combo._lastValue = value2;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value1, false);
+						combo.set('value', value2);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("called with "+value2, status, "onChange should have been called with "+value2);
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.3",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value1 = isComboBox ? 'Kentucky' : 'KY';
+						var value2 = isComboBox ? 'Texas' : 'TX';
+						combo._lastValueReported = combo._lastValue = value2;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value1, false);
+						combo.set('value', value2, false);
+						combo.set('value', value2, true);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("called with "+value2, status, "onChange should have been called with "+value2);
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.4",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value = isComboBox ? 'Kentucky' : 'KY';
+						combo._lastValueReported = combo._lastValue = value;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value, false);
+						combo.set('value', value, true);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("not called", status, "onChange should not have been called");
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.5",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value1 = isComboBox ? 'Kentucky' : 'KY';
+						var value2 = isComboBox ? 'Texas' : 'TX';
+						combo._lastValueReported = combo._lastValue = value2;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value1, false);
+						combo.set('value', value2, true);
+						combo.set('value', value1, false);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("called with "+value2, status, "onChange should have been called with "+value2);
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.6",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value1 = isComboBox ? 'Kentucky' : 'KY';
+						var value2 = isComboBox ? 'Texas' : 'TX';
+						combo._lastValueReported = combo._lastValue = value1;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value2, true);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("called with "+value2, status, "onChange should have been called with true"+value2);
+						}), 500);
+						return d;
+					}
+				},
+				{
+					timeout:2000,
+					name:"10988.7",
+					runTest:function(){
+						var d = new doh.Deferred();
+						var combo = dijit.byId("progCombo");
+						var value1 = isComboBox ? 'Kentucky' : 'KY';
+						var value2 = isComboBox ? 'Texas' : 'TX';
+						combo._lastValueReported = combo._lastValue = value2;
+						var status = "not called";
+						var connectHandle = combo.connect(combo, "onChange", function(v){
+							status = "called with " + v;
+						});
+						combo.set('value', value1, false);
+						combo.set('value', value1, true);
+						doh.robot.sequence(d.getTestCallback(function(){
+							combo.disconnect(connectHandle);
+							combo._pendingOnChange = false;
+							doh.is("called with "+value1, status, "onChange should have been called with "+value1);
+						}), 500);
+						return d;
+					}
+				}
+			]);
+
+			doh.register("destroy", [
+				{
+					timeout: 1000,
+					name: "destroy",
+					runTest: function(){
+						var d = new doh.Deferred();
+						doh.robot.sequence(d.getTestCallback(function(){
+							dijit.byId("combo_01").destroy();
+							doh.is(undefined, dojo.byId("combo_01"), 'widget was removed');
+							doh.f(dojo.byId('destroyDiv').firstChild, 'container node is empty');
+						}), 0);
+						return d;
+					}
+				}
+			]);
+
+			dojo.forEach(
+				[
+					{ attrs: { ignoreCase:true,  highlightMatch:"first", queryExpr:"${0}*"  }, results: { AA: "<>A<>A", Aa: "<>A<>a", aA: "<>a<>A", aa: "<>a<>a" } },
+					{ attrs: { ignoreCase:false, highlightMatch:"first", queryExpr:"${0}*"  }, results: { aA: "<>a<>A", aa: "<>a<>a" } },
+					{ attrs: { ignoreCase:true,  highlightMatch:"all",   queryExpr:"${0}*"  }, results: { AA: "<>A<>A", Aa: "<>A<>a", aA: "<>a<>A", aa: "<>a<>a" } },
+					{ attrs: { ignoreCase:true,  highlightMatch:"all",   queryExpr:"*${0}*" }, results: { AA: "<>A<><>A<>", Aa: "<>A<><>a<>", aA: "<>a<><>A<>", aa: "<>a<><>a<>" } },
+					{ attrs: { ignoreCase:false, highlightMatch:"all",   queryExpr:"*${0}*" }, results: { Aa: "A<>a<>", aA: "<>a<>A", aa: "<>a<><>a<>" } },
+					{ attrs: { ignoreCase:false, highlightMatch:"none",  queryExpr:"*${0}*" }, results: { Aa: "Aa", aA: "aA", aa: "aa" } },
+					{ attrs: { ignoreCase:true,  highlightMatch:"all",   queryExpr:"*${0}"  }, results: { AA: "A<>A<>", Aa: "A<>a<>", aA: "a<>A<>", aa: "a<>a<>" } },
+					{ attrs: { ignoreCase:false, highlightMatch:"first", queryExpr:"*${0}"  }, results: { Aa: "A<>a<>", aa: "a<>a<>" } }
+				], function(test){
+					doh.register("highlight", [
+						{
+							timeout: 6000,
+							name: dojo.toJson(test.attrs),
+							setUp: function(){
+								combo = dijit.byId("highlight");
+								dojo.mixin(combo, test.attrs);
+								combo.focusNode.focus();
+							},
+							runTest: function(){
+								var d = new doh.Deferred();
+								doh.robot.keyPress(dojo.keys.BACKSPACE, 1000);
+								doh.robot.typeKeys("a", 1, 100);
+								doh.robot.sequence(d.getTestCallback(function(){
+									dojo.forEach(["AA","Aa","aA","aa"], function(idx){
+										var item = findMenuItem(combo, idx);
+										if(idx in test.results){
+											var expected = test.results[idx];
+											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);
+										}
+									});
+								}), 1000, 500);
+								return d;
+							},
+							tearDown: function(){
+								combo.closeDropDown();
+							}
+						}
+					]);
+				}
+			);
+
 			doh.run();
 		});
 	</script>
diff --git a/dijit/tests/form/robot/_autoComplete_mouse.html b/dijit/tests/form/robot/_autoComplete_mouse.html
index e9fcf66..b5c0e32 100644
--- a/dijit/tests/form/robot/_autoComplete_mouse.html
+++ b/dijit/tests/form/robot/_autoComplete_mouse.html
@@ -30,6 +30,15 @@
 		}
 		isComboBox = testWidget=="dijit.form.ComboBox";
 		dojo.addOnLoad(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){
+					node = node.nextSibling;
+				}
+				return node;
+			}
 
 			doh.robot.initRobot('../_autoComplete.html?testWidget='+testWidget);
 
@@ -62,88 +71,90 @@
 					runTest:function(){
 						var d = new doh.Deferred();
 
-						var combo = dijit.byId("setvaluetest");
+						combo = dijit.byId("setvaluetest");
 
 						// Open drop down
-						doh.robot.mouseMoveAt(combo.downArrowNode, 500, 500);
+						doh.robot.mouseMoveAt(combo._buttonNode, 0, 0);
 						doh.robot.mouseClick({left:true}, 500);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							var list = dojo.byId("setvaluetest_popup"),
+							var list = combo.dropDown.domNode,
 								entries = dojo.query("li", list).filter(isVisible);
 							doh.t(isVisible(list), "list is visible");
 							doh.is(31, entries.length, "30 elements plus next button");
-						}), 1000, 500);
+							doh.is("California", combo.focusNode.value, "displayed value hasn't changed");
+						}), 1500, 100);
 
 						return d;
 					}
 				},
 
 				{
-					timeout:6000,
+					timeout:9000,
 					name:"next page",
 					runTest:function(){
 						var d = new doh.Deferred();
 
-						var list = dojo.byId("setvaluetest_popup"),
-							moreEntriesButton = dojo.query(":last-child", list)[0];
+						combo = dijit.byId("setvaluetest");
+						var list = combo.dropDown.domNode;
 
 						doh.t(isVisible(list), "list is still visible");
-						doh.t(moreEntriesButton, "found more entries button");
 
-						doh.robot.mouseMoveAt(moreEntriesButton, 500, 500);
-						doh.robot.mouseClick({left:true}, 500);
+						dojo.window.scrollIntoView(combo.dropDown.nextButton);
+						doh.robot.mouseMoveAt(combo.dropDown.nextButton, 1, 0);
+						doh.robot.mouseClick({left:true}, 1000);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							var list = dojo.byId("setvaluetest_popup"),
-								entries = dojo.query("li", list).filter(isVisible);
-								doh.is("Minnesota (MN)", innerText(entries[1]));
-						}), 1000, 500);
+							var entries = dojo.query("li", 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);
 
 						return d;
 					}
 				},
 
 				{
-					timeout:6000,
+					timeout:9000,
 					name:"last page",
 					runTest:function(){
 						var d = new doh.Deferred();
 
-						var moreEntriesButton = dojo.query(":last-child", dojo.byId("setvaluetest_popup"))[0];
-
-						doh.robot.mouseMoveAt(moreEntriesButton, 500, 500);
-						doh.robot.mouseClick({left:true}, 500);
+						combo = dijit.byId("setvaluetest");
+						dojo.window.scrollIntoView(combo.dropDown.nextButton);
+						doh.robot.mouseMoveAt(combo.dropDown.nextButton, 1, 0);
+						doh.robot.mouseClick({left:true}, 1000);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							var list = dojo.byId("setvaluetest_popup"),
+							var list = combo.dropDown.domNode,
 								entries = dojo.query("li", list).filter(isVisible);
-								doh.is(2, entries.length, "previous choices + wyoming");
-								doh.is("Wyoming (WY)", innerText(entries[1]));
-						}), 1000, 500);
+							doh.is(2, entries.length, "previous choices + wyoming");
+							doh.is("Wyoming (WY)", innerText(entries[1]));
+						}), 1500, 1000);
 
 						return d;
 					}
 				},
 
 				{
-					timeout:6000,
+					timeout:9000,
 					name:"previous page",
 					runTest:function(){
 						var d = new doh.Deferred();
 
-						var previousEntriesButton = dojo.query(":first-child", dojo.byId("setvaluetest_popup"))[0];
-
-						doh.robot.mouseMoveAt(previousEntriesButton, 500, 500);
-						doh.robot.mouseClick({left:true}, 500);
+						combo = dijit.byId("setvaluetest");
+						dojo.window.scrollIntoView(combo.dropDown.previousButton);
+						doh.robot.mouseMoveAt(combo.dropDown.previousButton, 0, 0);
+						doh.robot.mouseClick({left:true}, 1000);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							var list = dojo.byId("setvaluetest_popup"),
+							var list = combo.dropDown.domNode,
 								entries = dojo.query("li", 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]));
-						}), 1000, 500);
+							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]));
+							doh.is("California", combo.focusNode.value, "displayed value hasn't changed");
+						}), 1500, 1000);
 
 						return d;
 					}
@@ -155,18 +166,18 @@
 					runTest:function(){
 						var d = new doh.Deferred();
 
-						var list = dojo.byId("setvaluetest_popup"),
-							entries = dojo.query("li", list),
-							nj = entries[8];
+						combo = dijit.byId("setvaluetest");
+						var nj = findMenuItem(combo, "New Jersey (NJ)");
+						dojo.window.scrollIntoView(nj);
 
-						doh.robot.mouseMoveAt(nj, 500, 500);
+						doh.robot.mouseMoveAt(function(){ return nj }, 500, 0);
 						doh.robot.mouseClick({left:true}, 500);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is(isComboBox ? "New Jersey (NJ)" : "NJ", dijit.byId("setvaluetest").get("value"),
+							doh.is(isComboBox ? "New Jersey" : "NJ", dijit.byId("setvaluetest").get("value"),
 								"selected New Jersey from drop down");
 							var count = dijit.byId("setvaluetest").labelFuncCounts['NJ'];
-							doh.is(4, count, "custom labelFunc was called " + count + " times (expected 4)");
+							doh.is(2, count, "# custom labelFunc calls");
 						}), 1000, 500);
 
 						return d;
@@ -179,19 +190,19 @@
 					runTest:function(){
 						var d = new doh.Deferred();
 
-						var combo = dijit.byId("setvaluetest");
+						combo = dijit.byId("setvaluetest");
 						// focus combo
-						doh.robot.mouseMoveAt(combo.focusNode, 500, 500);
+						doh.robot.mouseMoveAt(combo.focusNode, 500, 0);
 						doh.robot.mouseClick({left:true}, 500);
 						// blur
-						doh.robot.mouseMoveAt('sv1_4', 500, 500);
+						doh.robot.mouseMoveAt('sv1_4', 500, 0);
 						doh.robot.mouseClick({left:true}, 500);
 
 						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is(isComboBox ? "New Jersey (NJ)" : "NJ", dijit.byId("setvaluetest").get("value"),
+							doh.is(isComboBox ? "New Jersey" : "NJ", dijit.byId("setvaluetest").get("value"),
 								"New Jersey still set after blur");
 							var count = dijit.byId("setvaluetest").labelFuncCounts['NJ'];
-							doh.is(4, count, "custom labelFunc was called " + count + " times (expected 4, unchanged after blur)");
+							doh.is(2, count, "# custom labelFunc calls unchanged after blur");
 						}), 1000, 500);
 
 						return d;
@@ -200,16 +211,135 @@
 			]);
 
 
+			// For back-compat with 1.0 need to report click events, even clicks on the button
+			// (which by default is stopped in _HasDropDown)
+			// Remove for 2.0.
+			doh.register("onClick", [
+				{
+					timeout: 5000,
+					name: "click on button",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						combo = dijit.byId("setvaluetest");
+						handle = 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);
+
+						doh.robot.mouseMoveAt(combo._buttonNode, 1000, 0);
+						doh.robot.mouseClick({left:true}, 500);
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handle);
+						combo.closeDropDown();
+					}
+				},
+				{
+					timeout: 5000,
+					name: "click on input",
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						combo = dijit.byId("setvaluetest");
+						handle = 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);
+
+						doh.robot.mouseMoveAt(combo.focusNode, 1000, 0);
+						doh.robot.mouseClick({left:true}, 500);
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handle);
+						combo.closeDropDown();
+					}
+				}
+			]);
+
+			// Test clicking more choices / previous choices buttons doesn't affect value in <input> area
+			doh.register("auto-complete", [
+				{
+					timeout:10000,
+					name:"open drop down",
+					setUp: function(){
+						combo = dijit.byId("datatest");
+						pageSize = combo.get('pageSize');
+						combo.set('pageSize', 1);
+						combo.set('displayedValue', null, false);
+					},
+					runTest: function(){
+						var d = new doh.Deferred();
+						handle = dojo.connect(combo, "openDropDown", function(){
+							setTimeout(d.getTestCallback(function(){
+								var list = combo.dropDown.domNode;
+								doh.t(list && isVisible(list), "drop down is visible");
+	
+								// Clicking "more choices" shouldn't change value in ComboBox
+								doh.is('Alabama', combo.focusNode.value, "focus value");
+								if(!isComboBox){
+									doh.t(combo.isValid(true), "FilteringSelect should be valid");
+								}
+							}), 0);
+						});
+
+						doh.robot.mouseMoveAt(combo.focusNode, 500, 0);
+						doh.robot.mouseClick({left:true}, 500);
+
+						doh.robot.typeKeys("a", 1500); // will open dropdown
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handle);
+					}
+				},
+				{
+					timeout:10000,
+					name:"click more choices",
+					runTest: function(){
+						var d = new doh.Deferred();
+						handle = dojo.connect(combo, "openDropDown", function(){
+							setTimeout(d.getTestCallback(function(){
+								var list = combo.dropDown.domNode;
+								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");
+							}), 0);
+						});
+
+						doh.robot.mouseMoveAt(combo.dropDown.nextButton, 1000, 0); // move to More choices
+						doh.robot.mouseClick({left:true}, 1000);	// will display new drop down
+					
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(handle);
+						combo.set('pageSize', pageSize);
+						combo.closeDropDown();
+					}
+				}
+			]);
+
 			// disabled tests+standard tests
 			doh.register("disabled", [
 				{
 					timeout:6000,
 					name: "focus by mouse",
 					runTest:function(){
-						var d = new doh.Deferred(),
-							combo = dijit.byId("combo3");
+						var d = new doh.Deferred();
+						combo = dijit.byId("combo3");
 
-						doh.robot.mouseMoveAt(combo.focusNode, 500, 500);
+						doh.robot.mouseMoveAt(combo.focusNode, 500, 0);
 						doh.robot.mouseClick({left:true}, 500);
 
 						doh.robot.sequence(d.getTestCallback(function(){
@@ -225,16 +355,16 @@
 					timeout:6000,
 					name:"dropdown button",
 					runTest:function(){
-						var d = new doh.Deferred(),
-							combo = dijit.byId("combo3");
+						var d = new doh.Deferred();
+						combo = dijit.byId("combo3");
 
 						// Press Arrow Button
-						doh.robot.mouseMoveAt(combo.downArrowNode, 500, 500);
+						doh.robot.mouseMoveAt(combo._buttonNode, 500, 0);
 						doh.robot.mouseClick({left:true}, 500);
 
 						// Assert that nothing happened
 						doh.robot.sequence(d.getTestCallback(function(){
-							doh.f(combo._popupWidget, "User was able to open the menu on a disabled ComboBox!");
+							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");
@@ -244,20 +374,20 @@
 				}
 			]);
 
-			doh.register("9898", [
+			doh.register("#9898", [
 				{
 					timeout: 9000,
 					name: "firefox mouse problem",
 					combo: "labelFunc",
 					handle: null,
 					setUp: function(){
-						this.combo = dijit.byId(this.combo);
+						combo = dijit.byId(this.combo);
 					},
 					runTest: function(){ // very hard to hit due to timing
 						var d = new doh.Deferred();
 						dojo.byId("native").scrollIntoView(false); // force to bottom of screen
 						// jump through hoops to increase the odds of hitting the problem
-						handle = this.combo.connect(this.combo, 'open', // when this.open() is called, set up 1 time event handlers
+						handle = combo.connect(combo, 'loadDropDown', // when drop down is about to be displayed, set up 1 time event handlers
 							function(){
 								var popup = dijit.byId("labelFunc_popup"); // combobox results
 								var old = dojo.global.dojo._setMarginBox; // menu is about to be shrunk to fit the viewport, so stop this
@@ -276,34 +406,34 @@
 								}), 1000, 500);
 							}
 						);
-						doh.robot.mouseMoveAt(this.combo.downArrowNode, 1000, 500);
+						doh.robot.mouseMoveAt(combo._buttonNode, 1000, 0);
 						doh.robot.mousePress({left:true}, 500) // mousedown on the arrow image
 
 						return d;
 					},
 					tearDown: function(){
-						this.combo.disconnect(handle);
-						this.combo._hideResultList();
+						combo.disconnect(handle);
+						combo.closeDropDown();
 					}
 				}
 			]);
 
-			doh.register("10431", [
+			doh.register("#10431", [
 				{
 					timeout: 9000,
 					name: "untouched blank value and required",
 					combo: "japanese",
 					setUp: function(){
-						this.combo = dijit.byId(this.combo);
+						combo = dijit.byId(this.combo);
 					},
 					runTest: function(){
-						doh.is("", this.combo.get("value"), "value");
-						doh.is("", this.combo.get('displayedValue'), "displayedValue");
-						doh.f(this.combo.isValid(), "isValid");
-						doh.is("", this.combo.state, "state");
+						doh.is("", combo.get("value"), "value");
+						doh.is("", combo.get('displayedValue'), "displayedValue");
+						doh.f(combo.isValid(), "isValid");
+						doh.is("Incomplete", combo.state, "state");
 					},
 					tearDown: function(){
-						this.combo._hideResultList();
+						combo.closeDropDown();
 					}
 				},
 				{
@@ -311,56 +441,61 @@
 					name: "blurred blank value and required",
 					combo: "japanese",
 					setUp: function(){
-						this.combo = dijit.byId(this.combo);
+						combo = dijit.byId(this.combo);
 					},
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.robot.mouseMoveAt(this.combo.focusNode, 500, 500);
+						doh.robot.mouseMoveAt(combo.focusNode, 500, 0);
 						doh.robot.mouseClick({left:true}, 500);
 						doh.robot.keyPress(dojo.keys.TAB, 1000);
 
 						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-							doh.is("", this.combo.get("value"), "value");
-							doh.is("", this.combo.get('displayedValue'), "displayedValue");
-							doh.f(this.combo.isValid(), "isValid");
-							doh.is("Error", this.combo.state, "state");
+							doh.is("", combo.get("value"), "value");
+							doh.is("", combo.get('displayedValue'), "displayedValue");
+							doh.f(combo.isValid(), "isValid");
+							doh.is("Error", combo.state, "state");
 						})), 1000, 500);
 						return d;
 					},
 					tearDown: function(){
-						this.combo._hideResultList();
+						combo.closeDropDown();
 					}
 				}
 			]);
 			
 			doh.register("placeHolder", [
 				{
-					timeout: 3000,
+					timeout: 6000,
 					name: "focus/blur",
 					combo: "placeholdertest",
 					setUp: function(){
-						this.combo = dijit.byId(this.combo);
+						combo = dijit.byId(this.combo);
 					},
 					runTest: function(){
 						var d = new doh.Deferred();
-						doh.is("", this.combo.get("value"), "value");
-						doh.is("", this.combo.get('displayedValue'), "displayedValue");
-						doh.is("Select a New England State", this.combo._phspan.innerHTML, "_phspan.innerHTML");
-						doh.isNot("none", this.combo._phspan.style.display, "_phspan.style.display");
+						doh.is("", combo.get("value"), "value");
+						doh.is("", combo.get('displayedValue'), "displayedValue");
+						doh.is("Select a New England State", combo._phspan.innerHTML, "_phspan.innerHTML");
+						doh.isNot("none", combo._phspan.style.display, "_phspan.style.display 1");
 
-						this.combo.focus();
-						doh.is("none", this.combo._phspan.style.display, "_phspan.style.display");
+						doh.robot.mouseMoveAt(combo.focusNode, 0, 0);
+						doh.robot.mouseClick({left:true}, 500);
+
+						doh.robot.sequence(d.getTestErrback(function(){
+							doh.is("none", combo._phspan.style.display, "_phspan.style.display 2");
 						
-						doh.robot.keyPress(dojo.keys.TAB, 500, {});
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this,function(){
-							doh.is("", this.combo.get("value"), "value");
-							doh.is("", this.combo.get('displayedValue'), "displayedValue");
-							doh.isNot("none", this.combo._phspan.style.display, "_phspan.style.display");
-						})), 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("", combo.get("value"), "value");
+								doh.is("", combo.get('displayedValue'), "displayedValue");
+								doh.isNot("none", combo._phspan.style.display, "_phspan.style.display 3");
+							}), 1000, 500);
+						}), 1500, 500);
 						return d;
 					},
 					tearDown: function(){
-						this.combo._hideResultList();
+						combo.closeDropDown();
 					}
 				},
 				{
@@ -368,30 +503,36 @@
 					name: "select a value",
 					combo: "placeholdertest",
 					setUp: function(){
-						this.combo = dijit.byId(this.combo);
+						combo = dijit.byId(this.combo);
 					},
 					runTest: function(){
 						var d = new doh.Deferred(), value = isComboBox?'Connecticut':'ct';
-						this.combo.set("value",value);
-						doh.is(value, this.combo.get("value"), "selected Connecticut from drop down");
+						combo.set("value", value);
+						doh.is(value, combo.get("value"), "selected Connecticut from drop down");
 
-						this.combo.focus();
-						doh.is("none", this.combo._phspan.style.display, "_phspan.style.display 1");
+						doh.robot.mouseMoveAt(combo.focusNode, 500, 0);
+						doh.robot.mouseClick({left:true}, 500);
+
+						doh.robot.sequence(d.getTestErrback(function(){
+							doh.is("none", combo._phspan.style.display, "_phspan.style.display 1");
 						
-						doh.robot.keyPress(dojo.keys.TAB, 500, {});
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this,function(){
-							doh.is(value, this.combo.get("value"), "value");
-							doh.is("none", this.combo._phspan.style.display, "_phspan.style.display 2");
-							doh.is('Connecticut', this.combo.textbox.value, "textbox.value 2");
-						})), 500);
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(value, combo.get("value"), "value");
+								doh.is("none", combo._phspan.style.display, "_phspan.style.display 2");
+								doh.is('Connecticut', combo.textbox.value, "textbox.value 2");
+							}), 1000, 500);
+						}), 1000, 500);
 						return d;
 					},
 					tearDown: function(){
-						this.combo._hideResultList();
+						combo.closeDropDown();
 					}
 				}
 			]);
 
+
 			doh.run();
 		});
 	</script>
diff --git a/dijit/tests/form/robot/test_validate.html b/dijit/tests/form/robot/test_validate.html
deleted file mode 100644
index 085b320..0000000
--- a/dijit/tests/form/robot/test_validate.html
+++ /dev/null
@@ -1,1113 +0,0 @@
-<!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>doh.robot Validation 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">
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../test_validate.html');
-
-				// Test initial conditions
-				doh.register("initial conditions", {
-					name: "initial conditions",
-					runTest: function(){
-						var form1 = dojo.byId("form1");
-						
-						doh.is("Testing Testing", form1.firstname.value, "firstname");
-						doh.is("not fired yet!", dojo.byId("oc1").value, "firstname onchange");
-
-						doh.is("TESTING TESTING", form1.lastname.value, "lastname");
-						
-						doh.is("", form1.age.value, "age");
-						doh.is("not fired yet!", dojo.byId("oc3").value, "age onchange");
-						
-						doh.is("", form1.occupation.value, "occupation");
-						
-						doh.is("3000", form1.elevation.value, "elevation");
-						doh.is("3,000", dojo.byId("q05").value, "elevation display value");
-						doh.is("not fired yet!", dojo.byId("oc5").value, "elevation onchange");
-						
-						doh.is("54775.53", form1.income1.value, "income1");
-						doh.is("$54,775.53", dojo.byId("q08").value, "income1 display value");
-						doh.is("not fired yet!", dojo.byId("oc8").value, "income1 onchange");
-
-						doh.is("54775.53", form1.income2.value, "income2");
-						doh.is("€54,775.53", dojo.byId("q08eur").value, "income2 display value");
-
-						doh.is("someTestString", form1.phone.value, "phone");
-						doh.is("", form1.password.value, "password");
-						doh.is("", form1.ticket1651.value, "ticket1651");
-						doh.is("cannot type here", form1.readOnly.value, "readonly");
-						doh.is("cannot type here", form1.disabled.value, "disabled");
-					}
-				});
-
-				var _setvaluetest = function(textbox, setVal, focusVal, attrVal, isValid, chgVal, required){
-					textbox = dijit.byId(textbox);
-					if(required !== undefined){
-						textbox.set('required', required);
-					}
-					textbox.set('value', setVal);
-					doh.is(focusVal, textbox.focusNode.value, "focusNode.value");
-					doh.is(attrVal, textbox.get('value'), "get('value')");
-					doh.is(typeof attrVal, typeof textbox.get('value'), "typeof get('value')");
-					doh.is(isValid, textbox.isValid(), "isValid()");
-					var d = new doh.Deferred();
-					var onChange = dojo.byId('oc3');
-					doh.robot.sequence(d.getTestCallback(function(){
-						doh.is(chgVal.toString(), onChange.value, "onChange.value");
-					}), 500);
-					return d;
-				};
-
-				doh.register("setvaluetest", [
-					{
-						name: "valid_max",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', 120, 120, 120, true, 120); }
-					},
-
-					{
-						name: "out_of_range_max",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', 121, 121, 121, false, 121); }
-					},
-
-					{
-						name: "valid_min",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', 0, 0, 0, true, 0); }
-					},
-
-					{
-						name: "out_of_range_min",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', -1, -1, -1, false, -1); }
-					},
-
-					{
-						name: "invalid",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', 'two', 'two', undefined, false, 'undefined'); }
-					},
-
-					{
-						name: "null_required",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', null, '', NaN, false, NaN, true); }
-					},
-
-					{
-						name: "null_notrequired",
-						timeout: 1000,
-						runTest: function(){ return _setvaluetest('q03', null, '', NaN, true, NaN, false); }
-					}
-				]);
-
-				doh.register("intermediatechanges", {
-					name: "valid",
-					textbox: "q01",
-					timeout: 60000,
-					setUp: function(){
-						this.textbox = dijit.byId(this.textbox);
-						this.textbox.set('value', '');
-						this.textbox.focusNode.focus();
-					},
-					runTest: function(){
-						var d = new doh.Deferred();
-						var onChange = dojo.byId('oc1');
-						doh.robot.typeKeys('Testing', 1000, 1400);
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-							// test that value changed while typing since intermediateChanges = true
-							doh.is('Testing', this.textbox.focusNode.value, "focusNode value");
-							doh.is('Testing', this.textbox.get('value'), "attr value");
-							doh.is('Testing', onChange.value, "onChange.value");
-						})), 1000);
-						return d;
-					}
-				});
-
-				doh.register("allcaps", {
-					name: "valid",
-					textbox: "q02",
-					timeout: 60000,
-					setUp: function(){
-						this.textbox = dijit.byId(this.textbox);
-						this.textbox.set('value', '');
-						this.textbox.focusNode.focus();
-					},
-					runTest: function(){
-						var d = new doh.Deferred();
-						doh.robot.typeKeys('Testing', 1000, 1400);
-						doh.robot.sequence(function(){
-							dojo.byId("q01").focus();
-						}, 500);
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-							doh.is('TESTING', this.textbox.focusNode.value, "focusNode.value");
-							doh.is('TESTING', this.textbox.get('value'), "get('value')");
-						})), 1000);
-						return d;
-					}
-				});
-
-				doh.register("maxlength", [
-					{
-						name: "3chars",
-						textbox: "fav",
-						timeout: 60000,
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							doh.robot.typeKeys('100', 1000, 600);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								// test that value changed while typing since intermediateChanges = true
-								doh.is('100', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(100, this.textbox.get('value'), "get('value')");
-							})), 1000);
-							return d;
-						}
-					},
-
-					{
-						name: "4chars",
-						textbox: "fav",
-						timeout: 60000,
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							doh.robot.typeKeys('1001', 1000, 800);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								// test that value changed while typing since intermediateChanges = true
-								doh.is('100', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(100, this.textbox.get('value'), "get('value')");
-								doh.robot.typeKeys('1', 500, 200);
-								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-									doh.is('100', this.textbox.focusNode.value, "focusNode.value");
-									doh.is(100, this.textbox.get('value'), "get('value')");
-								})), 500);
-							})), 1000);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("errorStyle", [
-					{
-						name: "beforeClick",
-						textbox: "q04",
-						runTest: function(){
-							this.textbox = dijit.byId(this.textbox);
-							doh.is('', this.textbox.get('state'));
-							doh.is(false, this.textbox.isValid(), "isValid()");
-						}
-					},
-
-					{
-						name: "afterClick",
-						textbox: "q04",
-						timeout: 60000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							this.textbox = dijit.byId(this.textbox);
-							doh.robot.sequence(dojo.hitch(this, function(){
-								this.textbox.focusNode.focus();
-							}), 500);
-							doh.robot.sequence(dojo.hitch(this, function(){
-								dojo.byId("q01").focus();
-							}), 1000);	// time for promptMessage to appear on q04 (IE6 takes a while due to iframe)
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('Error', this.textbox.get('state'));
-								doh.is(false, this.textbox.isValid(), "isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-
-					{
-						name: "valid",
-						textbox: "q04",
-						timeout: 60000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.focusNode.focus();
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is('Error', this.textbox.get('state'));
-								doh.is(false, this.textbox.isValid(), "isValid()");
-								doh.robot.typeKeys('a', 500, 200);
-								doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-									doh.is('a', this.textbox.get('value'), "get('value')");
-									doh.is('', this.textbox.get('state'), "state 1");
-									doh.is(true, this.textbox.isValid(), "isValid() 1");
-									dojo.byId("q01").focus();
-									doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-										doh.is('', this.textbox.get('state'), "state 2");
-										doh.is(true, this.textbox.isValid(), "isValid() 2");
-									})), 1000);
-								})), 500);
-							})), 1000);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("commaformat", [
-					{
-						name: "beforeClick",
-						textbox: "q05",
-						runTest: function(){
-							this.textbox = dijit.byId(this.textbox);
-							doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
-							doh.is('3000', this.textbox.get('value'), "get('value')");
-							doh.is(true, this.textbox.isValid(), "isValid()");
-						}
-					},
-
-					{
-						name: "click",
-						timeout: 60000,
-						textbox: "q05",
-						runTest: function(){
-							var d = new doh.Deferred();
-							this.textbox = dijit.byId(this.textbox);
-							var onChange = dojo.byId('oc5');
-							doh.robot.sequence(dojo.hitch(this, function(){
-								this.textbox.focusNode.focus();
-							}), 500);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								// comma should disappear on click, value shouldn't change
-								doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('3000', this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-								doh.is('not fired yet!', onChange.value);
-							})), 500);
-							return d;
-						}
-					},
-
-					{
-						name: "type_valid_nocomma",
-						timeout: 60000,
-						textbox: "q05",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc5');
-							doh.robot.typeKeys('3000', 1000, 800);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is('3000', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('3000', this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-								doh.is('NaN', onChange.value);
-								dojo.byId("q01").focus();
-								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-									doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
-									doh.is('3000', this.textbox.get('value'), "get('value')");
-									doh.is(true, this.textbox.isValid(), "isValid()");
-									doh.is('3000', onChange.value);
-								})), 1000);
-							})), 1000);
-							return d;
-						}
-					},
-
-					{
-						name: "type_valid_comma",
-						timeout: 60000,
-						textbox: "q05",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc5');
-							doh.robot.typeKeys('3,000', 1000, 1000);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('3000', this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-								doh.is('NaN', onChange.value);
-								dojo.byId("q01").focus();
-								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-									doh.is('3,000', this.textbox.focusNode.value, "focusNode.value");
-									doh.is('3000', this.textbox.get('value'), "get('value')");
-									doh.is(true, this.textbox.isValid(), "isValid()");
-									doh.is('3000', onChange.value);
-								})), 1000);
-							})), 1000);
-							return d;
-						}
-					},
-
-					{
-						name: "type_invalid_comma",
-						timeout: 60000,
-						textbox: "q05",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc5');
-							doh.robot.typeKeys('300,0', 1000, 1000);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is('300,0', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(undefined, this.textbox.get('value'), "get('value')");
-								doh.is(false, this.textbox.isValid(), "isValid()");
-								doh.is('NaN', onChange.value);
-								dojo.byId("q01").focus();
-								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-									doh.is('300,0', this.textbox.focusNode.value, "focusNode.value");
-									doh.is(undefined, this.textbox.get('value'), "get('value')");
-									doh.is(false, this.textbox.isValid(), "isValid()");
-									doh.is('undefined', onChange.value);
-								})), 1000);
-							})), 1000);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("currencyFormat", [
-					{
-						name: "beforeClick",
-						textbox: "q08",
-						runTest: function(){
-							this.textbox = dijit.byId(this.textbox);
-							doh.is('$54,775.53', this.textbox.focusNode.value, "focusNode.value");
-							doh.is('54775.53', this.textbox.get('value'), "get('value')");
-							doh.is(true, this.textbox.isValid(), "isValid()");
-						}
-					},
-
-					{
-						name: "click",
-						timeout: 60000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								// comma should disappear on click, value shouldn't change
-								doh.is('54775.53', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('54775.53', this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-								doh.is('not fired yet!', onChange.value);
-							})), 500);
-							return d;
-						}
-					},
-
-					{
-						name: "type_valid_number",
-						timeout: 60000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('10000.01', 1000, 1600);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is('10000.01', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('10000.01', this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-								doh.is('NaN', onChange.value);
-								dojo.byId("q01").focus();
-								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-									doh.is('$10,000.01', this.textbox.focusNode.value, "focusNode.value");
-									doh.is('10000.01', this.textbox.get('value'), "get('value')");
-									doh.is(true, this.textbox.isValid(), "isValid()");
-									doh.is('10000.01', onChange.value);
-								})), 1000);
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "type_valid_dollarsign",
-						timeout: 60000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('$20000.01', 1000, 1800);
-							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
-								doh.is('$20000.01', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(20000.01, this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-								doh.is('NaN', onChange.value);
-								dojo.byId("q01").focus();
-								doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-									doh.is('$20,000.01', this.textbox.focusNode.value, "focusNode.value");
-									doh.is(20000.01, this.textbox.get('value'), "get('value')");
-									doh.is(true, this.textbox.isValid(), "isValid()");
-									doh.is('20000.01', onChange.value);
-								})), 1000);
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "missing required decimal",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('123', 1000, 600);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('123', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(undefined, this.textbox.get('value'), "get('value')");
-								doh.f(this.textbox.isValid(), "!isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "too few decimal digits",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('123.0', 1000, 1000);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('123.0', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(undefined, this.textbox.get('value'), "get('value')");
-								doh.f(this.textbox.isValid(), "!isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "too many decimal digits",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('123.000', 1000, 1400);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('123.000', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(undefined, this.textbox.get('value'), "get('value')");
-								doh.f(this.textbox.isValid(), "!isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "negative decimal",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('-123.00', 1000, 1400);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('-123.00', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(-123, this.textbox.get('value'), "get('value')");
-								doh.t(this.textbox.isValid(), "isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "negative currency",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('($123.00)', 1000, 1600);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('($123.00)', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(-123, this.textbox.get('value'), "get('value')");
-								doh.t(this.textbox.isValid(), "isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "convert negative decimal to negative currency",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('-123.45', 1000, 1400);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('($123.45)', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(-123.45, this.textbox.get('value'), "get('value')");
-								doh.t(this.textbox.isValid(), "isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "convert negative negative currency to negative decimal",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('($123.45)', 1000, 1800);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('-123.45', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(-123.45, this.textbox.get('value'), "get('value')");
-								doh.t(this.textbox.isValid(), "isValid()");
-							})), 1000);
-							return d;
-						}
-					},
-					{
-						name: "exponent not allowed",
-						timeout: 6000,
-						textbox: "q08",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							var onChange = dojo.byId('oc8');
-							doh.robot.typeKeys('1.23e0', 1000, 1200);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('1.23e0', this.textbox.focusNode.value, "focusNode.value");
-								doh.is(undefined, this.textbox.get('value'), "get('value')");
-								doh.f(this.textbox.isValid(), "!isValid()");
-							})), 1000);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("euroformat", {
-					name: "type_1",
-					timeout: 60000,
-					textbox: "q08eur",
-					setUp: function(){
-						this.textbox = dijit.byId(this.textbox);
-						this.textbox.set('value', '');
-						this.textbox.focusNode.focus();
-					},
-					runTest: function(){
-						var d = new doh.Deferred();
-						doh.robot.typeKeys('1', 1000, 200);
-						doh.robot.sequence(dojo.hitch(this, function(){
-							dijit.byId('q01').focusNode.focus();
-						}), 500);
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-							doh.is('€1.00', this.textbox.focusNode.value, "focusNode.value");
-							doh.is('1', this.textbox.get('value'), "get('value')");
-							doh.is(true, this.textbox.isValid(), "isValid()");
-						})), 1000);
-						return d;
-					}
-				});
-
-				doh.register("regexp", [
-					{
-						name: "valid",
-						timeout: 60000,
-						textbox: "q22",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							doh.robot.typeKeys('a', 1000, 200);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('a', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('a', this.textbox.get('value'), "get('value')");
-								doh.is(true, this.textbox.isValid(), "isValid()");
-							})), 500);
-							return d;
-						}
-					},
-
-					{
-						name: "invalid",
-						timeout: 60000,
-						textbox: "q22",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							doh.robot.typeKeys('a ', 1000, 400);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('a ', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('a ', this.textbox.get('value'), "get('value')");
-								doh.is(false, this.textbox.isValid(), "isValid()");
-							})), 500);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("password", {
-					name: "type",
-					timeout: 60000,
-					textbox: "q23",
-					setUp: function(){
-						this.textbox = dijit.byId(this.textbox);
-						this.textbox.set('value', '');
-						this.textbox.focusNode.focus();
-					},
-					runTest: function(){
-						var d = new doh.Deferred();
-						doh.robot.typeKeys('abcdef', 1000, 1200);
-						doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-							doh.is('abcdef', this.textbox.focusNode.value, "focusNode.value");
-							doh.is('abcdef', this.textbox.get('value'), "get('value')");
-						})), 1000);
-						return d;
-					}
-				});
-
-				doh.register("readonly", [
-					{
-						name: "readonly",
-						timeout: 60000,
-						textbox: "q24",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							dojo.byId("mname").focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Tab into element (readonly *can* be focused, although disabled can't)
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift: true});
-
-							// typing on a disabled element should have no effect
-							doh.robot.typeKeys('abc', 500, 600);
-
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('cannot type here', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('cannot type here', this.textbox.get('value'), "get('value')");
-							})), 1000);
-							return d;
-						}
-					},
-
-					{
-						name: "write",
-						timeout: 60000,
-						textbox: "q24",
-						setUp: function(){
-							this.textbox = dijit.byId(this.textbox);
-							this.textbox.set('value', '');
-							this.textbox.set('readOnly', false);
-							this.textbox.focusNode.focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-							doh.robot.typeKeys('abc', 1000, 600);
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is('abc', this.textbox.focusNode.value, "focusNode.value");
-								doh.is('abc', this.textbox.get('value'), "get('value')");
-							})), 1000);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("disabled", [
-					{
-						name: "click doesn't focus",
-						timeout: 60000,
-						setUp: function(){
-							var textbox = dijit.byId("q24");
-							dojo.byId("mname").focus();
-							textbox.set('disabled', true);
-						},
-						runTest: function(){
-							var d = new doh.Deferred(),
-								textbox = dijit.byId("q24");
-
-							//  Clicking shouldn't have any effect since it's disabled
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500);
-							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");
-							})), 500);
-							return d;
-						}
-					},
-
-					{
-						name: "tab jumps over",
-						timeout: 60000,
-
-						setUp: function(){
-							var textbox = dijit.byId("q24");
-							dojo.byId("mname").focus();
-							textbox.set('disabled', true);
-						},
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.keyPress(dojo.keys.TAB, 500);
-
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("q26", dojo.global.dijit._curFocus.id,
-										"tabbed past input, to the button after it");
-							})), 500);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("selectOnClick", [
-					{
-						name: "1 click does highlight",
-						timeout: 9000,
-						setUp: function(){
-							dijit.byId("q02").focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred(),
-								textbox = dijit.byId("q01");
-
-							textbox.set('value', 'Testing');
-							//  Clicking shouldn't have any effect since it's disabled
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.typeKeys("abc", 1000, 600);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Abc", textbox.get('value'), "was highlighted");
-							}), 500);
-							return d;
-						}
-					},
-					{
-						name: "2 clicks doesn't highlight",
-						timeout: 9000,
-						setUp: function(){
-							dijit.byId("q02").focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred(),
-								textbox = dijit.byId("q01");
-
-							textbox.set('value', 'Testing');
-							//  Clicking shouldn't have any effect since it's disabled
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							var oldValue = textbox.get('value');
-							doh.robot.typeKeys("abc", 500, 600);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.isNot(oldValue, textbox.get('value'), "didn't change at all");
-								doh.isNot("Abc", textbox.get('value'), "was highlighted");
-							}), 500);
-							return d;
-						}
-					},
-					{
-						name: "TAB focus still highlights a selectOnFocus textbox",
-						timeout: 9000,
-						setUp: function(){
-							dijit.byId("q02").focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred(),
-								textbox = dijit.byId("q01");
-
-							textbox.set('value', 'Testing');
-							//  Clicking shouldn't have any effect since it's disabled
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.keyPress(dojo.keys.TAB, 1000);
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
-							doh.robot.typeKeys("abc", 500, 600);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("Abc", textbox.get('value'), "was not highlighted");
-							}), 500);
-							return d;
-						}
-					},
-					{
-						name: "click doesn't highlight after TAB focus",
-						timeout: 9000,
-						setUp: function(){
-							dijit.byId("q02").focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred(),
-								textbox = dijit.byId("q01");
-
-							textbox.set('value', 'Testing');
-							//  Clicking shouldn't have any effect since it's disabled
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.keyPress(dojo.keys.TAB, 1000);
-							doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
-							doh.robot.mouseClick({left: true}, 1000);
-							var oldValue = textbox.get('value');
-							doh.robot.typeKeys("abc", 500, 600);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.isNot(oldValue, textbox.get('value'), "didn't change at all");
-								doh.isNot("Abc", textbox.get('value'), "was highlighted");
-							}), 500);
-							return d;
-						}
-					},
-					{
-						name: "mouse selection still works",
-						timeout: 9000,
-						setUp: function(){
-							dijit.byId("q02").focus();
-						},
-						runTest: function(){
-							var d = new doh.Deferred(),
-								textbox = dijit.byId("q01");
-
-							textbox.set('value', 'MMMMMMM');
-							//  Clicking shouldn't have any effect since it's disabled
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500, 3, 6);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(textbox.focusNode, 500, 500, 10, 6);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.typeKeys("abc", 500, 600);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("AbcMMMMMM", textbox.get('value'), "could not select text");
-							}), 500);
-							return d;
-						}
-					}
-				]);
-
-				doh.register("set constraints", [
-					{
-						name: "number",
-						timeout: 6000,
-						runTest: function(){
-							var textWidget = dijit.byId("q05");
-							textWidget.set('value', 12345);
-							doh.is("12,345", textWidget.get('displayedValue'), "default value");
-							textWidget.set('constraints', {places:2});
-							doh.is("12,345.00", textWidget.get('displayedValue'), "decimal value");
-						}
-					},
-					{
-						name: "currency",
-						timeout: 6000,
-						runTest: function(){
-							var textWidget = dijit.byId("q08eurde");
-							textWidget.set('value', 12345.25);
-							doh.is("12.345,25\xa0€", textWidget.get('displayedValue'), "EUR value");
-							textWidget.set('constraints', {currency:'USD', locale:'en-us'});
-							doh.is("$12,345.25", textWidget.get('displayedValue'), "USD value");
-						}
-					}
-				]);
-				
-				doh.register("placeholder", [
-					{
-						name: "textbox",
-						runTest: function(){
-							var textWidget = dijit.byId("q26");
-							doh.is('', textWidget.get('value'),'initial value is empty');
-							doh.is('placeholder is here', textWidget._phspan.innerHTML, '_phspan.innerHTML');
-							textWidget.set('value','abc');
-							doh.is('abc', textWidget.get('value'));
-							textWidget.set('placeHolder','new placholder');
-							doh.is('abc', textWidget.get('value'));
-							textWidget.set('value','');
-							doh.is('new placholder', textWidget._phspan.innerHTML, '_phspan.innerHTML 1');
-							doh.is('', textWidget.get('value'));
-						}
-					},
-					{
-						name: "focus/blur textbox",
-						timeout: 6000,
-						runTest: function(){
-							var d = new doh.Deferred(), textWidget = dijit.byId("q26");
-							textWidget.set('placeHolder','placeholder is here');
-							textWidget.set('value','');
-							
-							//  Clicking into the input should hide _phspan
-							doh.robot.mouseMoveAt(textWidget.focusNode, 500, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("", textWidget.get('value'), "get('value')");
-								doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
-								
-								doh.robot.keyPress(dojo.keys.TAB, 500, {shift:true});
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is("", textWidget.get('value'), "get('value')");
-									doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display 1");
-								}), 1000);
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "type in textbox",
-						timeout: 6000,
-						runTest: function(){
-							var d = new doh.Deferred(), textWidget = dijit.byId("q26");
-							textWidget.set('placeHolder','placeholder is here');
-							textWidget.set('value','');
-							
-							//  Clicking into the input should hide _phspan
-							doh.robot.mouseMoveAt(textWidget.focusNode, 500, 500);
-							doh.robot.mouseClick({left: true}, 500);
-							
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("", textWidget.get('value'), "get('value')");
-								doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 1");
-								
-								doh.robot.typeKeys('new', 0, 600);
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is("new", textWidget.get('value'), "get('value')");
-									doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 2");
-								}), 500);
-							}), 1000);
-							return d;
-						}
-					},
-					{
-						name: "reset textbox",
-						timeout: 6000,
-						runTest: function(){
-							var textWidget = dijit.byId("q26"), d = new doh.Deferred();
-							textWidget.focus();
-							textWidget.set('placeHolder','placeholder is here');
-							textWidget.set('value','');
-							
-							doh.is("", textWidget.get('value'), "get('value') 1");
-							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
-							
-							textWidget.set('value','abc');
-							textWidget.reset();
-							
-							doh.is("", textWidget.get('value'), "get('value') 2");
-							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display 1");
-							
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.sequence(function(){
-								textWidget.set('value','xyz');
-								textWidget.reset();
-							}, 1000, 1000);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("", textWidget.get('value'), "get('value')");
-								doh.isNot("none", textWidget._phspan.style.display, "_phspan.style.display 2");
-							}), 500);
-							
-							return d;
-						}
-					},
-					{
-						name: "set textbox value",
-						runTest: function(){
-							var textWidget = dijit.byId("q26");
-							textWidget.set('placeHolder','placeholder is here');
-							textWidget.set('value','value');
-							doh.is("none", textWidget._phspan.style.display, "_phspan.style.display");
-						}
-					}
-				]);
-
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/form/robot/validationMessages.html b/dijit/tests/form/robot/validationMessages.html
index 65c7035..cd9c504 100644
--- a/dijit/tests/form/robot/validationMessages.html
+++ b/dijit/tests/form/robot/validationMessages.html
@@ -1,20 +1,19 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 	<head>
-		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Validation Message Test</title>
 
 		<style>
-			@import "../../../../dojo/resources/dojo.css";
+			@import "../../../themes/claro/document.css";
 			@import "../../css/dijitTests.css";
 			@import "../../../../util/doh/robot/robot.css";
 		</style>
-		<link id="themeStyles" rel="stylesheet" href="../../../themes/tundra/tundra.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../themes/dijit.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.form.NumberTextBox");
@@ -22,6 +21,19 @@
 
 			dojo.addOnLoad(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 = ""; });
+
+			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);
+					});
+			}
+
 			dojo.forEach([false, true], function(rangeBound){
 				dojo.forEach([false, true], function(required){
 					dojo.forEach(["", "p"], function(promptMessage){
@@ -29,22 +41,23 @@
 							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);
+
 								doh.register(name, [
 								{
 									name: name + " first focus, empty value",
 									timeout: 5000,
+									setUp:function(){
+										textbox.focusNode.scrollIntoView();
+									},
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.mouseMoveAt(textbox.focusNode, 0, 1000);
-										doh.robot.mouseClick({left: true}, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('mouseup', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 1000);
-
+											doh.is(required ? "Incomplete" : "", textbox.state, "state");
+											doh.is(promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.mouseMoveAt(textbox.focusNode, 0, 1);
+										doh.robot.mouseClick({left: true}, 0);
 										return d;
 									}
 								},
@@ -53,15 +66,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.typeKeys("1", 200, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(!rangeBound, textbox.isValid(false), "isValid");
-											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is(rangeBound ? "Incomplete" : "", textbox.state, "state");
+											doh.is(rangeBound? promptMessage : "", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("1", 0, 0);
 										return d;
 									}
 								},
@@ -70,15 +80,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.typeKeys("2", 200, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(true, textbox.isValid(false), "isValid");
 											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("2", 0, 0);
 										return d;
 									}
 								},
@@ -87,15 +94,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.typeKeys("a", 200, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(false, textbox.isValid(false), "isValid");
 											doh.is("Error", textbox.state, "state");
-											doh.is(invalidMessage||promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is(invalidMessage||promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("a", 0, 0);
 										return d;
 									}
 								},
@@ -104,15 +108,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.BACKSPACE, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(true, textbox.isValid(false), "isValid");
 											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
 										return d;
 									}
 								},
@@ -121,15 +122,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.BACKSPACE, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(!rangeBound, textbox.isValid(false), "isValid");
-											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is(rangeBound ? "Incomplete" : "", textbox.state, "state");
+											doh.is(rangeBound? promptMessage : "", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
 										return d;
 									}
 								},
@@ -138,15 +136,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.BACKSPACE, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is(required ? "Incomplete" : "", textbox.state, "state");
+											doh.is(promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
 										return d;
 									}
 								},
@@ -155,15 +150,13 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.TAB, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('blur', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is(!required, !textbox.state, "state");
-											doh.is("", textbox._message, "tooltip");
-										}), 500);
-
+											doh.is(required ? "Error" : "", textbox.state, "state");
+											doh.is("", tooltip, "no tooltip");
+											doh.is(required? (missingMessage||invalidMessage||promptMessage) : promptMessage, textbox.message, "message");
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 0);
 										return d;
 									}
 								},
@@ -172,15 +165,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.TAB, 200, { shift:true });
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('focus', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is(!required, !textbox.state, "state");
-											doh.is(required? (missingMessage||invalidMessage||promptMessage) : promptMessage, textbox._message, "tooltip");
-										}), 500);
-
+											doh.is(required ? "Error" : "", textbox.state, "state");
+											doh.is(required? (missingMessage||invalidMessage||promptMessage) : promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 0, { shift:true });
 										return d;
 									}
 								},
@@ -189,15 +179,25 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.typeKeys("1", 200, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(!rangeBound, textbox.isValid(false), "isValid");
+											doh.is(rangeBound ? "Incomplete" : "", textbox.state, "state");
+											doh.is(rangeBound? promptMessage : "", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("1", 0, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " 2nd valid character after refocus",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
 											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is("", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("2", 0, 0);
 										return d;
 									}
 								},
@@ -206,16 +206,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.typeKeys("2", 200, 200);
-										doh.robot.typeKeys("3", 200, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
 											doh.is(!rangeBound, textbox.isValid(false), "isValid");
-											doh.is(!rangeBound, !textbox.state, "state");
-											doh.is(rangeBound? textbox.rangeMessage : promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is(rangeBound ? "Error" : "", textbox.state, "state");
+											doh.is(rangeBound? textbox.rangeMessage : "", tooltip, "tooltip");
+										});
+										doh.robot.typeKeys("3", 0, 0);
 										return d;
 									}
 								},
@@ -224,15 +220,13 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.TAB, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('blur', textbox, d, function(){
 											doh.is(!rangeBound, textbox.isValid(false), "isValid");
-											doh.is(!rangeBound, !textbox.state, "state");
-											doh.is("", textbox._message, "tooltip");
-										}), 500);
-
+											doh.is(rangeBound ? "Error" : "", textbox.state, "state");
+											doh.is("", tooltip, "no tooltip");
+											doh.is(rangeBound? textbox.rangeMessage : "", textbox.message, "message");
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 0);
 										return d;
 									}
 								},
@@ -241,55 +235,73 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.TAB, 200, { shift:true });
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('focus', textbox, d, function(){
 											doh.is(!rangeBound, textbox.isValid(false), "isValid");
-											doh.is(!rangeBound, !textbox.state, "state");
-											doh.is(rangeBound? textbox.rangeMessage : promptMessage, textbox._message, "tooltip");
-										}), 500);
-
+											doh.is(rangeBound ? "Error" : "", textbox.state, "state");
+											doh.is(rangeBound? textbox.rangeMessage : "", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 0, { shift:true });
 										return d;
 									}
 								},
 								{
-									name: name + " delete out of range character",
+									name: name + " position input caret to end",
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
+										testOn('keyup', textbox, d, function(){
+											doh.is(!rangeBound, textbox.isValid(false), "isValid");
+											doh.is(rangeBound ? "Error" : "", textbox.state, "state");
+											doh.is(rangeBound? textbox.rangeMessage : "", tooltip, "tooltip");
+										});
 										if(dojo.isMac){
-											doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 200, {meta:true});
+											doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 0, {meta:true});
+											doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 0); // trigger keyup
 										}else{
-											doh.robot.keyPress(dojo.keys.END, 200);
+											doh.robot.keyPress(dojo.keys.END, 0);
 										}
-										doh.robot.keyPress(dojo.keys.BACKSPACE, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										return d;
+									}
+								},
+								{
+									name: name + " delete out of range character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
 											doh.is(true, textbox.isValid(false), "isValid");
 											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
+											doh.is("", tooltip, "tooltip");
 
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
 										return d;
 									}
 								},
 								{
-									name: name + " delete remaining characters",
+									name: name + " delete last in-range character",
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.BACKSPACE, 200);
-										doh.robot.keyPress(dojo.keys.BACKSPACE, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('keyup', textbox, d, function(){
+											doh.is(rangeBound ? "Incomplete" : "", textbox.state, "state");
+											doh.is(rangeBound? promptMessage : "", tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
+										return d;
+									}
+								},
+								{
+									name: name + " delete remaining character",
+									timeout: 2000,
+									runTest: function(){
+										var d = new doh.Deferred();
+										testOn('keyup', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is("", textbox.state, "state");
-											doh.is(promptMessage, textbox._message, "tooltip");
-										}), 200);
-
+											doh.is(required ? "Incomplete" : "", textbox.state, "state");
+											doh.is(promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.BACKSPACE, 0);
 										return d;
 									}
 								},
@@ -298,15 +310,13 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.TAB, 200);
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('blur', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is(!required, !textbox.state, "state");
-											doh.is("", textbox._message, "tooltip");
-										}), 500);
-
+											doh.is(required ? "Error" : "", textbox.state, "state");
+											doh.is("", tooltip, "no tooltip");
+											doh.is(required? (missingMessage||invalidMessage||promptMessage) : promptMessage, textbox.message, "message");
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 0);
 										return d;
 									}
 								},
@@ -315,15 +325,12 @@
 									timeout: 2000,
 									runTest: function(){
 										var d = new doh.Deferred();
-
-										doh.robot.keyPress(dojo.keys.TAB, 200, { shift:true });
-
-										doh.robot.sequence(d.getTestCallback(function(){
+										testOn('focus', textbox, d, function(){
 											doh.is(!required, textbox.isValid(false), "isValid");
-											doh.is(!required, !textbox.state, "state");
-											doh.is(required? (missingMessage||invalidMessage||promptMessage) : promptMessage, textbox._message, "tooltip");
-										}), 500, 1000);
-
+											doh.is(required ? "Error" : "", textbox.state, "state");
+											doh.is(required? (missingMessage||invalidMessage||promptMessage) : promptMessage, tooltip, "tooltip");
+										});
+										doh.robot.keyPress(dojo.keys.TAB, 0, { shift:true });
 										return d;
 									}
 								}]);
@@ -337,134 +344,135 @@
 			});
 		</script>
 	</head>
-	<body class="claro">
+	<body>
 		<label for="t00000">not required, no min/max, no prompt message, no invalid message, no missing message</label><br>
-		<input  id="t00000" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00000"><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>
 
 		<label for="t00001">not required, no min/max, no prompt message, no invalid message, missing message</label><br>
-		<input  id="t00001" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00001"><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>
 
 		<label for="t00010">not required, no min/max, no prompt message, invalid message, no missing message</label><br>
-		<input  id="t00010" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00010"><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>
 
 		<label for="t00011">not required, no min/max, no prompt message, invalid message, missing message</label><br>
-		<input  id="t00011" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00011"><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>
 
 		<label for="t00100">not required, no min/max, prompt message, no invalid message, no missing message</label><br>
-		<input  id="t00100" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="p" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00100"><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>
 
 		<label for="t00101">not required, no min/max, prompt message, no invalid message, missing message</label><br>
-		<input  id="t00101" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="p" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00101"><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>
 
 		<label for="t00110">not required, no min/max, prompt message, invalid message, no missing message</label><br>
-		<input  id="t00110" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="p" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00110"><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>
 
 		<label for="t00111">not required, no min/max, prompt message, invalid message, missing message</label><br>
-		<input  id="t00111" dojoType="dijit.form.NumberTextBox" required="false" promptMessage="p" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t00111"><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>
 
 		<label for="t01000">required, no min/max, no prompt message, no invalid message, no missing message</label><br>
-		<input  id="t01000" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01000"><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>
 
 		<label for="t01001">required, no min/max, no prompt message, no invalid message, missing message</label><br>
-		<input  id="t01001" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01001"><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>
 
 		<label for="t01010">required, no min/max, no prompt message, invalid message, no missing message</label><br>
-		<input  id="t01010" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01010"><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>
 
 		<label for="t01011">required, no min/max, no prompt message, invalid message, missing message</label><br>
-		<input  id="t01011" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01011"><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>
 
 		<label for="t01100">required, no min/max, prompt message, no invalid message, no missing message</label><br>
-		<input  id="t01100" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="p" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01100"><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>
 
 		<label for="t01101">required, no min/max, prompt message, no invalid message, missing message</label><br>
-		<input  id="t01101" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="p" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01101"><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>
 
 		<label for="t01110">required, no min/max, prompt message, invalid message, no missing message</label><br>
-		<input  id="t01110" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="p" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01110"><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>
 
 		<label for="t01111">required, no min/max, prompt message, invalid message, missing message</label><br>
-		<input  id="t01111" dojoType="dijit.form.NumberTextBox" required="true" promptMessage="p" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t01111"><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>
 
 		<label for="t10000">not required, min=10, max=100, no prompt message, no invalid message, no missing message</label><br>
-		<input  id="t10000" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10000"><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>
 
 		<label for="t10001">not required, min=10, max=100, no prompt message, no invalid message, missing message</label><br>
-		<input  id="t10001" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10001"><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>
 
 		<label for="t10010">not required, min=10, max=100, no prompt message, invalid message, no missing message</label><br>
-		<input  id="t10010" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10010"><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>
 
 		<label for="t10011">not required, min=10, max=100, no prompt message, invalid message, missing message</label><br>
-		<input  id="t10011" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10011"><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>
 
 		<label for="t10100">not required, min=10, max=100, prompt message, no invalid message, no missing message</label><br>
-		<input  id="t10100" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="p" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10100"><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>
 
 		<label for="t10101">not required, min=10, max=100, prompt message, no invalid message, missing message</label><br>
-		<input  id="t10101" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="p" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10101"><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>
 
 		<label for="t10110">not required, min=10, max=100, prompt message, invalid message, no missing message</label><br>
-		<input  id="t10110" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="p" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10110"><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>
 
 		<label for="t10111">not required, min=10, max=100, prompt message, invalid message, missing message</label><br>
-		<input  id="t10111" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="false" promptMessage="p" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t10111"><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>
 
 		<label for="t11000">required, min=10, max=100, no prompt message, no invalid message, no missing message</label><br>
-		<input  id="t11000" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11000"><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>
 
 		<label for="t11001">required, min=10, max=100, no prompt message, no invalid message, missing message</label><br>
-		<input  id="t11001" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11001"><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>
 
 		<label for="t11010">required, min=10, max=100, no prompt message, invalid message, no missing message</label><br>
-		<input  id="t11010" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11010"><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>
 
 		<label for="t11011">required, min=10, max=100, no prompt message, invalid message, missing message</label><br>
-		<input  id="t11011" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11011"><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>
 
 		<label for="t11100">required, min=10, max=100, prompt message, no invalid message, no missing message</label><br>
-		<input  id="t11100" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="p" invalidMessage="" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11100"><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>
 
 		<label for="t11101">required, min=10, max=100, prompt message, no invalid message, missing message</label><br>
-		<input  id="t11101" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="p" invalidMessage="" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11101"><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>
 
 		<label for="t11110">required, min=10, max=100, prompt message, invalid message, no missing message</label><br>
-		<input  id="t11110" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="p" invalidMessage="i" missingMessage="" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11110"><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>
 
 		<label for="t11111">required, min=10, max=100, prompt message, invalid message, missing message</label><br>
-		<input  id="t11111" dojoType="dijit.form.NumberTextBox" constraints="{min:10, max:100}" required="true" promptMessage="p" invalidMessage="i" missingMessage="m" rangeMessage="r" value="">
-		<input style="border:0px;" size="6" value="t11111"><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>
 
 	</body>
 </html>
+
diff --git a/dijit/tests/form/test_Button.html b/dijit/tests/form/test_Button.html
index 151dcfb..c791ea1 100644
--- a/dijit/tests/form/test_Button.html
+++ b/dijit/tests/form/test_Button.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo Button Widget Test</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 
 			/* group multiple buttons in a row */
@@ -13,17 +13,40 @@
 				display: block;
 				text-align: center;
 			}
+			BUTTON, INPUT,
 			.box .dijit {
 				margin-right: 10px;
+				vertical-align: middle;
+			}
+			.acmeButton .dijitButtonNode {
+				background: rgb(96,96,96) !important;
+				color: white !important;
+				padding: 10px !important;
+				font-size: x-large !important;
+				padding-top: 10px !important;
+				padding-bottom: 10px !important;
+				border: 2px inset rgb(96,96,96);
+			}
+			.acmeButtonHover .dijitButtonNode {
+				background-color: rgb(89,94,111) !important;
+				color: cyan !important;
+			}
+			.acmeButtonFocused .dijitButtonNode {
+				border: yellow inset 2px;
+			}
+			.acmeButtonActive .dijitButtonNode {
+				background-color: white !important;
+				color: black !important;
+				border: 2px solid black !important;
 			}
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -47,225 +70,204 @@
 	</p>
 	<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 id="1465" dojoType="dijit.form.Button" onClick='console.log("clicked simple");' iconClass="plusIcon" value="Create">
+		<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"'>
 			Create
 		</button>
-		<span dojoType="dijit.Tooltip" connectId="1465">tooltip on button</span>
-		<button id="1467" dojoType="dijit.form.Button" title="view title" onClick='console.log("clicked simple")'>
+		<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>
-		<span dojoType="dijit.Tooltip" connectId="1466">tooltip on button</span>
-		<button dojoType="dijit.form.ComboButton" id="comboCreate" optionsTitle='save options' onClick='console.log("clicked combo save")'
-				iconClass="plusIcon" title="creative title">
+		<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"'>
 			<span>Create</span>
-			<div dojoType="dijit.Menu" id="createMenu" style="display: none;">
-				<div dojoType="dijit.MenuItem"  iconClass="dijitEditorIcon dijitEditorIconSave"
-					onClick="console.log('not actually saving anything, just a test!')">Create blank</div>
-				<div dojoType="dijit.MenuItem"
-					onClick="console.log('not actually saving anything, just a test!')">Create from template</div>
-			</div>
+			<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 dojoType="dijit.form.DropDownButton" id="edit" iconClass="noteIcon" title="edit title" value="Edit">
+		<button id="edit" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", title:"edit title", value:"Edit"'>
 			<span>Edit<b>!</b></span>
-			<div dojoType="dijit.Menu" id="editMenu">
-				<div dojoType="dijit.MenuItem" id="cut" iconClass="dijitEditorIcon dijitEditorIconCut"
-					onClick="console.log('not actually cutting anything, just a test!')">Cut</div>
-				<div dojoType="dijit.MenuItem" id="copy" iconClass="dijitEditorIcon dijitEditorIconCopy"
-					onClick="console.log('not actually copying anything, just a test!')">Copy</div>
-				<div dojoType="dijit.MenuItem" id="paste" iconClass="dijitEditorIcon dijitEditorIconPaste"
-					onClick="console.log('not actually pasting anything, just a test!')">Paste</div>
-				<div dojoType="dijit.MenuSeparator"></div>
-				<div dojoType="dijit.PopupMenuItem">
+			<span id="editMenu" data-dojo-type="dijit.Menu" >
+				<span id="cut" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+					onClick:function(){ console.log("not actually cutting anything, just a test!"); }'>Cut</span>
+				<span id="copy" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+					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 data-dojo-type="dijit.MenuSeparator"></span>
+				<span data-dojo-type="dijit.PopupMenuItem">
 					<span>Submenu</span>
-					<div dojoType="dijit.Menu" id="submenu2">
-						<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-						<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
-						<div dojoType="dijit.PopupMenuItem">
+					<span id="submenu2" data-dojo-type="dijit.Menu" >
+						<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!"); }'>Submenu Item One</span>
+						<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!"); }'>Submenu Item Two</span>
+						<span data-dojo-type="dijit.PopupMenuItem">
 							<span>Deeper Submenu</span>
-							<div dojoType="dijit.Menu" id="submenu4">
-								<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 1!')">Sub-sub-menu Item One</div>
-								<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
-							</div>
-						</div>
-					</div>
-				</div>
-			</div>
+							<span id="submenu4" data-dojo-type="dijit.Menu" >
+								<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!"); }'>Sub-sub-menu Item One</span>
+								<span data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!"); }'>Sub-sub-menu Item Two</span>
+							</span>
+						</span>
+					</span>
+				</span>
+			</span>
 		</button>
-		<button dojoType="dijit.form.DropDownButton" id="color" iconClass="noteIcon" value="color">
+		<button id="color" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", value:"color"'>
 			<span>Color</span>
-			<div dojoType="dijit.ColorPalette" id="colorPalette" style="display: none" palette="3x4"
-				onChange="console.log(this.value);"></div>
+			<span id="colorPalette" data-dojo-type="dijit.ColorPalette"
+				data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 		</button>
-		<button dojoType="dijit.form.ComboButton" id="save" optionsTitle='save options' onClick='console.log("clicked combo save")'
-				iconClass="plusBlockIcon">
+		<button id="save" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+				iconClass:"plusBlockIcon"'>
 			<span>Save</span>
-			<div dojoType="dijit.Menu" id="saveMenu" style="display: none;">
-				<div dojoType="dijit.MenuItem" id="saveMenuItem" iconClass="dijitEditorIcon dijitEditorIconSave"
-					onClick="console.log('not actually saving anything, just a test!')">Save</div>
-				<div dojoType="dijit.MenuItem" id="saveAs"
-					onClick="console.log('not actually saving anything, just a test!')">Save As</div>
-			</div>
+			<span id="saveMenu" data-dojo-type="dijit.Menu">
+				<span id="saveMenuItem" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
+				<span id="saveAs" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
+			</span>
 		</button>
-		<button dojoType="dijit.form.Button" id="disabled" onClick='console.log("clicked simple")' disabled='true' iconClass="plusIcon">
+		<button id="disabled" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, disabled:true, iconClass:"plusIcon"'>
 			Disabled
 		</button>
 	</p>
-	<br clear="all">
+	<br style="clear:both;"/>
 	<h2>DropDownButtons with different drop down positions</h2>
-	<button dojoType="dijit.form.DropDownButton" id="dropdown_default" iconClass="noteIcon" value="color">
+	<button id="dropdown_default" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", value:"color"'>
 		<span>Default (below)</span>
-		<div dojoType="dijit.ColorPalette" style="display: none" palette="3x4"
-			onChange="console.log(this.value);"></div>
+		<span data-dojo-type="dijit.ColorPalette"
+			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button dojoType="dijit.form.DropDownButton" id="dropdown_up" dropDownPosition="above" iconClass="noteIcon" value="color">
+	<button id="dropdown_up" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["above"], iconClass:"noteIcon", value:"color"'>
 		<span>Above</span>
-		<div dojoType="dijit.ColorPalette" style="display: none" palette="3x4"
-			onChange="console.log(this.value);"></div>
+		<span data-dojo-type="dijit.ColorPalette"
+			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button dojoType="dijit.form.DropDownButton" id="dropdown_before" dropDownPosition="before" iconClass="noteIcon" value="color">
+	<button id="dropdown_before" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["before"], iconClass:"noteIcon", value:"color"'>
 		<span>Before</span>
-		<div dojoType="dijit.ColorPalette" style="display: none" palette="3x4"
-			onChange="console.log(this.value);"></div>
+		<span data-dojo-type="dijit.ColorPalette"
+			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
-	<button dojoType="dijit.form.DropDownButton" id="dropdown_after" dropDownPosition="after" iconClass="noteIcon" value="color">
+	<button id="dropdown_after" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='dropDownPosition:["after"], iconClass:"noteIcon", value:"color"'>
 		<span>After</span>
-		<div dojoType="dijit.ColorPalette" style="display: none" palette="3x4"
-			onChange="console.log(this.value);"></div>
+		<span data-dojo-type="dijit.ColorPalette"
+			data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'></span>
 	</button>
 	<h2>ComboButtons with different drop down positions</h2>
-	<button dojoType="dijit.form.ComboButton" id="combo_default" optionsTitle='save options' onClick='console.log("clicked combo save")'
-			iconClass="plusBlockIcon">
+	<button id="combo_default" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", onClick:function(){ console.log("clicked combo save") },
+			iconClass:"plusBlockIcon"'>
 		<span>Default (below)</span>
-		<div dojoType="dijit.Menu" tyle="display: none;">
-			<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconSave"
-				onClick="console.log('not actually saving anything, just a test!')">Save</div>
-			<div dojoType="dijit.MenuItem"
-				onClick="console.log('not actually saving anything, just a test!')">Save As</div>
-		</div>
+		<span data-dojo-type="dijit.Menu">
+			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
+			<span data-dojo-type="dijit.MenuItem"
+				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
+		</span>
 	</button>
-	<button dojoType="dijit.form.ComboButton" id="combo_above" dropDownPosition="above" optionsTitle='save options' onClick='console.log("clicked combo save")'
-			iconClass="plusBlockIcon">
+	<button id="combo_above" data-dojo-type="dijit.form.ComboButton" data-dojo-props='dropDownPosition:["above"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+			iconClass:"plusBlockIcon"'>
 		<span>Up</span>
-		<div dojoType="dijit.Menu" style="display: none;">
-			<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconSave"
-				onClick="console.log('not actually saving anything, just a test!')">Save</div>
-			<div dojoType="dijit.MenuItem"
-				onClick="console.log('not actually saving anything, just a test!')">Save As</div>
-		</div>
+		<span data-dojo-type="dijit.Menu">
+			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
+			<span data-dojo-type="dijit.MenuItem"
+				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
+		</span>
 	</button>
-	<button dojoType="dijit.form.ComboButton" id="combo_before" dropDownPosition="before" optionsTitle='save options' onClick='console.log("clicked combo save")'
-			iconClass="plusBlockIcon">
+	<button id="combo_before" data-dojo-type="dijit.form.ComboButton" data-dojo-props='dropDownPosition:["before"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+			iconClass:"plusBlockIcon"'>
 		<span>Before</span>
-		<div dojoType="dijit.Menu" style="display: none;">
-			<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconSave"
-				onClick="console.log('not actually saving anything, just a test!')">Save</div>
-			<div dojoType="dijit.MenuItem"
-				onClick="console.log('not actually saving anything, just a test!')">Save As</div>
-		</div>
+		<span data-dojo-type="dijit.Menu">
+			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
+			<span data-dojo-type="dijit.MenuItem"
+				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
+		</span>
 	</button>
-	<button dojoType="dijit.form.ComboButton" id="combo_after" dropDownPosition="after" optionsTitle='save options' onClick='console.log("clicked combo save")'
-			iconClass="plusBlockIcon">
+	<button id="combo_after" data-dojo-type="dijit.form.ComboButton" data-dojo-props='dropDownPosition:["after"], optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); },
+			iconClass:"plusBlockIcon"'>
 		<span>After</span>
-		<div dojoType="dijit.Menu" style="display: none;">
-			<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconSave"
-				onClick="console.log('not actually saving anything, just a test!')">Save</div>
-			<div dojoType="dijit.MenuItem"
-				onClick="console.log('not actually saving anything, just a test!')">Save As</div>
-		</div>
+		<span data-dojo-type="dijit.Menu">
+			<span data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+				onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</span>
+			<span data-dojo-type="dijit.MenuItem"
+				data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</span>
+		</span>
 	</button>
 	<h2>Buttons with no text label</h2>
 	<p>Buttons have showLabel=false so text is not displayed.  If no title attribute supplied, Should have label as title attribute displayed on mouse over</p>
 	<div class="box">
-		<button id="1466" dojoType="dijit.form.Button" title="title attrib rather than label" onClick='console.log("clicked simple button with no text label")'
-		iconClass="plusIcon" showLabel="false">
+		<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"); },
+		iconClass:"plusIcon", showLabel:false'>
 		<span><b>Rich</b><i> Text</i> Test!</span>
 		</button>
-				<div dojoType="dijit.form.DropDownButton" iconClass="noteIcon" showLabel="false" title="color title">
+				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"noteIcon", showLabel:false, title:"color title"'>
 			<span>Color</span>
-			<div dojoType="dijit.ColorPalette" id="colorPalette2" style="display: none" palette="3x4"
-				onChange="console.log(this.value);">
+			<div id="colorPalette2" data-dojo-type="dijit.ColorPalette"
+				data-dojo-props='palette:"3x4", onChange:function(val){ console.log(val); }'>
 			</div>
 	</div>
-	<div dojoType="dijit.form.ComboButton" optionsTitle='save options' title="save title" onClick='console.log("clicked combo save")'
-				iconClass="plusBlockIcon" showLabel="false">
+	<div data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", title:"save title", onClick:function(){ console.log("clicked combo save"); },
+				iconClass:"plusBlockIcon", showLabel:false'>
 			<span>Save</span>
-			<div dojoType="dijit.Menu" id="saveMenu2" style="display: none;">
-				<div dojoType="dijit.MenuItem"  iconClass="dijitEditorIcon dijitEditorIconSave"
-					onClick="console.log('not actually saving anything, just a test!')">Save</div>
-				<div dojoType="dijit.MenuItem"
-					onClick="console.log('not actually saving anything, just a test!')">Save As</div>
+			<div id="saveMenu2" data-dojo-type="dijit.Menu">
+				<div data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+					onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save</div>
+				<div data-dojo-type="dijit.MenuItem"
+					data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!"); }'>Save As</div>
 			</div>
 		</div>
 	</div>
-	<br clear="all">
+	<br style="clear:both;"/>
 	<h2>Toggle buttons</h2>
 	<p>The button CSS as well as the icon CSS can change on toggle </p>
 	<div class="box">
-		<button dojoType="dijit.form.ToggleButton" id="toggle1" checked onChange="console.log('toggled button checked='+arguments[0]);this.set('label',arguments[0] ==
-		true ? 'toggle me off' : 'toggle me on');" iconClass="dijitCheckBoxIcon">
+		<button id="toggle1" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='checked:true,
+			onChange:function(val){
+				console.log("toggled button checked="+val);
+				this.set("label", val ? "toggle me off" : "toggle me on");
+			}, iconClass:"dijitCheckBoxIcon"'>
 			Toggle me off
 		</button>
-		<button dojoType="dijit.form.ToggleButton" id="toggle2" onChange="console.log('toggled button checked='+arguments[0]);" iconClass="dijitRadioIcon">
+		<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>
 	</div>
-	<br clear="all">
+	<br style="clear:both;"/>
 	<h2>Sizing</h2>
 	<p>Short button, tall buttons, big buttons, small buttons...
 	These buttons size to their content (just like <button>).</p>
 	<div class="box">
-		<button dojoType="dijit.form.Button" onclick='console.log("big");' iconClass="flatScreenIcon">
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("big"); }, iconClass:"flatScreenIcon"'>
 			<span style="font-size:xx-large">big</span>
 		</button>
-		<button id="smallButton1" dojoType="dijit.form.Button" onclick='console.log("small");'>
-			<img src="../images/arrowSmall.gif" width="15" height="5">
+		<button id="smallButton1" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("small"); }'>
+			<img src="../images/arrowSmall.gif" width="15" height="5"/>
 			<span style="font-size:x-small">small</span>
 		</button>
-		<button dojoType="dijit.form.Button" onclick='console.log("long");'>
-			<img src="../images/tube.gif" width="150" height="16">
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("long"); }'>
+			<img src="../images/tube.gif" width="150" height="16"/>
 			long
 		</button>
-		<button dojoType="dijit.form.Button" onclick='console.log("tall");' width2height="0.1">
-			<img src="../images/tubeTall.gif" height="75" width="35"><br>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("tall"); }'>
+			<img src="../images/tubeTall.gif" height="75" width="35"/><br>
 			<span style="font-size:medium">tall</span>
 		</button>
 		<div style="clear: both;"></div>
 	</div>
-	<br clear="all">
+	<br style="clear:both;"/>
 	<h2>Customized buttons</h2>
 	<p>Dojo users can customize styles.  Here's an example:</p>
-	<style type="text/css">
-		.acmeButton .dijitButtonNode {
-			background: rgb(96,96,96) !important;
-			color: white !important;
-			padding: 10px !important;
-			font-size: x-large !important;
-			padding-top: 10px !important;
-			padding-bottom: 10px !important;
-			border: 2px inset rgb(96,96,96);
-		}
-		.acmeButtonHover .dijitButtonNode {
-			background-color: rgb(89,94,111) !important;
-			color: cyan !important;
-		}
-		.acmeButtonFocused .dijitButtonNode {
-			border: yellow inset 2px;
-		}
-		.acmeButtonActive .dijitButtonNode {
-			background-color: white !important;
-			color: black !important;
-			border: 2px solid black !important;
-		}
-	</style>
 	<div class="box">
-		<button baseClass="acmeButton" dojoType="dijit.form.Button" onclick='console.log("short");'>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("short"); }'>
 			short
 		</button>
-		<button baseClass="acmeButton" dojoType="dijit.form.Button" onclick='console.log("longer");'>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("longer"); }'>
 			bit longer
 		</button>
-		<button baseClass="acmeButton" dojoType="dijit.form.Button" onclick='console.log("longer yet");'>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='baseClass:"acmeButton", onClick:function(){ console.log("longer yet"); }'>
 			ridiculously long
 		</button>
 		<div style="clear: both;"></div>
@@ -275,15 +277,15 @@
 	(Ticket <a href="http://trac.dojotoolkit.org/ticket/403">#403</a>)
 	</p>
 	<div class="box">
-		<button dojoType="dijit.form.Button" onclick='dojo.byId("hiddenNode").style.display="inline";'>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dojo.byId("hiddenNode").style.display="inline"; }'>
 			Show Hidden Buttons
 		</button>
 	</div>
 	<div class="box" style="display:none;" id="hiddenNode">
-		<button dojoType="dijit.form.Button" onclick='console.log("clicked simple")' iconClass="plusIcon">
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
 			Create
 		</button>
-		<button dojoType="dijit.form.Button" onclick='console.log("clicked simple")' iconClass="plusIcon">
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ console.log("clicked simple"); }, iconClass:"plusIcon"'>
 			Create
 		</button>
 	</div>
@@ -301,9 +303,9 @@
 			forEachButton(function(widget){ widget.set('disabled',disabled); });
 			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>",
+		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",
-					 "<img src='../images/plus.gif' width='16' height='16'>boy"];
+					 "<img src='../images/plus.gif' width='16' height='16'/>boy"];
 		var idx = 0;
 		function changeLabels(){
 			forEachButton(function(widget){
@@ -387,34 +389,34 @@
 	<div>Testing that submit and reset buttons work properly.  OnSubmit and OnReset handlers
 		for the form just output to the console.
 	</div>
-	<form dojoType="dijit.form.Form" id="testForm" name="testForm"
-		encType="multipart/form-data" action="../formAction.html" method="" >
-		<script type="dojo/method" event="onReset">
+	<form id="testForm" data-dojo-type="dijit.form.Form" data-dojo-props='name:"testForm",
+		encType:"multipart/form-data", action:"../formAction.html", method:"" '>
+		<script type="dojo/method" data-dojo-event="onReset">
 			console.log("testForm onReset invoked");
 		</script>
-		<script type="dojo/method" event="onSubmit">
+		<script type="dojo/method" data-dojo-event="onSubmit">
 			console.log("testForm onSubmit invoked - not really submitting");
 			return false;
 		</script>
-		<label for="testName">Name: </label><input dojoType="dijit.form.TextBox" id="testName" name="testName" value=""><br>
-		<button dojoType="dijit.form.Button" type="submit" id="bSubmit">Submit</button>  
-		<button dojoType="dijit.form.Button" type="reset" id="bReset">Reset</button>
+		<label for="testName">Name: </label><input id="testName" data-dojo-type="dijit.form.TextBox" data-dojo-props='name:"testName", value:""'/><br>
+		<button id="bSubmit" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit" '>Submit</button>  
+		<button id="bReset" data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset" '>Reset</button>
 	</form>
 
 	<h3>onClick Tests</h3>
 	<div>Testing that onClick works properly
 	</div>
 	<form>
-		<label for="onClickName">Value: </label><input id="onClickName" name="onClickName" value="RESET"><br>
-		<button dojoType="dijit.form.Button" type="reset" id="reset1">Reset with no onClick handler should reset</button>
+		<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 type="reset" id="reset1N">Native Reset with no onClick handler should reset</button><br>
-		<button dojoType="dijit.form.Button" type="reset" id="reset2" onClick="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 dojoType="dijit.form.Button" type="reset" id="reset3" onClick="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 dojoType="dijit.form.Button" type="reset" id="reset4" onClick="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 dojoType="dijit.form.Button" type="reset" id="reset5" onClick="">Reset with "" onClick handler should reset</button>
+		<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 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 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 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 type="reset" id="reset5N" onClick="">Native Reset with "" onClick handler should reset</button><br>
 	</form>
 
@@ -427,25 +429,24 @@
 			}
 		};
 	</script>
-	<form dojoType="dijit.form.Form" id="myForm"
-		encType="multipart/form-data" action="../formAction.html" method="" target="_formSubmitIframe">
-		<button id="Plain" name="Plain" type="submit" dojoType="dijit.form.Button" value="Plain Submit" label="Plain Submit"></button>
-		<button id="Combo" name="Combo" type="submit" dojoType="dijit.form.ComboButton" value="Combo Submit" label="Combo Submit">
-			<div dojoType="dijit.Menu" style="display:none;">
-				<div id="ComboMenuItem" dojoType="dijit.MenuItem" onclick="dijit.byId('myForm').submit()">Combo MenuItem Submit</div>
-			</div>
+	<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"'>
+			<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>
 		</button>
-		<button id="DropDown" name="DropDown" type="submit" dojoType="dijit.form.DropDownButton" value="DropDown Submit" label="DropDown Submit">
-			<div dojoType="dijit.Menu" style="display:none;">
-				<div id="DropDownMenuItem" dojoType="dijit.MenuItem" onclick="dijit.byId('myForm').submit()">DropDown MenuItem Submit</div>
-			</div>
+		<button id="DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='name:"DropDown", type:"submit", value:"DropDown Submit", label:"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>
 		</button>
-		<button id="Disabled" name="Disabled" type="submit" dojoType="dijit.form.Button" disabled value="Disabled Submit" label="Disabled Submit"></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>
 	</form>
 	<br>
-	<label for="buttonName">Submitted name:</label><input id="buttonName"><br>
-	<nobr style="width:100%;"><label for="buttonValue">Submitted value:</label><input id="buttonValue" style="width:100%;overflow:hidden;"></nobr>
-<iframe name="_formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
-
+	<label for="buttonName">Submitted name:</label><input id="buttonName"/><br>
+	<label for="buttonValue">Submitted value:</label><input id="buttonValue"/>
+	<br>
+	<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values) submittedValues(this.values);" style="display:none;"></iframe>
 </body>
 </html>
diff --git a/dijit/tests/form/test_CheckBox.html b/dijit/tests/form/test_CheckBox.html
index f393126..7f3afda 100644
--- a/dijit/tests/form/test_CheckBox.html
+++ b/dijit/tests/form/test_CheckBox.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>CheckBox Widget Demo</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		label { margin-right: 0.80em; }
@@ -13,17 +13,17 @@
 
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
 	<script type="text/javascript">
-		dojo.require("doh.runner"); // optimize: load dijit layer
+		dojo.require("doh.runner");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.form.CheckBox");
 		dojo.require("dijit.form.RadioButton");
@@ -42,167 +42,20 @@
 			dojo.byId("onvaluechangedoutput").innerHTML = value;
 		}
 
-		// These are the values assigned to the widgets in the page's HTML
-		var originalGet = {
-			cb1: [],
-			cb2: ["on"],
-			cb4: ["on"],
-			cb5: [],
-			cb6: ["on"],
-			cb7: [],
-			'g[1]': "talk",
-			g2: null
-		};
-
-		var originalSubmit = {
-			cb2: "on",
-			cb4: "on",
-			cb6: "on",
-			'g[1]': "talk"
-		};
-
-		// attempt to change these values
-		var change = {
-			cb1: ["foo"],
-			cb2: [],
-			cb3: ["on"],
-			cb4: [],
-			cb5: ["on"],
-			cb6: ["foo"],
-			'g[1]': "weather",
-			g2: "country"
-		};
-
-		// changed values
-		var changedGet = {
-			cb1: ["foo"],
-			cb2: [],
-			cb4: [],
-			cb5: ["on"],
-			cb6: [],
-			cb7: [],
-			'g[1]': null,
-			g2: "country"
-		};
-
-		var changedSubmit = {
-			cb1: "foo",
-			cb5: "on",
-			g2: "country"
-		};
-
 		dojo.addOnLoad(function(){
 			var params = {id: "cb6", name: "cb6", checked: true };
-			var widget = new dijit.form.CheckBox(params, dojo.byId("checkboxContainer"));
-
-			// should be able to query for all of the inputs, including hidden ones
-			doh.register("query input by checked state", [
-				{
-					name: "query checked",
-					runTest: function(){
-						var queried=dojo.query("input[checked]", dojo.byId('myForm'));
-						doh.is(5,queried.length,"expected: 5 checked widgets, got: "+queried.length);
-					}
-				}
-			]);
-
-			doh.register("query input by name", [
-				{
-					name: "query name",
-					runTest: function(){
-						var queried=dojo.query("input[name]", dojo.byId('myForm'));
-						doh.is(13,queried.length,"expected: 13 named widgets, got: "+queried.length);
-					}
-				}
-			]);
-
-			var formWidget = dijit.byId("myForm");
+			new dijit.form.CheckBox(params, "cb6");
+			
+			new dijit.form.RadioButton({
+				checked: true,
+				value: "tea",
+				name: "drink"
+			}, "g4rb1");
+			new dijit.form.RadioButton({
+				value: "coffee",
+				name: "drink"
+			}, "g4rb2");
 
-			var submitForm = function(name, testValues){
-				return {
-					name: name,
-					timeout: 5000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						submittedValues = function(formValues){
-							d.getTestCallback(function(){
-								for(var i in originalGet){ doh.is(testValues[i], formValues[i], i); }
-							})();
-						};
-						formWidget.submit();
-						return d;
-					},
-					tearDown: function(){
-						submittedValues = defaultSubmitHandler;
-					}
-				};
-			};
-
-			// delay produces a "test" which simply waits for ms milliseconds.
-			// this is necessary for IE, which gets confused by multiple quick submits.
-			var delay = function(ms){
-				return {
-					name: "delay for IE's sake",
-					timeout: 50000,
-					runTest: function(){
-						var d = new doh.Deferred();
-						setTimeout(function(){
-							d.callback(true);
-						}, ms);
-						console.log("set timeout");
-						return d;
-					}
-				};
-			};
-
-			doh.register("CheckBox values",
-				[
-					function getValues(){
-						doh.is( dojo.toJson(originalGet), dojo.toJson(formWidget.get('value')) );
-					},
-					submitForm("original submit", originalSubmit),
-					delay(500),
-					function setValues(){
-						formWidget.set('value', change);
-						doh.is( dojo.toJson(changedGet), dojo.toJson(formWidget.get('value')) );
-					},
-					submitForm("changed submit", changedSubmit),
-					delay(500),
-					function resetValues(){
-						formWidget.reset();
-						doh.is( dojo.toJson(originalGet), dojo.toJson(formWidget.get('value')), "reset to original values" );
-					},
-					submitForm("reset submit", originalSubmit)
-				]
-			);
-
-			doh.register("CheckBox onChange",
-				[
-					function fireOnChange(){
-						var d = new doh.Deferred();
-						var cb = dijit.byId('cb2');
-						var lastOnChange = dojo.byId('oncheckedoutput').innerHTML;
-						cb.set('checked', !cb.get('checked'));
-						setTimeout(d.getTestCallback(function(){
-							doh.isNot(lastOnChange, dojo.byId('oncheckedoutput').innerHTML);
-						}), 0);
-						return d;
-					},
-
-					function skipOnChange(){
-						var d = new doh.Deferred();
-						var cb = dijit.byId('cb2');
-						var lastOnChange = dojo.byId('oncheckedoutput').innerHTML;
-						cb.set('checked', !cb.get('checked'), false);
-						setTimeout(d.getTestCallback(function(){
-							doh.is(lastOnChange, dojo.byId('oncheckedoutput').innerHTML);
-						}), 0);
-						return d;
-					}
-				]
-			);
-
-			doh.run();
 		});
 	</script>
 </head>
@@ -214,34 +67,33 @@
 	</p>
 	<!--    to test form submission, you'll need to create an action handler similar to
 		http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-	<form dojoType="dijit.form.Form" id="myForm"
-			action="../formAction.html" method="" target="_formSubmitIframe">
+	<form id="myForm" data-dojo-type="dijit.form.Form" data-dojo-props='action:"../formAction.html", method:"", target:"formSubmitIframe"'>
 		<input type="checkbox" id="cb0" checked/>
 			<label for="cb0">cb0: Vanilla (non-dojo) checkbox (for comparison purposes)</label>
 		<br>
-		<input name="cb1" id="cb1" jsid="cb1" value="foo" dojoType="dijit.form.CheckBox" onClick="console.log('clicked cb1')">
+		<input id="cb1" data-dojo-id="cb1" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb1", value:"foo", onClick:function(){ console.log("clicked cb1") }'/>
 			<label for="cb1">cb1: normal checkbox, with value=foo, clicking generates console log messages</label>
 			<button type=button onclick="alert(dijit.byId('cb1').get('value'));">get('value')</button>
 		<br>
-		<input onChange="reportChecked" name="cb2" id="cb2" dojoType="dijit.form.CheckBox" checked="checked"/>
+		<input id="cb2" data-dojo-type="dijit.form.CheckBox" data-dojo-props='onChange:reportChecked, name:"cb2", checked:true'/>
 			<label for="cb2">cb2: normal checkbox, with default value, initially turned on.</label>
 			<span>"onChange" handler updates: [<span id="oncheckedoutput"></span>]</span>
 			<button type=button onclick="alert(dijit.byId('cb2').get('value'));">get('value')</button>
 		<br>
-		<input name="cb3" id="cb3" dojoType="dijit.form.CheckBox" disabled>
+		<input id="cb3" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb3", disabled:true'/>
 			<label for="cb3">cb3: disabled checkbox</label>
 		<br>
-		<input name="cb4" id="cb4" dojoType="dijit.form.CheckBox" readOnly checked/>
+		<input id="cb4" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb4", readOnly:true, checked:true'/>
 			<label for="cb4">cb4: readOnly checkbox, turned on</label>
 		<br>
-		<input name="cb5" id="cb5" type="checkbox" value="" dojoType="dijit.form.CheckBox" onClick="console.log('clicked cb5')">
+		<input id="cb5" data-dojo-type="dijit.form.CheckBox" data-dojo-props='name:"cb5", value:"", onClick:function(){ console.log("clicked cb5"); }'/>
 			<label for="cb5">cb5: normal checkbox, with specified value="", clicking generates console log messages</label>
 			<button type=button onclick="alert(dijit.byId('cb5').get('value'));">get('value')</button>
 		<br>
-		<div id="checkboxContainer"></div>
+		<input id="cb6"/>
 			<label for="cb6">cb6: instantiated from script</label>
 		<br>
-		<input onChange="reportValueChanged" name="cb7" id="cb7" dojoType="dijit.form.CheckBox">
+		<input id="cb7" data-dojo-type="dijit.form.CheckBox" data-dojo-props='onChange:reportValueChanged, name:"cb7" '/>
 			<label for="cb7">cb7: normal checkbox.</label>
 			<input type="button" onclick='dijit.byId("cb7").set("disabled",true);' value="disable" />
 			<input type="button" onclick='dijit.byId("cb7").set("disabled",false);' value="enable" />
@@ -254,27 +106,27 @@
 	</p>
 		<p>
 			<span>Radio group #1:</span>
-			<input type="radio" name="g[1]" id="g1rb1" value="news" dojoType="dijit.form.RadioButton">
+			<input id="g1rb1" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g[1]", value:"news" '/>
 			<label for="g1rb1">news</label>
-			<input type="radio" name="g[1]" id="g1rb2" value="talk" dojoType="dijit.form.RadioButton" checked="checked"/>
+			<input id="g1rb2" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g[1]", value:"talk", checked:true'/>
 			<label for="g1rb2">talk</label>
-			<input type="radio" name="g[1]" id="g1rb3" value="weather" dojoType="dijit.form.RadioButton" disabled="disabled"/>
+			<input id="g1rb3" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g[1]", value:"weather", disabled:true'/>
 			<label for="g1rb3">weather</label>
-			<input type="button" onclick='dijit.byId("g1rb3").set("disabled",false);' value="enable weather" />
+			<input type="button" id="enableWeatherButton" onclick='dijit.byId("g1rb3").set("disabled",false);' value="enable weather" />
 			<input type="button" onclick='dijit.byId("g1rb3").set("disabled",true);' value="disable weather" />
 		</p>
 		<p>
 			<span>Radio group #2: (no default value, and has breaks)</span><br>
-			<input type="radio" name="g2" id="g2rb1" value="top40" dojoType="dijit.form.RadioButton"/>
+			<input id="g2rb1" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g2", value:"top40" '/>
 			<label for="g2rb1">top 40</label><br>
-			<input type="radio" name="g2" id="g2rb2" value="oldies" dojoType="dijit.form.RadioButton"/>
+			<input id="g2rb2" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g2", value:"oldies" '/>
 			<label for="g2rb2">oldies</label><br>
-			<input type="radio" name="g2" id="g2rb3" value="country" dojoType="dijit.form.RadioButton"/>
+			<input id="g2rb3" data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"g2", value:"country" '/>
 			<label for="g2rb3">country</label><br>
 			(Note if using keyboard: tab to navigate, and use arrow or space to select)
 		</p>
-		<button dojoType="dijit.form.Button" type="submit" value="Submit">Submit</button>
-		<button dojoType="dijit.form.Button" type="reset">HTML Reset</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", value:"Submit"'>Submit</button>
+		<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"reset"'>HTML Reset</button>
 	</form>
 
 	<p>
@@ -291,21 +143,28 @@
 		These 6 radio buttons have the same name but are in separate forms so they can be selected independently.
 		<form>
 			1:
-			<input dojoType="dijit.form.RadioButton" type=radio name='a1' id='b1' value="1"/><label for='b1'>b1</label>
-			<input dojoType="dijit.form.RadioButton" type=radio name='a1' id='b2' value="2"/><label for='b2'>b2</label>
+			<input id='b1' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='b1'>b1</label>
+			<input id='b2' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='b2'>b2</label>
 		</form>
 		<form>
 			2:
-			<input dojoType="dijit.form.RadioButton" type=radio name='a1' id='c1' value="1"/><label for='c1'>c1</label>
-			<input dojoType="dijit.form.RadioButton" type=radio name='a1' id='c2' value="2"/><label for='c2'>c2</label>
+			<input id='c1' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='c1'>c1</label>
+			<input id='c2' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='c2'>c2</label>
 		</form>
 		<div>
 			3:
-			<input dojoType="dijit.form.RadioButton" type=radio name='a1' id='d1' value="1"/><label for='d1'>d1</label>
-			<input dojoType="dijit.form.RadioButton" type=radio name='a1' id='d2' value="2"/><label for='d2'>d2</label>
+			<input id='d1' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"1"'/><label for='d1'>d1</label>
+			<input id='d2' data-dojo-type="dijit.form.RadioButton" data-dojo-props='name:"a1", value:"2"'/><label for='d2'>d2</label>
 		</div>
 	</div>
-
-<iframe name="_formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
+	
+	<div>
+		<span>Programmatic radio buttons:</span>
+		<form id="myform">
+			<input type="radio" name="drink" id="g4rb1" checked value="tea"/> <label for="g4rb1">Tea</label> <br />
+			<input type="radio" name="drink" id="g4rb2" checked value="coffee"/> <label for="g4rb2">Coffee</label> <br />
+		</form>
+	</div>
+<iframe name="formSubmitIframe" src="about:blank" onload="if(this.values)submittedValues(this.values)" style="display:none;"></iframe>
 </body>
 </html>
diff --git a/dijit/tests/form/test_ComboBox_destroy.html b/dijit/tests/form/test_ComboBox_destroy.html
deleted file mode 100644
index b47e75f..0000000
--- a/dijit/tests/form/test_ComboBox_destroy.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>Dojo ComboBox Widget Destruction Issue</title>
-
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.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"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<!-- only needed for alternate theme testing: -->
-		<script type="text/javascript" src="../_testCommon.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.form.ComboBox");
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-			dojo.addOnLoad(function(){
-				dojo.connect(dojo.byId("killit"), "onclick", function(){
-					dijit.byId("combo_01").destroy();
-				});
-			});
-		</script>
-	</head>
-	<body class="claro">
-
-		<h1 class="testTitle">Dojo ComboBox Widget Destruction Issue</h1>
-		<p>
-			<tt>ComboBox</tt> does not destroy itself properly, leading to a
-			JavaScript error.  Could it have something to do with not disconnecting
-			events?
-		</p>
-		<p></p>
-		Steps:
-		<ol>
-			<li>Pick a state from the combo box below.</li>
-			<li>Click the "killit" button, which calls <tt>destroy</tt> on the widget.</li>
-			<li>Observe the JavaScript error.</li>
-		</ol>
-		<p></p>
-		<form action="#" method="GET">
-		   <input type="button" id="killit" name="killit" value="killit" />
-			<select name="state" searchField="name" keyField="abbreviation"
-				id="combo_01" dojoType="dijit.form.ComboBox" style="width: 300px;"
-				name="foo.bar1" autoComplete="false">
-				<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>
-			</select>
-		</form>
-	</body>
-</html>
diff --git a/dijit/tests/form/test_DateTextBox.html b/dijit/tests/form/test_DateTextBox.html
index 32ac67a..068ed54 100644
--- a/dijit/tests/form/test_DateTextBox.html
+++ b/dijit/tests/form/test_DateTextBox.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Test DateTextBox Widget</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 
 			.testExample {
@@ -27,11 +27,11 @@
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true, extraLocale: ['de-de', 'en-us']"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true, extraLocale: ['de-de', 'en-us']"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -46,7 +46,7 @@
 			function eventHandler(e){
 				// use this.domNode.getAttribute('widgetId') to show "this" is the widget
 				// mouseleave/enter map to mouseout/over in all browsers except IE
-				console.log(this.domNode.getAttribute('widgetId') + ' ' + arguments[0].type);
+				console.log(this.domNode.getAttribute('widgetId') + ' ' + e.type);
 			}
 			dojo.addOnLoad(function(){
 				dijit.byId("localLong").parse = function(value,constraints){
@@ -63,46 +63,46 @@
 		<h1 class="testTitle">Test DateTextBox Widget</h1>
 		<!--	to test form submission, you'll need to create an action handler similar to
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="form1" dojoType='dijit.form.Form' action="" name="example" method="" onSubmit="return this.validate()">
+		<form id="form1" data-dojo-type='dijit.form.Form' data-dojo-props='action:"", name:"example", method:"", onSubmit:function(){ return this.validate() }'>
 			<div class="dojoTitlePaneLabel">
 				<label for="local"> Date (local format) </label>
 				<span class="noticeMessage">DateTextBox class, no attributes</span>
 			</div>
 			<div class="testExample">
-				<input id="local" name="noDOMvalue" value="2008-12-31" type="text" dojoType="dijit.form.DateTextBox"
-					onMouseEnter="eventHandler"
-					onMouseLeave="eventHandler"
-					onKeyDown="eventHandler"
-					onChange="dojo.byId('oc1').value=''+arguments[0]"
-				>
-				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off">
-				<nobr>
+				<input id="local" data-dojo-type="dijit.form.DateTextBox"
+					data-dojo-props='name:"noDOMvalue", value:"2008-12-31", type:"text", onMouseEnter:eventHandler,
+					onMouseLeave:eventHandler,
+					onKeyDown:eventHandler,
+					onChange:function(val){ dojo.byId("oc1").value = "" + val; }
+				'/>
+				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<span style='white-space:nowrap;'>
 				<button type="button" onclick="dijit.byId('local').set('value', null);">set('value',null)</button>
 				<button type="button" onclick="dojo.byId('gv1').value=''+dijit.byId('local').get('value');">get('value')</button>
 				<button type="button" onclick="dojo.byId('gv1').value=''+dijit.byId('local').value;">.value</button>
-				<input id="gv1" size="34" disabled value="not called yet!" autocomplete="off">
-				</nobr>
+				<input id="gv1" size="34" disabled value="not called yet!" autocomplete="off"/>
+				</span>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<label for="localLong"> Date (local format - long) </label>
 				<span class="noticeMessage">DateTextBox class,
-					Attributes: required="true", trim="true", constraints={min:'2004-01-01',max:'2006-12-31',formatLength:'long'}. Works for leap years</span>
+					Attributes: required="true", trim="true", openOnClick=false, constraints={min:'2004-01-01',max:'2006-12-31',formatLength:'long'}. Works for leap years</span>
 			</div>
 			<div class="testExample">
-				<div id="localLong" jsid="localLong" type="text" name="date1" value="2005-12-30"
-					dojoType="dijit.form.DateTextBox"
-					constraints="{min:'2004-01-01',max:'2006-12-31',formatLength:'long'}"
-					required="true"
-					trim="true"
-					onChange="dojo.byId('oc2').value=arguments[0]"
-					invalidMessage="Invalid date." >
-					<script type="dojo/connect" event="onMouseEnter">eventHandler.apply(this, arguments)</script>
-					<script type="dojo/connect" event="onMouseLeave">eventHandler.apply(this, arguments)</script>
-					<script type="dojo/connect" event="onKeyDown">eventHandler.apply(this, arguments)</script>
-				</div>
- 				onChange:<input id="oc2" size="34" disabled value="not fired yet!" autocomplete="off">
-				<input type="button" value="Destroy" onClick="dijit.byId('localLong').destroy(); return false;">
-				<input type="button" value="set max to 2007-12-31" onClick="dijit.byId('localLong').constraints.max = new Date(2007,11,31); dijit.byId('localLong').validate(false); return false;">
+				<input id="localLong" data-dojo-id="localLong" data-dojo-type="dijit.form.DateTextBox"
+					data-dojo-props='type:"text", name:"date1", value:"2005-12-30",
+					constraints:{min:"2004-01-01",max:"2006-12-31",formatLength:"long"},
+					required:true,
+					trim:true,
+					openOnClick:false,
+					onChange:function(val){ dojo.byId("oc2").value = val; },
+					onMouseEnter:eventHandler,
+					onMouseLeave:eventHandler,
+					onKeyDown:eventHandler,
+					invalidMessage:"Invalid date." '/>
+ 				onChange:<input id="oc2" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<input type="button" value="Destroy" onClick="dijit.byId('localLong').destroy(); return false;"/>
+				<input type="button" value="set max to 2007-12-31" onClick="dijit.byId('localLong').constraints.max = new Date(2007,11,31); dijit.byId('localLong').validate(false); return false;"/>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<label for="american"> Date (American format) </label>
@@ -112,22 +112,21 @@
 				</span>
 			</div>
 			<div class="testExample">
-				<div id="american" type="text" name="date2" value="2005-12-30"
-					dojoType="dijit.form.DateTextBox"
-					constraints="{min:'2004-01-01',max:'2006-12-31'}"
-					lang="en-us"
-					required="true"
-					promptMessage="mm/dd/yyyy"
-					invalidMessage="Invalid date. Use mm/dd/yyyy format.">
-					<script type="dojo/method" event="onMouseEnter">eventHandler.call(this, arguments[0])</script>
-					<script type="dojo/method" event="onMouseLeave">eventHandler.call(this, arguments[0])</script>
-					<script type="dojo/method" event="onKeyDown">eventHandler.call(this, arguments[0])</script>
-				</div>
+				<input id="american" data-dojo-type="dijit.form.DateTextBox"
+					data-dojo-props='type:"text", name:"date2", value:"2005-12-30",
+					constraints:{min:"2004-01-01",max:"2006-12-31"},
+					lang:"en-us",
+					required:true,
+					onMouseEnter:eventHandler,
+					onMouseLeave:eventHandler,
+					onKeyDown:eventHandler,
+					promptMessage:"mm/dd/yyyy",
+					invalidMessage:"Invalid date. Use mm/dd/yyyy format."'/>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<label for="german"> Date (German format)</label>
 				<span class="noticeMessage">DateTextBox class,
-					Attributes: lang="de-de", constraints={min:2004-01-01, max:2006-12-31}. Works for leap years.
+					Attributes: lang="de-de", hasDownArrow=false, constraints={min:2004-01-01, max:2006-12-31}. Works for leap years.
 					Prompt message whenever field is blank.
 				</span>
 			</div>
@@ -140,7 +139,7 @@
 				<span class="noticeMessage">Date, overriding pattern with dd-MM-yyyy</span>
 			</div>
 			<div class="testExample">
-				<input id="pattern" name="noDOMvalue" type="text" dojoType="dijit.form.DateTextBox" constraints="{datePattern:'dd-MM-yyyy', strict:true}">
+				<input id="pattern" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='name:"noDOMvalue", type:"text", constraints:{datePattern:"dd-MM-yyyy", strict:true}'/>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<strong>Using title attrib for label</strong>
@@ -150,13 +149,13 @@
 				</span>
 			</div>
 			<div class="testExample">
-				<div id="american2" type="text" name="date20" value="2008-12-30"
-					dojoType="dijit.form.DateTextBox"
-					title="Date in month, day, year format"
-					lang="en-us"
-					required="true"
-					promptMessage="mm/dd/yyyy"
-					invalidMessage="Invalid date. Use mm/dd/yyyy format.">
+				<div id="american2" data-dojo-type="dijit.form.DateTextBox"
+					data-dojo-props='type:"text", name:"date20", value:"2008-12-30",
+					title:"Date in month, day, year format",
+					lang:"en-us",
+					required:true,
+					promptMessage:"mm/dd/yyyy",
+					invalidMessage:"Invalid date. Use mm/dd/yyyy format."'>
 				</div>
 			</div>
 
@@ -172,6 +171,7 @@
 					value: new Date(2006,10,29),
 					constraints: {min:new Date(2004,0,1),max:new Date(2006,11,31)},
 					lang: "de-de",
+					hasDownArrow: false,
 					onMouseEnter: eventHandler,
 					onMouseLeave: eventHandler,
 					onKeyDown: eventHandler,
@@ -200,12 +200,12 @@
 				 Date pairs, from/to (won't submit unless from/to fields filled in correctly):
 			</div>
 			<div class="testExample">
-				<label for="fromDate">From:</label> <input id="fromDate" type="text" name="fromDate" dojoType="dijit.form.DateTextBox"
-					required="true"
-					onChange="dijit.byId('toDate').constraints.min = this.get('value');" />
-				<label for="toDate">To:</label> <input id="toDate" type="text" name="toDate" dojoType="dijit.form.DateTextBox"
-					required="true"
-					onChange="dijit.byId('fromDate').constraints.max = this.get('value');" />
+				<label for="fromDate">From:</label> <input id="fromDate" data-dojo-type="dijit.form.DateTextBox"
+					data-dojo-props='type:"text", name:"fromDate", required:true,
+					onChange:function(){ dijit.byId("toDate").constraints.min = this.get("value"); } '/>
+				<label for="toDate">To:</label> <input id="toDate" data-dojo-type="dijit.form.DateTextBox"
+					data-dojo-props='type:"text", name:"toDate", required:true,
+					onChange:function(){ dijit.byId("fromDate").constraints.max = this.get("value"); } '/>
 
 				<button type="button" name="button" onclick="displayData(); return false;">view data</button>
 				<input type="submit" name="submit" />
diff --git a/dijit/tests/form/test_Form_onsubmit.html b/dijit/tests/form/test_Form_onsubmit.html
index 57d3ffe..345da16 100644
--- a/dijit/tests/form/test_Form_onsubmit.html
+++ b/dijit/tests/form/test_Form_onsubmit.html
@@ -1,20 +1,21 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Form unit test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -33,66 +34,74 @@
 		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);
+		}
 	</script>
 
 </head>
 <body class="claro">
 
-	<h1 class="testTitle">Form Widget Unit Test</h1>
-	<form dojoType="dijit.form.Form" id="myForm1"
-		encType="multipart/form-data" action="" method="GET"
-		onSubmit="dojo.stopEvent(arguments[0]);"
-		onReset="dojo.stopEvent(arguments[0]);">
+	<h1 class="testTitle">Form Widget Submit Test</h1>
+	<p>Tests dojo.stopEvent() etc. calls inside dijit.form.Form onSubmit and onReset callbacks.</p>
+	<form id="myForm1" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+		onSubmit:function(e){ dojo.stopEvent(e); },
+		onReset:function(e){ dojo.stopEvent(e); }'>
 		<h3>This form shouldn't submit, nor reset</h3>
-		<select name="plop.combo" dojoType="dijit.form.ComboBox">
+		<select id="combo1" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 		</select>
-		<button dojoType=dijit.form.Button type="submit">Submit</button>
-		<button dojoType=dijit.form.Button type="reset">Reset</button>
+		<button id="submit1" data-dojo-type=dijit.form.Button data-dojo-props='type:"submit"'>Submit</button>
+		<button id="reset1" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
 
-	<form dojoType="dijit.form.Form" id="myForm2"
-		encType="multipart/form-data" action="" method="GET"
-		onSubmit="return false;"
-		onReset="return false;">
+	<form id="myForm2" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+		onSubmit:function(){ return false; },
+		onReset:function(){ return false; }'>
 		<h3>This form shouldn't submit, nor reset</h3>
-		<select name="plop.combo" dojoType="dijit.form.ComboBox">
+		<select id="combo2" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 		</select>
-		<button dojoType=dijit.form.Button type="submit">Submit</button>
-		<button dojoType=dijit.form.Button type="reset">Reset</button>
+		<button id="submit2" data-dojo-type=dijit.form.Button data-dojo-props='type:"submit"'>Submit</button>
+		<button id="reset2" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
 
-	<form dojoType="dijit.form.Form" id="myForm3"
-		encType="multipart/form-data" action="" method="GET"
-		onSubmit="return true;"
-		onReset="return true;">
+	<form id="myForm3" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+		onSubmit:function(){ return true; },
+		onReset:function(){ return true; }'>
 		<h3>This form <em>should</em> submit and reset</h3>
-		<select name="plop.combo" dojoType="dijit.form.ComboBox">
+		<select id="combo3" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 		</select>
-		<button dojoType=dijit.form.Button type="submit">Submit</button>
-		<button dojoType=dijit.form.Button type="reset">Reset</button>
+		<button id="submit3" data-dojo-type=dijit.form.Button data-dojo-props='type:"submit"'>Submit</button>
+		<button id="reset3" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
 
-	<form dojoType="dijit.form.Form" id="myForm4"
-		encType="multipart/form-data" action="" method="GET"
-		onSubmit="void(0)"
-		onReset="void(0)">
+	<form id="myForm4" data-dojo-type="dijit.form.Form" data-dojo-props='encType:"multipart/form-data", action:"../formAction.html", method:"", target:"formSubmitIframe",
+		onSubmit:function(){ void(0) },
+		onReset:function(){ void(0) }'>
 		<h3>This form <em>should</em> submit and reset</h3>
-		<select name="plop.combo" dojoType="dijit.form.ComboBox">
+		<select id="combo4" data-dojo-type="dijit.form.ComboBox" data-dojo-props='name:"plopcombo" '>
 			<option value="one">one</option>
 			<option value="two">two</option>
 			<option value="three">three</option>
 		</select>
-		<button dojoType=dijit.form.Button type="submit">Submit</button>
-		<button dojoType=dijit.form.Button type="reset">Reset</button>
+		<button id="submit4" data-dojo-type=dijit.form.Button data-dojo-props='type:"submit"'>Submit</button>
+		<button id="reset4" data-dojo-type=dijit.form.Button data-dojo-props='type:"reset"'>Reset</button>
 	</form>
+	
+	<h3>Submitted value:</h3>
+	<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>
 </html>
diff --git a/dijit/tests/form/test_Form_state.html b/dijit/tests/form/test_Form_state.html
new file mode 100644
index 0000000..bf23b3e
--- /dev/null
+++ b/dijit/tests/form/test_Form_state.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>dijit.form.Form Valid/Invalid State Test</title>
+
+		<style type="text/css">
+			@import "../../themes/claro/document.css";
+			@import "../css/dijitTests.css";
+		</style>
+
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+			data-dojo-config="isDebug: true, parseOnLoad: true, extraLocale: ['de-de', 'en-us']"></script>
+
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../_testCommon.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.form.ValidationTextBox");
+			dojo.require("dijit.form.DateTextBox");
+			dojo.require("dijit.form.Button");
+			dojo.require("dijit.form.FilteringSelect");
+			dojo.require("dijit.form.Form");
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		</script>
+	</head>
+
+	<body class="claro">
+		<h1 class="testTitle">dijit.form.Form Valid/Invalid State Test</h1>
+		<p>
+			Tests that dijit.form.Form correctly changes state from valid to invalid (as indicated by disabled/enabled submit button)
+			according to child widget state.
+		</p>
+		<form id="form1" data-dojo-type="dijit.form.Form" data-dojo-props='action:"", name:"example", method:""'>
+			<table>
+				<tr>
+					<td><label for="name">Name:</label></td>
+					<td><input id="name" data-dojo-type="dijit.form.ValidationTextBox"
+						data-dojo-props='required:true, name:"name" '/></td>
+				</tr>
+				<tr id="newRow" style="display: none;">
+					<td><label for="lastName">Last Name:</label></td>
+					<td><input id="lastName" /></td>
+				</tr>
+				<tr>
+					<td><label for="birth">Birthdate (before 2006-12-31):</label><br><br><br><br></td>
+					<td><div><input id="birth" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='value:"2000-01-01",
+						required:true, name:"birth", constraints:{min:"1900-01-01", max:"2006-12-31"} '/> <br>
+					<button id="disable" onclick="dijit.byId('birth').set('disabled',true);return false;">Disable</button>
+					<button id="enable" onclick="dijit.byId('birth').set('disabled',false);return false;">Enable</button>
+					<button id="reset" onclick="dijit.byId('birth').reset();return false">Reset</button> <br><br>
+					</div></td>
+				</tr>
+				<tr>
+					<td><label for="notes">Notes (optional)</label></td>
+					<td><input id="notes" data-dojo-type="dijit.form.TextBox"
+						data-dojo-props='name:"notes" '/></td>
+				</tr>
+				<tr id="newRow2" style="display: none;">
+					<td><label for="color">Favorite Color</label></td>
+					<td><select id="color">
+						<option value="red">Red</option>
+						<option value="yellow">Yellow</option>
+						<option value="blue">Blue</option>
+					</select></td>
+				</tr>
+			</table>
+			<button id="submitButton" data-dojo-type="dijit.form.Button" >
+				<script type="dojo/method" data-dojo-event="onClick">
+					console.dir(dijit.byId("form1").get('value'));
+				</script>
+				<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" >
+				<script type="dojo/method" data-dojo-event="onClick">
+					new dijit.form.FilteringSelect({id: "color",
+													name: "color",
+													required: true},
+													dojo.byId("color"));
+					new dijit.form.ValidationTextBox({id: "lastName",
+													name: "lastName",
+													required: true},
+													dojo.byId("lastName"));
+					dojo.byId("newRow").style.display = "";
+					dojo.byId("newRow2").style.display = "";
+					this.set("disabled", true);
+					this.domNode.blur();
+					// Call this, since we added a new widget - so that our
+					// form knows that we have something else to watch.
+					dijit.byId("form1").connectChildren();
+				</script>
+				Add More Fields
+			</button>
+			<button data-dojo-type="dijit.form.Button">
+				<script type="dojo/method" data-dojo-event="onClick">
+					dijit.byId("name").validate();
+				</script>
+				validate
+			</button>
+		</form>
+	</body>
+</html>
diff --git a/dijit/tests/form/test_MultiSelect.html b/dijit/tests/form/test_MultiSelect.html
index 8771867..35d95b4 100644
--- a/dijit/tests/form/test_MultiSelect.html
+++ b/dijit/tests/form/test_MultiSelect.html
@@ -1,7 +1,7 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-	"http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Testing MultiSelect form widget | The Dojo Toolkit</title>
 
 	<style type="text/css">
@@ -22,11 +22,11 @@
 
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -51,12 +51,14 @@
 				return dojo.byId((++l%2 == 0 ? "select":"select2" ));
 			}
 			// based on the the 'dijit' object
+			var count=0;
 			for(var i in dijit){
 				var n = opt().appendChild(dojo.clone(c));
-				n.value = n.innerHTML = i;
+				n.value = count++;
+				n.innerHTML = i;
 			}
 
-			// turn any non-dojoType selects into widgets programatically:
+			// turn any non-data-dojo-type selects into widgets programatically:
 			dojo.query("select").forEach(function(n){
 				if(!dijit.byNode(n)){
 					var foo = new dijit.form.MultiSelect({ name: n.name }, n);
@@ -89,11 +91,7 @@
 				console.log('select3 value:',dijit.byId("select3").get('value'));
 			});
 
-			// natural form reaction:
-			dojo.connect(dojo.byId("test"),"onsubmit",function(e){
-				e.preventDefault();
-			});
-			dojo.connect(dojo.byId("formSubmit"),"onclick",function(e){
+			dojo.connect(dojo.byId("formSubmit"), "onclick", function(e){
 				// see what the real form says about our widgets:
 				var vals = dojo.formToJson("test");
 				console.log(vals);
@@ -103,14 +101,14 @@
 </head>
 <body class="claro" style="padding:20px">
 
-		<h1 class="testTitle" tabindex="0">dijit.form.MultiSelect:</h1>
+		<h1 class="testTitle">dijit.form.MultiSelect:</h1>
 		<p>Select one or more items in First or Second list and move them between lists using the buttons provided.</p>
-		<form action="#" method="get" id="test">
+		<form action="#" method="get" id="test" onsubmit="return false">
 
 			<div>
 				<div id="sel1" role="presentation">
 					<label for="select">First list:</label><br>
-					<select id="select" multiple="true" size="7" name="easing">
+					<select id="select" multiple size="7" name="easing" tabindex="1">
 						<option class="clone" value="dojo._defaultEasing">dojo._defaultEasing</option>
 					</select>
 				</div>
@@ -122,37 +120,37 @@
 				</div>
 				<div id="sel2" role="presentation">
 					<label for="select2">Second list:</label><br>
-					<select id="select2" multiple="true" size="7" name="second">
+					<select id="select2" multiple size="7" name="second">
 					</select>
 				</div>
 			</div>
 
-			<br style="clear: both;"><br>
+			<br style="clear: both;"/><br>
 
 			<button class='invert' id="i1">invert first list</button>
 			<button class="invert" id="i2">invert second list</button>
-			<button id="formSubmit">Submit</button>
+			<button id="formSubmit" type="submit">Submit</button>
 
-		</form>
 
 		<button class="debug">call get('value')</button>
 
 		<h3><label for="select3">markup:</label></h3>
 
-		<select id="select3" multiple="true" name="select3"
-			dojoType="dijit.form.MultiSelect"
-			style="height:200px; width:175px; border:5px solid #ededed;">
+		<select id="select3" multiple data-dojo-type="dijit.form.MultiSelect"
+			data-dojo-props='name:"select3",
+			style:{height:"200px", width:"175px", border:"5px solid #ededed"}'>
 
-			<option value="TN" selected="true">Tennessee</option>
+			<option value="TN" selected>Tennessee</option>
 			<option value="VA">Virginia</option>
 			<option value="WA">Washington</option>
 			<option value="FL">Florida</option>
 			<option value="CA">California</option>
 
 		</select>
-
+		</form>
 		<br><br>
 		<button class='invert' id="i3">invert markup list</button>
 		<button class='set' id="s1" onclick="dijit.byId('select3').set('value', ['VA', 'WA']);">set markup list to [VA, WA]</button>
+		
 </body>
 </html>
diff --git a/dijit/tests/form/test_Select.html b/dijit/tests/form/test_Select.html
index 6bec1b7..3a761c2 100644
--- a/dijit/tests/form/test_Select.html
+++ b/dijit/tests/form/test_Select.html
@@ -1,31 +1,31 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>dijit.form.Select test</title>
 
 		<style>
-			@import url(../../../dojo/resources/dojo.css);
-			@import url(../../themes/tundra/tundra.css);
+			@import url(../../themes/claro/document.css);
+			@import url(../../themes/claro/claro.css);
 			@import url(../css/dijitTests.css);
 			.ark { text-decoration: underline; }
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 	
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 	
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
 
 		<script type="text/javascript" src="../helpers.js"></script>
 
-	    <script type="text/javascript">
+		<script type="text/javascript">
 			dojo.require("doh.runner");
-	        dojo.require("dojo.parser");
+			dojo.require("dojo.parser");
 			dojo.require("dijit.form.Select");
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.form.Form");
@@ -106,11 +106,8 @@
 							timeout: 5000,
 							runTest: function(t){
 								var d = new doh.Deferred();
-								t.is(dojo.toJson({s1:"VA", s2:"CA", s3:"AL", s4: "AK", s5: "move", s6: "", s7:"NY", s8a:"AL", s8b:"AL",
-									s9:"CT", s10:"AL", s11:"AL", s12: "AL"}), dojo.toJson(form.get("value")));
-									
-								// set s1 to a valid value
-								s1.set("value", "WA");
+								t.is("VA", form.get("value").s1, "initial value");
+								s1.set("value", "WA"); // set s1 to a valid value
 								t.is("WA", s1.value);
 
 								setTimeout(function(){ try{ // allow onChange to fire
@@ -122,7 +119,14 @@
 
 									setTimeout(function(){ try{ // allow onChange to fire
 										t.is(2, numChanges);
-										d.callback(true);
+										
+										// prevent onChange from firing
+										s1.set("value", "FL", false);
+										
+										setTimeout(function(){ try{ // allow onChange to fire if it's wrong
+											t.is(2, numChanges);
+											d.callback(true);
+										}catch(e){ d.errback(e); }}, 0)
 									}catch(e){ d.errback(e); }}, 0);
 								}catch(e){ d.errback(e); }}, 0);
 								return d;
@@ -332,24 +336,21 @@
 			</select>
 		</form>
 		<h2>dijit.form.Select</h2>
-		<form dojoType="dijit.form.Form" jsId="form" method="get">
+		<form data-dojo-id="form" data-dojo-type="dijit.form.Form" data-dojo-props='method:"get"'>
 			<h4 class="testSubtitle">Setting Defaults</h4>
 			<label for="s1">Test One: </label>
-			<select jsId="s1" name="s1" id="s1" dojoType="dijit.form.Select" >
+			<select id="s1" data-dojo-id="s1" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s1" '>
 				<option value="TN">Tennessee</option>
 				<option value="VA" selected="selected">Virginia</option>
 				<option value="WA">Washington</option>
 				<option value="FL">Florida</option>
 				<option value="CA">California</option>
 			</select>
-			<button id="s1button" dojoType="dijit.form.Button" type="button">
-				<script type="dojo/method" event="onClick">
-					console.log(s1.get("displayedValue"));
-				</script>
+			<button id="s1button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ console.log(s1.get("displayedValue")); }'>
 				Get Displayed Value
 			</button>
 			<label for="s2">Test Two: </label>
-			<select jsId="s2" name="s2" id="s2" value="CA" dojoType="dijit.form.Select">
+			<select id="s2" data-dojo-id="s2" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s2", value:"CA" '>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
 				<option value="AZ">Arizona</option>
@@ -357,72 +358,67 @@
 				<option value="CA">California</option>
 			</select>
 			<label for="s3">Test Three: </label>
-			<select jsId="s3" name="s3" id="s3" style="width: 150px;" dojoType="dijit.form.Select">
+			<select id="s3" data-dojo-id="s3" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s3", style:{width:"150px"},
+					required:true,
+					onChange: function(){
+						if(!this.options[0].value){
+							this.removeOption(0);
+						}
+					}
+				'>
+				<option> </option>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
-				<option type="separator"></option>
+				<option></option>
 				<option value="AZ">Arizona</option>
 				<option value="AR">Arkansas</option>
-				<option type="separator"></option>
+				<option></option>
 				<option value="CA">California</option>
 			</select>
 		<hr>
 			<h4 class="testSubtitle">Rich Text (Need to use divs and spans - since browsers hack selects to pieces)</h4>
-			<label for="s4">Rich text One: </label>
-			<div jsId="s4" name="s4" id="s4" value="AK" dojoType="dijit.form.Select">
-				<span value="AL"><b>Alabama</b></span>
-				<span value="AK"><font color="red">A</font><font color="orange">l</font><font color="yellow">a</font><font color="green">s</font><font color="blue">k</font><font color="purple">a</font></span>
-				<span value="AZ"><i>Arizona</i></span>
-				<span value="AR"><span class="ark">Arkansas</span></span>
-				<span value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
-				<span value="NM" disabled="disabled">New<br>  Mexico</span>
-			</div>
-			<button dojoType="dijit.form.Button" type="button">
-				<script type="dojo/method" event="onClick">
-					s4.set("disabled", !s4.get("disabled"));
-				</script>
+			<label>Rich text One: 
+			<span id="s4" data-dojo-id="s4" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s4", value:"AK" '>
+				<span data-dojo-value="AL"><b>Alabama</b></span>
+				<span data-dojo-value="AK"><span style="color:red;">A</span><span style="color:orange;">l</span><span style="color:yellow;">a</span><span style="color:green;">s</span><span style="color:blue;">k</span><span style="color:purple;">a</span></span>
+				<span data-dojo-value="AZ"><i>Arizona</i></span>
+				<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
+				<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+				<button value="NM" disabled="disabled">New<br>  Mexico</button>
+			</span></label>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ s4.set("disabled", !s4.get("disabled")); }'>
 				Toggle Disabled
 			</button>
-			<label for="s5">Rich text two: </label>
-			<div jsId="s5" name="s5" id="s5" value="move" dojoType="dijit.form.Select">
-				<span value="copy"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndCopy.png" /> Copy</span>
-				<span value="move"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndMove.png" /> Move</span>
-				<span value="nocopy"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoCopy.png" /> No Copy</span>
-				<span value="nomove"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> No Move</span>
-				<span value="long"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> Very Long Menu Entry</span>
-			</div>
+			<label>Rich text two: 
+			<span id="s5" data-dojo-id="s5" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s5", value:"move" '>
+				<span data-dojo-value="copy"><img style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndCopy.png" /> Copy</span>
+				<span data-dojo-value="move"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndMove.png" /> Move</span>
+				<span data-dojo-value="nocopy"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoCopy.png" /> No Copy</span>
+				<span data-dojo-value="nomove"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> No Move</span>
+				<span data-dojo-value="long"><img  style="vertical-align: middle;margin-top: 1px;margin-bottom:1px;" src="../../../dijit/themes/tundra/images/dndNoMove.png" /> Very Long Menu Entry</span>
+			</span></label>
 		<hr>
 			<h4 class="testSubtitle"><label for="s6">Initially Empty</label></h4>
-			<select jsId="s6" name="s6" id="s6" maxHeight="100" dojoType="dijit.form.Select">
+			<select id="s6" data-dojo-id="s6" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s6", maxHeight:100 '>
 			</select>
-			<button dojoType="dijit.form.Button" type="button">
-				<script type="dojo/method" event="onClick">
-					numOptions++;
-					s6.addOption({value: numOptions + "", label: "Option " + numOptions});
-				</script>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ numOptions++; s6.addOption({value: numOptions + "", label: "Option " + numOptions}); }'>
 				Add Option
 			</button>
-			<button dojoType="dijit.form.Button" type="button">
-				<script type="dojo/method" event="onClick">
-					s6.removeOption(0);
-				</script>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ s6.removeOption(0); }'>
 				Remove Top Option
 			</button>
-			<button dojoType="dijit.form.Button" type="button">
-				<script type="dojo/method" event="onClick">
-					s6.set("disabled", !s6.get("disabled"));
-				</script>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ s6.set("disabled", !s6.get("disabled")); }'>
 				Toggle Disabled
 			</button>
 			<hr>
 		<h4 class="testSubtitle"><label for="s7">Single Item</label></h4>
-			<select jsId="s7" name="s7" id="s7" dojoType="dijit.form.Select">
+			<select id="s7" data-dojo-id="s7" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s7" '>
 				<option value="NY">New York</option>
 			</select>
 		<hr>
 		<h4 class="testSubtitle">Long lists</h4>
 			<label for="s8a">maxHeight=200:</label>
-			<select jsId="s8a" name="s8a" id="s8a" maxHeight="200" dojoType="dijit.form.Select">
+			<select id="s8a" data-dojo-id="s8a" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s8a", maxHeight:200 '>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
 				<option value="AZ">Arizona</option>
@@ -476,7 +472,7 @@
 				<option value="WY">Wyoming</option>
 			</select>
 			<label for="s8b">no maxHeight:</label>
-			<select jsId="s8b" name="s8b" id="s8b" dojoType="dijit.form.Select">
+			<select id="s8b" data-dojo-id="s8b" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s8b" '>
 				<option value="AL">Alabama</option>
 				<option value="AK">Alaska</option>
 				<option value="AZ">Arizona</option>
@@ -532,37 +528,34 @@
 			<hr>
 			<h4 class="testSubtitle">Store-based</h4>
 			<label for="s9">Example 1</label>
-			<select jsId="s9" name="s9" id="s9" store="readStore" value="CT" dojoType="dijit.form.Select">
+			<select id="s9" data-dojo-id="s9" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s9", store:readStore, value:"CT" '>
 			</select>
 			<label for="s10">Example 2</label>
-			<select jsId="s10" name="s10" id="s10" store="readStore" dojoType="dijit.form.Select">
+			<select id="s10" data-dojo-id="s10" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s10", store:readStore '>
 			</select>
 			<label for="s11">Example 3</label>
-			<select jsId="s11" name="s11" id="s11" store="writeStore" dojoType="dijit.form.Select">
+			<select id="s11" data-dojo-id="s11" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s11", store:writeStore '>
 			</select>
 			<label for="s12">Example 4</label>
-			<select jsId="s12" name="s12" id="s12" store="readStore" dojoType="dijit.form.Select">
+			<select id="s12" data-dojo-id="s12" data-dojo-type="dijit.form.Select" data-dojo-props='name:"s12", store:readStore '>
 			</select>
 			<hr>
 			<h4 class="testSubtitle">Inlined with text (all IE modes except for IE8 Standards)</h4>
 			<label for="txtPrompt">Text Prompt:</label>
-			<select dojoType="dijit.form.Select" id="txtPrompt">
+			<select id="txtPrompt" data-dojo-type="dijit.form.Select" >
 				<option value="SEL" selected="selected">Select</option>
 				<option value="OTHER">Other</option>
 			</select>
 			<hr>
-			<button dojoType="dijit.form.Button" type="button">
-				<script type="dojo/method" event="onClick">
-					console.dir(form.getValues());
-				</script>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ console.dir(form.getValues()); }'>
 				Get Values
 			</button>
-			<button dojoType="dijit.form.Button" type="submit">Submit</button>
+			<button data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit"'>Submit</button>
 		</form>
 		<hr>
 		<h4 class="testSubtitle">Disabled</h4>
 		<label for="testDisabled">Disabled:</label>
-		<select dojoType="dijit.form.Select" disabled="disabled" jsId='testDisabled' name='testDisabled' id='testDisabled'>
+		<select id='testDisabled' data-dojo-id='testDisabled' data-dojo-type="dijit.form.Select" data-dojo-props='disabled:true, name:"testDisabled" '>
 			<option value="foo">foo</option>
 			<option value="bar">bar</option>
 		</select>
diff --git a/dijit/tests/form/test_SimpleTextarea.html b/dijit/tests/form/test_SimpleTextarea.html
index 2e8d3ff..4ed94fa 100644
--- a/dijit/tests/form/test_SimpleTextarea.html
+++ b/dijit/tests/form/test_SimpleTextarea.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
-	"http://www.w3.org/TR/html4/loose.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Testing SimpleTextArea | The Dojo Toolkit</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -38,43 +38,43 @@
 		</p>
 
 		<h2>Plain textarea (rows=5, cols=50), selectOnClick=true</h2>
-		<textarea id="ta1" dojoType="dijit.form.SimpleTextarea" name="ta1" rows="5" cols="50"
-			onFocus="console.log('user focus handler')"
-			onBlur="console.log('user blur handler')"
-		        onChange="dojo.byId('oc1').value=''+arguments[0]"
-			selectOnClick="true"
-		>
+		<textarea id="ta1" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"ta1", rows:"5", cols:"50",
+			onFocus:function(){ console.log("user focus handler") },
+			onBlur:function(){ console.log("user blur handler") },
+			onChange:function(val){ dojo.byId("oc1").value = "" + val; },
+			selectOnClick:true
+		'>
 			shichashaw, textarea text baw.
 		</textarea>
-		onChange:<textarea id="oc1" rows="6" cols="50" disabled autocomplete="off">not fired yet!</textarea>
-		<nobr>
-		<button onclick="dijit.byId('q1').reset();">reset</button>
-		<button onclick="dijit.byId('q1').set('value', null);">set value to null</button>
-		<button onclick="dojo.byId('gv1').value=''+dijit.byId('q1').get('value');">get value</button>
-		<textarea id="gv1" rows="6" cols="50" disabled autocomplete="off">no value yet!</textarea>
-		</nobr>
+		onChange:<textarea id="oc1" rows="6" cols="50" disabled >not fired yet!</textarea>
+		<span style='white-space:nowrap;'>
+		<button id="resetButton" onclick="dijit.byId('ta1').reset();">reset</button>
+		<button id="setNullButton" onclick="dijit.byId('ta1').set('value', null);">set value to null</button>
+		<button id="getValueButton" onclick="dojo.byId('gv1').value=''+dijit.byId('ta1').get('value');">get value</button>
+		<textarea id="gv1" rows="6" cols="50" disabled >no value yet!</textarea>
+		</span>
 
 
 		<h2>Plain textarea with style="height: 300px; width: 300px" rows="" cols=""</h2>
-		<textarea id="ta2" dojoType="dijit.form.SimpleTextarea" name="ta2"
-			style="height: 300px; width: 300px" rows="" cols="">I have a style setting rather than rows/cols setting</textarea>
+		<textarea id="ta2" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"ta2",
+			style:{height:"300px", width:"300px"}, rows:"", cols:""'>I have a style setting rather than rows/cols setting</textarea>
 
 		<h2>In a BorderContainer</h2>
 
-		<div id="container" dojoType="dijit.layout.BorderContainer" style="width:500px; height:400px; border: inset gray 3px;">
-			<textarea id="top" name="top" dojoType="dijit.form.SimpleTextarea" region="top" splitter="true" style="height: 100px;">
+		<div id="container" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:{width:"500px", height:"400px", border:"inset gray 3px"}'>
+			<textarea id="top" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"top", region:"top", splitter:true, style:{height:"100px"}'>
 				This is just some text in the top region.
 			</textarea>
-			<textarea id="left" name="left" dojoType="dijit.form.SimpleTextarea" region="left" splitter="true" style="width: 200px;">
+			<textarea id="left" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"left", region:"left", splitter:true, style:{width:"200px"}'>
 				This is just some text in the left region.
 			</textarea>
-			<textarea id="center" name="center" dojoType="dijit.form.SimpleTextarea" region="center">
+			<textarea id="center" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"center", region:"center"'>
 				This is just some text in the center region.
 			</textarea>
-			<textarea id="right" name="right" dojoType="dijit.form.SimpleTextarea" region="right" splitter="true" style="width: 200px;">
+			<textarea id="right" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"right", region:"right", splitter:true, style:{width:"200px"}'>
 				This is just some text in the right region.
 			</textarea>
-			<textarea id="bottom" name="bottom" dojoType="dijit.form.SimpleTextarea" region="bottom" splitter="true" style="height: 100px;">
+			<textarea id="bottom" data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props='name:"bottom", region:"bottom", splitter:true, style:{height:"100px"}'>
 				This is just some text in the bottom region.
 			</textarea>
 		</div>
@@ -84,9 +84,9 @@
 				dijit.registry.byClass('dijit.form.SimpleTextarea').forEach(function(widget){ widget.set(attr, value);});
 			}
 		</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('disabled', true);" value="Disable">
-		<input type="button" onclick="setAttr('disabled', false);" value="Enable">
+		<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('disabled', true);" value="Disable"/>
+		<input type="button" onclick="setAttr('disabled', false);" value="Enable"/>
 </body>
 </html>
diff --git a/dijit/tests/form/test_Slider.html b/dijit/tests/form/test_Slider.html
index 2844ca1..74c2db7 100644
--- a/dijit/tests/form/test_Slider.html
+++ b/dijit/tests/form/test_Slider.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo Slider Widget Demo</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 			@import "../../../util/doh/robot/robot.css";
 			#slider2 .dijitButtonNode {
@@ -18,11 +18,11 @@
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -53,7 +53,7 @@
 					// setup the rules
 					var sliderRules = new dijit.form.VerticalRule({
 						count:11,
-						style:"width:5px"
+						style:{width:"5px"}
 					},rulesNode);
 
 					// and setup the slider
@@ -65,7 +65,7 @@
 						name:"programaticSlider",
 						slideDuration:0,
 						onChange:function(val){ dojo.byId('sliderProgInput').value=val; },
-						style:"height:165px",
+						style:{height:"165px"},
 						minimum:1000,
 						maximum:3000,
 						discreteValues:11,
@@ -90,80 +90,80 @@
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
 		<form id="form1" action="" name="example" method="post">
 		<br>initial value=10, min=0, max=100, pageIncrement=100, onChange event triggers input box value change immediately<br>
-		<label for="slider1"><strong>Horizontal Slider Example</strong></label>
-		<div dojoType="dijit.form.HorizontalSlider" name="horizontal1"
-			onChange="dojo.byId('slider1input').value=dojo.number.format(arguments[0]/100,{places:1,pattern:'#%'});"
-			value="10"
-			maximum="100"
-			minimum="0"
-			pageIncrement="100"
-			showButtons="true"
-			intermediateChanges="true"
-			slideDuration="500"
-			style="width:500px; height: 20px;"
-			id="slider1">
-				<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;" count="6" numericMargin="1"></ol>
-				<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=6 style="height:5px;"></div>
-				<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div>
-				<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
+		<strong>Horizontal Slider Example</strong>
+		<div id="slider1" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontal1",
+			onChange:function(val){ dojo.byId("slider1input").value=dojo.number.format(val/100,{places:1,pattern:"#%"}); },
+			value:10,
+			maximum:100,
+			minimum:0,
+			pageIncrement:100,
+			showButtons:true,
+			intermediateChanges:true,
+			slideDuration:500,
+			style:{width:"500px", 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>
 
-		Slider1 Value:<input readonly id="slider1input" size="4" value="10.0%">
+		Slider1 Value:<input readonly id="slider1input" size="4" value="10.0%"/>
 		<br>
-		<button id="disableButton" dojoType="dijit.form.Button" onClick="dijit.byId('slider1').set('disabled', true);dijit.byId('disableButton').set('disabled',true);dijit.byId('enableButton').set('disabled',false);">Disable previous slider</button>
-		<button id="enableButton"  dojoType="dijit.form.Button" onClick="dijit.byId('slider1').set('disabled',false);dijit.byId('disableButton').set('disabled',false);dijit.byId('enableButton').set('disabled', true);" disabled>Enable previous slider</button>
+		<button id="disableButton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("slider1").set("disabled", true);dijit.byId("disableButton").set("disabled",true);dijit.byId("enableButton").set("disabled",false); }'>Disable previous slider</button>
+		<button id="enableButton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("slider1").set("disabled",false);dijit.byId("disableButton").set("disabled",false);dijit.byId("enableButton").set("disabled", true); }, disabled:true'>Enable previous slider</button>
 		<br>
 		<br>initial value=10, min=0, max=100, onChange event triggers input box value change when you mouse up or tab away<br>
-		<label for="slider2"><strong>Vertical Slider Example</strong></label>
-		<div dojoType="dijit.form.VerticalSlider" name="vertical1"
-			onChange="dojo.byId('slider2input').value=arguments[0];"
-			value="10"
-			maximum="100"
-			minimum="0"
-			discreteValues="11"
-			style="height:300px;"
-			id="slider2">
-				<ol dojoType="dijit.form.VerticalRuleLabels" container="leftDecoration" style="width:2em;" labelStyle="right:0px;">
+		<strong>Vertical Slider Example</strong>
+		<div id="slider2" data-dojo-type="dijit.form.VerticalSlider" data-dojo-props='name:"vertical1",
+			onChange:function(val){ dojo.byId("slider2input").value = val; },
+			value:10,
+			maximum:100,
+			minimum:0,
+			discreteValues:11,
+			style:{height:"300px"}
+			'>
+				<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"leftDecoration", style:{width:"2em"}, labelStyle:"right:0px;"'>
 					<li>0</li>
 					<li>100</li>
 				</ol>
-				<div dojoType="dijit.form.VerticalRule" container="leftDecoration" count=11 style="width:5px;" ruleStyle="border-color: #888"></div>
-				<div dojoType="dijit.form.VerticalRule" container="rightDecoration" count=11 style="width:5px;" ruleStyle="border-color: #888"></div>
-				<ol dojoType="dijit.form.VerticalRuleLabels" container="rightDecoration" style="width:2em;" count="6" numericMargin="1" maximum="100" constraints="{pattern:'#'}"></ol>
+				<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"leftDecoration", count:11, style:{width:"5px"}, ruleStyle:"border-color: #888"'></div>
+				<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"rightDecoration", count:11, style:{width:"5px"}, ruleStyle:"border-color: #888"'></div>
+				<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:{width:"2em"}, count:6, numericMargin:1, maximum:100, constraints:{pattern:"#"}'></ol>
 		</div>
-		Slider2 Value:<input readonly id="slider2input" size="3" value="10">
+		Slider2 Value:<input readonly id="slider2input" size="3" value="10"/>
 		<h1>Fancy HTML labels (no slide animation):</h1>
-		<div dojoType="dijit.form.HorizontalSlider" name="horizontal2"
-			title="Fancy HTML Labels"
-			minimum="1"
-			value="2"
-			maximum="3"
-			discreteValues="3"
-			showButtons="false"
-			intermediateChanges="true"
-			slideDuration="0"
-			style="width:300px; height: 40px;"
-			id="slider3">
-				<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=3 style="height:5px;"></div>
-				<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
-					<li><img width=10 height=10 src="../images/note.gif"><br><span style="font-size: small">small</span></li>
-					<li><img width=15 height=15 src="../images/note.gif"><br><span style="font-size: medium">medium</span></li>
-					<li><img width=20 height=20 src="../images/note.gif"><br><span style="font-size: large">large</span></li>
+		<div id="slider3" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontal2",
+			title:"Fancy HTML Labels",
+			minimum:1,
+			value:2,
+			maximum:3,
+			discreteValues:3,
+			showButtons:false,
+			intermediateChanges:true,
+			slideDuration:0,
+			style:"width:300px; height: 40px;"
+			'>
+				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:{height:"5px"}'></div>
+				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
+					<li><img width=10 height=10 src="../images/note.gif"/><br><span style="font-size: small">small</span></li>
+					<li><img width=15 height=15 src="../images/note.gif"/><br><span style="font-size: medium">medium</span></li>
+					<li><img width=20 height=20 src="../images/note.gif"/><br><span style="font-size: large">large</span></li>
 				</ol>
 		</div>
 
 		<p></p><h1>Standalone ruler example:</h1><p></p>
 
 		<div style="width:2in;border-top:1px solid black;">
-			<div dojoType="dijit.form.HorizontalRule" count=17 style="height:.4em;"></div>
-			<div dojoType="dijit.form.HorizontalRule" count=9 style="height:.4em;"></div>
-			<div dojoType="dijit.form.HorizontalRule" count=5 style="height:.4em;"></div>
-			<div dojoType="dijit.form.HorizontalRule" count=3 style="height:.4em;"></div>
-			<ol dojoType="dijit.form.HorizontalRuleLabels" labelStyle="font-style:monospace;font-size:.7em;margin:-1em 0px 0px -.35em;">
+			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:17, style:{height:".4em"}'></div>
+			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:9, style:{height:".4em"}'></div>
+			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:5, style:{height:".4em"}'></div>
+			<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='count:3, style:{height:".4em"}'></div>
+			<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='labelStyle:"font-style:monospace;fontSize:.7em;margin:-1em 0px 0px -.35em;"'>
 				<li></li>
 				<li>1</li>
 				<li>2</li>
@@ -172,20 +172,20 @@
 
 		<h1>horizontal, with buttons, disabled (to show styling):</h1>
 
-		<div dojoType="dijit.form.HorizontalSlider" name="horizontalH2"
-			onChange="dojo.byId('slider1input').value=arguments[0];"
-			value="10"
-			maximum="100"
-			minimum="0"
-			disabled="true"
-			showButtons="true"
-			intermediateChanges="true"
-			style="width:50%; height: 20px;"
-			id="sliderH2">
-				<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;" count="7" constraints="{pattern:'#.00%'}"></ol>
-				<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=7 style="height:5px;"></div>
-				<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div>
-				<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
+		<div id="sliderH2" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props='name:"horizontalH2",
+			onChange:function(val){ dojo.byId("slider1input").value = val; },
+			value:10,
+			maximum:100,
+			minimum:0,
+			disabled:true,
+			showButtons:true,
+			intermediateChanges:true,
+			style:{width:"50%", height:"20px"}
+			'>
+				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:{height:"1.2em", fontSize:"75%"}, count:7, constraints:{pattern:"#.00%"}'></ol>
+				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:7, style:"height:5px;"'></div>
+				<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
+				<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:{height:"1em", fontSize:"75%"}'>
 					<li>lowest</li>
 					<li>normal</li>
 					<li>highest</li>
@@ -197,7 +197,7 @@
 		<h3>min:1000, max:3000, 11 discrete values, no animation</h3>
 
 		<div id="programaticSlider"></div>
-		Programmatic Value:<input readonly id="sliderProgInput" size="5" value="1400">
+		Programmatic Value:<input readonly id="sliderProgInput" size="5" value="1400"/>
 
 		        <script>
 				// so robot can get to it easily
diff --git a/dijit/tests/form/test_Spinner.html b/dijit/tests/form/test_Spinner.html
index 1d0fc67..7ccbf4d 100644
--- a/dijit/tests/form/test_Spinner.html
+++ b/dijit/tests/form/test_Spinner.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo Spinner Widget Test</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 			@import "../../../util/doh/robot/robot.css";
 
@@ -16,11 +16,11 @@
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -43,35 +43,35 @@
 			<br>
 			initial value=900, no delta specified, no min specified, max=1550, onChange captured, big font<br>
 			<label for="integerspinner1">Spinbox #1: </label><br>
-			<input dojoType="dijit.form.NumberSpinner"
-				onChange="dojo.byId('oc1').value=arguments[0]"
-				value="900"
-				class="bigFont"
-				constraints="{max:1550,places:0}"
-				name="integerspinner1"
-				id="integerspinner1">
-			onChange:<input id="oc1" disabled value="not fired yet!" autocomplete="off">
-			<input type="button" id="sv1_1" value="Set value to 400" onClick="dijit.byId('integerspinner1').set('value',400)" tabIndex="-1">
-			<input type="button" id="sv1_2" value="Set value to null" onClick="dijit.byId('integerspinner1').set('value',null)" tabIndex="-1">
-			<input type="button" id="sv1_3" value="Set required to false" onClick="dijit.byId('integerspinner1').set('required',false)" tabIndex="-1">
-			<input type="button" id="sv1_4" value="Set required to true" onClick="dijit.byId('integerspinner1').set('required',true)" tabIndex="-1">
+			<input id="integerspinner1" data-dojo-type="dijit.form.NumberSpinner"
+				data-dojo-props='onChange:function(val){ dojo.byId("oc1").value = val; },
+				value:900,
+				"class":"bigFont",
+				constraints:{max:1550,places:0},
+				name:"integerspinner1"
+				'/>
+			onChange:<input id="oc1" disabled value="not fired yet!" autocomplete="off"/>
+			<input type="button" id="sv1_1" value="Set value to 400" onClick="dijit.byId('integerspinner1').set('value',400)" tabIndex="-1"/>
+			<input type="button" id="sv1_2" value="Set value to null" onClick="dijit.byId('integerspinner1').set('value',null)" tabIndex="-1"/>
+			<input type="button" id="sv1_3" value="Set required to false" onClick="dijit.byId('integerspinner1').set('required',false)" tabIndex="-1"/>
+			<input type="button" id="sv1_4" value="Set required to true" onClick="dijit.byId('integerspinner1').set('required',true)" tabIndex="-1"/>
 			<br>
 			<br>
 			initial value=1000, delta=10, min=9 max=1550<br>
 			<label for="integerspinner2">Spinbox with custom styling (width=50%, 200% Courier font): </label>
-			<input dojoType="dijit.form.NumberSpinner"
-				style="font-size:200%;font-family:Courier;border:1px solid blue;width:50%;"
-				value="1000"
-				smallDelta="10"
-				largeDelta="100"
-				constraints="{min:9,max:1550,places:0}"
-				name="integerspinner2"
-				id="integerspinner2">
+			<input id="integerspinner2" data-dojo-type="dijit.form.NumberSpinner"
+				data-dojo-props='style:{fontSize:"200%", fontFamily:"Courier", border:"1px solid blue", width:"50%"},
+				value:1000,
+				smallDelta:10,
+				largeDelta:100,
+				constraints:{min:9,max:1550,places:0},
+				name:"integerspinner2"
+				'/>
 			<br>
 			<br>
 			<label for="integertextbox3">Spinner line break test: </label>initial value not specified, delta not specified, min not specified, max not specified, signed not specified, separator not specified<br>
 			[verify no line break just after this text]
-			<input dojoType="dijit.form.NumberSpinner" name="integertextbox3" id="integertextbox3">
+			<input id="integertextbox3" data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='name:"integertextbox3" '/>
 			[verify no line break just before this text]
 			<br>
 			<br>
@@ -79,30 +79,30 @@
 			<br>
 			initial value=+1.0, smalldelta=0.1, largedelta=1.0, min=-10.9, max=155, places=1, maxLength=20, exponent=false<br>
 			<label for="realspinner1">Real Number Spinbox #1: </label><br>
-			<input dojoType="dijit.form.NumberSpinner"
-				value="1.0"
-				smallDelta="0.1"
-				largeDelta="1.0"
-				constraints="{min:-10.9,max:155,places:1,round:true,exponent:false}"
-				maxLength="20"
-				name="realspinner1"
-				id="realspinner1">
+			<input id="realspinner1" data-dojo-type="dijit.form.NumberSpinner"
+				data-dojo-props='value:1.0,
+				smallDelta:0.1,
+				largeDelta:1.0,
+				constraints:{min:-10.9,max:155,places:1,round:true,exponent:false},
+				maxLength:"20",
+				name:"realspinner1"
+				'/>
 			<br>
 
 			<p>
 			<label for="spinnerMinOnly">Spinner with no maximum, 1 decimal place: </label><br>
-			<input dojoType="dijit.form.NumberSpinner"
-				value="1.0"
-				smallDelta="0.1"
-				largeDelta="1.0"
-				constraints="{min:-10.9,places:1,round:false}"
-				maxLength="20"
-				name="spinnerMinOnly"
-				id="spinnerMinOnly">
-			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('readOnly',false);" value="Remove readOnly">
-			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('readOnly',true);" value="Set readOnly">
-			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('disabled',false);" value="Remove disabled">
-			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('disabled',true);" value="Set disabled">
+			<input id="spinnerMinOnly" data-dojo-type="dijit.form.NumberSpinner"
+				data-dojo-props='value:1.0,
+				smallDelta:0.1,
+				largeDelta:1.0,
+				constraints:{min:-10.9,places:1,round:false},
+				maxLength:"20",
+				name:"spinnerMinOnly"
+				'/>
+			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('readOnly',false);" value="Remove readOnly"/>
+			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('readOnly',true);" value="Set readOnly"/>
+			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('disabled',false);" value="Remove disabled"/>
+			<input type="button" onclick="dijit.byId('spinnerMinOnly').set('disabled',true);" value="Set disabled"/>
 			</p>
 			<p>
 			<script type="text/javascript">
diff --git a/dijit/tests/form/test_Textarea.html b/dijit/tests/form/test_Textarea.html
index 7aa6c3e..1c94093 100644
--- a/dijit/tests/form/test_Textarea.html
+++ b/dijit/tests/form/test_Textarea.html
@@ -1,22 +1,23 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<!DOCTYPE html>
 <!-- IE8 beta 2 incorrectly sets TEXTAREA scrollHeight when using strict DTD -->
 <html>
 	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Dojo dijit.form.Textarea Widget Test</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 
 			br { margin-bottom: 4em; }
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -32,22 +33,23 @@
 	</head>
 	<body class="claro">
 
-		<h1 class="testTitle">Auto-sizing Textarea Widget Test</h2>
+		<h1 class="testTitle">Auto-sizing Textarea Widget Test</h1>
 
 		<!--    to test form submission, you'll need to create an action handler similar to
 		        http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="form1" action="" name="example" method="" style="width: 800px;">
+		<form id="form1" action="" name="example" method="GET" style="width: 800px;">
 
 			<h2>Various dijit.form.Textarea widgets</h2>
 			<label for="blank">dijit.form.Textarea, initially blank:</label>
-			<textarea dojoType="dijit.form.Textarea" id="blank"></textarea>
+			<textarea id="blank" data-dojo-type="dijit.form.Textarea" ></textarea>
 			<br>
 
-			<label for="simple">dijit.form.Textarea, inline with maxLength=50:</label><div name="simpleTextArea" maxLength="50" dojoType="dijit.form.Textarea" id="simple" style="width:33%;"
-	         		onChange="dojo.byId('ocSimple').value=arguments[0]"
-	         		onFocus="console.log('user focus handler')"
-	         		onBlur="console.log('user blur handler')"
-				>this is a very simple resizable text area</div>
+			<label for="simple">dijit.form.Textarea, inline with maxLength=50:</label>
+			<textarea id="simple" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"simpleTextArea", maxLength:"50", style:{width:"33%"},
+	         		onChange:function(val){ dojo.byId("ocSimple").value = val; },
+	         		onFocus:function(){ console.log("user focus handler"); },
+	         		onBlur:function(){ console.log("user blur handler"); }
+				'>this is a very simple resizable text area</textarea>
 			onChange:<textarea id="ocSimple" readOnly>not fired yet!</textarea>
 			<br>
 
@@ -57,13 +59,13 @@
 			</textarea>
 			<br>
 
-			<div dojoType="dijit.layout.TabContainer" persist="true" tabStrip="true" style="width: 100%; height: 20em;">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='persist:true, tabStrip:true, style:{width:"100%", height:"20em"}'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					<label for="programmatic">dijit.form.Textarea in TabContainer, programmatically created with custom styling:</label><br>
 					<textarea id="programmatic"></textarea>
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
-					<input type="button" onclick="programmaticTextarea.set('value', 'new value for programmatic textarea\nmore text for testing\nmore\neven more\nvery last line');" value="change value">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
+					<input type="button" onclick="programmaticTextarea.set('value', 'new value for programmatic textarea\nmore text for testing\nmore\neven more\nvery last line');" value="change value"/>
 				</div>
 			</div>
 			<script type="text/javascript">
@@ -74,7 +76,7 @@
 						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"}
 					}, "programmatic");
 				});
 			</script>
@@ -84,7 +86,7 @@
 			<label for="largeTextArea">dijit.form.Textarea, initially full:</label>
 <!--	‪ and ‬ are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that 
 	cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
-		<textarea dojoType="dijit.form.Textarea" name="largeTextArea" id="largeTextArea">
+		<textarea id="largeTextArea" data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"largeTextArea" '>
 ‪This is a textarea with a LOT of content.‬
 
 Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril d [...]
@@ -113,10 +115,10 @@ Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
 					dijit.registry.byClass('dijit.form.Textarea').forEach(function(widget){ widget.set(attr, value);});
 				}
 			</script>
-			<input type="button" onclick="setAttr('readOnly', false);" value="Remove readOnly">
-			<input type="button" onclick="setAttr('readOnly', true);" value="Set readOnly">
-			<input type="button" onclick="setAttr('disabled', true);" value="Disable">
-			<input type="button" onclick="setAttr('disabled', false);" value="Enable">
+			<input type="button" onclick="setAttr('readOnly', false);" value="Remove readOnly"/>
+			<input type="button" onclick="setAttr('readOnly', true);" value="Set readOnly"/>
+			<input type="button" onclick="setAttr('disabled', true);" value="Disable"/>
+			<input type="button" onclick="setAttr('disabled', false);" value="Enable"/>
 
 			<h2>Submit page as form</h2>
 			<div>
diff --git a/dijit/tests/form/test_TimeTextBox.html b/dijit/tests/form/test_TimeTextBox.html
index 8ea9cd1..9a633dc 100644
--- a/dijit/tests/form/test_TimeTextBox.html
+++ b/dijit/tests/form/test_TimeTextBox.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Test TimeTextBox Widget</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 
 			.testExample {
@@ -27,11 +27,11 @@
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -47,127 +47,131 @@
 			dojo.require("dojo.currency");
 			dojo.require("dojo.date.locale");
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+			formValue = null;
+	
+			function displayData() {
+				var f = document.getElementById("form1");
+				var s = "";
+				for (var i = 0; i < f.elements.length; i++) {
+						var elem = f.elements[i];
+						if (elem.name == "button")  { continue; }
+						s += elem.name + ": " + elem.value + "\n";
+				}
+				console.log(s);
+				formValue = s;
+			}
 		</script>
 	</head>
 
 	<body class="claro">
 		<h1 class="testTitle">Test TimeTextBox Widget</h1>
-		<!--	to test form submission, you'll need to create an action handler similar to
-			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="form1" action="" name="example" method="">
-
-	<div class="dojoTitlePaneLabel">
-		<label for="q1">Time using local conventions with seconds</label>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {formatLength:'medium'}</span>
-	</div>
-	<div class="testExample">
-		<input id="q1" type="text" name="time1" value="T17:45:00"
-			dojoType="dijit.form.TimeTextBox"
-			constraints="{formatLength:'medium'}"
-			required="true"
-			onChange="dojo.byId('oc1').value=arguments[0]"
-			invalidMessage="Invalid time." />
-		onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off">
-	</div>
-
-	<div class="dojoTitlePaneLabel">
-		<label for="q2">Time using local conventions without seconds, required, no invalid message tooltip</label>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {formatLength:'short'}</span>
-	</div>
-	<div class="testExample">
-		<input id="q2" type="text" name="time1a" value="T17:45:00"
-			dojoType="dijit.form.TimeTextBox"
-			constraints="{formatLength:'short'}"
-			required="true"
-			invalidMessage="" />
-	</div>
-
-	<div class="dojoTitlePaneLabel">
-		<label for="q3"> 12 Hour Time </label>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {timePattern:'h:mm:ss a'}</span>
-	</div>
-	<div class="testExample">
-		<input id="q3" type="text" name="time1b" value="T17:45:00"
-			dojoType="dijit.form.TimeTextBox"
-			constraints="{timePattern:'h:mm:ss a'}"
-			required="true"
-			invalidMessage="Invalid time." />
-	</div>
-
-	<div class="dojoTitlePaneLabel">
-		<label for="q4"> 24 Hour Time</label>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {timePattern:'HH:mm:ss'}</span>
-	</div>
-	<div class="testExample">
-		<input id="q4" type="text" name="time2" value="T17:45:00"
-			dojoType="dijit.form.TimeTextBox"
-			constraints="{timePattern:'HH:mm:ss'}"
-			required="true"
-			invalidMessage="Invalid time. Use HH:mm:ss where HH is 00 - 23 hours.">
-	</div>
-
-	<div class="dojoTitlePaneLabel">
-		<label for="q5">24 Hour Time with 1 Hour TimePicker</label>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {timePattern:'HH:mm:ss', clickableIncrement:'T00:15:00', visibleIncrement:'T00:15:00', visibleRange:'T01:00:00'}</span>
-	</div>
-	<div class="testExample">
-		<input id="q5" type="text" name="time2" value="T17:45:00"
-			dojoType="dijit.form.TimeTextBox"
-			constraints="{timePattern:'HH:mm:ss', clickableIncrement:'T00:15:00', visibleIncrement:'T00:15:00', visibleRange:'T01:00:00'}"
-			required="true"
-			invalidMessage="Invalid time. Use HH:mm:ss where HH is 00 - 23 hours.">
-	</div>
-
-	<div class="dojoTitlePaneLabel">
-		<label for="q6">Initially empty time text box</label>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {formatLength:'medium',min:'T00:00:00',max:'T12:00:00'}</span>
-	</div>
-	<div class="testExample">
-		<input id="q6" type="text" name="time6"
-			dojoType="dijit.form.TimeTextBox"
-			constraints="{formatLength:'medium',min:'T00:00:00',max:'T12:00:00'}"
-			required="true"
-			onChange="dojo.byId('oc6').value=arguments[0]"
-			invalidMessage="Invalid time." />
-		onChange:<input id="oc6" size="34" disabled value="not fired yet!" autocomplete="off">
-	</div>
-	<div class="dojoTitlePaneLabel">
-		<strong>Using title attribute for label.</strong>
-		<span class="noticeMessage">TimeTextBox class,
-			Attributes: {formatLength:'short'} Time using local conventions without seconds, required, no invalid message tooltip</span>
-	</div>
-	<div class="testExample">
-		<input id="q20" type="text" name="q20" value="T17:45:00"
-			dojoType="dijit.form.TimeTextBox"
-			title="title: Time using local conventions"
-			constraints="{formatLength:'short'}"
-			required="true"
-			invalidMessage="" />
-	</div>
-
-	<script>
-	        function displayData() {
-	                var f = document.getElementById("form1");
-	                var s = "";
-	                for (var i = 0; i < f.elements.length; i++) {
-	                        var elem = f.elements[i];
-	                        if (elem.name == "button")  { continue; }
-	                        s += elem.name + ": " + elem.value + "\n";
-	                }
-	                alert(s);
-	        }
-	</script>
-
-		<div>
-			<button name="button" onclick="displayData(); return false;">view data</button>
-			<input type="submit" name="submit" />
-		</div>
+		<!--
+			To really test form submission, you'll need to create an action handler similar to
+			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi.   This just logs the form values
+			to the console.
+		 -->
+		<form id="form1" action="" name="example" method="GET" onsubmit="displayData(); return false;">
+
+			<div>
+				<input type="submit" name="submit" value="fake submit"/>
+			</div>
+			<br/>
+
+			<div class="dojoTitlePaneLabel">
+				<label for="q1">Time using local conventions with seconds</label>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {formatLength:'medium'}</span>
+			</div>
+			<div class="testExample">
+				<input id="q1" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"time1", value:"T17:45:00",
+					constraints:{formatLength:"medium"},
+					required:true,
+					onChange:function(val){ dojo.byId("oc1").value = val; },
+					invalidMessage:"Invalid time." '/>
+				onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
+			</div>
+		
+			<div class="dojoTitlePaneLabel">
+				<label for="q2">Time using local conventions without seconds, required, no invalid message tooltip</label>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {formatLength:'short'}</span>
+			</div>
+			<div class="testExample">
+				<input id="q2" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"time1a", value:"T17:45:00",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</div>
+		
+			<div class="dojoTitlePaneLabel">
+				<label for="q3"> 12 Hour Time </label>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {timePattern:'h:mm:ss a'}</span>
+			</div>
+			<div class="testExample">
+				<input id="q3" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"time1b", value:"T17:45:00",
+					constraints:{timePattern:"h:mm:ss a"},
+					required:true,
+					invalidMessage:"Invalid time." '/>
+			</div>
+		
+			<div class="dojoTitlePaneLabel">
+				<label for="q4"> 24 Hour Time</label>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {timePattern:'HH:mm:ss'}</span>
+			</div>
+			<div class="testExample">
+				<input id="q4" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"time2", value:"T17:45:00",
+					constraints:{timePattern:"HH:mm:ss"},
+					required:true,
+					invalidMessage:"Invalid time. Use HH:mm:ss where HH is 00 - 23 hours."'/>
+			</div>
+		
+			<div class="dojoTitlePaneLabel">
+				<label for="q5">24 Hour Time with 1 Hour TimePicker</label>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {timePattern:'HH:mm:ss', clickableIncrement:'T00:15:00', visibleIncrement:'T00:15:00', visibleRange:'T01:00:00'}</span>
+			</div>
+			<div class="testExample">
+				<input id="q5" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"time2", value:"T17:45:00",
+					constraints:{timePattern:"HH:mm:ss", clickableIncrement:"T00:15:00", visibleIncrement:"T00:15:00", visibleRange:"T01:00:00"},
+					required:true,
+					invalidMessage:"Invalid time. Use HH:mm:ss where HH is 00 - 23 hours."'/>
+			</div>
+		
+			<div class="dojoTitlePaneLabel">
+				<label for="q6">Initially empty time text box</label>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {formatLength:'medium',min:'T00:00:00',max:'T12:00:00'}</span>
+			</div>
+			<div class="testExample">
+				<input id="q6" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"time6",
+					constraints:{formatLength:"medium",min:"T00:00:00",max:"T12:00:00"},
+					required:true,
+					onChange:function(val){ dojo.byId("oc6").value = val; },
+					invalidMessage:"Invalid time." '/>
+				onChange:<input id="oc6" size="34" disabled value="not fired yet!" autocomplete="off"/>
+			</div>
+			<div class="dojoTitlePaneLabel">
+				<strong>Using title attribute for label.</strong>
+				<span class="noticeMessage">TimeTextBox class,
+					Attributes: {formatLength:'short'} Time using local conventions without seconds, required, no invalid message tooltip</span>
+			</div>
+			<div class="testExample">
+				<input id="q20" data-dojo-type="dijit.form.TimeTextBox"
+					data-dojo-props='type:"text", name:"q20", value:"T17:45:00",
+					title:"title: Time using local conventions",
+					constraints:{formatLength:"short"},
+					required:true,
+					invalidMessage:"" '/>
+			</div>
 
 		</form>
 	</body>
diff --git a/dijit/tests/form/test_validStatePerformance.html b/dijit/tests/form/test_validStatePerformance.html
index 8bf5cf1..72e1561 100644
--- a/dijit/tests/form/test_validStatePerformance.html
+++ b/dijit/tests/form/test_validStatePerformance.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-  "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
   <head>
+    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
     <title>Performance Test of NumberTextBox</title>
 
     <style type="text/css">
-      @import "../../../dojo/resources/dojo.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">
+    <link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
     <!-- required: dojo.js -->
     <script type="text/javascript" src="../../../dojo/dojo.js"
-      djConfig="isDebug: true, parseOnLoad: true"></script>
+      data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
     <!-- only needed for alternate theme testing: -->
     <script type="text/javascript" src="../_testCommon.js"></script>
@@ -65,50 +65,50 @@
         console.log("Time 4: Inserting value into ValidationTextBox-fields: " + ((new Date()).getTime() - startTime4) + " millis");
       }
     </script>
-      <form id="form1" dojoType="dijit.form.Form" action="" method="">
-      <input id="input1_1" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_2" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_3" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_4" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_5" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_6" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_7" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_8" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_9" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_10" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_11" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_12" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_13" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_14" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_15" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_16" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_17" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_18" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_19" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
-      <input id="input1_20" name="input1" maxLength="6" type="text" dojoType="dijit.form.NumberTextBox"/>
+      <form id="form1" data-dojo-type="dijit.form.Form" data-dojo-props='action:"", method:""'>
+      <input id="input1_1" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_2" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_3" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_4" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_5" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_6" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_7" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_8" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_9" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_10" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_11" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_12" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_13" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_14" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_15" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_16" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_17" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_18" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_19" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input1_20" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
       </form>
       <br/>
-      <form id="form2" dojoType="dijit.form.Form" action="" method="">
-      <input id="input2_1" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_2" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_3" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_4" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_5" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_6" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_7" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_8" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_9" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_10" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_11" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_12" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_13" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_14" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_15" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_16" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_17" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_18" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_19" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
-      <input id="input2_20" name="input1" maxLength="6" type="text" dojoType="dijit.form.ValidationTextBox"/>
+      <form id="form2" data-dojo-type="dijit.form.Form" data-dojo-props='action:"", method:""'>
+      <input id="input2_1" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_2" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_3" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_4" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_5" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_6" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_7" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_8" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_9" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_10" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_11" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_12" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_13" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_14" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_15" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_16" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_17" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_18" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_19" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
+      <input id="input2_20" data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props='name:"input1", maxLength:"6", type:"text" '/>
       </form>
       <br/>
       <button name="button" onclick="performancetest()">Run tests</button>
diff --git a/dijit/tests/form/test_validate.html b/dijit/tests/form/test_validate.html
index a7d3aa6..bcb7739 100644
--- a/dijit/tests/form/test_validate.html
+++ b/dijit/tests/form/test_validate.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Test TextBox Validation Widgets</title>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 
 			.testExample {
@@ -40,19 +40,28 @@
 			#widget_q26 .dijitInputField {
 				padding:10px !important;
 			}
+
+			.monospace .dijitTextBox {
+				font-family: monospace;
+			}
+
+			.sans {
+				font-family: sans-serif;
+			}
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true, extraLocale: ['de-de']"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: true, extraLocale: ['de-de']"></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("dijit.dijit"); // optimize: load dijit layer
 			dojo.require("dijit.form.TextBox");
 			dojo.require("dijit.form.ValidationTextBox");
@@ -60,6 +69,61 @@
 			dojo.require("dijit.form.CurrencyTextBox");
 			dojo.require("dojo.currency");
 			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+
+			dojo.addOnLoad(function(){
+
+				new dijit.form.TextBox({id: 'monospace1', disabled: true, value: 'M|M:monospace?'}, 'monospace1');
+				new dijit.form.TextBox({id: 'monospace2', disabled: true, value: 'M|M:monospace?'}).placeAt('widget_monospace1', 'after');
+				
+				new dijit.form.TextBox({id: 'sans1', disabled: true, value: 'sans1'}, 'sans1');
+				new dijit.form.TextBox({id: 'sans2', disabled: true, value: 'sans2'}).placeAt('widget_sans1', 'after');
+
+
+				doh.register("font inheritance", [
+					{
+						name: "with srcNodeRef, style on .dijitTextBox",
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								doh.is("monospace", dojo.style('monospace1', "fontFamily"));
+							}), 0);
+							return d;
+						}
+					},
+					{
+						name: "without srcNodeRef, style on .dijitTextBox",
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								doh.is("monospace", dojo.style('monospace2', "fontFamily"));
+							}), 0);
+							return d;
+						}
+					},
+					{
+						name: "with srcNodeRef, style inherited",
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								doh.is("sans-serif", dojo.style('sans1', "fontFamily"));
+							}), 0);
+							return d;
+						}
+					},
+					{
+						name: "without srcNodeRef, style inherited",
+						runTest: function(){
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								doh.is("sans-serif", dojo.style('sans2', "fontFamily"));
+							}), 0);
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
 		</script>
 	</head>
 
@@ -67,36 +131,36 @@
 		<h1 class="testTitle">Dijit Validation Widgets</h1>
 		<!--	to test form submission, you'll need to create an action handler similar to
 			http://www.utexas.edu/teamweb/cgi-bin/generic.cgi -->
-		<form id="form1" action="" name="example" method="">
+		<form id="form1" action="" name="example" method="GET">
 
 			<div class="dojoTitlePaneLabel">
 				<label for="q01">First Name:  </label>
 				<span class="noticeMessage"> TextBox class, <b>tabIndex=2</b>, Attributes: {trim: true, propercase: true, intermediateChanges: true, style: 'width:700px', selectOnClick: true}, First letter of each word is upper case.</span>
 			</div>
 			<div class="testExample">
-				<input id="q01" type="text" name="firstname" value="testing testing" style="width: 700px;" tabIndex=2
-					dojoType="dijit.form.TextBox"
-					trim="true"
-					selectOnClick="true"
-					onfocus="console.log('user onfocus handler')"
-					onblur="console.log('user onblur handler')"
-				        onChange="dojo.byId('oc1').value=arguments[0]"
-					intermediateChanges="true"
-					propercase="true" />
-				<br>onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off">
-				<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', true);" value="Disable">
-				<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', false);" value="Enable">
+				<input id="q01" data-dojo-type="dijit.form.TextBox"
+					data-dojo-props='name:"firstname", value:"testing testing", style:{width:"700px"}, tabIndex:"2",
+					trim:true,
+					selectOnClick:true,
+					onFocus:function(){ console.log("user onfocus handler"); },
+					onBlur:function(){ console.log("user onblur handler"); },
+					onChange:function(v){ dojo.byId("oc1").value=v; },
+					intermediateChanges:true,
+					propercase:true '/>
+				<br>onChange:<input id="oc1" size="34" disabled value="not fired yet!" autocomplete="off"/>
+				<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', true);" value="Disable"/>
+				<input tabIndex="-1" type="button" onclick="dijit.byId('q01').set('disabled', false);" value="Enable"/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
 				<label for="q02">Last Name:  </label>
-				<span class="noticeMessage"> TextBox class, Attributes: {trim: true, uppercase: true, class: 'verylong'}, all letters converted to upper case. </span>
+				<span class="noticeMessage"> TextBox class, Attributes: {trim: true, uppercase: true, "class": 'verylong'}, all letters converted to upper case. </span>
 			</div>
 			<div class="testExample">
-				<input id="q02" type="text" name="lastname" value="testing testing" class="verylong"
-					dojoType="dijit.form.TextBox"
-					trim="true"
-					uppercase="true" />
+				<input id="q02" data-dojo-type="dijit.form.TextBox"
+					data-dojo-props='name:"lastname", value:"testing testing", "class":"verylong",
+					trim:true,
+					uppercase:true '/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -104,24 +168,24 @@
 				<span class="noticeMessage"> NumberTextBox class, <b>tabIndex=1</b>, Attributes: {trim: true}, no initial value specified, tooltipPosition=[above, below].  Displays a prompt message if field is blank.</span>
 			</div>
 			<div class="testExample">
-				<input id="q03" type="text" name="age" tabIndex=1
-					dojoType="dijit.form.NumberTextBox"
-					promptMessage="(optional) Enter an age between 0 and 120"
-					maxLength="3"
-					class="small"
-					constraints="{places:0,min:0,max:120}"
-                                        onChange="dojo.byId('oc3').value=''+arguments[0]"
-					tooltipPosition="above, below"
-                                >
-				onChange:<input id="oc3" size="14" disabled value="not fired yet!" autocomplete="off">
-				<nobr>
+				<input id="q03" data-dojo-type="dijit.form.NumberTextBox"
+					data-dojo-props='name:"age", tabIndex:"1",
+					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"]
+				'/>
+				onChange:<input id="oc3" size="14" disabled value="not fired yet!" autocomplete="off"/>
+				<span style='white-space:nowrap;'>
 				<button id="q03_valid" type=button onclick="dijit.byId('q03').set('value', 120);">set value to 120</button>
 				<button id="q03_outofrange" type=button onclick="dijit.byId('q03').set('value', 121);">set value to 121</button>
 				<button id="q03_invalid" type=button onclick="dijit.byId('q03').set('value', 'two');">set value to two</button>
 				<button id="q03_null" type=button onclick="dijit.byId('q03').set('value', null);">set value to null</button>
 				<button type=button onclick="dojo.byId('gv3').value=''+dijit.byId('q03').get('value');">get value</button>
-				<input id="gv3" size="10" disabled value="" autocomplete="off">
-				</nobr>
+				<input id="gv3" size="10" disabled value="" autocomplete="off"/>
+				</span>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -129,12 +193,12 @@
 				<span class="noticeMessage"> NumberTextBox class, Attributes: required=true, must be integer, no messages provided,  no initial value specified, maxlength=3</span>
 			</div>
 			<div class="testExample">
-				<input id="fav" type="text" name="fav" class="small"
-					dojoType="dijit.form.NumberTextBox"
-					maxLength="3"
-					constraints="{places:0,min:1,max:100}"
-					regExpGen="return '\\d+'"
-					required="true">
+				<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'/>
 					<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>
@@ -142,25 +206,25 @@
 			<div class="dojoTitlePaneLabel">
 				<label for="q04">Occupation:  </label>
 				<span class="noticeMessage">ValidationTextBox class,
-					Attributes: {lowercase: true, required: true, class: verylong, style: font-size: 15pt;}. Displays a prompt message if field is blank.</span>
+					Attributes: {lowercase: true, required: true, "class": verylong, style: font-size: 15pt;}. Displays a prompt message if field is blank.</span>
 			</div>
 			<div class="testExample">
-				<input id="q04" type="text" name="occupation" class="verylong" style="font-size:15pt;"
-					dojoType="dijit.form.ValidationTextBox"
-					lowercase="true"
-					required="true"
-					promptMessage="Enter an occupation" />
+				<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" '/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
 				<label for="q05">Elevation:  </label>
 				<span class="noticeMessage">IntegerTextBox class,
 					Attributes: {required: true, min:-20000, max:+20000 }, displays a prompt message if field is blank, thousands separator remains during editing.</span>
-				<span calss="noticeMessage">Enter feet above sea level with a sign.</span>
+				<span class="noticeMessage">Enter feet above sea level with a sign.</span>
 			</div>
 			<div class="testExample">
 				<input id="q05" class="small"/>
-				onChange:<input id="oc5" size="10" disabled value="not fired yet!" autocomplete="off">
+				onChange:<input id="oc5" size="10" disabled value="not fired yet!" autocomplete="off"/>
 			</div>
 <script>
 	// See if we can make a widget in script and attach it to the DOM ourselves.
@@ -173,7 +237,7 @@
 			required: true,
 			editOptions:{pattern:'#,##0'},
 			invalidMessage: "Invalid elevation.",
-			onChange: function(){dojo.byId('oc5').value=arguments[0]},
+			onChange: function(val){dojo.byId('oc5').value = val; },
 			"class": "medium"
 		};
 		var w = new dijit.form.NumberTextBox(props, "q05");
@@ -212,7 +276,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q06" type="text" name="real1" class="medium" value="+0.1234"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.realNumber"
 					trim="true"
 					required="true"
@@ -225,7 +289,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q07" type="text" name="real2" class="medium" value="+0.12"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.realNumber"
 					trim="true"
 					required="true"
@@ -241,24 +305,24 @@
 			</div>
 
 			<div class="testExample">
-				<input id="q08" type="text" name="income1" class="medium" value="54775.53"
-					dojoType="dijit.form.CurrencyTextBox"
-					required="true"
-					constraints="{fractional:true}"
-					currency="USD"
-				        onChange="dojo.byId('oc8').value=arguments[0]"
-					invalidMessage="Invalid amount.  Cents are MANDATORY." />USD
-				 onChange:<input id="oc8" size="15" disabled value="not fired yet!" autocomplete="off">
+				<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
+				 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" type="text" name="income2"
-					class="medium" value="54775.53"
-					dojoType="dijit.form.CurrencyTextBox"
-					required="true"
-					currency="EUR"
-					invalidMessage="Invalid amount.  Include cents." />EUR
+				<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
 				<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>
@@ -298,7 +362,7 @@
 			</div>
 			<div class="testExample">
 				<input id="q08a" type="text" name="income3" class="medium" value="$54,775.53"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.currency"
 					trim="true"
 					required="true"
@@ -313,12 +377,12 @@
 			</div>
 			<div class="testExample">
 				<input id="q09" type="text" name="ipv4" class="medium" value="24.17.155.40"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.ipAddress"
 					trim="true"
 					required="true"
 					constraints="{allowIPv6:false,allowHybrid:false}"
-					invalidMessage="Invalid IPv4 address.">
+					invalidMessage="Invalid IPv4 address."/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -329,13 +393,13 @@
 			</div>
 			<div class="testExample">
 				<input id="q10" type="text" name="ipv6" class="long" value="0000:0000:0000:0000:0000:0000:0000:0000"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.ipAddress"
 					trim="true"
 					uppercase = "true"
 					required="true"
 					constraints="{allowDottedDecimal:false, allowDottedHex:false, allowDottedOctal:false}"
-					invalidMessage="Invalid IPv6 address, please enter eight groups of four hexadecimal digits. x:x:x:x:x:x:x:x">
+					invalidMessage="Invalid IPv6 address, please enter eight groups of four hexadecimal digits. x:x:x:x:x:x:x:x"/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -346,7 +410,7 @@
 
 			<div class="testExample">
 				<input id="q11" type="text" name="url" class="long" value="http://www.xyz.com/a/b/c?x=2#p3"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.url"
 					trim="true"
 					required="true"
@@ -362,7 +426,7 @@
 
 			<div class="testExample">
 				<input id="q12" type="text" name="email" class="long" value="fred&barney at stonehenge.com"
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.emailAddress"
 					trim="true"
 					required="true"
@@ -377,7 +441,7 @@
 
 			<div class="testExample">
 				<input id="q13" type="text" name="email" class="long" value="a at xyz.com; b at xyz.com; c at xyz.com; "
-					dojoType="dijit.form.ValidationTextBox"
+					data-dojo-type="dijit.form.ValidationTextBox"
 					regExpGen="dojo.regexp.emailAddressList"
 					trim="true"
 					required="true"
@@ -390,11 +454,11 @@
 					Attributes: {required: true} </span>
 			</div>
 			<div class="testExample">
-				<input id="q22" type="text" name="phone" class="medium" value="someTestString"
-					dojoType="dijit.form.ValidationTextBox"
-					regExp="[\w]+"
-					required="true"
-					invalidMessage="Invalid Non-Space Text.">
+				<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."'/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -402,8 +466,8 @@
 				<span class="noticeMessage">(just a test that type attribute is obeyed) </span>
 			</div>
 			<div class="testExample">
-				<input id="q23" type="password" name="password" class="medium"
-					dojoType="dijit.form.TextBox">
+				<input id="q23" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"password", name:"password", "class":"medium"
+					'/>
 			</div>
 
 			<div class="dojoTitlePaneLabel">
@@ -415,15 +479,17 @@
 			</div>
 
 			<script>
-					// See if we can make a widget in script and attach it to the DOM ourselves.
-					dojo.addOnLoad(function(){
-							var props = {
-									name: "ticket1651",
-									id: "mname",
-									value: null
-							};
-							var w = new dijit.form.TextBox(props, "ticket1651");
-					});
+				// See if we can make a widget in script and attach it to the DOM ourselves.
+				dojo.addOnLoad(function(){
+					var props = {
+							name: "ticket1651",
+							id: "mname",
+							templateString: null, // #11493
+							templatePath: dojo.moduleUrl('dijit.form', 'templates/TextBox.html'),
+							value: null
+					};
+					var w = new dijit.form.TextBox(props, "ticket1651");
+				});
 			</script>
 
 			<div class="dojoTitlePaneLabel">
@@ -431,27 +497,27 @@
 				<span class="noticeMessage">a test that readOnly and disabled are understood for TextBox</span>
 			</div>
 			<div class="testExample">
-				<input id="q24" type="text" name="readOnly" class="medium" readOnly value="cannot type here"
-					dojoType="dijit.form.TextBox">
-				<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">
-				<input type="button" onclick="dijit.byId('q24').set('disabled',true);" value="Set disabled" tabIndex="-1">
+				<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" '/>
+				<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"/>
+				<input type="button" onclick="dijit.byId('q24').set('disabled',true);" value="Set disabled" tabIndex="-1"/>
 			</div>
 			<div class="dojoTitlePaneLabel">
 				<label for="q25">initially disabled ValidationTextBox</label>
 				<span class="noticeMessage">a test that disabled is understood for ValidationTextBox</span>
 			</div>
 			<div class="testExample">
-				<input id="q25" type="text" name="disabled" class="medium" disabled value="cannot type here"
-					dojoType="dijit.form.ValidationTextBox">
-				<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">
-				<input type="button" onclick="dijit.byId('q25').set('disabled',true);" value="Set disabled" tabIndex="-1">
+				<input id="q25" data-dojo-type="dijit.form.ValidationTextBox"
+					data-dojo-props='name: "disabled", "class": "medium", disabled: true, 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"/>
+				<input type="button" onclick="dijit.byId('q25').set('disabled',true);" value="Set disabled" tabIndex="-1"/>
 			</div>
 
-		        <script>
+			<script>
 				// so robot can get to it easily
 				document.displayData=function() {
 					var f = document.getElementById("form1");
@@ -463,7 +529,7 @@
 					}
 					return s;
 				}
-		        </script>
+			</script>
 
 			<div>
 				<button name="button" onclick="alert(document.displayData()); return false;" tabIndex="-1">view data</button>
@@ -476,8 +542,8 @@
 				<span class="noticeMessage">a test that placeholder works for TextBox.  10px padding added for testing.</span>
 		</div>
 		<div class="testExample">
-			<input id="q26" type="text" placeHolder="placeholder is here" name="placeHolder" value=""
-						dojoType="dijit.form.TextBox">
+			<input id="q26" data-dojo-type="dijit.form.TextBox" data-dojo-props='placeHolder:"placeholder is here", name:"placeHolder", value:""
+						'/>
 		</div>
 		<h2>Tooltip positioning</h2>
 		<p>
@@ -487,5 +553,12 @@
 		</p>
 		<button onclick="dijit.Tooltip.defaultPosition=['above', 'below'];">above, below</button>
 		<button onclick="dijit.Tooltip.defaultPosition=['after', 'before'];">after, before (default)</button>
+
+		<div class="monospace">
+			<input id="monospace1"/>
+		</div>
+		<div class="sans">
+			<input id="sans1"/>
+		</div>
 	</body>
 </html>
diff --git a/dijit/tests/form/test_validationState.html b/dijit/tests/form/test_validationState.html
deleted file mode 100644
index 405f979..0000000
--- a/dijit/tests/form/test_validationState.html
+++ /dev/null
@@ -1,102 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>Test Form Validation State</title>
-
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.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"
-			djConfig="isDebug: true, parseOnLoad: true, extraLocale: ['de-de', 'en-us']"></script>
-
-		<!-- only needed for alternate theme testing: -->
-		<script type="text/javascript" src="../_testCommon.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.form.ValidationTextBox");
-			dojo.require("dijit.form.DateTextBox");
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.form.FilteringSelect");
-			dojo.require("dijit.form.Form");
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-		</script>
-	</head>
-
-	<body class="claro">
-		<h1 class="testTitle">Dijit Validation State</h1>
-		<form dojoType="dijit.form.Form" id="form1" action="" name="example" method="">
-			<table>
-				<tr>
-					<td><label for="name">Name:</label></td>
-					<td><input id="name" dojoType="dijit.form.ValidationTextBox"
-						required="true" name="name" /></td>
-				</tr>
-				<tr id="newRow" style="display: none;">
-					<td><label for="lastName">Last Name:</label></td>
-					<td><input id="lastName" /></td>
-				</tr>
-				<tr>
-					<td><label for="birth">Birthdate (before 2006-12-31):</label></td>
-					<td><div><input id="birth" dojoType="dijit.form.DateTextBox" value="2000-01-01"
-						required="true" name="birth" constraints="{min:'1900-01-01', max:'2006-12-31'}" />
-					<button onclick="dijit.byId('birth').set('disabled',true);return false">Disable</button>
-					<button onclick="dijit.byId('birth').set('disabled',false);return false">Enable</button>
-					<button onclick="dijit.byId('birth').reset();return false">Reset</button>
-					</div></td>
-				</tr>
-				<tr>
-					<td><label for="notes">Notes (optional)</label></td>
-					<td><input id="notes" dojoType="dijit.form.TextBox"
-						name="notes" /></td>
-				</tr>
-				<tr id="newRow2" style="display: none;">
-					<td><label for="color">Favorite Color</label></td>
-					<td><select id="color">
-						<option value="red">Red</option>
-						<option value="yellow">Yellow</option>
-						<option value="blue">Blue</option>
-					</select></td>
-				</tr>
-			</table>
-			<button dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
-					console.dir(dijit.byId("form1").get('value'));
-				</script>
-				<script type="dojo/method" 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 dojoType="dijit.form.Button">
-				<script type="dojo/method" event="onClick">
-					new dijit.form.FilteringSelect({name: "color",
-													required: true},
-													dojo.byId("color"));
-					new dijit.form.ValidationTextBox({name: "lastName",
-													required: true},
-													dojo.byId("lastName"));
-					dojo.byId("newRow").style.display = "";
-					dojo.byId("newRow2").style.display = "";
-					this.set("disabled", true);
-					this.domNode.blur();
-					// Call this, since we added a new widget - so that our
-					// form knows that we have something else to watch.
-					dijit.byId("form1").connectChildren();
-				</script>
-				Add More Fields
-			</button>
-		</form>
-	</body>
-</html>
diff --git a/dijit/tests/form/test_verticalAlign.html b/dijit/tests/form/test_verticalAlign.html
new file mode 100644
index 0000000..ed3fd18
--- /dev/null
+++ b/dijit/tests/form/test_verticalAlign.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dojo Form Widget Vertical Alignment Test</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../css/dijitTests.css";
+		BUTTON, SELECT, INPUT {
+			vertical-align: middle;
+		}
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.DropDownButton");
+		dojo.require("dijit.form.ComboButton");
+		dojo.require("dijit.Menu");
+		dojo.require("dijit.MenuItem");
+		dojo.require("dijit.form.Select");
+		dojo.require("dijit.form.ComboBox");
+		dojo.require("dijit.form.TextBox");
+		dojo.require("dijit.form.NumberTextBox");
+		dojo.require("dojo.parser");
+
+		dojo.addOnLoad(function(){
+
+			function test_all(pre){
+				function compare2native(className){
+					var
+						widget = dijit.byId(pre + "_" + className),
+						pos = dojo.position(widget.domNode),
+						mid = pos.y + (pos.h >> 1);
+
+					doh.t(Math.abs(mid - native_mid) <= 1, "native y:h = " + native_pos.y + ":" + native_pos.h + ", " + className + " y:h = " + pos.y + ":" + pos.h);
+				}
+				var
+					nativeNode = dojo.byId(pre+"_native"),
+					native_pos = dojo.position(nativeNode),
+					native_mid = native_pos.y + (native_pos.h >> 1);
+
+				compare2native("Button");
+				compare2native("DropDown");
+				compare2native("ComboButton");
+				compare2native("Select");
+				compare2native("ComboBox");
+				compare2native("TextBox");
+				compare2native("NumberTextBox");
+			}
+					
+			doh.register("check alignment", [
+				{
+					name: "p",
+					runTest: function(){
+						test_all("p");
+					}
+				},
+				{
+					name: "div",
+					runTest: function(){
+						test_all("div");
+					}
+				},
+				{
+					name: "font",
+					runTest: function(){
+						test_all("font");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="testTitle">Dojo Form Widget Vertical Alignment Test</h1>
+
+	<p>In a P</p>
+	<p class="box"><span style='white-space:nowrap;'>
+		<button id="p_native">native</button>
+		<button id="p_Button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Button"'>
+			Button
+		</button>
+		<button id="p_DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
+			<span data-dojo-type="dijit.Menu" data-dojo-props='style:"display:none;"'>
+				<span data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+			</span>
+		</button>
+		<button id="p_ComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
+			<span>Create</span>
+			<span data-dojo-type="dijit.Menu">
+				<span data-dojo-type="dijit.MenuItem">One</span>
+				<span data-dojo-type="dijit.MenuItem">Two</span>
+			</span>
+		</button>
+		<label for="p_Select">Select</label>
+		<select id="p_Select" data-dojo-type="dijit.form.Select">
+			<option value="one">one</option>
+			<option value="two">two</option>
+			<option value="three">three</option>
+			<option value="four">four</option>
+		</select>
+		<label for="p_ComboBox">ComboBox</label>
+		<select id="p_ComboBox" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{width:"5em"}'>
+			<option value="one">one</option>
+			<option value="two">two</option>
+			<option value="three">three</option>
+			<option value="four">four</option>
+		</select>
+		<label for="p_TextBox">TextBox</label>
+		<input id="p_TextBox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
+		<label for="p_NumberTextBox">NumberTextBox</label>
+		<input id="p_NumberTextBox" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
+	</span></p>
+
+	<p>In a DIV</p>
+	<div><span style='white-space:nowrap;'>
+		<button id="div_native">native</button>
+		<button id="div_Button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Create"'>
+			Button
+		</button>
+		<button id="div_DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
+			<span data-dojo-type="dijit.Menu">
+				<span data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+			</span>
+		</button>
+		<button id="div_ComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
+			<span>Create</span>
+			<span data-dojo-type="dijit.Menu">
+				<span data-dojo-type="dijit.MenuItem">One</span>
+				<span data-dojo-type="dijit.MenuItem">Two</span>
+			</span>
+		</button>
+		<label for="div_Select">Select</label>
+		<select id="div_Select" data-dojo-type="dijit.form.Select">
+			<option value="one">one</option>
+			<option value="two">two</option>
+			<option value="three">three</option>
+			<option value="four">four</option>
+		</select>
+		<label for="div_ComboBox">ComboBox</label>
+		<select id="div_ComboBox" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{width:"5em"}'>
+			<option value="one">one</option>
+			<option value="two">two</option>
+			<option value="three">three</option>
+			<option value="four">four</option>
+		</select>
+		<label for="div_TextBox">TextBox</label>
+		<input id="div_TextBox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
+		<label for="div_NumberTextBox">NumberTextBox</label>
+		<input id="div_NumberTextBox" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
+	</span></div>
+
+	<p>font-size 200%</p>
+	<div style="font-size: 200%;"><span style='white-space:nowrap;'>
+		<button id="font_native">native</button>
+		<button id="font_Button" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", iconClass:"plusIcon", value:"Button"'>
+			Button
+		</button>
+		<button id="font_DropDown" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='type:"button", value:"DropDown", label:"DropDown"'>
+			<span data-dojo-type="dijit.Menu"'>
+				<span data-dojo-type="dijit.MenuItem">DropDown MenuItem</span>
+			</span>
+		</button>
+		<button id="font_ComboButton" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"options", iconClass:"plusIcon", title:"title"'>
+			<span>Create</span>
+			<span data-dojo-type="dijit.Menu">
+				<span data-dojo-type="dijit.MenuItem">One</span>
+				<span data-dojo-type="dijit.MenuItem">Two</span>
+			</span>
+		</button>
+		<label for="font_Select">Select</label>
+		<select id="font_Select" data-dojo-type="dijit.form.Select">
+			<option value="one">one</option>
+			<option value="two">two</option>
+			<option value="three">three</option>
+			<option value="four">four</option>
+		</select>
+		<label for="font_ComboBox">ComboBox</label>
+		<select id="font_ComboBox" data-dojo-type="dijit.form.ComboBox" data-dojo-props='style:{width:"5em"}'>
+			<option value="one">one</option>
+			<option value="two">two</option>
+			<option value="three">three</option>
+			<option value="four">four</option>
+		</select>
+		<label for="font_TextBox">TextBox</label>
+		<input id="font_TextBox" data-dojo-type="dijit.form.TextBox" data-dojo-props='value:"Text", style:{width:"5em"}'/>
+		<label for="font_NumberTextBox">NumberTextBox</label>
+		<input id="font_NumberTextBox" data-dojo-type="dijit.form.NumberTextBox" data-dojo-props='value:23, style:{width:"3em"}'/>
+	</span></div>
+
+</body>
+</html>
diff --git a/dijit/tests/general-module.js b/dijit/tests/general-module.js
index 7e57f72..ffd42bb 100644
--- a/dijit/tests/general-module.js
+++ b/dijit/tests/general-module.js
@@ -4,26 +4,39 @@ try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?");
 
 	// top level widget tests
-	doh.registerUrl("dijit.tests.robot.Menu_mouse", dojo.moduleUrl("dijit","tests/robot/Menu_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.robot.Menu_a11y", dojo.moduleUrl("dijit","tests/robot/Menu_a11y.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.Bidi", dojo.moduleUrl("dijit","tests/Bidi.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.Dialog_mouse", dojo.moduleUrl("dijit","tests/robot/Dialog_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.robot.Dialog_a11y", dojo.moduleUrl("dijit","tests/robot/Dialog_a11y.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.robot.Menu_mouse", dojo.moduleUrl("dijit","tests/robot/Menu_mouse.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Menu_a11y", dojo.moduleUrl("dijit","tests/robot/Menu_a11y.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Menu_iframe", dojo.moduleUrl("dijit","tests/robot/Menu_iframe.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.Tooltip_mouse", dojo.moduleUrl("dijit","tests/robot/Tooltip_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.robot.Tooltip_a11y", dojo.moduleUrl("dijit","tests/robot/Tooltip_a11y.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.Dialog", dojo.moduleUrl("dijit","tests/Dialog.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Dialog_mouse", dojo.moduleUrl("dijit","tests/robot/Dialog_mouse.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Dialog_a11y", dojo.moduleUrl("dijit","tests/robot/Dialog_a11y.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Dialog_focusDestroy", dojo.moduleUrl("dijit","tests/robot/Dialog_focusDestroy.html"+userArgs), 999999);
+	
+	doh.registerUrl("dijit.tests.ProgressBar", dojo.moduleUrl("dijit","tests/ProgressBar.html"+userArgs), 999999);
+	
+	doh.registerUrl("dijit.tests.robot.Tooltip_a11y", dojo.moduleUrl("dijit","tests/robot/Tooltip_a11y.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Tooltip_mouse", dojo.moduleUrl("dijit","tests/robot/Tooltip_mouse.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.Tooltip_mouse_quirks", dojo.moduleUrl("dijit","tests/robot/Tooltip_mouse_quirks.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.Tooltip-placement", dojo.moduleUrl("dijit","tests/Tooltip-placement.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.TooltipDialog_mouse", dojo.moduleUrl("dijit","tests/robot/TooltipDialog_mouse.html"+userArgs), 99999999);
-	doh.registerUrl("dijit.tests.robot.TooltipDialog_a11y", dojo.moduleUrl("dijit","tests/robot/TooltipDialog_a11y.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.robot.TooltipDialog_mouse", dojo.moduleUrl("dijit","tests/robot/TooltipDialog_mouse.html"+userArgs), 999999);
+	doh.registerUrl("dijit.tests.robot.TooltipDialog_a11y", dojo.moduleUrl("dijit","tests/robot/TooltipDialog_a11y.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.InlineEditBox", dojo.moduleUrl("dijit","tests/robot/InlineEditBox.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.robot.InlineEditBox", dojo.moduleUrl("dijit","tests/robot/InlineEditBox.html"+userArgs), 999999);
+	
+	doh.registerUrl("dijit.tests.robot.ColorPalette", dojo.moduleUrl("dijit","tests/robot/ColorPalette.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.ColorPalette", dojo.moduleUrl("dijit","tests/robot/ColorPalette.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.robot.Calendar_a11y", dojo.moduleUrl("dijit","tests/robot/Calendar_a11y.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.TitlePane", dojo.moduleUrl("dijit","tests/robot/TitlePane.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.robot.TitlePane", dojo.moduleUrl("dijit","tests/robot/TitlePane.html"+userArgs), 999999);
 
-	doh.registerUrl("dijit.tests.robot.Toolbar", dojo.moduleUrl("dijit","tests/robot/Toolbar.html"+userArgs), 99999999);
+	doh.registerUrl("dijit.tests.robot.Toolbar", dojo.moduleUrl("dijit","tests/robot/Toolbar.html"+userArgs), 999999);
+
+	doh.registerUrl("dijit.tests.robot.BgIframe", dojo.moduleUrl("dijit","tests/robot/BgIframe.html"+userArgs), 999999);
 
 }catch(e){
 	doh.debug(e);
-}
\ No newline at end of file
+}
diff --git a/dijit/tests/helpers.js b/dijit/tests/helpers.js
index 297aaad..4aea33e 100644
--- a/dijit/tests/helpers.js
+++ b/dijit/tests/helpers.js
@@ -1,19 +1,74 @@
 // Helper methods for automated testing
 
-function isVisible(node){
-		if(node.domNode){ node = node.domNode; }
-		return (dojo.style(node, "display") != "none") &&
-				(dojo.style(node, "visibility") != "hidden") &&
-				(dojo.position(node).y + (dojo._getBorderExtents(node).t || 0) >= 0); // border check is for claro prone to shifting the border offscreen
+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), p.y + p.h >= 0 && p.x + p.w >= 0 && p.h && p.w);
 }
 
-function isHidden(node){
-		if(node.domNode){ node = node.domNode; }
-		return (dojo.style(node, "display") == "none") ||
-				(dojo.style(node, "visibility") == "hidden") ||
-				(dojo.position(node).y < 0); // + dojo.position(node).h ??
+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), p.y + p.h < 0 || p.x + p.w < 0 || p.h <= 0 || p.w <= 0);
 }
 
-function innerText(node){
+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/dijit/tests/i18n/calendar.html b/dijit/tests/i18n/calendar.html
index cf2e855..a23f9d7 100644
--- a/dijit/tests/i18n/calendar.html
+++ b/dijit/tests/i18n/calendar.html
@@ -1,23 +1,17 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 	<head>
-		<title>Calendar Widget Test</title>
-
-		<!-- for tests -->
-		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../css/dijitTests.css";
-		</style>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+		<title>Calendar I18N Test</title>
 
 		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js.
 			Explicitly include extra locales because this example has multiple locales
 			on the page besides the browser's default.  -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="parseOnLoad: true, isDebug: true, extraLocale: ['en-us', 'ar-sy', 'es-es', 'zh-cn']"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true, extraLocale: ['en-us', 'ar-sy', 'es-es', 'zh-cn']"></script>
 
 		<!-- not needed, for testing alternate themes -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -28,25 +22,6 @@
 			dojo.require("dojo.date.locale");
 			dojo.require("dojo.parser"); // scan page for widgets
 
-			dojo.addOnLoad(function(){
-				//Need to declare BigCalendar here in an addOnLoad block so that it works
-				//with xdomain loading, where the dojo.require for dijit.Calendar
-				//may load asynchronously. This also means we cannot have HTML
-				//markup in the body tag for BigCalendar, but instead inject it in this
-				//onload handler after BigCalendar is defined.
-				dojo.declare("BigCalendar", dijit.Calendar, {
-					templateString: dojo.cache("dijit", "tests/_altCalendar.html"),
-					isDisabledDate: dojo.date.locale.isWeekend,
-					getClassForDate: function(date){
-						if(!(date.getDate() % 10)){ return "blue"; } // apply special style to all days divisible by 10
-					}
-				});
-
-				var bigCalendar = dojo.byId("calendar5");
-				bigCalendar.setAttribute("dojoType", "BigCalendar");
-				dojo.parser.parse(bigCalendar.parentNode);
-			});
-
 			function myHandler(id,newValue){
 				console.debug("onChange for id = " + id + ", value: " + newValue);
 			}
@@ -54,40 +29,16 @@
 	</head>
 	<body class="claro">
 
-		<h1 class="testTitle">Dijit Calendar Test</h1>
+		<h1 class="testTitle">Dijit Calendar I18N Test</h1>
 
 		before
-		<input id="calendar1" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])" lang="en-us">
-		<input id="calendar2" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])" lang="es-es">
-		<input id="calendar3" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])" lang="zh-cn">
-		<input id="calendar4" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])" lang="ar-sy">
+
+		<input id="calendar1" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"en-us"'/>
+		<input id="calendar2" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"es-es"'/>
+		<input id="calendar3" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"zh-cn"'/>
+		<input id="calendar4" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(val){ myHandler(this.id, val); }, lang:"ar-sy"'/>
+
 		after
-		<p>
-			<a href="#"
-			   onClick="for(var i=1; i!=5; i++){
-						var c = dijit.byId('calendar'+i);
-						c.isDisabledDate=dojo.date.locale.isWeekend;
-						c._populateGrid();
-					}
-				">disable weekends</a>
-		</p>
 
-		<p>Customized template with "today" button</p>
-		<style>
-			#calendar5 .dijitCalendarDateTemplate { height: 50px; width: 50px; border: 1px solid #ccc; vertical-align: top }
-			#calendar5 .dijitCalendarDateLabel, #calendar5 .dijitCalendarDateTemplate { text-align: inherit }
-			#calendar5 .dijitCalendarDayLabel { font-weight: bold }
-			#calendar5 .dijitCalendarSelectedYear { font-size: 1.5em }
-			#calendar5 .dijitCalendarMonth { font-family: serif; letter-spacing: 0.2em; font-size: 2em }
-			.blue { color: blue }
-		</style>
-		<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" dayWidth="abbr" value="2008-03-15">
-		</div>
-<!--
-		<input id="calendar5" dojoType="dijit.Calendar" dayWidth="abbr" templatePath="../dijit/tests/_altCalendar.html" value="2008-03-15">
- -->
 	</body>
 </html>
diff --git a/dijit/tests/i18n/currency.html b/dijit/tests/i18n/currency.html
index ca73528..697da59 100644
--- a/dijit/tests/i18n/currency.html
+++ b/dijit/tests/i18n/currency.html
@@ -29,8 +29,8 @@
 		</script>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../themes/tundra/tundra.css";
+			@import "../../themes/claro/document.css";
+			@import "../../themes/claro/claro.css";
 			@import "../css/dijitTests.css";
 
 			.title {
diff --git a/dijit/tests/i18n/date.html b/dijit/tests/i18n/date.html
index 6b3354f..1e982c6 100644
--- a/dijit/tests/i18n/date.html
+++ b/dijit/tests/i18n/date.html
@@ -29,8 +29,8 @@
 		</script>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../themes/tundra/tundra.css";
+			@import "../../themes/claro/document.css";
+			@import "../../themes/claro/claro.css";
 			@import "../css/dijitTests.css";
 
 			.title {
diff --git a/dijit/tests/i18n/digit.html b/dijit/tests/i18n/digit.html
index 3890100..9b421d7 100644
--- a/dijit/tests/i18n/digit.html
+++ b/dijit/tests/i18n/digit.html
@@ -61,8 +61,8 @@
 			}
 		</script>
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../themes/tundra/tundra.css";
+			@import "../../themes/claro/document.css";
+			@import "../../themes/claro/claro.css";
 			@import "../css/dijitTests.css";
 
 			.title {
diff --git a/dijit/tests/i18n/module.js b/dijit/tests/i18n/module.js
index aa62367..40cc667 100644
--- a/dijit/tests/i18n/module.js
+++ b/dijit/tests/i18n/module.js
@@ -2,12 +2,12 @@ dojo.provide("dijit.tests.i18n.module");
 
 try{
 	if(dojo.isBrowser){
-		doh.registerUrl("dijit.tests.i18n.currency", dojo.moduleUrl("dijit", "tests/i18n/currency.html"), 99999999);
-		doh.registerUrl("dijit.tests.i18n.date", dojo.moduleUrl("dijit", "tests/i18n/date.html"), 99999999);
-		doh.registerUrl("dijit.tests.i18n.number", dojo.moduleUrl("dijit", "tests/i18n/number.html"), 99999999);
-		doh.registerUrl("dijit.tests.i18n.textbox", dojo.moduleUrl("dijit", "tests/i18n/textbox.html"), 99999999);
-		doh.registerUrl("dijit.tests.i18n.time", dojo.moduleUrl("dijit", "tests/i18n/time.html"), 99999999);
-		doh.registerUrl("dijit.tests.i18n.digit", dojo.moduleUrl("dijit", "tests/i18n/digit.html"), 99999999);
+		doh.registerUrl("dijit.tests.i18n.currency", dojo.moduleUrl("dijit", "tests/i18n/currency.html"), 999999);
+		doh.registerUrl("dijit.tests.i18n.date", dojo.moduleUrl("dijit", "tests/i18n/date.html"), 999999);
+		doh.registerUrl("dijit.tests.i18n.number", dojo.moduleUrl("dijit", "tests/i18n/number.html"), 999999);
+		doh.registerUrl("dijit.tests.i18n.textbox", dojo.moduleUrl("dijit", "tests/i18n/textbox.html"), 999999);
+		doh.registerUrl("dijit.tests.i18n.time", dojo.moduleUrl("dijit", "tests/i18n/time.html"), 999999);
+		doh.registerUrl("dijit.tests.i18n.digit", dojo.moduleUrl("dijit", "tests/i18n/digit.html"), 999999);
 	}
 }catch(e){
 	doh.debug(e);
diff --git a/dijit/tests/i18n/number.html b/dijit/tests/i18n/number.html
index 774eddf..000366f 100644
--- a/dijit/tests/i18n/number.html
+++ b/dijit/tests/i18n/number.html
@@ -29,8 +29,8 @@
 		</script>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../themes/tundra/tundra.css";
+			@import "../../themes/claro/document.css";
+			@import "../../themes/claro/claro.css";
 			@import "../css/dijitTests.css";
 
 			.title {
diff --git a/dijit/tests/i18n/test_i18n.js b/dijit/tests/i18n/test_i18n.js
index caac878..2e0d6fd 100644
--- a/dijit/tests/i18n/test_i18n.js
+++ b/dijit/tests/i18n/test_i18n.js
@@ -54,7 +54,7 @@ function getAllTestCases(){
 			runTest: new Function("t", "startTestFormat(" + i + ", t)")
 		});
 	}
-	for(var i = 0; i < validateWidgetCount; i++){
+	for(i = 0; i < validateWidgetCount; i++){
 		allTestCases.push({
 			name: "validate-" + i,
 			runTest: new Function("t", "startTestValidate(" + i + ", t)")
@@ -117,21 +117,24 @@ function startTestValidate(i, t){
 }
 
 function genFormatTestCase(desc, dojoType, dojoAttrs, value, expValue, comment){
-	dojo.doc.write("<tr>");
-	dojo.doc.write("<td>" + desc + "</td>");
-	dojo.doc.write("<td>");
-	dojo.doc.write("<input id='test_display_" + formatWidgetCount + "' type='text' value='" + value + "' ");
-	dojo.doc.write("dojoType='" + dojoType + "' ");
+	var res = "";
+	res += "<tr>";
+	res += "<td>" + desc + "</td>";
+	res += "<td>";
+	res += "<input id='test_display_" + formatWidgetCount + "' type='text' value='" + value + "' ";
+	res += "dojoType='" + dojoType + "' ";
 	for(var attr in dojoAttrs){
-		dojo.doc.write(attr + "=\"" + dojoAttrs[attr] + "\" ");
+		res += attr + "=\"" + dojoAttrs[attr] + "\" ";
 	}
-	dojo.doc.write("/>");
-	dojo.doc.write("</td>");
-	dojo.doc.write("<td><input id='test_display_expected_" + formatWidgetCount + "' value='" + expValue + "'></td>");
-	dojo.doc.write("<td id='test_display_result_" + formatWidgetCount + "'></td>");
-	dojo.doc.write("<td style='white-space:normal'>" + comment + "</td>");
-	dojo.doc.write("</tr>");
+	res += "/>";
+	res += "</td>";
+	res += "<td><input id='test_display_expected_" + formatWidgetCount + "' value='" + expValue + "'></td>";
+	res += "<td id='test_display_result_" + formatWidgetCount + "'></td>";
+	res += "<td style='white-space:normal'>" + comment + "</td>";
+	res += "</tr>";
 	formatWidgetCount++;
+	
+	return res;
 }
 /*
 [
@@ -140,43 +143,49 @@ function genFormatTestCase(desc, dojoType, dojoAttrs, value, expValue, comment){
 ]
 */
 function genFormatTestCases(title, dojoType, testCases){
-	dojo.doc.write("<h2 class=testTitle>" + title + "</h2>");
-	dojo.doc.write("<table border=1>");
-	dojo.doc.write("<tr>");
-	dojo.doc.write("<td class=title><b>Test Description</b></td>");
-	dojo.doc.write("<td class=title><b>Test</b></td>");
-	dojo.doc.write("<td class=title><b>Expected</b></td>");
-	dojo.doc.write("<td class=title><b>Result</b></td>");
-	dojo.doc.write("<td class=title><b>Comment</b></td>");
-	dojo.doc.write("</tr>");
+	var res = "";
+	res += "<h2 class=testTitle>" + title + "</h2>";
+	res += "<table border=1>";
+	res += "<tr>";
+	res += "<td class=title><b>Test Description</b></td>";
+	res += "<td class=title><b>Test</b></td>";
+	res += "<td class=title><b>Expected</b></td>";
+	res += "<td class=title><b>Result</b></td>";
+	res += "<td class=title><b>Comment</b></td>";
+	res += "</tr>";
 
 	for(var i = 0; i < testCases.length; i++){
 		var testCase = testCases[i];
-		genFormatTestCase(testCase.desc, dojoType, testCase.attrs, testCase.value, testCase.expValue, testCase.comment);
+		res += genFormatTestCase(testCase.desc, dojoType, testCase.attrs, testCase.value, testCase.expValue, testCase.comment);
 	}
 
-	dojo.doc.write("</table>");
+	res += "</table>";
+	
+	dojo.place(res, dojo.body());
 }
 
 function genValidateTestCase(desc, dojoType, dojoAttrs, input, value, comment, isWrong){
-	dojo.doc.write("<tr>");
-	dojo.doc.write("<td>" + desc + "</td>");
-	dojo.doc.write("<td>");
-	dojo.doc.write("<input id='test_validate_" + validateWidgetCount + "' type='text' ");
-	dojo.doc.write("dojoType='" + dojoType + "' ");
+	var res = "";
+	res += "<tr>";
+	res += "<td>" + desc + "</td>";
+	res += "<td>";
+	res += "<input id='test_validate_" + validateWidgetCount + "' type='text' ";
+	res += "dojoType='" + dojoType + "' ";
 	for(var attr in dojoAttrs){
-		dojo.doc.write(attr + "=\"" + dojoAttrs[attr] + "\" ");
+		res += attr + "=\"" + dojoAttrs[attr] + "\" ";
 	}
-	dojo.doc.write("/>");
-	dojo.doc.write("</td>");
-	dojo.doc.write("<td><input id='test_validate_input_" + validateWidgetCount + "' value='" + input + "'></td>");
-	dojo.doc.write("<td id='test_display_value_" + validateWidgetCount + "'></td>");
-	dojo.doc.write("<td id='test_validate_expected_" + validateWidgetCount + "'>" + (isWrong ? "Wrong" : "Correct") + "</td>");
-	dojo.doc.write("<td id='test_validate_result_" + validateWidgetCount + "'></td>");
-	dojo.doc.write("<td style='white-space:normal'>" + comment + "</td>");
-	dojo.doc.write("</tr>");
+	res += "/>";
+	res += "</td>";
+	res += "<td><input id='test_validate_input_" + validateWidgetCount + "' value='" + input + "'></td>";
+	res += "<td id='test_display_value_" + validateWidgetCount + "'></td>";
+	res += "<td id='test_validate_expected_" + validateWidgetCount + "'>" + (isWrong ? "Wrong" : "Correct") + "</td>";
+	res += "<td id='test_validate_result_" + validateWidgetCount + "'></td>";
+	res += "<td style='white-space:normal'>" + comment + "</td>";
+	res += "</tr>";
 	validateValues.push(value);
 	validateWidgetCount++;
+	
+	return res;
 }
 /*
 [
@@ -185,22 +194,24 @@ function genValidateTestCase(desc, dojoType, dojoAttrs, input, value, comment, i
 ]
 */
 function genValidateTestCases(title, dojoType, testCases){
-	dojo.doc.write("<h2 class=testTitle>" + title + "</h2>");
-	dojo.doc.write("<table border=1>");
-	dojo.doc.write("<tr>");
-	dojo.doc.write("<td class=title><b>Test Description</b></td>");
-	dojo.doc.write("<td class=title><b>Test</b></td>");
-	dojo.doc.write("<td class=title><b>Input</b></td>");
-	dojo.doc.write("<td class=title><b>Parsed Value</b></td>");
-	dojo.doc.write("<td class=title><b>Expected</b></td>");
-	dojo.doc.write("<td class=title><b>Result</b></td>");
-	dojo.doc.write("<td class=title><b>Comment</b></td>");
-	dojo.doc.write("</tr>");
+	var res = "";
+	res += "<h2 class=testTitle>" + title + "</h2>";
+	res += "<table border=1>";
+	res += "<tr>";
+	res += "<td class=title><b>Test Description</b></td>";
+	res += "<td class=title><b>Test</b></td>";
+	res += "<td class=title><b>Input</b></td>";
+	res += "<td class=title><b>Parsed Value</b></td>";
+	res += "<td class=title><b>Expected</b></td>";
+	res += "<td class=title><b>Result</b></td>";
+	res += "<td class=title><b>Comment</b></td>";
+	res += "</tr>";
 
 	for(var i = 0; i < testCases.length; i++){
 		var testCase = testCases[i];
-		genValidateTestCase(testCase.desc, dojoType, testCase.attrs, testCase.expValue, testCase.value, testCase.comment, testCase.isWrong);
+		res += genValidateTestCase(testCase.desc, dojoType, testCase.attrs, testCase.expValue, testCase.value, testCase.comment, testCase.isWrong);
 	}
 
-	dojo.doc.write("</table>");
+	res += "</table>";
+	dojo.place(res, dojo.body());
 }
diff --git a/dijit/tests/i18n/textbox.html b/dijit/tests/i18n/textbox.html
index f9b41c4..01087c0 100644
--- a/dijit/tests/i18n/textbox.html
+++ b/dijit/tests/i18n/textbox.html
@@ -29,8 +29,8 @@
 		</script>
 
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../themes/tundra/tundra.css";
+			@import "../../themes/claro/document.css";
+			@import "../../themes/claro/claro.css";
 			@import "../css/dijitTests.css";
 
 			.title {
diff --git a/dijit/tests/i18n/time.html b/dijit/tests/i18n/time.html
index c921183..99c0de6 100644
--- a/dijit/tests/i18n/time.html
+++ b/dijit/tests/i18n/time.html
@@ -5,31 +5,9 @@
 		<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 		<title>Test TextBox for Time</title>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp','ar-eg','ru-ru','hi-in','en-us']"></script>
-		<script type="text/javascript" src="../../../dojo/currency.js"></script>
-		<script type="text/javascript" src="../../../dojo/number.js"></script>
-		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit.form.ValidationTextBox");
-			dojo.require("dojo.date.locale");
-			dojo.require("dojo.date.stamp");
-			dojo.require("dojo.date");
-			dojo.require("dojo.string");
-			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-			dojo.require("doh.runner");
-		</script>
-		<script src="test_i18n.js"></script>
-		<script type="text/javascript">
-			dojo.addOnLoad(function(){
-				doh.register("t", getAllTestCases());
-				doh.run();
-			});
-		</script>
-
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
-			@import "../../themes/tundra/tundra.css";
+			@import "../../themes/claro/document.css";
+			@import "../../themes/claro/claro.css";
 			@import "../css/dijitTests.css";
 
 			.title {
@@ -53,156 +31,148 @@
 
 			td {white-space:nowrap}
 		</style>
-		<script>
-			dojo.declare(
-				"dijit.form.TimeTextBox",
-				dijit.form.ValidationTextBox,
-				{
-					regExpGen: dojo.date.locale.regexp,
-					format: dojo.date.locale.format,
-					parse: dojo.date.locale.parse,
-					value: new Date()
-				}
-			);
-
-			var tz_s = dojo.date.getTimezoneName(new Date());
-			if (!tz_s) {
-				var offset = new Date().getTimezoneOffset();
-				var tz = [
-					(offset <= 0 ? "+" : "-"),
-					dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2),
-					dojo.string.pad(Math.abs(offset) % 60, 2)
-				];
-				tz.splice(0, 0, "GMT");
-				tz.splice(3, 0, ":");
-				tz_s = tz.join("");
-			}
 
-			function gen4DateFormat(testCases, language, locale, date, short, shortCmt, medium, mediumCmt, long, longCmt, full, fullCmt) {
-				var tz_l = language.indexOf("hi") == 0 && dojo.number.normalizeDigitChars ?
-					dojo.number.normalizeDigitChars(tz_s, language) : tz_s;
-
-				short = short.replace(/UTC/, tz_l);
-				medium = medium.replace(/UTC/, tz_l);
-				long = long.replace(/UTC/g, tz_l);
-				full = full.replace(/UTC/, tz_l);
-
-				var shortDate = null;
-				testCases.push({
-				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'short', selector:'time', localeDigit:true}" : "{formatLength:'short', selector:'time'}",
-				  		lang: language},
-				  desc: "Locale: <b>" + locale + "</b> Format: <b>Short</b>",
-				  value: typeof(date) == "string" ? date : shortDate = new Date(date.getYear(), date.getMonth(), date.getDay() - 5, date.getHours(), date.getMinutes()),
-				  expValue: short,
-				  comment: shortCmt
-				});
-				testCases.push({
-				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'medium', selector:'time', localeDigit:true}" : "{formatLength:'medium', selector:'time'}",
-				  		lang: language},
-				  desc: "Locale: <b>" + locale + "</b> Format: <b>Medium</b>",
-				  value: date,
-				  expValue: medium,
-				  comment: mediumCmt
-				});
-				testCases.push({
-				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'long', selector:'time', localeDigit:true}" : "{formatLength:'long', selector:'time'}",
-				  		lang: language},
-				  desc: "Locale: <b>" + locale + "</b> Format: <b>Long</b>",
-				  value: date,
-				  expValue: long,
-				  comment: longCmt
-				});
-				testCases.push({
-				  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'full', selector:'time', localeDigit:true}" : "{formatLength:'full', selector:'time'}",
-				  		lang: language},
-				  desc: "Locale: <b>" + locale + "</b> Format: <b>Full</b>",
-				  //value: typeof(date) == "string" || language.indexOf("fr") ? date : shortDate,
-				  value: date,
-				  expValue: full,
-				  comment: fullCmt
-				});
-
-				date.processValue = function (value) {
-					return value ? new Date(1970, 0, 1, value.getHours(), value.getMinutes(), value.getSeconds()) : value;
-				};
-				if (shortDate) {
-					shortDate.processValue = date.processValue;
+		<script type="text/javascript" src="../../../dojo/dojo.js"
+			djConfig="isDebug: true, extraLocale: ['zh-cn','fr-fr','ja-jp','ar-eg','ru-ru','hi-in','en-us']"></script>
+		<script type="text/javascript" src="../../../dojo/currency.js"></script>
+		<script type="text/javascript" src="../../../dojo/number.js"></script>
+		<script type="text/javascript" src="test_i18n.js"></script>
+		<script type="text/javascript">
+			dojo.require("dijit.form.ValidationTextBox");
+			dojo.require("dojo.date.locale");
+			dojo.require("dojo.date.stamp");
+			dojo.require("dojo.date");
+			dojo.require("dojo.string");
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+			dojo.require("doh.runner");
+
+			dojo.addOnLoad(function(){
+				dojo.declare(
+					"dijit.form.TimeTextBox",
+					dijit.form.ValidationTextBox,
+					{
+						regExpGen: dojo.date.locale.regexp,
+						format: dojo.date.locale.format,
+						parse: dojo.date.locale.parse,
+						value: new Date()
+					}
+				);
+	
+				var tz_s = dojo.date.getTimezoneName(new Date());
+				if (!tz_s) {
+					var offset = new Date().getTimezoneOffset();
+					var tz = [
+						(offset <= 0 ? "+" : "-"),
+						dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2),
+						dojo.string.pad(Math.abs(offset) % 60, 2)
+					];
+					tz.splice(0, 0, "GMT");
+					tz.splice(3, 0, ":");
+					tz_s = tz.join("");
 				}
-			}
+	
+				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;
+	
+					shortFmt = shortFmt.replace(/UTC/, tz_l);
+					mediumFmt = mediumFmt.replace(/UTC/, tz_l);
+					longFmt = longFmt.replace(/UTC/g, tz_l);
+					full = full.replace(/UTC/, tz_l);
+	
+					var shortDate = null;
+					testCases.push({
+					  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'short', selector:'time', localeDigit:true}" : "{formatLength:'short', selector:'time'}",
+					  		lang: language},
+					  desc: "Locale: <b>" + locale + "</b> Format: <b>short</b>",
+					  value: typeof(date) == "string" ? date : shortDate = new Date(date.getYear(), date.getMonth(), date.getDay() - 5, date.getHours(), date.getMinutes()),
+					  expValue: shortFmt,
+					  comment: shortCmt
+					});
+					testCases.push({
+					  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'medium', selector:'time', localeDigit:true}" : "{formatLength:'medium', selector:'time'}",
+					  		lang: language},
+					  desc: "Locale: <b>" + locale + "</b> Format: <b>medium</b>",
+					  value: date,
+					  expValue: mediumFmt,
+					  comment: mediumCmt
+					});
+					testCases.push({
+					  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'long', selector:'time', localeDigit:true}" : "{formatLength:'long', selector:'time'}",
+					  		lang: language},
+					  desc: "Locale: <b>" + locale + "</b> Format: <b>long</b>",
+					  value: date,
+					  expValue: longFmt,
+					  comment: longCmt
+					});
+					testCases.push({
+					  attrs: {constraints: language.indexOf("hi") == 0 ? "{formatLength:'full', selector:'time', localeDigit:true}" : "{formatLength:'full', selector:'time'}",
+					  		lang: language},
+					  desc: "Locale: <b>" + locale + "</b> Format: <b>Full</b>",
+					  //value: typeof(date) == "string" || language.indexOf("fr") ? date : shortDate,
+					  value: date,
+					  expValue: full,
+					  comment: fullCmt
+					});
+	
+					date.processValue = function (value) {
+						return value ? new Date(1970, 0, 1, value.getHours(), value.getMinutes(), value.getSeconds()) : value;
+					};
+					if (shortDate) {
+						shortDate.processValue = date.processValue;
+					}
+				}
+
+				var testCases = [];
+				gen4DateFormat(testCases, "ru-ru", "ru_RU", "1970-01-01T15:25:35",
+					"15:25", "", "15:25:35", "", "15:25:35 UTC", "", "15:25:35 UTC", "");
+				gen4DateFormat(testCases, "zh-cn", "zh_CN", "1970-01-01T15:25:35",
+					"下午3:25", "", "下午03:25:35", "", "下午03时25分35秒", "", "下午03时25分35秒 UTC", "");
+				gen4DateFormat(testCases, "en-us", "en_US", "1970-01-01T15:25:35",
+					"3:25 PM", "", "3:25:35 PM", "", "3:25:35 PM UTC", "", "3:25:35 PM UTC", "");
+				gen4DateFormat(testCases, "fr-fr", "fr_FR", "1970-01-01T15:25:35",
+					"15:25", "", "15:25:35", "", "15:25:35 UTC", "", "15:25:35 UTC", "");
+				gen4DateFormat(testCases, "ja-jp", "ja_JP", "1970-01-01T15:25:35",
+					"15:25", "", "15:25:35", "", "15:25:35:UTC", "", "15時25分35秒UTC", "");
+				gen4DateFormat(testCases, "ar-eg", "ar_EG", "1970-01-01T15:25:35",
+					"3:25 \u0645", "", "3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "");
+				gen4DateFormat(testCases, "hi-in", "hi_IN", "1970-01-01T15:25:35",
+					"१५:२५", "", "१५:२५:३५", "", "१५:२५:३५ UTC", " ", "१५:२५:३५ UTC", " ");
+
+				genFormatTestCases("Time Format", "dijit.form.TimeTextBox", testCases);
+	
+				testCases = [];
+				gen4DateFormat(testCases, "ru-ru", "ru_RU", new Date(1970, 0, 1, 15, 25, 35),
+					"15:25", "", "15:25:35", "", "15:25:35 UTC", "", "15:25:35 UTC", "");
+				gen4DateFormat(testCases, "zh-cn", "zh_CN", new Date(1970, 0, 1, 15, 25, 35),
+					"下午3:25", "", "下午03:25:35", "", "下午03时25分35秒", "", "下午03时25分35秒 UTC", "");
+				gen4DateFormat(testCases, "en-us", "en_US", new Date(1970, 0, 1, 15, 25, 35),
+					"3:25 PM", "", "3:25:35 PM", "", "3:25:35 PM UTC", "", "3:25:35 PM UTC", "");
+				gen4DateFormat(testCases, "fr-fr", "fr_FR", new Date(1970, 0, 1, 15, 25, 35),
+					"15:25", "", "15:25:35", "", "15:25:35 UTC", "", "15:25:35 UTC", "");
+				gen4DateFormat(testCases, "ja-jp", "ja_JP", new Date(1970, 0, 1, 15, 25, 35),
+					"15:25", "", "15:25:35", "", "15:25:35:UTC", "", "15時25分35秒UTC", "");
+				gen4DateFormat(testCases, "ar-eg", "ar_EG", new Date(1970, 0, 1, 15, 25, 35),
+					"3:25 \u0645", "", "3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "");
+				gen4DateFormat(testCases, "hi-in", "hi_IN", new Date(1970, 0, 1, 15, 25, 35),
+					"१५:२५", "", "१५:२५:३५", "", "१५:२५:३५ UTC", " ", "१५:२५:३५ UTC", " ");
+				genValidateTestCases("Time Validate", "dijit.form.TimeTextBox", testCases);
+
+				dojo.parser.parse();
+
+				doh.register("t", getAllTestCases());
+
+				doh.run();
+			});
 		</script>
 	</head>
 
 	<body class="claro">
 		<h1 class="testTitle">Dijit TextBox Globalization Test for Time</h1>
 
-		<h2 class="testTitle">Press the following button to start all test after this page is loaded.</h2>
-		<button id="startButton" onclick="startTest()">Start Test</button>
 		<p>
 			Before start this test, make sure the <b>dojo/cldr/nls</b> contains the data for "zh-cn", "fr-fr", "ja-jp", "ru-ru", "hi-in", "en-us" and "ar-eg". If not, convert these CLDR data and put them there.
 		</p>
-
-		<script>
-		(function() {
-			var testCases = [];
-			gen4DateFormat(testCases, "ru-ru", "ru_RU", "1970-01-01T15:25:35",
-				"15:25", "", "15:25:35", "", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "zh-cn", "zh_CN", "1970-01-01T15:25:35",
-				"下午3:25", "", "下午03:25:35", "", "下午03时25分35秒", "", "下午03时25分35秒 UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "en-us", "en_US", "1970-01-01T15:25:35",
-				"3:25 PM", "", "3:25:35 PM", "", "3:25:35 PM UTC", "<a href='#cmt_1'>See #1.</a>", "3:25:35 PM UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "fr-fr", "fr_FR", "1970-01-01T15:25:35",
-				"15:25", "", "15:25:35", "", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "ja-jp", "ja_JP", "1970-01-01T15:25:35",
-				"15:25", "", "15:25:35", "", "15:25:35:UTC", "<a href='#cmt_1'>See #1.</a>", "15時25分35秒UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "ar-eg", "ar_EG", "1970-01-01T15:25:35",
-				"3:25 \u0645", "", "3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "hi-in", "hi_IN", "1970-01-01T15:25:35",
-				"१५:२५", "<a href='#cmt_2'>See #2.</a>", "१५:२५:३५", "<a href='#cmt_2'>See #2.</a>", "१५:२५:३५ UTC", "<a href='#cmt_1'>See #1.</a> <a href='#cmt_2'>See #2.</a>", "१५:२५:३५ UTC", "<a href='#cmt_1'>See #1.</a> <a href='#cmt_2'>See #2.</a>");
-			genFormatTestCases("Time Format", "dijit.form.TimeTextBox", testCases);
-
-			testCases = [];
-			gen4DateFormat(testCases, "ru-ru", "ru_RU", new Date(1970, 0, 1, 15, 25, 35),
-				"15:25", "", "15:25:35", "", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "zh-cn", "zh_CN", new Date(1970, 0, 1, 15, 25, 35),
-				"下午3:25", "<a href='#cmt_3'>See #3.</a>", "下午03:25:35", "<a href='#cmt_3'>See #3.</a>", "下午03时25分35秒", "<a href='#cmt_3'>See #3.</a>", "下午03时25分35秒 UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "en-us", "en_US", new Date(1970, 0, 1, 15, 25, 35),
-				"3:25 PM", "", "3:25:35 PM", "", "3:25:35 PM UTC", "<a href='#cmt_1'>See #1.</a>", "3:25:35 PM UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "fr-fr", "fr_FR", new Date(1970, 0, 1, 15, 25, 35),
-				"15:25", "", "15:25:35", "", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>", "15:25:35 UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "ja-jp", "ja_JP", new Date(1970, 0, 1, 15, 25, 35),
-				"15:25", "", "15:25:35", "", "15:25:35:UTC", "<a href='#cmt_1'>See #1.</a>", "15時25分35秒UTC", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "ar-eg", "ar_EG", new Date(1970, 0, 1, 15, 25, 35),
-				"3:25 \u0645", "", "3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "", "UTC 3:25:35 \u0645", "<a href='#cmt_1'>See #1.</a>");
-			gen4DateFormat(testCases, "hi-in", "hi_IN", new Date(1970, 0, 1, 15, 25, 35),
-				"१५:२५", "<a href='#cmt_2'>See #2.</a>", "१५:२५:३५", "<a href='#cmt_2'>See #2.</a>", "१५:२५:३५ UTC", "<a href='#cmt_1'>See #1.</a> <a href='#cmt_2'>See #2.</a>", "१५:२५:३५ UTC", "<a href='#cmt_1'>See #1.</a> <a href='#cmt_2'>See #2.</a>");
-			genValidateTestCases("Time Validate", "dijit.form.TimeTextBox", testCases);
-
-			dojo.parser.parse();
-		})();
-		</script>
-
-		<h2 class="testTitle">Issues & Comments</h2>
-		<h3 class="testTitle"><a name="cmt_1">Issue #1 <sup style="color:blue">Fixed</sup></a></h3>
-		<p>
-			Currently Dojo do not support parsing for most "long" and "full" time format which have a timezone mark in it.
-		</p>
-
-		<h3 class="testTitle"><a name="cmt_2">Issue #2 <sup style="color:blue">Fixed: added a "localeDigit" to the options</sup></a></h3>
-		<p>
-			Strictly speaking, the data conversion must support non-European number characters in some locales like Arabic and Hindi.
-			For example, ICU formats a number data into Indic number characters by default in the Arabic locale.
-			However, currently Dojo does not support this feature (Dojo uses the default number conversion of the browser).
-		</p>
-
-		<h3 class="testTitle"><a name="cmt_3">Issue #3 <sup style="color:blue">Fixed</sup></a></h3>
-		<p>
-			This defect only occurs on the "zh-cn" locale. Dojo accepts "下午"(pm) in the textbox, but it automatically changes it to
-			"上午"(am) after the focus changed. The date value of the textbox is also changed.
-		</p>
-		<p>
-			The root cause of this issue is that the parser method's code assumes am/pm symbol always appears after the hour value.
-			But this is not true, for example, the pattern for "zh-cn" puts am/pm field before all the other fields.
-		</p>
 	</body>
 </html>
 
diff --git a/dijit/tests/infrastructure-module.js b/dijit/tests/infrastructure-module.js
index e6d6dd9..870cb8a 100644
--- a/dijit/tests/infrastructure-module.js
+++ b/dijit/tests/infrastructure-module.js
@@ -2,19 +2,26 @@ dojo.provide("dijit.tests.infrastructure-module");
 
 try{
 	// _Widget
-	doh.registerUrl("dijit.tests._Widget-lifecycle", dojo.moduleUrl("dijit", "tests/_Widget-lifecycle.html"), 99999999);
-	doh.registerUrl("dijit.tests._Widget-attr", dojo.moduleUrl("dijit", "tests/_Widget-attr.html"), 99999999);
-	doh.registerUrl("dijit.tests._Widget-subscribe", dojo.moduleUrl("dijit", "tests/_Widget-subscribe.html"), 99999999);
-	doh.registerUrl("dijit.tests.Widget-placeAt", dojo.moduleUrl("dijit", "tests/Widget-placeAt.html"), 99999999);
-	doh.registerUrl("dijit.tests.robot._Widget-deferredConnect", dojo.moduleUrl("dijit","tests/robot/_Widget-deferredConnect.html"), 99999999);
-	doh.registerUrl("dijit.tests.robot._Widget-ondijitclick_mouse", dojo.moduleUrl("dijit","tests/robot/_Widget-ondijitclick_mouse.html"), 99999999);
+	doh.registerUrl("dijit.tests._Widget-lifecycle", dojo.moduleUrl("dijit", "tests/_Widget-lifecycle.html"), 999999);
+	doh.registerUrl("dijit.tests._Widget-attr", dojo.moduleUrl("dijit", "tests/_Widget-attr.html"), 999999);
+	doh.registerUrl("dijit.tests._Widget-subscribe", dojo.moduleUrl("dijit", "tests/_Widget-subscribe.html"), 999999);
+	doh.registerUrl("dijit.tests._Widget-placeAt", dojo.moduleUrl("dijit", "tests/_Widget-placeAt.html"), 999999);
+	doh.registerUrl("dijit.tests.robot._Widget-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"), 99999999);
+	doh.registerUrl("dijit.tests.robot._Widget-ondijitclick_a11y", dojo.moduleUrl("dijit","tests/robot/_Widget-ondijitclick_a11y.html"), 999999);
 
-	// _Templated and other base classes
-	doh.registerUrl("dijit.tests._Templated", dojo.moduleUrl("dijit", "tests/_Templated.html"), 99999999);
-	doh.registerUrl("dijit.tests._Templated-widgetsInTemplate", dojo.moduleUrl("dijit", "tests/_Templated-widgetsInTemplate.html"), 99999999);
-	doh.registerUrl("dijit.tests._Container", dojo.moduleUrl("dijit", "tests/_Container.html"), 99999999);
+	// _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._Templated-widgetsInTemplate1.x", dojo.moduleUrl("dijit", "tests/_Templated-widgetsInTemplate1.x.html"), 999999);
+	doh.registerUrl("dijit.tests._Container", dojo.moduleUrl("dijit", "tests/_Container.html"), 999999);
+
+	doh.registerUrl("dijit.tests.Declaration", dojo.moduleUrl("dijit","tests/test_Declaration.html"), 999999);
+	doh.registerUrl("dijit.tests.Declaration_1.x", dojo.moduleUrl("dijit","tests/test_Declaration_1.x.html"), 999999);
+
+	// Miscellaneous
+	doh.registerUrl("dijit.tests.NodeList-instantiate", dojo.moduleUrl("dijit","tests/NodeList-instantiate.html"), 999999);
 }catch(e){
 	doh.debug(e);
-}
\ No newline at end of file
+}
diff --git a/dijit/tests/layout/AccordionContainer.html b/dijit/tests/layout/AccordionContainer.html
index 188abc3..8aa732c 100644
--- a/dijit/tests/layout/AccordionContainer.html
+++ b/dijit/tests/layout/AccordionContainer.html
@@ -1,25 +1,28 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Accordion Widget Automated Test</title>
 
 	<!-- only needed for test files: -->
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
+	<!-- helper methods -->
+	<script type="text/javascript" src="../helpers.js"></script>
+
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
@@ -54,12 +57,16 @@
 						name: "initially open pane",
 						runTest: function(t){
 							// Pane 2 is initially open
-							var openPanes = dojo.query(".dijitAccordionInnerContainer > .dijitVisible", accordion.containerNode);
+							var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								return node.parentNode.style.display != "none";
+							});
 							t.is(1, openPanes.length, "exactly one open pane");
 							t.is("pane 2", dijit.byNode(openPanes[0]).title, "pane 2 is initially open");
 
 							// And others are closed
-							var closedPanes = dojo.query(".dijitAccordionInnerContainer > .dijitHidden", accordion.containerNode);
+							var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								return node.parentNode.style.display == "none";
+							});
 							t.is(2, closedPanes.length, "n-1 closed panes");
 						}
 					},
@@ -114,38 +121,66 @@
 						name: "initially open pane (checking again)",
 						runTest: function(t){
 							// Pane 2 is initially open
-							var openPanes = dojo.query(".dijitAccordionInnerContainer > .dijitVisible", accordion.containerNode);
+							var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								return node.parentNode.style.display != "none";
+							});
 							t.is(1, openPanes.length, "exactly one open pane");
 							t.is("pane 2", dijit.byNode(openPanes[0]).title, "pane 2 is initially open");
 
 							// And others are closed
-							var closedPanes = dojo.query(".dijitAccordionInnerContainer > .dijitHidden", accordion.containerNode);
+							var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								return node.parentNode.style.display == "none";
+							});
 							t.is(3, closedPanes.length, "n-1 closed panes");
 						}
 					},
 					{
 						name: "select new pane",
+						runTest: function(t){
+							// Selecting pane 3 should open it and close pane 1
+
+							// select w/out animation
+							accordion.selectChild(dijit.byId('pane 3'));
+
+							// Pane 3 is now open
+							var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								return node.parentNode.style.display != "none";
+							});
+							t.is(1, openPanes.length, "exactly one open pane");
+							t.is("pane 3", dijit.byNode(openPanes[0]).title, "pane 3 is now open");
+
+							// And others are closed
+							var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+								return node.parentNode.style.display == "none";
+							});
+							t.is(3, closedPanes.length, "n-1 closed panes");
+						}
+					},
+					{
+						name: "select new pane with animation",
 						timeout: 3000,
 						setUp: function(t){
 							// Note that this kicks off an animation so it might be a while before the
 							// bottom setTimeout() fires, likely longer than the 300ms specified
-							accordion.selectChild(dijit.byId('pane 3'));
+							accordion.selectChild(dijit.byId('pane 2'), true);
 						},
 						runTest: function(t){
-							// Selecting pane 3 should open it and close pane 1
+							// Selecting pane 2 should open it and close pane 3
 							var d = new doh.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									// Pane 3 is now open
-									var openPanes = dojo.query(".dijitAccordionInnerContainer > .dijitVisible", accordion.containerNode);
-									t.is(1, openPanes.length, "exactly one open pane");
-									t.is("pane 3", dijit.byNode(openPanes[0]).title, "pane 3 is now open");
-
-									// And others are closed
-									var closedPanes = dojo.query(".dijitAccordionInnerContainer > .dijitHidden", accordion.containerNode);
-									t.is(3, closedPanes.length, "n-1 closed panes");
-								})
-							, 300);
+							setTimeout(d.getTestCallback(function(){
+								// Pane 2 is now open
+								var openPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+									return node.parentNode.style.display != "none";
+								});
+								t.is(1, openPanes.length, "exactly one open pane");
+								t.is("pane 2", dijit.byNode(openPanes[0]).title, "pane 3 is now open");
+
+								// And others are closed
+								var closedPanes = dojo.query(".dijitAccordionChildWrapper > *", accordion.containerNode).filter(function(node){
+									return node.parentNode.style.display == "none";
+								});
+								t.is(3, closedPanes.length, "n-1 closed panes");
+							}), 300);
 							return d;
 						}
 					},
@@ -158,6 +193,30 @@
 					}
 				]
 			);
+
+			doh.register("child events", function childEvents(t){
+				accordion = new dijit.layout.AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(dojo.body());
+
+				dojo.forEach([ "a", "b", "c" ], function(title, i){
+					var content = new dijit.layout.ContentPane({id: title, title: title, selected: i==1});
+					content.containerNode.innerHTML = "this is " + title;
+					accordion.addChild(content);
+				});
+				accordion.startup();
+
+				// Change title of a pane, should change corresponding button label			
+				dijit.byId("b").set("title", "b changed");
+				var titles = dojo.query(".dijitAccordionText", accordion.domNode);
+				t.is(3, titles.length, "number of titles");
+				t.is("b changed", titles[1].innerHTML);
+
+				// Change tooltip of a pane, should change corresponding button tooltip			
+				dijit.byId("c").set("tooltip", "c tooltip changed");
+				titles = dojo.query(".dijitAccordionText", accordion.domNode);
+				t.is(3, titles.length, "number of titles");
+				t.is("c tooltip changed", titles[2].title);
+			});
+
 			doh.register("zero children",
 				[
 					{
@@ -217,6 +276,144 @@
 				]
 			);
 
+			// This section tests that the animation doesn't leave residual height=... settings on the
+			// node that interfere with future operations
+			doh.register("animation",
+				[
+					{
+						name: "create",
+						runTest: function(t){
+							accordion = new dijit.layout.AccordionContainer({style: "width: 400px; height: 400px;"}).placeAt(dojo.body());
+
+							dojo.forEach([ "pane 1", "pane 2", "pane 3" ], function(title, i){
+								var content = new dijit.layout.ContentPane({id: title, title: title, selected: i==1});
+								content.containerNode.innerHTML = "this is " + title;
+								accordion.addChild(content);
+							});
+							accordion.startup();
+
+							// make sure size of selected child is correct						
+							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+							doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+						}
+					},
+					{
+						name: "select new pane with animation",
+						timeout: 3000,
+						setUp: function(t){
+							// Note that this kicks off an animation so it might be a while before the
+							// bottom setTimeout() fires, likely longer than the 300ms specified
+							accordion.selectChild(dijit.byId('pane 2'), true);
+						},
+						runTest: function(t){
+							// Selecting pane 2 should open it and close pane 3
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								doh.is("pane 2", accordion.selectedChildWidget.title);
+
+								// make sure size of selected child is correct						
+								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+								doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+							}), 300);
+							return d;
+						}
+					},
+
+					// Make sure that the animation didn't leave a residual height: 1px that affect
+					// pane #1 when it is reselected w/out an animation
+					{
+						name: "remove pane #2, reselecting pane #1",
+						runTest: function(t){
+							accordion.removeChild(dijit.byId("pane 2"));
+
+							doh.is("pane 1", accordion.selectedChildWidget.title);
+
+							// make sure size of selected child is correct						
+							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+							doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+						}
+					},
+					{
+						name: "select pane #3 with animation",
+						timeout: 3000,
+						setUp: function(t){
+							// Note that this kicks off an animation so it might be a while before the
+							// bottom setTimeout() fires, likely longer than the 300ms specified
+							accordion.selectChild(dijit.byId('pane 3'), true);
+						},
+						runTest: function(t){
+							// Selecting pane 2 should open it and close pane 3
+							var d = new doh.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								doh.is("pane 3", accordion.selectedChildWidget.title);
+
+								// make sure size of selected child is correct						
+								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 300, "child height > 300");
+								doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 400, "child height < 400");
+								doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+							}), 300);
+							return d;
+						}
+					},
+
+					// Make sure that the wipe-in animation didn't leave a residual height: 300px type
+					// setting that will interfere with resizing
+					{
+						name: "resize",
+						timeout: 3000,
+						runTest: function(t){
+							accordion.resize({h: 200});
+
+							// make sure size of selected child is correct						
+							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h > 100, "child height > 150");
+							doh.t(dojo.position(accordion.selectedChildWidget.domNode).h < 200, "child height < 200");
+							doh.is(dojo.marginBox(accordion.selectedChildWidget.domNode).h, dojo.contentBox(accordion.selectedChildWidget._wrapperWidget.containerNode).h, "child height vs. wrapper height")
+						}
+					}
+				]
+			);
+
+			doh.register("destroy", [
+				function setUp(){
+					accPane = new dijit.layout.ContentPane({
+						id: "accPane",
+						onContentError: function(msg){
+							throw new Error(msg);
+						}
+					});
+					accPane.placeAt(dojo.body());
+					html='<div data-dojo-type="dijit.layout.AccordionContainer" id="Accordion" style="height: 300px;">' +
+						 	'<div data-dojo-type="dijit.layout.ContentPane" title="first" id="first">' +
+								'<div data-dojo-type=dijit.form.Button id=myButton>hello world</div></div>' +
+						 	'<div data-dojo-type="dijit.layout.ContentPane" title="second" id="second">second</div>' +
+							'</div>';
+				},
+
+				function destroyUnstarted(){
+					// Since the wrapper ContentPane hasn't been started yet, the Accordion won't be started, and wrapper
+					// (AccordionInnerContainer) widgets won't be created...
+					accPane.set("content", html);
+					doh.t(dojo.byId("Accordion"), "accordion created #1");
+					accPane.set("content", html); //setting the content twice will initiate a destroy
+					dijit.byId("Accordion").destroy();
+					doh.is(undefined, dojo.byId("Accordion"), "accordion destroyed #1");
+				},
+				
+				function destroyStarted(){
+					// Try same tests again when wrapper ContentPane is started
+					accPane.startup();
+
+					accPane.set("content", html);
+					doh.t(dojo.byId("Accordion"), "accordion created #2");
+					accPane.set("content", html); //setting the content twice will initiate a destroy
+					dijit.byId("Accordion").destroy();
+					doh.is(undefined, dojo.byId("Accordion"), "accordion destroyed #2");
+				}
+			]);
+
 			doh.run();
 		});
 	</script>
diff --git a/dijit/tests/layout/BorderContainer.html b/dijit/tests/layout/BorderContainer.html
new file mode 100644
index 0000000..0d6f758
--- /dev/null
+++ b/dijit/tests/layout/BorderContainer.html
@@ -0,0 +1,259 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>dijit.layout.BorderContainer DOH Test</title>
+
+	<!-- only needed for test files: -->
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript" src="robot/borderContainerTestFunctions.js"></script>
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.layout.BorderContainer");
+		dojo.require("dijit.layout.ContentPane");
+		dojo.require("dijit.form.FilteringSelect");
+		dojo.require("doh.runner");
+
+		var bc, cp1, cp2, cp3;
+        dojo.addOnLoad(function(){
+
+			doh.register("markup", [
+				function parse(){
+					dojo.parser.parse();
+				},
+				function initialConditions(){
+					checkBCpanes(dijit.byId("border1"));
+					checkBCpanes(dijit.byId("border2"));
+				},
+
+				function resize(){
+					// current size of panes
+					var oTop = dojo.position(dojo.byId("border1-top")),
+						oLeft = dojo.position(dojo.byId("border1-left")),
+						oCenter = dojo.position(dojo.byId("border1-center")),
+						oRight = dojo.position(dojo.byId("border1-right")),
+						oBottom = dojo.position(dojo.byId("border1-bottom"));
+
+					// make whole BorderContainer 100px bigger (width and height)
+					var mb = dojo.marginBox("border1");
+					dijit.byId("border1").resize({w: mb.w + 100, h: mb.h + 100});
+
+					// new size of panes
+					var nTop = dojo.position(dojo.byId("border1-top")),
+						nLeft = dojo.position(dojo.byId("border1-left")),
+						nCenter = dojo.position(dojo.byId("border1-center")),
+						nRight = dojo.position(dojo.byId("border1-right")),
+						nBottom = dojo.position(dojo.byId("border1-bottom"));
+
+					doh.is(oTop.w + 100, nTop.w, "top width + 100");
+					doh.is(oTop.h, nTop.h, "top height unchanged");
+					doh.is(oCenter.w + 100, nCenter.w, "center width + 100");
+					doh.is(oCenter.h + 100, nCenter.h, "center height + 100");
+					doh.is(oBottom.w + 100, nBottom.w, "bottom width + 100");
+					doh.is(oBottom.h, nBottom.h, "bottom height unchanged");
+					doh.is(oLeft.w, nLeft.w, "left width unchanged");
+					doh.is(oLeft.h + 100, nLeft.h, "left height + 100");
+					doh.is(oRight.w, nRight.w, "right width unchanged");
+					doh.is(oRight.h + 100, nRight.h, "right height + 100");
+
+					// size BorderContainer back to original size
+					dijit.byId("border1").resize({w: mb.w, h: mb.h});
+
+					var nnTop = dojo.position(dojo.byId("border1-top")),
+						nnLeft = dojo.position(dojo.byId("border1-left")),
+						nnCenter = dojo.position(dojo.byId("border1-center")),
+						nnRight = dojo.position(dojo.byId("border1-right")),
+						nnBottom = dojo.position(dojo.byId("border1-bottom"));
+
+					doh.is(dojo.toJson(oTop), dojo.toJson(nnTop), "top after second resize");
+					doh.is(dojo.toJson(oCenter), dojo.toJson(nnCenter), "center after second resize");
+					doh.is(dojo.toJson(oBottom), dojo.toJson(nnBottom), "bottom after second resize");
+					doh.is(dojo.toJson(oLeft), dojo.toJson(nnLeft), "left after second resize");
+					doh.is(dojo.toJson(oRight), dojo.toJson(nnRight), "right after second resize");
+				},
+
+				function addRemovePanes(){
+					// current size of panes
+					var oLeft = dojo.position(dojo.byId("border1-left")),
+						oCenter = dojo.position(dojo.byId("border1-center")),
+						oRight = dojo.position(dojo.byId("border1-right")),
+						oBottom = dojo.position(dojo.byId("border1-bottom"));
+
+					// remove top pane... should expand left/center/right
+					dijit.byId("border1").removeChild(dijit.byId("border1-top"));
+					doh.is("auto", dijit.byId("border1-top").domNode.style.top, "border1-topremove, style.top-->auto")
+					doh.is("auto", dijit.byId("border1-top").domNode.style.left, "border1-topremove, style.left-->auto")
+					doh.is("static", dijit.byId("border1-top").domNode.style.position, "border1-topremove, style.position")
+
+					// new size of panes
+					var nLeft = dojo.position(dojo.byId("border1-left")),
+						nCenter = dojo.position(dojo.byId("border1-center")),
+						nRight = dojo.position(dojo.byId("border1-right")),
+						nBottom = dojo.position(dojo.byId("border1-bottom"));
+
+					doh.t(nLeft.h > oLeft.h, "left height increased");
+					doh.t(nCenter.h > oCenter.h, "center height increased");
+					doh.t(nRight.h > oRight.h, "left height increased");
+					doh.is(oBottom.h, nBottom.h, "bottom height didn't change");
+
+					// remove left pane... should just expand center pane
+					dijit.byId("border1").removeChild(dijit.byId("border1-left"));
+
+					// new size of panes
+					var nnCenter = dojo.position(dojo.byId("border1-center")),
+						nnRight = dojo.position(dojo.byId("border1-right")),
+						nnBottom = dojo.position(dojo.byId("border1-bottom"));
+
+					doh.t(nnCenter.w > nCenter.w, "center width increased");
+					doh.is(dojo.toJson(nRight), dojo.toJson(nnRight), "right stayed same");
+					doh.is(dojo.toJson(nBottom), dojo.toJson(nnBottom), "bottom stayed same");
+
+					// check that all panes sane
+					checkBCpanes(dijit.byId("border1"));
+
+					// put back left pane as the top pane
+					dijit.byId("border1").addChild(dijit.byId("border1-left"));
+
+					// check that all panes sane
+					checkBCpanes(dijit.byId("border1"));
+				}
+			]);
+
+			doh.register("programmatic creation", [
+				function createProgramatically(){
+					originalWidgetCnt = dijit.registry.length;
+
+					bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
+		
+					cp1 = new dijit.layout.ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
+					cp1.domNode.innerHTML = "top pane";
+					bc.addChild(cp1);
+		
+					cp2 = new dijit.layout.ContentPane({region:'center',style:'background-color:green', id:'cp2'});
+					cp2.domNode.innerHTML = "center pane";
+					bc.addChild(cp2);
+		
+					cp3 = new dijit.layout.ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
+					cp3.domNode.innerHTML = "left pane";
+					
+					bc.startup();
+
+					checkBCpanes(bc);
+				},
+				function addLeftPane(){
+					var nWidgetsBefore = dijit.registry.length;
+					bc.addChild(cp3);
+					checkBCpanes(bc);
+					doh.t(isVisible(cp3));
+					doh.is(nWidgetsBefore + 1, dijit.registry.length, "splitter widget created");
+				},
+				function removeTopPane(){
+					var nWidgetsBefore = dijit.registry.length;
+					bc.removeChild(cp1);
+					checkBCpanes(bc);
+					doh.f(isVisible(cp1));
+					doh.is(nWidgetsBefore - 1, dijit.registry.length, "splitter widget destroyed");
+				},
+				function removeLeftPane(){
+					bc.removeChild(cp3);
+					checkBCpanes(bc);
+					doh.f(isVisible(cp3));
+				},
+				function addLeftPane2(){
+					bc.addChild(cp3);
+					checkBCpanes(bc);
+					doh.t(isVisible(cp3));
+				},
+				function addTopPane(){
+					bc.addChild(cp1);
+					checkBCpanes(bc);
+					doh.t(isVisible(cp3));
+				},
+				function destroyAll(){
+					bc.destroyRecursive();
+					doh.is(originalWidgetCnt, dijit.registry.length, "BorderContainer and all contained widgets destroyed");
+				}
+			]);
+
+			doh.run();
+        });
+
+	</script>
+</head>
+<body class="claro">
+	<p>Headline layout (default), left is constrained - min:150, max:250</p>
+	<div id="border1" data-dojo-type="dijit.layout.BorderContainer"
+		data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
+		<div role="banner" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-top", region:"top", style:"background-color: #b39b86; border: 15px black solid; height: 50px;", splitter:true'>
+			top bar (resizable)
+		</div>
+		<div role="navigation" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-left", region:"left", style:"background-color: #acb386; border: 10px green solid; width: 100px;",
+		splitter:true, minSize:150, maxSize:250'>
+			left (resizable b/w 150 → 250)
+		</div>
+		<div role="main" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-center", region:"center", style:"background-color: #f5ffbf; padding: 30px;"'>
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select data-dojo-type="dijit.form.FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-right", region:"right", style:"background-color: #acb386; width: 100px;"'>
+			right (fixed size)
+		</div>
+		<div role="contentinfo" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-bottom", region:"bottom", style:"background-color: #b39b86; height: 50px;", splitter:true'>
+			bottom bar (resizable)
+		</div>
+	</div>
+
+	<p>Sidebar layout, BiDi sensitive, liveSplitters: false</p>
+	<div id="border2" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", liveSplitters:false,
+		style:"border: 20px solid black; width: 1000px; height: 300px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
+			leading (fixed size)
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-top", region:"top", style:"background-color: #b39b86; height: 80px;"'>
+			top bar (fixed size)
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select data-dojo-type="dijit.form.FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-bottom", region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
+			bottom bar (resizable)
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
+			trailing (resizable)
+		</div>
+	</div>
+
+	<p>Programatically created</p>
+	<div id='main'></div>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/ContentPane-remote.html b/dijit/tests/layout/ContentPane-remote.html
new file mode 100644
index 0000000..d8766b4
--- /dev/null
+++ b/dijit/tests/layout/ContentPane-remote.html
@@ -0,0 +1,663 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>ContentPane Remote Loading Test</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="isDebug: true, parseOnLoad: false"></script>
+
+	<!-- only needed for alternate theme testing: do NOT use in your code! -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<!-- functions to help test -->
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script 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("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
+
+		var tabCounter;
+		function testClose(pane, tab){
+			// remove html from title
+			var title = dojo.trim(tab.title.replace(/<\/?[a-z][a-z0-9]*[^>]*>/ig, ""));
+			return confirm("Please confirm that you want tab "+title+" closed");
+		}
+
+		function createTab(){
+			if(!tabCounter){ tabCounter = 3; }
+
+			var title = '<img src="../images/plus.gif" style="background-color:#95B7D3;"/> Tab ' +(++tabCounter);
+			var refreshOnShow = !!(tabCounter % 2);
+
+			var newTab = new dijit.layout.ContentPane({
+				id: "ttab" + tabCounter,
+				title: title + (refreshOnShow ? ' <i>refreshOnShow</i>': ''),
+				closable:true,
+				refreshOnShow: refreshOnShow,
+				href: 'getResponse.php?delay=1000&messId='+tabCounter
+					+"&message="+encodeURI("<h1>Programmatically created Tab "+tabCounter+"</h1>")
+			}, dojo.doc.createElement('div'));
+
+			dijit.byId('ttabs').addChild(newTab);
+
+			newTab.startup();
+		}
+
+		function isLoading(domNode){
+			return domNode.firstChild.innerHTML == "Loading...";
+		}
+
+		dojo.addOnLoad(function(){
+			// create a do nothing, only for test widget
+			dojo.declare("dijit.TestWidget",
+				[dijit._Widget, dijit._Templated], {
+				templateString: "<span class='dijitTestWidget'></span>"
+			});
+
+			doh.register("parse", function parse(){
+				dojo.parser.parse();
+			});
+
+			var cp;
+
+			doh.register("ContentPane", [
+				function create(){
+					cp = new dijit.layout.ContentPane({}, dojo.byId("cp"));
+				},
+
+				{
+					name: "setHref_loading",
+					timeout: 10000,
+					setUp: function(t){
+					},
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						cp.set('href', 'getResponse.php?messId=1').then(d.getTestCallback(function(){
+							doh.is(1, dijit._Widget.prototype.getChildren.call(cp).length);
+						}));
+						return d;
+					}
+				},
+				{
+					name: "setHref_then_cancel",
+					timeout: 2800,
+					setUp: function(t){
+						cp.set("content", "");// clear previous
+					},
+					runTest: function(t){
+						var msg = "This should NEVER be seen!";
+						cp.set('href', 'getResponse.php?delay=1000&message='+encodeURI(msg));
+						var d = new t.Deferred();
+						setTimeout(d.getTestCallback(
+							function(){
+								doh.f(cp.domNode.innerHTML == msg);
+							}
+						), 2500);
+
+						cp.cancel();
+
+						return d;
+					}
+				},
+				{
+					// test that setHref cancels a inflight setHref
+					name: "setHref_cancels_previous_setHref",
+					timeout: 2800,
+					setUp: function(t){
+						cp.set("content", "");
+					},
+					runTest: function(t){
+						var msgCanceled = "This should be canceled";
+						cp.set('href', "getResponse.php?delay=1000&message="+encodeURI(msgCanceled));
+
+						var msg = "This message should win over the previous";
+						setTimeout(function(){
+							cp.set('href', "getResponse.php?message="+encodeURI(msg));
+						}, 900);
+
+						var d = new t.Deferred();
+						setTimeout(d.getTestCallback(
+							function(){
+								doh.is(msg, cp.domNode.innerHTML);
+							}
+						), 2500);
+						return d;
+					}
+				},
+				{
+					name: "setContent_cancels_setHref",
+					timeout: 2800,
+					setUp: function(t){
+						cp.set("content", "");
+					},
+					runTest: function(t){
+						dojo.connect(cp, "onUnload", function(){
+							console.log("cp unload of: " + cp.get('content'));
+						});
+						dojo.connect(cp, "onLoad", function(){
+							console.log("cp load of: " + cp.get('content'));
+						});
+						var msgCanceled = "This message be canceled";
+						cp.set('href', "getResponse.php?delay=1000&message="+encodeURI(msgCanceled));
+
+						var msg = "This message should win over (ie, cancel) the inflight one";
+						setTimeout(function(){
+							cp.set("content", msg);
+						}, 500);
+
+						var d = new t.Deferred();
+						setTimeout(d.getTestCallback(
+							function(){
+								doh.is(msg, cp.domNode.innerHTML);
+							}
+						), 2500);
+						return d;
+					}
+				},
+				{
+					name: "refresh",
+					timeout: 1900,
+					setUp: function(t){
+						cp.set('href', "getResponse.php?message="+encodeURI('initial load'));
+					},
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						setTimeout(d.getTestErrback(function(){
+							var msg = 'refreshed load'
+							cp.href = "getResponse.php?message="+encodeURI(msg);
+							cp.refresh().then(d.getTestCallback(function(){
+								doh.is(msg, cp.domNode.innerHTML);
+							}));
+						}), 100);
+
+						return d;
+					}
+				},
+				{
+					// Test isLoaded attribute lifecycle and that onLoad/onUnload callbacks
+					// are called at the right times
+					name: "isLoaded",
+
+					timeout: 10000,
+					setUp: function(t){
+						cp.set("content", "");
+					},
+					runTest: function(t){
+						doh.t(cp.isLoaded, "cp initially loaded");
+
+						// Setup handlers to track when onUnload and onLoad are called,
+						// including tracking if they get called repeatedly (they shouldn't)
+						var history = "";
+						var handles = [
+							dojo.connect(cp, "onUnload", function(){ history += "unloaded"}),
+							dojo.connect(cp, "onLoad", function(){ history += " and reloaded"})
+						];
+
+						cp.set('href', "getResponse.php?delay=300&message=test");
+
+						doh.f(cp.isLoaded, "immediately after href set, cp isLoaded == false");
+						doh.is("unloaded", history);
+
+						var ilObj = {}; // a object to get a reference instead of copy
+
+						// probe after 200ms
+						setTimeout(function(){
+							ilObj.probed = cp.isLoaded;
+						}, 200);
+
+						var d = new t.Deferred();
+						handles.push(dojo.connect(cp, "_setContent", d.getTestCallback(function(){
+							doh.f(ilObj.probed, "200ms after href set, cp was not loaded");
+							doh.t(cp.isLoaded, "eventually, cp was loaded");
+							doh.is("unloaded and reloaded", history);
+
+							dojo.forEach(handles, dojo.disconnect);
+						})));
+						return d;
+					}
+				},
+				{
+					// test that we don't load a response if we are hidden
+					name: "wait_with_load_when_domNode_hidden",
+					timeout: 1800,
+					setUp: function(t){
+						cp.domNode.style.display = 'none';
+						cp.set("content", "");
+					},
+					runTest: function(t){
+						cp._msg = "This text should not be loaded until after widget is shown";
+						cp.set('href', "getResponse.php?message="+encodeURI(cp._msg));
+						var d = new t.Deferred();
+						setTimeout(d.getTestCallback(
+							function(){
+								doh.isNot(cp._msg, cp.domNode.innerHTML);
+							}
+						), 1500);
+						return d;
+					},
+					tearDown: function(t){
+						cp.domNode.style.display = "";
+					}
+				},
+				{
+					name: "onDownloadError",
+					timeout: 1800,
+					setUp: function(t){
+						cp.set("content", "");
+					},
+					runTest: function(t){
+						var msg = "Error downloading modified message";
+						orig = cp.onDownloadError;
+
+						cp.onDownloadError = function(){
+							return msg;
+						}
+
+						var d = new doh.Deferred();
+
+						evtHandle = dojo.connect(cp, 'onDownloadError', d.getTestErrback(function(e){
+							doh.t(e, "onDownloadError got event argument on invokation");
+							setTimeout(d.getTestCallback(function(){
+								doh.is(msg, cp.domNode.innerHTML, "custom errortext set");
+							}), 1);
+						}));
+
+						// test onDownloadError
+						cp.set('href', 'nonexistant');
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(evtHandle);
+						cp.onDownloadError = orig;
+					}
+				},
+
+				// Test that setting an href calls onDownloadStart followed by onDownloadEnd,
+				// and also setting of custom download message instead of "Loading..."
+				{
+					name: "onDownloadStart|End",
+					timeout: 5000,
+					setUp:function(t){
+						cp.set("content", "");
+					},
+					runTest:function(t){
+						var d = new doh.Deferred();
+
+						// set custom message
+						origStart = cp.onDownloadStart;
+						var msg = "custom downloadstart message";
+						cp.onDownloadStart = function(){ return msg; };
+
+						startHandle = dojo.connect(cp, 'onDownloadStart', d.getTestErrback(function(){
+							setTimeout(d.getTestErrback(function(){
+								// check that custom message was set
+								doh.is(msg, cp.containerNode.innerHTML, "custom download message was set");
+
+								// and then wait for the download to complete						
+								endHandle = dojo.connect(cp, 'onDownloadEnd', d.getTestCallback(function(){
+									// if this gets called (before the test timeout) then test succeeded
+								}));
+							}), 1);
+						}));
+						cp.set('href', 'getResponse.php?delay=400');
+
+						return d;
+					},
+					tearDown: function(){
+						cp.onDownloadStart = origStart;
+						dojo.disconnect(startHandle);
+						dojo.disconnect(endHandle);
+					}
+				},
+
+				// Test that setting an href calls onUnload followed by onLoad
+				{
+					name: "onLoad|onUnload",
+					timeout: 5000,
+					setUp:function(t){
+						cp.set("content", "");
+					},
+					runTest:function(t){
+						var d = new doh.Deferred();
+
+						loadHandle = dojo.connect(cp, 'onUnload', d.getTestErrback(function(){							
+							unloadHandle = dojo.connect(cp, 'onLoad', d.getTestCallback(function(){
+								// if this gets called (before the test timeout) then test succeeded
+							}));
+						}));
+						cp.set('href', 'getResponse.php?delay=400');
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(loadHandle);
+						dojo.disconnect(unloadHandle);
+					}
+				}
+			]);
+
+			function selectChildAndTestLoad(/*String*/ parentId, /*String*/ childId, /*String*/ startOfExpectedContent){
+				// summary:
+				//		Test deferred load of child of StackContainer widget
+
+				var d = new doh.Deferred(),
+					loadingContent,
+					child = dijit.byId(childId),
+					contentNode = dojo.byId(childId);
+
+				child.ioMethod = function(args){
+					loadingContent = innerText(contentNode);
+					delete child.ioMethod;
+					return dojo.xhrGet(args);
+				};
+
+				dojo.when(dijit.byId(parentId).selectChild(child), function(){
+					setTimeout(d.getTestCallback(
+						function(){
+							doh.is(child.loadingMessage.replace(/<[^>]*>/g, ""), loadingContent, "loading message");
+							var startOfActualContent = innerText(contentNode).substring(0, startOfExpectedContent.length);
+							doh.is(startOfExpectedContent, startOfActualContent, "expected content");
+						}
+					), 1); // return from handler, then test
+				});
+
+				return d;
+			}
+
+			var st,		// stack container
+				pane3, pane3UnloadCnt=0, pane3LoadCnt=0,	// second child of stack container (initially hidden)
+				tmp;
+
+			doh.register("ContentPane in StackContainer", [
+				{
+					// TODO: this test should be moved to registerGroup setUp now that #3504 is fixed
+					//		We actually don't need to test anything here, just setUp
+					name: "setUp_StackContainer",
+					setUp:function(t){
+						// create a StackContainer
+						st = dojo.byId('stackcontainer');
+						dojo.addClass(st, 'box');
+						st = new dijit.layout.StackContainer({style: {height: "150px"}}, st);
+
+						// the first child (by default) is the one that will
+						// be shown
+						st.addChild(new dijit.TestWidget());
+
+						// the second child *won't* be shown until selected
+						pane3 = new dijit.layout.ContentPane({
+							id:"sc_pane2",
+							href:'getResponse.php?delay=300&message=Loaded!',
+							preventCache: true,
+							onLoad: function(){ pane3LoadCnt++; },
+							onUnload: function(){ pane3UnloadCnt++; }
+						}, dojo.doc.createElement('div'));
+						st.addChild(pane3);
+
+						// start the StackContainer; shouldn't cause ContentPane to load.
+						st.startup();
+					},
+					runTest:function(t){
+						doh.t(st);
+						doh.is(2, st.getChildren().length);
+					}
+				},
+				{
+					name: "preload_false_by_default",
+					runTest: function(t){
+						doh.f(pane3.isLoaded);
+						doh.is('', pane3.domNode.innerHTML);
+					}
+				},
+				{
+					name: "unload event not called initially",
+					runTest: function(t){
+						doh.is(0, pane3UnloadCnt);
+					}
+				},
+				{
+					name: "load event fired when pane is shown",
+					timeout: 10000,
+					runTest: function(t){
+						doh.is(0, pane3LoadCnt, "onload hasn't been called yet");
+
+						var d = new doh.Deferred();
+
+						dojo.when(st.selectChild(pane3), function(){
+							setTimeout(d.getTestCallback(function(){
+								doh.t(pane3.isLoaded, "pane3.isLoaded");
+								doh.is(1, pane3LoadCnt, "onload was called");
+								doh.is('Loaded!', pane3.domNode.innerHTML);
+								doh.is(0, pane3UnloadCnt,
+									"unload shouldn't have been called b/c no initial contents (#2)");
+							}), 1);
+						});
+
+						doh.is(0, pane3UnloadCnt,
+							"unload shouldn't have been called b/c no initial contents (#1)");
+
+						return d;
+					}
+				},
+				{
+					name: "refreshOnShow parameter works",
+					timeout: 10000,
+					setUp: function(t){
+						tmp = {
+							onUnload: function(){ this._unload_fired = 1; },
+							onLoad: function(){ this._load_fired = 1; }
+						};
+						tmp.unloadHandle = dojo.connect(pane3, 'onUnload', tmp, 'onUnload');
+						tmp.loadHandle = dojo.connect(pane3, 'onLoad', tmp, 'onLoad');
+
+						pane3.refreshOnShow = true;
+					},
+					runTest: function(t){
+						var d = new doh.Deferred();
+
+						// Show pane 3 again and see if events fire
+						st.back();
+						st.forward().then(function(){
+							setTimeout(d.getTestCallback(function(){
+								doh.t(tmp._unload_fired, "unload was fired");
+								doh.t(tmp._load_fired, "load was fired");
+								doh.is('Loaded!', pane3.domNode.innerHTML);
+							}), 1);
+						});
+
+						return d;
+					},
+					tearDown: function(){
+						dojo.disconnect(tmp.unloadHandle);
+						dojo.disconnect(tmp.loadHandle);
+						pane3.refreshOnShow = pane3.constructor.prototype.refreshOnShow;
+					}
+				}
+			]);
+
+			doh.register("ContentPane in TabContainer", [
+				{
+					name: "tab1InitialLoading",
+					timeout: 9000,
+					runTest: function(){ return selectChildAndTestLoad("ttabs", "ttab1", "IT WAS"); }
+				}
+			]);			
+
+			doh.register("ContentPane in AccordionContainer", [
+				{
+					name: "pane3InitialLoading",
+					timeout: 9000,
+					runTest: function(){ return selectChildAndTestLoad("ac", "ac_pane3", "There"); }
+				},
+				{
+					name: "cpInitialLoading",
+					timeout: 9000,
+					runTest: function(){ return selectChildAndTestLoad("ac", "ac_pane2", "There"); }
+				},
+				{
+					name: "pane3Refresh",
+					timeout: 5000,
+					runTest: function(t){
+						var d = new doh.Deferred(),
+						wasLoading = false,
+						widget = dijit.byId("ac_pane3"),
+						loadhandler = widget.connect(widget, "onDownloadStart",
+							function(){
+    							widget.disconnect(loadhandler);
+								wasLoading = true;
+							}
+						),
+						showhandler = widget.connect(widget, "_onShow",
+							function(){
+    							widget.disconnect(showhandler);
+								setTimeout(d.getTestCallback(
+									function(){
+										doh.f(wasLoading, "should not have reloaded")
+									}
+								), 1000);
+							}
+						);
+
+						dijit.byId("ac").selectChild("ac_pane3");
+						
+						return d;
+					}
+				},
+				{
+					name: "cpRefresh",
+					timeout: 9000,
+					runTest: function(){ return selectChildAndTestLoad("ac", "ac_pane2", "There"); }
+				}
+			]);
+
+			doh.register("TooltipDialog", [
+				// The preload=true TooltipDialog should already be loaded, or at least be loading,
+				// if it isn't already loading then this test will timeout.
+				{
+					name: "preload=true",
+					timeout: 5000,
+					runTest: function(t){
+						var dlg = dijit.byId("preloadTooltipDlg");
+						if(!dlg.isLoaded){
+							var d = new doh.Deferred();
+							dlg.onLoadDeferred.then(
+								function(){ d.callback(true); },
+								function(e){ d.errback(e); }
+							);
+							return d;
+						}
+					}
+				},
+
+				// The preload=false TooltipDialog shouldn't load until opened.
+				{
+					name: "preload=false",
+					timeout: 5000,
+					runTest: function(){
+						// Check that it isn't loaded yet
+						var dlg = dijit.byId("noPreloadTooltipDlg");
+						doh.f(dlg.isLoaded, "didn't load yet");
+	
+						// Open the dialog and then return Deferred waiting for it to load.
+						// If it doesn't load then this test will get a timeout.
+						var btn = dijit.byId("noPreloadTooltipDlgBtn");
+						btn.openDropDown();
+						doh.t(dlg.onLoadDeferred, "onLoadDeferred exists");
+						var d = new doh.Deferred();
+						dlg.onLoadDeferred.then(
+							function(){ d.callback(true); },
+							function(e){ d.errback(e); }
+						);
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Dijit layout.ContentPane (delayed) remote tests</h1>
+
+	<h2>Plain ContentPane</h2>
+	<div id='cp' class='box'></div>
+
+	<h2>StackContainer</h2>
+	<div id='stackcontainer'></div>
+
+	<h2>TabContainer</h2>
+	<p>These tabs are made up of external content. Loading is delayed to make it easier to see if refreshOnShow and preload = 'false' is working.<br/>
+	The tabs also tests to insert html in the Tab title
+	</p>
+
+	<div id="createTab" data-dojo-type='dijit.form.Button' data-dojo-props='onClick:function(){ createTab() }'>Create a Tab</div>
+	<div id="ttabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 20em;"'>
+		<a id="ttab1" data-dojo-type="dijit.layout.LinkPane"
+			data-dojo-props='href:"getResponse.php?messId=3&delay=1000",
+			closable:true
+		'><img src='../images/copy.gif'/> Tab1</a>
+		<a id="ttab2" data-dojo-type="dijit.layout.LinkPane"
+			data-dojo-props='href:"getResponse.php?messId=4&delay=1000",
+			refreshOnShow:true, title:"Tab 2 ",
+			selected:true,
+			closable:true
+		'><i>refreshOnShow</i>
+			<img src='../images/cut.gif'/>
+		</a>
+		<a id="ttab3" data-dojo-type="dijit.layout.LinkPane"
+			data-dojo-props='href:"getResponse.php?messId=5&delay=1000",
+			onClose:testClose,
+			closable:true
+		'>
+			<b>Tab 3</b>
+			<img src='../images/paste.gif'/>
+		</a>
+	</div>
+
+	<h2>AccordionContainer</h2>
+	<div data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='id:"ac", style:"height:300px; width:400px;"'>
+		<div id="ac_pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"one", refreshOnShow:false, href:"getResponse.php?messId=4&delay=1000"'></div>
+		<div id="ac_pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"two", refreshOnShow:true, href:"getResponse.php?messId=4&delay=4000"'></div>
+		<div id="ac_pane3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"three", refreshOnShow:false, href:"getResponse.php?messId=4&delay=4100"'></div>
+	</div>
+
+	<h2>TooltipDialog</h2>
+	<div data-dojo-type="dijit.layout.ContentPane">
+		<div id="preloadTooltipDlgBtn" data-dojo-type="dijit.form.DropDownButton">
+			<span>Show Preload TooltipDialog</span>
+			<div id="preloadTooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information", preload: true, href: "doc1.html"'>
+			</div>
+		</div>
+	</div>
+
+	<div id="noPreloadTooltipDlgBtn" data-dojo-type="dijit.form.DropDownButton">
+		<span>Show No-Preload TooltipDialog</span>
+		<div id="noPreloadTooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information", preload: false, href: "doc1.html"'>
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/ContentPane.html b/dijit/tests/layout/ContentPane.html
index a75d4c2..997c540 100644
--- a/dijit/tests/layout/ContentPane.html
+++ b/dijit/tests/layout/ContentPane.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane DOH test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../themes/tundra/tundra.css";
+		@import "../../themes/claro/document.css";
+		@import "../../themes/claro/claro.css";
 		@import "../css/dijitTests.css";
 
 		.box {
@@ -20,7 +20,7 @@
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript">
 		dojo.require("doh.runner");
 		dojo.require("dijit.layout.ContentPane");
@@ -29,15 +29,17 @@
 		dojo.require("dijit.layout._LayoutWidget");
 		dojo.require("dijit._Templated");
 		dojo.require("dijit.layout.StackContainer");
-
-		// create a do nothing, only for test widget
-		dojo.declare("dijit.TestWidget",
-			[dijit._Widget, dijit._Templated], {
-			templateString: "<span class='dijitTestWidget'></span>"
-		});
+		dojo.require("dojo.parser");
+		dojo.require("dijit.Dialog");
 
 
 		dojo.addOnLoad(function(){
+			// create a do nothing, only for test widget
+			dojo.declare("dijit.TestWidget",
+				[dijit._Widget, dijit._Templated], {
+				templateString: "<span class='dijitTestWidget'></span>"
+			});
+
 			doh.register("pane1",
 				[
 					{
@@ -64,8 +66,8 @@
 							pane2.set("content", "");// pass undefined on purpose
 						},
 						runTest: function(t){
-							t.assertEqual(0, dijit._Widget.prototype.getChildren.call(pane2).length);
-							t.assertEqual("", pane2.domNode.innerHTML)
+							doh.is(0, dijit._Widget.prototype.getChildren.call(pane2).length);
+							doh.is("", pane2.domNode.innerHTML)
 						}
 					},
 					{
@@ -76,7 +78,7 @@
 						runTest: function(t){
 							var msg = "<h3>a simple html string</h3>";
 							pane2.set("content", msg);
-							t.assertEqual(msg, pane2.domNode.innerHTML.toLowerCase());
+							doh.is(msg, pane2.domNode.innerHTML.toLowerCase());
 						}
 					},
 					{
@@ -84,11 +86,11 @@
 						setUp: function(t){
 							var div = dojo.doc.createElement('div');
 							div.innerHTML = "set('content', [DOMNode] )";
-							div.setAttribute('dojoType', 'dijit.TestWidget');
+							div.setAttribute('data-dojo-type', 'dijit.TestWidget');
 							pane2.set("content", div);
 						},
 						runTest: function(t){
-							t.assertEqual(1, dijit._Widget.prototype.getChildren.call(pane2).length);
+							doh.is(1, dijit._Widget.prototype.getChildren.call(pane2).length);
 						},
 						tearDown: function(t){
 							pane2.set("content", ""); // clear content for next test
@@ -98,22 +100,22 @@
 						name: "setContent_NodeList",
 						setUp: function(t){
 							var div = dojo.doc.createElement('div');
-							div.innerHTML = "<div dojotype='dijit.TestWidget'>above</div>"
+							div.innerHTML = "<div data-dojo-type='dijit.TestWidget'>above</div>"
 											+"Testing!<div><p><span><b>Deep nested</b></span></p></div>"
-											+"<div dojotype='dijit.TestWidget'>below</div>";
+											+"<div data-dojo-type='dijit.TestWidget'>below</div>";
 
 							var list = div.childNodes;
 							pane2.set("content", div.childNodes);
 						},
 						runTest: function(t){
-							t.assertEqual(2, dijit._Widget.prototype.getChildren.call(pane2).length);
+							doh.is(2, dijit._Widget.prototype.getChildren.call(pane2).length);
 
 							//regular DOM check
 							var children = pane2.domNode.childNodes;
-							t.assertEqual(4, children.length);
-							t.assertEqual("Testing!", children[1].nodeValue);
-							t.assertEqual("div", children[2].nodeName.toLowerCase());
-							t.assertEqual("<p><span><b>deep nested</b></span></p>", children[2].innerHTML.toLowerCase());
+							doh.is(4, children.length);
+							doh.is("Testing!", children[1].nodeValue);
+							doh.is("div", children[2].nodeName.toLowerCase());
+							doh.is("<p><span><b>deep nested</b></span></p>", children[2].innerHTML.toLowerCase());
 						}
 					},
 					{
@@ -123,9 +125,9 @@
 						},
 						runTest: function(t){
 							var div = dojo.doc.createElement('div');
-							div.innerHTML = "<div dojotype='dijit.TestWidget'>above</div>"
+							div.innerHTML = "<div data-dojo-type='dijit.TestWidget'>above</div>"
 										+"Testing!<div><p><span><b>Deep nested</b></span></p></div>"
-										+"<div dojotype='dijit.TestWidget'>below</div>";
+										+"<div data-dojo-type='dijit.TestWidget'>below</div>";
 
 							var list = new dojo.NodeList();
 							dojo.forEach(div.childNodes, function(n){
@@ -133,14 +135,14 @@
 							});
 
 							pane2.set("content", list);
-							t.assertEqual(4, pane2.domNode.childNodes.length);
+							doh.is(4, pane2.domNode.childNodes.length);
 						}
 					},
 					{
 						name: "extractContent",
 						runTest: function(t){
 							var def = pane2.extractContent;
-							t.assertFalse(def);
+							doh.f(def);
 
 							// test that it's actually working
 							pane2.extractContent = true;
@@ -149,450 +151,11 @@
 								+'<html><head><style>body{font-weight:bold;}</style></head>'
 								+'<body>extractContent test</body></html>');
 
-							t.assertEqual("extractContent test", pane2.domNode.innerHTML);
+							doh.is("extractContent test", pane2.domNode.innerHTML);
 
 							// reset back to default
 							pane2.extractContent = def;
 						}
-					},
-
-					/////////////////////////////////////////////////////////////////////////
-					// We assume that our network connection has a maximum of 1.5 sec latency
-					/////////////////////////////////////////////////////////////////////////
-					{
-						name: "setHref_loading",
-						timeout: 1800,
-						setUp: function(t){
-							pane2.set('href', 'getResponse.php?messId=1');
-						},
-						runTest: function(t){
-							var d = new tests.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertEqual(1, dijit._Widget.prototype.getChildren.call(pane2).length);
-								})
-							, 1500);
-							return d;
-						}
-					},
-					{
-						name: "setHref_then_cancel",
-						timeout: 2800,
-						setUp: function(t){
-							pane2.set("content", "");// clear previous
-						},
-						runTest: function(t){
-							var msg = "This should NEVER be seen!";
-							pane2.set('href', 'getResponse.php?delay=1000&message='+encodeURI(msg));
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertFalse(pane2.domNode.innerHTML == msg);
-								}
-							), 2500);
-
-							pane2.cancel();
-
-							return d;
-						}
-					},
-					{
-						// test that setHref cancels a inflight setHref
-						name: "setHref_cancels_previous_setHref",
-						timeout: 2800,
-						setUp: function(t){
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							var msgCanceled = "This should be canceled";
-							pane2.set('href', "getResponse.php?delay=1000&message="+encodeURI(msgCanceled));
-
-							var msg = "This message should win over the previous";
-							setTimeout(function(){
-								pane2.set('href', "getResponse.php?message="+encodeURI(msg));
-							}, 900);
-
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertEqual(msg, pane2.domNode.innerHTML);
-								}
-							), 2500);
-							return d;
-						}
-					},
-					{
-						name: "setContent_cancels_setHref",
-						timeout: 2800,
-						setUp: function(t){
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							dojo.connect(pane2, "onUnload", function(){
-								console.log("pane2 unload of: " + pane2.get('content'));
-							});
-							dojo.connect(pane2, "onLoad", function(){
-								console.log("pane2 load of: " + pane2.get('content'));
-							});
-							var msgCanceled = "This message be canceled";
-							pane2.set('href', "getResponse.php?delay=1000&message="+encodeURI(msgCanceled));
-
-							var msg = "This message should win over (ie, cancel) the inflight one";
-							setTimeout(function(){
-								pane2.set("content", msg);
-							}, 500);
-
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertEqual(msg, pane2.domNode.innerHTML);
-								}
-							), 2500);
-							return d;
-						}
-					},
-					{
-						name: "refresh",
-						timeout: 1900,
-						setUp: function(t){
-							pane2.set('href', "getResponse.php?message="+encodeURI('initial load'));
-						},
-						runTest: function(t){
-							var msg = 'refreshed load'
-							setTimeout(function(){
-								pane2.href = "getResponse.php?message="+encodeURI(msg);
-								pane2.refresh();
-							}, 100);
-
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertEqual(msg, pane2.domNode.innerHTML);
-								}
-							), 1600);
-							return d;
-
-						}
-					},
-					{
-						// Test isLoaded attribute lifecycle and that onLoad/onUnload callbacks
-						// are called at the right times
-						name: "isLoaded",
-
-						timeout: 1800,
-						setUp: function(t){
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							t.assertTrue(pane2.isLoaded);
-
-							// Setup handlers to track when onUnload and onLoad are called,
-							// including tracking if they get called repeatedly (they shouldn't)
-							var history = "";
-							var handles = [
-								dojo.connect(pane2, "onUnload", function(){ history += "unloaded"}),
-								dojo.connect(pane2, "onLoad", function(){ history += " and reloaded"})
-							];
-
-							pane2.set('href', "getResponse.php?delay=300&message=test");
-
-							t.assertFalse(pane2.isLoaded);
-							t.assertEqual("unloaded", history);
-
-							var ilObj = {}; // a object to get a reference instead of copy
-
-							// probe after 200ms
-							setTimeout(function(){
-								ilObj.probed = pane2.isLoaded;
-							}, 200);
-
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertTrue(pane2.isLoaded);
-									t.assertFalse(ilObj.probed);
-									t.assertEqual("unloaded and reloaded", history);
-									console.log("history in callback is ", history);
-
-									dojo.forEach(handles, dojo.disconnect);
-								}
-							), 1500);
-							return d;
-						}
-					},
-					{
-						// test that we don't load a response if we are hidden
-						name: "wait_with_load_when_domNode_hidden",
-						timeout: 1800,
-						setUp: function(t){
-							pane2.domNode.style.display = 'none';
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							pane2._msg = "This text should not be loaded until after widget is shown";
-							pane2.set('href', "getResponse.php?message="+encodeURI(pane2._msg));
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertFalse(pane2.domNode.innerHTML == pane2._msg);
-								}
-							), 1500);
-							return d;
-						},
-						tearDown: function(t){
-							pane2.domNode.style.display = "";
-						}
-					},
-					{
-						name: "onDownloadError",
-						timeout: 1800,
-						setUp: function(t){
-							pane2.set("content", "");
-						},
-						runTest: function(t){
-							var res = {};
-							var msg = "Error downloading modified message";
-							var orig = pane2.onDownloadError;
-
-
-							pane2.onDownloadError = function(){
-								return msg;
-							}
-
-							this.onError = function(e){
-								res.onError = true;
-								res.onError_Arg = !!e;
-								return "This message should be ignored as it gets invoked by dojo.connect";
-							}
-
-							var evtHandle = dojo.connect(pane2, 'onDownloadError', this, 'onError');
-
-							// test onDownloadError
-							pane2.set('href', 'nonexistant');
-
-							// do the test
-							var d = new t.Deferred();
-							setTimeout(function(){
-								try{
-									if(!res.onError){
-										d.errback(new doh._AssertFailure("onDownloadError was never invoked"));
-									}
-									if(!res.onError_Arg){
-										d.errback(new doh._AssertFailure("onDownloadError did'nt get any argument on invokation"));
-									}
-									if(pane2.domNode.innerHTML != msg){
-										d.errback(new doh._AssertFailure("custom errortext not set"));
-									}
-									d.callback(true);
-								}catch(e){
-									d.errback(e);
-								}finally{
-									// reset to default
-									dojo.disconnect(evtHandle);
-									pane2.onDownloadError = orig;
-								}
-							}, 1500);
-
-							return d;
-						}
-					},
-					{
-						name: "onLoad|Unload_onDownloadStart|End",
-						timeout: 2400,
-						setUp:function(t){
-							pane2.set("content", "");
-						},
-						runTest:function(t){
-							var obj = {
-								start:function(){
-									this.start_called = 1;
-									// check that custom message gets set
-									setTimeout(function(){
-										obj.start_msg = (pane2.domNode.innerHTML == msg);
-									}, 20);
-								},
-								end: function(){ this.end_called = 1; },
-								load: function(){ this.load_called = 1; },
-								unload: function(){ this.unload_called = 1; }
-							};
-
-							//set custom message
-							var origStart = pane2.onDownloadStart;
-							var msg = "custom downloadstart message";
-							pane2.onDownloadStart = function(){ return msg; };
-
-							var startHandler = dojo.connect(pane2, 'onDownloadStart', obj, 'start');
-							var endHandler = dojo.connect(pane2, 'onDownloadEnd', obj, 'end');
-							var loadHandler = dojo.connect(pane2, 'onLoad', obj, 'load');
-							var unloadHandler = dojo.connect(pane2, 'onUnload', obj, 'unload');
-
-							pane2.set('href', 'getResponse.php?delay=400');
-
-							var d = new t.Deferred();
-							setTimeout(function(){
-								try{
-									if(!obj.start_called){
-										d.errback(new doh._AssertFailure('onDownloadStart not called'));
-									}
-									if(!obj.start_msg){
-										d.errback(new doh._AssertFailure('custom download message not set'));
-									}
-									if(!obj.end_called){
-										d.errback(new doh._AssertFailure('onDownloadEnd not called'));
-									}
-									if(!obj.unload_called){
-										d.errback(new doh._AssertFailure('onUnload not called'));
-									}
-									if(!obj.load_called){
-										d.errback(new doh._AssertFailure('onLoad not called'));
-									}
-									d.callback(true);
-								}catch(e){
-									d.errback(e);
-								}finally{
-									dojo.disconnect(endHandler);
-									dojo.disconnect(startHandler);
-									dojo.disconnect(unloadHandler);
-									dojo.disconnect(loadHandler);
-
-									pane2.onDownloadStart = origStart;
-								}
-							}, 1900);
-
-							return d;
-						}
-					}
-
-				]
-			);
-
-			var st,		// stack container
-				pane3, pane3UnloadCnt=0, pane3LoadCnt=0,	// second child of stack container (initially hidden)
-				tmp;
-
-			doh.registerGroup("child_to_StackContainer",
-				[
-					{
-						// TODO: this test should be moved to registerGroup setUp now that #3504 is fixed
-						//		We actually don't need to test anything here, just setUp
-						name: "setUp_StackContainer",
-						setUp:function(t){
-							// create a StackContainer
-							st = dojo.byId('stackcontainer');
-							dojo.addClass(st, 'box');
-							st = new dijit.layout.StackContainer({}, st);
-
-							// the first child (by default) is the one that will
-							// be shown
-							st.addChild(new dijit.TestWidget());
-
-							// the second child *won't* be shown until selected
-							pane3 = new dijit.layout.ContentPane({
-								href:'getResponse.php?delay=300&message=Loaded!',
-								preventCache: true,
-								onLoad: function(){ pane3LoadCnt++; },
-								onUnload: function(){ pane3UnloadCnt++; }
-							}, dojo.doc.createElement('div'));
-							st.addChild(pane3);
-
-							// start the StackContainer; shouldn't cause ContentPane to load.
-							st.startup();
-						},
-						runTest:function(t){
-							t.assertTrue(st);
-							t.assertEqual(2, st.getChildren().length);
-						}
-					},
-					{
-						name: "preload_false_by_default",
-						runTest: function(t){
-							t.assertFalse(pane3.isLoaded);
-							t.assertEqual('', pane3.domNode.innerHTML);
-						}
-					},
-					{
-						name: "unload event not called initially",
-						runTest: function(t){
-							t.assertEqual(0, pane3UnloadCnt);
-						}
-					},
-					{
-						name: "load event fired when pane is shown",
-						timeout: 2100,
-						runTest: function(t){
-							t.assertEqual(0, pane3LoadCnt, "onload hasn't been called yet");
-							st.selectChild(pane3);
-							t.assertEqual(0, pane3UnloadCnt,
-								"unload shouldn't have been called b/c no initial contents (#1)");
-
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(
-								function(){
-									t.assertTrue(pane3.isLoaded);
-									t.assertEqual(1, pane3LoadCnt, "onload was called");
-									t.assertEqual('Loaded!', pane3.domNode.innerHTML);
-									t.assertEqual(0, pane3UnloadCnt,
-										"unload shouldn't have been called b/c no initial contents (#2)");
-								}
-							), 1800);
-
-							return d;
-						}
-					},
-					{
-						name: "refreshOnShow parameter works",
-						timeout: 2100,
-						setUp: function(t){
-							tmp = {
-								onUnload: function(){ this._unload_fired = 1; },
-								onLoad: function(){ this._load_fired = 1; }
-							};
-							tmp.unloadHandle = dojo.connect(pane3, 'onUnload', tmp, 'onUnload');
-							tmp.loadHandle = dojo.connect(pane3, 'onLoad', tmp, 'onLoad');
-
-							pane3.refreshOnShow = true;
-						},
-						runTest: function(t){
-							var d = new t.Deferred();
-							st.back();
-							st.forward();	// show pane #3
-
-							setTimeout(d.getTestCallback(function(){
-								t.assertTrue(tmp._unload_fired, "unload was fired");
-								t.assertTrue(tmp._load_fired, "load was fired");
-								t.assertEqual('Loaded!', pane3.domNode.innerHTML);
-							}), 1800);
-
-							return d;
-						},
-						tearDown: function(){
-							dojo.disconnect(tmp.unloadHandle);
-							dojo.disconnect(tmp.loadHandle);
-							pane3.refreshOnShow = pane3.constructor.prototype.refreshOnShow;
-						}
-					},
-					{
-						// Test if a plain ContentPane downloads it's contents when startup() is called.
-						// Nothing in particular to do with StackContainer.
-						name: "downloadTriggeredOnStartup",
-						timeout: 1800,
-						runTest: function(t){
-							var href = 'getResponse.php?message=Loaded!'
-							var pane4 = new dijit.layout.ContentPane({
-								href:href,
-								preventCache: true
-							});
-							pane4.placeAt(st.domNode, "after");
-
-							pane4.startup(); // parser should call startup when djConfig.parseOnLoad=true
-
-							var d = new t.Deferred();
-							setTimeout(d.getTestCallback(function(){
-								t.assertEqual('Loaded!', pane4.domNode.innerHTML);
-								pane4.destroy();
-							}), 1500);
-							return d;
-						}
 					}
 				]
 			);
@@ -607,14 +170,14 @@
 						name: "simple",
 						setUp: function(t){
 							pane5 = new dijit.layout.ContentPane({
-								content:"<div dojoType='dijit.layout.StackContainer'></div>"
+								content:"<div data-dojo-type='dijit.layout.StackContainer'></div>"
 							}, dojo.byId("pane5"));
 							console.log(pane5);
 						},
 						runTest: function(t){
 							// since there's just a single child it should be marked
 							// for layout/resize along w/the ContentPane
-							t.assertTrue(pane5._singleChild);
+							doh.t(pane5._singleChild);
 						},
 						tearDown: function(t){
 							pane5.destroyRecursive();
@@ -625,13 +188,13 @@
 						setUp: function(t){
 							pane5 = new dijit.layout.ContentPane({
 								content:
-									"<div dojoType='dijit.layout.StackContainer'></div>",
+									"<div data-dojo-type='dijit.layout.StackContainer'></div>",
 								doLayout: false
 							}, dojo.byId("pane5"));
 						},
 						runTest: function(t){
 							// since doLayout=false shouldn't try to resize child
-							t.assertFalse(pane5._singleChild);
+							doh.f(pane5._singleChild);
 						},
 						tearDown: function(t){
 							pane5.destroyRecursive();
@@ -643,13 +206,13 @@
 							pane5 = new dijit.layout.ContentPane({
 								content:
 									"<span>hello world</span>" +
-									"<div dojoType='dijit.layout.StackContainer'></div>"
+									"<div data-dojo-type='dijit.layout.StackContainer'></div>"
 							}, dojo.byId("pane5"));
 						},
 						runTest: function(t){
 							// since there's plain HTML along with the widget, ContentPane shouldn't try to adjust
 							// this size of the widget (since that would cover up the other HTML)
-							t.assertFalse(pane5._singleChild);
+							doh.f(pane5._singleChild);
 						},
 						tearDown: function(t){
 							pane5.destroyRecursive();
@@ -660,14 +223,14 @@
 						setUp: function(t){
 							pane5 = new dijit.layout.ContentPane({
 								content:
-									"<div dojoType='dijit.layout.StackContainer'></div>" +
-									"<div dojoType='dijit.layout.StackContainer'></div>"
+									"<div data-dojo-type='dijit.layout.StackContainer'></div>" +
+									"<div data-dojo-type='dijit.layout.StackContainer'></div>"
 							}, dojo.byId("pane5"));
 						},
 						runTest: function(t){
 							// since there are multiple children, neither should be marked
 							// for layout/resize along w/the ContentPane
-							t.assertFalse(pane5._singleChild);
+							doh.f(pane5._singleChild);
 						},
 						tearDown: function(t){
 							pane5.destroyRecursive();
@@ -678,16 +241,16 @@
 						setUp: function(t){
 							pane5 = new dijit.layout.ContentPane({
 								content:
-									"<div dojoType='dojo.data.ItemFileReadStore' jsId='dd'></div>" +
-									"<div dojoType='dijit.layout.StackContainer' id='sc'></div>"
+									"<div data-dojo-type='dojo.data.ItemFileReadStore' data-dojo-id='dd'></div>" +
+									"<div data-dojo-type='dijit.layout.StackContainer' id='sc'></div>"
 							}, dojo.byId("pane5"));
 						},
 						runTest: function(t){
 							// there are two children but one is invisible, so the other should be marked
 							// for layout/resize along w/the ContentPane
-							t.assertTrue(dd);
-							t.assertTrue(dijit.byId("sc"));
-							t.assertEqual(pane5._singleChild, dijit.byId("sc"));
+							doh.t(dd, "dd exists");
+							doh.t(dijit.byId("sc"), "sc exists");
+							doh.is(dijit.byId("sc"), pane5._singleChild, "pane5._singleChild");
 						},
 						tearDown: function(t){
 							pane5.destroyRecursive();
@@ -699,12 +262,12 @@
 							pane5 = new dijit.layout.ContentPane({
 								content:
 									"<scri" + "pt></scri" + "pt>" +
-									"<div dojoType='dijit.layout.StackContainer' id='sc'></div>"
+									"<div data-dojo-type='dijit.layout.StackContainer' id='sc'></div>"
 							}, dojo.byId("pane5"));
 						},
 						runTest: function(t){
 							// script tag should be ignored, should be detected as single child
-							t.assertTrue(pane5._singleChild, "script tag ignored, marked as single child");
+							doh.t(pane5._singleChild, "script tag ignored, marked as single child");
 						},
 						tearDown: function(t){
 							pane5.destroyRecursive();
@@ -739,11 +302,11 @@
 							container.set('content',
 								'<span>plain non-widget content</span>' +
 								'<div><span>' +
-									'<div id="zero" dojoType="dijit.TestContained"></div>' +
-									'<div id="one" dojoType="dijit.TestContained"></div>' +
+									'<div id="zero" data-dojo-type="dijit.TestContained"></div>' +
+									'<div id="one" data-dojo-type="dijit.TestContained"></div>' +
 								'</span></div>' +
-								'<div id="two" dojoType="dijit.TestContained"></div>' +
-								'<div id="three" dojoType="dijit._Widget"></div>'
+								'<div id="two" data-dojo-type="dijit.TestContained"></div>' +
+								'<div id="three" data-dojo-type="dijit._Widget"></div>'
 							);
 
 							// Since ContentPane is a container it should call startup
@@ -781,11 +344,11 @@
 							hiddenCP.set('content',
 								'<span>plain non-widget content</span>' +
 								'<div><span>' +
-									'<div id="deferredZero" dojoType="dijit.TestContained"></div>' +
-									'<div id="deferredOne" dojoType="dijit.TestContained"></div>' +
+									'<div id="deferredZero" data-dojo-type="dijit.TestContained"></div>' +
+									'<div id="deferredOne" data-dojo-type="dijit.TestContained"></div>' +
 								'</span></div>' +
-								'<div id="deferredTwo" dojoType="dijit.TestContained"></div>' +
-								'<div id="deferredThree" dojoType="dijit._Widget"></div>'
+								'<div id="deferredTwo" data-dojo-type="dijit.TestContained"></div>' +
+								'<div id="deferredThree" data-dojo-type="dijit._Widget"></div>'
 							);
 
 							t.f(dijit.byId('deferredTwo')._resized, "not resized yet");
@@ -840,6 +403,70 @@
 				]
 			);
 
+			// Test that popup widgets in a ContentPane are created and deleted correctly
+			doh.register("popup test", [
+				function create(){
+					dojo.parser.parse(dojo.byId("popupTest"));
+					doh.t(dijit.byId("popupPane"), "popup ContentPane created");
+					doh.t(dijit.byId("dialog"), "dialog created");
+					doh.is(dojo.body(), dijit.byId("dialog").domNode.parentNode, "dialog child of <body>");
+				},
+				function destroy(){
+					dijit.byId("popupPane").destroyRecursive();
+					doh.f(dijit.byId("popupPane"), "popup ContentPane destroyed");
+					doh.f(dijit.byId("dialog"), "dialog widget destroyed");
+					doh.f(dojo.byId("dialog"), "dialog DOMNode gone too");
+				}
+			]);
+
+			// Test that startup() on child widgets and plain JS objects is called at the correct time
+
+			var nwStartupCalls = 0;
+			dojo.declare("NonWidget", null, {
+				// summary: doesn't extend _Widget, used to test that startup() is still called
+				startup: function(){
+					if(!this._started){
+						nwStartupCalls++;
+						this._started = true;
+					}
+				}
+			});
+
+			doh.register("startup", [
+				function startupAfter(){
+					var cp1 = new dijit.layout.ContentPane({
+						content: "<div id='startup-c1' data-dojo-type='dijit.TestContained'></div>"
+					}).placeAt(dojo.body());
+					
+					var child = dijit.byId("startup-c1");
+					doh.t(child, "child widget created");
+					doh.f(child._started, "child widget not started yet");
+					
+					cp1.startup();
+					
+					doh.t(child._started, "starting ContentPane starts child widget");
+				},
+				function startupBefore(){
+					var cp2 = new dijit.layout.ContentPane({}).placeAt(dojo.body());
+					cp2.startup();
+					
+					cp2.set("content", "<div id='startup-c2' data-dojo-type='dijit.TestContained'></div>");
+					var child = dijit.byId("startup-c2");
+					doh.t(child, "child widget created");
+					doh.t(child._started, "child widget started");
+				},
+
+				function nonWidget(){
+					// 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");
+
+					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.run();
 		});
 	</script>
@@ -849,31 +476,46 @@
 	<h3>Test designed to run on localhost (minimize impact from network latency)</h3>
 
 	<h4>This should NOT be parsed automatically</h4>
-	<div dojoType="dijit.layout.ContentPane" class="box" id="pane1">
-		<div dojoType='dijit.TestWidget'>If this has a different background and a red border, the page parsed when it shouldn't</div>
+	<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
+		<div data-dojo-type='dijit.TestWidget'>If this has a different background and a red border, the page parsed when it shouldn't</div>
 	</div>
 	<br/><h3>Testing ContentPane</h3>
 	<div id='pane2' class='box'>
 		Even though the entire page isn't scanned for widgets,
 		any sub widgets of a ContentPane will be created when a ContentPane is created<br/>
-		<span id="zero" dojoType='dijit.TestWidget'>This should have a backgroundcolor and a border</span>
-		<div id="one" dojoType="dijit._Widget"></div>
-		<div id="two" dojoType="dijit._Widget"></div>
-		<div id="three" dojoType="dijit._Widget"></div>
+		<span id="2_zero" data-dojo-type='dijit.TestWidget'>This should have a backgroundcolor and a border</span>
+		<div id="2_one" data-dojo-type="dijit._Widget"></div>
+		<div id="2_two" data-dojo-type="dijit._Widget"></div>
+		<div id="2_three" data-dojo-type="dijit._Widget"></div>
 	</div>
 	<br/><br/>
-	<div id='stackcontainer'></div>
 	<div id="pane5"></div>
 
 	<!-- for container tests -->
-	<div id="container" dojoType="dijit.layout.ContentPane">
-		<div id="zero" dojoType="dijit.TestContained"></div>
-		<div id="one" dojoType="dijit.TestContained"></div>
-		<div id="two" dojoType="dijit.TestContained"></div>
-		<div id="three" dojoType="dijit._Widget"></div>
+	<div id="container" data-dojo-type="dijit.layout.ContentPane">
+		<div id="zero" data-dojo-type="dijit.TestContained"></div>
+		<div id="one" data-dojo-type="dijit.TestContained"></div>
+		<div id="two" data-dojo-type="dijit.TestContained"></div>
+		<div id="three" data-dojo-type="dijit._Widget"></div>
+	</div>
+	<div id="outside" data-dojo-type="dijit._Widget"></div>
+	<div id="outsideCont" data-dojo-type="dijit.TestContained"></div>
+
+	<!-- for testing popup widgets inside of a content pane -->
+	<div id="popupTest">
+		<div id="popupPane" data-dojo-type="dijit.layout.ContentPane">
+			<div id="dialog" data-dojo-type="dijit.Dialog">
+				hello world
+			</div>
+		</div>
+	</div>
+
+	<!-- for testing non-widgets inside of a content pane -->
+	<div id="nonWidgetTest">
+		<div id="nonWidgetPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-id="nwp">
+			<div data-dojo-type="NonWidget" data-dojo-id="nw1"></div>
+		</div>
 	</div>
-	<div id="outside" dojoType="dijit._Widget"></div>
-	<div id="outsideCont" dojoType="dijit.TestContained"></div>
 
 </body>
 </html>
diff --git a/dijit/tests/layout/ContentPaneLayout.html b/dijit/tests/layout/ContentPaneLayout.html
index ac143ff..e3ced12 100644
--- a/dijit/tests/layout/ContentPaneLayout.html
+++ b/dijit/tests/layout/ContentPaneLayout.html
@@ -1,49 +1,41 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane layout-related DOH test</title>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../themes/tundra/tundra.css";
+		@import "../../themes/claro/document.css";
+		@import "../../themes/claro/claro.css";
 		@import "../css/dijitTests.css";
 
 		.resizableWidget {
 			border: 1px dashed red;
-			background-color: #C0E209 ;
+			background-color: #C0E209;
 		}
 	</style>
 
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
+
 	<script type="text/javascript">
 		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
+
 		dojo.require("dijit._Widget");
 		dojo.require("dijit._Templated");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.layout.BorderContainer");
 		dojo.require("dijit.TitlePane");
+		dojo.require("dijit.form.Form");
 		dojo.require("dijit.Dialog");
 
 		// widgets used in doc loaded via href
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.Button");
 
-		// create a do nothing, only for test widget
-		dojo.declare("ResizableWidget",
-			[dijit._Widget, dijit._Templated], {
-			templateString: "<span class='resizableWidget'>resizable widget</span>",
-			_resized: 0,
-			_resizeArgs: null,
-			resize: function(){
-				this._resized++;
-				this._resizeArgs = arguments;
-			}
-		});
-
 		// Keep track of which panes have had a load event, and how
-		// many load events have occured for those panes
+		// many load events have occurred for those panes
 		var loadEvents = {
 		};
 		function myOnLoad(){
@@ -53,6 +45,31 @@
 
 		dojo.addOnLoad(function(){
 
+			// create a do nothing, only for test widget
+			dojo.declare("ResizableWidget",
+				[dijit._Widget, dijit._Templated], {
+				templateString: "<span class='dijitInline resizableWidget'>resizable widget</span>",
+				_resized: 0,
+				_resizeArgs: null,
+				
+				constructor: function(){
+					this.history = [];
+				},
+
+				startup: function(){
+					this.history.push("started");
+				},
+
+				resize: function(newSize){
+					this.history.push("resized");
+					this._resized++;
+					this._resizeArgs = arguments;
+					if(newSize){
+						dojo.marginBox(this.domNode, newSize);
+					}
+				}
+			});
+	
 			// Keep track of the number of startup() calls to every widget.
 			// Since the href's widgets haven't been created yet we monitor startup() calls on the prototype
 			var startups = {};
@@ -60,6 +77,10 @@
 				startups[this.id] = (startups[this.id] || 0) + 1;
 			});
 
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
 			// Test that ContentPanes calls startup() on child widgets appropriately
 			// TODO: overlap here (and other places) with ContentPane.html?
 			doh.register("startup events",
@@ -303,6 +324,94 @@
 							}), 4000);
 							return d;
 						}
+					},
+
+					// Test that resize() is called on resizable children hidden inside of a form widget
+					// where the form widget is inside a layout container
+					{
+						name: "multiple resizable elements hidden in form in TabContainer",
+						runTest: function(t){
+							var child1 = dijit.byId("resizableInForm1"),
+								child2 = dijit.byId("resizableInForm2");
+
+							doh.is(0, child1._resized, "child1 hasn't been shown yet so no resize events");
+							doh.is(1, child1.history.length, "child1 # of history events (before show)");
+							doh.is("started", child1.history[0], "child1 history");
+
+							doh.is(0, child2._resized, "child2 hasn't been shown yet so no resize events");
+							doh.is(1, child1.history.length, "child2 # of history events (before show)");
+							doh.is("started", child2.history[0], "child2 history");
+
+							dijit.byId("resizeTC").selectChild(dijit.byId("multipleResizableInForm"))
+
+							doh.t(child1._resized, "got resize event for child1");
+							doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1")
+							doh.t(child2._resized, "got resize event for child2");
+							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+						}
+					},
+
+					{
+						name: "single resizable element hidden in form in TabContainer",
+						runTest: function(t){
+							var child = dijit.byId("resizableInForm0");
+
+							doh.is(0, child._resized, "child hasn't been shown yet so no resize events");
+							doh.is(1, child.history.length, "child # of history events (before show)");
+							doh.is("started", child.history[0], "child history");
+
+							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")
+						}
+					},
+
+					// Test that form where parent *isn't* a layout container calls startup() and resize()
+					// on it's child layout widgets
+					{
+						name: "single resizable element in form with size",
+						runTest: function(t){
+							var child = dijit.byId("fssc");
+							doh.t(child._resized, "got resize event for child");
+							doh.is(1, child._resizeArgs && child._resizeArgs.length, "size specified")
+						}
+					},
+					
+					{
+						name: "multiple resizable elements in form with size",
+						runTest: function(t){
+							var child1 = dijit.byId("fsmc1"),
+								child2 = dijit.byId("fsmc2");
+
+							doh.t(child1._resized, "got resize event for child1");
+							doh.is(0, child1._resizeArgs && child1._resizeArgs.length, "no size specified for child1")
+							doh.t(child2._resized, "got resize event for child2");
+							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+						}
+					},
+
+					{
+						name: "single resizable elements in form with no size, doLayout=false",
+						runTest: function(t){
+							var child = dijit.byId("fnsc");
+
+							doh.t(child._resized, "got resize event for child");
+							doh.is(0, child._resizeArgs && child._resizeArgs.length, "no size specified for child")
+						}
+					},
+
+					{
+						name: "multiple resizable elements in form with no size",
+						runTest: function(t){
+							var child1 = dijit.byId("fnmc1"),
+								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.t(child2._resized, "got resize event for child2");
+							doh.is(0, child2._resizeArgs && child2._resizeArgs.length, "no size specified for child2")
+						}
 					}
 				]
 			);
@@ -536,115 +645,158 @@
 	</script>
 </head>
 <body class="claro">
-	<h2>dijit.layout.ContentPane layout related DOH test</h2>
+	<h1>dijit.layout.ContentPane layout related DOH test</h1>
 
 	<p>
 		Tests ContentPane in it's role as a layout widget, including as child of another layout widgets (especially TabContainer).
 	</p>
-	<hr>
 
-	<p>Tests that href gets loaded when ContentPane is first made visible:</p>
-	<div dojoType="dijit.layout.TabContainer" id="outerTC" style="width: 880px; height: 200px;">
-		<div dojoType="dijit.layout.ContentPane" id="pane1" href="doc0.html" title="Initially Selected" onLoad="myOnLoad">
+	<h2>Tests that href gets loaded when ContentPane is first made visible</h2>
+	<div id="outerTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 880px; height: 200px;"'>
+		<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad'>
 			initially selected pane
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="pane2" href="doc1.html" title="Initially Hidden" onLoad="myOnLoad">
+		<div id="pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
 			unselected pane
 		</div>
-		<div dojoType="dijit.layout.TabContainer" id="innerTC" nested="true" title="Nested TabContainer">
-			<div dojoType="dijit.layout.ContentPane" id="innerPane1" href="doc0.html" title="Initially Selected" onLoad="myOnLoad">
+		<div id="innerTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='nested:true, title:"Nested TabContainer"'>
+			<div id="innerPane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad'>
 				initially selected inner pane
 			</div>
-			<div dojoType="dijit.layout.ContentPane" id="innerPane2" href="doc1.html" title="Initially Hidden" onLoad="myOnLoad">
+			<div id="innerPane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
 				unselected pane
 			</div>
 		</div>
-		<div dojoType="dijit.layout.BorderContainer" id="bc" title="BorderContainer">
-			<div dojoType="dijit.layout.ContentPane" id="bcPane1" href="doc0.html" region="left" style="width: 200px;" onLoad="myOnLoad">
+		<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"BorderContainer"'>
+			<div id="bcPane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", region:"left", style:"width: 200px;", onLoad:myOnLoad'>
 				left pane
 			</div>
-			<div dojoType="dijit.layout.ContentPane" id="bcPane2" href="doc1.html" region="center" onLoad="myOnLoad">
+			<div id="bcPane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", region:"center", onLoad:myOnLoad'>
 				center pane
 
 				<!-- when this ContentPane is shown each of these widgets should get a resize()
 				 	 call w/no size specification -->
-				<div dojoType="ResizableWidget" id="bcResizable1"></div>
-				<div dojoType="ResizableWidget" id="bcResizable2"></div>
+				<div id="bcResizable1" data-dojo-type="ResizableWidget" ></div>
+				<div id="bcResizable2" data-dojo-type="ResizableWidget" ></div>
 			</div>
 		</div>
 	</div>
 
-	<p>Tests for resizing in a layout container hierarchy:</p>
-	<div dojoType="dijit.layout.TabContainer" id="resizeTC" style="width: 880px; height: 200px;">
-		<div dojoType="dijit.layout.ContentPane" id="resizePane1" title="Initially Selected" onLoad="myOnLoad">
+	<h2>Tests for resizing in a layout container hierarchy</h2>
+	<div id="resizeTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 880px; height: 200px;"'>
+		<div id="resizePane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Initially Selected", onLoad:myOnLoad'>
 			initially selected pane
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="singleChildPane" title="Single ResizableChild" onLoad="myOnLoad">
-			<div dojoType="ResizableWidget" id="singleChildResizable"></div>
+		<div id="singleChildPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Single ResizableChild", onLoad:myOnLoad'>
+			<div id="singleChildResizable" data-dojo-type="ResizableWidget" ></div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="multipleChildPanes" title="Multiple ResizableChild" onLoad="myOnLoad">
-			<div dojoType="ResizableWidget" id="multipleChildResizable1"></div>
+		<div id="multipleChildPanes" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Multiple ResizableChild", onLoad:myOnLoad'>
+			<div id="multipleChildResizable1" data-dojo-type="ResizableWidget" ></div>
 			<div style="border: groove blue medium;">
 				<span>hide the second widget to see if ContentPane can still find it</span>
-				<div dojoType="ResizableWidget" id="multipleChildResizable2"></div>
+				<div id="multipleChildResizable2" data-dojo-type="ResizableWidget" ></div>
 				<span>ending text</span>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="singleChildHref" title="Href Single Child"
-			href="borderContainer.php?id=singleChildHref" onLoad="myOnLoad"></div>
-		<div dojoType="dijit.layout.ContentPane" id="multipleChildHref" title="Href Multiple Children"
-			href="multipleLayoutWidgets.php?id=multipleChildHref" onLoad="myOnLoad"></div>
+		<div id="multipleResizableInForm" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Multiple resizable in form", onLoad:myOnLoad'>
+			<div data-dojo-type="dijit.form.Form">
+				<div id="resizableInForm1" data-dojo-type="ResizableWidget" ></div>
+				<div id="resizableInForm2" data-dojo-type="ResizableWidget" ></div>
+			</div>
+		</div>
+		<div id="singleResizableInForm" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Single resizable in form", onLoad:myOnLoad'>
+			<div data-dojo-type="dijit.form.Form">
+				<div id="resizableInForm0" data-dojo-type="ResizableWidget" ></div>
+			</div>
+		</div>
+		<div id="singleChildHref" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Href Single Child",
+			href:"borderContainer.php?id=singleChildHref", onLoad:myOnLoad'></div>
+		<div id="multipleChildHref" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Href Multiple Children",
+			href:"multipleLayoutWidgets.php?id=multipleChildHref", onLoad:myOnLoad'></div>
 	</div>
 
-	<p>Tests that ContentPane resize doesn't trigger reload:</p>
-	<div dojoType="dijit.layout.TabContainer" id="reloadTC" style="width: 880px; height: 200px;">
-		<div dojoType="dijit.layout.ContentPane" id="reloadTC_pane1" href="doc0.html" title="Initially Selected" onLoad="myOnLoad" refreshOnShow=true>
+	
+	<h2>Size on Form, single nested layout widgets</h2>
+	<form data-dojo-type="dijit.form.Form" style="height:100px; width: 100px; border: medium inset gray; padding: 10px;" id="fss">
+		<div data-dojo-type="ResizableWidget" id="fssc">
+		</div>
+	</form>
+
+	<h2>Size on Form, multiple nested layout widget</h2>
+	<form data-dojo-type="dijit.form.Form" style="height:250px; width: 150px; border: medium inset gray; padding: 10px;" id="fsm">
+		<div data-dojo-type="ResizableWidget" style="width: 100px; height: 100px; border: 1px solid black;" id="fsmc1">
+			child #1 (100x100)
+		</div>
+		<div data-dojo-type="ResizableWidget" style="width: 100px; height: 100px; border: 1px solid black;" id="fsmc2">
+			child #2 (100x100)
+		</div>
+	</form>
+
+	<h2>No size on Form, single nested layout widgets</h2>
+	<form data-dojo-type="dijit.form.Form" style="border: medium inset gray; padding: 10px;" data-dojo-props="doLayout: false" id="fns">
+		<div data-dojo-type="ResizableWidget" style="height:200px; width: 400px;" id="fnsc">
+		</div>
+	</form>
+
+	<h2>No size on Form, multiple nested layout widget</h2>
+	<form data-dojo-type="dijit.form.Form" style="border: medium inset gray; padding: 10px;" id="fnm">
+		<div data-dojo-type="ResizableWidget" style="width: 100px; height: 100px; border: 1px solid black;" id="fnmc1">
+			child #1 (100x100)
+		</div>
+		<div data-dojo-type="ResizableWidget" style="width: 100px; height: 100px; border: 1px solid black;" id="fnmc2">
+			child #2 (100x100)
+		</div>
+	</form>
+
+	<h2>Tests that ContentPane resize doesn't trigger reload</h2>
+	<div id="reloadTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 880px; height: 200px;"'>
+		<div id="reloadTC_pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc0.html", title:"Initially Selected", onLoad:myOnLoad, refreshOnShow:true'>
 			initially selected pane
 		</div>
-		<div dojoType="dijit.layout.ContentPane" id="reloadTC_pane2" href="doc1.html" title="Initially Hidden" onLoad="myOnLoad">
+		<div id="reloadTC_pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"doc1.html", title:"Initially Hidden", onLoad:myOnLoad'>
 			unselected pane
 		</div>
 	</div>
 
-	<p>Test the ContentPane loads href and resizes children (as per it's contract a layout widget)
-			when it's not a child of a layout container itself:</p>
-	<div dojoType="dijit.TitlePane" id="ctpHsc" title="Closed TitlePane Href Single Child" open=false
-		href="borderContainer.php?id=ctpHsc&sized=true" onLoad="myOnLoad"></div>
+	<h2>Test the ContentPane loads href and resizes children (as per it's contract a layout widget)
+			when it's not a child of a layout container itself</h2>
+	<div id="ctpHsc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Closed TitlePane Href Single Child", open:false,
+		href:"borderContainer.php?id=ctpHsc&sized=true", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div dojoType="dijit.TitlePane" id="ctpHmc" title="Closed TitlePane Href Multiple Children" open=false
-		href="multipleLayoutWidgets.php?id=ctpHmc" onLoad="myOnLoad"></div>
+	<div id="ctpHmc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Closed TitlePane Href Multiple Children", open:false,
+		href:"multipleLayoutWidgets.php?id=ctpHmc", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div dojoType="dijit.TitlePane" id="otpHsc" title="Opened TitlePane Href Single Child"
-		href="borderContainer.php?id=otpHsc&sized=true" onLoad="myOnLoad"></div>
+	<div id="otpHsc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Opened TitlePane Href Single Child",
+		href:"borderContainer.php?id=otpHsc&sized=true", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div dojoType="dijit.TitlePane" id="otpHmc" title="Opened TitlePane Href Multiple Children"
-		href="multipleLayoutWidgets.php?id=otpHmc" onLoad="myOnLoad"></div>
+	<div id="otpHmc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Opened TitlePane Href Multiple Children",
+		href:"multipleLayoutWidgets.php?id=otpHmc", onLoad:myOnLoad'></div>
 	<br><br>
 
-	<div dojoType="dijit.TitlePane" id="otpMc" title="Opened TitlePane Multiple Children">
+	<div id="otpMc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Opened TitlePane Multiple Children"'>
 		<!-- these widgets should get a resize on page load -->
-		<div dojoType="ResizableWidget" id="otpMc_child1"></div>
-		<div dojoType="ResizableWidget" id="otpMc_child2"></div>
+		<div id="otpMc_child1" data-dojo-type="ResizableWidget" ></div>
+		<div id="otpMc_child2" data-dojo-type="ResizableWidget" ></div>
 	</div>
 	<br><br>
 
-	<div dojoType="dijit.TitlePane" id="ctpMc" title="Closed TitlePane Multiple Children" open=false>
+	<div id="ctpMc" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Closed TitlePane Multiple Children", open:false'>
 		<!-- these widgets should get a resize() when the TitlePane is opened -->
-		<div dojoType="ResizableWidget" id="ctpMc_child1"></div>
-		<div dojoType="ResizableWidget" id="ctpMc_child2"></div>
+		<div id="ctpMc_child1" data-dojo-type="ResizableWidget" ></div>
+		<div id="ctpMc_child2" data-dojo-type="ResizableWidget" ></div>
 	</div>
 	<br><br>
 
-	<div dojoType="dijit.Dialog" id="dlgHmc" title="Dialog Href Multiple Children"
-		href="multipleLayoutWidgets.php?id=dlgHmc" onLoad="myOnLoad"></div>
+	<div id="dlgHmc" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Dialog Href Multiple Children",
+		href:"multipleLayoutWidgets.php?id=dlgHmc", onLoad:myOnLoad'></div>
 
-	<div dojoType="dijit.Dialog" id="dlgMc" title="Dialog Multiple Children">
+	<div id="dlgMc" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Dialog Multiple Children"'>
 		<!-- these widgets should get a resize() when the Dialog is opened -->
-		<div dojoType="ResizableWidget" id="dlgMc_child1"></div>
-		<div dojoType="ResizableWidget" id="dlgMc_child2"></div>
+		<div id="dlgMc_child1" data-dojo-type="ResizableWidget" ></div>
+		<div id="dlgMc_child2" data-dojo-type="ResizableWidget" ></div>
 	</div>
 
 </body>
diff --git a/dijit/tests/layout/LayoutContainer.html b/dijit/tests/layout/LayoutContainer.html
new file mode 100644
index 0000000..fae7ff6
--- /dev/null
+++ b/dijit/tests/layout/LayoutContainer.html
@@ -0,0 +1,296 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dijit.layout.LayoutContainer Test</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../themes/claro/claro.css";
+	</style>
+
+	<!-- required: the default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		djConfig="isDebug: true"></script>
+
+	<!-- only needed for alternate theme testing: do NOT use in your code! -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.layout.LayoutContainer");
+		dojo.require("dijit.layout.ContentPane");
+		dojo.require("dijit.form.FilteringSelect");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		
+		function checkInside(/*Widget*/ child, /*Widget*/ parent){
+			// summary:
+			//		Test that child is fully inside of parent
+			var cp = dojo.position(child.domNode, true),
+				pp = dojo.position(parent.domNode, true);
+
+			doh.t(
+				cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
+				cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
+				child.layoutAlign + " inside " + parent.id + dojo.toJson(cp) + dojo.toJson(pp)
+			);
+		}
+		function checkAbove(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
+			// summary:
+			//		Test that child is fully inside of parent
+
+			var ap = dojo.position(above.domNode, true),
+				bp = dojo.position(below.domNode, true);
+
+			doh.t(ap.y+ap.h <= bp.y,
+				comment + " " + above.layoutAlign + " above " + below.layoutAlign + dojo.toJson(ap) + dojo.toJson(bp)
+			);
+		}
+		function checkLeft(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
+			// summary:
+			//		Test that child is fully inside of parent
+
+			var lp = dojo.position(left.domNode, true),
+				rp = dojo.position(right.domNode, true);
+
+			doh.t(lp.x+lp.w <= rp.x,
+				comment + " " + left.layoutAlign + " to left of " + right.layoutAlign + dojo.toJson(lp) + dojo.toJson(rp)
+			);
+		}
+
+		dojo.addOnLoad(function(){
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("LayoutContainer", [
+				function basic(){
+					var lc = dijit.byId("basic");
+					dojo.forEach(lc.getChildren(), function(child){
+						checkInside(child, lc);
+					});
+
+					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");
+
+					// Check positions
+					checkLeft("left vs top", left, top);
+					checkLeft("left vs center", left, center);
+					checkLeft("bottom vs right", bottom, right);
+					checkAbove("top vs center", top, center);
+					checkAbove("center vs bottom", center, bottom);
+
+					// Check tab order
+					var tabbable = tabOrder(lc.domNode);
+					doh.is(7, tabbable.length, "each pane plus link and select");
+					doh.is(left.id, tabbable[0].id, "left");
+					doh.is(right.id, tabbable[1].id, "right");
+					doh.is(top.id, tabbable[2].id, "top");
+					doh.is(center.id, tabbable[3].id, "center");
+					doh.is(bottom.id, tabbable[6].id, "bottom");
+				},
+
+				function advanced(){
+					var lc = dijit.byId("advanced");
+					dojo.forEach(lc.getChildren(), function(child){
+						checkInside(child, lc);
+					});
+
+					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"),
+						bottom = dijit.byId("bottomcp_layout2");
+
+					// Check positions
+					checkLeft("left vs top", left, top);
+					checkLeft("left vs centerLeft", left, centerLeft);
+					checkLeft("centerLeft vs center", centerLeft, center);
+					checkLeft("center vs centerRight", center, centerRight);
+					checkAbove("top vs center", top, center);
+					checkAbove("top vs inner right", top, centerRight);
+					checkAbove("centerLeft vs bottom", centerLeft, bottom);
+
+					// Check tab order
+					var tabbable = tabOrder(lc.domNode);
+					doh.is(8, tabbable.length, "each pane plus link and select");
+					doh.is(left.id, tabbable[0].id, "left");
+					doh.is(top.id, tabbable[1].id, "top");
+					doh.is(bottom.id, tabbable[2].id, "bottom");
+					doh.is(centerLeft.id, tabbable[3].id, "center left");
+					doh.is(center.id, tabbable[4].id, "center");
+					doh.is(centerRight.id, tabbable[7].id, "center right");
+				}
+			]);
+			
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+	<h2 id="heading" >Dijit layout.LayoutContainer tests</h2>
+
+	<p>Basic layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
+	should be:  left, right, top, middle/main, bottom</p>
+
+	<div id="basic" dojoType="dijit.layout.LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div dojoType="dijit.layout.ContentPane" id="leftcp_layout1" layoutAlign="left" style="background-color: #acb386; width: 100px;" tabindex="0">
+			left
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="rightcp_layout1" layoutAlign="right" style="background-color: #acb386;"  tabindex="0">
+			right
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="topcp_layout1" layoutAlign="top" style="background-color: #b39b86; "  tabindex="0">
+			top bar
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="centercp_layout1" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px;"  tabindex="0">
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select dojoType="dijit.form.FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+
+		<div dojoType="dijit.layout.ContentPane" id="bottomcp_layout1" layoutAlign="bottom" style="background-color: #b39b86;"  tabindex="0">
+			bottom bar
+		</div>
+
+	</div>
+
+	<p>Advanced layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
+	should be:  left, top, bottom, inner left, inner middle, inner right. This is not an ideal tab order. See below to use nested
+	layout containers to achieve a tab order which matches presentation and source code order.</p>
+	<div id="advanced" dojoType="dijit.layout.LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div dojoType="dijit.layout.ContentPane" id="leftcp_layout2" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
+			left
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="topcp_layout2" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
+			top bar
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="bottomcp_layout2" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0">
+
+			bottom bar
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="centerLeftcp_layout2" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+			inner left
+		</div>
+
+		<div dojoType="dijit.layout.ContentPane" id="centercp_layout2" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+
+			(to check we're copying children around properly).<br />
+			<select dojoType="dijit.form.FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+		<div dojoType="dijit.layout.ContentPane" id="centerRightcp_layout2" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+			inner right
+		</div>
+	</div>
+
+	<p>Advanced layout with nested containers.  Tabindex="0" added to content panes to show tab order. Order should be:
+	left, top, inner left, inner middle, inner right, bottom. This is the preferred tab order for this type of layout.</p>
+	<div dojoType="dijit.layout.LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div dojoType="dijit.layout.ContentPane" id="leftcp_layout3" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
+			left
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="margin: 5px;" >
+			<div dojoType="dijit.layout.LayoutContainer"	style="height:90%;border: 2px solid black;padding: 10px;">
+
+				<div dojoType="dijit.layout.ContentPane" id="topcp_layout3" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
+					top bar
+				</div>
+				<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="margin: 5px;">
+					<div dojoType="dijit.layout.LayoutContainer"	style="height:80%;border: 2px solid black;padding: 10px;">
+						<div dojoType="dijit.layout.ContentPane" id="centerLeftcp_layout3" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+							inner left
+						</div>
+						<div dojoType="dijit.layout.ContentPane" id="centercp_layout3" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
+							main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+							(to check we're copying children around properly).<br />
+							<select dojoType="dijit.form.FilteringSelect">
+								<option value="1">foo</option>
+								<option value="2">bar</option>
+								<option value="3">baz</option>
+							</select>
+							Here's some text that comes AFTER the combo box.
+						</div>
+						<div dojoType="dijit.layout.ContentPane" id="centerRightcp_layout3" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
+							inner right
+						</div>
+					</div>
+				</div>
+				<div dojoType="dijit.layout.ContentPane" id="bottomcp_layout3" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0"	>
+					bottom bar
+				</div>
+			</div>
+		</div>
+	</div>
+
+	<p>Goofy spiral layout.  Match of source code order to tab order can not be achieved with this type of layout.</p>
+	<div dojoType="dijit.layout.LayoutContainer"
+		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
+	>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #663333; color: white; width: 100px;">
+			outer left
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #333366; color: white; height: 50px;">
+			outer top
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #663333; color: white; width: 100px;">
+			outer right
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #333366; color: white; height: 50px;">
+			outer bottom
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #99CC99; width: 100px;">
+			inner left
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #999966; height: 50px;">
+			inner top
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #99CC99; width: 100px;">
+			inner right
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #999966; height: 50px;">
+			inner bottom
+		</div>
+		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="padding: 10px;">
+			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
+			(to check we're copying children around properly).<br />
+			<select dojoType="dijit.form.FilteringSelect">
+				<option value="1">foo</option>
+				<option value="2">bar</option>
+				<option value="3">baz</option>
+			</select>
+			Here's some text that comes AFTER the combo box.
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/TabContainer.html b/dijit/tests/layout/TabContainer.html
index ab2222f..943e7e8 100644
--- a/dijit/tests/layout/TabContainer.html
+++ b/dijit/tests/layout/TabContainer.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
-	<title>TabContainer Test</title>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>TabContainer DOH Test</title>
 
 	<style>
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 	<script type="text/javascript" src="../helpers.js"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
@@ -31,6 +31,10 @@
 		// create a do nothing, only for test widget
 		dojo.addOnLoad(function(){
 
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
 			doh.register("creationAndDestruction", [
 
 				// Test that destroyRecursive removes all supporting widgets, including the list-of-tabs menu
@@ -47,36 +51,7 @@
 	
 						tc.destroyRecursive();
 	
-						t.assertEqual(dijit.registry.length, num);
-					}
-				},
-	
-				// Tests that creating a TabContainer creates the list-of-tabs Menu.
-				// (Note though that TabContainer doesn't need to create that Menu until the user presses the show-menu Button)
-				{
-					name: 'createWithMenu',
-					runTest: function(t){
-						var numMenus = dijit.registry.byClass("dijit.Menu").length;
-						var tc = new dijit.layout.TabContainer({ id:"createWithMenu", useMenu:true }).placeAt(dojo.body());
-						
-						var numCreatedMenus = dijit.registry.byClass("dijit.Menu").length;
-						t.assertEqual(numMenus + 1, numCreatedMenus);
-	
-						tc.destroyRecursive();
-					}
-				},
-	
-				// Tests that creating a TabContainer with useMenu=false doesn't create a list-of-tabs Menu.
-				{
-					name: 'createWithoutMenu',
-					runTest: function(t){
-						var numMenus = dijit.registry.byClass("dijit.Menu").length;
-						var tc = new dijit.layout.TabContainer({ id:"createWithoutMenu", useMenu:false }).placeAt(dojo.body());
-						
-						var numCreatedMenus = dijit.registry.byClass("dijit.Menu").length;
-						t.assertEqual(numMenus, numCreatedMenus);
-	
-						tc.destroyRecursive();
+						t.is(dijit.registry.length, num);
 					}
 				},
 				
@@ -85,30 +60,28 @@
 					name: 'checkTabLabels',
 					runTest: function(t){
 						var tabLabels = dojo.query("#tc1 .tabLabel");
-						t.assertEqual(4, tabLabels.length);
+						t.is(4, tabLabels.length);
 					}
 				}
 			]);
 			
 			doh.register("addingTabs", [
 
-				// Test that adding a pane creates new tab button and new menu item
+				// Test that adding a pane creates new tab button
 				{
 					name: 'add new tab',
 					runTest: function(t){
 						var tc = dijit.byId("tc1");
 						var cp1 = new dijit.layout.ContentPane({
-								id: "newTab1",
-						         title: "newTab1",
-						         content: "newTab1 content"
-						    });
+							id: "newTab1",
+							title: "newTab1",
+							content: "newTab1 content"
+						});
 						tc.addChild(cp1);
 						
 						var tabLabels = dijit.byId("tc1").getChildren();
-						var menuLabels = dijit.byId("tc1_tablist_menu").getChildren();
 						
-						t.assertEqual(5, tabLabels.length, "there are 5 tabs");
-						t.assertEqual(5, menuLabels.length, "there are 5 menu items");
+						t.is(5, tabLabels.length, "there are 5 tabs");
 					}
 				},
 				
@@ -119,23 +92,23 @@
 						var tc = dijit.byId("tc1");
 						
 						var cp2 = new dijit.layout.ContentPane({
-						         id: "newTab2",
-						         title: "newTab2",
-						         content: "newTab2 content"
-							});
+							id: "newTab2",
+							title: "newTab2",
+							content: "newTab2 content"
+						});
 						tc.addChild(cp2);
 						
 						var left = dojo.byId("tc1_tablist_leftBtn");
 						var right = dojo.byId("tc1_tablist_rightBtn");						
 						var menu = dojo.byId("tc1_tablist_menuBtn");
 
-						t.assertTrue(left, "verify left scroll button exists");
-						t.assertTrue(right, "verify right scroll button exists");
-						t.assertTrue(menu, "verify dropdown menu button exists");
+						t.t(left, "verify left scroll button exists");
+						t.t(right, "verify right scroll button exists");
+						t.t(menu, "verify dropdown menu button exists");
 							
-						t.assertTrue(isVisible(left), "left scroll is displayed");
-						t.assertTrue(isVisible(right), "right scroll is displayed");
-						t.assertTrue(isVisible(menu), "menu is displayed");	
+						t.t(isVisible(left), "left scroll button is displayed");
+						t.t(isVisible(right), "right scroll button is displayed");
+						t.t(isVisible(menu), "menu button is displayed");	
 					}
 				}
 			]);
@@ -155,18 +128,18 @@
 						tc.selectChild(cp);
 						
 						setTimeout(d.getTestCallback(function(){
-								var cpLeft = dojo.byId("tc1_tablist_leftBtn");
-								var left = dojo.position(cpLeft).x + dojo.position(cpLeft).w;
+							var cpLeft = dojo.byId("tc1_tablist_leftBtn");
+							var left = dojo.position(cpLeft).x + dojo.position(cpLeft).w;
 
-								var cpRight = dojo.byId("tc1_tablist_rightBtn");
-								var right = dojo.position(cpRight).x;
+							var cpRight = dojo.byId("tc1_tablist_rightBtn");
+							var right = dojo.position(cpRight).x;
 
-								var tab = dijit.byId("tc1_tablist_newTab1");
-								var tabLeft = dojo.position(tab.domNode).x;
-								var tabRight = dojo.position(tab.domNode).x + dojo.position(tab.domNode).w;
+							var tab = dijit.byId("tc1_tablist_newTab1");
+							var tabLeft = dojo.position(tab.domNode).x;
+							var tabRight = dojo.position(tab.domNode).x + dojo.position(tab.domNode).w;
 								
-								var isTabVisible = ((tabLeft > left) && (tabRight < right));
-								doh.t(isTabVisible, "verify chosen tab is in viewable area");
+							var isTabVisible = ((tabLeft > left) && (tabRight < right));
+							doh.t(isTabVisible, "verify chosen tab is in viewable area");
 						}), 1000);
 						
 						return d;
@@ -178,31 +151,31 @@
 				{
 					name: "initialIcon",
 					runTest: function(t){
-						var cp =  dijit.byId("cp4");
-						var menuTitle = dijit.byId("cp7_stcMi").label;
+						var cp = dijit.byId("cp4");
 						
-						t.assertEqual('plusIcon', cp.controlButton.iconClass, "an icon image is displayed");
-						t.assertEqual('plus', menuTitle, "the menu's text label is 'plus'");
+						t.is('tab1', innerText(cp.controlButton.containerNode), "tab label");
+						t.is('plusIcon', cp.controlButton.iconClass, "tab icon");
 					}
 				},
 				{
 					name: "changeIcon",
 					runTest: function(t){
-						var cp =  dijit.byId("cp4");
-						cp.set("iconClass", "noteIcon"); 
-						cp.set("title", "note");
-						
-						var menuTitle = dijit.byId("cp7_stcMi").label;
+						var cp = dijit.byId("cp4");
+
+						cp.set({
+							"title": "note",
+							"iconClass": "noteIcon"
+						});
 						
-						t.assertEqual('noteIcon', cp.controlButton.iconClass, "new icon is displayed in tab");
-						t.assertEqual('plus', menuTitle, "the menu's text label has changed");
+						t.is('note', innerText(cp.controlButton.containerNode), "the tab's label has changed");
+						t.is('noteIcon', cp.controlButton.iconClass, "new icon is displayed in tab");
 					}
 				},
 				{
 					name: "noTitle",
 					runTest: function(t){
-						var cp =  dijit.byId("cp7");
-						t.assertFalse(cp.controlButton.showLabel, "an icon exists, but there is no text label");
+						var cp = dijit.byId("cp7");
+						t.f(cp.controlButton.showLabel, "an icon exists, but there is no text label");
 					}
 				}
 			]);
@@ -215,17 +188,15 @@
 						cp.set('title', 'newTitle');
 						
 						var title = dojo.query("#tc1_tablist_cpTitle span.tabLabel")[0];
-						var menuTitle = dijit.byId("cpTitle_stcMi").label;
 						
-						t.assertEqual('newTitle', innerText(title), "the tab's text label has changed");
-						t.assertEqual('newTitle', menuTitle, "the menu's text label has changed");
+						t.is('newTitle', innerText(title), "the tab's text label has changed");
 					}
 				}
 			]);
 
 			doh.register("deletingTabs", [
 
-				// Check that deleting a pane removes the tab button, menu item, etc.
+				// Check that deleting a pane removes the tab button
 				{
 					name: 'deleteTab',
 					runTest: function(t){
@@ -235,14 +206,12 @@
 						tc1.removeChild(cp);
 						
 						var childPanes = tc1.getChildren();
-						var menuLabels = dijit.byId("tc1_tablist_menu").getChildren();
 						
-						t.assertEqual(5, childPanes.length, "verify there are now only 4 tabs instead of 5");
-						t.assertEqual(5,  menuLabels.length, "verify there are now only 4 menu items instead of 5");
-						t.assertTrue(cp.domNode, "verify that the deleted tab's content pane still exists on the page");
+						t.is(5, childPanes.length, "verify there are now only 4 tabs instead of 5");
+						t.t(cp.domNode, "verify that the deleted tab's content pane still exists on the page");
 
 						var label = dojo.byId("#tc1_tablist_cpTitle");
-						t.assertFalse(label, "verify that deleted tab's label does not exist");
+						t.f(label, "verify that deleted tab's label does not exist");
 					}
 				},
 				
@@ -265,9 +234,9 @@
 						var right = dijit.byId("tc3_tablist_rightBtn").domNode;
 						var menu = dijit.byId("tc3_tablist_menuBtn").domNode;
 						
-						t.assertTrue(isHidden(left), "left scroll is hidden");
-						t.assertTrue(isHidden(right), "right scroll is hidden");
-						t.assertTrue(isHidden(menu), "menu is hidden");
+						t.t(isHidden(left), "left scroll is hidden");
+						t.t(isHidden(right), "right scroll is hidden");
+						t.t(isHidden(menu), "menu is hidden");
 					}
 				}
 			]);
@@ -279,58 +248,138 @@
 						var cp = dijit.byId("cp6");
 						var cp2 = dijit.byId("cp5");
 						
-						t.assertTrue(cp.controlButton.closeButton, "close button is displayed");
-						t.assertFalse(cp2.controlButton.closeButton, "close button is displayed");
+						t.t(cp.controlButton.closeButton, "close button is displayed");
+						t.f(cp2.controlButton.closeButton, "close button is not displayed");
 					}
 				}
 			]);		
 
+			doh.register("menu", {
+				name: "menu",
+				runTest: function(t){
+					var tc1 = dijit.byId("tc1"),
+						children = tc1.getChildren();
+				
+					// add an icon and change the title just for testing that the icon and label appear in the menu
+					children[0].set({
+						title: "new title",
+						iconClass: "noteIcon"
+					});
+						
+					var menuBtn = dijit.byId("tc1_tablist_menuBtn");
+					menuBtn.toggleDropDown();
+
+					var menu = dijit.byId("tc1_menu");
+					doh.t(isVisible(menu), "menu exists and is visible");
+					doh.is(menu.getChildren().length, children.length, "# of menu children");
+					doh.is("new title", innerText(menu.getChildren()[0].containerNode));
+					doh.is("noteIcon", menu.getChildren()[0].iconClass);
+				},
+				tearDown: function(){
+					var tc1 = dijit.byId("tc1"),
+						children = tc1.getChildren();
+
+					children[0].set({
+						title: "old title",
+						iconClass: ""
+					});
+
+					var menuBtn = dijit.byId("tc1_tablist_menuBtn");
+					menuBtn.closeDropDown();
+				}
+			});
+
 			doh.register("layoutTests", [
 				{
-					name: "topLeftRightBottom",
+					name: "tabPosition",
 					runTest: function(t){
 						var tc = dijit.byId("tc1");
 
-						// TODO: should test actual positions of tabs vs. content, not just settings
-						t.assertEqual('top', tc.tabPosition, "tabs are on the top of the container");
-						
-						tc.set("tabPosition", "left");						
-						t.assertEqual('left', tc.tabPosition, "tabs are on the left of the container");
-						
-						tc.set("tabPosition", "right");						
-						t.assertEqual('right', tc.tabPosition, "tabs are on the right of the container");
-						
-						tc.set("tabPosition", "bottom");						
-						t.assertEqual('bottom', tc.tabPosition, "tabs are on the bottom of the container");
+						// top tabs above content
+						var topTabs = dojo.byId("tc1_tablist"),
+							topContent = dojo.query(".dijitTabPaneWrapper", "tc1")[0],
+							topTabsPos = dojo.position(topTabs),
+							topContentPos = dojo.position(topContent);
+						t.t(topTabsPos.y + topTabsPos.h <= topContentPos.y, "top tabs above content " +
+							dojo.toJson(topTabsPos) + dojo.toJson(topContentPos));
+
+						// left tabs to left of content
+						var leftTabs = dojo.byId("leftTabs_tablist"),
+							leftContent = dojo.query(".dijitTabPaneWrapper", "leftTabs")[0],
+							leftTabsPos = dojo.position(leftTabs),
+							leftContentPos = dojo.position(leftContent);
+						t.t(leftTabsPos.x + Math.floor(leftTabsPos.w) <= leftContentPos.x, "left tabs before content " +
+							dojo.toJson(leftTabsPos) + dojo.toJson(leftContentPos));
+
+						// right tabs to right of content
+						var rightTabs = dojo.byId("rightTabs_tablist"),
+							rightContent = dojo.query(".dijitTabPaneWrapper", "rightTabs")[0],
+							rightTabsPos = dojo.position(rightTabs),
+							rightContentPos = dojo.position(rightContent);
+						t.t(rightTabsPos.x >= rightContentPos.x + rightContentPos.w, "right tabs after content " +
+							dojo.toJson(rightTabsPos) + dojo.toJson(rightContentPos));
+
+						// bottom tabs below content
+						var bottomTabs = dojo.byId("bottomTabs_tablist"),
+							bottomContent = dojo.query(".dijitTabPaneWrapper", "bottomTabs")[0],
+							bottomTabsPos = dojo.position(bottomTabs),
+							bottomContentPos = dojo.position(bottomContent);
+						t.t(bottomTabsPos.y >= bottomContentPos.y + bottomContentPos.h, "bottom tabs below content " +
+							dojo.toJson(bottomTabsPos) + dojo.toJson(bottomContentPos));
 					}
 				},
 				{
 					name: "nested",
 					runTest: function(t){
-						var tc = dijit.byId("tcNested");
+						var parent = dijit.byId("tcNestedParent"),
+							child = dijit.byId("tcNestedChild");
 
-						// TODO: check that nested CSS class applied in the right place
-						t.assertFalse(tc.nested, "parent TabContainer is not nested");
+						t.f(parent.nested, "parent TabContainer is not nested");
 						
-						var children = tc.getChildren();
-						t.assertEqual(2, children.length, "parent TabContainer has multiple children");
+						var children = parent.getChildren();
+						t.is(2, children.length, "parent TabContainer has multiple children");
 						
-						t.assertTrue(children[1].nested, "second child of parent TabContainer has nested tabs");
+						t.t(children[1].nested, "second child of parent TabContainer has nested tabs");
+						t.t(dojo.hasClass("tcNestedChild_tablist", "dijitTabContainerTabListNested"), "nested CSS applied");
+						
+						// test that when TabButtons overflow to 2 rows, the content area is reduced
+						parent.selectChild(dijit.byId("tcNestedChild"));
+						var content = dojo.query(".dijitTabPaneWrapper", "tcNestedChild")[0],
+							height0 = dojo.position(content).h;
+
+						var newGrandchildren = [];
+						for(var i=0; i<10; i++){
+							var gc = new dijit.layout.ContentPane({
+								title: "additional child #" + i,
+								content: "hello world " + i
+							});
+							newGrandchildren.push(gc);
+							child.addChild(gc);
+						}
+						var height1 = dojo.position(content).h;
+						doh.t(height1 < height0, "content area size reduced ", height1, height0);
+
+						// and that size increases back when children are removed
+						dojo.forEach(newGrandchildren, dojo.hitch(child, "removeChild"));
+						var height2 = dojo.position(content).h;
+						doh.is(height0, height2, "after deleting extra children height restored to original");
 					}
 				},
 				{
 					name: "doLayoutFalse",
 					runTest: function(t){
-						var tc = dijit.byId("tcDoLayout");
+						var tc = dijit.byId("tcNoLayout");
 						var cps = tc.getChildren();
 
-						// TODO: should check that height of TabContainer itself changes when different
-						// tabs are selected
+						tc.selectChild(cps[0]);
+						var height1 = tc.domNode.offsetHeight;
 						tc.selectChild(cps[1]);
-						var height1 = cps[0]._contentBox.h;
-						var height2 = cps[1]._contentBox.h;
-						
-						t.assertTrue(height1 < height2, "height changes with the content length");
+						var height2 = tc.domNode.offsetHeight;
+						tc.selectChild(cps[2]);
+						var height3 = tc.domNode.offsetHeight;
+
+						t.t(height1 < height2, "height 1 < height 2" + height1 + " < " + height2);
+						t.t(height2 < height3, "height 2 < height 3" + height2 + " < " + height3);
 					}
 				},
 				{
@@ -338,36 +387,82 @@
 					runTest: function(t){
 						var tc = dijit.byId("tc3");
 						var cps = tc.getChildren();
-						
-						// TODO: should check that height of TabContainer itself stays constant when different
-						// tabs are selected
+
+						tc.selectChild(cps[0]);
+						var height1 = tc.domNode.offsetHeight;
 						tc.selectChild(cps[1]);
-						var height1 = cps[0]._contentBox.h;
-						var height2 = cps[1]._contentBox.h;
-						
-						t.assertTrue(height1 === height2, "height does not change with the content length");
+						var height2 = tc.domNode.offsetHeight;
+						tc.selectChild(cps[2]);
+						var height3 = tc.domNode.offsetHeight;
+
+						t.is(height1, height2);
+						t.is(height2, height3);
+						t.t(height1 > 10, "make sure height measurement is giving something reasonable");
 					}
 				}
 				
 			]);
-			doh.register("destroy widget", [
-				// TODO: looks like this can be moved up to be part of top group, creationAndDestruction?
-				{
-					name: 'destroyRecursive',
-					runTest: function(t){
-						var tcAmount = dijit.registry.byClass("dijit.layout.TabContainer").length - 1;
+			var tabId = 1;
+	        function addTab(tc){
+				// summary:
+				//		Add a tab to specified TabContainer
+				var cp = new dijit.layout.ContentPane({
+					title: 'Tab' + tabId,
+					content: "Contents of Tab " + tabId++
+				});
+				tc.addChild(cp);
+	        }
 
-						var tc = dijit.byId("tc1");
-						tc.destroyRecursive();
-						
-						var tc1 = dojo.query("#tc1");
-						var tcNewAmount = dijit.registry.byClass("dijit.layout.TabContainer").length;
+			doh.register("empty tab container",[
+				function createEmptyTabContainer(){
+					var emptyTC = new dijit.layout.TabContainer({id:"emptyTC", style:'height:200px;width:500px;'});
+					dojo.place(emptyTC.domNode, dojo.body());
+					emptyTC.startup();
 
-						t.assertEqual(0, tc1.length, "the html for the TabContainer is removed from the page");
-						t.assertEqual(tcAmount, tcNewAmount, "the amount of TabContainers on the page");
-					}
+					var children = emptyTC.getChildren();
+					doh.is(0, children.length);
+					doh.t(isVisible(emptyTC));
+					
+					var pos = dojo.position(emptyTC.domNode);
+					var heightDiff = 200 - pos.h;
+					var widthDiff = 500 - pos.w;
+					doh.t(-0.01 < heightDiff && heightDiff < 0.01);
+					doh.t(-0.01 < widthDiff && widthDiff < 0.01);
+				},
+				function addTabToEmptyTabContainer(){
+					var tc = dijit.byId("emptyTC");
+					addTab(tc);							
+
+					var children = tc.getChildren();
+					doh.is(1, children.length);
+					doh.is("Tab1", children[0].title);
+					doh.is("Contents of Tab 1", tc.selectedChildWidget.domNode.innerHTML);
+
+					doh.t(isVisible(tc.tablist.containerNode.childNodes[0]));
+				},
+				function add2ndTabToEmptyTabContainer(){
+					var tc = dijit.byId("emptyTC");
+					addTab(tc);							
+					tc.selectChild(tc.getChildren()[1]);							
+
+					var children = tc.getChildren();
+					doh.is(2, children.length);
+					doh.is("Tab2", children[1].title);
+					doh.is("Contents of Tab 2", tc.selectedChildWidget.domNode.innerHTML);
+					
+					doh.t(isVisible(tc.tablist.containerNode.childNodes[1]));
+				},
+				function remove2ndTabToEmptyTabContainer(){
+					var tc = dijit.byId("emptyTC");
+					tc.removeChild(tc.getChildren()[1]);							
+
+					var children = tc.getChildren();
+					doh.is(1, children.length);
+					doh.is("Tab1", children[0].title);
+					doh.is("Contents of Tab 1", tc.selectedChildWidget.domNode.innerHTML);
 				}
-			]);
+			]);			
+
 			doh.run();
 
 		});
@@ -376,104 +471,132 @@
 </head>
 <body class="claro">
 
-	<h1 class="testTitle">Dijit layout.TabContainer tests</h1>
+	<h1 class="testTitle">Dijit layout.TabContainer DOH tests</h1>
 	
-	<div dojoType="dijit.layout.TabContainer" style="width: 300px; height: 100px;" id="tc1">
-	  <div dojoType="dijit.layout.ContentPane" title="tab1" id="cpTitle" selected="true">
-	    Lorem ipsum and all around...
-	  </div>
-	  <div dojoType="dijit.layout.ContentPane" title="tab2">
-	    Lorem ipsum and all around - second...
-	  </div>
-	  <div dojoType="dijit.layout.ContentPane" id="t3" title="tab3" closable="true">
-	    Lorem ipsum and all around - last...
-	  </div>
-		 <div dojoType="dijit.layout.ContentPane" title="tab4" closable="true">
-		    Lorem ipsum and all around - last...
-		  </div>
+	<div id="tc1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 300px; height: 100px;" '>
+		<div id="cpTitle" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab1", selected:true'>
+			Lorem ipsum and all around...
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab2"'>
+			Lorem ipsum and all around - second...
+		</div>
+		<div id="t3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab3", closable:true'>
+			Lorem ipsum and all around - third...
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab4", closable:true'>
+			Lorem ipsum and all around - last...
+		</div>
 	</div>
 	
-	<div dojoType="dijit.layout.TabContainer" style="width: 300px; height: 100px;" id="tc2">
-	  <div dojoType="dijit.layout.ContentPane" id="cp1" title="tab1" selected="true">
-	    Lorem ipsum and all around...
-	  </div>
-	  <div dojoType="dijit.layout.ContentPane" id="cp2" title="tab2">
-	    Lorem ipsum and all around - second...
-	  </div>
-	  <div dojoType="dijit.layout.ContentPane" id="cp3" title="tab3" closable="true">
-	    Lorem ipsum and all around - last...
-	  </div>
+	<div id="tc3" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 300px; height: 100px;" '>
+		<div id="cp4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab1", selected:true, iconClass:"plusIcon"'>
+			Lorem ipsum and all around...
+		</div>
+		<div id="cp5" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab2"'>
+			 Lorem ipsum and all around - last...
+			<br />
+			<br />
+			<br />
+			Hmmm even more expanding tabs......
+		</div>
+		<div id="cp6" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab3", closable:true'>
+			Lorem ipsum and all around - last...
+		</div>
+		<div id="cp7" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"plus", closable:true, iconClass:"plusIcon", showTitle:false'>
+			Lorem ipsum and all around - last...
+		</div>
+		<div id="cp8" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab4", closable:true'>
+			Lorem ipsum and all around - last...
+		</div>
+		<div id="cp9" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab5", closable:true'>
+			Lorem ipsum and all around - last...
+		</div>
+		<div id="cp10" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"tab6", closable:true'>
+			Lorem ipsum and all around - last...
+		</div>
 	</div>
 	
-	<div dojoType="dijit.layout.TabContainer" style="width: 300px; height: 100px;" id="tc3">
-	  	<div dojoType="dijit.layout.ContentPane" id="cp4" title="tab1" selected="true" iconClass="plusIcon">
-	    	Lorem ipsum and all around...
-	  	</div>
-	  	<div dojoType="dijit.layout.ContentPane" id="cp5" title="tab2">
-	    	 Lorem ipsum and all around - last...
-	            <br />
-	            <br />
-	            <br />
-	            Hmmm even more expanding tabs......
-	  	</div>
-	  	<div dojoType="dijit.layout.ContentPane" id="cp6" title="tab3" closable="true">
-	    	Lorem ipsum and all around - last...
-	  	</div>
-		<div dojoType="dijit.layout.ContentPane" id="cp7" title="plus" closable="true" iconClass="plusIcon" showTitle="false">
-	    	Lorem ipsum and all around - last...
-	  	</div>
-		<div dojoType="dijit.layout.ContentPane" id="cp8" title="tab4" closable="true">
-	    	Lorem ipsum and all around - last...
-	  	</div>
-		<div dojoType="dijit.layout.ContentPane" id="cp9" title="tab5" closable="true">
-	    	Lorem ipsum and all around - last...
-	  	</div>
-		<div dojoType="dijit.layout.ContentPane" id="cp10" title="tab6" closable="true">
-	    	Lorem ipsum and all around - last...
-	  	</div>
+	<div id="tcNestedParent" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 300px;" '>
+		<div id="tcNestedChild" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 1", nested:true '>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first inner tab", selected:true'>
+				Lorem ipsum and all around...
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second inner tab"'>
+				Lorem ipsum and all around - second...
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last inner tab"'>
+				Lorem ipsum and all around - last...
+			</div>
+		</div>
+		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 2", nested:true'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first inner tab", selected:true'>
+				Lorem ipsum and all around...
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second inner tab"'>
+				Lorem ipsum and all around - second...
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last inner tab"'>
+				Lorem ipsum and all around - last...
+			</div>
+		</div>
 	</div>
 	
-	<div dojoType="dijit.layout.TabContainer" style="width: 400px; height: 100px;" id="tcNested">
-	    <div dojoType="dijit.layout.TabContainer" title="Tab 1" nested="true">
-	        <div dojoType="dijit.layout.ContentPane" title="My first inner tab" selected="true">
-	            Lorem ipsum and all around...
-	        </div>
-	        <div dojoType="dijit.layout.ContentPane" title="My second inner tab">
-	            Lorem ipsum and all around - second...
-	        </div>
-	        <div dojoType="dijit.layout.ContentPane" title="My last inner tab">
-	            Lorem ipsum and all around - last...
-	        </div>
-	    </div>
-	    <div dojoType="dijit.layout.TabContainer" title="Tab 2" nested="true">
-	        <div dojoType="dijit.layout.ContentPane" title="My first inner tab" selected="true">
-	            Lorem ipsum and all around...
-	        </div>
-	        <div dojoType="dijit.layout.ContentPane" title="My second inner tab">
-	            Lorem ipsum and all around - second...
-	        </div>
-	        <div dojoType="dijit.layout.ContentPane" title="My last inner tab">
-	            Lorem ipsum and all around - last...
-	        </div>
-	    </div>
+	<div id="tcNoLayout" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 100%;", doLayout:false'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+			Lorem ipsum and all around...
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+			Lorem ipsum and all around - second...
+			<br />
+			Hmmm expanding tabs......
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+			Lorem ipsum and all around - last...
+			<br />
+			<br />
+			<br />
+			Hmmm even more expanding tabs......
+		</div>
 	</div>
-	
-	<div dojoType="dijit.layout.TabContainer" id="tcDoLayout" style="width: 100%;" doLayout="false">
-	        <div dojoType="dijit.layout.ContentPane" title="My first tab" selected="true">
-	            Lorem ipsum and all around...
-	        </div>
-	        <div dojoType="dijit.layout.ContentPane" title="My second tab" closable="true">
-	            Lorem ipsum and all around - second...
-	            <br />
-	            Hmmm expanding tabs......
-	        </div>
-	        <div dojoType="dijit.layout.ContentPane" title="My last tab">
-	            Lorem ipsum and all around - last...
-	            <br />
-	            <br />
-	            <br />
-	            Hmmm even more expanding tabs......
-	        </div>
-	    </div>
-	</body>
-</html>
\ No newline at end of file
+	<br />
+
+	<div id="leftTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"left-h"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+			Left tabs
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+			Lorem ipsum and all around - second...
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+			Lorem ipsum and all around - last...
+		</div>
+	</div>
+	<br />
+
+	<div id="rightTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"right-h"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+			Right tabs
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+			Lorem ipsum and all around - second...
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+			Lorem ipsum and all around - last...
+		</div>
+	</div>
+	<br />
+
+	<div id="bottomTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 500px; height: 200px;",  tabPosition:"bottom"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My first tab", selected:true'>
+			Bottom tabs
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My second tab", closable:true'>
+			Lorem ipsum and all around - second...
+		</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"My last tab"'>
+			Lorem ipsum and all around - last...
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/TabContainerTitlePane.html b/dijit/tests/layout/TabContainerTitlePane.html
new file mode 100644
index 0000000..48b256b
--- /dev/null
+++ b/dijit/tests/layout/TabContainerTitlePane.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>TabContainer Nested TitlePane Test</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- 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">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.layout.TabContainer");
+		dojo.require("dijit.TitlePane");
+
+		var resized = {};
+
+		dojo.addOnLoad(function(){
+			dojo.connect(dijit.layout.TabContainer.prototype, "resize", function(){
+				resized[this.id] = true;
+			});
+			dojo.parser.parse(dojo.body());
+
+			// Tests that TabContainer.resize() (for the TabContainers nested in TitlePanes)
+			// is called at the right time.
+			doh.register("resize timing", [
+				{
+					name: "subtabs1",
+					runTest: function(t){
+						// Since tab 1 is selected and TitlePane 1 is open, subtabs1 should have resized on parse
+						doh.t(resized["subtabs1"], "subtabs1");
+						doh.f(resized["subtabs2"], "subtabs2");
+						doh.f(resized["subtabs3"], "subtabs3");
+					}
+				},
+				{
+					name: "subtabs2",
+					runTest: function(t){
+						// Since TitlePane 2 is open, subtabs2 should get a resize when tab2 is selected
+						dijit.byId("mainTabContainer").selectChild(dijit.byId("tab2"));
+						doh.t(resized["subtabs2"], "subtabs2");
+						doh.f(resized["subtabs3"], "subtabs3");
+					}
+				},
+				{
+					name: "subtabs3",
+					runTest: function(t){
+						// Since TitlePane 3 is closed, subtabs3 shouldn't get a resize until tab3 is selected
+						// and TitlePane is open
+						dijit.byId("mainTabContainer").selectChild(dijit.byId("tab3"));
+						doh.f(resized["subtabs3"], "subtabs3 not sized yet");
+						dijit.byId("tp3").set("open", true);
+						doh.t(resized["subtabs3"], "subtabs3 sized");
+					}
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Dijit layout.TabContainer nested TitlePane tests</h1>
+
+	<div id="mainTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 100%; height: 150px;"'>
+
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "tab1", title:"Tab 1"'>
+			<h1>I am tab 1</h1>
+			<div data-dojo-type="dijit.TitlePane" data-dojo-props='id: "tp1", title:"Title pane 1", style:{width:"300px"}'>
+				<p>This is a title pane, containing another tab container ...</p>
+				<p>
+					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
+				</p>
+				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='id: "subtabs1", style:"width: 100%; height: 150px;"'>
+					<div id="tab1_1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="tab1_2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				</div>
+			</div>
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "tab2", title:"Tab 2"'>
+			<h1>I am tab 2</h1>
+			<div data-dojo-type="dijit.TitlePane" data-dojo-props='id: "tp2", title:"Title pane 2", style:{width:"300px"}'>
+				<p>This is a title pane, containing another tab container ...</p>
+				<p>
+					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
+				</p>
+				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='id: "subtabs2", style:"width: 100%; height: 150px;"'>
+					<div id="tab2_1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="tab2_2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				</div>
+			</div>
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "tab3", title:"Tab 3"'>
+			<h1>I am tab 3</h1>
+			<div data-dojo-type="dijit.TitlePane" data-dojo-props='id: "tp3", title:"Title pane 3", style:{width:"300px"}, open: false'>
+				<p>This is a title pane, containing another tab container ...</p>
+				<p>
+					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
+				</p>
+				<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='id: "subtabs3", style:"width: 100%; height: 150px;"'>
+					<div id="tab3_1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+					<div id="tab3_2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+				</div>
+			</div>
+		</div>
+
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "hrefTab", href:"tab2.html", title:"Href Tab"'></div>
+	</div>
+
+	<h3>Rendering time</h3>
+
+</body>
+</html>
diff --git a/dijit/tests/layout/borderContainer.php b/dijit/tests/layout/borderContainer.php
index 1585325..25d8995 100644
--- a/dijit/tests/layout/borderContainer.php
+++ b/dijit/tests/layout/borderContainer.php
@@ -7,26 +7,28 @@
 
 	// sized=true means that it will add a width/height to the BorderContainer
 ?>
-<div dojoType="dijit.layout.BorderContainer"
-	id="<?=$id?>BorderContainer"
+<div data-dojo-type="dijit.layout.BorderContainer"
+	id="<?php echo $id?>BorderContainer"
 	<?php
 		if($_GET['sized']){
 			print "style='width: 300px; height: 300px;'";
 		}
 	?>
 >
-	<div dojoType="dijit.layout.ContentPane" region="left" style="width: 200px;">
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width: 200px;"'>
 		This file contains a single top-level BorderContainer layout widget.
 	</div>
-	<div dojoType="dijit.layout.ContentPane" region="center" onLoad="myOnLoad">
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", onLoad:myOnLoad'>
 		But it also has some nested layout widgets, and when this file is loaded the TabContainer and
 		BorderContainer below should get resize() called on them
-		<div dojoType="dijit.layout.TabContainer" id="<?=$id?>InnerTabContainer" style="width: 300px; height: 300px;">
-			<div dojoType="dijit.layout.ContentPane" title="Tab 1"><?=$id?> tab1</div>
-			<div dojoType="dijit.layout.ContentPane" title="Tab 2"><?=$id?> tab2</div>
+		<div data-dojo-type="dijit.layout.TabContainer" id="<?php echo $id?>InnerTabContainer"
+			data-dojo-props='style:"width: 300px; height: 300px;"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'><?php echo $id?> tab1</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'><?php echo $id?> tab2</div>
 		</div>
-		<div dojoType="dijit.layout.BorderContainer" id="<?=$id?>InnerBorderContainer" style="width: 300px; height: 300px;">
-			<div dojoType="dijit.layout.ContentPane" region="center">inner border container</div>
+		<div data-dojo-type="dijit.layout.BorderContainer" id="<?php echo $id?>InnerBorderContainer"
+			data-dojo-props='style:"width: 300px; height: 300px;"'>
+			<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
diff --git a/dijit/tests/layout/combotab.html b/dijit/tests/layout/combotab.html
index c881761..47fa563 100644
--- a/dijit/tests/layout/combotab.html
+++ b/dijit/tests/layout/combotab.html
@@ -1,11 +1,9 @@
-<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
-	url="../_data/states.json"></div>
+<div data-dojo-id="stateStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
 State:
-<span id="editable" dojoType="dijit.InlineEditBox" editor="dijit.form.ComboBox"
-	editorParams="{value: 'California', store: stateStore, searchAttr: 'name', promptMessage: 'Please enter a state'}">
-	<script type="dojo/connect" event="onChange">
+<span id="editable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.ComboBox",
+	editorParams:{value: "California", store: stateStore, searchAttr: "name", promptMessage: "Please enter a state"}'>
+	<script type="dojo/connect" data-dojo-event="onChange">
 		// connect to editable onChange event, Note that we dont need to disconnect
 		console.log('User selected:'+this.getValue());
 	</script>
 </span>
-
diff --git a/dijit/tests/layout/doc0.html b/dijit/tests/layout/doc0.html
index f2fb959..6317194 100644
--- a/dijit/tests/layout/doc0.html
+++ b/dijit/tests/layout/doc0.html
@@ -2,13 +2,13 @@
 This document has <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 (to check we're copying children around properly).<br />
 Plus some widgets and native fields:<br />
-<input value="native input">
-<select dojoType="dijit.form.ComboBox">
+<input value="native input"/>
+<select data-dojo-type="dijit.form.ComboBox">
 	<option value="1">dijit</option>
 	<option value="2">form</option>
 	<option value="3">ComboBox</option>
 </select>
 <button>native button</button>
-<button dojoType="dijit.form.Button">dijit.Button</button><br>
+<button data-dojo-type="dijit.form.Button">dijit.Button</button><br>
 
 Here's some text that comes AFTER the button.
diff --git a/dijit/tests/layout/getResponse.php b/dijit/tests/layout/getResponse.php
index 4510547..2d3e0ad 100644
--- a/dijit/tests/layout/getResponse.php
+++ b/dijit/tests/layout/getResponse.php
@@ -24,11 +24,11 @@
 				$delay = 2;
 				break;
 			case 1:
-				echo "<div dojotype='dijit.TestWidget'>Testing attr('href', ...)</div>";
+				echo "<div data-dojo-type='dijit.TestWidget'>Testing attr('href', ...)</div>";
 				break;
 			case 2:
-				echo "<div dojotype='dijit.TestWidget'>Delayed attr('href', ...) test</div>
-					  <div dojotype='dijit.TestWidget'>Delayed by " . ($delay/1000000) . " sec.</div>";
+				echo "<div data-dojo-type='dijit.TestWidget'>Delayed attr('href', ...) test</div>
+					  <div data-dojo-type='dijit.TestWidget'>Delayed by " . ($delay/1000000) . " sec.</div>";
 				break;
 			case 3:
 				echo "IT WAS the best of times, it was the worst of <a id='timeref' href='http://www.timeanddate.com/worldclock/'>times</a>, it was the age of wisdom, it was the age of foolishness, it was the epoch of belief, it was the epoch of incredulity, it was the season of Light, it was the season of Darkness, it was the spring of hope, it was the winter of despair, we had everything before us, we had nothing before us, we were all going direct to Heaven, we were all going direct the other way [...]
diff --git a/dijit/tests/layout/module.js b/dijit/tests/layout/module.js
index 7e61101..2f739b2 100644
--- a/dijit/tests/layout/module.js
+++ b/dijit/tests/layout/module.js
@@ -1,20 +1,34 @@
 dojo.provide("dijit.tests.layout.module");
 
 try{
-	doh.registerUrl("dijit.tests.layout.ContentPane", dojo.moduleUrl("dijit", "tests/layout/ContentPane.html"), 99999999);
-	doh.registerUrl("dijit.tests.layout.ContentPaneLayout", dojo.moduleUrl("dijit", "tests/layout/ContentPaneLayout.html"), 99999999);
+	doh.registerUrl("dijit.tests.layout.ContentPane", dojo.moduleUrl("dijit", "tests/layout/ContentPane.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.test_ContentPane", dojo.moduleUrl("dijit", "tests/layout/test_ContentPane.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.ContentPaneLayout", dojo.moduleUrl("dijit", "tests/layout/ContentPaneLayout.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.ContentPane-remote", dojo.moduleUrl("dijit","tests/layout/ContentPane-remote.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.StackContainer", dojo.moduleUrl("dijit", "tests/layout/nestedStack.html"), 99999999); 
+	doh.registerUrl("dijit.tests.layout.robot.GUI", dojo.moduleUrl("dijit","tests/layout/robot/GUI.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.TabContainer", dojo.moduleUrl("dijit", "tests/layout/TabContainer.html"), 99999999);
-	doh.registerUrl("dijit.tests.layout.robot.TabContainer_a11y", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_a11y.html"), 99999999);
-	doh.registerUrl("dijit.tests.layout.robot.TabContainer_mouse", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_mouse.html"), 99999999);
+	doh.registerUrl("dijit.tests.layout.LayoutContainer", dojo.moduleUrl("dijit", "tests/layout/LayoutContainer.html"), 999999);
 
-	doh.registerUrl("dijit.tests.layout.AccordionContainer", dojo.moduleUrl("dijit", "tests/layout/AccordionContainer.html"), 99999999);
-	doh.registerUrl("dijit.tests.layout.robot.AccordionContainer_a11y", dojo.moduleUrl("dijit","tests/layout/robot/AccordionContainer_a11y.html"), 99999999);
-	doh.registerUrl("dijit.tests.layout.robot.AccordionContainer_mouse", dojo.moduleUrl("dijit","tests/layout/robot/AccordionContainer_mouse.html"), 99999999);
+	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.robot.BorderContainer", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer.html"), 99999999); 
+	doh.registerUrl("dijit.tests.layout.TabContainer", dojo.moduleUrl("dijit", "tests/layout/TabContainer.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.TabContainer_a11y", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_a11y.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.TabContainer_mouse", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_mouse.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.TabContainer_noLayout", dojo.moduleUrl("dijit","tests/layout/robot/TabContainer_noLayout.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.TabContainerTitlePane", dojo.moduleUrl("dijit","tests/layout/TabContainerTitlePane.html"), 999999);
+	
+	doh.registerUrl("dijit.tests.layout.AccordionContainer", dojo.moduleUrl("dijit", "tests/layout/AccordionContainer.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.AccordionContainer_a11y", dojo.moduleUrl("dijit","tests/layout/robot/AccordionContainer_a11y.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.AccordionContainer_mouse", dojo.moduleUrl("dijit","tests/layout/robot/AccordionContainer_mouse.html"), 999999);
+
+	doh.registerUrl("dijit.tests.layout.BorderContainer", dojo.moduleUrl("dijit", "tests/layout/BorderContainer.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.BorderContainer", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.BorderContainer_full", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer_full.html"), 999999);
+	doh.registerUrl("dijit.tests.layout.robot.BorderContainer_complex", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer_complex.html"), 999999);
+
+	doh.registerUrl("dijit.tests.layout.robot.BorderContainer_nested", dojo.moduleUrl("dijit", "tests/layout/robot/BorderContainer_nested.html"), 999999);
 }catch(e){
 	doh.debug(e);
 }
diff --git a/dijit/tests/layout/multipleLayoutWidgets.php b/dijit/tests/layout/multipleLayoutWidgets.php
index 9437111..890d30f 100644
--- a/dijit/tests/layout/multipleLayoutWidgets.php
+++ b/dijit/tests/layout/multipleLayoutWidgets.php
@@ -5,10 +5,10 @@
 ?>
 This file has some nested layout widgets, and when this file is loaded the TabContainer and
 BorderContainer below should get resize() called on them
-<div dojoType="dijit.layout.TabContainer" id="<?=$id?>TabContainer" style="width: 300px; height: 300px;">
-	<div dojoType="dijit.layout.ContentPane" title="Tab 1">doc4 tab1</div>
-	<div dojoType="dijit.layout.ContentPane" title="Tab 2">doc4 tab2</div>
+<div data-dojo-type="dijit.layout.TabContainer" id="<?php echo $id ?>TabContainer" data-dojo-props='style:"width: 300px; height: 300px;"'>
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>doc4 tab1</div>
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>doc4 tab2</div>
 </div>
-<div dojoType="dijit.layout.BorderContainer" id="<?=$id?>BorderContainer" style="width: 300px; height: 300px;">
-	<div dojoType="dijit.layout.ContentPane" region="center">inner border container</div>
+<div data-dojo-type="dijit.layout.BorderContainer" id="<?php echo $id ?>BorderContainer" data-dojo-props='style:"width: 300px; height: 300px;"'>
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>inner border container</div>
 </div>
\ No newline at end of file
diff --git a/dijit/tests/layout/nestedStack.html b/dijit/tests/layout/nestedStack.html
index 9713acf..24e733b 100644
--- a/dijit/tests/layout/nestedStack.html
+++ b/dijit/tests/layout/nestedStack.html
@@ -1,17 +1,18 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
 	<title>TabContainerLite in StackContainer</title>
-	<link href="../../themes/tundra/tundra.css" rel="stylesheet" type="text/css" />
-	<link href="../../../dojo/resources/dojo.css" rel="stylesheet" type="text/css" />
+	<link href="../../themes/claro/claro.css" rel="stylesheet" type="text/css"/>
+	<link href="../../themes/claro/document.css" rel="stylesheet" type="text/css"/>
 	<script type="text/javascript"
-			language="javascript"
 			src="../../../dojo/dojo.js"
-			djConfig="parseOnLoad: true, isDebug: true">
+			data-dojo-config="isDebug: true">
 	</script>
-	<script type="text/javascript" language="javascript">
+	<script type="text/javascript">
 		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
 		dojo.require("dijit.layout._LayoutWidget");
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.layout.ContentPane");
@@ -32,22 +33,26 @@
 			resizeLog[widget.id] = dojo.style(widget.domNode, "style");
 			resizeCnt[widget.id] = (resizeCnt[widget.id] || 0) + 1;
 		}
-
-		dojo.declare("dijit.TestLayoutContained",
-			dijit.layout._LayoutWidget, {
-				startup: function(){
-					this.inherited(arguments);
-					this._started = true;
-				},
-				resize: function(){
-					this.inherited(arguments);
-					this._contentBox = dojo.contentBox(this.domNode);
-					this._resized = true;
+	
+		dojo.addOnLoad(function(){
+			dojo.declare("dijit.TestLayoutContained",
+				dijit.layout._LayoutWidget, {
+					startup: function(){
+						this.inherited(arguments);
+						this._started = true;
+					},
+					resize: function(){
+						this.inherited(arguments);
+						this._contentBox = dojo.contentBox(this.domNode);
+						this._resized = true;
+					}
 				}
-			}
-		);
+			);
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
 
-		dojo.addOnLoad(function(){
 			doh.registerGroup("after load",
 				[
 					{
@@ -148,45 +153,43 @@
 <body class="claro">
 	<h1>Integration: TabContainer in StackContainer</h1>
 	<br>
-	<button dojoType="dijit.form.Button" id="previousPR"
-		onClick="dijit.byId('myStackContainerPR').back()"><</button>
-	<span dojoType="dijit.layout.StackController" containerId="myStackContainerPR"></span>
-	<button dojoType="dijit.form.Button" id="nextPR"
-		onClick="dijit.byId('myStackContainerPR').forward()">></button>
-	<div id="myStackContainerPR" dojoType="dijit.layout.StackContainer"
-		style="height:150px; width: 400px;">
-			<div dojoType="dijit.layout.TabContainer" id="tab1" title="tab container 1">
-				<script type="dojo/connect" event="resize">
+	<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:"height:150px; width: 400px;"'>
+			<div id="tab1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"tab container 1"'>
+				<script type="dojo/connect" data-dojo-event="resize">
 					onResize(this);
 				</script>
-				<div dojoType="dijit.layout.ContentPane" id="tab1cp1" title="TC1/tab1" href="tab1.html">
-					<script type="dojo/connect" event="resize">
+				<div id="tab1cp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC1/tab1", href:"tab1.html"'>
+					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 				</div>
-				<div dojoType="dijit.layout.ContentPane" id="tab1cp2" title="TC1/tab2" href="tab2.html">
-					<script type="dojo/connect" event="resize">
+				<div id="tab1cp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC1/tab2", href:"tab2.html"'>
+					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 				</div>
 			</div>
-			<div dojoType="dijit.layout.TabContainer" id="tab2" title="tab container 2">
-				<script type="dojo/connect" event="resize">
+			<div id="tab2" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"tab container 2"'>
+				<script type="dojo/connect" data-dojo-event="resize">
 					onResize(this);
 				</script>
-				<div dojoType="dijit.layout.ContentPane" id="tab2cp1" title="TC2/tab 1" href="tab1.html">
-					<script type="dojo/connect" event="resize">
+				<div id="tab2cp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC2/tab 1", href:"tab1.html"'>
+					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
 				</div>
-				<div dojoType="dijit.layout.ContentPane" id="tab2cp2" title="TC2/tab 2">
-					<script type="dojo/connect" event="resize">
+				<div id="tab2cp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"TC2/tab 2"'>
+					<script type="dojo/connect" data-dojo-event="resize">
 						onResize(this);
 					</script>
-					<div><span>
-						<div jsId="deferredZero" dojoType="dijit.TestLayoutContained">test nested layout widget</div>
-						<div jsId="deferredOne" dojoType="dijit.TestLayoutContained">another test nested layout widget</div>
-					</span></div>
+					<div><div>
+						<div data-dojo-id="deferredZero" data-dojo-type="dijit.TestLayoutContained">test nested layout widget</div>
+						<div data-dojo-id="deferredOne" data-dojo-type="dijit.TestLayoutContained">another test nested layout widget</div>
+					</div></div>
 				</div>
 			</div>
 	</div>
diff --git a/dijit/tests/layout/robot/AccordionContainer_a11y.html b/dijit/tests/layout/robot/AccordionContainer_a11y.html
index f4297ee..bce55e8 100644
--- a/dijit/tests/layout/robot/AccordionContainer_a11y.html
+++ b/dijit/tests/layout/robot/AccordionContainer_a11y.html
@@ -20,7 +20,7 @@
 
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_AccordionContainer.html');
-				doh.register("Accordion A11Y tests",[
+				doh.register("Accordion A11Y tests", [
 					{
 						name: "basic operation",
 						timeout: 10000,
@@ -44,6 +44,13 @@
 								doh.is("lazyLoadPane", dojo.global.dijit.byId("markupAccordion").get("selectedChildWidget").id, "second pane is now selected");
 							}), 500);
 
+							// Workaround FF4 bug where overflow:auto panes get focus even when
+							// they don't have a scrollbar, remove when
+							// https://bugzilla.mozilla.org/show_bug.cgi?id=616594 fixed
+							if(dojo.isFF == 4){
+								dojo.query("#lazyLoadPane").style("overflow", "hidden");
+							}
+
 							// Tab into second pane's content area, landing on link inside pane
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestErrback(function(){
diff --git a/dijit/tests/layout/robot/AccordionContainer_mouse.html b/dijit/tests/layout/robot/AccordionContainer_mouse.html
index 9a165a3..5fee52c 100644
--- a/dijit/tests/layout/robot/AccordionContainer_mouse.html
+++ b/dijit/tests/layout/robot/AccordionContainer_mouse.html
@@ -17,7 +17,7 @@
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
-
+			
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_AccordionContainer.html');
 				doh.register("Accordion Mouse tests",[
@@ -28,18 +28,18 @@
 							var d = new doh.Deferred();
 
 							// Click open second pane
-							doh.robot.mouseMoveAt("lazyLoadPane_button_title", 500);
+							doh.robot.mouseMoveAt("lazyLoadPane_button_title", 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.is("lazyLoadPane", dojo.global.dijit.byId("markupAccordion").get("selectedChildWidget").id, "second pane is now selected");
 							}), 500);
 
 							// Click open fourth pane
-							doh.robot.mouseMoveAt("embeddedLayoutPane_button_title", 500);
-							doh.robot.mouseClick({left: true}, 2000);
+							doh.robot.mouseMoveAt("embeddedLayoutPane_button_title", 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is("embeddedLayoutPane", dojo.global.dijit.byId("markupAccordion").get("selectedChildWidget").id, "fourth pane is now selected");
-							}), 500);
+							}), 2000);
 
 							return d;
 						}
diff --git a/dijit/tests/layout/robot/BorderContainer.html b/dijit/tests/layout/robot/BorderContainer.html
index 3412500..a20f2c1 100644
--- a/dijit/tests/layout/robot/BorderContainer.html
+++ b/dijit/tests/layout/robot/BorderContainer.html
@@ -14,203 +14,14 @@
 
 		<!-- functions to help test -->
 		<script type="text/javascript" src="../../helpers.js"></script>
+		<script type="text/javascript" src="./borderContainerTestFunctions.js"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			function checkInside(/*Widget*/ child, /*Widget*/ parent){
-				// summary:
-				//		Test that child is fully inside of parent
-				var cp = dojo.position(child.domNode, true),
-					pp = dojo.position(parent.domNode, true);
-
-				doh.t(
-					cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
-					cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
-					child.region + " inside " + parent.id + dojo.toJson(cp) + dojo.toJson(pp)
-				);
-			}
-			function checkAbove(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
-				// summary:
-				//		Test that child is fully inside of parent
-
-				var ap = dojo.position(above.domNode, true),
-					bp = dojo.position(below.domNode, true);
-
-				doh.t(ap.y+ap.h < bp.y,
-					comment + " " + above.region + " above " + below.region + dojo.toJson(ap) + dojo.toJson(bp)
-				);
-			}
-			function checkLeft(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
-				// summary:
-				//		Test that child is fully inside of parent
-
-				var lp = dojo.position(left.domNode, true),
-					rp = dojo.position(right.domNode, true);
-
-				doh.t(lp.x+lp.w < rp.x,
-					comment + " " + left.region + " to left of " + right.region + dojo.toJson(lp) + dojo.toJson(rp)
-				);
-			}
-
-			function checkBCpanes(/*BorderContainer*/ bc){
-				// summary:
-				//		Check that all the panes in this BorderContainer are in sane
-				//		positions relative to each other
-				var children = bc.getChildren(),
-					regions = {};
-
-				// Check all panes inside BorderContainer
-				dojo.forEach(children, function(child){
-					checkInside(child, bc);
-					regions[child.region] = child;
-				});
-
-				// Check pane positions relative to each other
-				dojo.forEach(children, function(child){
-					switch(child.region){
-						case "top":
-							dojo.forEach(bc.design == "sidebar" ? ["center", "bottom"] : ["left", "center", "right", "bottom"], function(region){
-								if(regions[region]){
-									checkAbove(bc.id, child, regions[region]);
-								}
-							});
-							break;
-						case "bottom":
-							dojo.forEach(bc.design == "sidebar" ? ["center", "top"] : ["left", "center", "right", "top"], function(region){
-								if(regions[region]){
-									checkAbove(bc.id, regions[region], child);
-								}
-							});
-							break;
-						case "left":
-							dojo.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "right"] : ["right"], function(region){
-								if(regions[region]){
-									checkLeft(bc.id, child, regions[region]);
-								}
-							});
-							break;
-						case "right":
-							dojo.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "left"] : ["left"], function(region){
-								if(regions[region]){
-									checkLeft(bc.id, regions[region], child);
-								}
-							});
-							break;
-					}
-				});
-			}
-
-			function within(/*Number*/ a, /*Number*/ b, /*Number*/ range){
-				// summary:
-				//		Returns true if a and b are within range
-				return Math.abs(a-b) <= range;
-			}
-
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_BorderContainer.html');
 
-				doh.register("API", [
-					function initialConditions(){
-						checkBCpanes(dijit.byId("border1"));
-						checkBCpanes(dijit.byId("border2"));
-					},
-
-					function resize(){
-						// current size of panes
-						var oTop = dojo.position(dojo.byId("border1-top")),
-							oLeft = dojo.position(dojo.byId("border1-left")),
-							oCenter = dojo.position(dojo.byId("border1-center")),
-							oRight = dojo.position(dojo.byId("border1-right")),
-							oBottom = dojo.position(dojo.byId("border1-bottom"));
-
-						// make whole BorderContainer 100px bigger (width and height)
-						var mb = dojo.marginBox("border1");
-						dijit.byId("border1").resize({w: mb.w + 100, h: mb.h + 100});
-
-						// new size of panes
-						var nTop = dojo.position(dojo.byId("border1-top")),
-							nLeft = dojo.position(dojo.byId("border1-left")),
-							nCenter = dojo.position(dojo.byId("border1-center")),
-							nRight = dojo.position(dojo.byId("border1-right")),
-							nBottom = dojo.position(dojo.byId("border1-bottom"));
-
-						doh.is(oTop.w + 100, nTop.w, "top width + 100");
-						doh.is(oTop.h, nTop.h, "top height unchanged");
-						doh.is(oCenter.w + 100, nCenter.w, "center width + 100");
-						doh.is(oCenter.h + 100, nCenter.h, "center height + 100");
-						doh.is(oBottom.w + 100, nBottom.w, "bottom width + 100");
-						doh.is(oBottom.h, nBottom.h, "bottom height unchanged");
-						doh.is(oLeft.w, nLeft.w, "left width unchanged");
-						doh.is(oLeft.h + 100, nLeft.h, "left height + 100");
-						doh.is(oRight.w, nRight.w, "right width unchanged");
-						doh.is(oRight.h + 100, nRight.h, "right height + 100");
-
-						// size BorderContainer back to original size
-						dijit.byId("border1").resize({w: mb.w, h: mb.h});
-
-						var nnTop = dojo.position(dojo.byId("border1-top")),
-							nnLeft = dojo.position(dojo.byId("border1-left")),
-							nnCenter = dojo.position(dojo.byId("border1-center")),
-							nnRight = dojo.position(dojo.byId("border1-right")),
-							nnBottom = dojo.position(dojo.byId("border1-bottom"));
-
-						doh.is(dojo.toJson(oTop), dojo.toJson(nnTop), "top after second resize");
-						doh.is(dojo.toJson(oCenter), dojo.toJson(nnCenter), "center after second resize");
-						doh.is(dojo.toJson(oBottom), dojo.toJson(nnBottom), "bottom after second resize");
-						doh.is(dojo.toJson(oLeft), dojo.toJson(nnLeft), "left after second resize");
-						doh.is(dojo.toJson(oRight), dojo.toJson(nnRight), "right after second resize");
-					},
-
-					function addRemovePanes(){
-						// current size of panes
-						var oLeft = dojo.position(dojo.byId("border1-left")),
-							oCenter = dojo.position(dojo.byId("border1-center")),
-							oRight = dojo.position(dojo.byId("border1-right")),
-							oBottom = dojo.position(dojo.byId("border1-bottom"));
-
-						// remove top pane... should expand left/center/right
-						dijit.byId("border1").removeChild(dijit.byId("border1-top"));
-
-						// new size of panes
-						var nLeft = dojo.position(dojo.byId("border1-left")),
-							nCenter = dojo.position(dojo.byId("border1-center")),
-							nRight = dojo.position(dojo.byId("border1-right")),
-							nBottom = dojo.position(dojo.byId("border1-bottom"));
-
-						doh.t(nLeft.h > oLeft.h, "left height increased");
-						doh.t(nCenter.h > oCenter.h, "center height increased");
-						doh.t(nRight.h > oRight.h, "left height increased");
-						doh.is(oBottom.h, nBottom.h, "bottom height didn't change");
-
-						// remove left pane... should just expand center pane
-						dijit.byId("border1").removeChild(dijit.byId("border1-left"));
-
-						// new size of panes
-						var nnCenter = dojo.position(dojo.byId("border1-center")),
-							nnRight = dojo.position(dojo.byId("border1-right")),
-							nnBottom = dojo.position(dojo.byId("border1-bottom"));
-
-						doh.t(nnCenter.w > nCenter.w, "center width increased");
-						doh.is(dojo.toJson(nRight), dojo.toJson(nnRight), "right stayed same");
-						doh.is(dojo.toJson(nBottom), dojo.toJson(nnBottom), "bottom stayed same");
-
-						// check that all panes sane
-						checkBCpanes(dijit.byId("border1"));
-
-						// put back left pane as the top pane
-						// Due to #11430 need to clear style info on the pane first
-						dijit.byId("border1-left").set({
-							region: "top",
-							style: {top: "auto", bottom: "auto", left: "auto", right: "auto", width: "auto", height: "auto"}
-						});
-						dijit.byId("border1").addChild(dijit.byId("border1-left"));
-
-						// check that all panes sane
-						checkBCpanes(dijit.byId("border1"));
-					}
-				]);
-
 				doh.register("mouse", [
 					{
 						name: "expand right pane",
@@ -278,6 +89,15 @@
 				]);
 
 				doh.register("keyboard", [
+					function setup(){
+						// Workaround FF4 bug where overflow:auto panes get focus even when
+						// they don't have a scrollbar, remove when
+						// https://bugzilla.mozilla.org/show_bug.cgi?id=616594 fixed
+						if(dojo.isFF == 4){
+							dojo.query(".dijitContentPane").style("overflow", "hidden");
+						}
+					},
+
 					{
 						name: "tabIndex",
 						timeout: 10000,
@@ -350,7 +170,7 @@
 						}
 					}
 				]);
-
+				
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/layout/robot/BorderContainer_complex.html b/dijit/tests/layout/robot/BorderContainer_complex.html
new file mode 100644
index 0000000..6e99b31
--- /dev/null
+++ b/dijit/tests/layout/robot/BorderContainer_complex.html
@@ -0,0 +1,295 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot BorderContainer complex 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" src="./borderContainerTestFunctions.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_BorderContainer_complex.html');
+
+				doh.register("API", [
+					function initialConditions(){
+						checkBCpanes(dijit.byId("border1"));
+					}
+				]);
+
+				//test some basic functionality of the complex widgets to get a feel for whether they work inside the border container
+				doh.register("tabContainer", [
+					{
+						name: "tab2Selected",
+						runTest: function(t){
+							doh.t(dijit.byId("tab2").selected, "tab2 was not selected");
+							doh.f(dijit.byId("tab1").selected, "tab1 was selected");
+							doh.f(dijit.byId("tab3").selected, "tab3 was selected");
+							doh.f(dijit.byId("tab4").selected, "tab4 was selected");
+							doh.f(dijit.byId("tab5").selected, "tab5 was selected");
+							doh.f(dijit.byId("tab6").selected, "tab6 was selected");
+						}
+					},
+					{
+						name: "tabsCanBeShownWhenSelected_tab1",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("mainTabContainer_tablist_tab1", 500, 1);
+							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("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");
+							}), 1000);
+							
+							return d;
+						}
+					},
+					{
+						name: "tabsCanBeShownWhenSelected_tab2",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();		
+							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("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");
+							}), 1000);
+							
+							return d;
+						}
+					},
+					{
+						name: "tabsCanBeShownWhenSelected_tab3",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();		
+							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("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");
+							}), 1000);
+							
+							return d;
+						}
+					},
+					{
+						name: "tabsCanBeShownWhenSelected_tab4",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();		
+							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("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");
+							}), 1000);
+							
+							return d;
+						}
+					},
+					{
+						name: "tabsCanBeShownWhenSelected_tab5",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();		
+							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("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");
+							}), 1000);
+							
+							return d;
+						}
+					},
+					{
+						name: "tabsCanBeShownWhenSelected_tab6",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();		
+							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("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");
+							}), 1000);
+							
+							return d;
+						}
+					}					
+				]);
+				
+				doh.register("AccordionContainer", [
+					{
+						name: "pane1Selected",
+						runTest: function(t){
+							doh.t(dijit.byId("ap1").selected, "ap1 selected");
+							doh.f(dijit.byId("ap2").selected, "ap2 not selected");
+							doh.f(dijit.byId("ap3").selected, "ap3 not selected");
+							doh.t(isVisible(dijit.byId("ap1")), "ap1 is visible");
+							doh.t(isHidden(dijit.byId("ap2")), "ap2 is hidden");
+							doh.t(isHidden(dijit.byId("ap3")), "ap3 is hidden");
+						}
+					},
+					{
+						name: "focus ap1 title bar",
+						runTest: function(t){
+							dijit.byId("ap1_button").focusNode.focus();
+						}
+					},
+					{
+						name: "select ap2",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							// Connect to _hideChild() as a trick to tell when animation is finished
+							handle = dojo.connect(dijit.byId("ac1"), "_hideChild", function(){
+								setTimeout(d.getTestCallback(function(){
+									doh.is("ap2_button", dojo.global.dijit._curFocus.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");
+								}), 0);
+							});
+							
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+
+							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handle);
+						}
+					},
+					{
+						name: "select ap3",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							// Connect to _hideChild() as a trick to tell when animation is finished
+							handle = dojo.connect(dijit.byId("ac1"), "_hideChild", function(){
+								setTimeout(d.getTestCallback(function(){
+									doh.is("ap3_button", dojo.global.dijit._curFocus.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");
+								}), 0);
+							});
+							
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000, {});
+
+							return d;
+						},
+						tearDown: function(){
+							dojo.disconnect(handle);
+						}
+					},
+					{
+						name: "resize accordion",
+						timeout: 6000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var accordion = dojo.position(dojo.byId("ac1"));
+							var centerPane = dojo.position(dojo.byId("mainCP"));
+
+							// Drag slider to shrink pane 
+							var size = dojo.position("ac1_splitter");
+							doh.robot.mouseMoveAt("ac1_splitter", 500, 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
+								var newCenterPane = dojo.position(dojo.byId("mainCP"));
+								doh.is(newCenterPane.w, centerPane.w-30);
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+				
+				doh.register("filteringSelect", [
+					{
+						name: "changeValue",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							dijit.byId("filteringSelect").connect(dijit.byId("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, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							
+							return d;
+						}
+					}
+				]); 
+				
+				doh.register("editor", [
+					{
+						name: "changeValue",
+						timeout: 3000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+														
+							doh.robot.sequence(function(){
+								var editor = dijit.byId("editor1");
+								editor.setValue("<div id='myDiv'>This is my new text</div>");
+							}, 1000); 
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var myDiv = dijit.byId("editor1").editNode.childNodes[0];
+								doh.is("myDiv", myDiv.id, "myDiv was not the first child node as expectd");
+								doh.t(isVisible(myDiv), "myDiv is visible");
+							}), 1000);
+							
+							return d;
+						}
+					}
+				]);
+				
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/layout/robot/BorderContainer_full.html b/dijit/tests/layout/robot/BorderContainer_full.html
new file mode 100644
index 0000000..3dff857
--- /dev/null
+++ b/dijit/tests/layout/robot/BorderContainer_full.html
@@ -0,0 +1,110 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot BorderContainer full 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" src="./borderContainerTestFunctions.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_BorderContainer_full.html');
+
+				doh.register("API", [
+					function initialConditions(){
+						var bc = dijit.byId("main");
+						checkBCpanes(bc);
+						doh.t(bc.getChildren().length==5);
+					},
+					
+					function testFullScreen() {
+						var borderContainerPos = dojo.position(dojo.byId("main"));
+						var view = dojo.window.getBox();
+						doh.t( borderContainerPos.h-view.h < 3);
+						doh.t( borderContainerPos.w-view.w < 3);
+					}
+				]);
+
+				doh.register("mouse", [
+					{
+						name: "expand right pane",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var oTop = dojo.position(dojo.byId("main-top")),
+								oCenter = dojo.position(dojo.byId("main-center")),
+								oRight = dojo.position(dojo.byId("main-trailing")),
+								oBottom = dojo.position(dojo.byId("main-bottom"));
+
+							// Drag slider to expand pane 
+							var size = dojo.position("main-trailing_splitter");
+							doh.robot.mouseMoveAt("main-trailing_splitter", 500);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("main-trailing_splitter", 500, 100,
+								size.w/2 + (dojo._isBodyLtr() ? -100 : 100), size.h/2);
+							doh.robot.mouseRelease({left: true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								var nTop = dojo.position(dojo.byId("main-top")),
+									nCenter = dojo.position(dojo.byId("main-center")),
+									nRight = dojo.position(dojo.byId("main-trailing")),
+									nBottom = dojo.position(dojo.byId("main-bottom"));
+					
+								doh.t(within(oRight.w + 100, nRight.w, 10), "right width went from " + oRight.w + " to " + nRight.w);
+								doh.t(within(oTop.w - 100, nTop.w, 10), "top width went from " + oTop.w + " to " + nTop.w);
+								doh.t(within(oCenter.w - 100, nCenter.w, 10), "center width went from " + oCenter.w + " to " + nCenter.w);
+								doh.t(within(oBottom.w - 100, nBottom.w, 10), "bottom width went from " + nBottom.w + " to " + nBottom.w);
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "shrink bottom pane",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							var oTop = dojo.position(dojo.byId("main-top")),
+								oCenter = dojo.position(dojo.byId("main-center")),
+								oRight = dojo.position(dojo.byId("main-trailing")),
+								oBottom = dojo.position(dojo.byId("main-bottom"));
+
+							// Drag slider to shrink pane 
+							var size = dojo.position("main-bottom_splitter");
+							doh.robot.mouseMoveAt("main-bottom_splitter", 500);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("main-bottom_splitter", 500, 100, size.w/2, size.h/2 + 10);
+							doh.robot.mouseRelease({left: true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								var nTop = dojo.position(dojo.byId("main-top")),
+									nCenter = dojo.position(dojo.byId("main-center")),
+									nRight = dojo.position(dojo.byId("main-trailing")),
+									nBottom = dojo.position(dojo.byId("main-bottom"));
+					
+								doh.t(within(oBottom.h - 10, nBottom.h, 10), "bottom height went from " + oBottom.h + " to " + nBottom.h);
+								doh.t(within(oCenter.h + 10, nCenter.h, 10), "center height went from " + oCenter.h + " to " + nCenter.h);
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/layout/robot/BorderContainer_nested.html b/dijit/tests/layout/robot/BorderContainer_nested.html
new file mode 100644
index 0000000..5d47af6
--- /dev/null
+++ b/dijit/tests/layout/robot/BorderContainer_nested.html
@@ -0,0 +1,148 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot BorderContainer nested 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" src="./borderContainerTestFunctions.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			function checkLayoutPriorityBC(){
+				checkAbove("top bar above second top bar", "top1", "top2");
+				checkAbove("second top bar above inner top bar", "top2", "top3");
+				checkLeft("outer left vs. inner left", "left1", "left2");
+				checkLeft("inner left vs. inner top", "left2", "top3");
+				checkLeft("inner left vs. inner bottom", "left2", "bottom3");
+				checkAbove("inner top vs. center", "top3", "center");
+				checkAbove("center vs. inner bottom", "center", "bottom3");
+				checkLeft("inner right vs. inner top", "top3", "right2");
+				checkLeft("inner right vs. center", "center", "right2");
+				checkAbove("inner bottom bar above second bottom bar", "bottom3", "bottom2");
+				checkAbove("second bottom bar above bottom bar", "bottom2", "bottom1");
+			}
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_BorderContainer_nested.html');
+
+				doh.register("initial layout", [
+					function nestedBC(){
+						checkBCpanes(dijit.byId("nbc"));
+						doh.t(isVisible(dijit.byId("nbc")));
+						checkInside("nbc", "tc");
+					},
+					function layoutPriorityBC(){
+						dijit.byId("tc").selectChild(dijit.byId("pbc"));	
+						doh.t(isVisible(dijit.byId("pbc")), "second pane visible");
+
+						// Check layout of BorderContainer panes relative to each other
+						checkLayoutPriorityBC();
+
+						// Check that all panes within BC borders
+						var children = dijit.byId("pbc").getChildren();
+						doh.is(11, children.length, "# of children");
+						dojo.forEach(children, function(child){
+							checkInside(child, dijit.byId("pbc"));
+						});
+					}							
+				]);
+
+				// Verify that tab stops are as per original markup (i.e., children are still in the
+				// logical order specified in the original markup)
+				doh.register("tabIndex", function tabstops(){
+					var tabstops = tabOrder(dijit.byId("pbc").domNode);
+					doh.is(21, tabstops.length);
+					doh.is("tabstop #1", tabstops[0].value);
+					doh.is("tabstop #3", tabstops[2].value);
+					doh.is("tabstop #5", tabstops[4].value);
+					doh.is("tabstop #7", tabstops[6].value);
+					doh.is("tabstop #9", tabstops[8].value);
+					doh.is("tabstop #11", tabstops[10].value);
+					doh.is("tabstop #12", tabstops[11].value);
+					doh.is("tabstop #14", tabstops[13].value);
+					doh.is("tabstop #16", tabstops[15].value);
+					doh.is("tabstop #18", tabstops[17].value);
+					doh.is("tabstop #20", tabstops[19].value);
+				});
+
+				doh.register("keyboard", [
+					{
+						name: "top1",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var top1Size, centerSize;
+
+							doh.robot.sequence(function(){
+								dojo.byId("top1_splitter").focus();
+								
+								top1Size = dojo.position("top1");
+								centerSize = dojo.position("center");
+							}, 500, 500);
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(within(top1Size.h + 3, dojo.position("top1").h, 0.5), "top size increased");
+								doh.t(within(centerSize.h - 3, dojo.position("center").h, 0.5), "center size decreased");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "right1",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var right1Size, centerSize, top2Size, bottom1Size;
+
+							doh.robot.sequence(function(){
+								dojo.byId("right1_splitter").focus();
+								
+								right1Size = dojo.position("right1");
+								centerSize = dojo.position("center");
+								top2Size = dojo.position("top2");
+								bottom1Size = dojo.position("bottom1");
+							}, 500, 500);
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(within(right1Size.w + 3, dojo.position("right1").w, 0.5), "right size increased");
+								doh.t(within(centerSize.w - 3, dojo.position("center").w, 0.5), "center size decreased");
+								doh.t(within(centerSize.w - 3, dojo.position("top3").w, 0.5), "inner top size decreased");
+								doh.t(within(centerSize.w - 3, dojo.position("bottom3").w, 0.5), "inner bottom size decreased");
+								doh.t(within(top2Size.h, dojo.position("top2").h, 0.5), "top2 height unchanged");
+								doh.t(within(top2Size.w, dojo.position("top2").w, 0.5), "top2 width unchanged");
+								doh.t(within(bottom1Size.h, dojo.position("bottom1").h, 0.5), "bottom1 height unchanged");
+								doh.t(within(bottom1Size.w, dojo.position("bottom1").w, 0.5), "bottom1 width unchanged");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/layout/robot/GUI.html b/dijit/tests/layout/robot/GUI.html
new file mode 100644
index 0000000..40acb12
--- /dev/null
+++ b/dijit/tests/layout/robot/GUI.html
@@ -0,0 +1,303 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot GUI 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" src="./borderContainerTestFunctions.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_Gui.html');
+
+				doh.register("API", [
+					function initialConditions(){
+						checkBCpanes(dijit.byId("main")); // This test will fail in opera because it thinks that the center content is taller than the border container.  However, it displays fine.
+						checkBCpanes(dijit.byId("mainSplit"));
+						checkBCpanes(dijit.byId("embeddedBC"));
+						checkBCpanes(dijit.byId("bottomSplit"));
+						checkInside(dijit.byId("topTabs1"), dijit.byId("centerSplit"));
+						doh.t(isVisible(dijit.byId("basdicFormTab").domNode));
+					}
+				]);
+				
+				doh.register("test_left_accordion", [
+					{
+						name: "open ac pane 2",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+														
+							doh.robot.mouseMoveAt("ac_pane2_button", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(dijit.byId("leftAccordion").domNode), "Accordion container is not visible");
+								doh.t(isVisible(dijit.byId("ac_pane2").domNode), "accordion container pane2 is not visible");
+								doh.t(isHidden(dijit.byId("ac_pane3").domNode), "accordion container pane3 is not hidden");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("test_Top_Tab_Container", [
+					{
+						name: "open top tab 2",
+						timeout: 9000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							//Drag splitter to the left to make more room for the tab container
+							doh.robot.mouseMoveAt("leftAccordion_splitter", 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("leftAccordion_splitter", 500, 100, -100, 100);
+							doh.robot.mouseRelease({left: true}, 500);
+							
+							doh.robot.mouseMoveAt("topTabs1_tablist_tabAccordion", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("dijit_layout_ContentPane_2_button", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_2")), "Accordion tab 2 is not visible");
+								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_4").domNode), "Accordion tab 4 is not hidden");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "open top tab 3",
+						timeout: 9000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("topTabs1_tablist_textareaTab", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("dijit_layout_ContentPane_6_button", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(dijit.byId("tabAccordionContainer").domNode), "Accordion container is not visible");
+								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_6")), "Accordion tab 4 is not visible");
+								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_7").domNode), "Accordion tab 3 is not hidden");
+								doh.t(isVisible(dijit.byId("bbtab1").domNode), "Nested tab1 is not visible");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "open top tab 3 and close nested tab",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dijit.byId("accTabs_tablist_bbtab3").closeNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+														
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, dijit.byId("accTabs_tablist_bbtab3"));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "open top tab 4",
+						timeout: 5000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("topTabs1_tablist_titlePaneCP", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var children = dijit.byId("titlePaneCP").domNode.childNodes;
+								doh.t(children.length == 3);
+								doh.t(isVisible(children[1]), "The title pane child node is not visible");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "open top tab 4 and close title pane",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dijit.byId("tp").focusNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								var titlePane = dijit.byId("tp");
+								doh.f(titlePane.open);
+								doh.t(isHidden(dojo.byId("tp_pane")), "Title pane is not hidden");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "open top tab 5",
+						timeout: 5000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("topTabs1_tablist_tabContainerInTabCP", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("tabContainerInTabCP_tablist_basicFormTab2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(dijit.byId("basicFormTab2").domNode), "The embedded tab content is not visible");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "close top tab 5",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dijit.byId("topTabs1_tablist_tabContainerInTabCP").closeNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, dijit.byId("topTabs1_tablist_tabContainerInTabCP"));
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+				
+				doh.register("test_Center_tab_containers", [
+					{
+						name: "open tab 2",
+						timeout: 7000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+														
+							//Drag splitter up to make more room for the tab container
+							doh.robot.mouseMoveAt("topTabs1_splitter", 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("topTabs1_splitter", 500, 100, 100, -200);
+							doh.robot.mouseRelease({left: true}, 500);
+							
+							doh.robot.mouseMoveAt("bottomTabs1_tablist_btabB", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								checkInside(dijit.byId("bottomTabs1"), dijit.byId("embeddedBC"));
+								checkInside(dijit.byId("bottomTabs2"), dijit.byId("embeddedBC"));
+								doh.t(isVisible(dijit.byId("btabB").domNode), "Tab 2 is not visible");
+								doh.t(isHidden(dijit.byId("btabA").domNode), "Tab 1 is not hidden");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "close tab 3",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+														
+							doh.robot.mouseMoveAt(dijit.byId("bottomTabs1_tablist_btabC").closeNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, dijit.byId("bottomTabs1_tablist_btabC"));
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+				
+				doh.register("test_Bottom_tab_containers", [
+					{
+						name: "test1",
+						timeout: 5000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+														
+							//Drag splitter up to make more room for the tab container
+							doh.robot.mouseMoveAt("bottomTabs_splitter", 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("bottomTabs_splitter", 500, 100, 100, -200);
+							doh.robot.mouseRelease({left: true}, 500);
+														
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_9").domNode));
+								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_9_splitter").domNode));
+								doh.t(isVisible(dijit.byId("btabAA").domNode));
+								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_10").domNode));
+								doh.t(isVisible(dijit.byId("dijit_layout_ContentPane_10_splitter").domNode));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "test2",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("bottomTabs_tablist_btab2", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(dijit.byId("btab2").domNode));
+								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_9").domNode));
+								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_9_splitter").domNode));
+								doh.t(isHidden(dijit.byId("btabAA").domNode));
+								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_10").domNode));
+								doh.t(isHidden(dijit.byId("dijit_layout_ContentPane_10_splitter").domNode));
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "test3",
+						timeout: 4000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt(dijit.byId("bottomTabs_tablist_btab3").closeNode, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, dijit.byId("bottomTabs_tablist_btab3"));
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/layout/robot/StackContainer_mouse.html b/dijit/tests/layout/robot/StackContainer_mouse.html
new file mode 100644
index 0000000..29b1a91
--- /dev/null
+++ b/dijit/tests/layout/robot/StackContainer_mouse.html
@@ -0,0 +1,372 @@
+<!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 bd34434..e1365ca 100644
--- a/dijit/tests/layout/robot/TabContainer_a11y.html
+++ b/dijit/tests/layout/robot/TabContainer_a11y.html
@@ -22,123 +22,248 @@
 				doh.robot.initRobot('../test_TabContainer.html');
 				doh.register("basic navigation",[
 					{
-						name: "focus on first tab",
+						name: "focus on button before TabContainer",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								doh.robot.sequence(function(){
-									dojo.query("button")[0].focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.TAB, 500, {});
-								
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is("mainTabContainer_tablist_tab2", dojo.global.dijit._curFocus.id, "tabbing to focuses on selected Tab");
-								}), 500);
+							var d = new doh.Deferred();
 
-								return d;
+							onFocus(d.getTestCallback(function(node){
+							}));
+
+							dojo.query("button")[0].focus();							
+
+							return d;
 						}
 					},
 					{
-						name: "move to tab with RIGHT button",
+						name: "tab into main TabContainer",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.sequence(function(){
-									dojo.byId("mainTabContainer_tablist_tab2").focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								
-								doh.robot.sequence(d.getTestCallback(function(){
-									var tc = dijit.byId("mainTabContainer");
-									doh.is('mainTabContainer_tablist_tab3', dojo.global.dijit._curFocus.id, "currently chosen tab");
-									doh.is("tab3", tc.selectedChildWidget.id, "currently displayed pane");
-								}), 750);
-								return d;
+							var d = new doh.Deferred();
+							
+							onFocus(d.getTestCallback(function(node){
+								doh.is("mainTabContainer_tablist_tab2", node.id, "focus");
+							}));
+
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+
+							return d;
 						}
 					},
 					{
-						name: "move to with LEFT button",
+						name: "move to tab 3 with RIGHT arrow",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							var d = new doh.Deferred();
+
+							onFocus(d.getTestCallback(function(node){
 								var tc = dijit.byId("mainTabContainer");
-								
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('mainTabContainer_tablist_tab2', dojo.global.dijit._curFocus.id, "currently chosen tab");
-									doh.is("tab2", tc.selectedChildWidget.id, "currently chosen pane");
-								}), 750);
-								
-								return d;
+								doh.is('mainTabContainer_tablist_tab3', node.id, "currently chosen tab");
+								doh.is("tab3", tc.selectedChildWidget.id, "currently displayed pane");
+							}));
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							
+							return d;
 						}
 					},
+					{
+						name: "move to tab 2 with LEFT arrow",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							var tc = dijit.byId("mainTabContainer");							
+							onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab2', node.id, "currently chosen tab");
+								doh.is("tab2", tc.selectedChildWidget.id, "currently chosen pane");
+							}));
+							
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+
+							return d;
+						}
+					},
+
+					{
+						name: "move to tab 3 again with RIGHT arrow",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							onFocus(d.getTestCallback(function(node){
+							}));
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							
+							return d;
+						}
+					},
+					{
+						name: "move to inlined subcontainer tab with RIGHT arrow",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
 
+							onFocus(d.getTestCallback(function(node){
+							}));
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							
+							return d;
+						}
+					},
 					
 					{
 						name: "TAB focus to nested tab",
 						timeout: 10000,
 						runTest: function(t){
 								var d = new doh.Deferred();
+
+								onFocus(d.getTestCallback(function(node){
+									doh.is('inlined_tablist_tab2href', node.id);
+								}));								
 								
-								doh.robot.sequence(function(){
-									dojo.byId("mainTabContainer_tablist_tab2").focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-								doh.robot.keyPress(dojo.keys.TAB, 750, {});
-								
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('inlined_tablist_tab2href', dojo.global.dijit._curFocus.id);
-								}), 500);
-								
+								doh.robot.keyPress(dojo.keys.TAB, 750);
+
 								return d;
 						}
 					},
+
 					{
-						name: "move through parent tabs from nested tabs",
+						name: "move to second nested tab button",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.sequence(function(){
-									dojo.byId("inlined_tablist_tab2href").focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								doh.robot.keyPress(dojo.keys.TAB, 750, {shift:true});
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								
-								//verify that we can navigate to the top menu from a nested tab container
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('mainTabContainer_tablist_tab3href', dojo.global.dijit._curFocus.id);
-								}), 750);
-								return d;
+							var d = new doh.Deferred();
+
+							onFocus(d.getTestCallback(function(node){
+							}));
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							
+							return d;
 						}
 					},
 					{
-						name: "verify nested tabs keep their state",
+						name: "shift-TAB to parent tabs from nested tabs",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.sequence(function(){
-									dojo.byId("mainTabContainer_tablist_tab3href").focus();
-								}, 500, 500);
+							var d = new doh.Deferred();
+							
+							onFocus(d.getTestCallback(function(node){
+							}));
+
+							doh.robot.keyPress(dojo.keys.TAB, 750, {shift:true});
+							
+							return d;
+						}
+					},
+					{
+						name: "left arrow to tab 3",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab3', node.id);
+							}));
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+							
+							return d;
+						}
+					},
+					{
+						name: "right arrow to inline subtabcontainer",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							onFocus(d.getTestCallback(function(node){
+							}));
+
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							
+							return d;
+						}
+					},
+					{
+						name: "verify nested tablist keeps it's state",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							//verify that the third nested tab is still selected
+							onFocus(d.getTestCallback(function(node){
+								doh.is('inlined_tablist_subtab3', node.id);
+							}));
+
+							doh.robot.keyPress(dojo.keys.TAB, 750, {});	// give IE8 time to complete slide animation
+							
+							return d;
+						}
+					}
+				]);
+
+				doh.register("HOME/END keys", [
+					{
+						name: "focus tab 3",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							dijit.byId("mainTabContainer").selectChild(dijit.byId("tab3"), false);
+
+							setTimeout(d.getTestCallback(function(){
+								dojo.byId("mainTabContainer_tablist_tab3href").focus();
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "home key",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
 								
-								doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-								doh.robot.keyPress(dojo.keys.TAB, 750, {});	// give IE8 time to complete slide animation
+							onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab1', node.id);
+							}));
+
+							doh.robot.keyPress(dojo.keys.HOME, 500, {});
+
+							return d;
+						}
+					},
+					{
+						name: "end key",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
 								
-								//verify that the second tab in Tab 1 is still focused
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('inlined_tablist_subtab3', dojo.global.dijit._curFocus.id);
-								}), 500);
+							onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_embedded', node.id);
+							}));
+
+							doh.robot.keyPress(dojo.keys.END, 500, {});
+
+							return d;
+						}
+					},
+					{
+						name: "verify left/right arrows still work",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
 								
-								return d;
+							onFocus(d.getTestCallback(function(node){
+								doh.is('mainTabContainer_tablist_tab4href', node.id);
+							}));
+
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
+
+							return d;
 						}
 					}
 				]);
@@ -148,47 +273,47 @@
 						name: "close tab with DELETE button",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.sequence(function(){
-									dojo.byId("mainTabContainer_tablist_inlined").focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								doh.robot.keyPress(dojo.keys.DELETE, 750, {});
+							var d = new doh.Deferred();
+							
+							doh.robot.sequence(function(){
+								dojo.byId("mainTabContainer_tablist_inlined").focus();
+							}, 500, 500);
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.DELETE, 750, {});
 
-								var tc = dijit.byId("mainTabContainer");
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is(6, tc.getChildren().length);
-								}), 500);
-								
-								return d;
+							var tc = dijit.byId("mainTabContainer");
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(6, tc.getChildren().length);
+							}), 500);
+							
+							return d;
 						}
 					},
 					{
 						name: "close tab with CTRL-W button",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.sequence(function(){
-									dojo.byId("mainTabContainer_tablist_tab1").focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-								if(dojo.isChrome){
-									// on chrome ctrl+w isn't trapped, and closes the whole browser!
-									doh.robot.keyPress(dojo.keys.DELETE, 750, {});
-								}else{
-									doh.robot.keyPress("w", 750, {ctrl:true});
-								}
-								
-								var tc = dijit.byId("mainTabContainer");
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is(5, tc.getChildren().length);
-								}), 500);
-								return d;
+							var d = new doh.Deferred();
+							
+							doh.robot.sequence(function(){
+								dojo.byId("mainTabContainer_tablist_tab1").focus();
+							}, 500, 500);
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
+							if(dojo.isChrome){
+								// on chrome ctrl+w isn't trapped, and closes the whole browser!
+								doh.robot.keyPress(dojo.keys.DELETE, 750, {});
+							}else{
+								doh.robot.keyPress("w", 750, {ctrl:true});
+							}
+							
+							var tc = dijit.byId("mainTabContainer");
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(5, tc.getChildren().length);
+							}), 500);
+							return d;
 						}
 					}
 				]);
@@ -202,31 +327,31 @@
 						name: "close tab through context menu",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-								doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
-								
-								// open via keyboard
-								if(dojo.isMac){
-									doh.robot.keyPress(dojo.keys.SPACE, 500, {
-										ctrl: true
-									});
-								}else{
-									doh.robot.keyPress(dojo.keys.F10, 500, {
-										shift: true
-									});
-								}
-								
-								doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-								
-								var tc = dijit.byId("mainTabContainer");
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is(4, tc.getChildren().length);
-								}), 500);
-								
-								return d;
+							var d = new doh.Deferred();
+							
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 750, {});
+							
+							// open via keyboard
+							if(dojo.isMac){
+								doh.robot.keyPress(dojo.keys.SPACE, 500, {
+									ctrl: true
+								});
+							}else{
+								doh.robot.keyPress(dojo.keys.F10, 500, {
+									shift: true
+								});
+							}
+							
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
+							
+							var tc = dijit.byId("mainTabContainer");
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(4, tc.getChildren().length);
+							}), 500);
+							
+							return d;
 						}
 					});
 				}
@@ -236,37 +361,36 @@
 						name: "move to tab with DOWN button",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.sequence(function(){
-									dojo.byId("ltabs_tablist_HanselGretel1").focus();
-								}, 500, 500);
-								
-								doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-								var tc = dijit.byId("ltabs");
-								
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('ltabs_tablist_GreenTwigs1', dojo.global.dijit._curFocus.id, "currently chosen tab");
-									doh.is("GreenTwigs1", tc.selectedChildWidget.id, "currently displayed pane");
-								}), 500);
-								return d;
+							var d = new doh.Deferred();
+							
+							dojo.byId("ltabs_tablist_HanselGretel1").focus();
+
+							var tc = dijit.byId("ltabs");
+							onFocus(d.getTestCallback(function(node){
+								doh.is('ltabs_tablist_GreenTwigs1', node.id, "currently chosen tab");
+								doh.is("GreenTwigs1", tc.selectedChildWidget.id, "currently displayed pane");
+							}));
+
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
+
+							return d;
 						}
 					},
 					{
 						name: "move to tab with UP button",
 						timeout: 10000,
 						runTest: function(t){
-								var d = new doh.Deferred();
-								
-								doh.robot.keyPress(dojo.keys.UP_ARROW, 500, {});
-								var tc = dijit.byId("ltabs");
-								
-								doh.robot.sequence(d.getTestCallback(function(){
-									doh.is('ltabs_tablist_HanselGretel1', dojo.global.dijit._curFocus.id, "currently chosen tab");
-									doh.is("HanselGretel1", tc.selectedChildWidget.id, "currently chosen pane");
-								}), 500);
-								
-								return d;
+							var d = new doh.Deferred();
+							
+							var tc = dijit.byId("ltabs");							
+							onFocus(d.getTestCallback(function(node){
+								doh.is('ltabs_tablist_HanselGretel1', node.id, "currently chosen tab");
+								doh.is("HanselGretel1", tc.selectedChildWidget.id, "currently chosen pane");
+							}));
+
+							doh.robot.keyPress(dojo.keys.UP_ARROW, 500, {});
+							
+							return d;
 						}
 					}
 				]);
diff --git a/dijit/tests/layout/robot/TabContainer_mouse.html b/dijit/tests/layout/robot/TabContainer_mouse.html
index 4f6d636..daa04e9 100644
--- a/dijit/tests/layout/robot/TabContainer_mouse.html
+++ b/dijit/tests/layout/robot/TabContainer_mouse.html
@@ -67,6 +67,42 @@
 						}
 					},
 					{
+						name: "scrolling",
+						timeout: 10000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+
+							// save original position of one of the tab labels
+							var pos0 = dojo.position("mainTabContainer_tablist_tab2").x,
+								pos1,
+								pos2;
+
+							// Initially scrolled all the way to the left, so left scroll button
+							// should be disabled
+							doh.t(dijit.byId("mainTabContainer_tablist_leftBtn").get("disabled"), "left scroll button disabled");
+							doh.f(dijit.byId("mainTabContainer_tablist_rightBtn").get("disabled"), "right scroll button enabled");
+
+							// Scroll to the right
+							doh.robot.mouseMoveAt('mainTabContainer_tablist_rightBtn', 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.sequence(d.getTestErrback(function(){
+								pos1 = dojo.position("mainTabContainer_tablist_tab2").x;
+								doh.t(pos1 < pos0, "scrolled to the right: " + pos1 + " < " + pos0);
+								doh.f(dijit.byId("mainTabContainer_tablist_leftBtn").get("disabled"), "left scroll button enabled");
+							}), 500);
+							
+							// And then scroll back to the left
+							doh.robot.mouseMoveAt('mainTabContainer_tablist_leftBtn', 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								pos2 = dojo.position("mainTabContainer_tablist_tab2").x;
+								doh.t(pos2 > pos1, "scrolled to the left: " + pos2 + " > " + pos1);
+							}), 500);
+							
+							return d;
+						}
+					},
+					{
 						name: "close button hover state",
 						timeout: 10000,
 						runTest: function(t){
diff --git a/dijit/tests/layout/robot/TabContainer_noLayout.html b/dijit/tests/layout/robot/TabContainer_noLayout.html
new file mode 100644
index 0000000..0c5c81f
--- /dev/null
+++ b/dijit/tests/layout/robot/TabContainer_noLayout.html
@@ -0,0 +1,435 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot TabContainer No Layout 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");
+			
+			function checkInside(childDomNode, parentDomNode){
+				var cp = dojo.position(childDomNode, true),
+					pp = dojo.position(parentDomNode, true);
+
+				doh.t(
+					cp.y > pp.y && cp.y+cp.h < pp.y+pp.h &&
+					cp.x > pp.x && cp.x+cp.w < pp.x+pp.w,
+					childDomNode.id + "child not inside " + parentDomNode.id + dojo.toJson(cp) + dojo.toJson(pp)
+				);
+			}
+
+			var oldPos;
+			
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_TabContainer_noLayout.html');
+				doh.register("plain TabContainer",[
+					{
+						name: "tab1",
+						timeout: 3000,
+						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];
+								
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab2",
+						timeout: 3000,
+						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];
+								
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab3",
+						timeout: 3000,
+						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);
+								
+								var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+								doh.f(oldPos.y == newPos.y);
+								oldPos = newPos;
+							}), 500);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab4_innerTab1",
+						timeout: 4000,
+						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];
+								
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab4_innerTab2",
+						timeout: 3000,
+						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];
+
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab5_innerTab1",
+						timeout: 7000,
+						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);
+							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;
+						}
+					},
+					{
+						name: "tab5_innerTab2",
+						timeout: 3000,
+						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);
+								
+								var newPos = dojo.position(dojo.byId("textAfterTabContainer1"), true);
+								doh.f(oldPos.y == newPos.y);
+								oldPos = newPos;
+							}), 500);
+							
+							return d;
+						}
+					},
+					{
+						name: "addTab",
+						timeout: 6000,
+						runTest: function(t){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt('addTab', 500);
+							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;
+						}
+					},
+					{
+						timeout: 3000,
+						name: "destroy",
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt('destroyTabContainer', 500);
+							doh.robot.mouseClick({left: true}, 500);
+								
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, dojo.byId("plainTabContainer"), 'widget was not removed');
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+				
+				doh.register("TabContainer in table",[
+					function width(){
+						// Make sure the scrolling tabs don't make the width of the table explode to 50,0000px
+						doh.is(400, dojo.position(dojo.byId("tableTabContainer")).w);
+					},
+					{
+						name: "tab1_t2",
+						timeout: 3000,
+						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];
+								
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab2_t2",
+						timeout: 3000,
+						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];
+								
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab3_t2",
+						timeout: 3000,
+						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);
+								
+								var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+								doh.f(oldPos.y == newPos.y);
+								oldPos = newPos;
+							}), 500);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab4_innerTab1_t2",
+						timeout: 5000,
+						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];
+								
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab4_innerTab2_t2",
+						timeout: 3000,
+						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];
+
+								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);
+							
+							return d;
+						}
+					},
+					{
+						name: "tab5_innerTab1_t2",
+						timeout: 6000,
+						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);
+							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;
+						}
+					},
+					{
+						name: "tab5_innerTab2_t2",
+						timeout: 3000,
+						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);
+								
+								var newPos = dojo.position(dojo.byId("textAfterTabContainer2"), true);
+								doh.f(oldPos.y == newPos.y);
+							}), 500);
+							
+							return d;
+						}
+					}
+				]);
+				
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/layout/robot/borderContainerTestFunctions.js b/dijit/tests/layout/robot/borderContainerTestFunctions.js
new file mode 100644
index 0000000..3e4a6d7
--- /dev/null
+++ b/dijit/tests/layout/robot/borderContainerTestFunctions.js
@@ -0,0 +1,99 @@
+			function checkInside(/*Widget*/ child, /*Widget*/ parent, /*String?*/ comment){
+				// summary:
+				//		Test that child is fully inside of parent
+
+				child = dijit.byId(child);
+				parent = dijit.byId(parent);
+
+				var cp = dojo.position(child.domNode, true),
+					pp = dojo.position(parent.domNode, true);
+
+				doh.t(
+					cp.y >= pp.y && cp.y+cp.h <= pp.y+pp.h &&
+					cp.x >= pp.x && cp.x+cp.w <= pp.x+pp.w,
+					(comment ? comment + ": " : "") + child.region + " inside " + parent.id + dojo.toJson(cp) + dojo.toJson(pp)
+				);
+			}
+			function checkAbove(/*String*/ comment, /*Widget*/ above, /*Widget*/ below){
+				// summary:
+				//		Test that child is fully above parent
+
+				above = dijit.byId(above);
+				below = dijit.byId(below);
+
+				var ap = dojo.position(above.domNode, true),
+					bp = dojo.position(below.domNode, true);
+
+				doh.t(ap.y+ap.h < bp.y,
+					comment + " " + above.region + " above " + below.region + dojo.toJson(ap) + dojo.toJson(bp)
+				);
+			}
+			function checkLeft(/*String*/ comment, /*Widget*/ left, /*Widget*/ right){
+				// summary:
+				//		Test that child is fully left of parent
+
+				left = dijit.byId(left);
+				right = dijit.byId(right);
+
+				var lp = dojo.position(left.domNode, true),
+					rp = dojo.position(right.domNode, true);
+
+				doh.t(lp.x+lp.w < rp.x,
+					comment + " " + left.region + " to left of " + right.region + dojo.toJson(lp) + dojo.toJson(rp)
+				);
+			}
+
+			function checkBCpanes(/*BorderContainer*/ bc){
+				// summary:
+				//		Check that all the panes in this BorderContainer are in sane
+				//		positions relative to each other.   Assumes at most one pane
+				//		in each region.
+				var children = bc.getChildren(),
+					regions = {};
+
+				// Check all panes inside BorderContainer
+				dojo.forEach(children, function(child){
+					checkInside(child, bc);
+					regions[child.region] = child;
+				});
+
+				// Check pane positions relative to each other
+				dojo.forEach(children, function(child){
+					switch(child.region){
+						case "top":
+							dojo.forEach(bc.design == "sidebar" ? ["center", "bottom"] : ["left", "center", "right", "bottom"], function(region){
+								if(regions[region]){
+									checkAbove(bc.id, child, regions[region]);
+								}
+							});
+							break;
+						case "bottom":
+							dojo.forEach(bc.design == "sidebar" ? ["center", "top"] : ["left", "center", "right", "top"], function(region){
+								if(regions[region]){
+									checkAbove(bc.id, regions[region], child);
+								}
+							});
+							break;
+						case "left":
+							dojo.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "right"] : ["right"], function(region){
+								if(regions[region]){
+									checkLeft(bc.id, child, regions[region]);
+								}
+							});
+							break;
+						case "right":
+							dojo.forEach(bc.design == "sidebar" ? ["top", "center", "bottom", "left"] : ["left"], function(region){
+								if(regions[region]){
+									checkLeft(bc.id, regions[region], child);
+								}
+							});
+							break;
+					}
+				});
+			}
+			
+			function within(/*Number*/ a, /*Number*/ b, /*Number*/ range){
+				// summary:
+				//		Returns true if a and b are within range
+				return Math.abs(a-b) <= range;
+			}
diff --git a/dijit/tests/layout/runTests.html b/dijit/tests/layout/runTests.html
new file mode 100644
index 0000000..4f9559b
--- /dev/null
+++ b/dijit/tests/layout/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=dijit.tests.layout.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dijit/tests/layout/tab3.html b/dijit/tests/layout/tab3.html
index e7a1710..6340f5e 100644
--- a/dijit/tests/layout/tab3.html
+++ b/dijit/tests/layout/tab3.html
@@ -1,8 +1,8 @@
-<div dojoType="dijit.layout.TabContainer" nested="true">
-	<div dojoType="dijit.layout.ContentPane" title="Subtab #1">
+<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='nested:true'>
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #1"'>
 		<p>This is a nested tab container BUT loaded via an href.</p>
 	</div>
-	<div dojoType="dijit.layout.ContentPane" title="Subtab #2">
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #2"'>
 		<p>
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -36,4 +36,4 @@
 		hymenaeos.
 		</p>
 	</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/dijit/tests/layout/tab3_noLayout.html b/dijit/tests/layout/tab3_noLayout.html
index 9a3a6b9..421867b 100644
--- a/dijit/tests/layout/tab3_noLayout.html
+++ b/dijit/tests/layout/tab3_noLayout.html
@@ -1,8 +1,8 @@
-<div dojoType="dijit.layout.TabContainer" doLayout="false">
-	<div dojoType="dijit.layout.ContentPane" title="Subtab #1">
+<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='doLayout:false'>
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #1"'>
 		<p>This is a nested tab container BUT loaded via an href.</p>
 	</div>
-	<div dojoType="dijit.layout.ContentPane" title="Subtab #2">
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Subtab #2"'>
 		<p>
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 		semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -36,4 +36,4 @@
 		hymenaeos.
 		</p>
 	</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/dijit/tests/layout/tab4.html b/dijit/tests/layout/tab4.html
index de9cd3c..ea422b0 100644
--- a/dijit/tests/layout/tab4.html
+++ b/dijit/tests/layout/tab4.html
@@ -1,8 +1,8 @@
-<div dojoType="dijit.layout.SplitContainer" orientation="vertical">
-	<div dojoType="dijit.layout.ContentPane" title="split #1">
+<div data-dojo-type="dijit.layout.SplitContainer" data-dojo-props='orientation:"vertical"'>
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"split #1"'>
 		<p>Top of split container loaded via an href.</p>
 	</div>
-	<div dojoType="dijit.layout.ContentPane" title="split #2">
+	<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"split #2"'>
 		<p>Bottom of split container loaded via an href.</p>
 		<p>
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
@@ -37,4 +37,4 @@
 		hymenaeos.
 		</p>
 	</div>
-</div>
\ No newline at end of file
+</div>
diff --git a/dijit/tests/layout/test_AccordionContainer.html b/dijit/tests/layout/test_AccordionContainer.html
index 7a307d4..9f94e99 100644
--- a/dijit/tests/layout/test_AccordionContainer.html
+++ b/dijit/tests/layout/test_AccordionContainer.html
@@ -1,21 +1,21 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Accordion Widget Demo</title>
 
 	<!-- only needed for test files: -->
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -39,6 +39,14 @@
 		dojo.addOnLoad(function(){
 			dojo.subscribe("focusNode", function(node){ console.log("focused on " + (node?(node.id||node.tagName):"nothing"));});
 		});
+		
+		function createAccordion(){
+			var html='<div data-dojo-type="dijit.layout.AccordionContainer" id="Accordion">' +
+				 	'<div data-dojo-type="dijit.layout.ContentPane" title="first" id="first">first</div>' +
+				 	'<div data-dojo-type="dijit.layout.ContentPane" title="second" id="second">second</div>' +
+					'</div>';
+			dijit.byId("accPane").set("content",html);
+		}
 	</script>
 
 	<style type="text/css">
@@ -56,11 +64,10 @@
 
 	<h2>Accordion from markup:</h2>
 
-	<input id="beforeMarkupAccordion" value="for tabIndex testing">
-	<div dojoType="dijit.layout.AccordionContainer" id="markupAccordion"
-		style="width: 400px; height: 300px; overflow: hidden">
-		<div dojoType="dijit.layout.ContentPane" selected="true"
-			title="A Simple Pane" iconClass="dijitEditorIcon dijitEditorIconSave" tooltip="tooltip for simple pane" id="pane1">
+	<input id="beforeMarkupAccordion" value="for tabIndex testing"/>
+	<div id="markupAccordion" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width: 400px; height: 300px; overflow: hidden"'>
+		<div id="pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true,
+			title:"A Simple Pane", iconClass:"dijitEditorIcon dijitEditorIconSave", tooltip:"tooltip for simple pane" '>
 				<select>
 					<option>red</option>
 					<option>blue</option>
@@ -94,12 +101,11 @@
 		</div>
 
 		<!-- test lazy loading.   margin style for testing size calculations. -->
-		<div dojoType="dijit.layout.ContentPane" id="lazyLoadPane"
-			title="Lazy Load Pane" iconClass="dijitEditorIcon dijitEditorIconCopy" href="tab1.html"
-			style="margin: 5px;"></div>
+		<div id="lazyLoadPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Lazy Load Pane", iconClass:"dijitEditorIcon dijitEditorIconCopy", href:"tab1.html",
+			style:"margin: 5px;"'></div>
 
-		<div dojoType="dijit.layout.BorderContainer" id="borderContainerPane" title="BorderContainer Pane" iconClass="dijitEditorIcon dijitEditorIconPaste">
-			<div dojoType="dijit.layout.ContentPane" region="left" style="width:50%" splitter="true">
+		<div id="borderContainerPane" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"BorderContainer Pane", iconClass:"dijitEditorIcon dijitEditorIconPaste"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:50%", splitter:true'>
 			1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 			Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 			vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -114,7 +120,7 @@
 			sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 			ut eros sit amet ante pharetra interdum.
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="center">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 			2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 			Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 			vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -131,7 +137,7 @@
 			</div>
 		</div>
 
-		<div dojoType="dijit.layout.ContentPane" id="embeddedLayoutPane" title="Embedded layout widgets" iconClass="dijitEditorIcon dijitEditorIconCut">
+		<div id="embeddedLayoutPane" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Embedded layout widgets", iconClass:"dijitEditorIcon dijitEditorIconCut"'>
 			<p>
 				The pane has some text, plus two embedded layout widgets, which should
 				appear correctly even though the pane is initially hidden.
@@ -139,8 +145,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -155,7 +161,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -174,8 +180,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -190,7 +196,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -211,16 +217,16 @@
 			</p>
 		</div>
 	</div>
-	<input id="afterMarkupAccordion" value="for tabIndex testing">
+	<input id="afterMarkupAccordion" value="for tabIndex testing"/>
 	<button onclick="dijit.byId('pane1').set('title', 'My First Pane');">Change title of first pane</button>
 	<button onclick="dijit.byId('pane1').set('iconClass', 'plusIcon');">Change icon of first pane</button>
 	<button onclick="dijit.byId('markupAccordion').removeChild(dijit.byId('lazyLoadPane'));">Remove lazy-load pane</button>
 
 	<p></p>
 	<h2>Accordion with padding</h2>
-	<div dojoType="dijit.layout.AccordionContainer"
-		style="width: 400px; height: 300px; overflow: hidden">
-		<div dojoType="dijit.layout.ContentPane" class="somePadding" title="Some Padding">
+	<div data-dojo-type="dijit.layout.AccordionContainer"
+		data-dojo-props='style:"width: 400px; height: 300px; overflow: hidden"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"somePadding", title:"Some Padding"'>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -247,7 +253,7 @@
 				ut eros sit amet ante pharetra interdum.
 			</p>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" title="No Padding">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"No Padding"'>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 				suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -274,7 +280,7 @@
 				ut eros sit amet ante pharetra interdum.
 			</p>
 		</div>
-		<div dojoType="dijit.layout.AccordionPane" class="extremePadding" title="Extreme Padding">
+		<div data-dojo-type="dijit.layout.AccordionPane" data-dojo-props='"class":"extremePadding", title:"Extreme Padding"'>
 			<p>(Leaving one to test deprecation)</p>
 			<p>
 				Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
@@ -303,6 +309,13 @@
 			</p>
 		</div>
 	</div>
-
+	
+	<br><br>
+	<h2>Accordion container destroy</h2>
+	<div id="accPane" data-dojo-type="dijit.layout.ContentPane" >
+	</div>
+	Click the button twice - it will work correctly unless there was a problem destroying the accordion, in which case the second time
+	the Accordion will not be created and you will see an error like <b>Tried to register widget with id==first_button but that id is already registered</b><br/>
+	<button type="button" onclick="createAccordion()">create Accordion</button>
 </body>
 </html>
diff --git a/dijit/tests/layout/test_AccordionContainerDestroy.html b/dijit/tests/layout/test_AccordionContainerDestroy.html
deleted file mode 100644
index 90172e6..0000000
--- a/dijit/tests/layout/test_AccordionContainerDestroy.html
+++ /dev/null
@@ -1,57 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Accordion Widget Demo</title>
-
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<!-- uncomment for profiling
-		<script type="text/javascript"
-			src="../../../dojo/_base/html.js"></script>
-		<script type="text/javascript"
-			src="../../base/Layout.js"></script>
-	-->
-
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.AccordionContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-	<script type="text/javascript">
-		function createAccordion()
-		{
-			var html='<div dojoType="dijit.layout.AccordionContainer" id="Accordion">' +
-				 	'<div dojoType="dijit.layout.ContentPane" title="first" id="first">first</div>' +
-				 	'<div dojoType="dijit.layout.ContentPane" title="second" id="second">second</div>' +
-					'</div>';
-			accPane.set("content",html);
-		}
-	</script>
-</head>
-<body class="claro" style="padding: 50px;">
-
-	<h1 class="testTitle">AccordionContainer Tests</h1>
-	<div dojoType="dijit.layout.ContentPane" jsId="accPane">
-	</div>
-	Click the button twice - it will work correctly unless there was a problem destroying the accordion, in which case the second time
-	the Accordion will not be created and you will see an error like <b>Tried to register widget with id==first_button but that id is already registered</b><br/>
-	<button type="button" onclick="createAccordion()">create Accordion</button>
-
-</body>
-</html>
diff --git a/dijit/tests/layout/test_BorderContainer.html b/dijit/tests/layout/test_BorderContainer.html
index 1b5e76b..6ef574e 100644
--- a/dijit/tests/layout/test_BorderContainer.html
+++ b/dijit/tests/layout/test_BorderContainer.html
@@ -1,11 +1,12 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.layout.BorderContainer Test</title>
 
 	<!-- only needed for test files: -->
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		/* styles for this test */
@@ -22,15 +23,16 @@
 		}
 		#mondrian SPAN { display: none }
 		#mondrian:hover SPAN { display: inline }
+		#mondrian .dijitContentPane { padding: 0 }
 
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -59,7 +61,6 @@
 		}
 
 		function watchSplitters(bc) {
-
 			var out = dojo.byId("watchedOutput");
 			var moveConnects = {};
 			dojo.forEach(["top", "left"], function(region) {
@@ -84,38 +85,56 @@
 				});
 			})
 		}
-		dojo.addOnLoad(function() {
+
+		var bc, cp1, cp2, cp3;
+        dojo.addOnLoad(function(){
 			watchSplitters( dijit.byId("watchedBC") );
-		})
+				
+			bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
+
+			cp1 = new dijit.layout.ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true, id:"cp1"});
+			cp1.domNode.innerHTML = "top pane";
+			bc.addChild(cp1);
+
+			cp2 = new dijit.layout.ContentPane({region:'center',style:'background-color:green', id:'cp2'});
+			cp2.domNode.innerHTML = "center pane";
+			bc.addChild(cp2);
+
+			cp3 = new dijit.layout.ContentPane({region:'left', splitter: true, style:'width: 100px;', id:'cp3'});
+			cp3.domNode.innerHTML = "left pane";
+			
+			bc.startup();
+        });
+
 	</script>
 </head>
 <body class="claro">
 
 	<h2 class="testTitle">dijit.layout.BorderContainer tests</h2>
 	<p>Headline layout (default), left is constrained - min:150, max:250</p>
-	<div id="border1" dojoType="dijit.layout.BorderContainer"
-		style="width: 1000px; height: 300px; border: 2px solid blue;">
-		<div id="border1-top" dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; border: 15px black solid; height: 50px;" splitter="true" role="banner">
+	<div id="border1" data-dojo-type="dijit.layout.BorderContainer"
+		data-dojo-props='style:"width: 1000px; height: 300px; border: 2px solid blue;"'>
+		<div role="banner" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-top", region:"top", style:"background-color: #b39b86; border: 15px black solid; height: 50px;", splitter:true'>
 			top bar (resizable)
 		</div>
-		<div id="border1-left" dojoType="dijit.layout.ContentPane" region="left" style="background-color: #acb386; border: 10px green solid; width: 100px;"
-		role="navigation" splitter="true" minSize="150" maxSize="250">
+		<div role="navigation" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-left", region:"left", style:"background-color: #acb386; border: 10px green solid; width: 100px;",
+		splitter:true, minSize:150, maxSize:250'>
 			left (resizable b/w 150 → 250)
 		</div>
-		<div id="border1-center" dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 30px;" role="main">
+		<div role="main" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-center", region:"center", style:"background-color: #f5ffbf; padding: 30px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit.form.FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div id="border1-right" dojoType="dijit.layout.ContentPane" region="right" style="background-color: #acb386; width: 100px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-right", region:"right", style:"background-color: #acb386; width: 100px;"'>
 			right (fixed size)
 		</div>
-		<div id="border1-bottom" dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 50px;" splitter="true" role="contentinfo">
+		<div role="contentinfo" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border1-bottom", region:"bottom", style:"background-color: #b39b86; height: 50px;", splitter:true'>
 			bottom bar (resizable)
 		</div>
 	</div>
@@ -124,79 +143,79 @@
 	<br />
 
 	<p>Sidebar layout, BiDi sensitive, liveSplitters: false</p>
-	<div id="border2" dojoType="dijit.layout.BorderContainer" design="sidebar" liveSplitters="false"
-		style="border: 20px solid black; width: 1000px; height: 300px;">
-		<div id="border2-leading" dojoType="dijit.layout.ContentPane" region="leading" style="background-color: #acb386; width: 100px;">
+	<div id="border2" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", liveSplitters:false,
+		style:"border: 20px solid black; width: 1000px; height: 300px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
 			leading (fixed size)
 		</div>
-		<div id="border2-top" dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 80px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-top", region:"top", style:"background-color: #b39b86; height: 80px;"'>
 			top bar (fixed size)
 		</div>
-		<div id="border2-center" dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit.form.FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div id="border2-bottom" dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 80px;" splitter="true">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-bottom", region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
 			bottom bar (resizable)
 		</div>
-		<div id="border2-trailing" dojoType="dijit.layout.ContentPane" region="trailing" style="background-color: #acb386; width: 100px;" splitter="true">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"border2-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
 			trailing (resizable)
 		</div>
 	</div>
 
 	<p>gutters=false layout</p>
 
-	<div dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false"
-		style="border: 20px solid black; width: 1000px; height: 300px;">
-		<div dojoType="dijit.layout.ContentPane" region="leading" style="background-color: #acb386; width: 100px;">
+	<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", gutters:false,
+		style:"border: 20px solid black; width: 1000px; height: 300px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"leading", style:"background-color: #acb386; width: 100px;"'>
 			leading
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 80px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 80px;"'>
 			top bar
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit.form.FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 80px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 80px;"'>
 			bottom bar
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="trailing" style="background-color: #acb386; width: 100px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"trailing", style:"background-color: #acb386; width: 100px;"'>
 			trailing
 		</div>
 	</div>
 
 	<p>Vertical panels only with splitters</p>
 
-	<div dojoType="dijit.layout.BorderContainer" design="sidebar"
-		style="border: 2px solid black; width: 1000px; height: 300px; padding: 10px;">
-		<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 80px;" splitter="true">
+	<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar",
+		style:"border: 2px solid black; width: 1000px; height: 300px; padding: 10px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 80px;", splitter:true'>
 			top bar
 		</div>
 
-		<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit.form.FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 80px;" splitter="true">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 80px;", splitter:true'>
 			bottom bar
 		</div>
 	</div>
@@ -204,38 +223,46 @@
 	<br />
 	<p>More fun with layouts</p>
 
-	<div id="mondrian" dojoType="dijit.layout.BorderContainer" design="sidebar" gutters="false" persist="true" style="height: 300px; width: 400px;">
-		<div id="mondrian_top" dojoType="dijit.layout.ContentPane" region="top" style="height: 100px" splitter="true">
-			<div  id="mondrian_top_bc" dojoType="dijit.layout.BorderContainer" persist="true" gutters="false" style="height: 100px; width: 100%">
-				<div id="top_a" dojoType="dijit.layout.ContentPane" region="leading" style="width: 125px" splitter="true"><span>top a</span></div>
-				<div id="top_b" dojoType="dijit.layout.ContentPane" region="center" style="background-color: yellow" splitter="true"><span>top b</span></div>
+	<div id="mondrian" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar", gutters:false, persist:true, style:"height: 300px; width: 400px;"'>
+		<div id="mondrian_top" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"height: 100px", splitter:true'>
+			<div id="mondrian_top_bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 100px; width: 100%"'>
+				<div id="top_a" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"leading", style:"width: 125px", splitter:true'><span>top a</span></div>
+				<div id="top_b" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: yellow", splitter:true'><span>top b</span></div>
 			</div>
 		</div>
-		<div id="mondrian_bottom" dojoType="dijit.layout.ContentPane" region="bottom" style="height: 100px" splitter="true">
-			<div id="mondrian_bottom_bc" dojoType="dijit.layout.BorderContainer" persist="true" gutters="false" style="height: 100px; width: 100%">
-				<div id="bottom_c" dojoType="dijit.layout.ContentPane" region="top" style="height: 40px" splitter="true"><span>bottom c</span></div>
-				<div id="bottom_d" dojoType="dijit.layout.ContentPane" region="center"><span>bottom d</span></div>
+		<div id="mondrian_bottom" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"height: 100px", splitter:true'>
+			<div id="mondrian_bottom_bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 100px; width: 100%"'>
+				<div id="bottom_c" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"height: 40px", splitter:true'><span>bottom c</span></div>
+				<div id="bottom_d" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'><span>bottom d</span></div>
 			</div>
 		</div>
-		<div id="mondrian_leading" dojoType="dijit.layout.ContentPane" region="leading" style="width: 100px" splitter="true">
-			<div id="mondrian_leading_bc" dojoType="dijit.layout.BorderContainer" persist="true" gutters="false" style="height: 300px; width: 100%">
-				<div id="leading_e" dojoType="dijit.layout.ContentPane" region="center"><span>leading e</span></div>
-				<div id="leading_f" dojoType="dijit.layout.ContentPane" region="bottom" style="height: 100px; background-color: red" splitter="true"><span>leading f</span></div>
+		<div id="mondrian_leading" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"leading", style:"width: 100px", splitter:true'>
+			<div id="mondrian_leading_bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:true, gutters:false, style:"height: 300px; width: 100%"'>
+				<div id="leading_e" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'><span>leading e</span></div>
+				<div id="leading_f" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"height: 100px; background-color: red", splitter:true'><span>leading f</span></div>
 			</div>
 		</div>
-		<div id="trailing_g" dojoType="dijit.layout.ContentPane" region="trailing" style="width: 100px" splitter="true"><span>trailing g</span></div>
+		<div id="trailing_g" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"trailing", style:"width: 100px", splitter:true'><span>trailing g</span></div>
 	</div>
 
 	<br />
 	<p>Watching the splitter events</p>
-	<div dojoType="dijit.layout.BorderContainer" id="watchedBC" persist="false" gutters="false" style="height: 200px; width: 100%">
-		<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 id="watchedBC" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='persist:false, gutters:false, style:"height: 200px; width: 100%"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true, style:"background-color: #ccffcc; height: 50px;"'>Top:</div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"background-color: #ccccff; width: 40px", splitter:true'><span>Bottom</span></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #ffffcc"'><span>Center</span></div>
 	</div>
 
 	<p>Splitter coords output:</p>
 	<div id="watchedOutput" style="border: 1px solid #999">nothing moving</div>
 
+	
+	<h2 class="testTitle">dijit.layout.BorderContainer programmatic test</h2>
+	<div id='main'></div>
+
+	<button id="addLeft" onclick="bc.addChild(cp3);">add left pane</button>
+	<button id="removeLeft" onclick="bc.removeChild(cp3);">remove left pane</button>
+	<button id="addTop" onclick="bc.addChild(cp1);">add top pane</button>
+	<button id="removeTop" onclick="bc.removeChild(cp1);">remove top pane</button>
 </body>
 </html>
diff --git a/dijit/tests/layout/test_BorderContainer_complex.html b/dijit/tests/layout/test_BorderContainer_complex.html
index 6685ebb..e1b7469 100644
--- a/dijit/tests/layout/test_BorderContainer_complex.html
+++ b/dijit/tests/layout/test_BorderContainer_complex.html
@@ -1,20 +1,21 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.layout.BorderContainer Test - complex layout</title>
 
 	<!-- only needed for test files: -->
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -36,14 +37,14 @@
 
 	<h1 class="testTitle">dijit.layout.BorderContainer complex layout test</h1>
 
-	<div dojoType="dijit.layout.BorderContainer"
-		style="border: 2px solid black; width: 90%; height: 500px; padding: 10px;">
-		<div dojoType="dijit.layout.AccordionContainer"
-			region="left" style="background-color: #acb386; width: 400px;" splitter="true">
-			<div dojoType="dijit.layout.ContentPane" title="a">
+	<div id="border1" data-dojo-type="dijit.layout.BorderContainer"
+		data-dojo-props='style:"border: 2px solid black; width: 90%; height: 500px; padding: 10px;" '>
+		<div id="ac1" data-dojo-type="dijit.layout.AccordionContainer"
+			data-dojo-props='region:"left", style:"background-color: #acb386; width: 400px;", splitter:true'>
+			<div id="ap1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"a"'>
 				left bar
 			</div>
-			<div dojoType="dijit.layout.ContentPane" title="b">
+			<div id="ap2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"b"'>
 				<p>
 					Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 					suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -70,17 +71,17 @@
 					ut eros sit amet ante pharetra interdum.
 				</p>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" title="c">
+			<div id="ap3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"c"'>
 				<p>The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.</p>
 			</div>
 		</div>
 
-		<div dojoType="dijit.layout.AccordionContainer"
-			region="right" style="background-color: #acb386; width: 200px;">
-			<div dojoType="dijit.layout.ContentPane" title="a">
+		<div data-dojo-type="dijit.layout.AccordionContainer"
+			data-dojo-props='region:"right", style:"background-color: #acb386; width: 80px;"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"a"'>
 				right bar
 			</div>
-			<div dojoType="dijit.layout.ContentPane" title="b">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"b"'>
 				<p>
 					Nunc consequat nisi vitae quam. Suspendisse sed nunc. Proin
 					suscipit porta magna. Duis accumsan nunc in velit. Nam et nibh.
@@ -107,26 +108,26 @@
 					ut eros sit amet ante pharetra interdum.
 				</p>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" title="c">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"c"'>
 				<p>The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.  The quick brown fox jumps over the lazy dog.</p>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 150px;" splitter="true">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 150px;", splitter:true'>
 
-			<div id="mainTabContainer" dojoType="dijit.layout.TabContainer" style="width: 100%; height: 20em;">
+			<div id="mainTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 100%; height: 20em;"'>
 
-				<div id="tab1" dojoType="dijit.layout.ContentPane" href="../../../dijit/tests/layout/tab1.html" title="Tab 1"></div>
+				<div id="tab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab1.html", title:"Tab 1"'></div>
 
-				<div id="tab2" dojoType="dijit.layout.ContentPane" href="../../../dijit/tests/layout/tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+				<div id="tab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"../../../dijit/tests/layout/tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-				<div dojoType="dijit.layout.ContentPane" title="Tab 3">
+				<div id="tab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"'>
 					<h1>I am tab 3</h1>
 					<p>And I was already part of the page! That's cool, no?</p>
 					<p id="foo">tooltip on this paragraph</p>
-					<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-					<button dojoType="dijit.form.Button">I'm a button </button>
+					<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
+					<button data-dojo-type="dijit.form.Button">I'm a button </button>
 					<br>
-					<button dojoType="dijit.form.Button">So am I!</button>
+					<button data-dojo-type="dijit.form.Button">So am I!</button>
 					<p>
 					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 					semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -150,26 +151,26 @@
 					</p>
 				</div>
 
-				<div dojoType="dijit.layout.TabContainer" title="Inlined Sub TabContainer">
-					<a dojoType="dijit.layout.LinkPane" href="../../../dijit/tests/layout/tab1.html">SubTab 1</a>
-					<a dojoType="dijit.layout.LinkPane" href="../../../dijit/tests/layout/tab2.html" selected="true">SubTab 2</a>
+				<div id="tab4" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Inlined Sub TabContainer"'>
+					<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab1.html"'>SubTab 1</a>
+					<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab2.html", selected:true'>SubTab 2</a>
 				</div>
 
-				<a dojoType="dijit.layout.LinkPane" href="../../../dijit/tests/layout/tab3.html">Sub TabContainer from href</a>
+				<a id="tab5" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab3.html"'>Sub TabContainer from href</a>
 
-				<a dojoType="dijit.layout.LinkPane" href="../../../dijit/tests/layout/tab4.html">SplitContainer from href</a>
+				<a id="tab6" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"../../../dijit/tests/layout/tab4.html"'>SplitContainer from href</a>
 
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 150px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 150px;"'>
 			<div style="border: 1px solid black;">
-				<div dojoType="dijit.Editor" id="editor1"><p>bottom bar (edit me)</p></div>
+				<div id="editor1" data-dojo-type="dijit.Editor" ><p>bottom bar (edit me)</p></div>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
+		<div id="mainCP" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select id="filteringSelect" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props='style:"width:4em;"'>
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
diff --git a/dijit/tests/layout/test_BorderContainer_experimental.html b/dijit/tests/layout/test_BorderContainer_experimental.html
index 77d5e9a..b51de94 100644
--- a/dijit/tests/layout/test_BorderContainer_experimental.html
+++ b/dijit/tests/layout/test_BorderContainer_experimental.html
@@ -1,11 +1,12 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
     <head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>BorderContainer Experiments | The Dojo Toolkit</title>
 
 		<!-- only needed for test files: -->
 		<style type="text/css">
-			@import "../../../dojo/resources/dojo.css";
+			@import "../../themes/claro/document.css";
 			@import "../css/dijitTests.css";
 			#pane1 { background-color:red;
 			}
@@ -23,11 +24,11 @@
 		</style>
 
 		<!-- required: the default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true"></script>
 
 		<!-- only needed for alternate theme testing: -->
 		<script type="text/javascript" src="../_testCommon.js"></script>
@@ -37,105 +38,108 @@
 			dojo.require("dijit.form.Button");
 			dojo.require("dijit.layout.ContentPane");
 			dojo.require("dijit.layout.BorderContainer");
-			dojo.declare("my.BorderContainer",dijit.layout.BorderContainer,{
 
-				opts: {
-					// single pane view
-					"a":{
-						panes: [
-							{ id: "pane0", sizeable:false, region:"center", style: { width:"100%", height:"100%" } },
-							{ id: "pane1", hidden:true },
-							{ id: "pane2", hidden:true },
-							{ id: "pane3", hidden:true }
-						]
+			var open = false;
+
+			dojo.addOnLoad(function(){
+				dojo.declare("my.BorderContainer",dijit.layout.BorderContainer,{
+	
+					opts: {
+						// single pane view
+						"a":{
+							panes: [
+								{ id: "pane0", sizeable:false, region:"center", style: { width:"100%", height:"100%" } },
+								{ id: "pane1", hidden:true },
+								{ id: "pane2", hidden:true },
+								{ id: "pane3", hidden:true }
+							]
+						},
+						// top / bottom view
+						"ah":{
+							panes: [
+								{ id: "pane0", sizeable:false, region:"center", style: { width:"100%", height:"50%" } },
+								{ id: "pane1", sizeable:true, region:"bottom", style: { width:"100%", height:"50%" } },
+								{ id: "pane2", hidden:true },
+								{ id: "pane3", hidden:true }
+							]
+						},
+						// left / right view
+						"av":{
+							panes: [
+								{ id: "pane0", sizeable:true, region:"left", style: { width:"50%", height:"100%" } },
+								{ id: "pane1", sizeable:false, region:"center", style: { width:"50%", height:"100%" } },
+								{ id: "pane2", hidden:true },
+								{ id: "pane3", hidden:true }
+							]
+						}
+	
 					},
-					// top / bottom view
-					"ah":{
-						panes: [
-							{ id: "pane0", sizeable:false, region:"center", style: { width:"100%", height:"50%" } },
-							{ id: "pane1", sizeable:true, region:"bottom", style: { width:"100%", height:"50%" } },
-							{ id: "pane2", hidden:true },
-							{ id: "pane3", hidden:true }
-						]
+	
+					_clearSplitters: function(){
+						// cleanup all splitters on the page
+						dojo.query(".dijitSplitter",this.domNode).forEach(function(n){
+							dijit.byNode(n).destroy();
+						});
+						dojo.query(".dijitSplitterCover").forEach(dojo.destroy);
+						delete this._splitters;
+						this._splitters = {};
 					},
-					// left / right view
-					"av":{
-						panes: [
-							{ id: "pane0", sizeable:true, region:"left", style: { width:"50%", height:"100%" } },
-							{ id: "pane1", sizeable:false, region:"center", style: { width:"50%", height:"100%" } },
-							{ id: "pane2", hidden:true },
-							{ id: "pane3", hidden:true }
-						]
-					}
-
-				},
-
-				_clearSplitters: function(){
-					// cleanup all splitters on the page
-					dojo.query(".dijitSplitter",this.domNode).forEach(function(n){
-						dijit.byNode(n).destroy();
-					});
-					dojo.query(".dijitSplitterCover").forEach(dojo.destroy);
-					delete this._splitters;
-					this._splitters = {};
-				},
-
-				setLayoutENUM: function(lay){
-					// set the layout to a predefined setup
-					if(this._layoutSetting != lay){
-
-						this._layoutSetting = lay;
-						var struct = this.opts[lay] || false;
-						this._clearSplitters();
-
-						dojo.forEach(struct.panes,function(pane,i){
-							// setup each pane
-							var d = dijit.byId(pane.id);
-							d.region = pane.region || "center";
-							d.splitter = pane.sizeable;
-							if(pane.minSize){ d.minSize = pane.minSize; }
-							if(pane.maxSize){ d.maxSize = pane.maxSize; }
-							if(pane.hidden){
-								// reset this widget to our hidden holder node
-								this.extractChild(d,dojo.byId("holder"));
-								d.splitter = null;
-								d.region = null;
-								d.maxSize = null;
-								d.minSize = null;
-							}else{
-								if(pane.style){
-									// object setter via style only in trunk:
-									dojo.style(d.domNode,pane.style);
+	
+					setLayoutENUM: function(lay){
+						// set the layout to a predefined setup
+						if(this._layoutSetting != lay){
+	
+							this._layoutSetting = lay;
+							var struct = this.opts[lay] || false;
+							this._clearSplitters();
+	
+							dojo.forEach(struct.panes,function(pane,i){
+								// setup each pane
+								var d = dijit.byId(pane.id);
+								d.region = pane.region || "center";
+								d.splitter = pane.sizeable;
+								if(pane.minSize){ d.minSize = pane.minSize; }
+								if(pane.maxSize){ d.maxSize = pane.maxSize; }
+								if(pane.hidden){
+									// reset this widget to our hidden holder node
+									this.extractChild(d,dojo.byId("holder"));
+									d.splitter = null;
+									d.region = null;
+									d.maxSize = null;
+									d.minSize = null;
+								}else{
+									if(pane.style){
+										// object setter via style only in trunk:
+										dojo.style(d.domNode,pane.style);
+									}
+									this.addChild(d,i);
 								}
-								this.addChild(d,i);
-							}
-						},this);
-					}
-					this.layout();
-				},
-
-				extractChild: function(/*dijit._Widget*/ child, /*DomNode*/ node){
-					// a non-destructive cleanup for the bordercontainer.
-					// cleanup a widget, and append it's domNode to some
-					// other node in the dom
-					var region = child.region;
-					var splitter = this._splitters[region];
-					if(splitter){
-						dijit.byNode(splitter).destroy();
-						delete this._splitters[region];
-					}
-					delete this["_"+region];
-					node.appendChild(child.domNode);
-					if(this._started){
-						this._layoutChildren();
+							},this);
+						}
+						this.layout();
+					},
+	
+					extractChild: function(/*dijit._Widget*/ child, /*DomNode*/ node){
+						// a non-destructive cleanup for the bordercontainer.
+						// cleanup a widget, and append it's domNode to some
+						// other node in the dom
+						var region = child.region;
+						var splitter = this._splitters[region];
+						if(splitter){
+							dijit.byNode(splitter).destroy();
+							delete this._splitters[region];
+						}
+						delete this["_"+region];
+						node.appendChild(child.domNode);
+						if(this._started){
+							this._layoutChildren();
+						}
+						return child.domNode;
 					}
-					return child.domNode;
-				}
-			});
+				});
+	
+				dojo.parser.parse();
 
-			var open = false;
-
-			dojo.addOnLoad(function(){
 				// make buttons
 				dojo.forEach(["a","av","ah"],function(n){
 
@@ -167,14 +171,14 @@
 			<div id="buttons"></div>
 		</div>
 
-		<div jsId="layout" id="container" dojoType="my.BorderContainer" style="width:600px; height:300px; border:3px solid #333;">
-			<div dojoType="dijit.layout.ContentPane" region="center" id="pane0">
+		<div id="container" data-dojo-id="layout" data-dojo-type="my.BorderContainer" data-dojo-props='style:"width:600px; height:300px; border:3px solid #333;"'>
+			<div id="pane0" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center" '>
 				pane0
 			</div>
 		</div>
 
-		<div class="bc" dojoType="dijit.layout.BorderContainer" style="height:200px">
-			<div dojoType="dijit.layout.ContentPane" region="center">
+		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 				Sinlge pane - l1
 			</div>
 		</div>
@@ -183,15 +187,15 @@
 			<h3>two panes, vertical split:</h3>
 
 
-			<div class="bc" id="animBC" dojoType="dijit.layout.BorderContainer" style="height:200px">
-				<div dojoType="dijit.layout.ContentPane" id="sizing1" style="background-color:red" region="left" splitter="true">
+			<div id="animBC" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+				<div id="sizing1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='style:"background-color:red", region:"left", splitter:true'>
 					Sinlge pane - left
 				</div>
-				<div dojoType="dijit.layout.ContentPane"  region="center">
+				<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='region:"center"'>
 					Sinlge pane - center
-					<button dojoType="dijit.form.Button">
+					<button data-dojo-type="dijit.form.Button">
 					Size Me
-					<script type="dojo/method" event="onClick">
+					<script type="dojo/method" data-dojo-event="onClick">
 						var n = dijit.byId("sizing1").domNode;
 						dojo.animateProperty({
 							node:n,
@@ -207,51 +211,51 @@
 				</div>
 			</div>
 
-			<div class="bc" dojoType="dijit.layout.BorderContainer" style="height:200px">
-				<div dojoType="dijit.layout.ContentPane" region="center" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", splitter:true'>
 					Single pane - center (splitter) (this is unsupported, and does not work)
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="right">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right"'>
 					Single pane - right (no splitter)
 				</div>
 			</div>
 
-			<div class="bc" dojoType="dijit.layout.BorderContainer" style="height:200px">
-				<div dojoType="dijit.layout.ContentPane" region="center">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"height:200px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					Single pane - center (no splitter)
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="right" splitter="true">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", splitter:true'>
 					Single pane - right (splitter)
 				</div>
 			</div>
 		</div>
 
-		<div class="bc" dojoType="dijit.layout.BorderContainer" style="width:200px; height:400px;">
-			<div dojoType="dijit.layout.ContentPane" region="top" splitter="true">
+		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"width:200px; height:400px;"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true'>
 				Single pane - top (splitter)
 
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="center">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 				Single pane - center
 			</div>
 		</div>
 
-		<div class="bc" dojoType="dijit.layout.BorderContainer" style="width:200px; height:400px;">
-			<div dojoType="dijit.layout.ContentPane" region="center">
+		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='"class":"bc", style:"width:200px; height:400px;"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 				Single pane - center
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="bottom" splitter="true">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", splitter:true'>
 				Single Pane Bottom (splitter)
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="top" splitter="true">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true'>
 				Single Pane Top (splitter)
 			</div>
 		</div>
 
 		<div id="holder" style="visibility:hidden">
-			<div dojoType="dijit.layout.ContentPane" id="pane1">pane 1</div>
-			<div dojoType="dijit.layout.ContentPane" id="pane2">pane 2</div>
-			<div dojoType="dijit.layout.ContentPane" id="pane3">pane 3</div>
+			<div id="pane1" data-dojo-type="dijit.layout.ContentPane" >pane 1</div>
+			<div id="pane2" data-dojo-type="dijit.layout.ContentPane" >pane 2</div>
+			<div id="pane3" data-dojo-type="dijit.layout.ContentPane" >pane 3</div>
 		</div>
 
     </body>
diff --git a/dijit/tests/layout/test_BorderContainer_full.html b/dijit/tests/layout/test_BorderContainer_full.html
index e823571..fa27fbd 100644
--- a/dijit/tests/layout/test_BorderContainer_full.html
+++ b/dijit/tests/layout/test_BorderContainer_full.html
@@ -1,10 +1,11 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.layout.BorderContainer Test - Full Screen</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		html, body, #main{
@@ -18,11 +19,11 @@
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -36,27 +37,27 @@
 
 </head>
 <body class="claro">
-	<div dojoType="dijit.layout.BorderContainer" design="sidebar" id="main">
-		<div dojoType="dijit.layout.ContentPane" region="leading" style="background-color: #acb386; width: 100px;">
+	<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='design:"sidebar" '>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-leading", region:"leading", style:"background-color: #acb386; width: 100px;"'>
 			leading
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 100px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-top", region:"top", style:"background-color: #b39b86; height: 100px;"'>
 			top bar
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
+			<select data-dojo-type="dijit.form.FilteringSelect">
 				<option value="1">foo</option>
 				<option value="2">bar</option>
 				<option value="3">baz</option>
 			</select>
 			Here's some text that comes AFTER the combo box.
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 100px;" splitter="true">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-bottom", region:"bottom", style:"background-color: #b39b86; height: 100px;", splitter:true'>
 			bottom bar
 		</div>
-		<div dojoType="dijit.layout.ContentPane" region="trailing" style="background-color: #acb386; width: 100px;" splitter="true">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"main-trailing", region:"trailing", style:"background-color: #acb386; width: 100px;", splitter:true'>
 			trailing
 		</div>
 	</div>
diff --git a/dijit/tests/layout/test_BorderContainer_nested.html b/dijit/tests/layout/test_BorderContainer_nested.html
index cd34acd..e7a3d29 100644
--- a/dijit/tests/layout/test_BorderContainer_nested.html
+++ b/dijit/tests/layout/test_BorderContainer_nested.html
@@ -1,19 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>dijit.layout.BorderContainer Test</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -29,42 +30,47 @@
 <body class="claro">
 
 	<h2 class="testTitle">dijit.layout.BorderContainer tests</h2>
-	<p>Basic layout</p>
 
-	<div dojoType="dijit.layout.TabContainer" style="width:800px;height:600px;">
-		<div dojoType="dijit.layout.BorderContainer" title="Tab 1"
-			style="border: 2px solid black; width: 90%; height: 500px; padding: 10px;">
-			<div dojoType="dijit.layout.ContentPane" region="left" style="background-color: #acb386; width: 100px;">
+	<p>
+		The second tab holds a single BorderContainer but specifying layoutPriority on it's children to have multiple children
+		for each region.
+	</p>
+	<p>
+		The first tab holds a BorderContainer which nests another BorderContainer, simulating multiple children in a single region.
+	</p>
+
+	<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width:800px;height:600px;"'>
+		<div id="nbc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"Nested BC"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"background-color: #acb386; width: 100px;"'>
 				left
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="right" style="background-color: #acb386; width: 100px;">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", style:"background-color: #acb386; width: 100px;"'>
 				right
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 100px;">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 100px;"'>
 				top bar
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 100px;">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 100px;"'>
 				bottom bar
 			</div>
 
-			<div dojoType="dijit.layout.BorderContainer" region="center" design="sidebar"
-				style="border: 2px solid black; padding: 0px;">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="background-color: #acb386; width: 100px;">
-					left
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='region:"center", design:"sidebar"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"background-color: #acb386; width: 100px;"'>
+					left inner
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="right" style="background-color: #acb386; width: 100px;">
-					right
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"right", style:"background-color: #acb386; width: 100px;"'>
+					right inner
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 100px;">
-					top bar
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", style:"background-color: #b39b86; height: 100px;"'>
+					inner top bar
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 100px;">
-					bottom bar
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", style:"background-color: #b39b86; height: 100px;"'>
+					inner bottom bar
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
 					main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
 					(to check we're copying children around properly).<br />
-					<select dojoType="dijit.form.FilteringSelect">
+					<select data-dojo-type="dijit.form.FilteringSelect">
 						<option value="1">foo</option>
 						<option value="2">bar</option>
 						<option value="3">baz</option>
@@ -73,44 +79,51 @@
 				</div>
 			</div>
 		</div>
-		<div dojoType="dijit.layout.BorderContainer" title="Tab 2">
-			<div dojoType="dijit.layout.ContentPane" region="left" splitter="true" style="background-color: #770; width: 100px;">
-				left
+
+		<div id="pbc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='title:"layoutPriority BC"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"top1", region:"top", splitter:true, layoutPriority: 1, style:"background-color: #077; color: white; height: 50px;"'>
+				top bar (layoutPriority == 1)
+				<input id="top1_input" value="tabstop #1"/>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="right" splitter="true" style="background-color: #077; width: 100px;">
-				right
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"top2", region:"top", splitter:true, layoutPriority: 2, style:"background-color: #f5ffbf; height: 50px;"'>
+				second top bar (layoutPriority == 2)
+				<input id="top2_input" value="tabstop #3"/>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="top" splitter="true" style="background-color: #700; height: 100px;">
-				top bar
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"left1", region:"left", splitter:true, layoutPriority: 3, style:"background-color: #770; width: 100px;"'>
+				left (layoutPriority == 3)
+				<input id="left1_input" value="tabstop #5"/>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="bottom" splitter="true" style="background-color: #007; height: 100px;">
-				bottom bar
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"left2", region:"left", splitter:true, layoutPriority: 4, style:"background-color: #acb386; width: 100px;"'>
+				inner left (layoutPriority == 4)
+				<input id="left2_input" value="tabstop #7"/>
 			</div>
-
-			<div dojoType="dijit.layout.BorderContainer" region="center" design="sidebar"
-				style="border: 2px solid black; padding: 0px;">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="background-color: #acb386; width: 100px;">
-					left
-				</div>
-				<div dojoType="dijit.layout.ContentPane" region="right" style="background-color: #acb386; width: 100px;">
-					right
-				</div>
-				<div dojoType="dijit.layout.ContentPane" region="top" style="background-color: #b39b86; height: 100px;">
-					top bar
-				</div>
-				<div dojoType="dijit.layout.ContentPane" region="bottom" style="background-color: #b39b86; height: 100px;">
-					bottom bar
-				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center" style="background-color: #f5ffbf; padding: 10px;">
-					main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-					(to check we're copying children around properly).<br />
-					<select dojoType="dijit.form.FilteringSelect">
-						<option value="1">foo</option>
-						<option value="2">bar</option>
-						<option value="3">baz</option>
-					</select>
-					Here's some text that comes AFTER the combo box.
-				</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"top3", region:"top", splitter:true, layoutPriority: 5, style:"background-color: #b39b86; height: 50px;"'>
+				inner top bar (layoutPriority == 5)
+				<input id="top3_input" value="tabstop #9"/>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"center", region:"center", style:"background-color: #f5ffbf; padding: 10px;"'>
+				center
+				<input id="center_input" value="tabstop #11"/>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"bottom3", region:"bottom", splitter:true, layoutPriority: 5, style:"background-color: #b39b86; height: 50px;"'>
+				inner bottom bar (layoutPriority == 5)
+				<input id="bottom3_input" value="tabstop #12"/>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"right2", region:"right", splitter:true, layoutPriority: 4, style:"background-color: #acb386; width: 100px;"'>
+				inner right (layoutPriority == 4)
+				<input id="right2_input" value="tabstop #14"/>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"right1", region:"right", splitter:true, layoutPriority: 3, style:"background-color: #770; width: 100px;"'>
+				right (layoutPriority == 3)
+				<input id="right1_input" value="tabstop #16"/>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id:"bottom2", region:"bottom", splitter:true, layoutPriority: 2, style:"background-color: #f5ffbf; height: 50px;"'>
+				second bottom bar (layoutPriority == 2)
+				<input id="bottom2_input" value="tabstop #18"/>
+			</div>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='id: "bottom1", region:"bottom", splitter:true, layoutPriority: 1, style:"background-color: #077; color: white; height: 50px;"'>
+				bottom bar (layoutPriority == 1)
+				<input id="bottom1_input" value="tabstop #20"/>
 			</div>
 		</div>
 	</div>
diff --git a/dijit/tests/layout/test_BorderContainer_prog.html b/dijit/tests/layout/test_BorderContainer_prog.html
deleted file mode 100644
index 4821025..0000000
--- a/dijit/tests/layout/test_BorderContainer_prog.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>dijit.layout.BorderContainer Test</title>
-
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.BorderContainer");
-        dojo.require("dijit.layout.ContentPane");
-
-		var bc, cp1, cp2, cp3;
-        dojo.addOnLoad(function(){
-                bc = new dijit.layout.BorderContainer({style:'height:400px;width:500px;border:1px solid black'}, dojo.byId('main'));
-
-				cp1 = new dijit.layout.ContentPane({region:'top',style:'height:100px;background-color:red',splitter:true});
-				cp1.domNode.innerHTML = "top pane";
-				bc.addChild(cp1);
-
-				cp2 = new dijit.layout.ContentPane({region:'center',style:'background-color:green'});
-				cp2.domNode.innerHTML = "center pane";
-				bc.addChild(cp2);
-
-                bc.startup();
-        });
-
-        function addLeftPane(){
-			cp3 = new dijit.layout.ContentPane({region:'left', splitter: true, style:'width: 100px;'});
-			cp3.domNode.innerHTML = "left pane";
-			bc.addChild(cp3);
-        }
-	</script>
-</head>
-<body class="claro">
-	<h2 class="testTitle">dijit.layout.BorderContainer programmatic test</h2>
-	<div id='main'></div>
-
-	<button onclick="addLeftPane();">add left pane</button>
-	<button onclick="bc.removeChild(cp1);">remove top pane</button>
-</body>
-</html>
diff --git a/dijit/tests/layout/test_ContentPane.html b/dijit/tests/layout/test_ContentPane.html
index 5e70511..a8140d5 100644
--- a/dijit/tests/layout/test_ContentPane.html
+++ b/dijit/tests/layout/test_ContentPane.html
@@ -1,15 +1,15 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ContentPane Test</title>
 
 	<style>
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		.box {
-		  position: relative;
+			position: relative;
 			background-color: white;
 			border: 2px solid black;
 			padding: 8px;
@@ -18,11 +18,11 @@
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -38,16 +38,20 @@
 		dojo.require("dijit.InlineEditBox");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-		// create a do nothing, only for test widget
-		dojo.declare("dijit.TestWidget",
-			[dijit._Widget, dijit._Templated], {
-			templateString: "<span class='dojoxTestWidget'></span>"
-		});
-
 		dojo.addOnLoad(function(){
 
-			var pane1 = dijit.byId('parsedPane');
-			var dialogCtrPane = dijit.byId("dialogContainer");
+			// create a do nothing, only for test widget
+			dojo.declare("dijit.TestWidget",
+				[dijit._Widget, dijit._Templated], {
+				templateString: "<span class='dojoxTestWidget'></span>"
+			});
+
+			doh.register("parse", function(){
+				dojo.parser.parse();				
+
+				pane1 = dijit.byId('parsedPane');
+				dialogCtrPane = dijit.byId("dialogContainer");
+			});
 
 			doh.register("basicChecks", [
 			{
@@ -73,7 +77,7 @@
 					console.log("basicChecks: " + this.name);
 					dialogCtrPane.set(
 						"content",
-						'<div dojoType="dijit.Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
+						'<div data-dojo-type="dijit.Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
 						+'	<p>This dialog should be cleanly destroyed when the unit tests run</p>'
 						+'</div>'
 					);
@@ -106,7 +110,7 @@
 					// do the same thing over again - we should be error free
 					dialogCtrPane.set(
 						"content",
-						'<div dojoType="dijit.Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
+						'<div data-dojo-type="dijit.Dialog" id="sacrificialDlg" title="Life is short for this fellow">'
 						+'	<p>This dialog should be cleanly destroyed when the unit tests run</p>'
 						+'</div>'
 					);
@@ -154,26 +158,26 @@
 	<h1 class="testTitle">Dijit layout.ContentPane tests</h1>
 		<p>pre-container paragraph</p>
 
-		<div dojoType="dijit.layout.ContentPane" class="box">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
 			some text (top-level container)
 
-			<div dojoType="dijit.layout.ContentPane" class="box">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
 
 				text in the inner container (1)
 
-				<div dojoType="dijit.layout.ContentPane" class="box" href="tab2.html">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box", href:"tab2.html"'>
 					hi
 				</div>
 
 				text in the inner container (2)
 
-				<div dojoType="dijit.layout.ContentPane" class="box">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
 					inner-inner 2
 				</div>
 
 				text in the inner container (3)
 
-				<div dojoType="dijit.layout.ContentPane" class="box">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
 					inner-inner 3
 				</div>
 
@@ -186,23 +190,23 @@
 
 		<p>mid-container paragraph</p>
 
-		<div dojoType="dijit.layout.ContentPane" class="box">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box"'>
 			2nd top-level container
 		</div>
 
 		<p>post-container paragraph</p>
 
-		<div dojoType="dijit.layout.ContentPane" class="box" href="combotab.html" id="test">
+		<div id="test" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box", href:"combotab.html" '>
 			<p style='background-color:yellow;border:1px solid red;text-align:center;'>This text should automatically be replaced by downloaded content from combotab.html</p>
 		</div>
 
 		<hr/>
 		<p>ContentPanes used by the unit tests to verify functionality
-		<div class='box' dojoType="dijit.layout.ContentPane" id='parsedPane'>
+		<div id='parsedPane' data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box" '>
 			Some Content Here
 		</div>
-		<div class='box' dojoType="dijit.layout.ContentPane" id='dialogContainer'>
-			<div dojoType="dijit.TestWidget" id="parserTest"></div>
+		<div id='dialogContainer' data-dojo-type="dijit.layout.ContentPane" data-dojo-props='"class":"box" '>
+			<div id="parserTest" data-dojo-type="dijit.TestWidget" ></div>
 		</div>
 	</body>
 </html>
diff --git a/dijit/tests/layout/test_ContentPane_prog.html b/dijit/tests/layout/test_ContentPane_prog.html
deleted file mode 100644
index 5a0ec9d..0000000
--- a/dijit/tests/layout/test_ContentPane_prog.html
+++ /dev/null
@@ -1,49 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>ContentPane Programmatic Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.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"
-		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">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.form.Button");
-		dojo.require("dijit.form.ComboBox");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		var cp;
-
-		dojo.addOnLoad(function(){
-			cp = new dijit.layout.ContentPane({
-				content: "hello world",
-				style: "border: solid black thin;"
-			});
-			dojo.body().appendChild(cp.domNode);
-		});
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit layout.ContentPane programmatic tests</h1>
-
-	<button onclick="cp.set('content', 'good night, sweet prince')">set content</button>
-	<button onclick="cp.set('href', 'doc0.html')">set href</button>
-
-</body>
-</html>
diff --git a/dijit/tests/layout/test_Gui.html b/dijit/tests/layout/test_Gui.html
index 865be23..175215c 100644
--- a/dijit/tests/layout/test_Gui.html
+++ b/dijit/tests/layout/test_Gui.html
@@ -1,13 +1,13 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit UI Tester</title>
 
 	<!-- required: a default theme -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 
 		html, body {
 			height: 100%;
@@ -36,7 +36,7 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: false"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: false"></script>
 
 	<!-- do not use: only for debugging / testing themes -->
 	<script type="text/javascript" src="../../tests/_testCommon.js"></script>
@@ -58,102 +58,93 @@
 <body class="claro">
 
 	<!-- "main" BorderContainer just contains page title and another BorderContainer -->
-	<div id="main" dojoType="dijit.layout.BorderContainer" gutters=true>
-		<div dojoType="dijit.layout.ContentPane" region="top" splitter="false">This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
+	<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='gutters:true, style:"height:700px;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:false'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
 
 		<!-- "mainSplit" BorderContainer has all the real content -->
-		<div dojoType="dijit.layout.BorderContainer" liveSplitters="false" design="sidebar"
-			region="center" id="mainSplit">
+		<div id="mainSplit" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, design:"sidebar",
+			region:"center" '>
 
-			<div dojoType="dijit.layout.AccordionContainer"
-				minSize="20" style="width: 300px;" id="leftAccordion" region="leading" splitter="true">
+			<div id="leftAccordion" data-dojo-type="dijit.layout.AccordionContainer"
+				data-dojo-props='minSize:20, style:"width: 300px;", region:"leading", splitter:true'>
 
-				<div dojoType="dijit.layout.ContentPane" title="Popups and Alerts">
+				<div id="ac_pane1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'>
 				</div>
 
-				<div dojoType="dijit.layout.ContentPane" title="Dojo Tree from Store">
+				<div id="ac_pane2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Dojo Tree from Store"'>
 				</div>
 
-				<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true">
+				<div id="ac_pane3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Calendar", selected:true'>
 				</div>
 
-				<div dojoType="dijit.layout.ContentPane" title="Color Picker">
+				<div id="ac_pane4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
 				</div>
 
 			</div><!-- end AccordionContainer -->
 
-			<div dojoType="dijit.layout.BorderContainer" liveSplitters="false" region="center">
+			<div id="centerSplit" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, region:"center"'>
 				<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
-				<div dojoType="dijit.layout.TabContainer" region="top" id="topTabs1" tabStrip="true" splitter="true" style="height:200px;">
+				<div id="topTabs1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='region:"top", tabStrip:true, splitter:true, style:"height:200px;"'>
 
-					<div dojoType="dijit.layout.ContentPane"
-						id="basdicFormTab"
-						title="Basic Form Widgets"
-						layoutType="fit"
-						style="padding:10px;display:none;">
+					<div id="basdicFormTab" data-dojo-type="dijit.layout.ContentPane"
+						data-dojo-props='title:"Basic Form Widgets",
+						style:"padding:10px;display:none;"'>
 						Hi friends of dijit
 					</div> <!-- end of basic form widgets -->
-					<div dojoType="dijit.layout.AccordionContainer"
-						id="tabAccordion"
-						title="Accordion in Tab"
-						layoutType="tab"
-						minSize="20"
-						style="width: 100%;">
-
-						<div dojoType="dijit.layout.ContentPane" title="Popups and Alerts">
+					<div id="tabAccordion" data-dojo-type="dijit.layout.AccordionContainer"
+						data-dojo-props='title:"Accordion in Tab",
+						minSize:20,
+						style:"width: 100%;"'>
+
+						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'>
 						</div>
 
-						<div dojoType="dijit.layout.ContentPane" title="Dojo Tree from Store">
+						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Dojo Tree from Store"'>
 						</div>
 
-						<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true">
+						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Calendar", selected:true'>
 						</div>
 
-						<div dojoType="dijit.layout.ContentPane" title="Color Picker">
+						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
 						</div>
 
 					</div><!-- end AccordionContainer -->
 
-					<div dojoType="dijit.layout.ContentPane"
-						id="textareaTab"
-						layoutType="tab"
-						title="Accordion in Content Tab">
+					<div id="textareaTab" data-dojo-type="dijit.layout.ContentPane"
+						data-dojo-props='
+						title:"Accordion in Content Tab"'>
 
-						<div dojoType="dijit.layout.AccordionContainer"
-							minSize="20" layoutType="default" style="width: 100%;" id="tabAccordionContainer">
+						<div id="tabAccordionContainer" data-dojo-type="dijit.layout.AccordionContainer"
+							data-dojo-props='minSize:20, style:"width: 100%;" '>
 
-							<div dojoType="dijit.layout.ContentPane" title="Popups and Alerts">
+							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'>
 							</div>
 
-							<div dojoType="dijit.layout.ContentPane" title="Tabs in Accordion">
+							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tabs in Accordion"'>
 								<!-- bottom right tabs -->
-								<div dojoType="dijit.layout.BorderContainer" liveSplitters="false" design="sidebar"
-									id="mainSplit1" style="padding: 0px;width: 300px; height: 100px">
+								<div id="mainSplit1" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, design:"sidebar",
+									style:"padding: 0px;width: 300px; height: 100px"'>
 
-									<div dojoType="dijit.layout.TabContainer" id="accTabs"
-										tabPosition="top" region="center" selectedChild="bbtab1">
+									<div id="accTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", region:"center"'>
 
 										<!-- btab 1 -->
-										<div dojoType="dijit.layout.ContentPane" id="bbtab1"
-											layoutType="tab" title="Info" style=" padding:10px;">
+										<div id="bbtab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:" padding:10px;"'>
 										</div><!-- end:info btab1 -->
 
-										<div dojoType="dijit.layout.ContentPane" id="bbtab2"
-											layoutType="tab" title="Alternate Themes" style="padding:20px;">
+										<div id="bbtab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 										</div><!-- btab2 -->
 
-										<div dojoType="dijit.layout.ContentPane" id="bbtab3"
-											layoutType="tab" title="Bottom 3" closable="true">
+										<div id="bbtab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 										</div><!-- btab3 -->
 
 									</div><!-- end Bottom TabContainer -->
 								</div>
 							</div>
 
-							<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true">
+							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Calendar", selected:true'>
 							</div>
 
-							<div dojoType="dijit.layout.ContentPane" title="Color Picker">
+							<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
 							</div>
 
 						</div><!-- end AccordionContainer -->
@@ -161,113 +152,111 @@
 					</div><!-- end of Textarea/Editor tab -->
 
 
-					<div dojoType="dijit.layout.ContentPane"
-						title="Title Pane in Content Pane"
-						layoutType="tab"
-						doLayout="false"
-						style="display:none;">
+					<div id="titlePaneCP" data-dojo-type="dijit.layout.ContentPane"
+						data-dojo-props='title:"Title Pane in Content Pane",
+						doLayout:false,
+						style:"display:none;"'>
 
 						Here's some text, then a TitlePane:
-						<div dojoType="dijit.TitlePane" title="Color Picker">
+						<div id="tp" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Color Picker"'>
 							Hi friends of dijit
 						</div>
 						... and some more text.
 					</div>
 
-					<div dojoType="dijit.layout.TabContainer" title="TabContainer in Tab" nested="true" closable="true">
-						<div id="basicFormTab1" dojoType="dijit.layout.ContentPane"
-							layoutType="fit" title="Basic Form Widgets 1"
-							style="padding:10px; display:none;">
+					<div id="tabContainerInTabCP" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"TabContainer in Tab", nested:true, closable:true'>
+						<div id="basicFormTab1" data-dojo-type="dijit.layout.ContentPane"
+							data-dojo-props='title:"Basic Form Widgets 1",
+							style:"padding:10px; display:none;"'>
 						    Hi friends of dijit
 						</div>
-						<div id="basicFormTab2" dojoType="dijit.layout.ContentPane"
-							layoutType="fit" title="Basic Form Widgets 2"
-							style="padding:10px; display:none;">
-						    Hi friends of dijit
+						<div id="basicFormTab2" data-dojo-type="dijit.layout.ContentPane"
+							data-dojo-props='title:"Basic Form Widgets 2",
+							style:"padding:10px; display:none;"'>
+						    Tab 2 content
 						</div>
 					</div>
 
-					<div id="closableTab" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Closable ContentPane w/TabContainer"
-						style="display:none; padding:0px;" closable="true">
+					<div id="closableTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Closable ContentPane w/TabContainer",
+						style:"display:none; padding:0px;", closable:true'>
 
-						<div dojoType="dijit.layout.TabContainer" title="Tab in Tab" nested="true">
+						<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab in Tab", nested:true'>
 
-							<div id="basicFormTab3" dojoType="dijit.layout.ContentPane" layoutType="fit" title="Basic Form Widgets 3" style="padding:10px;display:none;">
+							<div id="basicFormTab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Basic Form Widgets 3", style:"padding:10px;display:none;"'>
 							    Hi friends of dijit
 							</div>
-							<div id="basicFormTab4" dojoType="dijit.layout.ContentPane" layoutType="fit" title="Basic Form Widgets 4" style="padding:10px;display:none;">
+							<div id="basicFormTab4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Basic Form Widgets 4", style:"padding:10px;display:none;"'>
 							    Hi friends of dijit
 							</div>
 						</div>
 					</div>
 				</div><!-- end of region="center" TabContainer -->
-				<div dojoType="dijit.layout.BorderContainer" liveSplitters="false" region="center">
-					<div dojoType="dijit.layout.TabContainer" id="bottomTabs1" tabStrip="true"
-						tabPosition="left-h" selectedChild="btabA" region="top" style="height: 50%;" splitter="true">
+				<div id="embeddedBC" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='liveSplitters:false, region:"center"'>
+					<div id="bottomTabs1" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true,
+						tabPosition:"left-h", region:"top", style:"height: 50%;", splitter:true'>
 
 						<!-- btab 1 -->
-						<div id="btabA" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Info" style="padding:10px;">
+						<div id="btabA" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>
 
 						</div><!-- end:info btabA -->
 
-						<div id="btabB" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Alternate Themes" style="padding:20px;">
+						<div id="btabB" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 
 						</div><!-- btabB -->
 
-						<div id="btabC" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Bottom 3" closable="true">
+						<div id="btabC" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 
 						</div><!-- btabC -->
 
 					</div><!-- end Bottom TabContainer -->
-					<div dojoType="dijit.layout.TabContainer" id="bottomTabs2" tabStrip="true"
-						tabPosition="right-h" selectedChild="btabD" region="center">
+					<div id="bottomTabs2" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true,
+						tabPosition:"right-h", region:"center"'>
 
 						<!-- btab 1 -->
-						<div id="btabD" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Info" style="padding:10px;">
+						<div id="btabD" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>
 
 						</div><!-- end:info btabD -->
 
-						<div id="btabE" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Alternate Themes" style="padding:20px;">
+						<div id="btabE" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 
 						</div><!-- btabE -->
 
-						<div id="btabF" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Bottom 3" closable="true">
+						<div id="btabF" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 
 						</div><!-- btabF -->
 
 					</div><!-- end Bottom TabContainer -->
 				</div>
 				<!-- bottom right tabs -->
-				<div dojoType="dijit.layout.TabContainer" id="bottomTabs" tabStrip="true"
-					tabPosition="bottom" selectedChild="btab1" region="bottom" splitter="true">
+				<div id="bottomTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true,
+					tabPosition:"bottom", region:"bottom", splitter:true'>
 
 					<!-- btab 1 -->
-					<div dojoType="dijit.layout.BorderContainer" liveSplitters="false" design="sidebar"
-						region="center" id="bottomSplit" title="BorderContainer in Tabs" style="padding: 5px; width: 100%">
-						<div dojoType="dijit.layout.ContentPane" region="top" splitter="true" liveSplitters="false">This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
-						<div dojoType="dijit.layout.TabContainer" id="bottomTabs22"
-							tabPosition="top" selectedChild="btabAA" region="center" splitter="true">
+					<div id="bottomSplit" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='selected:true, liveSplitters:false, design:"sidebar",
+						region:"center", title:"BorderContainer in Tabs", style:"padding: 5px; width: 100%"'>
+						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"top", splitter:true'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
+						<div id="bottomTabs22" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", region:"center", splitter:true'>
 
 							<!-- btab 1 -->
-							<div id="btabAA" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Info" style="padding:10px;">Hi</div>
+							<div id="btabAA" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Info", style:"padding:10px;"'>Hi</div>
 						</div>
 
-						<div dojoType="dijit.layout.ContentPane" region="bottom" splitter="true" liveSplitters="false">This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
+						<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"bottom", splitter:true'>This test is to make sure nested layout elements work fine in regards to double borders etc. You need a screen with a very high resolution to not get cramped tabs and other weird visual effects </div>
 
 					</div>
 
-					<div id="btab2" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Alternate Themes" style="padding:20px;">
+					<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 
 					</div><!-- btab2 -->
 
-					<div id="btab3" dojoType="dijit.layout.ContentPane" layoutType="tab" title="Bottom 3" closable="true">
+					<div id="btab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 
 					</div><!-- btab3 -->
 
 				</div><!-- end Bottom TabContainer -->
 			</div>
 		</div> <!-- end of "mainSplit" BorderContainer -->
-		<div dojoType="dijit.layout.ContentPane" region="trailing" splitter="true" style="width: 10%;" liveSplitters="false">Hi </div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"trailing", splitter:true, style:"width: 10%;"'>Hi </div>
 
 	</div><!-- end of "main" BorderContainer -->
 
diff --git a/dijit/tests/layout/test_LayoutContainer.html b/dijit/tests/layout/test_LayoutContainer.html
deleted file mode 100644
index 9f642fc..0000000
--- a/dijit/tests/layout/test_LayoutContainer.html
+++ /dev/null
@@ -1,183 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>dijit.layout.LayoutContainer Test</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../../themes/tundra/tundra.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, 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.LayoutContainer");
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.form.FilteringSelect");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-
-</head>
-<body class="claro">
-	<h2>Dijit layout.LayoutContainer tests</h2>
-
-	<p>Basic layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
-	should be:  left, right, top, middle/main, bottom</p>
-
-	<div dojoType="dijit.layout.LayoutContainer"
-		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
-	>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #acb386; width: 100px;" tabindex="0">
-			left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #acb386;"  tabindex="0">
-			right
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #b39b86; "  tabindex="0">
-			top bar
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px;"  tabindex="0">
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
-				<option value="1">foo</option>
-				<option value="2">bar</option>
-				<option value="3">baz</option>
-			</select>
-			Here's some text that comes AFTER the combo box.
-		</div>
-
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #b39b86;"  tabindex="0">
-			bottom bar
-		</div>
-
-	</div>
-
-	<p>Advanced layout. Tabindex="0" added to each pane to test for tab order matching source code order.  Tab order
-	should be:  left, top, bottom, inner left, inner middle, inner right. This is not an ideal tab order. See below to use nested
-	layout containers to achieve a tab order which matches presentation and source code order.</p>
-	<div dojoType="dijit.layout.LayoutContainer"
-		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
-	>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
-			left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
-			top bar
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0">
-
-			bottom bar
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
-			inner left
-		</div>
-
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-
-			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
-				<option value="1">foo</option>
-				<option value="2">bar</option>
-				<option value="3">baz</option>
-			</select>
-			Here's some text that comes AFTER the combo box.
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
-			inner right
-		</div>
-	</div>
-
-	<p>Advanced layout with nested containers.  Tabindex="0" added to content panes to show tab order. Order should be:
-	left, top, inner left, inner middle, inner right, bottom. This is the preferred tab order for this type of layout.</p>
-	<div dojoType="dijit.layout.LayoutContainer"
-		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
-	>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #acb386; width: 100px; margin: 5px;" tabindex="0">
-			left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="margin: 5px;" >
-			<div dojoType="dijit.layout.LayoutContainer"	style="height:90%;border: 2px solid black;padding: 10px;">
-
-				<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #b39b86;  margin: 5px;" tabindex="0">
-					top bar
-				</div>
-				<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="margin: 5px;">
-					<div dojoType="dijit.layout.LayoutContainer"	style="height:80%;border: 2px solid black;padding: 10px;">
-						<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
-							inner left
-						</div>
-						<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="background-color: #f5ffbf; padding: 10px; margin: 5px;" tabindex="0">
-							main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-							(to check we're copying children around properly).<br />
-							<select dojoType="dijit.form.FilteringSelect">
-								<option value="1">foo</option>
-								<option value="2">bar</option>
-								<option value="3">baz</option>
-							</select>
-							Here's some text that comes AFTER the combo box.
-						</div>
-						<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #eeeeee; width: 100px; margin: 5px;" tabindex="0">
-							inner right
-						</div>
-					</div>
-				</div>
-				<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #b39b86; margin: 5px;" tabindex="0"	>
-					bottom bar
-				</div>
-			</div>
-		</div>
-	</div>
-
-	<p>Goofy spiral layout.  Match of source code order to tab order can not be achieved with this type of layout.</p>
-	<div dojoType="dijit.layout.LayoutContainer"
-		style="border: 2px solid black; width: 90%; height: 300px; padding: 10px;"
-	>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #663333; color: white; width: 100px;">
-			outer left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #333366; color: white; height: 50px;">
-			outer top
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #663333; color: white; width: 100px;">
-			outer right
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #333366; color: white; height: 50px;">
-			outer bottom
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="left" style="background-color: #99CC99; width: 100px;">
-			inner left
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="top" style="background-color: #999966; height: 50px;">
-			inner top
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="right" style="background-color: #99CC99; width: 100px;">
-			inner right
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="bottom" style="background-color: #999966; height: 50px;">
-			inner bottom
-		</div>
-		<div dojoType="dijit.layout.ContentPane" layoutAlign="client" style="padding: 10px;">
-			main panel with <a href="http://www.dojotoolkit.org/">a link</a>.<br />
-			(to check we're copying children around properly).<br />
-			<select dojoType="dijit.form.FilteringSelect">
-				<option value="1">foo</option>
-				<option value="2">bar</option>
-				<option value="3">baz</option>
-			</select>
-			Here's some text that comes AFTER the combo box.
-		</div>
-	</div>
-
-</body>
-</html>
diff --git a/dijit/tests/layout/test_SplitContainer.html b/dijit/tests/layout/test_SplitContainer.html
index 1089290..2070780 100644
--- a/dijit/tests/layout/test_SplitContainer.html
+++ b/dijit/tests/layout/test_SplitContainer.html
@@ -5,7 +5,7 @@
 	<title>SplitContainer Widget Demo</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 		.dojoContentPane {
 			padding:1em;
@@ -13,7 +13,7 @@
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
diff --git a/dijit/tests/layout/test_StackContainer.html b/dijit/tests/layout/test_StackContainer.html
index f41d579..87b4e5b 100644
--- a/dijit/tests/layout/test_StackContainer.html
+++ b/dijit/tests/layout/test_StackContainer.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>StackContainer Demo</title>
 
 	<style>
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 		.dijitStackController .dijitToggleButtonChecked button {
 			background-color: white;
@@ -17,11 +17,11 @@
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -36,6 +36,33 @@
 		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");
@@ -51,47 +78,43 @@
 <body class="claro">
 	<h1 class="testTitle">A Tale Of Two Cities</h1>
 
-	<button dojoType="dijit.form.Button" id="previous"
-		onClick="dijit.byId('myStackContainer').back()"><</button>
-	<span dojoType="dijit.layout.StackController" containerId="myStackContainer"></span>
-	<button dojoType="dijit.form.Button" id="next"
-		onClick="dijit.byId('myStackContainer').forward()">></button>
-
-	<div id="myStackContainer" dojoType="dijit.layout.StackContainer"
-		style="width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;">
-		<p id="page1" dojoType="dijit.layout.ContentPane" 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 were all going direct the  [...]
-		<p id="page2" dojoType="dijit.layout.ContentPane" 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" dojoType="dijit.layout.ContentPane" 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 Westminster. Even the Cock- [...]
+	<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 dojoType="dijit.form.Button" id="previous2" onClick="dijit.byId('myStackContainer').back()"><</button>
-	<span dojoType="dijit.layout.StackController" containerId="myStackContainer"></span>
-	<button dojoType="dijit.form.Button" id="next2" onClick="dijit.byId('myStackContainer').forward()">></button>
+	<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 dojoType="dijit.form.Button" id="previousPR"
-		onClick="dijit.byId('myStackContainerPR').back()"><</button>
-	<span dojoType="dijit.layout.StackController" containerId="myStackContainerPR"></span>
-	<button dojoType="dijit.form.Button" id="nextPR"
-		onClick="dijit.byId('myStackContainerPR').forward()">></button>
+	<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" dojoType="dijit.layout.StackContainer"
-		style="width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;">
-		<div id="page1PR" dojoType="dijit.layout.ContentPane" title="page 1">
+	<div id="myStackContainerPR" data-dojo-type="dijit.layout.StackContainer"
+		data-dojo-props='style:"width: 90%; border: 1px solid #9b9b9b; height: 20em; margin: 0.5em 0 0.5em 0; padding: 0.5em;"'>
+		<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" dojoType="dijit.layout.ContentPane" title="page 2" style="padding: 1em;">
+		<div id="page2PR" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"page 2", style:"padding: 1em;"'>
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -106,7 +129,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -125,8 +148,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<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
@@ -141,7 +164,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -163,9 +186,15 @@
 		</div>
 	</div>
 
-	<button dojoType="dijit.form.Button" id="previous2PR" onClick="dijit.byId('myStackContainerPR').back()"><</button>
-	<span dojoType="dijit.layout.StackController" containerId="myStackContainerPR"></span>
-	<button dojoType="dijit.form.Button" id="next2PR" onClick="dijit.byId('myStackContainerPR').forward()">></button>
+	<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_StackContainer_code.html b/dijit/tests/layout/test_StackContainer_code.html
deleted file mode 100644
index cdc1583..0000000
--- a/dijit/tests/layout/test_StackContainer_code.html
+++ /dev/null
@@ -1,72 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>StackContainer Demo</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.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"
-		djConfig="isDebug: true"></script>
-
-	<!-- only needed for alternate theme testing: do NOT use in your code! -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript">
-		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.form.Button");
-
-		dojo.addOnLoad(function(){
-			// make the container
-			var container = new dijit.layout.StackContainer({ id: "sc" },"myStackContainer");
-			container.addChild(new dijit.layout.ContentPane({
-					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({
-					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({
-					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();
-		});
-	</script>
-</head>
-
-<body class="claro">
-	<h1 class="testTitle">A Tale Of Two Cities</h1>
-
-	Links: <span id="holder"></span>
-
-	<div id="myStackContainer" 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 e2816ae..851d48b 100644
--- a/dijit/tests/layout/test_TabContainer.html
+++ b/dijit/tests/layout/test_TabContainer.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TabContainer Demo</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		body {
@@ -21,11 +21,11 @@
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -85,23 +85,23 @@
 
 	<br><br>
 
-	<div id="mainTabContainer" dojoType="dijit.layout.TabContainer"
-				persist="false" tabStrip="true" style="width: 400px;height: 20em;">
+	<div id="mainTabContainer" data-dojo-type="dijit.layout.TabContainer"
+				data-dojo-props='persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
 
-		<div id="tab1" dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1" iconClass="plusIcon"
-			tooltip="Tooltip for tab #1"></div>
+		<div id="tab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1", iconClass:"plusIcon",
+			tooltip:"Tooltip for tab #1"'></div>
 
-		<div id="tab2" dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" iconClass="noteIcon" selected="true"></div>
+		<div id="tab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", iconClass:"noteIcon", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane" id="tab3" title="Tab 3"
-				iconClass="dijitEditorIcon dijitEditorIconSave" closable="true">
+		<div id="tab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3",
+				iconClass:"dijitEditorIcon dijitEditorIconSave", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p id="foo">tooltip on this paragraph</p>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit.form.Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -125,23 +125,23 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer" id="inlined" title="Inlined Sub TabContainer" iconClass="plusIcon" nested="true">
-			<a dojoType="dijit.layout.LinkPane" id="tab1href" href="tab1.html" onLoad="console.log('load of SubTab 1');" iconClass="plusIcon" >SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane" id="tab2href" href="tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true"  iconClass="dijitEditorIcon dijitEditorIconSave">SubTab 2</a>
-			<div dojoType="dijit.layout.ContentPane" id="subtab3" title="SubTab 3"  iconClass="dijitEditorIcon dijitEditorIconCut">
+		<div id="inlined" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Inlined Sub TabContainer", iconClass:"plusIcon", nested:true'>
+			<a id="tab1href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }, iconClass:"plusIcon" '>SubTab 1</a>
+			<a id="tab2href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true,  iconClass:"dijitEditorIcon dijitEditorIconSave"'>SubTab 2</a>
+			<div id="subtab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"SubTab 3",  iconClass:"dijitEditorIcon dijitEditorIconCut"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" id="subtab4" title="SubTab 4" iconClass="dijitEditorIcon dijitEditorIconCopy">
+			<div id="subtab4" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"SubTab 4", iconClass:"dijitEditorIcon dijitEditorIconCopy"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane" id="tab3href" href="tab3.html" refreshOnShow="true" closable="true"
-				style="padding: 0" iconClass="dijitEditorIcon dijitEditorIconSave">Sub TabContainer from href</a>
-		<a dojoType="dijit.layout.LinkPane" id="tab4href" href="tab4.html"
-				closable="true" iconClass="dijitEditorIcon dijitEditorIconCut">SplitContainer from href</a>
-		<div dojoType="dijit.layout.ContentPane" id="embedded" title="Embedded layout widgets"
-				closable="true" iconClass="dijitEditorIcon dijitEditorIconCopy">
+		<a id="tab3href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab3.html", refreshOnShow:true, closable:true,
+				style:"padding: 0", iconClass:"dijitEditorIcon dijitEditorIconSave"'>Sub TabContainer from href</a>
+		<a id="tab4href" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab4.html",
+				closable:true, iconClass:"dijitEditorIcon dijitEditorIconCut"'>SplitContainer from href</a>
+		<div id="embedded" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Embedded layout widgets",
+				closable:true, iconClass:"dijitEditorIcon dijitEditorIconCopy"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -149,8 +149,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" id="bc" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div id="bc" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -165,7 +165,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -184,8 +184,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer" id="embeddedTC" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" id="embeddedTab1" title="Tab 1">
+			<div id="embeddedTC" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div id="embeddedTab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -200,7 +200,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" id="embeddedTab2" title="Tab 2">
+				<div id="embeddedTab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -230,21 +230,21 @@
 		This tab container has the Menu function for selecting tabs disabled, using <b>useMenu="false"</b>
 	</p>
 
-	<div dojoType="dijit.layout.TabContainer" useMenu="false"
-				persist="false" tabStrip="true" style="width: 400px;height: 20em;">
-		<div  dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
+	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='useMenu:false,
+				persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
 
-		<div  dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane"  title="Tab 3" closable="true">
+		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
-			<p id="foo">tooltip on this paragraph</p>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<p id="foo2">tooltip on this paragraph</p>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo2"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit.form.Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -268,22 +268,22 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer"  closable="true" title="Inlined Sub TabContainer" nested="true">
-			<a dojoType="dijit.layout.LinkPane"  href="tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane"  href="tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 3">
+		<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 4">
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane"  href="tab3.html" closable="true" refreshOnShow="true" style="padding: 0">Sub TabContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
 
-		<a dojoType="dijit.layout.LinkPane"  closable="true" href="tab4.html">SplitContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
 
-		<div dojoType="dijit.layout.ContentPane"  closable="true" title="Embedded layout widgets">
+		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -291,8 +291,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -307,7 +307,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -326,8 +326,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer"  style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -342,7 +342,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -368,31 +368,31 @@
 	<br/>
 
 	<p>Tabs w/only icons (except in high-contrast mode where labels display):</p>
-	<div id="iconTabs" dojoType="dijit.layout.TabContainer" tabPosition="top" style="width: 100%; height: 10em;">
-		<div id="iconTab1" dojoType="dijit.layout.ContentPane" title="Cut" tooltip="tooltip for cut button" showTitle="false" iconClass="dijitEditorIcon dijitEditorIconCut">Cut icon tab</div>
-		<div id="iconTab2" dojoType="dijit.layout.ContentPane" title="Copy" showTitle="false" iconClass="dijitEditorIcon dijitEditorIconCopy">Copy icon tab</div>
-		<div id="iconTab3" dojoType="dijit.layout.ContentPane" title="Paste" showTitle="false" iconClass="dijitEditorIcon dijitEditorIconPaste">Paste icon tab</div>
+	<div id="iconTabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 10em;"'>
+		<div id="iconTab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Cut", tooltip:"tooltip for cut button", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconCut"'>Cut icon tab</div>
+		<div id="iconTab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Copy", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconCopy"'>Copy icon tab</div>
+		<div id="iconTab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Paste", showTitle:false, iconClass:"dijitEditorIcon dijitEditorIconPaste"'>Paste icon tab</div>
 	</div>
 
 
 	<p>
 		This tab container has the Slider function for selecting tabs disabled, using <b>useSlider="false"</b>
 	</p>
-	<div dojoType="dijit.layout.TabContainer" useSlider="false"
-				persist="false" tabStrip="true" style="width: 400px;height: 20em;">
+	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='useSlider:false,
+				persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
 
-		<div  dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div  dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane"  title="Tab 3" closable="true">
+		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
-			<p id="foo">tooltip on this paragraph</p>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<p id="foo3">tooltip on this paragraph</p>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo3"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit.form.Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -416,22 +416,22 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer"  closable="true" title="Inlined Sub TabContainer" nested="true">
-			<a dojoType="dijit.layout.LinkPane"  href="tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane"  href="tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 3">
+		<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 4">
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane"  href="tab3.html" closable="true" refreshOnShow="true" style="padding: 0">Sub TabContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
 
-		<a dojoType="dijit.layout.LinkPane"  closable="true" href="tab4.html">SplitContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
 
-		<div dojoType="dijit.layout.ContentPane"  closable="true" title="Embedded layout widgets">
+		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -439,8 +439,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -455,7 +455,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -474,8 +474,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer"  style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -490,7 +490,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -515,21 +515,21 @@
 	<p>
 		This tab container has the tab strip disabled, using <b>tabStrip="false"</b>
 	</p>
-	<div dojoType="dijit.layout.TabContainer" tabStrip="false"
-				persist="false" tabStrip="true" style="width: 400px;height: 20em;">
+	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:false,
+				persist:false, tabStrip:true, style:"width: 400px;height: 20em;"'>
 
-		<div  dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div  dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane"  title="Tab 3" closable="true">
+		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"Tab 3", closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
-			<p id="foo">tooltip on this paragraph</p>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<p id="foo4">tooltip on this paragraph</p>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo4"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit.form.Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -553,22 +553,22 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer"  closable="true" title="Inlined Sub TabContainer" nested="true">
-			<a dojoType="dijit.layout.LinkPane"  href="tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane"  href="tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 3">
+		<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 4">
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane"  href="tab3.html" closable="true" refreshOnShow="true" style="padding: 0">Sub TabContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab3.html", closable:true, refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
 
-		<a dojoType="dijit.layout.LinkPane"  closable="true" href="tab4.html">SplitContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
 
-		<div dojoType="dijit.layout.ContentPane"  closable="true" title="Embedded layout widgets">
+		<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -576,8 +576,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -592,7 +592,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -611,8 +611,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer"  style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer"  data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -627,7 +627,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -655,21 +655,21 @@
 	and the tabPosition is "bottom"
 	</p>
 
-	<div id="mainTabContainerBottom" dojoType="dijit.layout.TabContainer" tabPosition="bottom"
-				persist="true" tabStrip="true" style="width: 400px; height: 20em;">
+	<div id="mainTabContainerBottom" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"bottom",
+				persist:true, tabStrip:true, style:"width: 400px; height: 20em;"'>
 
-		<div dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane" closable="true" title="Tab 3">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Tab 3"'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
-			<p id="foo">tooltip on this paragraph</p>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<p id="foo5">tooltip on this paragraph</p>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo5"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit.form.Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -693,22 +693,22 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer" closable="true" title="Inlined Sub TabContainer" nested="true">
-			<a dojoType="dijit.layout.LinkPane"  href="tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane"  href="tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 3">
+		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 4">
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane" closable="true" href="tab3.html" refreshOnShow="true" style="padding: 0">Sub TabContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab3.html", refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
 
-		<a dojoType="dijit.layout.LinkPane" closable="true" href="tab4.html">SplitContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
 
-		<div dojoType="dijit.layout.ContentPane" closable="true" title="Embedded layout widgets">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -716,8 +716,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -732,7 +732,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -751,8 +751,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -767,7 +767,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -793,21 +793,21 @@
 		This tab container has its tabs at the bottom, and the tab strip disabled
 	</p>
 
-	<div dojoType="dijit.layout.TabContainer" tabPosition="bottom"
-				persist="true" tabStrip="false" style="width: 400px; height: 20em;">
+	<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"bottom",
+				persist:true, tabStrip:false, style:"width: 400px; height: 20em;"'>
 
-		<div dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane" closable="true" title="Tab 3">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Tab 3"'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
-			<p id="foo">tooltip on this paragraph</p>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<p id="foo6">tooltip on this paragraph</p>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo6"]'>I'm a tooltip!</div>
+			<button data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
+			<button data-dojo-type="dijit.form.Button">So am I!</button>
 			<p>
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
@@ -831,22 +831,22 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer" closable="true" title="Inlined Sub TabContainer" nested="true">
-			<a dojoType="dijit.layout.LinkPane"  href="tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane"  href="tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 3">
+		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='closable:true, title:"Inlined Sub TabContainer", nested:true'>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane"  data-dojo-props='href:"tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 3"'>
 				<h1>I am tab 3, inlined.</h1>
 			</div>
-			<div dojoType="dijit.layout.ContentPane"  title="SubTab 4">
+			<div data-dojo-type="dijit.layout.ContentPane"  data-dojo-props='title:"SubTab 4"'>
 				<h1>I am tab 4, inlined.</h1>
 			</div>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane" closable="true" href="tab3.html" refreshOnShow="true" style="padding: 0">Sub TabContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab3.html", refreshOnShow:true, style:"padding: 0"'>Sub TabContainer from href</a>
 
-		<a dojoType="dijit.layout.LinkPane" closable="true" href="tab4.html">SplitContainer from href</a>
+		<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='closable:true, href:"tab4.html"'>SplitContainer from href</a>
 
-		<div dojoType="dijit.layout.ContentPane" closable="true" title="Embedded layout widgets">
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='closable:true, title:"Embedded layout widgets"'>
 			<p>
 				The tab has some text, plus two embedded layout widgets, which should
 				appear correctly even though the tab is initially hidden.
@@ -854,8 +854,8 @@
 			<p>
 				Here's a BorderContainer:
 			</p>
-			<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+			<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -870,7 +870,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" region="center">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -889,8 +889,8 @@
 			<p>
 				And a TabContainer:
 			</p>
-			<div dojoType="dijit.layout.TabContainer" style="height:200px; width:300px">
-				<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 					1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -905,7 +905,7 @@
 					sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 					ut eros sit amet ante pharetra interdum.
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 					2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 					Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 					vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -932,13 +932,13 @@
 		Tab 1 and Tab 3 can be closed; Tab 3 has a confirm box.
 	</p>
 
-	<div id="ttabs" dojoType="dijit.layout.TabContainer" tabPosition="top" style="width: 100%; height: 10em;"
-		onfocus="console.log('user focus handler')"
-		onblur="console.log('user blur handler')"
-	>
-		<div id="ttab1" dojoType="dijit.layout.ContentPane" href="tab1.html" title="First" closable="true"></div>
-		<div id="ttab2" dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Second"></div>
-		<div dojoType="dijit.layout.ContentPane" title="Third" onClose="testClose" closable="true">
+	<div id="ttabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"top", style:"width: 100%; height: 10em;",
+		onFocus:function(){ console.log("user focus handler") },
+		onBlur:function(){ console.log("user blur handler") }
+	'>
+		<div id="ttab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"First", closable:true'></div>
+		<div id="ttab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Second"'></div>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Third", onClose:testClose, closable:true'>
 			<h1>I am tab 3</h1>
 			<p>And I was already part of the page! That's cool, no?</p>
 			<p>If you try to close me there should be a confirm dialog.</p>
@@ -947,28 +947,28 @@
 
 	<p>Tabs with titles on the bottom:</p>
 
-	<div id="btabs" dojoType="dijit.layout.TabContainer" tabPosition="bottom" style="width: 100%; height: 10em;">
-		<div id="btab1" dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1" closable="true"></div>
-		<div id="btab2" dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" onLoad="console.debug('Tab2 onLoad');" title="Tab 2"></div>
+	<div id="btabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabPosition:"bottom", style:"width: 100%; height: 10em;"'>
+		<div id="btab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1", closable:true'></div>
+		<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, onLoad:function(){ console.debug("Tab2 onLoad"); }, title:"Tab 2"'></div>
 	</div>
 
 	<p>Tabs with titles on the left and tabStrip="false":</p>
 
-	<div id="ltabs" dojoType="dijit.layout.TabContainer" style="width:500px;height:100px" tabStrip="false" tabPosition="left-h">
-		<div id="LittleRed1" dojoType="dijit.layout.ContentPane" title="Little Red Cap">
+	<div id="ltabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width:500px;height:100px", tabStrip:false, tabPosition:"left-h"'>
+		<div id="LittleRed1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div id="HanselGretel1" dojoType="dijit.layout.ContentPane"
-		     title="Hansel and Gretel" closable="true" selected="true">
+		<div id="HanselGretel1" data-dojo-type="dijit.layout.ContentPane"
+		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div id="GreenTwigs1" dojoType="dijit.layout.ContentPane"
-		 title="The Three Green Twigs">
+		<div id="GreenTwigs1" data-dojo-type="dijit.layout.ContentPane"
+		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
 			and every evening he carried, to the glory of God, two pails of water
@@ -978,21 +978,21 @@
 
 	<p>Tabs with titles on the left and tabStrip=true:</p>
 
-	<div id="ltabsStrip" dojoType="dijit.layout.TabContainer" style="width:500px;height:100px" tabStrip="true" tabPosition="left-h">
-		<div dojoType="dijit.layout.ContentPane" title="Little Red Cap">
+	<div id="ltabsStrip" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width:500px;height:100px", tabStrip:true, tabPosition:"left-h"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div dojoType="dijit.layout.ContentPane"
-		     title="Hansel and Gretel" closable="true" selected="true">
+		<div data-dojo-type="dijit.layout.ContentPane"
+		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div dojoType="dijit.layout.ContentPane"
-		 title="The Three Green Twigs">
+		<div data-dojo-type="dijit.layout.ContentPane"
+		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
 			and every evening he carried, to the glory of God, two pails of water
@@ -1002,21 +1002,21 @@
 
 	<p>Tabs with titles on the right and tabStrip=true:</p>
 
-	<div id="rtabsStrip" dojoType="dijit.layout.TabContainer" tabStrip="true" style="width:500px;height:100px" tabPosition="right-h">
-		<div id="LittleRed2" dojoType="dijit.layout.ContentPane" title="Little Red Cap">
+	<div id="rtabsStrip" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:true, style:"width:500px;height:100px", tabPosition:"right-h"'>
+		<div id="LittleRed2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div id="HanselGretel2" dojoType="dijit.layout.ContentPane"
-		     title="Hansel and Gretel" closable="true" selected="true">
+		<div id="HanselGretel2" data-dojo-type="dijit.layout.ContentPane"
+		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div id="GreenTwigs2" dojoType="dijit.layout.ContentPane"
-		 title="The Three Green Twigs">
+		<div id="GreenTwigs2" data-dojo-type="dijit.layout.ContentPane"
+		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
 			and every evening he carried, to the glory of God, two pails of water
@@ -1026,21 +1026,21 @@
 
 	<p>Tabs with titles on the right and tabStrip=false:</p>
 
-	<div id="rtabs" dojoType="dijit.layout.TabContainer" tabStrip="false" style="width:500px;height:100px" tabPosition="right-h">
-		<div dojoType="dijit.layout.ContentPane" title="Little Red Cap">
+	<div id="rtabs" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='tabStrip:false, style:"width:500px;height:100px", tabPosition:"right-h"'>
+		<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Little Red Cap"'>
 			Once upon a time there was a dear little girl who was loved by
 			every one who looked at her, but most of all by her grandmother,
 			and there was nothing that she would not have given to the child.
 		</div>
-		<div dojoType="dijit.layout.ContentPane"
-		     title="Hansel and Gretel" closable="true" selected="true">
+		<div data-dojo-type="dijit.layout.ContentPane"
+		     data-dojo-props='title:"Hansel and Gretel", closable:true, selected:true'>
 			Hard by a great forest dwelt a poor wood-cutter with his wife
 			and his two children. The boy was called Hansel and the girl Gretel.
 			He had little to bite and to break, and once when great dearth fell
 			on the land, he could no longer procure even daily bread.
 		</div>
-		<div dojoType="dijit.layout.ContentPane"
-		 title="The Three Green Twigs">
+		<div data-dojo-type="dijit.layout.ContentPane"
+		 data-dojo-props='title:"The Three Green Twigs"'>
 			There was once upon a time a hermit who lived in a forest at the foot
 			of a mountain, and passed his time in prayer and good works,
 			and every evening he carried, to the glory of God, two pails of water
@@ -1049,7 +1049,7 @@
 	</div>
 
 	<h3>Typical rendering time</h3>
-	<table border=1>
+	<table style="border:1px solid black;">
 	  <tr><th>IE</th><th>Firefox (mac)</th></tr>
 	  <tr><td>1719</td><td>922</td></tr>
 	</table>
diff --git a/dijit/tests/layout/test_TabContainerTitlePane.html b/dijit/tests/layout/test_TabContainerTitlePane.html
deleted file mode 100644
index 175cb7f..0000000
--- a/dijit/tests/layout/test_TabContainerTitlePane.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>TabContainer Nested TitlePane Test</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-
-		body {
-			font-family : sans-serif;
-			margin:20px;
-		}
-
-		/* add padding to each contentpane inside the tab container, and scrollbar if necessary */
-		.dojoTabPane {
-			padding : 10px 10px 10px 10px;
-			overflow: auto;
-		}
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		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">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.TitlePane");
-
-		startTime = new Date();
-		dojo.addOnLoad(function(){
-			var elapsed = new Date().getTime() - startTime;
-			var p = document.createElement("p");
-			p.appendChild(document.createTextNode("Widgets loaded in " + elapsed + "ms"));
-			document.body.appendChild(p);
-			// dojo.parser.parse(dojo.body());
-		});
-
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit layout.TabContainer nested TitlePane tests</h1>
-
-	<div id="mainTabContainer" dojoType="dijit.layout.TabContainer" style="width: 100%; height: 20em;">
-
-		<div dojoType="dijit.layout.ContentPane" title="Tab 1">
-			<h1>I am tab 1</h1>
-			<div dojoType="dijit.TitlePane" title="Title pane" width="300">
-				<p>This is a title pane, containing another tab container ...</p>
-				<p>
-					Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede. More Ipsum...
-				</p>
-				<div id="subTabContainer" dojoType="dijit.layout.TabContainer" style="width: 100%; height: 20em;">
-					<div id="tab3" dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 3"></div>
-					<div id="tab4" dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 4" selected="true"></div>
-				</div>
-			</div>
-		</div>
-		<div id="tab2" dojoType="dijit.layout.ContentPane" href="tab2.html" title="Tab 2"></div>
-
-	</div>
-
-
-	<h3>Typical rendering time</h3>
-	<table border=1>
-	  <tr><th>IE</th><th>Firefox (mac)</th></tr>
-	  <tr><td>1719</td><td>922</td></tr>
-	</table>
-	<h3>Rendering time</h3>
-
-</body>
-</html>
diff --git a/dijit/tests/layout/test_TabContainer_noLayout.html b/dijit/tests/layout/test_TabContainer_noLayout.html
index 0488241..51635c8 100644
--- a/dijit/tests/layout/test_TabContainer_noLayout.html
+++ b/dijit/tests/layout/test_TabContainer_noLayout.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TabContainer doLayout=false Demo</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 
 		body {
@@ -21,11 +21,11 @@
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
@@ -46,9 +46,9 @@
 		var tab = 6;
 
         function addTab(){
-			cp = new dijit.layout.ContentPane({title: 'Tab' + tab, closable: true});
+			cp = new dijit.layout.ContentPane({id: 'newTab' + tab, title: 'Tab' + tab, closable: true});
 			cp.domNode.innerHTML = "Contents of Tab " + tab++;
-			dijit.byId("mainTabContainer").addChild(cp);
+			dijit.byId("plainTabContainer").addChild(cp);
         }
 	</script>
 </head>
@@ -64,24 +64,24 @@
 		With doLayout=false mode tabs only (the default) tabPosition=top is supported.
 	</p>
 
-	<button onclick="addTab();">add tab</button>
-	<button onclick="dijit.byId('mainTabContainer').destroyRecursive();">destroy tab container</button>
+	<button id="addTab" onclick="addTab();">add tab</button>
+	<button id="destroyTabContainer" onclick="dijit.byId('plainTabContainer').destroyRecursive();">destroy tab container</button>
 
-	<div id="mainTabContainer" dojoType="dijit.layout.TabContainer" doLayout="false" style="width: 700px;">
+	<div id="plainTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='doLayout:false, style:"width: 700px;"'>
 
-		<div id="tab1" dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
+		<div id="tab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
 
-		<div id="tab2" dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
+		<div id="tab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
 
-		<div dojoType="dijit.layout.ContentPane" title="Tab 3">
-			<h1>I am tab 3</h1>
-			<p>And I was already part of the page! That's cool, no?</p>
+		<div id="tab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"'>
+			<h1 id="h3">I am tab 3</h1>
+			<p id="p3">And I was already part of the page! That's cool, no?</p>
 			<span id="foo">tooltip on this span</span>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
+			<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo"]'>I'm a tooltip!</div>
+			<button id="b3" data-dojo-type="dijit.form.Button">I'm a button </button>
 			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
-			<p>
+			<button id="b4" data-dojo-type="dijit.form.Button">So am I!</button>
+			<p id="p4">
 			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
 			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
 			porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
@@ -89,7 +89,7 @@
 			Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
 			risus.
 			</p>
-			<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+			<p id="p5">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
@@ -104,66 +104,72 @@
 			</p>
 		</div>
 
-		<div dojoType="dijit.layout.TabContainer" title="Inlined Sub TabContainer" doLayout="false" nested="true">
-			<a dojoType="dijit.layout.LinkPane" href="tab1.html">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane" href="tab2.html" selected="true">SubTab 2</a>
+		<div id="tab4" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 4", doLayout:false, nested:true'>
+			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab1.html"'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab2.html", selected:true'>SubTab 2</a>
 		</div>
 
-		<a dojoType="dijit.layout.LinkPane" href="tab3_noLayout.html" doLayout="false">Sub TabContainer from href</a>
+		<a id="tab5" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab3_noLayout.html", doLayout:false'>Tab 5</a>
 	</div>
 
-	<p>
+	<p id="textAfterTabContainer1">
 		Some text here.  This should appear directly below the TabContainer,
 		and the position will change based on the current height of the TabContainer.
 	</p>
 
-	<p>No width specified (defaults to 100%):</p>
-	<div id="anotherTabContainer" dojoType="dijit.layout.TabContainer" doLayout="false">
-
-		<div id="atab1" dojoType="dijit.layout.ContentPane" href="tab1.html" title="Tab 1"></div>
-
-		<div id="atab2" dojoType="dijit.layout.ContentPane" href="tab2.html" refreshOnShow="true" title="Tab 2" selected="true"></div>
-
-		<div dojoType="dijit.layout.ContentPane" title="Tab 3">
-			<h1>I am tab 3</h1>
-			<p>And I was already part of the page! That's cool, no?</p>
-			<span id="foo">tooltip on this span</span>
-			<div dojoType="dijit.Tooltip" connectId="foo">I'm a tooltip!</div>
-			<button dojoType="dijit.form.Button">I'm a button </button>
-			<br>
-			<button dojoType="dijit.form.Button">So am I!</button>
-			<p>
-			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
-			semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
-			porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
-			Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
-			Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
-			risus.
-			</p>
-			<p>Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
-			imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
-			nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
-			massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
-			pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
-			quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
-			felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
-			quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
-			rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
-			semper velit ante id metus. Praesent massa dolor, porttitor sed,
-			pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
-			tortor pharetra congue. Suspendisse pulvinar.
-			</p>
-		</div>
-
-		<div dojoType="dijit.layout.TabContainer" title="Inlined Sub TabContainer" nested="true" doLayout="false">
-			<a dojoType="dijit.layout.LinkPane" href="tab1.html">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane" href="tab2.html" selected="true">SubTab 2</a>
-		</div>
-
-		<a dojoType="dijit.layout.LinkPane" href="tab3_noLayout.html" doLayout="false">Sub TabContainer from href</a>
-	</div>
-
-	<p>
+	<p>No width specified but inside a table w/width=400px:</p>
+	<table>
+		<tr>
+			<td style="width:400px; max-width:400px; border:1px solid red">
+				<div id="tableTabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='doLayout:false'>
+			
+					<div id="atab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab1.html", title:"Tab 1"'></div>
+			
+					<div id="atab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='href:"tab2.html", refreshOnShow:true, title:"Tab 2", selected:true'></div>
+			
+					<div id="atab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 3"'>
+						<h1 id="h4">I am tab 3</h1>
+						<p id="p6">And I was already part of the page! That's cool, no?</p>
+						<span id="foo2">tooltip on this span</span>
+						<div data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["foo2"]'>I'm a tooltip!</div>
+						<button id="b5" data-dojo-type="dijit.form.Button">I'm a button </button>
+						<br>
+						<button id="b6" data-dojo-type="dijit.form.Button">So am I!</button>
+						<p id="p7">
+						Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean
+						semper sagittis velit. Cras in mi. Duis porta mauris ut ligula. Proin
+						porta rutrum lacus. Etiam consequat scelerisque quam. Nulla facilisi.
+						Maecenas luctus venenatis nulla. In sit amet dui non mi semper iaculis.
+						Sed molestie tortor at ipsum. Morbi dictum rutrum magna. Sed vitae
+						risus.
+						</p>
+						<p id="p8">Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
+						imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
+						nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
+						massa bibendum suscipit. Integer eros. Nullam suscipit mauris. In
+						pellentesque. Mauris ipsum est, pharetra semper, pharetra in, viverra
+						quis, tellus. Etiam purus. Quisque egestas, tortor ac cursus lacinia,
+						felis leo adipiscing nisi, et rhoncus elit dolor eget eros. Fusce ut
+						quam. Suspendisse eleifend leo vitae ligula. Nulla facilisi. Nulla
+						rutrum, erat vitae lacinia dictum, pede purus imperdiet lacus, ut
+						semper velit ante id metus. Praesent massa dolor, porttitor sed,
+						pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
+						tortor pharetra congue. Suspendisse pulvinar.
+						</p>
+					</div>
+			
+					<div id="atab4" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='title:"Tab 4", nested:true, doLayout:false'>
+						<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab1.html"'>SubTab 1</a>
+						<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab2.html", selected:true'>SubTab 2</a>
+					</div>
+			
+					<a id="atab5" data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"tab3_noLayout.html", doLayout:false'>Tab 5</a>
+				</div>
+			</td>
+			</tr>
+	</table>
+	
+	<p id="textAfterTabContainer2">
 		Some text here.  This should appear directly below the TabContainer,
 		and the position will change based on the current height of the TabContainer.
 	</p>
diff --git a/dijit/tests/layout/test_TabContainer_prog.html b/dijit/tests/layout/test_TabContainer_prog.html
deleted file mode 100644
index da754ba..0000000
--- a/dijit/tests/layout/test_TabContainer_prog.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>dijit.layout.TabContainer Programmatic Test</title>
-
-	<!-- only needed for test files: -->
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.TabContainer");
-        dojo.require("dijit.layout.ContentPane");
-
-		var tab = 1;
-
-		var tc, cp;
-		function create(initialTabs){
-			tc = new dijit.layout.TabContainer({style:'height:200px;width:500px;'}, dojo.byId('main'));
-
-			for(var i=0; i<initialTabs; i++){
-				cp = new dijit.layout.ContentPane({title: 'Tab ' + tab});
-				cp.domNode.innerHTML = "Contents of Tab " + tab++;
-				tc.addChild(cp);
-			}
-
-			tc.startup();
-        }
-
-        function addTab(){
-			cp = new dijit.layout.ContentPane({title: 'Tab' + tab});
-			cp.domNode.innerHTML = "Contents of Tab " + tab++;
-			tc.addChild(cp);
-        }
-	</script>
-</head>
-<body class="claro">
-	<h2 class="testTitle">dijit.layout.TabContainer programmatic test</h2>
-	<div id='main'>
-	</div>
-
-	<button onclick="create(0)">create empty tab container</button>
-	<button onclick="create(2)">create tab container w/2 tabs</button>
-
-	<button onclick="tc.selectChild(tc.getChildren()[1]);">select second tab</button>
-	<button onclick="tc.removeChild(tc.getChildren()[1]);">remove second tab</button>
-	<button onclick="addTab();">add tab</button>
-</body>
-</html>
diff --git a/dijit/tests/layout/test_TabContainer_remote.html b/dijit/tests/layout/test_TabContainer_remote.html
deleted file mode 100644
index c09f11f..0000000
--- a/dijit/tests/layout/test_TabContainer_remote.html
+++ /dev/null
@@ -1,116 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>TabContainer Demo</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-
-		body {
-			font-family : sans-serif;
-			margin:20px;
-		}
-
-		/* add padding to each contentpane inside the tab container, and scrollbar if necessary */
-		.dojoTabPane {
-			padding : 10px 10px 10px 10px;
-			overflow: auto;
-		}
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		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">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.layout.ContentPane");
-		dojo.require("dijit.layout.TabContainer");
-		dojo.require("dijit.Tooltip");
-		dojo.require("dijit.layout.LinkPane");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		var tabCounter;
-		function testClose(pane, tab){
-			// remove html from title
-			var title = dojo.trim(tab.title.replace(/<\/?[a-z][a-z0-9]*[^>]*>/ig, ""));
-			return confirm("Please confirm that you want tab "+title+" closed");
-		}
-
-		function randomMessageId(){
-			return Math.floor(Math.random() * 3) + 3;
-		}
-
-		function createTab(){
-			if(!tabCounter){ tabCounter = 3; }
-
-			var title = '<img src="../images/plus.gif" style="background-color:#95B7D3;"/> Tab ' +(++tabCounter);
-			var refreshOnShow = !!(tabCounter % 2);
-
-			var newTab = new dijit.layout.ContentPane({
-				title: title + (refreshOnShow ? ' <i>refreshOnShow</i>': ''),
-				closable:true,
-				refreshOnShow: refreshOnShow,
-				href: 'getResponse.php?delay=1000&messId='+randomMessageId()
-					+"&message="+encodeURI("<h1>Programmatically created Tab "+tabCounter+"</h1>")
-			}, dojo.doc.createElement('div'));
-
-			dijit.byId('ttabs').addChild(newTab);
-
-			newTab.startup(); // find parent TabContainer and subscribe to selectChild event
-		}
-
-		startTime = new Date();
-		dojo.addOnLoad(function(){
-			var elapsed = new Date().getTime() - startTime;
-			var p = document.createElement("p");
-			p.appendChild(document.createTextNode("Widgets loaded in " + elapsed + "ms"));
-			document.body.appendChild(p);
-		});
-	</script>
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit layout.TabContainer (delayed) remote tests</h1>
-
-	<p>These tabs are made up of external content. Loading is delayed to make it easier to see if refreshOnShow and preload = 'false' is working.<br/>
-	The tabs also tests to insert html in the Tab title
-	</p>
-
-	<div dojoType='dijit.form.Button' onClick='createTab()'>Create a Tab</div>
-	<div id="ttabs" dojoType="dijit.layout.TabContainer" tabPosition="top" style="width: 100%; height: 20em;">
-		<a id="ttab1" dojoType="dijit.layout.LinkPane"
-			href="getResponse.php?messId=3&delay=1000"
-			closable="true"
-		><img src='../images/copy.gif'/> Tab1</a>
-		<a id="ttab2" dojoType="dijit.layout.LinkPane"
-			href="getResponse.php?messId=4&delay=1000"
-			refreshOnShow="true" title="Tab 2 "
-			selected='true'
-			closable='true'
-		><i>refreshOnShow</i>
-			<img src='../images/cut.gif'/>
-		</a>
-		<a dojoType="dijit.layout.LinkPane"
-			href="getResponse.php?messId=5&delay=1000"
-			onClose="testClose"
-			closable="true"
-		>
-			<b>Tab 3</b>
-			<img src='../images/paste.gif'/>
-		</a>
-	</div>
-
-	<h3>Rendering time</h3>
-
-</body>
-</html>
diff --git a/dijit/tests/layout/test_refreshOnShow.html b/dijit/tests/layout/test_refreshOnShow.html
deleted file mode 100644
index 844cedb..0000000
--- a/dijit/tests/layout/test_refreshOnShow.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>ContentPane Test</title>
-
-	<style>
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-
-		body {
-			margin: 1em;
-			padding: 1em;
-		}
-
-		.box {
-		  position: relative;
-			background-color: white;
-			border: 2px solid black;
-			padding: 8px;
-			margin: 4px;
-		}
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, 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.TabContainer");
-		dojo.require("dijit.layout.AccordionContainer");
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit layout.ContentPane tests</h1>
-
-	<!-- works: -->
-	<div dojoType="dijit.layout.TabContainer" style="height:200px;">
-		<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="one" refreshOnShow="false"></div>
-		<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="two" refreshOnShow="false"></div>
-		<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="three" refreshOnShow="false"></div>
-	</div>
-
-	<!-- does not work yet: -->
-    <div dojoType="dijit.layout.AccordionContainer" style="height:200px; width:400px;">
-		<div dojoType="dijit.layout.ContentPane" title="one" refreshOnShow="false" href="_lorem.html"></div>
-		<div dojoType="dijit.layout.ContentPane" title="two" refreshOnShow="true" href="_lorem.html"></div>
-		<div dojoType="dijit.layout.ContentPane" title="three" refreshOnShow="false" href="_lorem.html"></div>
-	</div>
-
-
-
-</body>
-</html>
diff --git a/dijit/tests/robot/BgIframe.html b/dijit/tests/robot/BgIframe.html
new file mode 100644
index 0000000..8c01f9b
--- /dev/null
+++ b/dijit/tests/robot/BgIframe.html
@@ -0,0 +1,142 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot bgIframe Test</title>
+
+		<style>
+			@import "../../../util/doh/robot/robot.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" src="../helpers.js"></script>
+			
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_bgIframe.html');
+	
+				dojo.forEach(["applet", "xapp"], function(xId){
+					doh.register(xId, [
+					{
+						name: "dialog_" + xId,
+						timeout: 15000,
+						runTest: function(){
+							if(dojo.isWebKit){ return; }  // TODO: Remove skip-test for non-WebKit after #11822 is fixed
+							var d = new doh.Deferred();
+
+							var wasClicked = false;
+							var connection;
+							
+							//Show the dialog
+							doh.robot.mouseMoveAt("showDialog", 500,  1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							//drag the dialog on top of the applet
+							doh.robot.mouseMoveAt(dijit.byId("dialog").titleNode, 2000,  1);
+							doh.robot.mousePress({left:true}, 500);
+							doh.robot.mouseMoveAt(xId, 500,  1000);
+							doh.robot.mouseRelease({left:true}, 500);
+							
+							doh.robot.sequence(function(){
+								connection = dojo.connect(dijit.byId("dialog").containerNode, "onclick", function(e){ wasClicked = true; });
+							}, 500); 
+							
+							//Click on the dialog
+							doh.robot.mouseMoveAt(dijit.byId("dialog").containerNode, 1, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								dojo.disconnect(connection);
+								//verify the native select did not disappear
+								doh.t(isVisible(dojo.byId("dropDown_" + xId)), "The native select is not visible");
+								
+								dijit.byId("dialog").hide();
+								
+								doh.t(wasClicked, "Dialog was not visible because the onclick did not fire.");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "tooltip_" + xId,
+						timeout: 8000,
+						runTest: function(){
+							if(!dojo.isIE){ return; }  // TODO: Remove skip-test for non-IE after #11822 is fixed
+							var d = new doh.Deferred();
+
+							var tooltipWasClicked = false;
+							var connection, oldHide;
+							
+							//Show the tooltip
+							doh.robot.mouseMoveAt("two_" + xId, 500, 1);
+							
+							doh.robot.sequence(function(){ 
+								var tooltip = dijit.byId("dijit__MasterTooltip_0");
+								oldHide = tooltip.hide;
+								tooltip.hide = function(aroundNode){
+									//don't allow the tooltip to be hidden							
+								};
+								connection = dojo.connect(tooltip.domNode, "onclick",
+									function(e){
+										tooltipWasClicked = true;
+										tooltip.hide = oldHide;
+										tooltip.hide(tooltip.aroundNode);
+									}
+								);
+							}, 2000); 
+							
+							//Click on the tooltip
+							doh.robot.mouseMoveAt("dijit__MasterTooltip_0", 1, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								dojo.disconnect(connection);
+								doh.t(tooltipWasClicked, "The tooltip is not visible because the onclick event was not fired.");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "dateTextBox_" + xId,
+						timeout: 7000,
+						runTest: function(){
+							if(!dojo.isIE){ return; }  // TODO: Remove skip-test for non-IE after #11822 is fixed
+							var d = new doh.Deferred();
+
+							var wasClicked = false;
+							var connection;
+							
+							//Show the popup
+							doh.robot.mouseMoveAt("dateText_" + xId, 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(function(){
+								connection = dojo.connect(dijit.byId("dateText_"+xId+"_popup").domNode, "onclick", function(e){ wasClicked = true; });
+							}, 2000); 
+							
+							//Click on the popup
+							doh.robot.mouseMoveAt("dateText_"+xId+"_popup", 1, 1, 10, 10);
+							doh.robot.mouseClick({left:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(function(){
+								dojo.disconnect(connection);
+								doh.t(wasClicked);
+							}), 1000);
+
+							return d;
+						}
+					}
+					]);
+				});
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/robot/Calendar_a11y.html b/dijit/tests/robot/Calendar_a11y.html
index d26c6de..0088665 100644
--- a/dijit/tests/robot/Calendar_a11y.html
+++ b/dijit/tests/robot/Calendar_a11y.html
@@ -28,13 +28,122 @@
 				// log of calls to onChange handler
 				var changes = [];
 
-				doh.register("dijit.Calendar keyboard tests",[
+				// 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();
+						},
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Tab in
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is(16, innerText(dojo.global.dijit._curFocus), "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");
+							})), 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");
+							})), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "reverse",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// shift-tab back into calendar, should go to previously focused day
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is(24, innerText(dojo.global.dijit._curFocus), "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");
+							})), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "advance a month",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Tab in
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is(24, innerText(dojo.global.dijit._curFocus), "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");
+							})), 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");
+							})), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "reverse again",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// shift-tab back into calendar, should go to previously focused day
+							doh.robot.keyPress(dojo.keys.TAB, 500, {shift: true});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is(24, innerText(dojo.global.dijit._curFocus), "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");
+							})), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				// Make sure that all the navigation and selection keystrokes work
+				doh.register("navigation",[
 					{
 						name: "arrow navigation",
 						timeout: 10000,
 						setUp: function(){
 							// refs to Calendar widget
-					    	cal1 = dijit.byId('calendar1');
+						    	cal1 = dijit.byId('calendar1');
 							cal1.set("value", new Date(2009, 8, 16));
 
 					    	// setup onChange handler to monitor onChange calls on cal1
@@ -45,25 +154,69 @@
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
+
 							doh.robot.sequence(function(){
 								// monitor onchange events
 								changes = [];
-								cal1.domNode.focus();
+								cal1.focus();
 							}, 500);
 
+							// Initial conditions
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								// 16th is selected
+								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								doh.is(1, selected.length, "one selected node");
+								doh.is("16", innerText(selected[0]));
+
+								// initial focus is on selected value
+								doh.is("16", innerText(dojo.global.dijit._curFocus));
+
+								// and get("value") working
+								doh.is(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'get("value")');
+							})), 1000);
+
+							// Mouse moves around focus without changing value
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.UP_ARROW, 500, {});
-							doh.robot.keyPress(dojo.keys.UP_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(0, dojo.date.compare(new Date(2009, 8, 16), cal1.get('value')), 'value unchanged');
+								
+								// 16th is still selected
+								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								doh.is(1, selected.length, "one selected node");
+								doh.is("16", innerText(selected[0]));								
+							})), 500);
+							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 0, {});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is(18, innerText(dojo.global.dijit._curFocus));
+							})), 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));
+							})), 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));
+							})), 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));
+							})), 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));
+							})), 500);
+							doh.robot.keyPress(dojo.keys.ENTER, 0, {});
+
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var value = cal1.get('value');
 								doh.is(0, dojo.date.compare(new Date(2009, 8, 10), value), 'actual value is ' + value);
-								doh.is(6, changes.length, 'six onchange events');
-								doh.is(0, dojo.date.compare(new Date(2009, 8, 17), changes[0]),
+								doh.is(1, changes.length, 'onchange events');
+								doh.is(0, dojo.date.compare(new Date(2009, 8, 10), changes[0]),
 										'value reported by onchange: ' + changes[0] +
-										', should be ' + new Date(2009, 8, 17));
+										', should be ' + new Date(2009, 8, 10));
 							})), 1000);
 							return d;
 						}
@@ -73,21 +226,51 @@
 						timeout: 5000,
 						setUp: function(){
 							// refs to Calendar widget
-					    	cal1 = dijit.byId('calendar1');
+					   	 	cal1 = dijit.byId('calendar1');
 							cal1.set("value", new Date(2008, 0, 31));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
+
 							doh.robot.sequence(function(){
-								// monitor onchange events
-								cal1.domNode.focus();
+								cal1.focus();
 							}, 500);
 
+							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(0, dojo.date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (first page down)');
+
+								// month label should have changed
+								var monthLabel = dojo.query(".dijitCalendarCurrentMonthLabel", cal1.domNode);
+								doh.is(1, monthLabel.length, "one month label");
+								doh.is("February", innerText(monthLabel[0]));
+
+								// jan 31 from previous month still visible, should be shown as selected
+								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								doh.is(1, selected.length, "no selected node");
+							})), 500);
+
 							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500, {});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								// focus moved from jan 31 to feb 29
+								doh.is(29, innerText(dojo.global.dijit._curFocus));
+
+								doh.is(0, dojo.date.compare(new Date(2008, 0, 31), cal1.get('value')), 'value unchanged (second page down)');
+								
+								// since january no longer visible, no selected date should be visible
+								var selected = dojo.query(".dijitCalendarSelectedDate", cal1.domNode);
+								doh.is(0, selected.length, "no selected node");
+							})), 500);
+
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var value = cal1.get('value');
-								doh.is(0, dojo.date.compare(new Date(2008, 1, 29), value), 'actual value is ' + value);
+								doh.is(0, dojo.date.compare(new Date(2008, 2, 29), value), 'actual value is ' + value);
 							})), 1000);
+
 							return d;
 						}
 					},
@@ -96,24 +279,29 @@
 						timeout: 5000,
 						setUp: function(){
 							// refs to Calendar widget
-					    	cal1 = dijit.byId('calendar1');
+						    	cal1 = dijit.byId('calendar1');
 							cal1.set("value", new Date(2008, 1, 15));
 						},
 						runTest: function(){
 							var d = new doh.Deferred();
+
 							doh.robot.sequence(function(){
-								// monitor onchange events
-								cal1.domNode.focus();
+								cal1.focus();
 							}, 500);
 
-							doh.robot.keyPress(dojo.keys.END, 500, {});
-							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500, {ctrl:true});
-							doh.robot.keyPress(dojo.keys.PAGE_UP, 500, {ctrl:true});
-							doh.robot.keyPress(dojo.keys.PAGE_UP, 500, {ctrl:true});
+							doh.robot.keyPress(dojo.keys.END, 1000, {});
+							// Chrome switches tabs with ctrl+page up/down (not even a keydown is generated), yet not Safari.
+							// I don't see a way to do feature-detection since browser window focus is lost.
+							doh.robot.keyPress(dojo.keys.PAGE_DOWN, 500, dojo.isChrome ? {alt:true} : {ctrl:true});
+							doh.robot.keyPress(dojo.keys.PAGE_UP, 500, dojo.isChrome ? {alt:true} : {ctrl:true});
+							doh.robot.keyPress(dojo.keys.PAGE_UP, 500, dojo.isChrome ? {alt:true} : {ctrl:true});
+							doh.robot.keyPress(dojo.keys.ENTER, 500);
+
 							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
 								var value = cal1.get('value');
 								doh.is(0, dojo.date.compare(new Date(2007, 1, 28), value), 'actual value is ' + value);
 							})), 1000);
+
 							return d;
 						}
 					}
diff --git a/dijit/tests/robot/ColorPalette.html b/dijit/tests/robot/ColorPalette.html
index 7371980..d5f8a1c 100644
--- a/dijit/tests/robot/ColorPalette.html
+++ b/dijit/tests/robot/ColorPalette.html
@@ -77,7 +77,8 @@
 						name: "arrow navigation",
 						timeout: 10000,
 						runTest: function(){
-							var d = new doh.Deferred();
+							var d = new doh.Deferred(),
+								enterPressed = false;
 
 							// Move around some
 							doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 500, {});
@@ -96,20 +97,34 @@
                                 var dye = big._getDye(focus);
 								doh.is("#ffc0cb", dye.getValue(), "focused on right color");
 							})), 1000);
-							
-							// Select the current value
-							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
-								doh.is("#ffc0cb", big.get("value"), "selected value");
-								
-								doh.is(1, changes.length, 'one onchange event');
-								doh.is("#ffc0cb", changes[0], "correct value");
+
+							// Setup handler to catch onChange event from ENTER keypress below
+							handle = dojo.connect(big, "onChange", d.getTestCallback(dojo.hitch(this, function(val){
+								dojo.disconnect(handle);
+								handle = null;
+
+								doh.is("#ffc0cb", val, "onChange() argument");
+								doh.is("#ffc0cb", big.get("value"), "get('value')");
+
+								doh.is(1, changes.length, 'just one onchange event');
+								doh.t(enterPressed, "onChange event didn't come until enter key was pressed");
 								
 								big.set('value', null);
 								doh.is(big.get('value'), null, "value has been cleared");
-							})), 1000);
+							})));
+
+							// Select the current value
+							doh.robot.sequence(function(){
+								enterPressed = true;
+							}, 0);
+							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
 
 							return d;
+						},
+						tearDown: function(){
+							if(handle){
+								dojo.disconnect(handle);
+							}
 						}
 					},
 
@@ -186,7 +201,7 @@
 								doh.robot.mouseClick({left: true}, 500);
 							}
 							
-								var green = dojo.query("[title=verde]", small.domNode);
+							var green = dojo.query("[title=verde]", small.domNode);
 							doh.is(1, green.length, "found verde (green)");
 
 							doh.robot.mouseMoveAt(green[0], 500);
@@ -211,8 +226,9 @@
 								
 								//test that selected style was removed from previously selected cell and added to new selection
 								doh.f(dojo.hasClass(red[0], "dijitPaletteCellSelected"),
-								"Red swatch should not have selected class, actual class is: " + red[0].className);
-								doh.t(dojo.hasClass(green[0], "dijitPaletteCellSelected"), "Green swatch should have selected class, actual class is: " + green[0].className);
+									"Red swatch should not have selected class, actual class is: " + red[0].className);
+								doh.t(dojo.hasClass(green[0], "dijitPaletteCellSelected"),
+									"Green swatch should have selected class, actual class is: " + green[0].className);
 							}), 1000);
 							
 							
diff --git a/dijit/tests/robot/Dialog_a11y.html b/dijit/tests/robot/Dialog_a11y.html
index d7066ff..17920ad 100644
--- a/dijit/tests/robot/Dialog_a11y.html
+++ b/dijit/tests/robot/Dialog_a11y.html
@@ -18,97 +18,10 @@
 		<script type="text/javascript">
 			dojo.require("dijit.robotx");
 
-			var dialogIds = [
-				{ dlg: "dialog1", firstFocus: "name" },
-				{ dlg: "tabDialog", firstFocus: "tc_tablist_cp1" },
-				{ dlg: "fifthDlg", firstFocus: "timeref" }, //timeref is in layout/getResponse.php
-				{ dlg: "dialog6", firstFocus: "dialog6", fileInput: "afile" },
-				{ dlg: "cantmove", firstFocus: "cantmove" },
-				{ dlg: "preventer", firstFocus: "preventerOK" }
-			];
-
-			// testing utilities
-			function dialogTests(){
-				var that = {};
-				var xtraPara = null;
-				var firstTabStop = null;
-				var gotFocus = false;
-				var lostFocus = false;
-				var focusConnect = null;
-				var blurConnect = null;
-
-				// Define a known location to place keyboard focus, and put it there.  Allows for a
-				// place for focus to return to when dialog is dismissed.
-				function addTabNavFocus(){
-					removeTabNavFocus();
-					xtraPara = dojo.doc.createElement("p");
-					dojo.attr(xtraPara, 'tabIndex', 0);
-					xtraPara.innerHTML = "Tab-focussable paragraph";
-					xtraPara.id="focusPara";
-					dojo.place(xtraPara, dojo.body(), "first");
-					xtraPara.focus();
-				};
-
-				function removeTabNavFocus(){
-					if(xtraPara && xtraPara.parentNode){
-						xtraPara.parentNode.removeChild(xtraPara);
-					}
-				};
-
-				that.ariaFocusSetup = function(/*dialog's and first focusable ids*/ ids){
-					addTabNavFocus();
-					gotFocus = lostFocus = false;
-					var dlog = dijit.byId(ids.dlg);
-					// need to show dialog in order to find the first tab stop.
-					if( !dojo.isMoz && ids.fileInput){
-						that.firstTabStop = ids.fileInput;
-					}else{
-						that.firstTabStop = ids.firstFocus;
-					}
-				};
-
-				that.ariaFocusTeardown = function(){
-					removeTabNavFocus();
-				};
-
-				that.ariaFocus = function(dlogId){
-					var d = new doh.Deferred();
-					var dlog = dijit.byId(dlogId.dlg);
-					var doShow = function(){
-						dlog.show();
-					};
-					var doHide = function(){
-						dlog.hide();
-					};
-					var doFocusTest = function(){
-						gotFocus = (dojo.global.dijit._curFocus.id == that.firstTabStop);
-					}
-					var doBlurTest = function(){
-						lostFocus = (dojo.global.dijit._curFocus.id != that.firstTabStop);
-					}
-					// <firstTabStop> set in that.ariaFocusSetup(), above.
-					doh.isNot(null, that.firstTabStop,  + "no first-focusable item for dialog: " + dlog.id);
-					doh.robot.sequence(doShow, 200);
-					doh.robot.sequence(doFocusTest, (dlogId.dlg == "fifthDlg" ? 4000 : 1000));  // wait for dialog to display
-					doh.robot.sequence(doHide, 1000);
-					doh.robot.sequence(doBlurTest, 1000);
-					var testShowHide = function(){
-						doh.t(gotFocus, "first focusable didn't get focus on open, for: " + dlog.id);
-						doh.t(lostFocus, "first focusable didn't lose focus on close, for: " + dlog.id);
-					};
-					doh.robot.sequence(d.getTestCallback(testShowHide), 1000);
-					return d;
-				};
-				return that;
-
-			}	// end dialogTests().
-
-			var dialogTest;
-
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_Dialog.html');
 
-				doh.register("dijit.Dialog keyboard tests (cancel)",[
+				doh.register("keyboard tests (cancel)",[
 					{
 						name: "open dialog",
 						timeout: 10000,
@@ -118,16 +31,14 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							doh.robot.sequence(function(){
-								dojo.byId("dialog1button").focus();
-							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 1500, {});
-							doh.robot.typeKeys("Bill", 1000, 2000);
+							dojo.byId("dialog1button").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							doh.robot.typeKeys("Bill", 1000, 800);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("dialog1"), "dialog 1 has been made visible");
 								doh.is("name", dojo.global.dijit._curFocus.id, "focus is on the first field");
-							}), 1000);
+							}), 500);
 
 							return d;
 						}
@@ -140,7 +51,7 @@
 							var d = new doh.Deferred();
 
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.typeKeys("Japan", 500, 2500);
+							doh.robot.typeKeys("Japan", 1000, 1000);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -152,11 +63,12 @@
 					},
 
 					{
-						name: "close date drop down",
+						name: "open and close date drop down",
 						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
+							doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500, {});
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -221,7 +133,7 @@
 					}
 				]);
 
-				doh.register("dijit.Dialog keyboard tests (submit)",[
+				doh.register("keyboard tests (submit)",[
 					{
 						name: "submit some data",
 						timeout: 15000,
@@ -238,22 +150,20 @@
 							});
 
 							// Open the dialog
-							doh.robot.sequence(function(){
-								dojo.byId("dialog1button").focus();
-							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dojo.byId("dialog1button").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
 
 							// Enter some info
-							doh.robot.typeKeys("Ted", 2000, 1500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.typeKeys("America", 500, 3500);
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
-							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.typeKeys("Ted", 2000, 600);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.typeKeys("America", 1000, 1400);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
+							doh.robot.keyPress(dojo.keys.TAB, 1000, {});
 
 							// Submit
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("dialog1"), "dialog 1 was closed on submit");
@@ -267,7 +177,7 @@
 					}
 				]);
 
-				doh.register("dijit.Dialog keyboard tests (cancel via Cancel button)",[
+				doh.register("keyboard tests (cancel via Cancel button)",[
 					{
 						name: "close Dialog via Cancel button",
 						timeout: 15000,
@@ -284,10 +194,8 @@
 							});
 
 							// Open the dialog
-							doh.robot.sequence(function(){
-								dojo.byId("ABDlg1Btn").focus();
-							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+							dojo.byId("ABDlg1Btn").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible("ABDlg1"), "dialog opened");
@@ -308,84 +216,139 @@
 					}
 				]);
 
-				var dialogTest = dialogTests();
-
-				// Loop to register tests for each dialog in the <dialogIds> array
-				// TODO:
-				//		The a11yAriaRole, a11yLabel, and a11yAriaExpanded tests probably only need
-				//		to be done for one dialog.
-				// TODO:
-				//		Even the focus tests, the only things we need to test that haven't been tested
-				//		already are:
-				//			1. focus for a dialog with no focusable elements
-				//			2. the file focus thing
-				for(i=0; i<dialogIds.length; i++){
-
-					// aria role and properties (aria-labelledby) tests.
-					doh.register("a11yAriaRole", {
-						name:dialogIds[i].dlg+"_role",
-						dialogId:dialogIds[i].dlg,
-						runTest:function(){
-							var dlog = dijit.byId(this.dialogId);
-							doh.is("dialog", dijit.getWaiRole(dlog.domNode), dlog.id + ": aria role (dialog)");
-						}
-					});
-					doh.register("a11yLabel", {
-						name:dialogIds[i].dlg+"_label",
-						dialogId:dialogIds[i].dlg,
-						runTest:function(){
-							var dlog = dijit.byId(this.dialogId);
-							var label = dijit.getWaiState(dlog.domNode, 'label');
-							if(!label){
-								var labelNodeId = dijit.getWaiState(dlog.domNode, 'labelledby');
-								if(labelNodeId){
-									var labelNode = dojo.byId(labelNodeId);
-								}
-								if(labelNode){
-									label = labelNode.innerHTML;
-								}
-							}
-							var hint = "aria-label or aria-labelledby (" + dlog.id + ")";
-							doh.isNot(null, label, "null " + hint);
-							doh.isNot("", label, "empty " + hint);
+				// Test aria roles, etc.
+				doh.register("aria", function(){
+					var dlog = dijit.byId("dialog1");
+					doh.is("dialog", dlog.domNode.getAttribute("role"), "role");
+					doh.is("dialog1_title", dlog.domNode.getAttribute("aria-labelledby"), "aria-labelledby");
+					doh.isNot(undefined, dojo.byId("dialog1_title"), "label node exists");
+					doh.isNot("", innerText(dojo.byId("dialog1_title")), "label node has text");
+					// dijit.Dialog does not implement aria-expanded as of this writing -- should it?
+				});
+
+				// Focus tests for special cases.   Focus for normal cases was already tested above.
+				doh.register("special focus", [
+					{
+						name: "no focusable elements",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Click the button.  We do this manually rather than calling Dialog.show()
+							// so we can later test that focus is restored (to the previous position)
+							// when the dialog is closed
+							dojo.byId("unmovablebutton").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+
+							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");
+							}), 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");
+							}), 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");
+							}), 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");
+							}), 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");
+							}), 500);
+
+							return d;
 						}
-					});
-
-	/*				// dijit.Dialog does not implment aria-expanded as of this writing -- should it?
-					doh.register("a11yAriaExpanded",{
-						name:dialogIds[i].dlg+"_aria-expanded",
-						dialogId:dialogIds[i].dlg,
-						runTest:function(){
-							var dlog = dijit.byId(this.dialogId);
-							var expanded = dijit.getWaiState(dlog.domNode, 'expanded');
-							if(expanded=="") expanded = "false";
-							doh.is("false", expanded, dlog.id + ": not shown");
-							dlog.show();
-							expanded = dijit.getWaiState(dlog.domNode, 'expanded');
-							dlog.hide();
-							doh.is("true", expanded, dlog.id + ": shown");
+					},
+					
+					{
+						name: "input type=file",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Click the button.  We do this manually rather than calling Dialog.show()
+							// so we can later test that focus is restored (to the previous position)
+							// when the dialog is closed
+							dojo.byId("filebutton").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+
+							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");
+							}), 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");
+							}), 500);
+
+							return d;
 						}
-					});
-	*/
-
-					// First focusable tests
-					doh.register("a11yFirstFocusable",{
-						name:"a11yFirstFocusable_"+dialogIds[i].dlg,
-						dialog:dialogIds[i],
-						timeout:20000,
-						setUp:function(){
-							dialogTest.ariaFocusSetup(this.dialog);
-						},
-						runTest:function(){
-							return dialogTest.ariaFocus(this.dialog);
-						},
-						tearDown:function(){
-							dialogTest.ariaFocusTeardown();
+					},
+
+					{
+						name: "radio button as last element",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Click the button.  We do this manually rather than calling Dialog.show()
+							// so we can later test that focus is restored (to the previous position)
+							// when the dialog is closed
+							dojo.byId("RadioButtonDlgBtn").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
+
+							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");
+							}), 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");
+							}), 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");
+							}), 500);
+
+							return d;
 						}
-					});
-				}	// end for() loop thru dialogIds array.
+					}
+				]);
 
-				doh.register("dijit.Dialog keyboard tests (multiple dialogs)",[
+				doh.register("keyboard tests (multiple dialogs)",[
 					{
 						name: "open first dialog",
 						timeout: 10000,
@@ -398,11 +361,9 @@
 							// Click the button.  We do this manually rather than calling Dialog.show()
 							// so we can later test that focus is restored (to the previous position)
 							// when the dialog is closed
-							doh.robot.sequence(function(){
-								dojo.byId("dialog1button").focus();
-							}, 500);
-							doh.robot.keyPress(dojo.keys.SPACE, 500, {});
-							doh.robot.typeKeys("lower", 1000,1000);
+							dojo.byId("dialog1button").focus();
+							doh.robot.keyPress(dojo.keys.SPACE, 1000, {});
+							doh.robot.typeKeys("lower", 1000, 1000);
 
 							// Move focus to second field
 							doh.robot.keyPress(dojo.keys.TAB, 1000);
@@ -417,7 +378,7 @@
 									") above underlay (zIndex=" + underlayZ + ")");
 
 								doh.is("loc", dojo.global.dijit._curFocus.id, "focus is on the second field");
-							}), 5000);
+							}), 1000);
 
 							return d;
 						}
@@ -429,9 +390,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.sequence(function(){
-								dijit.byId("tabDialog").show();
-							}, 500);
+							dijit.byId("tabDialog").show();
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isVisible("tabDialog"), "tab dialog has been made visible");
@@ -445,7 +404,7 @@
 									") above underlay (zIndex=" + underlayZ + ")");
 								doh.t(dialog1Z < underlayZ, "dialog1 (zIndex=" + dialog1Z +
 									") below underlay (zIndex=" + underlayZ + ")");
-							}), 5000);
+							}), 2000);
 
 							return d;
 						}
@@ -470,7 +429,7 @@
 									") above underlay (zIndex=" + underlayZ + ")");
 
 								doh.is("loc", dojo.global.dijit._curFocus.id, "focus is on the second field");
-							}), 5000);
+							}), 2000);
 
 							return d;
 						}
@@ -487,7 +446,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");
-							}), 5000);
+							}), 2000);
 
 							return d;
 						}
diff --git a/dijit/tests/robot/Dialog_focusDestroy.html b/dijit/tests/robot/Dialog_focusDestroy.html
new file mode 100644
index 0000000..983ffa8
--- /dev/null
+++ b/dijit/tests/robot/Dialog_focusDestroy.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot dialog focus destroy 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>
+
+		<script type="text/javascript">
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_Dialog_focusDestroy.html');
+					
+				doh.register("TestDestroy",[
+					{
+						name: "destroy",
+						timeout: 11000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt("testInput", 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+							doh.robot.keyPress("a", 1000);
+							doh.robot.mouseMoveAt("showDialog", 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress("a", 1000);
+							doh.robot.mouseMoveAt("destroyButton", 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("testInput", 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.keyPress(dojo.keys.BACKSPACE, 500);
+							doh.robot.keyPress("b", 1000);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								var inputBox = dojo.byId("testInput");
+								doh.is("b", inputBox.value);
+							})), 1000);
+
+							return d;
+						}
+					}
+				]);
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/robot/Dialog_mouse.html b/dijit/tests/robot/Dialog_mouse.html
index 889f7cd..764c870 100644
--- a/dijit/tests/robot/Dialog_mouse.html
+++ b/dijit/tests/robot/Dialog_mouse.html
@@ -2,7 +2,7 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<title>doh.robot Dialog A11Y Test</title>
+		<title>doh.robot Dialog Mouse Test</title>
 
 		<style>
 			@import "../../../util/doh/robot/robot.css";
@@ -29,15 +29,19 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
+							var oldOnClick = dijit.byId("dialog1button").onClick;
+							dijit.byId("dialog1button").onClick = function(){
+								dijit.byId("dialog1").show().then(d.getTestCallback(function(){
+									doh.t(isVisible("dialog1"), "dialog 1 has been made visible");
+									doh.is("name", dojo.global.dijit._curFocus.id, "focus is on the first field");
+								}));
+								dijit.byId("dialog1button").onClick = oldOnClick;
+							};
+
 							// Open the dialog
 							doh.robot.mouseMoveAt("dialog1button", 1000);
 							doh.robot.mouseClick({left: true}, 1000);
 
-							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");
-							}), 1000);
-
 							return d;
 						}
 					},
@@ -66,13 +70,17 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("date", 500);
-							doh.robot.mouseClick({left: true}, 1000);
+							onFocus(function(){
+								// Focus might first go to input, then to calendar, so wait for that
+								setTimeout(d.getTestCallback(function(){
+									var calDomNode = dojo.query(".dijitCalendarContainer");
+									doh.t(calDomNode.length == 1 && isVisible(calDomNode[0]), "calendar is being shown");
+									doh.t(dojo.isDescendant(dojo.global.dijit._curFocus, calDomNode[0]), "focus is on the calendar ");
+								}), 500);
+							});
 
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is("date", dojo.global.dijit._curFocus.id, "focus is on the date field");
-								doh.is(1, dojo.query(".dijitCalendarContainer").length, "calendar is being shown");
-							}), 1000);
+							doh.robot.mouseMoveAt(function(){ return dojo.query(".dijitArrowButton", dijit.byId("date").domNode)[0]; }, 500);
+							doh.robot.mouseClick({left: true}, 1000);
 
 							return d;
 						}
@@ -88,7 +96,8 @@
 							doh.robot.mouseClick({left: true}, 1000);
 
 							doh.robot.sequence(d.getTestCallback(function(){
-								doh.is(0, dojo.query(".dijitCalendarContainer").length, "calendar has disappeared");
+								var calDomNode= dojo.query(".dijitCalendarContainer");
+								doh.t(calDomNode.length == 0 || isHidden(calDomNode[0]), "calendar has disappeared");
 								doh.t(isVisible("dialog1"), "dialog 1 wasn't closed");
 							}), 1000);
 
@@ -102,15 +111,15 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
+							onFocus(d.getTestCallback(function(node){
+								doh.t(isHidden("dialog1"), "dialog 1 was closed");
+								doh.is("dialog1button", node.id, "focus returned to button");
+							}));
+
 							var button = dojo.query("#dialog1 .dijitDialogCloseIcon")[0];
 							doh.robot.mouseMoveAt(button, 500);
 							doh.robot.mouseClick({left: true}, 1000);
 
-							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");
-							}), 1000);
-
 							return d;
 						}
 					}
@@ -133,22 +142,21 @@
 							});
 
 							// Open the dialog
-							doh.robot.mouseMoveAt("dialog1button", 500);
-							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.mouseMoveAt("dialog1button", 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
 
 							// Enter some info
-							doh.robot.mouseMoveAt("name", 2000);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.typeKeys("Ted", 500);
-
-							doh.robot.mouseMoveAt("loc", 500);
-							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.typeKeys("America", 500);
+							doh.robot.mouseMoveAt("name", 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.typeKeys("Ted", 500, 600);
 
+							doh.robot.mouseMoveAt("loc", 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.typeKeys("America", 500, 1400);
 
 							// Submit
-							doh.robot.mouseMoveAt("ok", 500);
-							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.mouseMoveAt("ok", 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.t(isHidden("dialog1"), "dialog 1 was closed on submit");
diff --git a/dijit/tests/robot/InlineEditBox.html b/dijit/tests/robot/InlineEditBox.html
index 22dd685..c429105 100644
--- a/dijit/tests/robot/InlineEditBox.html
+++ b/dijit/tests/robot/InlineEditBox.html
@@ -23,30 +23,9 @@
 				doh.robot.initRobot('../test_InlineEditBox.html');
 
 				function moveAndClick(node) {
-					doh.robot.mouseMoveAt(node, 500, 500);
+					doh.robot.mouseMoveAt(node, 500, 1);
 					doh.robot.mouseClick({left: true}, 500);
 				}
-				function cancel(deferred, widget){
-					moveAndClick(function(){
-						try{
-							var buttons = dojo.query(".cancelButton", widget.domNode.parentNode);
-							return buttons[buttons.length-1];
-						}catch(e){ deferred.errback(e); }
-					});
-					doh.robot.sequence(function(){}, 1000); // slow down to allow widget to exit edit mode
-				}
-				function save(deferred, widget){
-					moveAndClick(function(){
-						try{
-							var buttons = dojo.query(".saveButton", widget.domNode.parentNode);
-							return buttons[buttons.length-1];
-						}catch(e){ deferred.errback(e); }
-					});
-					doh.robot.sequence(function(){}, 1000); // slow down to allow widget to exit edit mode
-				}
-				function testOK(deferred, delay){
-					doh.robot.sequence(dojo.hitch(deferred, "callback", true), delay? delay : 1);
-				}
 
 				doh.register("dijit.InlineEditBox autosave tests", [
 					{
@@ -74,16 +53,19 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							var inlineBox = dijit.byId("dollar_as");
+							var displayedValue, isValid;
 							moveAndClick(inlineBox.domNode);
 							doh.robot.typeKeys("dollar", 1000, 1200); // invalid
 							doh.robot.keyPress(dojo.keys.ENTER, 500, {});
-							doh.robot.sequence(d.getTestErrback(function(){
+							doh.robot.sequence(function(){
 								var currencyTextBox = inlineBox.wrapperWidget.editWidget;
-								doh.is('dollar', currencyTextBox.get("displayedValue"), "displayedValue");
-								doh.f(currencyTextBox.isValid(), "!isValid");
-							}), 1000);
+								displayedValue = currencyTextBox.get("displayedValue");
+								isValid = currencyTextBox.isValid();
+							}, 1000);
 							doh.robot.keyPress(dojo.keys.ESCAPE, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is('dollar', displayedValue, "displayedValue");
+								doh.f(isValid, "!isValid");
 								doh.is('', inlineBox.get("value"), "value");
 							}), 1000);
 							return d;
@@ -155,6 +137,8 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 							var inlineBox = dijit.byId("editable");
+							var initialOnChange = inlineBox._onChangeValue;
+							inlineBox.set("value", "");
 							moveAndClick(inlineBox.domNode);
 							doh.robot.typeKeys("editable", 1000, 1600);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
@@ -169,13 +153,43 @@
 							doh.robot.typeKeys(" again", 1000, 1200);
 							doh.robot.keyPress(dojo.keys.TAB, 500, {});
 							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(undefined, initialOnChange, "no onChange value");
 								doh.is('$567.00', dijit.byId("dollar_as").get("value"), "value");
 								doh.is('editable again', inlineBox.get("value"), "value");
+								doh.is('editable again', inlineBox._onChangeValue, "onChange value");
 							}), 1000);
 							return d;
 						}
 					},
 					{
+						name: "onChange set value",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var inlineBox = dijit.byId("editable");
+							inlineBox.set("value", "programmatic value");
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("programmatic value", inlineBox._onChangeValue, "programmatic set causes onChange");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "onChange programmatic creation",
+						timeout: 2000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							var inlineBox = dijit.byId("programmatic");
+							inlineBox.edit();
+							inlineBox.wrapperWidget.editWidget.set('value', 'changed');
+							inlineBox.save();
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("changed", inlineBox._onChangeValue, "editing causes onChange");
+							}), 500);
+							return d;
+						}
+					},
+					{
 						name: "Textarea test",
 						timeout: 15000,
 						runTest: function(){
@@ -199,94 +213,46 @@
 				// For example, in this markup:
 				//		<span dojoType="dijit.InlineEditBox" ...>01/05/2007</span>
 				// When the editor is clicked the calendar should open to that date.
-				doh.register("dijit.InlineEditBox preDefinedValue tests", [
-					{
-						name: "CurrencyTextBox preDefinedValue",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("dollar");
-							moveAndClick(inlineBox.domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is('$2,000', inlineBox.get("value"), "value");
-								var currencyTextBox = inlineBox.wrapperWidget.editWidget;
-								doh.is('2000.00', currencyTextBox.get("displayedValue"), "displayedValue");
-							}), 1000);
-							cancel(d, inlineBox);
-							testOK(d);
-							return d;
-						}
-					},
-					{
-						name: "NumberSpinner preDefinedValue",
-						timeout: 10000,
+				dojo.forEach([
+					{ widget: "CurrencyTextBox", id: "dollar", textValue: "$2,000", widgetValue: 2000 },
+					{ widget: "NumberTextBox", id: "quantity", textValue: "3", widgetValue: 3 },
+					{ widget: "ComboBox", id: "item", textValue: "refrigerators", widgetValue: "refrigerators" },
+					{ widget: "DateTextBox", id: "purchase", textValue: "01/05/2007", widgetValue: dojo.date.locale.parse("01/05/2007", {datePattern: 'MM/dd/yyyy', selector:'date'}) },
+					{ widget: "FilteringSelect", id: "state", textValue: "Pennsylvania", widgetValue: "PA" }
+				], function(test){
+					doh.register("preDefinedValue " + test.widget, {
+						timeout: 5000,
+ 						name: dojo.toJson(test.id),
 						runTest: function(){
 							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("quantity");
+							var inlineBox = dijit.byId(test.id);
+							var handler = inlineBox.connect(inlineBox, 'edit',
+								function(){
+									inlineBox.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");
+										doh.is(typeof expected, typeof actual, "editor value typeof");
+										doh.is(expected.toString(), actual.toString(), "editor widget value");
+										handler = inlineBox.connect(inlineBox, 'onCancel',
+											function(){
+												inlineBox.disconnect(handler);
+												setTimeout(d.getTestCallback(function(){
+													doh.t(isHidden(inlineBox.wrapperWidget), "editor widget should hidden");
+												}), 500);
+											});
+										var buttons = dojo.query(".cancelButton", inlineBox.domNode.parentNode);
+										moveAndClick(buttons[buttons.length-1]);
+									}), 1000);
+								});
 							moveAndClick(inlineBox.domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is(3, inlineBox.get("value"));
-								var numberSpinner = inlineBox.wrapperWidget.editWidget;
-								doh.is(3, numberSpinner.get("value"));
-							}), 1000);
-							cancel(d, inlineBox);
-							testOK(d);
 							return d;
 						}
-					},
-					{
-						name: "ComboBox preDefinedValue",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("item");
-							moveAndClick(inlineBox.domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("refrigerators", dojo.trim(inlineBox.get("value")));
-								var comboBox = inlineBox.wrapperWidget.editWidget;
-								doh.is("refrigerators", comboBox.get("value"));
-							}), 1000);
-							cancel(d, inlineBox);
-							testOK(d);
-							return d;
-						}
-					},
-					{
-						name: "DateTextBox preDefinedValue",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("purchase");
-							moveAndClick(inlineBox.domNode);
-							var preDate = dojo.date.locale.parse("01/05/2007", {datePattern: 'MM/dd/yyyy', selector:'date'});
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("01/05/2007", inlineBox.get("value"));
-								var dateTextBox = inlineBox.wrapperWidget.editWidget;
-								doh.is(preDate.toString(), dateTextBox.get("value").toString());
-							}), 1000);
-							cancel(d, inlineBox);
-							testOK(d);
-							return d;
-						}
-					},
-					{
-						name: "FilteringSelect preDefinedValue",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-							var inlineBox = dijit.byId("state");
-							moveAndClick(inlineBox.domNode);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.is("Pennsylvania", dojo.trim(inlineBox.get("value")));
-								var filteringSelect = inlineBox.wrapperWidget.editWidget;
-								doh.is("PA", filteringSelect.get("value"));
-							}), 1000);
-							cancel(d, inlineBox);
-							testOK(d);
-							return d;
-						}
-					}
-				]);
+					})
+				});
 
 				doh.register("renderAsHtml", [
 
@@ -373,20 +339,31 @@
 					}
 				]);
 
-
 				doh.register("focus tests", [
 					{
 						name: "RTE",
-						timeout: 10000,
+						timeout: 7000,
 						runTest: function(){
 							var d = new doh.Deferred();
 							var inlineBox = dijit.byId("inlineRTE");
+							var handler = inlineBox.connect(inlineBox, 'edit',
+								function(){
+									inlineBox.disconnect(handler);
+									setTimeout(function(){
+										handler = inlineBox.connect(inlineBox, 'save',
+											function(){
+												inlineBox.disconnect(handler);
+												setTimeout(d.getTestCallback(function(){
+													doh.t(isHidden(inlineBox.wrapperWidget), "editor widget should visible");
+													doh.t(inlineBox.get("value").indexOf('!start!') >= 0, "value changed");
+												}), 1000);
+											});
+										doh.robot.typeKeys("!start!", 1, 1400);
+										var buttons = dojo.query(".saveButton", inlineBox.domNode.parentNode);
+										moveAndClick(buttons[buttons.length-1]);
+									}, 1000);
+								});
 							moveAndClick(inlineBox.domNode);
-							doh.robot.typeKeys("!start!", 1000, 1400);
-							save(d, inlineBox);
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(inlineBox.get("value").indexOf('!start!') >= 0, "value changed");
-							}), 1000);
 							return d;
 						}
 					}
diff --git a/dijit/tests/robot/Menu_a11y.html b/dijit/tests/robot/Menu_a11y.html
index 12d2b01..80ce436 100644
--- a/dijit/tests/robot/Menu_a11y.html
+++ b/dijit/tests/robot/Menu_a11y.html
@@ -21,7 +21,6 @@
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_Menu.html');
 
-				if(!(dojo.isSafari < 4)){ // Tab-focus not well supported on old Safari
 				doh.register("dijit.MenuBar general keyboard tests",[
 					{
 						name: "start focus on the link, outside of menubar",
@@ -439,7 +438,6 @@
 						}
 					}
 				]);
-				} // !dojo.isSafari
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Menu_iframe.html b/dijit/tests/robot/Menu_iframe.html
new file mode 100644
index 0000000..6baeb77
--- /dev/null
+++ b/dijit/tests/robot/Menu_iframe.html
@@ -0,0 +1,224 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Menu iframe 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_Menu_iframe.html');
+					
+				var handler, menu;
+				doh.register("TestMenuIFrame",[
+					{
+						name: "detachMenu",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							menu = dijit.byId("menu");
+							handler = menu.connect(menu, 'onOpen', function(){ d.errback(new doh._AssertFailure('user context menu should not have opened')); });
+							doh.robot.mouseMoveAt("detachMenu", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 1000, 1);
+							doh.robot.sequence(function(){
+								doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							}, 0);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.f(isVisible(menu.domNode));
+							})), 1000);
+
+							return d;
+						},
+						tearDown: function(){
+							menu.disconnect(handler);
+						}
+					},
+					{
+						name: "reattachMenu",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.global.scrollTo(0,0);
+							doh.robot.mouseMove(30, 30, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("reattachMenu", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 500, 1);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								var menu = dijit.byId("menu");
+								doh.t(isVisible(menu.domNode));
+							})), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "resetToDoc",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("resetToDoc", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 500, 1);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								var menu = dijit.byId("menu");
+								doh.t(isVisible(menu.domNode));
+
+								var iframe = dojo.byId("iframe");
+								var heading = dojo.withGlobal(iframe.contentWindow,'query', dojo, ["h1"])[0];
+								doh.is("Document 0", heading.innerHTML);
+							})), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "detachMenu2",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							menu = dijit.byId("menu");
+							handler = menu.connect(menu, 'onOpen', function(){ d.errback(new doh._AssertFailure('user context menu should not have opened')); });
+							doh.robot.mouseMoveAt("detachMenu", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 1000, 1);
+							doh.robot.sequence(function(){
+								doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							}, 0);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.f(isVisible(menu.domNode));
+							})), 1000);
+
+							return d;
+						},
+						tearDown: function(){
+							menu.disconnect(handler);
+						}
+					},
+					{
+						name: "reattachMenu2",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.global.scrollTo(0,0);
+							doh.robot.mouseMove(30, 30, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("reattachMenu", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 500, 1);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								var menu = dijit.byId("menu");
+								doh.t(isVisible(menu.domNode));
+							})), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "resetToBill",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("resetToBill", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 500, 1);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								var menu = dijit.byId("menu");
+								doh.t(isVisible(menu.domNode));
+
+								var iframe = dojo.byId("iframe");
+								var div = dojo.withGlobal(iframe.contentWindow,'query', dojo, ["div"])[0];
+								doh.is("bill was here", div.innerHTML);
+							})), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "detachMenu3",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							menu = dijit.byId("menu");
+							handler = menu.connect(menu, 'onOpen', function(){ d.errback(new doh._AssertFailure('user context menu should not have opened')); });
+							doh.robot.mouseMoveAt("detachMenu", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 1000, 1);
+							doh.robot.sequence(function(){
+								doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							}, 0);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								doh.f(isVisible(menu.domNode));
+							})), 1000);
+
+							return d;
+						},
+						tearDown: function(){
+							menu.disconnect(handler);
+						}
+					},
+					{
+						name: "reattachMenu3",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dojo.global.scrollTo(0,0);
+							doh.robot.mouseMove(30, 30, 500);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("reattachMenu", 500, 1);
+							doh.robot.mouseClick({left:true}, 500);
+							doh.robot.mouseMoveAt("iframe", 500, 1);
+							doh.robot.mouseClick({right:true}, 500);
+							
+							doh.robot.sequence(d.getTestCallback(dojo.hitch(this, function(){
+								var menu = dijit.byId("menu");
+								doh.t(isVisible(menu.domNode));
+							})), 1000);
+
+							return d;
+						}
+					}
+				]);
+				
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/robot/Menu_mouse.html b/dijit/tests/robot/Menu_mouse.html
index 663ff4e..0563d47 100644
--- a/dijit/tests/robot/Menu_mouse.html
+++ b/dijit/tests/robot/Menu_mouse.html
@@ -34,7 +34,7 @@
 							doh.t(isHidden("fileMenu"), "File menu is hidden");
 
 							// Move over the File MenuBarItem
-							doh.robot.mouseMoveAt("file", 500);
+							doh.robot.mouseMoveAt("file", 500, 1000);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// The "File" MenuBarItem should be highlighted
@@ -56,7 +56,7 @@
 							var d = new doh.Deferred();
 
 							// click the File MenuBarItem
-							doh.robot.mouseMoveAt("file", 500);
+							doh.robot.mouseMoveAt("file", 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -85,7 +85,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("edit", 500);
+							doh.robot.mouseMoveAt("edit", 500, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// Since we've already activated the MenuBar by clicking "File",
@@ -106,7 +106,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("copy", 500);
+							doh.robot.mouseMoveAt("copy", 500, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.f(dojo.hasClass("edit", "dijitMenuItemHover"),
@@ -126,21 +126,20 @@
 
 					{
 						name: "click copy",
-						timeout: 4000,
+						timeout: 2000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							var clicked = false;
-							dijit.byId("copy").onClick = function(){ clicked = true; };
-
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(clicked, "copy was clicked");
+							var w = dijit.byId("copy");
+							var orig = w.onClick;
+							w.onClick = d.getTestCallback(function(){
+								w.onClick = orig;
 								doh.t(isHidden("editMenu"), "edit menu disappeared");
 								doh.f(dojo.hasClass("edit", "dijitMenuItemSelected"),
 									"Edit MenuBarItem should no longer have selected effect, actual class is: " + dojo.byId("edit").className);
-							}), 500);
+							});
+
+							doh.robot.mouseClick({left: true}, 1);
 
 							return d;
 						}
@@ -157,7 +156,7 @@
 							doh.t(isHidden("fileMenu"), "File menu is hidden");
 
 							// Move over the File MenuBarItem
-							doh.robot.mouseMoveAt("file", 500);
+							doh.robot.mouseMoveAt("file", 500, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// The "File" MenuBarItem should be highlighted
@@ -191,7 +190,7 @@
 							doh.f(dojo.hasClass("navMenuPopupItem1", "dijitMenuItemHover"), "navMenuPopupItem1 MenuItem doesn't have hover effect");
 							doh.t(isHidden("navMenuSub1"), "sub menu is hidden");
 
-							doh.robot.mouseMoveAt("navMenuPopupItem1", 500);
+							doh.robot.mouseMoveAt("navMenuPopupItem1", 500, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
 								// The "enabled submenu" MenuItem should be highlighted
@@ -240,7 +239,7 @@
 
 							doh.f(dijit.byId("checked2").get('checked'), "not initially checked");
 
-							doh.robot.mouseMoveAt("checked2", 500);
+							doh.robot.mouseMoveAt("checked2", 500, 1);
 							doh.robot.mouseClick({left: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -255,7 +254,7 @@
 				doh.register("Context menu mouse tests", [
 					{
 						name: "open global context menu (mouse)",
-						timeout: 3000,
+						timeout: 4000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
@@ -264,7 +263,7 @@
 							doh.t(isHidden(menu), "menu should be initially hidden");
 
 							// click random point on screen
-							doh.robot.mouseMoveAt("link", 500);
+							doh.robot.mouseMoveAt("link", 500, 500);
 							doh.robot.mouseClick({right: true}, 500);
 
 							doh.robot.sequence(d.getTestCallback(function(){
@@ -275,9 +274,9 @@
 
 								doh.t(menuCoords.x > linkCoords.x, "to right of link left edge");
 								doh.t(menuCoords.x < linkCoords.x + linkCoords.w, "to left of link right edge");
-								doh.t(menuCoords.y > linkCoords.y, "starts below top of link");
-								doh.t(menuCoords.y < linkCoords.x + linkCoords.h, "starts above bottom of link");
-							}), 500);
+								doh.t(menuCoords.y > linkCoords.y, "menu (" + menuCoords.y + ") starts below top of link (" + linkCoords.y + ")");
+								doh.t(menuCoords.y < linkCoords.y + linkCoords.h, "menu (" + menuCoords.y + ") starts above bottom of link (" + linkCoords.y + "+" + linkCoords.h + ")");
+							}), 1000);
 
 							return d;
 						}
@@ -301,24 +300,76 @@
 
 							return d;
 						}
+					},
+
+					{
+						name: "open context menu over form widget (mouse)",
+						timeout: 5000,
+						runTest: function(){
+							var d = new doh.Deferred();
+	
+							var menu = dijit.byId("windowContextMenu");
+	
+							doh.t(isHidden(menu), "menu should be initially hidden");
+	
+							// right-click on form widget
+							doh.robot.mouseMoveAt("formwidget", 500, 1);
+							doh.robot.mouseClick({right: true}, 500);
+	
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible(menu), "menu is now shown");
+	
+								var widgetCoords = dojo.position("formwidget");
+									menuCoords = dojo.position(menu.domNode);
+	
+								doh.t(((menuCoords.x > widgetCoords.x) && (menuCoords.x < (widgetCoords.x + widgetCoords.w))) ||
+									(((menuCoords.x + menuCoords.w) > widgetCoords.x) && ((menuCoords.x + menuCoords.w) < (widgetCoords.x + widgetCoords.w))),
+									"begins or ends within the form widget horizontal boundaries");
+								doh.t(((menuCoords.y > widgetCoords.y) && (menuCoords.y < (widgetCoords.y + widgetCoords.h))) ||
+									(((menuCoords.y + menuCoords.h) > widgetCoords.y) && ((menuCoords.y + menuCoords.h) < (widgetCoords.y + widgetCoords.h))),
+									"begins or ends within the form widget vertical boundaries");
+							}), 1000);
+	
+							return d;
+						}
+					},
+
+					{
+						name: "close form widget context menu (mouse)",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var menu = dijit.byId("windowContextMenu");
+
+							// close menu from above test
+							doh.robot.mouseMove(2, 2, 100);
+							doh.robot.mouseClick({left: true}, 100);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isHidden(menu), "menu should be hidden again");
+							}), 1000);
+
+							return d;
+						}
 					}
 				]);
 
 				doh.register("More MenuBar mouse tests", [
 					{
 						name: "MenuBar selection and cancellation",
-						timeout: 20000,
+						timeout: 15000,
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("file", 500);
+							doh.robot.mouseMoveAt("file", 500, 1000);
 							doh.robot.mouseClick({left: true}, 500); // click File
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible("fileMenu"), "File menu should be visible #1");
 							}), 1000);
 
 							doh.robot.mouseClick({left: true}, 500); // close File menu
-							doh.robot.mouseMoveAt("edit", 500);
+							doh.robot.mouseMoveAt("edit", 500, 500);
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden("fileMenu"), "File menu is hidden #1");
@@ -333,9 +384,9 @@
 							}), 1000);
 
 							doh.robot.mouseClick({left: true}, 500); // open edit menu
-							doh.robot.mouseMoveAt("paste", 1000);
+							doh.robot.mouseMoveAt("paste", 1000, 1);
 							doh.robot.mouseClick({left: true}, 500); // click paste, closing edit menu
-							doh.robot.mouseMoveAt("edit", 1000);
+							doh.robot.mouseMoveAt("edit", 1000, 500);
 
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(dojo.hasClass("edit", "dijitMenuItemHover"),
@@ -343,31 +394,51 @@
 								doh.t(isHidden("editMenu"), "edit menu disappeared #1");
 							}), 1000);
 
-							doh.robot.mouseMoveAt("file", 500);
+							doh.robot.mouseMoveAt("file", 500, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden("fileMenu"), "File menu should be hidden #2");
 							}), 500);
 
-							doh.robot.mouseClick({left: true}, 500); // click File
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("fileMenu"), "File menu should be visible #2");
-							}), 1000);
-
-							doh.robot.mouseMoveAt("view", 0, 150); // #9846
-							doh.robot.mouseMoveAt("edit", 0, 75);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isHidden("fileMenu"), "File menu should be hidden #3");
-								doh.t(isVisible("editMenu"), "Edit menu should be visible");
-								var paste = dojo.position('paste');
-								doh.robot._mouseMove(paste.x + (paste.w >> 1), paste.y + paste.h + 20, false, 500);
-							}), 500, 1000);
-
-							// click point on screen under the Edit menu
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								doh.t(isHidden("editMenu"), "edit menu disappeared #2");
-							}), 1000);
+							doh.robot.sequence(function(){
+								var
+								fileMenu = dijit.byId("fileMenu"),
+								editMenu = dijit.byId("editMenu"),
+								handler = fileMenu.connect(fileMenu, 'onOpen',
+									function(){
+										fileMenu.disconnect(handler);
+										setTimeout(d.getTestErrback(function(){
+											doh.t(isVisible(fileMenu), "File menu should be visible #2");
+											handler = fileMenu.connect(fileMenu, 'onClose',
+												function(){
+													fileMenu.disconnect(handler);
+													setTimeout(d.getTestErrback(function(){
+														doh.t(isHidden(fileMenu), "File menu should be hidden #3");
+														handler = editMenu.connect(editMenu, 'onOpen',
+															function(){
+																editMenu.disconnect(handler);
+																setTimeout(d.getTestErrback(function(){
+																	doh.t(isVisible(editMenu), "Edit menu should be visible");
+																	handler = editMenu.connect(editMenu, 'onClose',
+																		function(){
+																			editMenu.disconnect(handler);
+																			setTimeout(d.getTestCallback(function(){
+																				doh.t(isHidden(editMenu), "Edit menu disappeared #2");
+																			}), 150);
+																		});
+																	var paste = dojo.position('paste');
+																	doh.robot._mouseMove(paste.x + (paste.w >> 1), paste.y + paste.h + 20, false, 1);
+																	// click point on screen under the Edit menu
+																	doh.robot.mouseClick({left: true}, 100);
+																}), 150);
+															});
+														doh.robot.mouseMoveAt("edit", 0, 1);
+													}), 150);
+												});
+											doh.robot.mouseMoveAt("view", 0, 1); // #9846
+										}), 150);
+									});
+							}, 1);
+							doh.robot.mouseClick({left: true}, 1); // click File that starts the event sequence above
 
 							return d;
 						}
@@ -377,14 +448,13 @@
 						name: "MenuBar navigation with BOTH mouse and keyboard",
 						timeout: 20000,
 						runTest: function(){
-						    if(!(dojo.isSafari < 4)){ // doesn't support keyboard navigation
 							var d = new doh.Deferred();
 
 							// click random point on screen
-							doh.robot.mouseMoveAt("link", 500);
+							doh.robot.mouseMoveAt("link", 500, 500);
 							doh.robot.mouseClick({left: true}, 500); // click link to focus it
 
-							doh.robot.mouseMoveAt("view", 500);
+							doh.robot.mouseMoveAt("view", 500, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(dojo.hasClass("view", "dijitMenuItemHover"),
 									"View MenuBarItem should have hover effect, actual class is: " + dojo.byId("view").className);
@@ -401,7 +471,7 @@
 									"View MenuBarItem shouldn't have hover effect anymore, actual class is: " + dojo.byId("view").className);
 							}), 1000);
 
-							doh.robot.mouseMoveAt("edit", 500);
+							doh.robot.mouseMoveAt("edit", 500, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(dojo.hasClass("edit", "dijitMenuItemHover"),
 									"Edit MenuBarItem should have hover effect, actual class is: " + dojo.byId("edit").className);
@@ -419,7 +489,6 @@
 							}), 1000);
 
 							return d;
-						    }
 						}
 					}
 				]);
@@ -431,7 +500,7 @@
 						runTest: function(){
 							var d = new doh.Deferred();
 
-							doh.robot.mouseMoveAt("navMenuPopupItem1", 500); // move to Enabled submenu
+							doh.robot.mouseMoveAt("navMenuPopupItem1", 500, 500); // move to Enabled submenu
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden("navMenuSub1"), "Enabled submenu should be hidden");
 							}), 500);
@@ -441,7 +510,7 @@
 								doh.t(isVisible("navMenuSub1"), "Enabled submenu should be visible");
 							}), 1000);
 
-							doh.robot.mouseMoveAt("navMenuDisabledItem", 500);
+							doh.robot.mouseMoveAt("navMenuDisabledItem", 500, 500);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isHidden("navMenuSub1"), "Enabled submenu should be hidden");
 							}), 1000); // linger long enough for menu to close
diff --git a/dijit/tests/robot/TitlePane.html b/dijit/tests/robot/TitlePane.html
index 159a4ab..4809a9a 100644
--- a/dijit/tests/robot/TitlePane.html
+++ b/dijit/tests/robot/TitlePane.html
@@ -247,6 +247,54 @@
 					}
 				]);
 
+				doh.register("TitlePane in AccordionContainer", [
+					{
+						name: "initial conditions",
+						runTest: function(){
+							// none of the TitlePane's inside of the AccordionContainer should have loaded
+							// their href, since they are closed
+					    	doh.f(dojo.global["actp1Loaded"], "closed TitlePane in open accordion pane not loaded");
+					    	doh.t(dojo.global["actp2Loaded"], "open TitlePane in open accordion pane loaded");
+					    	doh.f(dojo.global["actp3Loaded"], "first TitlePane in closed accordion pane not loaded");
+					    	doh.f(dojo.global["actp4Loaded"], "open TitlePane in closed accordion pane not loaded");
+						}
+					},
+
+					{
+						name: "switch open accordion pane",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dijit.byId("ac").selectChild(dijit.byId("accp2"));
+
+							setTimeout(d.getTestCallback(function(){
+						    	doh.f(dojo.global["actp1Loaded"], "closed TitlePane in newly closed accordion pane not loaded");
+						    	doh.f(dojo.global["actp3Loaded"], "closed TitlePane in newly opened accordion pane not loaded");
+						    	doh.t(dojo.global["actp4Loaded"], "opened TitlePane in newly opened accordion pane loaded");
+							}), 500);
+							
+							return d;
+						}
+					},
+
+					{
+						name: "open a TitlePane",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							dijit.byId("actp3").set("open", true);
+
+							setTimeout(d.getTestCallback(function(){
+						    	doh.t(dojo.global["actp3Loaded"], "opening TitlePane causes href to load");
+							}), 500);
+							
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Toolbar.html b/dijit/tests/robot/Toolbar.html
index 5e4d80a..3618eac 100644
--- a/dijit/tests/robot/Toolbar.html
+++ b/dijit/tests/robot/Toolbar.html
@@ -149,6 +149,37 @@
 							return d;
 						}
 					},
+	
+					{
+						name: "home/end keys",
+						timeout: 40000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Initial focus (upon tabbing into toolbar) should go to first enabled button,
+							// which is "italic", since "cut" and "copy" are disabled
+							toolbar1Before.focus();
+							doh.robot.keyPress(dojo.keys.TAB, 500, {});
+							doh.robot.sequence(d.getTestErrback(dojo.hitch(this, function(){
+								doh.is("toolbar1.italic", dojo.global.dijit._curFocus.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");
+							})), 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");
+							})), 1000);
+
+							return d;
+						}
+					},
 
 					// Test drop down ability.   These tests are probably redundant with the Button tests themselves,
 					// so they aren't strictly necessary.
diff --git a/dijit/tests/robot/TooltipDialog_mouse.html b/dijit/tests/robot/TooltipDialog_mouse.html
index bfff248..69a1106 100644
--- a/dijit/tests/robot/TooltipDialog_mouse.html
+++ b/dijit/tests/robot/TooltipDialog_mouse.html
@@ -21,21 +21,29 @@
 			dojo.addOnLoad(function(){
 				doh.robot.initRobot('../test_TooltipDialog.html');
 
-				doh.register("TooltipDialog", [
+				doh.register("Select", [
 					{
-						name: "Select",
+						name: "open TooltipDialog",
 						timeout: 10000,
 						runTest: function(){
-							var d = new doh.Deferred(),
-								select = dijit.byId("select");
+							var d = new doh.Deferred();
 							
-							// open TooltipDialog
 							doh.robot.mouseMoveAt("tooltipDlgButton", 1000);
 							doh.robot.mouseClick({left: true}, 1000);
-							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should be showing");
+							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)")
 							}), 1000);
+						}
+					},
 
+					{
+						name: "pick option from Select drop down",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								select = dijit.byId("select");
+							
 							// open Select
 							doh.robot.mouseMoveAt("select", 0);
 							doh.robot.mouseClick({left: true}, 1000);
@@ -50,13 +58,79 @@
 							}, 0);
 							doh.robot.mouseClick({left: true}, 1000);
 
-							doh.robot.sequence(d.getTestErrback(function(){
+							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("peppers", select.get("value"), "selected peppers");
 							}), 1000);
 
-							// close TooltipDialog
+							return d;
+						}
+					},
+
+					{
+						name: "close Select by clicking TooltipDialog",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								select = dijit.byId("select");
+							
+							// open Select
+							doh.robot.mouseMoveAt("select", 0);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(isVisible("select_menu"), "Select Menu showing too");
+							}), 1000);
+							
+							// click unfocusable area of TooltipDialog to get select to close
+							// (but TooltipDialog itself should remain open)
+							doh.robot.mouseMoveAt(function(){
+								return dojo.query("label[for='select']", dojo.byId("tooltipDlg"))[0];
+							}, 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");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "close select by clicking another control",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred(),
+								select = dijit.byId("select");
+							
+							// open Select
+							doh.robot.mouseMoveAt("select", 0);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestErrback(function(){
+								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
+								doh.t(isVisible("select_menu"), "Select Menu showing too");
+							}), 1000);
+							
+							// click TextBox to get select to close
+							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")
+							}), 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);
 
@@ -66,9 +140,12 @@
 
 							return d;
 						}
-					},
+					}
+				]);
+
+				doh.register("InlineEditBox", [
 					{
-						name: "InlineEditBox",
+						name: "auto-save",
 						timeout: 20000,
 						runTest: function(){
 							var d = new doh.Deferred(),
@@ -78,11 +155,11 @@
 							doh.robot.mouseMoveAt("tooltipDlgButton", 500);
 							doh.robot.mouseClick({left: true}, 1000);
 							doh.robot.sequence(d.getTestErrback(function(){
-								doh.t(isVisible("tooltipDlg"), "TooltipDialog should be showing");
+								doh.t(isVisible("tooltipDlg"), "TooltipDialog visible");
 							}), 1000);
 
 							// start editing InlineEditBox
-							doh.robot.mouseMoveAt("inline", 0);
+							doh.robot.mouseMoveAt("inline", 0, 500, 10, 5);
 							doh.robot.mouseClick({left: true}, 1000);
 							doh.robot.sequence(d.getTestErrback(function(){
 								doh.t(isVisible("tooltipDlg"), "TooltipDialog should still be showing");
@@ -114,6 +191,122 @@
 					}
 				]);
 
+				doh.register("Menu", [
+					{
+						name: "open outer TooltipDialog",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("outerDdBtn", 1000);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible("outerTtDialog"), "Outer TooltipDialog visible");
+							}), 1000);
+						}
+					},
+					{
+						name: "open inner TooltipDialog",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("innerDdBtn", 1000);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible("innerTtDialog"), "Inner TooltipDialog visible");
+							}), 1000);
+						}
+					},
+
+					{
+						name: "open submenu",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("popupMenuItem", 0);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible("innerTtDialog"), "inner TooltipDialog should still be showing");
+								doh.t(isVisible("submenu"), "nested Menu showing too");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close submenu by clicking inner TooltipDialog",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("plaintext", 0);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible("innerTtDialog"), "Inner TooltipDialog should still be showing");
+								doh.t(isHidden("submenu"), "SubMenu was closed");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "open submenu again",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("popupMenuItem", 0);
+							doh.robot.mouseClick({left: true}, 1000);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(isVisible("innerTtDialog"), "inner TooltipDialog should still be showing");
+								doh.t(isVisible("submenu"), "nested Menu showing too");
+							}), 1000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "close submenu by clicking another control",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							// click TextBox to get submenu to close
+							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")
+							}), 1000);
+						}
+					},
+
+					{
+						name: "close both TooltipDialogs",
+						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("innerTtDialog"), "inner Tooltip dialog closed");
+								doh.t(isHidden("outerTtDialog"), "inner Tooltip dialog closed");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
 				doh.run();
 			});
 		</script>
diff --git a/dijit/tests/robot/Tooltip_a11y.html b/dijit/tests/robot/Tooltip_a11y.html
index ea363ed..1689033 100644
--- a/dijit/tests/robot/Tooltip_a11y.html
+++ b/dijit/tests/robot/Tooltip_a11y.html
@@ -342,6 +342,14 @@
 
 							return d;
 						}
+					},
+
+					// Nominal tests for old dojoType syntax, remove in 2.0
+					function oldDojoTypeSyntax(){
+						var tooltip = dijit.byId("oldmulti1,oldmulti2_tooltip");
+						doh.is(2, tooltip.get("connectId").length);
+						doh.is("oldmulti1", tooltip.get("connectId")[0]);
+						doh.is("oldmulti2", tooltip.get("connectId")[1]);
 					}
 				]);
 
diff --git a/dijit/tests/robot/Tooltip_mouse_quirks.html b/dijit/tests/robot/Tooltip_mouse_quirks.html
new file mode 100644
index 0000000..0fba813
--- /dev/null
+++ b/dijit/tests/robot/Tooltip_mouse_quirks.html
@@ -0,0 +1,55 @@
+<!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("../quirks.html?file=test_Tooltip.html");
+
+				doh.register("dijit.Tooltip mouse quirks tests", [
+					// Test that BackgroundIFrame has right proportions; this used to fail in quirks mode
+					// because the BackgroundIFrame would overlap the calendar, blocking clicks on elements on the right.
+					{
+						name: "BackgroundIframe",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseMoveAt(dojo.query(".dijitArrowButton", dijit.byId("dtb").domNode)[0], 500);
+							doh.robot.mouseClick({left: true}, 500);
+
+							// Click Dec 4, 2010
+							doh.robot.mouseMoveAt(function(){
+								return dojo.query(".dijitCalendarDateLabel", dijit.byId("dtb_popup").domNode)[6];
+							} , 1000);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("12/4/2010", dijit.byId("dtb").get("displayedValue"));
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/robot/Tree_a11y.html b/dijit/tests/robot/Tree_a11y.html
deleted file mode 100644
index 21b8659..0000000
--- a/dijit/tests/robot/Tree_a11y.html
+++ /dev/null
@@ -1,772 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>doh.robot Tree 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">
-		dojo.require("dijit.robotx");
-
-		var treeIds = ["mytree", "tree2"];
-
-		function treeTests(){
-			var that = {};
-
-			var forceLoadChildItems = function(/*dijit._TreeNode*/inNode, /*dijit.Tree*/inTree){
-				if(inTree.model.mayHaveChildren(inNode.item)){
-					if(inNode.getChildren().length > 0){
-						return;
-					}
-					var childItems = null;
-					inTree.model.getChildren(inNode.item, function(items){ childItems = items; });
-					inNode.setChildItems(childItems);
-					childItems = null;
-				}
-			};
-
-			that.testTreeItemRole = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
-				if(inRoot){
-					doh.is("treeitem", dijit.getWaiRole(inRoot.labelNode), inRoot.label + "[" + inTree.id + "]: aria role (treeItem)");
-					//recurse
-					forceLoadChildItems(inRoot, inTree);
-					var children = inRoot.getChildren();
-					for(var i = 0; i < children.length; i++){
-						that.testTreeItemRole(children[i], inTree);
-					}
-				}
-			};
-
-			that.test1TreeItemExpandedState = function(/*dijit._TreeNode*/inItem, /*dijit.Tree*/inTree){
-				if(inItem){
-					if(inItem.isExpandable){
-						var wasExpanded = inItem.isExpanded;
-						inTree._expandNode(inItem);
-						var nowExpanded = dijit.getWaiState(inItem.labelNode, "expanded");
-						inTree._collapseNode(inItem);
-						var nowCollapsed = dijit.getWaiState(inItem.labelNode, "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");
-					}
-				}
-			};
-
-			that.testTreeItemExpandedState = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
-				if(inRoot){
-					that.test1TreeItemExpandedState(inRoot, inTree);
-					//recurse
-					forceLoadChildItems(inRoot, inTree);
-					var children = inRoot.getChildren();
-					for(var i = 0; i < children.length; i++){
-						that.testTreeItemExpandedState(children[i], inTree);
-					}
-				}
-			};
-
-			// Tab focus test data and functions
-			var xtraParas = [];
-			var expectedBlurCount = 0;
-			var focusCount = 0;
-			var blurCount = 0;
-			var gotFocus = function(){
-				focusCount++;
-			};
-			var lostFocus = function(){
-				blurCount++;
-			};
-			that.focusConnect = null;
-			that.blurConnect = null;
-
-			var addTabNavFoci = function(inTree){
-				var aPara = dojo.doc.createElement("p");
-				dojo.attr(aPara, 'tabIndex', 0);
-				aPara.innerHTML = "Tab-focussable paragraph just above " + inTree.id;
-				dojo.place(aPara, inTree.domNode, "before");
-				xtraParas.push(aPara);
-				aPara = dojo.doc.createElement("p");
-				dojo.attr(aPara, 'tabIndex', 0);
-				aPara.innerHTML = "Tab-focussable paragraph just below  " + inTree.id;
-				dojo.place(aPara, inTree.domNode, "after");
-				xtraParas.push(aPara);
-			};
-
-			var walkTreeToLeaf = function(inTree, inRootNode, /*array, optional*/ioPath){
-				var leaf = inRootNode;
-				if (ioPath){ ioPath.push(inRootNode); }
-				if(inRootNode.isExpandable){
-					forceLoadChildItems(inRootNode, inTree);
-					inTree._expandNode(inRootNode);
-					var down = inRootNode.getChildren()[0];
-					if(down){
-						leaf = walkTreeToLeaf(inTree, down, ioPath);
-					}
-				}
-				return(leaf);
-			};
-
-			that.tabFocusSetup = function(inTreeId, /*boolean*/ leaf){
-				var tree = dijit.byId(inTreeId);
-				that.collapseAllButRoot(tree);
-				addTabNavFoci(tree);
-				// set up focus listener machinery
-				focusCount = blurCount = 0;
-				var focusThing;
-				if(leaf){
-					focusThing = walkTreeToLeaf(tree, tree.rootNode);
-				}else if(tree.showRoot){
-					focusThing = tree.rootNode;
-				}else{
-					focusThing = tree.rootNode.getChildren()[0];
-				}
-				that.focusConnect = tree.connect(focusThing.labelNode, "onfocus", gotFocus);
-				that.blurConnect = tree.connect(focusThing.labelNode, "onblur", lostFocus);
-				tree.focusNode(focusThing);
-			};
-
-			that.tabFocusA11yTest = function(inTreeId){
-				var d = new doh.Deferred();
-				var tree = dijit.byId(inTreeId);
-				// shift+tab away, tab back, tab away, shift+tab back
-				doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
-				doh.robot.keyPress(dojo.keys.TAB, 300);
-				doh.robot.keyPress(dojo.keys.TAB, 300);
-				doh.robot.keyPress(dojo.keys.TAB, 300, {shift:true});
-				var checkTabNav = function(){
-					tree.disconnect(that.focusConnect);
-					tree.disconnect(that.blurConnect);
-					doh.is(3, focusCount,  tree.id + ": # of times focussed");
-					doh.is(2, blurCount, tree.id + ": # of times lost focus");
-				};
-				doh.robot.sequence(d.getTestCallback(checkTabNav), 500);
-				return d;
-			};
-
-			that.tabFocusTearDown = function(){
-				dojo.forEach(xtraParas, function(item){
-					item.parentNode.removeChild(item);
-				});
-				xtraParas.length = 0;
-				that.focusCount = 0;
-				that.blurCount = 0;
-			};
-
-			// arrow key navigation, expand, and collapse tests.
-			that.collapseAllButRoot = function(inTree){
-				function collapse(node){
-					if(node){
-						var children = node.getChildren();
-						dojo.forEach(children, function(child){
-							if(child.isExpandable){
-								collapse(child);
-								inTree._collapseNode(child);
-							}
-						});
-					}
-				}
-				if(inTree){
-					collapse(inTree.rootNode);
-				}
-			};
-
-			that.openConnect = null;
-			that.closeConnect = null;
-			var openedLabels = [];
-			var closedLabels = [];
-
-			that.a11yNavExpandCollapseSetup = function(inTreeId){
-				var tree = dijit.byId(inTreeId);
-				that.collapseAllButRoot(tree);
-				var startingNode = tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0];
-				tree.focusNode(startingNode);
-				var rootChilds = tree.rootNode.getChildren();
-				// down, right (open), left (close), down, left (open)
-				if(tree.showRoot){
-					openedLabels[0] = { expected: rootChilds[0].label };
-					openedLabels[1] = { expected: rootChilds[1].label };
-				}else{
-					openedLabels[0] = { expected: rootChilds[1].label };
-					openedLabels[1] = { expected: rootChilds[2].label };
-				}
-				closedLabels[0] = openedLabels[0];
-				var openIdx = 0;
-				var collectOpen = function(item, node){
-					openedLabels[openIdx].actual = node.label;
-				};
-				var collectClose = function(item, node){
-					closedLabels[openIdx].actual = node.label;
-					openIdx++;
-				};
-				that.openConnect = dojo.connect(tree, "onOpen", collectOpen);
-				that.closeConnect = dojo.connect(tree, "onClose", collectClose);
-			};
-
-			that.a11yNavExpandCollapseTest = function(inTreeId){
-				var d = new doh.Deferred();
-				// assume (1) collapaseAllButRoot(), and (2) focus is on first visible child.
-				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);		// move down one
-				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
-				doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse
-				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down one
-				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
-				var checkKeystrokes = function(){
-					for(var idx = 0; idx < openedLabels.length; idx++){
-						doh.is(openedLabels[idx].expected, openedLabels[idx].actual, "onOpen");
-					}
-					for(idx = 0; idx < closedLabels.length; idx++){
-						doh.is(closedLabels[idx].expected, closedLabels[idx].actual, "onClose");
-					}
-				};
-				doh.robot.sequence(d.getTestCallback(checkKeystrokes), 500);
-				return d;
-			};
-
-			that.a11yNavExpandCollapseTearDown = function(){
-				dojo.disconnect(that.openConnect);
-				dojo.disconnect(that.closeConnect);
-			};
-
-			var expectedNode;
-			var actualNode;
-			var arrowDownCount;
-			var arrowRightCount;
-
-			that.a11yNavToLeafSetup = function(inTreeId){
-				var tree = dijit.byId(inTreeId);
-				// randomly choose a top-level node to traverse.
-				arrowDownCount = Math.floor(Math.random() * tree.rootNode.getChildren().length);
-				var path = [];
-				expectedNode = walkTreeToLeaf(tree, tree.rootNode.getChildren()[arrowDownCount], path);
-				that.collapseAllButRoot(tree);
-				if(tree.showRoot){
-					tree.focusNode(tree.rootNode);
-					arrowDownCount++;
-				}else{
-					tree.focusNode(tree.rootNode.getChildren()[0]);
-				}
-				// 1 to open root node, 2 for every non-leaf, 1 to get to the leaf
-				arrowRightCount = 1 + (path.length - 2)*2 + 1;
-				that.focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
-					actualNode = evt.target;
-				});
-			};
-
-			that.a11yNavToLeaf = function(inTreeId){
-				var d = new doh.Deferred();
-				var tree = dijit.byId(inTreeId);
-				// assume (1) collapseAllButRoot(), and (2) focus is on a top level tree node.
-				for(var i = 0; i < arrowDownCount; i++) {
-					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
-				}
-				for(i = 0; i < arrowRightCount; i++){
-					doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);
-				}
-				var checkLeaf = function(){
-					tree.disconnect(that.focusConnect);
-					doh.is(expectedNode.labelNode, actualNode, "expected: " + expectedNode.label + ", actual: " + actualNode.innerHTML);
-				};
-				doh.robot.sequence(d.getTestCallback(checkLeaf), 500);
-				return d;
-			};
-
-			that.lastVisibleNode = function(inTree){
-				var node = inTree.rootNode;
-				while(node.isExpanded){
-					var c = node.getChildren();
-					node = c[c.length-1];
-				}
-				return node;
-			};
-
-			that.a11yHomeEndKeySetup = function(inTreeId, inKey){
-				// put focus on an random leaf.
-				var tree = dijit.byId(inTreeId);
-				that.collapseAllButRoot(tree);
-				var topLvl = Math.floor(Math.random() * tree.rootNode.getChildren().length);
-				var leaf = walkTreeToLeaf(tree, tree.rootNode.getChildren()[topLvl]);
-				tree.focusNode(leaf);
-				// determine the expected/actual home.
-				if(inKey == dojo.keys.HOME){
-					expectedNode = ( tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0] );
-				}else{
-					expectedNode = that.lastVisibleNode(tree);
-				}
-				focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
-					actualNode = evt.target;
-				});
-			};
-
-			that.a11yHomeEndKeyTest = function(inTreeId, inKey){
-				var d = new doh.Deferred();
-				var tree = dijit.byId(inTreeId);
-				doh.robot.keyPress(inKey, 300);
-				var checkAtHomeEnd = function(){
-					tree.disconnect(focusConnect);
-					doh.is(expectedNode.label, actualNode.innerHTML);
-				}
-				doh.robot.sequence(d.getTestCallback(checkAtHomeEnd), 500);
-				return d;
-			};
-
-			return that;
-		}
-
-		dojo.addOnLoad(function(){
-			doh.robot.initRobot('../test_Tree.html');
-			var treeTest = treeTests();
-
-			// aria role and properties tests.
-			doh.register("a11yAria",
-			[
-				function ariaTreeRole(){
-					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						doh.is("tree", dijit.getWaiRole(tree.domNode), tree.id + ": aria role (tree)");
-					}
-				},
-
-				function ariaTreeStateExpanded(){
-					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						var wasExpanded = tree.rootNode.isExpanded;
-						tree.rootNode.expand();
-						var nowExpanded = dijit.getWaiState(tree.domNode, "expanded");
-						tree.rootNode.collapse();
-						var nowCollapsed = dijit.getWaiState(tree.domNode, "expanded");
-						if(wasExpanded){
-							tree.rootNode.expand();
-						}
-						doh.is("true", nowExpanded, tree.id + ": aria state expanded=true");
-						doh.is("false", nowCollapsed, tree.id + ": aria state expanded=false ");
-					}
-				},
-
-				function ariaTreeItemRole(){
-					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						treeTest.testTreeItemRole(tree.rootNode, tree);
-					}
-				},
-
-				function ariaTreeItemStateExpanded(){
-					for(i=0; i<treeIds.length; i++){
-						var tree = dijit.byId(treeIds[i]);
-						treeTest.testTreeItemExpandedState(tree.rootNode, tree);
-					}
-				}
-			]);
-
-			// Keyboard focus robot tests
-			doh.register("a11y tab navigation",
-			[
-				{
-					name:"mytreeTabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('mytree', false);
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('mytree');
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
-					}
-				},
-				{
-					name:"tree2TabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('tree2');
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('tree2', false);
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
-					}
-				},
-				{
-					name:"mytreeExpandedTabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('mytree', true);
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('mytree');
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
-					}
-				},
-				{
-					name:"tree2ExpandedTabFocusTest",
-					timeout:4000,
-					setUp:function(){
-						treeTest.tabFocusSetup('tree2', true);
-					},
-					runTest:function(){
-						return treeTest.tabFocusA11yTest('tree2');
-					},
-					tearDown:function(){
-						treeTest.tabFocusTearDown();
-					}
-				}
-			]);
-
-			// Keyboard navigate/expand/collapse robot tests (arrow keys, and home/end)
-			doh.register("keyboard arrow navigation/expand/collapse",
-			[
-				{
-					name:"mytreeNavExpandCollpaseA11y",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavExpandCollapseSetup('mytree');
-					},
-					runTest:function(){
-						return treeTest.a11yNavExpandCollapseTest('mytree');
-					},
-					tearDown: function(){
-						treeTest.a11yNavExpandCollapseTearDown();
-					}
-				},
-				{
-					name:"tree2NavExpandCollpaseA11y",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavExpandCollapseSetup('tree2');
-					},
-					runTest:function(){
-						return treeTest.a11yNavExpandCollapseTest('tree2');
-					},
-					tearDown: function(){
-						treeTest.a11yNavExpandCollapseTearDown();
-					}
-				},
-				{
-					name:"mytreeNavToLeaf",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavToLeafSetup('mytree');
-					},
-					runTest:function(){
-						return treeTest.a11yNavToLeaf('mytree');
-					}
-				},
-				{
-					name:"tree2NavToLeaf",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yNavToLeafSetup('tree2');
-					},
-					runTest:function(){
-						return treeTest.a11yNavToLeaf('tree2');
-					}
-				},
-				{
-					name:"mytreeNavToHome",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.HOME);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.HOME);
-					}
-				},
-				{
-					name:"mytreeNavToEnd",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.END);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.END);
-					}
-				},
-				{
-					name:"tree2NavToHome",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.HOME);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.HOME);
-					}
-				},
-				{
-					name:"tree2NavToEnd",
-					timeout:4000,
-					setUp:function(){
-						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.END);
-					},
-					runTest:function(){
-						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.END);
-					}
-				}
-			]);
-
-			// Test for typing "a" to navigate to nodes that start with "a", etc.
-			doh.register("keyboard search tests",
-			[
-				{
-					name:"Setup tree",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var tree = dijit.byId("mytree");
-
-						// Close all tree nodes except for Asia and Oceania
-						dojo.forEach(tree.rootNode.getChildren(), function(child, idx){
-							if(child.label == "Asia" || child.label == "Oceania"){
-								console.log("expanding " + child.label);
-								if(!child.isExpanded){
-									tree._expandNode(child);
-								}
-							}else{
-								console.log("collapsing " + child.label);
-								if(child.isExpanded){
-									tree._collapseNode(child);
-								}
-							}
-						});
-
-						doh.robot.sequence(d.getTestCallback(function(){
-							// Just waiting for animation to finish...
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"Focus on Continents",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var tree = dijit.byId("mytree");
-						tree.focusNode(tree.rootNode);
-
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dojo.global.dijit._curFocus;
-							doh.t(tree.rootNode.labelNode, "focused on continents");
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"First 'A' key goes to Africa",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						// From Continents node, press "A".   Should go to Africa.
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Africa", focus.label);
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"Second 'A' key goes to Asia",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						// From Africa node, press "A" again.   Should go to Asia.
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Asia", focus.label);
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"Third 'A' key goes to Australia (nested node)",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var oceania = dijit.byId("mytree").rootNode.getChildren()[2];
-						doh.t(oceania, "found Oceania node");
-						doh.t(oceania.isExpanded, "Oceania node is expanded");
-
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Australia", focus.label);
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"Fourth 'A' key loops back to Africa",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						doh.robot.keyPress("a", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Africa", focus.label);
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"multi-key navigation",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						// Skip over China and go to Continents
-						doh.robot.typeKeys("co", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Continents", focus.label);
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"multi-key navigation",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						// By typing AS should skip over Africa and go to Asia
-						doh.robot.typeKeys("as", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("Asia", focus.label);
-						}), 500);
-
-						return d;
-					}
-				},
-				{
-					name:"multi-key navigation clears",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						// After the 500ms delay from above, typing a new character should
-						// start a new search
-						doh.robot.typeKeys("n", 100);
-						doh.robot.sequence(d.getTestCallback(function(){
-							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
-							doh.t(focus, "there is a focused widget");
-							doh.is("North America", focus.label);
-						}), 500);
-
-						return d;
-					}
-				}
-			]);
-
-			doh.register("selection and focus",
-			[
-				{
-					name:"select Africa",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var tree = dijit.byId("mytree");
-
-						doh.robot.keyPress(dojo.keys.HOME, 300);			// go to Continents
-						doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
-						doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Africa
-						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Africa", tree.lastFocused.label, "Africa is focused");
-
-							var item = tree.get("selectedItem"),
-								label = tree.model.getLabel(item);
-							doh.is("Africa", label, "Africa is selected");
-						}), 500);
-
-						return d;
-					}
-				},
-
-				{
-					name:"focus Asia",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var tree = dijit.byId("mytree");
-
-						if(tree.lastFocused.isExpanded){
-							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
-						}
-						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Asia
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							doh.is("Asia", tree.lastFocused.label, "Asia is focused");
-
-							var item = tree.get("selectedItem"),
-								label = tree.model.getLabel(item);
-							doh.is("Africa", label, "but Africa is still selected");
-						}), 500);
-
-						return d;
-					}
-				},
-
-				{
-					name:"select Asia",
-					timeout:4000,
-					runTest:function(){
-						var d = new doh.Deferred();
-
-						var tree = dijit.byId("mytree");
-
-						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
-						
-						doh.robot.sequence(d.getTestCallback(function(){
-							var item = tree.get("selectedItem"),
-								label = tree.model.getLabel(item);
-							doh.is("Asia", label, "after ENTER focus shifted from Africa to Asia");
-						}), 500);
-
-						return d;
-					}
-				}
-			]);
-
-			doh.run();
-		});
-
-	</script>
-</head>
-</html>
-
diff --git a/dijit/tests/robot/Tree_dnd.html b/dijit/tests/robot/Tree_dnd.html
deleted file mode 100644
index f2c8273..0000000
--- a/dijit/tests/robot/Tree_dnd.html
+++ /dev/null
@@ -1,340 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>doh.robot Tree DnD 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>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
-		<script type="text/javascript" src="Tree_dnd.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../tree/test_Tree_DnD.html');
-
-				doh.register("setup", {
-					name: "setup",
-					timeout: 20000,
-					setUp: function(){
-						setup();
-					}
-				});
-
-				// Dragging from an external source and dropping onto the Tree,
-				// creating a duplicate of the dragged item
-				doh.register("drop into", [
-					{
-						name: "drag 'Apple' over 'Fruits'",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							// Find the fruitsTreeNode category
-							var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-							doh.f(fruitsTreeNode.isExpanded, "fruitsTreeNode is initially closed");
-							doh.t(fruitsTreeNode.isExpandable, "but has (or may have) children");
-
-							// Check state of store too
-							var children = getNamesOfChildrenOfItem("Fruits");
-							doh.is(1, children.categories.length, "one category child");
-							doh.is("Citrus", children.categories[0]);
-							doh.is(0, children.items.length, "no item children yet");
-
-							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(fruitsTreeNode.domNode);
-
-							// Drag "Apple" onto Fruits.
-							doh.robot.mouseMoveAt("1001", 0, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 500, 2000);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// TODO: check drag avatar shows drop is valid (ie, avatar is green)
-								doh.t(dojo.hasClass(fruitsTreeNode.rowNode, "dijitTreeRowHover"), "tree node has hover class");
-								doh.t(dojo.hasClass(fruitsTreeNode.rowNode, "dojoDndItemOver"), "tree node has DND drop class");
-							}), 500);
-
-							return d;
-						}
-					},
-					{
-						name: "drop 'Apple' on to 'Fruits'",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// Check that new item was created and added to the store.
-								var children = getNamesOfChildrenOfItem("Fruits");
-								doh.is(1, children.categories.length, "one category child");
-								doh.is("Citrus", children.categories[0]);
-								doh.is(1, children.items.length, "one item child");
-								doh.is("Apple", children.items[0]);
-
-								// Check that data store update was reflected in the tree
-								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-
-								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
-								var treeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(2, treeNodeChildren.length, "2 TreeNode children")
-								doh.is("Apple", innerText(treeNodeChildren[0].labelNode));
-								doh.is("Citrus", innerText(treeNodeChildren[1].labelNode));
-							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
-
-							return d;
-						}
-					}
-				]);
-
-				// Moving an item w/in the tree
-				doh.register("re-parent an item", [
-					{
-						name: "drag 'Apple' from 'Fruits' to 'Citrus'",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-								appleTreeNode = findTreeNode("itemTree", "Apple"),
-								citrusTreeNode = findTreeNode("itemTree", "Citrus");
-
-							// Drag "Apple" into Citrus .
-							doh.robot.mouseMoveAt(appleTreeNode.labelNode, 0, 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);
-							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);// If prev. mouseMove caused scroll, readjust
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
-
-								// Check that data store item was orphaned from Fruits
-								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits");
-								doh.is(0, fruitsItemChildren.items.length, "no item children");
-
-								// Check that data store update was reflected in the tree
-								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
-
-								var fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(1, fruitsTreeNodeChildren.length, "1 TreeNode children")
-								doh.is("Citrus", innerText(fruitsTreeNodeChildren[0].labelNode));
-
-								// ... and parented to Citrus item
-								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
-								doh.is(2, citrusItemChildren.items.length, "two item children");
-								doh.is("Orange", citrusItemChildren.items[0]);
-								doh.is("Apple", citrusItemChildren.items[1]);
-
-								// Check that data store update was reflected in the tree
-								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
-
-								var citrusTreeNodeChildren = citrusTreeNode.getChildren();
-								doh.is(2, citrusTreeNodeChildren.length, "2 TreeNode children for Citrus")
-								doh.is("Orange", innerText(citrusTreeNodeChildren[0].labelNode), "child of Citrus TreeNode");
-								doh.is("Apple", innerText(citrusTreeNodeChildren[1].labelNode), "child of Citrus TreeNode");
-							}), 2000);
-
-							return d;
-						}
-					},
-
-					{
-						name: "drag 'Cereals' to be before 'Vegetables' (reordering)",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
-								cerealsTreeNode = findTreeNode("collectionsTree", "Cereals (0)");
-
-							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(cerealsTreeNode.domNode);
-
-							// Drag 'Cereals' and drop near top edge of 'Vegetables'.
-							// It should become Vegetables' prior-sibling
-							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1000, 50, 2);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
-
-								// Check that order of children was changed
-								var foodsItemChildren = getNamesOfChildrenOfItem("Foods").categories;
-								doh.is(3, foodsItemChildren.length, "3 categories");
-								doh.is("Fruits", foodsItemChildren[0]);
-								doh.is("Cereals", foodsItemChildren[1]);
-								doh.is("Vegetables", foodsItemChildren[2]);
-
-								// Check that data store update was reflected in the tree
-								var foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
-									foodsTreeNodeChildren = foodsTreeNode.getChildren();
-								doh.is(3, foodsTreeNodeChildren.length, "3 TreeNode children")
-								doh.is("Fruits (2)", innerText(foodsTreeNodeChildren[0].labelNode));
-								doh.is("Cereals (0)", innerText(foodsTreeNodeChildren[1].labelNode));
-								doh.is("Vegetables (0)", innerText(foodsTreeNodeChildren[2].labelNode));
-							}), 2000);
-
-							return d;
-						}
-					},
-
-					// We need to expand the Fruits TreeNode for the benefit of the next test,
-					// and we do it as a separate test so that citrusTreeNode will exist etc.
-					// by the time the next test starts.
-					{
-						name: "expand 'Fruits' TreeNode",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)");
-							doh.robot.mouseMoveAt(fruitsTreeNode.expandoNode, 500, 1000);
-							doh.robot.mouseClick({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// This is just here to wait for the expand operation to take place,
-								// and then notify DOH that we are finished
-							}), 1000);
-							return d;
-						}
-					},
-
-					{
-						name: "drag 'Vegetables' to be after 'Citrus' (reordering)",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
-								citrusTreeNode = findTreeNode("collectionsTree", "Citrus (1)"),
-								citrusTreeNodeSize = dojo.contentBox(citrusTreeNode.domNode);
-
-							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(vegetablesTreeNode.domNode);
-
-							// Drag 'Vegetables' and drop near bottom edge of 'Citrus'.
-							// It should become Citrus' prior-sibling
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(citrusTreeNode.domNode, 1000, 2000, 50, citrusTreeNodeSize.h - 2);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
-
-								// Check that order of children in data store was changed
-								var foodsItemChildren = getNamesOfChildrenOfItem("Foods").categories;
-								doh.is(2, foodsItemChildren.length, "2 categories under foods");
-								doh.is("Fruits", foodsItemChildren[0]);
-								doh.is("Cereals", foodsItemChildren[1]);
-
-								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits").categories;
-								doh.is(2, fruitsItemChildren.length, "2 categories under fruits");
-								doh.is("Citrus", fruitsItemChildren[0]);
-								doh.is("Vegetables", fruitsItemChildren[1]);
-
-								// Check that data store update was reflected in the tree
-								var foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
-									foodsTreeNodeChildren = foodsTreeNode.getChildren();
-								doh.is(2, foodsTreeNodeChildren.length, "2 TreeNode children for foods")
-								doh.is("Fruits (2)", innerText(foodsTreeNodeChildren[0].labelNode));
-								doh.is("Cereals (0)", innerText(foodsTreeNodeChildren[1].labelNode));
-
-								var fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)"),
-								fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
-								doh.is(2, fruitsTreeNodeChildren.length, "2 TreeNode children for fruits")
-								doh.is("Citrus (1)", innerText(fruitsTreeNodeChildren[0].labelNode));
-								doh.is("Vegetables (0)", innerText(fruitsTreeNodeChildren[1].labelNode));
-							}), 500);
-
-							return d;
-						}
-					}
-
-				]);
-
-				doh.register("drag between trees", [
-					{
-						name: "move 'Vegetables' from left tree to right tree, from 'Fruits' to 'Foods'",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)");
-								foodsTreeNode = dijit.byId("itemTree").rootNode;
-
-							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 0, 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(foodsTreeNode.labelNode, 500, 1000);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var myStore = dojo.global.myStore;
-
-								// Check that data store item was orphaned from Fruits
-								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits");
-								doh.is(1, fruitsItemChildren.categories.length, "one fruits child");
-								doh.is("Citrus", fruitsItemChildren.categories[0], "one fruits child");
-
-								// And added to Foods
-								var foodsItemChildren = getNamesOfChildrenOfItem("Foods");
-								doh.is(3, foodsItemChildren.categories.length, "three foods children");
-								doh.is("Fruits", foodsItemChildren.categories[0], "food child");
-								doh.is("Cereals", foodsItemChildren.categories[1], "food child");
-								doh.is("Vegetables", foodsItemChildren.categories[2], "food child");
-							}), 500);
-
-							return d;
-						}
-					}
-				]);
-
-				doh.register("drop in Tree outside of a treeNode", [
-					{
-						name: "drop 'Orange' within Tree but not over a TreeNode",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var orangeTreeNode = findTreeNode("itemTree", "Orange");
-
-							doh.robot.mouseMoveAt(orangeTreeNode.labelNode, 0, 500);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.mouseMoveAt("itemTree", 0, 500, 5, 50);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt("itemTree", 0, 500, 5, 100);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								var org = findTreeNode("itemTree", "Orange");
-								doh.t( org != null);
-							}), 500);
-							return d;
-						}
-					}
-				]);
-
-				// TODO: test icon and highlighting when valid drop target and invalid target (another item)
-
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/robot/Tree_dnd.js b/dijit/tests/robot/Tree_dnd.js
deleted file mode 100644
index da82a08..0000000
--- a/dijit/tests/robot/Tree_dnd.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Helper functions for Tree_dnd.html and Tree_dnd_multiParent.html tests
- */
-
-function setup(){
-	// Disable auto-scrolling because otherwise the viewport scrolls as doh.robot.mouseMoveAt()
-	// moves the mouse, literally making the the drop target a moving target
-	// (and mouseMoveAt() doesn't take this possibility into account).
-	dojo.global.dojo.dnd.autoScrollNodes = function(){};
-
-	// Scroll viewport to (try to) make sure that both tree and drag-source
-	// are simultaneously in view.
-	var scroll = dojo.position("1001").y;
-	dojo.body().parentNode.scrollTop = scroll;	// works on FF
-	dojo.body().scrollTop = scroll;	// works on safari
-}
-
-function findTreeNode(/*String*/ treeId, /*String*/ label){
-	// summary:
-	//		Find the TreeNode with the specified label in the given tree.
-	//		Assumes that there's only one TreeNode w/that label (i.e. it
-	//		breaks if certain items have multiple parents and appear in the
-	//		tree multiple times)
-	var nodes = dojo.query(".dijitTreeLabel", treeId);
-	for(var i=0; i<nodes.length; i++){
-		if(innerText(nodes[i]) == label){
-			return dijit.getEnclosingWidget(nodes[i]);	// TreeNode
-		}
-	}
-	return null;
-}
-
-function findTreeNodeByPath(/*String*/ treeId, /*String[] */ path){
-	// summary:
-	//		Find the TreeNode with the specified path (like ["Fruits", "Apple"] in a tree like:
-	//	|	* Foods
-	//	|		* Vegetbles
-	//	|		* Fruits
-	//	|			* Orange
-	//	|			* Apple
-	//		Path shouldn't include the root node.
-
-	var tree = dijit.byId(treeId);
-	for(var i=0, node=tree.rootNode; i<path.length; i++){
-		var pathElem = path[i], matchingChildNode;
-		for(var j=0, children=node.getChildren(); j < children.length; j++){
-			if(children[j].label == pathElem){
-				matchingChildNode = children[j];
-				break;
-			}
-		}
-		if(!matchingChildNode){
-			return null;
-		}
-		node = matchingChildNode;
-	}
-	return node;
-}
-
-function getChildrenOfItem(/*String*/ name){
-	// summary:
-	//		Return the children of the data store item w/the specified name
-	//		Note that test_Tree_Dnd.html splits the children up into the "children"
-	//		and "items" attributes.
-
-	// Get the parent item
-	// Note that the ItemFileWriteStore's callback will happen immediately.
-	var myStore = dojo.global.myStore,
-		parentItem;
-	myStore.fetch({
-		query: {name: name},
-		onItem: function(item){ parentItem = item; }
-	});
-
-	// Get the children, which are stored in two separate attributes,
-	// categories (like 'Fruits') and items (ie, leaf nodes)  (like 'Apple')
-	return {
-		categories: myStore.getValues(parentItem, 'children'),
-		items: myStore.getValues(parentItem, 'items')
-	};
-}
-
-function mapItemsToNames(ary){
-	// summary:
-	//		Convert an array of items into an array of names
-	var myStore = dojo.global.myStore;
-	return dojo.map(ary, function(item){
-		return myStore.getValue(item, "name");
-	});
-}
-
-function getNamesOfChildrenOfItem(/*String*/ name){
-	// summary:
-	//		Return the names of the (items that are) children of the item w/the specified name
-
-	// Get the parent item (according to
-	var obj = getChildrenOfItem(name);
-	return {
-		categories: mapItemsToNames(obj.categories),
-		items: mapItemsToNames(obj.items)
-	};
-}
-
diff --git a/dijit/tests/robot/Tree_dnd_multiParent.html b/dijit/tests/robot/Tree_dnd_multiParent.html
deleted file mode 100644
index 2c5ab14..0000000
--- a/dijit/tests/robot/Tree_dnd_multiParent.html
+++ /dev/null
@@ -1,273 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-	<head>
-		<title>doh.robot Tree DnD Multi-parent Test</title>
-
-		<style>
-			@import "../../../util/doh/robot/robot.css";
-		</style>
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../../dojo/dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<!-- functions to help test -->
-		<script type="text/javascript" src="../helpers.js"></script>
-		<script type="text/javascript" src="Tree_dnd.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dojo.window");
-			dojo.require("dijit.robotx");
-
-			dojo.addOnLoad(function(){
-				doh.robot.initRobot('../tree/test_Tree_DnD.html');
-
-				doh.register("setup", {
-					name: "setup",
-					timeout: 20000,
-					setUp: function(){
-						setup();
-					}
-				});
-
-				doh.register("multi-parent tests", [
-					{
-						name: "add 'Fruits' as parent of vegetables",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var vegetablesTreeNode = findTreeNodeByPath("collectionsTree", ["Vegetables (0)"]),	// the left tree
-								foodsTreeNode = dijit.byId("itemTree").rootNode,								// right tree
-								fruitsTreeNode = findTreeNodeByPath("itemTree", ["Fruits"]);					// right tree
-
-							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(fruitsTreeNode.domNode);
-
-							// Drag and Drop, *copying* in order to add a parent rather than change
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1000);
-							doh.robot.keyDown(dojo.keys.copyKey, 500);
-							if(dojo.isMac){
-								// I can't get DOH robot to generate the mousePress event w/metaKey=true so
-								// hack it
-								doh.robot.sequence(function(){
-									realIsCopyKey = dojo.global.dojo.isCopyKey;
-									dojo.global.dojo.isCopyKey = function(){ return true; }
-								});
-							}
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 500, 2000);
-							doh.robot.mouseRelease({left: true}, 500);
-							doh.robot.keyUp(dojo.keys.copyKey, 500);
-							if(dojo.isMac){
-								// See if(dojo.isMac) above
-								doh.robot.sequence(function(){
-									dojo.global.dojo.isCopyKey = realIsCopyKey;
-								});
-							}
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// Check that Vegetables remains a child of Foods
-								var children = getNamesOfChildrenOfItem("Foods");
-								doh.is(3, children.categories.length, "foods category child");
-								doh.is("Fruits", children.categories[0]);
-								doh.is("Vegetables", children.categories[1]);
-								doh.is("Cereals", children.categories[2]);
-
-								// Check that Vegetables added as child of Fruits
-								var children = getNamesOfChildrenOfItem("Fruits");
-								doh.is(2, children.categories.length, "foods category child");
-								doh.is("Citrus", children.categories[0]);
-								doh.is("Vegetables", children.categories[1]);
-
-								// Check that new item *wasn't* created
-								var items;
-								dojo.global.myStore.fetch({
-									onComplete: function(i){ items = i; }
-								});
-								doh.is(6, items.length, "# of items in store");
-
-								// 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("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
-
-							return d;
-						}
-					},
-					{
-						name: "move Foods/Vegetables to Foods/Cereal/Vegetables",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var vegetablesTreeNode = findTreeNodeByPath("itemTree", ["Vegetables"]),
-								cerealsTreeNode = findTreeNodeByPath("itemTree", ["Cereals"]);
-
-							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(cerealsTreeNode.domNode);
-
-							// Drag and Drop
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 0, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(cerealsTreeNode.labelNode, 500, 1000);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// Check that Vegetables remains a child of Fruits
-								var children = getNamesOfChildrenOfItem("Fruits");
-								doh.is(2, children.categories.length, "fruits category child");
-								doh.is("Citrus", children.categories[0]);
-								doh.is("Vegetables", children.categories[1]);
-
-								// Check that Vegetables added as child of Cereals
-								children = getNamesOfChildrenOfItem("Cereals");
-								doh.is(1, children.categories.length, "cereals category child");
-								doh.is("Vegetables", children.categories[0]);
-
-								// Check that Vegetables no longer a child of Foods
-								children = getNamesOfChildrenOfItem("Foods");
-								doh.is(2, children.categories.length, "foods category child");
-								doh.is("Fruits", children.categories[0]);
-								doh.is("Cereals", children.categories[1]);
-
-								// Check that new item *wasn't* created
-								var items;
-								dojo.global.myStore.fetch({
-									onComplete: function(i){ items = i; }
-								});
-								doh.is(6, items.length, "# of items in store");
-							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
-
-							return d;
-						}
-					},
-					{
-						name: "move Fruits/Vegetables to Fruits/Citrus",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var vegetablesTreeNode = findTreeNodeByPath("itemTree", ["Fruits", "Vegetables"]),
-								citrusTreeNode = findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
-
-							// (Try to) make sure drag source and drop source are both in viewport
-							dojo.window.scrollIntoView(vegetablesTreeNode.domNode);
-
-							// Drag and Drop
-							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 0, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-								// Check that Vegetables remains a child of Cereals
-								var children = getNamesOfChildrenOfItem("Cereals");
-								doh.is(1, children.categories.length, "cereals category child");
-								doh.is("Vegetables", children.categories[0]);
-
-								// Check that Vegetables added as child of Citrus
-								children = getNamesOfChildrenOfItem("Citrus");
-								doh.is(1, children.categories.length, "citrus category child");
-								doh.is("Vegetables", children.categories[0]);
-								doh.is(1, children.items.length, "citrus item child");
-								doh.is("Orange", children.items[0]);
-
-								// Check that Vegetables removed as child of Fruits
-								children = getNamesOfChildrenOfItem("Fruits");
-								doh.is(1, children.categories.length, "fruits category child");
-								doh.is("Citrus", children.categories[0]);
-
-								// Check that new item *wasn't* created
-								var items;
-								dojo.global.myStore.fetch({
-									onComplete: function(i){ items = i; }
-								});
-								doh.is(6, items.length, "# of items in store");
-							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
-
-							return d;
-						}
-					}
-				]);
-
-				doh.register("external drop tests", [
-					{
-						name: "drop banana on fruits",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var fruitsTreeNode = findTreeNodeByPath("itemTree", ["Fruits"]);					// right tree
-
-							doh.robot.mouseMoveAt(dojo.byId("1003"), 500, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 500, 2000);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-
-								var children = getChildrenOfItem("Fruits");
-								doh.is(1, children.items.length, "new item added");
-								doh.is(1003, children.items[0].id, "id of new item came from dropped node");
-								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");
-
-								dojo.global.myStore.fetch({
-									query: { name: "Banana" },
-									queryOptions: { deep: true },
-									onComplete: function(i){ items = i; }
-								});
-								doh.is(1, items.length, "1 banana item in store");
-							}), 1000);
-
-							return d;
-						}
-					},
-					{
-						name: "drop banana on cereal",
-						timeout: 10000,
-						runTest: function(){
-							var d = new doh.Deferred();
-
-							var cerealsTreeNode = findTreeNodeByPath("itemTree", ["Cereals"]);					// right tree
-
-							doh.robot.mouseMoveAt(dojo.byId("1003"), 500, 1000);
-							doh.robot.mousePress({left: true}, 500);
-							doh.robot.mouseMoveAt(cerealsTreeNode.labelNode, 500, 2000);
-							doh.robot.mouseRelease({left: true}, 500);
-
-							doh.robot.sequence(d.getTestCallback(function(){
-
-								var children = getChildrenOfItem("Cereals");
-								doh.is(1, children.items.length, "banana is child of cereals");
-								doh.is(1003, children.items[0].id, "id of item came from dropped node");
-								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");
-
-								var 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");
-
-								dojo.global.myStore.fetch({
-									query: { name: "Banana" },
-									queryOptions: { deep: true },
-									onComplete: function(i){ items = i; }
-								});
-								doh.is(1, items.length, "1 banana item in store (with 2 parents)");
-							}), 1000);
-
-							return d;
-						}
-					}
-
-				]);
-
-				doh.run();
-			});
-		</script>
-	</head>
-</html>
diff --git a/dijit/tests/robot/_Widget-ondijitclick_a11y.html b/dijit/tests/robot/_Widget-ondijitclick_a11y.html
index 8abc73e..a591af6 100644
--- a/dijit/tests/robot/_Widget-ondijitclick_a11y.html
+++ b/dijit/tests/robot/_Widget-ondijitclick_a11y.html
@@ -70,22 +70,16 @@
 							widgetClicks = buttonClicks = 0;
 							var d = new doh.Deferred();
 
-							// Keyboard-click with modifier shouldn't do anything
 							doh.robot.sequence(function(){
 								w.domNode.focus();
 							}, 500);
+				
+							// Try shift-space/shift-enter just to make sure it doesn't do anything.
+							// Don't try ctrl-space or meta-space since those keystrokes have special functions
+							// (like context menu) in various browsers
 							doh.robot.keyPress(dojo.keys[key], 100, {shift: true});
-							if(!dojo.isMac){
-								// Don't do this check on mac because ctrl-space causes the context menu to show up
-								doh.robot.keyPress(dojo.keys[key], 100, {ctrl: true});
-							}
 
-							// meta key can open browser menus etc.   let's just not
-							// even try it...
-							//doh.robot.keyPress(dojo.keys[key], 100, {meta: true});
-
-							// Check that ondijitclick fired but no spurious event
-							// on the widget that got focused in the ondijitclick handler
+							// Check that ondijitclick didn't fire
 							doh.robot.sequence(d.getTestCallback(function(){
 								doh.is(0, widgetClicks, "ondijitclick handler wasn't fired");
 								doh.is(0, buttonClicks, "button click handler wasn't fired");
diff --git a/dijit/tests/test.html b/dijit/tests/test.html
deleted file mode 100644
index 5db5044..0000000
--- a/dijit/tests/test.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>widget infrastructure test</title>
-
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="isDebug: true"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.form.Button");
-
-		dojo.addOnLoad(function(){
-			for(var i=1; i<=3; i++){
-				var node = dojo.byId("b"+i);
-				var myButton = new dijit.form.Button(null, node);
-			}
-		});
-
-	</script>
-
-	<style type="text/css">
-
-		@import "../../dojo/resources/dojo.css";
-		@import "../themes/tundra/tundra.css";
-		@import "css/dijitTests.css";
-
-		body { padding: 5em; }
-	</style>
-</head>
-
-<body class="claro">
-	<button id="b1" style="background: yellow;">button #1</button>
-	<button id="b2" style="background: orange;">button #2</button>
-	<button id="b3" style="background: violet;">button #3</button>
-</body>
-</html>
diff --git a/dijit/tests/test_Calendar.html b/dijit/tests/test_Calendar.html
index 8f4272d..5ebab83 100644
--- a/dijit/tests/test_Calendar.html
+++ b/dijit/tests/test_Calendar.html
@@ -1,12 +1,12 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 	<head>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Calendar Widget Test</title>
 
 		<!-- for tests -->
 		<style type="text/css">
-			@import "../../dojo/resources/dojo.css";
+			@import "../themes/claro/document.css";
 			@import "css/dijitTests.css";
 		</style>
 
@@ -20,11 +20,11 @@
 		</style>
 
 		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../dojo/dojo.js"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 		<!-- not needed, for testing alternate themes -->
 		<script type="text/javascript" src="_testCommon.js"></script>
@@ -50,7 +50,7 @@
 				});
 
 				var bigCalendar = dojo.byId("calendar5");
-				bigCalendar.setAttribute("dojoType", "BigCalendar");
+				bigCalendar.setAttribute("data-dojo-type", "BigCalendar");
 				dojo.parser.parse(bigCalendar.parentNode);
 			});
 
@@ -63,9 +63,9 @@
 
 		<h1 class="testTitle">Dijit Calendar Test</h1>
 
-		<input value="input before" id="before">
-		<input id="calendar1" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
-		<input value="input after" id="after">
+		<input value="input before" id="before"/>
+		<input id="calendar1" data-dojo-type="dijit.Calendar" data-dojo-props='onChange:function(v){ myHandler(this.id, v) }'/>
+		<input value="input after" id="after"/>
 		<p>
 			<a href="#"
 			   onClick="dijit.registry.forEach(function(c){
@@ -78,7 +78,7 @@
 		<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" dayWidth="abbr" value="2008-03-14">
+			<input id="calendar5" data-dojo-props='dayWidth:"abbr", value:"2008-03-14"'/>
 		</div>
 	</body>
 </html>
diff --git a/dijit/tests/test_ColorPalette.html b/dijit/tests/test_ColorPalette.html
index f2abdfa..b78bfdb 100644
--- a/dijit/tests/test_ColorPalette.html
+++ b/dijit/tests/test_ColorPalette.html
@@ -1,29 +1,35 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>ColorPalette Test</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true, extraLocale: ['en-us', 'es-mx']"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true, extraLocale: ['en-us', 'es-mx']"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
 
-	<script language="JavaScript" type="text/javascript">
+	<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();
@@ -44,15 +50,15 @@
 	<h1 class="testTitle">dijit.ColorPalette test:</h1>
 
 	<p>Large color palette (7x10), English tooltips:</p>
-	<input id="beforeBig" value="for tabIndex testing">
-	<div dojoType="dijit.ColorPalette" id="big" onChange="setColor(this.value);" lang="en-us"></div>
+	<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>
 	Test color is: <span id="outputSpan"></span>.
-	<input id="afterBig" value="for tabIndex testing">
+	<input id="afterBig" value="for tabIndex testing"/>
 
 	<p>Small color palette (3x4), Spanish tooltips:</p>
-	<input id="beforeSmall" value="for tabIndex testing">
-	<div dojoType="dijit.ColorPalette" id="small" palette="3x4" lang="es-mx"></div>
-	<input id="afterSmall" value="for tabIndex testing">
+	<input id="beforeSmall" value="for tabIndex testing"/>
+	<div id="small" data-dojo-type="dijit.ColorPalette" data-dojo-props='palette:"3x4", lang:"es-mx"'></div>
+	<input id="afterSmall" value="for tabIndex testing"/>
 
 	<p>Default color palette (7x10) created programatically:</p>
 	<div id="programPalette"></div>
diff --git a/dijit/tests/test_Declaration.html b/dijit/tests/test_Declaration.html
index 91df301..b287bdf 100644
--- a/dijit/tests/test_Declaration.html
+++ b/dijit/tests/test_Declaration.html
@@ -1,20 +1,21 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Dojo Toolkit - Declaration test</title>
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -24,72 +25,108 @@
 		dojo.require("dijit.Declaration");
 		dojo.require("dijit.ProgressBar");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("doh.runner");
+
+		dojo.addOnLoad(function(){
+			doh.register("dijit.Declaration", [
+				function parse(){
+					// run parser inside of DOH so we can tell if there are any exceptions
+					dojo.parser.parse();
+
+					// test instantiation of dojo.Declaration widgets
+					doh.t(hideButtonA, "hideButtonA instantiated");
+					doh.t(hideButtonB, "hideButtonB instantiated");
+					doh.t(hideButton2A, "hideButton2A instantiated");
+					doh.t(hideButton2B, "hideButton2B instantiated");
+				},
+
+				function basicTests(){	
+					// test <script type="dojo/method">	
+					doh.t(HideButton.prototype.myHandler, "myHandler method added to HideButton prototype");
+					doh.t(HideButton2.prototype.myHandler, "myHandler method added to HideButton2 prototype");
+	
+					// test prototype extension	
+					doh.t(mPrototypeExecuted, "m prototype executed");
+	
+					// test parameters
+					doh.is("blah", m1.foo, "m1.foo");
+					doh.is(73, m2.progress, "m2.progress");
+	
+					// 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");
+				}
+			]);
+
+			doh.run();
+		});
 	</script>
 
 </head>
 <body class="claro">
 	<h3>Simple macro:</h3>
 	<p>(Check to make sure that links contain employee number)
-	<div dojoType="dijit.Declaration" widgetClass="Employee" defaults="{ empid: 123, name: '' }">
+	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"Employee", defaults:{ empid: 123, name: "" }'>
 		<span>${name}</span>
 		<a href="update.php?id=${empid}">update</a>
 		<a href="delete.php?id=${empid}">delete</a>
 	</div>
-	<div dojoType="Employee" empid="100" name="Alan Allen"></div>
-	<div dojoType="Employee" empid="101" name="Bob Brown"></div>
-	<div dojoType="Employee" empid="102" name="Cathy Cameron"></div>
-
-	<h3>Using dojoAttachEvent, dojoAttachPoint</h3>
-	<div dojoType="dijit.Declaration" widgetClass="HideButton">
-		XXX<button dojoAttachEvent="onclick" dojoAttachPoint="containerNode"></button>XXX
-		<script type='dojo/method' event='onclick'>
+	<div data-dojo-type="Employee" data-dojo-props='empid:100, name:"Alan Allen"'></div>
+	<div data-dojo-type="Employee" data-dojo-props='empid:101, name:"Bob Brown"'></div>
+	<div data-dojo-type="Employee" data-dojo-props='empid:102, name:"Cathy Cameron"'></div>
+
+	<h3>Using data-dojo-attach-event, data-dojo-attach-point</h3>
+	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"HideButton"'>
+		XXX<button data-dojo-attach-event="onclick: myHandler" data-dojo-attach-point="containerNode"></button>XXX
+		<script type='dojo/method' data-dojo-event='myHandler'>
 			this.domNode.style.display="none";
 		</script>
 	</div>
-	<button dojoType="HideButton">Click to hide</button>
-	<button dojoType="HideButton">Click to hide #2</button>
+	<button data-dojo-id="hideButtonA" data-dojo-type="HideButton" >Click to hide</button>
+	<button data-dojo-id="hideButtonB" data-dojo-type="HideButton" >Click to hide #2</button>
 
 	<h3>Extending another widget</h3>
 	<p>HideButton2 extends HideButton (above) and changes the template (but keeps the onclick handler).</p>
-	<span dojoType="dijit.Declaration" widgetClass="HideButton2" mixins="HideButton">
-		YYY<button dojoAttachEvent="onclick" dojoAttachPoint="containerNode"></button>YYY
+	<span data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"HideButton2", mixins:["HideButton"]'>
+		YYY<button data-dojo-attach-event="onclick: myHandler" data-dojo-attach-point="containerNode"></button>YYY
 	</span>
-	<button dojoType="HideButton2">Hide me extended</button>
-	<button dojoType="HideButton2">Hide me extended #2</button>
+	<button data-dojo-id="hideButton2A" data-dojo-type="HideButton2" >Hide me extended</button>
+	<button data-dojo-id="hideButton2B" data-dojo-type="HideButton2" >Hide me extended #2</button>
 
 	<h3>Using dojo/method:</h3>
-	<div dojoType="dijit.Declaration" widgetClass="m" defaults="{ foo: 'thud', progress: 10 }">
-		<script type='dojo/method' event='postCreate'>
+	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"m", defaults:{ foo: "thud", progress: 10 }'>
+		<script type='dojo/method' data-dojo-event='postCreate'>
 			console.log("in postCreate ", this, arguments);
+			mPrototypeExecuted = true;
 			this.inherited(arguments);
 			this.baz.innerHTML += " (created via custom postCreate) ";
 		</script>
 
 		<p>thinger blah stuff ${foo}</p>
 
-		<div style="width:400px" maximum="200"
-			progress="${progress}" dojoType="dijit.ProgressBar"></div>
-		<p dojoAttachPoint='baz'>baz thud</p>
+		<div data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", maximum:200,
+			progress:${progress}'></div>
+		<p data-dojo-attach-point='baz'>baz thud</p>
 	</div>
 
-	<div dojoType="m" foo="blah" progress="50"></div>
-	<div dojoType="m" foo="thinger" progress="73"></div>
+	<div data-dojo-id="m1" data-dojo-type="m" data-dojo-props='foo:"blah", progress:50'></div>
+	<div data-dojo-id="m2" data-dojo-type="m" data-dojo-props='foo:"thinger", progress:73'></div>
 
 	<h3>Using dojo/connect:</h3>
-	<div dojoType="dijit.Declaration" widgetClass="foo" defaults="{ foo: 'thud', progress: 10 }">
-		<script type='dojo/connect' event='startup'>
+	<div data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"foo", defaults:{ foo: "thud", progress: 10 }'>
+		<script type='dojo/connect' data-dojo-event='startup'>
 			this.baz.innerHTML += " (modified by dojo/connect event=startup) ";
 		</script>
 
 		<p>thinger blah stuff ${foo}</p>
 
-		<div style="width:400px" maximum="200"
-			progress="${progress}" dojoType="dijit.ProgressBar"></div>
-		<p dojoAttachPoint='baz'>baz thud</p>
+		<div data-dojo-type="dijit.ProgressBar" data-dojo-props='style:"width:400px", maximum:200,
+			progress:${progress}'></div>
+		<p data-dojo-attach-point='baz'>baz thud</p>
 	</div>
 
-	<div dojoType="foo" foo="blah" progress="50"></div>
-	<div dojoType="foo" foo="thinger" progress="73"></div>
+	<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>
 
 </body>
 </html>
diff --git a/dijit/tests/test_Declaration_1.x.html b/dijit/tests/test_Declaration_1.x.html
new file mode 100644
index 0000000..ee5493b
--- /dev/null
+++ b/dijit/tests/test_Declaration_1.x.html
@@ -0,0 +1,131 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+
+	<title>Dojo Toolkit - Declaration test</title>
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		djConfig="isDebug: true"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.Declaration");
+		dojo.require("dijit.ProgressBar");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("doh.runner");
+
+		dojo.addOnLoad(function(){
+			doh.register("dijit.Declaration_1.x", [
+				function parse(){
+					// run parser inside of DOH so we can tell if there are any exceptions
+					dojo.parser.parse();
+
+					// test instantiation of dojo.Declaration widgets
+					doh.t(hideButtonA, "hideButtonA instantiated");
+					doh.t(hideButtonB, "hideButtonB instantiated");
+					doh.t(hideButton2A, "hideButton2A instantiated");
+					doh.t(hideButton2B, "hideButton2B instantiated");
+				},
+
+				function basicTests(){	
+					// test <script type="dojo/method">	
+					doh.t(HideButton.prototype.myHandler, "myHandler method added to HideButton prototype");
+					doh.t(HideButton2.prototype.myHandler, "myHandler method added to HideButton2 prototype");
+	
+					// test prototype extension	
+					doh.t(mPrototypeExecuted, "m prototype executed");
+	
+					// test parameters
+					doh.is("blah", m1.foo, "m1.foo");
+					doh.is(73, m2.progress, "m2.progress");
+	
+					// 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");
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+	<h3>Simple macro:</h3>
+	<p>(Check to make sure that links contain employee number)
+	<div dojoType="dijit.Declaration" widgetClass="Employee" defaults="{ empid: 123, name: '' }">
+		<span>${name}</span>
+		<a href="update.php?id=${empid}">update</a>
+		<a href="delete.php?id=${empid}">delete</a>
+	</div>
+	<div dojoType="Employee" empid="100" name="Alan Allen"></div>
+	<div dojoType="Employee" empid="101" name="Bob Brown"></div>
+	<div dojoType="Employee" empid="102" name="Cathy Cameron"></div>
+
+	<h3>Using dojoAttachEvent, dojoAttachPoint</h3>
+	<div dojoType="dijit.Declaration" widgetClass="HideButton">
+		XXX<button dojoAttachEvent="onclick: myHandler" dojoAttachPoint="containerNode"></button>XXX
+		<script type='dojo/method' event='myHandler'>
+			this.domNode.style.display="none";
+		</script>
+	</div>
+	<button dojoType="HideButton" jsId="hideButtonA">Click to hide</button>
+	<button dojoType="HideButton" jsId="hideButtonB">Click to hide #2</button>
+
+	<h3>Extending another widget</h3>
+	<p>HideButton2 extends HideButton (above) and changes the template (but keeps the onclick handler).</p>
+	<span dojoType="dijit.Declaration" widgetClass="HideButton2" mixins="HideButton">
+		YYY<button dojoAttachEvent="onclick: myHandler" dojoAttachPoint="containerNode"></button>YYY
+	</span>
+	<button dojoType="HideButton2" jsId="hideButton2A">Hide me extended</button>
+	<button dojoType="HideButton2" jsId="hideButton2B">Hide me extended #2</button>
+
+	<h3>Using dojo/method:</h3>
+	<div dojoType="dijit.Declaration" widgetClass="m" defaults="{ foo: 'thud', progress: 10 }">
+		<script type='dojo/method' event='postCreate'>
+			console.log("in postCreate ", this, arguments);
+			mPrototypeExecuted = true;
+			this.inherited(arguments);
+			this.baz.innerHTML += " (created via custom postCreate) ";
+		</script>
+
+		<p>thinger blah stuff ${foo}</p>
+
+		<div style="width:400px" maximum="200"
+			progress="${progress}" dojoType="dijit.ProgressBar"></div>
+		<p dojoAttachPoint='baz'>baz thud</p>
+	</div>
+
+	<div dojoType="m" jsId="m1" foo="blah" progress="50"></div>
+	<div dojoType="m" jsId="m2" foo="thinger" progress="73"></div>
+
+	<h3>Using dojo/connect:</h3>
+	<div dojoType="dijit.Declaration" widgetClass="foo" defaults="{ foo: 'thud', progress: 10 }">
+		<script type='dojo/connect' event='startup'>
+			this.baz.innerHTML += " (modified by dojo/connect event=startup) ";
+		</script>
+
+		<p>thinger blah stuff ${foo}</p>
+
+		<div style="width:400px" maximum="200"
+			progress="${progress}" dojoType="dijit.ProgressBar"></div>
+		<p dojoAttachPoint='baz'>baz thud</p>
+	</div>
+
+	<div dojoType="foo" jsId="foo1" foo="blah" progress="50"></div>
+	<div dojoType="foo" jsId="foo2" foo="thinger" progress="73"></div>
+
+</body>
+</html>
diff --git a/dijit/tests/test_Dialog.html b/dijit/tests/test_Dialog.html
index c2afb48..852ccbf 100644
--- a/dijit/tests/test_Dialog.html
+++ b/dijit/tests/test_Dialog.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dialog Widget Dojo Tests</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 
 		form { margin-bottom : 0; }
@@ -15,11 +15,11 @@
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -40,12 +40,6 @@
 		dojo.require("dijit.Menu");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
 
-		// create a do nothing, only for test widget
-		dojo.declare("dijit.TestWidget",
-			[dijit._Widget, dijit._Templated], {
-			templateString: "<div style='margin: 10px; border: inset #700 4px; padding: 5px;' dojoAttachPoint='containerNode'></div>"
-		});
-
 		// make dojo.toJson() print dates correctly (this feels a bit dirty)
 		Date.prototype.json = function(){ return dojo.date.stamp.toISOString(this, {selector: 'date'});};
 
@@ -62,9 +56,7 @@
 			}
 			setTimeout(function(){ thirdDlg.show(); },"3000");
 		}
-		dojo.addOnLoad(function(){
-			dojo.subscribe("focusNode", function(node){ console.log("focused on " + (node?(node.id||node.tagName):"nothing"));});
-		});
+
 		function open2Dialogs(){
 			dijit.byId('dialog1').show();
 			setTimeout(dojo.hitch(dijit.byId('fifthDlg'), 'show'), 1000);
@@ -74,46 +66,46 @@
 <body class="claro">
 
 	<h1 class="testTitle">Dijit layout.Dialog tests</h1>
-	<button dojoType="dijit.form.Button"  id="dialog1button" onclick="dijit.byId('dialog1').show()">Show Dialog</button> |
+	<button id="dialog1button" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("dialog1").show() }'>Show Dialog</button> |
 
-	<div dojoType="dijit.Dialog" id="dialog1" title="First Dialog"
-			aria-describedby="intro"
-			onfocus="console.log('user focus handler')"
-			onblur="console.log('user blur handler')"
-			execute="console.log('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
+	<div id="dialog1" data-dojo-type="dijit.Dialog" data-dojo-props='title:"First Dialog",
+			"aria-describedby":"intro",
+			onFocus:function(){ console.log("user focus handler") },
+			onBlur:function(){ console.log("user blur handler") },
+			execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
 		<div id="intro" style="width:30em;">Introductory information spoken by screen reader if aria-describedby is
 		added to the declaration of dialog above with value equal to the id of the container element for this text. This technique
 		will work in Dojo 1.4. </div>
-		<table>
+		<table style="position:relative;">
 			<tr>
 				<td><label for="name">Name: </label></td>
-				<td><input dojoType=dijit.form.TextBox type="text" name="name" id="name"></td>
+				<td><input id="name" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"name" '/></td>
 			</tr>
 			<tr>
 				<td><label for="loc">Location: </label></td>
-				<td><input dojoType=dijit.form.TextBox type="text" name="loc" id="loc"></td>
+				<td><input id="loc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"loc" '/></td>
 			</tr>
 			<tr>
 				<td><label for="date">Date: </label></td>
-				<td><input dojoType=dijit.form.DateTextBox type="text" name="date" id="date"></td>
+				<td><input id="date" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text", name:"date" '/></td>
 			</tr>
 			<tr>
-				<td><label for="time">Time: </label></td>
-				<td><div dojoType="dijit.InlineEditBox" editor=dijit.form.TimeTextBox type="text" name="time" id="time" width="100px" style="width:100px;"></div></td>
+				<td><label>Time: </label></td>
+				<td><div id="time" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.TimeTextBox", editorParams:{type:"text", name:"time"}, width:"100px", style:"width:100px;"'></div></td>
 			</tr>
 			<tr>
 				<td><label for="desc">Description: </label></td>
-				<td><input dojoType=dijit.form.TextBox type="text" name="desc" id="desc"></td>
+				<td><input id="desc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"desc" '/></td>
 			</tr>
 			<tr>
-				<td colspan="2" align="center">
-					<button dojoType=dijit.form.Button id="ok" type="submit">OK</button></td>
+				<td colspan="2" style="text-align:center;">
+					<button id="ok" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit"'>OK</button></td>
 			</tr>
 		</table>
 	</div>
 
 
-	<button dojoType="dijit.form.Button" onclick="createDialog()" title="shows after 3 second delay, with blue background">Programatic Dialog (3 second delay)</button> |
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ createDialog() }, title:"shows after 3 second delay, with blue background"'>Programatic Dialog (3 second delay)</button> |
 
 
 	<div id="thirdDialog" style="display: none;">
@@ -140,11 +132,11 @@
 		</p>
 	</div>
 
-	<button dojoType="dijit.form.Button" onclick="dijit.byId('tabDialog').show()">Show TabContainer Dialog</button> |
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("tabDialog").show() }'>Show TabContainer Dialog</button> |
 
-	<div dojoType="dijit.Dialog" id="tabDialog" title="TabContainer Dialog">
-		<div dojoType="dijit.layout.TabContainer" id="tc" style="width: 400px; height: 400px;">
-			<div dojoType="dijit.layout.ContentPane" id="cp1" title="First tab">
+	<div id="tabDialog" data-dojo-type="dijit.Dialog" data-dojo-props='title:"TabContainer Dialog"'>
+		<div id="tc" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 400px;"'>
+			<div id="cp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"First tab"'>
 				<p>
 					This is the first tab.
 				</p>
@@ -157,7 +149,7 @@
 				risus.
 				</p>
 			</div>
-			<div dojoType="dijit.layout.ContentPane" id="cp2" title="Second tab">
+			<div id="cp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Second tab"'>
 				<p>
 					This is the second tab.
 				</p>
@@ -189,39 +181,39 @@
 		</div>
 	</div>
 
-	<button dojoType="dijit.form.Button" onclick="dijit.byId('fifthDlg').show();">Test slow loading HREF Dialog</button> |
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("fifthDlg").show(); }'>Test slow loading HREF Dialog</button> |
 
-	<div dojoType="dijit.Dialog" id="fifthDlg" href="layout/getResponse.php?delay=3000&messId=3"
-		style="width: 300px" title="From HREF (slow network simulated)"></div>
+	<div id="fifthDlg" data-dojo-type="dijit.Dialog" data-dojo-props='href:"layout/getResponse.php?delay=3000&messId=3",
+		style:"width: 300px", title:"From HREF (slow network simulated)"'></div>
 
-	<button dojoType="dijit.form.Button" onclick="dijit.byId('dialog6').show()">Show File Dialog</button>
+	<button id="filebutton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("file").show() }'>Show File Dialog</button>
 
-	<div dojoType="dijit.Dialog" id="dialog6" title="File Dialog"
-			onfocus="console.log('user focus handler')"
-			onblur="console.log('user blur handler')"
-			execute="alert('submitted w/args:\n' + dojo.toJson(arguments[0], true));" style="min-width: 350px">
+	<div id="file" data-dojo-type="dijit.Dialog" data-dojo-props='title:"File Dialog",
+			onFocus:function(){ console.log("user focus handler") },
+			onBlur:function(){ console.log("user blur handler") },
+			execute:function(args){ alert("submitted w/args:\n" + dojo.toJson(args, true)); }, style:"min-width: 350px"'>
 		<!-- note: style="min-width: 350px" to workaround FF bug where width is too short, see http://bugs.dojotoolkit.org/ticket/5976 -->
 			<label for="afile">ID File: </label>
-			<input dojoType=dijit.form.TextBox type="file" name="afile" id="afile">
+			<input id="afile" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"file", name:"afile" '/>
 	</div>
 
-	<button dojoType="dijit.form.Button" onclick="dijit.byId('cantmove').show()">Show Unmovable</button>
+	<button id="unmovablebutton" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("unmovable").show() }'>Show Unmovable</button>
 
-	<div dojoType="dijit.Dialog" id="cantmove" title="unmovable" draggable="false">
+	<div id="unmovable" data-dojo-type="dijit.Dialog" data-dojo-props='title:"unmovable", draggable:false'>
 		<p>You should not be able to <br /> drag this dialog</p>
 	</div>
 
-	<button dojoType="dijit.form.Button" onclick="dijit.byId('preventer').show()">Show Close prevention</button>
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("preventer").show() }'>Show Close prevention</button>
 
-	<div dojoType="dijit.Dialog" id="preventer" title="Confirm Close">
+	<div id="preventer" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Confirm Close"'>
 		I am done entering data:
-		<button dojoType="dijit.form.Button" id="preventerOK" type="submit" onClick="return confirm('Are you sure?')">OK</button>
+		<button id="preventerOK" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit", onClick:function(){ return confirm("Are you sure?") }'>OK</button>
 	</div>
 
-	<button dojoType="dijit.form.Button" onclick="dijit.byId('embedded').show()">Dialog w/embedded layout widgets</button> |
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("embedded").show() }'>Dialog w/embedded layout widgets</button> |
 
-	<div dojoType="dijit.Dialog" id="embedded" title="Embedded layout widgets"
-		onShow="dojo.attr(this.domNode, 'aria-describedby', 'describe');" >
+	<div id="embedded" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Embedded layout widgets",
+		onShow:function(){ dojo.attr(this.domNode, "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.
@@ -229,8 +221,8 @@
 		<p>
 			Here's a BorderContainer:
 		</p>
-		<div dojoType="dijit.layout.BorderContainer" style="height:200px; width:300px">
-			<div dojoType="dijit.layout.ContentPane" region="left" style="width:100px" splitter="true">
+		<div data-dojo-type="dijit.layout.BorderContainer" data-dojo-props='style:"height:200px; width:300px"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"left", style:"width:100px", splitter:true'>
 				1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -245,7 +237,7 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div dojoType="dijit.layout.ContentPane" region="center">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='region:"center"'>
 				2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -264,8 +256,8 @@
 		<p>
 			And a TabContainer:
 		</p>
-		<div dojoType="dijit.layout.TabContainer" style="height:200px; width:300px">
-			<div dojoType="dijit.layout.ContentPane" title="Tab 1">
+		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"height:200px; width:300px"'>
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 1"'>
 				1Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -280,7 +272,7 @@
 				sollicitudin sed, consequat nec, facilisis sit amet, orci. Aenean
 				ut eros sit amet ante pharetra interdum.
 			</div>
-			<div dojoType="dijit.layout.ContentPane" title="Tab 2">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tab 2"'>
 				2Sed arcu magna, molestie at, fringilla in, sodales eu, elit.
 				Curabitur mattis lorem et est. Quisque et tortor. Integer bibendum
 				vulputate odio. Nam nec ipsum. Vestibulum mollis eros feugiat
@@ -303,12 +295,12 @@
 	
 	
 	<!-- Action Bar test case -->
-	<button dojoType="dijit.form.Button"  id="ABDlg1Btn" onclick="dijit.byId('ABDlg1').show()">Show Dialog With Action Buttons</button>
-	<div dojoType="dijit.Dialog" id="ABDlg1" title="ActionBar Dialog 1" 
-			onExecute="console.log('OK button pressed')"
-			onCancel="console.log('Cancel button pressed')"
-			aria-describedby="intro"
-			execute="console.log('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
+	<button id="ABDlg1Btn" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("ABDlg1").show() }'>Show Dialog With Action Buttons</button>
+	<div id="ABDlg1" data-dojo-type="dijit.Dialog" data-dojo-props='title:"ActionBar Dialog 1",
+			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">
 			<div id="ABintro1" style="width:30em;">Introductory information spoken by screen reader if aria-describedby is
 			added to the declaration of dialog above with value equal to the id of the container element for this text. This technique
@@ -317,18 +309,18 @@
 		
 		
 		<div class="dijitDialogPaneActionBar">
-			<button dojoType="dijit.form.Button" type="submit" id="ABdialog1button1">OK</button>
-			<button dojoType="dijit.form.Button" type="button" onClick="dijit.byId('ABDlg1').onCancel();" 
-					id="ABdialog1button2">Cancel</button>
+			<button id="ABdialog1button1" data-dojo-type="dijit.form.Button" data-dojo-props='type:"submit" '>OK</button>
+			<button id="ABdialog1button2" data-dojo-type="dijit.form.Button" data-dojo-props='type:"button", onClick:function(){ dijit.byId("ABDlg1").onCancel(); } 
+					'>Cancel</button>
 		</div>
 	</div>
 	
-	<button dojoType="dijit.form.Button"  id="NABDlgBtn" onclick="dijit.byId('NABDlg').show()">Show Dialog With No Action Buttons</button>
-	<div dojoType="dijit.Dialog" id="NABDlg" title="No Action Bar Dialog"
-			aria-describedby="intro"
-			onfocus="console.log('user focus handler')"
-			onblur="console.log('user blur handler')"
-			execute="console.log('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
+	<button id="NABDlgBtn" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("NABDlg").show() }'>Show Dialog With No Action Buttons</button>
+	<div id="NABDlg" data-dojo-type="dijit.Dialog" data-dojo-props='title:"No Action Bar Dialog",
+			"aria-describedby":"intro",
+			onFocus:function(){ console.log("user focus handler") },
+			onBlur:function(){ console.log("user blur handler") },
+			execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
 				
 		<div class="dijitDialogPaneContentArea">
 			<div id="NABintro" style="width:30em;">Introductory information spoken by screen reader if aria-describedby is
@@ -336,34 +328,48 @@
 			will work in Dojo 1.4. </div>
 			<table>
 				<tr>
-					<td><label for="name">Name: </label></td>
-					<td><input dojoType=dijit.form.TextBox type="text" name="NABname" id="NABname"></td>
+					<td><label for="NABname">Name: </label></td>
+					<td><input id="NABname" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"NABname" '/></td>
 				</tr>
 				<tr>
-					<td><label for="loc">Location: </label></td>
-					<td><input dojoType=dijit.form.TextBox type="text" name="NABloc" id="NABloc"></td>
+					<td><label for="NABloc">Location: </label></td>
+					<td><input id="NABloc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"NABloc" '/></td>
 				</tr>
 				<tr>
-					<td><label for="date">Date: </label></td>
-					<td><input dojoType=dijit.form.DateTextBox type="text" name="NABdate" id="NABdate"></td>
+					<td><label for="NABdate">Date: </label></td>
+					<td><input id="NABdate" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text", name:"NABdate" '/></td>
 				</tr>
 				<tr>
-					<td><label for="desc">Description: </label></td>
-					<td><input dojoType=dijit.form.TextBox type="text" name="NABdesc" id="NABdesc"></td>
+					<td><label for="NABdesc">Description: </label></td>
+					<td><input id="NABdesc" data-dojo-type="dijit.form.TextBox" data-dojo-props='type:"text", name:"NABdesc" '/></td>
 				</tr>
 			</table>
 		</div>
 	</div>
 
 
-	<button dojoType="dijit.form.Button"  id="layeredDialogs" onclick="open2Dialogs">Show 2 Dialogs</button>
+	<button id="layeredDialogs" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:open2Dialogs'>Show 2 Dialogs</button>
 
-	<button dojoType="dijit.form.Button"  id="iframeDlg" onclick='dijit.byId("dlgFrame").show();'>Show iframe in dialog</button>
-	<div dojoType="dijit.Dialog" id="dlgFrame" title="Search">
-		<iframe title="Test IFrame" src="layout/getResponse.php?delay=3000&messId=3" style="width:600px; height: 400px;">
+	<button id="iframeDlg" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("dlgFrame").show(); }'>Show iframe in dialog</button>
+	<div id="dlgFrame" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Search"'>
+		<iframe title="Test IFrame" src="layout/getResponse.php?delay=3000&messId=3" style="width:600px; height: 400px;">
 	</iframe>
 				
 	</div>
+
+	<button id="RadioButtonDlgBtn" data-dojo-type="dijit.form.Button"  data-dojo-props='onClick:function(){ dijit.byId("RadioButtonDlg").show() }'>Show Dialog With Radio Button at End</button>
+	<div id="RadioButtonDlg" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Radio Button Dialog"'>
+	  <div class="dijitDialogPaneContentArea">
+	    <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>
+	      <label for="dograd">Dog</label> -
+	      <input id="catrad" type="radio" name="pet"></input>
+	      <label for="catrad">Cat</label>
+	    </fieldset>
+	  </div>
+	</div>
 	
 	<p><b><i>(scroll down to see more links to click, for testing positioning / scroll handling)</i></b></p>
 
@@ -373,7 +379,7 @@
 	</p>
 
 	<form>
-	<input id="plainInput">
+	<input id="plainInput"/>
 	<br>
 	<button id="plainButton">hello</button>
 	<br>
@@ -412,12 +418,12 @@
 	hymenaeos.
 	</p>
 	<form>
-		<center>
+		<div style="text-align:center;">
 			<select>
 				<option>1</option>
 				<option>2</option>
 			</select>
-		</center>
+		</div>
 	</form>
 	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
 	et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
@@ -467,12 +473,12 @@
 	hymenaeos.
 	</p>
 	<form>
-		<center>
+		<div style="text-align:center;">
 			<select>
 				<option>1</option>
 				<option>2</option>
 			</select>
-		</center>
+		</div>
 	</form>
 	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
 	et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
@@ -490,7 +496,7 @@
 	</p>
 
 	<p>
-	<button dojoType="dijit.form.Button" onClick="dijit.byId('dialog1').show()">Show Dialog</button> |
+	<button data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ dijit.byId("dialog1").show() }'>Show Dialog</button> |
 	<!-- showing a dialog from an anchor with inline onclick="" is a solution to page onUnLoad firing
 		but you must return false; alternatively, you can dojo.connect() to the anchor links, and
 		e.preventDefault() on the event object passed. using href="javascript:" inline causes onUnLoad
@@ -595,5 +601,3 @@
 
 </body>
 </html>
-
-
diff --git a/dijit/tests/test_Dialog_focusDestroy.html b/dijit/tests/test_Dialog_focusDestroy.html
index fe5de72..cfe7c43 100644
--- a/dijit/tests/test_Dialog_focusDestroy.html
+++ b/dijit/tests/test_Dialog_focusDestroy.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>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dialog Widget Dojo Tests</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 
 		body { font-family : sans-serif; }
@@ -15,11 +15,11 @@
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -29,8 +29,12 @@
 		dojo.require("dijit.Dialog");
 		dojo.require("dijit.form.Button");
 
+    //-sie
+    //the dojo.required code might not be here yet!
+    dojo.addOnLoad(function() {
+
 		// make dojo.toJson() print dates correctly (this feels a bit dirty)
-		function createAndShow() {
+		createAndShow= function() {
 			var node = document.createElement("div");
 			dojo.body().appendChild(node);
 			var dlg = new dijit.Dialog({ title: "test input focus" }, node);
@@ -39,7 +43,7 @@
 			dojo.attr(input,"tabIndex","0");
 			dlg.containerNode.appendChild(input);
 
-			var btn = new dijit.form.Button({ label: "Close" });
+			var btn = new dijit.form.Button({ id:"destroyButton", label: "Close" });
 			dlg.containerNode.appendChild(btn.domNode);
 
 			dojo.connect(btn, "onClick", function(){
@@ -49,6 +53,8 @@
 			});
 			dlg.show();
 		}
+
+    });
 	</script>
 </head>
 <body class="claro">
@@ -61,8 +67,7 @@
 
 	<input id="testInput" name="foo" value="bar" />
 
-	<button dojoType="dijit.form.Button" onclick="createAndShow()">Show Dialog</button>
+	<button id="showDialog" data-dojo-type="dijit.form.Button" data-dojo-props='onClick:function(){ createAndShow() }'>Show Dialog</button>
 
 </body>
 </html>
-
diff --git a/dijit/tests/test_InlineEditBox.html b/dijit/tests/test_InlineEditBox.html
index 5484a38..1312280 100644
--- a/dijit/tests/test_InlineEditBox.html
+++ b/dijit/tests/test_InlineEditBox.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>
+		<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 		<title>Inline Edit Box Test</title>
 
 		<style type="text/css">
-			@import "../../dojo/resources/dojo.css";
+			@import "../themes/claro/document.css";
 			@import "css/dijitTests.css";
 
 			.inlineEdit { background-color: #CCC76A; }
@@ -17,11 +17,11 @@
 		</style>
 
 		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 		<!-- required: dojo.js -->
 		<script type="text/javascript" src="../../dojo/dojo.js"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
+			data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 		<!-- not needed, for testing alternate themes -->
 		<script type="text/javascript" src="_testCommon.js"></script>
@@ -44,29 +44,18 @@
 
 			dojo.require("dojo.parser");	  // scan page for widgets and instantiate them
 
-			function myHandler(id,newValue){
-				console.debug("onChange for id = " + id + ", value: " + newValue);
-			};
-			/*
-			dojo.addOnLoad(function(){
-				dojo.subscribe("widgetFocus", function(widget){
-					console.log("focused on widget " + (widget?widget:"nothing"));
-				});
-				dojo.subscribe("widgetBlur", function(widget){
-					console.log("blurred widget " + (widget?widget:"nothing"));
-				});
-				dojo.subscribe("focusNode", function(node){ console.log("focused on node " + (node?(node.id||node.tagName):"nothing"));});
-			});
-			*/
+			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 Test</h1>
 
-		<span dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
-			url="_data/states.json"></span>
-		<span dojoType="dojo.data.ItemFileReadStore" jsId="productStore">
+		<span data-dojo-id="stateStore" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"_data/states.json"'></span>
+		<span data-dojo-id="productStore" data-dojo-type="dojo.data.ItemFileReadStore" >
 			<script type="dojo/method">
 				this._jsonData =
 					{ identifier: 'name',
@@ -82,50 +71,50 @@
 
 		<h2>Form Letter with blanks</h2>
 		<div class="letter">
-			<h3 id="editable" dojoType="dijit.InlineEditBox" onChange="myHandler(this.id,arguments[0])" autoSave="true" title="company name"></h3>
+			<h3 id="editable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='value:"markup value", onChange:myHandler, autoSave:true, title:"company name"'></h3>
 			<p>
-				Dear <span id="MrSmith" dojoType="dijit.InlineEditBox" width="200px" title="recipient name"></span>,
+				Dear <span id="MrSmith" data-dojo-type="dijit.InlineEditBox" data-dojo-props='width:"200px", title:"recipient name"'></span>,
 			</p>
 			<p class="letter">
 				Thank you for your recent order.
 				Please remit
-				<span id="dollar_as" dojoType="dijit.InlineEditBox" editor="dijit.form.CurrencyTextBox" editorParams="{currency: 'USD'}" width="100px" title="dollar amount"></span> for
+				<span id="dollar_as" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.CurrencyTextBox", editorParams:{currency: "USD"}, width:"100px", title:"dollar amount"'></span> for
 				your purchase of
-				<span dojoType="dijit.InlineEditBox" editor="dijit.form.NumberSpinner" editorParams="{constraints: {places:0} }" width="70px" title="quantity"></span> deluxe
-				<span dojoType="dijit.InlineEditBox" editor="dijit.form.ComboBox" title="item name"
-					editorParams="{searchAttr: 'name', store: productStore, autocomplete: false, hasDownArrow: false}"
-					 width="200px"></span> on
-				<span dojoType="dijit.InlineEditBox" editor="dijit.form.DateTextBox" width="200px" title="purchase date as mm/dd/yy"></span> in
-				<span dojoType="dijit.InlineEditBox" editor="dijit.form.FilteringSelect"
-					editorParams="{searchAttr: 'name', keyAttr: 'abbreviation', store: stateStore, autocomplete: true, hasDownArrow: true}"
-					 width="200px" title="state of purchase"></span>.
+				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.NumberSpinner", editorParams:{constraints: {places:0} }, width:"70px", title:"quantity"'></span> deluxe
+				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.ComboBox", title:"item name",
+					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
+					 width:"200px"'></span> on
+				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.DateTextBox", width:"200px", title:"purchase date as mm/dd/yy"'></span> in
+				<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.FilteringSelect",
+					editorParams:{searchAttr: "name", keyAttr: "abbreviation", store: stateStore, autocomplete: true, hasDownArrow: true},
+					 width:"200px", title:"state of purchase"'></span>.
 			</p>
-			<p id="textarea" dojoType="dijit.InlineEditBox" autoSave="true" editor="dijit.form.Textarea" title="additional details"></p>
+			<p id="textarea" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:true, editor:"dijit.form.Textarea", title:"additional details"'></p>
 			<p>
 				Sincerely,
 			</p>
-			<span  style="margin-left: 2em; font-family: cursive;" dojoType="dijit.InlineEditBox" width="400px" title="sender name"                                                                           ></span>
+			<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='style:"margin-left: 2em; font-family: cursive;", width:"400px", title:"sender name"                                                                           '></span>
 		</div>
-		<hr style="margin-bottom: 1em;">
+		<hr style="margin-bottom: 1em;"/>
 
 		<h2>Form Letter with <span id="predefined">predefined values</span>, and no auto-save</h2>
 		<div class="letter">
-			<h3 id="editable2" dojoType="dijit.InlineEditBox" onChange="myHandler(this.id,arguments[0])" autoSave="false" title="company name">
+			<h3 id="editable2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='onChange:myHandler, autoSave:false, title:"company name"'>
 				Bob Vance Refrigeration
 			</h3>
 			<p>
-				Dear <span dojoType="dijit.InlineEditBox" width="200px" autoSave="false" title="recipient name">John</span>,
+				Dear <span data-dojo-type="dijit.InlineEditBox" data-dojo-props='width:"200px", autoSave:false, title:"recipient name"'>John</span>,
 			</p>
 			<p class="letter">
 				Thank you for your recent order.
 				Please remit
-				<span id="dollar" dojoType="dijit.InlineEditBox" editor="dijit.form.CurrencyTextBox" editorParams="{currency: 'USD'}" width="100px" autoSave="false" title="dollar amount">$2,000</span>
+				<span id="dollar" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.CurrencyTextBox", editorParams:{currency: "USD"}, width:"100px", autoSave:false, title:"dollar amount"'>$2,000</span>
 				for your purchase of
-				<span id="quantity" dojoType="dijit.InlineEditBox" editor="dijit.form.NumberSpinner" editorParams="{constraints: {places:0} }" width="70px" autoSave="false" title="quantity">3</span>
+				<span id="quantity" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.NumberSpinner", editorParams:{constraints: {places:0} }, width:"70px", autoSave:false, title:"quantity"'>3</span>
 				deluxe
-				<span id="item" dojoType="dijit.InlineEditBox" editor="dijit.form.ComboBox"
-					editorParams="{searchAttr: 'name', store: productStore, autocomplete: false, hasDownArrow: false}"
-					 width="200px" autoSave="false" title="item name">refrigerators</span>
+				<span id="item" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.ComboBox",
+					editorParams:{searchAttr: "name", store: productStore, autocomplete: false, hasDownArrow: false},
+					 width:"200px", autoSave:false, title:"item name"'>refrigerators</span>
 				on
 				<!--
 					normally the server is in charge of formatting the displayed date pattern (01/05/2007) below
@@ -133,25 +122,25 @@
 					but since this test is static HTML, we instead hardcode the displayed value and use editorParams
 					to tell DateTextBox to expect that pattern regardless of the machine's locale
 				-->
-				<span id="purchase" dojoType="dijit.InlineEditBox"
-					editor="dijit.form.DateTextBox" editorParams="{constraints: {datePattern: 'MM/dd/yyyy'}}"
-					width="200px" autoSave="false" title="purchase date as mm/dd/yy">01/05/2007</span>
+				<span id="purchase" data-dojo-type="dijit.InlineEditBox"
+					data-dojo-props='editor:"dijit.form.DateTextBox", editorParams:{constraints: {datePattern: "MM/dd/yyyy"}},
+					width:"200px", autoSave:false, title:"purchase date as mm/dd/yy"'>01/05/2007</span>
 				in
-				<span id="state" dojoType="dijit.InlineEditBox" editor="dijit.form.FilteringSelect"
-					editorParams="{searchAttr: 'name', keyAttr: 'abbreviation', store: stateStore, autocomplete: true, hasDownArrow: false}"
-					 width="200px" autoSave="false" title="state of purchase">
+				<span id="state" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.FilteringSelect",
+					editorParams:{searchAttr: "name", keyAttr: "abbreviation", store: stateStore, autocomplete: true, hasDownArrow: false},
+					 width:"200px", autoSave:false, title:"state of purchase"'>
 					 Pennsylvania
 				</span>.
 			</p>
-			<p dojoType="dijit.InlineEditBox" autoSave="false" editor="dijit.form.Textarea" title="additional details">
+			<p data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:false, editor:"dijit.form.Textarea", title:"additional details"'>
 				We sincerely appreciate your business and hope we can do business again.
 			</p>
 			<p>
 				Sincerely,
 			</p>
-			<span  style="margin-left: 2em; font-family: cursive;" dojoType="dijit.InlineEditBox" width="400px" autoSave="false" title="sender name">Bob Vance</span>
+			<span data-dojo-type="dijit.InlineEditBox" data-dojo-props='style:"margin-left: 2em; font-family: cursive;", width:"400px", autoSave:false, title:"sender name"'>Bob Vance</span>
 		</div>
-		<hr style="margin-bottom: 1em;">
+		<hr style="margin-bottom: 1em;"/>
 
 
 		<h2>Inline-block Text (of 400px width)</h2>
@@ -162,11 +151,11 @@
 		(before plain inline) <fieldset class="dijitInline"><div style="width: 400px;">hello world</div></fieldset> (after plain inline)
 		<br>
 		(before editable inline)
-		<fieldset class="dijitInline"><div dojoType="dijit.InlineEditBox" onChange="myHandler(this.id,arguments[0])" width="400px" style="width: 400px;">
+		<fieldset class="dijitInline"><div data-dojo-type="dijit.InlineEditBox" data-dojo-props='onChange:myHandler, width:"400px", style:"width: 400px;"'>
 			hello world
 		</div></fieldset>
 		(after editable inline)
-		<hr style="width:100%;">
+		<hr style="width:100%;"/>
 
 		<h2>Pararagraph</h2>
 		(before plain paragraph)
@@ -185,7 +174,7 @@ pulvinar in, consequat ut, leo. Nullam nec est. Aenean id risus blandit
 tortor pharetra congue. Suspendisse pulvinar.
 		</p>
 		(before editable paragraph.  the editable paragraph has Save/Cancel buttons when open.)
-		<p id="areaEditable" dojoType="dijit.InlineEditBox" autoSave="false" editor="dijit.form.Textarea">
+		<p id="areaEditable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='autoSave:false, editor:"dijit.form.Textarea"'>
 			Aliquam vitae enim. Duis scelerisque metus auctor est venenatis
 imperdiet. Fusce dignissim porta augue. Nulla vestibulum. Integer lorem
 nunc, ullamcorper a, commodo ac, malesuada sed, dolor. Aenean id mi in
@@ -203,14 +192,14 @@ tortor pharetra congue. Suspendisse pulvinar.
 		<button onClick="dijit.byId('areaEditable').set('disabled', true)">disable</button> /
 		<button onClick="dijit.byId('areaEditable').set('disabled', false)">enable</button>
 		the InlineEditBox above.
-		<hr style="width:100%;">
+		<hr style="width:100%;"/>
 
 		<h2>Editor</h2>
-		<div id="inlineRTE" dojoType="dijit.InlineEditBox" editor="dijit.Editor"
-			autoSave="false" renderAsHtml="true"
-			editorParams="{height: '', extraPlugins: ['dijit._editor.plugins.AlwaysShowToolbar']}">
+		<div id="inlineRTE" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.Editor",
+			autoSave:false, renderAsHtml:true,
+			editorParams:{height: "", extraPlugins: ["dijit._editor.plugins.AlwaysShowToolbar"]}'>
 			<b>Aliquam</b> vitae enim. <i>Duis</i> scelerisque metus auctor est venenatis
-imperdiet. <u>Fusce</u> dignissim porta augue. Nulla vestibulum. Integer lorem
+imperdiet. <span style="text-decoration: underline;"> Fusce</span> 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
@@ -230,31 +219,31 @@ tortor pharetra congue. Suspendisse pulvinar.
 
 		<h2>FilteringSelect (no down arrow, and save/cancel buttons):</h2>
 		before
-		<span id="filteringSelect2" dojoType="dijit.InlineEditBox" editor="dijit.form.FilteringSelect"
-			editorParams="{searchAttr: 'name', keyAttr: 'abbreviation', store: stateStore, autocomplete: true, hasDownArrow: false}"
-			 width="200px" autoSave="false">
+		<span id="filteringSelect2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:"dijit.form.FilteringSelect",
+			editorParams:{searchAttr: "name", keyAttr: "abbreviation", store: stateStore, autocomplete: true, hasDownArrow: false},
+			 width:"200px", autoSave:false'>
 			Indiana
 		</span>
 		<button onclick="dijit.byId('filteringSelect2').edit();return false;">Edit previous value</button>
 		after
-		<hr style="width:100%;">
+		<hr style="width:100%;"/>
 
 		<h2>Programmatically created:</h2>
 		before block<div style="display:block;" id="programmatic">Click here to edit a block programmatically created inline edit region</div>after
 		<script type="text/javascript">
 			// See if we can make a widget in script
 			dojo.addOnLoad(function(){
-				var inlineWidget = new dijit.InlineEditBox({renderAsHtml: true}, 'programmatic');
+				var inlineWidget = new dijit.InlineEditBox({ renderAsHtml: true, onChange:myHandler }, 'programmatic');
  			});
 		</script>
-		<hr style="width:100%;">
+		<hr style="width:100%;"/>
 		<h2>Complex renderAsHtml="false"</h2>
-		<div id="renderAsHtml_false" dojoType="dijit.InlineEditBox" renderAsHtml="false" width="400px" style="width:400px;">
+		<div id="renderAsHtml_false" data-dojo-type="dijit.InlineEditBox" data-dojo-props='renderAsHtml:false, width:"400px", style:"width:400px;"'>
 			<B>not bold</B>&lt;input&gt;
 		</div>
-		<hr style="width:100%;">
+		<hr style="width:100%;"/>
 		<h2>Complex renderAsHtml="true"</h2>
-		<div id="renderAsHtml_true" dojoType="dijit.InlineEditBox" renderAsHtml="true" width="400px" style="width:400px;">
+		<div id="renderAsHtml_true" data-dojo-type="dijit.InlineEditBox" data-dojo-props='renderAsHtml:true, width:"400px", style:"width:400px;"'>
 			<B>not bold</B><B>bold</B>&lt;input&gt;
 		</div>
 	</body>
diff --git a/dijit/tests/test_Menu.html b/dijit/tests/test_Menu.html
index b647159..b669bba 100644
--- a/dijit/tests/test_Menu.html
+++ b/dijit/tests/test_Menu.html
@@ -1,12 +1,13 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Menu System Test</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 
 		body { padding: 0; }
@@ -25,16 +26,16 @@
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
 
-	<script language="JavaScript" type="text/javascript">
+	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.Menu");
 		dojo.require("dijit.MenuItem");
@@ -44,10 +45,11 @@
 		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 language="Javascript" type="text/javascript">
+    <script type="text/javascript">
         function createMenu() {
             // create a menu programmatically
             function fClick() {console.log("clicked!")};
@@ -106,219 +108,219 @@
 </head>
 <body class="claro">
 
-	<div dojoType="dijit.Menu" id="windowContextMenu" contextMenuForWindow="true" style="display: none;">
-		<div dojoType="dijit.MenuItem" onClick="console.log('Hello world');">Context Menu</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.MenuItem" disabled="true" onClick="alert('this shouldn\'t appear');">Disabled Item</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
-			onClick="console.log('not actually cutting anything, just a test!')" accelKey="Ctrl+X">Cut</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
-			onClick="console.log('not actually copying anything, just a test!')" accelKey="Ctrl+C">Copy</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
-			onClick="console.log('not actually pasting anything, just a test!')" accelKey="Ctrl+V">Paste</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.PopupMenuItem" id="enabledSubmenu">
+	<div id="windowContextMenu" data-dojo-type="dijit.Menu" data-dojo-props='contextMenuForWindow:true, style:"display: none;"'>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Context Menu</div>
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true, onClick:function(){ alert("this should NOT appear"); }'>Disabled Item</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+			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 dojoType="dijit.Menu" id="submenu2">
-				<div dojoType="dijit.MenuItem" id="submenu2_item1" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-				<div dojoType="dijit.MenuItem" id="submenu2_item2" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
-				<div dojoType="dijit.PopupMenuItem" id="deeperSubmenu">
+			<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 dojoType="dijit.Menu" id="submenu4">
-						<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 1!')">Sub-sub-menu Item One</div>
-						<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
+					<div id="submenu4" data-dojo-type="dijit.Menu" >
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem" disabled="true">
+		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
 			<span>Disabled Submenu</span>
-			<div dojoType="dijit.Menu" id="submenu3" style="display: none;">
-				<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-				<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
+			<div id="submenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 			</div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Different popup</span>
-			<div dojoType="dijit.ColorPalette"></div>
+			<div data-dojo-type="dijit.ColorPalette"></div>
 		</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.CheckedMenuItem" checked="true" onChange="console.log('Now set to ' + arguments[0])">Checked</div>
-		<div dojoType="dijit.CheckedMenuItem">Not Checked</div>
-		<div dojoType="dijit.CheckedMenuItem" checked="true" disabled="true">Checked Disabled</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
+		<div data-dojo-type="dijit.CheckedMenuItem">Not Checked</div>
+		<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Bigger Submenu</span>
-			<div dojoType="dijit.Menu" id="bigsubmenu" style="display: none;">
-				<div dojoType="dijit.MenuItem">Item One</div>
-				<div dojoType="dijit.MenuItem">Item Two</div>
-				<div dojoType="dijit.MenuItem">Item Three</div>
-				<div dojoType="dijit.MenuItem">Item Four</div>
-				<div dojoType="dijit.MenuItem">Item Five</div>
-				<div dojoType="dijit.MenuItem">Item Six</div>
-				<div dojoType="dijit.MenuItem">Item Seven</div>
-				<div dojoType="dijit.MenuItem">Item Eight</div>
-				<div dojoType="dijit.MenuItem">Item Nine</div>
-				<div dojoType="dijit.MenuItem">Item Ten</div>
+			<div id="bigsubmenu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit.MenuItem">Item One</div>
+				<div data-dojo-type="dijit.MenuItem">Item Two</div>
+				<div data-dojo-type="dijit.MenuItem">Item Three</div>
+				<div data-dojo-type="dijit.MenuItem">Item Four</div>
+				<div data-dojo-type="dijit.MenuItem">Item Five</div>
+				<div data-dojo-type="dijit.MenuItem">Item Six</div>
+				<div data-dojo-type="dijit.MenuItem">Item Seven</div>
+				<div data-dojo-type="dijit.MenuItem">Item Eight</div>
+				<div data-dojo-type="dijit.MenuItem">Item Nine</div>
+				<div data-dojo-type="dijit.MenuItem">Item Ten</div>
 			</div>
 		</div>
 	</div>
 
-	<div dojoType="dijit.Menu" id="leftClickContextMenu" leftClickToOpen="true" targetNodeIds="input2" style="display: none;">
-		<div dojoType="dijit.MenuItem" disabled="true">Left Click Menu</div>
-		<div dojoType="dijit.MenuItem" onClick="console.log('Hello world');">Enabled Item</div>
-		<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
-			onClick="console.log('not actually cutting anything, just a test!')">Cut</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
-			onClick="console.log('not actually copying anything, just a test!')">Copy</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
-			onClick="console.log('not actually pasting anything, just a test!')">Paste</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.PopupMenuItem">
+	<div id="leftClickContextMenu" data-dojo-type="dijit.Menu" data-dojo-props='leftClickToOpen:true, targetNodeIds:["input2"], style:"display: none;"'>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true'>Left Click Menu</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Enabled Item</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true'>Disabled Item</div>
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+			onClick:function(){ console.log("not actually cutting anything, just a test!") }'>Cut</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+			onClick:function(){ console.log("not actually copying anything, just a test!") }'>Copy</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+			onClick:function(){ console.log("not actually pasting anything, just a test!") }'>Paste</div>
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Enabled Submenu</span>
-			<div dojoType="dijit.Menu" id="leftsubmenu2">
-				<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-				<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
-				<div dojoType="dijit.PopupMenuItem">
+			<div id="leftsubmenu2" data-dojo-type="dijit.Menu" >
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+				<div data-dojo-type="dijit.PopupMenuItem">
 					<span>Deeper Submenu</span>
-					<div dojoType="dijit.Menu" id="leftsubmenu4">
-						<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 1!')">Sub-sub-menu Item One</div>
-						<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
+					<div id="leftsubmenu4" data-dojo-type="dijit.Menu" >
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem" disabled="true">
+		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
 			<span>Disabled Submenu</span>
-			<div dojoType="dijit.Menu" id="leftsubmenu3" style="display: none;">
-				<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-				<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
+			<div id="leftsubmenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 			</div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Different popup</span>
-			<div dojoType="dijit.ColorPalette"></div>
+			<div data-dojo-type="dijit.ColorPalette"></div>
 		</div>
 	</div>
 
 	<table id="formattingTable">
 		<tr>
-			<td 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
 				     with the URL when clicked -->
 				<textarea id="link" tabIndex="0" readOnly class="dijitReset" style="font-family:monospace;font-size:12px;width:84px;text-decoration:underline;overflow:hidden;background-color:transparent;" rows=1>random link</textarea>
 			</td>
-			<td id="menuBarContainer" width="100%">
-				<div id="menubar" dojoType="dijit.MenuBar">
-					<div dojoType="dijit.PopupMenuBarItem" id="file">
+			<td id="menuBarContainer" style="width:100%;">
+				<div id="menubar" data-dojo-type="dijit.MenuBar">
+					<div id="file" data-dojo-type="dijit.PopupMenuBarItem" >
 						<span>File</span>
-						<div dojoType="dijit.Menu" id="fileMenu">
-							<div dojoType="dijit.MenuItem" id="new">New</div>
-							<div dojoType="dijit.MenuItem" id="open">Open</div>
-							<div dojoType="dijit.MenuSeparator" id="separator"></div>
-							<div dojoType="dijit.MenuItem" id="save" iconClass="dijitEditorIconSave">Save</div>
-							<div dojoType="dijit.MenuItem" id="saveas">Save As...</div>
+						<div id="fileMenu" data-dojo-type="dijit.Menu" >
+							<div id="new" data-dojo-type="dijit.MenuItem" >New</div>
+							<div id="open" data-dojo-type="dijit.MenuItem" >Open</div>
+							<div id="separator" data-dojo-type="dijit.MenuSeparator" ></div>
+							<div id="save" data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIconSave"'>Save</div>
+							<div id="saveas" data-dojo-type="dijit.MenuItem" >Save As...</div>
 						</div>
 					</div>
-					<div dojoType="dijit.PopupMenuBarItem" id="edit">
+					<div id="edit" data-dojo-type="dijit.PopupMenuBarItem" >
 						<span>Edit</span>
-						<div dojoType="dijit.Menu" id="editMenu">
-							<div dojoType="dijit.MenuItem" id="cut" iconClass="dijitEditorIcon dijitEditorIconCut"
-								onClick="console.log('not actually cutting anything, just a test!');" accelKey="Ctrl+X">Cut</div>
-							<div dojoType="dijit.MenuItem" id="copy" iconClass="dijitEditorIcon dijitEditorIconCopy"
-								onClick="console.log('not actually copying anything, just a test!')" accelKey="Ctrl+C">Copy</div>
-							<div dojoType="dijit.MenuItem" id="paste" iconClass="dijitEditorIcon dijitEditorIconPaste"
-								onClick="console.log('not actually pasting anything, just a test!')" accelKey="Ctrl+V">Paste</div>
+						<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 dojoType="dijit.PopupMenuBarItem" id="view">
+					<div id="view" data-dojo-type="dijit.PopupMenuBarItem" >
 						<span>View</span>
-						<div dojoType="dijit.Menu" id="viewMenu">
-							<div dojoType="dijit.MenuItem">Normal</div>
-							<div dojoType="dijit.MenuItem">Outline</div>
-							<div dojoType="dijit.PopupMenuItem">
+						<div id="viewMenu" data-dojo-type="dijit.Menu" >
+							<div data-dojo-type="dijit.MenuItem">Normal</div>
+							<div data-dojo-type="dijit.MenuItem">Outline</div>
+							<div data-dojo-type="dijit.PopupMenuItem">
 								<span>Zoom</span>
-								<div dojoType="dijit.Menu" id="zoomMenu">
-									<div dojoType="dijit.MenuItem">50%</div>
-									<div dojoType="dijit.MenuItem">75%</div>
-									<div dojoType="dijit.MenuItem">100%</div>
-									<div dojoType="dijit.MenuItem">150%</div>
-									<div dojoType="dijit.MenuItem">200%</div>
+								<div id="zoomMenu" data-dojo-type="dijit.Menu" >
+									<div data-dojo-type="dijit.MenuItem">50%</div>
+									<div data-dojo-type="dijit.MenuItem">75%</div>
+									<div data-dojo-type="dijit.MenuItem">100%</div>
+									<div data-dojo-type="dijit.MenuItem">150%</div>
+									<div data-dojo-type="dijit.MenuItem">200%</div>
 								</div>
 							</div>
 						</div>
 					</div>
-					<div dojoType="dijit.PopupMenuBarItem" id="help">
+					<div id="help" data-dojo-type="dijit.PopupMenuBarItem" >
 						<span>Help</span>
-						<div dojoType="dijit.Menu" id="helpMenu">
-							<div dojoType="dijit.MenuItem">Help Topics</div>
-							<div dojoType="dijit.MenuItem">About Dijit</div>
+						<div id="helpMenu" data-dojo-type="dijit.Menu" >
+							<div data-dojo-type="dijit.MenuItem">Help Topics</div>
+							<div data-dojo-type="dijit.MenuItem">About Dijit</div>
 						</div>
 					</div>
-					<div dojoType="dijit.PopupMenuBarItem" disabled="true">
+					<div data-dojo-type="dijit.PopupMenuBarItem" data-dojo-props='disabled:true'>
 						<span>Disabled</span>
-						<div dojoType="dijit.Menu">
-							<div dojoType="dijit.MenuItem">You should not see this</div>
+						<div data-dojo-type="dijit.Menu">
+							<div data-dojo-type="dijit.MenuItem">You should not see this</div>
 						</div>
 					</div>
-					<div dojoType="dijit.PopupMenuBarItem">
+					<div data-dojo-type="dijit.PopupMenuBarItem">
 						<span>Empty</span>
-						<div dojoType="dijit.Menu">
+						<div data-dojo-type="dijit.Menu">
 						</div>
 					</div>
-					<div dojoType="dijit.MenuBarItem" onclick="console.log('no submenu, just a clickable MenuItem');">
+					<div data-dojo-type="dijit.MenuBarItem" data-dojo-props='onClick:function(){ console.log("no submenu, just a clickable MenuItem"); }'>
 						Click me!
 					</div>
 				</div>
 			</td>
 		</tr>
 		<tr>
-			<td id="navMenuContainer" class="dijitMenu" valign=top width="0%">
+			<td id="navMenuContainer" class="dijitMenu" style="vertical-align:top; width:0%;">
 
 				<h3 style="margin-bottom: 2em;">Navigation menu:</h3>
-				<div dojoType="dijit.Menu" id="navMenu">
-					<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
-						onClick="console.log('drama!');">Drama</div>
-					<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
-						onClick="console.log('comedy!')">Comedy</div>
-					<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
-						onClick="console.log('romance!')">Romance</div>
-					<div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
-						onClick="console.log('documentary!')">Documentary</div>
-					<div dojoType="dijit.MenuSeparator"></div>
-					<div dojoType="dijit.PopupMenuItem" id="navMenuPopupItem1">
+				<div id="navMenu" data-dojo-type="dijit.Menu" >
+					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+						onClick:function(){ console.log("drama!"); }'>Drama</div>
+					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+						onClick:function(){ console.log("comedy!") }'>Comedy</div>
+					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+						onClick:function(){ console.log("romance!") }'>Romance</div>
+					<div data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+						onClick:function(){ console.log("documentary!") }'>Documentary</div>
+					<div data-dojo-type="dijit.MenuSeparator"></div>
+					<div id="navMenuPopupItem1" data-dojo-type="dijit.PopupMenuItem" >
 						<span>Enabled Submenu</span>
-						<div dojoType="dijit.Menu" id="navMenuSub1">
-							<div dojoType="dijit.MenuItem" id="navMenuSub1_item1" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-							<div dojoType="dijit.MenuItem" id="navMenuSub1_item2" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
-							<div dojoType="dijit.PopupMenuItem" id="navMenuSub1_popup">
+						<div id="navMenuSub1" data-dojo-type="dijit.Menu" >
+							<div id="navMenuSub1_item1" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+							<div id="navMenuSub1_item2" data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
+							<div id="navMenuSub1_popup" data-dojo-type="dijit.PopupMenuItem" >
 								<span>Deeper Submenu</span>
-								<div dojoType="dijit.Menu" id="navMenuSub2">
-									<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 1!')">Sub-sub-menu Item One</div>
-									<div dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
+								<div id="navMenuSub2" data-dojo-type="dijit.Menu" >
+									<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</div>
+									<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</div>
 								</div>
 							</div>
 						</div>
 					</div>
-					<div dojoType="dijit.PopupMenuItem" disabled="true" id="navMenuDisabledItem">
+					<div id="navMenuDisabledItem" data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true '>
 						<span>Disabled Submenu</span>
-						<div dojoType="dijit.Menu" id="navMenuSub3" style="display: none;">
-							<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</div>
-							<div dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</div>
+						<div id="navMenuSub3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+							<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</div>
+							<div data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</div>
 						</div>
 					</div>
-					<div dojoType="dijit.PopupMenuItem">
+					<div data-dojo-type="dijit.PopupMenuItem">
 						<span>Different popup</span>
-						<div dojoType="dijit.ColorPalette"></div>
+						<div data-dojo-type="dijit.ColorPalette"></div>
 					</div>
-					<div dojoType="dijit.MenuSeparator"></div>
-					<div dojoType="dijit.CheckedMenuItem" checked="true" onChange="console.log('Now set to ' + arguments[0])">Checked</div>
-					<div dojoType="dijit.CheckedMenuItem" id="checked2" >Not Checked</div>
-					<div dojoType="dijit.CheckedMenuItem" checked="true" disabled="true">Checked Disabled</div>
+					<div data-dojo-type="dijit.MenuSeparator"></div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, onChange:function(val){ console.log("Now set to " + val); }'>Checked</div>
+					<div id="checked2" data-dojo-type="dijit.CheckedMenuItem" >Not Checked</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props='checked:true, disabled:true'>Checked Disabled</div>
 				</div>
 			</td>
 
@@ -331,6 +333,7 @@
 					<li>"Navigation bar" Menu widget on left, a.k.a vertical MenuBar
 					<li>MenuBar on top
 					<li>page level context menu (right-click anywhere on page)
+					<li>form widget context menu (right-click on textbox widget)</li>
 					<li>left click context menu (left click on input on far right)
 					<li>Example of programatically created menu
 					<li>Note: while some accelerator (shortcut) keys are displayed in the context menu, they are not actually hooked up to the corresponding actions (if any), they need to be setup explicitly by the user
@@ -345,16 +348,17 @@
 						the right menu by verifying the left<br/>
 						click one starts with "Left Click Menu"<br/>
 						at the very top.
-						<input id=input2 value="top-right">
+						<input id=input2 value="top-right"/>
 					</p>
-					<input id=input1 value="top-left">
+					<input id=input1 value="top-left"/>
 					<textarea id=textarea>hello there!</textarea><br>
 					<select>
 						<option>check if i</option>
 						<option>bleed through</option>
 						<option>on IE6</option>
 					</select>
-					<button id=button>push me</button>
+					<button id=button>push me</button><br>
+					<input data-dojo-type="dijit.form.TextBox" id="formwidget" data-dojo-props='style:"width:25em;", value:"dijit.form._FormWidget focus test"'/>
 				</form>
 
 			    <div id="prog_menu" style="clear: both; border:1px solid blue; padding:10px; margin:20px 0;">
@@ -367,8 +371,8 @@
 				<p>(this space intentionally left blank to aid testing with controls
 				at the bottom of the browser window)</p>
 				<div style="height:500px"></div>
-				<input id=input3 value="bottom-left">
-				<p style="text-align:right"><input id=input4 value="bottom-right"></p>
+				<input id=input3 value="bottom-left"/>
+				<p style="text-align:right"><input id=input4 value="bottom-right"/></p>
 
 				<p>See also: <a href="form/test_Button.html">form/test_Button</a>
 				(PopupMenu is used with DropDownButton and ComboButton)</p>
diff --git a/dijit/tests/test_Menu_iframe.html b/dijit/tests/test_Menu_iframe.html
index 3fa36b6..d916b7e 100644
--- a/dijit/tests/test_Menu_iframe.html
+++ b/dijit/tests/test_Menu_iframe.html
@@ -1,24 +1,27 @@
+<!DOCTYPE html>
 <html>
 <head>
-<style type="text/css">
-	@import "../themes/tundra/tundra.css";
-</style>
-<script type="text/javascript" src="../../dojo/dojo.js"
-	djConfig="parseOnLoad:true, isDebug:true"></script>
-<script type="text/javascript">
-	dojo.require("dijit.Menu");
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Menu iframe test</title>
+	<style type="text/css">
+		@import "../themes/claro/claro.css";
+	</style>
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad:true, isDebug:true"></script>
+	<script type="text/javascript">
+		dojo.require("dijit.Menu");
 
-	function setContents(str){
-		dojo.byId('iframe').src = "javascript:'" + str.replace("'", "\\'") + "'";
-	}
-	function button2(){
-		setContents('<div style="height: 300px; border: solid blue 2px">bill was here</div>');
-	}
-</script>
+		function setContents(str){
+			dojo.byId('iframe').src = "javascript:'" + str.replace("'", "\\'") + "'";
+		}
+		function button2(){
+			setContents('<div style="height: 300px; border: solid blue 2px">bill was here</div>');
+		}
+	</script>
 </head>
 <body class="claro">
-	<div dojoType="dijit.Menu" id="menu" targetNodeIds="iframe" style="display:none;">
-		<div dojoType="dijit.MenuItem">context menu</div>
+	<div id="menu" data-dojo-type="dijit.Menu" data-dojo-props='targetNodeIds:["iframe"], style:"display:none;"'>
+		<div data-dojo-type="dijit.MenuItem">context menu</div>
 	</div>
 	<div style="border: 1px solid gray; height: 150px;">filler div to offset iframe position (for testing)</div>
 	<div style="position: relative; border: 3px solid blue; padding: 10px;">
@@ -30,9 +33,9 @@
 		End of div.
 	</div>
 	<br>
-	<button onclick="dojo.byId('iframe').src='layout/doc0.html'">reset contents to doc0.html</button>
-	<button onclick="button2();">reset contents to 'bill was here'</button>
-	<button onclick="dijit.byId('menu').unBindDomNode('iframe')">detach menu</button>
-	<button onclick="dijit.byId('menu').bindDomNode('iframe')">re-attach menu</button>
+	<button id="resetToDoc" onclick="dojo.byId('iframe').src='layout/doc0.html'">reset contents to doc0.html</button>
+	<button id="resetToBill" onclick="button2();">reset contents to 'bill was here'</button>
+	<button id="detachMenu" onclick="dijit.byId('menu').unBindDomNode('iframe')">detach menu</button>
+	<button id="reattachMenu" onclick="dijit.byId('menu').bindDomNode('iframe')">re-attach menu</button>
 </body>
 </html>
diff --git a/dijit/tests/test_ProgressBar.html b/dijit/tests/test_ProgressBar.html
deleted file mode 100644
index a832030..0000000
--- a/dijit/tests/test_ProgressBar.html
+++ /dev/null
@@ -1,172 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Dojo Toolkit - ProgressBar test</title>
-
-	<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
-
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "css/dijitTests.css";
-		body {
-			margin: 1em;
-		}
-		.smallred .dijitProgressBarTile {
-			background:red;
-		}
-		.smallred .dijitProgressBarLabel {
-			display:none;
-		}
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.ProgressBar");
-		dojo.require("dojo.parser");	// scan page for widgets
-		dojo.require("dojo.string");
-
-		dojo.addOnLoad(go);
-
-		function go(){
-			// note that programmatic instantiation doesn't pull any parameters from the srcNodeRef, not even id
-			var theBar = new dijit.ProgressBar({id: "testBar", width: 400, maximum: 256, duration: 2000,
-				report:function(percent){
-					return dojo.string.substitute("${0} out of ${1} max chars", [this.progress, this.maximum]);
-				}
-			}, dojo.byId("testBar"));
-
-			dojo.byId("test").value="";
-			dojo.byId("progressValue").focus();
-			dojo.byId("progressValue").value = dijit.byId("setTestBar").progress;
-			dojo.byId("maximum").value = dijit.byId("setTestBar").maximum;
-			dojo.connect(dojo.byId("test"), "onkeyup", null, keyUpHandler);
-			dojo.connect(dojo.byId("set"), "onclick", null, setParameters);
-			dojo.connect(dojo.byId("startTimer"), "onclick", null,
-				function(){ remoteProgress(dijit.byId("timerBar")); } );
-
-			function indeterminateSetter(id, value){
-				return function(){
-					dijit.byId(id).update({'indeterminate': value});
-				}
-			}
-			dojo.connect(dojo.byId("setIndeterminate1True"), "onclick", null,
-				indeterminateSetter("indeterminateBar1", true));
-			dojo.connect(dojo.byId("setIndeterminate1False"), "onclick", null,
-				indeterminateSetter("indeterminateBar1", false));
-			dojo.connect(dojo.byId("setIndeterminate2True"), "onclick", null,
-				indeterminateSetter("indeterminateBar2", true));
-			dojo.connect(dojo.byId("setIndeterminate2False"), "onclick", null,
-				indeterminateSetter("indeterminateBar2", false));
-		}
-
-		// An example of polling on a separate (heartbeat) server thread.  This is useful when the progress
-		// is entirely server bound and there is no existing interaction with the server to determine status.
-
-		// We don't have a server to run against, but a simple heartbeat implementation might look something
-		// like this:
-
-		// function getProgressReport(){
-		//	var dataSource = "http://dojotoolkit.org";
-		//	return dojo.xhrGet({url: dataSource, handleAs: "json", content: {key: "progress"}});
-		// }
-
-		// Instead, we'll just tick off intervals of 10
-
-		var fakeProgress = 0;
-		function getProgressReport(){
-			var deferred = new dojo.Deferred();
-			fakeProgress = Math.min(fakeProgress + 10, 100);
-			deferred.callback(fakeProgress+"%");
-			return deferred;
-		}
-
-		function remoteProgress(bar){
-			var _timer = setInterval(function(){
-				var report = getProgressReport();
-				report.addCallback(function(response){
-					bar.update({progress: response});
-					if(response == "100%"){
-						clearInterval(_timer);
-						_timer = null;
-						return;
-					}
-				});
-			}, 3000); // on 3 second intervals
-		}
-
-		function setParameters(){
-			dijit.byId("setTestBar").update({maximum: dojo.byId("maximum").value, progress: dojo.byId("progressValue").value});
-		}
-
-		function keyUpHandler(){
-			dijit.byId("testBar").update({progress:dojo.byId("test").value.length});
-			dijit.byId("testBarInt").update({progress:dojo.byId("test").value.length});
-			dijit.byId("smallTestBar").update({progress:dojo.byId("test").value.length});
-		}
-	</script>
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit ProgressBar Tests</h1>
-
-	<h3>Test 1</h3>
-	Progress Value <input type="text" name="progressValue" id="progressValue" />
-	<br>
-	Max Progress Value <input type="text" name="maximum" id="maximum" />
-	<br>
-	<input type="button" name="set" id="set" value="set!" />
-	<br>
-	<div style="width:400px"
-		maximum="200" id="setTestBar" progress="20" dojoType="dijit.ProgressBar"></div>
-
-	<h3>Test 2</h3>
-	Write here: <input type="text" value="" name="test" maxLength="256" id="test" style="width:300"/>
-	<br />
-	<br />
-	<div id="testBar" style='width:300px'></div>
-	<br />
-	Small, without text and background image:
-	<br />
-	<div style="width:400px; height:10px" class="smallred"
-		maximum="256" id="smallTestBar" dojoType="dijit.ProgressBar"></div>
-	<br />
-	Show decimal place:
-	<div places="1" style="width:400px"
-		maximum="256" id="testBarInt" dojoType="dijit.ProgressBar"></div>
-
-	<h3>Test 3</h3>
-	No explicit maximum (both 50%)
-	<div style="width:400px"
-		id="implied1" progress="50" dojoType="dijit.ProgressBar"></div>
-	<br />
-	<div style="width:400px"
-		id="implied2" progress="50%" dojoType="dijit.ProgressBar"></div>
-
-	<h3>Test 4</h3>
-	<input type="button" name="startTimer" id="startTimer" value="Start Timer" />
-	<div style="width:400px" id="timerBar"
-		maximum="100" progress="0" dojoType="dijit.ProgressBar"></div>
-
-	<h3>Test 5 - indeterminate progess</h3>
-	<input type="button" name="setIndeterminate1True" id="setIndeterminate1True" value="Make Indeterminate" />
-	<input type="button" name="setIndeterminate1False" id="setIndeterminate1False" value="Make Determinate" />
-	<div style="width:400px" indeterminate="true" id="indeterminateBar1"
-		dojoType="dijit.ProgressBar"></div>
-	<input type="button" name="setIndeterminate2True" id="setIndeterminate2True" value="Make Indeterminate" />
-	<input type="button" name="setIndeterminate2False" id="setIndeterminate2False" value="Make Determinate" />
-	<div style="width:400px" progress="50" id="indeterminateBar2"
-		dojoType="dijit.ProgressBar"></div>
-
-</body>
-</html>
diff --git a/dijit/tests/test_TitlePane.html b/dijit/tests/test_TitlePane.html
index 94ef483..db9292b 100644
--- a/dijit/tests/test_TitlePane.html
+++ b/dijit/tests/test_TitlePane.html
@@ -1,25 +1,25 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TitlePane Test</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: false, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
 
-	<script language="JavaScript" type="text/javascript">
+	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.TitlePane");
 		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
@@ -28,41 +28,47 @@
 		dojo.require("dijit.form.Button");
 		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.layout.TabContainer");
+		dojo.require("dijit.layout.AccordionContainer");
 		dojo.require("dijit.layout.LinkPane");
 
 		function randomMessageId(){
 			return Math.floor(Math.random() * 3) + 3;
 		}
 
-		dojo.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"' +
-							                'waiRole="button" dojoAttachPoint="focusNode,arrowNode" style="cursor: pointer;">' +
-										'<img src="${_blankGif}" alt="" class="dijitArrowNode" waiRole="presentation">' +
-										'<span dojoAttachPoint="arrowNodeInner" class="dijitArrowNodeInner"></span>' +
-									 '</span>' +
-							        '<span dojoAttachPoint="titleNode" class="dijitTitlePaneTextNode"></span>' +
-							    '</div>' +
-							    '<div class="dijitTitlePaneContentOuter" dojoAttachPoint="hideNode">' +
-							        '<div class="dijitReset" dojoAttachPoint="wipeNode">' +
-							            '<div class="dijitTitlePaneContentInner" dojoAttachPoint="containerNode" waiRole="region" tabindex="-1">' +
-							            '</div>' +
-							        '</div>' +
-							    '</div>' +
-							'</div>'
-		});
+	    dojo.addOnLoad(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;">' +
+											'<img src="${_blankGif}" alt="" class="dijitArrowNode" role="presentation"/>' +
+											'<span dojoAttachPoint="arrowNodeInner" class="dijitArrowNodeInner"></span>' +
+										 '</span>' +
+								        '<span dojoAttachPoint="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>' +
+								        '</div>' +
+								    '</div>' +
+								'</div>'
+			});
+	
+		    dojo.parser.parse();
+	    });
 	</script>
 </head>
 <body class="claro">
 	<h1 class="testTitle">Dijit TitlePane Test</h1>
 
-	<input id="input" value="for tab testing">
+	<input id="input" value="for tab testing"/>
 
 	<h1>Test #1: plain title pane, width=300px</h1>
-	<div dojoType="dijit.TitlePane" title="Title Pane #1"
-		tooltip="I'm the tooltip for Title Pane #1's title bar"
-		style="width: 300px;" jsId="pane1" id="testPane1">
+	<div id="testPane1" data-dojo-id="pane1" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #1",
+		tooltip:"I\"m the tooltip for Title Pane #1\"s title bar",
+		style:"width: 300px;" '>
 		Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 		iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 		orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -75,54 +81,54 @@
 	<button id="closeButton" onclick="pane1.set('open', false)">close pane</button>
 	<h1>Test #2: title pane with form, width=300px</h1>
 
-	<div dojoType="dijit.TitlePane" title="Title Pane #2" id="pane_2" style="width: 300px;">
+	<div id="pane_2" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #2", style:"width: 300px;"'>
 		<form>
-			<label for="age">Age: </label> <input id="age"><br>
-			<label for="disc">Discount card </label><input id="disc" type=checkbox><br>
+			<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>
 
 	<h1>Test #3: initially closed pane</h1>
-	<div id="closed" dojoType="dijit.TitlePane" title="Initially closed pane" open="false" width="200">
+	<div id="closed" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Initially closed pane", open:false, style:"width:500px;"'>
 		<form>
-			<label for="age">Age: </label><input id="age"><br>
-			<label for="discount">Discount card </label><input type="checkbox" id="discount"><br>
+			<label for="age2">Age: </label><input id="age2"/><br>
+			<label for="discount">Discount card </label><input type="checkbox" id="discount"/><br>
 			<button>Submit</button><br>
 		</form>
 
 		<p>And a TabContainer, to make sure it lays out correctly:</p>
-		<div id="tabContainer" dojoType="dijit.layout.TabContainer" style="width: 400px; height: 250px;">
-			<a dojoType="dijit.layout.LinkPane" href="layout/tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-			<a dojoType="dijit.layout.LinkPane" href="layout/tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
+		<div id="tabContainer" data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 250px;"'>
+			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"layout/tab1.html", onLoad:function(){ console.log("load of SubTab 1"); }'>SubTab 1</a>
+			<a data-dojo-type="dijit.layout.LinkPane" data-dojo-props='href:"layout/tab2.html",  onLoad:function(){ console.log("load of SubTab 2"); }, selected:true'>SubTab 2</a>
 		</div>
 	</div>
 	<button onclick="dijit.byId('closed').set('content', 'hello world! (' + new Date() + ')');">reset content</button>
 
 	<h1>Test #4: title pane with href (initially closed)</h1>
 	<p>The pane should open to "Loading..." message and then 3 seconds later it should slide open more to show loaded data.</p>
-	<div dojoType="dijit.TitlePane" duration="1000" title="Pane from href" id="href1" open="false"
-		href="layout/getResponse.php?delay=3000&messId=3" preventCache="true"
-		style="width: 400px;">
+	<div id="href1" data-dojo-type="dijit.TitlePane" data-dojo-props='duration:1000, title:"Pane from href", open:false,
+		href:"layout/getResponse.php?delay=3000&messId=3", preventCache:true,
+		style:"width: 400px;"'>
 		Loading...
 	</div>
 
 	<h1>Test #5: title pane with href (initially closed)</h1>
 	<p>The pane should start to open to "Loading..." but halfway through href data will be loaded, and it should expand correctly.</p>
-	<div dojoType="dijit.TitlePane" duration="1000" title="Pane from href" id="href2" open="false"
-		href="layout/getResponse.php?delay=500&messId=3" preventCache="true"
-		style="width: 400px;">
+	<div id="href2" data-dojo-type="dijit.TitlePane" data-dojo-props='duration:1000, title:"Pane from href", open:false,
+		href:"layout/getResponse.php?delay=500&messId=3", preventCache:true,
+		style:"width: 400px;"'>
 		Loading...
 	</div>
 
 	<h1>Test #6: nested title pane</h1>
-	<div id="outer" dojoType="dijit.TitlePane" title="Outer pane" width="300">
+	<div id="outer" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Outer pane", style:"width:300px;"'>
 		<p>This is a title pane, containing another title pane ...
 		<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus pulvinar orci, sed vestibulum urna sem ut pede.
 More Ipsum...
 
-		<div id="inner" dojoType="dijit.TitlePane" title="Inner pane" width="250">
+		<div id="inner" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Inner pane", style:"width:250px;"'>
 			<p>And this is the inner title pane...
 			<p>Sed sollicitudin suscipit risus. Nam ullamcorper. Sed nisl lectus, pellentesque nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
 		</div>
@@ -131,7 +137,7 @@ More Ipsum...
 	</div>
 
 	<h1>Test #7: subclassed title pane (only arrow is selectable and focusable)</h1>
-	<div dojoType="dijit.TestTitlePane" title="Title Pane #7" style="width: 300px;" id="ttp">
+	<div id="ttp" data-dojo-type="dijit.TestTitlePane" data-dojo-props='title:"Title Pane #7", style:"width: 300px;" '>
 		Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 		iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 		orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -149,7 +155,7 @@ More Ipsum...
 		</tr>
 	</table>
 	<h1>Test #8: locked open title pane</h1>
-	<div dojoType="dijit.TitlePane" title="Title Pane #8" style="width: 300px;" toggleable="false" id="locked">
+	<div id="locked" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #8", style:"width: 300px;", toggleable:false '>
 		Lorem Ipsum Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Quisque
 		iaculis, nulla id semper faucibus, pede tellus nonummy magna, vitae adipiscing
 		orci arcu ut augue. Nunc condimentum, magna a vestibulum convallis, libero purus
@@ -158,5 +164,30 @@ More Ipsum...
 		nec, malesuada eget, ornare a, libero. Lorem ipsum dolor sit amet,
 		consectetuer adipiscing elit.
 	</div>
+
+	<h1>Test #9: TitlePane in AccordionContainer</h1>
+	<div id="ac" data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props='style:"width: 400px; height: 300px;" '>
+		<div id="accp1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"pane 1", selected:true'>
+			Here's a closed title pane:
+			<div id="actp1" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #9", style:"width: 300px;", open:false, 
+					href:"layout/tab1.html", onLoad:function(){ console.log("load of actp1"); actp1Loaded = true; }'>
+			</div>
+			and an open one:
+			<div id="actp2" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #10", style:"width: 300px;", open:true, 
+					href:"layout/tab2.html", onLoad:function(){ console.log("load of actp2"); actp2Loaded = true; }'>
+			</div>
+		</div>
+		<div id="accp2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"pane 2" '>
+			Here's a closed title pane:
+			<div id="actp3" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #11", style:"width: 300px;", open:false, 
+					href:"layout/tab1.html", onLoad:function(){ console.log("load of actp3"); actp3Loaded = true; }'>
+			</div>
+			and an open one:
+			<div id="actp4" data-dojo-type="dijit.TitlePane" data-dojo-props='title:"Title Pane #12", style:"width: 300px;", open:true, 
+					href:"layout/tab2.html", onLoad:function(){ console.log("load of actp4"); actp4Loaded = true; }'>
+			</div>
+		</div>
+	</div>
+
 </body>
 </html>
diff --git a/dijit/tests/test_Toolbar.html b/dijit/tests/test_Toolbar.html
index 3b76936..a601fc0 100644
--- a/dijit/tests/test_Toolbar.html
+++ b/dijit/tests/test_Toolbar.html
@@ -1,20 +1,20 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dojo Toolbar Widget Test</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -61,88 +61,88 @@
 <body class="claro">
 	<h1 class="testTitle">Toolbar test</h1>
 
-	<span dojoType="dijit.Declaration" widgetClass="ToolbarSectionStart" defaults="{ label: 'Label'}">
-		<span dojoType="dijit.ToolbarSeparator"></span><i>${label}:</i>
+	<span data-dojo-type="dijit.Declaration" data-dojo-props='widgetClass:"ToolbarSectionStart", defaults:{ label: "Label"}'>
+		<span data-dojo-type="dijit.ToolbarSeparator"></span><i>${label}:</i>
 	</span>
 
 	<h2>Toolbar from markup</h2>
 
-	<input id="toolbar1Before" value="input before toolbar1">
-	<div id="toolbar1" dojoType="dijit.Toolbar"
-			><div dojoType="ToolbarSectionStart" label="Buttons"></div
-			><div dojoType="dijit.form.Button" id="toolbar1.cut" iconClass="dijitEditorIcon dijitEditorIconCut" showLabel="false">Cut</div
-			><div dojoType="dijit.form.Button" id="toolbar1.copy" iconClass="dijitEditorIcon dijitEditorIconCopy" showLabel="true">Copy</div
+	<input id="toolbar1Before" value="input before toolbar1"/>
+	<div id="toolbar1" data-dojo-type="dijit.Toolbar"
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Buttons"'></div
+			><div id="toolbar1.cut" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut", showLabel:false'>Cut</div
+			><div id="toolbar1.copy" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy", showLabel:true'>Copy</div
 
-			><div dojoType="ToolbarSectionStart" label="Toggles"></div
-			><div dojoType="dijit.form.ToggleButton" id="toolbar1.bold" iconClass="dijitEditorIcon dijitEditorIconBold" showLabel="false">Bold</div
-			><div dojoType="dijit.form.ToggleButton" id="toolbar1.italic" iconClass="dijitEditorIcon dijitEditorIconItalic" showLabel="true">Italic</div
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Toggles"'></div
+			><div id="toolbar1.bold" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBold", showLabel:false'>Bold</div
+			><div id="toolbar1.italic" data-dojo-type="dijit.form.ToggleButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconItalic", showLabel:true'>Italic</div
 
 ><!--
-			<span dojoType="dijit.ToolbarSeparator"> </span>
+			<span data-dojo-type="dijit.ToolbarSeparator"> </span>
 
 			<span dojo:type="ToolbarButtonGroup" name="justify" defaultButton="justifyleft" preventDeselect="true" showLabel="false">
-				<div dojoType="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyLeft" name="justify" showLabel="false">Left</div>
-				<div dojoType="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyRight" name="justify" showLabel="false">Right</div>
-				<div dojoType="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyCenter" name="justify" showLabel="false">Center</div>
+				<div data-dojo-type="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyLeft" name="justify" showLabel="false">Left</div>
+				<div data-dojo-type="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyRight" name="justify" showLabel="false">Right</div>
+				<div data-dojo-type="dijit.form.ToggleButton" iconClass="dijitEditorIcon dijitEditorIconJustifyCenter" name="justify" showLabel="false">Center</div>
 			 </span>
 -->
 
-			<div dojoType="ToolbarSectionStart" label="Dropdowns"></div
-			><div dojoType="dijit.form.DropDownButton" id="toolbar1.dialog" iconClass="plusIcon" showLabel="true">
+			<div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Dropdowns"'></div
+			><div id="toolbar1.dialog" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"plusIcon", showLabel:true'>
 				<span>TooltipDialog</span>
-				<div dojoType="dijit.TooltipDialog" id="tooltipDlg" title="Enter Login information"
-					execute="console.log('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
+				<div id="tooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information",
+					execute:function(args){ console.log("submitted w/args:\n" + dojo.toJson(args, true)); }'>
 					<table>
 						<tr>
 							<td><label for="user">User:</label></td>
-							<td><input id="user" dojoType=dijit.form.TextBox type="text" name="user" ></td>
+							<td><input id="user" data-dojo-type=dijit.form.TextBox data-dojo-props='type:"text", name:"user" '/></td>
 						</tr>
 						<tr>
-							<td><label for="pwd">Password:</label></td>
-							<td><input id="password" dojoType=dijit.form.TextBox type="password" name="pwd"></td>
+							<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" align="center">
-								<button dojoType=dijit.form.Button type="submit" name="submit">Login</button></td>
+							<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 dojoType="dijit.form.DropDownButton" id="toolbar1.backcolor" iconClass="dijitEditorIcon dijitEditorIconBackColor" showLabel="true">
+			><div id="toolbar1.backcolor" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconBackColor", showLabel:true'>
 				<span>ColorPalette</span>
-				<div dojoType="dijit.ColorPalette" id="toolbar1.colorPalette" style="display: none" palette="7x10" onChange="console.log(this.value);"></div>
+				<div id="toolbar1.colorPalette" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display: none", palette:"7x10", onChange:function(){ console.log(this.value); }'></div>
 			</div
-			><div dojoType="dijit.form.DropDownButton" id="toolbar1.forecolor" iconClass="dijitEditorIcon dijitEditorIconForeColor" showLabel="false">
+			><div id="toolbar1.forecolor" data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconForeColor", showLabel:false'>
 				<span>Foreground</span>
-				<div dojoType="dijit.ColorPalette" id="toolbar1.colorPalette2" style="display: none" palette="3x4" onChange="console.log(this.value);"></div>
+				<div id="toolbar1.colorPalette2" data-dojo-type="dijit.ColorPalette" data-dojo-props='style:"display: none", palette:"3x4", onChange:function(){ console.log(this.value); }'></div>
 			</div
 
-			><div dojoType="ToolbarSectionStart" label="Combos"></div
-			><div dojoType="dijit.form.ComboButton" id="toolbar1.combo" optionsTitle='save options' iconClass="plusIcon" showLabel="true"
-				onClick='console.log("clicked combo save")'>
+			><div data-dojo-type="ToolbarSectionStart" data-dojo-props='label:"Combos"'></div
+			><div id="toolbar1.combo" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options", iconClass:"plusIcon", showLabel:true,
+				onClick:function(){ console.log("clicked combo save") }'>
 				<span>Menu</span>
-				<div dojoType="dijit.Menu" id="saveMenu" style="display: none;">
-					<div dojoType="dijit.MenuItem"  iconClass="dijitEditorIcon dijitEditorIconSave"
-						onClick="console.log('not actually saving anything, just a test!')">Save</div>
-					<div dojoType="dijit.MenuItem"
-						onClick="console.log('not actually saving anything, just a test!')">Save As</div>
+				<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 dojoType="dijit.form.ComboButton" id="toolbar1.combo2" optionsTitle='save options2' iconClass="plusIcon" showLabel="false"
-				onClick='console.log("clicked combo save")'>
+			><div id="toolbar1.combo2" data-dojo-type="dijit.form.ComboButton" data-dojo-props='optionsTitle:"save options2", iconClass:"plusIcon", showLabel:false,
+				onClick:function(){ console.log("clicked combo save") }'>
 				<span>Menu2</span>
-				<div dojoType="dijit.Menu" id="saveMenu2" style="display: none;">
-					<div dojoType="dijit.MenuItem"  iconClass="dijitEditorIcon dijitEditorIconSave"
-						onClick="console.log('not actually saving anything, just a test!')">Save</div>
-					<div dojoType="dijit.MenuItem"
-						onClick="console.log('not actually saving anything, just a test!')">Save As</div>
+				<div id="saveMenu2" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+					<div data-dojo-type="dijit.MenuItem"  data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconSave",
+						onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save</div>
+					<div data-dojo-type="dijit.MenuItem"
+						data-dojo-props='onClick:function(){ console.log("not actually saving anything, just a test!") }'>Save As</div>
 				</div>
 			</div
 
-			><span dojoType="dijit.ToolbarSeparator"></span
-			><div dojoType="dijit.form.Button" id="toolbar1.insertorderedlist" iconClass="dijitEditorIcon dijitEditorIconInsertOrderedList" showLabel="false">Ordered list</div
+			><span data-dojo-type="dijit.ToolbarSeparator"></span
+			><div id="toolbar1.insertorderedlist" data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconInsertOrderedList", showLabel:false'>Ordered list</div
 	></div>
-	<input id="toolbar1After" value="input after toolbar1">
+	<input id="toolbar1After" value="input after toolbar1"/>
 
 	<h2>Toolbar from script with icons only</h2>
 	<div id="toolbar2"></div>
diff --git a/dijit/tests/test_Tooltip.html b/dijit/tests/test_Tooltip.html
index 359d9a7..2a04d7e 100644
--- a/dijit/tests/test_Tooltip.html
+++ b/dijit/tests/test_Tooltip.html
@@ -1,22 +1,22 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dojo Tooltip Widget Test</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 
 		td { padding: 20px; }
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -25,6 +25,7 @@
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.Tooltip");
 		dojo.require("dijit.ColorPalette");
+		dojo.require("dijit.form.DateTextBox");
 		dojo.addOnLoad(function(){
 			console.log("on load func");
 			var tt = new dijit.Tooltip({label:"programmatically created tooltip", connectId:["programmaticTest"]});
@@ -69,6 +70,9 @@
 			<td>
 				Set background color:
 			</td>
+			<td>
+				Prompt message test (for quirks mode):
+			</td>
 		</tr>
 		<tr>
 			<td>
@@ -79,12 +83,17 @@
 				</div>
 			</td>
 			<td>
-				<div dojoType="dijit.ColorPalette" onChange="dojo.query('body').style('background', arguments[0]);"></div>
+				<div data-dojo-type="dijit.ColorPalette" data-dojo-props='onChange:function(val){ dojo.query("body").style("background", val); }'></div>
+			</td>
+			<td>
+				<input data-dojo-type="dijit.form.DateTextBox" data-dojo-props='id: "dtb", value: "2010-12-15", promptMessage: "Please Enter a date in dd/MM/yyyy format", style:"width: 8em;"'>				
 			</td>
 		</tr>
 	</table>
-	<div><span id="one" class="tt" tabindex="0"> focusable text </span>
-		<span dojoType="dijit.Tooltip" connectId="one" id="one_tooltip">
+	<input value="input, no tooltip"/>
+	<div>
+		<span id="one" class="tt" tabindex="0"> focusable text </span>
+		<span id="one_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["one"]'>
 			<b>
 				<span style="color: blue;">rich formatting</span>
 				<span style="color: red; font-size: x-large;"><i>!</i></span>
@@ -92,18 +101,18 @@
 		</span>
 	</div>
 	<span id="oneA" class="tt"> plain text (not focusable) </span>
-	<span dojoType="dijit.Tooltip" connectId="oneA" id="oneA_tooltip">
+	<span id="oneA_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["oneA"]'>
 		<span> keyboard users can not access this tooltip</span>
 	</span>
     <a id="three" href="#bogus">anchor</a>
-	<span dojoType="dijit.Tooltip" connectId="three" id="three_tooltip">tooltip on a link </span>
+	<span id="three_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["three"]'>tooltip on a link </span>
 	<p></p>
 
 	<span id="programmaticTest">this text has a programmatically created tooltip</span>
 	<br>
 
 	<button id="four">button w/tooltip</button>
-	<span id="btnTt" dojoType="dijit.Tooltip" connectId="four" id="four_tooltip">tooltip on a button</span>
+	<span id="btnTt" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["four"]'>tooltip on a button</span>
 	<button id="removeButton" onclick="dijit.byId('btnTt').destroy()">Remove</button> tooltip from "button w/tooltip".
 
 	<span style="float: right">
@@ -115,7 +124,7 @@
 			<option value="delta">Delta</option>
 		</select>
 
-		<span dojoType="dijit.Tooltip" connectId="seven" id="seven_tooltip">
+		<span id="seven_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["seven"]'>
 			tooltip on a select<br>
 			two line tooltip.
 		</span>
@@ -124,12 +133,12 @@
 	<p></p>
 
 	<form>
-		<input id="id1" value="#1"><br>
-		<input id="id2" value="#2"><br>
-		<input id="id3" value="#3"><br>
-		<input id="id4" value="#4"><br>
-   		<input id="id5" value="#5"><br>
-		<input id="id6" value="#6"><br>
+		<input id="id1" value="#1"/><br>
+		<input id="id2" value="#2"/><br>
+		<input id="id3" value="#3"/><br>
+		<input id="id4" value="#4"/><br>
+   		<input id="id5" value="#5"/><br>
+		<input id="id6" value="#6"/><br>
 	</form>
 	<br>
 
@@ -141,29 +150,33 @@
 		<span id="s5">s5 text</span><br><br><br>
 	</div>
 
-	<span dojoType="dijit.Tooltip" connectId="id1" id="id1_tooltip">
+	<span id="id1_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id1"]'>
 
 	tooltip for #1<br>
 	long long long long long long long long long long long text<br>
 	make sure that this works properly with a really narrow window
 	</span>
 
-	<span dojoType="dijit.Tooltip" connectId="id2" id="id2_tooltip">tooltip for #2</span>
-	<span dojoType="dijit.Tooltip" connectId="id3" id="id3_tooltip">tooltip for #3</span>
-	<span dojoType="dijit.Tooltip" connectId="id4" id="id4_tooltip">tooltip for #4</span>
-	<span dojoType="dijit.Tooltip" connectId="id5" id="id5_tooltip">tooltip for #5</span>
-	<span dojoType="dijit.Tooltip" connectId="id6" id="id6_tooltip">tooltip for #6</span>
+	<span id="id2_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id2"]'>tooltip for #2</span>
+	<span id="id3_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id3"]'>tooltip for #3</span>
+	<span id="id4_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id4"]'>tooltip for #4</span>
+	<span id="id5_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id5"]'>tooltip for #5</span>
+	<span id="id6_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["id6"]'>tooltip for #6</span>
 
-	<span dojoType="dijit.Tooltip" connectId="s1" id="s1_tooltip">s1 tooltip</span>
-	<span dojoType="dijit.Tooltip" connectId="s2" id="s2_tooltip">s2 tooltip</span>
-	<span dojoType="dijit.Tooltip" connectId="s3" id="s3_tooltip">s3 tooltip</span>
-	<span dojoType="dijit.Tooltip" connectId="s4" id="s4_tooltip">s4 tooltip</span>
-	<span dojoType="dijit.Tooltip" connectId="s5" id="s5_tooltip">s5 tooltip</span>
+	<span id="s1_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s1"]'>s1 tooltip</span>
+	<span id="s2_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s2"]'>s2 tooltip</span>
+	<span id="s3_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s3"]'>s3 tooltip</span>
+	<span id="s4_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s4"]'>s4 tooltip</span>
+	<span id="s5_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["s5"]'>s5 tooltip</span>
 
 	<h3>One Tooltip for multiple connect nodes</h3>
-	<span dojoType="dijit.Tooltip" connectId="multi1,multi2" id="multi1,multi2_tooltip" style="display:none;">multi tooltip</span>
+	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["multi1","multi2"], id:"multi1,multi2_tooltip", style:"display:none;"'>multi tooltip</span>
 	<a id="multi1" href="#bogus">multi1</a><br><a id="multi2" href="#bogus">multi2</a>
 
+	<h3>One Tooltip for multiple connect nodes w/ dojoType</h3>
+	<span dojoType="dijit.Tooltip" connectId="oldmulti1, oldmulti2" id="oldmulti1,oldmulti2_tooltip" style="display:none">multi tooltip dojoType</span>
+	<a id="oldmulti1" href="#bogus">multi1</a><br><a id="oldmulti2" href="#bogus">multi2</a>
+
 
 	<h3>Dynamic target tooltip</h3>
 	<div>
@@ -186,7 +199,6 @@
 	<span id="t_connected_id"></span><br>
 	<span id="t_shown">Tooltip hidden (initial)</span>
 
-	<span dojoType="dijit.Tooltip" connectId="t1,t3" id="t_tooltip">Dynamic target tooltip</span>
+	<span id="t_tooltip" data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["t1","t3"]'>Dynamic target tooltip</span>
 </body>
 </html>
-
diff --git a/dijit/tests/test_TooltipDialog.html b/dijit/tests/test_TooltipDialog.html
index 08155fb..ea068e7 100644
--- a/dijit/tests/test_TooltipDialog.html
+++ b/dijit/tests/test_TooltipDialog.html
@@ -1,41 +1,41 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>TooltipDialog Widget Tests</title>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
+		@import "../themes/claro/document.css";
 		@import "css/dijitTests.css";
 
 		body { font-family : sans-serif; }
 		form { margin-bottom : 0; }
 		table { border: none; }
-		.tundra .tooltipLink .dijitButtonNode,
-		.tundra .tooltipLink .dijitButtonNode .dijitDropDownButtonHover,
-		.tundra .buttonLink .dijitButtonNode,
-		.tundra .buttonLink .dijitButtonHover .dijitButtonNode {
-				background: none !important;
-				border:none;
+		.claro .tooltipLink .dijitButtonNode,
+		.claro .tooltipLink .dijitButtonNode .dijitDropDownButtonHover,
+		.claro .buttonLink .dijitButtonNode,
+		.claro .buttonLink .dijitButtonHover .dijitButtonNode {
+			background: none !important;
+			border:none;
 		}
-		.tundra .tooltipLink .dijitArrowButtonInner {
+		.claro .tooltipLink .dijitArrowButtonInner {
 			display:none;
 		}
-		.tundra .tooltipLink button,
-		.tundra .tooltipLink button .dijitButtonText,
-		.tundra .buttonLink button .dijitButtonText {
-				text-decoration:underline !important;
-				color:blue;
-				display:inline;
+		.claro .tooltipLink button,
+		.claro .tooltipLink button .dijitButtonText,
+		.claro .buttonLink button .dijitButtonText {
+			text-decoration:underline !important;
+			color:blue;
+			display:inline;
 		}
 	</style>
 
 	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
@@ -43,7 +43,7 @@
 	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.TooltipDialog");
-		dojo.require("dijit.form.Button");
+		dojo.require("dijit.form.DropDownButton");
 		dojo.require("dijit.form.TextBox");
 		dojo.require("dijit.form.DateTextBox");
 		dojo.require("dijit.form.TimeTextBox");
@@ -52,46 +52,89 @@
 		dojo.require("dijit.layout.TabContainer");
 		dojo.require("dijit.InlineEditBox");
 		dojo.require("dijit.Menu");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		// create a do nothing, only for test widget
-		dojo.declare("dijit.TestWidget",
-			[dijit._Widget, dijit._Templated], {
-			templateString: "<div style='margin: 10px; border: inset #700 4px; padding: 5px;' dojoAttachPoint='containerNode'></div>"
-		});
+		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(){
+			// create a do nothing, only for test widget
+			dojo.declare("dijit.TestWidget",
+				[dijit._Widget, dijit._Templated], {
+				templateString: "<div style='margin: 10px; border: inset #700 4px; padding: 5px;' dojoAttachPoint='containerNode'></div>"
+			});
+
+			// scan page for widgets and instantiate them
+			dojo.parser.parse();
+
+			// Nested TooltipDialog that contains a nested Menu
+			var innerTtDialog = new dijit.TooltipDialog({
+				id: "innerTtDialog",
+				content:
+					'<div dojoType="dijit.Menu" id="navMenu"><div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut" >Drama</div><div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy" >Comedy</div><div dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste" >Romance</div><div dojoType="dijit.MenuSeparator"></div><div dojoType="dijit.PopupMenuItem" id="popupMenuItem"><span>Action</span><div dojoType="dijit.Menu" id="submenu"><div dojoType= [...]
+					+ '<label for="name">Name:</label> <input dojoType="dijit.form.TextBox" id="name" name="name"><br>' 
+					+ '<label for="hobby">Hobby:</label> <input dojoType="dijit.form.TextBox" id="hobby" name="hobby"><br>' 
+					+ '<button dojoType="dijit.form.Button" type="button">Save</button>'
+					+ '<div id="plaintext">plain text</div>'
+			 });
+
+			var innerDdBtn = new dijit.form.DropDownButton({
+				id: "innerDdBtn",
+				label: "Inner TooltipDialog (innerTtDialog)",
+				dropDown: innerTtDialog
+			});
+
+			var ddDialogCp = new dijit.layout.ContentPane({
+				id: "ddDialogCp",
+				title: '',
+				refreshOnShow: true
+			});
+			ddDialogCp.startup();
+			ddDialogCp.set("content", innerDdBtn);
+
+			var outerTtDialog = new dijit.TooltipDialog({
+			   id: "outerTtDialog",
+			   content:ddDialogCp
+			});
+
+			var launcherBtn = new dijit.form.DropDownButton({
+				id: "outerDdBtn",
+				label: "Nested TooltipDialog (ttDialog)",
+				dropDown: outerTtDialog
+			});
+
+			dojo.byId("dropdownButtonContainer").appendChild(launcherBtn.domNode);
+		});
 	</script>
 </head>
 <body class="claro">
 
 	<h1 class="testTitle">dijit.TooltipDialog tests</h1>
 
-	<div dojoType="dijit.form.DropDownButton" id="tooltipDlgButton">
+	<div id="tooltipDlgButton" data-dojo-type="dijit.form.DropDownButton" >
 		<span>Show Tooltip Dialog</span>
-		<div dojoType="dijit.TooltipDialog" id="tooltipDlg" title="Enter Login information">
+		<div id="tooltipDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Enter Login information"'>
 			<table>
 				<tr>
-					<td><label for="inline">InlineEditBox:</label></td>
-					<td><div dojoType=dijit.InlineEditBox type="text" name="inline" id="inline">inline</div></td>
+					<td><label>InlineEditBox:</label></td>
+					<td><div id="inline" data-dojo-type=dijit.InlineEditBox data-dojo-props='editorParams:{type:"text", name:"inline"}'>inline</div></td>
 				</tr>
 				<tr>
 					<td><label for="text">TextBox:</label></td>
-					<td><input dojoType=dijit.form.TextBox name="text" id="text"></td>
+					<td><input id="text" data-dojo-type=dijit.form.TextBox data-dojo-props='name:"text" '/></td>
 				</tr>
 				<tr>
 					<td><label for="date2">Date:</label></td>
-					<td><input dojoType=dijit.form.DateTextBox name="date" id="date2"></td>
+					<td><input id="date2" data-dojo-type=dijit.form.DateTextBox data-dojo-props='name:"date" '/></td>
 				</tr>
 				<tr>
 					<td><label for="time2">Time:</label></td>
-					<td><input dojoType=dijit.form.TimeTextBox name="time" id="time2"></td>
+					<td><input id="time2" data-dojo-type=dijit.form.TimeTextBox data-dojo-props='name:"time" '/></td>
 				</tr>
 				<tr>
 					<td><label for="combo">FilteringSelect:</label></td>
 					<td>
-						<select dojoType=dijit.form.FilteringSelect name="combo" id="combo" hasDownArrow="true">
+						<select id="combo" data-dojo-type=dijit.form.FilteringSelect data-dojo-props='name:"combo", hasDownArrow:true'>
 							<option value="cheese">cheese</option>
 							<option value="pepperoni">pepperoni</option>
 							<option value="sausage">sausage</option>
@@ -101,7 +144,7 @@
 				<tr>
 					<td><label for="select">Select:</label></td>
 					<td>
-						<select dojoType=dijit.form.Select name="select" id="select">
+						<select id="select" data-dojo-type=dijit.form.Select data-dojo-props='name:"select" '>
 							<option value="olives">olives</option>
 							<option value="peppers">peppers</option>
 							<option value="tomatoes">tomatoes</option>
@@ -109,8 +152,8 @@
 					</td>
 				</tr>
 				<tr>
-					<td colspan="2" align="center">
-						<button dojoType=dijit.form.Button type="submit" name="submit" id="submit">Order</button>
+					<td colspan="2" style="text-align:center;">
+						<button id="submit" data-dojo-type=dijit.form.Button data-dojo-props='type:"submit", name:"submit" '>Order</button>
 					</td>
 				</tr>
 			</table>
@@ -118,11 +161,11 @@
 		</div>
 	</div> |
 
-	<div dojoType="dijit.form.DropDownButton">
+	<div data-dojo-type="dijit.form.DropDownButton">
 		<span>Show Tooltip Dialog with TabContainer</span>
-		<div dojoType="dijit.TooltipDialog" id="tabTooltip" title="Tab Container Tooltip">
-			<div dojoType="dijit.layout.TabContainer" style="width: 400px; height: 300px;">
-				<div dojoType="dijit.layout.ContentPane" title="First tab">
+		<div id="tabTooltip" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Tab Container Tooltip"'>
+			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props='style:"width: 400px; height: 300px;"'>
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"First tab"'>
 					<p>
 						This is the first tab.
 					</p>
@@ -135,7 +178,7 @@
 					risus.
 					</p>
 				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Second tab">
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Second tab"'>
 					<p>
 						This is the second tab.
 					</p>
@@ -152,17 +195,17 @@
 		</div>
 	</div> |
 
-	<div dojoType="dijit.form.DropDownButton">
+	<div data-dojo-type="dijit.form.DropDownButton">
 		<span>Test slowloading HREF Tooltip Dialog</span>
-		<div dojoType="dijit.TooltipDialog" id="slowLoad" href="layout/getResponse.php?delay=500&messId=2"
-			title="tooltip dialog with no focusable items"></div>
+		<div id="slowLoad" data-dojo-type="dijit.TooltipDialog" data-dojo-props='href:"layout/getResponse.php?delay=500&messId=2",
+			title:"tooltip dialog with no focusable items"'></div>
 	</div> |
 
-<div dojoType="dijit.form.DropDownButton" class="tooltipLink">
+<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='"class":"tooltipLink"'>
 	<span>What is this?</span>
-	<div dojoType="dijit.TooltipDialog" id="tooltipHelpDlg" title="Test Dialog tooltip" style="width:350px" >
-		<div class="buttonLink" style="float:right;font-size:x-small" title="close" tabindex="0" dojoType="dijit.form.Button">[close]
-			<script type="dojo/method" event="onClick">
+	<div id="tooltipHelpDlg" data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"Test Dialog tooltip", style:"width:350px" '>
+		<div data-dojo-type="dijit.form.Button" data-dojo-props='"class":"buttonLink", style:"float:right;font-size:x-small", title:"close", tabIndex:"0" '>[close]
+			<script type="dojo/method" data-dojo-event="onClick">
 					dijit.byId('tooltipHelpDlg').onCancel();
 			</script>
 		</div>
@@ -178,6 +221,9 @@
 	</div>
 </div>
 
+	<span id="dropdownButtonContainer">
+		<!-- programatically created nested TooltipDialog will be placed here -->
+	</span>
 
 	<p><b><i>(scroll down to see more links to click, for testing positioning / scroll handling)</i></b></p>
 
@@ -206,12 +252,12 @@
 	hymenaeos.
 	</p>
 	<form>
-		<center>
+		<div style="text-align:center;">
 			<select>
 				<option>1</option>
 				<option>2</option>
 			</select>
-		</center>
+		</div>
 	</form>
 	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
 	et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
@@ -227,9 +273,9 @@
 	turpis sed odio. Curabitur in est id nibh tempus ultrices. Aliquam
 	consectetuer dapibus eros. Aliquam nisl.
 	</p>
-	<div style="float:right;clear:right;" dojoType="dijit.form.DropDownButton">
+	<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='style:"float:right;clear:right;" '>
 		<span>dropdown at right</span>
-	<div dojoType="dijit.TooltipDialog" id="dialogright">
+	<div id="dialogright" data-dojo-type="dijit.TooltipDialog" >
 			<div style="white-space:nowrap;">Aliquam vitae enim. Duis scelerisque metus auctor est venenatis</div>
 	</div>
 	</div>
@@ -255,9 +301,9 @@
 	tortor pharetra congue. Suspendisse pulvinar.
 	</p>
 
-	<div dojoType="dijit.form.DropDownButton" title="Enter Login information2">
+	<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='title:"Enter Login information2"'>
 		<span>Show Tooltip Dialog pointing upwards, with links</span>
-		<div dojoType="dijit.TooltipDialog" title="General Information Dialog">
+		<div data-dojo-type="dijit.TooltipDialog" data-dojo-props='title:"General Information Dialog"'>
 			<p>Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
 			ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
 			nonummy mollis. <a href="http://www.lipsum.com/">Vestibulum</a> vel purus ac pede semper accumsan. Vivamus
@@ -285,12 +331,12 @@
 	hymenaeos.
 	</p>
 	<form>
-		<center>
+		<div style="text-align:center;">
 			<select>
 				<option>1</option>
 				<option>2</option>
 			</select>
-		</center>
+		</div>
 	</form>
 	<p>Mauris pharetra lorem sit amet sapien. Nulla libero metus, tristique
 	et, dignissim a, tempus et, metus. Ut libero. Vivamus tempus purus vel
@@ -402,4 +448,3 @@
 
 </body>
 </html>
-
diff --git a/dijit/tests/test_Tree.html b/dijit/tests/test_Tree.html
deleted file mode 100644
index 3919742..0000000
--- a/dijit/tests/test_Tree.html
+++ /dev/null
@@ -1,174 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Dijit Tree Test</title>
-
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-	<script language="JavaScript" 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("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit Tree Test</h1>
-
-	<div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
-		url="_data/countries.json"></div>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="continentModel"
-		store="continentStore" query="{type:'continent'}"
-		rootId="continentRoot" rootLabel="Continents" childrenAttrs="children"></div>
-
-	<h2>Tree with hardcoded root node (not corresponding to any item in the store)</h2>
-	<p>
-		Clicking a folder node will open/close it (openOnclick==true),
-		and clicking a leaf node will log a message to the console.
-	</p>
-	<div dojoType="dijit.Tree" id="mytree"
-		model="continentModel" openOnClick="true" onLoad="console.log('loaded mytree (first tree)');">
-		<script type="dojo/method" event="onClick" args="item">
-			console.log("Execute of node " + continentStore.getLabel(item)
-				+", population=" + continentStore.getValue(item, "population"));
-		</script>
-		<script type="dojo/method" event="onOpen" args="item">
-			console.log("Open of node " + continentStore.getLabel(item)||"root");
-		</script>
-		<script type="dojo/method" event="onClose" args="item">
-			console.log("Close of node " + continentStore.getLabel(item)||"root");
-		</script>
-	</div>
-
-	<button onclick="dijit.byId('mytree').destroyRecursive();">destroy</button>
-
-	<h2>A rootless tree (no "continents" node) with context menus, and custom icons</h2>
-
-	<ul dojoType="dijit.Menu" id="tree_menu" style="display: none;">
-		<li dojoType="dijit.MenuItem" onClick="console.log('Hello world');">Enabled Item</li>
-		<li dojoType="dijit.MenuItem" disabled="true">Disabled Item</li>
-		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCut"
-			onClick="console.log('not actually cutting anything, just a test!')">Cut</li>
-		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconCopy"
-			onClick="console.log('not actually copying anything, just a test!')">Copy</li>
-		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
-			onClick="console.log('not actually pasting anything, just a test!')">Paste</li>
-		<li dojoType="dijit.PopupMenuItem">
-			<span>Enabled Submenu</span>
-			<ul dojoType="dijit.Menu" id="submenu2">
-				<li dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</li>
-				<li dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</li>
-				<li dojoType="dijit.PopupMenuItem">
-					<span>Deeper Submenu</span>
-					<ul dojoType="dijit.Menu" id="submenu4">
-						<li dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 1!')">Sub-sub-menu Item One</li>
-						<li dojoType="dijit.MenuItem" onClick="console.log('Sub-submenu 2!')">Sub-sub-menu Item Two</li>
-					</ul>
-				</li>
-			</ul>
-		</li>
-		<li dojoType="dijit.PopupMenuItem" disabled="true">
-			<span>Disabled Submenu</span>
-			<ul dojoType="dijit.Menu" id="submenu3" style="display: none;">
-				<li dojoType="dijit.MenuItem" onClick="console.log('Submenu 1!')">Submenu Item One</li>
-				<li dojoType="dijit.MenuItem" onClick="console.log('Submenu 2!')">Submenu Item Two</li>
-			</ul>
-		</li>
-	</ul>
-
-	<div dojoType="dijit.Tree" id="tree2"
-		model="continentModel" showRoot="false" openOnClick="true"onLoad="console.log('loaded tree2 (second tree)');">
-
-		<script type="dojo/connect">
-			var menu = dijit.byId("tree_menu");
-			// when we right-click anywhere on the tree, make sure we open the menu
-			menu.bindDomNode(this.domNode);
-
-			dojo.connect(menu, "_openMyself", this, function(e){
-				// get a hold of, and log out, the tree node that was the source of this open event
-				var tn = dijit.getEnclosingWidget(e.target);
-				console.debug(tn);
-
-				// now inspect the data store item that backs the tree node:
-				console.debug(tn.item);
-
-				// contrived condition: if this tree node doesn't have any children, disable all of the menu items
-				dojo.forEach(menu.getChildren(), function(i){ i.set('disabled', !tn.item.children); });
-
-				// IMPLEMENT CUSTOM MENU BEHAVIOR HERE
-			});
-		</script>
-		<script type="dojo/method" event="getIconClass" args="item, opened">
-           return (item == this.model.root || continentStore.getValue(item, "type") == "continent") ?
-                   (opened ? "customFolderOpenedIcon" : "customFolderClosedIcon") :
-                    "noteIcon";
-		</script>
-		<script type="dojo/method" event="onClick" args="item">
-			console.log("Execute of node " + this.model.getLabel(item)
-				+", population=" + continentStore.getValue(item, "population"));
-		</script>
-</div>
-
-	<h2>Double click, expand on load, direct style setting, tooltip test</h2>
-	<p>
-		Double-Clicking a folder node will open/close it (openOnDblClick==true),
-		and clicking or Double Clicking a leaf node will log a message to the console.
-	</p>
-	<div dojoType="dijit.Tree" id="mytree3" store="continentStore" query="{type:'continent'}"
-		label="Continents" openOnClick="false" openOnDblClick="true"
-		autoExpand="true" onLoad="console.log('loaded mytree3 (third tree)');">
-		<script type="dojo/method" event="getLabelStyle" args="item,opened">
-			if(item && continentStore.getValue(item,"type") == "continent"){
-				return {color: "red"};
-			}else{
-				return {color: "green"};
-			}
-		</script>
-		<script type="dojo/method" event="getIconStyle" 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" event="getIconClass" args="item, opened">
-	       if (!item || continentStore.getValue(item, "type") != "continent")
-				return (!item || this.model.mayHaveChildren(item)) ? (opened ? "dijitFolderOpened" : "dijitFolderClosed") : "dijitLeaf"
-	       	else
-	       		return "";
-		</script>
-		<script type="dojo/method" event="getTooltip" args="item,opened">
-			return item && ("Tooltip for " + this.model.getLabel(item));
-		</script>
-		<script type="dojo/method" event="onDblClick" args="item">
-			console.log("Execute of node " + this.model.getLabel(item)
-				+", population=" + continentStore.getValue(item, "population"));
-		</script>
-	</div>
-
-
-</body>
-</html>
diff --git a/dijit/tests/test_Tree_Notification_API_Support.html b/dijit/tests/test_Tree_Notification_API_Support.html
deleted file mode 100644
index b27577f..0000000
--- a/dijit/tests/test_Tree_Notification_API_Support.html
+++ /dev/null
@@ -1,293 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Dijit Tree Test</title>
-
-	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../../dojo/resources/dnd.css";
-		@import "../../dojo/tests/dnd/dndDefault.css";
-		@import "css/dijitTests.css";
-
-		.clear {
-			clear: both;
-		}
-
-		.box {
-			border: #ccc 3px solid;
-			padding: 1em;
-			-moz-border-radius: 8px 8px;
-			radius: 8px;
-		}
-
-		label {
-			display: inline-block;
-			min-width: 8em;
-		}
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="_testCommon.js"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("dojo.dnd.Source");
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dijit.Declaration");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.TreeStoreModel");
-		dojo.require("dijit.Menu");
-		dojo.require("dijit.form.Button");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-
-		// Hash of id-->item for all the items (including children) in the data store.
-		var allItems = {};
-
-		function deleteItem(){
-			store.deleteItem(selectedItem);
-			store.save();
-
-			resetForms();
-			loadItemsTable();
-		}
-
-		function newItem(){
-			var pInfo = selectedItem ? {parent: selectedItem, attribute:"children"} : null,
-				item = {
-					id: dojo.byId('nId').value,
-					name: dojo.byId("nLabel").value,
-					someProperty: dojo.byId("nSomeProperty").value,
-					children: dojo.query("> *", "nChildren").map( function(child){
-								var id = child.id;
-								return allItems[id];
-							})
-				};
-
-			console.debug("New item: ", item, ", pInfo = ", pInfo);
-
-			store.newItem(item, pInfo);
-			store.save();
-
-			resetForms();
-			loadItemsTable();
-		}
-
-		function resetForms() {
-			selectedItem=null;
-
-			// Update item form
-			dojo.byId("uLabel").value = "";
-			dojo.byId("uSomeProperty").value = "";
-
-			dojo.byId("uChildren").innerHTML = "";
-			uChildrenDragSource.clearItems();
-
-			dojo.byId("uPotentialChildren").innerHTML = "";
-			uPotentialChildrenDragSource.clearItems();
-
-			// New item form
-			dojo.byId("nChildren").innerHTML = "";
-			nChildrenDragSource.clearItems();
-
-			dojo.byId("nPotentialChildren").innerHTML = "";
-			nPotentialChildrenDragSource.clearItems();
-		}
-
-		function updateItem(){
-			if (selectedItem!=null){
-				if (dojo.byId("uLabel").value != store.getValue(selectedItem, "name")){
-					store.setValue(selectedItem, "name", dojo.byId("uLabel").value);
-				}
-
-				if (dojo.byId("uSomeProperty").value != store.getValue(selectedItem, "someProperty")){
-					store.setValue(selectedItem, "someProperty", dojo.byId("uSomeProperty").value);
-				}
-
-				var children = dojo.query("> *", "uChildren").map( function(child){
-					var id = child.id;
-					return allItems[id];
-				});
-				store.setValues(selectedItem, "children", children);
-
-				store.save();
-
-				resetForms();
-				loadItemsTable();
-			}else{
-				console.error("Can't update the tree root");
-			}
-		}
-
-		dojo.addOnLoad(function(){
-			resetForms();
-			loadItemsTable();
-		});
-
-		function loadItemsTable(){
-			// summary: for each item in the datastore generate a row in the table
-			function processItem(item){
-				allItems[store.getIdentity(item)] = item;
-
-				var vals = {
-					itemId: store.getIdentity(item),
-					label: store.getLabel(item),
-					someProperty: store.getValue(item, "someProperty"),
-					children: store.getValues(item, "children")
-				};
-
-				// add this item to children list in "new item" form
-				dojo.byId("nPotentialChildren").innerHTML +=
-					"<div class='dojoDndItem' id='" + vals.itemId + "'>" +
-						vals.label +
-					"</div>";
-				nPotentialChildrenDragSource.setItem(vals.itemId, {
-					data: vals.label,
-					type: ["text"]
-				});
-
-				// update table listing items
-				var row = new ItemRow(vals);
-				dojo.byId("itemsTable").appendChild(row.domNode);
-
-				//dojo.forEach(vals.children, processItem);
-			}
-
-			allItems = {};
-			dijit.registry.byClass("ItemRow").forEach(function(widget){ widget.destroy(); });
-			store.fetch({onItem: processItem});
-		}
-
-		function onSelectItem(item){
-			resetForms();
-			loadItemsTable();
-
-			console.log("Selected item: ", item ? store.getLabel(item) : "none");
-			selectedItem = item;
-
-			if(item){
-				// Display basic attribute values
-				dojo.byId('uLabel').value = item ? store.getLabel(item) : "";
-				dojo.byId('uSomeProperty').value = item ? store.getValue(item,"someProperty") : "";
-
-				// Fill in info about children
-				var children = store.getValues(item, "children");
-				dojo.forEach(children, function(item){
-					var id = store.getIdentity(item),
-						label = store.getLabel(item);
-					dojo.byId("uChildren").innerHTML +=
-						"<div class='dojoDndItem' id='" + id + "'>" +
-							label +
-						"</div>";
-					uChildrenDragSource.setItem(id, {
-						data: label,
-						type: ["text"]
-					});
-				});
-
-				// and the items that could be children but aren't currently
-				// (including items that would cause cycles, because i'm lazy)
-				for(var id in allItems){
-					var child = allItems[id];
-					if(dojo.indexOf(children, child) == -1){
-						var label = store.getLabel(child);
-						dojo.byId("uPotentialChildren").innerHTML +=
-							"<div class='dojoDndItem' id='" + id + "'>" +
-								label +
-							"</div>";
-						uPotentialChildrenDragSource.setItem(id, {
-							data: label,
-							type: ["text"]
-						});
-					}
-				}
-			}
-
-			// New Item section
-			dojo.byId('nParent').value = item ? store.getLabel(item) : "";
-		}
-	</script>
-
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit Tree Test - dojo.data.Notification API support</h1>
-
-	<div dojoType="dojo.data.ItemFileWriteStore" jsId="store"
-		url="../tests/_data/treeTest.json"></div>
-	<div dojoType="dijit.tree.TreeStoreModel" jsId="model"
-		store="store" query="{id:'root'}"></div>
-	<div dojoType="dijit.Tree" id="myTree" model="model" onClick="onSelectItem"></div>
-
-	<br />
-	<h2>Selected Item:</h2>
-	<div class="box">
-		<label for="uLabel">Name:</label>				<input id="uLabel" width="50" value="Enter Node Label"  autocomplete="off"/><br />
-		<label for="uSomeProperty">Description:</label> <input id="uSomeProperty" width="50" value="Some Test Property"  autocomplete="off"/><br /><br />
-		<div style="float:left; margin-right: 2em;">
-			<label for="uChildren">Children (in order):</label>
-			<div dojoType="dojo.dnd.Source" class="container" id="uChildren" jsId="uChildrenDragSource"></div>
-		</div>
-		<div style="float:left">
-			<label for="uPotentialChildren">Potential Children:</label>
-			<div dojoType="dojo.dnd.Source" class="container" id="uPotentialChildren" jsId="uPotentialChildrenDragSource"></div>
-		</div>
-		<div class="clear">(drag and drop items to adjust list of children, and order of those children)</div>
-	</div>
-	<div dojoType="dijit.form.Button" iconClass="noteIcon" onClick="updateItem();">Update Item</div>
-	<div dojoType="dijit.form.Button" iconClass="noteIcon" onClick="deleteItem();">Delete Item</div>
-
-	<h2>New Item</h2>
-	<p>Enter an Id, Name, and optionally a description to be added as a new item to the store.  Upon successful addition, the tree will recieve notification of this event and respond accordingly.  If you select a node the item will be added to that node, otherwise the item will be added to the tree root. "Id" is the identifer here and as such must be unique for all items in the store.</p>
-	<div class="box">
-		<label for="nId">Id:</label>					<input id="nId" width="50" value="Enter Item Id"  autocomplete="off"/><br />
-		<label for="nLabel">Name:</label>				<input id="nLabel" width="50" value="Enter Item Name"  autocomplete="off"/><br />
-		<label for="nSomeProperty">Description:</label> <input id="nSomeProperty" width="50" value="Enter Some Property Value"  autocomplete="off"/><br /><br />
-		<label for="nParent">Parent:</label>			<input id="nParent" readonly autocomplete="off"/><br /><br />
-		<div style="float:left; margin-right: 2em;">
-			Children (in order):
-			<div dojoType="dojo.dnd.Source" class="container" id="nChildren" jsId="nChildrenDragSource"></div>
-		</div>
-		<div style="float:left">
-			<label for="nPotentialChildren">Potential Children:</label>
-			<div dojoType="dojo.dnd.Source" class="container" id="nPotentialChildren" jsId="nPotentialChildrenDragSource"></div>
-		</div>
-		<div class="clear">(drag and drop items to adjust list of children, and order of those children)</div>
-	</div>
-
-	<div dojoType="dijit.form.Button" iconClass="noteIcon" onClick="newItem();">Add Item to Store</div>
-	<br />
-
-	<h2>Data in flat form</h2>
-	<!--
-		flat view of the items in the data store.
-		TODO: use the table widget from the mail demo, or dojox.Grid
-	-->
-	<div dojoType="dijit.Declaration" widgetClass="ItemRow" defaults="{ item: {}, itemId: 'thud', label: 'foo', someProperty: 'foo', children: {} }">
-		Id: ${itemId}, Label: ${label}
-
-		Children:
-		<span class="dijitInline" dojoAttachPoint="childrenContainerNode"></span>
-
-		<script type='dojo/connect' event='postCreate'>
-			var children =
-				dojo.map(this.children, function(childItem){
-					return "<span class='itemReference'>" + store.getLabel(childItem) + "</span>";
-				});
-			this.childrenContainerNode.innerHTML = children.join(" ");
-		</script>
-	</div>
-	<div id="itemsTable"></div>
-	</body>
-</html>
-
-
-
-
diff --git a/dijit/tests/test_bgIframe.html b/dijit/tests/test_bgIframe.html
index ebf8864..c88754f 100644
--- a/dijit/tests/test_bgIframe.html
+++ b/dijit/tests/test_bgIframe.html
@@ -1,28 +1,26 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Dojo Toolkit - Background Iframe test</title>
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
 
 	<!-- not needed, for testing alternate themes -->
 	<script type="text/javascript" src="_testCommon.js"></script>
 
 	<script type="text/javascript">
-		// adding this for IE
-		doh = { robot: {}, run: function(){} };
-
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dijit.Dialog");
 		dojo.require("dijit.form.DateTextBox");
@@ -33,55 +31,90 @@
 
 </head>
 <body class="claro">
-	<span dojoType="dijit.Tooltip" connectId="one" id="one_tooltip">
+	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["one_applet"]'>
 		This is one tooltip.
 	</span>
-	<span dojoType="dijit.Tooltip" connectId="two" id="two_tooltip">
+	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["two_applet"]'>
 		This is another tooltip.  A little longer...
 	</span>
-	<button dojoType="dijit.form.Button">
+	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["one_xapp"]'>
+		This is one tooltip.
+	</span>
+	<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:["two_xapp"]'>
+		This is another tooltip.  A little longer...
+	</span>
+	<button id="showDialog" data-dojo-type="dijit.form.Button">
 		Show Dialog
-		<script type="dojo/connect" event="onClick">
+		<script type="dojo/connect" data-dojo-event="onClick">
 			dialog.show();
 		</script>
 	</button>
 	<table>
-		<tbody>
 			<tr>
 				<td></td>
 				<td>
-					<input dojoType="dijit.form.DateTextBox" type="text" />
+					<input id="dateText_applet" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text" '/>
 				</td>
 			</tr>
 			<tr>
 				<td>
 					<div style="width: 200px;">
-						This tooltip will disappear on IE6
+						This <select> will disappear on IE6
 						when the dialog is displayed.
-						But the tooltip's iframe shouldn't make it disappear because they shouldn't overlap.
+						But the dialog's iframe shouldn't make it disappear because they shouldn't overlap.
 					</div>
-					<select>
+					<select id="dropDown_applet">
 						<option>cat</option>
 						<option>dog</option>
 						<option>mouse</option>
 					</select>
-					<br /><br />
+					<br><br>
 
-					<div id="one">Mouse over this to see the tooltip</div>
-					<br />
-					<div id="two">Mouse over this to see a different tooltip</div>
+					<div id="one_applet">Mouse over this to see the tooltip</div>
+					<br>
+					<div id="two_applet">Mouse over this to see a different tooltip</div>
 				</td>
-				<td>
-					<applet width="400" height="400" code="DOHRobot.class" archive="../../util/doh/robot/DOHRobot.jar">
+				<td id="applet_td">
+					<!-- TODO: remove the applet tag which is deprecated -->
+					<applet id="applet" width="400" height="300" code="javax.swing.JApplet">
 						<param name="mayscript" value="false">
 						<param name="scriptable" value="false">
 						<param name="initial_focus" value="false">
 					</applet>
 				</td>
 			</tr>
-		</tbody>
 	</table>
-	<div id="dialog" jsId="dialog" dojoType="dijit.Dialog">
+	<table>
+			<tr>
+				<td></td>
+				<td>
+					<input id="dateText_xapp" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='type:"text" '/>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div style="width: 200px;">
+						This select will disappear on IE6
+						when the dialog is displayed.
+						But the dialog's iframe shouldn't make it disappear because they shouldn't overlap.
+					</div>
+					<select id="dropDown_xapp">
+						<option>cat</option>
+						<option>dog</option>
+						<option>mouse</option>
+					</select>
+					<br><br>
+
+					<div id="one_xapp">Mouse over this to see the tooltip</div>
+					<br>
+					<div id="two_xapp">Mouse over this to see a different tooltip</div>
+				</td>
+				<td>
+					<embed id="xapp" src="../../dojox/av/resources/video.swf" width="400" height="300" />
+				</td>
+			</tr>
+	</table>
+	<div id="dialog" data-dojo-id="dialog" data-dojo-type="dijit.Dialog">
 		Hello!
 	</div>
 </body>
diff --git a/dijit/tests/test_instantiate.html b/dijit/tests/test_instantiate.html
deleted file mode 100644
index b681aa1..0000000
--- a/dijit/tests/test_instantiate.html
+++ /dev/null
@@ -1,118 +0,0 @@
-<html>
-	<head>
-		<title>dojo.NodeList.instantiate() tests</title>
-
-		<style type="text/css">
-			@import "../../dojo/resources/dojo.css";
-			@import "css/dijitTests.css";
-			#container { height:200px; }
-		</style>
-
-		<!-- required: a default dijit theme: -->
-		<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
-
-		<!-- required: dojo.js -->
-		<script type="text/javascript" src="../../dojo/dojo.js"
-			djConfig="parseOnLoad: true, isDebug: true"></script>
-
-		<!-- not needed, for testing alternate themes -->
-		<script type="text/javascript" src="_testCommon.js"></script>
-
-		<script type="text/javascript">
-			dojo.require("dijit.dijit"); // optimize: load dijit layer
-			dojo.require("dijit._Widget");
-			dojo.require("dojo.parser");
-			dojo.require("dijit.form.Button");
-			dojo.require("dijit.layout.TabContainer");
-			dojo.require("dijit.layout.ContentPane");
-			dojo.require("dijit.layout.LinkPane");
-
-			// declare a simple widget to use as a base test:
-			dojo.declare("test._Widget",dijit._Widget,{
-				message:"",
-				postCreate:function(){
-					this.inherited(arguments);
-					this.connect(this.domNode,"onclick","workit");
-					dojo.style(this.domNode,{
-						cursor:"pointer",
-						color:"#333"
-					});
-					this.domNode.innerHTML += this.message +" ("+this.id +")";
-					console.log('created',this.id);
-				},
-				workit:function(){
-					dojo.place(this.domNode,this.domNode.parentNode,"end");
-				}
-			});
-
-			var init = function(){
-				dojo.byId("status").innerHTML = "after.";
-
-				// test widgeting
-				dojo.query("#testList li").instantiate(test._Widget,{}).connect("onclick",console.log);
-
-				// make a tab container from some div, and all it's children div's
-				dojo.query("#container")
-					.forEach(function(n){
-						dojo.query("div",n)
-							// create contentpanes from the children and style them
-							.instantiate(dijit.layout.ContentPane,{})
-							.forEach(function(wn,idx){
-								dojo.mixin(dijit.byNode(wn),{ title:"tab" + (idx + 1) })
-							})
-						;
-					})
-					.instantiate(dijit.layout.TabContainer,{})
-				;
-				// should we add auto-startup calling?
-				dijit.byId("container").startup();
-				//dijit.byId("container").layout();
-
-				// another test widget example
-				dojo.query("#altList li").instantiate(test._Widget,{ message:"woot" });
-
-				// bunches of buttons, use you imagination on how to relate them to something
-				dojo.query("#buttonTest").forEach(function(n){
-					dojo.query("button",n).instantiate(dijit.form.Button,{
-						onClick:function(){
-							console.log('clicked:',this.domNode);
-						}
-					});
-				});
-			};
-			dojo.addOnLoad(init)
-			//dojo.addOnLoad(function(){
-			//	setTimeout(init,25);
-			//});
-		</script>
-	</head>
-	<body class="claro">
-
-		<h1>dojo.NodeList.instantiate() tests: <span id="status">before</span></h1>
-
-			<h2>Some simple widgets:</h2>
-			<ul id="testList">
-					<li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li>
-			</ul>
-			<ul id="altList">
-					<li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li><li>inner</li>
-			</ul>
-
-			<h2>A TabContainer:</h2>
-			<div id="container">
-				<div>pane1</div>
-				<div>pane2</div>
-				<div>pane3</div>
-			</div>
-
-			<h2>Some Buttons</h2>
-			<div id="buttonTest">
-				<button>button 1</button>
-				<button>button 2</button>
-				<button>button 3</button>
-				<button>button 4</button>
-				<button>button 5</button>
-			</div>
-
-	</body>
-</html>
diff --git a/dijit/tests/tree/CustomLabel.html b/dijit/tests/tree/CustomLabel.html
new file mode 100644
index 0000000..a006f20
--- /dev/null
+++ b/dijit/tests/tree/CustomLabel.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dijit Tree Custom Label Test</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		data-dojo-config="parseOnLoad: true, isDebug: true"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dijit.Tree");
+		dojo.require("dijit.tree.ForestStoreModel");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		
+		dojo.addOnLoad(function(){
+			doh.register("Test custom label",
+				[
+					{
+						name: "testLabels",
+						timeout: 1000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							setTimeout(d.getTestCallback(function(){
+								var nameTree = dijit.byId("nameTree");
+								var nameChildren = nameTree.rootNode.getChildren();
+								doh.is("Arizona", nameChildren[3].label);
+								doh.is("Colorado", nameChildren[9].label);
+								
+								var codeTree = dijit.byId("codeTree");
+								var codeChildren = codeTree.rootNode.getChildren();
+								doh.is("AZ", codeChildren[3].label);
+								doh.is("CO", codeChildren[9].label);
+								
+								var customTree = dijit.byId("customTree");
+								var customChildren = customTree.rootNode.getChildren();
+								doh.is("Arizona (AZ)", customChildren[3].label);
+								doh.is("Colorado (CO)", customChildren[9].label);
+							}), 500);
+							
+							return d;
+						}
+					}
+				]
+			);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Dijit Tree Custom Label Test</h1>
+
+	<div data-dojo-id="store" data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-props='url:"../_data/states.json"'></div>
+
+	<h2>Standard label (state names)</h2>
+	<div data-dojo-id="nameModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:store, rootLabel:"States"'></div>
+	<div id="nameTree" data-dojo-type="dijit.Tree" data-dojo-props='model:nameModel, openOnClick:true'></div>
+
+	<h2>LabelAttr (state abbreviation)</h2>
+	<div data-dojo-id="codeModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:store, rootLabel:"States", labelAttr:"abbreviation"'></div>
+	<div id="codeTree" data-dojo-type="dijit.Tree" data-dojo-props='model:codeModel, openOnClick:true'></div>
+
+	<h2>Custom label via callback</h2>
+	<div data-dojo-id="customModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:store'>
+		<script type="dojo/method" data-dojo-event="getLabel" data-dojo-args="item">
+			if(item.root){ return "States"; }
+			return (store.getLabel(item) + " (" + store.getIdentity(item) + ")");
+		</script>
+	</div>
+	<div id="customTree" data-dojo-type="dijit.Tree" data-dojo-props='model:customModel, openOnClick:true'></div>
+
+
+</body>
+</html>
diff --git a/dijit/tests/tree/Tree.html b/dijit/tests/tree/Tree.html
new file mode 100644
index 0000000..aac5dcd
--- /dev/null
+++ b/dijit/tests/tree/Tree.html
@@ -0,0 +1,353 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dijit.Tree Automatic Tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../../dojo/resources/dnd.css";
+		@import "../../../dojo/tests/dnd/dndDefault.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		djConfig="isDebug: true"></script>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dijit.Tree");
+		dojo.require("dijit.tree.ForestStoreModel");
+		dojo.require("dijit.tree.TreeStoreModel");
+		dojo.require("dijit.tree.dndSource");
+		
+		function getRowClass(item, isExpanded) {
+			if (!item
+					|| !treeStore.isItem(item)
+					|| treeStore.getValue(item, "type") != "header") {
+				return null;
+			}
+			return "headerRow";
+		}
+
+		dojo.addOnLoad(function(){
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("paths", [
+				function create(){
+					var d = new doh.Deferred();
+					myStore = new dojo.data.ItemFileWriteStore({url:'../_data/countries.json'});
+					doh.t(myStore, "store created");
+
+					myModel = new dijit.tree.ForestStoreModel({
+						store: myStore,
+						query: {type:'continent'},
+						rootId: "earth",
+						rootLabel: "Earth",
+						childrenAttrs: ["children"]
+					});
+					doh.t(myModel, "model created");
+
+					myTree = new dijit.Tree({
+						id: "myTree",
+						model: myModel,
+						persist: false,		// persist==true is too hard to test
+						dndController: "dijit.tree.dndSource"
+					});
+					doh.t(myTree, "tree created");
+
+					dojo.byId("container").appendChild(myTree.domNode);
+					myTree.startup();
+
+					setTimeout(d.getTestCallback(function(){
+						// Give the tree time to load, and the do checks that it
+						// loaded correctly
+						doh.t(myTree.rootNode, "root node exists");
+						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+
+						var children = myTree.rootNode.getChildren();
+						doh.is(6, children.length, "six children");
+						doh.is("Africa", children[0].label, "first child");
+						doh.f(children[0].isExpanded, "first child not expanded");
+						doh.is("South America", children[5].label, "last child");
+
+						// Last child has special CSS for drawing the grid lines
+						doh.f(dojo.hasClass(children[3].domNode, "dijitTreeIsLast"), "middle node doesn't have dijitTreeIsLast");
+						doh.t(dojo.hasClass(children[5].domNode, "dijitTreeIsLast"), "last node has dijitTreeIsLast");
+					}), 750);
+					return d;
+				},
+
+				{
+					name: "createWithPath",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						myTree2 = new dijit.Tree({
+							id: "myTree2",
+							model: myModel,
+							persist: false,		// persist==true is too hard to test
+							dndController: "dijit.tree.dndSource",
+							path: ["earth", "EU", "IT"]
+						});
+						doh.t(myTree2, "myTree2 created");
+
+						dojo.byId("container2").appendChild(myTree2.domNode);
+						myTree2.startup();
+
+						setTimeout(d.getTestCallback(function(){
+							doh.t(myTree2.rootNode, "root node exists");
+							doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
+							doh.t(myTree2.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
+							doh.is(myTree2.rootNode.getChildren()[3].getChildren()[3], myTree2.selectedNode, "selected correct node");
+						}), 2000);
+
+						return d;
+					}
+				},
+				function copyPath(){
+					var d = new doh.Deferred();
+
+					myTree.set("path", myTree2.get("path")).then(d.getTestCallback(function(){
+						doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+						doh.t(myTree.rootNode.getChildren()[3].isExpanded, "europe node is expanded");
+						doh.is(myTree.rootNode.getChildren()[3].getChildren()[3], myTree.get("selectedNode"), "selected correct node");
+					}));
+
+					return d;
+				},
+
+				{
+					name: "copyPathByIds",
+					timeout: 5000,
+					runTest: function(){
+						var d = new doh.Deferred();
+
+						myTree.set("path", ["earth", "NA", "CA", "Ottawa"]).then(d.getTestErrback(function(){
+							var path = dojo.map(myTree.get("path"), function(item){ return myTree.model.getIdentity(item); });
+							doh.is(["earth", "NA", "CA", "Ottawa"], path, "path got set on myTree");
+
+							myTree2.set("path", path).then(d.getTestCallback(function(){
+								doh.t(myTree2.rootNode.isExpanded, "root node is expanded");
+								doh.t(myTree2.rootNode.getChildren()[4].isExpanded, "north america node is expanded");
+								doh.t(myTree2.rootNode.getChildren()[4].getChildren()[1].isExpanded, "canada node is expanded");
+								doh.is(myTree2.rootNode.getChildren()[4].getChildren()[1].getChildren()[0], myTree2.get("selectedNode"), "selected correct node");
+							}));
+						}));
+
+						return d;
+					}
+				},
+
+				function setPathToNull(){
+					var d = new doh.Deferred();
+
+					myTree2.set("path", []).addCallback(d.getTestCallback(function(){
+						doh.is(null, myTree2.get("selectedNode"), "no selected node");
+					}));
+					return d;
+				},
+
+				function setPathToRoot(){
+					var d = new doh.Deferred();
+
+					myTree2.set("path", ["earth"]).addCallback(d.getTestCallback(function(){
+						doh.is(myTree2.rootNode, myTree2.get("selectedNode"), "selected root node");
+					}));
+					return d;
+				},
+
+				function setPaths(){
+					var d = new doh.Deferred();
+
+					myTree2.set("paths", [["earth","AF","KE","Nairobi"],
+										  ["earth","NA","MX","Guadalajara"]]).addCallback(d.getTestCallback(function(){
+							  var ids = dojo.map(myTree2.selectedItems, function(x){return myTree2.model.getIdentity(x);}).sort();
+							  doh.is(["Guadalajara", "Nairobi"], ids);
+						  }));
+					return d;
+				}
+			]);
+
+			doh.register("data store", [
+				function itemUpdate(){
+					// Test that Tree noticed when data store items change, and updates accordingly
+
+					var item = myTree.rootNode.getChildren()[3].item;
+					myStore.setValue(item, "name", "EU");
+
+					doh.is("EU", innerText(myTree.rootNode.getChildren()[3].labelNode), "label changed");
+				},
+
+				function topLevelItemDelete(){
+					// Delete a top level item.   ForestStoreModel needs to realize that the top level
+					// children have changed and notify Tree
+
+					// Remove "South America"
+					var item = myTree.rootNode.getChildren()[5].item;
+					myStore.deleteItem(item);
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(5, children.length, "five children");
+					doh.is("North America", children[4].label, "last child");
+					doh.t(dojo.hasClass(children[4].domNode, "dijitTreeIsLast"),
+							"North america has become the last node so it gets the CSS class for that");
+				},
+
+				function openANode(){
+					var d = new doh.Deferred();
+
+					var asia = myTree.rootNode.getChildren()[1];
+
+					doh.is(0, asia.getChildren().length, "no children loaded yet");
+
+					myTree._onExpandoClick({node: asia});
+
+					setTimeout(d.getTestCallback(function(){
+						// Give the tree time to load the children, and the do checks that it
+						// loaded correctly
+
+						var children = asia.getChildren();
+						doh.is(4, children.length, "four children");
+						doh.is("China", children[0].label, "first child");
+						doh.is("Mongolia", children[3].label, "last child");
+					}), 750);
+					return d;
+				},
+
+				function selectAnItem(){
+					myTree.set('selectedItem','CN');
+					doh.is('CN',myTree.model.getIdentity(myTree.get('selectedItem')));
+				},
+
+				function nestedItemDelete(){
+					// Delete a nested item
+
+					// Remove "China"
+					var asia = myTree.rootNode.getChildren()[1],
+						china = asia.getChildren()[0];
+					myStore.deleteItem(china.item);
+
+					var children = asia.getChildren();
+					doh.is(3, children.length, "three children");
+				},
+
+				function topLevelItemInsert(){
+					// Create a new top level item as last child.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.newItem({
+						id: 'PA',
+						name:'Pacifica',
+						type:'continent',
+						children: []
+					});
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(6, children.length, "six children");
+					doh.is("Pacifica", children[5].label, "last child");
+					doh.f(dojo.hasClass(children[4].domNode, "dijitTreeIsLast"),
+						"North America no longer last child");
+					doh.t(dojo.hasClass(children[5].domNode, "dijitTreeIsLast"),
+						"Pacifica is last child");
+				},
+
+				function topLevelItemModify(){
+					// Modify a top level item so it's no longer top level.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.fetchItemByIdentity({
+						identity: 'PA',
+						onItem: function(item){
+							// in real life we would need to give the item a parent,
+							// but this is enough for testing
+							myStore.setValue(item, 'type', 'country');
+						}
+					})
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(5, children.length, "five children again");
+				},
+
+				function nestedItemModify(){
+					// Modify a nested item so it matches the query for top level items in the tree.
+					// ForestStoreModel needs to realize that the top level children have changed and notify Tree.
+
+					myStore.fetchItemByIdentity({
+						identity: 'PA',
+						onItem: function(item){
+							// in real life we would need to give the item a parent,
+							// but this is enough for testing
+							myStore.setValue(item, 'type', 'continent');
+						}
+					})
+
+					var children = myTree.rootNode.getChildren();
+					doh.is(6, children.length, "six children again");
+				},
+
+				function destroyTree(){
+					// Just running this to make sure we don't get an exception
+					console.log("destroying tree");
+					myTree.destroy();
+					myTree2.destroy();
+				}
+			]);
+
+			doh.register("delete selected node", [
+				function create(){
+					var d = new doh.Deferred();
+
+					myTree = new dijit.Tree({
+						id: "myTree",
+						model: myModel,
+						persist: false,		// persist==true is too hard to test
+						path: ["earth", "EU", "IT"]
+					});
+					doh.t(myTree, "tree created");
+
+					dojo.byId("container").appendChild(myTree.domNode);
+					myTree.startup();
+
+					setTimeout(d.getTestCallback(function(){
+						doh.is("IT", myTree.get("selectedItem").id);
+					}), 500);
+					return d;
+				},
+
+				function deleteSelectedItem(){
+					myStore.deleteItem(myTree.get("selectedItem"));
+				},
+
+				function selectNewItem(){
+					myTree.set("path", ["earth", "EU", "FR"]);
+					doh.is("FR", myTree.get("selectedItem").id);
+				}
+			]);
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Dijit.Tree automated tests</h1>
+	<div id="container"> <!--  tree will go here --></div>
+	<div id="container2"> <!--  tree2 will go here --></div>
+</body>
+</html>
diff --git a/dijit/tests/tree/Tree_with_JRS.html b/dijit/tests/tree/Tree_with_JRS.html
new file mode 100644
index 0000000..ab26006
--- /dev/null
+++ b/dijit/tests/tree/Tree_with_JRS.html
@@ -0,0 +1,132 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>dijit.Tree Automatic Tests</title>
+
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
+		@import "../../../dojo/resources/dnd.css";
+		@import "../../../dojo/tests/dnd/dndDefault.css";
+		@import "../css/dijitTests.css";
+	</style>
+
+	<!-- required: a default dijit theme: -->
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+	
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../../dojo/dojo.js"
+		djConfig="isDebug: true"></script>
+	
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript" src="../helpers.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("doh.runner");
+		dojo.require("dojo.parser");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dojox.data.JsonRestStore");
+		dojo.require("dijit.Tree");
+		dojo.require("dijit.tree.ForestStoreModel");
+		dojo.require("dijit.tree.dndSource");
+
+		dojo.addOnLoad(function(){
+			var handler, myTree;
+
+			doh.register("parse", function(){
+				dojo.parser.parse();
+			});
+
+			doh.register("Tree tests",
+				[
+					{
+						timeout: 3000,
+						name: "create",
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+			 					myStore = new dojox.data.JsonRestStore({target:"./", labelAttribute:"name"}),
+								myModel = new dijit.tree.ForestStoreModel({
+									store: myStore,
+									deferItemLoadingUntilExpand: true,
+									query: "treeTestRoot",
+									childrenAttrs: ["children"]
+								});
+							myTree = new dijit.Tree({
+								id: "myTree",
+								model: myModel,
+								"label": "Example",
+								persist: false,		// persist==true is too hard to test
+								dndController: "dijit.tree.dndSource" 
+							});
+							doh.t(myTree, "tree created");
+
+							dojo.byId("container").appendChild(myTree.domNode);
+							handler = myTree.connect(myTree, "onOpen",
+								d.getTestCallback(function(){
+									// Give the tree time to load, and the do checks that it
+									// loaded correctly
+									doh.t(myTree.rootNode, "root node exists");
+									doh.t(myTree.rootNode.isExpanded, "root node is expanded");
+
+									var children = myTree.rootNode.getChildren();
+									doh.is(5, children.length, "six children");
+									doh.is("node1", children[0].label, "first child");
+									doh.f(children[0].isExpanded, "first child not expanded");
+								})
+							);
+							myTree.startup();
+							return d;
+						},
+						tearDown: function(){
+							myTree.disconnect(handler);
+						}
+					},
+					{
+						timeout: 2000,
+						name: "open a node",
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								first = myTree.rootNode.getChildren()[0],
+								runNext = function(){
+									var firstFirst = first.getChildren()[0];
+									runNext = d.getTestCallback(function(){
+										var children = firstFirst.getChildren();
+										doh.is(2, children.length, "two children");
+										doh.is("node1.1.1", children[0].label, "first child");
+									});
+									myTree._onExpandoClick({
+										node: firstFirst
+									});
+								};
+							handler = myTree.connect(myTree, "onOpen",
+								function(){ runNext(); });
+
+							myTree._onExpandoClick({
+								node: first
+							});
+
+							return d;
+						},
+						tearDown: function(){
+							myTree.disconnect(handler);
+						}
+					}
+				]
+			);
+
+			doh.run();
+		});
+	</script>
+
+</head>
+<body class="claro">
+
+	<h1 class="testTitle">Dijit.Tree automated tests</h1>
+	<div id="container"> <!--  tree will go here --></div>
+	<div id="container2"> <!--  tree2 will go here --></div>
+</body>
+</html>
diff --git a/dijit/tests/tree/module.js b/dijit/tests/tree/module.js
index e059eff..5ce348e 100644
--- a/dijit/tests/tree/module.js
+++ b/dijit/tests/tree/module.js
@@ -4,12 +4,20 @@ try{
 	var userArgs = window.location.search.replace(/[\?&](dojoUrl|testUrl|testModule)=[^&]*/g,"").replace(/^&/,"?"),
 		test_robot = true;
 
-	doh.registerUrl("dijit.tests.Tree", dojo.moduleUrl("dijit", "tests/Tree.html"), 99999999);
-	doh.registerUrl("dijit.tests.Tree_with_JRS", dojo.moduleUrl("dijit", "tests/Tree_with_JRS.html"), 99999999);
+	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){
-		doh.registerUrl("dijit.tests.robot.Tree_a11y", dojo.moduleUrl("dijit","tests/robot/Tree_a11y.html"+userArgs), 99999999);
-		doh.registerUrl("dijit.tests.robot.Tree_DnD", dojo.moduleUrl("dijit","tests/robot/Tree_dnd.html"+userArgs), 99999999);
-		doh.registerUrl("dijit.tests.robot.Tree_DnD_multiParent", dojo.moduleUrl("dijit","tests/robot/Tree_dnd_multiParent.html"+userArgs), 99999999);
+		doh.registerUrl("dijit.tests.tree.robot.Tree_a11y", dojo.moduleUrl("dijit","tests/tree/robot/Tree_a11y.html"+userArgs), 999999);
+		doh.registerUrl("dijit.tests.tree.robot.Tree_DnD", dojo.moduleUrl("dijit","tests/tree/robot/Tree_dnd.html"+userArgs), 999999);
+		doh.registerUrl("dijit.tests.tree.robot.Tree_selector", dojo.moduleUrl("dijit","tests/tree/robot/Tree_selector.html"+userArgs), 999999);
+		doh.registerUrl("dijit.tests.tree.robot.Tree_selector_only",
+			dojo.moduleUrl("dijit","tests/tree/robot/Tree_selector.html?controller=selector&"+userArgs.substr(1)), 999999);
+		doh.registerUrl("dijit.tests.tree/robot.Tree_DnD_multiParent", dojo.moduleUrl("dijit","tests/tree/robot/Tree_dnd_multiParent.html"+userArgs), 999999);
+		doh.registerUrl("dijit.tests.tree.robot.Tree_v1", dojo.moduleUrl("dijit","tests/tree/robot/Tree_v1.html"+userArgs), 999999);
 	}
 }catch(e){
 	doh.debug(e);
diff --git a/dijit/tests/tree/robot/Tree_a11y.html b/dijit/tests/tree/robot/Tree_a11y.html
new file mode 100644
index 0000000..2da2f45
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_a11y.html
@@ -0,0 +1,785 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>doh.robot Tree 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">
+		dojo.require("dijit.robotx");
+
+		var treeIds = ["mytree", "tree2"];
+
+		function treeTests(){
+			var that = {};
+
+			var forceLoadChildItems = function(/*dijit._TreeNode*/inNode, /*dijit.Tree*/inTree){
+				if(inTree.model.mayHaveChildren(inNode.item)){
+					if(inNode.getChildren().length > 0){
+						return;
+					}
+					var childItems = null;
+					inTree.model.getChildren(inNode.item, function(items){ childItems = items; });
+					inNode.setChildItems(childItems);
+					childItems = null;
+				}
+			};
+
+			that.testTreeItemRole = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
+				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 + ")");
+					//recurse
+					forceLoadChildItems(inRoot, inTree);
+					var children = inRoot.getChildren();
+					for(var i = 0; i < children.length; i++){
+						that.testTreeItemRole(children[i], inTree);
+					}
+				}
+			};
+
+			that.test1TreeItemExpandedState = function(/*dijit._TreeNode*/inItem, /*dijit.Tree*/inTree){
+				if(inItem){
+					if(inItem.isExpandable){
+						var wasExpanded = inItem.isExpanded;
+						inTree._expandNode(inItem);
+						var nowExpanded = dijit.getWaiState(inItem.labelNode, "expanded");
+						inTree._collapseNode(inItem);
+						var nowCollapsed = dijit.getWaiState(inItem.labelNode, "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");
+					}
+				}
+			};
+
+			that.testTreeItemExpandedState = function(/*dijit._TreeNode*/inRoot, /*dijit.Tree*/inTree){
+				if(inRoot){
+					that.test1TreeItemExpandedState(inRoot, inTree);
+					//recurse
+					forceLoadChildItems(inRoot, inTree);
+					var children = inRoot.getChildren();
+					for(var i = 0; i < children.length; i++){
+						that.testTreeItemExpandedState(children[i], inTree);
+					}
+				}
+			};
+
+			// Tab focus test data and functions
+			var xtraParas = [];
+			var expectedBlurCount = 0;
+			var focusCount = 0;
+			var blurCount = 0;
+			var gotFocus = function(){
+				focusCount++;
+			};
+			var lostFocus = function(){
+				blurCount++;
+			};
+			that.focusConnect = null;
+			that.blurConnect = null;
+
+			var addTabNavFoci = function(inTree){
+				var aPara = dojo.doc.createElement("p");
+				dojo.attr(aPara, 'tabIndex', 0);
+				aPara.innerHTML = "Tab-focussable paragraph just above " + inTree.id;
+				dojo.place(aPara, inTree.domNode, "before");
+				xtraParas.push(aPara);
+				aPara = dojo.doc.createElement("p");
+				dojo.attr(aPara, 'tabIndex', 0);
+				aPara.innerHTML = "Tab-focussable paragraph just below  " + inTree.id;
+				dojo.place(aPara, inTree.domNode, "after");
+				xtraParas.push(aPara);
+			};
+
+			var walkTreeToLeaf = function(inTree, inRootNode, /*array, optional*/ioPath){
+				var leaf = inRootNode;
+				if (ioPath){ ioPath.push(inRootNode); }
+				if(inRootNode.isExpandable){
+					forceLoadChildItems(inRootNode, inTree);
+					inTree._expandNode(inRootNode);
+					var down = inRootNode.getChildren()[0];
+					if(down){
+						leaf = walkTreeToLeaf(inTree, down, ioPath);
+					}
+				}
+				return(leaf);
+			};
+
+			that.tabFocusSetup = function(inTreeId, /*boolean*/ leaf){
+				var tree = dijit.byId(inTreeId);
+				that.collapseAllButRoot(tree);
+				addTabNavFoci(tree);
+				// set up focus listener machinery
+				focusCount = blurCount = 0;
+				var focusThing;
+				if(leaf){
+					focusThing = walkTreeToLeaf(tree, tree.rootNode);
+				}else if(tree.showRoot){
+					focusThing = tree.rootNode;
+				}else{
+					focusThing = tree.rootNode.getChildren()[0];
+				}
+				that.focusConnect = tree.connect(focusThing.labelNode, "onfocus", gotFocus);
+				that.blurConnect = tree.connect(focusThing.labelNode, "onblur", lostFocus);
+				tree.focusNode(focusThing);
+			};
+
+			that.tabFocusA11yTest = function(inTreeId){
+				var d = new doh.Deferred();
+				var tree = dijit.byId(inTreeId);
+				// shift+tab away, tab back, tab away, shift+tab back
+				doh.robot.keyPress(dojo.keys.TAB, 1000, {shift:true});
+				doh.robot.keyPress(dojo.keys.TAB, 300);
+				doh.robot.keyPress(dojo.keys.TAB, 300);
+				doh.robot.keyPress(dojo.keys.TAB, 300, {shift:true});
+				var checkTabNav = function(){
+					tree.disconnect(that.focusConnect);
+					tree.disconnect(that.blurConnect);
+					doh.is(3, focusCount,  tree.id + ": # of times focussed");
+					doh.is(2, blurCount, tree.id + ": # of times lost focus");
+				};
+				doh.robot.sequence(d.getTestCallback(checkTabNav), 500);
+				return d;
+			};
+
+			that.tabFocusTearDown = function(){
+				dojo.forEach(xtraParas, function(item){
+					item.parentNode.removeChild(item);
+				});
+				xtraParas.length = 0;
+				that.focusCount = 0;
+				that.blurCount = 0;
+			};
+
+			// arrow key navigation, expand, and collapse tests.
+			that.collapseAllButRoot = function(inTree){
+				function collapse(node){
+					if(node){
+						var children = node.getChildren();
+						dojo.forEach(children, function(child){
+							if(child.isExpandable){
+								collapse(child);
+								inTree._collapseNode(child);
+							}
+						});
+					}
+				}
+				if(inTree){
+					collapse(inTree.rootNode);
+				}
+			};
+
+			that.openConnect = null;
+			that.closeConnect = null;
+			var openedLabels = [];
+			var closedLabels = [];
+
+			that.a11yNavExpandCollapseSetup = function(inTreeId){
+				var tree = dijit.byId(inTreeId);
+				that.collapseAllButRoot(tree);
+				var startingNode = tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0];
+				tree.focusNode(startingNode);
+				var rootChilds = tree.rootNode.getChildren();
+				// down, right (open), left (close), down, left (open)
+				if(tree.showRoot){
+					openedLabels[0] = { expected: rootChilds[0].label };
+					openedLabels[1] = { expected: rootChilds[1].label };
+				}else{
+					openedLabels[0] = { expected: rootChilds[1].label };
+					openedLabels[1] = { expected: rootChilds[2].label };
+				}
+				closedLabels[0] = openedLabels[0];
+				var openIdx = 0;
+				var collectOpen = function(item, node){
+					openedLabels[openIdx].actual = node.label;
+				};
+				var collectClose = function(item, node){
+					closedLabels[openIdx].actual = node.label;
+					openIdx++;
+				};
+				that.openConnect = dojo.connect(tree, "onOpen", collectOpen);
+				that.closeConnect = dojo.connect(tree, "onClose", collectClose);
+			};
+
+			that.a11yNavExpandCollapseTest = function(inTreeId){
+				var d = new doh.Deferred();
+				// assume (1) collapaseAllButRoot(), and (2) focus is on first visible child.
+				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 1000);		// move down one
+				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
+				doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse
+				doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down one
+				doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
+				var checkKeystrokes = function(){
+					for(var idx = 0; idx < openedLabels.length; idx++){
+						doh.is(openedLabels[idx].expected, openedLabels[idx].actual, "onOpen");
+					}
+					for(idx = 0; idx < closedLabels.length; idx++){
+						doh.is(closedLabels[idx].expected, closedLabels[idx].actual, "onClose");
+					}
+				};
+				doh.robot.sequence(d.getTestCallback(checkKeystrokes), 500);
+				return d;
+			};
+
+			that.a11yNavExpandCollapseTearDown = function(){
+				dojo.disconnect(that.openConnect);
+				dojo.disconnect(that.closeConnect);
+			};
+
+			var expectedNode;
+			var actualNode;
+			var arrowDownCount;
+			var arrowRightCount;
+
+			that.a11yNavToLeafSetup = function(inTreeId){
+				var tree = dijit.byId(inTreeId);
+				// randomly choose a top-level node to traverse.
+				arrowDownCount = Math.floor(Math.random() * tree.rootNode.getChildren().length);
+				var path = [];
+				expectedNode = walkTreeToLeaf(tree, tree.rootNode.getChildren()[arrowDownCount], path);
+				that.collapseAllButRoot(tree);
+				if(tree.showRoot){
+					tree.focusNode(tree.rootNode);
+					arrowDownCount++;
+				}else{
+					tree.focusNode(tree.rootNode.getChildren()[0]);
+				}
+				// 1 to open root node, 2 for every non-leaf, 1 to get to the leaf
+				arrowRightCount = 1 + (path.length - 2)*2 + 1;
+				that.focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
+					actualNode = evt.target;
+				});
+			};
+
+			that.a11yNavToLeaf = function(inTreeId){
+				var d = new doh.Deferred();
+				var tree = dijit.byId(inTreeId);
+				// assume (1) collapseAllButRoot(), and (2) focus is on a top level tree node.
+				for(var i = 0; i < arrowDownCount; i++) {
+					doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);
+				}
+				for(i = 0; i < arrowRightCount; i++){
+					doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);
+				}
+				var checkLeaf = function(){
+					tree.disconnect(that.focusConnect);
+					doh.is(expectedNode.labelNode, actualNode, "expected: " + expectedNode.label + ", actual: " + actualNode.innerHTML);
+				};
+				doh.robot.sequence(d.getTestCallback(checkLeaf), 500);
+				return d;
+			};
+
+			that.lastVisibleNode = function(inTree){
+				var node = inTree.rootNode;
+				while(node.isExpanded){
+					var c = node.getChildren();
+					node = c[c.length-1];
+				}
+				return node;
+			};
+
+			that.a11yHomeEndKeySetup = function(inTreeId, inKey){
+				// put focus on an random leaf.
+				var tree = dijit.byId(inTreeId);
+				that.collapseAllButRoot(tree);
+				var topLvl = Math.floor(Math.random() * tree.rootNode.getChildren().length);
+				var leaf = walkTreeToLeaf(tree, tree.rootNode.getChildren()[topLvl]);
+				tree.focusNode(leaf);
+				// determine the expected/actual home.
+				if(inKey == dojo.keys.HOME){
+					expectedNode = ( tree.showRoot ? tree.rootNode : tree.rootNode.getChildren()[0] );
+				}else{
+					expectedNode = that.lastVisibleNode(tree);
+				}
+				focusConnect = tree.connect(expectedNode.labelNode, "onfocus", function(evt){
+					actualNode = evt.target;
+				});
+			};
+
+			that.a11yHomeEndKeyTest = function(inTreeId, inKey){
+				var d = new doh.Deferred();
+				var tree = dijit.byId(inTreeId);
+				doh.robot.keyPress(inKey, 300);
+				var checkAtHomeEnd = function(){
+					tree.disconnect(focusConnect);
+					doh.is(expectedNode.label, actualNode.innerHTML);
+				}
+				doh.robot.sequence(d.getTestCallback(checkAtHomeEnd), 500);
+				return d;
+			};
+
+			return that;
+		}
+
+		dojo.addOnLoad(function(){
+			doh.robot.initRobot('../test_Tree.html');
+			var treeTest = treeTests();
+
+			doh.register("_setup",{
+				timeout:20000,
+				runTest:function(){
+					var d = new doh.Deferred();
+					var store = dojo.global.dijit.byId('mytree3').get('store');
+					store.fetch({query:{id:'*'}, onComplete:function(){
+						d.callback(true);
+					}});
+					return d;
+				}
+			});
+
+			// aria role and properties tests.
+			doh.register("a11yAria",
+			[
+				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 + ")");
+					}
+				},
+
+				function ariaTreeStateExpanded(){
+					for(i=0; i<treeIds.length; i++){
+						var tree = dijit.byId(treeIds[i]);
+						var wasExpanded = tree.rootNode.isExpanded;
+						tree.rootNode.expand();
+						var nowExpanded = dijit.getWaiState(tree.domNode, "expanded");
+						tree.rootNode.collapse();
+						var nowCollapsed = dijit.getWaiState(tree.domNode, "expanded");
+						if(wasExpanded){
+							tree.rootNode.expand();
+						}
+						doh.is("true", nowExpanded, tree.id + ": aria state expanded=true");
+						doh.is("false", nowCollapsed, tree.id + ": aria state expanded=false ");
+					}
+				},
+
+				function ariaTreeItemRole(){
+					for(i=0; i<treeIds.length; i++){
+						var tree = dijit.byId(treeIds[i]);
+						treeTest.testTreeItemRole(tree.rootNode, tree);
+					}
+				},
+
+				function ariaTreeItemStateExpanded(){
+					for(i=0; i<treeIds.length; i++){
+						var tree = dijit.byId(treeIds[i]);
+						treeTest.testTreeItemExpandedState(tree.rootNode, tree);
+					}
+				}
+			]);
+
+			// Keyboard focus robot tests
+			doh.register("a11y tab navigation",
+			[
+				{
+					name:"mytreeTabFocusTest",
+					timeout:4000,
+					setUp:function(){
+						treeTest.tabFocusSetup('mytree', false);
+					},
+					runTest:function(){
+						return treeTest.tabFocusA11yTest('mytree');
+					},
+					tearDown:function(){
+						treeTest.tabFocusTearDown();
+					}
+				},
+				{
+					name:"tree2TabFocusTest",
+					timeout:4000,
+					setUp:function(){
+						treeTest.tabFocusSetup('tree2');
+					},
+					runTest:function(){
+						return treeTest.tabFocusA11yTest('tree2', false);
+					},
+					tearDown:function(){
+						treeTest.tabFocusTearDown();
+					}
+				},
+				{
+					name:"mytreeExpandedTabFocusTest",
+					timeout:4000,
+					setUp:function(){
+						treeTest.tabFocusSetup('mytree', true);
+					},
+					runTest:function(){
+						return treeTest.tabFocusA11yTest('mytree');
+					},
+					tearDown:function(){
+						treeTest.tabFocusTearDown();
+					}
+				},
+				{
+					name:"tree2ExpandedTabFocusTest",
+					timeout:4000,
+					setUp:function(){
+						treeTest.tabFocusSetup('tree2', true);
+					},
+					runTest:function(){
+						return treeTest.tabFocusA11yTest('tree2');
+					},
+					tearDown:function(){
+						treeTest.tabFocusTearDown();
+					}
+				}
+			]);
+
+			// Keyboard navigate/expand/collapse robot tests (arrow keys, and home/end)
+			doh.register("keyboard arrow navigation/expand/collapse",
+			[
+				{
+					name:"mytreeNavExpandCollpaseA11y",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yNavExpandCollapseSetup('mytree');
+					},
+					runTest:function(){
+						return treeTest.a11yNavExpandCollapseTest('mytree');
+					},
+					tearDown: function(){
+						treeTest.a11yNavExpandCollapseTearDown();
+					}
+				},
+				{
+					name:"tree2NavExpandCollpaseA11y",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yNavExpandCollapseSetup('tree2');
+					},
+					runTest:function(){
+						return treeTest.a11yNavExpandCollapseTest('tree2');
+					},
+					tearDown: function(){
+						treeTest.a11yNavExpandCollapseTearDown();
+					}
+				},
+				{
+					name:"mytreeNavToLeaf",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yNavToLeafSetup('mytree');
+					},
+					runTest:function(){
+						return treeTest.a11yNavToLeaf('mytree');
+					}
+				},
+				{
+					name:"tree2NavToLeaf",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yNavToLeafSetup('tree2');
+					},
+					runTest:function(){
+						return treeTest.a11yNavToLeaf('tree2');
+					}
+				},
+				{
+					name:"mytreeNavToHome",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.HOME);
+					},
+					runTest:function(){
+						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.HOME);
+					}
+				},
+				{
+					name:"mytreeNavToEnd",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yHomeEndKeySetup('mytree', dojo.keys.END);
+					},
+					runTest:function(){
+						return treeTest.a11yHomeEndKeyTest('mytree', dojo.keys.END);
+					}
+				},
+				{
+					name:"tree2NavToHome",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.HOME);
+					},
+					runTest:function(){
+						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.HOME);
+					}
+				},
+				{
+					name:"tree2NavToEnd",
+					timeout:4000,
+					setUp:function(){
+						treeTest.a11yHomeEndKeySetup('tree2', dojo.keys.END);
+					},
+					runTest:function(){
+						return treeTest.a11yHomeEndKeyTest('tree2', dojo.keys.END);
+					}
+				}
+			]);
+
+			// Test for typing "a" to navigate to nodes that start with "a", etc.
+			doh.register("keyboard search tests",
+			[
+				{
+					name:"Setup tree",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						var tree = dijit.byId("mytree");
+
+						// Close all tree nodes except for Asia and Oceania
+						dojo.forEach(tree.rootNode.getChildren(), function(child, idx){
+							if(child.label == "Asia" || child.label == "Oceania"){
+								console.log("expanding " + child.label);
+								if(!child.isExpanded){
+									tree._expandNode(child);
+								}
+							}else{
+								console.log("collapsing " + child.label);
+								if(child.isExpanded){
+									tree._collapseNode(child);
+								}
+							}
+						});
+
+						doh.robot.sequence(d.getTestCallback(function(){
+							// Just waiting for animation to finish...
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"Focus on Continents",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						var tree = dijit.byId("mytree");
+						tree.focusNode(tree.rootNode);
+
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dojo.global.dijit._curFocus;
+							doh.t(tree.rootNode.labelNode, "focused on continents");
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"First 'A' key goes to Africa",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						// From Continents node, press "A".   Should go to Africa.
+						doh.robot.keyPress("a", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("Africa", focus.label);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"Second 'A' key goes to Asia",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						// From Africa node, press "A" again.   Should go to Asia.
+						doh.robot.keyPress("a", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("Asia", focus.label);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"Third 'A' key goes to Australia (nested node)",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						var oceania = dijit.byId("mytree").rootNode.getChildren()[2];
+						doh.t(oceania, "found Oceania node");
+						doh.t(oceania.isExpanded, "Oceania node is expanded");
+
+						doh.robot.keyPress("a", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("Australia", focus.label);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"Fourth 'A' key loops back to Africa",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						doh.robot.keyPress("a", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("Africa", focus.label);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"multi-key navigation",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						// Skip over China and go to Continents
+						doh.robot.typeKeys("co", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("Continents", focus.label);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"multi-key navigation",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						// By typing AS should skip over Africa and go to Asia
+						doh.robot.typeKeys("as", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("Asia", focus.label);
+						}), 500);
+
+						return d;
+					}
+				},
+				{
+					name:"multi-key navigation clears",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						// After the 500ms delay from above, typing a new character should
+						// start a new search
+						doh.robot.typeKeys("n", 100);
+						doh.robot.sequence(d.getTestCallback(function(){
+							var focus = dijit.getEnclosingWidget(dojo.global.dijit._curFocus);
+							doh.t(focus, "there is a focused widget");
+							doh.is("North America", focus.label);
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.register("selection and focus",
+			[
+				{
+					name:"select Africa",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						var tree = dijit.byId("mytree");
+
+						doh.robot.keyPress(dojo.keys.HOME, 300);			// go to Continents
+						doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
+						doh.robot.keyPress(dojo.keys.RIGHT_ARROW, 300);		// expand
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Africa
+						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("Africa", tree.lastFocused.label, "Africa is focused");
+
+							var item = tree.get("selectedItem"),
+								label = tree.model.getLabel(item);
+							doh.is("Africa", label, "Africa is selected");
+						}), 500);
+
+						return d;
+					}
+				},
+
+				{
+					name:"focus Asia",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						var tree = dijit.byId("mytree");
+
+						if(tree.lastFocused.isExpanded){
+							doh.robot.keyPress(dojo.keys.LEFT_ARROW, 300);		// collapse tree, if it's open
+						}
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 300);		// move down to Asia
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							doh.is("Asia", tree.lastFocused.label, "Asia is focused");
+
+							var item = tree.get("selectedItem"),
+								label = tree.model.getLabel(item);
+							doh.is("Africa", label, "but Africa is still selected");
+						}), 500);
+
+						return d;
+					}
+				},
+
+				{
+					name:"select Asia",
+					timeout:4000,
+					runTest:function(){
+						var d = new doh.Deferred();
+
+						var tree = dijit.byId("mytree");
+
+						doh.robot.keyPress(dojo.keys.ENTER, 300);			// select it
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							var item = tree.get("selectedItem"),
+								label = tree.model.getLabel(item);
+							doh.is("Asia", label, "after ENTER focus shifted from Africa to Asia");
+						}), 500);
+
+						return d;
+					}
+				}
+			]);
+
+			doh.run();
+		});
+
+	</script>
+</head>
+</html>
+
diff --git a/dijit/tests/tree/robot/Tree_dnd.html b/dijit/tests/tree/robot/Tree_dnd.html
new file mode 100644
index 0000000..de67c46
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_dnd.html
@@ -0,0 +1,704 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Tree DnD 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>
+
+		<!-- functions to help test -->
+		<script type="text/javascript" src="../../helpers.js"></script>
+		<script type="text/javascript" src="Tree_dnd.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojo.window");
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_Tree_DnD.html');
+
+				setup();
+
+				// Dragging from an external source and dropping onto the Tree,
+				// creating a duplicate of the dragged item
+				doh.register("drop into", [
+					{
+						name: "drag 'Apple' over 'Fruits'",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+							doh.f(fruitsTreeNode.isExpanded, "fruitsTreeNode is initially closed");
+							doh.t(fruitsTreeNode.isExpandable, "but has (or may have) children");
+
+							// Check state of store too
+							var children = getNamesOfChildrenOfItem("Fruits");
+							doh.is(1, children.categories.length, "one category child");
+							doh.is("Citrus", children.categories[0]);
+							doh.is(0, children.items.length, "no item children yet");
+
+							// (Try to) make sure drag source and drop source are both in viewport
+							dojo.window.scrollIntoView(fruitsTreeNode.domNode);
+
+							// Drag "Apple" onto Fruits.
+							doh.robot.mouseMoveAt("1001", 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 500, 2000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// TODO: check drag avatar shows drop is valid (ie, avatar is green)
+								doh.t(dojo.hasClass(fruitsTreeNode.rowNode, "dijitTreeRowHover"), "tree node has hover class");
+								doh.t(dojo.hasClass(fruitsTreeNode.rowNode, "dojoDndItemOver"), "tree node has DND drop class");
+							}), 500);
+
+							return d;
+						}
+					},
+					{
+						name: "drop 'Apple' on to 'Fruits'",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Check that new item was created and added to the store.
+								var children = getNamesOfChildrenOfItem("Fruits");
+								doh.is(1, children.categories.length, "one category child");
+								doh.is("Citrus", children.categories[0]);
+								doh.is(1, children.items.length, "one item child");
+								doh.is("Apple", children.items[0]);
+
+								// Check that data store update was reflected in the tree
+								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+
+								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
+								var treeNodeChildren = fruitsTreeNode.getChildren();
+								doh.is(2, treeNodeChildren.length, "2 TreeNode children")
+								doh.is("Apple", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Citrus", innerText(treeNodeChildren[1].labelNode));
+							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
+
+							return d;
+						}
+					}
+				]);
+
+				// Moving an item w/in the tree
+				doh.register("re-parent an item", [
+					{
+						name: "drag 'Apple' from 'Fruits' to 'Citrus'",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								fruitsTreeNode = findTreeNode("itemTree", "Fruits"),
+								appleTreeNode = findTreeNode("itemTree", "Apple"),
+								citrusTreeNode = findTreeNode("itemTree", "Citrus");
+							dijit.scrollIntoView("itemTree");
+							// Drag "Apple" into "Citrus".
+							doh.robot.mouseMoveAt(appleTreeNode.labelNode, 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);
+							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 500, 1000);// If prev. mouseMove caused scroll, readjust
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var myStore = dojo.global.myStore;
+
+								// Check that data store item was orphaned from Fruits
+								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits");
+								doh.is(0, fruitsItemChildren.items.length, "no item children");
+
+								// Check that data store update was reflected in the tree
+								var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+
+								var fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
+								doh.is(1, fruitsTreeNodeChildren.length, "1 TreeNode children")
+								doh.is("Citrus", innerText(fruitsTreeNodeChildren[0].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(2, citrusItemChildren.items.length, "two item children");
+								doh.is("Orange", citrusItemChildren.items[0]);
+								doh.is("Apple", citrusItemChildren.items[1]);
+
+								// Check that data store update was reflected in the tree
+								var citrusTreeNode = findTreeNode("itemTree", "Citrus");
+
+								var citrusTreeNodeChildren = citrusTreeNode.getChildren();
+								doh.is(2, citrusTreeNodeChildren.length, "2 TreeNode children for Citrus")
+								doh.is("Orange", innerText(citrusTreeNodeChildren[0].labelNode), "child of Citrus TreeNode");
+								doh.is("Apple", innerText(citrusTreeNodeChildren[1].labelNode), "child of Citrus TreeNode");
+							}), 2000);
+
+							return d;
+						}
+					},
+
+					{
+						name: "drag 'Cereals' to be before 'Vegetables' (reordering)",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
+								cerealsTreeNode = findTreeNode("collectionsTree", "Cereals (0)");
+
+							// (Try to) make sure drag source and drop source are both in viewport
+							dojo.window.scrollIntoView(cerealsTreeNode.domNode);
+
+							// Drag 'Cereals' and drop near top edge of 'Vegetables'.
+							// It should become Vegetables' prior-sibling
+							// Note: if mousemove duration is too small itemTree doesn't get onmouseout event on IE6/7,
+							// causing subsequent JS exceptions
+							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1000, 50, 3);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var myStore = dojo.global.myStore;
+
+								// Check that order of children was changed
+								var foodsItemChildren = getNamesOfChildrenOfItem("Foods").categories;
+								doh.is(3, foodsItemChildren.length, "3 categories");
+								doh.is("Fruits", foodsItemChildren[0]);
+								doh.is("Cereals", foodsItemChildren[1]);
+								doh.is("Vegetables", foodsItemChildren[2]);
+
+								// Check that data store update was reflected in the tree
+								var
+									foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
+									foodsTreeNodeChildren = foodsTreeNode.getChildren();
+								doh.is(3, foodsTreeNodeChildren.length, "3 TreeNode children")
+								doh.is("Fruits (2)", innerText(foodsTreeNodeChildren[0].labelNode));
+								doh.is("Cereals (0)", innerText(foodsTreeNodeChildren[1].labelNode));
+								doh.is("Vegetables (0)", innerText(foodsTreeNodeChildren[2].labelNode));
+							}), 2000);
+
+							return d;
+						}
+					},
+
+					// We need to expand the Fruits TreeNode for the benefit of the next test,
+					// and we do it as a separate test so that citrusTreeNode will exist etc.
+					// by the time the next test starts.
+					{
+						name: "expand 'Fruits' TreeNode",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)");
+							doh.robot.mouseMoveAt(fruitsTreeNode.expandoNode, 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// This is just here to wait for the expand operation to take place,
+								// and then notify DOH that we are finished
+							}), 1000);
+							return d;
+						}
+					},
+
+					{
+						name: "drag 'Vegetables' to be after 'Citrus' (reordering)",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
+								citrusTreeNode = findTreeNode("collectionsTree", "Citrus (1)"),
+								citrusTreeNodeSize = dojo.contentBox(citrusTreeNode.domNode);
+
+							// (Try to) make sure drag source and drop source are both in viewport
+							dojo.window.scrollIntoView(vegetablesTreeNode.domNode);
+
+							// Drag 'Vegetables' and drop near bottom edge of 'Citrus'.
+							// It should become Citrus' prior-sibling
+							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(citrusTreeNode.domNode, 1000, 2000, 50, citrusTreeNodeSize.h - 2);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var myStore = dojo.global.myStore;
+
+								// Check that order of children in data store was changed
+								var foodsItemChildren = getNamesOfChildrenOfItem("Foods").categories;
+								doh.is(2, foodsItemChildren.length, "2 categories under foods");
+								doh.is("Fruits", foodsItemChildren[0]);
+								doh.is("Cereals", foodsItemChildren[1]);
+
+								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits").categories;
+								doh.is(2, fruitsItemChildren.length, "2 categories under fruits");
+								doh.is("Citrus", fruitsItemChildren[0]);
+								doh.is("Vegetables", fruitsItemChildren[1]);
+
+								// Check that data store update was reflected in the tree
+								var
+									foodsTreeNode = findTreeNode("collectionsTree", "Foods (1)"),
+									foodsTreeNodeChildren = foodsTreeNode.getChildren();
+								doh.is(2, foodsTreeNodeChildren.length, "2 TreeNode children for foods")
+								doh.is("Fruits (2)", innerText(foodsTreeNodeChildren[0].labelNode));
+								doh.is("Cereals (0)", innerText(foodsTreeNodeChildren[1].labelNode));
+
+								var fruitsTreeNode = findTreeNode("collectionsTree", "Fruits (2)"),
+								fruitsTreeNodeChildren = fruitsTreeNode.getChildren();
+								doh.is(2, fruitsTreeNodeChildren.length, "2 TreeNode children for fruits")
+								doh.is("Citrus (1)", innerText(fruitsTreeNodeChildren[0].labelNode));
+								doh.is("Vegetables (0)", innerText(fruitsTreeNodeChildren[1].labelNode));
+							}), 500);
+
+							return d;
+						}
+					}
+
+				]);
+
+				doh.register("drag between trees", [
+					{
+						name: "move 'Vegetables' from left tree to right tree, from 'Fruits' to 'Foods'",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNode("collectionsTree", "Vegetables (0)"),
+								foodsTreeNode = dijit.byId("itemTree").rootNode;
+
+							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 0, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(foodsTreeNode.labelNode, 500, 1000);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var myStore = dojo.global.myStore;
+
+								// Check that data store item was orphaned from Fruits
+								var fruitsItemChildren = getNamesOfChildrenOfItem("Fruits");
+								doh.is(1, fruitsItemChildren.categories.length, "one fruits child");
+								doh.is("Citrus", fruitsItemChildren.categories[0], "one fruits child");
+
+								// And added to Foods
+								var foodsItemChildren = getNamesOfChildrenOfItem("Foods");
+								doh.is(3, foodsItemChildren.categories.length, "three foods children");
+								doh.is("Fruits", foodsItemChildren.categories[0], "food child");
+								doh.is("Cereals", foodsItemChildren.categories[1], "food child");
+								doh.is("Vegetables", foodsItemChildren.categories[2], "food child");
+							}), 500);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("drop in Tree outside of a treeNode", [
+					{
+						name: "drop 'Orange' within Tree but not over a TreeNode",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							var orangeTreeNode = findTreeNode("itemTree", "Orange");
+
+							doh.robot.mouseMoveAt(orangeTreeNode.labelNode, 0, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("itemTree", 500, 500, 5, 100);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var org = findTreeNode("itemTree", "Orange");
+								doh.t( org != null);
+							}), 1000);
+							return d;
+						}
+					}
+				]);
+
+				// special function to allow dragging within a very short test window
+				function dragSourceToItemTree(srcId, destId, after){
+					var
+						child = dojo.global.dojo.byId(srcId),
+						parent = child.parentNode,
+						childPos = dojo.position(child),
+						parentPos = dojo.position(parent),
+						destTreeNode = findTreeNode("itemTree", destId);
+					dojo.window.scrollIntoView(parent);
+					parent.scrollTop += childPos.y + childPos.h - parentPos.y - parentPos.h;
+					doh.robot.mouseMoveAt(srcId, 500, 1);
+					doh.robot.mousePress({left: true}, 500);
+					doh.robot.mouseMoveAt(srcId, 1000, 500, (childPos.w >> 1) + 2, childPos.h >> 1); // start drag before scrolling to dest
+					doh.robot.sequence(function(){
+						dojo.window.scrollIntoView("itemTree");
+					}, 0);
+					doh.robot.mouseMoveAt(destTreeNode.labelNode, 500, 1); // move to dest center
+					doh.robot.mouseMoveAt(destTreeNode.labelNode, 500, 500, 0,
+						after
+							? (dojo.position(destTreeNode.domNode).h - dojo.position(destTreeNode.labelNode).y + dojo.position(destTreeNode.domNode).y - 1)
+							: -2
+					);
+					doh.robot.mouseRelease({left: true}, 500);
+				}
+
+				//=================
+				// Testing drag before and after items
+				// Dragging from an external source and dropping onto the Tree, creating a duplicate of the dragged item
+				//-----------------
+				doh.register("drag before and after items", [
+					{
+						name: "drag before the first item",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Drag "Banana" before Orange.
+							dragSourceToItemTree("1003", "Orange", !"after");
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// 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("Banana", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Orange", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Apple",  innerText(treeNodeChildren[2].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(3, citrusItemChildren.items.length, "three item children");
+								doh.is("Banana", citrusItemChildren.items[0]);
+								doh.is("Orange", citrusItemChildren.items[1]);
+								doh.is("Apple",  citrusItemChildren.items[2]);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag after the first item",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Drag "Tomato" after Banana.
+							dragSourceToItemTree("1004", "Banana", "after");
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// 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("Banana", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Orange", innerText(treeNodeChildren[2].labelNode));
+								doh.is("Apple",  innerText(treeNodeChildren[3].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(4, citrusItemChildren.items.length, "four item children");
+								doh.is("Banana", citrusItemChildren.items[0]);
+								doh.is("Tomato", citrusItemChildren.items[1]);
+								doh.is("Orange", citrusItemChildren.items[2]);
+								doh.is("Apple",  citrusItemChildren.items[3]);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag before in the middle of the list of items",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Drag "Pepper" before Orange.
+							dragSourceToItemTree("1005", "Orange", !"after");
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// 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("Banana", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
+								doh.is("Apple",  innerText(treeNodeChildren[4].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(5, citrusItemChildren.items.length, "five item children");
+								doh.is("Banana", citrusItemChildren.items[0]);
+								doh.is("Tomato", citrusItemChildren.items[1]);
+								doh.is("Pepper", citrusItemChildren.items[2]);
+								doh.is("Orange", citrusItemChildren.items[3]);
+								doh.is("Apple",  citrusItemChildren.items[4]);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag after in the middle of the list of items",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Drag "Wheat" after Orange.
+							dragSourceToItemTree("1006", "Orange", "after");
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// 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("Banana", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
+								doh.is("Wheat",  innerText(treeNodeChildren[4].labelNode));
+								doh.is("Apple",  innerText(treeNodeChildren[5].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(6, citrusItemChildren.items.length, "six item children");
+								doh.is("Banana", citrusItemChildren.items[0]);
+								doh.is("Tomato", citrusItemChildren.items[1]);
+								doh.is("Pepper", citrusItemChildren.items[2]);
+								doh.is("Orange", citrusItemChildren.items[3]);
+								doh.is("Wheat",  citrusItemChildren.items[4]);
+								doh.is("Apple",  citrusItemChildren.items[5]);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag before on the last item",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Drag "Corn" before Apple.
+							dragSourceToItemTree("1007", "Apple", !"after");
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// 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("Banana", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
+								doh.is("Wheat",  innerText(treeNodeChildren[4].labelNode));
+								doh.is("Corn",   innerText(treeNodeChildren[5].labelNode));
+								doh.is("Apple",  innerText(treeNodeChildren[6].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(7, citrusItemChildren.items.length, "seven item children");
+								doh.is("Banana", citrusItemChildren.items[0]);
+								doh.is("Tomato", citrusItemChildren.items[1]);
+								doh.is("Pepper", citrusItemChildren.items[2]);
+								doh.is("Orange", citrusItemChildren.items[3]);
+								doh.is("Wheat",  citrusItemChildren.items[4]);
+								doh.is("Corn",   citrusItemChildren.items[5]);
+								doh.is("Apple",  citrusItemChildren.items[6]);
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag after on the last item",
+						timeout: 10000,
+						runTest: function(){
+							var d = new doh.Deferred();
+
+							// Drag "Spinach" after Apple.
+							dragSourceToItemTree("1008", "Apple", "after");
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// 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("Banana", innerText(treeNodeChildren[0].labelNode));
+								doh.is("Tomato", innerText(treeNodeChildren[1].labelNode));
+								doh.is("Pepper", innerText(treeNodeChildren[2].labelNode));
+								doh.is("Orange", innerText(treeNodeChildren[3].labelNode));
+								doh.is("Wheat",  innerText(treeNodeChildren[4].labelNode));
+								doh.is("Corn",   innerText(treeNodeChildren[5].labelNode));
+								doh.is("Apple",  innerText(treeNodeChildren[6].labelNode));
+								doh.is("Spinach",innerText(treeNodeChildren[7].labelNode));
+
+								// ... and parented to Citrus item
+								var citrusItemChildren = getNamesOfChildrenOfItem("Citrus");
+								doh.is(8, citrusItemChildren.items.length, "eight item children");
+								doh.is("Banana", citrusItemChildren.items[0]);
+								doh.is("Tomato", citrusItemChildren.items[1]);
+								doh.is("Pepper", citrusItemChildren.items[2]);
+								doh.is("Orange", citrusItemChildren.items[3]);
+								doh.is("Wheat",  citrusItemChildren.items[4]);
+								doh.is("Corn",   citrusItemChildren.items[5]);
+								doh.is("Apple",  citrusItemChildren.items[6]);
+								doh.is("Spinach",citrusItemChildren.items[7]);
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("multi-dnd", [
+					{
+						name: "click on a new node and drag should select it",
+						timeout: 15000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								fruitsTreeNode = findTreeNode("itemTree", "Fruits"),
+								cerealsTreeNode = findTreeNode("itemTree", "Cereals"),
+								tree = dijit.byId("itemTree");
+
+							// click fruit item
+							doh.robot.mouseMoveAt(fruitsTreeNode.rowNode, 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							// drag cereal node to fruits node
+							doh.robot.mouseMoveAt(cerealsTreeNode.rowNode, 0, 1);
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(fruitsTreeNode.rowNode, 500, 1000);
+							doh.robot.mouseRelease({left: true}, 500);
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(fruitsTreeNode == cerealsTreeNode.getParent());
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag parent and child to another child should do nothing",
+						timeout: 15000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								citrusTreeNode = findTreeNode("itemTree", "Citrus"), 
+								citrusParent = citrusTreeNode.getParent(),
+								orangeTreeNode = findTreeNode("itemTree", "Orange"),
+								appleTreeNode = findTreeNode("itemTree", "Apple"),
+								tree = dijit.byId("itemTree");
+
+							doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange is child of citrus');
+
+							// click Citrus item
+							doh.robot.mouseMoveAt(citrusTreeNode.rowNode, 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							// ctrl-click Orange item
+							doh.robot.mouseMoveAt(orangeTreeNode.rowNode, 0, 1);
+							doh.robot.keyDown(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyUp(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+
+							// drag to Apple Foods
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(appleTreeNode.rowNode, 500, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(citrusParent, citrusTreeNode.getParent(), 'citrus parent should not change');
+								doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange should still be under citrus');
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag parent and child should only reparent parent",
+						timeout: 15000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								citrusTreeNode = findTreeNode("itemTree", "Citrus"),
+								orangeTreeNode = findTreeNode("itemTree", "Orange"),
+								cerealsTreeNode = findTreeNode("itemTree", "Cereals"),
+								tree = dijit.byId("itemTree");
+
+							doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange is child of citrus');
+
+							// click Citrus category
+							doh.robot.mouseMoveAt(citrusTreeNode.rowNode, 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							// ctrl-click Orange item
+							doh.robot.mouseMoveAt(orangeTreeNode.rowNode, 0, 1);
+							doh.robot.keyDown(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyUp(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+
+							// drag to Cereals category
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(cerealsTreeNode.rowNode, 500, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(cerealsTreeNode, citrusTreeNode.getParent(), 'citrus should be under cereals');
+								doh.is(citrusTreeNode, orangeTreeNode.getParent(), 'orange should still be under citrus');
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drag multiple items",
+						timeout: 15000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNode("itemTree", "Vegetables"),
+								cerealsTreeNode = findTreeNode("itemTree", "Cereals"),
+								foodsTreeNode = findTreeNode("itemTree", "Foods"),
+								tree = dijit.byId("itemTree");
+
+							// click Vegetables item
+							doh.robot.mouseMoveAt(vegetablesTreeNode.rowNode, 0, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							// ctrl-click cereals item
+							doh.robot.mouseMoveAt(cerealsTreeNode.rowNode, 0, 1);
+							doh.robot.keyDown(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.keyUp(dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, 500);
+
+							// drag to root item Foods
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(foodsTreeNode.rowNode, 500, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is(foodsTreeNode, vegetablesTreeNode.getParent());
+								doh.is(foodsTreeNode, cerealsTreeNode.getParent());
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+				// TODO: test icon and highlighting when valid drop target and invalid target (another item)
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/tree/robot/Tree_dnd.js b/dijit/tests/tree/robot/Tree_dnd.js
new file mode 100644
index 0000000..c4c1675
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_dnd.js
@@ -0,0 +1,131 @@
+/*
+ * Helper functions for Tree_dnd.html and Tree_dnd_multiParent.html tests
+ */
+
+function setup(){
+	doh.register("setup screen", function(){		
+		// Hide boilerplate text so it's easier to drag on small screen
+		dojo.query("h1,h2,p").style("display", "none");
+	
+		// Disable auto-scrolling because otherwise the viewport scrolls as doh.robot.mouseMoveAt()
+		// moves the mouse, literally making the the drop target a moving target
+		// (and mouseMoveAt() doesn't take this possibility into account).
+		dojo.global.dojo.dnd.autoScrollNodes = function(){};
+	
+		// Scroll viewport to (try to) make sure that both tree and drag-source
+		// are simultaneously in view.
+		var scroll = dojo.position("1001").y;
+		dojo.body().parentNode.scrollTop = scroll;	// works on FF
+		dojo.body().scrollTop = scroll;	// works on safari
+	});
+
+	// Wait for trees to load
+	doh.register("wait for load", dojo.map(["collectionsTree", "itemTree"], function(id){
+		return {
+			name: id,
+			timeout: 10000,
+			runTest: function(){
+				var
+					tree = dijit.byId(id),
+					d, handler;
+				if(!tree.rootNode){
+					d = new doh.Deferred();
+					handler = tree.connect(tree, "onLoad",
+						function(){
+							tree.disconnect(handler);
+							d.callback(true);
+						}
+					);
+					return d;
+				}
+			}
+		};
+	}));
+}
+
+function findTreeNode(/*String*/ treeId, /*String*/ label){
+	// summary:
+	//		Find the TreeNode with the specified label in the given tree.
+	//		Assumes that there's only one TreeNode w/that label (i.e. it
+	//		breaks if certain items have multiple parents and appear in the
+	//		tree multiple times)
+	var nodes = dojo.query(".dijitTreeLabel", treeId);
+	for(var i=0; i<nodes.length; i++){
+		if(innerText(nodes[i]) == label){
+			return dijit.getEnclosingWidget(nodes[i]);	// TreeNode
+		}
+	}
+	return null;
+}
+
+function findTreeNodeByPath(/*String*/ treeId, /*String[] */ path){
+	// summary:
+	//		Find the TreeNode with the specified path (like ["Fruits", "Apple"] in a tree like:
+	//	|	* Foods
+	//	|		* Vegetbles
+	//	|		* Fruits
+	//	|			* Orange
+	//	|			* Apple
+	//		Path shouldn't include the root node.
+
+	var tree = dijit.byId(treeId);
+	for(var i=0, node=tree.rootNode; i<path.length; i++){
+		var pathElem = path[i], matchingChildNode;
+		for(var j=0, children=node.getChildren(); j < children.length; j++){
+			if(children[j].label == pathElem){
+				matchingChildNode = children[j];
+				break;
+			}
+		}
+		if(!matchingChildNode){
+			return null;
+		}
+		node = matchingChildNode;
+	}
+	return node;
+}
+
+function getChildrenOfItem(/*String*/ name){
+	// summary:
+	//		Return the children of the data store item w/the specified name
+	//		Note that test_Tree_Dnd.html splits the children up into the "children"
+	//		and "items" attributes.
+
+	// Get the parent item
+	// Note that the ItemFileWriteStore's callback will happen immediately.
+	var myStore = dojo.global.myStore,
+		parentItem;
+	myStore.fetch({
+		query: {name: name},
+		onItem: function(item){ parentItem = item; }
+	});
+
+	// Get the children, which are stored in two separate attributes,
+	// categories (like 'Fruits') and items (ie, leaf nodes)  (like 'Apple')
+	return {
+		categories: myStore.getValues(parentItem, 'children'),
+		items: myStore.getValues(parentItem, 'items')
+	};
+}
+
+function mapItemsToNames(ary){
+	// summary:
+	//		Convert an array of items into an array of names
+	var myStore = dojo.global.myStore;
+	return dojo.map(ary, function(item){
+		return myStore.getValue(item, "name");
+	});
+}
+
+function getNamesOfChildrenOfItem(/*String*/ name){
+	// summary:
+	//		Return the names of the (items that are) children of the item w/the specified name
+
+	// Get the parent item (according to
+	var obj = getChildrenOfItem(name);
+	return {
+		categories: mapItemsToNames(obj.categories),
+		items: mapItemsToNames(obj.items)
+	};
+}
+
diff --git a/dijit/tests/tree/robot/Tree_dnd_multiParent.html b/dijit/tests/tree/robot/Tree_dnd_multiParent.html
new file mode 100644
index 0000000..e582b8d
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_dnd_multiParent.html
@@ -0,0 +1,272 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Tree DnD Multi-parent Test</title>
+
+		<style>
+			@import "../../../../util/doh/robot/robot.css";
+		</style>
+
+		<!-- required: dojo.js -->
+		<script type="text/javascript" src="../../../../dojo/dojo.js"
+			djConfig="isDebug: true, parseOnLoad: true"></script>
+
+		<!-- functions to help test -->
+		<script type="text/javascript" src="../../helpers.js"></script>
+		<script type="text/javascript" src="Tree_dnd.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojo.window");
+			dojo.require("dijit.robotx");
+
+			dojo.addOnLoad(function(){
+				doh.robot.initRobot('../test_Tree_DnD.html');
+
+				setup();
+
+				doh.register("multi-parent tests", [
+					{
+						name: "add 'Fruits' as parent of vegetables",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNodeByPath("collectionsTree", ["Vegetables (0)"]),	// the left tree
+								fruitsTreeNode = findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree
+
+							doh.robot.mouseMoveAt("collectionsTree", 500, 1); // scroll source parent into view
+							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
+							// Drag and Drop, *copying* in order to add a parent rather than change
+							doh.robot.keyDown(dojo.keys.copyKey, 500);
+							if(dojo.isMac){
+								// I can't get DOH robot to generate the mousePress event w/metaKey=true so
+								// hack it
+								doh.robot.sequence(function(){
+									realIsCopyKey = dojo.global.dojo.isCopyKey;
+									dojo.global.dojo.isCopyKey = function(){ return true; }
+								});
+							}
+
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt("itemTree", 500, 500); // move to dest parent to scroll it into view
+							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 0, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+							doh.robot.keyUp(dojo.keys.copyKey, 500);
+							if(dojo.isMac){
+								// See if(dojo.isMac) above
+								doh.robot.sequence(function(){
+									dojo.global.dojo.isCopyKey = realIsCopyKey;
+								});
+							}
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Check that Vegetables remains a child of Foods
+								var children = getNamesOfChildrenOfItem("Foods");
+								doh.is(3, children.categories.length, "foods category child");
+								doh.is("Fruits", children.categories[0]);
+								doh.is("Vegetables", children.categories[1]);
+								doh.is("Cereals", children.categories[2]);
+
+								// Check that Vegetables added as child of Fruits
+								var children = getNamesOfChildrenOfItem("Fruits");
+								doh.is(2, children.categories.length, "foods category child");
+								doh.is("Citrus", children.categories[0]);
+								doh.is("Vegetables", children.categories[1]);
+
+								// Check that new item *wasn't* created
+								var items;
+								dojo.global.myStore.fetch({
+									onComplete: function(i){ items = i; }
+								});
+								doh.is(6, items.length, "# of items in store");
+
+								// 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("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
+
+							return d;
+						}
+					},
+					{
+						name: "move Foods/Vegetables to Foods/Cereal/Vegetables",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNodeByPath("itemTree", ["Vegetables"]),
+								cerealsTreeNode = findTreeNodeByPath("itemTree", ["Cereals"]);
+
+							dojo.global.scrollTo(0, 9000); // scroll to bottom to try and prevent the DnD code from autoscrolling
+
+							// Drag and Drop
+							doh.robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500); // helps prevent screen jitter
+							doh.robot.mousePress({left: true}, 1000);
+							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
+							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100); // double move to allow for autoscrolling jitter
+							doh.robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Check that Vegetables remains a child of Fruits
+								var children = getNamesOfChildrenOfItem("Fruits");
+								doh.is(2, children.categories.length, "fruits category child");
+								doh.is("Citrus", children.categories[0]);
+								doh.is("Vegetables", children.categories[1]);
+
+								// Check that Vegetables added as child of Cereals
+								children = getNamesOfChildrenOfItem("Cereals");
+								doh.is(1, children.categories.length, "cereals category child");
+								doh.is("Vegetables", children.categories[0]);
+
+								// Check that Vegetables no longer a child of Foods
+								children = getNamesOfChildrenOfItem("Foods");
+								doh.is(2, children.categories.length, "foods category child");
+								doh.is("Fruits", children.categories[0]);
+								doh.is("Cereals", children.categories[1]);
+
+								// Check that new item *wasn't* created
+								var items;
+								dojo.global.myStore.fetch({
+									onComplete: function(i){ items = i; }
+								});
+								doh.is(6, items.length, "# of items in store");
+							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
+
+							return d;
+						}
+					},
+					{
+						name: "move Fruits/Vegetables to Fruits/Citrus",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								vegetablesTreeNode = findTreeNodeByPath("itemTree", ["Fruits", "Vegetables"]),
+								citrusTreeNode = findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
+
+							// Drag and Drop
+							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500); // helps prevent screen jitter
+							doh.robot.mousePress({left: true}, 1000);
+							doh.robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
+							doh.robot.mouseMoveAt(citrusTreeNode.labelNode, 0, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								// Check that Vegetables remains a child of Cereals
+								var children = getNamesOfChildrenOfItem("Cereals");
+								doh.is(1, children.categories.length, "cereals category child");
+								doh.is("Vegetables", children.categories[0]);
+
+								// Check that Vegetables added as child of Citrus
+								children = getNamesOfChildrenOfItem("Citrus");
+								doh.is(1, children.categories.length, "citrus category child");
+								doh.is("Vegetables", children.categories[0]);
+								doh.is(1, children.items.length, "citrus item child");
+								doh.is("Orange", children.items[0]);
+
+								// Check that Vegetables removed as child of Fruits
+								children = getNamesOfChildrenOfItem("Fruits");
+								doh.is(1, children.categories.length, "fruits category child");
+								doh.is("Citrus", children.categories[0]);
+
+								// Check that new item *wasn't* created
+								var items;
+								dojo.global.myStore.fetch({
+									onComplete: function(i){ items = i; }
+								});
+								doh.is(6, items.length, "# of items in store");
+							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node
+
+							return d;
+						}
+					}
+				]);
+
+				doh.register("external drop tests", [
+					{
+						name: "drop banana on fruits",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								fruitsTreeNode = findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree
+
+							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
+							doh.robot.mouseMoveAt(dojo.byId("1003"), 500, 1); // move to source banana node
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
+							doh.robot.mouseMoveAt("itemTree", 500, 500); // go to target parent top to allow for better scrolling of the destination
+							doh.robot.mouseMoveAt(fruitsTreeNode.labelNode, 1000, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+
+								var children = getChildrenOfItem("Fruits");
+								doh.is(1, children.items.length, "new item added");
+								doh.is(1003, children.items[0].id, "id of new item came from dropped node");
+								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");
+
+								dojo.global.myStore.fetch({
+									query: { name: "Banana" },
+									queryOptions: { deep: true },
+									onComplete: function(i){ items = i; }
+								});
+								doh.is(1, items.length, "1 banana item in store");
+							}), 1000);
+
+							return d;
+						}
+					},
+					{
+						name: "drop banana on cereal",
+						timeout: 10000,
+						runTest: function(){
+							var
+								d = new doh.Deferred(),
+								cerealsTreeNode = findTreeNodeByPath("itemTree", ["Cereals"]);					// right tree
+
+							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
+							doh.robot.mouseMoveAt(dojo.byId("1003"), 500, 1); // move to source banana node
+							doh.robot.mousePress({left: true}, 500);
+							doh.robot.mouseMoveAt(dojo.byId("1003").parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
+							doh.robot.mouseMoveAt("itemTree", 500, 100); // go to target parent top to allow for better scrolling of the destination
+							doh.robot.mouseMoveAt(cerealsTreeNode.labelNode, 1000, 500);
+							doh.robot.mouseRelease({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+
+								var children = getChildrenOfItem("Cereals");
+								doh.is(1, children.items.length, "banana is child of cereals");
+								doh.is(1003, children.items[0].id, "id of item came from dropped node");
+								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");
+
+								var 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");
+
+								dojo.global.myStore.fetch({
+									query: { name: "Banana" },
+									queryOptions: { deep: true },
+									onComplete: function(i){ items = i; }
+								});
+								doh.is(1, items.length, "1 banana item in store (with 2 parents)");
+							}), 1000);
+
+							return d;
+						}
+					}
+				]);
+
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/tree/robot/Tree_selector.html b/dijit/tests/tree/robot/Tree_selector.html
new file mode 100644
index 0000000..58c68de
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_selector.html
@@ -0,0 +1,243 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Tree selector 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>
+
+		<!-- functions to help test -->
+		<script type="text/javascript" src="../../helpers.js"></script>
+		<script type="text/javascript" src="Tree_dnd.js"></script>
+
+		<script type="text/javascript">
+			dojo.require("dojo.window");
+			dojo.require("dijit.robotx");
+
+			function clickItem(modifiers){
+				var i;
+				for(i = 0; i < modifiers.length; i++){
+					doh.robot.keyDown(modifiers[i], 250);
+				}
+				doh.robot.mouseClick({left: true}, 250);
+				for(i = modifiers.length - 1; i >= 0; i--){
+					doh.robot.keyUp(modifiers[i], 250);
+				}
+			}
+
+			function pressEnter(modifiers) {
+				var i;
+				for(i = 0; i < modifiers.length; i++){
+					doh.robot.keyDown(modifiers[i], 250);
+				}
+				
+				// Use ENTER on mac because meta-space controls the IME (switching input language),
+				// but SPACE on IE6 because ctrl-shift-ENTER doesn't do anything (although not sure
+				// why we are testing ctrl-shift combination anyway)
+				doh.robot.keyPress(dojo.isMac ? dojo.keys.ENTER : dojo.keys.SPACE, 250);
+
+				for(i = modifiers.length - 1; i >= 0; i--){
+					doh.robot.keyUp(modifiers[i], 250);
+				}
+			}
+			function mouseSelect(tree, item, modifiers, k) {
+				doh.robot.mouseMoveAt(item.domNode, 250, 200);
+				clickItem(modifiers);
+				doh.robot.sequence(k);
+			}
+			function keyboardSelect(tree, item, modifiers, k) {
+				var focused = dojo.query("#itemTree .dijitTreeLabelFocused");
+				if(!(focused.length > 0)) {
+					doh.robot.keyPress(dojo.keys.TAB, 250);
+					doh.robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 250);
+					return;
+				}
+				
+				focused_node = focused[0].parentNode.parentNode.parentNode;
+				var diff = dojo.position(item.domNode).y - dojo.position(focused_node).y;
+				if(diff != 0) {
+					if(diff > 0) {
+						doh.robot.keyPress(dojo.keys.DOWN_ARROW, 500);
+					} else {
+						doh.robot.keyPress(dojo.keys.UP_ARROW, 500);
+					}
+				} else {
+					pressEnter(modifiers);
+					doh.robot.sequence(k);
+					return;
+				}
+				doh.robot.sequence(function(){ keyboardSelect(tree, item, modifiers, k); }, 500);
+				return;
+            }
+			
+			function getSelected(tree){
+				//in IE, for(var i in object) will not honor the order the properties are set
+				//(it's in the order properties are first set even delete a property won't 
+				//change it)
+				var selected = tree.dndController.getSelectedTreeNodes();
+				selected.sort(function(a, b){return a.item.id<b.item.id?-1:1});
+				return selected;
+			}
+			function testSingleItem(selector, clicker){
+				var d = new doh.Deferred();
+				
+				// Find the fruitsTreeNode category
+				var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+				var tree = dijit.byId("itemTree");
+				
+				// select fruit item
+				selector(tree, fruitsTreeNode, [], function(){
+					doh.robot.sequence(d.getTestErrback(function(){
+						var selected = getSelected(tree);
+						
+						doh.is(1, selected.length);
+						doh.is(fruitsTreeNode, selected[0]);
+						
+						//ctrl-click the item to deselect it
+						clicker([dojo.isMac ? dojo.keys.META : dojo.keys.CTRL]);
+						
+						doh.robot.sequence(d.getTestCallback(function(){
+							var selected = getSelected(tree);
+							
+							doh.is(0, selected.length);
+						}), 500);
+					}), 500);
+				});
+				return d;
+			}
+			function testCtrlSelect(selector, clicker) {
+				var d = new doh.Deferred();
+				
+				// Find the fruitsTreeNode category
+				var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+				var tree = dijit.byId("itemTree");
+				
+				// select fruit item
+				selector(tree, fruitsTreeNode, [], function(){
+					doh.robot.sequence(function(){
+						dijit.scrollIntoView("itemTree");
+					}, 500);
+					
+					// ctrl-click Cereals item
+					var cerealsTreeNode = findTreeNode("itemTree", "Cereals");
+					selector(tree, cerealsTreeNode, 
+							 [dojo.isMac ? dojo.keys.META : dojo.keys.CTRL], function(){
+						 doh.robot.sequence(d.getTestCallback(function(){
+							 var selected = getSelected(tree);
+							 
+							 doh.is(2, selected.length);
+							 doh.is(fruitsTreeNode, selected[0]);
+							 doh.is(cerealsTreeNode, selected[1]);
+							 doh.is(cerealsTreeNode, tree.dndController.anchor, 'anchor should be the Cereals item');
+						 }), 500); });
+				});
+				return d;
+			}
+			function _getCtrlShiftTest(selector, keys){ 
+				return function(){
+					var d = new doh.Deferred();
+					
+					// Find the fruitsTreeNode category
+					var fruitsTreeNode = findTreeNode("itemTree", "Fruits");
+					var cerealsTreeNode = findTreeNode("itemTree", "Cereals");
+					var vegetablesTreeNode = findTreeNode("itemTree", "Vegetables");
+					var tree = dijit.byId("itemTree");
+					
+					// select fruit item (no modifiers)
+					selector(tree, fruitsTreeNode, [], atFruits);
+
+					function atFruits() {
+						// shift-select Cereals item
+                        selector(tree, cerealsTreeNode, keys, atCereals);
+					}
+					function atCereals(){ 
+						doh.robot.sequence(d.getTestErrback(function(){
+							var selected = getSelected(tree);
+						
+							doh.is(3, selected.length);
+							doh.is(fruitsTreeNode, selected[0]);
+							doh.is(vegetablesTreeNode, selected[1]);
+							doh.is(cerealsTreeNode, selected[2]);
+							doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 1');
+						
+							// shift-select Vegetables item
+                            keyboardSelect(tree, vegetablesTreeNode, keys, atVegetables);
+						}));
+					}
+									
+					function atVegetables(){
+						doh.robot.sequence(d.getTestCallback(function(){
+							var selected = getSelected(tree);
+							doh.is(2, selected.length);
+							doh.is(fruitsTreeNode, selected[0]);
+							doh.is(vegetablesTreeNode, selected[1]);
+							doh.is(fruitsTreeNode, tree.dndController.anchor, 'anchor should not change 2'); 
+						}));
+					}
+
+					return d;
+				};
+			}
+			dojo.addOnLoad(function(){
+				var controller = '', ind=window.location.href.indexOf("?controller=");
+				
+				if(ind > -1){
+					controller = window.location.href.substr(ind + 12);
+					controller = controller.split('&')[0];
+				}
+				doh.robot.initRobot('../test_Tree_DnD.html?testController=' + controller);
+
+				setup();
+
+				doh.register("focus page", {
+					name: "focus page",
+					timeout: 20000,
+					runTest: function(){
+						var d = new doh.Deferred();
+						doh.robot.mouseClick({left:true}, 100);
+						doh.robot.sequence(function(){
+                            //Focus the page, so tabbing will work.
+							d.callback(true);
+						}, 250);
+						return d;
+					}
+				});
+				doh.register("item selection (keyboard)", itemSelection(keyboardSelect, pressEnter) );
+				doh.register("item selection (mouse)", itemSelection(mouseSelect, clickItem) );
+
+				function itemSelection(selector, clicker){
+					return [
+						{
+							name: "select/deselect a single item",
+							timeout: 15000,
+							runTest: function(){ return testSingleItem(selector, clicker); }
+						}, 
+						{
+							name: "ctrl select",
+							timeout: 15000,
+							runTest: function(){ return testCtrlSelect(selector, clicker); }
+						},
+						{
+							name: "shift select",
+							timeout: 15000,
+							runTest: _getCtrlShiftTest(selector, [dojo.keys.SHIFT])
+						},
+						{
+							name: "ctrl shift select",
+							timeout: 15000,
+							runTest: _getCtrlShiftTest(selector, [dojo.isMac ? dojo.keys.META : dojo.keys.CTRL, dojo.keys.SHIFT])
+						}
+					];
+				}
+				
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/tree/robot/Tree_v1.html b/dijit/tests/tree/robot/Tree_v1.html
new file mode 100644
index 0000000..cbb77cb
--- /dev/null
+++ b/dijit/tests/tree/robot/Tree_v1.html
@@ -0,0 +1,267 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>doh.robot Tree_v1 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_Tree_v1.html');
+
+				doh.register("setup",{
+					name: "setup",
+					timeout:20000,
+					runTest:function(){
+						var d = new doh.Deferred();
+						var store = dojo.global.dijit.byId('mytree').get('store');
+						store.fetch({query:{id:'*'}, onComplete:function(){
+							d.callback(true);
+						}});
+						return d;
+					}
+				});
+							
+				doh.register("Test tree 1", [
+					{
+						name: "expand first child",
+						timeout: 7000,
+						runTest: function(){
+							var d = new doh.Deferred();
+														
+							var myTree = dijit.byId("mytree");
+							var children = myTree.rootNode.getChildren();
+								
+							doh.robot.mouseMoveAt(children[0].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							doh.robot.mouseMoveAt(children[4].contentNode, 1000, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.t(children[0].isExpanded, "failed to expand africa child node");
+								doh.t(children[4].isExpanded, "failed to expand north america child node");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "click Africa's first child",
+						timeout: 7000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("mytree");
+							var rootChildren = myTree.rootNode.getChildren();
+							var africaChildren = rootChildren[0].getChildren();
+							var naChildren = rootChildren[4].getChildren();
+							doh.robot.mouseMoveAt(naChildren[0].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							
+							doh.robot.mouseMoveAt(africaChildren[0].contentNode, 1000, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Egypt was clicked", africaChildren[0].labelNode.innerHTML);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "click Mexico's first child",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("mytree");
+							var rootChildren = myTree.rootNode.getChildren();
+							var naChildren = rootChildren[4].getChildren();
+							var mexicoChildren = naChildren[0].getChildren();
+							
+							doh.robot.mouseMoveAt(mexicoChildren[0].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Mexico City was clicked", mexicoChildren[0].labelNode.innerHTML);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "close tree nodes",
+						timeout: 7000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("mytree");
+							var rootChildren = myTree.rootNode.getChildren();
+							var naChildren = rootChildren[4].getChildren();
+							
+							doh.robot.mouseMoveAt(naChildren[0].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							
+							doh.robot.mouseMoveAt(rootChildren[4].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+							
+							doh.robot.mouseMoveAt(rootChildren[0].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(naChildren[0].isExpanded, "failed to close Mexico child node");
+								doh.f(rootChildren[0].isExpanded, "failed to close Africa child node");
+								doh.f(rootChildren[4].isExpanded, "failed to close North America child node");
+							}), 500);
+							return d;
+						}
+					},
+					{
+						name: "Destroy tree",
+						timeout: 4000,
+						runTest: function(){
+							dijit.byId("mytree").destroy();
+
+							doh.is(undefined, dijit.byId("mytree"), "tree was not destroyed");
+							doh.is(undefined, dojo.byId("mytree"), 'widget was removed');
+						}
+					}
+				]);
+				
+				doh.register("Test tree 2", [
+					{
+						name: "expand first node",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("tree2");
+							var children = myTree.rootNode.getChildren();
+							
+							var ex = children[0].expandoNode;
+							doh.robot.mouseMoveAt(children[0].expandoNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(isVisible(myTree.rootNode.labelNode), "root node is visible");
+								doh.t(children[0].isExpanded, "failed to expand first node");
+								
+								var style = dojo.getComputedStyle(children[0].iconNode);
+								doh.t(style.backgroundImage.indexOf("folderIcons.")>0, "custom icon was not used");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "click Africa",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("tree2");
+							var rootChildren = myTree.rootNode.getChildren();
+														
+							doh.robot.mouseMoveAt(rootChildren[0].contentNode, 500, 1);
+							doh.robot.mouseClick({left: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.is("Africa (population: 900 million)", rootChildren[0].labelNode.innerHTML);
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "open context menu",
+						timeout: 4000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("tree2");
+							var children = myTree.rootNode.getChildren();
+							
+							doh.robot.mouseMoveAt(children[1].expandoNode, 500, 1);
+							doh.robot.mouseClick({right: true}, 500);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var menu = dijit.byId("tree_menu");
+								doh.t(isVisible(menu.domNode), "Menu is not visible");
+								
+								menu = dijit.byId("submenu2");
+								doh.t(isHidden(menu.domNode), "Sub menu is not visible");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "open sub menu 1",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("popupSubMenu", 500, 1);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var menu = dijit.byId("tree_menu");
+								doh.t(isVisible(menu.domNode), "Menu is not visible");
+								menu = dijit.byId("submenu2");
+								doh.t(isVisible(menu.domNode), "Sub menu is not visible");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "open deeper sub menu",
+						timeout: 3000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							doh.robot.mouseMoveAt("deeperSubmenu", 500, 1);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								var menu = dijit.byId("tree_menu");
+								doh.t(isVisible(menu.domNode), "Menu is not visible");
+								menu = dijit.byId("submenu2");
+								doh.t(isVisible(menu.domNode), "Sub menu is not visible");
+								menu = dijit.byId("submenu4");
+								doh.t(isVisible(menu.domNode), "Deeper menu is not visible");
+							}), 1000);
+							return d;
+						}
+					},
+					{
+						name: "close tree nodes",
+						timeout: 9000,
+						runTest: function(){
+							var d = new doh.Deferred();
+							
+							var myTree = dijit.byId("tree2");
+							var children = myTree.rootNode.getChildren();
+							
+							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							doh.robot.keyPress(dojo.keys.ESCAPE, 1000, {}, true);
+							
+							doh.robot.mouseMoveAt(children[0].expandoNode, 1000, 1);
+							doh.robot.mouseClick({left: true}, 1000);
+
+							doh.robot.sequence(d.getTestCallback(function(){
+								doh.f(children[0].isExpanded, "failed to close first node");
+							}), 1000);
+							return d;
+						}
+					}					
+				]);
+				
+				doh.run();
+			});
+		</script>
+	</head>
+</html>
diff --git a/dijit/tests/tree/runTests.html b/dijit/tests/tree/runTests.html
new file mode 100644
index 0000000..5ecdbb1
--- /dev/null
+++ b/dijit/tests/tree/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=dijit.tests.tree.module"></HEAD>
+	<BODY>
+		Redirecting to D.O.H runner.
+	</BODY>
+</HTML>
diff --git a/dijit/tests/tree/test_CustomLabel.html b/dijit/tests/tree/test_CustomLabel.html
deleted file mode 100644
index 73e693c..0000000
--- a/dijit/tests/tree/test_CustomLabel.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-		"http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Dijit Tree Custom Label Test</title>
-
-	<style type="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-	</style>
-
-	<!-- required: a default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true, isDebug: true"></script>
-
-	<!-- not needed, for testing alternate themes -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script language="JavaScript" type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileReadStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
-	</script>
-</head>
-<body class="claro">
-
-	<h1 class="testTitle">Dijit Tree Custom Label Test</h1>
-
-	<div dojoType="dojo.data.ItemFileReadStore" jsId="store"
-		url="../_data/states.json"></div>
-
-	<h2>Standard label (state names)</h2>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="nameModel" store="store" rootLabel="States"></div>
-	<div dojoType="dijit.Tree" id="nameTree" model="nameModel" openOnClick="true"></div>
-
-	<h2>LabelAttr (state abbreviation)</h2>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="codeModel" store="store" rootLabel="States" labelAttr="abbreviation"></div>
-	<div dojoType="dijit.Tree" id="codeTree" model="codeModel" openOnClick="true"></div>
-
-	<h2>Custom label via callback</h2>
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="customModel" store="store">
-		<script type="dojo/method" event="getLabel" args="item">
-			if(item.root){ return "States"; }
-			return (store.getLabel(item) + " (" + store.getIdentity(item) + ")");
-		</script>
-	</div>
-	<div dojoType="dijit.Tree" id="customTree" model="customModel" openOnClick="true"></div>
-
-
-</body>
-</html>
diff --git a/dijit/tests/tree/test_Tree.html b/dijit/tests/tree/test_Tree.html
new file mode 100644
index 0000000..3d3efd6
--- /dev/null
+++ b/dijit/tests/tree/test_Tree.html
@@ -0,0 +1,170 @@
+<!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>
+
+	<!-- not needed, for testing alternate themes -->
+	<script type="text/javascript" src="../_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dojo.data.ItemFileReadStore");
+		dojo.require("dijit.dijit"); // optimize: load dijit layer
+		dojo.require("dijit.Tree");
+		dojo.require("dijit.tree.ForestStoreModel");
+		dojo.require("dijit.ColorPalette");
+		dojo.require("dijit.Menu");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+	</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:"../_data/countries.json"'></div>
+	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
+		rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
+
+	<h2>Tree with hardcoded root node (not corresponding to any item in the store)</h2>
+	<p>
+		Clicking a folder node will open/close it (openOnclick==true),
+		and clicking a leaf node will log a message to the console.
+	</p>
+	<div id="mytree" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, openOnClick:true, onLoad:function(){ console.log("loaded mytree (first tree)"); }'>
+		<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="item">
+			console.log("Execute of node " + continentStore.getLabel(item)
+				+", population=" + continentStore.getValue(item, "population"));
+		</script>
+		<script type="dojo/method" data-dojo-event="onOpen" data-dojo-args="item">
+			console.log("Open of node " + continentStore.getLabel(item)||"root");
+		</script>
+		<script type="dojo/method" data-dojo-event="onClose" data-dojo-args="item">
+			console.log("Close of node " + continentStore.getLabel(item)||"root");
+		</script>
+	</div>
+
+	<button onclick="dijit.byId('mytree').destroyRecursive();">destroy</button>
+
+	<h2>A rootless tree (no "continents" node) with context menus, and custom icons</h2>
+
+	<ul id="tree_menu" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+		<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Hello world"); }'>Enabled Item</li>
+		<li data-dojo-type="dijit.MenuItem" data-dojo-props='disabled:true'>Disabled Item</li>
+		<li data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCut",
+			onClick:function(){ console.log("not actually cutting anything, just a test!") }'>Cut</li>
+		<li data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconCopy",
+			onClick:function(){ console.log("not actually copying anything, just a test!") }'>Copy</li>
+		<li data-dojo-type="dijit.MenuItem" data-dojo-props='iconClass:"dijitEditorIcon dijitEditorIconPaste",
+			onClick:function(){ console.log("not actually pasting anything, just a test!") }'>Paste</li>
+		<li data-dojo-type="dijit.PopupMenuItem">
+			<span>Enabled Submenu</span>
+			<ul id="submenu2" data-dojo-type="dijit.Menu" >
+				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</li>
+				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</li>
+				<li data-dojo-type="dijit.PopupMenuItem">
+					<span>Deeper Submenu</span>
+					<ul id="submenu4" data-dojo-type="dijit.Menu" >
+						<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 1!") }'>Sub-sub-menu Item One</li>
+						<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Sub-submenu 2!") }'>Sub-sub-menu Item Two</li>
+					</ul>
+				</li>
+			</ul>
+		</li>
+		<li data-dojo-type="dijit.PopupMenuItem" data-dojo-props='disabled:true'>
+			<span>Disabled Submenu</span>
+			<ul id="submenu3" data-dojo-type="dijit.Menu" data-dojo-props='style:"display: none;"'>
+				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 1!") }'>Submenu Item One</li>
+				<li data-dojo-type="dijit.MenuItem" data-dojo-props='onClick:function(){ console.log("Submenu 2!") }'>Submenu Item Two</li>
+			</ul>
+		</li>
+	</ul>
+
+	<div id="tree2" data-dojo-type="dijit.Tree" data-dojo-props='model:continentModel, showRoot:false, openOnClick:true,onLoad:function(){ console.log("loaded tree2 (second tree)"); }'>
+
+		<script type="dojo/connect">
+			var menu = dijit.byId("tree_menu");
+			// when we right-click anywhere on the tree, make sure we open the menu
+			menu.bindDomNode(this.domNode);
+
+			dojo.connect(menu, "_openMyself", this, function(e){
+				// get a hold of, and log out, the tree node that was the source of this open event
+				var tn = dijit.getEnclosingWidget(e.target);
+				console.debug(tn);
+
+				// now inspect the data store item that backs the tree node:
+				console.debug(tn.item);
+
+				// contrived condition: if this tree node doesn't have any children, disable all of the menu items
+				dojo.forEach(menu.getChildren(), function(i){ i.set('disabled', !tn.item.children); });
+
+				// IMPLEMENT CUSTOM MENU BEHAVIOR HERE
+			});
+		</script>
+		<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>
+		<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="item">
+			console.log("Execute of node " + this.model.getLabel(item)
+				+", population=" + continentStore.getValue(item, "population"));
+		</script>
+</div>
+
+	<h2>Double click, expand on load, direct style setting, tooltip test</h2>
+	<p>
+		Double-Clicking a folder node will open/close it (openOnDblClick==true),
+		and clicking or Double Clicking a leaf node will log a message to the console.
+	</p>
+	<div id="mytree3" data-dojo-type="dijit.Tree" data-dojo-props='store:continentStore, query:{type:"continent"},
+		label:"Continents", openOnClick:false, openOnDblClick:true,
+		autoExpand:true, onLoad:function(){ console.log("loaded mytree3 (third tree)"); }'>
+		<script type="dojo/method" data-dojo-event="getLabelStyle" data-dojo-args="item,opened">
+			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>
+		<script type="dojo/method" data-dojo-event="getTooltip" data-dojo-args="item,opened">
+			return item && ("Tooltip for " + this.model.getLabel(item));
+		</script>
+		<script type="dojo/method" data-dojo-event="onDblClick" data-dojo-args="item">
+			console.log("Execute of node " + this.model.getLabel(item)
+				+", population=" + continentStore.getValue(item, "population"));
+		</script>
+	</div>
+
+
+</body>
+</html>
diff --git a/dijit/tests/tree/test_Tree_DnD.html b/dijit/tests/tree/test_Tree_DnD.html
index 3926f28..fa9b2fc 100644
--- a/dijit/tests/tree/test_Tree_DnD.html
+++ b/dijit/tests/tree/test_Tree_DnD.html
@@ -1,32 +1,42 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
 	<title>Dijit Tree Test</title>
 
-	<style someProperty="text/css">
-		@import "../../../dojo/resources/dojo.css";
+	<style type="text/css">
+		@import "../../themes/claro/document.css";
 		@import "../css/dijitTests.css";
 		@import "../../../dojo/resources/dnd.css";
 		@import "../../../dojo/tests/dnd/dndDefault.css";
+		
+		.dojoDndItemSelected,
+		.dojoDndItemAnchor{
+			background-color: #D8EDFF !important;
+		}
 	</style>
 
 	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: do NOT use in your code! -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
-	<script language="JavaScript" someProperty="text/javascript">
+	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojo.data.ItemFileWriteStore");
 		dojo.require("dijit.Tree");
 		dojo.require("dijit.tree.TreeStoreModel");
-		dojo.require("dijit.tree.dndSource");
+		
+		var testController = dojo._getVar("testController", "")=="selector"?"dijit.tree._dndSelector":"dijit.tree.dndSource";
+
+		dijit.Tree.prototype.dndController = testController;
+		
+		dojo.require(testController);
 		dojo.require("dijit.Menu");
 		dojo.require("dijit.form.Button");
 
@@ -86,15 +96,18 @@
 			return label + ' (' + num+ ')';
 		}
 
-		//on item tree , we only want to drop on containers, or the root node itself, not on items in the containers
-		function itemTreeCheckItemAcceptance(node,source) {
+		//on item tree , we want to drop on containers, the root node itself, or between items in the containers
+		function itemTreeCheckItemAcceptance(node,source,position) {
 			source.forInSelectedItems(function(item){
-				console.log("testing to drop item of type " + item.type[0] + " and data " + item.data);
+				console.log("testing to drop item of type " + item.type[0] + " and data " + item.data + ", position " + position);
 			});
 			var item = dijit.getEnclosingWidget(node).item;
 			if (item && (item.root || myStore.hasAttribute(item,"numberOfItems"))){
 				return true;
 			}
+			if (position != "over") {
+				return true;
+			}
 			return false;
 		}
 
@@ -123,14 +136,12 @@
 
 	<style>
 		.myFolder{
-			display: "block";
 			width: 16px;
 			height: 16px;
 			background: blue;
 		}
 
 		.myItem{
-			display: "block";
 			width: 16px;
 			height: 16px;
 			background: green;
@@ -142,23 +153,22 @@
 <body class="claro">
 	<h1 class="testTitle">Dijit Tree Test - Drag And Drop Support</h1>
 
-	<div dojoType="dojo.data.ItemFileWriteStore" jsId="myStore"
-		url="../_data/categories.json"></div>
+	<div data-dojo-id="myStore" data-dojo-type="dojo.data.ItemFileWriteStore" data-dojo-props='url:"../_data/categories.json"'></div>
 
-	<table width="100%" style="margin:5px solid gray" >
+	<table style="margin:5px solid gray;width:100%;" >
 
 	<tr style="width:100%">
 		<td style="width: 50%">
 			<h2>Custom</h2>
 			<p>Should add this category to the store.  The second parameter is the value for numberOfItems.</p>
 			<div class="container">
-				<input id="newCat" type="text" value="Pottedmeat" /><input id="numItems" type="text" value="0" size="3"/><div id="addButton" dojoType="dijit.form.Button">Add Category</div>
+				<input id="newCat" type="text" value="Pottedmeat" /><input id="numItems" type="text" value="0" size="3"/><div id="addButton" data-dojo-type="dijit.form.Button">Add Category</div>
 			</div>
 		</td>
 		<td>
 			<h2>Items: </h2>
 			<p>List of Items to be categorized<p>
-				<div dojoType="dojo.dnd.Source" jsId="c2" class="container" style="height: 100px; overflow: auto">
+				<div data-dojo-id="c2" data-dojo-type="dojo.dnd.Source" class="container" style="height:100px; overflow:auto;">
 				<div class="dojoDndItem" id="1001">Apple</div>
 				<div class="dojoDndItem" id="1002">Orange</div>
 				<div class="dojoDndItem" id="1003">Banana</div>
@@ -184,28 +194,26 @@
 				You can't drop items onto this tree, but you can reorder categories. The between threshold
 				is set to 5, so if you are near the top or bottom of a node the drop will be above or below it.
 			</p>
-			<div dojoType="dijit.tree.TreeStoreModel" jsId="catModel"
-				store="myStore" query="{id: '0'}"></div>
-			<div class="container" dojoType="dijit.Tree" id="collectionsTree" model="catModel"
-				getLabel="catTreeCustomLabel"  dndController="dijit.tree.dndSource" betweenThreshold="5"
-				checkAcceptance="dndAccept" checkItemAcceptance="collectionTreeCheckItemAcceptance" getIconClass="getIcon"
-				persist="false"></div>
+			<div data-dojo-id="catModel" data-dojo-type="dijit.tree.TreeStoreModel" data-dojo-props='store:myStore, query:{id: "0"}'></div>
+			<div id="collectionsTree" data-dojo-type="dijit.Tree" data-dojo-props='"class":"container", model:catModel,
+				getLabel:catTreeCustomLabel, betweenThreshold:5,
+				checkAcceptance:dndAccept, checkItemAcceptance:collectionTreeCheckItemAcceptance, getIconClass:getIcon,
+				persist:false'></div>
 		</td>
 		<td>
 			<h2>Collection</h2>
 			<p>
-				Drop items from above list onto this tree, but only on to categories; should fail to let you drop on other items.
-				Can also move items within this tree. The drag threshold is set to 8, so you have a few pixels
+				Drop items from above list onto this tree, only on to categories or between other items; should fail to let you drop on other items.
+				Can also move items within this tree. The drag threshold is set to 8, between threshold is set to 5, so you have a few pixels
 				of buffer before drag operations start.
 			</p>
-			<div dojoType="dijit.tree.TreeStoreModel" jsId="itemModel"
-				store="myStore" query="{id: '0'}" childrenAttrs="items, children"></div>
-			<div class="container" dojoType="dijit.Tree" id="itemTree"
-				model="itemModel"
-				dndController="dijit.tree.dndSource" checkAcceptance="dndAccept" checkItemAcceptance="itemTreeCheckItemAcceptance"
-				dragThreshold="8"
-				getIconClass="getIcon"
-				persist="false"></div>
+			<div data-dojo-id="itemModel" data-dojo-type="dijit.tree.TreeStoreModel" data-dojo-props='store:myStore, query:{id: "0"}, childrenAttrs:["items", "children"]'></div>
+			<div id="itemTree" data-dojo-type="dijit.Tree" data-dojo-props='"class":"container", model:itemModel,
+				checkAcceptance:dndAccept, checkItemAcceptance:itemTreeCheckItemAcceptance,
+				dragThreshold:8,
+				betweenThreshold:5,
+				getIconClass:getIcon,
+				persist:false'></div>
 		</td>
 	</tr>
 	</table>
diff --git a/dijit/tests/tree/test_Tree_Programmatic.html b/dijit/tests/tree/test_Tree_Programmatic.html
deleted file mode 100644
index 3f86815..0000000
--- a/dijit/tests/tree/test_Tree_Programmatic.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Dijit Tree Programmatic Test</title>
-
-	<style someProperty="text/css">
-		@import "../../../dojo/resources/dojo.css";
-		@import "../css/dijitTests.css";
-		@import "../../../dojo/resources/dnd.css";
-		@import "../../../dojo/tests/dnd/dndDefault.css";
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css">
-
-	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
-
-	<!-- only needed for alternate theme testing: -->
-	<script type="text/javascript" src="../_testCommon.js"></script>
-
-	<script language="JavaScript" someProperty="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dijit.Tree");
-		dojo.require("dijit.tree.ForestStoreModel");
-		dojo.require("dijit.tree.dndSource");
-
-		dojo.addOnLoad(function(){
- 			myStore = new dojo.data.ItemFileWriteStore({url:'../_data/countries.json'});
-			myModel = new dijit.tree.ForestStoreModel({
-				store: myStore,
-				query: {type:'continent'},
-				rootId: "earth",
-				rootLabel: "Earth",
-				childrenAttrs: ["children"]
-			});
-		});
-
-		function createTree(){
-			myTree = new dijit.Tree({
-				id: "myTree",
-				model: myModel,
-				dndController: "dijit.tree.dndSource"
-			});
-			dojo.byId("container").appendChild(myTree.domNode);
-			myTree.startup();
-			dojo.byId("create").disabled = true;
-			dojo.byId("destroy").disabled = false;
-		}
-
-		function destroyTree(){
-			myTree.destroy();
-			dojo.byId("create").disabled = false;
-			dojo.byId("destroy").disabled = true;
-		}
-	</script>
-</head>
-<body class="claro">
-        <h1 class="testTitle">Dijit Forest Store Programmatic Test</h1>
-        <button id="create" onclick="createTree();">Create Tree</button>
-        <button id="destroy" onclick="destroyTree();" disabled>Destroy Tree</button>
-        <div id="container"></div>
-</body>
-</html>
diff --git a/dijit/tests/tree/test_Tree_Styling.html b/dijit/tests/tree/test_Tree_Styling.html
deleted file mode 100644
index 2992b02..0000000
--- a/dijit/tests/tree/test_Tree_Styling.html
+++ /dev/null
@@ -1,113 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
-	<title>Styling The Tree to have Headers</title>
-
-	<style someProperty="text/css">
-		@import "../../../dojo/dojo/resources/dojo.css";
-		@import "../../../dojo/dijit/css/dijitTests.css";
-		@import "../../../dojo/dojo/resources/dnd.css";
-
-		.listTree {
-			width: 300px;
-		}
-
-		.dijitTreeExpandoOpened,
-		.dijitTreeExpandoClosed {
-			display: none;
-		}
-
-
-		.dijitTreeNode .dijitTreeRow {
-			padding-top: 4px;
-			padding-bottom: 2px;
-			border-bottom: 1px solid #bbb;
-		}
-
-		.dijitTreeExpandoLeaf {
-			display: none;
-		}
-
-		.dijitTreeIsLast,
-		.dijitTreeNode {
-			background: transparent;
-		}
-		.dojoDndItemAnchor,
-		.dojoDndItemSelected {
-			background:#CCCCFF none repeat scroll 0 0;
-			color:black;
-		}
-
-		.headerRow {
-			background-color: #eee;
-		}
-		.headerRow .dijitTreeLabel {
-			font-weight: bold;
-		}
-
-		.dijitExpandoText {
-			display: none;
-		}
-
-	</style>
-
-	<!-- required: the default dijit theme: -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/soria/soria.css">
-
-	<!-- required: dojo.js -->
-
-	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="parseOnLoad: true"></script>
-
-	<script type="text/javascript">
-		dojo.require("dijit.dijit"); // optimize: load dijit layer
-		dojo.require("dojo.data.ItemFileWriteStore");
-		dojo.require("dijit.tree.TreeStoreModel");
-		dojo.require("dijit.Tree");
-
-		function getRowClass(item, isExpanded) {
-			if (!item
-					|| !treeStore.isItem(item)
-					|| treeStore.getValue(item, "type") != "header") {
-				return null;
-			}
-			return "headerRow";
-		}
-
-	</script>
-
-</head>
-<body class="soria">
-
-	<div dojoType="dojo.data.ItemFileWriteStore" jsId="treeStore"
-		url="places.json"></div>
-
-	<div
-		dojoType="dijit.tree.TreeStoreModel"
-		jsId="treeModel"
-		store="treeStore"
-		query="{id:'root'}"
-		childrenAttrs="children"></div>
-
-	<h1 class="testTitle">Styling a Tree to appear like an expandable list</h1>
-	<p>
-		This example shows how to style the dijit.Tree widget to look like an expandable list.
-		To do this, you must specify the getRowClass function
-	</p>
-
-	<div
-		dojoType="dijit.Tree"
-		id="placeTree"
-		model="treeModel"
-		showRoot="false"
-
-		getRowClass="getRowClass"
-
-		class="listTree"
-		openOnClick="true"
-		persist="false"
-	></div>
-
-	</body>
-</html>
diff --git a/dijit/tests/tree/test_Tree_v1.html b/dijit/tests/tree/test_Tree_v1.html
index 1047ffc..c9178c2 100644
--- a/dijit/tests/tree/test_Tree_v1.html
+++ b/dijit/tests/tree/test_Tree_v1.html
@@ -2,24 +2,25 @@
 		"http://www.w3.org/TR/html4/strict.dtd">
 <html>
 <head>
-	<title>Dijit Tree Test</title>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Dijit Tree V1 API Test</title>
 
 	<style type="text/css">
-		@import "../../../dojo/resources/dojo.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">
+	<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js"
-		djConfig="isDebug: true, parseOnLoad: true"></script>
+		data-dojo-config="isDebug: true, parseOnLoad: true"></script>
 
 	<!-- only needed for alternate theme testing: -->
 	<script type="text/javascript" src="../_testCommon.js"></script>
 
-	<script language="JavaScript" type="text/javascript">
+	<script type="text/javascript">
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojo.data.ItemFileReadStore");
 		dojo.require("dijit.Tree");
@@ -30,20 +31,22 @@
 </head>
 <body class="claro">
 
-	<h1 class="testTitle">Dijit Tree Test</h1>
-
+	<h1 class="testTitle">Dijit Tree V1 API Test</h1>
+	<p>
+		This file is for testing the old Tree API's, where the store is specified directly
+		rather than specifying a model which connects to a store.
+	</p>
 	<div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
-		url="../../tests/_data/countries.json"></div>
+		url="../_data/countries.json"></div>
 
 	<h3>Tree with hardcoded root node (not corresponding to any item in the store)</h3>
-	<p>Clicking a folder node will open/close it (openOnclick==true), and clicking a leaf node will popup an alert.</p>
+	<p>Clicking a folder node will open/close it (openOnclick==true), and clicking a leaf node will change the display name of the leaf node.</p>
 	<div dojoType="dijit.Tree" id="mytree" store="continentStore" query="{type:'continent'}"
 		onfocus="console.log('user focus handler')"
 		onblur="console.log('user blur handler')"
-		label="Continents" openOnClick="true">
-		<script type="dojo/method" event="onClick" args="item">
-			alert("Execute of node " + continentStore.getLabel(item)
-				+", population=" + continentStore.getValue(item, "population"));
+		label="Continents" openOnClick="true" persist="false">
+		<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="item">
+			this.getNodesByItem(item)[0].labelNode.innerHTML=item.name[0] + " was clicked";
 		</script>
 	</div>
 
@@ -60,12 +63,12 @@
 			onClick="alert('not actually copying anything, just a test!')">Copy</li>
 		<li dojoType="dijit.MenuItem" iconClass="dijitEditorIcon dijitEditorIconPaste"
 			onClick="alert('not actually pasting anything, just a test!')">Paste</li>
-		<li dojoType="dijit.PopupMenuItem">
+		<li id="popupSubMenu" dojoType="dijit.PopupMenuItem">
 			<span>Enabled Submenu</span>
 			<ul dojoType="dijit.Menu" id="submenu2">
 				<li dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</li>
 				<li dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</li>
-				<li dojoType="dijit.PopupMenuItem">
+				<li id="deeperSubmenu" dojoType="dijit.PopupMenuItem">
 					<span>Deeper Submenu</span>
 					<ul dojoType="dijit.Menu" id="submenu4">
 						<li dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 1!')">Sub-sub-menu Item One</li>
@@ -83,7 +86,7 @@
 		</li>
 	</ul>
 
-	<div dojoType="dijit.Tree" id="tree2" store="continentStore" query="{type:'continent'}">
+	<div dojoType="dijit.Tree" id="tree2" store="continentStore" query="{type:'continent'}" persist="false">
 		<script type="dojo/connect">
 			var menu = dijit.byId("tree_menu");
 			// when we right-click anywhere on the tree, make sure we open the menu
@@ -108,9 +111,9 @@
                    (opened ? "customFolderOpenedIcon" : "customFolderClosedIcon") :
                     "noteIcon";
 		</script>
-		<script type="dojo/method" event="onClick" args="item">
-			alert("Execute of node " + continentStore.getLabel(item)
-				+", population=" + continentStore.getValue(item, "population"));
+		<script type="dojo/method" data-dojo-event="onClick" data-dojo-args="item">
+			this.getNodesByItem(item)[0].labelNode.innerHTML = item.name[0] 
+				+ " (population: " + continentStore.getValue(item, "population") +")";
 		</script>
 </div>
 
diff --git a/dijit/themes/a11y/colors3x4-rtl.png b/dijit/themes/a11y/colors3x4-rtl.png
deleted file mode 100644
index 51a7d11..0000000
Binary files a/dijit/themes/a11y/colors3x4-rtl.png and /dev/null differ
diff --git a/dijit/themes/a11y/colors7x10-rtl.png b/dijit/themes/a11y/colors7x10-rtl.png
deleted file mode 100644
index c191e90..0000000
Binary files a/dijit/themes/a11y/colors7x10-rtl.png and /dev/null differ
diff --git a/dijit/themes/claro/Calendar.css b/dijit/themes/claro/Calendar.css
index 0cd4b4c..ff8e64f 100644
--- a/dijit/themes/claro/Calendar.css
+++ b/dijit/themes/claro/Calendar.css
@@ -13,7 +13,7 @@
  *      .dijitCalendarArrowActive .dijitCalendarDecrease - states e.g. hover,active
  * 
  * 3. Date
- * 		.dijitCalendarDayLabelTemplate - week day column header e.g. S M T w T F S
+ * 		.dijitCalendarDayLabelTemplate - week day column header e.g. S M T W T F S
  * 		.dijitCalendarDateTemplate - date label wrapper
  * 		.dijitCalendarPreviousMonth .dijitCalendarDateLabel - special labels for previous or next month
  *      .dijitCalendarSelectedDate .dijitCalendarDateLabel - styles for selected date
@@ -27,231 +27,256 @@
  *      .dijitCalendarNextYearHover / .dijitCalendarPreviousYearHover - states e.g. hover,active
  *      
  * 5. Dropdown Month Menu
- * 		.dijitCalendarMonthContainer .dijitMenu - menu container     
- * 		.dijitCalendarMonthContainer .dijitMenu .dijitCalendarMonthLabel - month label in menu item
- * 		.dijitCalendarMonthContainer .dijitMenu .dijitMenuItemHover - menu item hover state
+ * 		.dijitCalendarMonthMenu - menu container     
+ * 		.dijitCalendarMonthMenu .dijitCalendarMonthLabel - month label in menu item
+ * 		.dijitCalendarMonthMenu .dijitCalendarMonthLabelHover - menu item hover state
  */
-
 .claro .dijitCalendar {
-	border:solid 1px #b5bcc7;
-	background-color:#d4ebff;
-	background-image:url("images/calendarContainerImages.png");
-	background-position:0px -448px;
-	background-repeat:repeat-x;
-	text-align:center;
-	padding:6px 5px 3px 5px;
-	-moz-border-radius:4px;
-	-webkit-border-radius:4px;	
+  border: solid 1px #b5bcc7;
+  background-color: #cfe5fa;
+  background-image: url("images/calendarContainerImages.png");
+  background-position: 0 -448px;
+  background-repeat: repeat-x;
+  text-align: center;
+  padding: 6px 5px 3px 5px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
 }
 .dj_ie6 .claro .dijitCalendar {
-	background-image:none;
+  background-image: none;
 }
 .claro .dijitCalendar img {
-	border:none;
+  border: none;
 }
-.claro .dijitCalendarHover,
-.claro .dijitCalendarActive {
-	background-color: #b7dcff;
-	border:solid 1px #769dc0;
+.claro .dijitCalendarHover, .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;
 }
 .claro .dijitCalendarMonthContainer th {
-	text-align:center;
-	padding-bottom:4px;
-	vertical-align:middle;
-}
-.claro .dijitCalendarMonthLabelSpacer {
-	display:none;
+  text-align: center;
+  padding-bottom: 4px;
+  vertical-align: middle;
 }
 .claro .dijitCalendarMonthLabel {
-	color:#000000;
-	font-size: 1.091em;
-	display: block;
+  color: #000000;
+  font-size: 1.091em;
+  padding: 0 4px;
 }
-
 /* next/previous month arrows */
 .claro .dijitCalendarIncrementControl {
-	width:18px;
-	height:16px;
-	background-image: url("images/calendarArrows.png");
-	background-repeat: no-repeat;
+  width: 18px;
+  height: 16px;
+  background-image: url("images/calendarArrows.png");
+  background-repeat: no-repeat;
 }
 .dj_ie6 .claro .dijitCalendarIncrementControl {
-	background-image: url("images/calendarArrows8bit.png");
+  background-image: url("images/calendarArrows8bit.png");
 }
 .claro .dijitCalendarIncrease {
-	background-position:-18px 0px;
+  background-position: -18px 0;
 }
 .claro .dijitCalendarArrowHover .dijitCalendarDecrease {
-	background-position:-36px 0px;
+  background-position: -36px 0;
 }
 .claro .dijitCalendarArrowHover .dijitCalendarIncrease {
-	background-position:-55px 0px;
+  background-position: -55px 0;
 }
 .claro .dijitCalendarArrowActive .dijitCalendarDecrease {
-	background-position:-72px 0px;
+  background-position: -72px 0;
 }
 .claro .dijitCalendarArrowActive .dijitCalendarIncrease {
-	background-position:-91px 0px;
+  background-position: -91px 0;
 }
 .claro .dijitA11ySideArrow {
-	/* text +/- labels instead of arrow icons, for high contrast mode */
-	display: none;
-}
-
+  /* text +/- labels instead of arrow icons, for high contrast mode */
 
+  display: none;
+}
 .claro .dijitDayLabels th {
-	padding:0px 4px 0px 4px;
-	border-bottom:solid 1px #99b5cd;
-	font-weight:bold;
-	text-align:center;
+  padding: 0 4px 0 4px;
+  font-weight: bold;
+  text-align: center;
 }
 .claro .dijitCalendarDayLabelTemplate {
-	padding-bottom:0em;
-	text-align:center;
-	border-bottom:1px solid #99B5CD;
-	font-size:0.909em;
-	padding:0 3px 2px;
+  padding-bottom: 0;
+  text-align: center;
+  border-bottom: 1px solid #b5bcc7;
+  font-size: 0.909em;
+  padding: 0 3px 2px;
 }
 .claro .dijitCalendarDateTemplate {
-	text-align:center;
-	background-color:#fff;
-	background-image:url("images/calendarContainerImages.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
-	border-bottom: 1px solid #dadde1;
-	padding-top:0px;
-	font-size:0.909em;
-	font-family: Arial;
-	font-weight:bold;
-	letter-spacing:.05em;
-	text-align:center;
+  text-align: center;
+  background-color: #ffffff;
+  background-image: url("images/calendarContainerImages.png");
+  background-position: 0 0;
+  background-repeat: repeat-x;
+  border-bottom: 1px solid #d3d3d3;
+  padding-top: 0;
+  font-size: 0.909em;
+  font-family: Arial;
+  font-weight: bold;
+  letter-spacing: .05em;
+  text-align: center;
 }
 .dj_ie6 .claro .dijitCalendarDateTemplate {
-	background-image: none;
+  background-image: none;
 }
-.claro .dijitCalendarPreviousMonth,
-.claro .dijitCalendarNextMonth {
-	background-color:#ebf3f9;
-	background-image:none;
-	border-bottom:solid 1px #d2dae8;
-	color:#547da1;
+.claro .dijitCalendarPreviousMonth, .claro .dijitCalendarNextMonth {
+  background-color: #e9f4fe;
+  background-image: none;
+  border-bottom: solid 1px #d3d3d3;
+  /* todo: redundant with above .dijitCalendarDateTemplate rule */
 }
 .claro .dijitCalendarDateTemplate .dijitCalendarDateLabel {
-	text-decoration:none;
-	display:block;
-	padding:3px 5px 3px 4px;
-	border:solid 1px #fff;
-	color:#1e1e1e;
-	background-color:rgba(171,212,251,0);	/* transparent causes black-flash animation problem on webkit */
-	-webkit-transition-property:background-color, border;
- 	-webkit-transition-duration:.35s;
-}
-.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel,
-.claro .dijitCalendarNextMonth .dijitCalendarDateLabel{
-	color:#547da1;
-	border-color:#ebf3f9;
-}
+  text-decoration: none;
+  display: block;
+  padding: 3px 5px 3px 4px;
+  border: solid 1px #ffffff;
+  /* intentionally matches background-color, no visible border until hover/selection */
+
+  background-color: rgba(171, 212, 251, 0);
+  /* transparent causes black-flash animation problem on webkit */
+
+  -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;
+}
+.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel, .claro .dijitCalendarNextMonth .dijitCalendarDateLabel {
+  color: #769dc0;
+  border-color: #e9f4fe;
+  /* intentionally matches background-color, no visible border until hover/selection */
 
+}
 .claro .dijitCalendarYearContainer {
-	vertical-align:middle;
+  vertical-align: middle;
 }
 .claro .dijitCalendarYearControl {
-	padding: 1px 2px 2px 2px;
+  padding: 1px 2px 2px 2px;
 }
 .claro .dijitCalendarYearLabel {
-	padding:2px 0px 0px 0px;
-	margin:0;
+  padding: 2px 0 0 0;
+  margin: 0;
 }
 .claro .dijitCalendarYearLabel span {
-	/* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
-	vertical-align:middle;
+  /* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
+
+  vertical-align: middle;
 }
 .claro .dijitCalendarSelectedYear {
-	padding:0px 3px;
+  padding: 0 3px;
 }
-.claro .dijitCalendarNextYear,
-.claro .dijitCalendarPreviousYear {
-	padding: 1px 6px 1px 6px;
-	font-size:0.909em;
+.claro .dijitCalendarNextYear, .claro .dijitCalendarPreviousYear {
+  padding: 1px 6px 1px 6px;
+  font-size: 0.909em;
 }
 .claro .dijitCalendarSelectedYear {
-	font-size:1.091em;
-	color:#000;
+  font-size: 1.091em;
+  color: #000000;
 }
 /* End Normal Calendar Style */
 /* Hovered Calendar Style */
-.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel{
-	background-color:#abd4fb;
-	border:solid 1px #729dc2;
-	color:#000;
-	-webkit-transition-duration:.2s;
-}
-.claro .dijitCalendarNextYearHover,
-.claro .dijitCalendarPreviousYearHover {
-	color:#000;
-	border:solid 1px #fefefe;
-	padding: 0px 5px 0px 5px;	/* reduced by 1 to make room for border */
-	background-color:#eaf4fe;
+.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel {
+  background-color: #abd6ff;
+  border: solid 1px #769dc0;
+  color: #000000;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dijitCalendarNextYearHover, .claro .dijitCalendarPreviousYearHover {
+  color: #000000;
+  border: solid 1px #ffffff;
+  padding: 0 5px 0 5px;
+  /* reduced by 1 to make room for border */
+
+  background-color: #e9f4fe;
 }
 /* End Hovered Calendar Style */
 /* Active Calendar Style */
-.claro .dijitCalendarNextYearActive,
-.claro .dijitCalendarPreviousYearActive {
-	border: solid 1px #87b3d9;
-	padding: 0px 5px 0px 5px;	/* reduced by 1 to make room for border */
-	background-color:#90bde6;
+.claro .dijitCalendarNextYearActive, .claro .dijitCalendarPreviousYearActive {
+  border: solid 1px #769dc0;
+  padding: 0 5px 0 5px;
+  /* reduced by 1 to make room for border */
+
+  background-color: #cfe5fa;
 }
 .claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
-	background-image:url("images/calendarContainerImages.png");
-	background-position:0px -300px;
-	background-color:#75b5f0;
-	border:solid 1px #fff;
-	-webkit-transition-duration:.1s;
+  background-image: url("images/calendarContainerImages.png");
+  background-position: 0 -300px;
+  background-color: #7dbefa;
+  border: solid 1px #ffffff;
+  -webkit-transition-duration: 0.1s;
+  -moz-transition-duration: 0.1s;
+  transition-duration: 0.1s;
 }
 .dj_ie6 .claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
-	background-image:none;
+  background-image: none;
 }
 /* End Active Calendar Style */
 /* Selected Calendar Style */
 .claro .dijitCalendarSelectedDate .dijitCalendarDateLabel {
-	color:#000;
-	background-color:#e7f4ff;
-	border-color:#accfed;
+  color: #000000;
+  background-color: #abd6ff;
+  border-color: #769dc0;
 }
 /* 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: 0px;
-	padding: 4px 6px 4px 5px;
-	color: #547DA1;
-}
+  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;
+}
 /* End Disabled Calendar Style */
-
+/* Styling for month DropDownButton */
+.claro .dijitCalendar .dijitDropDownButton {
+  margin: 0;
+}
+.claro .dijitCalendar .dijitButtonText {
+  padding: 1px 0 3px;
+  margin-right: -4px;
+}
+.claro .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+  background-color: transparent;
+  background-image: none;
+  padding: 0 3px 0 2px;
+  border: solid 1px #b5bcc7;
+  -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+}
+.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode {
+  background-color: #e9f4fe;
+  border: solid 1px #ffffff;
+}
 /* Styling for month drop down list */
+.claro .dijitCalendarMonthMenu {
+  border-color: #769dc0;
+  background-color: #ffffff;
+  text-align: center;
+  background-image: none;
+}
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+  border-top: solid 1px #ffffff;
+  /* intentionally invisible until hover */
 
-.claro .dijitCalendarMonthContainer .dijitMenu{
-	/* top: 20px !important modifying date drop down so it appears below, instead of over, the current date */
-	top: 20px !important;
-	left: 0px;
-	border-color: #769dc0;
-	background-color: #fff;
-	text-align:center;
-	background-image: none;
-}
-.claro .dijitCalendarMonthContainer .dijitMenu .dijitCalendarMonthLabel{
-	border-top: solid 1px #fff;
-	border-bottom: solid 1px #fff;
-	padding: 2px 20px;
-}
-.claro .dijitCalendarMonthContainer .dijitMenu .dijitMenuItemHover {
-	background-color: #abd6ff;
-	border-color: #769dc0;
-	border-width:1px 0px;
-	background-image: url("images/commonHighlight.png");
-	background-repeat:repeat-x;
-}
\ No newline at end of file
+  border-bottom: solid 1px #ffffff;
+  padding: 2px 0;
+}
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+  background-color: #abd6ff;
+  border-color: #769dc0;
+  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
new file mode 100644
index 0000000..ec6aa46
--- /dev/null
+++ b/dijit/themes/claro/Calendar.less
@@ -0,0 +1,273 @@
+/* Calendar
+ * 
+ * Styling Calendar mainly includes:
+ * 
+ * 1. Calendar container
+ * 		.dijitCalendar - main container
+ * 		.dijitCalendarHover / .dijitCalendarActive - states e.g. hover,active
+ * 
+ * 2. Month
+ * 		.dijitCalendarMonthContainer
+ * 		.dijitCalendarMonthLabel
+ *      .dijitCalendarDecrease / .dijitCalendarDecrease - icons for switching to previous/next month
+ *      .dijitCalendarArrowActive .dijitCalendarDecrease - states e.g. hover,active
+ * 
+ * 3. Date
+ * 		.dijitCalendarDayLabelTemplate - week day column header e.g. S M T W T F S
+ * 		.dijitCalendarDateTemplate - date label wrapper
+ * 		.dijitCalendarPreviousMonth .dijitCalendarDateLabel - special labels for previous or next month
+ *      .dijitCalendarSelectedDate .dijitCalendarDateLabel - styles for selected date
+ * 		.dijitCalendarDisabledDate .dijitCalendarDateLabel - styles for disabled date
+ * 		.dijitCalendarActiveDate .dijitCalendarDateLabel - states e.g. hover,active
+ * 
+ * 4. Year
+ * 		.dijitCalendarYearContainer
+ * 		.dijitCalendarYearLabel
+ * 		.dijitCalendarPreviousYear /.dijitCalendarNextYear
+ *      .dijitCalendarNextYearHover / .dijitCalendarPreviousYearHover - states e.g. hover,active
+ *      
+ * 5. Dropdown Month Menu
+ * 		.dijitCalendarMonthMenu - menu container     
+ * 		.dijitCalendarMonthMenu .dijitCalendarMonthLabel - month label in menu item
+ * 		.dijitCalendarMonthMenu .dijitCalendarMonthLabelHover - menu item hover state
+ */
+
+ at import "variables";
+
+.claro .dijitCalendar {
+	border:solid 1px @border-color;
+	background-color: @calendar-background-color;
+	background-image:url("images/calendarContainerImages.png");
+	background-position:0 -448px;
+	background-repeat:repeat-x;
+	text-align:center;
+	padding:6px 5px 3px 5px;
+	.border-radius(4px);
+}
+.dj_ie6 .claro .dijitCalendar {
+	background-image:none;
+}
+.claro .dijitCalendar img {
+	border:none;
+}
+.claro .dijitCalendarHover,
+.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: @hovered-background-color;
+	border:solid 1px @hovered-border-color;
+}
+.claro .dijitCalendarMonthContainer th {
+	text-align:center;
+	padding-bottom:4px;
+	vertical-align:middle;
+}
+.claro .dijitCalendarMonthLabel {
+	color: @text-color;
+	font-size: 1.091em;
+	padding: 0 4px;
+}
+
+/* next/previous month arrows */
+.claro .dijitCalendarIncrementControl {
+	width:18px;
+	height:16px;
+	background-image: url("images/calendarArrows.png");
+	background-repeat: no-repeat;
+}
+.dj_ie6 .claro .dijitCalendarIncrementControl {
+	background-image: url("images/calendarArrows8bit.png");
+}
+.claro .dijitCalendarIncrease {
+	background-position:-18px 0;
+}
+.claro .dijitCalendarArrowHover .dijitCalendarDecrease {
+	background-position:-36px 0;
+}
+.claro .dijitCalendarArrowHover .dijitCalendarIncrease {
+	background-position:-55px 0;
+}
+.claro .dijitCalendarArrowActive .dijitCalendarDecrease {
+	background-position:-72px 0;
+}
+.claro .dijitCalendarArrowActive .dijitCalendarIncrease {
+	background-position:-91px 0;
+}
+.claro .dijitA11ySideArrow {
+	/* text +/- labels instead of arrow icons, for high contrast mode */
+	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 .dijitCalendarDateTemplate {
+	text-align:center;
+	background-color:@calendar-currentmonth-background-color;
+	background-image:url("images/calendarContainerImages.png");
+	background-position:0 0;
+	background-repeat:repeat-x;
+	border-bottom: 1px solid @minor-border-color;
+	padding-top:0;
+	font-size:0.909em;
+	font-family: Arial;
+	font-weight:bold;
+	letter-spacing:.05em;
+	text-align:center;
+}
+.dj_ie6 .claro .dijitCalendarDateTemplate {
+	background-image: none;
+}
+.claro .dijitCalendarPreviousMonth,
+.claro .dijitCalendarNextMonth {
+	background-color: @calendar-adjacentmonth-background-color;
+	background-image:none;
+	border-bottom:solid 1px @minor-border-color;	/* todo: redundant with above .dijitCalendarDateTemplate rule */	
+}
+.claro .dijitCalendarDateTemplate .dijitCalendarDateLabel {
+	text-decoration:none;
+	display:block;
+	padding:3px 5px 3px 4px;
+	border:solid 1px @calendar-currentmonth-background-color;	/* intentionally matches background-color, no visible border until hover/selection */
+	background-color:rgba(171,212,251,0);	/* transparent causes black-flash animation problem on webkit */
+	.transition-property(background-color, border);
+ 	.transition-duration(.35s);
+}
+.claro .dijitCalendarPreviousMonth .dijitCalendarDateLabel,
+.claro .dijitCalendarNextMonth .dijitCalendarDateLabel{
+	color: @calendar-adjacentmonth-text-color;
+	border-color: @calendar-adjacentmonth-background-color;	/* intentionally matches background-color, no visible border until hover/selection */
+}
+
+.claro .dijitCalendarYearContainer {
+	vertical-align:middle;
+}
+.claro .dijitCalendarYearControl {
+	padding: 1px 2px 2px 2px;
+}
+.claro .dijitCalendarYearLabel {
+	padding:2px 0 0 0;
+	margin:0;
+}
+.claro .dijitCalendarYearLabel span {
+	/* trying to center next/current/previous year vertically, doesn't work on IE6/7 though */
+	vertical-align:middle;
+}
+.claro .dijitCalendarSelectedYear {
+	padding:0 3px;
+}
+.claro .dijitCalendarNextYear,
+.claro .dijitCalendarPreviousYear {
+	padding: 1px 6px 1px 6px;
+	font-size:0.909em;
+}
+.claro .dijitCalendarSelectedYear {
+	font-size:1.091em;
+	color:@selected-text-color;
+}
+/* End Normal Calendar Style */
+/* Hovered Calendar Style */
+.claro .dijitCalendarHoveredDate .dijitCalendarDateLabel{
+	background-color:@hovered-background-color;
+	border:solid 1px @hovered-border-color;
+	color:@hovered-text-color;
+	.transition-duration(.2s);
+}
+.claro .dijitCalendarNextYearHover,
+.claro .dijitCalendarPreviousYearHover {
+	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 */
+	background-color: @calendar-button-hovered-background-color;
+}
+/* End Hovered Calendar Style */
+/* Active Calendar Style */
+.claro .dijitCalendarNextYearActive,
+.claro .dijitCalendarPreviousYearActive {
+	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");
+	background-position:0 -300px;
+	background-color: @calendar-date-pressed-background-color;
+	border:solid 1px @calendar-date-pressed-border-color;
+	.transition-duration(.1s);
+}
+.dj_ie6 .claro .dijitCalendarActiveDate .dijitCalendarDateLabel {
+	background-image:none;
+}
+/* End Active Calendar Style */
+/* Selected Calendar Style */
+.claro .dijitCalendarSelectedDate .dijitCalendarDateLabel {
+	color:@selected-text-color;
+	background-color: @calendar-date-selected-background-color;
+	border-color: @calendar-date-selected-border-color;
+}
+/* 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;
+}
+
+/* End Disabled Calendar Style */
+
+/* Styling for month DropDownButton */
+
+.claro .dijitCalendar .dijitDropDownButton {
+	margin: 0;
+}
+.claro .dijitCalendar .dijitButtonText {
+	padding: 1px 0 3px;
+	margin-right:-4px;
+}
+.claro .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+	background-color: transparent;
+	background-image: none;
+	padding: 0 3px 0 2px;
+	border:solid 1px @border-color;
+	.box-shadow(0 0 0 rgba(0,0,0,0));
+}
+.claro .dijitCalendar .dijitDropDownButtonHover .dijitButtonNode {
+	background-color: @calendar-button-hovered-background-color;
+	border:solid 1px @calendar-button-hovered-border-color;
+}
+
+/* Styling for month drop down list */
+
+.claro .dijitCalendarMonthMenu {
+	border-color: @popup-border-color;
+	background-color: @menu-background-color;
+	text-align:center;
+	background-image: none;
+}
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+	border-top: solid 1px @menu-background-color;		/* intentionally invisible until hover */
+	border-bottom: solid 1px @menu-background-color;
+	padding: 2px 0;
+}
+.claro .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+	background-color: @hovered-background-color;
+	border-color: @hovered-border-color;
+	border-width:1px 0;
+	background-image: url("images/commonHighlight.png");
+	background-repeat:repeat-x;
+}
diff --git a/dijit/themes/claro/Calendar_rtl.css b/dijit/themes/claro/Calendar_rtl.css
index 424844b..5892a64 100644
--- a/dijit/themes/claro/Calendar_rtl.css
+++ b/dijit/themes/claro/Calendar_rtl.css
@@ -1,19 +1,18 @@
-.claro .dijitCalendarRtl .dijitCalendarIncrease{
-	background-position: 0px 0px;
+.claro .dijitCalendarRtl .dijitCalendarIncrease {
+  background-position: 0 0;
 }
 .claro .dijitCalendarRtl .dijitCalendarDecrease {
-	background-position: -18px 0px;
+  background-position: -18px 0;
 }
 .claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarIncrease {
-	background-position: -36px 0px;
+  background-position: -36px 0;
 }
 .claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarDecrease {
-	background-position: -55px 0px;
+  background-position: -55px 0;
 }
 .claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarIncrease {
-	background-position: -72px 0px;
+  background-position: -72px 0;
 }
 .claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarDecrease {
-	background-position: -91px 0px;
+  background-position: -91px 0;
 }
-
diff --git a/dijit/themes/claro/Calendar_rtl.less b/dijit/themes/claro/Calendar_rtl.less
new file mode 100644
index 0000000..713717b
--- /dev/null
+++ b/dijit/themes/claro/Calendar_rtl.less
@@ -0,0 +1,19 @@
+.claro .dijitCalendarRtl .dijitCalendarIncrease{
+	background-position: 0 0;
+}
+.claro .dijitCalendarRtl .dijitCalendarDecrease {
+	background-position: -18px 0;
+}
+.claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarIncrease {
+	background-position: -36px 0;
+}
+.claro .dijitCalendarRtl .dijitCalendarArrowHover .dijitCalendarDecrease {
+	background-position: -55px 0;
+}
+.claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarIncrease {
+	background-position: -72px 0;
+}
+.claro .dijitCalendarRtl .dijitCalendarArrowActive .dijitCalendarDecrease {
+	background-position: -91px 0;
+}
+
diff --git a/dijit/themes/claro/ColorPalette.css b/dijit/themes/claro/ColorPalette.css
index 938ceb1..34d1c72 100644
--- a/dijit/themes/claro/ColorPalette.css
+++ b/dijit/themes/claro/ColorPalette.css
@@ -20,25 +20,22 @@
  *		.dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
  *		adds border for active or selected state
  */
-
 .claro  .dijitColorPalette {
-	outline: 1px solid #769dc0; 
-	border: 1px solid #c0ccdf;
-	background:#fff;
-
-	-moz-border-radius: 0px;
+  border: 1px solid #b5bcc7;
+  background: #ffffff;
+  -moz-border-radius: 0;
+  border-radius: 0;
 }
-
 .claro .dijitColorPalette .dijitPaletteImg {
-	/* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
+  /* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
 	 * displays border around a color swatch
 	 * overrides border color in dijit.css */
-	border: 1px solid #cecece;
+
+  border: 1px solid #d3d3d3;
 }
 .claro .dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
-	border: 1px solid #000;
+  border: 1px solid #000000;
 }
-.claro .dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg,
-.claro .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
-	border: 2px solid #000;
+.claro .dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg, .claro .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
+  border: 2px solid #000000;
 }
diff --git a/dijit/themes/claro/ColorPalette.less b/dijit/themes/claro/ColorPalette.less
new file mode 100644
index 0000000..e032733
--- /dev/null
+++ b/dijit/themes/claro/ColorPalette.less
@@ -0,0 +1,44 @@
+/* ColorPalette
+ * 
+ * Styling of the ColorPalette consists of the following:
+ * 
+ * 1. the whole color palette
+ *		.dijitColorPalette - for outline, border, and background color of the whole color palette
+ *		Note: outline does not work for IE
+ *
+ * 2. the color swatch 
+ *		.dijitColorPalette .dijitPaletteImg
+ *		transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
+ *		displays border around a color swatch
+ *
+ * 3. hovered swatch
+ * 		.dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg
+ *		the hovered state of the color swatch - adds border
+ * 	
+ * 4. active and selected swatch
+ * 		.dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg
+ *		.dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg
+ *		adds border for active or selected state
+ */
+
+ at import "variables";
+
+.claro  .dijitColorPalette {
+	border: 1px solid @border-color;
+	background: @colorpalette-background-color;
+	.border-radius(0);
+}
+
+.claro .dijitColorPalette .dijitPaletteImg {
+	/* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
+	 * displays border around a color swatch
+	 * overrides border color in dijit.css */
+	border: 1px solid @minor-border-color;
+}
+.claro .dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
+	border: 1px solid @swatch-hovered-border-color;
+}
+.claro .dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg,
+.claro .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
+	border: 2px solid @swatch-selected-border-color;
+}
diff --git a/dijit/themes/claro/Common.css b/dijit/themes/claro/Common.css
index e2f21be..110b303 100644
--- a/dijit/themes/claro/Common.css
+++ b/dijit/themes/claro/Common.css
@@ -1,79 +1,75 @@
 /* ========= Styling rules to affect widgets ========= */
-
 .claro .dijitPopup {
-	box-shadow: 0px 1px 5px rgba(0,0,0,0.25);
-	-webkit-box-shadow: 0px 1px 5px rgba(0,0,0,0.25);
-	-moz-box-shadow: 0px 1px 5px rgba(0,0,0,0.25);
+  -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 .dijitTooltipDialogPopup {
-	/* exception popups: do not use a shadow on these because they aren't rectangular */
-	box-shadow: none;
-	-webkit-box-shadow: none;
-	-moz-box-shadow: none;
-}
+  /* exception popups: do not use a shadow on these because they aren't rectangular */
 
-/* The highlight is shown in the ComboBox menu. */
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+}
+/* The highlight is shown in the ComboBox menu.  TODO: move to form/Common.less */
 .claro .dijitComboBoxHighlightMatch {
-	background-color:#a5beda;
+  background-color: #abd6ff;
 }
-
 .claro .dijitFocusedLabel {
-	/* for checkboxes or radio buttons, hatch border around the corresponding label, to indicate focus */
-	outline: 1px dotted #666666;
-}
+  /* 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;
+  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; 
-	no-repeat left center;
-	padding-left:25px;
+  background: url('../../icons/images/commonIconsObjActEnabled.png') no-repeat left center;
+  background-position: -496px;
+  padding-left: 25px;
 }
-
 /* Drag and Drop */
-.claro .dojoDndItemBefore,
-.claro .dojoDndItemAfter{
-	border-top: 1px solid #769DC0;
+.claro .dojoDndItemBefore, .claro .dojoDndItemAfter {
+  border-top: 1px solid #769dc0;
 }
 .claro .dojoDndItemOver {
-	cursor:pointer;
-	}
+  cursor: pointer;
+}
 .claro table.dojoDndAvatar {
-	border: 1px solid #b5bcc7;
-	border-collapse: collapse;
-	background-color: #fff;
-	-webkit-box-shadow:0px 1px 3px rgba(0, 0, 0, .25);
+  border: 1px solid #b5bcc7;
+  border-collapse: collapse;
+  background-color: #ffffff;
+  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
+  -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
 }
-.claro .dojoDndAvatarHeader td	{ 
-	height: 20px;
-	padding-left:21px;
+.claro .dojoDndAvatarHeader td {
+  height: 20px;
+  padding-left: 21px;
 }
 .claro.dojoDndMove .dojoDndAvatarHeader, .claro.dojoDndCopy .dojoDndAvatarHeader {
-	background-image: url(images/dnd.png);
-	background-repeat: no-repeat;
-	background-position:2px -122px;
+  background-image: url(images/dnd.png);
+  background-repeat: no-repeat;
+  background-position: 2px -122px;
 }
 .claro .dojoDndAvatarItem td {
-	padding: 5px;
+  padding: 5px;
 }
-.claro.dojoDndMove .dojoDndAvatarHeader	{
-	background-color: #f58383; 
-	background-position:2px -103px;
+.claro.dojoDndMove .dojoDndAvatarHeader {
+  background-color: #f58383;
+  background-position: 2px -103px;
 }
-.claro.dojoDndCopy .dojoDndAvatarHeader	{
-	background-color: #f58383; 
-	background-position:2px -68px;
+.claro.dojoDndCopy .dojoDndAvatarHeader {
+  background-color: #f58383;
+  background-position: 2px -68px;
 }
-.claro.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{
-	background-color: #97e68d; 
-	background-position:2px -33px;
+.claro.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader {
+  background-color: #97e68d;
+  background-position: 2px -33px;
 }
-.claro.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{
-	background-color: #97e68d;
-	background-position:2px 2px;
+.claro.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader {
+  background-color: #97e68d;
+  background-position: 2px 2px;
 }
diff --git a/dijit/themes/claro/Common.less b/dijit/themes/claro/Common.less
new file mode 100644
index 0000000..872cf89
--- /dev/null
+++ b/dijit/themes/claro/Common.less
@@ -0,0 +1,76 @@
+/* ========= Styling rules to affect widgets ========= */
+
+ at import "variables";
+
+.claro .dijitPopup {
+	.box-shadow(0 1px 5px rgba(0,0,0,0.25));
+}
+.claro .dijitTooltipDialogPopup {
+	/* exception popups: do not use a shadow on these because they aren't rectangular */
+	.box-shadow(none);
+}
+
+/* The highlight is shown in the ComboBox menu.  TODO: move to form/Common.less */
+.claro .dijitComboBoxHighlightMatch {
+	background-color: @select-matchedtext-background-color;
+}
+
+.claro .dijitFocusedLabel {
+	/* for checkboxes or radio buttons, hatch border around the corresponding label, to indicate focus */
+	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{
+	border-top: 1px solid @dnd-dropseparator-color;
+}
+.claro .dojoDndItemOver {
+	cursor:pointer;
+	}
+.claro table.dojoDndAvatar {
+	border: 1px solid @border-color;
+	border-collapse: collapse;
+	background-color: @dnd-avatar-background-color;
+	.box-shadow(0 1px 3px rgba(0, 0, 0, .25));
+}
+.claro .dojoDndAvatarHeader td	{ 
+	height: 20px;
+	padding-left:21px;
+}
+.claro.dojoDndMove .dojoDndAvatarHeader, .claro.dojoDndCopy .dojoDndAvatarHeader {
+	background-image: url(images/dnd.png);
+	background-repeat: no-repeat;
+	background-position:2px -122px;
+}
+.claro .dojoDndAvatarItem td {
+	padding: 5px;
+}
+.claro.dojoDndMove .dojoDndAvatarHeader	{
+	background-color: @dnd-avatar-header-background-color; 
+	background-position:2px -103px;
+}
+.claro.dojoDndCopy .dojoDndAvatarHeader	{
+	background-color: @dnd-avatar-header-background-color; 
+	background-position:2px -68px;
+}
+.claro.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{
+	background-color: @dnd-avatar-candrop-header-background-color; 
+	background-position:2px -33px;
+}
+.claro.dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader	{
+	background-color: @dnd-avatar-candrop-header-background-color;
+	background-position:2px 2px;
+}
diff --git a/dijit/themes/claro/Dialog.css b/dijit/themes/claro/Dialog.css
index b3bdfcb..119900e 100644
--- a/dijit/themes/claro/Dialog.css
+++ b/dijit/themes/claro/Dialog.css
@@ -28,185 +28,176 @@
  * 2. tooltip connector: 
  * 		.dijitTooltipConnector - tooltip anchor includes 4 direction(up, down, left, right)
  */
-
 .claro .dijitDialog {
-	border: 1px solid #769dc0;
-	box-shadow:0px 1px 5px rgba(0,0,0,0.25);
-	-webkit-box-shadow:0px 1px 5px rgba(0,0,0,0.25);
-	-moz-box-shadow: 0px 1px 5px rgba(0,0,0,0.25);
-} 
-
+  border: 1px solid #769dc0;
+  -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: #fff repeat-x top left;
-	border-top: 1px solid #769dc0;
-	padding:10px 8px;
-	position: relative;
+  background: #ffffff repeat-x top left;
+  border-top: 1px solid #769dc0;
+  padding: 10px 8px;
+  position: relative;
 }
-
 .claro .dijitDialogPaneContentArea {
-	/* trick to get action bar (gray bar at bottom with OK/cancel buttons) to span from
+  /* trick to get action bar (gray bar at bottom with OK/cancel buttons) to span from
 	 * left to right but still indent dialog content
-	 */ 
-	margin: -10px -8px;
-	padding: 10px 8px;
+	 */
+  margin: -10px -8px;
+  padding: 10px 8px;
 }
-
 .claro .dijitDialogPaneActionBar {
-	/* gray bar at bottom of dialog with OK/Cancel buttons */
-	background-color: #f2f2f2;
-	padding: 3px 5px 2px 7px;
-	text-align: right;
-	border-top: 1px solid #cdcdcd;
-	margin: 10px -8px -10px;
+  /* gray bar at bottom of dialog with OK/Cancel buttons */
+
+  background-color: #efefef;
+  padding: 3px 5px 2px 7px;
+  text-align: right;
+  border-top: 1px solid #d3d3d3;
+  margin: 10px -8px -10px;
 }
 .claro .dijitDialogPaneActionBar .dijitButton {
-	float: none;
+  float: none;
 }
-
 .claro .dijitDialogTitleBar {
-	/* outer container for the titlebar of the dialog */
-	border: 1px solid #fff;
-	border-top:none;
-	background-color: #abd6ff;
-	background-image: url("images/titlebar.png");
-	background-repeat:repeat-x;
-	padding: 5px 7px 4px 7px;
-}
+  /* outer container for the titlebar of the dialog */
 
-.claro .dijitDialogTitle {
-	/* typography and styling of the dialog title */
-	padding: 0px 1px;
-	font-size:1.091em;
+  border: 1px solid #ffffff;
+  border-top: none;
+  background-color: #abd6ff;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  padding: 5px 7px 4px 7px;
 }
+.claro .dijitDialogTitle {
+  /* typography and styling of the dialog title */
 
+  padding: 0 1px;
+  font-size: 1.091em;
+}
 .claro .dijitDialogCloseIcon {
-	/* the default close icon for the dialog */
-	background: url("images/dialogCloseIcon.png");
-	background-repeat:no-repeat;
-	position: absolute;
-	right: 5px;
-	height: 15px;
-	width: 21px;
+  /* the default close icon for the dialog */
+
+  background: url("images/dialogCloseIcon.png");
+  background-repeat: no-repeat;
+  position: absolute;
+  right: 5px;
+  height: 15px;
+  width: 21px;
 }
 .dj_ie6 .claro .dijitDialogCloseIcon {
-	background-image: url("images/dialogCloseIcon8bit.png");
+  background-image: url("images/dialogCloseIcon8bit.png");
 }
 .claro .dijitDialogCloseIconHover {
-	background-position:-21px;
+  background-position: -21px;
 }
 .claro .dijitDialogCloseIconActive {
-	background-position:-42px;
+  background-position: -42px;
 }
-
 /* Tooltip and TooltipDialog */
+.claro .dijitTooltip, .claro .dijitTooltipDialog {
+  /* the outermost dom node, holding the connector and container */
+
+  background: transparent;
+  /* make the area on the sides of the arrow transparent */
 
-.claro .dijitTooltip,
-.claro .dijitTooltipDialog {
-	/* the outermost dom node, holding the connector and container */
-	background: transparent;	/* make the area on the sides of the arrow transparent */
 }
 .dijitTooltipBelow {
-	/* leave room for arrow above content */
-	padding-top: 13px;
-	padding-left:3px;
-	padding-right:3px;
-}
+  /* leave room for arrow above content */
 
-.dijitTooltipAbove {
-	/* leave room for arrow below content */
-	padding-bottom: 13px;
-	padding-left:3px;
-	padding-right:3px;
+  padding-top: 13px;
+  padding-left: 3px;
+  padding-right: 3px;
 }
+.dijitTooltipAbove {
+  /* leave room for arrow below content */
 
+  padding-bottom: 13px;
+  padding-left: 3px;
+  padding-right: 3px;
+}
 .claro .dijitTooltipContainer {
-	/* the part with the text */
-	background-color:#fff;
-	background-image:url("images/tooltip.png");
-	background-repeat:repeat-x;
-	background-position:-575px 100%;
-	border:1px solid #769DC0;
-	padding:6px 8px;
-	border-radius: 4px;
-	-webkit-border-radius: 4px;
-	-moz-border-radius: 4px;
-	box-shadow:0px 1px 3px rgba(0,0,0,0.25);
-	-webkit-box-shadow:0px 1px 3px rgba(0,0,0,0.25);
-	-moz-box-shadow: 0px 1px 3px rgba(0,0,0,0.25);
-	font-size: 1em;
-} 
-
+  /* the part with the text */
+
+  background-color: #ffffff;
+  background-image: url("images/tooltipGradient.png");
+  background-repeat: repeat-x;
+  background-position: bottom;
+  border: 1px solid #769dc0;
+  padding: 6px 8px;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
+  -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;
+}
 .dj_ie6 .claro .dijitTooltipContainer {
-	background-image: none;
+  background-image: none;
 }
 .claro .dijitTooltipConnector {
-	/* the arrow piece */
-	border: 0px;
-	z-index: 2;
-	background-image:url("images/tooltip.png");
-	background-repeat:no-repeat;
-	width:16px;
-	height:14px;
+  /* the arrow piece */
+
+  border: 0;
+  z-index: 2;
+  background-image: url("images/tooltip.png");
+  background-repeat: no-repeat;
+  width: 16px;
+  height: 14px;
 }
 .dj_ie6 .claro .dijitTooltipConnector {
-	background-image:url("images/tooltip8bit.png");
+  background-image: url("images/tooltip8bit.png");
 }
 .claro .dijitTooltipABRight .dijitTooltipConnector {
-	/* above or below tooltip, but the arrow appears on the right,
+  /* above or below tooltip, but the arrow appears on the right,
 		and the right edges of target and tooltip are aligned rather than the left */
-	left: auto !important;
-	right: 3px;
-}
 
-.claro .dijitTooltipBelow .dijitTooltipConnector {
-	/* the arrow piece for tooltips below an element */
-	top: 0px;
-	left: 3px;
-	background-position:-31px 0%;
-	width:16px;
-	height:14px;
+  left: auto !important;
+  right: 3px;
 }
+.claro .dijitTooltipBelow .dijitTooltipConnector {
+  /* the arrow piece for tooltips below an element */
 
+  top: 0;
+  left: 3px;
+  background-position: -31px 0;
+  width: 16px;
+  height: 14px;
+}
 .claro .dijitTooltipAbove .dijitTooltipConnector {
-	/* the arrow piece for tooltips above an element */
-	bottom: 0px;
-	left: 3px;
-	background-position:-15px 0%;
-	width:16px;
-	height:14px;
+  /* the arrow piece for tooltips above an element */
+
+  bottom: 0;
+  left: 3px;
+  background-position: -15px 0;
+  width: 16px;
+  height: 14px;
 }
-.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector,
-.dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
-	bottom: -1px;
+.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector, .dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
+  bottom: -1px;
 }
-
 .claro .dijitTooltipLeft {
-	padding-right: 14px;
-}
-.dj_ie6 .claro .dijitTooltipLeft {
-	padding-left: 15px;
+  padding-right: 14px;
 }
 .claro .dijitTooltipLeft .dijitTooltipConnector {
-	/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
-	right: 0px;
-	bottom: 3px;
-	background-position:0px 0%;
-	width:16px;
-	height:14px;
-}
+  /* the arrow piece for tooltips to the left of an element, bottom borders aligned */
 
+  right: 0;
+  background-position: 0 0;
+  width: 16px;
+  height: 14px;
+}
 .claro .dijitTooltipRight {
-	padding-left: 14px;
+  padding-left: 14px;
 }
 .claro .dijitTooltipRight .dijitTooltipConnector {
-	/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
-	left: 0px;
-	bottom: 3px;
-	background-position:-48px 0%;
-	width:16px;
-	height:14px;
-}
+  /* the arrow piece for tooltips to the right of an element, bottom borders aligned */
 
+  left: 0;
+  background-position: -48px 0;
+  width: 16px;
+  height: 14px;
+}
 .claro .dijitDialogUnderlay {
-	background: #fff;
+  background: #ffffff;
 }
diff --git a/dijit/themes/claro/Dialog.less b/dijit/themes/claro/Dialog.less
new file mode 100644
index 0000000..ff5c1e6
--- /dev/null
+++ b/dijit/themes/claro/Dialog.less
@@ -0,0 +1,203 @@
+/* Dialog 
+ * 
+ * Styling Dialog includes two sections: Dialog and Tooltip & TooltipDialog
+ * 
+ * Dialog:
+ * 1. Dialog (default styling): 
+ * 		.dijitDialog - styles for dialog's bounding box
+ *
+ * 2. Dialog title 
+ * 		.dijitDialogTitleBar - styles for the title container at the top of dialog
+ * 		.dijitDialogTitle - the text container in dialog title
+ * 
+ * 3. Dialog content 
+ * 		.dijitDialogPaneContent - main container for content area and action bar
+ * 		.dijitDialogPaneContentArea - styles for content container
+ * 
+ * 4. Dialog action bar 
+ * 		.dijitDialogPaneActionBar - styles for action buttons lie at the bottom of dialog pane content
+ * 
+ * 5. Dialog underlay 
+ * 		.dijitDialogUnderlay - div under the dialog which used for separate dialog and page content
+ * 
+ * 
+ * Tooltip & TooltipDialog:
+ * 1. tooltip content container: 
+ * 		.dijitTooltipContainer - tooltip content container
+ *
+ * 2. tooltip connector: 
+ * 		.dijitTooltipConnector - tooltip anchor includes 4 direction(up, down, left, right)
+ */
+
+ at import "variables";
+
+.claro .dijitDialog {
+	border: 1px solid @popup-border-color;
+	.box-shadow(0 1px 5px rgba(0,0,0,0.25));
+} 
+
+.claro .dijitDialogPaneContent {
+	background: @pane-background-color repeat-x top left;
+	border-top: 1px solid @popup-border-color;
+	padding:10px 8px;
+	position: relative;
+}
+
+.claro .dijitDialogPaneContentArea {
+	/* trick to get action bar (gray bar at bottom with OK/cancel buttons) to span from
+	 * left to right but still indent dialog content
+	 */ 
+	margin: -10px -8px;
+	padding: 10px 8px;
+}
+
+.claro .dijitDialogPaneActionBar {
+	/* gray bar at bottom of dialog with OK/Cancel buttons */
+	background-color: @bar-background-color;
+	padding: 3px 5px 2px 7px;
+	text-align: right;
+	border-top: 1px solid @minor-border-color;
+	margin: 10px -8px -10px;
+}
+.claro .dijitDialogPaneActionBar .dijitButton {
+	float: none;
+}
+
+.claro .dijitDialogTitleBar {
+	/* outer container for the titlebar of the dialog */
+	border: 1px solid @dialog-titlebar-border-color;
+	border-top:none;
+	background-color: @dialog-titlebar-background-color;
+	background-image: url("images/titlebar.png");
+	background-repeat:repeat-x;
+	padding: 5px 7px 4px 7px;
+}
+
+.claro .dijitDialogTitle {
+	/* typography and styling of the dialog title */
+	padding: 0 1px;
+	font-size:1.091em;
+}
+
+.claro .dijitDialogCloseIcon {
+	/* the default close icon for the dialog */
+	background: url("images/dialogCloseIcon.png");
+	background-repeat:no-repeat;
+	position: absolute;
+	right: 5px;
+	height: 15px;
+	width: 21px;
+}
+.dj_ie6 .claro .dijitDialogCloseIcon {
+	background-image: url("images/dialogCloseIcon8bit.png");
+}
+.claro .dijitDialogCloseIconHover {
+	background-position:-21px;
+}
+.claro .dijitDialogCloseIconActive {
+	background-position:-42px;
+}
+
+/* Tooltip and TooltipDialog */
+
+.claro .dijitTooltip,
+.claro .dijitTooltipDialog {
+	/* the outermost dom node, holding the connector and container */
+	background: transparent;	/* make the area on the sides of the arrow transparent */
+}
+.dijitTooltipBelow {
+	/* leave room for arrow above content */
+	padding-top: 13px;
+	padding-left:3px;
+	padding-right:3px;
+}
+
+.dijitTooltipAbove {
+	/* leave room for arrow below content */
+	padding-bottom: 13px;
+	padding-left:3px;
+	padding-right:3px;
+}
+
+.claro .dijitTooltipContainer {
+	/* the part with the text */
+	background-color:@popup-background-color;
+	background-image:url("images/tooltipGradient.png");
+	background-repeat:repeat-x;
+	background-position:bottom;
+	border:1px solid @popup-border-color;
+	padding:6px 8px;
+	.border-radius(4px);
+	.box-shadow(0 1px 3px rgba(0,0,0,0.25));
+	font-size: 1em;
+} 
+
+.dj_ie6 .claro .dijitTooltipContainer {
+	background-image: none;
+}
+.claro .dijitTooltipConnector {
+	/* the arrow piece */
+	border: 0;
+	z-index: 2;
+	background-image:url("images/tooltip.png");
+	background-repeat:no-repeat;
+	width:16px;
+	height:14px;
+}
+.dj_ie6 .claro .dijitTooltipConnector {
+	background-image:url("images/tooltip8bit.png");
+}
+.claro .dijitTooltipABRight .dijitTooltipConnector {
+	/* above or below tooltip, but the arrow appears on the right,
+		and the right edges of target and tooltip are aligned rather than the left */
+	left: auto !important;
+	right: 3px;
+}
+
+.claro .dijitTooltipBelow .dijitTooltipConnector {
+	/* the arrow piece for tooltips below an element */
+	top: 0;
+	left: 3px;
+	background-position:-31px 0;
+	width:16px;
+	height:14px;
+}
+
+.claro .dijitTooltipAbove .dijitTooltipConnector {
+	/* the arrow piece for tooltips above an element */
+	bottom: 0;
+	left: 3px;
+	background-position:-15px 0;
+	width:16px;
+	height:14px;
+}
+.dj_ie7 .claro .dijitTooltipAbove .dijitTooltipConnector,
+.dj_ie6 .claro .dijitTooltipAbove .dijitTooltipConnector {
+	bottom: -1px;
+}
+
+.claro .dijitTooltipLeft {
+	padding-right: 14px;
+}
+.claro .dijitTooltipLeft .dijitTooltipConnector {
+	/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
+	right: 0;
+	background-position:0 0;
+	width:16px;
+	height:14px;
+}
+
+.claro .dijitTooltipRight {
+	padding-left: 14px;
+}
+.claro .dijitTooltipRight .dijitTooltipConnector {
+	/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
+	left: 0;
+	background-position:-48px 0;
+	width:16px;
+	height:14px;
+}
+
+.claro .dijitDialogUnderlay {
+	background: @dialog-underlay-color;
+}
diff --git a/dijit/themes/claro/Dialog_rtl.css b/dijit/themes/claro/Dialog_rtl.css
index 7c1e0f5..34930eb 100644
--- a/dijit/themes/claro/Dialog_rtl.css
+++ b/dijit/themes/claro/Dialog_rtl.css
@@ -1,10 +1,9 @@
 /* Dialog */
 .claro .dijitDialogRtl .dijitDialogCloseIcon {
-	right: auto;
-	left: 5px;
+  right: auto;
+  left: 5px;
 }
-
 .claro .dijitDialogRtl .dijitDialogPaneActionBar {
-	text-align: left;
-	padding: 3px 7px 2px 5px;
+  text-align: left;
+  padding: 3px 7px 2px 5px;
 }
diff --git a/dijit/themes/claro/Dialog_rtl.less b/dijit/themes/claro/Dialog_rtl.less
new file mode 100644
index 0000000..452fe93
--- /dev/null
+++ b/dijit/themes/claro/Dialog_rtl.less
@@ -0,0 +1,13 @@
+/* Dialog */
+
+ at import "variables";
+
+.claro .dijitDialogRtl .dijitDialogCloseIcon {
+	right: auto;
+	left: 5px;
+}
+
+.claro .dijitDialogRtl .dijitDialogPaneActionBar {
+	text-align: left;
+	padding: 3px 7px 2px 5px;
+}
diff --git a/dijit/themes/claro/Editor.css b/dijit/themes/claro/Editor.css
index 8c30469..641990a 100644
--- a/dijit/themes/claro/Editor.css
+++ b/dijit/themes/claro/Editor.css
@@ -14,43 +14,37 @@
  * 3. disabled Editor iframe container 
  * 		.dijitEditorDisabled - editor's inner iframe container disable status styles: background, border
  */
-
-.claro .dijitEditorIFrameContainer{
-	padding:3px 3px 1px 10px;
+.claro .dijitEditorIFrameContainer {
+  padding: 3px 3px 1px 10px;
 }
 .claro .dijitEditorIFrame {
-	background-color: #fff;
+  background-color: #ffffff;
 }
 .claro .dijitEditor {
-	border: 1px solid #b5bcc7;
-}
-.claro .dijitEditor .dijitEditorIFrameContainer{
-	background-color: #fff;
-	background-image: url('form/images/textBox_back.png');
-	background-repeat:repeat-x;
+  border: 1px solid #b5bcc7;
 }
-.dj_ie6 .claro .dijitEditor .dijitEditorIFrameContainer{
-	background-image: none;
+.claro .dijitEditor .dijitEditorIFrameContainer {
+  background-color: #ffffff;
+  background-image: url('form/images/textBox_back.png');
+  background-repeat: repeat-x;
 }
-.claro .dijitEditorHover .dijitEditorIFrameContainer,
-.claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame{
-	background-color: #eef7ff;
+.dj_ie6 .claro .dijitEditor .dijitEditorIFrameContainer {
+  background-image: none;
 }
-.claro .dijitEditorFocused .dijitEditorIFrameContainer,
-.claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame{
-	/* TODO: contradicts rule above, which background-color do you want? */
-	background-color: #fff;
+.claro .dijitEditorHover .dijitEditorIFrameContainer, .claro .dijitEditorHover .dijitEditorIFrameContainer .dijitEditorIFrame {
+  background-color: #e9f4fe;
 }
+.claro .dijitEditorFocused .dijitEditorIFrameContainer, .claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame {
+  /* TODO: contradicts rule above, which background-color do you want? */
 
-
+  background-color: #ffffff;
+}
 /* Disabled */
 .claro .dijitEditorDisabled {
-	border: 1px solid #d3d3d3;
-	color: #818181;
+  border: 1px solid #d3d3d3;
+  color: #818181;
+}
+.claro .dijitDisabled .dijitEditorIFrame, .claro .dijitDisabled .dijitEditorIFrameContainer, .claro .dijitDisabled .dijitEditorIFrameContainer .dijitEditorIFrame {
+  background-color: #efefef;
+  background-image: none;
 }
-
-.claro .dijitDisabled .dijitEditorIFrame,
-.claro .dijitDisabled .dijitEditorIFrameContainer {
-	background-color: #efefef;
-	background-image: none;
-}
\ No newline at end of file
diff --git a/dijit/themes/claro/Editor.less b/dijit/themes/claro/Editor.less
new file mode 100644
index 0000000..43e6d39
--- /dev/null
+++ b/dijit/themes/claro/Editor.less
@@ -0,0 +1,59 @@
+/* Editor 
+ * 
+ * Styling Editor means styling the Editor inside iframe container (dijitEditorIFrameContainer)
+ * 
+ * 1. Editor iframe container (default styling): 
+ * 		.dijitEditorIFrameContainer - normal state styles: background-color, border, padding
+ *
+ * 2. hovered Editor iframe container (ie, mouse hover on editor)
+ * 		.dijitEditorHover .dijitEditorIFrameContainer/dijitEditorIFrame - styles when mouse hover on the container
+ * 
+ * 3. focused Editor iframe container (ie, mouse focus on the editor pane)
+ * 		.dijitEditorFocused .dijitEditorIFrameContainer/dijitEditorIFrame - styles when container focused
+ * 
+ * 3. disabled Editor iframe container 
+ * 		.dijitEditorDisabled - editor's inner iframe container disable status styles: background, border
+ */
+
+ at import "variables";
+
+.claro .dijitEditorIFrameContainer{
+	padding:3px 3px 1px 10px;
+}
+.claro .dijitEditorIFrame {
+	background-color: @textbox-background-color;
+}
+.claro .dijitEditor {
+	border: 1px solid @border-color;
+}
+.claro .dijitEditor .dijitEditorIFrameContainer{
+	background-color: @textbox-background-color;
+	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: @textbox-hovered-background-color;
+}
+.claro .dijitEditorFocused .dijitEditorIFrameContainer,
+.claro .dijitEditorFocused .dijitEditorIFrameContainer .dijitEditorIFrame{
+	/* TODO: contradicts rule above, which background-color do you want? */
+	background-color: @textbox-focused-background-color;
+}
+
+
+/* Disabled */
+.claro .dijitEditorDisabled {
+	border: 1px solid @disabled-border-color;
+	color: @disabled-text-color;
+}
+
+.claro .dijitDisabled .dijitEditorIFrame,
+.claro .dijitDisabled .dijitEditorIFrameContainer,
+.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/Editor_rtl.css b/dijit/themes/claro/Editor_rtl.css
index f9427db..f633558 100644
--- a/dijit/themes/claro/Editor_rtl.css
+++ b/dijit/themes/claro/Editor_rtl.css
@@ -1,7 +1,4 @@
 /* Editor */
-
-.claro .dijitEditorRtl .dijitEditorIFrameContainer{
-	padding:3px 10px 1px 3px;
+.claro .dijitEditorRtl .dijitEditorIFrameContainer {
+  padding: 3px 10px 1px 3px;
 }
-
-
diff --git a/dijit/themes/claro/Editor_rtl.less b/dijit/themes/claro/Editor_rtl.less
new file mode 100644
index 0000000..8ebc013
--- /dev/null
+++ b/dijit/themes/claro/Editor_rtl.less
@@ -0,0 +1,9 @@
+/* Editor */
+
+ at import "variables";
+
+.claro .dijitEditorRtl .dijitEditorIFrameContainer{
+	padding:3px 10px 1px 3px;
+}
+
+
diff --git a/dijit/themes/claro/InlineEditBox.css b/dijit/themes/claro/InlineEditBox.css
index 50bb5c0..e6058f7 100644
--- a/dijit/themes/claro/InlineEditBox.css
+++ b/dijit/themes/claro/InlineEditBox.css
@@ -8,16 +8,13 @@
  * 2. Hover state
  * 		.dijitInlineEditBoxDisplayModeHover - for border and background color
  */
-
 .claro .dijitInlineEditBoxDisplayMode {
-	border: 1px solid transparent;
+  border: 1px solid transparent;
 }
-
 .claro .dijitInlineEditBoxDisplayModeHover {
-	background-color: #e2f1ff;
-	border: solid 1px #769dc0;
+  background-color: #e9f4fe;
+  border: solid 1px #769dc0;
 }
-
 .dj_ie6 .claro .dijitInlineEditBoxDisplayMode {
-	border: none;
+  border: none;
 }
diff --git a/dijit/themes/claro/InlineEditBox.less b/dijit/themes/claro/InlineEditBox.less
new file mode 100644
index 0000000..a7162be
--- /dev/null
+++ b/dijit/themes/claro/InlineEditBox.less
@@ -0,0 +1,25 @@
+/* InlineEditBox
+ * 
+ * Styling InlineEditBox mainly includes:
+ * 
+ * 1. Normal state
+ * 		.dijitInlineEditBoxDisplayMode  - for border
+ * 
+ * 2. Hover state
+ * 		.dijitInlineEditBoxDisplayModeHover - for border and background color
+ */
+
+ at import "variables";
+
+.claro .dijitInlineEditBoxDisplayMode {
+	border: 1px solid transparent;
+}
+
+.claro .dijitInlineEditBoxDisplayModeHover {
+	background-color: @textbox-hovered-background-color;
+	border: solid 1px @hovered-border-color;
+}
+
+.dj_ie6 .claro .dijitInlineEditBoxDisplayMode {
+	border: none;
+}
diff --git a/dijit/themes/claro/Menu.css b/dijit/themes/claro/Menu.css
index df310f6..c55176d 100644
--- a/dijit/themes/claro/Menu.css
+++ b/dijit/themes/claro/Menu.css
@@ -30,153 +30,155 @@ There are three areas of styling for the Menu:
 
 */
 .claro .dijitMenuBar {
-	border: 1px solid #b5bcc7;
-	margin: 0px;
-	padding: 0px;
-	background-color: #e6e6e7;
-	background-image: url("images/commonHighlight.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
+  border: 1px solid #b5bcc7;
+  margin: 0;
+  padding: 0;
+  background-color: #efefef;
+  background-image: url("images/commonHighlight.png");
+  background-position: 0 0;
+  background-repeat: repeat-x;
 }
 .dj_ie6 .claro .dijitMenuBar {
-	background-image:none;
+  background-image: none;
 }
 .claro .dijitMenu {
-	background-repeat:repeat-y;
-	background-color:#fff;
-	border: 1px solid #769dc0;
+  background-repeat: repeat-y;
+  background-color: #ffffff;
+  border: 1px solid #769dc0;
+  /* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
 
-	/* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
-	margin: -1px 0;
-}
-.claro .dijitMenuBar .dijitMenuItem {  
-	padding: 6px 10px 7px;
-	background-position:0px 100px;
-	color:#4a4a4a;
-	margin:-1px;
-}	
-.claro .dijitMenuItem {
-	background-image: url("images/menuHighlight.png");
-	background-position:0px -40px;
-	background-repeat:repeat-x;
+  margin: -1px 0;
 }
+.dj_ie6 .claro .dijitMenu {
+  margin: 0;
+  /* above -1px makes top/bottom borders disappear on IE6 */
 
+}
+.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;
+}
 /* this prevents jiggling upon hover of a menu item */
 .claro .dijitMenuTable {
-	border-collapse:separate;
-	border-spacing:0 0;
-	padding:0px;
+  border-collapse: separate;
+  border-spacing: 0 0;
+  padding: 0;
 }
-.claro .dijitMenuItem td{
-	padding:1px;
+.claro .dijitMenuItem td {
+  padding: 1px;
 }
 /* hover over a MenuBarItem */
-.claro .dijitMenuPassive .dijitMenuItemHover,
-.claro .dijitMenuPassive .dijitMenuItemSelected {
-	background-color: #abd6ff;
-	border:solid 1px #769dc0;
-	background-position:0px 0px;
-	color:#000;
-	padding: 5px 9px 6px;
+.claro .dijitMenuPassive .dijitMenuItemHover, .claro .dijitMenuPassive .dijitMenuItemSelected {
+  background-color: #abd6ff;
+  border: solid 1px #769dc0;
+  background-position: 0 0;
+  color: #000000;
+  padding: 5px 9px 6px;
 }
-.claro .dijitMenuPassive .dijitMenuItemActive{
-	background-position:0px -177px;
+.claro .dijitMenuPassive .dijitMenuItemActive {
+  background-position: 0 -177px;
 }
-.dj_ie6 .claro .dijitMenuItem,
-.dj_ie6 .claro .dijitMenuPassive .dijitMenuItem {
-	background-image: none;
+.dj_ie6 .claro .dijitMenuItem, .dj_ie6 .claro .dijitMenuPassive .dijitMenuItem {
+  background-image: none;
 }
-
 /* MenuBarItem that has been selected and menu drops down from it */
-.claro .dijitMenuActive .dijitMenuItemHover,
-.claro .dijitMenuActive .dijitMenuItemSelected {
-	border:solid 1px #769dc0;
-	padding: 5px 9px 6px;
-	background-color: #9dcfff;
-	background-position:0px 0px;
-	color:#000;
+.claro .dijitMenuActive .dijitMenuItemHover, .claro .dijitMenuActive .dijitMenuItemSelected {
+  border: solid 1px #769dc0;
+  padding: 5px 9px 6px;
+  background-color: #abd6ff;
+  background-position: 0 0;
+  color: #000000;
 }
 .dj_ie .claro .dijitMenuActive .dijitMenuItemHover,
 .dj_ie .claro .dijitMenuActive .dijitMenuItemSelected,
 .dj_ie .claro .dijitMenuPassive .dijitMenuItemHover,
 .dj_ie .claro .dijitMenuPassive .dijitMenuItemSelected {
-	padding-top: 6px;
-	padding-bottom: 5px;
-	margin-top: -3px;
+  padding-top: 6px;
+  padding-bottom: 5px;
+  margin-top: -3px;
 }
-.claro .dijitMenuActive .dijitMenuItemActive{
-	background-color: #7dbefa;
-	background-position:0px -177px;
+.claro .dijitMenuActive .dijitMenuItemActive {
+  background-color: #7dbefa;
+  background-position: 0 -177px;
 }
 .claro .dijitMenuItemActive {
-	background-position:0px -177px;
+  background-position: 0 -177px;
 }
 .claro td.dijitMenuItemIconCell {
- padding: 2px;
- margin: 0px 0px 0px 4px;
+  padding: 2px;
+  margin: 0 0 0 4px;
 }
 .claro td.dijitMenuItemLabel {
-	padding-top: 5px;
-	padding-bottom: 5px;
+  padding-top: 5px;
+  padding-bottom: 5px;
 }
 .claro .dijitMenuExpand {
-	width: 7px;
-	height: 7px;
-	background-image: url('images/spriteArrows.png');
-	background-position: -14px 0px;
-	margin-right:3px;
+  width: 7px;
+  height: 7px;
+  background-image: url('images/spriteArrows.png');
+  background-position: -14px 0;
+  margin-right: 3px;
 }
 .claro .dijitMenuItemDisabled .dijitMenuItemIconCell {
-	opacity:1;
+  opacity: 1;
 }
 .claro .dijitMenuSeparatorTop {
-	height: auto;
-	margin-top:1px; /* prevents spacing above/below separator */
-	border-bottom: 1px solid #b5bcc7
+  height: auto;
+  margin-top: 1px;
+  /* prevents spacing above/below separator */
+
+  border-bottom: 1px solid #b5bcc7;
 }
-.claro .dijitMenuSeparatorBottom{
-	height: auto;
-	margin-bottom:1px;
+.claro .dijitMenuSeparatorBottom {
+  height: auto;
+  margin-bottom: 1px;
 }
 /* the checked menu item */
 .claro .dijitCheckedMenuItemIconChar {
-	display: none;
+  display: none;
 }
 .claro .dijitCheckedMenuItemIcon {
-	background-image: url('form/images/checkboxRadioButtonStates.png');
-	background-repeat:no-repeat;
-	background-position: -15px 50%;
-	width:15px;
-	height:16px;
+  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%;
+  background-position: 0 50%;
 }
-
 /*ComboBox Menu*/
 .claro .dijitComboBoxMenu {
-	margin-left:0px;
-	background-image: none;
+  margin-left: 0;
+  background-image: none;
 }
-.claro .dijitComboBoxMenu .dijitMenuItem{
-	padding:2px 0px;
-	text-indent:6px;
-	border-width:1px 0px 1px 0px;
-	border-style:solid;
-	border-color:#fff;
+.claro .dijitComboBoxMenu .dijitMenuItem {
+  padding: 2px;
+  border-width: 1px 0 1px 0;
+  border-style: solid;
+  border-color: #ffffff;
 }
 .claro .dijitComboBoxMenu .dijitMenuItemSelected {
-	color:#000;
-	border-color:#768dc0;
-	background-color:#abd6ff;
+  color: #000000;
+  border-color: #769dc0;
+  background-color: #abd6ff;
 }
 .claro .dijitComboBoxMenuActive .dijitMenuItemSelected {
-	background-position:0px -177px;
-	background-color:#7dbefa;
+  background-position: 0 -177px;
+  background-color: #7dbefa;
+  /* TODO: why is this a different color than normal .dijitMenuItemSelected? */
+
 }
 .claro .dijitMenuPreviousButton, .claro .dijitMenuNextButton {
-	font-style: italic;
+  font-style: italic;
 }
diff --git a/dijit/themes/claro/Menu.less b/dijit/themes/claro/Menu.less
new file mode 100644
index 0000000..1528df4
--- /dev/null
+++ b/dijit/themes/claro/Menu.less
@@ -0,0 +1,188 @@
+/* Menu 
+
+There are three areas of styling for the Menu:  
+ 
+ 1. The menu 
+ 	There are three types of menus:
+ 	i)Context Menu
+ 	ii)Drop down Menu
+ 	iii) Navigation Menu
+ 	All three types of menus are affected by the .dijitMenu class in which you can set the background-color, padding and border
+ 	.dijitMenu affects the drop down menu in TimeTextBox, Calendar, ComboBox and FilteringSelect
+  .dijitMenuTable - for padding - also affects Select widget 	
+  	
+ 2. The menu bar
+ 	.dijitMenuBar - for border, margins, padding, background-color of the menu bar
+ 	.dijitMenuBar .dijitMenuItem - for padding, text color of menu items in the menu bar (overrides .dijitMenuItem) 
+ 	
+ 3. Menu items - items in the menu.  
+ 	.dijitMenuItem - for color
+ 	.dijitMenuItemHover, .dijitMenuItemSelected - for background-color, border, text color, padding of a menu item or menubar item that has been hovered over or selected	
+ 	.dijitMenuItemActive - for bacgkround-color of an active (mousedown) menu item
+	td.dijitMenuItemIconCell - for padding around a  menu item's icon
+	td.dijitMenuItemLabel - for padding around a menu item's label	
+	.dijitMenuSeparatorTop - for border, top border, of the separator
+	.dijitMenuSeparatorBottom - for bottom margin of the separator
+	
+	Styles specific to ComboBox and FilteringSelect widgets: 
+	.dijitComboBoxMenu .dijitMenuItem - for padding and border of a menu item in a ComboBox or FilteringSelect widget's menu
+	.dijitComboBoxMenu .dijitMenuItemSelected- for text color, background-color and border of a menu item in a ComboBox or FilteringSelect widget's menu
+
+*/
+
+ at import "variables";
+
+.claro .dijitMenuBar {
+	border: 1px solid @border-color;
+	margin: 0;
+	padding: 0;
+	background-color: @bar-background-color;
+	background-image: url("images/commonHighlight.png");
+	background-position:0 0;
+	background-repeat:repeat-x;
+}
+.dj_ie6 .claro .dijitMenuBar {
+	background-image:none;
+}
+.claro .dijitMenu {
+	background-repeat:repeat-y;
+	background-color:@menu-background-color;
+	border: 1px solid @popup-border-color;
+
+	/* so adjoining borders of MenuBar/ComboBox and Menu overlap, avoiding double border */
+	margin: -1px 0;
+}
+.dj_ie6 .claro .dijitMenu {
+	margin: 0;	/* above -1px makes top/bottom borders disappear on IE6 */
+}
+.claro .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-position:0 -40px;
+	background-repeat:repeat-x;
+}
+
+/* this prevents jiggling upon hover of a menu item */
+.claro .dijitMenuTable {
+	border-collapse:separate;
+	border-spacing:0 0;
+	padding:0;
+}
+.claro .dijitMenuItem td{
+	padding:1px;
+}
+/* hover over a MenuBarItem */
+.claro .dijitMenuPassive .dijitMenuItemHover,
+.claro .dijitMenuPassive .dijitMenuItemSelected {
+	background-color: @hovered-background-color;
+	border:solid 1px @hovered-border-color;
+	background-position:0 0;
+	color:@text-color;
+	padding: 5px 9px 6px;
+}
+.claro .dijitMenuPassive .dijitMenuItemActive{
+	background-position:0 -177px;
+}
+.dj_ie6 .claro .dijitMenuItem,
+.dj_ie6 .claro .dijitMenuPassive .dijitMenuItem {
+	background-image: none;
+}
+
+/* MenuBarItem that has been selected and menu drops down from it */
+.claro .dijitMenuActive .dijitMenuItemHover,
+.claro .dijitMenuActive .dijitMenuItemSelected {
+	border:solid 1px @hovered-border-color;
+	padding: 5px 9px 6px;
+	background-color: @hovered-background-color;
+	background-position:0 0;
+	color:@hovered-text-color;
+}
+.dj_ie .claro .dijitMenuActive .dijitMenuItemHover,
+.dj_ie .claro .dijitMenuActive .dijitMenuItemSelected,
+.dj_ie .claro .dijitMenuPassive .dijitMenuItemHover,
+.dj_ie .claro .dijitMenuPassive .dijitMenuItemSelected {
+	padding-top: 6px;
+	padding-bottom: 5px;
+	margin-top: -3px;
+}
+.claro .dijitMenuActive .dijitMenuItemActive{
+	background-color: @pressed-background-color;
+	background-position:0 -177px;
+}
+.claro .dijitMenuItemActive {
+	background-position:0 -177px;
+}
+.claro td.dijitMenuItemIconCell {
+ padding: 2px;
+ margin: 0 0 0 4px;
+}
+.claro td.dijitMenuItemLabel {
+	padding-top: 5px;
+	padding-bottom: 5px;
+}
+.claro .dijitMenuExpand {
+	width: 7px;
+	height: 7px;
+	background-image: url('images/spriteArrows.png');
+	background-position: -14px 0;
+	margin-right:3px;
+}
+.claro .dijitMenuItemDisabled .dijitMenuItemIconCell {
+	opacity:1;
+}
+.claro .dijitMenuSeparatorTop {
+	height: auto;
+	margin-top:1px; /* prevents spacing above/below separator */
+	border-bottom: 1px solid @border-color
+}
+.claro .dijitMenuSeparatorBottom{
+	height: auto;
+	margin-bottom:1px;
+}
+/* the checked menu item */
+.claro .dijitCheckedMenuItemIconChar {
+	display: none;
+}
+.claro .dijitCheckedMenuItemIcon {
+	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');
+}
+.claro .dijitCheckedMenuItemChecked .dijitCheckedMenuItemIcon {
+	background-position: 0 50%;
+}
+
+/*ComboBox Menu*/
+.claro .dijitComboBoxMenu {
+	margin-left:0;
+	background-image: none;
+}
+
+.claro .dijitComboBoxMenu .dijitMenuItem {
+	padding: @textbox-padding;	// Make drop down menu text line up with text in <input>.
+	border-width:1px 0 1px 0;
+	border-style:solid;
+	border-color: @select-dropdownitem-background-color;
+}
+.claro .dijitComboBoxMenu .dijitMenuItemSelected {
+	color:@selected-text-color;
+	border-color:@hovered-border-color;
+	background-color:@hovered-background-color;
+}
+.claro .dijitComboBoxMenuActive .dijitMenuItemSelected {
+	background-position:0 -177px;
+	background-color: @select-dropdownitem-hovered-background-color;	/* TODO: why is this a different color than normal .dijitMenuItemSelected? */
+}
+.claro .dijitMenuPreviousButton, .claro .dijitMenuNextButton {
+	font-style: italic;
+}
diff --git a/dijit/themes/claro/Menu_rtl.css b/dijit/themes/claro/Menu_rtl.css
index 00e820c..2b96cba 100644
--- a/dijit/themes/claro/Menu_rtl.css
+++ b/dijit/themes/claro/Menu_rtl.css
@@ -1,9 +1,8 @@
 .claro .dijitMenuItemRtl .dijitMenuExpand {
-	background-position: -7px 0px;
-	margin-right: 0px;
-	margin-left: 3px;
+  background-position: -7px 0;
+  margin-right: 0;
+  margin-left: 3px;
 }
-
 .claro .dijitMenuItemRtl .dijitMenuItemIcon {
-	margin:0px 4px 0px 0px;
+  margin: 0 4px 0 0;
 }
diff --git a/dijit/themes/claro/Menu_rtl.less b/dijit/themes/claro/Menu_rtl.less
new file mode 100644
index 0000000..6f669f5
--- /dev/null
+++ b/dijit/themes/claro/Menu_rtl.less
@@ -0,0 +1,11 @@
+ at import "variables";
+
+.claro .dijitMenuItemRtl .dijitMenuExpand {
+	background-position: -7px 0;
+	margin-right: 0;
+	margin-left: 3px;
+}
+
+.claro .dijitMenuItemRtl .dijitMenuItemIcon {
+	margin:0 4px 0 0;
+}
diff --git a/dijit/themes/claro/ProgressBar.css b/dijit/themes/claro/ProgressBar.css
index 57c5a2a..c735e5c 100644
--- a/dijit/themes/claro/ProgressBar.css
+++ b/dijit/themes/claro/ProgressBar.css
@@ -24,30 +24,34 @@
  *		.dijitProgressBarIndeterminate .dijitProgressBarTile 
  * 		sets animated gif for the progress bar in 'indeterminate' mode
  */
- 
 .claro .dijitProgressBar {
-	margin:2px 0px 2px 0px;
+  margin: 2px 0 2px 0;
 }
 .claro .dijitProgressBarEmpty {
-	/* outer container and background of the bar that's not finished yet*/
-	background:#fff url("images/progressBarEmpty.png") repeat-none left;
-	border-color: #769dc0;
+  /* outer container and background of the bar that's not finished yet*/
+
+  background: #ffffff url("images/progressBarEmpty.png") repeat-none left;
+  border-color: #769dc0;
 }
 .claro .dijitProgressBarTile {
-	/* inner container for finished portion when in 'tile' (image) mode */
-	background:#9dcfff url("images/progressBarFull.png") repeat-x top;	
+  /* inner container for finished portion when in 'tile' (image) mode */
+
+  background: #abd6ff url("images/progressBarFull.png") repeat-x top;
 }
 .dj_ie6 .claro .dijitProgressBarTile {
-	background-image: none;
-} 
+  background-image: none;
+}
 .claro .dijitProgressBarFull {
-	border-right:1px solid #769dc0;
+  border-right: 1px solid #769dc0;
 }
 .claro .dijitProgressBarLabel {
-	/* Set to a color that contrasts with both the "Empty" and "Full" parts. */
-	color:#293a4b;
+  /* Set to a color that contrasts with both the "Empty" and "Full" parts. */
+
+  color: #000000;
 }
 .claro .dijitProgressBarIndeterminate .dijitProgressBarTile {
-	/* use an animated gif for the progress bar in 'indeterminate' mode */
-	background:#cad2de url("images/progressBarAnim.gif") repeat-x top;
-} 
\ No newline at end of file
+  /* use an animated gif for the progress bar in 'indeterminate' mode;
+		background-color won't appear unless user has turned off background images */
+
+  background: #efefef url("images/progressBarAnim.gif") repeat-x top;
+}
diff --git a/dijit/themes/claro/ProgressBar.less b/dijit/themes/claro/ProgressBar.less
new file mode 100644
index 0000000..d361952
--- /dev/null
+++ b/dijit/themes/claro/ProgressBar.less
@@ -0,0 +1,56 @@
+/* ProgressBar
+ * 
+ * Styling of the ProgressBar consists of the following:
+ * 
+ * 1. the base progress bar
+ *		.dijitProgressBar -	sets margins for the progress bar
+ *
+ * 2. the empty bar
+ *		.dijitProgressBarEmpty  - sets background img and color for bar or parts of bar that are not finished yet
+ *		Also sets border color for whole bar
+ *
+ * 3. tile mode
+ * 		.dijitProgressBarTile
+ *		inner container for finished portion when in 'tile' (image) mode 
+ * 	
+ * 4. full bar mode
+ * 		.dijitProgressBarFull
+ *		adds border to right side of the filled portion of bar
+ *
+ * 5. text for label of  bar
+ *		.dijitProgressBarLabel - sets text color, which must contrast with both the "Empty" and "Full" parts. 
+ * 	
+ * 6. indeterminate mode
+ *		.dijitProgressBarIndeterminate .dijitProgressBarTile 
+ * 		sets animated gif for the progress bar in 'indeterminate' mode
+ */
+ 
+ @import "variables";
+ 
+.claro .dijitProgressBar {
+	margin:2px 0 2px 0;
+}
+.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;
+	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;	
+}
+.dj_ie6 .claro .dijitProgressBarTile {
+	background-image: none;
+} 
+.claro .dijitProgressBarFull {
+	border-right:1px solid @progressbar-border-color;
+}
+.claro .dijitProgressBarLabel {
+	/* Set to a color that contrasts with both the "Empty" and "Full" parts. */
+	color: @progressbar-text-color;
+}
+.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
diff --git a/dijit/themes/claro/README b/dijit/themes/claro/README
new file mode 100644
index 0000000..5ef4714
--- /dev/null
+++ b/dijit/themes/claro/README
@@ -0,0 +1,64 @@
+These are "less" files that compile into the CSS of claro.
+
+---------
+Installing and running on Windows:
+
+1. Install node:
+    a) Go to https://github.com/ajaxorg/node-builds, press download button, and select "download zip"
+    b) unzip the file into C:\
+
+2. 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:
+
+    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
+
+4. To compile all the files:
+
+	C:\> cd C:\myworkspace\dijit\themes\claro
+	C:\> node compile.js
+
+--------
+To install/run less version 2 on mac:
+
+1. Install Node.js
+	Download a built copy from https://github.com/ajaxorg/node-builds.
+	Alternately, o 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:
+
+	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 3b6ca98..fb8bf5e 100644
--- a/dijit/themes/claro/TimePicker.css
+++ b/dijit/themes/claro/TimePicker.css
@@ -18,108 +18,113 @@
  *
  *	Other classes provide the fundamental structure of the TimePicker and should not be modified. 
  */
-
 /* override Button.css */
 .claro .dijitTimePicker .dijitButtonNode {
-	padding: 0 0;
-	border-radius: 0;
-	-moz-border-radius: 0;
-	-webkit-border-radius: 0;
-}
-.claro .dijitTimePicker{
-	border:1px #b5bcc7 solid;
-	border-top:none;
-	border-bottom:none;
-	background-color:#fff;
-}
-.claro .dijitTimePickerItem{
-	/* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
-	background-image: url("images/commonHighlight.png");
-	background-position:0px -1px;
-	background-repeat:repeat-x;
-	border-top:solid 1px #b5bcc7;
-	border-bottom:solid 1px #b5bcc7;
-	margin-right:-1px;
-	margin-left:-1px;
-	margin-top:-1px;
+  padding: 0 0;
+  -moz-border-radius: 0;
+  border-radius: 0;
+}
+.claro .dijitTimePicker {
+  border: 1px #b5bcc7 solid;
+  border-top: none;
+  border-bottom: none;
+  background-color: #fff;
+  /* TODO: useless?   Appears to be overridden by settings on individual elements */
+
+}
+.claro .dijitTimePickerItem {
+  /* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
+
+  background-image: url("images/commonHighlight.png");
+  background-position: 0 -1px;
+  background-repeat: repeat-x;
+  border-top: solid 1px #b5bcc7;
+  border-bottom: solid 1px #b5bcc7;
+  margin-right: -1px;
+  margin-left: -1px;
+  margin-top: -1px;
 }
 /* to make up for lack of alpha transparency in IE6 */
 .dj_ie6 .claro .dijitTimePickerItem {
-	background-image: none;
+  background-image: none;
 }
 .claro .dijitTimePickerTick {
-	/* minor value */
-	color:#7a7a7a;
-	background-color:#f2f2f2;
-	font-size:0.818em;
+  /* minor value */
+
+  color: #818181;
+  background-color: #efefef;
+  font-size: 0.818em;
 }
 .claro .dijitTimePickerMarker {
-	/* major value - 1:00, 2:00, times on the hour */
-	color:#000;
-	background-color:#e3f2ff;
-	font-size: 1em;
-	white-space: nowrap;
+  /* major value - 1:00, 2:00, times on the hour */
+
+  background-color: #e9f4fe;
+  font-size: 1em;
+  white-space: nowrap;
 }
 .claro .dijitTimePickerTickHover,
 .claro .dijitTimePickerMarkerHover,
 .claro .dijitTimePickerMarkerSelected,
 .claro .dijitTimePickerTickSelected {
-	background-color: #83c0fa;
-	color:#000;
-	border:solid 1px #b5bcc7;
-	margin-left:-7px;
-	margin-right:-7px;
+  background-color: #7dbefa;
+  border: solid 1px #b5bcc7;
+  margin-left: -7px;
+  margin-right: -7px;
+  color: #000000;
+}
+.claro .dijitTimePickerMarkerSelected, .claro .dijitTimePickerTickSelected {
+  font-size: 1em;
 }
-.claro .dijitTimePickerMarkerSelected,
-.claro .dijitTimePickerTickSelected {
-	font-size: 1em;
-	}
 .dj_ie .claro .dijitTimePickerTickHover,
 .dj_ie .claro .dijitTimePickerMarkerHover,
 .dj_ie .claro .dijitTimePickerMarkerSelected,
-.dj_ie .claro .dijitTimePickerTickSelected  {
-	width: 114%;
+.dj_ie .claro .dijitTimePickerTickSelected {
+  width: 114%;
 }
 .dj_ie6 .claro .dijitTimePickerTickHover,
 .dj_ie6 .claro .dijitTimePickerMarkerHover,
 .dj_ie6 .claro .dijitTimePickerMarkerSelected,
-.dj_ie6 .claro .dijitTimePickerTickSelected  {
-	position: relative; /* creates widening of element */	
-	zoom: 1; /* creates widening of element */
+.dj_ie6 .claro .dijitTimePickerTickSelected {
+  position: relative;
+  /* creates widening of element */
+  zoom: 1;
+  /* creates widening of element */
+
 }
 .claro .dijitTimePickerTick .dijitTimePickerItemInner {
-	padding:1px;
-	margin:0px;
+  padding: 1px;
+  margin: 0;
 }
 .claro .dijitTimePicker .dijitButtonNode {
-	border-left:none;
-	border-right:none;
-	border-color:#b5bcc7;
-	background-color: #f6f7fa;
-	background-image: url("images/commonHighlight.png");
-	background-position:0px -1px;
-	background-repeat:repeat-x;
+  border-left: none;
+  border-right: none;
+  border-color: #b5bcc7;
+  background-color: #efefef;
+  background-image: url("images/commonHighlight.png");
+  background-position: 0 -1px;
+  background-repeat: repeat-x;
 }
 .dj_ie6 .claro .dijitTimePicker .dijitButtonNode {
-	background-image: none;
+  background-image: none;
 }
-.claro .dijitTimePicker .dijitArrowButtonInner{
-	height: 100%; /* hack claro.button.css */
-	background-image: url("form/images/commonFormArrows.png");
-	background-repeat: no-repeat;
-	background-position:-140px 45%;
+.claro .dijitTimePicker .dijitArrowButtonInner {
+  height: 100%;
+  /* hack claro.button.css */
+
+  background-image: url("form/images/commonFormArrows.png");
+  background-repeat: no-repeat;
+  background-position: -140px 45%;
 }
-.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner{
-	background-position:-35px 45%;
+.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner {
+  background-position: -35px 45%;
 }
 /* hover */
-.claro .dijitTimePicker .dijitUpArrowHover, 
-.claro .dijitTimePicker .dijitDownArrowHover {
-	background-color: #abd6ff;
+.claro .dijitTimePicker .dijitUpArrowHover, .claro .dijitTimePicker .dijitDownArrowHover {
+  background-color: #abd6ff;
 }
 .claro .dijitTimePicker .dijitUpArrowHover .dijitArrowButtonInner {
-	background-position:-175px 45%;
+  background-position: -175px 45%;
 }
 .claro .dijitTimePicker .dijitDownArrowHover .dijitArrowButtonInner {
-	background-position:-70px 45%;
-}
\ No newline at end of file
+  background-position: -70px 45%;
+}
diff --git a/dijit/themes/claro/TimePicker.less b/dijit/themes/claro/TimePicker.less
new file mode 100644
index 0000000..cd07a63
--- /dev/null
+++ b/dijit/themes/claro/TimePicker.less
@@ -0,0 +1,124 @@
+/* Time Picker 
+ *
+ * Styling the Time Picker consists of the following: 
+ *
+ * 1. minor time values
+ * 		.dijitTimePickerTick - set text color, size, background color of minor values
+ * 		.dijitTimePickerTickHover - set hover style of minor time values
+ * 		dijitTimePickerTickSelected - set selected style of minor time values
+ *
+ * 2. major time values - 1:00, 2:00, times on the hour 
+ * 		set text color, size, background color, left/right margins for "zoom" affect
+ * 		.dijitTimePickerMarkerHover - to set hover style of major time values
+ * 		.dijitTimePickerMarkerSelected - set selected style of major time values
+ * 
+ * 3. up and down arrow buttons
+ * 		.dijitTimePicker .dijitButtonNode - background-color, border
+ * 		.dijitTimePicker .dijitUpArrowHover, .dijitTimePicker .dijitDownArrowHover - set background-color for hover state
+ *
+ *	Other classes provide the fundamental structure of the TimePicker and should not be modified. 
+ */
+
+ at import "variables";
+
+/* override Button.css */
+.claro .dijitTimePicker .dijitButtonNode {
+	padding: 0 0;
+	.border-radius(0);
+}
+.claro .dijitTimePicker{
+	border:1px @border-color solid;
+	border-top:none;
+	border-bottom:none;
+	background-color:#fff;	/* TODO: useless?   Appears to be overridden by settings on individual elements */
+}
+.claro .dijitTimePickerItem{
+	/* dijitTimePickerItem refers to both Tick's (minor values like 2:15, 2:30, 2:45) and Marker's (major values like 2PM, 3PM) */
+	background-image: url("images/commonHighlight.png");
+	background-position:0 -1px;
+	background-repeat:repeat-x;
+	border-top:solid 1px @border-color;
+	border-bottom:solid 1px @border-color;
+	margin-right:-1px;
+	margin-left:-1px;
+	margin-top:-1px;
+}
+/* to make up for lack of alpha transparency in IE6 */
+.dj_ie6 .claro .dijitTimePickerItem {
+	background-image: none;
+}
+.claro .dijitTimePickerTick {
+	/* minor value */
+	color:@timepicker-minorvalue-text-color;
+	background-color:@timepicker-minorvalue-background-color;
+	font-size:0.818em;
+}
+.claro .dijitTimePickerMarker {
+	/* major value - 1:00, 2:00, times on the hour */
+	background-color: @timepicker-majorvalue-background-color;
+	font-size: 1em;
+	white-space: nowrap;
+}
+.claro .dijitTimePickerTickHover,
+.claro .dijitTimePickerMarkerHover,
+.claro .dijitTimePickerMarkerSelected,
+.claro .dijitTimePickerTickSelected {
+	background-color: @timepicker-value-hovered-background-color;
+	border:solid 1px @border-color;
+	margin-left:-7px;
+	margin-right:-7px;
+	color:@timepicker-value-hovered-text-color;
+}
+.claro .dijitTimePickerMarkerSelected,
+.claro .dijitTimePickerTickSelected {
+	font-size: 1em;
+}
+.dj_ie .claro .dijitTimePickerTickHover,
+.dj_ie .claro .dijitTimePickerMarkerHover,
+.dj_ie .claro .dijitTimePickerMarkerSelected,
+.dj_ie .claro .dijitTimePickerTickSelected  {
+	width: 114%;
+}
+.dj_ie6 .claro .dijitTimePickerTickHover,
+.dj_ie6 .claro .dijitTimePickerMarkerHover,
+.dj_ie6 .claro .dijitTimePickerMarkerSelected,
+.dj_ie6 .claro .dijitTimePickerTickSelected  {
+	position: relative; /* creates widening of element */	
+	zoom: 1; /* creates widening of element */
+}
+.claro .dijitTimePickerTick .dijitTimePickerItemInner {
+	padding:1px;
+	margin:0;
+}
+.claro .dijitTimePicker .dijitButtonNode {
+	border-left:none;
+	border-right:none;
+	border-color:@border-color;
+	background-color: @unselected-background-color;
+	background-image: url("images/commonHighlight.png");
+	background-position:0 -1px;
+	background-repeat:repeat-x;
+}
+.dj_ie6 .claro .dijitTimePicker .dijitButtonNode {
+	background-image: none;
+}
+.claro .dijitTimePicker .dijitArrowButtonInner{
+	height: 100%; /* hack claro.button.css */
+	background-image: url("form/images/commonFormArrows.png");
+	background-repeat: no-repeat;
+	background-position:-140px 45%;
+}
+.claro .dijitTimePicker .dijitDownArrowButton .dijitArrowButtonInner{
+	background-position:-35px 45%;
+}
+/* hover */
+.claro .dijitTimePicker .dijitUpArrowHover, 
+.claro .dijitTimePicker .dijitDownArrowHover {
+	background-color: @timepicker-arrow-hovered-background-color;
+}
+.claro .dijitTimePicker .dijitUpArrowHover .dijitArrowButtonInner {
+	background-position:-175px 45%;
+}
+.claro .dijitTimePicker .dijitDownArrowHover .dijitArrowButtonInner {
+	background-position:-70px 45%;
+}
diff --git a/dijit/themes/claro/TimePicker_rtl.css b/dijit/themes/claro/TimePicker_rtl.css
index 0a471a9..6dfcf83 100644
--- a/dijit/themes/claro/TimePicker_rtl.css
+++ b/dijit/themes/claro/TimePicker_rtl.css
@@ -1,10 +1,9 @@
 /* TimePicker */
-
 .dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickHover,
 .dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerHover,
 .dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerSelected,
 .dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickSelected {
-	margin-left:-6px;
-	margin-right:-8px;
-	width: 114%;	
-}
\ No newline at end of file
+  margin-left: -6px;
+  margin-right: -8px;
+  width: 114%;
+}
diff --git a/dijit/themes/claro/TimePicker_rtl.less b/dijit/themes/claro/TimePicker_rtl.less
new file mode 100644
index 0000000..44f5da5
--- /dev/null
+++ b/dijit/themes/claro/TimePicker_rtl.less
@@ -0,0 +1,12 @@
+/* TimePicker */
+
+ at import "variables";
+
+.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickHover,
+.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerHover,
+.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerMarkerSelected,
+.dj_ie .claro .dijitTimePickerRtl .dijitTimePickerTickSelected {
+	margin-left:-6px;
+	margin-right:-8px;
+	width: 114%;	
+}
\ No newline at end of file
diff --git a/dijit/themes/claro/TitlePane.css b/dijit/themes/claro/TitlePane.css
index b7bdecb..7f0cdbf 100644
--- a/dijit/themes/claro/TitlePane.css
+++ b/dijit/themes/claro/TitlePane.css
@@ -17,57 +17,57 @@
  * 1. outer/inner container: 
  * 		.dijitTitlePaneContentOuter / dijitTitlePaneContentInner - styles for the content outer div
  */
-
 .claro .dijitTitlePaneTitle {
-	background-color: #e6e6e7;
-	background-image: url("images/titlebar.png");
-	background-repeat:repeat-x;
-	border:1px solid #b5bcc7;
-	padding: 0px 7px 3px 7px;
-	min-height:17px;
-	color:#131313;
+  background-color: #efefef;
+  background-image: url("images/titlebar.png");
+  background-repeat: repeat-x;
+  border: 1px solid #b5bcc7;
+  padding: 0 7px 3px 7px;
+  min-height: 17px;
 }
 .dj_ie6 .claro .dijitTitlePaneTitle {
-	background-image: none;
+  background-image: none;
 }
 .claro .dijitTitlePaneTitleHover {
-	background-color: #abd6ff;
-	border-color: #769dc0;
+  background-color: #abd6ff;
+  border-color: #769dc0;
 }
 .claro .dijitTitlePaneTitleActive {
-	background-color: #7dbefa;
-	border-color: #769dc0;
-	background-position:0px -136px;
+  background-color: #7dbefa;
+  border-color: #769dc0;
+  background-position: 0 -136px;
 }
 .claro .dijitTitlePaneTitleFocus {
-	margin-top:3px;
-	padding-bottom:2px;
+  margin-top: 3px;
+  padding-bottom: 2px;
 }
 .claro .dijitTitlePane .dijitArrowNode {
-	background-image: url('images/spriteArrows.png');
-	background-repeat: no-repeat;
-	height: 8px;
-	width: 7px;
+  background-image: url('images/spriteArrows.png');
+  background-repeat: no-repeat;
+  height: 8px;
+  width: 7px;
 }
 .claro .dijitTitlePane .dijitOpen .dijitArrowNode {
-	background-position: 0px 0px;
+  background-position: 0 0;
 }
 .claro .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: -14px 0px;
+  background-position: -14px 0;
 }
 .claro .dijitTitlePaneFocused .dijitTitlePaneTextNode {
-	color:#000;
+  color: #000000;
+  /* TODO: do we need this?   we usually don't change text color on focus */
+
 }
 .claro .dijitTitlePaneContentOuter {
-	background: #ffffff;
-	border:1px solid #b5bcc7;
-	border-top:none;
+  background: #ffffff;
+  border: 1px solid #b5bcc7;
+  border-top: none;
 }
 .claro .dijitTitlePaneContentInner {
-	padding:10px;
+  padding: 10px;
 }
 .claro .dijitTitlePaneTextNode {
-	margin-left: 4px;
-	margin-right: 4px;
-	vertical-align:text-top;
-}
\ No newline at end of file
+  margin-left: 4px;
+  margin-right: 4px;
+  vertical-align: text-top;
+}
diff --git a/dijit/themes/claro/TitlePane.less b/dijit/themes/claro/TitlePane.less
new file mode 100644
index 0000000..22bacca
--- /dev/null
+++ b/dijit/themes/claro/TitlePane.less
@@ -0,0 +1,74 @@
+/* TitlePane 
+ * 
+ * Styling TitlePane means styling the TitlePane title and its content container  (dijitTitlePane)
+ * 
+ * TitlePane title:
+ * 1. TitlePane title (default styling): 
+ * 		.dijitTitlePaneTitle - TitlePane's title div style: background-color, border
+ *
+ * 2. hovered TitlePane title (ie, mouse hover on a title bar)
+ * 		.dijitTitlePaneTitleHover - styles when mouse hover on the title div
+ * 
+ * 3. active TitlePane title (ie, mouse down on a title bar)
+ * 		.dijitTitlePaneTitleActive - styles when mouse down on the title div
+ * 
+ * 
+ * TitlePane Content Container:
+ * 1. outer/inner container: 
+ * 		.dijitTitlePaneContentOuter / dijitTitlePaneContentInner - styles for the content outer div
+ */
+
+ at import "variables";
+
+.claro .dijitTitlePaneTitle {
+	background-color: @unselected-background-color;	// TODO: Mailed Jason, shouldn't this toggle to @selected-background-color when pane opened?
+	background-image: url("images/titlebar.png");
+	background-repeat:repeat-x;
+	border:1px solid @border-color;
+	padding: 0 7px 3px 7px;
+	min-height:17px;
+}
+.dj_ie6 .claro .dijitTitlePaneTitle {
+	background-image: none;
+}
+.claro .dijitTitlePaneTitleHover {
+	background-color: @hovered-background-color;
+	border-color: @hovered-border-color;
+}
+.claro .dijitTitlePaneTitleActive {
+	background-color: @pressed-background-color;
+	border-color: @pressed-border-color;
+	background-position:0 -136px;
+}
+.claro .dijitTitlePaneTitleFocus {
+	margin-top:3px;
+	padding-bottom:2px;
+}
+.claro .dijitTitlePane .dijitArrowNode {
+	background-image: url('images/spriteArrows.png');
+	background-repeat: no-repeat;
+	height: 8px;
+	width: 7px;
+}
+.claro .dijitTitlePane .dijitOpen .dijitArrowNode {
+	background-position: 0 0;
+}
+.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 .dijitTitlePaneContentOuter {
+	background: @pane-background-color;
+	border:1px solid @border-color;
+	border-top:none;
+}
+.claro .dijitTitlePaneContentInner {
+	padding:10px;
+}
+.claro .dijitTitlePaneTextNode {
+	margin-left: 4px;
+	margin-right: 4px;
+	vertical-align:text-top;
+}
\ No newline at end of file
diff --git a/dijit/themes/claro/TitlePane_rtl.css b/dijit/themes/claro/TitlePane_rtl.css
index a0e2856..3f68ab3 100644
--- a/dijit/themes/claro/TitlePane_rtl.css
+++ b/dijit/themes/claro/TitlePane_rtl.css
@@ -1,4 +1,4 @@
 /* TitlePane */
 .claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
-	background-position: -7px 0px;
-}
\ No newline at end of file
+  background-position: -7px 0;
+}
diff --git a/dijit/themes/claro/TitlePane_rtl.less b/dijit/themes/claro/TitlePane_rtl.less
new file mode 100644
index 0000000..693584f
--- /dev/null
+++ b/dijit/themes/claro/TitlePane_rtl.less
@@ -0,0 +1,7 @@
+/* TitlePane */
+
+ at import "variables";
+
+.claro .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
+	background-position: -7px 0;
+}
\ No newline at end of file
diff --git a/dijit/themes/claro/Toolbar.css b/dijit/themes/claro/Toolbar.css
index a222aa5..a9e6f4f 100644
--- a/dijit/themes/claro/Toolbar.css
+++ b/dijit/themes/claro/Toolbar.css
@@ -17,154 +17,142 @@
  * 4. actived widget inside toolbar (ie, mouse down on the widget inside)
  * 			.dijitToolbar .dijitButtonNodeActive  - mouse down on Button widget
  */
-
 .claro .dijitToolbar {
-	border-bottom: 1px solid #b5bcc7;
-	background-color: #f1f1f1;
-	background-image: url("images/commonHighlight.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
-	padding: 2px 0px 2px 4px;
-	zoom: 1;
+  border-bottom: 1px solid #b5bcc7;
+  background-color: #efefef;
+  background-image: url("images/commonHighlight.png");
+  background-position: 0 0;
+  background-repeat: repeat-x;
+  padding: 2px 0 2px 4px;
+  zoom: 1;
 }
-
 .claro .dijitToolbar label {
-	padding: 0px 3px 0 6px;
+  padding: 0 3px 0 6px;
 }
-
 /** override claro/form/Button.css **/
 .claro .dijitToolbar .dijitButtonNode {
-	border:none;
-	padding: 2px;
-	background-image: url("images/commonHighlight.png");
-	background-position:0 -30px;
-	background-repeat:repeat-x;
-	background-color:rgba(171,214,255,0);
-	border-radius: 2px;	
-	-moz-border-radius: 2px;	
-	-webkit-border-radius: 2px;	
-	-moz-box-shadow: none;
-	-webkit-box-shadow: none;
-	-webkit-transition-property:background-color;
-	-webkit-transition-duration:.3s, .35s;
-}
-.claro .dijitToolbar .dijitComboButton .dijitButtonNode{
-	padding: 3px 2px 3px 2px;	/* make the ComboButton in toolbar more stable when mouse hovering */
+  border-width: 0;
+  /* on hover/active, border-->1px, padding-->1px */
+
+  padding: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+  -webkit-transition-property: background-color;
+  -moz-transition-property: background-color;
+  transition-property: background-color;
+  -webkit-transition-duration: 0.3s, 0.35s;
+  -moz-transition-duration: 0.3s, 0.35s;
+  transition-duration: 0.3s, 0.35s;
+  background-image: url("images/commonHighlight.png");
+  background-position: 0 -30px;
+  background-repeat: repeat-x;
+  background-color: rgba(171, 214, 255, 0);
 }
 .dj_ie .claro .dijitToolbar .dijitButtonNode {
-	background-color: transparent;   /* for IE, which doesn't understand rgba(...) */
+  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 */
+  background: none;
+  /* because background-color: transparent above doesn't work */
+
 }
+.claro .dijitToolbar .dijitComboButton .dijitStretch {
+  /* no rounded border on side adjacent to arrow */
 
-.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
-	padding: 0px;
+  -moz-border-radius: 2px 0 0 2px;
+  border-radius: 2px 0 0 2px;
 }
+.claro .dijitToolbar .dijitComboButton .dijitArrowButton {
+  /* no rounded border on side adjacent to button */
 
-.claro .dijitToolbar .dijitComboButton {
-	padding: 1px;
+  -moz-border-radius: 0 2px 2px 0;
+  border-radius: 0 2px 2px 0;
+}
+.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
+  padding: 0;
 }
 /* hover status */
 .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
 .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
-.claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode {
-	background-position:0 0;
-	border:solid 1px #769dc0;
-	background-color: #abd6ff;
-	padding: 1px;
-}
-.claro .dijitToolbar .dijitComboButtonHover {
-	background-color: #abd6ff;
-	border: solid 1px #769dc0;
-	padding: 0px;
-}
-.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode,
-.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
-	background-position:0 0;
-	padding: 2px;
-}
-.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
-	background-color: #7dd6fa;
-}
-/* actve status */
-.claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
-.claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
-.claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
-	border:solid 1px #769dc0;
-	background-color:#7dbefa;
-	background-position:0px -177px;
-	padding: 1px;
+.claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode {
+  background-position: 0 0;
+  border-width: 1px;
+  background-color: #abd6ff;
+  padding: 1px;
+}
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
+  background-position: 0 0;
+  background-color: #f4ffff;
+}
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover, .claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
+  background-color: #abd6ff;
+}
+/* active status */
+.claro .dijitToolbar .dijitButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
+  border-width: 1px;
+  background-color: #7dbefa;
+  background-position: 0 -177px;
+  padding: 1px;
 }
 .claro .dijitToolbar .dijitComboButtonActive {
-	-webkit-transition-duration:.2s;
-	border: solid 1px #769dc0;
-	padding: 0px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+  border-width: 1px;
+  padding: 0;
 }
-.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode {
-	background-color: #7dbefa;
-	background-position:0px -177px;
-	padding: 2px;
+.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
+  background-color: #f4ffff;
+  background-position: 0 -177px;
+  padding: 2px;
 }
-.claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonActive {
-	background-color: #7dbefa;
+.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
+  background-color: #7dbefa;
 }
-/* toggle button checked status */
-.claro .dijitToolbar .dijitToggleButtonChecked .dijitButtonNode {
-	border-color: #769dc0;
-	background-color:#fff;
-	padding: 1px;
+.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
+  background-color: #7dbefa;
 }
-
-
-/** hacks for browsers **/
-.dj_ie6 .claro .dijitToolbar .dijitButtonContents, 
-.dj_ie7 .claro .dijitToolbar .dijitButtonContents {
-	margin: -2px 0;
-	padding: 0;
-}
-
-.dj_ie6 .claro .dijitToolbar {
-	background-image: none;
+/* Avoid double border between button and arrow */
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton, .claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
+  border-left-width: 0;
 }
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
+  padding-left: 2px;
+  /* since there's no left border, don't reduce from 2px --> 1px */
 
-.dj_ie6 .claro .dijitToolbar .dijitButtonNode {
-	margin: 1px; /* as transparent the border */
-	border: none;
 }
-
-.dj_ie6 .claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitButtonNodeHover,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover,
-.dj_ie6 .claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitButtonNodeActive,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonActive,
-.dj_ie6 .claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode,
+/* toggle button checked status */
 .claro .dijitToolbar .dijitToggleButtonChecked .dijitButtonNode {
-	margin: 0;	/* remove margin and add a border */
-	border-width: 1px;
-	border-style: solid;
-	background-image: none;
-}
+  margin: 0;
+  /* remove margin and add a border */
 
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitButtonNodeHover,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitButtonNodeActive,
-.dj_ie6 .claro .dijitToolbar .dijitComboButton .dijitDownArrowButtonActive {
-	padding: 1px;	/* ComboButton use table td has no margin, so we minus padding 2px -> 1px for the 1px border. ie6... */
+  border-width: 1px;
+  border-style: solid;
+  background-image: none;
+  border-color: #769dc0;
+  background-color: #ffffff;
+  padding: 1px;
 }
-
-.claro .dijitToolbarSeparator {
-	/* separator icon in the editor sprite */
-	background: url('../../icons/images/editorIconsEnabled.png');
+.dj_ie6 .claro .dijitToolbar {
+  background-image: none;
 }
+.claro .dijitToolbarSeparator {
+  /* separator icon in the editor sprite */
 
+  background: url('../../icons/images/editorIconsEnabled.png');
+}
 /* Toolbar inside of disabled Editor */
 .claro .dijitDisabled .dijitToolbar {
-	background:none;
-	background-color:#f5f5f5;
-	border-bottom: 1px solid #d3d3d3;
+  background: none;
+  background-color: #efefef;
+  border-bottom: 1px solid #d3d3d3;
+}
+.claro .dijitToolbar .dijitComboBoxDisabled .dijitArrowButtonInner {
+  background-position: 0 50%;
 }
diff --git a/dijit/themes/claro/Toolbar.less b/dijit/themes/claro/Toolbar.less
new file mode 100644
index 0000000..eb99f2f
--- /dev/null
+++ b/dijit/themes/claro/Toolbar.less
@@ -0,0 +1,157 @@
+/* Toolbar 
+ * 
+ * Styling Toolbar means styling the toolbar container and the widget inside toolbar  (dijitToolbar)
+ * 
+ * 1. toolbar (default styling): 
+ * 		.dijitToolbar - styles for outer container
+ *
+ * 2. widget inside toolbar
+ * 		.dijitToolbar .dijitButtonNode   - Button widget
+ * 					  .dijitComboButton  - ComboButton widget
+ * 					  .dijitDropDownButton  - DropDownButton widget
+ * 					  .dijitToggleButton  - ToggleButton widget
+ * 		
+ * 3. hovered widget inside toolbar (ie, mouse hover on the widget inside)
+ * 			.dijitToolbar .dijitButtonNodeHover  - styles for hovered Button widget
+ * 
+ * 4. actived widget inside toolbar (ie, mouse down on the widget inside)
+ * 			.dijitToolbar .dijitButtonNodeActive  - mouse down on Button widget
+ */
+
+ at import "variables";
+
+.claro .dijitToolbar {
+	border-bottom: 1px solid @border-color;
+	background-color: @bar-background-color;
+	background-image: url("images/commonHighlight.png");
+	background-position:0 0;
+	background-repeat:repeat-x;
+	padding: 2px 0 2px 4px;
+	zoom: 1;
+}
+
+.claro .dijitToolbar label {
+	padding: 0 3px 0 6px;
+}
+
+/** override claro/form/Button.css **/
+.claro .dijitToolbar .dijitButtonNode {
+	border-width: 0;	/* on hover/active, border-->1px, padding-->1px */
+	padding: 2px;
+	.border-radius(@toolbar-button-border-radius);
+	.box-shadow(none);
+	.transition-property(background-color);
+	.transition-duration(.3s, .35s);
+
+	background-image: url("images/commonHighlight.png");
+	background-position:0 -30px;
+	background-repeat:repeat-x;
+	background-color:rgba(171,214,255,0);
+}
+.dj_ie .claro .dijitToolbar .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 */
+}
+
+.claro .dijitToolbar .dijitComboButton .dijitStretch {
+	/* no rounded border on side adjacent to arrow */
+	.border-radius(@toolbar-button-border-radius 0 0 @toolbar-button-border-radius);
+}
+.claro .dijitToolbar .dijitComboButton .dijitArrowButton {
+	/* no rounded border on side adjacent to button */
+	.border-radius(0 @toolbar-button-border-radius @toolbar-button-border-radius 0);
+}
+
+.claro .dijitToolbar .dijitComboBox .dijitButtonNode {
+	padding: 0;
+}
+
+/* hover status */
+.claro .dijitToolbar .dijitButtonHover .dijitButtonNode,
+.claro .dijitToolbar .dijitDropDownButtonHover .dijitButtonNode,
+.claro .dijitToolbar .dijitToggleButtonHover .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode {
+	background-position:0 0;
+	border-width:1px;
+	background-color: @hovered-background-color;
+	padding: 1px;
+}
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
+	background-position:0 0;
+	background-color: @toolbar-combobutton-hovered-unhoveredsection-background-color;
+}
+.claro .dijitToolbar .dijitComboButtonHover .dijitButtonNodeHover,
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButtonHover {
+	background-color: @hovered-background-color;
+}
+
+/* active status */
+.claro .dijitToolbar .dijitButtonActive .dijitButtonNode,
+.claro .dijitToolbar .dijitDropDownButtonActive .dijitButtonNode,
+.claro .dijitToolbar .dijitToggleButtonActive .dijitButtonNode {
+	border-width: 1px;
+	background-color:@pressed-background-color;
+	background-position:0 -177px;
+	padding: 1px;
+}
+.claro .dijitToolbar .dijitComboButtonActive {
+	.transition-duration(.2s);
+	border-width: 1px;
+	padding: 0;
+}
+.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
+	background-color: @toolbar-combobutton-hovered-unhoveredsection-background-color;
+	background-position:0 -177px;
+	padding: 2px;
+}
+.claro .dijitToolbar .dijitComboButtonActive .dijitButtonNodeActive {
+	background-color: @pressed-background-color;
+}
+.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButtonActive {
+	background-color: @pressed-background-color;
+}
+
+/* Avoid double border between button and arrow */
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton,
+.claro .dijitToolbar .dijitComboButtonActive .dijitDownArrowButton {
+	border-left-width: 0;
+}
+.claro .dijitToolbar .dijitComboButtonHover .dijitDownArrowButton {
+	padding-left: 2px;		/* since there's no left border, don't reduce from 2px --> 1px */
+}
+
+/* toggle button checked status */
+.claro .dijitToolbar .dijitToggleButtonChecked .dijitButtonNode {
+	margin: 0;	/* remove margin and add a border */
+	border-width: 1px;
+	border-style: solid;
+	background-image: none;
+	border-color: @selected-border-color;
+	background-color: @toolbar-button-checked-background-color;
+	padding: 1px;
+}
+
+.dj_ie6 .claro .dijitToolbar {
+	background-image: none;
+}
+
+.claro .dijitToolbarSeparator {
+	/* separator icon in the editor sprite */
+	background: url('../../icons/images/editorIconsEnabled.png');
+}
+
+/* Toolbar inside of disabled Editor */
+.claro .dijitDisabled .dijitToolbar {
+	background:none;
+	background-color:@disabled-background-color;
+	border-bottom: 1px solid @disabled-border-color;
+}
+
+.claro .dijitToolbar .dijitComboBoxDisabled .dijitArrowButtonInner {
+	background-position:0 50%;
+}
+
diff --git a/dijit/themes/claro/Toolbar_rtl.css b/dijit/themes/claro/Toolbar_rtl.css
new file mode 100644
index 0000000..2fab1de
--- /dev/null
+++ b/dijit/themes/claro/Toolbar_rtl.css
@@ -0,0 +1,30 @@
+/* Toolbar RTL */
+/* Repeated rules from Toolbar.css to override rule from Button_rtl.css, which is loaded after Toolbar.css */
+.claro .dijitToolbar .dijitComboButtonRtl .dijitButtonNode {
+  border-width: 0;
+  padding: 2px;
+}
+.claro .dijitToolbar .dijitComboButtonRtlHover .dijitButtonNode, .claro .dijitToolbar .dijitComboButtonRtlActive .dijitButtonNode {
+  border-width: 1px;
+  padding: 1px;
+}
+.claro .dijitToolbar .dijitComboButtonRtl .dijitStretch {
+  /* no rounded border on side adjacent to arrow */
+
+  -moz-border-radius: 0 2px 2px 0;
+  border-radius: 0 2px 2px 0;
+}
+.claro .dijitToolbar .dijitComboButtonRtl .dijitArrowButton {
+  /* no rounded border on side adjacent to button */
+
+  -moz-border-radius: 2px 0 0 2px;
+  border-radius: 2px 0 0 2px;
+}
+.claro .dijitToolbar .dijitComboButtonRtlHover .dijitArrowButton, .claro .dijitToolbar .dijitComboButtonRtlActive .dijitArrowButton {
+  /* border between button and arrow */
+
+  border-left-width: 1px;
+  border-right-width: 0;
+  padding-left: 1px;
+  padding-right: 2px;
+}
diff --git a/dijit/themes/claro/Toolbar_rtl.less b/dijit/themes/claro/Toolbar_rtl.less
new file mode 100644
index 0000000..8d31c88
--- /dev/null
+++ b/dijit/themes/claro/Toolbar_rtl.less
@@ -0,0 +1,32 @@
+/* Toolbar RTL */
+
+ at import "variables";
+
+/* Repeated rules from Toolbar.css to override rule from Button_rtl.css, which is loaded after Toolbar.css */
+.claro .dijitToolbar .dijitComboButtonRtl .dijitButtonNode {
+	border-width: 0;
+	padding: 2px;
+}
+.claro .dijitToolbar .dijitComboButtonRtlHover .dijitButtonNode,
+.claro .dijitToolbar .dijitComboButtonRtlActive .dijitButtonNode {
+	border-width: 1px;
+	padding: 1px;
+}
+
+.claro .dijitToolbar .dijitComboButtonRtl .dijitStretch {
+	/* no rounded border on side adjacent to arrow */
+	.border-radius(0 2px 2px 0);
+}
+.claro .dijitToolbar .dijitComboButtonRtl .dijitArrowButton {
+	/* no rounded border on side adjacent to button */
+	.border-radius(2px 0 0 2px);
+}
+
+.claro .dijitToolbar .dijitComboButtonRtlHover .dijitArrowButton,
+.claro .dijitToolbar .dijitComboButtonRtlActive .dijitArrowButton {
+	/* border between button and arrow */
+	border-left-width: 1px;
+	border-right-width: 0;
+	padding-left: 1px;
+	padding-right: 2px;
+}
diff --git a/dijit/themes/claro/Tree.css b/dijit/themes/claro/Tree.css
index 9158c40..069deb8 100644
--- a/dijit/themes/claro/Tree.css
+++ b/dijit/themes/claro/Tree.css
@@ -22,101 +22,113 @@
  * Drag and Drop on TreeNodes: (insert line on dijitTreeContent node so it'll aligned w/ target element)
  * 		.dijitTreeNode .dojoDndItemBefore/.dojoDndItemAfter - use border style simulate a separate line
  */
-
 .claro .dijitTreeNode {
-    zoom: 1;	/* force layout on IE (TODO: may not be needed anymore) */
+  zoom: 1;
+  /* force layout on IE (TODO: may not be needed anymore) */
+
 }
 .claro .dijitTreeIsRoot {
-    background-image: none;
-}
-.claro .dijitTreeRow {
-	/* so insert line shows up on IE when dropping after a target element */
-	padding: 4px 1px 2px 0px;
-	margin-left: 1px;
-	background-image: url("images/commonHighlight.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
-	border-color: rgba(118,157,192,0);
-	background-color: rgba(171,214,255,0);
-	-webkit-transition-property:background-color, border-color;
-	-webkit-transition-duration:.25s ;
-	-webkit-transition-timing-function: ease-out;
+  background-image: none;
+}
+/* Styling for basic tree node (unhovered, unselected)
+ * Also use this styling when dropping between items on the tree (in other words, don't
+ * use hover effect)
+ */
+.claro .dijitTreeRow, .claro .dijitTreeNode .dojoDndItemBefore, .claro .dijitTreeNode .dojoDndItemAfter {
+  /* so insert line shows up on IE when dropping after a target element */
+
+  padding: 4px 1px 2px 0;
+  margin: 0 1px;
+  /* replaced by border for selected/hovered row */
+
+  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;
+  -webkit-transition-property: background-color, border-color;
+  -moz-transition-property: background-color, border-color;
+  transition-property: background-color, border-color;
+  -webkit-transition-duration: 0.25s;
+  -moz-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  -webkit-transition-timing-function: ease-out;
+  -moz-transition-timing-function: ease-out;
+  transition-timing-function: ease-out;
 }
 .dj_ie6 .claro .dijitTreeRow {
-	background-image: none;
+  background-image: none;
 }
-
 .claro .dijitTreeRowSelected {
-	background-repeat:repeat-x;
-	background-color:#d8edff;
-	padding: 3px 0px 1px;
-	margin-left: 0px;
-	border:solid 1px #c3e2fd;
-	color:#000;
+  background-repeat: repeat-x;
+  background-color: #cfe5fa;
+  padding: 3px 0 1px;
+  margin: 0;
+  border: solid 1px #769dc0;
+  color: #000000;
 }
 .claro .dijitTreeRowHover {
-	background-color:#abd6ff;
-	padding: 3px 0px 1px;
-	margin-left: 0px;
-	border:solid 1px #769dc0;
-	color:#000;
-	-webkit-transition-duration:.25s ; 
+  background-color: #abd6ff;
+  padding: 3px 0 1px;
+  margin: 0;
+  border: solid 1px #769dc0;
+  color: #000000;
+  -webkit-transition-duration: 0.25s;
+  -moz-transition-duration: 0.25s;
+  transition-duration: 0.25s;
 }
 .claro .dijitTreeRowActive {
-	background-color:#7dbefa;
-	background-position:0px -177px;
-	padding: 3px 0px 1px;
-	margin-left: 0px;
-	border:solid 1px #769dc0;
-	color:#000;
+  background-color: #7dbefa;
+  background-position: 0 -177px;
+  padding: 3px 0 1px;
+  margin-left: 0;
+  border: solid 1px #769dc0;
+  color: #000000;
 }
 .dj_ie6 .claro .dijitTreeRowActive {
-	background-image: none;
+  background-image: none;
 }
 .claro .dijitTreeRowFocused {
-	background-repeat: repeat;
+  background-repeat: repeat;
 }
-
 /* expando (open/closed) icon */
-
 .claro .dijitTreeExpando {
-	background-image: url('images/treeExpandImages.png');
-    width: 16px;
-    height: 16px;
-	background-position: -35px 0px		/* for dijitTreeExpandoOpened */
+  background-image: url('images/treeExpandImages.png');
+  width: 16px;
+  height: 16px;
+  background-position: -35px 0;
+  /* for dijitTreeExpandoOpened */
+
 }
 .dj_ie6 .claro .dijitTreeExpando {
-	background-image: url('images/treeExpandImages8bit.png');
+  background-image: url('images/treeExpandImages8bit.png');
 }
 .claro .dijitTreeRowHover .dijitTreeExpandoOpened {
-	background-position: -53px 0px;
+  background-position: -53px 0;
 }
 .claro .dijitTreeExpandoClosed {
-	background-position: 1px 0px;
+  background-position: 1px 0;
 }
 .claro .dijitTreeRowHover .dijitTreeExpandoClosed {
-	background-position: -17px 0px;
+  background-position: -17px 0;
 }
-.claro .dijitTreeExpandoLeaf{
-	background-image:none;
+.claro .dijitTreeExpandoLeaf, .dj_ie6 .claro .dijitTreeExpandoLeaf {
+  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/
  * (ie, indented equally with) target element, even
  * though dijitTreeRowNode is the actual "drag object"
  */
-.claro .dijitTreeNode .dojoDndItemBefore,
-.claro .dijitTreeNode .dojoDndItemAfter {
-	border-bottom: none;
-	border-top: none;
-}
 .claro .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
-	border-top: 2px solid #369;
+  border-top: 2px solid #769dc0;
 }
 .claro .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
-	border-bottom: 2px solid #369;
+  border-bottom: 2px solid #769dc0;
 }
diff --git a/dijit/themes/claro/Tree.less b/dijit/themes/claro/Tree.less
new file mode 100644
index 0000000..4e639ca
--- /dev/null
+++ b/dijit/themes/claro/Tree.less
@@ -0,0 +1,133 @@
+/* Tree 
+ * 
+ * Styling Tree mostly means styling the TreeRow (dijitTreeRow)
+ * There are 4 basic states to style:
+ * 
+ * Tree Row:
+ * 1. tree row (default styling): 
+ * 		.dijitTreeRow - styles for each row of the tree
+ *
+ * 2. hovered tree row (mouse hover on a tree row)
+ * 		.dijitTreeRowHover - styles when mouse over on one row
+ * 
+ * 3. active tree row (mouse down on a tree row)
+ * 		.dijitTreeRowActive - styles when mouse down on one row
+ * 
+ * 4. selected tree row
+ * 		dijitTreeRowSelected - style when the row has been selected
+ * 
+ * Tree Expando:
+ * 	    dijitTreeExpando - the expando at the left of the text of each tree row
+ * 
+ * Drag and Drop on TreeNodes: (insert line on dijitTreeContent node so it'll aligned w/ target element)
+ * 		.dijitTreeNode .dojoDndItemBefore/.dojoDndItemAfter - use border style simulate a separate line
+ */
+
+ at import "variables";
+
+.claro .dijitTreeNode {
+    zoom: 1;	/* force layout on IE (TODO: may not be needed anymore) */
+}
+.claro .dijitTreeIsRoot {
+    background-image: none;
+}
+
+/* Styling for basic tree node (unhovered, unselected)
+ * Also use this styling when dropping between items on the tree (in other words, don't
+ * use hover effect)
+ */
+.claro .dijitTreeRow,
+.claro .dijitTreeNode .dojoDndItemBefore,
+.claro .dijitTreeNode .dojoDndItemAfter {
+	/* so insert line shows up on IE when dropping after a target element */
+	padding: 4px 1px 2px 0;
+	margin: 0 1px;	/* replaced by border for selected/hovered row */
+
+	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;
+
+	.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;
+	padding: 3px 0 1px;
+	margin: 0;
+	border:solid 1px @selected-border-color;
+	color:@selected-text-color;
+}
+.claro .dijitTreeRowHover {
+	background-color:@hovered-background-color;
+	padding: 3px 0 1px;
+	margin: 0;
+	border:solid 1px @hovered-border-color;
+	color:@hovered-text-color;
+	.transition-duration(.25s);
+}
+.claro .dijitTreeRowActive {
+	background-color:@pressed-background-color;
+	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 {
+	background-image: none;
+}
+.claro .dijitTreeRowFocused {
+	background-repeat: repeat;
+}
+
+/* expando (open/closed) icon */
+
+.claro .dijitTreeExpando {
+	background-image: url('images/treeExpandImages.png');
+    width: 16px;
+    height: 16px;
+	background-position: -35px 0;		/* for dijitTreeExpandoOpened */
+}
+.dj_ie6 .claro .dijitTreeExpando {
+	background-image: url('images/treeExpandImages8bit.png');
+}
+.claro .dijitTreeRowHover .dijitTreeExpandoOpened {
+	background-position: -53px 0;
+}
+.claro .dijitTreeExpandoClosed {
+	background-position: 1px 0;
+}
+.claro .dijitTreeRowHover .dijitTreeExpandoClosed {
+	background-position: -17px 0;
+}
+.claro .dijitTreeExpandoLeaf,
+.dj_ie6 .claro .dijitTreeExpandoLeaf {
+	background-image:none;
+}
+.claro .dijitTreeExpandoLoading {
+	background-image: url('images/loadingAnimation.gif');
+}
+
+/* Drag and Drop on TreeNodes
+ * Put insert line on dijitTreeContent node so it's aligned w/
+ * (ie, indented equally with) target element, even
+ * though dijitTreeRowNode is the actual "drag object"
+ */
+.claro .dijitTreeNode .dojoDndItemBefore .dijitTreeContent {
+	border-top: 2px solid @dnd-dropseparator-color;		// TODO: normal separator is just 1px, why is this 2px?
+}
+.claro .dijitTreeNode .dojoDndItemAfter .dijitTreeContent {
+	border-bottom: 2px solid @dnd-dropseparator-color;	// TODO: normal separator is just 1px, why is this 2px?
+}
diff --git a/dijit/themes/claro/claro.css b/dijit/themes/claro/claro.css
index f11f380..d3cb268 100644
--- a/dijit/themes/claro/claro.css
+++ b/dijit/themes/claro/claro.css
@@ -1,5 +1,4 @@
 @import url("../dijit.css");
- at import url("document.css");	/* rules on the document itself (rather than widgets), overriding dojo.css */
 @import url("../../icons/commonIcons.css");/*sprite containing common icons to be used by all themes*/
 @import url("Common.css");
 @import url("form/Common.css");
diff --git a/dijit/themes/claro/claro_rtl.css b/dijit/themes/claro/claro_rtl.css
index 874f20c..6f85707 100644
--- a/dijit/themes/claro/claro_rtl.css
+++ b/dijit/themes/claro/claro_rtl.css
@@ -13,3 +13,4 @@
 @import url("Menu_rtl.css");
 @import url("Calendar_rtl.css");
 @import url("TimePicker_rtl.css");
+ at import url("Toolbar_rtl.css");
diff --git a/dijit/themes/claro/compile.js b/dijit/themes/claro/compile.js
new file mode 100644
index 0000000..9edbe7e
--- /dev/null
+++ b/dijit/themes/claro/compile.js
@@ -0,0 +1,55 @@
+// Script to process all the less files and convert them to CSS files
+// Run from themes/dijit/claro like:
+//
+//	$ 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
+
+var options = {
+	compress: false,
+	optimization: 1,
+	silent: false
+};
+
+var allFiles = [].concat(
+		fs.readdirSync("."),
+		fs.readdirSync("form").map(function(fname){ return "form/"+fname; }),
+		fs.readdirSync("layout").map(function(fname){ return "layout/"+fname; })
+	),
+	lessFiles = allFiles.filter(function(name){ return name && name != "variables.less" && /\.less$/.test(name); });
+
+lessFiles.forEach(function(fname){
+	console.log("=== " + fname);
+	fs.readFile(fname, 'utf-8', function (e, data){
+		if(e){
+			console.error("lessc: " + e.message);
+			process.exit(1);
+		}
+
+		new(less.Parser)({
+			paths: [path.dirname(fname)],
+			optimization: options.optimization,
+			filename: fname
+		}).parse(data, function(err, tree){
+			if(err){
+				less.writeError(err, options);
+				process.exit(1);
+			}else{
+				try{
+					var css = tree.toCSS({ compress: options.compress }),
+						outputFname = fname.replace('.less', '.css');
+					fd = fs.openSync(outputFname, "w");
+					fs.writeSync(fd, css, 0, "utf8");
+				}catch(e){
+					less.writeError(e, options);
+					process.exit(2);
+				}
+			}
+		});
+	});
+});
diff --git a/dijit/themes/claro/document.css b/dijit/themes/claro/document.css
index 9a965bb..64e470c 100644
--- a/dijit/themes/claro/document.css
+++ b/dijit/themes/claro/document.css
@@ -1,109 +1,41 @@
+ at import url("../../../dojo/resources/dojo.css");
 /* ======= Styling for the document itself (overriding dojo.css) ======== */
-
 .claro {
-	font-family:Verdana,Arial,Helvetica,sans-serif;
-	font-size: .688em;
-	color: #131313;
+  font-family: Verdana, Arial, Helvetica, sans-serif;
+  font-size: .688em;
+  color: #131313;
 }
-
 /* Headings */
-h1 {
-	font-size: 1.545em; 
-	font-weight: normal;
-	line-height: 1em; 
-	margin-top: 1em;
-	margin-bottom:0.727em;
+.claro h1 {
+  font-size: 1.545em;
+  margin-bottom: 0.727em;
+}
+.claro h2 {
+  font-size: 1.364em;
+  line-height: 1.455em;
+  margin-top: 1em;
+  margin-bottom: 0.60em;
+  font-weight: normal;
+}
+.claro h3,
+.claro h4,
+.claro h5,
+.claro h6 {
+  font-size: 1.091em;
+  font-weight: normal;
 }
-.claro .dijitDialog h1 { 
-	margin-top:0em; 
-
-}
-h2 { 
-	font-size: 1.364em; 
-	line-height: 1.455em; 
-	margin-top:1em; 
-	margin-bottom:0.60em;
-	font-weight: normal;
-}
-
-h3, h4, h5, h6 {
-	font-size:1.091em; 
-	font-weight: normal; 
-	line-height: 1.5em; 
-	margin-top: 1.5em; 
-	margin-bottom: 0;
-}
-
 /* paragraphs, quotes and lists */
-p { 
-	font-size: 1em; 
-	line-height: 1.3em;
-}
-
-blockquote { 
-	font-size: 0.916em; 
-	margin-top: 3.272em; 
-	margin-bottom: 3.272em; 
-	line-height: 1.636em; 
-	padding: 1.636em; 
-	border-top: 1px solid #ccc; 
-	border-bottom: 1px solid #ccc;
-}
-
-ol li, ul li { 
-	font-size: 1em; 
-	line-height: 1.5em; 
-	margin: 0;
+.claro p {
+  line-height: 1.3em;
 }
-
 /* pre and code */
-pre, code { 
-	font-size:115%;
-	*font-size:100%;
-	font-family:inherit; 
-	background-color: #efefef; 
-	border: 1px solid #ccc;
-}
-
-pre { 
-	border-width: 1px 0; 
-	padding: 1.5em;
-}
-/*
-	Tables
-
-	Note that these table definitions make the assumption that you are using tables
-	to display tabular data, and NOT using tables as layout mechanisms.  If you are
-	using tables for layout, you will probably want to override these rules with
-	more specific ones.
-
-	These definitions make tabular data look presentable, particularly when presented
-	inline with paragraphs.
-*/
-table {  font-size:100%; }
-
-table.dojoTabular { 
-	border-collapse: collapse; 
-	border-spacing: 0; 
-	border: 1px solid #ccc; 
-	margin: 0 1.5em;
-}
-
-.dojoTabular th { 
-	text-align: center; 
-	font-weight: bold;
-}
-
-table.dojoTabular thead, table.dojoTabular tfoot { 
-	background-color: #efefef; 
-	border: 1px solid #ccc; 
-	border-width: 1px 0; 
+.claro pre, .claro code {
+  font-family: inherit;
+  background-color: #efefef;
+  border: 1px solid #d3d3d3;
 }
-
-table.dojoTabular thead tr th,
-table.dojoTabular thead tr td,
-table.dojoTabular tbody tr td,
-table.dojoTabular tfoot tr td { 
-	padding: 0.25em 0.5em;
+/* tables */
+.claro table.dojoTabular thead, .claro table.dojoTabular tfoot {
+  background-color: #efefef;
+  border: 1px solid #d3d3d3;
 }
-
diff --git a/dijit/themes/claro/document.less b/dijit/themes/claro/document.less
new file mode 100644
index 0000000..7f86356
--- /dev/null
+++ b/dijit/themes/claro/document.less
@@ -0,0 +1,45 @@
+/* ======= Styling for the document itself (overriding dojo.css) ======== */
+
+ at import "variables";
+ at import url("../../../dojo/resources/dojo.css");
+
+.claro {
+  font-family: Verdana, Arial, Helvetica, sans-serif;
+  font-size: .688em;
+  color: @document-text-color;
+}
+
+/* Headings */
+.claro h1 {
+	font-size: 1.545em; 
+	margin-bottom:0.727em;
+}
+.claro h2 { 
+	font-size: 1.364em; 
+	line-height: 1.455em; 
+	margin-top:1em; 
+	margin-bottom:0.60em;
+	font-weight: normal;
+}
+.claro h3, .claro h4, .claro h5, .claro h6 {
+	font-size:1.091em; 
+	font-weight: normal; 
+}
+
+/* paragraphs, quotes and lists */
+.claro p { 
+	line-height: 1.3em;
+}
+
+/* pre and code */
+.claro pre, .claro code { 
+	font-family:inherit; 
+	background-color: @document-shadedsection-background-color; 
+	border: 1px solid @document-border-color;
+}
+
+/* tables */
+.claro table.dojoTabular thead, .claro table.dojoTabular tfoot { 
+	background-color: @document-shadedsection-background-color; 
+	border: 1px solid @document-border-color; 
+}
diff --git a/dijit/themes/claro/form/Button.css b/dijit/themes/claro/form/Button.css
index 7edec6b..e01a1d3 100644
--- a/dijit/themes/claro/form/Button.css
+++ b/dijit/themes/claro/form/Button.css
@@ -12,7 +12,7 @@
  * 		.dijitButtonText
  * 
  * 3. Arrows - only for DropDownButton and ComboButton
- * 	     There are total four diredtions arrows - down, left, right, up:
+ * 	     There are total four directions arrows - down, left, right, up:
  * 		.dijitArrowButtonInner - down arrow by default
  *      .dijitLeftArrowButton .dijitArrowButtonInner - left arrow
  *      .dijitRightArrowButton .dijitArrowButtonInner - right arrow
@@ -25,144 +25,136 @@
  *      
  *      .dijitDisabled .dijitArrowButtonInner  - disabled arrow states 
  */
-
 .claro .dijitButtonNode {
-	/* rules for dijit.form.*Button widgets and arrow nodes on ComboBox, Spinner etc. */
-	-webkit-transition-property:background-color;
- 	-webkit-transition-duration:.3s;
-}
+  /* rules for dijit.form.*Button widgets and arrow nodes on ComboBox, Spinner etc. */
 
+  -webkit-transition-property: background-color;
+  -moz-transition-property: background-color;
+  transition-property: background-color;
+  -webkit-transition-duration: 0.3s;
+  -moz-transition-duration: 0.3s;
+  transition-duration: 0.3s;
+}
 .claro .dijitButton .dijitButtonNode,
 .claro .dijitDropDownButton .dijitButtonNode,
 .claro .dijitComboButton .dijitButtonNode,
 .claro .dijitToggleButton .dijitButtonNode {
-	/* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
-	border: 1px solid #769dc0;
-	padding:2px 4px 4px 4px;
-	background-image: url("images/button.png");
-	background-position: center top;
-	background-repeat: repeat-x;
-	background-color: #e4f2ff;
-	border-radius: 4px;
-	-moz-border-radius: 4px;
-	-webkit-border-radius: 4px;
-	box-shadow:0px 1px 1px rgba(0,0,0,0.15);
-	-webkit-box-shadow:0px 1px 1px rgba(0,0,0,0.15);
-	-moz-box-shadow: 0px 1px 1px rgba(0,0,0,0.15);	
-}
+  /* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
 
-.claro .dijitComboButton .dijitArrowButton {
-	border-left-width: 0px;
-	padding: 4px 2px 4px 2px;	/* TODO: still needed? */
+  border: 1px solid #769dc0;
+  padding: 2px 4px 4px 4px;
+  background-image: url("images/button.png");
+  background-position: center top;
+  background-repeat: repeat-x;
+  background-color: #e9f4fe;
+  -moz-border-radius: 4px;
+  border-radius: 4px;
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
+  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
 }
+.claro .dijitComboButton .dijitArrowButton {
+  border-left-width: 0;
+  padding: 4px 2px 4px 2px;
+  /* TODO: still needed? */
 
+}
 /*arrow styles for down/up/left/right directions*/
 .claro .dijitArrowButtonInner {
-	width: 15px;
-	height: 15px;
-	margin: 0 auto;
-	background-image:url("images/buttonArrows.png");
-	background-repeat:no-repeat;
-	background-position:-51px 53%;
+  width: 15px;
+  height: 15px;
+  margin: 0 auto;
+  background-image: url("images/buttonArrows.png");
+  background-repeat: no-repeat;
+  background-position: -51px 53%;
 }
 .claro .dijitLeftArrowButton .dijitArrowButtonInner {
-	background-position: -77px 53%;
+  background-position: -77px 53%;
 }
 .claro .dijitRightArrowButton .dijitArrowButtonInner {
-	background-position: -26px 53%;
+  background-position: -26px 53%;
 }
 .claro .dijitUpArrowButton .dijitArrowButtonInner {
-	background-position: 0px 53%;
+  background-position: 0 53%;
 }
 .claro .dijitDisabled .dijitArrowButtonInner {
-	background-position: -151px 53%;
+  background-position: -151px 53%;
 }
 .claro .dijitDisabled .dijitLeftArrowButton .dijitArrowButtonInner {
-	background-position: -177px 53%;
+  background-position: -177px 53%;
 }
 .claro .dijitDisabled .dijitRightArrowButton .dijitArrowButtonInner {
-	background-position: -126px 53%;
+  background-position: -126px 53%;
 }
 .claro .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner {
-	background-position: -100px 53%;
+  background-position: -100px 53%;
 }
-
 .claro .dijitButtonText {
-	padding: 0 0.3em;
-	text-align: center;
-}
-
-.claro .dijitDisabled .dijitButtonText {
-	color: #7F7F7F;
+  padding: 0 0.3em;
+  text-align: center;
 }
-
 /* hover status */
 .claro .dijitButtonHover .dijitButtonNode,
 .claro .dijitDropDownButtonHover .dijitButtonNode,
-.claro .dijitComboButton .dijitButtonNodeHover, 
+.claro .dijitComboButton .dijitButtonNodeHover,
 .claro .dijitComboButton .dijitDownArrowButtonHover,
 .claro .dijitToggleButtonHover .dijitButtonNode {
-	background-color: #afd9ff;
-	color:#000;
- 	-webkit-transition-duration:.2s;
+  background-color: #abd6ff;
+  color: #000000;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
 }
-
 /* checked status */
-.claro .dijitButtonActive .dijitButtonNode, 
+.claro .dijitButtonActive .dijitButtonNode,
 .claro .dijitDropDownButtonActive .dijitButtonNode,
 .claro .dijitComboButtonActive .dijitButtonNode,
 .claro .dijitToggleButtonActive .dijitButtonNode {
-	background-color: #99cfff;
-	box-shadow:0px 0px 0px rgba(0,0,0,0);
-	-webkit-box-shadow:0px 0px 0px rgba(0,0,0,0);
-	-moz-box-shadow: 0px 0px 0px rgba(0,0,0,0);
- 	-webkit-transition-duration:.1s;
+  background-color: #abd6ff;
+  -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  -webkit-transition-duration: 0.1s;
+  -moz-transition-duration: 0.1s;
+  transition-duration: 0.1s;
 }
-
 /* disabled status */
 .claro .dijitButtonDisabled,
 .claro .dijitDropDownButtonDisabled,
 .claro .dijitComboButtonDisabled,
 .claro .dijitToggleButtonDisabled {
-	background-image: none;
-	outline: none;
+  background-image: none;
+  outline: none;
 }
-
 .claro .dijitButtonDisabled .dijitButtonNode,
 .claro .dijitDropDownButtonDisabled .dijitButtonNode,
 .claro .dijitComboButtonDisabled .dijitButtonNode,
-.claro .dijitToggleButtonDisabled .dijitButtonNode { 
-	background-position:0px -149px;
-	background-color: #e3e3e3;
-	border: solid 1px #c9c9c9;
-	color: #696969;
-	box-shadow:0px 0px 0px rgba(0,0,0,0);
-	-webkit-box-shadow:0px 0px 0px rgba(0,0,0,0);
-	-moz-box-shadow: 0px 0px 0px rgba(0,0,0,0);
-}
-.claro .dijitComboButtonDisabled .dijitArrowButton{ 
-	border-left-width: 0px;
+.claro .dijitToggleButtonDisabled .dijitButtonNode {
+  background-position: 0 -149px;
+  background-color: #efefef;
+  border: solid 1px #d3d3d3;
+  color: #818181;
+  -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  -moz-box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+  box-shadow: 0 0 0 rgba(0, 0, 0, 0);
+}
+.claro .dijitComboButtonDisabled .dijitArrowButton {
+  border-left-width: 0;
 }
 /* for ComboButton */
 .claro table.dijitComboButton {
-	border-collapse: separate;	/* override dijit.css so that ComboBox rounded corners work */
-}
+  border-collapse: separate;
+  /* override dijit.css so that ComboBox rounded corners work */
 
+}
 .dj_ie6 .claro .dijitButtonNode {
-	background-image: none;
+  background-image: none;
 }
-
 .claro .dijitComboButton .dijitStretch {
-	-moz-border-radius: 4px 0px 0px 4px;
-	-webkit-border-top-left-radius: 4px;
-	-webkit-border-top-right-radius: 0px;
-	-webkit-border-bottom-right-radius: 0px;
-	-webkit-border-bottom-left-radius: 4px;
+  -moz-border-radius: 4px 0 0 4px;
+  border-radius: 4px 0 0 4px;
 }
 .claro .dijitComboButton .dijitArrowButton {
-	-moz-border-radius: 0px 4px 4px 0px;
-	-webkit-border-top-left-radius: 0px;
-	-webkit-border-top-right-radius: 4px;
-	-webkit-border-bottom-right-radius: 4px;
-	-webkit-border-bottom-left-radius: 0px;
-}
\ No newline at end of file
+  -moz-border-radius: 0 4px 4px 0;
+  border-radius: 0 4px 4px 0;
+}
diff --git a/dijit/themes/claro/form/Button.less b/dijit/themes/claro/form/Button.less
new file mode 100644
index 0000000..b076d2a
--- /dev/null
+++ b/dijit/themes/claro/form/Button.less
@@ -0,0 +1,154 @@
+/* Button | DropDownButton | ComboButton | ToggleButton
+ * 
+ * Styling Buttons mainly includes:
+ * 
+ * 1. Containers
+ * 		.dijitButton
+ * 		.dijitDropDownButton
+ * 		.dijitComboButton
+ * 		.dijitButtonNode - common button/arrow wrapper shared across all three button types 
+ *
+ * 2. Button text
+ * 		.dijitButtonText
+ * 
+ * 3. Arrows - only for DropDownButton and ComboButton
+ * 	     There are total four directions arrows - down, left, right, up:
+ * 		.dijitArrowButtonInner - down arrow by default
+ *      .dijitLeftArrowButton .dijitArrowButtonInner - left arrow
+ *      .dijitRightArrowButton .dijitArrowButtonInner - right arrow
+ *      .dijitUpArrowButton .dijitArrowButtonInner - up arrow
+ * 
+ * 4. States - Hover, Active, Disabled, e.g.
+ * 		.dijitButtonHover .dijitButtonNode
+ * 		.dijitButtonActive .dijitButtonNode
+ * 		.dijitButtonDisabled .dijitButtonNode
+ *      
+ *      .dijitDisabled .dijitArrowButtonInner  - disabled arrow states 
+ */
+
+ at import "../variables";
+
+.claro .dijitButtonNode {
+	/* rules for dijit.form.*Button widgets and arrow nodes on ComboBox, Spinner etc. */
+	.transition-property(background-color);
+ 	.transition-duration(.3s);
+}
+
+.claro .dijitButton .dijitButtonNode,
+.claro .dijitDropDownButton .dijitButtonNode,
+.claro .dijitComboButton .dijitButtonNode,
+.claro .dijitToggleButton .dijitButtonNode {
+	/* rules for the dijit.form.*Button widgets (see also ComboButton section below) */
+	border: 1px solid @button-border-color;
+	padding:2px 4px 4px 4px;
+	background-image: url("images/button.png");
+	background-position: center top;
+	background-repeat: repeat-x;
+	background-color: @button-background-color;
+	.border-radius(@button-border-radius);
+	.box-shadow(0 1px 1px rgba(0,0,0,0.15));
+}
+
+.claro .dijitComboButton .dijitArrowButton {
+	border-left-width: 0;
+	padding: 4px 2px 4px 2px;	/* TODO: still needed? */
+}
+
+/*arrow styles for down/up/left/right directions*/
+.claro .dijitArrowButtonInner {
+	width: 15px;
+	height: 15px;
+	margin: 0 auto;
+	background-image:url("images/buttonArrows.png");
+	background-repeat:no-repeat;
+	background-position:-51px 53%;
+}
+.claro .dijitLeftArrowButton .dijitArrowButtonInner {
+	background-position: -77px 53%;
+}
+.claro .dijitRightArrowButton .dijitArrowButtonInner {
+	background-position: -26px 53%;
+}
+.claro .dijitUpArrowButton .dijitArrowButtonInner {
+	background-position: 0 53%;
+}
+.claro .dijitDisabled .dijitArrowButtonInner {
+	background-position: -151px 53%;
+}
+.claro .dijitDisabled .dijitLeftArrowButton .dijitArrowButtonInner {
+	background-position: -177px 53%;
+}
+.claro .dijitDisabled .dijitRightArrowButton .dijitArrowButtonInner {
+	background-position: -126px 53%;
+}
+.claro .dijitDisabled .dijitUpArrowButton .dijitArrowButtonInner {
+	background-position: -100px 53%;
+}
+
+.claro .dijitButtonText {
+	padding: 0 0.3em;
+	text-align: center;
+}
+
+
+
+
+
+/* hover status */
+.claro .dijitButtonHover .dijitButtonNode,
+.claro .dijitDropDownButtonHover .dijitButtonNode,
+.claro .dijitComboButton .dijitButtonNodeHover, 
+.claro .dijitComboButton .dijitDownArrowButtonHover,
+.claro .dijitToggleButtonHover .dijitButtonNode {
+	background-color: @button-hovered-background-color;
+	color:@text-color;
+ 	.transition-duration(.2s);
+}
+
+/* checked status */
+.claro .dijitButtonActive .dijitButtonNode, 
+.claro .dijitDropDownButtonActive .dijitButtonNode,
+.claro .dijitComboButtonActive .dijitButtonNode,
+.claro .dijitToggleButtonActive .dijitButtonNode {
+	background-color: @button-pressed-background-color;
+	.box-shadow(0 0 0 rgba(0,0,0,0));
+ 	.transition-duration(.1s);
+}
+
+/* disabled status */
+.claro .dijitButtonDisabled,
+.claro .dijitDropDownButtonDisabled,
+.claro .dijitComboButtonDisabled,
+.claro .dijitToggleButtonDisabled {
+	background-image: none;
+	outline: none;
+}
+
+.claro .dijitButtonDisabled .dijitButtonNode,
+.claro .dijitDropDownButtonDisabled .dijitButtonNode,
+.claro .dijitComboButtonDisabled .dijitButtonNode,
+.claro .dijitToggleButtonDisabled .dijitButtonNode { 
+	background-position:0 -149px;
+	background-color: @disabled-background-color;
+	border: solid 1px @disabled-border-color;
+	color: @disabled-text-color;
+	.box-shadow(0 0 0 rgba(0,0,0,0));
+}
+.claro .dijitComboButtonDisabled .dijitArrowButton{ 
+	border-left-width: 0;
+}
+/* for ComboButton */
+.claro table.dijitComboButton {
+	border-collapse: separate;	/* override dijit.css so that ComboBox rounded corners work */
+}
+
+.dj_ie6 .claro .dijitButtonNode {
+	background-image: none;
+}
+
+.claro .dijitComboButton .dijitStretch {
+	.border-radius(@button-border-radius 0 0 @button-border-radius);
+}
+.claro .dijitComboButton .dijitArrowButton {
+	.border-radius(0 @button-border-radius @button-border-radius 0);
+}
diff --git a/dijit/themes/claro/form/Button_rtl.css b/dijit/themes/claro/form/Button_rtl.css
index 4cf6915..2d5b08b 100644
--- a/dijit/themes/claro/form/Button_rtl.css
+++ b/dijit/themes/claro/form/Button_rtl.css
@@ -1,22 +1,13 @@
 /* Combo Button */
-
 .claro .dijitComboButtonRtl .dijitStretch {
-	-moz-border-radius: 0px 4px 4px 0px;
-	-webkit-border-top-left-radius: 0px;
-    -webkit-border-top-right-radius: 4px;
-    -webkit-border-bottom-right-radius: 4px;
-    -webkit-border-bottom-left-radius: 0px;	
+  -moz-border-radius: 0 4px 4px 0;
+  border-radius: 0 4px 4px 0;
 }
-
 .claro .dijitComboButtonRtl .dijitArrowButton {
-	-moz-border-radius:  4px 0px 0px  4px;
-	-webkit-border-top-left-radius:4px;
-    -webkit-border-top-right-radius:0px;
-    -webkit-border-bottom-right-radius:0px;
-    -webkit-border-bottom-left-radius:4px;
-	padding:3px 0px 4px;
-	border-left-width: 1px;
-	border-right-width: 0px;
+  -moz-border-radius: 4px 0 0 4px;
+  border-radius: 4px 0 0 4px;
+  padding: 3px 0 4px;
+  border-left-width: 1px;
+  border-right-width: 0;
 }
-
 /* End Combo Button */
\ No newline at end of file
diff --git a/dijit/themes/claro/form/Button_rtl.less b/dijit/themes/claro/form/Button_rtl.less
new file mode 100644
index 0000000..6225d68
--- /dev/null
+++ b/dijit/themes/claro/form/Button_rtl.less
@@ -0,0 +1,16 @@
+ at import "../variables";
+
+/* Combo Button */
+
+.claro .dijitComboButtonRtl .dijitStretch {
+	.border-radius(0 @button-border-radius @button-border-radius 0);
+}
+
+.claro .dijitComboButtonRtl .dijitArrowButton {
+	.border-radius(@button-border-radius 0 0  @button-border-radius);
+	padding:3px 0 4px;
+	border-left-width: 1px;
+	border-right-width: 0;
+}
+
+/* End Combo Button */
\ No newline at end of file
diff --git a/dijit/themes/claro/form/Checkbox.css b/dijit/themes/claro/form/Checkbox.css
index a98f7bc..5765bb3 100644
--- a/dijit/themes/claro/form/Checkbox.css
+++ b/dijit/themes/claro/form/Checkbox.css
@@ -18,60 +18,54 @@
  * 5. Disabled state
  * 		.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');
+  /* checkbox sprite image */
 
-.claro .dijitCheckBox,
-.claro .dijitCheckBoxIcon		/* inside a toggle button */	{
-	background-image: url('images/checkboxRadioButtonStates.png'); /* checkbox sprite image */
-	background-repeat: no-repeat;
-	width: 15px;
-	height: 16px;
-	margin: 0 2px 0 0;
-	padding: 0;
+  background-repeat: no-repeat;
+  width: 15px;
+  height: 16px;
+  margin: 0 2px 0 0;
+  padding: 0;
 }
+.dj_ie6 .claro .dijitCheckBox, .dj_ie6 .claro .dijitCheckBoxIcon {
+  background-image: url('images/checkboxAndRadioButtons_IE6.png');
+  /* checkbox sprite image */
 
-.dj_ie6 .claro .dijitCheckBox,
-.dj_ie6 .claro .dijitCheckBoxIcon		/* inside a toggle button */	{
-	background-image: url('images/checkboxAndRadioButtons_IE6.png'); /* checkbox sprite image */
 }
+.claro .dijitCheckBox, .claro .dijitToggleButton .dijitCheckBoxIcon {
+  /* unchecked */
 
-.claro .dijitCheckBox,
-.claro .dijitToggleButton .dijitCheckBoxIcon {
-	/* unchecked */
-	background-position: -15px;
+  background-position: -15px;
 }
+.claro .dijitCheckBoxChecked, .claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
+  /* checked */
 
-.claro .dijitCheckBoxChecked,
-.claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
-	/* checked */
-	background-position: -0px;
+  background-position: 0;
 }
-
 .claro .dijitCheckBoxDisabled {
-	/* disabled */
-	background-position: -75px;
-}
+  /* disabled */
 
-.claro .dijitCheckBoxCheckedDisabled {
-	/* disabled but checked */
-	background-position: -60px;
+  background-position: -75px;
 }
+.claro .dijitCheckBoxCheckedDisabled {
+  /* disabled but checked */
 
-.claro .dijitCheckBoxHover {
-	/* hovering over an unchecked enabled checkbox */
-	background-position: -45px;
+  background-position: -60px;
 }
+.claro .dijitCheckBoxHover {
+  /* hovering over an unchecked enabled checkbox */
 
-.claro .dijitCheckBoxCheckedHover {
-	/* hovering over an checked enabled checkbox */
-	background-position: -30px;
+  background-position: -45px;
 }
+.claro .dijitCheckBoxCheckedHover {
+  /* hovering over an checked enabled checkbox */
 
-
+  background-position: -30px;
+}
diff --git a/dijit/themes/claro/form/Checkbox.less b/dijit/themes/claro/form/Checkbox.less
new file mode 100644
index 0000000..21769dc
--- /dev/null
+++ b/dijit/themes/claro/form/Checkbox.less
@@ -0,0 +1,79 @@
+/* CheckBox
+ * 
+ * Styling CheckBox mainly includes:
+ * 
+ * 1. Containers
+ * 		.dijitCheckBox|.dijitCheckBoxIcon - for border, padding, width|height and background image
+ * 
+ * 2. CheckBox within ToggleButton
+ * 		.dijitToggleButton|.dijitToggleButtonChecked .* - for background image
+ * 
+ * 3. Checked state
+ * 		.dijitCheckBoxChecked - for checked background-color|image
+ * 		.dijitToggleButtonChecked - for border, background-color|image, display and width|height
+ * 
+ * 4. Hover state
+ * 		.dijitCheckBoxHover|.dijitCheckBoxCheckedHover - for background image
+ * 
+ * 5. Disabled state
+ * 		.dijitCheckBoxDisabled|.dijitCheckBoxCheckedDisabled - for background image
+ */
+
+ at import "../variables";
+
+.claro .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url('../images/checkmarkNoBorder.png');
+}
+
+.dj_ie6 .claro .dijitToggleButton .dijitCheckBoxIcon {
+	background-image: url('../images/checkmarkNoBorder.gif');
+}
+
+.claro .dijitCheckBox,
+.claro .dijitCheckBoxIcon		/* inside a toggle button */	{
+	background-image: url('images/checkboxRadioButtonStates.png'); /* checkbox sprite image */
+	background-repeat: no-repeat;
+	width: 15px;
+	height: 16px;
+	margin: 0 2px 0 0;
+	padding: 0;
+}
+
+.dj_ie6 .claro .dijitCheckBox,
+.dj_ie6 .claro .dijitCheckBoxIcon		/* inside a toggle button */	{
+	background-image: url('images/checkboxAndRadioButtons_IE6.png'); /* checkbox sprite image */
+}
+
+.claro .dijitCheckBox,
+.claro .dijitToggleButton .dijitCheckBoxIcon {
+	/* unchecked */
+	background-position: -15px;
+}
+
+.claro .dijitCheckBoxChecked,
+.claro .dijitToggleButtonChecked .dijitCheckBoxIcon {
+	/* checked */
+	background-position: -0;
+}
+
+.claro .dijitCheckBoxDisabled {
+	/* disabled */
+	background-position: -75px;
+}
+
+.claro .dijitCheckBoxCheckedDisabled {
+	/* disabled but checked */
+	background-position: -60px;
+}
+
+.claro .dijitCheckBoxHover {
+	/* hovering over an unchecked enabled checkbox */
+	background-position: -45px;
+}
+
+.claro .dijitCheckBoxCheckedHover {
+	/* hovering over an checked enabled checkbox */
+	background-position: -30px;
+}
+
+
diff --git a/dijit/themes/claro/form/Common.css b/dijit/themes/claro/form/Common.css
index 4ee207f..ab8bb5c 100644
--- a/dijit/themes/claro/form/Common.css
+++ b/dijit/themes/claro/form/Common.css
@@ -1,176 +1,163 @@
 /* claro/form/Common.css */
-
 /*========================= common css =========================*/
-
 /* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
-
 .claro .dijitTextBoxError .dijitValidationContainer {
-	background-color: #d46363;
-	background-image: url('images/error.png');
-	background-position: top center;
-	border: solid #d46464 0px;
-	border-left-width: 1px;
-	width: 9px;
+  background-color: #d46464;
+  background-image: url('images/error.png');
+  background-position: top center;
+  border: solid #d46464 0;
+  border-left-width: 1px;
+  width: 9px;
 }
 .claro .dijitTextBoxError .dijitValidationIcon {
-	width: 0px;
-	background-color: transparent !important; /* so the INPUT doesn't obscure the border in rtl+a11y */
-}
+  width: 0;
+  background-color: transparent !important;
+  /* so the INPUT doesn't obscure the border in rtl+a11y */
 
-/* .dijitInputField .dijitPlaceHolder is explicitly listed below because
-   dijitPlaceHolder is absolutely positioned, so padding set on dijitInputField
-   won't affect it */
-.claro .dijitTextBox .dijitInputContainer,
-.claro .dijitTextArea,
-.claro .dijitInputField .dijitPlaceHolder {
-	padding: 2px;
 }
+/* Padding for the input area of TextBox based widgets, and corresponding padding for the
+ * down arrow button and the placeholder.   placeholder is explicitly listed  because
+ * dijitPlaceHolder is absolutely positioned, so padding set on dijitInputField
+ * won't affect it
+ */
+.claro .dijitTextArea, .claro .dijitInputField .dijitPlaceHolder {
+  padding: 2px;
+}
+.claro .dijitTextBox .dijitInputField {
+  padding: 1px 2px;
+}
+.dj_gecko .claro .dijitTextBox .dijitInputInner, .dj_webkit .claro .dijitTextBox .dijitInputInner {
+  padding: 1px;
+}
+.claro .dijitTextBox, .claro .dijitTextBox .dijitButtonNode {
+  /* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
 
-.claro .dijitTextBox,
-.claro .dijitTextBox .dijitButtonNode {
-	/* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
-	border-color: #b5bcc7;
-	-webkit-transition-property:background-color, border;
- 	-webkit-transition-duration:.35s;
+  border-color: #b5bcc7;
+  -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;
 }
 .claro .dijitTextBox {
-	background-color: #f7fcff;
+  background-color: #ffffff;
 }
-
 /* hover */
-.claro .dijitTextBoxHover,
-.claro .dijitTextBoxHover .dijitButtonNode {
-	border-color: #769dc0;
- 	-webkit-transition-duration:.25s;
+.claro .dijitTextBoxHover, .claro .dijitTextBoxHover .dijitButtonNode {
+  border-color: #769dc0;
+  -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-repeat: repeat-x;
+  background-color: #e9f4fe;
+  background-image: url('images/textBox_back.png');
+  background-repeat: repeat-x;
 }
-
 /* error state */
-.claro .dijitTextBoxError,
-.claro .dijitTextBoxError .dijitButtonNode {
-	border-color: #d46464;
+.claro .dijitTextBoxError, .claro .dijitTextBoxError .dijitButtonNode {
+  border-color: #d46464;
 }
-.claro .dijitTextBoxError,
-.claro .dijitTextBoxError .dijitInputContainer {
-	background-color: #fdf7f7;
+.claro .dijitTextBoxError, .claro .dijitTextBoxError .dijitInputContainer {
+  background-color: #ffffff;
 }
-
 /* focused state */
-.claro .dijitTextBoxFocused,
-.claro .dijitTextBoxFocused .dijitButtonNode {
-	border-color:#769dc0;
- 	-webkit-transition-duration:.1s;
+.claro .dijitTextBoxFocused, .claro .dijitTextBoxFocused .dijitButtonNode {
+  border-color: #769dc0;
+  -webkit-transition-duration: 0.1s;
+  -moz-transition-duration: 0.1s;
+  transition-duration: 0.1s;
 }
 .claro .dijitTextBoxFocused {
-	background-color: #fff;
-	background-image: url('images/textBox_back.png');
-	background-repeat: repeat-x;
+  background-color: #ffffff;
+  background-image: url('images/textBox_back.png');
+  background-repeat: repeat-x;
 }
 .claro .dijitTextBoxFocused .dijitInputContainer {
-	background: #fff;
+  background: #ffffff;
 }
-
-.claro .dijitTextBoxErrorFocused,
-.claro .dijitTextBoxErrorFocused .dijitButtonNode {
-	border-color: #ce4f4f;
+.claro .dijitTextBoxErrorFocused, .claro .dijitTextBoxErrorFocused .dijitButtonNode {
+  border-color: #ce4f4f;
 }
-
 /* disabled state */
-.claro .dijitTextBoxDisabled,
-.claro .dijitTextBoxDisabled .dijitButtonNode {
-	border-color: #d3d3d3;
+.claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitButtonNode {
+  border-color: #d3d3d3;
 }
-.claro .dijitTextBoxDisabled {
-	background-color: #efefef;
-	background-image: none;
-	color: #818181;
+.claro .dijitTextBoxDisabled, .claro .dijitTextBoxDisabled .dijitInputContainer {
+  background-color: #efefef;
+  background-image: none;
+  color: #818181;
 }
-
 /*========================= for special widgets =========================*/
-
-/* ComboBox */
-
+/* Input boxes with an arrow (for a drop down) */
 .claro .dijitComboBox .dijitArrowButtonInner {
-	background-image: url("images/commonFormArrows.png");
-	background-position:-35px 53%;
-	background-repeat: no-repeat;
-	margin: 0px;
-	width:16px;
-	height:100%;
-	border: 1px solid #fff;
+  background-image: url("images/commonFormArrows.png");
+  background-position: -35px 53%;
+  background-repeat: no-repeat;
+  margin: 0;
+  width: 16px;
+  border: 1px solid #ffffff;
 }
-
-.claro .dijitTextBox .dijitInputField {
-	padding-top: 1px; /* 1px and not 2px due to 1px padding on the INPUT */
-	padding-bottom: 1px;
+.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
+  border: none;
 }
-.claro .dijitTextBox .dijitInputInner {
-	/* left padding helps line up input text with menu text */
-	padding: 1px 2px 1px 0; /* match 1px vertical border on button */
+.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
+  border: none;
 }
-.claro .dijitTextBox .dijitValidationContainer {
-	padding: 0 0 2px 0; /* match 1px border height in button */
+/* Add 1px vertical padding to the <input> where user types and the validation icon,
+   to match the 1px border on arrow button */
+.claro .dijitTextBox .dijitInputInner, .claro .dijitTextBox .dijitValidationContainer {
+  padding: 1px 0;
 }
-
 .claro .dijitComboBox .dijitButtonNode {
-	background-color: #ebeef4;
-	background-image: url("images/formHighlight.png");
-	background-repeat:repeat-x;
+  background-color: #efefef;
+  background-image: url("images/formHighlight.png");
+  background-repeat: repeat-x;
+}
+/* Arrow "hover" effect:
+ * The arrow button should change color whenever the mouse is in a position such that clicking it
+ * will toggle the drop down.   That's either (1) anywhere over the ComboBox or (2) over the arrow
+ * button, depending on the openOnClick setting for the widget.
+ */
+.claro .dijitComboBoxOpenOnClickHover .dijitButtonNode, .claro .dijitComboBox .dijitDownArrowButtonHover {
+  background-color: #abd6ff;
 }
-
-/* hover state */
-.claro .dijitComboBoxHover .dijitButtonNode {
-	background-color:#abd6ff;
+.claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner, .claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
+  background-position: -70px 53%;
 }
-.claro .dijitComboBoxHover .dijitArrowButtonInner {
-	background-position:-70px 53%;
+/* Arrow Button change when drop down is open */
+.claro .dijitComboBox .dijitHasDropDownOpen {
+  background-color: #7dbefa;
+  background-position: 0 -177px;
+  padding: 1px;
 }
-
-/* focused state */
-.claro .dijitComboBoxFocused .dijitButtonNode {
-	background-color:#7dbefa;
-	background-position:0px -177px;
-	padding: 1px;
-}	
-.claro .dijitComboBoxFocused .dijitArrowButtonInner {
-	background-position:-70px 53%;
-	border: 0px none;
+.claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
+  background-position: -70px 53%;
+  border: 0 none;
 }
-
 /* disabled state */
 .claro div.dijitComboBoxDisabled .dijitArrowButtonInner {
-	/* specific selector set to override background-position setting from Button.js
+  /* specific selector set to override background-position setting from Button.js
 	 * (.claro .dijitComboBoxDisabled .dijitArrowButtonInner) */
-	background-position:0px 50%;
-	background-color:#f1f1f1;
-}
 
+  background-position: 0 50%;
+  background-color: #efefef;
+}
 /*========================= hacks for browsers =========================*/
-/* it seems the input[type="hidden"] has a height (16px) too... this may cause the widget's height calcuate error */
+/* it seems the input[type="hidden"] has a height (16px) too... this may cause the widget's height calculate error */
 .dj_ff3 .claro .dijitInputField input[type="hidden"] {
-	display: none;
-	height: 0;
-	width: 0;
+  display: none;
+  height: 0;
+  width: 0;
 }
-
 /* ie6 doesn't support transparent background img */
-.dj_ie6 .claro .dijitTextBox,
-.dj_ie6 .claro .dijitComboBox .dijitButtonNode {
-	background-image: none;
+.dj_ie6 .claro .dijitTextBox, .dj_ie6 .claro .dijitComboBox .dijitButtonNode {
+  background-image: none;
 }
-
-
-/* In quirks mode strangely all browsers do border-box sizing for input nodes.
- * Drop the 1px white border around ComboBox arrow to fix misalignment of icon, and to jump on focus.
- * Note also that these rules are copying what is done on focus.
- */
-.dj_quirks .claro .dijitComboBox .dijitArrowButtonInner {
-	border: 0px;
+.dj_borderbox .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
+  width: 18px;
 }
-.dj_quirks .claro .dijitComboBox .dijitArrowButtonContainer {
-	padding: 1px;
+.dj_borderbox .claro .dijitComboBoxFocused .dijitHasDropDownOpen .dijitArrowButtonInner {
+  width: 16px;
 }
diff --git a/dijit/themes/claro/form/Common.less b/dijit/themes/claro/form/Common.less
new file mode 100644
index 0000000..729867a
--- /dev/null
+++ b/dijit/themes/claro/form/Common.less
@@ -0,0 +1,194 @@
+/* claro/form/Common.css */
+
+/*========================= common css =========================*/
+
+ at import "../variables";
+
+/* 'dijitTextBox' refers to 'dijit(TextBox|DateTextBox|CurrencyTextBox|...)' */
+
+.claro .dijitTextBoxError .dijitValidationContainer {
+	background-color: @erroricon-background-color;
+	background-image: url('images/error.png');
+	background-position: top center;
+	border: solid @erroricon-background-color 0;
+	border-left-width: 1px;
+	width: 9px;
+}
+.claro .dijitTextBoxError .dijitValidationIcon {
+	width: 0;
+	background-color: transparent !important; /* so the INPUT doesn't obscure the border in rtl+a11y */
+}
+
+/* Padding for the input area of TextBox based widgets, and corresponding padding for the
+ * down arrow button and the placeholder.   placeholder is explicitly listed  because
+ * dijitPlaceHolder is absolutely positioned, so padding set on dijitInputField
+ * won't affect it
+ */
+.claro .dijitTextArea,
+.claro .dijitInputField .dijitPlaceHolder {
+	padding: @textbox-padding;
+}
+.claro .dijitTextBox .dijitInputField {
+	// Subtract 1px from top/bottom because we add 1px to other nodes, see rules below.
+	// Although we are theoretically only adding 1px to top/bottom browsers seem to pad inputs by 1px on left/right,
+	// although that varies by so compensate for that too.
+	padding: @textbox-padding - 1px  @textbox-padding;
+}
+.dj_gecko .claro .dijitTextBox .dijitInputInner,
+.dj_webkit .claro .dijitTextBox .dijitInputInner {
+	// Although we are theoretically only adding 1px to top/bottom, some browsers seem to pad inputs by 1px on left/right,
+	// so compensate for that too.
+	padding: @textbox-padding - 1px;
+}
+
+.claro .dijitTextBox,
+.claro .dijitTextBox .dijitButtonNode {
+	/* color for (outer) border on *TextBox widgets, and border between input and buttons on ComboBox and Spinner */
+	border-color: @border-color;
+	.transition-property(background-color, border);
+ 	.transition-duration(.35s);
+}
+.claro .dijitTextBox {
+	background-color: @textbox-background-color;
+}
+
+/* hover */
+.claro .dijitTextBoxHover,
+.claro .dijitTextBoxHover .dijitButtonNode {
+	border-color: @hovered-border-color;
+ 	.transition-duration(.25s);
+}
+.claro .dijitTextBoxHover {
+	background-color: @textbox-hovered-background-color;
+	background-image: url('images/textBox_back.png');
+	background-repeat: repeat-x;
+}
+
+/* error state */
+.claro .dijitTextBoxError,
+.claro .dijitTextBoxError .dijitButtonNode {
+	border-color: @error-border-color;
+}
+.claro .dijitTextBoxError,
+.claro .dijitTextBoxError .dijitInputContainer {
+	background-color: @textbox-error-background-color;
+}
+
+/* focused state */
+.claro .dijitTextBoxFocused,
+.claro .dijitTextBoxFocused .dijitButtonNode {
+	border-color:@focused-border-color;
+ 	.transition-duration(.1s);
+}
+.claro .dijitTextBoxFocused {
+	background-color: @textbox-focused-background-color;
+	background-image: url('images/textBox_back.png');
+	background-repeat: repeat-x;
+}
+.claro .dijitTextBoxFocused .dijitInputContainer {
+	background: @textbox-focused-background-color;
+}
+
+.claro .dijitTextBoxErrorFocused,
+.claro .dijitTextBoxErrorFocused .dijitButtonNode {
+	border-color: @error-focused-border-color;
+}
+
+/* disabled state */
+.claro .dijitTextBoxDisabled,
+.claro .dijitTextBoxDisabled .dijitButtonNode {
+	border-color: @disabled-border-color;
+}
+.claro .dijitTextBoxDisabled,
+.claro .dijitTextBoxDisabled .dijitInputContainer {
+	background-color: @textbox-disabled-background-color;
+	background-image: none;
+	color: @disabled-text-color;
+}
+
+/*========================= for special widgets =========================*/
+
+/* Input boxes with an arrow (for a drop down) */
+
+.claro .dijitComboBox .dijitArrowButtonInner {
+	background-image: url("images/commonFormArrows.png");
+	background-position:-35px 53%;
+	background-repeat: no-repeat;
+	margin: 0;
+	width:16px;
+	border: 1px solid @arrowbutton-inner-border-color;	// white gutter around the arrow button
+}
+
+.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
+	border: none;
+}
+
+.claro .dijitToolbar .dijitComboBox .dijitArrowButtonInner {
+	border: none;
+}
+
+/* Add 1px vertical padding to the <input> where user types and the validation icon,
+   to match the 1px border on arrow button */
+.claro .dijitTextBox .dijitInputInner,
+.claro .dijitTextBox .dijitValidationContainer {
+	padding: 1px 0;
+}
+
+.claro .dijitComboBox .dijitButtonNode {
+	background-color: @arrowbutton-background-color;
+	background-image: url("images/formHighlight.png");
+	background-repeat:repeat-x;
+}
+
+/* Arrow "hover" effect:
+ * The arrow button should change color whenever the mouse is in a position such that clicking it
+ * will toggle the drop down.   That's either (1) anywhere over the ComboBox or (2) over the arrow
+ * button, depending on the openOnClick setting for the widget.
+ */
+.claro .dijitComboBoxOpenOnClickHover .dijitButtonNode,
+.claro .dijitComboBox .dijitDownArrowButtonHover {
+	background-color:@arrowbutton-hovered-background-color;
+}
+.claro .dijitComboBoxOpenOnClickHover .dijitArrowButtonInner,
+.claro .dijitComboBox .dijitDownArrowButtonHover .dijitArrowButtonInner {
+	background-position:-70px 53%;
+}
+
+/* Arrow Button change when drop down is open */
+.claro .dijitComboBox .dijitHasDropDownOpen {	// .dijitHasDropDown is on dijitArrowButton node
+	background-color: @pressed-background-color;
+	background-position:0 -177px;
+	padding: 1px;		// Since no border on arrow button (see rule below)
+}	
+.claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
+	background-position:-70px 53%;
+	border: 0 none;
+}
+
+/* disabled state */
+.claro div.dijitComboBoxDisabled .dijitArrowButtonInner {
+	/* specific selector set to override background-position setting from Button.js
+	 * (.claro .dijitComboBoxDisabled .dijitArrowButtonInner) */
+	background-position:0 50%;
+	background-color:@disabled-background-color;
+}
+
+/*========================= hacks for browsers =========================*/
+/* it seems the input[type="hidden"] has a height (16px) too... this may cause the widget's height calculate error */
+.dj_ff3 .claro .dijitInputField input[type="hidden"] {
+	display: none;
+	height: 0;
+	width: 0;
+}
+
+/* ie6 doesn't support transparent background img */
+.dj_ie6 .claro .dijitTextBox,
+.dj_ie6 .claro .dijitComboBox .dijitButtonNode {
+	background-image: none;
+}
+.dj_borderbox .claro .dijitComboBox .dijitHasDropDownOpen .dijitArrowButtonInner {
+	width:18px;				// quirks mode means border-box sizing, so 18px with the border (same as 16px without border)
+}
+.dj_borderbox .claro .dijitComboBoxFocused .dijitHasDropDownOpen .dijitArrowButtonInner {
+	width:16px;				// when no border, then back to 16px just like content-box sizing
+}
\ No newline at end of file
diff --git a/dijit/themes/claro/form/Common_rtl.css b/dijit/themes/claro/form/Common_rtl.css
index 1e21dec..74827c1 100644
--- a/dijit/themes/claro/form/Common_rtl.css
+++ b/dijit/themes/claro/form/Common_rtl.css
@@ -1,10 +1,10 @@
 /* claro/form/Common_rtl.css */
 /*claro should not have the icon on the container
 .claro .dijitTextBoxRtlError .dijitValidationIcon {
-	border-left-width: 0px;
+	border-left-width: 0;
 	border-right-width: 1px;
 }*/
 .claro .dijitTextBoxRtlError .dijitValidationContainer {
-	border-left-width: 0px;
-	border-right-width: 1px;
+  border-left-width: 0;
+  border-right-width: 1px;
 }
diff --git a/dijit/themes/claro/form/Common_rtl.less b/dijit/themes/claro/form/Common_rtl.less
new file mode 100644
index 0000000..fd4975a
--- /dev/null
+++ b/dijit/themes/claro/form/Common_rtl.less
@@ -0,0 +1,13 @@
+/* claro/form/Common_rtl.css */
+
+ at import "../variables";
+
+/*claro should not have the icon on the container
+.claro .dijitTextBoxRtlError .dijitValidationIcon {
+	border-left-width: 0;
+	border-right-width: 1px;
+}*/
+.claro .dijitTextBoxRtlError .dijitValidationContainer {
+	border-left-width: 0;
+	border-right-width: 1px;
+}
diff --git a/dijit/themes/claro/form/NumberSpinner.css b/dijit/themes/claro/form/NumberSpinner.css
index 1009ee0..bc6e1ae 100644
--- a/dijit/themes/claro/form/NumberSpinner.css
+++ b/dijit/themes/claro/form/NumberSpinner.css
@@ -19,125 +19,120 @@
  * 5. Disabled state
  * 		.dijitSpinnerDisabled .* - for background color|image
  */
-
 .claro .dijitSpinnerButtonContainer {
-	overflow: hidden;
-	position: relative;
-	width: auto;
-	padding: 0 2px;
+  overflow: hidden;
+  position: relative;
+  width: auto;
+  padding: 0 2px;
 }
 .claro .dijitSpinnerButtonContainer .dijitSpinnerButtonInner {
-	border-width: 1px 0; /* reserve space to match the claro combobox button border with border and not padding to make IE happier */
-	border-style: solid none;
-}
+  border-width: 1px 0;
+  /* reserve space to match the claro combobox button border with border and not padding to make IE happier */
 
+  border-style: solid none;
+}
 /* button */
 .claro .dijitSpinner .dijitArrowButton {
-	width:auto;
-	background-color: #ebeef4;
-	background-image: url("images/formHighlight.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
-	overflow: hidden;
+  width: auto;
+  background-color: #efefef;
+  background-image: url("images/formHighlight.png");
+  background-position: 0 0;
+  background-repeat: repeat-x;
+  overflow: hidden;
 }
 .dj_iequirks .claro .dijitSpinner .dijitArrowButton {
-	overflow: visible; /* 0 height w/o this */
-}
+  overflow: visible;
+  /* 0 height w/o this */
 
+}
 .claro .dijitSpinner .dijitSpinnerButtonInner {
-	width: 15px;
+  width: 15px;
 }
 /* up & down button icons */
 .claro .dijitSpinner .dijitArrowButtonInner {
-	border:solid 1px #fff;
-	border-bottom-width: 0; /* 2 top borders = 1 top+bottom border in ComboBox */
-	background-image: url("images/commonFormArrows.png");
-	background-repeat: no-repeat;
-	height: 100%;
-	width:15px;
-	padding-left: 1px;
-	padding-right: 1px;
+  border: solid 1px #ffffff;
+  border-bottom-width: 0;
+  /* 2 top borders = 1 top+bottom border in ComboBox */
+
+  background-image: url("images/commonFormArrows.png");
+  background-repeat: no-repeat;
+  height: 100%;
+  width: 15px;
+  padding-left: 1px;
+  padding-right: 1px;
+  /* for up arrow */
 
-	/* for up arrow */
-	background-position:-139px center;
+  background-position: -139px center;
+  /* override button.css (TODO: move to Common.css since ComboBox needs this too) */
+
+  display: block;
+  margin: -1px 0 -1px 0;
+  /* compensate for inner border */
+
+}
+.dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner, .dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner {
+  margin-top: 0;
+  /* since its bottom aligned */
 
-	/* override button.css (TODO: move to Common.css since ComboBox needs this too) */
-	display: block;
-	margin: -1px 0px -1px 0px;	/* compensate for inner border */
-	#margin-top: 0; /* since its bottom aligned */
 }
 .dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner {
-	width: 19px;
+  width: 19px;
 }
 .claro .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner {
-	background-position:-34px;
+  background-position: -34px;
 }
 .claro .dijitSpinner .dijitArrowButtonInner .dijitInputField {
-	padding: 0;
+  padding: 0;
 }
-
 /** hover & focused status **/
-
-.claro .dijitUpArrowButtonActive,
-.claro .dijitDownArrowButtonActive {
-	background-color:#abd6ff;
+.claro .dijitUpArrowButtonActive, .claro .dijitDownArrowButtonActive {
+  background-color: #abd6ff;
 }
-
-.claro .dijitSpinner .dijitUpArrowButtonHover,
-.claro .dijitSpinner .dijitDownArrowButtonHover,
-.claro .dijitSpinnerFocused .dijitArrowButton {
-	background-color: #a0d1ff;
+.claro .dijitSpinner .dijitUpArrowButtonHover, .claro .dijitSpinner .dijitDownArrowButtonHover, .claro .dijitSpinnerFocused .dijitArrowButton {
+  background-color: #abd6ff;
 }
-
 .claro .dijitSpinner .dijitUpArrowButtonHover .dijitArrowButtonInner {
-	background-position:-174px;
+  background-position: -174px;
 }
 .claro .dijitSpinner .dijitDownArrowButtonHover .dijitArrowButtonInner {
-	background-position:-69px;
+  background-position: -69px;
 }
-
 .claro .dijitSpinnerFocused {
-	background-color: #fff;
-	background-image: none;
+  background-color: #ffffff;
+  background-image: none;
 }
-
 /* mouse down status */
-.claro .dijitSpinner .dijitDownArrowButtonActive,
-.claro .dijitSpinner .dijitUpArrowButtonActive {
-	background-color: #3299f9;
-	background-position:0px -177px;
+.claro .dijitSpinner .dijitDownArrowButtonActive, .claro .dijitSpinner .dijitUpArrowButtonActive {
+  background-color: #7dbefa;
+  background-position: 0 -177px;
 }
-.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner,
-.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
-	/* hide inner border while button is depressed */
-	border: 0px;
-	padding: 1px;
-	margin-right:2px;
-	margin-bottom:1px;
+.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner, .claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
+  /* hide inner border while button is depressed */
+
+  border: 0;
+  padding: 1px;
+  margin-right: 2px;
+  margin-bottom: 1px;
 }
 .claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner {
-	background-position:-173px;
+  background-position: -173px;
 }
 .claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
-	background-position:-68px;
+  background-position: -68px;
 }
-
 /* disabled */
-
 .claro .dijitSpinnerDisabled .dijitArrowButtonInner {
-	background-color: #f1f1f1;
+  background-color: #efefef;
 }
 .claro .dijitSpinnerDisabled .dijitUpArrowButton .dijitArrowButtonInner {
-	background-position:-104px;
+  background-position: -104px;
 }
 .claro .dijitSpinnerDisabled .dijitDownArrowButton .dijitArrowButtonInner {
-	background-position:1px;
+  background-position: 1px;
 }
-
 /** hacks for browsers **/
-
 /* for IE 7, when div is enlarged, 
  * should be no empty space between dijitInputLayoutContainer and dijitSpinner*/
 .dj_ie7 .claro .dijitSpinner {
-	overflow:visible;
-} 
\ No newline at end of file
+  overflow: visible;
+}
diff --git a/dijit/themes/claro/form/NumberSpinner.less b/dijit/themes/claro/form/NumberSpinner.less
new file mode 100644
index 0000000..ca78afb
--- /dev/null
+++ b/dijit/themes/claro/form/NumberSpinner.less
@@ -0,0 +1,150 @@
+/* NumberSpinner - namespace "dijitSpinner"
+ * 
+ * Styling NumberSpinner mainly includes:
+ * 
+ * 1. Arrows
+ * 		Outer containers: .dijitSpinnerButtonContainer|.dijitSpinnerButtonInner  - for border, padding and position
+ * 		Arrows: .dijitArrowButton|.dijitUpArrowButton.|dijitDownArrowButton
+ * 		Inner container: .dijitArrowButtonInner - for border, padding, width|height and background image
+ * 
+ * 2. Hover state
+ * 		.dijitUpArrowButtonHover|.dijitDownArrowButtonHover .*  - for background color|image
+ * 
+ * 3. Active state
+ * 		.dijitUpArrowButtonActive|.dijitDownArrowButtonActive .*  - for border, padding, margin and background color|image
+ * 
+ * 4. Focused state
+ * 		.dijitSpinnerFocused .* - for background color|image
+ * 
+ * 5. Disabled state
+ * 		.dijitSpinnerDisabled .* - for background color|image
+ */
+
+ at import "../variables";
+
+.claro .dijitSpinnerButtonContainer {
+	overflow: hidden;
+	position: relative;
+	width: auto;
+	padding: 0 2px;
+}
+.claro .dijitSpinnerButtonContainer .dijitSpinnerButtonInner {
+	border-width: 1px 0; /* reserve space to match the claro combobox button border with border and not padding to make IE happier */
+	border-style: solid none;
+}
+
+/* button */
+.claro .dijitSpinner .dijitArrowButton {
+	width:auto;
+	background-color: @arrowbutton-background-color;
+	background-image: url("images/formHighlight.png");
+	background-position:0 0;
+	background-repeat:repeat-x;
+	overflow: hidden;
+}
+.dj_iequirks .claro .dijitSpinner .dijitArrowButton {
+	overflow: visible; /* 0 height w/o this */
+}
+
+.claro .dijitSpinner .dijitSpinnerButtonInner {
+	width: 15px;
+}
+/* up & down button icons */
+.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-repeat: no-repeat;
+	height: 100%;
+	width:15px;
+	padding-left: 1px;
+	padding-right: 1px;
+
+	/* for up arrow */
+	background-position:-139px center;
+
+	/* override button.css (TODO: move to Common.css since ComboBox needs this too) */
+	display: block;
+	margin: -1px 0 -1px 0;	/* compensate for inner border */
+}
+
+.dj_ie6 .claro .dijitSpinner .dijitArrowButtonInner,
+.dj_ie7 .claro .dijitSpinner .dijitArrowButtonInner {
+	margin-top: 0; /* since its bottom aligned */
+}
+
+.dj_iequirks .claro .dijitSpinner .dijitArrowButtonInner {
+	width: 19px;
+}
+.claro .dijitSpinner .dijitDownArrowButton .dijitArrowButtonInner {
+	background-position:-34px;
+}
+.claro .dijitSpinner .dijitArrowButtonInner .dijitInputField {
+	padding: 0;
+}
+
+/** hover & focused status **/
+
+.claro .dijitUpArrowButtonActive,
+.claro .dijitDownArrowButtonActive {
+	background-color:@arrowbutton-pressed-background-color;
+}
+
+.claro .dijitSpinner .dijitUpArrowButtonHover,
+.claro .dijitSpinner .dijitDownArrowButtonHover,
+.claro .dijitSpinnerFocused .dijitArrowButton {
+	background-color: @arrowbutton-hovered-background-color;
+}
+
+.claro .dijitSpinner .dijitUpArrowButtonHover .dijitArrowButtonInner {
+	background-position:-174px;
+}
+.claro .dijitSpinner .dijitDownArrowButtonHover .dijitArrowButtonInner {
+	background-position:-69px;
+}
+
+.claro .dijitSpinnerFocused {
+	background-color: @textbox-focused-background-color;
+	background-image: none;
+}
+
+/* mouse down status */
+.claro .dijitSpinner .dijitDownArrowButtonActive,
+.claro .dijitSpinner .dijitUpArrowButtonActive {
+	background-color: #7dbefa;		// TODO.  Mailed Jason about inconsistent ComboBox/Spinner behavior.
+	background-position:0 -177px;
+}
+.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner,
+.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
+	/* hide inner border while button is depressed */
+	border: 0;
+	padding: 1px;
+	margin-right:2px;
+	margin-bottom:1px;
+}
+.claro .dijitSpinner .dijitUpArrowButtonActive .dijitArrowButtonInner {
+	background-position:-173px;
+}
+.claro .dijitSpinner .dijitDownArrowButtonActive .dijitArrowButtonInner {
+	background-position:-68px;
+}
+
+/* disabled */
+
+.claro .dijitSpinnerDisabled .dijitArrowButtonInner {
+	background-color: @disabled-background-color;
+}
+.claro .dijitSpinnerDisabled .dijitUpArrowButton .dijitArrowButtonInner {
+	background-position:-104px;
+}
+.claro .dijitSpinnerDisabled .dijitDownArrowButton .dijitArrowButtonInner {
+	background-position:1px;
+}
+
+/** hacks for browsers **/
+
+/* for IE 7, when div is enlarged, 
+ * 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 382386d..4dc3ad4 100644
--- a/dijit/themes/claro/form/RadioButton.css
+++ b/dijit/themes/claro/form/RadioButton.css
@@ -18,65 +18,62 @@
  * 5. Disabled state
  * 		.dijitRadioDisabled|.dijitRadioCheckedDisabled - for background image
  */
-
-.claro .dijitToggleButton .dijitRadio,
-.claro .dijitToggleButton .dijitRadioIcon {
-	background-image: url('images/checkboxRadioButtonStates.png');
+.claro .dijitToggleButton .dijitRadio, .claro .dijitToggleButton .dijitRadioIcon {
+  background-image: url('images/checkboxRadioButtonStates.png');
 }
-
-.dj_ie6 .claro .dijitToggleButton .dijitRadio,
-.dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
-	background-image: url('images/checkboxAndRadioButtons_IE6.png');
+.dj_ie6 .claro .dijitToggleButton .dijitRadio, .dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
+  background-image: url('images/checkboxAndRadioButtons_IE6.png');
 }
+.claro .dijitRadio, .claro .dijitRadioIcon {
+  /* inside a toggle button */
 
-.claro .dijitRadio,
-.claro .dijitRadioIcon	{		/* inside a toggle button */
-	background-image: url('images/checkboxRadioButtonStates.png'); /* checkbox sprite image */
-	background-repeat: no-repeat;
-	width: 15px;
-	height: 15px;
-	margin: 0px 2px 0px 0px;
-	padding: 0px;
-}
+  background-image: url('images/checkboxRadioButtonStates.png');
+  /* checkbox sprite image */
 
-.dj_ie6 .claro .dijitRadio,
-.dj_ie6 .claro .dijitRadioIcon	{		/* inside a toggle button */
-	background-image: url('images/checkboxAndRadioButtons_IE6.png'); /* checkbox sprite image */
+  background-repeat: no-repeat;
+  width: 15px;
+  height: 15px;
+  margin: 0 2px 0 0;
+  padding: 0;
 }
+.dj_ie6 .claro .dijitRadio, .dj_ie6 .claro .dijitRadioIcon {
+  /* inside a toggle button */
 
-.claro .dijitRadio{
-	/* unselected */
-	background-position: -105px;
-}
+  background-image: url('images/checkboxAndRadioButtons_IE6.png');
+  /* checkbox sprite image */
 
-.claro .dijitToggleButton .dijitRadioIcon {
-	/* unselected */
-	background-position: -107px;
 }
+.claro .dijitRadio {
+  /* unselected */
 
-.claro .dijitRadioDisabled {
-	/* unselected and disabled */
-	background-position: -165px;
+  background-position: -105px;
 }
+.claro .dijitToggleButton .dijitRadioIcon {
+  /* unselected */
 
-.claro .dijitRadioHover {
-	/* hovering over an unselected enabled radio button */
-	background-position: -135px;
+  background-position: -107px;
 }
+.claro .dijitRadioDisabled {
+  /* unselected and disabled */
 
-.claro .dijitRadioChecked{
-	background-position: -90px;
+  background-position: -165px;
 }
+.claro .dijitRadioHover {
+  /* hovering over an unselected enabled radio button */
 
+  background-position: -135px;
+}
+.claro .dijitRadioChecked {
+  background-position: -90px;
+}
 .claro .dijitToggleButtonChecked .dijitRadioIcon {
-	background-position: -92px;
+  background-position: -92px;
 }
-
-.claro .dijitRadioCheckedHover{
-	background-position: -120px;
+.claro .dijitRadioCheckedHover {
+  background-position: -120px;
 }
-
 .claro .dijitRadioCheckedDisabled {
-	/* selected but disabled */
-	background-position: -150px;
+  /* selected but disabled */
+
+  background-position: -150px;
 }
diff --git a/dijit/themes/claro/form/RadioButton.less b/dijit/themes/claro/form/RadioButton.less
new file mode 100644
index 0000000..18f1cc1
--- /dev/null
+++ b/dijit/themes/claro/form/RadioButton.less
@@ -0,0 +1,84 @@
+/* RadioButton
+ * 
+ * Styling RadioButton mainly includes:
+ * 
+ * 1. Containers
+ * 		.dijitRadio|.dijitRadioIcon - for border, padding, width|height and background image
+ * 
+ * 2. RadioButton within ToggleButton
+ * 		.dijitToggleButton|.dijitToggleButtonChecked .* - for background image
+ * 
+ * 3. Checked state
+ * 		.dijitRadioChecked - for checked background-color|image
+ * 		.dijitToggleButtonChecked - for border, background-color|image, display and width|height
+ * 
+ * 4. Hover state
+ * 		.dijitRadioHover|.dijitRadioCheckedHover - for background image
+ * 
+ * 5. Disabled state
+ * 		.dijitRadioDisabled|.dijitRadioCheckedDisabled - for background image
+ */
+
+ at import "../variables";
+
+.claro .dijitToggleButton .dijitRadio,
+.claro .dijitToggleButton .dijitRadioIcon {
+	background-image: url('images/checkboxRadioButtonStates.png');
+}
+
+.dj_ie6 .claro .dijitToggleButton .dijitRadio,
+.dj_ie6 .claro .dijitToggleButton .dijitRadioIcon {
+	background-image: url('images/checkboxAndRadioButtons_IE6.png');
+}
+
+.claro .dijitRadio,
+.claro .dijitRadioIcon	{		/* inside a toggle button */
+	background-image: url('images/checkboxRadioButtonStates.png'); /* checkbox sprite image */
+	background-repeat: no-repeat;
+	width: 15px;
+	height: 15px;
+	margin: 0 2px 0 0;
+	padding: 0;
+}
+
+.dj_ie6 .claro .dijitRadio,
+.dj_ie6 .claro .dijitRadioIcon	{		/* inside a toggle button */
+	background-image: url('images/checkboxAndRadioButtons_IE6.png'); /* checkbox sprite image */
+}
+
+.claro .dijitRadio{
+	/* unselected */
+	background-position: -105px;
+}
+
+.claro .dijitToggleButton .dijitRadioIcon {
+	/* unselected */
+	background-position: -107px;
+}
+
+.claro .dijitRadioDisabled {
+	/* unselected and disabled */
+	background-position: -165px;
+}
+
+.claro .dijitRadioHover {
+	/* hovering over an unselected enabled radio button */
+	background-position: -135px;
+}
+
+.claro .dijitRadioChecked{
+	background-position: -90px;
+}
+
+.claro .dijitToggleButtonChecked .dijitRadioIcon {
+	background-position: -92px;
+}
+
+.claro .dijitRadioCheckedHover{
+	background-position: -120px;
+}
+
+.claro .dijitRadioCheckedDisabled {
+	/* selected but disabled */
+	background-position: -150px;
+}
diff --git a/dijit/themes/claro/form/Select.css b/dijit/themes/claro/form/Select.css
index 5f4f019..a30ede6 100644
--- a/dijit/themes/claro/form/Select.css
+++ b/dijit/themes/claro/form/Select.css
@@ -16,109 +16,94 @@
  * 4. Various states
  * 		.dijitSelectHover|.dijitSelectFocused|.dijitSelectDisabled .* - for border, padding and background-color|image 
  */
-
 .claro .dijitSelect .dijitButtonText {
-	padding: 0px 5px 2px 5px;
+  padding: 2px;
 }
-
 /* normal status */
 .claro .dijitSelect {
-	border: 1px solid #b5bcc7;
-	background-color: #f7fcff;
-	border-collapse: separate;
+  border: 1px solid #b5bcc7;
+  background-color: #ffffff;
+  border-collapse: separate;
 }
-.dj_ie6 .claro .dijitSelect,
-.dj_ie6 .claro .dijitSelect .dijitButtonNode {
-	background-image:none;
+.dj_ie6 .claro .dijitSelect, .dj_ie6 .claro .dijitSelect .dijitButtonNode {
+  background-image: none;
 }
-
 .claro .dijitSelect .dijitButtonContents {
-	border: 0px solid #b5bcc7;
-	border-right-width: 1px;
+  border: 0 solid #b5bcc7;
+  border-right-width: 1px;
 }
-
 .claro .dijitSelect .dijitArrowButton {
-	padding: 0;
-	border: 1px solid #fff;	/* inner white border on button node */
-	border-top:none;
-	background-color:#ebeef4;
-	background-image: url("images/formHighlight.png");
-	background-repeat:repeat-x;
+  padding: 0;
+  border: 1px solid #ffffff;
+  border-top: none;
+  background-color: #efefef;
+  background-image: url("images/formHighlight.png");
+  background-repeat: repeat-x;
 }
-
 .claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
-	background-image: url("images/commonFormArrows.png");
-	background-position:-35px 70%;
-	background-repeat: no-repeat;
-	width:16px;
-	height:16px;
-	display:block;
+  background-image: url("images/commonFormArrows.png");
+  background-position: -35px 70%;
+  background-repeat: no-repeat;
+  width: 16px;
+  height: 16px;
 }
-
 /* hover status */
 .claro .dijitSelectHover {
-	border: 1px solid #769dc0;
-	background-color: #e9f4fe;
-	background-image: url('images/textBox_back.png');
-	background-repeat: repeat-x;
+  border: 1px solid #769dc0;
+  background-color: #e9f4fe;
+  background-image: url('images/textBox_back.png');
+  background-repeat: repeat-x;
 }
-
 .claro .dijitSelectHover .dijitButtonContents {
-	border-color:#81a5c6;
+  border-color: #769dc0;
 }
-
 .claro .dijitSelectHover .dijitArrowButton {
-	background-color:#abd6ff;
+  background-color: #abd6ff;
 }
 .claro .dijitSelectHover .dijitArrowButton .dijitArrowButtonInner {
-	background-position:-70px 70%;
+  background-position: -70px 70%;
 }
-
 /* focused status */
 .claro .dijitSelectFocused {
-	border: 1px solid #769dc0;
+  border: 1px solid #769dc0;
 }
 .claro .dijitSelectFocused .dijitButtonContents {
-	border-color:#81a5c6;
+  border-color: #769dc0;
 }
 .claro .dijitSelectFocused .dijitArrowButton {
-	background-color:#7dbefa;
-	background-position:0px -177px;
-	border: none;
-	padding: 0px 1px;
+  background-color: #7dbefa;
+  background-position: 0 -177px;
+  border: none;
+  padding: 0 1px;
 }
 .claro .dijitSelectFocused .dijitArrowButton .dijitArrowButtonInner {
-	background-position:-70px 70%;
-	margin-bottom: 1px;
+  background-position: -70px 70%;
+  margin-bottom: 1px;
 }
-
 /* disable status */
 .claro .dijitSelectDisabled {
-	border: 1px solid #d3d3d3;
-	background-color: #efefef;
-	background-image: none;
-	color: #818181;
+  border: 1px solid #d3d3d3;
+  background-color: #efefef;
+  background-image: none;
+  color: #818181;
 }
-.claro .dijitSelectDisabled .dijitArrowButton { 
-	background-color: #efefef;
+.claro .dijitSelectDisabled .dijitArrowButton {
+  background-color: #efefef;
 }
 .claro .dijitSelectDisabled .dijitArrowButton .dijitArrowButtonInner {
-	background-position:0px 70%
+  background-position: 0 70%;
 }
-
 /* Dropdown menu style for select */
+.claro .dijitSelectMenu td.dijitMenuItemIconCell, .claro .dijitSelectMenu td.dijitMenuArrowCell {
+  /* so that arrow and icon cells from MenuItem are not displayed */
 
-.claro .dijitSelectMenu td.dijitMenuItemIconCell,
-.claro .dijitSelectMenu td.dijitMenuArrowCell { 
-	/* so that arrow and icon cells from MenuItem are not displayed */
-	display: none;  
+  display: none;
 }
 .claro .dijitSelectMenu td.dijitMenuItemLabel {
-	/* line up menu text with text in select box (in LTR and RTL modes) */
-	padding-left: 5px;
-	padding-right: 5px;
-}
+  /* line up menu text with text in select box (in LTR and RTL modes) */
 
+  padding: 2px;
+}
 .claro .dijitSelectMenu .dijitMenuSeparatorTop {
-	border-bottom:1px solid #769dc0;
+  border-bottom: 1px solid #769dc0;
 }
diff --git a/dijit/themes/claro/form/Select.less b/dijit/themes/claro/form/Select.less
new file mode 100644
index 0000000..c429b2e
--- /dev/null
+++ b/dijit/themes/claro/form/Select.less
@@ -0,0 +1,124 @@
+/* Select
+ * 
+ * Styling Select mainly includes:
+ * 
+ * 1. Containers
+ * 		.dijitSelect - for border, background-color
+ * 		.dijitButtonContents - for border
+ *
+ * 2. Arrow
+ * 		.dijitArrowButton - for border, padding and background-color|image
+ * 		.dijitArrowButtonInner - for border, background-color|image, display and width|height
+ * 
+ * 3. Menu
+ * 		.dijitSelectMenu .* - for border, padding
+ * 
+ * 4. Various states
+ * 		.dijitSelectHover|.dijitSelectFocused|.dijitSelectDisabled .* - for border, padding and background-color|image 
+ */
+
+ at import "../variables";
+
+.claro .dijitSelect .dijitButtonText {
+	padding: @textbox-padding;
+}
+
+/* normal status */
+.claro .dijitSelect {
+	border: 1px solid @border-color;
+	background-color: @textbox-background-color;
+	border-collapse: separate;
+}
+.dj_ie6 .claro .dijitSelect,
+.dj_ie6 .claro .dijitSelect .dijitButtonNode {
+	background-image:none;
+}
+
+.claro .dijitSelect .dijitButtonContents {
+	border: 0 solid @border-color;
+	border-right-width: 1px;
+}
+
+.claro .dijitSelect .dijitArrowButton {
+	padding: 0;
+	border: 1px solid @arrowbutton-inner-border-color;
+	border-top:none;
+	background-color: @arrowbutton-background-color;
+	background-image: url("images/formHighlight.png");
+	background-repeat:repeat-x;
+}
+
+.claro .dijitSelect .dijitArrowButton .dijitArrowButtonInner {
+	background-image: url("images/commonFormArrows.png");
+	background-position:-35px 70%;
+	background-repeat: no-repeat;
+	width:16px;
+	height:16px;
+}
+
+/* hover status */
+.claro .dijitSelectHover {
+	border: 1px solid @hovered-border-color;
+	background-color: @textbox-hovered-background-color;
+	background-image: url('images/textBox_back.png');
+	background-repeat: repeat-x;
+}
+
+.claro .dijitSelectHover .dijitButtonContents {
+	border-color:@hovered-border-color;
+}
+
+.claro .dijitSelectHover .dijitArrowButton {
+	background-color:@arrowbutton-hovered-background-color;
+}
+.claro .dijitSelectHover .dijitArrowButton .dijitArrowButtonInner {
+	background-position:-70px 70%;
+}
+
+/* focused status */
+.claro .dijitSelectFocused {
+	border: 1px solid @focused-border-color;
+}
+.claro .dijitSelectFocused .dijitButtonContents {
+	border-color:@focused-border-color;
+}
+.claro .dijitSelectFocused .dijitArrowButton {
+	background-color:#7dbefa;		// TODO.  Mailed Jason about inconsistent ComboBox/Spinner behavior.
+	background-position:0 -177px;
+	border: none;
+	padding: 0 1px;
+}
+.claro .dijitSelectFocused .dijitArrowButton .dijitArrowButtonInner {
+	background-position:-70px 70%;
+	margin-bottom: 1px;
+}
+
+/* disable status */
+.claro .dijitSelectDisabled {
+	border: 1px solid @disabled-border-color;
+	background-color: @disabled-background-color;
+	background-image: none;
+	color: @disabled-text-color;
+}
+.claro .dijitSelectDisabled .dijitArrowButton { 
+	background-color: @disabled-background-color;
+}
+.claro .dijitSelectDisabled .dijitArrowButton .dijitArrowButtonInner {
+	background-position:0 70%
+}
+
+/* Dropdown menu style for select */
+
+.claro .dijitSelectMenu td.dijitMenuItemIconCell,
+.claro .dijitSelectMenu td.dijitMenuArrowCell { 
+	/* so that arrow and icon cells from MenuItem are not displayed */
+	display: none;  
+}
+.claro .dijitSelectMenu td.dijitMenuItemLabel {
+	/* line up menu text with text in select box (in LTR and RTL modes) */
+	padding: @textbox-padding;
+}
+
+.claro .dijitSelectMenu .dijitMenuSeparatorTop {
+	border-bottom:1px solid @focused-border-color;
+}
diff --git a/dijit/themes/claro/form/Select_rtl.css b/dijit/themes/claro/form/Select_rtl.css
index 4379750..a14d4ec 100644
--- a/dijit/themes/claro/form/Select_rtl.css
+++ b/dijit/themes/claro/form/Select_rtl.css
@@ -1,4 +1,4 @@
 .claro .dijitSelectRtl .dijitButtonContents {
-	border-right-width: 0px;
-	border-left-width: 1px;
+  border-right-width: 0;
+  border-left-width: 1px;
 }
diff --git a/dijit/themes/claro/form/Select_rtl.less b/dijit/themes/claro/form/Select_rtl.less
new file mode 100644
index 0000000..ffa40dc
--- /dev/null
+++ b/dijit/themes/claro/form/Select_rtl.less
@@ -0,0 +1,6 @@
+ at import "../variables";
+
+.claro .dijitSelectRtl .dijitButtonContents {
+	border-right-width: 0;
+	border-left-width: 1px;
+}
diff --git a/dijit/themes/claro/form/Slider.css b/dijit/themes/claro/form/Slider.css
index 3c109f1..5694e8c 100644
--- a/dijit/themes/claro/form/Slider.css
+++ b/dijit/themes/claro/form/Slider.css
@@ -49,220 +49,194 @@
  * 		.dijitSliderDisabled .dijitSliderDecrementIconH - styles for the icons in disabled slider
  * 		.dijitSliderReadOnly .dijitSliderIncrementIconV - styles for the icons in read-only slider
  */
-
 .claro .dijitSliderBar {
-	border-style: solid;
-	outline: 1px;
+  border-style: solid;
+  outline: 1px;
 }
 .claro .dijitSliderFocused .dijitSliderBar {
-	border-color: #769dc0;
+  border-color: #769dc0;
 }
 .claro .dijitSliderHover .dijitSliderBar {
-	border-color: #769dc0;
+  border-color: #769dc0;
 }
 .claro .dijitSliderDisabled .dijitSliderBar {
-	background-image: none;
-	border-color: #d3d3d3;
+  background-image: none;
+  border-color: #d3d3d3;
 }
-
 /* Horizontal Slider */
-
 .claro .dijitRuleLabelsContainerH {
-	padding: 2px 0px;
-}
-.claro .dijitSlider .dijitSliderProgressBarH,
-.claro .dijitSlider .dijitSliderLeftBumper{
-	background-image: url("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-repeat:repeat-x;
-	background-position:0 -11px;
-	border-color: #b5bcc7;
-	background-color: #fff;
+  padding: 2px 0;
+}
+.claro .dijitSlider .dijitSliderProgressBarH, .claro .dijitSlider .dijitSliderLeftBumper {
+  background-image: url("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-repeat: repeat-x;
+  background-position: 0 -11px;
+  border-color: #b5bcc7;
+  background-color: #ffffff;
 }
 .claro .dijitSliderRightBumper {
-	border-right: solid 1px #b5bcc7;
+  border-right: solid 1px #b5bcc7;
 }
 .claro .dijitSliderLeftBumper {
-	border-left: solid 1px #b5bcc7;
-}
-.claro .dijitSliderHover .dijitSliderProgressBarH,
-.claro .dijitSliderHover .dijitSliderLeftBumper{
-	background-position:0 -20px;
-	background-color: #abd6ff;
-	border-color: #769dc0;
-}
-.claro .dijitSliderHover .dijitSliderRemainingBarH,
-.claro .dijitSliderHover .dijitSliderRightBumper{
-	background-position:0 0px;
-	background-color: #fff;
-	border-color: #769dc0;
-}
-.claro .dijitSliderFocused .dijitSliderProgressBarH,
-.claro .dijitSliderFocused .dijitSliderLeftBumper{
-	background-position:0 -30px;
-	background-color: #abd6ff;
-	border-color: #769dc0;
-}
-.claro .dijitSliderFocused .dijitSliderRemainingBarH,
-.claro .dijitSliderFocused .dijitSliderRightBumper{
-	background-position:0 -9px;
-	background-color: #fff;
-	border-color: #769dc0;
-}
-.claro .dijitSliderDisabled .dijitSliderProgressBarH,
-.claro .dijitSliderDisabled .dijitSliderLeftBumper{
-	background-color: #cdcdcd;
-	background-image:none;
-}
-.claro .dijitSliderDisabled .dijitSliderRemainingBarH,
-.claro .dijitSliderDisabled .dijitSliderRightBumper{
-	background-color: #efefef;
-}
+  border-left: solid 1px #b5bcc7;
+}
+.claro .dijitSliderHover .dijitSliderProgressBarH, .claro .dijitSliderHover .dijitSliderLeftBumper {
+  background-position: 0 -20px;
+  background-color: #abd6ff;
+  border-color: #769dc0;
+}
+.claro .dijitSliderHover .dijitSliderRemainingBarH, .claro .dijitSliderHover .dijitSliderRightBumper {
+  background-position: 0 0;
+  background-color: #ffffff;
+  border-color: #769dc0;
+}
+.claro .dijitSliderFocused .dijitSliderProgressBarH, .claro .dijitSliderFocused .dijitSliderLeftBumper {
+  background-position: 0 -30px;
+  background-color: #abd6ff;
+  border-color: #769dc0;
+}
+.claro .dijitSliderFocused .dijitSliderRemainingBarH, .claro .dijitSliderFocused .dijitSliderRightBumper {
+  background-position: 0 -9px;
+  background-color: #ffffff;
+  border-color: #769dc0;
+}
+.claro .dijitSliderDisabled .dijitSliderProgressBarH, .claro .dijitSliderDisabled .dijitSliderLeftBumper {
+  background-color: #d3d3d3;
+  /* left side of slider, fill matches border */
 
+  background-image: none;
+}
+.claro .dijitSliderDisabled .dijitSliderRemainingBarH, .claro .dijitSliderDisabled .dijitSliderRightBumper {
+  background-color: #efefef;
+}
 /* Vertical Slider */
-
 .claro .dijitRuleLabelsContainerV {
-	padding: 0px 2px;
-}
-.claro .dijitSlider .dijitSliderProgressBarV,
-.claro .dijitSlider .dijitSliderBottomBumper{
-	background-image: url("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-repeat:repeat-y;
-	background-position:-3px 0;
-	border-color: #b5bcc7;
-	background-color: #fff;
+  padding: 0 2px;
+}
+.claro .dijitSlider .dijitSliderProgressBarV, .claro .dijitSlider .dijitSliderBottomBumper {
+  background-image: url("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-repeat: repeat-y;
+  background-position: -3px 0;
+  border-color: #b5bcc7;
+  background-color: #ffffff;
 }
 .claro .dijitSliderBottomBumper {
-	border-bottom: solid 1px #b5bcc7;
+  border-bottom: solid 1px #b5bcc7;
 }
 .claro .dijitSliderTopBumper {
-	border-top: solid 1px #b5bcc7;
+  border-top: solid 1px #b5bcc7;
 }
-.claro .dijitSliderHover .dijitSliderProgressBarV,
-.claro .dijitSliderHover .dijitSliderBottomBumper{
-	background-position:-36px 0;
-	background-color: #abd6ff;
+.claro .dijitSliderHover .dijitSliderProgressBarV, .claro .dijitSliderHover .dijitSliderBottomBumper {
+  background-position: -36px 0;
+  background-color: #abd6ff;
 }
-.claro .dijitSliderHover .dijitSliderRemainingBarV,
-.claro .dijitSliderHover .dijitSliderTopBumper{
-	background-position:0 0;
-	background-color: #fff;
+.claro .dijitSliderHover .dijitSliderRemainingBarV, .claro .dijitSliderHover .dijitSliderTopBumper {
+  background-position: 0 0;
+  background-color: #ffffff;
 }
-.claro .dijitSliderFocused .dijitSliderProgressBarV,
-.claro .dijitSliderFocused .dijitSliderBottomBumper{
-	background-position:-56px 0;
-	background-color: #abd6ff;
+.claro .dijitSliderFocused .dijitSliderProgressBarV, .claro .dijitSliderFocused .dijitSliderBottomBumper {
+  background-position: -56px 0;
+  background-color: #abd6ff;
 }
-.claro .dijitSliderFocused .dijitSliderRemainingBarV,
-.claro .dijitSliderFocused .dijitSliderTopBumper{
-	background-position:-18px 0;
-	background-color: #fff;
+.claro .dijitSliderFocused .dijitSliderRemainingBarV, .claro .dijitSliderFocused .dijitSliderTopBumper {
+  background-position: -18px 0;
+  background-color: #ffffff;
 }
-.claro .dijitSliderDisabled .dijitSliderProgressBarV,
-.claro .dijitSliderDisabled .dijitSliderBottomBumper{
-	background-color: #cdcdcd;
+.claro .dijitSliderDisabled .dijitSliderProgressBarV, .claro .dijitSliderDisabled .dijitSliderBottomBumper {
+  background-color: #d3d3d3;
+  /* bottom side of slider, fill matches border */
+
 }
-.claro .dijitSliderDisabled .dijitSliderRemainingBarV,
-.claro .dijitSliderDisabled .dijitSliderTopBumper{
-	background-color: #efefef;
+.claro .dijitSliderDisabled .dijitSliderRemainingBarV, .claro .dijitSliderDisabled .dijitSliderTopBumper {
+  background-color: #efefef;
 }
-
-
 /* ------- Thumbs ------- */
-
 .claro .dijitSliderImageHandleH {
-	border: 0px;
-	width: 18px;
-	height: 16px;
-	background-image: url("images/sliderThumbs.png");
-	background-repeat:no-repeat;
-	background-position:0 0;
+  border: 0;
+  width: 18px;
+  height: 16px;
+  background-image: url("images/sliderThumbs.png");
+  background-repeat: no-repeat;
+  background-position: 0 0;
 }
 .claro .dijitSliderHover .dijitSliderImageHandleH {
-	background-position:-18px 0;
+  background-position: -18px 0;
 }
 .claro .dijitSliderFocused .dijitSliderImageHandleH {
-	background-position:-36px 0;
+  background-position: -36px 0;
 }
-.claro .dijitSliderProgressBarH .dijitSliderThumbHover{
-	background-position:-36px 0;
+.claro .dijitSliderProgressBarH .dijitSliderThumbHover {
+  background-position: -36px 0;
 }
-.claro .dijitSliderProgressBarH .dijitSliderThumbActive{
-	background-position:-36px 0;
+.claro .dijitSliderProgressBarH .dijitSliderThumbActive {
+  background-position: -36px 0;
 }
-.claro .dijitSliderReadOnly .dijitSliderImageHandleH,
-.claro .dijitSliderDisabled .dijitSliderImageHandleH {
-	background-position:-54px 0;
+.claro .dijitSliderReadOnly .dijitSliderImageHandleH, .claro .dijitSliderDisabled .dijitSliderImageHandleH {
+  background-position: -54px 0;
 }
 .claro .dijitSliderImageHandleV {
-	border: 0px;
-	width: 18px;
-	height: 16px;
-	background-image: url("images/sliderThumbs.png");
-	background-repeat:no-repeat;
-	background-position:-289px 0;
+  border: 0;
+  width: 18px;
+  height: 16px;
+  background-image: url("images/sliderThumbs.png");
+  background-repeat: no-repeat;
+  background-position: -289px 0;
 }
 .claro .dijitSliderHover .dijitSliderImageHandleV {
-	background-position:-307px 0;
+  background-position: -307px 0;
 }
 .claro .dijitSliderFocused .dijitSliderImageHandleV {
-	background-position:-325px 0;
+  background-position: -325px 0;
 }
-.claro .dijitSliderProgressBarV .dijitSliderThumbHover{
-	background-position:-325px 0;
+.claro .dijitSliderProgressBarV .dijitSliderThumbHover {
+  background-position: -325px 0;
 }
-.claro .dijitSliderProgressBarV .dijitSliderThumbActive{
-	background-position:-325px 0;
+.claro .dijitSliderProgressBarV .dijitSliderThumbActive {
+  background-position: -325px 0;
 }
-.claro .dijitSliderReadOnly .dijitSliderImageHandleV,
-.claro .dijitSliderDisabled .dijitSliderImageHandleV {
-	background-position:-343px 0;
+.claro .dijitSliderReadOnly .dijitSliderImageHandleV, .claro .dijitSliderDisabled .dijitSliderImageHandleV {
+  background-position: -343px 0;
 }
-
 /* ---- Increment/Decrement Buttons ---- */
-
-.claro .dijitSliderButtonContainerH{
-	padding: 1px 3px 1px 2px;
+.claro .dijitSliderButtonContainerH {
+  padding: 1px 3px 1px 2px;
 }
-.claro .dijitSliderButtonContainerV{
-	padding: 3px 1px 2px 1px;
+.claro .dijitSliderButtonContainerV {
+  padding: 3px 1px 2px 1px;
 }
 .claro .dijitSliderDecrementIconH,
 .claro .dijitSliderIncrementIconH,
 .claro .dijitSliderDecrementIconV,
 .claro .dijitSliderIncrementIconV {
-	background-image: url('images/commonFormArrows.png');
-	background-repeat:no-repeat;
-	background-color: #e9ecf2;
-	-moz-border-radius: 2px;
-	-webkit-border-radius: 2px;
-	border: solid 1px #b5bcc7;
-	font-size: 1px;
-}
-.claro .dijitSliderDecrementIconH,
-.claro .dijitSliderIncrementIconH {
-	height: 12px;
-	width: 9px;
-}
-.claro .dijitSliderDecrementIconV,
-.claro .dijitSliderIncrementIconV {
-	height: 9px;
-	width: 12px;
+  background-image: url('images/commonFormArrows.png');
+  background-repeat: no-repeat;
+  background-color: #efefef;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  border: solid 1px #b5bcc7;
+  font-size: 1px;
+}
+.claro .dijitSliderDecrementIconH, .claro .dijitSliderIncrementIconH {
+  height: 12px;
+  width: 9px;
+}
+.claro .dijitSliderDecrementIconV, .claro .dijitSliderIncrementIconV {
+  height: 9px;
+  width: 12px;
 }
 .claro .dijitSliderActive .dijitSliderDecrementIconH,
 .claro .dijitSliderActive .dijitSliderIncrementIconH,
@@ -272,81 +246,74 @@
 .claro .dijitSliderHover .dijitSliderIncrementIconH,
 .claro .dijitSliderHover .dijitSliderDecrementIconV,
 .claro .dijitSliderHover .dijitSliderIncrementIconV {
-	border: solid 1px #769dc0;
-	background-color:#fff;
+  /* dijitSliderActive should be treated as dijitSliderHover since "clicking the slider" has no meaning */
+
+  border: solid 1px #769dc0;
+  background-color: #ffffff;
 }
 .claro .dijitSliderDecrementIconH {
-	background-position:-357px 50%;
+  background-position: -357px 50%;
 }
-.claro .dijitSliderActive .dijitSliderDecrementIconH
-.claro .dijitSliderHover .dijitSliderDecrementIconH {
-	background-position:-393px 50%;
+.claro .dijitSliderActive .dijitSliderDecrementIconH.claro .dijitSliderHover .dijitSliderDecrementIconH {
+  background-position: -393px 50%;
 }
 .claro .dijitSliderIncrementIconH {
-	background-position:-251px 50%;
+  background-position: -251px 50%;
 }
-.claro .dijitSliderActive .dijitSliderIncrementIconH
-.claro .dijitSliderHover .dijitSliderIncrementIconH {
-	background-position:-283px 50%;
+.claro .dijitSliderActive .dijitSliderIncrementIconH.claro .dijitSliderHover .dijitSliderIncrementIconH {
+  background-position: -283px 50%;
 }
 .claro .dijitSliderDecrementIconV {
-	background-position:-38px 50%;
+  background-position: -38px 50%;
 }
-.claro .dijitSliderActive .dijitSliderDecrementIconV
-.claro .dijitSliderHover .dijitSliderDecrementIconV {
-	background-position:-73px 50%;
+.claro .dijitSliderActive .dijitSliderDecrementIconV.claro .dijitSliderHover .dijitSliderDecrementIconV {
+  background-position: -73px 50%;
 }
 .claro .dijitSliderIncrementIconV {
-	background-position:-143px 49%;
+  background-position: -143px 49%;
 }
-.claro .dijitSliderActive .dijitSliderIncrementIconV
-.claro .dijitSliderHover .dijitSliderIncrementIconV {
-	background-position:-178px 49%;
+.claro .dijitSliderActive .dijitSliderIncrementIconV.claro .dijitSliderHover .dijitSliderIncrementIconV {
+  background-position: -178px 49%;
 }
 .claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonHover,
 .claro .dijitSliderButtonContainerH .dijitSliderDecrementButtonHover,
 .claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonHover,
 .claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonHover {
-	background-color: #cce3fc;
+  background-color: #cfe5fa;
 }
 .claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonActive,
 .claro .dijitSliderButtonContainerH .dijitSliderDecrementButtonActive,
 .claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonActive,
 .claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonActive {
-	background-color: #a5d0fc;
-	border-color:#6591b9;
+  background-color: #abd6ff;
+  border-color: #769dc0;
 }
 .claro .dijitSliderButtonInner {
-	visibility: hidden;
+  visibility: hidden;
 }
-.claro .dijitSliderDisabled .dijitSliderBar{
-	border-color: #d3d3d3;
+.claro .dijitSliderDisabled .dijitSliderBar {
+  border-color: #d3d3d3;
 }
-.claro .dijitSliderReadOnly *,.claro .dijitSliderDisabled * {
-	border-color: #d3d3d3;
-	color: #bdbdbd;
+.claro .dijitSliderReadOnly *, .claro .dijitSliderDisabled * {
+  border-color: #d3d3d3;
+  color: #818181;
 }
-.claro .dijitSliderReadOnly .dijitSliderDecrementIconH,
-.claro .dijitSliderDisabled .dijitSliderDecrementIconH {
-	background-position:-321px 50%;
-	background-color:#e9e9e9;
+.claro .dijitSliderReadOnly .dijitSliderDecrementIconH, .claro .dijitSliderDisabled .dijitSliderDecrementIconH {
+  background-position: -321px 50%;
+  background-color: #efefef;
 }
-.claro .dijitSliderReadOnly .dijitSliderIncrementIconH,
-.claro .dijitSliderDisabled .dijitSliderIncrementIconH {
-	background-position:-215px 50%;
-	background-color:#e9e9e9;
+.claro .dijitSliderReadOnly .dijitSliderIncrementIconH, .claro .dijitSliderDisabled .dijitSliderIncrementIconH {
+  background-position: -215px 50%;
+  background-color: #efefef;
 }
-.claro .dijitSliderReadOnly .dijitSliderDecrementIconV,
-.claro .dijitSliderDisabled .dijitSliderDecrementIconV {
-	background-position:-3px 49%;
-	background-color:#e9e9e9;
+.claro .dijitSliderReadOnly .dijitSliderDecrementIconV, .claro .dijitSliderDisabled .dijitSliderDecrementIconV {
+  background-position: -3px 49%;
+  background-color: #efefef;
 }
-.claro .dijitSliderReadOnly .dijitSliderIncrementIconV,
-.claro .dijitSliderDisabled .dijitSliderIncrementIconV {
-	background-position:-107px 49%;
-	background-color:#e9e9e9;
+.claro .dijitSliderReadOnly .dijitSliderIncrementIconV, .claro .dijitSliderDisabled .dijitSliderIncrementIconV {
+  background-position: -107px 49%;
+  background-color: #efefef;
 }
-
 .dj_ie6 .claro .dijitSlider .dijitSliderProgressBarH,
 .dj_ie6 .claro .dijitSlider .dijitSliderLeftBumper,
 .dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarH,
@@ -355,5 +322,5 @@
 .dj_ie6 .claro .dijitSlider .dijitSliderTopBumper,
 .dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarV,
 .dj_ie6 .claro .dijitSlider .dijitSliderBottomBumper {
-	background-image:none;
+  background-image: none;
 }
diff --git a/dijit/themes/claro/form/Slider.less b/dijit/themes/claro/form/Slider.less
new file mode 100644
index 0000000..82451b5
--- /dev/null
+++ b/dijit/themes/claro/form/Slider.less
@@ -0,0 +1,362 @@
+/* Slider 
+ * 
+ * Styling Slider mainly includes styling the Slider progress bar (dijitSliderProgressBar)
+ * 
+ * Slider progress bar:
+ * 1. Slider progress bar (default styling): 
+ * 		.dijitSliderProgressBarH - progress bar at the middle of horizontal slider
+ * 		.dijitSliderLeftBumper - bar at the left of horizontal slider
+ * 		.dijitSliderRightBumper - bar at the right of horizontal slider
+ * 		.dijitSliderProgressBarV - progress bar at the middle of vertical slider
+ * 		.dijitSliderTopBumper - bar at the top of vertical slider
+ * 		.dijitSliderBottomtBumper - bar at the bottom of vertical slider
+ * 
+ * 2. hovered Slider progress bar (ie, mouse hover on progress bar)
+ * 		.dijitSliderHover .dijitSliderProgressBarH(horizontal) - hovered bar style: background, border
+ * 
+ * 3. focused Slider progress bar (ie, mouse focused on progress bar)
+ * 		.dijitSliderFocused .dijitSliderProgressBarH(horizontal) - focus bar style: background, border
+ * 
+ * 4. disabled/read-only Slider progress bar 
+ * 		.dijitSliderDisabled .dijitSliderProgressBarH(horizontal) - bar styles when slider is disabled
+ * 
+ * 
+ * Slider Thumbs:
+ * 1. Slider Thumbs (default styling): 
+ * 		.dijitSliderImageHandleH / .dijitSliderImageHandleV - styles for the controller on the progress bar
+ * 
+ * 2. hovered Slider Thumbs (ie, mouse hover on slider thumbs)
+ * 		.dijitSliderHover .dijitSliderImageHandleH - hovered controller style
+ * 
+ * 3. focused Slider progress bar (ie, mouse focused on slider thumbs)
+ * 		.dijitSliderFocused .dijitSliderImageHandleV - focused controller style
+ * 
+ * 
+ * Slider Increment/Decrement Buttons:
+ * 1. Slider Increment/Decrement Buttons (default styling): 
+ * 		.dijitSliderDecrementIconH - decrement icon which lies at the left of horizontal slider
+ * 		.dijitSliderIncrementIconH - increment icon which lies at the right of horizontal slider
+ * 		.dijitSliderDecrementIconV - decrement icon which lies at the bottom of vertical slider
+ * 		.dijitSliderIncrementIconV - increment icon which lies at the top of vertical slider
+ * 
+ * 2. hovered Slider Increment/Decrement Buttons (mouse hover on the icons)
+ * 		.dijitSliderHover .dijitSliderDecrementIconH - for background, border
+ * 
+ * 3. active Slider Increment/Decrement Buttons (mouse down on the icons)
+ * 		.dijitSliderActive .dijitSliderIncrementIconV - for background, border
+ * 
+ * 4. disabled/read-only Slider Increment/Decrement Buttons
+ * 		.dijitSliderDisabled .dijitSliderDecrementIconH - styles for the icons in disabled slider
+ * 		.dijitSliderReadOnly .dijitSliderIncrementIconV - styles for the icons in read-only slider
+ */
+
+ at import "../variables";
+
+.claro .dijitSliderBar {
+	border-style: solid;
+	outline: 1px;
+}
+.claro .dijitSliderFocused .dijitSliderBar {
+	border-color: @focused-border-color;
+}
+.claro .dijitSliderHover .dijitSliderBar {
+	border-color: @hovered-border-color;
+}
+.claro .dijitSliderDisabled .dijitSliderBar {
+	background-image: none;
+	border-color: @disabled-border-color;
+}
+
+/* Horizontal Slider */
+
+.claro .dijitRuleLabelsContainerH {
+	padding: 2px 0;
+}
+.claro .dijitSlider .dijitSliderProgressBarH,
+.claro .dijitSlider .dijitSliderLeftBumper{
+	background-image: url("images/sliderHorizontal.png");
+	background-repeat:repeat-x;
+	background-position:0 -20px;
+	border-color: @border-color;
+	background-color: @slider-fullbar-background-color;
+}
+.claro .dijitSlider .dijitSliderRemainingBarH,
+.claro .dijitSlider .dijitSliderRightBumper{
+	background-image: url("images/sliderHorizontal.png");
+	background-repeat:repeat-x;
+	background-position:0 -11px;
+	border-color: @border-color;
+	background-color: @slider-remainingbar-background-color;
+}
+.claro .dijitSliderRightBumper {
+	border-right: solid 1px @border-color;
+}
+.claro .dijitSliderLeftBumper {
+	border-left: solid 1px @border-color;
+}
+.claro .dijitSliderHover .dijitSliderProgressBarH,
+.claro .dijitSliderHover .dijitSliderLeftBumper{
+	background-position:0 -20px;
+	background-color: @slider-hovered-fullbar-background-color;
+	border-color: @hovered-border-color;
+}
+.claro .dijitSliderHover .dijitSliderRemainingBarH,
+.claro .dijitSliderHover .dijitSliderRightBumper{
+	background-position:0 0;
+	background-color: @slider-hovered-remainingbar-background-color;
+	border-color: @hovered-border-color;
+}
+.claro .dijitSliderFocused .dijitSliderProgressBarH,
+.claro .dijitSliderFocused .dijitSliderLeftBumper{
+	background-position:0 -30px;
+	background-color: @slider-focused-fullbar-background-color;
+	border-color: @focused-border-color;
+}
+.claro .dijitSliderFocused .dijitSliderRemainingBarH,
+.claro .dijitSliderFocused .dijitSliderRightBumper{
+	background-position:0 -9px;
+	background-color: @slider-focused-remainingbar-background-color;
+	border-color: @focused-border-color;
+}
+.claro .dijitSliderDisabled .dijitSliderProgressBarH,
+.claro .dijitSliderDisabled .dijitSliderLeftBumper{
+	background-color: @disabled-border-color;		/* left side of slider, fill matches border */
+	background-image:none;
+}
+.claro .dijitSliderDisabled .dijitSliderRemainingBarH,
+.claro .dijitSliderDisabled .dijitSliderRightBumper{
+	background-color: @disabled-background-color;
+}
+
+/* Vertical Slider */
+
+.claro .dijitRuleLabelsContainerV {
+	padding: 0 2px;
+}
+.claro .dijitSlider .dijitSliderProgressBarV,
+.claro .dijitSlider .dijitSliderBottomBumper{
+	background-image: url("images/sliderVertical.png");
+	background-repeat:repeat-y;
+	background-position:-36px 0;
+	border-color: @border-color;
+	background-color: @slider-fullbar-background-color;
+}
+.claro .dijitSlider .dijitSliderRemainingBarV,
+.claro .dijitSlider .dijitSliderTopBumper{
+	background-image: url("images/sliderVertical.png");
+	background-repeat:repeat-y;
+	background-position:-3px 0;
+	border-color: @border-color;
+	background-color: @slider-remainingbar-background-color;
+}
+.claro .dijitSliderBottomBumper {
+	border-bottom: solid 1px @border-color;
+}
+.claro .dijitSliderTopBumper {
+	border-top: solid 1px @border-color;
+}
+.claro .dijitSliderHover .dijitSliderProgressBarV,
+.claro .dijitSliderHover .dijitSliderBottomBumper{
+	background-position:-36px 0;
+	background-color: @slider-hovered-fullbar-background-color;
+}
+.claro .dijitSliderHover .dijitSliderRemainingBarV,
+.claro .dijitSliderHover .dijitSliderTopBumper{
+	background-position:0 0;
+	background-color: @slider-hovered-remainingbar-background-color;
+}
+.claro .dijitSliderFocused .dijitSliderProgressBarV,
+.claro .dijitSliderFocused .dijitSliderBottomBumper{
+	background-position:-56px 0;
+	background-color: @slider-focused-fullbar-background-color;
+}
+.claro .dijitSliderFocused .dijitSliderRemainingBarV,
+.claro .dijitSliderFocused .dijitSliderTopBumper{
+	background-position:-18px 0;
+	background-color: @slider-focused-remainingbar-background-color;
+}
+.claro .dijitSliderDisabled .dijitSliderProgressBarV,
+.claro .dijitSliderDisabled .dijitSliderBottomBumper{
+	background-color: @disabled-border-color;	/* bottom side of slider, fill matches border */
+}
+.claro .dijitSliderDisabled .dijitSliderRemainingBarV,
+.claro .dijitSliderDisabled .dijitSliderTopBumper{
+	background-color: @disabled-background-color;
+}
+
+
+/* ------- Thumbs ------- */
+
+.claro .dijitSliderImageHandleH {
+	border: 0;
+	width: 18px;
+	height: 16px;
+	background-image: url("images/sliderThumbs.png");
+	background-repeat:no-repeat;
+	background-position:0 0;
+}
+.claro .dijitSliderHover .dijitSliderImageHandleH {
+	background-position:-18px 0;
+}
+.claro .dijitSliderFocused .dijitSliderImageHandleH {
+	background-position:-36px 0;
+}
+.claro .dijitSliderProgressBarH .dijitSliderThumbHover{
+	background-position:-36px 0;
+}
+.claro .dijitSliderProgressBarH .dijitSliderThumbActive{
+	background-position:-36px 0;
+}
+.claro .dijitSliderReadOnly .dijitSliderImageHandleH,
+.claro .dijitSliderDisabled .dijitSliderImageHandleH {
+	background-position:-54px 0;
+}
+.claro .dijitSliderImageHandleV {
+	border: 0;
+	width: 18px;
+	height: 16px;
+	background-image: url("images/sliderThumbs.png");
+	background-repeat:no-repeat;
+	background-position:-289px 0;
+}
+.claro .dijitSliderHover .dijitSliderImageHandleV {
+	background-position:-307px 0;
+}
+.claro .dijitSliderFocused .dijitSliderImageHandleV {
+	background-position:-325px 0;
+}
+.claro .dijitSliderProgressBarV .dijitSliderThumbHover{
+	background-position:-325px 0;
+}
+.claro .dijitSliderProgressBarV .dijitSliderThumbActive{
+	background-position:-325px 0;
+}
+.claro .dijitSliderReadOnly .dijitSliderImageHandleV,
+.claro .dijitSliderDisabled .dijitSliderImageHandleV {
+	background-position:-343px 0;
+}
+
+/* ---- Increment/Decrement Buttons ---- */
+
+.claro .dijitSliderButtonContainerH{
+	padding: 1px 3px 1px 2px;
+}
+.claro .dijitSliderButtonContainerV{
+	padding: 3px 1px 2px 1px;
+}
+.claro .dijitSliderDecrementIconH,
+.claro .dijitSliderIncrementIconH,
+.claro .dijitSliderDecrementIconV,
+.claro .dijitSliderIncrementIconV {
+	background-image: url('images/commonFormArrows.png');
+	background-repeat:no-repeat;
+	background-color: @arrowbutton-background-color;
+	.border-radius(2px);
+	border: solid 1px @border-color;
+	font-size: 1px;
+}
+.claro .dijitSliderDecrementIconH,
+.claro .dijitSliderIncrementIconH {
+	height: 12px;
+	width: 9px;
+}
+.claro .dijitSliderDecrementIconV,
+.claro .dijitSliderIncrementIconV {
+	height: 9px;
+	width: 12px;
+}
+.claro .dijitSliderActive .dijitSliderDecrementIconH,
+.claro .dijitSliderActive .dijitSliderIncrementIconH,
+.claro .dijitSliderActive .dijitSliderDecrementIconV,
+.claro .dijitSliderActive .dijitSliderIncrementIconV,
+.claro .dijitSliderHover .dijitSliderDecrementIconH,
+.claro .dijitSliderHover .dijitSliderIncrementIconH,
+.claro .dijitSliderHover .dijitSliderDecrementIconV,
+.claro .dijitSliderHover .dijitSliderIncrementIconV {
+	/* dijitSliderActive should be treated as dijitSliderHover since "clicking the slider" has no meaning */
+	border: solid 1px @hovered-border-color;
+	background-color: @slider-hoveredButton-background-color;
+}
+
+.claro .dijitSliderDecrementIconH {
+	background-position:-357px 50%;
+}
+.claro .dijitSliderActive .dijitSliderDecrementIconH
+.claro .dijitSliderHover .dijitSliderDecrementIconH {
+	background-position:-393px 50%;
+}
+.claro .dijitSliderIncrementIconH {
+	background-position:-251px 50%;
+}
+.claro .dijitSliderActive .dijitSliderIncrementIconH
+.claro .dijitSliderHover .dijitSliderIncrementIconH {
+	background-position:-283px 50%;
+}
+.claro .dijitSliderDecrementIconV {
+	background-position:-38px 50%;
+}
+.claro .dijitSliderActive .dijitSliderDecrementIconV
+.claro .dijitSliderHover .dijitSliderDecrementIconV {
+	background-position:-73px 50%;
+}
+.claro .dijitSliderIncrementIconV {
+	background-position:-143px 49%;
+}
+.claro .dijitSliderActive .dijitSliderIncrementIconV
+.claro .dijitSliderHover .dijitSliderIncrementIconV {
+	background-position:-178px 49%;
+}
+.claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonHover,
+.claro .dijitSliderButtonContainerH .dijitSliderDecrementButtonHover,
+.claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonHover,
+.claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonHover {
+	background-color: @slider-button-hovered-background-color;
+}
+.claro .dijitSliderButtonContainerV .dijitSliderDecrementButtonActive,
+.claro .dijitSliderButtonContainerH .dijitSliderDecrementButtonActive,
+.claro .dijitSliderButtonContainerV .dijitSliderIncrementButtonActive,
+.claro .dijitSliderButtonContainerH .dijitSliderIncrementButtonActive {
+	background-color: @slider-button-pressed-background-color;
+	border-color:@pressed-border-color;
+}
+.claro .dijitSliderButtonInner {
+	visibility: hidden;
+}
+.claro .dijitSliderDisabled .dijitSliderBar{
+	border-color: @disabled-border-color;
+}
+.claro .dijitSliderReadOnly *,.claro .dijitSliderDisabled * {
+	border-color: @disabled-border-color;
+	color: @disabled-text-color;
+}
+.claro .dijitSliderReadOnly .dijitSliderDecrementIconH,
+.claro .dijitSliderDisabled .dijitSliderDecrementIconH {
+	background-position:-321px 50%;
+	background-color:@disabled-background-color;
+}
+.claro .dijitSliderReadOnly .dijitSliderIncrementIconH,
+.claro .dijitSliderDisabled .dijitSliderIncrementIconH {
+	background-position:-215px 50%;
+	background-color:@disabled-background-color;
+}
+.claro .dijitSliderReadOnly .dijitSliderDecrementIconV,
+.claro .dijitSliderDisabled .dijitSliderDecrementIconV {
+	background-position:-3px 49%;
+	background-color:@disabled-background-color;
+}
+.claro .dijitSliderReadOnly .dijitSliderIncrementIconV,
+.claro .dijitSliderDisabled .dijitSliderIncrementIconV {
+	background-position:-107px 49%;
+	background-color:@disabled-background-color;
+}
+
+.dj_ie6 .claro .dijitSlider .dijitSliderProgressBarH,
+.dj_ie6 .claro .dijitSlider .dijitSliderLeftBumper,
+.dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarH,
+.dj_ie6 .claro .dijitSlider .dijitSliderRightBumper,
+.dj_ie6 .claro .dijitSlider .dijitSliderProgressBarV,
+.dj_ie6 .claro .dijitSlider .dijitSliderTopBumper,
+.dj_ie6 .claro .dijitSlider .dijitSliderRemainingBarV,
+.dj_ie6 .claro .dijitSlider .dijitSliderBottomBumper {
+	background-image:none;
+}
diff --git a/dijit/themes/claro/form/Slider_rtl.css b/dijit/themes/claro/form/Slider_rtl.css
index 6df7d4f..97e078b 100644
--- a/dijit/themes/claro/form/Slider_rtl.css
+++ b/dijit/themes/claro/form/Slider_rtl.css
@@ -3,29 +3,22 @@
 .claro .dijitSliderRtl .dijitSliderLeftBumper,
 .claro .dijitSliderRtl .dijitSliderRightBumper,
 .claro .dijitSliderRtl .dijitSliderTopBumper {
-	background-position: top right;
+  background-position: top right;
 }
-
-.claro .dijitSliderRtl .dijitSliderProgressBarV,
-.claro .dijitSliderRtl .dijitSliderRemainingBarV,
-.claro .dijitSliderRtl .dijitSliderBottomBumper {
-	background-position: bottom right;
+.claro .dijitSliderRtl .dijitSliderProgressBarV, .claro .dijitSliderRtl .dijitSliderRemainingBarV, .claro .dijitSliderRtl .dijitSliderBottomBumper {
+  background-position: bottom right;
 }
-
 .claro .dijitSliderRtl .dijitSliderLeftBumper {
-	border-left-width: 0px;
-	border-right-width: 1px;
+  border-left-width: 0;
+  border-right-width: 1px;
 }
-
 .claro .dijitSliderRtl .dijitSliderRightBumper {
-	border-left-width: 1px;
-	border-right-width: 0px;
+  border-left-width: 1px;
+  border-right-width: 0;
 }
-
 .claro .dijitSliderRtl .dijitSliderIncrementIconH {
-	background-position:-357px 50%;
+  background-position: -357px 50%;
 }
-
 .claro .dijitSliderRtl .dijitSliderDecrementIconH {
-	background-position:-251px 50%;
+  background-position: -251px 50%;
 }
diff --git a/dijit/themes/claro/form/Slider_rtl.less b/dijit/themes/claro/form/Slider_rtl.less
new file mode 100644
index 0000000..66a7116
--- /dev/null
+++ b/dijit/themes/claro/form/Slider_rtl.less
@@ -0,0 +1,33 @@
+ at import "../variables";
+
+.claro .dijitSliderRtl .dijitSliderProgressBarH,
+.claro .dijitSliderRtl .dijitSliderRemainingBarH,
+.claro .dijitSliderRtl .dijitSliderLeftBumper,
+.claro .dijitSliderRtl .dijitSliderRightBumper,
+.claro .dijitSliderRtl .dijitSliderTopBumper {
+	background-position: top right;
+}
+
+.claro .dijitSliderRtl .dijitSliderProgressBarV,
+.claro .dijitSliderRtl .dijitSliderRemainingBarV,
+.claro .dijitSliderRtl .dijitSliderBottomBumper {
+	background-position: bottom right;
+}
+
+.claro .dijitSliderRtl .dijitSliderLeftBumper {
+	border-left-width: 0;
+	border-right-width: 1px;
+}
+
+.claro .dijitSliderRtl .dijitSliderRightBumper {
+	border-left-width: 1px;
+	border-right-width: 0;
+}
+
+.claro .dijitSliderRtl .dijitSliderIncrementIconH {
+	background-position:-357px 50%;
+}
+
+.claro .dijitSliderRtl .dijitSliderDecrementIconH {
+	background-position:-251px 50%;
+}
diff --git a/dijit/themes/claro/images/loading.gif b/dijit/themes/claro/images/loading.gif
deleted file mode 100644
index 6e7c8e5..0000000
Binary files a/dijit/themes/claro/images/loading.gif and /dev/null differ
diff --git a/dijit/themes/claro/images/tooltip.png b/dijit/themes/claro/images/tooltip.png
index aca1498..2b22273 100644
Binary files a/dijit/themes/claro/images/tooltip.png and b/dijit/themes/claro/images/tooltip.png differ
diff --git a/dijit/themes/claro/images/tooltipGradient.png b/dijit/themes/claro/images/tooltipGradient.png
new file mode 100644
index 0000000..ce4860e
Binary files /dev/null and b/dijit/themes/claro/images/tooltipGradient.png differ
diff --git a/dijit/themes/claro/layout/AccordionContainer.css b/dijit/themes/claro/layout/AccordionContainer.css
index e55b862..f769479 100644
--- a/dijit/themes/claro/layout/AccordionContainer.css
+++ b/dijit/themes/claro/layout/AccordionContainer.css
@@ -3,106 +3,122 @@
  * Styling AccordionContainer basically means styling the accordion pane (dijitAccordionInnerContainer)
  * and the title inside of it (dijitAccordionTitle).   There are 4 basic states to style:
  * 
- * 1. accordion bounding container
- * 		.dijitAccordionContainer - container for the whole accordion 
- * 
- * 2. closed pane (and default styling): 
+ * 1. closed pane (and default styling): 
  * 		.dijitAccordionInnerContainer - container for each accordion child
  * 		.dijitAccordionTitle - title for each accordion child
  *
- * 3. active closed pane (ie, mouse down on a title bar)
+ * 2. active closed pane (ie, mouse down on a title bar)
  * 		.dijitAccordionInnerContainerActive - for background-color, border
  * 		.dijitAccordionInnerContainerActive dijitAccordionTitle - for text color
  * 
- * 4. open pane (expanded child)
+ * 3. open pane (expanded child)
+ *		.dijitAccordionChildWrapper - wraps around the child widget (typically ContentPane)
+ *			setting a margin so that there's blue trim all the way around the child
+ *
  * 		These rules need to override the closed pane active:
  *
  * 		.dijitAccordionInnerContainerSelected - for background-color, border
  * 		.dijitAccordionInnerContainerSelected .dijitAccordionTitle - for text color
  * 
- * 5. hovered pane, open or closed
+ * 4. hovered pane, open or closed
  * 		The selectors below affect hovering over both a closed pane (ie, hovering a title bar),
  * 		and hovering over an open pane.   Also, treat mouse down on an open pane as a hover:
  *
  * 		.dijitAccordionInnerContainerHover, .dijitAccordionInnerContainerSelectedActive - for background-color, border
  * 		.dijitAccordionInnerContainerHover .dijitAccordionTitle - for text color
  */
-
 .claro .dijitAccordionContainer {
-	border:none;
+  border: none;
 }
 .claro .dijitAccordionInnerContainer {
-	background-color: #e6e6e7;	/* gray, for closed pane */
-	border:solid 1px #b5bcc7;
-	margin-bottom:1px;
-	-webkit-transition-property:background-color,border;
- 	-webkit-transition-duration:.3s;
-	-webkit-transition-timing-function:linear;
+  background-color: #efefef;
+  /* gray, for closed pane */
+
+  border: solid 1px #b5bcc7;
+  margin-bottom: 1px;
+  -webkit-transition-property: background-color, border;
+  -moz-transition-property: background-color, border;
+  transition-property: background-color, border;
+  -webkit-transition-duration: 0.3s;
+  -moz-transition-duration: 0.3s;
+  transition-duration: 0.3s;
+  -webkit-transition-timing-function: linear;
+  -moz-transition-timing-function: linear;
+  transition-timing-function: linear;
 }
 .claro .dijitAccordionTitle {
-	background-color: transparent;	/* pick up color from dijitAccordionInnerContainer */
-	background-image: url("images/accordion.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
-	padding: 5px 7px 2px 7px;
-	min-height:17px;
-	color:#4a4a4a;
+  background-color: transparent;
+  /* pick up color from dijitAccordionInnerContainer */
+
+  background-image: url("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;
 }
 .dj_ie6 .claro .dijitAccordionTitle {
-	background-image: none;
+  background-image: none;
 }
-.claro .dijitAccordionContainer .dijitAccordionContainer-child {
-	background-color:#fff;
-	/*
-	 * border style need to be !important to override the style "border:medium none !important"
-	 * in class ".dijitTabPane, .dijitStackContainer-child, .dijitAccordionContainer-child"
+.claro .dijitAccordionContainer .dijitAccordionChildWrapper {
+  /* this extends the blue trim styling of the title bar to wrapping around the node.
+	 * done by setting margin
 	 */
-	border:1px solid #92bce1 !important;
-	margin: 0px 2px 2px;
-	padding: 9px;
+
+  background-color: #ffffff;
+  border: 1px solid #769dc0;
+  margin: 0 2px 2px;
 }
+.claro .dijitAccordionContainer .dijitAccordionContainer-child {
+  /* this is affecting the child widget itself */
 
+  padding: 9px;
+}
 /* Active state for closed pane */
-
 .claro .dijitAccordionInnerContainerActive {
-	border:1px solid #769DC0;
-	background-color:#7dbefa;
-	-webkit-transition-duration:.1s;
+  border: 1px solid #769dc0;
+  background-color: #7dbefa;
+  -webkit-transition-duration: 0.1s;
+  -moz-transition-duration: 0.1s;
+  transition-duration: 0.1s;
 }
 .claro .dijitAccordionInnerContainerActive .dijitAccordionTitle {
-	background-position:0px -136px;
-	color:#000;
+  background-position: 0 -136px;
+  color: #000000;
 }
-
-/* Open pane */
-
+/* Open (a.k.a. selected) pane */
 .claro .dijitAccordionInnerContainerSelected {
-	border-color:#92bce1;
-	background-color: #cde8ff;
+  border-color: #769dc0;
+  background-color: #cfe5fa;
 }
 .claro .dijitAccordionInnerContainerSelected .dijitAccordionTitle {
-	color:#000;
-	background-position: 0 0;	/* avoid effect when clicking the title of the open pane */
-}
+  color: #000000;
+  background-position: 0 0;
+  /* avoid effect when clicking the title of the open pane */
 
+}
 /* Hovering open or closed pane */
-
 .claro .dijitAccordionInnerContainerHover dijitAccordionTitle {
-	/* both open and closed */
-	color:#000;
-}
+  /* both open and closed */
 
-.claro .dijitAccordionInnerContainerHover,
-.claro .dijitAccordionInnerContainerSelectedActive {
-	border:1px solid #769DC0;
-	background-color:#9dcfff;
-	-webkit-transition-duration:.2s;
+  color: #000000;
 }
+.claro .dijitAccordionInnerContainerHover, .claro .dijitAccordionInnerContainerSelectedActive {
+  /* note: clicking the currently selected Accordion pane should have no effect, so treating same as hover. */
 
-.claro .dijitAccordionInnerContainerSelectedHover .dijitAccordionContainer-child,
-.claro .dijitAccordionInnerContainerSelectedActive .dijitAccordionContainer-child {
-	background-color:#ffffff;
-	border:1px solid #769DC0 !important;
-	-webkit-box-shadow:inset 0px 0px 3px rgba(0, 0, 0, .25);
-	-moz-box-shadow:inset 0px 0px 3px rgba(0, 0, 0, .25);
+  border: 1px solid #769dc0;
+  background-color: #abd6ff;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
+}
+.claro .dijitAccordionInnerContainerSelectedHover .dijitAccordionChildWrapper, .claro .dijitAccordionInnerContainerSelectedActive .dijitAccordionChildWrapper {
+  background-color: #ffffff;
+  border: 1px solid #769dc0 !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
new file mode 100644
index 0000000..01f4427
--- /dev/null
+++ b/dijit/themes/claro/layout/AccordionContainer.less
@@ -0,0 +1,116 @@
+/* Accordion
+ * 
+ * Styling AccordionContainer basically means styling the accordion pane (dijitAccordionInnerContainer)
+ * and the title inside of it (dijitAccordionTitle).   There are 4 basic states to style:
+ * 
+ * 1. closed pane (and default styling): 
+ * 		.dijitAccordionInnerContainer - container for each accordion child
+ * 		.dijitAccordionTitle - title for each accordion child
+ *
+ * 2. active closed pane (ie, mouse down on a title bar)
+ * 		.dijitAccordionInnerContainerActive - for background-color, border
+ * 		.dijitAccordionInnerContainerActive dijitAccordionTitle - for text color
+ * 
+ * 3. open pane (expanded child)
+ *		.dijitAccordionChildWrapper - wraps around the child widget (typically ContentPane)
+ *			setting a margin so that there's blue trim all the way around the child
+ *
+ * 		These rules need to override the closed pane active:
+ *
+ * 		.dijitAccordionInnerContainerSelected - for background-color, border
+ * 		.dijitAccordionInnerContainerSelected .dijitAccordionTitle - for text color
+ * 
+ * 4. hovered pane, open or closed
+ * 		The selectors below affect hovering over both a closed pane (ie, hovering a title bar),
+ * 		and hovering over an open pane.   Also, treat mouse down on an open pane as a hover:
+ *
+ * 		.dijitAccordionInnerContainerHover, .dijitAccordionInnerContainerSelectedActive - for background-color, border
+ * 		.dijitAccordionInnerContainerHover .dijitAccordionTitle - for text color
+ */
+
+ at import "../variables";
+
+.claro .dijitAccordionContainer {
+	border:none;
+}
+.claro .dijitAccordionInnerContainer {
+	background-color: @unselected-background-color;	/* gray, for closed pane */
+	border:solid 1px @border-color;
+	margin-bottom:1px;
+	.transition-property(background-color,border);
+ 	.transition-duration(.3s);
+	.transition-timing-function(linear);
+}
+.claro .dijitAccordionTitle {
+	background-color: transparent;	/* pick up color from dijitAccordionInnerContainer */
+	background-image: url("images/accordion.png");
+	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;
+}
+.claro .dijitAccordionContainer .dijitAccordionChildWrapper {
+	/* this extends the blue trim styling of the title bar to wrapping around the node.
+	 * done by setting margin
+	 */
+	background-color:@pane-background-color;
+	border:1px solid @selected-border-color;
+	margin: 0 2px 2px;
+}
+	
+.claro .dijitAccordionContainer .dijitAccordionContainer-child {
+	/* this is affecting the child widget itself */
+	padding: 9px;
+}
+
+/* Active state for closed pane */
+
+.claro .dijitAccordionInnerContainerActive {
+	border:1px solid @selected-border-color;
+	background-color:@pressed-background-color;
+	.transition-duration(.1s);
+}
+.claro .dijitAccordionInnerContainerActive .dijitAccordionTitle {
+	background-position:0 -136px;
+	color:@selected-text-color;
+}
+
+/* Open (a.k.a. selected) pane */
+
+.claro .dijitAccordionInnerContainerSelected {
+	border-color:@selected-border-color;
+	background-color: @selected-background-color;
+}
+.claro .dijitAccordionInnerContainerSelected .dijitAccordionTitle {
+	color:@selected-text-color;
+	background-position: 0 0;	/* avoid effect when clicking the title of the open pane */
+}
+
+/* Hovering open or closed pane */
+
+.claro .dijitAccordionInnerContainerHover dijitAccordionTitle {
+	/* both open and closed */
+	color:@hovered-text-color;
+}
+
+.claro .dijitAccordionInnerContainerHover,
+.claro .dijitAccordionInnerContainerSelectedActive {
+	/* note: clicking the currently selected Accordion pane should have no effect, so treating same as hover. */
+	border:1px solid @hovered-border-color;
+	background-color:@hovered-background-color;
+	.transition-duration(.2s);
+}
+
+.claro .dijitAccordionInnerContainerSelectedHover .dijitAccordionChildWrapper,
+.claro .dijitAccordionInnerContainerSelectedActive .dijitAccordionChildWrapper {
+	background-color:@pane-background-color;
+	border:1px solid @hovered-border-color !important;
+	.box-shadow(inset 0 0 3px rgba(0, 0, 0, .25));
+}
diff --git a/dijit/themes/claro/layout/BorderContainer.css b/dijit/themes/claro/layout/BorderContainer.css
index 894704e..ede2a56 100644
--- a/dijit/themes/claro/layout/BorderContainer.css
+++ b/dijit/themes/claro/layout/BorderContainer.css
@@ -28,107 +28,82 @@ Splitters and gutters:
 .dijitSplitterVHover .dijitSplitterThumb - for background-color of a hovered thumb on a vertical splitter
 .dijitSplitterHActive - for background-color of an active horizontal splitter
 .dijitSplitterVActive - for background-color of an active horizontal splitter
-
-
 */
 .claro .dijitBorderContainer {
-	border: 1px #b5bcc7 solid;
-	padding: 5px;
-}
+  /* matches the width of the splitters between panes */
 
-.claro .dijitSplitContainer-child,
-.claro .dijitBorderContainer-child {
-	/* By default put borders on all children of BorderContainer,
+  padding: 5px;
+}
+.claro .dijitSplitContainer-child, .claro .dijitBorderContainer-child {
+  /* By default put borders on all children of BorderContainer,
 	 *  to give illusion of borders on the splitters themselves.
 	 */
-	border: 1px #b5bcc7 solid;
-}
 
+  border: 1px #b5bcc7 solid;
+}
 .claro .dijitBorderContainer-dijitTabContainerTop,
 .claro .dijitBorderContainer-dijitTabContainerBottom,
 .claro .dijitBorderContainer-dijitTabContainerLeft,
 .claro .dijitBorderContainer-dijitTabContainerRight,
 .claro .dijitBorderContainer-dijitAccordionContainer {
-	/* except that TabContainer defines borders on it's sub-nodes (tablist and dijitTabPaneWrapper),
+  /* except that TabContainer defines borders on it's sub-nodes (tablist and dijitTabPaneWrapper),
 	 * so override rule setting border on domNode
 	 */
-	 border: none;
 
+  border: none;
 }
 .claro .dijitBorderContainer-dijitBorderContainer {
-	/* also, make nested BorderContainers look like a single big widget with lots of splitters */
-	border: 1px #c0ccdf solid;
-	padding: 5px;
-}
+  /* make nested BorderContainers look like a single big widget with lots of splitters */
 
+  border: 0;
+  padding: 0;
+}
 /* Splitters and gutters */
-
-.claro .dijitSplitterH,
-.claro .dijitGutterH {
-	background:none;
-	border:0;
-	height:5px;
+.claro .dijitSplitterH, .claro .dijitGutterH {
+  background: none;
+  border: 0;
+  height: 5px;
 }
-
 .claro .dijitSplitterH .dijitSplitterThumb {
-	background:#dde2e9 none;
-	height:1px;
-	top:2px;
-	width:19px;
+  background: #b5bcc7 none;
+  height: 1px;
+  top: 2px;
+  width: 19px;
 }
-
-.claro .dijitSplitterV,
-.claro .dijitGutterV {
-	background:none;
-	border:0;
-	width:5px;
-	margin: 0;
+.claro .dijitSplitterV, .claro .dijitGutterV {
+  background: none;
+  border: 0;
+  width: 5px;
+  margin: 0;
 }
-
 .claro .dijitSplitterV .dijitSplitterThumb {
-	background:#dde2e9 none;
-	height:19px;
-	left:2px;
-	width:1px;
-	margin: 0;
+  background: #b5bcc7 none;
+  height: 19px;
+  left: 2px;
+  width: 1px;
+  margin: 0;
 }
-
 /* hovered splitter */
 .claro .dijitSplitterHHover {
-	font-size: 1px;
-	background: url("images/splitterHorizontalHover.png") no-repeat center top;
+  font-size: 1px;
+  background: url("images/splitterHorizontalHover.png") no-repeat center top;
 }
-
-
 .claro .dijitSplitterHHover .dijitSplitterThumb {
-	background:#769dc0 none;
+  background: #769dc0 none;
 }
-
 .claro .dijitSplitterVHover {
-	font-size: 1px;
-	background: url("images/splitterVerticalHover.png") no-repeat center left;
+  font-size: 1px;
+  background: url("images/splitterVerticalHover.png") no-repeat center left;
 }
-
 .claro .dijitSplitterVHover .dijitSplitterThumb {
-	background:#769dc0 none;
+  background: #769dc0 none;
 }
-
-.dj_ie6 .dijitSplitterHHover,
-.dj_ie6 .claro .dijitSplitterVHover {
-	background-color:#cfe9ff;
-	background-image:none;
+.dj_ie6 .dijitSplitterHHover, .dj_ie6 .claro .dijitSplitterVHover {
+  background-color: #cfe5fa;
+  background-image: none;
 }
-
 /* active splitter */
-.claro .dijitSplitterHActive {
-	font-size: 1px;
-	background-color:#abd4fb;
-	border-top:blue;
-
-}
-
-.claro .dijitSplitterVActive {
-	font-size: 1px;
-	background-color:#abd4fb;
-
+.claro .dijitSplitterHActive, .claro .dijitSplitterVActive {
+  font-size: 1px;
+  background-color: #abd6ff;
 }
diff --git a/dijit/themes/claro/layout/BorderContainer.less b/dijit/themes/claro/layout/BorderContainer.less
new file mode 100644
index 0000000..17c4b63
--- /dev/null
+++ b/dijit/themes/claro/layout/BorderContainer.less
@@ -0,0 +1,128 @@
+/* BorderContainer 
+
+Splitters and gutters separate panes within a BorderContainer. Splitters can be moved up and down (horizonal splitters) or left and right (vertical splitters), while Gutters are static. A "thumb" is the slit on a Splitter that indicates it is movable. 
+
+Styling the BorderContainer widget consists of the following: 
+
+.dijitBorderContainer - for border and padding of the entire border container
+
+.dijitSplitContainer-child, .dijitBorderContainer-child - for border or child panes of the border container. By default borders are put on all children of BorderContainer.  
+
+.dijitBorderContainer-dijitTabContainerTop,
+.dijitBorderContainer-dijitTabContainerBottom,
+.dijitBorderContainer-dijitTabContainerLeft,
+.dijitBorderContainer-dijitTabContainerRight,
+.dijitBorderContainer-dijitAccordionContainer   -for border of the border containers within TabContainer or AccordionContainer widget
+
+.dijitBorderContainer-dijitBorderContainer - for border and padding of nested BorderContainers
+
+Splitters and gutters:  
+
+.dijitSplitterH, .dijitGutterH - for height, background, and border of a horizontal splitter and gutter 
+.dijitSplitterH .dijitSplitterThumb - for color, height/width of the thumb on a horizontal splitter
+.dijitSplitterV, .dijitGutterV - - for height, background, and border of a vertical splitter and gutter 
+.dijitSplitterV .dijitSplitterThumb - for color, height/width of the thumb on a vertical splitter
+.dijitSplitterHHover - for background-color of a hovered horizontal splitter
+.dijitSplitterHHover .dijitSplitterThumb - for background-color of a hovered thumb on a horizontal splitter
+.dijitSplitterVHover  - for background-color of a hovered vertical splitter
+.dijitSplitterVHover .dijitSplitterThumb - for background-color of a hovered thumb on a vertical splitter
+.dijitSplitterHActive - for background-color of an active horizontal splitter
+.dijitSplitterVActive - for background-color of an active horizontal splitter
+*/
+
+ at import "../variables";
+
+.claro .dijitBorderContainer {
+	/* matches the width of the splitters between panes */
+	padding: 5px;
+}
+
+.claro .dijitSplitContainer-child,
+.claro .dijitBorderContainer-child {
+	/* By default put borders on all children of BorderContainer,
+	 *  to give illusion of borders on the splitters themselves.
+	 */
+	border: 1px @border-color solid;
+}
+
+.claro .dijitBorderContainer-dijitTabContainerTop,
+.claro .dijitBorderContainer-dijitTabContainerBottom,
+.claro .dijitBorderContainer-dijitTabContainerLeft,
+.claro .dijitBorderContainer-dijitTabContainerRight,
+.claro .dijitBorderContainer-dijitAccordionContainer {
+	/* except that TabContainer defines borders on it's sub-nodes (tablist and dijitTabPaneWrapper),
+	 * so override rule setting border on domNode
+	 */
+	 border: none;
+
+}
+.claro .dijitBorderContainer-dijitBorderContainer {
+	/* make nested BorderContainers look like a single big widget with lots of splitters */
+	border: 0;
+	padding: 0;
+}
+
+/* Splitters and gutters */
+
+.claro .dijitSplitterH,
+.claro .dijitGutterH {
+	background:none;
+	border:0;
+	height:5px;
+}
+
+.claro .dijitSplitterH .dijitSplitterThumb {
+	background:@border-color none;
+	height:1px;
+	top:2px;
+	width:19px;
+}
+
+.claro .dijitSplitterV,
+.claro .dijitGutterV {
+	background:none;
+	border:0;
+	width:5px;
+	margin: 0;
+}
+
+.claro .dijitSplitterV .dijitSplitterThumb {
+	background:@border-color none;
+	height:19px;
+	left:2px;
+	width:1px;
+	margin: 0;
+}
+
+/* hovered splitter */
+.claro .dijitSplitterHHover {
+	font-size: 1px;
+	background: url("images/splitterHorizontalHover.png") no-repeat center top;
+}
+
+
+.claro .dijitSplitterHHover .dijitSplitterThumb {
+	background:@hovered-border-color none;
+}
+
+.claro .dijitSplitterVHover {
+	font-size: 1px;
+	background: url("images/splitterVerticalHover.png") no-repeat center left;
+}
+
+.claro .dijitSplitterVHover .dijitSplitterThumb {
+	background:@hovered-border-color none;
+}
+
+.dj_ie6 .dijitSplitterHHover,
+.dj_ie6 .claro .dijitSplitterVHover {
+	background-color: @splitter-hovered-background-color;
+	background-image:none;
+}
+
+/* active splitter */
+.claro .dijitSplitterHActive,
+.claro .dijitSplitterVActive {
+	font-size: 1px;
+	background-color:@splitter-dragged-background-color;
+}
diff --git a/dijit/themes/claro/layout/ContentPane.css b/dijit/themes/claro/layout/ContentPane.css
index b32c790..a7753de 100644
--- a/dijit/themes/claro/layout/ContentPane.css
+++ b/dijit/themes/claro/layout/ContentPane.css
@@ -21,20 +21,18 @@
  *	set background-color and padding of ContentPane nested within a BorderContainer 
  */
 .claro .dijitContentPane {
-	padding: 8px;
-}		
-
+  padding: 8px;
+}
 /* nested layouts */
 .claro .dijitTabContainerTop-dijitContentPane,
 .claro .dijitTabContainerLeft-dijitContentPane,
 .claro .dijitTabContainerBottom-dijitContentPane,
 .claro .dijitTabContainerRight-dijitContentPane,
 .claro .dijitAccordionContainer-dijitContentPane {
-	background-color: #fff;
-	padding: 8px;		
+  background-color: #ffffff;
+  padding: 8px;
+}
+.claro .dijitSplitContainer-dijitContentPane, .claro .dijitBorderContainer-dijitContentPane {
+  background-color: #ffffff;
+  padding: 8px;
 }
-.claro .dijitSplitContainer-dijitContentPane,
-.claro .dijitBorderContainer-dijitContentPane {
-	background-color: #fff;		
-	padding: 8px;
-}
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/ContentPane.less b/dijit/themes/claro/layout/ContentPane.less
new file mode 100644
index 0000000..83329bd
--- /dev/null
+++ b/dijit/themes/claro/layout/ContentPane.less
@@ -0,0 +1,43 @@
+/* ContentPane 
+ *	
+ * .dijitContentPane
+ * 	set padding for basic content pane
+ * 	
+ * Nested layouts:
+ * 
+ * .dijitTabContainerTop-dijitContentPane,
+ * .dijitTabContainerLeft-dijitContentPane,
+ * .dijitTabContainerBottom-dijitContentPane,
+ * .dijitTabContainerRight-dijitContentPane
+ * 	set background-color and padding of ContentPanes nested within TabContainer (can do top, left, bottom, or right) or Accordion Container
+ *
+ * .dijitAccordionContainer-dijitContentPane
+ * 	set background-color and padding of ContentPane nested within Accordion
+ *
+ * .dijitSplitContainer-dijitContentPane, 
+ *	set background-color and padding of ContentPane nested within a SplitContainer 
+ *
+ * .dijitBorderContainer-dijitContentPane
+ *	set background-color and padding of ContentPane nested within a BorderContainer 
+ */
+
+ at import "../variables";
+
+.claro .dijitContentPane {
+	padding: 8px;
+}		
+
+/* nested layouts */
+.claro .dijitTabContainerTop-dijitContentPane,
+.claro .dijitTabContainerLeft-dijitContentPane,
+.claro .dijitTabContainerBottom-dijitContentPane,
+.claro .dijitTabContainerRight-dijitContentPane,
+.claro .dijitAccordionContainer-dijitContentPane {
+	background-color: @pane-background-color;
+	padding: 8px;		
+}
+.claro .dijitSplitContainer-dijitContentPane,
+.claro .dijitBorderContainer-dijitContentPane {
+	background-color: @pane-background-color;		
+	padding: 8px;
+}
\ No newline at end of file
diff --git a/dijit/themes/claro/layout/TabContainer.css b/dijit/themes/claro/layout/TabContainer.css
index 12e4c8e..030e4b7 100644
--- a/dijit/themes/claro/layout/TabContainer.css
+++ b/dijit/themes/claro/layout/TabContainer.css
@@ -17,17 +17,17 @@
  * 		.tabStripButtonDisabled - styles for disabled tab strip buttons
  * 
  * Tab Button:
- * 		.dijitTabContainerTop-tabs .dijitTabInnerDiv/.dijitTabContent     - styles for top tab botton container
- * 		.dijitTabContainerBottom-tabs .dijitTabInnerDiv/.dijitTabContent  - styles for bottom tab botton container
- * 		.dijitTabContainerLeft-tabs .dijitTabInnerDiv/.dijitTabContent    - styles for left tab botton container
- * 		.dijitTabContainerRight-tabs .dijitTabInnerDiv/.dijitTabContent   - styles for right tab botton container
+ * 		.dijitTabContainerTop-tabs .dijitTabInnerDiv/.dijitTabContent     - styles for top tab button container
+ * 		.dijitTabContainerBottom-tabs .dijitTabInnerDiv/.dijitTabContent  - styles for bottom tab button container
+ * 		.dijitTabContainerLeft-tabs .dijitTabInnerDiv/.dijitTabContent    - styles for left tab button container
+ * 		.dijitTabContainerRight-tabs .dijitTabInnerDiv/.dijitTabContent   - styles for right tab button container
  * 
  * 		.dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv/.dijitTabContent    
- * 				- styles for selected status of top tab botton
+ * 				- styles for selected status of top tab button
  * 		same to Bottom, Left, Right Tabs
  * 
- * 		.dijitTabHover .dijitTabInnerDiv   - styles when mouse hover on tab bottons
- * 		.dijitTabActive .dijitTabInnerDiv  - styles when mouse down on tab bottons
+ * 		.dijitTabHover .dijitTabInnerDiv   - styles when mouse hover on tab buttons
+ * 		.dijitTabActive .dijitTabInnerDiv  - styles when mouse down on tab buttons
  * 		.dijitTabChecked .dijitTabInnerDiv  - styles when on buttons of selected tab		
  * 
  * 		.dijitTabCloseButton - the close action buttons lie at the right top of each tab button on closable tabs
@@ -46,394 +46,389 @@
  * 		.dijitTabContainerNested - Container for nested tabs
  * 		.dijitTabContainerTabListNested - tab list container for nested tabs
  */
-
 /*** some common features ***/
 .claro .dijitTabPaneWrapper {
-	background:#fff;
+  background: #ffffff;
 }
 .claro .dijitTabPaneWrapper,
 .claro .dijitTabContainerTop-tabs,
 .claro .dijitTabContainerBottom-tabs,
 .claro .dijitTabContainerLeft-tabs,
 .claro .dijitTabContainerRight-tabs {
-	/* todo: add common class name for this div */
-	border-color: #b5bcc7;
+  /* todo: add common class name for this div */
+
+  border-color: #b5bcc7;
 }
 .claro .dijitTabCloseButton {
-	background: url("images/tabClose.png") no-repeat;
-	width: 14px;
-	height: 14px;
-	margin-left: 5px;
-	margin-right:-3px;
+  background: url("images/tabClose.png") no-repeat;
+  width: 14px;
+  height: 14px;
+  margin-left: 5px;
+  margin-right: -5px;
 }
 .claro .dijitTabCloseButtonHover {
-	background-position:-14px;
+  background-position: -14px;
 }
 .claro .dijitTabCloseButtonActive {
-	background-position:-28px;
+  background-position: -28px;
 }
 .claro .dijitTabSpacer {
-	/* set the spacer invisible.  note that height:0 doesn't work on IE/quirks, it's still 10px. */
-	display: none;
+  /* set the spacer invisible.  note that height:0 doesn't work on IE/quirks, it's still 10px. */
+
+  display: none;
 }
 .claro .dijitTabInnerDiv {
-	background-color:#e6e6e7;
-	-webkit-transition-property:background-color, border;
- 	-webkit-transition-duration:.35s;
-	color:#4a4a4a;
+  background-color: #efefef;
+  -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;
+  color: #4a4a4a;
 }
 .claro .dijitTabHover .dijitTabInnerDiv {
-	background-color:#a9d6ff;
- 	-webkit-transition-duration:.25s;
-	color:#000;
+  background-color: #abd6ff;
+  -webkit-transition-duration: 0.25s;
+  -moz-transition-duration: 0.25s;
+  transition-duration: 0.25s;
+  color: #000000;
 }
 .claro .dijitTabActive .dijitTabInnerDiv {
-	background-color:#8bc4f9;
-	color:#000;
-	-webkit-transition-duration:.1s;
+  background-color: #7dbefa;
+  color: #000000;
+  -webkit-transition-duration: 0.1s;
+  -moz-transition-duration: 0.1s;
+  transition-duration: 0.1s;
 }
 .claro .dijitTabChecked .dijitTabInnerDiv {
-	background-color:#b2d4f3;
-	color:#000;
+  background-color: #cfe5fa;
+  color: #000000;
 }
-
 .claro .dijitTabContent {
-	border: 1px solid #b5bcc7;
+  border: 1px solid #b5bcc7;
+}
+.claro .dijitTabHover .dijitTabContent {
+  border-color: #769dc0;
 }
-.claro .dijitTabHover .dijitTabContent,
 .claro .dijitTabActive .dijitTabContent {
-	border-color: #769dc0;
+  border-color: #769dc0;
 }
 .claro .dijitTabChecked .dijitTabContent {
-	color:#000;
-	border-color: #b5bcc7;	
+  color: #000000;
+  border-color: #b5bcc7;
 }
-
 .claro .tabStripButton .dijitTabInnerDiv {
-	background-color: transparent;
+  background-color: transparent;
 }
 .claro .tabStripButton .dijitTabContent {
-	border: none;
+  border: none;
 }
 /*** end common ***/
-
-
 /*************** top tab ***************/
 .claro .dijitTabContainerTop-tabs .dijitTab {
-	top: 1px;	/* used for overlap */
-	margin-right: 1px;
-	padding-top: 3px;
+  top: 1px;
+  /* used for overlap */
+
+  margin-right: 1px;
+  padding-top: 3px;
 }
 .dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTab {
-	top: 3px;
+  top: 3px;
 }
 /* for top tab padding. change height when status changes */
 .claro .dijitTabContainerTop-tabs .dijitTabContent {
-	padding:3px 8px 3px 4px;
-	border-bottom: 1px;
-	background-image:url("images/tabTop.png");
-	background-position:0px 0px;
-	background-repeat:repeat-x;
-	min-width: 60px;
-	text-align: center;
+  padding: 3px 6px;
+  border-bottom-width: 0;
+  background-image: url("images/tabTop.png");
+  background-position: 0 0;
+  background-repeat: repeat-x;
+  min-width: 60px;
+  text-align: center;
 }
 .claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
-	padding-bottom: 4px;
-	padding-top: 6px;
+  padding-bottom: 4px;
+  padding-top: 6px;
 }
-.dj_ie .claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
-	border-bottom: none;
-}
-
 /* normal status */
 .claro .dijitTabContainerTop-tabs .dijitTabInnerDiv {
-	background-image:url("images/tabTop.png");
-	background-position:0px -248px;
-	background-position:bottom;
-	background-repeat:repeat-x;
-	box-shadow: 0px -1px 1px rgba(0, 0, 0, 0.04);
-	-webkit-box-shadow: 0px -1px 1px rgba(0, 0, 0, 0.04);
-	-moz-box-shadow: 0px -1px 1px rgba(0, 0, 0, 0.04);
+  background-image: url("images/tabTop.png");
+  background-position: 0 -248px;
+  background-position: bottom;
+  background-repeat: repeat-x;
+  -webkit-box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.04);
+  -moz-box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.04);
+  box-shadow: 0 -1px 1px rgba(0, 0, 0, 0.04);
 }
-
 /* checked status */
 .claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-image:none;
-	box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.05);
-	-webkit-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.05);
-	-moz-box-shadow: 0px -1px 2px rgba(0, 0, 0, 0.05);
+  background-image: none;
+  -webkit-box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.05);
+  -moz-box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.05);
+  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.05);
 }
 .claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
-	background-position:0px -102px;
-	background-repeat:repeat-x;
+  background-position: 0 -102px;
+  background-repeat: repeat-x;
 }
 /** end top tab **/
-
-
 /*************** bottom tab ***************/
 .claro .dijitTabContainerBottom-tabs .dijitTab {
-	top: -1px;	/* used for overlap */
-	margin-right: 1px;
+  top: -1px;
+  /* used for overlap */
+
+  margin-right: 1px;
 }
 /* calculate the position and size */
 .claro .dijitTabContainerBottom-tabs .dijitTabContent {
-	padding:3px 8px 4px 4px;
-	border-top: none;
-	background-image: url("images/tabBottom.png");
-	background-position:0px -249px;
-	background-repeat: repeat-x;
-	background-position:bottom;
-	min-width: 60px;
-	text-align: center;
+  padding: 3px 6px;
+  border-top-width: 0;
+  background-image: url("images/tabBottom.png");
+  background-position: 0 -249px;
+  background-repeat: repeat-x;
+  background-position: bottom;
+  min-width: 60px;
+  text-align: center;
 }
 .claro .dijitTabContainerBottom-tabs .dijitTab {
-	padding-bottom: 3px;
+  padding-bottom: 3px;
 }
 /* normal status */
 .claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
-	background-image: url("images/tabBottom.png");
-	background-position: top;
-	background-repeat: repeat-x;
-	box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.04);
-	-webkit-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.04);
-	-moz-box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.04);
-	
+  background-image: url("images/tabBottom.png");
+  background-position: top;
+  background-repeat: repeat-x;
+  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
+  -moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
+  box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
 }
-
 /* checked status */
 .claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabContent {
-	padding-bottom: 7px;
-	padding-top: 4px;
-	background-position:0px -119px;
+  padding-bottom: 7px;
+  padding-top: 4px;
+  background-position: 0 -119px;
 }
 .claro .dijitTabContainerBottom-tabs .dijitTabChecked {
-	padding-bottom: 0;
+  padding-bottom: 0;
 }
 .claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-image:none;
-	box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05);
-	-webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05);
-	-moz-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.05);
+  background-image: none;
+  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+  -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
 }
 /** end bottom tab **/
-
 /*************** left tab ***************/
 .claro .dijitTabContainerLeft-tabs .dijitTab {
-	left: 1px;	/* used for overlap */
-	margin-bottom: 1px;
+  border-right-width: 0;
+  left: 1px;
+  /* used for overlap */
+
+  margin-bottom: 1px;
 }
 /* normal status */
 .claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
-	background-image: url("images/tabLeft.png");
-	background-position: -347px -340px;
-	background-repeat: repeat-y;
+  background-image: url("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-repeat: repeat-y;
-	background-position:0px 0px;
+  padding: 3px 8px 4px 4px;
+  background-image: url("images/tabLeft.png");
+  background-repeat: repeat-y;
+  background-position: 0 0;
 }
 /* checked status */
 .claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabContent {
-	padding-right: 9px;
-	border-right: none;
-	background-image: none;
+  padding-right: 9px;
+  border-right: none;
+  background-image: none;
 }
 .claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-position:0px -179px;
-	background-repeat:repeat-y;
-	box-shadow: -1px 0px 2px rgba(0, 0, 0, .05);
-	-webkit-box-shadow: -1px 0px 2px rgba(0, 0, 0, .05);
-	-moz-box-shadow: -1px 0px 2px rgba(0, 0, 0, 0.05);
+  background-position: 0 -179px;
+  background-repeat: repeat-y;
+  -webkit-box-shadow: -1px 0 2px rgba(0, 0, 0, 0.05);
+  -moz-box-shadow: -1px 0 2px rgba(0, 0, 0, 0.05);
+  box-shadow: -1px 0 2px rgba(0, 0, 0, 0.05);
 }
 /** end left tab **/
-
 /*************** right tab ***************/
 .claro .dijitTabContainerRight-tabs .dijitTab {
-	left: -1px;	/* used for overlap */
-	margin-bottom: 1px;
+  border-left-width: 0;
+  left: -1px;
+  /* used for overlap */
+
+  margin-bottom: 1px;
 }
 /* normal status */
 .claro .dijitTabContainerRight-tabs .dijitTabInnerDiv {
-	background-image: url("images/tabRight.png");
-	background-repeat: repeat-y;
-	background-position: -1px -347px;
+  background-image: url("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-position:right top;
-	background-repeat: repeat-y;
+  padding: 3px 8px 4px 4px;
+  background-image: url("images/tabRight.png");
+  background-position: right top;
+  background-repeat: repeat-y;
 }
 /* checked status */
 .claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabContent {
-	padding-left: 5px;
-	border-left: none;
-	background-image: none;
+  padding-left: 5px;
+  border-left: none;
+  background-image: none;
 }
 .claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv {
-	background-position:-348px -179px;
-	box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.07);
-	-webkit-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.07);
-	-moz-box-shadow: 1px 0px 2px rgba(0, 0, 0, 0.07);
+  background-position: -348px -179px;
+  -webkit-box-shadow: 1px 0 2px rgba(0, 0, 0, 0.07);
+  -moz-box-shadow: 1px 0 2px rgba(0, 0, 0, 0.07);
+  box-shadow: 1px 0 2px rgba(0, 0, 0, 0.07);
 }
 /** end right tab **/
-
 /** round corner **/
-.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerTop-tabs .dijitTabContent {
-	border-radius: 2px 2px 0px 0px;
-	-moz-border-radius: 2px 2px 0px 0px;
-	-webkit-border-top-left-radius:2px;
-	-webkit-border-top-right-radius:2px;
-}
-.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerBottom-tabs .dijitTabContent{
-	border-radius: 0px 0px 2px 2px;
-	-moz-border-radius: 0px 0px 2px 2px;
-	-webkit-border-bottom-right-radius:2px;
-	-webkit-border-bottom-left-radius:2px;
-}
-.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerLeft-tabs .dijitTabContent{
-	border-radius: 2px 0px 0px 2px;
-	-moz-border-radius: 2px 0px 0px 2px;
-	-webkit-border-top-left-radius:2px;
-	-webkit-border-bottom-left-radius:2px;
+.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv, .claro .dijitTabContainerTop-tabs .dijitTabContent {
+  -moz-border-radius: 2px 2px 0 0;
+  border-radius: 2px 2px 0 0;
 }
-
-.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv,
-.claro .dijitTabContainerRight-tabs .dijitTabContent{
-	border-radius: 0px 2px 2px 0px;
-	-moz-border-radius: 0px 2px 2px 0px;
-	-webkit-border-top-right-radius:2px;
-	-webkit-border-bottom-right-radius:2px;
+.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv, .claro .dijitTabContainerBottom-tabs .dijitTabContent {
+  -moz-border-radius: 0 0 2px 2px;
+  border-radius: 0 0 2px 2px;
+}
+.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv, .claro .dijitTabContainerLeft-tabs .dijitTabContent {
+  -moz-border-radius: 2px 0 0 2px;
+  border-radius: 2px 0 0 2px;
+}
+.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv, .claro .dijitTabContainerRight-tabs .dijitTabContent {
+  -moz-border-radius: 0 2px 2px 0;
+  border-radius: 0 2px 2px 0;
 }
-
 /************ left/right scroll buttons + menu button ************/
 .claro .tabStripButton {
-	background-color:#deecf9;
-	border: 1px solid #b5bcc7;
+  background-color: #e9f4fe;
+  border: 1px solid #b5bcc7;
 }
 .claro .dijitTabListContainer-top .tabStripButton {
-	padding: 4px 3px;
-	margin-top:7px;
-	background-image: url("images/tabTop.png");
-	background-position:0px 0px;
+  padding: 4px 3px;
+  margin-top: 7px;
+  background-image: url("images/tabTop.png");
+  background-position: 0 0;
 }
 .claro .dijitTabListContainer-bottom .tabStripButton {
-	padding:5px 3px;
-	margin-bottom:4px;
-	background-image: url("images/tabTop.png");
-	background-position:0px -248px;
-	background-position:bottom;
+  padding: 5px 3px;
+  margin-bottom: 4px;
+  background-image: url("images/tabTop.png");
+  background-position: 0 -248px;
+  background-position: bottom;
 }
 .claro .tabStripButtonHover {
-	background-color:#a6d2fb;
+  background-color: #abd6ff;
 }
 .claro .tabStripButtonActive {
-	background-color:#7dbefa;
+  background-color: #7dbefa;
 }
 .claro .dijitTabStripIcon {
-	height:15px;
-	width:15px;
-	margin: 0 auto;
-	background:url("../form/images/buttonArrows.png") no-repeat -75px 50%;
-	background-color: transparent;
+  height: 15px;
+  width: 15px;
+  margin: 0 auto;
+  background: url("../form/images/buttonArrows.png") no-repeat -75px 50%;
+  background-color: transparent;
 }
-.claro .dijitTabStripSlideRightIcon{
-	background-position: -24px 50%;
+.claro .dijitTabStripSlideRightIcon {
+  background-position: -24px 50%;
 }
 .claro .dijitTabStripMenuIcon {
-	background-position: -51px 50%;
+  background-position: -51px 50%;
 }
-
 /*disabled styles for tab strip buttons*/
-.claro .dijitTabListContainer-top .tabStripButtonDisabled,
-.claro .dijitTabListContainer-bottom .tabStripButtonDisabled {
-	background-color:#dddddd;
-	border:1px solid #c9c9c9;
+.claro .dijitTabListContainer-top .tabStripButtonDisabled, .claro .dijitTabListContainer-bottom .tabStripButtonDisabled {
+  background-color: #d3d3d3;
+  border: 1px solid #b5bcc7;
+  /* to match border of TabContainer itself */
+
 }
 .claro .tabStripButtonDisabled .dijitTabStripSlideLeftIcon {
-	background-position:-175px 50%;
+  background-position: -175px 50%;
 }
 .claro .tabStripButtonDisabled .dijitTabStripSlideRightIcon {
-	background-position: -124px 50%;
+  background-position: -124px 50%;
 }
 .claro .tabStripButtonDisabled .dijitTabStripMenuIcon {
-	background-position: -151px 50%;
-} 
+  background-position: -151px 50%;
+}
 /* Nested Tabs */
 .claro .dijitTabContainerNested .dijitTabListWrapper {
-	height: auto;
+  height: auto;
 }
 .claro .dijitTabContainerNested .dijitTabContainerTop-tabs {
-	border-bottom:solid 1px #b5bcc7;
-	padding:1px 2px 4px;
-	margin-top:-2px;
+  border-bottom: solid 1px #b5bcc7;
+  padding: 1px 2px 4px;
+  margin-top: -2px;
 }
 .claro .dijitTabContainerTabListNested .dijitTabContent {
-	background:rgba(255, 255, 255, 0) none repeat scroll 0 0;
-	border: none;
-	padding: 4px;
-	border-color: rgba(118,157,192,0);
-	-webkit-transition-property:background-color, border-color;
- 	-webkit-transition-duration:.3s;
+  background: rgba(255, 255, 255, 0) none repeat scroll 0 0;
+  border: none;
+  padding: 4px;
+  border-color: rgba(118, 157, 192, 0);
+  -webkit-transition-property: background-color, border-color;
+  -moz-transition-property: background-color, border-color;
+  transition-property: background-color, border-color;
+  -webkit-transition-duration: 0.3s;
+  -moz-transition-duration: 0.3s;
+  transition-duration: 0.3s;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
 }
 .claro .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv {
-	/* 4 element selector to override box-shadow setting from above rule:
+  /* 4 element selector to override box-shadow setting from above rule:
 	 *		.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv { ... }
 	 */
-	background: none;
-	border: none;
-	top: 0px;/* to override top: 1px/-1px for normal tabs */
-	box-shadow: none;
-	-webkit-box-shadow: none;
-	-moz-box-shadow: none;
+
+  background: none;
+  border: none;
+  top: 0;
+  /* to override top: 1px/-1px for normal tabs */
+
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
 }
 .claro .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent {
-	background-color:#eaf4fc;
-	border-radius: 2px 2px 2px 2px;
-	-moz-border-radius: 2px 2px 2px 2px;
-	-webkit-border-radius:2px;
-	border:solid 1px #c8dff3;
-	padding: 3px;
-	webkit-transition-duration:.2s;
+  background-color: #e9f4fe;
+  border: solid 1px #cfe5fa;
+  padding: 3px;
+  -webkit-transition-duration: 0.2s;
+  -moz-transition-duration: 0.2s;
+  transition-duration: 0.2s;
 }
 .claro .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
-	text-decoration: none;
+  text-decoration: none;
 }
 .claro .dijitTabContainerTabListNested .dijitTabActive .dijitTabContent {
-	border-radius: 2px 2px 2px 2px;
-	-moz-border-radius: 2px 2px 2px 2px;
-	-webkit-border-radius:2px;
-	border:solid 1px #a8c7e2;
-	padding: 3px;
-	background:#b9d9f5 url("images/tabNested.png") repeat-x;
-	-webkit-transition-duration:.1s;
+  border: solid 1px #769dc0;
+  padding: 3px;
+  background: #abd6ff url("images/tabNested.png") repeat-x;
+  -webkit-transition-duration: 0.1s;
+  -moz-transition-duration: 0.1s;
+  transition-duration: 0.1s;
 }
 .claro .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent {
-	border-radius: 2px 2px 2px 2px;
-	-moz-border-radius: 2px 2px 2px 2px;
-	-webkit-border-radius:2px;
-	padding: 3px;
-	border:solid 1px #a8c7e2;
-	background-position: 0px 105px;
-	background-color:#d4e8f9;
+  padding: 3px;
+  border: solid 1px #769dc0;
+  background-position: 0 105px;
+  background-color: #cfe5fa;
 }
 .claro .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
-	text-decoration: none;
-	background-image:none;
+  text-decoration: none;
+  background-image: none;
 }
 .claro .dijitTabPaneWrapperNested {
-	border: none;/* prevent double border */
-}
-
+  border: none;
+  /* prevent double border */
 
+}
 .dj_ie6 .claro .dijitTabContent,
 .dj_ie6 .claro .dijitTabInnerDiv,
 .dj_ie6 .dijitTabListContainer-top .tabStripButton,
-.dj_ie6 .dijitTabListContainer-bottom .tabStripButton{
-	background-image: none;
+.dj_ie6 .dijitTabListContainer-bottom .tabStripButton {
+  background-image: none;
 }
diff --git a/dijit/themes/claro/layout/TabContainer.less b/dijit/themes/claro/layout/TabContainer.less
new file mode 100644
index 0000000..691900e
--- /dev/null
+++ b/dijit/themes/claro/layout/TabContainer.less
@@ -0,0 +1,408 @@
+/* TabContainer 
+ * 
+ * Styling TabContainer means styling the TabList and Its content container  (dijitTitlePane)
+ * 
+ * Tab List: (including 4 kinds of tab location)
+ * 		.dijitTabContainerTop-tabs     - tablist container at top
+ * 		.dijitTabContainerBottom-tabs  - tablist container at bottom
+ * 		.dijitTabContainerLeft-tabs    - tablist container at left
+ * 		.dijitTabContainerRight-tabs   - tablist container at right
+ * 
+ * Tab Strip Button:
+ * 		.dijitTabStripIcon - tab strip button icon
+ * 		.dijitTabStripMenuIcon - down arrow icon position
+ * 		.dijitTabStripSlideLeftIcon - left arrow icon position
+ * 		.dijitTabStripSlideRightIcon - right arrow icon position
+ * 
+ * 		.tabStripButtonDisabled - styles for disabled tab strip buttons
+ * 
+ * Tab Button:
+ * 		.dijitTabContainerTop-tabs .dijitTabInnerDiv/.dijitTabContent     - styles for top tab button container
+ * 		.dijitTabContainerBottom-tabs .dijitTabInnerDiv/.dijitTabContent  - styles for bottom tab button container
+ * 		.dijitTabContainerLeft-tabs .dijitTabInnerDiv/.dijitTabContent    - styles for left tab button container
+ * 		.dijitTabContainerRight-tabs .dijitTabInnerDiv/.dijitTabContent   - styles for right tab button container
+ * 
+ * 		.dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv/.dijitTabContent    
+ * 				- styles for selected status of top tab button
+ * 		same to Bottom, Left, Right Tabs
+ * 
+ * 		.dijitTabHover .dijitTabInnerDiv   - styles when mouse hover on tab buttons
+ * 		.dijitTabActive .dijitTabInnerDiv  - styles when mouse down on tab buttons
+ * 		.dijitTabChecked .dijitTabInnerDiv  - styles when on buttons of selected tab		
+ * 
+ * 		.dijitTabCloseButton - the close action buttons lie at the right top of each tab button on closable tabs
+ * 		.dijitTabCloseButtonHover - styles when mouse hover on close action button
+ * 		.dijitTabCloseButtonActive - styles when mouse down on close action button
+ * 
+ * Tab Button: (checked status)
+ * 
+ * Tab Content Container:
+ * 		.dijitTabContainerTop-dijitContentPane
+ * 		.dijitTabContainerBottom-dijitContentPane
+ * 		.dijitTabContainerLeft-dijitContentPane
+ * 		.dijitTabContainerRight-dijitContentPane - for background and padding
+ * 
+ * Nested Tabs:
+ * 		.dijitTabContainerNested - Container for nested tabs
+ * 		.dijitTabContainerTabListNested - tab list container for nested tabs
+ */
+
+ at import "../variables";
+
+/*** some common features ***/
+.claro .dijitTabPaneWrapper {
+	background:@pane-background-color;
+}
+.claro .dijitTabPaneWrapper,
+.claro .dijitTabContainerTop-tabs,
+.claro .dijitTabContainerBottom-tabs,
+.claro .dijitTabContainerLeft-tabs,
+.claro .dijitTabContainerRight-tabs {
+	/* todo: add common class name for this div */
+	border-color: @border-color;
+}
+.claro .dijitTabCloseButton {
+	background: url("images/tabClose.png") no-repeat;
+	width: 14px;
+	height: 14px;
+	margin-left: 5px;
+	margin-right:-5px;
+}
+.claro .dijitTabCloseButtonHover {
+	background-position:-14px;
+}
+.claro .dijitTabCloseButtonActive {
+	background-position:-28px;
+}
+.claro .dijitTabSpacer {
+	/* set the spacer invisible.  note that height:0 doesn't work on IE/quirks, it's still 10px. */
+	display: none;
+}
+.claro .dijitTabInnerDiv {
+	background-color:@unselected-background-color;
+	.transition-property(background-color, border);
+ 	.transition-duration(.35s);
+	color:@unselected-text-color;
+}
+.claro .dijitTabHover .dijitTabInnerDiv {
+	background-color:@hovered-background-color;
+ 	.transition-duration(.25s);
+	color:@hovered-text-color;
+}
+.claro .dijitTabActive .dijitTabInnerDiv {
+	background-color:@pressed-background-color;
+	color:@selected-text-color;
+	.transition-duration(.1s);
+}
+.claro .dijitTabChecked .dijitTabInnerDiv {
+	background-color:@selected-background-color;
+	color:@selected-text-color;
+}
+
+.claro .dijitTabContent {
+	border: 1px solid @border-color;
+}
+.claro .dijitTabHover .dijitTabContent {
+	border-color: @hovered-border-color;
+}
+.claro .dijitTabActive .dijitTabContent {
+	border-color: @pressed-border-color;
+}
+.claro .dijitTabChecked .dijitTabContent {
+	color:@selected-text-color;			// todo: redundant with .claro .dijitTabChecked .dijitTabInnerDiv above?
+	border-color: @border-color;			// don't use @selected-border-color because need to match border of TabContainer
+}
+
+.claro .tabStripButton .dijitTabInnerDiv {
+	background-color: transparent;
+}
+.claro .tabStripButton .dijitTabContent {
+	border: none;
+}
+/*** end common ***/
+
+
+/*************** top tab ***************/
+.claro .dijitTabContainerTop-tabs .dijitTab {
+	top: 1px;	/* used for overlap */
+	margin-right: 1px;
+	padding-top: 3px;
+}
+.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTab {
+	top: 3px;
+}
+/* for top tab padding. change height when status changes */
+.claro .dijitTabContainerTop-tabs .dijitTabContent {
+	padding:3px 6px;
+	border-bottom-width: 0;
+	background-image:url("images/tabTop.png");
+	background-position:0 0;
+	background-repeat:repeat-x;
+	min-width: 60px;
+	text-align: center;
+}
+.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
+	padding-bottom: 4px;
+	padding-top: 6px;
+}
+
+/* normal status */
+.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv {
+	background-image:url("images/tabTop.png");
+	background-position:0 -248px;
+	background-position:bottom;
+	background-repeat:repeat-x;
+	.box-shadow(0 -1px 1px rgba(0, 0, 0, 0.04));
+}
+
+/* checked status */
+.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background-image:none;
+	.box-shadow(0 -1px 2px rgba(0, 0, 0, 0.05));
+}
+.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabContent {
+	background-position:0 -102px;
+	background-repeat:repeat-x;
+}
+/** end top tab **/
+
+
+/*************** bottom tab ***************/
+.claro .dijitTabContainerBottom-tabs .dijitTab {
+	top: -1px;	/* used for overlap */
+	margin-right: 1px;
+}
+/* calculate the position and size */
+.claro .dijitTabContainerBottom-tabs .dijitTabContent {
+	padding:3px 6px;
+	border-top-width: 0;
+	background-image: url("images/tabBottom.png");
+	background-position:0 -249px;
+	background-repeat: repeat-x;
+	background-position:bottom;
+	min-width: 60px;
+	text-align: center;
+}
+.claro .dijitTabContainerBottom-tabs .dijitTab {
+	padding-bottom: 3px;
+}
+/* normal status */
+.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv {
+	background-image: url("images/tabBottom.png");
+	background-position: top;
+	background-repeat: repeat-x;
+	.box-shadow(0 1px 1px rgba(0, 0, 0, 0.04));
+	
+}
+
+/* checked status */
+.claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabContent {
+	padding-bottom: 7px;
+	padding-top: 4px;
+	background-position:0 -119px;
+}
+.claro .dijitTabContainerBottom-tabs .dijitTabChecked {
+	padding-bottom: 0;
+}
+.claro .dijitTabContainerBottom-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background-image:none;
+	.box-shadow(0 1px 2px rgba(0, 0, 0, 0.05));
+}
+/** end bottom tab **/
+
+/*************** left tab ***************/
+.claro .dijitTabContainerLeft-tabs .dijitTab {
+	border-right-width: 0;
+	left: 1px;	/* used for overlap */
+	margin-bottom: 1px;
+}
+/* normal status */
+.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv {
+	background-image: url("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-repeat: repeat-y;
+	background-position:0 0;
+}
+/* checked status */
+.claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabContent {
+	padding-right: 9px;
+	border-right: none;
+	background-image: none;
+}
+.claro .dijitTabContainerLeft-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background-position:0 -179px;
+	background-repeat:repeat-y;
+	.box-shadow(-1px 0 2px rgba(0, 0, 0, .05));
+}
+/** end left tab **/
+
+/*************** right tab ***************/
+.claro .dijitTabContainerRight-tabs .dijitTab {
+	border-left-width: 0;
+	left: -1px;	/* used for overlap */
+	margin-bottom: 1px;
+}
+/* normal status */
+.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv {
+	background-image: url("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-position:right top;
+	background-repeat: repeat-y;
+}
+/* checked status */
+.claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabContent {
+	padding-left: 5px;
+	border-left: none;
+	background-image: none;
+}
+.claro .dijitTabContainerRight-tabs .dijitTabChecked .dijitTabInnerDiv {
+	background-position:-348px -179px;
+	.box-shadow(1px 0 2px rgba(0, 0, 0, 0.07));
+}
+/** end right tab **/
+
+/** round corner **/
+.claro .dijitTabContainerTop-tabs .dijitTabInnerDiv,
+.claro .dijitTabContainerTop-tabs .dijitTabContent {
+	.border-radius(2px 2px 0 0);
+}
+.claro .dijitTabContainerBottom-tabs .dijitTabInnerDiv,
+.claro .dijitTabContainerBottom-tabs .dijitTabContent{
+	.border-radius(0 0 2px 2px);
+}
+.claro .dijitTabContainerLeft-tabs .dijitTabInnerDiv,
+.claro .dijitTabContainerLeft-tabs .dijitTabContent{
+	.border-radius(2px 0 0 2px);
+}
+
+.claro .dijitTabContainerRight-tabs .dijitTabInnerDiv,
+.claro .dijitTabContainerRight-tabs .dijitTabContent{
+	.border-radius(0 2px 2px 0);
+}
+
+/************ left/right scroll buttons + menu button ************/
+.claro .tabStripButton {
+	background-color:@button-background-color;
+	border: 1px solid @border-color;
+}
+.claro .dijitTabListContainer-top .tabStripButton {
+	padding: 4px 3px;
+	margin-top:7px;
+	background-image: url("images/tabTop.png");
+	background-position:0 0;
+}
+.claro .dijitTabListContainer-bottom .tabStripButton {
+	padding:5px 3px;
+	margin-bottom:4px;
+	background-image: url("images/tabTop.png");
+	background-position:0 -248px;
+	background-position:bottom;
+}
+.claro .tabStripButtonHover {
+	background-color:@hovered-background-color;
+}
+.claro .tabStripButtonActive {
+	background-color:@pressed-background-color;
+}
+.claro .dijitTabStripIcon {
+	height:15px;
+	width:15px;
+	margin: 0 auto;
+	background:url("../form/images/buttonArrows.png") no-repeat -75px 50%;
+	background-color: transparent;
+}
+.claro .dijitTabStripSlideRightIcon{
+	background-position: -24px 50%;
+}
+.claro .dijitTabStripMenuIcon {
+	background-position: -51px 50%;
+}
+
+/*disabled styles for tab strip buttons*/
+.claro .dijitTabListContainer-top .tabStripButtonDisabled,
+.claro .dijitTabListContainer-bottom .tabStripButtonDisabled {
+	background-color:@tab-disabled-background-color;
+	border:1px solid @border-color;	/* to match border of TabContainer itself */
+}
+.claro .tabStripButtonDisabled .dijitTabStripSlideLeftIcon {
+	background-position:-175px 50%;
+}
+.claro .tabStripButtonDisabled .dijitTabStripSlideRightIcon {
+	background-position: -124px 50%;
+}
+.claro .tabStripButtonDisabled .dijitTabStripMenuIcon {
+	background-position: -151px 50%;
+} 
+/* Nested Tabs */
+.claro .dijitTabContainerNested .dijitTabListWrapper {
+	height: auto;
+}
+.claro .dijitTabContainerNested .dijitTabContainerTop-tabs {
+	border-bottom:solid 1px @border-color;
+	padding:1px 2px 4px;
+	margin-top:-2px;
+}
+.claro .dijitTabContainerTabListNested .dijitTabContent {
+	background:rgba(255, 255, 255, 0) none repeat scroll 0 0;
+	border: none;
+	padding: 4px;
+	border-color: rgba(118,157,192,0);
+	.transition-property(background-color, border-color);
+ 	.transition-duration(.3s);
+	.border-radius(2px);
+}
+.claro .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv {
+	/* 4 element selector to override box-shadow setting from above rule:
+	 *		.claro .dijitTabContainerTop-tabs .dijitTabChecked .dijitTabInnerDiv { ... }
+	 */
+	background: none;
+	border: none;
+	top: 0;/* to override top: 1px/-1px for normal tabs */
+	.box-shadow(none);
+}
+.claro .dijitTabContainerTabListNested .dijitTabHover .dijitTabContent {
+	background-color: @nestedtab-hovered-background-color;
+	border:solid 1px @nestedtab-hovered-border-color;
+	padding: 3px;
+	.transition-duration(.2s);
+}
+.claro .dijitTabContainerTabListNested .dijitTabHover .tabLabel {
+	text-decoration: none;
+}
+.claro .dijitTabContainerTabListNested .dijitTabActive .dijitTabContent {
+	border:solid 1px @nestedtab-selected-border-color;
+	padding: 3px;
+	background: @nestedtab-selected-background-color url("images/tabNested.png") repeat-x;
+	.transition-duration(.1s);
+}
+.claro .dijitTabContainerTabListNested .dijitTabChecked .dijitTabContent {
+	padding: 3px;
+	border:solid 1px @selected-border-color;
+	background-position: 0 105px;
+	background-color:@selected-background-color;
+}
+.claro .dijitTabContainerTabListNested .dijitTabChecked .tabLabel {
+	text-decoration: none;
+	background-image:none;
+}
+.claro .dijitTabPaneWrapperNested {
+	border: none;/* prevent double border */
+}
+
+
+.dj_ie6 .claro .dijitTabContent,
+.dj_ie6 .claro .dijitTabInnerDiv,
+.dj_ie6 .dijitTabListContainer-top .tabStripButton,
+.dj_ie6 .dijitTabListContainer-bottom .tabStripButton{
+	background-image: none;
+}
diff --git a/dijit/themes/claro/layout/TabContainer_rtl.css b/dijit/themes/claro/layout/TabContainer_rtl.css
index 280582a..89fdff0 100644
--- a/dijit/themes/claro/layout/TabContainer_rtl.css
+++ b/dijit/themes/claro/layout/TabContainer_rtl.css
@@ -1,77 +1,67 @@
-.claro .dijitTabContainerTop-tabs .dijitTabRtl,
-.claro .dijitTabContainerBottom-tabs .dijitTabRtl {
-	margin-right: 0;
-	margin-left: 1px;
+.claro .dijitTabContainerTop-tabs .dijitTabRtl, .claro .dijitTabContainerBottom-tabs .dijitTabRtl {
+  margin-right: 0;
+  margin-left: 1px;
 }
 .claro .dijitTabRtl {
-	-moz-box-orient:horizontal;
-	text-align: right;
+  -moz-box-orient: horizontal;
+  text-align: right;
 }
 .dj_ie7 .claro .dijitTabRtl .dijitTabContent {
-	display: block;
-	left: 0;
+  display: block;
+  left: 0;
 }
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl,
-.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabCheckedRtl {
-	top: 1px;
+.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl, .dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabCheckedRtl {
+  top: 1px;
 }
 .dj_ie7 .claro .tabStripButtonRtl .dijitButtonContents,
-.dj_ie8 .claro .tabStripButtonRtl .dijitButtonContents,	/* needed for IE8 quirks, but breaks IE6 quirks */
+.dj_ie8 .claro .tabStripButtonRtl .dijitButtonContents,
 .dj_ie6 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
 .dj_ie6 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
 .dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
 .dj_ie7 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
 .dj_iequirks .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
 .dj_iequirks .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv {
-	float:left;
+  float: left;
 }
 .dj_ie6 .claro .dijitTabRtl .tabLabel,
 .dj_ie6 .claro .dijitTabContainerRight-tabs .dijitTabRtl,
 .dj_ie6 .claro .dijitTabContainerLeft-tabs .dijitTabRtl,
 .dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtl .dijitTabInnerDiv,
 .dj_ie7 .claro .dijitTabContainerLeft-tabs .dijitTabRtl .dijitTabInnerDiv {
-	/*Make the .tablabel have width in ie6 with haslayout property, fix Close icon position bug*/
-	zoom:1;
+  /*Make the .tablabel have width in ie6 with haslayout property, fix Close icon position bug*/
+
+  zoom: 1;
 }
-.dj_ie6 .claro .dijitTabRtl .dijitTabCloseButton,
-.dj_ie7 .claro .dijitTabRtl .dijitTabCloseButton,
-.dj_iequirks .claro .dijitTabRtl .dijitTabCloseButton {
-	margin-right:5px;
+.dj_ie6 .claro .dijitTabRtl .dijitTabCloseButton, .dj_ie7 .claro .dijitTabRtl .dijitTabCloseButton, .dj_iequirks .claro .dijitTabRtl .dijitTabCloseButton {
+  margin-right: 5px;
 }
-
-.dj_ie6 .claro .dijitTabContainerRightRtl .dijitTabContainerRight-tabs,
-.dj_ie6 .claro .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs {
-	width:1%;
+.dj_ie6 .claro .dijitTabContainerRightRtl .dijitTabContainerRight-tabs, .dj_ie6 .claro .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs {
+  width: 1%;
 }
-
-.dj_ie6 .dijitTabContainerTopStrip,
-.dj_ie6 .dijitTabContainerBottomStrip {
-	position:absolute;
+.dj_ie6 .dijitTabContainerTopStrip, .dj_ie6 .dijitTabContainerBottomStrip {
+  position: absolute;
 }
 .dj_iequirks .claro .dijitTabContainerTopRtl .dijitTabContainerTopStrip {
-	padding-top: 10px;
+  padding-top: 10px;
 }
 .dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtlChecked .dijitTabInnerDiv {
-	background-position:-341px -179px;
+  background-position: -341px -179px;
 }
-
-.dj_ie6 .dijitTabContainerTopRtl .dijitTabStripIcon,
-.dj_ie6 .dijitTabContainerBottomRtl .dijitTabStripIcon {
-   position: relative;
+.dj_ie6 .dijitTabContainerTopRtl .dijitTabStripIcon, .dj_ie6 .dijitTabContainerBottomRtl .dijitTabStripIcon {
+  position: relative;
 }
-
-
-.dj_ie6-rtl .claro .dijitTabContainerTop-tabs {	
-	/* this strange rule prevents IE6 bug in themeTester.html?dir=rtl upon closing
+.dj_ie6-rtl .claro .dijitTabContainerTop-tabs {
+  /* this strange rule prevents IE6 bug in themeTester.html?dir=rtl upon closing
 	 * "Closable" tab, where the other tabs disappear
 	 */
-	padding-left: 3px;
-}
 
+  padding-left: 3px;
+}
 .dj_iequirks-rtl .claro .dijitTabListWrapper {
-	/* this strange rule prevents IE6 bug in themeTesterQuirk.html?dir=rtl upon closing
+  /* this strange rule prevents IE6 bug in themeTesterQuirk.html?dir=rtl upon closing
 	 * "Closable" tab, where the other tabs disappear
 	 */
-	border-left: 1px solid #fff;
-	border-right: 1px solid #fff;
+
+  border-left: 1px solid #ffffff;
+  border-right: 1px solid #ffffff;
 }
diff --git a/dijit/themes/claro/layout/TabContainer_rtl.less b/dijit/themes/claro/layout/TabContainer_rtl.less
new file mode 100644
index 0000000..eaada0d
--- /dev/null
+++ b/dijit/themes/claro/layout/TabContainer_rtl.less
@@ -0,0 +1,81 @@
+ at import "../variables";
+
+.claro .dijitTabContainerTop-tabs .dijitTabRtl,
+.claro .dijitTabContainerBottom-tabs .dijitTabRtl {
+	margin-right: 0;
+	margin-left: 1px;
+}
+.claro .dijitTabRtl {
+	-moz-box-orient:horizontal;
+	text-align: right;
+}
+.dj_ie7 .claro .dijitTabRtl .dijitTabContent {
+	display: block;
+	left: 0;
+}
+.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl,
+.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabCheckedRtl {
+	top: 1px;
+}
+
+// Note that .tabStripButtonRtl .dijitButtonContents needed for IE8 quirks but breaks IE6 quirks
+.dj_ie7 .claro .tabStripButtonRtl .dijitButtonContents,
+.dj_ie8 .claro .tabStripButtonRtl .dijitButtonContents,
+.dj_ie6 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
+.dj_ie6 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
+.dj_ie7 .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
+.dj_ie7 .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv,
+.dj_iequirks .claro .dijitTabContainerTop-tabs .dijitTabRtl .dijitTabInnerDiv,
+.dj_iequirks .claro .dijitTabContainerBottom-tabs .dijitTabRtl .dijitTabInnerDiv {
+	float:left;
+}
+.dj_ie6 .claro .dijitTabRtl .tabLabel,
+.dj_ie6 .claro .dijitTabContainerRight-tabs .dijitTabRtl,
+.dj_ie6 .claro .dijitTabContainerLeft-tabs .dijitTabRtl,
+.dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtl .dijitTabInnerDiv,
+.dj_ie7 .claro .dijitTabContainerLeft-tabs .dijitTabRtl .dijitTabInnerDiv {
+	/*Make the .tablabel have width in ie6 with haslayout property, fix Close icon position bug*/
+	zoom:1;
+}
+.dj_ie6 .claro .dijitTabRtl .dijitTabCloseButton,
+.dj_ie7 .claro .dijitTabRtl .dijitTabCloseButton,
+.dj_iequirks .claro .dijitTabRtl .dijitTabCloseButton {
+	margin-right:5px;
+}
+
+.dj_ie6 .claro .dijitTabContainerRightRtl .dijitTabContainerRight-tabs,
+.dj_ie6 .claro .dijitTabContainerLeftRtl .dijitTabContainerLeft-tabs {
+	width:1%;
+}
+
+.dj_ie6 .dijitTabContainerTopStrip,
+.dj_ie6 .dijitTabContainerBottomStrip {
+	position:absolute;
+}
+.dj_iequirks .claro .dijitTabContainerTopRtl .dijitTabContainerTopStrip {
+	padding-top: 10px;
+}
+.dj_ie7 .claro .dijitTabContainerRight-tabs .dijitTabRtlChecked .dijitTabInnerDiv {
+	background-position:-341px -179px;
+}
+
+.dj_ie6 .dijitTabContainerTopRtl .dijitTabStripIcon,
+.dj_ie6 .dijitTabContainerBottomRtl .dijitTabStripIcon {
+   position: relative;
+}
+
+
+.dj_ie6-rtl .claro .dijitTabContainerTop-tabs {	
+	/* this strange rule prevents IE6 bug in themeTester.html?dir=rtl upon closing
+	 * "Closable" tab, where the other tabs disappear
+	 */
+	padding-left: 3px;
+}
+
+.dj_iequirks-rtl .claro .dijitTabListWrapper {
+	/* this strange rule prevents IE6 bug in themeTesterQuirk.html?dir=rtl upon closing
+	 * "Closable" tab, where the other tabs disappear
+	 */
+	border-left: 1px solid @pane-background-color;
+	border-right: 1px solid @pane-background-color;
+}
diff --git a/dijit/themes/claro/layout/images/tabBottom.png b/dijit/themes/claro/layout/images/tabBottom.png
index bf23240..dbcfc85 100644
Binary files a/dijit/themes/claro/layout/images/tabBottom.png and b/dijit/themes/claro/layout/images/tabBottom.png differ
diff --git a/dijit/themes/claro/layout/images/tabTop.png b/dijit/themes/claro/layout/images/tabTop.png
index db7626e..2822487 100644
Binary files a/dijit/themes/claro/layout/images/tabTop.png and b/dijit/themes/claro/layout/images/tabTop.png differ
diff --git a/dijit/themes/claro/variables.less b/dijit/themes/claro/variables.less
new file mode 100644
index 0000000..8d09c25
--- /dev/null
+++ b/dijit/themes/claro/variables.less
@@ -0,0 +1,189 @@
+// 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 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 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 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 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 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.
+
+
+
+// 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)
+
+// 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 textbox-focused-background-color: @textbox-background-color;
+ at textbox-error-background-color: @textbox-background-color;
+ at textbox-disabled-background-color: @disabled-background-color;
+
+ 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
+
+// TabContainer
+ at nestedtab-hovered-background-color: @textbox-hovered-background-color;
+ at nestedtab-hovered-border-color: #cfe5fa;
+ at 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)
+
+// 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
+
+// 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
+
+// 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
+
+// Menus
+ at 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-date-pressed-background-color: @pressed-background-color;
+ at 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-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.
+
+// 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-value-hovered-text-color: @hovered-text-color;
+ at timepicker-arrow-hovered-background-color: #abd6ff;
+
+// ColorPalette
+ at colorpalette-background-color: #fff;
+ at swatch-border-color: @minor-border-color;
+ at swatch-hovered-border-color: #000;
+ at 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;
+
+// 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
+
+// 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-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-header-background-color: #f58383;		// Title bar for dragged items
+ at 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
+
+// Document level
+ at document-text-color: #131313;									// Text color for document itself (text outside of widgets)
+ at 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.
+
+// Mixins
+
+.border-radius (@radius) {
+	-moz-border-radius: @radius;
+	border-radius: @radius;
+}
+
+.box-shadow (@value) {
+	-webkit-box-shadow: @value;
+	-moz-box-shadow: @value;
+	box-shadow: @value;
+}
+
+.transition-property (@value) {
+	-webkit-transition-property: @value;
+	-moz-transition-property: @value;
+	transition-property: @value;
+}
+
+.transition-property (@value1, @value2) {
+	-webkit-transition-property: @value1, @value2;
+	-moz-transition-property: @value1, @value2;
+	transition-property: @value1, @value2;
+}
+
+.transition-duration (@value) {
+	-webkit-transition-duration: @value;
+	-moz-transition-duration: @value;
+	transition-duration: @value;
+}
+
+.transition-duration (@value1, @value2) {
+	-webkit-transition-duration: @value1, @value2;
+	-moz-transition-duration: @value1, @value2;
+	transition-duration: @value1, @value2;
+}
+
+.transition-timing-function (@value) {
+	-webkit-transition-timing-function: @value;
+	-moz-transition-timing-function: @value;
+	transition-timing-function: @value;
+}
diff --git a/dijit/themes/dijit.css b/dijit/themes/dijit.css
index 450380a..b6d57dc 100644
--- a/dijit/themes/dijit.css
+++ b/dijit/themes/dijit.css
@@ -55,7 +55,9 @@
 	#zoom: 1;
 	overflow: hidden;
 	float: none !important; /* needed by FF to squeeze the INPUT in */
-	position:relative;
+	position: relative;
+	vertical-align: middle;
+	#display: inline;
 }
 
 .dj_ie INPUT.dijitTextBox,
@@ -94,7 +96,6 @@
 
 .dijitOffScreen {
 	position: absolute;
-	visibility: hidden;
 	left: 50%;
 	top: -10000px;
 }
@@ -110,12 +111,6 @@
 	border: 0;
 	padding: 0;
 }
-.dijit_a11y .dijitPopup,
-.dijit_ally .dijitPopup DIV,
-.dijit_a11y .dijitPopup TABLE,
-.dijit_a11y .dijitTooltipContainer {
-	background-color: white !important;
-}
 
 .dijitPositionOnly {
 	/* Null out all position-related properties */
@@ -161,15 +156,13 @@
 /****
 		A11Y
  ****/
-.dijit_a11y * {
-	background-image:none !important;
-}
 .dijit_a11y .dijitIcon,
 .dijit_a11y DIV.dijitArrowButtonInner, /* is this only for Spinner?  if so, it should be deleted */
 .dijit_a11y SPAN.dijitArrowButtonInner,
 .dijit_a11y IMG.dijitArrowButtonInner,
-.dijit_a11y .dijitCalendarIncrementControl {
-	/* hide icon nodes in high contrast mode; when necesary they will be replaced by character equivalents
+.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 */
 	display: none;
 }
@@ -194,20 +187,18 @@
 .dijit_a11y .dijitCalendarSelectedDate .dijitCalendarDateLabel {
 	border-style: dotted !important;
 	border-width: 1px;
-	padding: 0px;
+	padding: 0;
 }
 .dijit_a11y .dijitCalendarDateTemplate {
 	padding-bottom: 0.1em !important;	/* otherwise bottom border doesn't appear on IE */
 }
-
-.dijit_a11y .dijit * {
-	background:white !important;
-	color:black !important;
-}
 .dijit_a11y .dijitButtonNode {
-	border-color: black!important;
-	border-style: outset!important;
-	border-width: medium!important;
+	border: black outset medium !important;
+
+	/* In claro, hovering a toolbar button reduces padding and adds a border.
+	 * Not needed in a11y mode since Toolbar buttons always have a border.
+	 */
+	padding: 0 !important;
 }
 
 .dijit_a11y .dijitTextBoxReadOnly .dijitInputField,
@@ -262,6 +253,7 @@
 .dijitComboButton {
 	/* outside of button */
 	margin: 0.2em;
+	vertical-align: middle;
 }
 
 .dijitButtonContents {
@@ -277,13 +269,6 @@ td.dijitButtonContents {
 	/*margin-bottom:.2em;*/
 }
 
-TABLE.dijitComboButton { /* TODO: why not add dijitReset class to ComboButton? */
-	/* In ComboButton, borders are on each cell rather than on <table> itself */
-	border-collapse: collapse;
-	border:0;
-	padding:0;
-	margin:0;
-}
 .dijitToolbar .dijitComboButton {
 	/* because Toolbar only draws a border around the hovered thing */
 	border-collapse: separate;
@@ -301,10 +286,6 @@ TABLE.dijitComboButton { /* TODO: why not add dijitReset class to ComboButton? *
 	padding: 1px 2px;
 }
 
-.dj_ie .dijitComboButton {
-	/* hack to get inline-table to vertically align w/other buttons */
-	margin-bottom: -3px;
-}
 
 .dj_webkit .dijitToolbar .dijitDropDownButton {
 	padding-left: 0.3em;
@@ -364,7 +345,6 @@ DIV.dijitArrowButton {
 	#overflow: hidden; /* #6027, #6067 */
 	width: 15em;	/* need to set default size on outer node since inner nodes say <input style="width:100%"> and <td width=100%>.  user can override */
 	vertical-align: middle;
-	#vertical-align: auto;
 }
 
 .dijitTextBoxReadOnly,
@@ -377,7 +357,7 @@ DIV.dijitArrowButton {
 .dj_webkit TEXTAREA.dijitTextAreaDisabled {
 	color: #333; /* because WebKit lightens disabled input/textarea no matter what color you specify */
 }
-.dj_gecko .dijitTextBoxReadOnly 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 */
 }
@@ -472,6 +452,15 @@ DIV.dijitArrowButton {
 	/* dividing line between input area and up/down button(s) for ComboBox and Spinner */
 	border-width: 0 0 0 1px !important; /* !important needed due to wayward ".theme .dijitButtonNode" rules */
 }
+.dijitToolbar .dijitComboBox .dijitArrowButtonContainer {
+	/* overrides above rule plus mirror-image rule in dijit_rtl.css to have no divider when ComboBox in Toolbar */
+	border-width: 0 !important;
+}
+
+.dijitComboBoxMenu {
+	/* Drop down menu is implemented as <ul> <li/> <li/> ... but we don't want circles before each item */
+	list-style-type: none;
+}
 .dijitSpinner .dijitSpinnerButtonContainer .dijitButtonNode {
 	/* dividing line between input area and up/down button(s) for ComboBox and Spinner */
 	border-width: 0;
@@ -479,16 +468,9 @@ DIV.dijitArrowButton {
 .dj_ie .dijit_a11y .dijitSpinner .dijitSpinnerButtonContainer .dijitButtonNode {
 	clear: both; /* IE workaround */
 }
-.dijit_a11y .dijitTextBox .dijitValidationContainer,
-.dijit_a11y .dijitTextBox .dijitSpinnerButtonContainer,
-.dijit_a11y .dijitComboBox .dijitArrowButtonContainer {
-	/* dividing line between input area and up/down button(s) for ComboBox and Spinner */
-	border: solid black !important;
-	border-width: 0 0 0 1px !important;
-}
 
 .dj_ie .dijitToolbar .dijitComboBox {
-	/* make combobox buttons align porperly with other buttons in a toolbar */
+	/* make combobox buttons align properly with other buttons in a toolbar */
 	vertical-align: middle;
 }
 
@@ -527,8 +509,8 @@ DIV.dijitArrowButton {
 	width: 1.4em !important;
 }
 .dj_ie7 .dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
-	padding-left: 0.0em !important; /* manually center INPUT: character is .5em and total width = 1em */
-	padding-right: 0.0em !important;
+	padding-left: 0 !important; /* manually center INPUT: character is .5em and total width = 1em */
+	padding-right: 0 !important;
 	width: 1em !important;
 }
 .dj_ie6 .dijit_a11y .dijitSpinner .dijitArrowButtonInner .dijitInputField {
@@ -616,7 +598,7 @@ DIV.dijitArrowButton {
 	width: 1em;
 }
 .dijit_a11y .dijitSpinnerButtonContainer .dijitButtonNode {
-	border-width: 1px 0px 0px 0px;
+	border-width: 1px 0 0 0;
 	border-style: solid !important;
 }
 
@@ -721,10 +703,6 @@ DIV.dijitArrowButton {
 	height:1.6em;
 }
 
-.dijitProgressBarIndeterminate .dijitProgressBarLabel {
-	visibility:hidden;
-}
-
 .dijitProgressBarIndeterminate .dijitProgressBarTile {
 	/* animated gif for 'indeterminate' mode */
 }
@@ -761,7 +739,7 @@ DIV.dijitArrowButton {
 	z-index: 2000;
 	display: block;
 	/* make visible but off screen */
-	left: 50%;
+	left: 0;
 	top: -10000px;
 	overflow: visible;
 }
@@ -978,8 +956,8 @@ body .dijitAlignClient { position: absolute; }
 .dijitTitlePaneTitle {
 	cursor: pointer;
 }
-.dijitFixedOpen {
-	/* TitlePane that cannot be closed */
+.dijitFixedOpen, .dijitFixedClosed {
+	/* TitlePane that cannot be toggled */
 	cursor: default;
 }
 .dijitTitlePaneTitle * {
@@ -1016,13 +994,6 @@ body .dijitAlignClient { position: absolute; }
 	position: relative;
 }
 
-img.dijitColorPaletteUnder {
-	/* This single image contains the "icons" for every color in the color palette, and sits behind the transparent <table> */
-	border-style: none;
-	position: absolute;
-	left: 0;
-	top: 0;
-}
 .dijitColorPalette .dijitPaletteTable {
 	/* Table that holds the palette cells, and overlays image file with color swatches.
 	 * padding/margin to align table with image.
@@ -1044,28 +1015,30 @@ img.dijitColorPaletteUnder {
 }
 
 .dijitColorPalette .dijitPaletteCell {
-	/* <td> in the <table>, matching size of color swatches embedded in the img.dijitColorPaletteUnder */
-	height: 20px;
-	width: 20px;
+	/* <td> in the <table> */
 	font-size: 1px;
 	vertical-align: middle;
 	text-align: center;
+	background: none;
 }
 .dijitColorPalette .dijitPaletteImg {
-	/* transparent (but clickable) <img> node inside of each <td>, overlaying the color swatch.
-	 * displays border around a color swatch
-	 */
-	width: 16px;
-	height: 14px;
+	/* Called dijitPaletteImg for back-compat, this actually wraps the color swatch with a border and padding */
+	padding: 1px;		/* white area between gray border and color swatch */
 	border: 1px solid #999;
+	margin: 2px 1px;
 	cursor: default;
-	vertical-align: middle;
+	font-size: 1px;		/* prevent <span> from getting bigger just to hold a character */
 }
-.dj_iequirks .dijitColorPalette .dijitPaletteImg {
-	margin: 1px;	/* needed to fix spacing for ColorPalette in TooltipDialog on IE/quirks */
+.dj_gecko .dijitColorPalette .dijitPaletteImg {
+	padding-bottom: 0;	/* workaround rendering glitch on FF, it adds an extra pixel at the bottom */
+}
+.dijitColorPalette .dijitColorPaletteSwatch {
+	/* the actual part where the color is */
+	width: 14px;
+	height: 12px;
 }
 .dijitPaletteTable td {
-		padding: 0px;
+		padding: 0;
 }
 .dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
 	/* hovered color swatch */
@@ -1075,6 +1048,7 @@ img.dijitColorPaletteUnder {
 .dijitColorPalette .dijitPaletteCellActive .dijitPaletteImg,
 .dijitColorPalette .dijitPaletteCellSelected .dijitPaletteImg {
 	border: 2px solid #000;
+	margin: 1px 0;	/* reduce margin to compensate for increased border */
 }
 
 
@@ -1083,14 +1057,6 @@ img.dijitColorPaletteUnder {
 	/* table cells are to catch events, but the swatches are in the PaletteImg behind the table */
 	background-color: transparent !important;
 }
-.dj_gecko .dijit_a11y .dijitColorPalette .dijitPaletteCellFocused .dijitPaletteImg {
-	border: 3px dotted #000;	/* focus border on table cells broken in FF high contrast :-( */
-	margin: -1px;
-}
-
-.dijit_a11y  .dijitColorPalette .dijitPaletteCellHover .dijitPaletteImg {
-	border: 2px solid #000 !important;
-}
 
 /* AccordionContainer */
 
@@ -1122,12 +1088,9 @@ img.dijitColorPaletteUnder {
 	display: none;
 }
 
-.dj_ie6 .dijitAccordionTitle,
-.dj_iequirks .dijitAccordionTitle {
-	/* avoid IE6/IE quirks size calc bug where accordion ends up too short (themeTesterQuirk.html)
-	 * and IE6 bug where the first title bar turns white upon hovering any title bar
-	 */
-	zoom: 1;
+.dijitAccordionChildWrapper {
+	/* this is the node whose height is adjusted */
+	overflow: hidden;
 }
 
 /* Calendar */
@@ -1137,6 +1100,7 @@ img.dijitColorPaletteUnder {
 }
 .dijitCalendarContainer th, .dijitCalendarContainer td {
 	padding: 0;
+	vertical-align: middle;
 }
 
 .dijitCalendarNextYear {
@@ -1173,6 +1137,11 @@ img.dijitColorPaletteUnder {
   	visibility: hidden;
 }
 
+/* Styling for month drop down list */
+
+.dijitCalendarMonthMenu .dijitCalendarMonthLabel {
+	text-align:center;
+}
 
 /* Menu */
 
@@ -1291,7 +1260,7 @@ img.dijitColorPaletteUnder {
 }
 .dj_ie .dijit_a11y .dijitMenuBar .dijitMenuItem {
 	/* so bottom border of MenuBar appears on IE7 in high-contrast mode */
-	margin: 0px;
+	margin: 0;
 }
 
 /* StackContainer */
@@ -1339,7 +1308,7 @@ img.dijitColorPaletteUnder {
 	border-bottom: 1px solid black;
 }
 .dijitTabContainerTop-container {
-	border-top: 0px;
+	border-top: 0;
 }
 
 .dijitTabContainerLeft-tabs {
@@ -1347,14 +1316,14 @@ img.dijitColorPaletteUnder {
 	float: left;
 }
 .dijitTabContainerLeft-container {
-	border-left: 0px;
+	border-left: 0;
 }
 
 .dijitTabContainerBottom-tabs {
 	border-top: 1px solid black;
 }
 .dijitTabContainerBottom-container {
-	border-bottom: 0px;
+	border-bottom: 0;
 }
 
 .dijitTabContainerRight-tabs {
@@ -1362,7 +1331,7 @@ img.dijitColorPaletteUnder {
 	float: left;
 }
 .dijitTabContainerRight-container {
-	border-right: 0px;
+	border-right: 0;
 }
 
 DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
@@ -1427,31 +1396,36 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 	display:none;
 }
 
+.dijitTab .tabLabel {
+	/* make sure tabs w/close button and w/out close button are same height, even w/small (<15px) font.
+	 * assumes <=15px height for close button icon.
+	 */
+	min-height: 15px;
+	display: inline-block;
+}
+.dijitNoIcon {
+	/* applied to <img>/<span> node when there is no icon specified */
+	display: none;
+}
+.dj_ie6 .dijitTab .dijitNoIcon {
+	/* because min-height (on .tabLabel, above) doesn't work on IE6 */
+	display: inline;
+	height: 15px;
+	width: 1px;
+}
+
 /* images off, high-contrast mode styles */
 
 .dijit_a11y .dijitTabCloseButton {
 	background-image: none !important;
 	width: auto !important;
 	height: auto !important;
-	border: thin dotted;	/* non-hover state */
-}
-.dijit_a11y .dijitTabCloseButtonHover {
-	border:thin solid;	/* hover state */
 }
 
 .dijit_a11y .dijitTabCloseText {
 	display: inline;
 }
 
-.dijit_a11y .dijitTabChecked {
-	/* the selected tab */
-	border-style:dashed !important;
-}
-
-.dijit_a11y .dijitTabInnerDiv {
-	border-left:none !important;
- }
-
 .dijitTabPane,
 .dijitStackContainer-child,
 .dijitAccordionContainer-child {
@@ -1486,6 +1460,9 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 }
 
 /* Tree */
+.dijitTree {
+	overflow: auto;	/* for scrollbars when Tree has a height setting, and to prevent wrapping around float elements, see #11491 */
+}
 
 .dijitTreeIndent {
 	/* amount to indent each tree node (relative to parent node) */
@@ -1520,7 +1497,7 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 }
 
 .dijitTreeLabel {
-	margin: 0px 4px;
+	margin: 0 4px;
 }
 
 /* Dialog */
@@ -1661,14 +1638,14 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 
 .dijitSliderProgressBarV {
 	position:static !important;
-	height:0%;
+	height:0;
 	vertical-align:top;
 	text-align:left;
 }
 
 .dijitSliderProgressBarH {
 	position:absolute !important;
-	width:0%;
+	width:0;
 	vertical-align:middle;
 	overflow:visible;
 }
@@ -1719,7 +1696,9 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 .dijitSliderDecoration {
 	text-align:center;
 }
-.dijitSliderV TD {
+
+.dijitSliderDecorationC,
+.dijitSliderDecorationV {
 	position: relative; /* needed for IE+quirks+RTL+vertical (rendering bug) but add everywhere for custom styling consistency but this messes up IE horizontal sliders */
 }
 
@@ -1843,7 +1822,7 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 	line-height: 1em;
 	height: auto;
 	width: auto;
-	margin: 0px 4px;
+	margin: 0 4px;
 }
 
 /* Icon-only buttons (often in toolbars) still display the text in high-contrast mode */
@@ -1864,6 +1843,12 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 	width:auto;
 }
 
+.dijitExpandingTextArea {
+	/* for auto exanding textarea (called Textarea currently, rename for 2.0) don't want to display the grip to resize */
+	resize: none;
+}
+
+
 /* Toolbar
  * Note that other toolbar rules (for objects in toolbars) are scattered throughout this file.
  */
@@ -1990,7 +1975,7 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 	color:#999 !important;
 }
 .dijitSelect .dijitButtonContents {
-	padding: 0px;
+	padding: 0;
 	background: transparent none;
 	white-space: nowrap;
 	text-align: left;
@@ -2028,7 +2013,7 @@ DIV.dijitTabDisabled, .dj_ie DIV.dijitTabDisabled {
 /* Style the different areas of the button to look like a "real" dropdown */
 /* Remove margins on the sub-table */
 .dijitSelectMenu .dijitMenuTable {
-	margin: 0px;
+	margin: 0;
 	background-color: transparent;
 }
 
diff --git a/dijit/themes/dijit_rtl.css b/dijit/themes/dijit_rtl.css
index f777b4c..8ef3a28 100644
--- a/dijit/themes/dijit_rtl.css
+++ b/dijit/themes/dijit_rtl.css
@@ -18,20 +18,12 @@
 
 /* TextBox, ComboBox, Spinner */
 
-.dijit_a11y .dijitTextBoxRtl .dijitValidationContainer,
+.dijitTextBoxRtl .dijitValidationContainer,
 .dijitTextBoxRtl .dijitSpinnerButtonContainer,
 .dijitComboBoxRtl .dijitArrowButtonContainer {
 	/* combobox and spinner: line between the input area and the drop down button */
 	border-right-width: 1px !important;
-	border-right-style: solid !important;
-	border-left-width: 0px !important;
-	border-left-style: none !important;
-}
-.dijit_a11y .dijitTextBoxRtl .dijitValidationContainer,
-.dijit_a11y .dijitTextBoxRtl .dijitSpinnerButtonContainer,
-.dijit_a11y .dijitComboBoxRtl .dijitArrowButtonContainer {
-	border-right: 1px solid black !important;
-	border-left: 0px none black !important;
+	border-left-width: 0 !important;
 }
 
 .dijitSpinnerRtl .dijitSpinnerButtonContainer .dijitArrowButton {
@@ -103,7 +95,7 @@
 /* TabContainer */
 
 .dijitTabRtl .dijitTabCloseButton {
-	margin-left: 0px;
+	margin-left: 0;
 	margin-right: 1em;
 }
 
diff --git a/dijit/themes/nihilo/Calendar.css b/dijit/themes/nihilo/Calendar.css
index 81f3f71..2c9248b 100644
--- a/dijit/themes/nihilo/Calendar.css
+++ b/dijit/themes/nihilo/Calendar.css
@@ -41,7 +41,6 @@
 .dj_ie6 .nihilo .dijitCalendarMonthContainer th {
 	padding-top:.2em;
 	padding-bottom:.1em;
-
 }
 
 .nihilo .dijitCalendarDayLabelTemplate {
@@ -62,6 +61,7 @@
 .nihilo .dijitCalendarMonthLabel {
 	color:#293a4b;
 	font-weight: bold;
+	padding: 0 4px;
 }
 
 .nihilo .dijitCalendarDateTemplate {
@@ -135,4 +135,25 @@
 	/* label for next/prev years */
 	color:black !important;
 	font-weight:normal;
+}
+
+/* Styling for month DropDownButton */
+
+.nihilo .dijitCalendar .dijitDropDownButton {
+	margin: 0;
+}
+.nihilo .dijitCalendar .dijitButtonText {
+	padding: 0;
+}
+.nihilo .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+	background-color: transparent;
+	background-image: none;
+	padding: 0;
+}
+
+/* Styling for month drop down list */
+
+.nihilo .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+	background-color: #ffe284;
+	color: #243C5F;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/Calendar_rtl.css b/dijit/themes/nihilo/Calendar_rtl.css
index 7b29bac..6fc06f4 100644
--- a/dijit/themes/nihilo/Calendar_rtl.css
+++ b/dijit/themes/nihilo/Calendar_rtl.css
@@ -5,5 +5,5 @@
 }
 
 .dijitRtl .nihilo .dijitCalendarIncrease {
-	background-position: 0px top;
+	background-position: 0 top;
 }
diff --git a/dijit/themes/nihilo/ColorPalette.css b/dijit/themes/nihilo/ColorPalette.css
index 59a4689..8fbe9d7 100644
--- a/dijit/themes/nihilo/ColorPalette.css
+++ b/dijit/themes/nihilo/ColorPalette.css
@@ -1,5 +1,5 @@
 .dijitColorPalette {
 	border:1px solid #d3d3d3;
 	background:#fff;
-	-moz-border-radius: 0px !important;
+	-moz-border-radius: 0 !important;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/Dialog.css b/dijit/themes/nihilo/Dialog.css
index 64fbaf0..4affeb8 100644
--- a/dijit/themes/nihilo/Dialog.css
+++ b/dijit/themes/nihilo/Dialog.css
@@ -3,16 +3,16 @@
 .nihilo .dijitDialog {
 	background: #eee;
 	border: 1px solid #d3d3d3;
-	-webkit-box-shadow: 0px 5px 10px #adadad;
-	padding: 0px;
+	-webkit-box-shadow: 0 5px 10px #adadad;
+	padding: 0;
 }
 
 .nihilo .dijitDialog .dijitDialogTitle {
 	/* typography and styling of the dialog title */
 	font-size: 0.9em;
-	color: #3243C5F;
+	color: #243C5F;
 	font-weight: bold;
-	padding: 0px 4px;
+	padding: 0 4px;
 }
 
 .nihilo .dijitDialog .dijitDialogPaneContent {
@@ -33,7 +33,7 @@
 	/* the default close icon for the dialog */
 	background-image: url("images/spriteRoundedIconsSmall.png");
 	background-repeat: no-repeat;
-	background-position: -60px 0px;
+	background-position: -60px 0;
 	position: absolute;
 	vertical-align: middle;
 	right: 6px;
@@ -83,7 +83,7 @@
 
 .nihilo .dijitTooltipConnector {
 	/* the arrow piece */
-	border:0px;
+	border:0;
 	z-index: 2;
 }
 
@@ -96,7 +96,7 @@
 
 .nihilo .dijitTooltipBelow .dijitTooltipConnector {
 	/* the arrow piece for tooltips below an element */
-	top: 0px;
+	top: 0;
 	left: 6px;
 	background:url("images/tooltipConnectorUp.png") no-repeat top left;
 	width:17px;
@@ -109,7 +109,7 @@
 
 .nihilo .dijitTooltipAbove .dijitTooltipConnector {
 	/* the arrow piece for tooltips above an element */
-	bottom: 0px;
+	bottom: 0;
 	left: 6px;
 	background:url("images/tooltipConnectorDown.png") no-repeat top left;
 	width:17px;
@@ -125,13 +125,9 @@
 .nihilo .dijitTooltipLeft {
 	padding-right: 10px;
 }
-.dj_ie6 .nihilo .dijitTooltipLeft {
-	padding-left: 11px;
-}
 .nihilo .dijitTooltipLeft .dijitTooltipConnector {
 	/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
-	right: 0px;
-	bottom: 3px;
+	right: 0;
 	background:url("images/tooltipConnectorRight.png") no-repeat top left;
 	width:11px;
 	height:17px;
@@ -145,8 +141,7 @@
 }
 .nihilo .dijitTooltipRight .dijitTooltipConnector {
 	/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
-	left: 0px;
-	bottom: 3px;
+	left: 0;
 	background:url("images/tooltipConnectorLeft.png") no-repeat top left;
 	width:11px;
 	height:17px;
diff --git a/dijit/themes/nihilo/Menu.css b/dijit/themes/nihilo/Menu.css
index 6d128ab..cad4698 100644
--- a/dijit/themes/nihilo/Menu.css
+++ b/dijit/themes/nihilo/Menu.css
@@ -3,8 +3,8 @@
 .nihilo .dijitMenu,
 .nihilo .dijitMenuBar {
 	border: 1px solid #d3d3d3;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	background-color: #fff;
 }
 
@@ -14,7 +14,7 @@
 
 .nihilo .dijitMenuItem {
 	font-family: sans-serif;
-	margin: 0px;
+	margin: 0;
 	color: #243C5F;
 }
 .nihilo .dijitMenuBar .dijitMenuItem {
@@ -53,7 +53,7 @@
 	height: 1px;
 }
 
-/* separator can be two pixels -- set border of either one to 0px to have only one */
+/* separator can be two pixels -- set border of either one to 0 to have only one */
 .nihilo .dijitMenuSeparatorTop {
 	border-bottom: 1px solid #fff; /*97adcb; */
 }
diff --git a/dijit/themes/nihilo/Menu_rtl.css b/dijit/themes/nihilo/Menu_rtl.css
index f07fbd6..40b3b41 100644
--- a/dijit/themes/nihilo/Menu_rtl.css
+++ b/dijit/themes/nihilo/Menu_rtl.css
@@ -2,9 +2,9 @@
 
 .dijitRtl .nihilo .dijitMenuItem .dijitMenuItemIcon {
 	padding-left: 3px;
-	padding-right: 0px;
+	padding-right: 0;
 }
 
 .dijitRtl .nihilo .dijitMenuItem .dijitMenuExpand {
-	background-position: 0px top;
+	background-position: 0 top;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/ProgressBar.css b/dijit/themes/nihilo/ProgressBar.css
index aaa49ea..6c50a7e 100644
--- a/dijit/themes/nihilo/ProgressBar.css
+++ b/dijit/themes/nihilo/ProgressBar.css
@@ -4,7 +4,7 @@
  ****/
 
 .nihilo .dijitProgressBar {
-	margin:2px 0px 2px 0px;
+	margin:2px 0 2px 0;
 }
 
 .nihilo .dijitProgressBarEmpty{
diff --git a/dijit/themes/nihilo/TimePicker_rtl.css b/dijit/themes/nihilo/TimePicker_rtl.css
index 377f738..50848c3 100644
--- a/dijit/themes/nihilo/TimePicker_rtl.css
+++ b/dijit/themes/nihilo/TimePicker_rtl.css
@@ -1,4 +1,4 @@
 .dj_ie6-rtl .nihilo .dijitTimePickerMarkerHover,
 .dj_ie7-rtl .nihilo .dijitTimePickerMarkerHover {
-        border-top: 0px; /* IE6/7 bug causes mouseover/out event storm */
+        border-top: 0; /* IE6/7 bug causes mouseover/out event storm */
 }
diff --git a/dijit/themes/nihilo/TitlePane.css b/dijit/themes/nihilo/TitlePane.css
index ae5b452..6d16ff9 100644
--- a/dijit/themes/nihilo/TitlePane.css
+++ b/dijit/themes/nihilo/TitlePane.css
@@ -42,7 +42,7 @@
 .nihilo .dijitTitlePaneContentOuter {
 	background: #ffffff;
 	border:1px solid #bfbfbf;
-	border-top: 0px;
+	border-top: 0;
 }
 .nihilo .dijitTitlePaneContentInner {
 	padding:10px;
diff --git a/dijit/themes/nihilo/TitlePane_rtl.css b/dijit/themes/nihilo/TitlePane_rtl.css
index 50a5d43..7b3ba21 100644
--- a/dijit/themes/nihilo/TitlePane_rtl.css
+++ b/dijit/themes/nihilo/TitlePane_rtl.css
@@ -1,6 +1,6 @@
 .dijitRtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: 0px top;
+	background-position: 0 top;
 }
 .dj_ie6-rtl .nihilo .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: 0px top;
+	background-position: 0 top;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/Toolbar.css b/dijit/themes/nihilo/Toolbar.css
index 5b4cd12..1c3e327 100644
--- a/dijit/themes/nihilo/Toolbar.css
+++ b/dijit/themes/nihilo/Toolbar.css
@@ -12,8 +12,8 @@
 .nihilo .dijitToolbar .dijitComboButton .dijitButtonContents,
 .nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButton {
 	background: none;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	border: none;
 	font-size: 12px;
 }
@@ -61,5 +61,5 @@
 .dj_ie .nihilo .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
 	/* focus border doesn't appear on <td> for IE, so need to add it manually */
 	border: 1px #555 dotted !important;
-	padding: 0px;
+	padding: 0;
 }
\ No newline at end of file
diff --git a/dijit/themes/nihilo/Tree.css b/dijit/themes/nihilo/Tree.css
index f71b653..a33b969 100644
--- a/dijit/themes/nihilo/Tree.css
+++ b/dijit/themes/nihilo/Tree.css
@@ -4,7 +4,7 @@
     background : url('images/treeI.gif') no-repeat;
     background-position : top left;
     background-repeat : repeat-y;
-    zoom: 1;	/* MOW: what the heck is this doing in here? */
+    zoom: 1;
 }
 
 /* left vertical line (grid) for all nodes */
diff --git a/dijit/themes/nihilo/Tree_rtl.css b/dijit/themes/nihilo/Tree_rtl.css
index ecf3207..4462ed1 100644
--- a/dijit/themes/nihilo/Tree_rtl.css
+++ b/dijit/themes/nihilo/Tree_rtl.css
@@ -7,7 +7,7 @@
 }
 
 .dijitRtl .nihilo .dijitTreeContent {
-    padding-left: 0px;
+    padding-left: 0;
     padding-right: 1px;
 }
 
diff --git a/dijit/themes/nihilo/form/Button.css b/dijit/themes/nihilo/form/Button.css
index 934705e..0be9ea4 100644
--- a/dijit/themes/nihilo/form/Button.css
+++ b/dijit/themes/nihilo/form/Button.css
@@ -26,7 +26,7 @@
 }
 
 .nihilo .dijitComboBox .dijitButtonNode {
-	border-width: 0px 0px 0px 1px;
+	border-width: 0 0 0 1px;
 }
 
 .nihilo .dijitArrowButton {
@@ -92,7 +92,7 @@
 .nihilo .dijitArrowButtonInner {
 	background-image: url("../images/spriteArrows.png");
 	background-repeat: no-repeat;
-	background-position: 0px center;
+	background-position: 0 center;
 	width: 11px;
 	height: 11px;
 }
diff --git a/dijit/themes/nihilo/form/Button_rtl.css b/dijit/themes/nihilo/form/Button_rtl.css
index f856feb..60d4c4d 100644
--- a/dijit/themes/nihilo/form/Button_rtl.css
+++ b/dijit/themes/nihilo/form/Button_rtl.css
@@ -1,5 +1,5 @@
 .dijitRtl .nihilo .dijitComboBox .dijitButtonNode {
-	border-width: 0px 0px 0px 1px;
+	border-width: 0 0 0 1px;
 }
 .dijitRtl .nihilo .dijitSelect .dijitButtonContents {
 	border-left: none;
diff --git a/dijit/themes/nihilo/form/Checkbox.css b/dijit/themes/nihilo/form/Checkbox.css
index b35ebf3..260666f 100644
--- a/dijit/themes/nihilo/form/Checkbox.css
+++ b/dijit/themes/nihilo/form/Checkbox.css
@@ -43,7 +43,7 @@
 .nihilo .dijitCheckBoxChecked,
 .nihilo .dijitToggleButtonChecked .dijitCheckBoxIcon {
 	/* checked */
-	background-position: 0px;
+	background-position: 0;
 }
 
 .nihilo .dijitCheckBoxDisabled {
diff --git a/dijit/themes/nihilo/form/Common.css b/dijit/themes/nihilo/form/Common.css
index da77b3b..65dddc6 100644
--- a/dijit/themes/nihilo/form/Common.css
+++ b/dijit/themes/nihilo/form/Common.css
@@ -12,7 +12,7 @@
 
 .nihilo .dijitInputContainer INPUT,
 .nihilo .dijitTextBox {
-	margin: 0em 0.1em;
+	margin: 0 0.1em;
 }
 
 .nihilo .dijitTextBox,
diff --git a/dijit/themes/nihilo/form/RadioButton.css b/dijit/themes/nihilo/form/RadioButton.css
index 258f26d..d0dba30 100644
--- a/dijit/themes/nihilo/form/RadioButton.css
+++ b/dijit/themes/nihilo/form/RadioButton.css
@@ -42,7 +42,7 @@
 .nihilo .dijitRadioChecked,
 .nihilo .dijitToggleButtonChecked .dijitRadioIcon {
 	/* selected */
-	background-position: 0px;
+	background-position: 0;
 }
 
 .nihilo .dijitRadioDisabled {
diff --git a/dijit/themes/nihilo/form/Select.css b/dijit/themes/nihilo/form/Select.css
index 2d32ec3..61967e5 100644
--- a/dijit/themes/nihilo/form/Select.css
+++ b/dijit/themes/nihilo/form/Select.css
@@ -1,5 +1,5 @@
 .nihilo .dijitSelect .dijitButtonNode {
-	padding: 0px;
+	padding: 0;
 }
 
 /* Make unselected "look" more like a text box and less like a button */
@@ -16,11 +16,11 @@
 	background: transparent none;
 }
 .dj_ie .nihilo .dijitSelect .dijitButtonContents {
-	padding-top: 0px;
+	padding-top: 0;
 }
 
 .nihilo .dijitSelect .dijitArrowButton {
-	padding: 0px 2px;
+	padding: 0 2px;
 }
 
 /* Mirror DropDownButton */
@@ -45,7 +45,7 @@
 
 /* Make the menu look more combobox-like */
 .nihilo .dijitSelectMenu td {
-	padding: 0em;
+	padding: 0;
 }
 .nihilo .dijitSelectMenu .dijitMenuItemLabel,
 .nihilo .dijitSelectMenu .dijitMenuArrowCell {
diff --git a/dijit/themes/nihilo/form/Slider.css b/dijit/themes/nihilo/form/Slider.css
index d2db2ef..16bcd09 100644
--- a/dijit/themes/nihilo/form/Slider.css
+++ b/dijit/themes/nihilo/form/Slider.css
@@ -43,7 +43,7 @@
 }
 
 .nihilo .dijitSliderImageHandleH {
-	border:0px;
+	border:0;
 	width:15px;
 	height:18px;
 	background:url("../images/preciseSliderThumb.png") no-repeat center top;
@@ -67,7 +67,7 @@
 }
 
 .nihilo .dijitSliderImageHandleV {
-	border:0px;
+	border:0;
 	width:20px;
 	height:15px;
 	background:url("../images/sliderThumb.png") no-repeat center center;
@@ -110,8 +110,8 @@
 	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
 }
 .nihilo .dijitSliderDecrementIconH {
-	background:url('../images/spriteRoundedIconsSmall.png') no-repeat 0px top;
-	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat 0px top;
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat 0 top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat 0 top;
 }
 
 .nihilo .dijitSliderButtonInner {
@@ -125,7 +125,7 @@
 }
 .nihilo .dijitSliderReadOnly .dijitSliderDecrementIconH,
 .nihilo .dijitSliderDisabled .dijitSliderDecrementIconH {
-	background-position: 0px -15px;
+	background-position: 0 -15px;
 }
 .nihilo .dijitSliderReadOnly .dijitSliderIncrementIconH,
 .nihilo .dijitSliderDisabled .dijitSliderIncrementIconH {
diff --git a/dijit/themes/nihilo/form/Slider_rtl.css b/dijit/themes/nihilo/form/Slider_rtl.css
index 8410f36..1523d4a 100644
--- a/dijit/themes/nihilo/form/Slider_rtl.css
+++ b/dijit/themes/nihilo/form/Slider_rtl.css
@@ -16,13 +16,13 @@
 }
 
 .dijitRtl .nihilo .dijitSliderLeftBumper {
-	border-left-width: 0px;
+	border-left-width: 0;
 	border-right-width: 1px;
 }
 
 .dijitRtl .nihilo .dijitSliderRightBumper {
 	border-left-width: 1px;
-	border-right-width: 0px;
+	border-right-width: 0;
 }
 
 .dijitRtl .nihilo .dijitSliderIncrementIconH {
diff --git a/dijit/themes/nihilo/layout/AccordionContainer_rtl.css b/dijit/themes/nihilo/layout/AccordionContainer_rtl.css
index 760f783..f669a47 100644
--- a/dijit/themes/nihilo/layout/AccordionContainer_rtl.css
+++ b/dijit/themes/nihilo/layout/AccordionContainer_rtl.css
@@ -1,5 +1,5 @@
 .dijitRtl .nihilo .dijitAccordionArrow {
-	background-position: 0px top;
+	background-position: 0 top;
 }
 
 .dijitRtl .nihilo .dijitAccordionTitleSelected .dijitAccordionArrow {
diff --git a/dijit/themes/nihilo/layout/BorderContainer.css b/dijit/themes/nihilo/layout/BorderContainer.css
index 1e876f3..493da54 100644
--- a/dijit/themes/nihilo/layout/BorderContainer.css
+++ b/dijit/themes/nihilo/layout/BorderContainer.css
@@ -29,15 +29,15 @@
 .nihilo .dijitBorderContainer-dijitBorderContainer {
 	/* also, make nested BorderContainers look like a single big widget with lots of splitters */
 	border: none;
-	padding: 0px;
+	padding: 0;
 }
 
 .nihilo .dijitSplitterH,
 .nihilo .dijitGutterH {
 	background:#FCFCFC;
 	border:0;
-	border-left:0px solid #d3d3d3;
-	border-right:0px solid #d3d3d3;
+	border-left:0 solid #d3d3d3;
+	border-right:0 solid #d3d3d3;
 	height:5px;
 }
 
@@ -52,8 +52,8 @@
 .nihilo .dijitGutterV {
 	background:#FCFCFC;
 	border:0;
-	border-top:0px solid #d3d3d3;
-	border-bottom:0px solid #d3d3d3;
+	border-top:0 solid #d3d3d3;
+	border-bottom:0 solid #d3d3d3;
 	width:5px;
 }
 
diff --git a/dijit/themes/nihilo/layout/ContentPane.css b/dijit/themes/nihilo/layout/ContentPane.css
index 37ef084..75272db 100644
--- a/dijit/themes/nihilo/layout/ContentPane.css
+++ b/dijit/themes/nihilo/layout/ContentPane.css
@@ -1,7 +1,7 @@
 /* ContentPane */
 
 .nihilo .dijitContentPane {
-    padding: 0px;
+    padding: 0;
 }
 
 /* nested layouts */
diff --git a/dijit/themes/nihilo/layout/SplitContainer.css b/dijit/themes/nihilo/layout/SplitContainer.css
index e73c0e7..9f4defa 100644
--- a/dijit/themes/nihilo/layout/SplitContainer.css
+++ b/dijit/themes/nihilo/layout/SplitContainer.css
@@ -6,8 +6,8 @@
 .nihilo .dijitSplitContainerSizerH {
 	background:url("../images/splitContainerSizerV.png") repeat-y #fff;
 	border:0;
-	border-left:0px solid #d3d3d3;
-	border-right:0px solid #d3d3d3;
+	border-left:0 solid #d3d3d3;
+	border-right:0 solid #d3d3d3;
 	width:5px;
 }
 
@@ -21,8 +21,8 @@
 .nihilo .dijitSplitContainerSizerV {
 	background:url("../images/splitContainerSizerH.png") repeat-x #fff;
 	border:0;
-	border-top:0px solid #d3d3d3;
-	border-bottom:0px solid #d3d3d3;
+	border-top:0 solid #d3d3d3;
+	border-bottom:0 solid #d3d3d3;
 	height:2px;
 }
 
diff --git a/dijit/themes/nihilo/layout/TabContainer.css b/dijit/themes/nihilo/layout/TabContainer.css
index cbb2506..2126657 100644
--- a/dijit/themes/nihilo/layout/TabContainer.css
+++ b/dijit/themes/nihilo/layout/TabContainer.css
@@ -17,7 +17,7 @@
 }
 
 .nihilo .dijitTabContainerBottom .nowrapTabStrip .dijitTab {
-	top: 0px;
+	top: 0;
 }
 
 /* Tabs, shared classes */
@@ -29,7 +29,7 @@
 }
 
 .nihilo .dijitTabInnerDiv {
-	padding:0px 3px 0px 0px;
+	padding:0 3px 0 0;
 	margin: 0 0 0 4px;
 	background: url("../images/tabContainerSprite.gif") no-repeat;
 	background-position: right -400px;
@@ -38,7 +38,7 @@
 .nihilo .dijitTab {
 	line-height:normal;
 	margin:0 2px 0 0;	/* space between one tab and the next in top/bottom mode */
-	padding:0px;
+	padding:0;
 	background: url("../images/tabContainerSprite.gif") no-repeat 0 -300px;
 	color: #6d6d6d;
 	border-bottom: 1px #ccc solid;
@@ -53,7 +53,7 @@
 /* hovered tab */
 .nihilo .dijitTabHover {
 	color: #243C5F;
-	background: url("../images/tabContainerSprite.gif") no-repeat 0px -150px;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0 -150px;
 }
 
 .nihilo .dijitTabHover .dijitTabInnerDiv {
@@ -68,7 +68,7 @@
 .nihilo .dijitTabChecked
 {
 	/* the selected tab (with or without hover) */
-	background: url("../images/tabContainerSprite.gif") no-repeat 0px -0px;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0 -0;
 }
 
 .nihilo .dijitTabChecked .dijitTabInnerDiv {
@@ -88,12 +88,12 @@
 .nihilo .dijitTabContainerTabListNested {
 	background: #FDFDFD;
 	border: none;
-	margin-bottom: 0px;		/* override margin: -1px; */
+	margin-bottom: 0;		/* override margin: -1px; */
 }
 .nihilo .dijitTabContainerTabListNested .dijitTab {
 	background: none;
 	border: none;
-	top: 0px;	/* override top:1px setting of top-level tabs */
+	top: 0;	/* override top:1px setting of top-level tabs */
 }
 .nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
 .nihilo .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
@@ -108,8 +108,8 @@
 }
 .nihilo .dijitTabContainerSpacerNested {
 	/* thinner line between tab (labels) and content */
-	height: 0px;
-	border-bottom: 0px;
+	height: 0;
+	border-bottom: 0;
 }
 .nihilo .dijitTabPaneWrapperNested {
 	border: none;	/* prevent double border */
@@ -134,17 +134,6 @@
 	background: url("../images/spriteRoundedIconsSmall.gif") no-repeat -60px -15px;
 }
 
-.nihilo .dijitTab .tabLabel {
-	/* make sure tabs w/close button and w/out close button are same height, even w/small (<15px) font */
-	min-height: 15px;
-	display: inline-block;
-}
-.dj_ie6 .nihilo .dijitTabButtonIcon {
-	/* because min-height doesn't work on IE6 */
-	height: 18px;
-	width: 1px;
-}
-
 /* ================================ */
 /* top tabs */
 .nihilo .dijitTabContainerTop-tabs {
@@ -162,7 +151,7 @@
 .dj_ie6 .nihilo .dijitTabContainerTop-tabs,
 .dj_ie7 .nihilo .dijitTabContainerTop-tabs {
 	border-bottom: 1px solid #ccc;
-	padding-bottom: 0px;
+	padding-bottom: 0;
 }
 
 .nihilo .dijitTabContainerTopNoStrip {
@@ -432,18 +421,18 @@
 
 /* this resets the tabcontainer stripe when within a contentpane */
 .nihilo .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
-	border-left: 0px solid #ccc;
-	border-top: 0px solid #ccc;
-	border-right: 0px solid #ccc;
-	padding-top: 0px;
-	padding-left: 0px;
+	border-left: 0 solid #ccc;
+	border-top: 0 solid #ccc;
+	border-right: 0 solid #ccc;
+	padding-top: 0;
+	padding-left: 0;
 }
 
 /* ================================ */
 
 /* Menu and slider control styles */
 .nihilo .dijitTabContainer .tabStripButton {
-	margin-right: 0px;
+	margin-right: 0;
 }
 
 .nihilo .tabStripButton .dijitTabInnerDiv .dijitTabContent {
@@ -485,7 +474,7 @@
 }
 
 .nihilo .dijitTabContainerTopNone {
-	padding-top: 0px;
+	padding-top: 0;
 }
 
 .nihilo .dijitTabContainer .tabStripButton-top {
diff --git a/dijit/themes/nihilo/layout/TabContainer_rtl.css b/dijit/themes/nihilo/layout/TabContainer_rtl.css
index 7421e2e..225fc3e 100644
--- a/dijit/themes/nihilo/layout/TabContainer_rtl.css
+++ b/dijit/themes/nihilo/layout/TabContainer_rtl.css
@@ -26,16 +26,16 @@
 }
 
 .dj_ie-rtl .nihilo .dijitTabContainerLeft-tabs {
-	margin-left: 0px !important;
+	margin-left: 0 !important;
 }
 
 .dj_ie-rtl .nihilo .dijitTabContainerRight-tabs {
-	margin-right: 0px !important;
+	margin-right: 0 !important;
 }
 
 .dijitRtl .nihilo .dijitTabContainerLeft-tabs .dijitTab,
 .dijitRtl .nihilo .dijitTabContainerRight-tabs .dijitTab {
-	margin-left:0px;
+	margin-left:0;
 }
 
 .dj_ie-rtl .nihilo .dijitTab .dijitTabInnerDiv{
diff --git a/dijit/themes/soria/Calendar.css b/dijit/themes/soria/Calendar.css
index 7b38d4d..78572da 100644
--- a/dijit/themes/soria/Calendar.css
+++ b/dijit/themes/soria/Calendar.css
@@ -61,6 +61,7 @@
 .soria .dijitCalendarMonthLabel {
 	color:#293a4b;
 	font-weight: bold;
+	padding: 0 4px;
 }
 
 .soria .dijitCalendarDateTemplate {
@@ -134,4 +135,25 @@
 	/* label for next/prev years */
 	color:black !important;
 	font-weight:normal;
+}
+
+/* Styling for month DropDownButton */
+
+.soria .dijitCalendar .dijitDropDownButton {
+	margin: 0;
+}
+.soria .dijitCalendar .dijitButtonText {
+	padding: 0;
+}
+.soria .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+	background-color: transparent;
+	background-image: none;
+	padding: 0;
+}
+
+/* Styling for month drop down list */
+
+.soria .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+	background-color: #d9e6f9;
+	color: #243C5F;
 }
\ No newline at end of file
diff --git a/dijit/themes/soria/Calendar_rtl.css b/dijit/themes/soria/Calendar_rtl.css
index 70efe52..c2350b4 100644
--- a/dijit/themes/soria/Calendar_rtl.css
+++ b/dijit/themes/soria/Calendar_rtl.css
@@ -5,5 +5,5 @@
 }
 
 .dijitRtl .soria .dijitCalendarIncrease {
-	background-position: 0px top;
+	background-position: 0 top;
 }
diff --git a/dijit/themes/soria/ColorPalette.css b/dijit/themes/soria/ColorPalette.css
index ed922ac..85d6dd8 100644
--- a/dijit/themes/soria/ColorPalette.css
+++ b/dijit/themes/soria/ColorPalette.css
@@ -1,5 +1,5 @@
 .dijitColorPalette {
 	border:1px solid #cbcbcb;
 	background:#fff;
-	-moz-border-radius: 0px !important;
+	-moz-border-radius: 0 !important;
 }
\ No newline at end of file
diff --git a/dijit/themes/soria/Dialog.css b/dijit/themes/soria/Dialog.css
index c2a5107..1e0503a 100644
--- a/dijit/themes/soria/Dialog.css
+++ b/dijit/themes/soria/Dialog.css
@@ -3,16 +3,16 @@
 .soria .dijitDialog {
 	background: #eee;
 	border: 1px solid #cbcbcb;
-	-webkit-box-shadow: 0px 5px 10px #adadad;
-	padding: 0px;
+	-webkit-box-shadow: 0 5px 10px #adadad;
+	padding: 0;
 }
 
 .soria .dijitDialog .dijitDialogTitle {
 	/* typography and styling of the dialog title */
 	font-weight: bold;
-	padding: 0px 4px;
+	padding: 0 4px;
 	font-size: 0.9em;
-	color: #3243C5F;
+	color: #243C5F;
 }
 
 .soria .dijitDialog .dijitDialogPaneContent {
@@ -33,7 +33,7 @@
 	/* the default close icon for the dialog */
 	background-image: url("images/spriteRoundedIconsSmallBl.png");
 	background-repeat: no-repeat;
-	background-position: -60px 0px;
+	background-position: -60px 0;
 	position: absolute;
 	vertical-align: middle;
 	right: 6px;
@@ -83,7 +83,7 @@
 
 .soria .dijitTooltipConnector {
 	/* the arrow piece */
-	border:0px;
+	border:0;
 	z-index: 2;
 }
 
@@ -96,7 +96,7 @@
 
 .soria .dijitTooltipBelow .dijitTooltipConnector {
 	/* the arrow piece for tooltips below an element */
-	top: 0px;
+	top: 0;
 	left: 6px;
 	background:url("images/tooltipConnectorUp.png") no-repeat top left;
 	width:17px;
@@ -109,7 +109,7 @@
 
 .soria .dijitTooltipAbove .dijitTooltipConnector {
 	/* the arrow piece for tooltips above an element */
-	bottom: 0px;
+	bottom: 0;
 	left: 6px;
 	background:url("images/tooltipConnectorDown.png") no-repeat top left;
 	width:17px;
@@ -128,13 +128,9 @@
 .soria .dijitTooltipLeft {
 	padding-right: 10px;
 }
-.dj_ie6 .soria .dijitTooltipLeft {
-	padding-left: 11px;
-}
 .soria .dijitTooltipLeft .dijitTooltipConnector {
 	/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
-	right: 0px;
-	bottom: 3px;
+	right: 0;
 	background:url("images/tooltipConnectorRight.png") no-repeat top left;
 	width:11px;
 	height:17px;
@@ -148,8 +144,7 @@
 }
 .soria .dijitTooltipRight .dijitTooltipConnector {
 	/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
-	left: 0px;
-	bottom: 3px;
+	left: 0;
 	background:url("images/tooltipConnectorLeft.png") no-repeat top left;
 	width:11px;
 	height:17px;
diff --git a/dijit/themes/soria/Menu.css b/dijit/themes/soria/Menu.css
index 6a93f5f..4d9d068 100644
--- a/dijit/themes/soria/Menu.css
+++ b/dijit/themes/soria/Menu.css
@@ -3,8 +3,8 @@
 .soria .dijitMenu,
 .soria .dijitMenuBar {
 	border: 1px solid #cbcbcb;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	background-color: #fff;
 }
 
@@ -14,7 +14,7 @@
 
 .soria .dijitMenuItem {
 	font-family: sans-serif;
-	margin: 0px;
+	margin: 0;
 	color: #243C5F;
 }
 .soria .dijitMenuBar .dijitMenuItem {
@@ -53,7 +53,7 @@
 	height: 1px;
 }
 
-/* separator can be two pixels -- set border of either one to 0px to have only one */
+/* separator can be two pixels -- set border of either one to 0 to have only one */
 .soria .dijitMenuSeparatorTop {
 	border-bottom: 1px solid #fff; /*97adcb; */
 }
diff --git a/dijit/themes/soria/Menu_rtl.css b/dijit/themes/soria/Menu_rtl.css
index fd521af..0e01483 100644
--- a/dijit/themes/soria/Menu_rtl.css
+++ b/dijit/themes/soria/Menu_rtl.css
@@ -2,7 +2,7 @@
 
 .dijitRtl .soria .dijitMenuItem .dijitMenuItemIcon {
 	padding-left: 3px;
-	padding-right: 0px;
+	padding-right: 0;
 }
 
 .dijitRtl .soria .dijitMenuItem .dijitMenuExpand {
diff --git a/dijit/themes/soria/ProgressBar.css b/dijit/themes/soria/ProgressBar.css
index 7919cf3..b2f6d1f 100644
--- a/dijit/themes/soria/ProgressBar.css
+++ b/dijit/themes/soria/ProgressBar.css
@@ -4,7 +4,7 @@
  ****/
 
 .soria .dijitProgressBar {
-	margin:2px 0px 2px 0px;
+	margin:2px 0 2px 0;
 }
 
 .soria .dijitProgressBarEmpty{
diff --git a/dijit/themes/soria/TimePicker_rtl.css b/dijit/themes/soria/TimePicker_rtl.css
index bce88ad..a802ba6 100644
--- a/dijit/themes/soria/TimePicker_rtl.css
+++ b/dijit/themes/soria/TimePicker_rtl.css
@@ -1,4 +1,4 @@
 .dj_ie6-rtl .soria .dijitTimePickerMarkerHover,
 .dj_ie7-rtl .soria .dijitTimePickerMarkerHover {
-        border-top: 0px; /* IE6/7 bug causes mouseover/out event storm */
+        border-top: 0; /* IE6/7 bug causes mouseover/out event storm */
 }
diff --git a/dijit/themes/soria/TitlePane.css b/dijit/themes/soria/TitlePane.css
index 04f6e0a..7e1042e 100644
--- a/dijit/themes/soria/TitlePane.css
+++ b/dijit/themes/soria/TitlePane.css
@@ -46,7 +46,7 @@
 .soria .dijitTitlePaneContentOuter {
 	background: #ffffff;
 	border: 1px solid #bfbfbf;
-	border-top: 0px;
+	border-top: 0;
 }
 .soria .dijitTitlePaneContentInner {
 	padding:10px;
diff --git a/dijit/themes/soria/TitlePane_rtl.css b/dijit/themes/soria/TitlePane_rtl.css
index 82174fa..8a1b73d 100644
--- a/dijit/themes/soria/TitlePane_rtl.css
+++ b/dijit/themes/soria/TitlePane_rtl.css
@@ -1,6 +1,6 @@
 .dijitRtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: 0px top;
+	background-position: 0 top;
 }
 .dj_ie6-rtl .soria .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: 0px top;
+	background-position: 0 top;
 }
\ No newline at end of file
diff --git a/dijit/themes/soria/Toolbar.css b/dijit/themes/soria/Toolbar.css
index fc8913f..8af426a 100644
--- a/dijit/themes/soria/Toolbar.css
+++ b/dijit/themes/soria/Toolbar.css
@@ -12,8 +12,8 @@
 .soria .dijitToolbar .dijitComboButton .dijitButtonContents,
 .soria .dijitToolbar .dijitComboButton .dijitDownArrowButton {
 	background: none;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	border: none;
 	font-size: 12px;
 }
@@ -31,7 +31,7 @@
 .soria .dijitToolbar .dijitToggleButtonChecked {
 	background-color:#d8e5f8;
 	border:1px solid #316ac5;
-	padding: 0px;
+	padding: 0;
 }
 
 .soria .dijitToolbar .dijitButtonCheckedHover,
@@ -39,7 +39,7 @@
  {
 	background-color:#9abbea;
 	border:1px solid #316ac5;
-	padding: 0px;
+	padding: 0;
 }
 
 .soria .dijitToolbar .dijitButtonHover,
@@ -49,7 +49,7 @@
 .soria .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover {
 	/* TODO: change this from Hover to Selected so that button is still highlighted while drop down is being used */
 	border: 1px solid #316ac5;
-	padding: 0px;
+	padding: 0;
 	background-color:#9abbea;
 }
 
@@ -61,5 +61,5 @@
 .dj_ie .soria .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
 	/* focus border doesn't appear on <td> for IE, so need to add it manually */
 	border: 1px #777 dotted !important;
-	padding: 0px;
+	padding: 0;
 }
diff --git a/dijit/themes/soria/Tree.css b/dijit/themes/soria/Tree.css
index dacf166..d8edb67 100644
--- a/dijit/themes/soria/Tree.css
+++ b/dijit/themes/soria/Tree.css
@@ -4,7 +4,7 @@
     background : url('images/treeI.gif') no-repeat;
     background-position : top left;
     background-repeat : repeat-y;
-    zoom: 1;	/* MOW: what the heck is this doing in here? */
+    zoom: 1;
 }
 
 .soria .dijitTreeRowHover {
diff --git a/dijit/themes/soria/Tree_rtl.css b/dijit/themes/soria/Tree_rtl.css
index e68a1db..44daf3a 100644
--- a/dijit/themes/soria/Tree_rtl.css
+++ b/dijit/themes/soria/Tree_rtl.css
@@ -7,7 +7,7 @@
 }
 
 .dijitRtl .soria .dijitTreeContent {
-    padding-left: 0px;
+    padding-left: 0;
     padding-right: 1px;
 }
 
diff --git a/dijit/themes/soria/form/Button.css b/dijit/themes/soria/form/Button.css
index c5b2646..6b813a6 100644
--- a/dijit/themes/soria/form/Button.css
+++ b/dijit/themes/soria/form/Button.css
@@ -85,7 +85,7 @@
 .soria .dijitArrowButtonInner {
 	background-image: url("../images/spriteArrows.png");
 	background-repeat: no-repeat;
-	background-position: 0px center;
+	background-position: 0 center;
 	width: 11px;
 	height: 11px;
 }
diff --git a/dijit/themes/soria/form/Button_rtl.css b/dijit/themes/soria/form/Button_rtl.css
index 50a5c5e..e2f3728 100644
--- a/dijit/themes/soria/form/Button_rtl.css
+++ b/dijit/themes/soria/form/Button_rtl.css
@@ -1,5 +1,5 @@
 .dijitRtl .soria .dijitComboBox .dijitButtonNode {
-	border-width: 0px 0px 0px 1px;
+	border-width: 0 0 0 1px;
 }
 .dijitRtl .soria .dijitSelect .dijitButtonContents {
 	border-left: none;
diff --git a/dijit/themes/soria/form/Checkbox.css b/dijit/themes/soria/form/Checkbox.css
index 7ad1411..5a72bfc 100644
--- a/dijit/themes/soria/form/Checkbox.css
+++ b/dijit/themes/soria/form/Checkbox.css
@@ -43,7 +43,7 @@
 .soria .dijitCheckBoxChecked,
 .soria .dijitToggleButtonChecked .dijitCheckBoxIcon {
 	/* checked */
-	background-position: 0px;
+	background-position: 0;
 }
 
 .soria .dijitCheckBoxDisabled {
diff --git a/dijit/themes/soria/form/Common.css b/dijit/themes/soria/form/Common.css
index faf18ae..8e3688e 100644
--- a/dijit/themes/soria/form/Common.css
+++ b/dijit/themes/soria/form/Common.css
@@ -12,7 +12,7 @@
 
 .soria .dijitInputContainer INPUT,
 .soria .dijitTextBox {
-	margin: 0em 0.1em;
+	margin: 0 0.1em;
 }
 
 .soria .dijitTextBox,
diff --git a/dijit/themes/soria/form/RadioButton.css b/dijit/themes/soria/form/RadioButton.css
index 7b875db..1ea27bf 100644
--- a/dijit/themes/soria/form/RadioButton.css
+++ b/dijit/themes/soria/form/RadioButton.css
@@ -42,7 +42,7 @@
 .soria .dijitRadioChecked,
 .soria .dijitToggleButtonChecked .dijitRadioIcon {
 	/* selected */
-	background-position: 0px;
+	background-position: 0;
 }
 
 .soria .dijitRadioDisabled {
diff --git a/dijit/themes/soria/form/Select.css b/dijit/themes/soria/form/Select.css
index 758d25c..1856772 100644
--- a/dijit/themes/soria/form/Select.css
+++ b/dijit/themes/soria/form/Select.css
@@ -1,5 +1,5 @@
 .soria .dijitSelect .dijitButtonNode {
-	padding: 0px;
+	padding: 0;
 }
 
 /* Make unselected "look" more like a text box and less like a button */
@@ -16,11 +16,11 @@
 	background: transparent none;
 }
 .dj_ie .soria .dijitSelect .dijitButtonContents {
-	padding-top: 0px;
+	padding-top: 0;
 }
 
 .soria .dijitSelect .dijitArrowButton {
-	padding: 0px 2px;
+	padding: 0 2px;
 }
 
 /* Mirror DropDownButton */
@@ -45,7 +45,7 @@
 
 /* Make the menu look more combobox-like */
 .soria .dijitSelectMenu td {
-	padding: 0em;
+	padding: 0;
 }
 .soria .dijitSelectMenu .dijitMenuItemLabel,
 .soria .dijitSelectMenu .dijitMenuArrowCell {
diff --git a/dijit/themes/soria/form/Slider.css b/dijit/themes/soria/form/Slider.css
index 2884a13..3a68f46 100644
--- a/dijit/themes/soria/form/Slider.css
+++ b/dijit/themes/soria/form/Slider.css
@@ -43,7 +43,7 @@
 }
 
 .soria .dijitSliderImageHandleH {
-	border:0px;
+	border:0;
 	width:15px;
 	height:18px;
 	background:url("../images/preciseSliderThumb.png") no-repeat center top;
@@ -70,7 +70,7 @@
 }
 
 .soria .dijitSliderImageHandleV {
-	border:0px;
+	border:0;
 	width:20px;
 	height:15px;
 	background:url("../images/sliderThumb.png") no-repeat center center;
@@ -113,8 +113,8 @@
 	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat -15px top;
 }
 .soria .dijitSliderDecrementIconH {
-	background:url('../images/spriteRoundedIconsSmall.png') no-repeat 0px top;
-	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat 0px top;
+	background:url('../images/spriteRoundedIconsSmall.png') no-repeat 0 top;
+	#background:url('../images/spriteRoundedIconsSmall.gif') no-repeat 0 top;
 }
 
 .soria .dijitSliderButtonInner {
@@ -128,7 +128,7 @@
 }
 .soria .dijitSliderReadOnly .dijitSliderDecrementIconH,
 .soria .dijitSliderDisabled .dijitSliderDecrementIconH {
-	background-position: 0px -15px;
+	background-position: 0 -15px;
 }
 .soria .dijitSliderReadOnly .dijitSliderIncrementIconH,
 .soria .dijitSliderDisabled .dijitSliderIncrementIconH {
diff --git a/dijit/themes/soria/form/Slider_rtl.css b/dijit/themes/soria/form/Slider_rtl.css
index 2f7a08a..d9b67c5 100644
--- a/dijit/themes/soria/form/Slider_rtl.css
+++ b/dijit/themes/soria/form/Slider_rtl.css
@@ -16,13 +16,13 @@
 }
 
 .dijitRtl .soria .dijitSliderLeftBumper {
-	border-left-width: 0px;
+	border-left-width: 0;
 	border-right-width: 1px;
 }
 
 .dijitRtl .soria .dijitSliderRightBumper {
 	border-left-width: 1px;
-	border-right-width: 0px;
+	border-right-width: 0;
 }
 
 .dijitRtl .soria .dijitSliderIncrementIconH {
diff --git a/dijit/themes/soria/layout/AccordionContainer_rtl.css b/dijit/themes/soria/layout/AccordionContainer_rtl.css
index 4c20d39..c6bb820 100644
--- a/dijit/themes/soria/layout/AccordionContainer_rtl.css
+++ b/dijit/themes/soria/layout/AccordionContainer_rtl.css
@@ -1,5 +1,5 @@
 .dijitRtl .soria .dijitAccordionArrow {
-	background-position: 0px top;
+	background-position: 0 top;
 }
 
 .dijitRtl .soria .dijitAccordionTitleSelected .dijitAccordionArrow {
diff --git a/dijit/themes/soria/layout/BorderContainer.css b/dijit/themes/soria/layout/BorderContainer.css
index a170e83..63f2bf3 100644
--- a/dijit/themes/soria/layout/BorderContainer.css
+++ b/dijit/themes/soria/layout/BorderContainer.css
@@ -29,7 +29,7 @@
 .soria .dijitBorderContainer-dijitBorderContainer {
 	/* also, make nested BorderContainers look like a single big widget with lots of splitters */
 	border: none;
-	padding: 0px;
+	padding: 0;
 }
 
 
@@ -37,8 +37,8 @@
 .soria .dijitGutterH {
 	background: #E1EBFB;
 	border:0;
-	border-left:0px solid #d3d3d3;
-	border-right:0px solid #d3d3d3;
+	border-left:0 solid #d3d3d3;
+	border-right:0 solid #d3d3d3;
 	height:5px;
 }
 
@@ -53,8 +53,8 @@
 .soria .dijitGutterV {
 	background: #E1EBFB;
 	border:0;
-	border-top:0px solid #d3d3d3;
-	border-bottom:0px solid #d3d3d3;
+	border-top:0 solid #d3d3d3;
+	border-bottom:0 solid #d3d3d3;
 	width:5px;
 }
 
diff --git a/dijit/themes/soria/layout/ContentPane.css b/dijit/themes/soria/layout/ContentPane.css
index d1492d5..32398dc 100644
--- a/dijit/themes/soria/layout/ContentPane.css
+++ b/dijit/themes/soria/layout/ContentPane.css
@@ -1,7 +1,7 @@
 /* ContentPane */
 
 .soria .dijitContentPane {
-    padding: 0px;
+    padding: 0;
 }
 
 /* nested layouts */
diff --git a/dijit/themes/soria/layout/SplitContainer.css b/dijit/themes/soria/layout/SplitContainer.css
index e066a3c..bf7ca16 100644
--- a/dijit/themes/soria/layout/SplitContainer.css
+++ b/dijit/themes/soria/layout/SplitContainer.css
@@ -6,8 +6,8 @@
 .soria .dijitSplitContainerSizerH {
 	background:url("../images/splitContainerSizerV.png") repeat-y #cddef4;
 	border:0;
-	border-left:0px solid #436496;
-	border-right:0px solid #436496;
+	border-left:0 solid #436496;
+	border-right:0 solid #436496;
 	width:5px;
 }
 
@@ -21,8 +21,8 @@
 .soria .dijitSplitContainerSizerV {
 	background:url("../images/splitContainerSizerH.png") repeat-x #cddef4;
 	border:0;
-	border-top:0px solid #436496;
-	border-bottom:0px solid #436496;
+	border-top:0 solid #436496;
+	border-bottom:0 solid #436496;
 	height:2px;
 }
 
diff --git a/dijit/themes/soria/layout/TabContainer.css b/dijit/themes/soria/layout/TabContainer.css
index 45472a4..b96d169 100644
--- a/dijit/themes/soria/layout/TabContainer.css
+++ b/dijit/themes/soria/layout/TabContainer.css
@@ -29,11 +29,11 @@
 	background:#fff;
 	border:1px solid #B1BADF;
 	margin: 0;
-	padding-left: 0px;
+	padding-left: 0;
 }
 
 .soria .dijitTabInnerDiv {
-	padding:0px 3px 0px 0px;
+	padding:0 3px 0 0;
 	margin: 0 0 0 4px;
 	background: url("../images/tabContainerSprite.gif") no-repeat;
 	background-position: right -400px;
@@ -42,7 +42,7 @@
 .soria .dijitTab {
 	line-height:normal;
 	margin:0 2px 0 0;	/* space between one tab and the next in top/bottom mode */
-	padding:0px;
+	padding:0;
 	background: url("../images/tabContainerSprite.gif") no-repeat 0 -300px;
 	color: #243C5F;
 	border-bottom: 1px #B1BADF solid;
@@ -63,7 +63,7 @@
 /* hovered tab */
 .soria .dijitTabHover {
 	color: #243C5F;
-	background: url("../images/tabContainerSprite.gif") no-repeat 0px -150px;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0 -150px;
 }
 
 .soria .dijitTabHover .dijitTabInnerDiv {
@@ -78,7 +78,7 @@
 .soria .dijitTabChecked
 {
 	/* the selected tab (with or without hover) */
-	background: url("../images/tabContainerSprite.gif") no-repeat 0px -0px;
+	background: url("../images/tabContainerSprite.gif") no-repeat 0 -0;
 }
 
 .soria .dijitTabChecked .dijitTabInnerDiv {
@@ -100,7 +100,7 @@
 .soria .dijitTabContainerTabListNested .dijitTab {
 	background: none;
 	border: none;
-	top: 0px;	/* override top:1px setting of top-level tabs */
+	top: 0;	/* override top:1px setting of top-level tabs */
 }
 .soria .dijitTabContainerTabListNested .dijitTab .dijitTabInnerDiv,
 .soria .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
@@ -115,7 +115,7 @@
 }
 .soria .dijitTabContainerSpacerNested .dijitTabSpacer {
 	/* thinner line between tab (labels) and content */
-	height: 0px;
+	height: 0;
 }
 .soria .dijitTabPaneWrapperNested {
 	border: none;	/* prevent double border */
@@ -140,17 +140,6 @@
 	background: url("../images/spriteRoundedIconsSmall.gif") no-repeat -60px -15px;
 }
 
-.soria .dijitTab .tabLabel {
-	/* make sure tabs w/close button and w/out close button are same height, even w/small (<15px) font */
-	min-height: 15px;
-	display: inline-block;
-}
-.dj_ie6 .soria .dijitTabButtonIcon {
-	/* because min-height doesn't work on IE6 */
-	height: 18px;
-	width: 1px;
-}
-
 /* ================================ */
 /* top tabs */
 .soria .dijitTabContainerTop-tabs {
@@ -434,11 +423,11 @@
 
 /* this resets the tabcontainer stripe when within a contentpane */
 .soria .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
-	border-left: 0px solid #ccc;
-	border-top: 0px solid #ccc;
-	border-right: 0px solid #ccc;
-	padding-top: 0px;
-	padding-left: 0px;
+	border-left: 0 solid #ccc;
+	border-top: 0 solid #ccc;
+	border-right: 0 solid #ccc;
+	padding-top: 0;
+	padding-left: 0;
 }
 
 
diff --git a/dijit/themes/soria/layout/TabContainer_rtl.css b/dijit/themes/soria/layout/TabContainer_rtl.css
index e9e1fbf..eba3963 100644
--- a/dijit/themes/soria/layout/TabContainer_rtl.css
+++ b/dijit/themes/soria/layout/TabContainer_rtl.css
@@ -26,16 +26,16 @@
 }
 
 .dj_ie-rtl .soria .dijitTabContainerLeft-tabs {
-	margin-left: 0px !important;
+	margin-left: 0 !important;
 }
 
 .dj_ie-rtl .soria .dijitTabContainerRight-tabs {
-	margin-right: 0px !important;
+	margin-right: 0 !important;
 }
 
 .dijitRtl .soria .dijitTabContainerLeft-tabs .dijitTab,
 .dijitRtl .soria .dijitTabContainerRight-tabs .dijitTab {
-	margin-left:0px;
+	margin-left:0;
 }
 
 .dj_ie-rtl .soria .dijitTab .dijitTabInnerDiv{
diff --git a/dijit/themes/themeTester-orig.html b/dijit/themes/themeTester-orig.html
new file mode 100644
index 0000000..f5274ae
--- /dev/null
+++ b/dijit/themes/themeTester-orig.html
@@ -0,0 +1,1235 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Dijit Theme Tester</title>
+
+	<!-- required: a default theme -->
+	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+
+	<style type="text/css">
+		@import "../themes/claro/document.css";
+		@import "../tests/css/dijitTests.css";
+
+		html, body { height: 100%; width: 100%; padding: 0; border: 0; }
+		#main { height: 100%; width: 100%; border: 0; }
+		#header { margin: 0px; }
+		#leftAccordion { width: 25%; }
+		#bottomTabs { height: 40%; }
+
+		/* pre-loader specific stuff to prevent unsightly flash of unstyled content */
+		#loader {
+			padding:0;
+			margin:0;
+			position:absolute;
+			top:0; left:0;
+			width:100%; height:100%;
+			background:#ededed;
+			z-index:999;
+			vertical-align:middle;
+		}
+		#loaderInner {
+			padding:5px;
+			position:relative;
+			left:0;
+			top:0;
+			width:175px;
+			background:#3c3;
+			color:#fff;
+		}
+
+		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; }
+		.inputPadding1 .dijitInputField { padding: 1px !important; }
+		.inputPadding2 .dijitInputField { padding: 2px !important; }
+		.inputPadding3 .dijitInputField { padding: 3px !important; }
+		.inputPadding4 .dijitInputField { padding: 4px !important; }
+		.inputPadding5 .dijitInputField { padding: 5px !important; }
+	</style>
+
+	<!-- a check for stray globals: not needed! -->
+	<script type="text/javascript">
+		window.__globalList = {dojo: true, dijit: true, dojox: true, djConfig: true};
+		for(var i in window){
+			window.__globalList[i] = true;
+		}
+	</script>
+
+	<!-- required: dojo.js -->
+	<script type="text/javascript" src="../../dojo/dojo.js"
+		djConfig="parseOnLoad: false, isDebug: true"></script>
+
+	<!-- do not use: only for debugging / testing themes -->
+	<script type="text/javascript" src="../tests/_testCommon.js"></script>
+	<!--
+	<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.Calendar");
+		dojo.require("dijit.ColorPalette");
+		dojo.require("dijit.ProgressBar");
+		dojo.require("dijit.TitlePane");
+		dojo.require("dijit.Tooltip");
+		dojo.require("dijit.Tree");
+
+		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");
+
+		// scan page for widgets and instantiate them
+		dojo.require("dojo.parser");
+
+		// humm?
+		dojo.require("dojo.date.locale");
+
+		// for the Tree
+		dojo.require("dojo.data.ItemFileReadStore");
+
+		// for the colorpalette
+		function setColor(color){
+			var theSpan = dojo.byId("outputSpan");
+			dojo.style(theSpan,"color",color);
+			theSpan.innerHTML = color;
+		}
+
+		// for the calendar
+		function myHandler(id,newValue){
+			console.debug("onChange for id = " + id + ", value: " + newValue);
+		}
+
+		// current setting (if there is one) to override theme default padding on TextBox based widgets
+		currentInputPadding = "";
+
+		function setTextBoxPadding(){
+			// summary:
+			//		Handler for when a MenuItem is clicked to set non-default padding for
+			//		TextBox widgets
+
+			// Effectively ignore clicks on the  currently checked MenuItem
+			if(!this.get("checked")){
+				this.set("checked", true);
+			}
+
+			// val will be "theme default", "0px", "1px", ..., "5px"
+			var val = this.get("label");
+			
+			// Set class on body to get requested padding, and remove any previously set class
+			if(currentInputPadding){
+				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);
+				}
+			}, this);
+		}
+
+		dojo.addOnLoad(function() {
+
+			var start = new Date().getTime();
+			dojo.parser.parse(dojo.byId('container'));
+			console.info("Total parse time: " + (new Date().getTime() - start) + "ms");
+
+			dojo.byId('loaderInner').innerHTML += " done.";
+			setTimeout(function hideLoader(){
+				var loader = dojo.byId('loader');
+				dojo.fadeOut({ node: loader, duration:500,
+					onEnd: function(){
+						loader.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;
+		});
+
+		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 + "})");
+			});
+		});
+		***/
+	</script>
+</head>
+<body class="claro">
+	<!-- basic preloader: -->
+	<div id="loader"><div id="loaderInner" style="direction:ltr;">Loading themeTester ... </div></div>
+
+	<!-- data for tree and combobox -->
+	<div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
+		url="../tests/_data/countries.json"></div>
+	<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
+		url="../tests/_data/states.json"></div>
+	<!-- contentMenu popup -->
+	<div dojoType="dijit.Menu" id="submenu1" contextMenuForWindow="true" style="display: none;">
+		<div dojoType="dijit.MenuItem" onClick="alert('Hello world');">Enabled Item</div>
+		<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
+		<div dojoType="dijit.MenuSeparator"></div>
+		<div dojoType="dijit.MenuItem" iconClass="dijitIconCut"
+			onClick="alert('not actually cutting anything, just a test!')">Cut</div>
+		<div dojoType="dijit.MenuItem" iconClass="dijitIconCopy"
+			onClick="alert('not actually copying anything, just a test!')">Copy</div>
+		<div dojoType="dijit.MenuItem" iconClass="dijitIconPaste"
+			onClick="alert('not actually pasting anything, just a test!')">Paste</div>
+		<div dojoType="dijit.MenuSeparator"></div>
+		<div dojoType="dijit.PopupMenuItem">
+			<span>Enabled Submenu</span>
+			<div dojoType="dijit.Menu" id="submenu2">
+				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
+				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
+				<div dojoType="dijit.PopupMenuItem">
+					<span>Deeper Submenu</span>
+					<div dojoType="dijit.Menu" id="submenu4">
+						<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 1!')">Sub-sub-menu Item One</div>
+						<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
+					</div>
+				</div>
+			</div>
+		</div>
+		<div dojoType="dijit.PopupMenuItem" disabled="true">
+			<span>Disabled Submenu</span>
+			<div dojoType="dijit.Menu" id="submenu3" style="display: none;">
+				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
+				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
+			</div>
+		</div>
+		<div dojoType="dijit.PopupMenuItem">
+			<span>Different popup</span>
+			<div dojoType="dijit.ColorPalette"></div>
+		</div>
+		<div dojoType="dijit.PopupMenuItem">
+			<span>Different popup</span>
+			<div dojoType="dijit.Calendar"></div>
+		</div>
+	</div>
+	<!-- end contextMenu -->
+
+	<div id="main" dojoType="dijit.layout.BorderContainer" liveSplitters="false" design="sidebar">
+
+		<div id="header" dojoType="dijit.MenuBar" region="top">
+			<div dojoType="dijit.PopupMenuBarItem" id="file">
+				<span>File</span>
+				<div dojoType="dijit.Menu" id="fileMenu">
+					<div dojoType="dijit.MenuItem" id="globals" onClick="logStrayGlobals();">Log globals</div>
+					<div dojoType="dijit.MenuItem" id="widgets" onClick="logWidgets();">Log widgets</div>
+					<div dojoType="dijit.MenuItem" id="destroy" iconClass="dijitIconDelete" onClick="tearDown();">Destroy All</div>
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" id="edit">
+				<span>Edit</span>
+				<div dojoType="dijit.Menu" id="editMenu">
+					<div dojoType="dijit.MenuItem" id="cut" iconClass="dijitIconCut"
+						onClick="console.log('not actually cutting anything, just a test!')">Cut</div>
+					<div dojoType="dijit.MenuItem" id="copy" iconClass="dijitIconCopy"
+						onClick="console.log('not actually copying anything, just a test!')">Copy</div>
+					<div dojoType="dijit.MenuItem" id="paste" iconClass="dijitIconPaste"
+						onClick="console.log('not actually pasting anything, just a test!')">Paste</div>
+					<div dojoType="dijit.MenuSeparator" id="separator"></div>
+					<div dojoType="dijit.MenuItem" id="undo" iconClass="dijitIconUndo">Undo</div>
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" id="view">
+				<span>View</span>
+				<div dojoType="dijit.Menu" id="viewMenu">
+					<div dojoType="dijit.MenuItem">Normal</div>
+					<div dojoType="dijit.MenuItem">Outline</div>
+					<div dojoType="dijit.PopupMenuItem">
+						<span>Zoom</span>
+						<div dojoType="dijit.Menu" id="zoomMenu">
+							<div dojoType="dijit.MenuItem">50%</div>
+							<div dojoType="dijit.MenuItem">75%</div>
+							<div dojoType="dijit.MenuItem">100%</div>
+							<div dojoType="dijit.MenuItem">150%</div>
+							<div dojoType="dijit.MenuItem">200%</div>
+						</div>
+					</div>
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" id="themes">
+				<span>Themes</span>
+				<div dojoType="dijit.Menu" id="themeMenu">
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" id="dialogs">
+				<span>Dialogs</span>
+				<div dojoType="dijit.Menu" id="dialogMenu">
+					<div dojoType="dijit.MenuItem">
+						<script type="dojo/method" event="onClick">
+							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");
+						</script>
+						slow loading
+					</div>
+					<div dojoType="dijit.MenuItem">
+						<script type="dojo/method" event="onClick">
+							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");
+						</script>
+						action bar
+					</div>
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" id="inputPadding">
+				<span>TextBox Padding</span>
+				<div dojoType="dijit.Menu" id="inputPaddingMenu">
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding" checked>theme default</div>
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">0px</div>
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">1px</div>
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">2px</div>
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">3px</div>
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">4px</div>
+					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">5px</div>
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" id="help">
+				<span>Help</span>
+				<div dojoType="dijit.Menu" id="helpMenu">
+					<div dojoType="dijit.MenuItem">Help Topics</div>
+					<div dojoType="dijit.MenuItem">About Dijit</div>
+				</div>
+			</div>
+			<div dojoType="dijit.PopupMenuBarItem" disabled="true">
+				<span>Disabled</span>
+				<div dojoType="dijit.Menu">
+					<div dojoType="dijit.MenuItem">You should not see this</div>
+				</div>
+			</div>
+			<div dojoType="dijit.MenuBarItem" onclick="alert('no submenu, just a clickable MenuItem');">
+				Click me!
+			</div>
+		</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 style="padding:8px">
+				<h2>Tooltips</h2>
+				<ul>
+					<li>
+					<span id="ttRich"><b>rich</b> <i>text</i> tooltip</span>
+					<span dojoType="dijit.Tooltip" connectId="ttRich" style="display:none;">
+						Embedded <b>bold</b> <i>RICH</i> text <span style="color:#309; font-size:x-large;">weirdness!</span>
+					</span>
+					</li>
+
+					<li><a id="ttOne" href="#bogus">anchor tooltip</a>
+					<span dojoType="dijit.Tooltip" connectId="ttOne" style="display:none;">tooltip on anchor</span>
+					</li>
+				</ul>
+
+				<table style="width: 100%;">
+					<tr>
+						<td></td>
+						<td>
+							<div id="ttBelow" href="#bogus">tooltip below</div>
+							<div dojoType="dijit.Tooltip" connectId="ttBelow" style="display:none; width: 100px;" position="below" >I'm <i>below</i>!</div>
+						</td>
+						<td></td>
+					</tr>
+					<tr>
+						<td>
+							<div id="ttRight" href="#bogus">tooltip after</div>
+							<div dojoType="dijit.Tooltip" connectId="ttRight" style="display:none;" position="after" >I'm on the <i>right</i>!<br>(or left on RTL systems)</div>
+						</td>
+						<td></td>
+						<td>
+							<div id="ttLeft" href="#bogus">tooltip before</div>
+							<div dojoType="dijit.Tooltip" connectId="ttLeft" style="display:none;" position="before,after" >I'm on the <i>left</i>!<br>(or right on RTL systems)</div>
+						</td>
+					</tr>
+					<tr>
+						<td></td>
+						<td>
+							<div id="ttAbove" href="#bogus">tooltip above</div>
+							<div dojoType="dijit.Tooltip" connectId="ttAbove" style="display:none;" position="above" >I'm <i>above</i>!</div>
+						</td>
+						<td></td>
+					</tr>
+				</table>
+
+				<hr class="spacer">
+
+				<h2>Dialogs</h2>
+				<ul>
+					<li><a href="#" onclick="dijit.byId('dialog1').show()">slow loading modal dialog</a></li>
+					<li><a href="#" onclick="dijit.byId('dialogAB').show()">modal dialog w/action bar</a></li>
+				</ul>
+
+				<div dojoType="dijit.form.DropDownButton">
+					<span>Show Tooltip Dialog</span>
+					<div dojoType="dijit.TooltipDialog" id="tooltipDlg" title="Enter Login information"
+						execute="alert('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
+						<table>
+							<tr>
+								<td><label for="user">User:</label></td>
+								<td><input dojoType=dijit.form.TextBox type="text" id="user" name="user" ></td>
+							</tr>
+							<tr>
+								<td><label for="pwd">Password:</label></td>
+								<td><input dojoType=dijit.form.TextBox type="password" id="pwd" name="pwd"></td>
+							</tr>
+							<tr>
+								<td colspan="2" align="center">
+									<button dojoType=dijit.form.Button type="submit" name="submit">Login</button>
+							</tr>
+						</table>
+					</div>
+				</div>
+			</div>
+			</div>
+
+			<div dojoType="dijit.layout.ContentPane" title="Dojo Tree from Store">
+				<!-- tree widget -->
+				<div dojoType="dijit.Tree" store="continentStore" query="{type:'continent'}"
+					label="Continents" openOnClick="true">
+				</div>
+			</div>
+
+			<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true">
+				<!-- calendar widget pane -->
+				<input id="calendar1" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
+			</div>
+
+			<div dojoType="dijit.layout.ContentPane" title="Color Picker">
+				<p>
+					Selecting a color will change the background color of the page.
+					Use this to test how tooltips and drop downs appear with different backgrounds.
+				</p>
+				<h2 class="testHeader">3x4</h2>
+				<script>
+					function setBackground(color){
+						dojo.query('.dijitAccordionBody').style('background', color);
+						dojo.query('.dijitTabPaneWrapper').style('background', color);
+					}
+				</script>
+				<div dojoType="dijit.ColorPalette"  palette="3x4" onChange="setBackground(arguments[0]);"></div>
+				<h2 class="testHeader">7x10</h2>
+				<div dojoType="dijit.ColorPalette" onChange="setBackground(arguments[0]);"></div>
+			</div>
+			<div dojoType="dijit.layout.TabContainer" useMenu="false" title="Sliding TabContainer"
+						id="slidingTab">
+				<div dojoType="dijit.layout.ContentPane" title="Information">
+					This tab container uses slide controls when the tabs are too wide to fit beside each other.
+					If you make the left column narrow enough, the slide controls should appear.
+				</div>
+				<div dojoType="dijit.layout.ContentPane" title="Rootless Tree" closable="true">
+					<div
+						dojoType="dijit.Tree"
+						id="rootlessTree"
+						store="continentStore"
+						query="{type:'continent'}"
+						openOnClick="true">
+					</div>
+
+				</div>
+				<div dojoType="dijit.layout.TabContainer"
+						id="inlined" closable="true"
+						title="Nested TabContainer" nested="true">
+					<a dojoType="dijit.layout.LinkPane" id="tab1href" href="../tests/layout/tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
+					<a dojoType="dijit.layout.LinkPane" id="tab2href" href="../tests/layout/tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
+					<div dojoType="dijit.layout.ContentPane" id="subtab3" title="SubTab 3">
+						<h1>I am tab 3, inlined.</h1>
+					</div>
+					<div dojoType="dijit.layout.ContentPane" id="subtab4" title="SubTab 4">
+						<h1>I am tab 4, inlined.</h1>
+					</div>
+				</div>
+				<div dojoType="dijit.layout.ContentPane" title="Menu Bar" closable="true">
+					<div id="menubar" dojoType="dijit.MenuBar">
+					<div dojoType="dijit.PopupMenuBarItem" >
+						<span>File</span>
+						<div dojoType="dijit.Menu">
+							<div dojoType="dijit.MenuItem" iconClass="dijitIconNewTask">New</div>
+							<div dojoType="dijit.MenuItem">Open</div>
+							<div dojoType="dijit.MenuSeparator"></div>
+							<div dojoType="dijit.MenuItem" iconClass="dijitIconSave">Save</div>
+							<div dojoType="dijit.MenuItem">Save As...</div>
+						</div>
+					</div>
+					<div dojoType="dijit.PopupMenuBarItem">
+						<span>Edit</span>
+						<div dojoType="dijit.Menu" >
+							<div dojoType="dijit.MenuItem"  iconClass="dijitIconCut"
+								onClick="console.log('not actually cutting anything, just a test!')">Cut</div>
+							<div dojoType="dijit.MenuItem"  iconClass="dijitIconCopy"
+								onClick="console.log('not actually copying anything, just a test!')">Copy</div>
+							<div dojoType="dijit.MenuItem"  iconClass="dijitIconPaste"
+								onClick="console.log('not actually pasting anything, just a test!')">Paste</div>
+						</div>
+					</div>
+					<div dojoType="dijit.PopupMenuBarItem">
+						<span>View</span>
+						<div dojoType="dijit.Menu">
+							<div dojoType="dijit.MenuItem">Normal</div>
+							<div dojoType="dijit.MenuItem">Outline</div>
+							<div dojoType="dijit.PopupMenuItem">
+								<span>Zoom</span>
+								<div dojoType="dijit.Menu">
+									<div dojoType="dijit.MenuItem">50%</div>
+									<div dojoType="dijit.MenuItem">75%</div>
+									<div dojoType="dijit.MenuItem">100%</div>
+									<div dojoType="dijit.MenuItem">150%</div>
+									<div dojoType="dijit.MenuItem">200%</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					<div dojoType="dijit.PopupMenuBarItem">
+						<span>Help</span>
+						<div dojoType="dijit.Menu">
+							<div dojoType="dijit.MenuItem">Help Topics</div>
+							<div dojoType="dijit.MenuItem">About Dijit</div>
+						</div>
+					</div>
+					<div dojoType="dijit.PopupMenuBarItem" disabled="true">
+						<span>Disabled</span>
+						<div dojoType="dijit.Menu">
+							<div dojoType="dijit.MenuItem">You should not see this</div>
+						</div>
+					</div>
+					<div dojoType="dijit.MenuBarItem" onclick="alert('no submenu, just a clickable MenuItem');">
+						Click me!
+					</div>
+				</div>
+				</div>
+			</div>
+
+
+		</div><!-- end AccordionContainer -->
+
+		<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
+		<div dojoType="dijit.layout.TabContainer" region="center" id="topTabs" tabStrip="true">
+
+			<div id="basicFormTab" dojoType="dijit.layout.ContentPane" title="Basic Form Widgets" style="padding:10px;display:none;">
+
+				<h2>Buttons</h2>
+				<p>Buttons can do an action, display a menu, or both:</p>
+
+				Enabled:
+
+				<button dojoType="dijit.form.Button" iconClass="dijitIconTask" onClick='console.debug("clicked simple")'>
+					Simple
+				</button>
+
+				<button dojoType="dijit.form.DropDownButton" iconClass="dijitIconEdit">
+					<span>Drop Down</span>
+					<div dojoType="dijit.Menu" id="editMenu1" style="display: none;">
+						<div dojoType="dijit.MenuItem"
+							iconClass="dijitIconCut"
+							onClick="console.debug('not actually cutting anything, just a test!')">
+							Cut
+						</div>
+
+						<div dojoType="dijit.MenuItem"
+							 iconClass="dijitIconCopy"
+							onClick="console.debug('not actually copying anything, just a test!')">
+							Copy
+						</div>
+
+						<div dojoType="dijit.MenuItem"
+							 iconClass="dijitIconPaste"
+							onClick="console.debug('not actually pasting anything, just a test!')">
+							Paste
+						</div>
+					</div>
+				</button>
+
+				<button dojoType="dijit.form.ComboButton" iconClass="dijitIconSave"
+					optionsTitle='save options'
+					onClick='console.debug("clicked combo save")'>
+					<span>Combo</span>
+					<div dojoType="dijit.Menu" id="saveMenu1" style="display: none;">
+						<div dojoType="dijit.MenuItem"
+							 iconClass="dijitIconSave"
+							onClick="console.debug('not actually saving anything, just a test!')">
+							Save
+						</div>
+						<div dojoType="dijit.MenuItem"
+							onClick="console.debug('not actually saving anything, just a test!')">
+							Save As
+						</div>
+					</div>
+				</button>
+
+				<button dojoType="dijit.form.ToggleButton" checked onChange="console.log('toggled button checked='+arguments[0]);" iconClass="dijitCheckBoxIcon">
+					Toggle
+				</button>
+
+				<hr class="spacer">
+
+				Disabled:
+
+				<button dojoType="dijit.form.Button" iconClass="dijitIconTask" disabled>
+					Simple
+				</button>
+
+				<button dojoType="dijit.form.DropDownButton" iconClass="dijitIconEdit" disabled>
+					<span>Drop Down</span>
+					<div dojoType="dijit.Menu" id="editMenu2" style="display: none;">
+						<div dojoType="dijit.MenuItem"
+							iconClass="dijitIconCut"
+							onClick="console.debug('not actually cutting anything, just a test!')">
+							Cut
+						</div>
+
+						<div dojoType="dijit.MenuItem"
+							 iconClass="dijitIconCopy"
+							onClick="console.debug('not actually copying anything, just a test!')">
+							Copy
+						</div>
+
+						<div dojoType="dijit.MenuItem"
+							 iconClass="dijitIconPaste"
+							onClick="console.debug('not actually pasting anything, just a test!')">
+							Paste
+						</div>
+					</div>
+				</button>
+
+				<button dojoType="dijit.form.ComboButton" iconClass="dijitIconSave"
+					optionsTitle='save options'
+					disabled>
+					<span>Combo</span>
+					<div dojoType="dijit.Menu" id="saveMenu2" style="display: none;">
+						<div dojoType="dijit.MenuItem"
+							 iconClass="dijitIconSave"
+							onClick="console.debug('not actually saving anything, just a test!')">
+							Save
+						</div>
+						<div dojoType="dijit.MenuItem"
+							onClick="console.debug('not actually saving anything, just a test!')">
+							Save As
+						</div>
+					</div>
+				</button>
+
+				<button dojoType="dijit.form.ToggleButton" checked disabled iconClass="dijitCheckBoxIcon">
+					Toggle
+				</button>
+
+				<hr class="spacer">
+
+				<h2>CheckBox</h2>
+				<fieldset>
+					<input id="check1" type="checkBox" dojoType="dijit.form.CheckBox">
+					<label for="check1">unchecked</label>
+
+					<input id="check2" type="checkBox" dojoType="dijit.form.CheckBox" checked="checked">
+					<label for="check2">checked</label>
+
+					<input id="check3" type="checkBox" dojoType="dijit.form.CheckBox" disabled>
+					<label for="check3">disabled</label>
+
+					<input id="check4" type="checkBox" dojoType="dijit.form.CheckBox" checked="checked" disabled>
+					<label for="check4">disabled and checked</label>
+				</fieldset>
+
+				<h2>Radio Buttons</h2>
+				<fieldset>
+					<input type="radio" name="g1" id="g1rb1" value="news" dojoType="dijit.form.RadioButton">
+					<label for="g1rb1">news</label>
+					<input type="radio" name="g1" id="g1rb2" value="talk" dojoType="dijit.form.RadioButton" checked>
+					<label for="g1rb2">talk</label>
+					<input type="radio" name="g1" id="g1rb3" value="weather" dojoType="dijit.form.RadioButton" disabled>
+					<label for="g1rb3">weather (disabled)</label>
+				</fieldset>
+			</div> <!-- end of basic form widgets -->
+
+			<div id="textboxTab" dojoType="dijit.layout.ContentPane" title="Text Input Widgets" style="padding:10px;display:none;">
+
+				<h2>dijit.form.DateTextBox</h2>
+				<label for="date1">Enabled w/placeHolder:</label>
+				<input id="date1" name="date1" type="text" dojoType="dijit.form.DateTextBox" placeHolder="Birthday">
+				<label for="date2">Disabled w/placeHolder:</label>
+				<input id="date2" name="date2" type="text" dojoType="dijit.form.DateTextBox" placeHolder="Birthday" disabled="disabled">
+				<label for="date2">Disabled w/value:</label>
+				<input id="date3" name="date3" type="text" dojoType="dijit.form.DateTextBox" value="2008-12-25" disabled="disabled">
+
+				<h2>dijit.form.TimeTextBox</h2>
+				<label for="time1">Enabled:</label>
+				<input id="time1" name="time1" type="text" dojoType="dijit.form.TimeTextBox" value="T17:45:00">
+				<label for="time2">Disabled:</label>
+				<input id="time2" name="time2" type="text" dojoType="dijit.form.TimeTextBox" value="T17:45:00" disabled>
+
+				<h2>dijit.form.CurrencyTextBox</h2>
+				<label for="currency1">Enabled:</label>
+				<input id="currency1" type="text" name="income1" value="54775.53"
+					dojoType="dijit.form.CurrencyTextBox"
+					required="true"
+					constraints="{fractional:true}"
+					currency="USD"
+					invalidMessage="Invalid amount.  Include dollar sign, commas, and cents.  Cents are mandatory.">
+				<label for="currency2">Disabled:</label>
+				<input id="currency2" type="text" name="income1" value="54775.53"
+					dojoType="dijit.form.CurrencyTextBox"
+					required="true"
+					constraints="{fractional:true}"
+					currency="USD"
+					invalidMessage="Invalid amount.  Include dollar sign, commas, and cents.  Cents are mandatory." disabled>
+
+				<hr class="spacer">
+
+				<h2>dijit.form.NumberSpinner max=100</h2>
+				<label for="spinner1">Enabled: </label>
+				<input dojoType="dijit.form.NumberSpinner" constraints="{max:100,places:0}" id="spinner1" value="10">
+				<label for="spinner2">Disabled: </label>
+				<input dojoType="dijit.form.NumberSpinner" constraints="{max:100,places:0}" id="spinner2" value="10" disabled>
+
+			</div>
+
+			<div id="selectTab" dojoType="dijit.layout.ContentPane" title="Select Widgets" style="padding:10px;display:none;">
+
+				<h2>dijit.form.Select</h2>
+				<label for="selectEnabled">Enabled: </label>
+				<div id="selectEnabled" value="AK" dojoType="dijit.form.Select">
+					<span value="AL"><b>Alabama</b></span>
+					<span value="AK"><font color="red">A</font><font color="orange">l</font><font color="yellow">a</font><font color="green">s</font><font color="blue">k</font><font color="purple">a</font></span>
+					<span value="AZ"><i>Arizona</i></span>
+					<span value="AR"><span class="ark">Arkansas</span></span>
+					<span value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+					<span value="NM" disabled="disabled">New<br>  Mexico</span>
+				</div>
+	
+				<label for="selectDisabled">Disabled: </label>
+				<div id="selectDisabled" value="AK" dojoType="dijit.form.Select" disabled>
+					<span value="AL"><b>Alabama</b></span>
+					<span value="AK"><font color="red">A</font><font color="orange">l</font><font color="yellow">a</font><font color="green">s</font><font color="blue">k</font><font color="purple">a</font></span>
+					<span value="AZ"><i>Arizona</i></span>
+					<span value="AR"><span class="ark">Arkansas</span></span>
+					<span value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+					<span value="NM" disabled="disabled">New<br>  Mexico</span>
+				</div>
+
+				<hr class="spacer">
+
+				<h2>dijit.form.FilteringSelect</h2>
+				<label for="filteringSelect">Enabled w/placeHolder: </label>
+				<input dojoType="dijit.form.FilteringSelect"
+					placeHolder="State"
+					store="stateStore"
+					searchAttr="name"
+					name="state2"
+					id="filteringSelect"
+				>
+				<label for="filteringSelect2">Disabled w/placeHolder: </label>
+				<input dojoType="dijit.form.FilteringSelect"
+					placeHolder="State"
+					store="stateStore"
+					searchAttr="name"
+					name="state2"
+					id="filteringSelect2"
+					disabled
+				>
+				<label for="filteringSelect3">Disabled w/value: </label>
+				<input dojoType="dijit.form.FilteringSelect"
+					value="California"
+					store="stateStore"
+					searchAttr="name"
+					name="state3"
+					id="filteringSelect3"
+					disabled
+				>
+
+
+			</div>
+
+			<div id="textareaTab" dojoType="dijit.layout.ContentPane" title="Textarea" style="padding:10px;">
+
+				<!--	‪ and ‬ are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that
+					cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
+				<h2>dijit.form.Textarea</h2>
+				<p>Enabled:</p>
+				<textarea dojoType="dijit.form.Textarea" name="areText">This text area will expand and contract as you type ‪text.‬
+
+Lorem ipsum dolor sit ‪amet,‬
+consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
+tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo ‪consequat.‬
+				</textarea>
+
+				<br>
+				<p>Disabled:</p>
+				<textarea dojoType="dijit.form.Textarea" name="areText2" disabled>This text
+				area is disabled and you shouldn't be able to type in ‪it.‬
+				</textarea>
+
+
+				<h2>dijit.form.SimpleTextarea</h2>
+				<p></p>
+				<p>Enabled:</p>
+				<textarea dojoType="dijit.form.SimpleTextarea" name="areText">This text area has a constant height and displays a scrollbar when ‪necessary.‬
+
+Lorem ipsum dolor sit ‪amet,‬
+consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
+tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
+autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ‪consequat,‬
+vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
+dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
+nulla ‪facilisi.‬
+				</textarea>
+
+				<p>Disabled:</p>
+				<textarea dojoType="dijit.form.SimpleTextarea" name="areText2" disabled>Lorem ipsum dolor sit ‪amet,‬
+				consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
+				dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
+				tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
+				autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie ‪consequat,‬
+				vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio
+				dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait
+				nulla ‪facilisi.‬
+				</textarea>
+			</div><!-- end of Textarea tab -->
+
+			<div id="editorTab" dojoType="dijit.layout.ContentPane" title="Editor" style="padding:10px;">
+				<p>Enabled:</p>
+				<!-- FIXME:
+					set height on this node to size the whole editor, but causes the tab to not scroll
+					until you select another tab and come back. alternative is no height: here, but that
+					causes editor to become VERY tall, and size to a normal height when selected (like the
+					dijit.form.TextArea in "Form Feel" Tab), but in reverse. refs #3980 and is maybe new bug?
+				-->
+				<div height="175" dojoType="dijit.Editor" extraPlugins="['|', 'createLink', 'fontName']" styleSheets="../themes/claro/document.css">
+					<ul>
+						<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
+						<li>This is the Editor with a Toolbar attached.</li>
+					</ul>
+				</div>
+				<p>Disabled:</p>
+				<div height="175" dojoType="dijit.Editor" extraPlugins="['|', 'createLink', 'fontName']" styleSheets="../themes/claro/document.css" disabled="true">
+					<ul>
+						<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
+						<li>This is the Editor with a Toolbar attached.</li>
+					</ul>
+				</div>
+			</div><!-- end of Editor tab -->
+
+
+			<div dojoType="dijit.layout.ContentPane" title="Sliders" style="padding:10px;display:none;">
+
+
+				<!-- Sliders: -->
+
+				<h2>Enabled</h2>
+				<div style="float:right;">
+				<div dojoType="dijit.form.VerticalSlider"
+					onChange="dojo.byId('slider2input').value=arguments[0];"
+					value="10"
+					maximum="100"
+					minimum="0"
+					discreteValues="11"
+					style="height:176px; clear:both;"
+					id="slider2">
+						<ol dojoType="dijit.form.VerticalRuleLabels" container="leftDecoration"style="width:2em;" labelStyle="right:0px;">
+							<li>0
+							<li>100
+						</ol>
+
+						<div dojoType="dijit.form.VerticalRule" container="leftDecoration" count=11 style="width:5px;"></div>
+						<div dojoType="dijit.form.VerticalRule" container="rightDecoration" count=11 style="width:5px;"></div>
+						<ol dojoType="dijit.form.VerticalRuleLabels" container="rightDecoration"style="width:2em;" maximum="100" count="6" numericMargin="1" constraints="{pattern:'#'}"></ol>
+				</div>
+				<br> Slider2 Value:<input disabled id="slider2input" size="3" value="10" autocomplete="off">
+				</div>
+
+				<div dojoType="dijit.form.HorizontalSlider"
+					onChange="dojo.byId('slider1input').value=dojo.number.format(arguments[0]/100,{places:1,pattern:'#%'});"
+					value="10"
+					maximum="100"
+					minimum="0"
+					showButtons="false"
+					intermediateChanges="true"
+					style="width:50%; height: 20px;"
+					id="horizontal1">
+						<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;" numericMargin="1" count="6"></ol>
+						<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=11 style="height:5px;"></div>
+						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div>
+						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
+							<li>lowest
+							<li>normal
+							<li>highest
+						</ol>
+
+				</div>
+				<br>Value: <input disabled id="slider1input" size="5" value="10.0%" autocomplete="off">
+
+				<div dojoType="dijit.form.HorizontalSlider"
+					minimum="1"
+					value="2"
+					maximum="3"
+					discreteValues="3"
+					showButtons="false"
+					intermediateChanges="true"
+					style="width:300px; height: 40px;"
+					id="horizontal2">
+						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=3 style="height:5px;"></div>
+						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration"style="height:1em;font-size:75%;">
+							<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
+							<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
+
+							<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
+						</ol>
+				</div>
+
+				<h2 style="clear:both">Disabled</h2>
+				<div style="float:right;">
+				<div dojoType="dijit.form.VerticalSlider"
+					value="10"
+					maximum="100"
+					minimum="0"
+					discreteValues="11"
+					style="height:175px; clear:both"
+					disabled>
+						<ol dojoType="dijit.form.VerticalRuleLabels" container="leftDecoration"style="width:2em;" labelStyle="right:0px;">
+							<li>0
+							<li>100
+						</ol>
+
+						<div dojoType="dijit.form.VerticalRule" container="leftDecoration" count=11 style="width:5px;"></div>
+						<div dojoType="dijit.form.VerticalRule" container="rightDecoration" count=11 style="width:5px;"></div>
+						<ol dojoType="dijit.form.VerticalRuleLabels" container="rightDecoration"style="width:2em;" maximum="100" count="6" numericMargin="1" constraints="{pattern:'#'}"></ol>
+				</div>
+				</div>
+				<div dojoType="dijit.form.HorizontalSlider"
+					value="10"
+					maximum="100"
+					minimum="0"
+					showButtons="false"
+					intermediateChanges="true"
+					style="width:50%; height: 20px;"
+					disabled>
+						<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;" numericMargin="1" count="6"></ol>
+						<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=11 style="height:5px;"></div>
+						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div>
+						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
+							<li>lowest
+							<li>normal
+							<li>highest
+						</ol>
+
+				</div>
+
+				<div dojoType="dijit.form.HorizontalSlider"
+					minimum="1"
+					value="2"
+					maximum="3"
+					discreteValues="3"
+					showButtons="false"
+					intermediateChanges="true"
+					style="width:300px; height: 40px;"
+					disabled>
+						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=3 style="height:5px;"></div>
+						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration"style="height:1em;font-size:75%;">
+							<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
+							<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
+							<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
+						</ol>
+				</div>
+			</div>
+
+			<div id="variousTab" dojoType="dijit.layout.ContentPane" title="Various Dijits"
+				style="padding:10px; display:none;">
+
+
+				<h2>TitlePane</h2>
+				<div dojoType="dijit.TitlePane" title="my pane" width="275">
+					<p>This is a title pane.  It can be expanded and collapsed.</p>
+
+					<p>Sed sollicitudin suscipit risus. Nam
+					ullamcorper. Sed nisl lectus, pellentesque nec,
+					malesuada eget, ornare a, libero. Lorem ipsum dolor
+					sit amet, consectetuer adipiscing elit.</p>
+
+				</div><!-- end title pane -->
+
+				<hr class="spacer">
+
+				<h2>ProgressBar</h2>
+				<div style="width:400px;" maximum="200" id="setTestBar"
+					progress="20" dojoType="dijit.ProgressBar"></div>
+
+				Indeterminate:
+				<div style="width:400px;" indeterminate="true" dojoType="dijit.ProgressBar"></div>
+
+			</div><!-- end:various dijits upper tab -->
+
+			<div id="InlineEditBoxTab" dojoType="dijit.layout.ContentPane" title="InlineEditBox"
+				style="padding:10px; display:none;">
+
+				<h2 class="testTitle">dijit.InlineEditBox + dijit.form.TextBox on <h3></h2>
+
+				(HTML before)
+				<h3 id="editable" style="font-size:larger;" dojoType="dijit.InlineEditBox" onChange="myHandler(this.id,arguments[0])">
+					Edit me - I trigger the onChange callback
+				</h3>
+				(HTML after)
+
+				<hr class="spacer">
+
+				<h2>dijit.InlineEditBox + dijit.form.Textarea</h2>
+
+				(HTML before)
+				<p id="areaEditable" dojoType="dijit.InlineEditBox" editor="dijit.form.Textarea" autoSave="false">
+					I'm one big ‪paragraph.‬  Go ahead and edit ‪me.‬  I dare ‪you.‬
+					The quick brown fox jumped over the lazy ‪dog.‬  Blah blah blah blah blah blah ‪blah ...‬
+				</p>
+				(HTML after)
+
+				<p>
+					These links will
+					<a href="#" onClick="dijit.byId('areaEditable').set('disabled', true)">disable</a> /
+					<a href="#" onClick="dijit.byId('areaEditable').set('disabled', false)">enable</a>
+					the text area above.
+				</p>
+
+				<hr class="spacer">
+
+				<h2>dijit.form.DateTextBox</h2>
+
+				(HTML inline before)
+				<!-- set programmatically to match locale; a server might generate this content also. -->
+				<span id="backgroundArea" dojoType="dijit.InlineEditBox" editor="dijit.form.DateTextBox" width="170px"></span>
+				(HTML after)
+				<hr class="spacer">
+
+				<h2>dijit.form.TimeTextBox</h2>
+
+				(HTML inline before)
+				<!-- set programmatically to match locale; a server might generate this content also. -->
+				<span id="timePicker" dojoType="dijit.InlineEditBox" editor="dijit.form.TimeTextBox" width="150px"></span>
+				(HTML after)
+
+				<hr class="spacer">
+
+
+				<h2>dijit.form.FilteringSelect + Inline + remote data store</h2>
+				(HTML inline before)
+				<span id="backgroundArea2" dojoType="dijit.InlineEditBox" editor="dijit.form.FilteringSelect"
+					editorParams="{store: stateStore, autoComplete: true, promptMessage: 'Please enter a state'}"
+					width="300px">
+					Indiana
+				</span>
+				(HTML after)
+
+			</div><!-- end InlineEditBox tab -->
+
+			<div id="dndTab" dojoType="dijit.layout.ContentPane" title="DnD"
+				style="padding:10px; display:none;">
+				<div style="float:left; margin:5px;">
+					<h3>Source 1</h3>
+					<div dojoType="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
+						<div class="dojoDndItem">Item <strong>X</strong></div>
+						<div class="dojoDndItem">Item <strong>Y</strong></div>
+						<div class="dojoDndItem">Item <strong>Z</strong></div>
+					</div>
+				</div>
+				<div style="float:left; margin:5px; ">
+					<h3>Source 2</h3>
+					<div dojoType="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
+						<div class="dojoDndItem">Item <strong>1</strong></div>
+						<div class="dojoDndItem">Item <strong>2</strong></div>
+						<div class="dojoDndItem">Item <strong>3</strong></div>
+					</div>
+				</div>
+			</div><!-- end DnD tab -->
+
+			<div id="closableTab" dojoType="dijit.layout.ContentPane" title="Closable"
+				style="display:none; padding:10px; " closable="true">
+				This pane is closable, just for the icon ...
+			</div>
+		</div><!-- end of region="center" TabContainer -->
+
+		<!-- bottom right tabs -->
+		<div dojoType="dijit.layout.TabContainer" id="bottomTabs"
+			tabPosition="bottom" selectedChild="btab1" region="bottom" splitter="true" tabStrip="true">
+
+			<!-- btab 1 -->
+			<div id="btab1" dojoType="dijit.layout.ContentPane" title="Info" style=" padding:10px; ">
+				<p>You can explore this single page after applying a Theme
+				for use in creation of your own theme.</p>
+
+				<p>I am whole slew of Widgets on a page. Jump to <a href="../tests/">dijit tests</a> to
+				test individual components.</p>
+
+				<p>There is a right-click [context] pop-up menu here, as well.</p>
+			</div><!-- end:info btab1 -->
+
+			<div id="btab2" dojoType="dijit.layout.ContentPane" title="Alternate Themes" style="padding:20px;">
+				<span id="themeData"></span>
+			</div><!-- btab2 -->
+
+			<div id="btab3" dojoType="dijit.layout.ContentPane" title="Bottom 3" closable="true">
+				<p>I am the last Tab</p>
+				<div id="dialog2" dojoType="dijit.Dialog" title="Encased Dialog" style="display:none;">
+				I am the second dialog. I am
+				parented by the Low Tab Pane #3
+				</div>
+			</div><!-- btab3 -->
+
+		</div><!-- end Bottom TabContainer -->
+
+	</div><!-- end of BorderContainer -->
+
+	<!-- dialog in body -->
+	<div id="dialog1" dojoType="dijit.Dialog"
+		title="Floating Modal Dialog from href" style="display:none; width: 400px;"
+		href="../tests/layout/getResponse.php?delay=3000&messId=3" refreshOnShow="true"></div>
+	<div id="dialogAB" dojoType="dijit.Dialog"
+		title="Floating Modal Dialog" style="display:none;">
+		<div class="dijitDialogPaneContentArea">
+			<table>
+				<tr>
+					<td><label for="name">Name: </label></td>
+					<td><input dojoType=dijit.form.TextBox type="text" name="name" id="name"></td>
+				</tr>
+				<tr>
+					<td><label for="loc">Location: </label></td>
+					<td><input dojoType=dijit.form.TextBox type="text" name="loc" id="loc"></td>
+				</tr>
+				<tr>
+					<td><label for="date">Date: </label></td>
+					<td><input dojoType=dijit.form.DateTextBox type="text" name="date" id="date"></td>
+				</tr>
+			</table>
+		</div>
+		
+		
+		<div class="dijitDialogPaneActionBar">
+			<button dojoType="dijit.form.Button" type="submit" id="ABdialog1button1">OK</button>
+			<button dojoType="dijit.form.Button" type="button" onClick="dijit.byId('dialogAB').onCancel();" 
+					id="ABdialog1button2">Cancel</button>
+		</div>
+	</div>
+
+</body>
+</html>
diff --git a/dijit/themes/themeTester.html b/dijit/themes/themeTester.html
index b941691..4ae622c 100644
--- a/dijit/themes/themeTester.html
+++ b/dijit/themes/themeTester.html
@@ -1,22 +1,30 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-	"http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
+
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+
 	<title>Dijit Theme Tester</title>
 
+	<script>
+		var startTime = new Date();
+	</script>
+
 	<!-- required: a default theme -->
-	<link id="themeStyles" rel="stylesheet" href="../../dijit/themes/claro/claro.css">
+	<link rel="stylesheet" href="../themes/claro/document.css"/>
+	<link rel="stylesheet" href="../../dijit/themes/claro/claro.css"/>
+	<link rel="stylesheet" href="../tests/css/dijitTests.css"/>
 
 	<style type="text/css">
-		@import "../../dojo/resources/dojo.css";
-		@import "../tests/css/dijitTests.css";
-
 		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%; }
-
+		#hs-1width {
+			width:400px;
+			height:40px;
+		}
 		/* pre-loader specific stuff to prevent unsightly flash of unstyled content */
 		#loader {
 			padding:0;
@@ -38,6 +46,11 @@
 			color:#fff;
 		}
 
+		#indTestBar,
+		#setTestBar {
+			width:400px;
+		}
+		
 		hr.spacer { border:0; background-color:#ededed; width:80%; height:1px; }
 
 		/* rules used to test custom setting of TextBox padding */
@@ -51,7 +64,7 @@
 
 	<!-- a check for stray globals: not needed! -->
 	<script type="text/javascript">
-		window.__globalList = {dojo: true, dijit: true, dojox: true, djConfig: true};
+		window.__globalList = { dojo: true, dijit: true, dojox: true, dojoConfig:true };
 		for(var i in window){
 			window.__globalList[i] = true;
 		}
@@ -59,18 +72,16 @@
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../dojo/dojo.js"
-		djConfig="parseOnLoad: false, isDebug: true"></script>
+		data-dojo-config="parseOnLoad: false, isDebug: true"></script>
 
 	<!-- do not use: only for debugging / testing themes -->
 	<script type="text/javascript" src="../tests/_testCommon.js"></script>
-	<!--
-	<script type="text/javascript" src="http://prototypejs.org/assets/2007/10/16/prototype.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()
+	<script type="text/javascript"> // dojo.requires(), explicitly. 
 
 		dojo.require("dijit.Menu");
 		dojo.require("dijit.MenuItem");
@@ -81,7 +92,9 @@
 		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");
@@ -123,73 +136,79 @@
 		dojo.require("dijit.layout.LinkPane");
 		dojo.require("dijit.Dialog");
 
-		// scan page for widgets and instantiate them
 		dojo.require("dojo.parser");
 
-		// humm?
 		dojo.require("dojo.date.locale");
 
-		// for the Tree
 		dojo.require("dojo.data.ItemFileReadStore");
 
-		// for the colorpalette
-		function setColor(color){
-			var theSpan = dojo.byId("outputSpan");
-			dojo.style(theSpan,"color",color);
-			theSpan.innerHTML = color;
+		// 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");
 		}
-
-		// for the calendar
-		function myHandler(id,newValue){
-			console.debug("onChange for id = " + id + ", value: " + newValue);
+		
+		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");
 		}
 
-		// current setting (if there is one) to override theme default padding on TextBox based widgets
-		currentInputPadding = "";
-
-		function setTextBoxPadding(){
-			// 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");
+		var setTextBoxPadding;
+		(function(){
+			// current setting (if there is one) to override theme default padding on TextBox based widgets
+			var currentInputPadding = "";
 			
-			// 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);
+			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);
-		}
+	
+				// val will be "theme default", "0px", "1px", ..., "5px"
+				var val = this.get("label");
+				
+				// Set class on body to get requested padding, and remove any previously set class
+				if(currentInputPadding){
+					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);
+					}
+				}, this);
+			}
+		})();
 
 		dojo.addOnLoad(function() {
 
-			var start = new Date().getTime();
+			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().getTime() - start) + "ms");
+			console.info("Total parse time: " + (+new Date() - loadCompleteTime) + "ms");
 
 			dojo.byId('loaderInner').innerHTML += " done.";
 			setTimeout(function hideLoader(){
-				var loader = dojo.byId('loader');
-				dojo.fadeOut({ node: loader, duration:500,
-					onEnd: function(){
-						loader.style.display = "none";
+				dojo.fadeOut({ 
+					node: 'loader', 
+					duration:500,
+					onEnd: function(n){
+						n.style.display = "none";
 					}
 				}).play();
 			}, 250);
@@ -282,168 +301,155 @@
 	<div id="loader"><div id="loaderInner" style="direction:ltr;">Loading themeTester ... </div></div>
 
 	<!-- data for tree and combobox -->
-	<div dojoType="dojo.data.ItemFileReadStore" jsId="continentStore"
-		url="../tests/_data/countries.json"></div>
-	<div dojoType="dojo.data.ItemFileReadStore" jsId="stateStore"
-		url="../tests/_data/states.json"></div>
-	<!-- contentMenu popup -->
-	<div dojoType="dijit.Menu" id="submenu1" contextMenuForWindow="true" style="display: none;">
-		<div dojoType="dijit.MenuItem" onClick="alert('Hello world');">Enabled Item</div>
-		<div dojoType="dijit.MenuItem" disabled="true">Disabled Item</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitIconCut"
-			onClick="alert('not actually cutting anything, just a test!')">Cut</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitIconCopy"
-			onClick="alert('not actually copying anything, just a test!')">Copy</div>
-		<div dojoType="dijit.MenuItem" iconClass="dijitIconPaste"
-			onClick="alert('not actually pasting anything, just a test!')">Paste</div>
-		<div dojoType="dijit.MenuSeparator"></div>
-		<div dojoType="dijit.PopupMenuItem">
+	<div data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-id="continentStore"
+		data-dojo-props="url:'../tests/_data/countries.json'"></div>
+	<div data-dojo-id="continentModel" data-dojo-type="dijit.tree.ForestStoreModel" data-dojo-props='store:continentStore, query:{type:"continent"},
+		rootId:"continentRoot", rootLabel:"Continents", childrenAttrs:["children"]'></div>
+	<div data-dojo-type="dojo.data.ItemFileReadStore" data-dojo-id="stateStore"
+		data-dojo-props="url:'../tests/_data/states.json'"></div>
+	<!-- contentMenu popup -->												<!-- redundant display:none required here? -->
+	<div data-dojo-type="dijit.Menu" id="submenu1" data-dojo-props='contextMenuForWindow:true, style:"display:none"' style="display: none;">
+		<div data-dojo-type="dijit.MenuItem" 
+			data-dojo-props="onClick:function(){ alert('Hello world'); }">Enabled Item</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props="disabled:true">Disabled Item</div>
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconCut', onClick: function(){ alert('not actually cutting anything. Just a test!'); }">Cut</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconCopy', onClick:function(){ alert('not actually copying anything, just a test!'); }">Copy</div>
+		<div data-dojo-type="dijit.MenuItem" data-dojo-props="iconClass:'dijitIconPaste', onClick: function(){ alert('not actually pasting anything, just a test!'); }">Paste</div>
+		<div data-dojo-type="dijit.MenuSeparator"></div>
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Enabled Submenu</span>
-			<div dojoType="dijit.Menu" id="submenu2">
-				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
-				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
-				<div dojoType="dijit.PopupMenuItem">
+			<div data-dojo-type="dijit.Menu" id="submenu2">
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: function(){ alert('Submenu 1!') }">Submenu Item One</div>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: function(){ alert('Submenu 2!') }">Submenu Item Two</div>
+				<div data-dojo-type="dijit.PopupMenuItem">
 					<span>Deeper Submenu</span>
-					<div dojoType="dijit.Menu" id="submenu4">
-						<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 1!')">Sub-sub-menu Item One</div>
-						<div dojoType="dijit.MenuItem" onClick="alert('Sub-submenu 2!')">Sub-sub-menu Item Two</div>
+					<div data-dojo-type="dijit.Menu" id="submenu4">
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Sub-submenu 1!')}">Sub-sub-menu Item One</div>
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Sub-submenu 2!')}">Sub-sub-menu Item Two</div>
 					</div>
 				</div>
 			</div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem" disabled="true">
+		<div data-dojo-type="dijit.PopupMenuItem" data-dojo-props="disabled:true">
 			<span>Disabled Submenu</span>
-			<div dojoType="dijit.Menu" id="submenu3" style="display: none;">
-				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 1!')">Submenu Item One</div>
-				<div dojoType="dijit.MenuItem" onClick="alert('Submenu 2!')">Submenu Item Two</div>
+			<div data-dojo-type="dijit.Menu" id="submenu3" style="display: none;">
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Submenu 1!')}">Submenu Item One</div>
+				<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick:function(){alert('Submenu 2!')}">Submenu Item Two</div>
 			</div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Different popup</span>
-			<div dojoType="dijit.ColorPalette"></div>
+			<div data-dojo-type="dijit.ColorPalette"></div>
 		</div>
-		<div dojoType="dijit.PopupMenuItem">
+		<div data-dojo-type="dijit.PopupMenuItem">
 			<span>Different popup</span>
-			<div dojoType="dijit.Calendar"></div>
+			<div data-dojo-type="dijit.Calendar"></div>
 		</div>
 	</div>
 	<!-- end contextMenu -->
 
-	<div id="main" dojoType="dijit.layout.BorderContainer" liveSplitters="false" design="sidebar">
+	<div id="main" data-dojo-type="dijit.layout.BorderContainer" data-dojo-props="liveSplitters:false, design:'sidebar'">
 
-		<div id="header" dojoType="dijit.MenuBar" region="top">
-			<div dojoType="dijit.PopupMenuBarItem" id="file">
+		<div id="header" data-dojo-type="dijit.MenuBar" data-dojo-props="region:'top'">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="file">
 				<span>File</span>
-				<div dojoType="dijit.Menu" id="fileMenu">
-					<div dojoType="dijit.MenuItem" id="globals" onClick="logStrayGlobals();">Log globals</div>
-					<div dojoType="dijit.MenuItem" id="widgets" onClick="logWidgets();">Log widgets</div>
-					<div dojoType="dijit.MenuItem" id="destroy" iconClass="dijitIconDelete" onClick="tearDown();">Destroy All</div>
+				<div data-dojo-type="dijit.Menu" id="fileMenu">
+					<div data-dojo-type="dijit.MenuItem" id="globals" data-dojo-props="onClick: logStrayGlobals">Log globals</div>
+					<div data-dojo-type="dijit.MenuItem" id="widgets" data-dojo-props="onClick: logWidgets">Log widgets</div>
+					<div data-dojo-type="dijit.MenuItem" id="destroy" data-dojo-props="iconClass:'dijitIconDelete', onClick:tearDown">Destroy All</div>
 				</div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" id="edit">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="edit">
 				<span>Edit</span>
-				<div dojoType="dijit.Menu" id="editMenu">
-					<div dojoType="dijit.MenuItem" id="cut" iconClass="dijitIconCut"
-						onClick="console.log('not actually cutting anything, just a test!')">Cut</div>
-					<div dojoType="dijit.MenuItem" id="copy" iconClass="dijitIconCopy"
-						onClick="console.log('not actually copying anything, just a test!')">Copy</div>
-					<div dojoType="dijit.MenuItem" id="paste" iconClass="dijitIconPaste"
-						onClick="console.log('not actually pasting anything, just a test!')">Paste</div>
-					<div dojoType="dijit.MenuSeparator" id="separator"></div>
-					<div dojoType="dijit.MenuItem" id="undo" iconClass="dijitIconUndo">Undo</div>
+				<div data-dojo-type="dijit.Menu" id="editMenu">
+					<div data-dojo-type="dijit.MenuItem" id="cut" data-dojo-props="
+						iconClass:'dijitIconCut',
+						onClick:function(){ console.log('not actually cutting anything, just a test!') }
+					">Cut</div>
+					<div data-dojo-type="dijit.MenuItem" id="copy" data-dojo-props="
+						iconClass:'dijitIconCopy',
+						onClick: function(){ console.log('not actually copying anything, just a test!') }
+					">Copy</div>
+					<div data-dojo-type="dijit.MenuItem" id="paste" data-dojo-props="iconClass:'dijitIconPaste',
+						onClick: function(){ console.log('not actually pasting anything, just a test!') }">Paste</div>
+					<div data-dojo-type="dijit.MenuSeparator" id="separator"></div>
+					<div data-dojo-type="dijit.MenuItem" id="undo" data-dojo-props="iconClass:'dijitIconUndo'">Undo</div>
 				</div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" id="view">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="view">
 				<span>View</span>
-				<div dojoType="dijit.Menu" id="viewMenu">
-					<div dojoType="dijit.MenuItem">Normal</div>
-					<div dojoType="dijit.MenuItem">Outline</div>
-					<div dojoType="dijit.PopupMenuItem">
+				<div data-dojo-type="dijit.Menu" id="viewMenu">
+					<div data-dojo-type="dijit.MenuItem">Normal</div>
+					<div data-dojo-type="dijit.MenuItem">Outline</div>
+					<div data-dojo-type="dijit.PopupMenuItem">
 						<span>Zoom</span>
-						<div dojoType="dijit.Menu" id="zoomMenu">
-							<div dojoType="dijit.MenuItem">50%</div>
-							<div dojoType="dijit.MenuItem">75%</div>
-							<div dojoType="dijit.MenuItem">100%</div>
-							<div dojoType="dijit.MenuItem">150%</div>
-							<div dojoType="dijit.MenuItem">200%</div>
+						<div data-dojo-type="dijit.Menu" id="zoomMenu">
+							<div data-dojo-type="dijit.MenuItem">50%</div>
+							<div data-dojo-type="dijit.MenuItem">75%</div>
+							<div data-dojo-type="dijit.MenuItem">100%</div>
+							<div data-dojo-type="dijit.MenuItem">150%</div>
+							<div data-dojo-type="dijit.MenuItem">200%</div>
 						</div>
 					</div>
 				</div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" id="themes">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="themes">
 				<span>Themes</span>
-				<div dojoType="dijit.Menu" id="themeMenu">
-				</div>
+				<div data-dojo-type="dijit.Menu" id="themeMenu"></div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" id="dialogs">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="dialogs">
 				<span>Dialogs</span>
-				<div dojoType="dijit.Menu" id="dialogMenu">
-					<div dojoType="dijit.MenuItem">
-						<script type="dojo/method" event="onClick">
-							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");
-						</script>
-						slow loading
-					</div>
-					<div dojoType="dijit.MenuItem">
-						<script type="dojo/method" event="onClick">
-							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");
-						</script>
-						action bar
-					</div>
+				<div data-dojo-type="dijit.Menu" id="dialogMenu">
+					<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: showDialog">slow loading</div>
+					<div data-dojo-type="dijit.MenuItem" data-dojo-props="onClick: showDialogAb">action bar</div>
 				</div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" id="inputPadding">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="inputPadding">
 				<span>TextBox Padding</span>
-				<div dojoType="dijit.Menu" id="inputPaddingMenu">
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding" checked>theme default</div>
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">0px</div>
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">1px</div>
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">2px</div>
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">3px</div>
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">4px</div>
-					<div dojoType="dijit.CheckedMenuItem" onClick="setTextBoxPadding">5px</div>
+				<div data-dojo-type="dijit.Menu" id="inputPaddingMenu">
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding, checked:true">theme default</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">0px</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">1px</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">2px</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">3px</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">4px</div>
+					<div data-dojo-type="dijit.CheckedMenuItem" data-dojo-props="onClick:setTextBoxPadding">5px</div>
 				</div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" id="help">
+			<div data-dojo-type="dijit.PopupMenuBarItem" id="help">
 				<span>Help</span>
-				<div dojoType="dijit.Menu" id="helpMenu">
-					<div dojoType="dijit.MenuItem">Help Topics</div>
-					<div dojoType="dijit.MenuItem">About Dijit</div>
+				<div data-dojo-type="dijit.Menu" id="helpMenu">
+					<div data-dojo-type="dijit.MenuItem">Help Topics</div>
+					<div data-dojo-type="dijit.MenuItem">About Dijit</div>
 				</div>
 			</div>
-			<div dojoType="dijit.PopupMenuBarItem" disabled="true">
+			<div data-dojo-type="dijit.PopupMenuBarItem" data-dojo-props="disabled:true">
 				<span>Disabled</span>
-				<div dojoType="dijit.Menu">
-					<div dojoType="dijit.MenuItem">You should not see this</div>
+				<div data-dojo-type="dijit.Menu">
+					<div data-dojo-type="dijit.MenuItem">You should not see this</div>
 				</div>
 			</div>
-			<div dojoType="dijit.MenuBarItem" onclick="alert('no submenu, just a clickable MenuItem');">
+			<div data-dojo-type="dijit.MenuBarItem" data-dojo-props="onclick: function(){ alert('no submenu, just a clickable MenuItem'); }">
 				Click me!
 			</div>
 		</div>
 
-		<div dojoType="dijit.layout.AccordionContainer"
-			minSize="20" style="width: 300px;" id="leftAccordion" region="leading" splitter="true">
+		<div data-dojo-type="dijit.layout.AccordionContainer" data-dojo-props="region:'leading', splitter:true, minSize:20"
+			style="width: 300px;" id="leftAccordion">
 
-			<div dojoType="dijit.layout.ContentPane" title="Popups and Alerts"><div style="padding:8px">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Popups and Alerts"'><div style="padding:8px">
 				<h2>Tooltips</h2>
 				<ul>
 					<li>
 					<span id="ttRich"><b>rich</b> <i>text</i> tooltip</span>
-					<span dojoType="dijit.Tooltip" connectId="ttRich" style="display:none;">
+					<span data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttRich'" style="display:none;">
 						Embedded <b>bold</b> <i>RICH</i> text <span style="color:#309; font-size:x-large;">weirdness!</span>
 					</span>
 					</li>
 
-					<li><a id="ttOne" href="#bogus">anchor tooltip</a>
-					<span dojoType="dijit.Tooltip" connectId="ttOne" style="display:none;">tooltip on anchor</span>
+					<li><a id="ttOne" href='#bogus'>anchor tooltip</a>
+					<span data-dojo-type="dijit.Tooltip" data-dojo-props='connectId:"ttOne"' style="display:none;">tooltip on anchor</span>
 					</li>
 				</ul>
 
@@ -451,27 +457,27 @@
 					<tr>
 						<td></td>
 						<td>
-							<div id="ttBelow" href="#bogus">tooltip below</div>
-							<div dojoType="dijit.Tooltip" connectId="ttBelow" style="display:none; width: 100px;" position="below" >I'm <i>below</i>!</div>
+							<div id="ttBelow">tooltip below</div>
+							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttBelow', position:['below']" style="display:none; width: 100px;">I'm <i>below</i>!</div>
 						</td>
 						<td></td>
 					</tr>
 					<tr>
 						<td>
-							<div id="ttRight" href="#bogus">tooltip after</div>
-							<div dojoType="dijit.Tooltip" connectId="ttRight" style="display:none;" position="after" >I'm on the <i>right</i>!<br>(or left on RTL systems)</div>
+							<div id="ttRight">tooltip after</div>
+							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttRight', position:['after']" style="display:none;">I'm on the <i>right</i>!<br>(or left on RTL systems)</div>
 						</td>
 						<td></td>
 						<td>
-							<div id="ttLeft" href="#bogus">tooltip before</div>
-							<div dojoType="dijit.Tooltip" connectId="ttLeft" style="display:none;" position="before,after" >I'm on the <i>left</i>!<br>(or right on RTL systems)</div>
+							<div id="ttLeft">tooltip before</div>
+							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttLeft', position:['before','after']" style="display:none;">I'm on the <i>left</i>!<br>(or right on RTL systems)</div>
 						</td>
 					</tr>
 					<tr>
 						<td></td>
 						<td>
-							<div id="ttAbove" href="#bogus">tooltip above</div>
-							<div dojoType="dijit.Tooltip" connectId="ttAbove" style="display:none;" position="above" >I'm <i>above</i>!</div>
+							<div id="ttAbove">tooltip above</div>
+							<div data-dojo-type="dijit.Tooltip" data-dojo-props="connectId:'ttAbove', position:['above']" style="display:none;">I'm <i>above</i>!</div>
 						</td>
 						<td></td>
 					</tr>
@@ -485,22 +491,24 @@
 					<li><a href="#" onclick="dijit.byId('dialogAB').show()">modal dialog w/action bar</a></li>
 				</ul>
 
-				<div dojoType="dijit.form.DropDownButton">
+				<div data-dojo-type="dijit.form.DropDownButton">
 					<span>Show Tooltip Dialog</span>
-					<div dojoType="dijit.TooltipDialog" id="tooltipDlg" title="Enter Login information"
-						execute="alert('submitted w/args:\n' + dojo.toJson(arguments[0], true));">
+					<div data-dojo-type="dijit.TooltipDialog" id="tooltipDlg" data-dojo-props='
+						title:"Enter Login information",
+						execute: function(){ alert("submitted w/args:\n" + dojo.toJson(arguments[0], true)); }
+					'>
 						<table>
 							<tr>
 								<td><label for="user">User:</label></td>
-								<td><input dojoType=dijit.form.TextBox type="text" id="user" name="user" ></td>
+								<td><input data-dojo-type="dijit.form.TextBox" type="text" id="user" name="user" ></td>
 							</tr>
 							<tr>
 								<td><label for="pwd">Password:</label></td>
-								<td><input dojoType=dijit.form.TextBox type="password" id="pwd" name="pwd"></td>
+								<td><input data-dojo-type="dijit.form.TextBox" type="password" id="pwd" name="pwd"></td>
 							</tr>
 							<tr>
-								<td colspan="2" align="center">
-									<button dojoType=dijit.form.Button type="submit" name="submit">Login</button>
+								<td colspan="2">
+									<button data-dojo-type="dijit.form.Button" type="submit" name="submit">Login</button>
 							</tr>
 						</table>
 					</div>
@@ -508,19 +516,28 @@
 			</div>
 			</div>
 
-			<div dojoType="dijit.layout.ContentPane" title="Dojo Tree from Store">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Tree"'>
 				<!-- tree widget -->
-				<div dojoType="dijit.Tree" store="continentStore" query="{type:'continent'}"
-					label="Continents" openOnClick="true">
-				</div>
+				<div data-dojo-type="dijit.Tree" 
+					data-dojo-props="model: continentModel, query:{ type:'continent'}, label:'Continents', openOnClick:true"
+				></div>
 			</div>
 
-			<div dojoType="dijit.layout.ContentPane" title="Calendar" selected="true">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Rootless Tree'">
+				<div id="rootlessTree" data-dojo-type="dijit.Tree" data-dojo-props="
+					model:continentModel,
+					query:{ type:'continent' },
+					showRoot: false,
+					openOnClick:true
+				"></div>
+			</div>
+
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='selected:true, title:"Calendar"'>
 				<!-- calendar widget pane -->
-				<input id="calendar1" dojoType="dijit.Calendar" onChange="myHandler(this.id,arguments[0])">
+				<input id="calendar1" data-dojo-type="dijit.Calendar">
 			</div>
 
-			<div dojoType="dijit.layout.ContentPane" title="Color Picker">
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Color Picker"'>
 				<p>
 					Selecting a color will change the background color of the page.
 					Use this to test how tooltips and drop downs appear with different backgrounds.
@@ -532,208 +549,107 @@
 						dojo.query('.dijitTabPaneWrapper').style('background', color);
 					}
 				</script>
-				<div dojoType="dijit.ColorPalette"  palette="3x4" onChange="setBackground(arguments[0]);"></div>
+				<div data-dojo-type="dijit.ColorPalette" data-dojo-props="palette:'3x4', onChange:setBackground"></div>
 				<h2 class="testHeader">7x10</h2>
-				<div dojoType="dijit.ColorPalette" onChange="setBackground(arguments[0]);"></div>
-			</div>
-			<div dojoType="dijit.layout.TabContainer" useMenu="false" title="Sliding TabContainer"
-						id="slidingTab">
-				<div dojoType="dijit.layout.ContentPane" title="Information">
-					This tab container uses slide controls when the tabs are too wide to fit beside each other.
-					If you make the left column narrow enough, the slide controls should appear.
-				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Rootless Tree" closable="true">
-					<div
-						dojoType="dijit.Tree"
-						id="rootlessTree"
-						store="continentStore"
-						query="{type:'continent'}"
-						openOnClick="true">
-					</div>
-
-				</div>
-				<div dojoType="dijit.layout.TabContainer"
-						id="inlined" closable="true"
-						title="Nested TabContainer" nested="true">
-					<a dojoType="dijit.layout.LinkPane" id="tab1href" href="../tests/layout/tab1.html" onLoad="console.log('load of SubTab 1');">SubTab 1</a>
-					<a dojoType="dijit.layout.LinkPane" id="tab2href" href="../tests/layout/tab2.html"  onLoad="console.log('load of SubTab 2');" selected="true">SubTab 2</a>
-					<div dojoType="dijit.layout.ContentPane" id="subtab3" title="SubTab 3">
-						<h1>I am tab 3, inlined.</h1>
-					</div>
-					<div dojoType="dijit.layout.ContentPane" id="subtab4" title="SubTab 4">
-						<h1>I am tab 4, inlined.</h1>
-					</div>
-				</div>
-				<div dojoType="dijit.layout.ContentPane" title="Menu Bar" closable="true">
-					<div id="menubar" dojoType="dijit.MenuBar">
-					<div dojoType="dijit.PopupMenuBarItem" >
-						<span>File</span>
-						<div dojoType="dijit.Menu">
-							<div dojoType="dijit.MenuItem" iconClass="dijitIconNewTask">New</div>
-							<div dojoType="dijit.MenuItem">Open</div>
-							<div dojoType="dijit.MenuSeparator"></div>
-							<div dojoType="dijit.MenuItem" iconClass="dijitIconSave">Save</div>
-							<div dojoType="dijit.MenuItem">Save As...</div>
-						</div>
-					</div>
-					<div dojoType="dijit.PopupMenuBarItem">
-						<span>Edit</span>
-						<div dojoType="dijit.Menu" >
-							<div dojoType="dijit.MenuItem"  iconClass="dijitIconCut"
-								onClick="console.log('not actually cutting anything, just a test!')">Cut</div>
-							<div dojoType="dijit.MenuItem"  iconClass="dijitIconCopy"
-								onClick="console.log('not actually copying anything, just a test!')">Copy</div>
-							<div dojoType="dijit.MenuItem"  iconClass="dijitIconPaste"
-								onClick="console.log('not actually pasting anything, just a test!')">Paste</div>
-						</div>
-					</div>
-					<div dojoType="dijit.PopupMenuBarItem">
-						<span>View</span>
-						<div dojoType="dijit.Menu">
-							<div dojoType="dijit.MenuItem">Normal</div>
-							<div dojoType="dijit.MenuItem">Outline</div>
-							<div dojoType="dijit.PopupMenuItem">
-								<span>Zoom</span>
-								<div dojoType="dijit.Menu">
-									<div dojoType="dijit.MenuItem">50%</div>
-									<div dojoType="dijit.MenuItem">75%</div>
-									<div dojoType="dijit.MenuItem">100%</div>
-									<div dojoType="dijit.MenuItem">150%</div>
-									<div dojoType="dijit.MenuItem">200%</div>
-								</div>
-							</div>
-						</div>
-					</div>
-					<div dojoType="dijit.PopupMenuBarItem">
-						<span>Help</span>
-						<div dojoType="dijit.Menu">
-							<div dojoType="dijit.MenuItem">Help Topics</div>
-							<div dojoType="dijit.MenuItem">About Dijit</div>
-						</div>
-					</div>
-					<div dojoType="dijit.PopupMenuBarItem" disabled="true">
-						<span>Disabled</span>
-						<div dojoType="dijit.Menu">
-							<div dojoType="dijit.MenuItem">You should not see this</div>
-						</div>
-					</div>
-					<div dojoType="dijit.MenuBarItem" onclick="alert('no submenu, just a clickable MenuItem');">
-						Click me!
-					</div>
-				</div>
-				</div>
+				<div data-dojo-type="dijit.ColorPalette" data-dojo-props="onChange:setBackground"></div>
 			</div>
-
-
 		</div><!-- end AccordionContainer -->
 
 		<!-- top tabs (marked as "center" to take up the main part of the BorderContainer) -->
-		<div dojoType="dijit.layout.TabContainer" region="center" id="topTabs" tabStrip="true">
+		<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="region:'center', tabStrip:true" id="topTabs">
 
-			<div id="basicFormTab" dojoType="dijit.layout.ContentPane" title="Basic Form Widgets" style="padding:10px;display:none;">
+			<div id="basicFormTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Basic Form Widgets', style:'padding:10px;display:none;'">
 
 				<h2>Buttons</h2>
 				<p>Buttons can do an action, display a menu, or both:</p>
 
 				Enabled:
 
-				<button dojoType="dijit.form.Button" iconClass="dijitIconTask" onClick='console.debug("clicked simple")'>
+				<button data-dojo-type="dijit.form.Button" data-dojo-props="iconClass:'dijitIconTask', onClick:function(){ console.debug('clicked simple') }">
 					Simple
 				</button>
 
-				<button dojoType="dijit.form.DropDownButton" iconClass="dijitIconEdit">
+				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props="iconClass:'dijitIconEdit'">
 					<span>Drop Down</span>
-					<div dojoType="dijit.Menu" id="editMenu1" style="display: none;">
-						<div dojoType="dijit.MenuItem"
-							iconClass="dijitIconCut"
-							onClick="console.debug('not actually cutting anything, just a test!')">
-							Cut
-						</div>
-
-						<div dojoType="dijit.MenuItem"
-							 iconClass="dijitIconCopy"
-							onClick="console.debug('not actually copying anything, just a test!')">
-							Copy
-						</div>
-
-						<div dojoType="dijit.MenuItem"
-							 iconClass="dijitIconPaste"
-							onClick="console.debug('not actually pasting anything, just a test!')">
-							Paste
-						</div>
+					<div data-dojo-type="dijit.Menu" id="editMenu1" style="display: none;">
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconCut',
+							onClick:function(){ console.debug('not actually cutting anything, just a test!') }
+						">Cut</div>
+
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconCopy',
+							onClick:function(){ console.debug('not actually copying anyything, just a test!'); }
+						">Copy</div>
+
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconPaste',
+							onClick:function(){ console.debug('not actually pasting anyything, just a test!'); }
+						">Paste</div>
 					</div>
-				</button>
+				</div>
 
-				<button dojoType="dijit.form.ComboButton" iconClass="dijitIconSave"
-					optionsTitle='save options'
-					onClick='console.debug("clicked combo save")'>
+				<div data-dojo-type="dijit.form.ComboButton" data-dojo-props='iconClass:"dijitIconSave", optionsTitle:"save options", onClick:function(){ console.log("clicked combo save"); }'>
 					<span>Combo</span>
-					<div dojoType="dijit.Menu" id="saveMenu1" style="display: none;">
-						<div dojoType="dijit.MenuItem"
-							 iconClass="dijitIconSave"
-							onClick="console.debug('not actually saving anything, just a test!')">
-							Save
-						</div>
-						<div dojoType="dijit.MenuItem"
-							onClick="console.debug('not actually saving anything, just a test!')">
-							Save As
-						</div>
+					<div data-dojo-type="dijit.Menu" id="saveMenu1" style="display: none;">
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconSave',
+							onClick: function(){ console.debug('not actually saving anything, just a test!') }
+						">Save</div>
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+							onClick: function(){ console.debug('not actually saving anything, just a test!') }
+						">Save As</div>
 					</div>
-				</button>
+				</div>
 
-				<button dojoType="dijit.form.ToggleButton" checked onChange="console.log('toggled button checked='+arguments[0]);" iconClass="dijitCheckBoxIcon">
-					Toggle
-				</button>
+				<div data-dojo-type="dijit.form.ToggleButton" data-dojo-props="
+					checked:true, 
+					onChange: function(a){ console.log('toggle button checked=' + a); }, iconClass:'dijitCheckBoxIcon'
+				"> Toggle </div>
 
 				<hr class="spacer">
 
 				Disabled:
 
-				<button dojoType="dijit.form.Button" iconClass="dijitIconTask" disabled>
+				<button data-dojo-type="dijit.form.Button" data-dojo-props='iconClass:"dijitIconTask", disabled:true' disabled>
 					Simple
 				</button>
 
-				<button dojoType="dijit.form.DropDownButton" iconClass="dijitIconEdit" disabled>
+				<div data-dojo-type="dijit.form.DropDownButton" data-dojo-props='iconClass:"dijitIconEdit", disabled:true'>
 					<span>Drop Down</span>
-					<div dojoType="dijit.Menu" id="editMenu2" style="display: none;">
-						<div dojoType="dijit.MenuItem"
-							iconClass="dijitIconCut"
-							onClick="console.debug('not actually cutting anything, just a test!')">
-							Cut
-						</div>
-
-						<div dojoType="dijit.MenuItem"
-							 iconClass="dijitIconCopy"
-							onClick="console.debug('not actually copying anything, just a test!')">
-							Copy
-						</div>
-
-						<div dojoType="dijit.MenuItem"
-							 iconClass="dijitIconPaste"
-							onClick="console.debug('not actually pasting anything, just a test!')">
-							Paste
-						</div>
-					</div>
-				</button>
+					<ul data-dojo-type="dijit.Menu" id="editMenu2" style="display: none;">
+						<li data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconCut',
+							onClick: function(){ console.debug('not actually cutting anything, just a test!') }
+						">Cut</li>
+
+						<li data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconCopy',
+							onClick: function(){ console.debug('not actually copying anything, just a test!') }
+						">Copy</li>
+
+						<li data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconClass:'dijitIconPaste',
+							onClick: function(){ console.debug('not actually pasting anything, just a test!') }
+						">Paste</li>
+					</ul>
+				</div>
 
-				<button dojoType="dijit.form.ComboButton" iconClass="dijitIconSave"
-					optionsTitle='save options'
-					disabled>
+				<div data-dojo-type="dijit.form.ComboButton" data-dojo-props="iconClass:'dijitIconSave', optionsTitle:'save options', disabled:true">
 					<span>Combo</span>
-					<div dojoType="dijit.Menu" id="saveMenu2" style="display: none;">
-						<div dojoType="dijit.MenuItem"
-							 iconClass="dijitIconSave"
-							onClick="console.debug('not actually saving anything, just a test!')">
-							Save
-						</div>
-						<div dojoType="dijit.MenuItem"
+					<div data-dojo-type="dijit.Menu" id="saveMenu2" style="display: none;">
+						<div data-dojo-type="dijit.MenuItem" data-dojo-props="
+							iconCLass:'dijitIconSave',
+							onClick:function(){ console.log('not actually saving anything, just a test!' ); }
+						">Save</div>
+						<div data-dojo-type="dijit.MenuItem"
 							onClick="console.debug('not actually saving anything, just a test!')">
 							Save As
 						</div>
 					</div>
-				</button>
+				</div>
 
-				<button dojoType="dijit.form.ToggleButton" checked disabled iconClass="dijitCheckBoxIcon">
+				<button data-dojo-type="dijit.form.ToggleButton" data-dojo-props="checked:true, disabled:true, iconClass:'dijitCheckBoxIcon'">
 					Toggle
 				</button>
 
@@ -741,135 +657,125 @@
 
 				<h2>CheckBox</h2>
 				<fieldset>
-					<input id="check1" type="checkBox" dojoType="dijit.form.CheckBox">
+					<input id="check1" type="checkBox" data-dojo-type="dijit.form.CheckBox">
 					<label for="check1">unchecked</label>
 
-					<input id="check2" type="checkBox" dojoType="dijit.form.CheckBox" checked="checked">
+					<input id="check2" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props="checked:true" checked="checked">
 					<label for="check2">checked</label>
 
-					<input id="check3" type="checkBox" dojoType="dijit.form.CheckBox" disabled>
+					<input id="check3" type="checkBox" data-dojo-type="dijit.form.CheckBox" data-dojo-props='disabled:true' disabled>
 					<label for="check3">disabled</label>
 
-					<input id="check4" type="checkBox" dojoType="dijit.form.CheckBox" checked="checked" disabled>
+					<input id="check4" type="checkBox" data-dojo-type="dijit.form.CheckBox"	 data-dojo-props='disabled:true, checked:true' checked="checked" disabled>
 					<label for="check4">disabled and checked</label>
 				</fieldset>
 
 				<h2>Radio Buttons</h2>
 				<fieldset>
-					<input type="radio" name="g1" id="g1rb1" value="news" dojoType="dijit.form.RadioButton">
+					<input type="radio" name="g1" id="g1rb1" value="news" data-dojo-type="dijit.form.RadioButton">
 					<label for="g1rb1">news</label>
-					<input type="radio" name="g1" id="g1rb2" value="talk" dojoType="dijit.form.RadioButton" checked>
+					<input type="radio" name="g1" id="g1rb2" value="talk" data-dojo-type="dijit.form.RadioButton"  data-dojo-props='checked:true' checked>
 					<label for="g1rb2">talk</label>
-					<input type="radio" name="g1" id="g1rb3" value="weather" dojoType="dijit.form.RadioButton" disabled>
+					<input type="radio" name="g1" id="g1rb3" value="weather" data-dojo-type="dijit.form.RadioButton"  data-dojo-props='disabled:true' disabled>
 					<label for="g1rb3">weather (disabled)</label>
 				</fieldset>
 			</div> <!-- end of basic form widgets -->
 
-			<div id="textboxTab" dojoType="dijit.layout.ContentPane" title="Text Input Widgets" style="padding:10px;display:none;">
+			<div id="textboxTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Text Input Widgets", style:"padding:10px;display:none;"'>
 
 				<h2>dijit.form.DateTextBox</h2>
 				<label for="date1">Enabled w/placeHolder:</label>
-				<input id="date1" name="date1" type="text" dojoType="dijit.form.DateTextBox" placeHolder="Birthday">
+				<input id="date1" name="date1" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props="placeHolder:'Birthday'">
 				<label for="date2">Disabled w/placeHolder:</label>
-				<input id="date2" name="date2" type="text" dojoType="dijit.form.DateTextBox" placeHolder="Birthday" disabled="disabled">
+				<input id="date2" name="date2" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='placeHolder:"Birthday", disabled:true'>
 				<label for="date2">Disabled w/value:</label>
-				<input id="date3" name="date3" type="text" dojoType="dijit.form.DateTextBox" value="2008-12-25" disabled="disabled">
+				<input id="date3" name="date3" type="text" data-dojo-type="dijit.form.DateTextBox" data-dojo-props='value:"2008-12-25", disabled:true'>
 
 				<h2>dijit.form.TimeTextBox</h2>
 				<label for="time1">Enabled:</label>
-				<input id="time1" name="time1" type="text" dojoType="dijit.form.TimeTextBox" value="T17:45:00">
+				<input id="time1" name="time1" type="text" data-dojo-type="dijit.form.TimeTextBox" value="T17:45:00">
 				<label for="time2">Disabled:</label>
-				<input id="time2" name="time2" type="text" dojoType="dijit.form.TimeTextBox" value="T17:45:00" disabled>
+				<input id="time2" name="time2" type="text" data-dojo-type="dijit.form.TimeTextBox" value="T17:45:00"  data-dojo-props='disabled:true' disabled>
 
 				<h2>dijit.form.CurrencyTextBox</h2>
 				<label for="currency1">Enabled:</label>
-				<input id="currency1" type="text" name="income1" value="54775.53"
-					dojoType="dijit.form.CurrencyTextBox"
-					required="true"
-					constraints="{fractional:true}"
-					currency="USD"
-					invalidMessage="Invalid amount.  Include dollar sign, commas, and cents.  Cents are mandatory.">
+				<input id="currency1" type="text" name="income1" value="54775.53" data-dojo-type="dijit.form.CurrencyTextBox"
+					data-dojo-props="
+						required:true, constraints:{ fractional:true }, currency:'USD',
+						value:54775.53,
+						invalidMessage:'Invalid amount.	 Include dollar sign, commas, and cents.  Cents are mandatory.'
+				">
 				<label for="currency2">Disabled:</label>
 				<input id="currency2" type="text" name="income1" value="54775.53"
-					dojoType="dijit.form.CurrencyTextBox"
-					required="true"
-					constraints="{fractional:true}"
-					currency="USD"
-					invalidMessage="Invalid amount.  Include dollar sign, commas, and cents.  Cents are mandatory." disabled>
-
+					data-dojo-type="dijit.form.CurrencyTextBox" data-dojo-props="required:true, constraints:{ fractional:true },
+						currency:'USD', invalidMessage:'Invalid amount.	 Include dollar sign, commas, and cents.  Cents are mandatory.',
+						disabled:true
+				">
+				
 				<hr class="spacer">
 
 				<h2>dijit.form.NumberSpinner max=100</h2>
 				<label for="spinner1">Enabled: </label>
-				<input dojoType="dijit.form.NumberSpinner" constraints="{max:100,places:0}" id="spinner1" value="10">
+				<input data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10' id="spinner1">
 				<label for="spinner2">Disabled: </label>
-				<input dojoType="dijit.form.NumberSpinner" constraints="{max:100,places:0}" id="spinner2" value="10" disabled>
+				<input data-dojo-type="dijit.form.NumberSpinner" data-dojo-props='constraints:{max:100,places:0}, value:10, disabled:true' id="spinner2">
 
 			</div>
 
-			<div id="selectTab" dojoType="dijit.layout.ContentPane" title="Select Widgets" style="padding:10px;display:none;">
+			<div id="selectTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Select Widgets', style:'padding:10px;display:none;'">
 
 				<h2>dijit.form.Select</h2>
-				<label for="selectEnabled">Enabled: </label>
-				<div id="selectEnabled" value="AK" dojoType="dijit.form.Select">
-					<span value="AL"><b>Alabama</b></span>
-					<span value="AK"><font color="red">A</font><font color="orange">l</font><font color="yellow">a</font><font color="green">s</font><font color="blue">k</font><font color="purple">a</font></span>
-					<span value="AZ"><i>Arizona</i></span>
-					<span value="AR"><span class="ark">Arkansas</span></span>
-					<span value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
-					<span value="NM" disabled="disabled">New<br>  Mexico</span>
+				<!-- fixme: <label for=""> but target a form element like input select etc -->
+				<label>Enabled:</label>
+				<div id="selectEnabled" data-dojo-type="dijit.form.Select" data-dojo-props="value:'AK'">
+					<span data-dojo-value="AL"><b>Alabama</b></span>
+					<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span style="color:purple">a</span></span>
+					<span data-dojo-value="AZ"><i>Arizona</i></span>
+					<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
+					<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+					<span data-dojo-value="NM">New<br>  Mexico</span>
 				</div>
 	
-				<label for="selectDisabled">Disabled: </label>
-				<div id="selectDisabled" value="AK" dojoType="dijit.form.Select" disabled>
-					<span value="AL"><b>Alabama</b></span>
-					<span value="AK"><font color="red">A</font><font color="orange">l</font><font color="yellow">a</font><font color="green">s</font><font color="blue">k</font><font color="purple">a</font></span>
-					<span value="AZ"><i>Arizona</i></span>
-					<span value="AR"><span class="ark">Arkansas</span></span>
-					<span value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
-					<span value="NM" disabled="disabled">New<br>  Mexico</span>
+				<label>Disabled: </label>
+				<div id="selectDisabled" data-dojo-props="value:'AK', disabled:true" data-dojo-type="dijit.form.Select">
+					<span data-dojo-value="AL"><b>Alabama</b></span>
+					<span data-dojo-value="AK"><span style="color:red">A</span><span style="color:orange">l</span><span style="color:yellow">a</span><span style="color:green">s</span><span style="color:blue">k</span><span style="color:purple">a</span></span>
+					<span data-dojo-value="AZ"><i>Arizona</i></span>
+					<span data-dojo-value="AR"><span class="ark">Arkansas</span></span>
+					<span data-dojo-value="CA"><span style="font-size:25%">C</span><span style="font-size:50%">a</span><span style="font-size:75%">l</span><span style="font-size:90%">i</span><span style="font-size:100%">f</span><span style="font-size:125%">o</span><span style="font-size:133%">r</span><span style="font-size:150%">n</span><span style="font-size:175%">i</span><span style="font-size:200%">a</span></span>
+					<span data-dojo-value="NM">New<br>  Mexico</span>
 				</div>
 
 				<hr class="spacer">
 
 				<h2>dijit.form.FilteringSelect</h2>
 				<label for="filteringSelect">Enabled w/placeHolder: </label>
-				<input dojoType="dijit.form.FilteringSelect"
-					placeHolder="State"
-					store="stateStore"
-					searchAttr="name"
-					name="state2"
-					id="filteringSelect"
-				>
+				<input id="filteringSelect" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
+					placeHolder:'State',
+					store:stateStore,
+					searchAttr:'name',
+					name:'state2'
+				">
+
 				<label for="filteringSelect2">Disabled w/placeHolder: </label>
-				<input dojoType="dijit.form.FilteringSelect"
-					placeHolder="State"
-					store="stateStore"
-					searchAttr="name"
-					name="state2"
-					id="filteringSelect2"
-					disabled
-				>
+				<input id="filteringSelect2" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
+					disabled:true, store:stateStore, name:'state2', searchAttr:'name'
+				">
+				
 				<label for="filteringSelect3">Disabled w/value: </label>
-				<input dojoType="dijit.form.FilteringSelect"
-					value="California"
-					store="stateStore"
-					searchAttr="name"
-					name="state3"
-					id="filteringSelect3"
-					disabled
-				>
-
+				<input id="filteringSelect3" data-dojo-type="dijit.form.FilteringSelect" data-dojo-props="
+					store: stateStore, searchAttr:'name', disabled:true, value:'CA'
+				">
 
 			</div>
 
-			<div id="textareaTab" dojoType="dijit.layout.ContentPane" title="Textarea" style="padding:10px;">
+			<div id="textareaTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Textarea", style:"padding:10px;"'>
 
 				<!--	‪ and ‬ are inserted solely for testing purposes to mark the beginning and end of left-to-right text so that
 					cogniscent browsers don't render garbled punctuation nor exhibit strange home/end key behavior while in right-to-left mode -->
 				<h2>dijit.form.Textarea</h2>
 				<p>Enabled:</p>
-				<textarea dojoType="dijit.form.Textarea" name="areText">This text area will expand and contract as you type ‪text.‬
+				<textarea data-dojo-type="dijit.form.Textarea" data-dojo-props='name:"areText"' name="areText">This text area will expand and contract as you type ‪text.‬
 
 Lorem ipsum dolor sit ‪amet,‬
 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
@@ -879,7 +785,7 @@ tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo ‪conseq
 
 				<br>
 				<p>Disabled:</p>
-				<textarea dojoType="dijit.form.Textarea" name="areText2" disabled>This text
+				<textarea data-dojo-type="dijit.form.Textarea" data-dojo-props="disabled: true">This text
 				area is disabled and you shouldn't be able to type in ‪it.‬
 				</textarea>
 
@@ -887,7 +793,7 @@ tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo ‪conseq
 				<h2>dijit.form.SimpleTextarea</h2>
 				<p></p>
 				<p>Enabled:</p>
-				<textarea dojoType="dijit.form.SimpleTextarea" name="areText">This text area has a constant height and displays a scrollbar when ‪necessary.‬
+				<textarea data-dojo-type="dijit.form.SimpleTextarea">This text area has a constant height and displays a scrollbar when ‪necessary.‬
 
 Lorem ipsum dolor sit ‪amet,‬
 consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
@@ -900,7 +806,7 @@ nulla ‪facilisi.‬
 				</textarea>
 
 				<p>Disabled:</p>
-				<textarea dojoType="dijit.form.SimpleTextarea" name="areText2" disabled>Lorem ipsum dolor sit ‪amet,‬
+				<textarea data-dojo-type="dijit.form.SimpleTextarea" data-dojo-props="disabled: true">Lorem ipsum dolor sit ‪amet,‬
 				consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
 				dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci
 				tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis
@@ -911,7 +817,7 @@ nulla ‪facilisi.‬
 				</textarea>
 			</div><!-- end of Textarea tab -->
 
-			<div id="editorTab" dojoType="dijit.layout.ContentPane" title="Editor" style="padding:10px;">
+			<div id="editorTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Editor", style:"padding:10px;"'>
 				<p>Enabled:</p>
 				<!-- FIXME:
 					set height on this node to size the whole editor, but causes the tab to not scroll
@@ -919,14 +825,14 @@ nulla ‪facilisi.‬
 					causes editor to become VERY tall, and size to a normal height when selected (like the
 					dijit.form.TextArea in "Form Feel" Tab), but in reverse. refs #3980 and is maybe new bug?
 				-->
-				<div height="175" dojoType="dijit.Editor" extraPlugins="['|', 'createLink', 'fontName']" styleSheets="../../dojo/resources/dojo.css">
+				<div data-dojo-type="dijit.Editor" data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../themes/claro/document.css'">
 					<ul>
 						<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
 						<li>This is the Editor with a Toolbar attached.</li>
 					</ul>
 				</div>
 				<p>Disabled:</p>
-				<div height="175" dojoType="dijit.Editor" extraPlugins="['|', 'createLink', 'fontName']" styleSheets="../../dojo/resources/dojo.css" disabled="true">
+				<div data-dojo-type="dijit.Editor" data-dojo-props="height:175, extraPlugins:['|', 'createLink', 'fontName'], styleSheets:'../themes/claro/document.css', disabled:true">
 					<ul>
 						<li>Lorem <a href="http://dojotoolkit.org">and a link</a>, what do you think?</li>
 						<li>This is the Editor with a Toolbar attached.</li>
@@ -935,134 +841,102 @@ nulla ‪facilisi.‬
 			</div><!-- end of Editor tab -->
 
 
-			<div dojoType="dijit.layout.ContentPane" title="Sliders" style="padding:10px;display:none;">
-
-
+			<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="title:'Sliders', style:'padding:10px;display:none;'">
+				
 				<!-- Sliders: -->
-
+				
 				<h2>Enabled</h2>
 				<div style="float:right;">
-				<div dojoType="dijit.form.VerticalSlider"
-					onChange="dojo.byId('slider2input').value=arguments[0];"
-					value="10"
-					maximum="100"
-					minimum="0"
-					discreteValues="11"
-					style="height:176px; clear:both;"
-					id="slider2">
-						<ol dojoType="dijit.form.VerticalRuleLabels" container="leftDecoration"style="width:2em;" labelStyle="right:0px;">
+					<div id='slider2' data-dojo-type="dijit.form.VerticalSlider" data-dojo-props="
+						onChange: function(a){ dojo.byId('slider2input').value = a; },
+						value:10, maximum:100, minimum:0, discreetValues:11, style:'height:176px; clear:both'
+					">
+						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props="container:'leftDecoration', style:'width:2em;', labelStyle:'right:0px;'">
 							<li>0
 							<li>100
 						</ol>
 
-						<div dojoType="dijit.form.VerticalRule" container="leftDecoration" count=11 style="width:5px;"></div>
-						<div dojoType="dijit.form.VerticalRule" container="rightDecoration" count=11 style="width:5px;"></div>
-						<ol dojoType="dijit.form.VerticalRuleLabels" container="rightDecoration"style="width:2em;" maximum="100" count="6" numericMargin="1" constraints="{pattern:'#'}"></ol>
-				</div>
-				<br> Slider2 Value:<input disabled id="slider2input" size="3" value="10" autocomplete="off">
+						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props="container:'leftDecoration', style:'width:5px;', count:11"></div>
+						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props="container:'rightDecoration', style:'width:5px;', count:11"></div>
+						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props="container:'rightDecoration', style:'width:2em;', maximum:100, count:6, numericMargin:1, constraints:{ pattern:'#' }"></ol>
+					</div>
+					<br> Slider2 Value:<input disabled id="slider2input" size="3" value="10" autocomplete="off">
 				</div>
 
-				<div dojoType="dijit.form.HorizontalSlider"
-					onChange="dojo.byId('slider1input').value=dojo.number.format(arguments[0]/100,{places:1,pattern:'#%'});"
-					value="10"
-					maximum="100"
-					minimum="0"
-					showButtons="false"
-					intermediateChanges="true"
-					style="width:50%; height: 20px;"
-					id="horizontal1">
-						<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;" numericMargin="1" count="6"></ol>
-						<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=11 style="height:5px;"></div>
-						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div>
-						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
-							<li>lowest
-							<li>normal
-							<li>highest
-						</ol>
-
+				<div id="horizontal1" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
+					value:10, maximum:100, minimum:0, showButtons:false, intermediateChanges:true, style:'width:50%; height:20px',
+					onChange: function(a){ dojo.byId('slider1input').value = dojo.number.format(a / 100, { places:1, pattern:'#%' }) }
+				">
+					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
+					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
+					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
+					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+						<li>lowest
+						<li>normal
+						<li>highest
+					</ol>
 				</div>
 				<br>Value: <input disabled id="slider1input" size="5" value="10.0%" autocomplete="off">
 
-				<div dojoType="dijit.form.HorizontalSlider"
-					minimum="1"
-					value="2"
-					maximum="3"
-					discreteValues="3"
-					showButtons="false"
-					intermediateChanges="true"
-					style="width:300px; height: 40px;"
-					id="horizontal2">
-						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=3 style="height:5px;"></div>
-						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration"style="height:1em;font-size:75%;">
-							<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
-							<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
-
-							<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
-						</ol>
+				<div id="horizontal2" data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
+					minimum:1, value:2, maximum:3, discreteValues:3, showButtons:false, intermediateChanges:true,
+					style:'width:300px; height:40px'
+				">
+					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
+					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+						<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
+						<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
+						<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
+					</ol>
 				</div>
 
 				<h2 style="clear:both">Disabled</h2>
 				<div style="float:right;">
-				<div dojoType="dijit.form.VerticalSlider"
-					value="10"
-					maximum="100"
-					minimum="0"
-					discreteValues="11"
-					style="height:175px; clear:both"
-					disabled>
-						<ol dojoType="dijit.form.VerticalRuleLabels" container="leftDecoration"style="width:2em;" labelStyle="right:0px;">
+					<div data-dojo-type="dijit.form.VerticalSlider" data-dojo-props="
+						value:10, maximum:100, minimum:0, discreteValues:11, 
+						style:'height:175px; clear:both', disabled:true
+					">
+						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"leftDecoration", style:"width:2em;", labelStyle:"right:0px;"'>
 							<li>0
 							<li>100
 						</ol>
 
-						<div dojoType="dijit.form.VerticalRule" container="leftDecoration" count=11 style="width:5px;"></div>
-						<div dojoType="dijit.form.VerticalRule" container="rightDecoration" count=11 style="width:5px;"></div>
-						<ol dojoType="dijit.form.VerticalRuleLabels" container="rightDecoration"style="width:2em;" maximum="100" count="6" numericMargin="1" constraints="{pattern:'#'}"></ol>
+						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"leftDecoration", count:11, style:"width:5px;"'></div>
+						<div data-dojo-type="dijit.form.VerticalRule" data-dojo-props='container:"rightDecoration", count:11, style:"width:5px;"'></div>
+						<ol data-dojo-type="dijit.form.VerticalRuleLabels" data-dojo-props='container:"rightDecoration", style:"width:2em;", maximum:100, count:6, numericMargin:1, constraints:{ pattern:"#"}'></ol>
+					</div>
 				</div>
+				
+				<div data-dojo-type="dijit.form.HorizontalSlider" id="hs-1width" data-dojo-props="
+					value:10, maximum:100, minimum:0, showButtons:false, intermediateChanges:true, disabled:true
+				">
+					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"topDecoration", style:"height:1.2em;font-size:75%;", numericMargin:1, count:6'></ol>
+					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"topDecoration", count:11, style:"height:5px;"'></div>
+					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:5, style:"height:5px;"'></div>
+					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+						<li>lowest
+						<li>normal
+						<li>highest
+					</ol>
 				</div>
-				<div dojoType="dijit.form.HorizontalSlider"
-					value="10"
-					maximum="100"
-					minimum="0"
-					showButtons="false"
-					intermediateChanges="true"
-					style="width:50%; height: 20px;"
-					disabled>
-						<ol dojoType="dijit.form.HorizontalRuleLabels" container="topDecoration" style="height:1.2em;font-size:75%;" numericMargin="1" count="6"></ol>
-						<div dojoType="dijit.form.HorizontalRule" container="topDecoration" count=11 style="height:5px;"></div>
-						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=5 style="height:5px;"></div>
-						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" style="height:1em;font-size:75%;">
-							<li>lowest
-							<li>normal
-							<li>highest
-						</ol>
 
-				</div>
-
-				<div dojoType="dijit.form.HorizontalSlider"
-					minimum="1"
-					value="2"
-					maximum="3"
-					discreteValues="3"
-					showButtons="false"
-					intermediateChanges="true"
-					style="width:300px; height: 40px;"
-					disabled>
-						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count=3 style="height:5px;"></div>
-						<ol dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration"style="height:1em;font-size:75%;">
-							<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
-							<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
-							<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
-						</ol>
+				<div data-dojo-type="dijit.form.HorizontalSlider" data-dojo-props="
+					minimum:1, value:2, maximum:3, discreteValues:3, showButtons:false, intermediateChanges:true,
+					style:'width:300px; height:40px', disabled:true
+				">
+					<div data-dojo-type="dijit.form.HorizontalRule" data-dojo-props='container:"bottomDecoration", count:3, style:"height:5px;"'></div>
+					<ol data-dojo-type="dijit.form.HorizontalRuleLabels" data-dojo-props='container:"bottomDecoration", style:"height:1em;font-size:75%;"'>
+						<li><img width=10 height=10 src="../tests/images/note.gif"><br><span style="font-size: small">small</span>
+						<li><img width=15 height=15 src="../tests/images/note.gif"><br><span style="font-size: medium">medium</span>
+						<li><img width=20 height=20 src="../tests/images/note.gif"><br><span style="font-size: large">large</span>
+					</ol>
 				</div>
 			</div>
 
-			<div id="variousTab" dojoType="dijit.layout.ContentPane" title="Various Dijits"
-				style="padding:10px; display:none;">
-
+			<div id="variousTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Various Dijits", style:"padding:10px; display:none;"'>
 
 				<h2>TitlePane</h2>
-				<div dojoType="dijit.TitlePane" title="my pane" width="275">
+				<div data-dojo-type="dijit.TitlePane" data-dojo-props="title:'my pane', width:275">
 					<p>This is a title pane.  It can be expanded and collapsed.</p>
 
 					<p>Sed sollicitudin suscipit risus. Nam
@@ -1075,21 +949,19 @@ nulla ‪facilisi.‬
 				<hr class="spacer">
 
 				<h2>ProgressBar</h2>
-				<div style="width:400px;" maximum="200" id="setTestBar"
-					progress="20" dojoType="dijit.ProgressBar"></div>
+				<div data-dojo-props="maximum:200, value:20" id="setTestBar" data-dojo-type="dijit.ProgressBar"></div>
 
 				Indeterminate:
-				<div style="width:400px;" indeterminate="true" dojoType="dijit.ProgressBar"></div>
+				<div id="indTestBar" data-dojo-props="indeterminate:true" data-dojo-type="dijit.ProgressBar"></div>
 
 			</div><!-- end:various dijits upper tab -->
 
-			<div id="InlineEditBoxTab" dojoType="dijit.layout.ContentPane" title="InlineEditBox"
-				style="padding:10px; display:none;">
+			<div id="InlineEditBoxTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"InlineEditBox", style:"padding:10px;"'>
 
 				<h2 class="testTitle">dijit.InlineEditBox + dijit.form.TextBox on <h3></h2>
 
 				(HTML before)
-				<h3 id="editable" style="font-size:larger;" dojoType="dijit.InlineEditBox" onChange="myHandler(this.id,arguments[0])">
+				<h3 id="editable" style="font-size:larger;" data-dojo-type="dijit.InlineEditBox">
 					Edit me - I trigger the onChange callback
 				</h3>
 				(HTML after)
@@ -1099,16 +971,16 @@ nulla ‪facilisi.‬
 				<h2>dijit.InlineEditBox + dijit.form.Textarea</h2>
 
 				(HTML before)
-				<p id="areaEditable" dojoType="dijit.InlineEditBox" editor="dijit.form.Textarea" autoSave="false">
+				<p id="areaEditable" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor: dijit.form.Textarea, autoSave:false'>
 					I'm one big ‪paragraph.‬  Go ahead and edit ‪me.‬  I dare ‪you.‬
-					The quick brown fox jumped over the lazy ‪dog.‬  Blah blah blah blah blah blah ‪blah ...‬
+					The quick brown fox jumped over the lazy ‪dog.‬	 Blah blah blah blah blah blah ‪blah ...‬
 				</p>
 				(HTML after)
 
 				<p>
 					These links will
-					<a href="#" onClick="dijit.byId('areaEditable').set('disabled', true)">disable</a> /
-					<a href="#" onClick="dijit.byId('areaEditable').set('disabled', false)">enable</a>
+					<a href="#" onclick="dijit.byId('areaEditable').set('disabled', true)">disable</a> /
+					<a href="#" onclick="dijit.byId('areaEditable').set('disabled', false)">enable</a>
 					the text area above.
 				</p>
 
@@ -1118,7 +990,7 @@ nulla ‪facilisi.‬
 
 				(HTML inline before)
 				<!-- set programmatically to match locale; a server might generate this content also. -->
-				<span id="backgroundArea" dojoType="dijit.InlineEditBox" editor="dijit.form.DateTextBox" width="170px"></span>
+				<span id="backgroundArea" data-dojo-type="dijit.InlineEditBox" data-dojo-props="editor: dijit.form.DateTextBox, width:'170px'"></span>
 				(HTML after)
 				<hr class="spacer">
 
@@ -1126,7 +998,7 @@ nulla ‪facilisi.‬
 
 				(HTML inline before)
 				<!-- set programmatically to match locale; a server might generate this content also. -->
-				<span id="timePicker" dojoType="dijit.InlineEditBox" editor="dijit.form.TimeTextBox" width="150px"></span>
+				<span id="timePicker" data-dojo-type="dijit.InlineEditBox" data-dojo-props='editor:dijit.form.TimeTextBox, width:"150px"'></span>
 				(HTML after)
 
 				<hr class="spacer">
@@ -1134,20 +1006,19 @@ nulla ‪facilisi.‬
 
 				<h2>dijit.form.FilteringSelect + Inline + remote data store</h2>
 				(HTML inline before)
-				<span id="backgroundArea2" dojoType="dijit.InlineEditBox" editor="dijit.form.FilteringSelect"
-					editorParams="{store: stateStore, autoComplete: true, promptMessage: 'Please enter a state'}"
-					width="300px">
-					Indiana
-				</span>
+				<span id="backgroundArea2" data-dojo-type="dijit.InlineEditBox" data-dojo-props='
+					editor: dijit.form.FilteringSelect,
+					editorParams:{ store: stateStore, autoComplete: true, promptMessage: "Please enter a state"},
+					width:"300px"
+				'>Indiana</span>
 				(HTML after)
 
 			</div><!-- end InlineEditBox tab -->
 
-			<div id="dndTab" dojoType="dijit.layout.ContentPane" title="DnD"
-				style="padding:10px; display:none;">
+			<div id="dndTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"DnD", style:"padding:10px; display:none;"'>
 				<div style="float:left; margin:5px;">
 					<h3>Source 1</h3>
-					<div dojoType="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
+					<div data-dojo-type="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
 						<div class="dojoDndItem">Item <strong>X</strong></div>
 						<div class="dojoDndItem">Item <strong>Y</strong></div>
 						<div class="dojoDndItem">Item <strong>Z</strong></div>
@@ -1155,7 +1026,7 @@ nulla ‪facilisi.‬
 				</div>
 				<div style="float:left; margin:5px; ">
 					<h3>Source 2</h3>
-					<div dojoType="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
+					<div data-dojo-type="dojo.dnd.Source" style="border:3px solid #ccc; padding: 1em 3em; ">
 						<div class="dojoDndItem">Item <strong>1</strong></div>
 						<div class="dojoDndItem">Item <strong>2</strong></div>
 						<div class="dojoDndItem">Item <strong>3</strong></div>
@@ -1163,18 +1034,31 @@ nulla ‪facilisi.‬
 				</div>
 			</div><!-- end DnD tab -->
 
-			<div id="closableTab" dojoType="dijit.layout.ContentPane" title="Closable"
-				style="display:none; padding:10px; " closable="true">
+			<div data-dojo-type="dijit.layout.TabContainer" data-dojo-props="closable:true, title:'Nested TabContainer', nested:true" id="inlined">
+				<a data-dojo-type="dijit.layout.LinkPane" id="tab1href" data-dojo-props="href:'../tests/layout/tab1.html', onLoad:function(){ console.log('load of SubTab 1'); }">SubTab 1</a>
+				<a data-dojo-type="dijit.layout.LinkPane" id="tab2href" data-dojo-props="href:'../tests/layout/tab2.html', onLoad:function(){ console.log('load of SubTab 2'); }, selected:true">SubTab 2</a>
+				<div data-dojo-type="dijit.layout.ContentPane" id="subtab3" data-dojo-props='title:"SubTab 3"'>
+					<h1>I am tab 3, inlined.</h1>
+				</div>
+				<div data-dojo-type="dijit.layout.ContentPane" id="subtab4" data-dojo-props='title:"SubTab 4"'>
+					<h1>I am tab 4, inlined.</h1>
+				</div>
+			</div>
+
+			<div id="closableTab" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Closable", 
+				style:"display:none; padding:10px;", closable:true'>
 				This pane is closable, just for the icon ...
 			</div>
 		</div><!-- end of region="center" TabContainer -->
 
 		<!-- bottom right tabs -->
-		<div dojoType="dijit.layout.TabContainer" id="bottomTabs"
-			tabPosition="bottom" selectedChild="btab1" region="bottom" splitter="true" tabStrip="true">
-
+		<div data-dojo-type="dijit.layout.TabContainer" id="bottomTabs"
+			data-dojo-props="
+				tabPosition:'bottom', selectedchild:'btab1', region:'bottom',
+				splitter:true, tabStrip:true
+			">
 			<!-- btab 1 -->
-			<div id="btab1" dojoType="dijit.layout.ContentPane" title="Info" style=" padding:10px; ">
+			<div id="btab1" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Info", style:" padding:10px; "'>
 				<p>You can explore this single page after applying a Theme
 				for use in creation of your own theme.</p>
 
@@ -1184,13 +1068,13 @@ nulla ‪facilisi.‬
 				<p>There is a right-click [context] pop-up menu here, as well.</p>
 			</div><!-- end:info btab1 -->
 
-			<div id="btab2" dojoType="dijit.layout.ContentPane" title="Alternate Themes" style="padding:20px;">
+			<div id="btab2" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Alternate Themes", style:"padding:20px;"'>
 				<span id="themeData"></span>
 			</div><!-- btab2 -->
 
-			<div id="btab3" dojoType="dijit.layout.ContentPane" title="Bottom 3" closable="true">
+			<div id="btab3" data-dojo-type="dijit.layout.ContentPane" data-dojo-props='title:"Bottom 3", closable:true'>
 				<p>I am the last Tab</p>
-				<div id="dialog2" dojoType="dijit.Dialog" title="Encased Dialog" style="display:none;">
+				<div id="dialog2" data-dojo-type="dijit.Dialog" data-dojo-props='title:"Encased Dialog", style:"display:none;"'>
 				I am the second dialog. I am
 				parented by the Low Tab Pane #3
 				</div>
@@ -1201,32 +1085,33 @@ nulla ‪facilisi.‬
 	</div><!-- end of BorderContainer -->
 
 	<!-- dialog in body -->
-	<div id="dialog1" dojoType="dijit.Dialog"
-		title="Floating Modal Dialog from href" style="display:none; width: 400px;"
-		href="../tests/layout/getResponse.php?delay=3000&messId=3" refreshOnShow="true"></div>
-	<div id="dialogAB" dojoType="dijit.Dialog"
-		title="Floating Modal Dialog" style="display:none;">
+	<div id="dialog1" data-dojo-type="dijit.Dialog" style="display:none;" data-dojo-props="
+		title:'Floating Modal Dialog from href',
+		href:'../tests/layout/getResponse.php?delay=3000&messId=3',
+		style: 'width: 400px;',
+		refreshOnShow:true
+	"></div>
+	<div id="dialogAB" data-dojo-type="dijit.Dialog" data-dojo-props="title:'Floating Modal Dialog'" style="display:none;">
 		<div class="dijitDialogPaneContentArea">
 			<table>
 				<tr>
 					<td><label for="name">Name: </label></td>
-					<td><input dojoType=dijit.form.TextBox type="text" name="name" id="name"></td>
+					<td><input data-dojo-type="dijit.form.TextBox" type="text" name="name" id="name"></td>
 				</tr>
 				<tr>
 					<td><label for="loc">Location: </label></td>
-					<td><input dojoType=dijit.form.TextBox type="text" name="loc" id="loc"></td>
+					<td><input data-dojo-type="dijit.form.TextBox" type="text" name="loc" id="loc"></td>
 				</tr>
 				<tr>
 					<td><label for="date">Date: </label></td>
-					<td><input dojoType=dijit.form.DateTextBox type="text" name="date" id="date"></td>
+					<td><input data-dojo-type="dijit.form.DateTextBox" type="text" name="date" id="date"></td>
 				</tr>
 			</table>
 		</div>
 		
-		
 		<div class="dijitDialogPaneActionBar">
-			<button dojoType="dijit.form.Button" type="submit" id="ABdialog1button1">OK</button>
-			<button dojoType="dijit.form.Button" type="button" onClick="dijit.byId('dialogAB').onCancel();" 
+			<button data-dojo-type="dijit.form.Button" type="submit" id="ABdialog1button1">OK</button>
+			<button data-dojo-type="dijit.form.Button" type="button" data-dojo-props="onClick:function(){ dijit.byId('dialogAB').onCancel(); }" 
 					id="ABdialog1button2">Cancel</button>
 		</div>
 	</div>
diff --git a/dijit/themes/tundra/Calendar.css b/dijit/themes/tundra/Calendar.css
index be235b3..5fef68e 100644
--- a/dijit/themes/tundra/Calendar.css
+++ b/dijit/themes/tundra/Calendar.css
@@ -48,7 +48,7 @@
 	background:white url("images/calendarDayLabel.png") repeat-x bottom;
 	font-weight:normal;
 	padding-top:.15em;
-	padding-bottom:0em;
+	padding-bottom:0;
 	border-top: 1px solid #eeeeee;
 	color:#293a4b;
 	text-align:center;
@@ -61,6 +61,7 @@
 .tundra .dijitCalendarMonthLabel {
 	color:#293a4b;
 	font-weight: bold;
+	padding: 0 4px;
 }
 
 .tundra .dijitCalendarDateTemplate {
@@ -134,4 +135,25 @@
 	/* label for next/prev years */
 	color:black !important;
 	font-weight:normal;
+}
+
+/* Styling for month DropDownButton */
+
+.tundra .dijitCalendar .dijitDropDownButton {
+	margin: 0;
+}
+.tundra .dijitCalendar .dijitButtonText {
+	padding: 0;
+}
+.tundra .dijitCalendar .dijitDropDownButton .dijitButtonNode {
+	background-color: transparent;
+	background-image: none;
+	padding: 0;
+}
+
+/* Styling for month drop down list */
+
+.tundra .dijitCalendarMonthMenu .dijitCalendarMonthLabelHover {
+	background-color: #3559ac;
+	color:#fff;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/Calendar_rtl.css b/dijit/themes/tundra/Calendar_rtl.css
index 58e7653..fbfe27b 100644
--- a/dijit/themes/tundra/Calendar_rtl.css
+++ b/dijit/themes/tundra/Calendar_rtl.css
@@ -5,5 +5,5 @@
 }
 
 .tundra .dijitCalendarRtl .dijitCalendarIncrease {
-	background-position: 0px top;
+	background-position: 0 top;
 }
diff --git a/dijit/themes/tundra/ColorPalette.css b/dijit/themes/tundra/ColorPalette.css
index 9d3c4cc..38088b8 100644
--- a/dijit/themes/tundra/ColorPalette.css
+++ b/dijit/themes/tundra/ColorPalette.css
@@ -1,5 +1,5 @@
 .dijitColorPalette {
 	border:1px solid #7eabcd;
 	background:#fff;
-	-moz-border-radius: 0px !important;
+	-moz-border-radius: 0 !important;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/Dialog.css b/dijit/themes/tundra/Dialog.css
index 535603a..b346f62 100644
--- a/dijit/themes/tundra/Dialog.css
+++ b/dijit/themes/tundra/Dialog.css
@@ -3,8 +3,8 @@
 .tundra .dijitDialog {
 	background: #fff;
 	border: 1px solid #7eabcd;
-	padding: 0px;
-	-webkit-box-shadow: 0px 5px 10px #adadad;
+	padding: 0;
+	-webkit-box-shadow: 0 5px 10px #adadad;
 }
 
 .tundra .dijitDialogPaneContent {
@@ -24,7 +24,7 @@
 .tundra .dijitDialogTitle {
 	/* typography and styling of the dialog title */
 	font-weight: bold;
-	padding: 0px 4px;
+	padding: 0 4px;
 }
 
 .tundra .dijitDialogCloseIcon {
@@ -80,7 +80,7 @@
 
 .tundra .dijitTooltipConnector {
 	/* the arrow piece */
-	border:0px;
+	border:0;
 	z-index: 2;
 }
 .tundra .dijitTooltipABRight .dijitTooltipConnector {
@@ -92,7 +92,7 @@
 
 .tundra .dijitTooltipBelow .dijitTooltipConnector {
 	/* the arrow piece for tooltips below an element */
-	top: 0px;
+	top: 0;
 	left: 3px;
 	background:url("images/tooltipConnectorUp.png") no-repeat top left;
 	width:16px;
@@ -106,7 +106,7 @@
 
 .tundra .dijitTooltipAbove .dijitTooltipConnector {
 	/* the arrow piece for tooltips above an element */
-	bottom: 0px;
+	bottom: 0;
 	left: 3px;
 	background:url("images/tooltipConnectorDown.png") no-repeat top left;
 	width:16px;
@@ -122,13 +122,9 @@
 .tundra .dijitTooltipLeft {
 	padding-right: 14px;
 }
-.dj_ie6 .tundra .dijitTooltipLeft {
-	padding-left: 15px;
-}
 .tundra .dijitTooltipLeft .dijitTooltipConnector {
 	/* the arrow piece for tooltips to the left of an element, bottom borders aligned */
-	right: 0px;
-	bottom: 3px;
+	right: 0;
 	background:url("images/tooltipConnectorRight.png") no-repeat top left;
 	width:16px;
 	height:14px;
@@ -142,8 +138,7 @@
 }
 .tundra .dijitTooltipRight .dijitTooltipConnector {
 	/* the arrow piece for tooltips to the right of an element, bottom borders aligned */
-	left: 0px;
-	bottom: 3px;
+	left: 0;
 	background:url("images/tooltipConnectorLeft.png") no-repeat top left;
 	width:16px;
 	height:14px;
@@ -153,5 +148,5 @@
 }
 
 .dj_webkit .tundra .dijitTooltipContainer {
-	-webkit-box-shadow: 0px 5px 10px #adadad;
+	-webkit-box-shadow: 0 5px 10px #adadad;
 }
diff --git a/dijit/themes/tundra/Menu.css b/dijit/themes/tundra/Menu.css
index ff1e640..6229b17 100644
--- a/dijit/themes/tundra/Menu.css
+++ b/dijit/themes/tundra/Menu.css
@@ -1,8 +1,8 @@
 .tundra .dijitMenu,
 .tundra .dijitMenuBar {
 	border: 1px solid #7eabcd;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	background-color: #f7f7f7;
 }
 
@@ -42,13 +42,13 @@
 	width: 7px;
 	height: 7px;
 	background-image: url('images/spriteArrows.png');
-	background-position: -14px 0px;
+	background-position: -14px 0;
 }
 .dj_ie6 .tundra .dijitMenuExpand {
 	background-image: url('images/spriteArrows.gif');
 }
 
-/* separator can be two pixels -- set border of either one to 0px to have only one */
+/* separator can be two pixels -- set border of either one to 0 to have only one */
 .tundra .dijitMenuSeparatorTop {
 	border-bottom: 1px solid #9b9b9b;
 }
diff --git a/dijit/themes/tundra/Menu_rtl.css b/dijit/themes/tundra/Menu_rtl.css
index 0e7fbbe..f148592 100644
--- a/dijit/themes/tundra/Menu_rtl.css
+++ b/dijit/themes/tundra/Menu_rtl.css
@@ -1,3 +1,3 @@
 .tundra .dijitMenuItemRtl .dijitMenuExpand {
-	background-position: -7px 0px;
+	background-position: -7px 0;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/ProgressBar.css b/dijit/themes/tundra/ProgressBar.css
index 5b8a118..2d70e28 100644
--- a/dijit/themes/tundra/ProgressBar.css
+++ b/dijit/themes/tundra/ProgressBar.css
@@ -1,5 +1,5 @@
 .tundra .dijitProgressBar {
-	margin:2px 0px 2px 0px;
+	margin:2px 0 2px 0;
 }
 
 .tundra .dijitProgressBarEmpty {
diff --git a/dijit/themes/tundra/TimePicker_rtl.css b/dijit/themes/tundra/TimePicker_rtl.css
index da923d9..7a4d5e5 100644
--- a/dijit/themes/tundra/TimePicker_rtl.css
+++ b/dijit/themes/tundra/TimePicker_rtl.css
@@ -1,4 +1,4 @@
  .dj_ie6 .tundra .dijitTimePickerRtl .dijitTimePickerMarkerHover,
 .dj_ie7 .tundra .dijitTimePickerRtl .dijitTimePickerMarkerHover {
-        border-top: 0px; /* IE6/7 bug causes mouseover/out event storm */
+        border-top: 0; /* IE6/7 bug causes mouseover/out event storm */
 }
diff --git a/dijit/themes/tundra/TitlePane.css b/dijit/themes/tundra/TitlePane.css
index 141cc4b..e964bf8 100644
--- a/dijit/themes/tundra/TitlePane.css
+++ b/dijit/themes/tundra/TitlePane.css
@@ -11,7 +11,7 @@
 .tundra .dijitTitlePane .dijitArrowNode {
 	background-image: url('images/spriteArrows.png');
 	background-repeat: no-repeat;
-	background-position: 0px 0px;
+	background-position: 0 0;
 	height: 7px;
 	width: 7px;
 }
@@ -20,13 +20,13 @@
 }
 
 .tundra .dijitTitlePane .dijitClosed .dijitArrowNode {
-	background-position: -14px 0px;
+	background-position: -14px 0;
 }
 
 .tundra .dijitTitlePaneContentOuter {
 	background: #ffffff;
 	border:1px solid #bfbfbf;
-	border-top: 0px;
+	border-top: 0;
 }
 .tundra .dijitTitlePaneContentInner {
 	padding:10px;
diff --git a/dijit/themes/tundra/TitlePane_rtl.css b/dijit/themes/tundra/TitlePane_rtl.css
index e4b082d..5f63a03 100644
--- a/dijit/themes/tundra/TitlePane_rtl.css
+++ b/dijit/themes/tundra/TitlePane_rtl.css
@@ -1,3 +1,3 @@
 .tundra .dijitTitlePaneRtl .dijitClosed .dijitArrowNode {
-	background-position: -7px 0px;
+	background-position: -7px 0;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/Toolbar.css b/dijit/themes/tundra/Toolbar.css
index 2e6420f..ebe9cda 100644
--- a/dijit/themes/tundra/Toolbar.css
+++ b/dijit/themes/tundra/Toolbar.css
@@ -12,8 +12,8 @@
 .tundra .dijitToolbar .dijitComboButton .dijitButtonContents,
 .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButton {
 	background: none;
-	margin: 0px;
-	padding: 0px;
+	margin: 0;
+	padding: 0;
 	border: none;
 	font-size: 12px;
 }
@@ -31,7 +31,7 @@
 .tundra .dijitToolbar .dijitToggleButtonChecked {
 	background-color:#d4dff2;
 	border:1px solid #316ac5;
-	padding: 0px;	/* reduce padding to compensate for space taken by border */
+	padding: 0;	/* reduce padding to compensate for space taken by border */
 }
 
 .tundra .dijitToolbar .dijitButtonCheckedHover,
@@ -39,7 +39,7 @@
  {
 	background-color:#abc1e5;
 	border:1px solid #316ac5;
-	padding: 0px;	/* reduce padding to compensate for space taken by border */
+	padding: 0;	/* reduce padding to compensate for space taken by border */
 }
 
 .tundra .dijitToolbar .dijitButtonHover,
@@ -49,7 +49,7 @@
 .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButtonHover {
 	/* TODO: change this from Hover to Selected so that button is still highlighted while drop down is being used */
 	border: 1px solid #869cbf;
-	padding: 0px;	/* reduce padding to compensate for space taken by border */
+	padding: 0;	/* reduce padding to compensate for space taken by border */
 	background-color:#e1e5f0;
 }
 
@@ -61,7 +61,7 @@
 .dj_ie .tundra .dijitToolbar .dijitComboButton .dijitDownArrowButtonFocused {
 	/* focus border doesn't appear on <td> for IE, so need to add it manually */
 	border: 1px #555 dotted !important;
-	padding: 0px;
+	padding: 0;
 }
 
 .tundra .dijitToolbarSeparator {
diff --git a/dijit/themes/tundra/form/Button.css b/dijit/themes/tundra/form/Button.css
index fe307fe..2c68aef 100644
--- a/dijit/themes/tundra/form/Button.css
+++ b/dijit/themes/tundra/form/Button.css
@@ -79,10 +79,10 @@
 }
 
 .tundra .dijitArrowButtonInner {
-	background:url("../images/spriteArrows.png") no-repeat scroll 0px center;
+	background:url("../images/spriteArrows.png") no-repeat scroll 0 center;
 	width: 7px;
 	height: 7px;
-	margin: 0px 4px 0px 4px;
+	margin: 0 4px 0 4px;
 }
 .tundra .dijitTextBox .dijitArrowButtonInner {
 	background-position: 0 center;
diff --git a/dijit/themes/tundra/form/Checkbox.css b/dijit/themes/tundra/form/Checkbox.css
index 5a93037..28a7d79 100644
--- a/dijit/themes/tundra/form/Checkbox.css
+++ b/dijit/themes/tundra/form/Checkbox.css
@@ -30,7 +30,7 @@
 .tundra .dijitCheckBoxChecked,
 .tundra .dijitToggleButtonChecked .dijitCheckBoxIcon {
 	/* checked */
-	background-position: 0px;
+	background-position: 0;
 }
 
 .tundra .dijitCheckBoxDisabled {
diff --git a/dijit/themes/tundra/form/Common.css b/dijit/themes/tundra/form/Common.css
index 1abf817..2013686 100644
--- a/dijit/themes/tundra/form/Common.css
+++ b/dijit/themes/tundra/form/Common.css
@@ -12,7 +12,7 @@
 
 .tundra .dijitInputContainer INPUT,
 .tundra .dijitTextBox {
-	margin: 0em 0.1em;
+	margin: 0 0.1em;
 }
 
 .tundra .dijitTextArea {
diff --git a/dijit/themes/tundra/form/Select.css b/dijit/themes/tundra/form/Select.css
index a52eb71..b029016 100644
--- a/dijit/themes/tundra/form/Select.css
+++ b/dijit/themes/tundra/form/Select.css
@@ -1,8 +1,8 @@
 .tundra .dijitSelect .dijitButtonNode {
-	padding: 0px;
+	padding: 0;
 }
 .tundra .dijitSelect .dijitButtonNode .dijitArrowButtonInner {
-	margin: 0px 4px 0px 5px;
+	margin: 0 4px 0 5px;
 }
 
 /* Make unselected content portion "look" more like a text box and less like a button */
@@ -19,7 +19,7 @@
 	background: transparent none;
 }
 .dj_ie .tundra .dijitSelect .dijitButtonContents {
-	padding-top: 0px;
+	padding-top: 0;
 }
 
 /* Mirror DropDownButton */
@@ -47,7 +47,7 @@
 
 /* Make the menu look more combobox-like */
 .tundra .dijitSelectMenu td {
-	padding: 0em;
+	padding: 0;
 }
 .tundra .dijitSelectMenu .dijitMenuItemLabel,
 .tundra .dijitSelectMenu .dijitMenuArrowCell {
diff --git a/dijit/themes/tundra/form/Slider.css b/dijit/themes/tundra/form/Slider.css
index 17c3d6e..7465e83 100644
--- a/dijit/themes/tundra/form/Slider.css
+++ b/dijit/themes/tundra/form/Slider.css
@@ -37,7 +37,7 @@
 }
 
 .tundra .dijitSliderImageHandleH {
-	border:0px;
+	border:0;
 	width:16px;
 	height:16px;
 	background:url("../images/preciseSliderThumb.png") no-repeat center top;
@@ -64,7 +64,7 @@
 }
 
 .tundra .dijitSliderImageHandleV {
-	border:0px;
+	border:0;
 	width:16px;
 	height:16px;
 	background:url("../images/sliderThumb.png") no-repeat center center;
@@ -108,16 +108,16 @@
 }
 
 .tundra .dijitSliderDecrementIconH {
-	background-position: -7px 0px;
+	background-position: -7px 0;
 }
 .tundra .dijitSliderIncrementIconH {
-	background-position: -14px 0px;
+	background-position: -14px 0;
 }
 .tundra .dijitSliderDecrementIconV {
-	background-position: 0px 0px;
+	background-position: 0 0;
 }
 .tundra .dijitSliderIncrementIconV {
-	background-position: -21px 0px;
+	background-position: -21px 0;
 }
 
 .tundra .dijitSliderButtonInner {
@@ -131,17 +131,17 @@
 }
 .tundra .dijitSliderReadOnly .dijitSliderDecrementIconH,
 .tundra .dijitSliderDisabled .dijitSliderDecrementIconH {
-	background-position: -35px 0px;
+	background-position: -35px 0;
 }
 .tundra .dijitSliderReadOnly .dijitSliderIncrementIconH,
 .tundra .dijitSliderDisabled .dijitSliderIncrementIconH {
-	background-position: -42px 0px;
+	background-position: -42px 0;
 }
 .tundra .dijitSliderReadOnly .dijitSliderDecrementIconV,
 .tundra .dijitSliderDisabled .dijitSliderDecrementIconV {
-	background-position: -28px 0px;
+	background-position: -28px 0;
 }
 .tundra .dijitSliderReadOnly .dijitSliderIncrementIconV,
 .tundra .dijitSliderDisabled .dijitSliderIncrementIconV {
-	background-position: -49px 0px;
+	background-position: -49px 0;
 }
\ No newline at end of file
diff --git a/dijit/themes/tundra/form/Slider_rtl.css b/dijit/themes/tundra/form/Slider_rtl.css
index e816d7a..9375c4e 100644
--- a/dijit/themes/tundra/form/Slider_rtl.css
+++ b/dijit/themes/tundra/form/Slider_rtl.css
@@ -13,19 +13,19 @@
 }
 
 .tundra .dijitSliderRtl .dijitSliderLeftBumper {
-	border-left-width: 0px;
+	border-left-width: 0;
 	border-right-width: 1px;
 }
 
 .tundra .dijitSliderRtl .dijitSliderRightBumper {
 	border-left-width: 1px;
-	border-right-width: 0px;
+	border-right-width: 0;
 }
 
 .tundra .dijitSliderRtl .dijitSliderIncrementIconH {
-	background-position: -7px 0px;
+	background-position: -7px 0;
 }
 
 .tundra .dijitSliderRtl .dijitSliderDecrementIconH {
-	background-position: -14px 0px;
+	background-position: -14px 0;
 }
diff --git a/dijit/themes/tundra/layout/BorderContainer.css b/dijit/themes/tundra/layout/BorderContainer.css
index 0057fcb..0dd1b1b 100644
--- a/dijit/themes/tundra/layout/BorderContainer.css
+++ b/dijit/themes/tundra/layout/BorderContainer.css
@@ -26,7 +26,7 @@
 .tundra .dijitBorderContainer-dijitBorderContainer {
 	/* also, make nested BorderContainers look like a single big widget with lots of splitters */
 	border: none;
-	padding: 0px;
+	padding: 0;
 }
 
 .tundra .dijitSplitterH,
diff --git a/dijit/themes/tundra/layout/ContentPane.css b/dijit/themes/tundra/layout/ContentPane.css
index 27d8fb9..21d25d5 100644
--- a/dijit/themes/tundra/layout/ContentPane.css
+++ b/dijit/themes/tundra/layout/ContentPane.css
@@ -1,7 +1,7 @@
 /* ContentPane */
 
 .tundra .dijitContentPane {
-	padding: 0px;
+	padding: 0;
 }
 
 /* nested layouts */
diff --git a/dijit/themes/tundra/layout/TabContainer.css b/dijit/themes/tundra/layout/TabContainer.css
index d28eab5..667da4a 100644
--- a/dijit/themes/tundra/layout/TabContainer.css
+++ b/dijit/themes/tundra/layout/TabContainer.css
@@ -9,7 +9,7 @@
 .tundra .dijitTab {
 	line-height:normal;
 	margin-right:4px;	/* space between one tab and the next in top/bottom mode */
-	padding:0px;
+	padding:0;
 	border:1px solid #ccc;
 	background:#e2e2e2 url("../images/tabEnabled.png") repeat-x;
 }
@@ -33,7 +33,7 @@
 	top: 2px;
 }
 .tundra .dijitTabContainerBottom .nowrapTabStrip .dijitTab {
-	top: 0px;
+	top: 0;
 	bottom: 2px;
 }
 
@@ -96,7 +96,7 @@
 .tundra .dijitTabContainerTabListNested .dijitTab {
 	background: none;
 	border: none;
-	top: 0px;		/* to override top: 1px/-1px for normal tabs */
+	top: 0;		/* to override top: 1px/-1px for normal tabs */
 }
 .tundra .dijitTabContainerTabListNested .dijitTab .dijitTabContent {
 }
@@ -134,13 +134,13 @@
 /* top tabs */
 
 .tundra .dijitTabContainerTop-tabs {
-	margin-bottom: 0px;
+	margin-bottom: 0;
 	border-color: #cccccc;
 	padding-left: 3px;
 	background-position: bottom;
 }
 .tundra .dijitTabContainerTop-tabs .dijitTab {
-	top: 0px;
+	top: 0;
 	margin-bottom: -1px;
 }
 
@@ -170,20 +170,20 @@
 }
 
 .tundra .dijitTabContainerTopNone {
-	padding-top: 0px;
+	padding-top: 0;
 }
 
 
 /* ================================ */
 /* bottom tabs */
 .tundra .dijitTabContainerBottom-tabs {
-	margin-top: 0px;
+	margin-top: 0;
 	border-color: #cccccc;
 	background-position: top;
 	padding-left: 3px;
 }
 .tundra .dijitTabContainerBottom-tabs .dijitTab {
-	bottom: 0px;
+	bottom: 0;
 	margin-top: -1px;
 }
 
@@ -267,7 +267,7 @@
 /* left/right tabs */
 .tundra .dijitTabContainerLeft-tabs .dijitTab,
 .tundra .dijitTabContainerRight-tabs .dijitTab {
-	margin-right:0px;
+	margin-right:0;
 	margin-bottom:4px;	/* space between one tab and the next in left/right mode */
 }
 
@@ -275,11 +275,11 @@
 
 /* this resets the tabcontainer stripe when within a contentpane */
 .tundra .dijitTabContainerTop-dijitContentPane .dijitTabContainerTop-tabs {
-	border-left: 0px solid #ccc;
-	border-top: 0px solid #ccc;
-	border-right: 0px solid #ccc;
-	padding-top: 0px;
-	padding-left: 0px;
+	border-left: 0 solid #ccc;
+	border-top: 0 solid #ccc;
+	border-right: 0 solid #ccc;
+	padding-top: 0;
+	padding-left: 0;
 }
 
 /* ================================ */
diff --git a/dijit/themes/tundra/layout/TabContainer_rtl.css b/dijit/themes/tundra/layout/TabContainer_rtl.css
index 95c8a66..fb8e28e 100644
--- a/dijit/themes/tundra/layout/TabContainer_rtl.css
+++ b/dijit/themes/tundra/layout/TabContainer_rtl.css
@@ -31,7 +31,7 @@
 
 .tundra .dijitTabContainerLeft-tabs .dijitTabRtl,
 .tundra .dijitTabContainerRight-tabs .dijitTabRtl {
-	margin-left:0px;
+	margin-left:0;
 }
 
 .dj_ie .tundra .dijitTabRtl .dijitTabInnerDiv {
diff --git a/dijit/tree/ForestStoreModel.js b/dijit/tree/ForestStoreModel.js
index f39a978..9fa8011 100644
--- a/dijit/tree/ForestStoreModel.js
+++ b/dijit/tree/ForestStoreModel.js
@@ -1,17 +1,23 @@
-dojo.provide("dijit.tree.ForestStoreModel");
-
-dojo.require("dijit.tree.TreeStoreModel");
+define("dijit/tree/ForestStoreModel", ["dojo", "dijit", "dijit/tree/TreeStoreModel"], function(dojo, dijit) {
 
 dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 	// summary:
-	//		Interface between Tree and a dojo.store that doesn't have a root item,
-	//		i.e. has multiple "top level" items.
+	//		Interface between a dijit.Tree and a dojo.data store that doesn't have a root item,
+	//		a.k.a. a store that has multiple "top level" items.
 	//
 	// description
-	//		Use this class to wrap a dojo.store, making all the items matching the specified query
+	//		Use this class to wrap a dojo.data store, making all the items matching the specified query
 	//		appear as children of a fabricated "root item".  If no query is specified then all the
 	//		items returned by fetch() on the underlying store become children of the root item.
-	//		It allows dijit.Tree to assume a single root item, even if the store doesn't have one.
+	//		This class allows dijit.Tree to assume a single root item, even if the store doesn't have one.
+	//
+	//		When using this class the developer must override a number of methods according to their app and
+	//		data, including:
+	//			- onNewRootItem
+	//			- onAddToRoot
+	//			- onLeaveRoot
+	//			- onNewItem
+	//			- onSetItem
 
 	// Parameters to constructor
 
@@ -211,9 +217,9 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 		//		a new item is created, since any new item could be a top level item (even in
 		//		addition to being a child of another item, since items can have multiple parents).
 		//
-		//		Developers can override this function to do something more efficient if they can
-		//		detect which items are possible top level items (based on the item and the
-		//		parentInfo parameters).  Often all top level items have parentInfo==null, but
+		//		If developers can detect which items are possible top level items (based on the item and the
+		//		parentInfo parameters), they should override this method to only call _requeryTop() for top
+		//		level items.  Often all top level items have parentInfo==null, but
 		//		that will depend on which store you use and what your data is like.
 		// tags:
 		//		extension
@@ -233,7 +239,33 @@ dojo.declare("dijit.tree.ForestStoreModel", dijit.tree.TreeStoreModel, {
 		}
 
 		this.inherited(arguments);
+	},
+
+	onSetItem: function(/* item */ item,
+					/* attribute-name-string */ attribute,
+					/* object | array */ oldValue,
+					/* object | array */ newValue){
+		// summary:
+		//		Updates the tree view according to changes to an item in the data store.
+		//		Developers should override this method to be more efficient based on their app/data.
+		// description:
+		//		Handles updates to an item's children by calling onChildrenChange(), and
+		//		other updates to an item by calling onChange().
+		//
+		//		Also, any change to any item re-executes the query for the tree's top-level items,
+		//		since this modified item may have started/stopped matching the query for top level items.
+		//
+		//		If possible, developers should override this function to only call _requeryTop() when
+		//		the change to the item has caused it to stop/start being a top level item in the tree.
+		// tags:
+		//		extension
+
+		this._requeryTop();
+		this.inherited(arguments);
 	}
+
 });
 
 
+return dijit.tree.ForestStoreModel;
+});
diff --git a/dijit/tree/TreeStoreModel.js b/dijit/tree/TreeStoreModel.js
index 660b2fd..e188b58 100644
--- a/dijit/tree/TreeStoreModel.js
+++ b/dijit/tree/TreeStoreModel.js
@@ -1,4 +1,4 @@
-dojo.provide("dijit.tree.TreeStoreModel");
+define("dijit/tree/TreeStoreModel", ["dojo", "dijit"], function(dojo, dijit) {
 
 dojo.declare(
 		"dijit.tree.TreeStoreModel",
@@ -211,7 +211,7 @@ dojo.declare(
 			//		to parents with multiple children attributes, in order to define which
 			//		children attribute points to the new item.
 
-			var pInfo = {parent: parent, attribute: this.childrenAttrs[0], insertIndex: insertIndex};
+			var pInfo = {parent: parent, attribute: this.childrenAttrs[0]}, LnewItem;
 
 			if(this.newItemIdAttr && args[this.newItemIdAttr]){
 				// Maybe there's already a corresponding item in the store; if so, reuse it.
@@ -221,12 +221,20 @@ dojo.declare(
 						this.pasteItem(item, null, parent, true, insertIndex);
 					}else{
 						// Create new item in the tree, based on the drag source.
-						this.store.newItem(args, pInfo);
+						LnewItem=this.store.newItem(args, pInfo);
+						if (LnewItem && (insertIndex!=undefined)){
+							// Move new item to desired position
+							this.pasteItem(LnewItem, parent, parent, false, insertIndex);
+						}
 					}
 				}});
 			}else{
 				// [as far as we know] there is no id so we must assume this is a new item
-				this.store.newItem(args, pInfo);
+				LnewItem=this.store.newItem(args, pInfo);
+				if (LnewItem && (insertIndex!=undefined)){
+					// Move new item to desired position
+					this.pasteItem(LnewItem, parent, parent, false, insertIndex);
+				}
 			}
 		},
 
@@ -361,3 +369,5 @@ dojo.declare(
 	});
 
 
+return dijit.tree.TreeStoreModel;
+});
diff --git a/dijit/tree/_dndContainer.js b/dijit/tree/_dndContainer.js
index 3fa3c5d..4b50340 100644
--- a/dijit/tree/_dndContainer.js
+++ b/dijit/tree/_dndContainer.js
@@ -1,6 +1,29 @@
-dojo.provide("dijit.tree._dndContainer");
-dojo.require("dojo.dnd.common");
-dojo.require("dojo.dnd.Container");
+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,
@@ -63,9 +86,9 @@ dojo.declare("dijit.tree._dndContainer",
 			// tags:
 			//		protected
 
-			var node = this.selection[key],
+			var widget = this.selection[key],
 				ret = {
-					data: dijit.getEnclosingWidget(node),
+					data: widget,
 					type: ["treeNode"]
 				};
 
@@ -87,8 +110,7 @@ dojo.declare("dijit.tree._dndContainer",
 			//		Called when mouse is moved over a TreeNode
 			// tags:
 			//		protected
-			this.current = widget.rowNode;
-			this.currentWidget = widget;
+			this.current = widget;
 		},
 
 		onMouseOut: function(/*TreeNode*/ widget, /*Event*/ evt){
@@ -97,7 +119,6 @@ dojo.declare("dijit.tree._dndContainer",
 			// tags:
 			//		protected
 			this.current = null;
-			this.currentWidget = null;
 		},
 
 		_changeState: function(type, newState){
@@ -110,8 +131,7 @@ dojo.declare("dijit.tree._dndContainer",
 			var prefix = "dojoDnd" + type;
 			var state = type.toLowerCase() + "State";
 			//dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
-			dojo.removeClass(this.node, prefix + this[state]);
-			dojo.addClass(this.node, prefix + newState);
+			dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
 			this[state] = newState;
 		},
 
@@ -151,3 +171,7 @@ dojo.declare("dijit.tree._dndContainer",
 			this._changeState("Container", "");
 		}
 });
+
+
+return dijit.tree._dndContainer;
+});
diff --git a/dijit/tree/_dndSelector.js b/dijit/tree/_dndSelector.js
index bfecfed..91f850d 100644
--- a/dijit/tree/_dndSelector.js
+++ b/dijit/tree/_dndSelector.js
@@ -1,6 +1,4 @@
-dojo.provide("dijit.tree._dndSelector");
-dojo.require("dojo.dnd.common");
-dojo.require("dijit.tree._dndContainer");
+define("dijit/tree/_dndSelector", ["dojo", "dijit", "dojo/dnd/common", "dijit/tree/_dndContainer"], function(dojo, dijit) {
 
 dojo.declare("dijit.tree._dndSelector",
 	dijit.tree._dndContainer,
@@ -26,7 +24,8 @@ dojo.declare("dijit.tree._dndSelector",
 
 			this.selection={};
 			this.anchor = null;
-			this.simpleSelection=false;
+
+			dijit.setWaiState(this.tree.domNode, "multiselect", !this.singular);
 
 			this.events.push(
 				dojo.connect(this.tree.domNode, "onmousedown", this,"onMouseDown"),
@@ -41,14 +40,17 @@ dojo.declare("dijit.tree._dndSelector",
 		singular: false,
 
 		// methods
-
-		getSelectedNodes: function(){
+		getSelectedTreeNodes: function(){
 			// summary:
-			//		Returns the set of selected nodes.
+			//		Returns a list of selected node(s).
 			//		Used by dndSource on the start of a drag.
 			// tags:
 			//		protected
-			return this.selection;
+			var nodes=[], sel = this.selection;
+			for(var i in sel){
+				nodes.push(sel[i]);
+			}
+			return nodes;
 		},
 
 		selectNone: function(){
@@ -57,7 +59,8 @@ dojo.declare("dijit.tree._dndSelector",
 			// tags:
 			//		private
 
-			return this._removeSelection()._removeAnchor();	// self
+			this.setSelection([]);
+			return this;	// self
 		},
 
 		destroy: function(){
@@ -66,7 +69,89 @@ dojo.declare("dijit.tree._dndSelector",
 			this.inherited(arguments);
 			this.selection = this.anchor = null;
 		},
+		addTreeNode: function(/*dijit._TreeNode*/node, /*Boolean?*/isAnchor){
+			// summary
+			//		add node to current selection
+			// node: Node
+			//		node to add
+			// isAnchor: Boolean
+			//		Whether the node should become anchor.
 
+			this.setSelection(this.getSelectedTreeNodes().concat( [node] ));
+			if(isAnchor){ this.anchor = node; }
+			return node;
+		},
+		removeTreeNode: function(/*dijit._TreeNode*/node){
+			// summary
+			//		remove node from current selection
+			// node: Node
+			//		node to remove
+			this.setSelection(this._setDifference(this.getSelectedTreeNodes(), [node]))
+			return node;
+		},
+		isTreeNodeSelected: function(/*dijit._TreeNode*/node){
+			// summary
+			//		return true if node is currently selected
+			// node: Node
+			//		the node to check whether it's in the current selection
+
+			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.
+			// newSelection: Node[]
+			//      list of tree nodes to make selected
+			var oldSelection = this.getSelectedTreeNodes();
+			dojo.forEach(this._setDifference(oldSelection, newSelection), dojo.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){
+				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__; });
+
+			// clean up after ourselves.
+			dojo.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]
+			
+			var selected = this.getSelectedTreeNodes();
+			var paths = [], nodes = [];
+			dojo.forEach(selected, function(node) {
+				nodes.push(node);
+				paths.push(node.getTreePath());
+			});
+			var items = dojo.map(nodes,function(node) { return node.item; });
+			this.tree._set("paths", paths);
+			this.tree._set("path", paths[0] || []);
+			this.tree._set("selectedNodes", nodes);
+			this.tree._set("selectedNode", nodes[0] || null);
+			this.tree._set("selectedItems", items);
+			this.tree._set("selectedItem", items[0] || null);
+		},
 		// mouse events
 		onMouseDown: function(e){
 			// summary:
@@ -76,72 +161,26 @@ dojo.declare("dijit.tree._dndSelector",
 			// tags:
 			//		protected
 
-			if(!this.current){ return; }
+			// ignore click on expando node
+			if(!this.current || this.tree.isExpandoNode( e.target, this.current)){ return; }
 
 			if(e.button == dojo.mouseButtons.RIGHT){ return; }	// ignore right-click
 
-			var treeNode = dijit.getEnclosingWidget(this.current),
-				id = treeNode.id + "-dnd"	// so id doesn't conflict w/widget
+			dojo.stopEvent(e);
 
-			if(!dojo.hasAttr(this.current, "id")){
-				dojo.attr(this.current, "id", id);
-			}
+			var treeNode = this.current,
+			  copy = dojo.isCopyKey(e), id = treeNode.id;
 
-			if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
-				this.simpleSelection = true;
-				dojo.stopEvent(e);
+			// 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
+			// will be canceled by onmousemove.
+			if(!this.singular && !e.shiftKey && this.selection[id]){
+				this._doDeselect = true;
 				return;
-			}
-			if(this.singular){
-				if(this.anchor == this.current){
-					if(dojo.isCopyKey(e)){
-						this.selectNone();
-					}
-				}else{
-					this.selectNone();
-					this.anchor = this.current;
-					this._addItemClass(this.anchor, "Anchor");
-
-					this.selection[this.current.id] = this.current;
-				}
 			}else{
-				if(!this.singular && e.shiftKey){
-					if(dojo.isCopyKey(e)){
-						//TODO add range to selection
-					}else{
-						//TODO select new range from anchor
-					}
-				}else{
-					if(dojo.isCopyKey(e)){
-						if(this.anchor == this.current){
-							delete this.selection[this.anchor.id];
-							this._removeAnchor();
-						}else{
-							if(this.current.id in this.selection){
-								this._removeItemClass(this.current, "Selected");
-								delete this.selection[this.current.id];
-							}else{
-								if(this.anchor){
-									this._removeItemClass(this.anchor, "Anchor");
-									this._addItemClass(this.anchor, "Selected");
-								}
-								this.anchor = this.current;
-								this._addItemClass(this.current, "Anchor");
-								this.selection[this.current.id] = this.current;
-							}
-						}
-					}else{
-						if(!(id in this.selection)){
-							this.selectNone();
-							this.anchor = this.current;
-							this._addItemClass(this.current, "Anchor");
-							this.selection[id] = this.current;
-						}
-					}
-				}
+				this._doDeselect = false;
 			}
-
-			dojo.stopEvent(e);
+			this.userSelect(treeNode, copy, e.shiftKey);
 		},
 
 		onMouseUp: function(e){
@@ -152,57 +191,73 @@ dojo.declare("dijit.tree._dndSelector",
 			// tags:
 			//		protected
 
-			// TODO: this code is apparently for handling an edge case when the user is selecting
-			// multiple nodes and then mousedowns on a node by accident... it lets the user keep the
-			// current selection by moving the mouse away (or something like that).   It doesn't seem
-			// to work though and requires a lot of plumbing (including this code, the onmousemove
-			// handler, and the this.simpleSelection attribute.   Consider getting rid of all of it.
-
-			if(!this.simpleSelection){ return; }
-			this.simpleSelection = false;
-			this.selectNone();
-			if(this.current){
-				this.anchor = this.current;
-				this._addItemClass(this.anchor, "Anchor");
-				this.selection[this.current.id] = this.current;
-			}
+			// _doDeselect is the flag to indicate that the user wants to either ctrl+click on
+			// a already selected item (to deselect the item), or click on a not-yet selected item
+			// (which should remove all current selection, and add the clicked item). This can not
+			// be done in onMouseDown, because the user may start a drag after mousedown. By moving
+			// the deselection logic here, the user can drags an already selected item.
+			if(!this._doDeselect){ return; }
+			this._doDeselect = false;
+			this.userSelect(this.current, dojo.isCopyKey( e ), e.shiftKey);
 		},
 		onMouseMove: function(e){
 			// summary
 			//		event processor for onmousemove
 			// e: Event
 			//		mouse event
-			this.simpleSelection = false;
+			this._doDeselect = false;
 		},
 
-		_removeSelection: function(){
+		userSelect: function(node, multi, range){
 			// summary:
-			//		Unselects all items
+			//		Add or remove the given node from selection, responding
+			//      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
+			//		Indicates whether this is meant to be a ranged action (e.g. shift-click)
 			// tags:
-			//		private
-			var e = dojo.dnd._empty;
-			for(var i in this.selection){
-				if(i in e){ continue; }
-				var node = dojo.byId(i);
-				if(node){ this._removeItemClass(node, "Selected"); }
-			}
-			this.selection = {};
-			return this;	// self
-		},
+			//		protected
 
-		_removeAnchor: function(){
-			// summary:
-			//		Removes the Anchor CSS class from a node.
-			//		According to `dojo.dnd.Selector`, anchor means that
-			//		"an item is selected, and is an anchor for a 'shift' selection".
-			//		It's not relevant for Tree at this point, since we don't support multiple selection.
-			// tags:
-			//		private
-			if(this.anchor){
-				this._removeItemClass(this.anchor, "Anchor");
-				this.anchor = null;
+			if(this.singular){
+				if(this.anchor == node && multi){
+					this.selectNone();
+				}else{
+					this.setSelection([node]);
+					this.anchor = node;
+				}
+			}else{
+				if(range && this.anchor){
+					var cr = dijit.tree._compareNodes(this.anchor.rowNode, node.rowNode),
+					begin, end, anchor = this.anchor;
+					
+					if(cr < 0){ //current is after anchor
+						begin = anchor;
+						end = node;
+					}else{ //current is before anchor
+						begin = node;
+						end = anchor;
+					}
+					nodes = [];
+					//add everything betweeen begin and end inclusively
+					while(begin != end) {
+						nodes.push(begin)
+						begin = this.tree._getNextNode(begin);
+					}
+					nodes.push(end)
+
+					this.setSelection(nodes);
+				}else{
+				    if( this.selection[ node.id ] && multi ) {
+						this.removeTreeNode( node );
+				    } else if(multi) {
+						this.addTreeNode(node, true);
+					} else {
+						this.setSelection([node]);
+						this.anchor = node;
+				    }
+				}
 			}
-			return this;	// self
 		},
 
 		forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
@@ -211,8 +266,12 @@ dojo.declare("dijit.tree._dndSelector",
 			//		see `dojo.dnd.Container.forInItems()` for details
 			o = o || dojo.global;
 			for(var id in this.selection){
-				console.log("selected item id: " + id);
+				// 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 54b867b..45c4165 100644
--- a/dijit/tree/dndSource.js
+++ b/dijit/tree/dndSource.js
@@ -1,7 +1,4 @@
-dojo.provide("dijit.tree.dndSource");
-
-dojo.require("dijit.tree._dndSelector");
-dojo.require("dojo.dnd.Manager");
+define("dijit/tree/dndSource", ["dojo", "dijit", "dijit/tree/_dndSelector", "dojo/dnd/Manager"], function(dojo, dijit) {
 
 /*=====
 dijit.tree.__SourceArgs = function(){
@@ -135,9 +132,8 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		//		Keeps track of current drop target.
 
 		var m = dojo.dnd.manager(),
-			oldTarget = this.targetAnchor,			// the DOMNode corresponding to TreeNode mouse was previously over
-			newTarget = this.current,				// DOMNode corresponding to TreeNode mouse is currently over
-			newTargetWidget = this.currentWidget,	// the TreeNode itself
+			oldTarget = this.targetAnchor,			// the TreeNode corresponding to TreeNode mouse was previously over
+			newTarget = this.current,				// TreeNode corresponding to TreeNode mouse is currently over
 			oldDropPosition = this.dropPosition;	// the previous drop position (over/before/after)
 
 		// calculate if user is indicating to drop the dragged node before, after, or over
@@ -146,7 +142,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, true);
+				this.targetBox = dojo.position(newTarget.rowNode, true);
 			}
 			if((e.pageY - this.targetBox.y) <= this.betweenThreshold){
 				newDropPosition = "Before";
@@ -157,23 +153,23 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 
 		if(newTarget != oldTarget || newDropPosition != oldDropPosition){
 			if(oldTarget){
-				this._removeItemClass(oldTarget, oldDropPosition);
+				this._removeItemClass(oldTarget.rowNode, oldDropPosition);
 			}
 			if(newTarget){
-				this._addItemClass(newTarget, newDropPosition);
+				this._addItemClass(newTarget.rowNode, newDropPosition);
 			}
 
 			// Check if it's ok to drop the dragged node on/before/after the target node.
 			if(!newTarget){
 				m.canDrop(false);
-			}else if(newTargetWidget == this.tree.rootNode && newDropPosition != "Over"){
+			}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, m.source, newDropPosition.toLowerCase())
-					&& !this._isParentChildDrop(m.source, newTarget)){
+			}else if(this.checkItemAcceptance(newTarget.rowNode, m.source, newDropPosition.toLowerCase())
+					&& !this._isParentChildDrop(m.source, newTarget.rowNode)){
 				m.canDrop(true);
 			}else{
 				m.canDrop(false);
@@ -199,12 +195,23 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		}else{
 			if(this.mouseDown && this.isSource &&
 				 (Math.abs(e.pageX-this._lastX)>=this.dragThreshold || Math.abs(e.pageY-this._lastY)>=this.dragThreshold)){
-				var n = this.getSelectedNodes();
-				var nodes=[];
-				for(var i in n){
-					nodes.push(n[i]);
-				}
+				var nodes = this.getSelectedTreeNodes();
 				if(nodes.length){
+					if(nodes.length > 1){
+						//filter out all selected items which has one of their ancestor selected as well
+						var seen = this.selection, i = 0, r = [], n, p;
+						nextitem: while((n = nodes[i++])){
+							for(p = n.getParent(); p && p !== this.tree; p = p.getParent()){
+								if(seen[p.id]){ //parent is already selected, skip this node
+									continue nextitem;
+								}
+							}
+							//this node does not have any ancestors selected, add it
+							r.push(n);
+						}
+						nodes = r;
+					}
+					nodes = dojo.map(nodes, function(n){return n.domNode});
 					m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e)));
 				}
 			}
@@ -222,7 +229,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		this.mouseButton = e.button;
 		this._lastX = e.pageX;
 		this._lastY = e.pageY;
-		this.inherited("onMouseDown",arguments);
+		this.inherited(arguments);
 	},
 
 	onMouseUp: function(e){
@@ -234,7 +241,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		//		private
 		if(this.mouseDown){
 			this.mouseDown = false;
-			this.inherited("onMouseUp",arguments);
+			this.inherited(arguments);
 		}
 	},
 
@@ -360,7 +367,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 			this.isDragging = false;
 
 			// Compute the new parent item
-			var targetWidget = dijit.getEnclosingWidget(target);
+			var targetWidget = target;
 			var newParentItem;
 			var insertIndex;
 			newParentItem = (targetWidget && targetWidget.item) || tree.item;
@@ -416,7 +423,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 					// Get the hash to pass to model.newItem().  A single call to
 					// itemCreator() returns an array of hashes, one for each drag source node.
 					if(!newItemsParams){
-						newItemsParams = this.itemCreator(nodes, target, source);
+						newItemsParams = this.itemCreator(nodes, target.rowNode, source);
 					}
 
 					// Create new item in the tree, based on the drag source.
@@ -490,16 +497,13 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 
 
 		var root = source.tree.domNode;
-		var ids = {};
-		for(var x in source.selection){
-			ids[source.selection[x].parentNode.id] = true;
-		}
+		var ids = source.selection;
 
 		var node = targetRow.parentNode;
 
 		// Iterate up the DOM hierarchy from the target drop row,
 		// checking of any of the dragged nodes have the same ID.
-		while(node != root && (!node.id || !ids[node.id])){
+		while(node != root && !ids[node.id]){
 			node = node.parentNode;
 		}
 
@@ -512,7 +516,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		// tags:
 		//		private
 		if(!this.targetAnchor){ return; }
-		this._removeItemClass(this.targetAnchor, this.dropPosition);
+		this._removeItemClass(this.targetAnchor.rowNode, this.dropPosition);
 		this.targetAnchor = null;
 		this.targetBox = null;
 		this.dropPosition = null;
@@ -524,3 +528,7 @@ dojo.declare("dijit.tree.dndSource", dijit.tree._dndSelector, {
 		this._changeState("Source", copy ? "Copied" : "Moved");
 	}
 });
+
+
+return dijit.tree.dndSource;
+});
diff --git a/dojo/AdapterRegistry.js b/dojo/AdapterRegistry.js
index d186330..b906954 100644
--- a/dojo/AdapterRegistry.js
+++ b/dojo/AdapterRegistry.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.AdapterRegistry");
+define("dojo/AdapterRegistry", ["dojo"], function(dojo) {
 
 dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
 	//	summary:
@@ -31,11 +31,11 @@ dojo.AdapterRegistry = function(/*Boolean?*/ returnWrappers){
 
 	this.pairs = [];
 	this.returnWrappers = returnWrappers || false; // Boolean
-}
+};
 
 dojo.extend(dojo.AdapterRegistry, {
 	register: function(/*String*/ name, /*Function*/ check, /*Function*/ wrap, /*Boolean?*/ directReturn, /*Boolean?*/ override){
-		//	summary: 
+		//	summary:
 		//		register a check function to determine if the wrap function or
 		//		object gets selected
 		//	name:
@@ -93,3 +93,6 @@ dojo.extend(dojo.AdapterRegistry, {
 		return false;
 	}
 });
+
+return dojo.AdapterRegistry;
+});
diff --git a/dojo/DeferredList.js b/dojo/DeferredList.js
index 797c612..232ee43 100644
--- a/dojo/DeferredList.js
+++ b/dojo/DeferredList.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.DeferredList");
+define("dojo/DeferredList", ["dojo"], function(dojo) {
+
 dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*Boolean?*/ fireOnOneErrback, /*Boolean?*/ consumeErrors, /*Function?*/ canceller){
 	// summary:
 	//		Provides event handling for a group of Deferred objects.
@@ -56,7 +57,7 @@ dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*B
 dojo.DeferredList.prototype = new dojo.Deferred();
 
 dojo.DeferredList.prototype.gatherResults= function(deferredList){
-	// summary:	
+	// summary:
 	//	Gathers the results of the deferreds for packaging
 	//	as the parameters to the Deferred Lists' callback
 
@@ -70,3 +71,6 @@ dojo.DeferredList.prototype.gatherResults= function(deferredList){
 	});
 	return d;
 };
+
+return dojo.DeferredList;
+});
diff --git a/dojo/LICENSE b/dojo/LICENSE
index 4c93ded..aa6b39f 100644
--- a/dojo/LICENSE
+++ b/dojo/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2010, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/dojo/NodeList-data.js b/dojo/NodeList-data.js
new file mode 100644
index 0000000..ee5fe69
--- /dev/null
+++ b/dojo/NodeList-data.js
@@ -0,0 +1,170 @@
+define("dojo/NodeList-data", ["dojo"], function(dojo) {
+(function(d){
+
+/*=====
+	dojo.NodeList.prototype.data = function(key, value){
+		// summary: stash or get some arbitrary data on/from these nodes.
+		//
+		// description:
+		//		Stash or get some arbirtrary data on/from these nodes. This private _data function is
+		//		exposed publicly on `dojo.NodeList`, eg: as the result of a `dojo.query` call.
+		//		DIFFERS from jQuery.data in that when used as a getter, the entire list is ALWAYS
+		//		returned. EVEN WHEN THE LIST IS length == 1.
+		//
+		//		A single-node version of this function is provided as `dojo._nodeData`, which follows
+		//		the same signature, though expects a String ID or DomNode reference in the first
+		//		position, before key/value arguments.
+		//
+		// node: String|DomNode
+		//		The node to associate data with
+		//
+		// key: Object?|String?
+		//		If an object, act as a setter and iterate over said object setting data items as defined.
+		//		If a string, and `value` present, set the data for defined `key` to `value`
+		//		If a string, and `value` absent, act as a getter, returning the data associated with said `key`
+		//
+		// value: Anything?
+		//		The value to set for said `key`, provided `key` is a string (and not an object)
+		//
+		// example:
+		//		Set a key `bar` to some data, then retrieve it.
+		//	|	dojo.query(".foo").data("bar", "touched");
+		//	|	var touched = dojo.query(".foo").data("bar");
+		//	|	if(touched[0] == "touched"){ alert('win'); }
+		//
+		// example:
+		//		Get all the data items for a given node.
+		//	|	var list = dojo.query(".foo").data();
+		//	|	var first = list[0];
+		//
+		// example:
+		//		Set the data to a complex hash. Overwrites existing keys with new value
+		//	|	dojo.query(".foo").data({ bar:"baz", foo:"bar" });
+		//		Then get some random key:
+		//	|	dojo.query(".foo").data("foo"); // returns [`bar`]
+		//
+		//	returns: Object|Anything|Nothing
+		//		When used as a setter via `dojo.NodeList`, a NodeList instance is returned
+		//		for further chaning. When used as a getter via `dojo.NodeList` an ARRAY
+		//		of items is returned. The items in the array correspond to the elements
+		//		in the original list. This is true even when the list length is 1, eg:
+		//		when looking up a node by ID (#foo)
+	};
+
+	dojo.NodeList.prototype.removeData = function(key){
+		// summary: Remove the data associated with these nodes.
+		// key: String?
+		//		If ommitted, clean all data for this node.
+		//		If passed, remove the data item found at `key`
+	};
+
+	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,
+		dopid = function(node){
+			// summary: Return a uniqueish ID for the passed node reference
+			var pid = d.attr(node, dataattr);
+			if(!pid){
+				pid = "pid" + (x++);
+				d.attr(node, dataattr, pid);
+			}
+			return pid;
+		}
+	;
+
+	//>>excludeStart("debugging", true);
+	// exposed for unit tests:
+	d._nodeDataCache = dataCache;
+	//>>excludeEnd("debugging");
+
+	var dodata = d._nodeData = function(node, key, value){
+
+		var pid = dopid(node), r;
+		if(!dataCache[pid]){ dataCache[pid] = {}; }
+
+		// API discrepency: calling with only a node returns the whole object. $.data throws
+		if(arguments.length == 1){ r = dataCache[pid]; }
+		if(typeof key == "string"){
+			// either getter or setter, based on `value` presence
+			if(arguments.length > 2){
+				dataCache[pid][key] = value;
+			}else{
+				r = dataCache[pid][key];
+			}
+		}else{
+			// must be a setter, mix `value` into data hash
+			// API discrepency: using object as setter works here
+			r = d._mixin(dataCache[pid], key);
+		}
+
+		return r; // Object|Anything|Nothing
+	};
+
+	var removeData = d._removeNodeData = function(node, key){
+		// summary: Remove some data from this node
+		// node: String|DomNode
+		//		The node reference to remove data from
+		// key: String?
+		//		If omitted, remove all data in this dataset.
+		//		If passed, remove only the passed `key` in the associated dataset
+		var pid = dopid(node);
+		if(dataCache[pid]){
+			if(key){
+				delete dataCache[pid][key];
+			}else{
+				delete dataCache[pid];
+			}
+		}
+	};
+
+	d._gcNodeData = function(){
+		// summary: super expensive: GC all data in the data for nodes that no longer exist in the dom.
+		// description:
+		//		super expensive: GC all data in the data for nodes that no longer exist in the dom.
+		//		MUCH safer to do this yourself, manually, on a per-node basis (via `NodeList.removeData()`)
+		//		provided as a stop-gap for exceptionally large/complex applications with constantly changing
+		//		content regions (eg: a dijit.layout.ContentPane with replacing data)
+		//		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);
+		for(var i in dataCache){
+			if(dojo.indexOf(livePids, i) < 0){ delete dataCache[i]; }
+		}
+	};
+
+	// make nodeData and removeNodeData public on dojo.NodeList:
+	d.extend(nl, {
+		data: nl._adaptWithCondition(dodata, function(a){
+			return a.length === 0 || a.length == 1 && (typeof a[0] == "string");
+		}),
+		removeData: nl._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){
+//		var a = arguments, r;
+//		if(a.length === 0 || a.length == 1 && (typeof a[0] == "string")){
+//			r = this.map(function(node){
+//				return d._data(node, key);
+//			});
+//			if(r.length == 1){ r = r[0]; } // the offending line, and the diff on adaptWithCondition
+//		}else{
+//			r = this.forEach(function(node){
+//				d._data(node, key, value);
+//			});
+//		}
+//		return r; // dojo.NodeList|Array|SingleItem
+//	};
+
+})(dojo);
+
+return dojo.NodeList;
+});
diff --git a/dojo/NodeList-fx.js b/dojo/NodeList-fx.js
index 40d3b39..c784100 100644
--- a/dojo/NodeList-fx.js
+++ b/dojo/NodeList-fx.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo.NodeList-fx");
-dojo.require("dojo.fx");
+define("dojo/NodeList-fx", ["dojo", "dojo/fx"], function(dojo) {
 
 /*=====
 dojo["NodeList-fx"] = {
@@ -16,7 +15,7 @@ dojo.extend(dojo.NodeList, {
 				dojo.mixin(tmpArgs, args);
 				return obj[method](tmpArgs);
 			})
-		); 
+		);
 		return args.auto ? a.play() && this : a; // dojo.Animation|dojo.NodeList
 	},
 
@@ -25,7 +24,7 @@ dojo.extend(dojo.NodeList, {
 		//		wipe in all elements of this NodeList via `dojo.fx.wipeIn`
 		//
 		//	args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of 
+		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
 		//	returns: dojo.Animation|dojo.NodeList
@@ -49,7 +48,7 @@ dojo.extend(dojo.NodeList, {
 		//		wipe out all elements of this NodeList via `dojo.fx.wipeOut`
 		//
 		//	args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of 
+		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
 		//	returns: dojo.Animation|dojo.NodeList
@@ -68,7 +67,7 @@ dojo.extend(dojo.NodeList, {
 		//		slide all elements of the node list to the specified place via `dojo.fx.slideTo`
 		//
 		//	args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of 
+		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
 		//	returns: dojo.Animation|dojo.NodeList
@@ -91,7 +90,7 @@ dojo.extend(dojo.NodeList, {
 		//		fade in all elements of this NodeList via `dojo.fadeIn`
 		//
 		//	args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of 
+		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
 		//	returns: dojo.Animation|dojo.NodeList
@@ -110,7 +109,7 @@ dojo.extend(dojo.NodeList, {
 		//		fade out all elements of this NodeList via `dojo.fadeOut`
 		//
 		//	args: Object?
-		//		Additional dojo.Animation arguments to mix into this set with the addition of 
+		//		Additional dojo.Animation arguments to mix into this set with the addition of
 		//		an `auto` parameter.
 		//
 		//	returns: dojo.Animation|dojo.NodeList
@@ -146,14 +145,14 @@ dojo.extend(dojo.NodeList, {
 		//	example:
 		//	|	dojo.query(".zork").animateProperty({
 		//	|		duration: 500,
-		//	|		properties: { 
+		//	|		properties: {
 		//	|			color:		{ start: "black", end: "white" },
-		//	|			left:		{ end: 300 } 
-		//	|		} 
+		//	|			left:		{ end: 300 }
+		//	|		}
 		//	|	}).play();
 		//
 		//	example:
-		//	|	dojo.query(".grue").animateProperty({ 
+		//	|	dojo.query(".grue").animateProperty({
 		//	|		auto:true,
 		//	|		properties: {
 		//	|			height:240
@@ -162,9 +161,9 @@ dojo.extend(dojo.NodeList, {
 		return this._anim(dojo, "animateProperty", args); // dojo.Animation|dojo.NodeList
 	},
 
-	anim: function( /*Object*/			properties, 
-					/*Integer?*/		duration, 
-					/*Function?*/		easing, 
+	anim: function( /*Object*/			properties,
+					/*Integer?*/		duration,
+					/*Function?*/		easing,
 					/*Function?*/		onEnd,
 					/*Integer?*/		delay){
 		//	summary:
@@ -172,8 +171,8 @@ dojo.extend(dojo.NodeList, {
 		//		The returned animation object will already be playing when it
 		//		is returned. See the docs for `dojo.anim` for full details.
 		//	properties: Object
-		//		the properties to animate. does NOT support the `auto` parameter like other 
-		//		NodeList-fx methods. 
+		//		the properties to animate. does NOT support the `auto` parameter like other
+		//		NodeList-fx methods.
 		//	duration: Integer?
 		//		Optional. The time to run the animations for
 		//	easing: Function?
@@ -198,10 +197,13 @@ dojo.extend(dojo.NodeList, {
 					easing: easing
 				});
 			})
-		); 
+		);
 		if(onEnd){
 			dojo.connect(canim, "onEnd", onEnd);
 		}
 		return canim.play(delay||0); // dojo.Animation
 	}
 });
+
+return dojo.NodeList;
+});
diff --git a/dojo/NodeList-html.js b/dojo/NodeList-html.js
index e485a1d..22826c1 100644
--- a/dojo/NodeList-html.js
+++ b/dojo/NodeList-html.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo.NodeList-html");
-dojo.require("dojo.html");
+define("dojo/NodeList-html", ["dojo", "dojo/html"], function(dojo) {
 
 /*=====
 dojo["NodeList-html"] = {
@@ -12,15 +11,15 @@ dojo.extend(dojo.NodeList, {
 		//	summary:
 		//		see `dojo.html.set()`. Set the content of all elements of this NodeList
 		//
-		// description: 
-		//		Based around `dojo.html.set()`, set the content of the Elements in a 
+		// description:
+		//		Based around `dojo.html.set()`, set the content of the Elements in a
 		//		NodeList to the given content (string/node/nodelist), with optional arguments
 		//		to further tune the set content behavior.
 		//
 		//	example:
 		//	| dojo.query(".thingList").html("<li dojoType='dojo.dnd.Moveable'>1</li><li dojoType='dojo.dnd.Moveable'>2</li><li dojoType='dojo.dnd.Moveable'>3</li>",
-		//	| { 
-		//	| 	parseContent: true, 
+		//	| {
+		//	| 	parseContent: true,
 		//	| 	onBegin: function(){
 		//	| 		this.content = this.content.replace(/([0-9])/g, this.id + ": $1");
 		//	| 		this.inherited("onBegin", arguments);
@@ -29,10 +28,13 @@ dojo.extend(dojo.NodeList, {
 
 		var dhs = new dojo.html._ContentSetter(params || {});
 		this.forEach(function(elm){
-			dhs.node = elm; 
+			dhs.node = elm;
 			dhs.set(content);
 			dhs.tearDown();
 		});
 		return this; // dojo.NodeList
 	}
 });
+
+return dojo.NodeList;
+});
diff --git a/dojo/NodeList-manipulate.js b/dojo/NodeList-manipulate.js
index f0e4db1..a8923e9 100644
--- a/dojo/NodeList-manipulate.js
+++ b/dojo/NodeList-manipulate.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.NodeList-manipulate");
+define("dojo/NodeList-manipulate", ["dojo"], function(dojo) {
 
 /*=====
 dojo["NodeList-manipulate"] = {
@@ -42,7 +42,7 @@ dojo["NodeList-manipulate"] = {
 	}
 
 	function makeWrapNode(/*DOMNode||String*/html, /*DOMNode*/refNode){
-		// summary: 
+		// summary:
 		// 		convert HTML into nodes if it is not already a node.
 		if(typeof html == "string"){
 			html = dojo._toDom(html, (refNode && refNode.ownerDocument));
@@ -646,25 +646,25 @@ dojo["NodeList-manipulate"] = {
 			//	example:
 			//		assume a DOM created by this markup:
 			//	|	<div class="container">
-			// 	|		<div class="spacer">___</div>			
+			// 	|		<div class="spacer">___</div>
 			// 	|		<div class="red">Red One</div>
-			// 	|		<div class="spacer">___</div>			
+			// 	|		<div class="spacer">___</div>
 			// 	|		<div class="blue">Blue One</div>
-			// 	|		<div class="spacer">___</div>			
+			// 	|		<div class="spacer">___</div>
 			// 	|		<div class="red">Red Two</div>
-			// 	|		<div class="spacer">___</div>			
+			// 	|		<div class="spacer">___</div>
 			// 	|		<div class="blue">Blue Two</div>
 			//	|	</div>
 			//		Running this code:
 			//	|	dojo.query(".red").replaceAll(".blue");
 			//		Results in this DOM structure:
 			//	|	<div class="container">
-			// 	|		<div class="spacer">___</div>			
-			// 	|		<div class="spacer">___</div>			
+			// 	|		<div class="spacer">___</div>
+			// 	|		<div class="spacer">___</div>
 			// 	|		<div class="red">Red One</div>
 			// 	|		<div class="red">Red Two</div>
-			// 	|		<div class="spacer">___</div>			
-			// 	|		<div class="spacer">___</div>			
+			// 	|		<div class="spacer">___</div>
+			// 	|		<div class="spacer">___</div>
 			// 	|		<div class="red">Red One</div>
 			// 	|		<div class="red">Red Two</div>
 			//	|	</div>
@@ -718,3 +718,6 @@ dojo["NodeList-manipulate"] = {
 		dojo.NodeList.prototype.html = dojo.NodeList.prototype.innerHTML;
 	}
 })();
+
+return dojo.NodeList;
+});
diff --git a/dojo/NodeList-traverse.js b/dojo/NodeList-traverse.js
index b14095f..c4e570f 100644
--- a/dojo/NodeList-traverse.js
+++ b/dojo/NodeList-traverse.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.NodeList-traverse");
+define("dojo/NodeList-traverse", ["dojo"], function(dojo) {
 
 /*=====
 dojo["NodeList-traverse"] = {
@@ -19,18 +19,7 @@ dojo.extend(dojo.NodeList, {
 				ary = ary.concat(items);
 			}
 		}
-		return ary;	
-	},
-
-	_filterQueryResult: function(nodeList, query){
-		// summmary: 
-		// 		Replacement for dojo._filterQueryResult that does a full
-		// 		query. Slower, but allows for more types of queries.
-		var filter = dojo.filter(nodeList, function(node){
-			return dojo.query(query, node.parentNode).indexOf(node) != -1;
-		});
-		var result = this._wrap(filter);
-		return result;
+		return ary;
 	},
 
 	_getUniqueAsNodeList: function(nodes){
@@ -56,7 +45,7 @@ dojo.extend(dojo.NodeList, {
 		// 		gets unique element nodes, filters them further
 		// 		with an optional query and then calls _stash to track parent NodeList.
 		var ary = this._getUniqueAsNodeList(nodes);
-		ary = (query ? this._filterQueryResult(ary, query) : ary);
+		ary = (query ? dojo._filterQueryResult(ary, query) : ary);
 		return ary._stash(this);  //dojo.NodeList
 	},
 
@@ -64,7 +53,7 @@ dojo.extend(dojo.NodeList, {
 		// summary:
 		// 		cycles over all the nodes and calls a callback
 		// 		to collect nodes for a possible inclusion in a result.
-		// 		The callback will get two args: callback(node, ary), 
+		// 		The callback will get two args: callback(node, ary),
 		// 		where ary is the array being used to collect the nodes.
 		return this._getUniqueNodeListWithParent(this._buildArrayFromCallback(callback), query);  //dojo.NodeList
 	},
@@ -100,7 +89,7 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	},
 
-	closest: function(/*String*/query){
+	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.
@@ -109,6 +98,8 @@ dojo.extend(dojo.NodeList, {
 		// 		original dojo.NodeList.
 		//	query:
 		//		a CSS selector.
+		// root:
+		//		If specified, query is relative to "root" rather than document body.
 		// returns:
 		//		dojo.NodeList, the closest parent that matches the query, including the current
 		//		node in this dojo.NodeList if it matches the query.
@@ -124,13 +115,12 @@ dojo.extend(dojo.NodeList, {
 		//		Running this code:
 		//	|	dojo.query(".red").closest(".container");
 		//		returns the div with class "container".
-		var self = this;
-		return this._getRelatedUniqueNodes(query, function(node, ary){
+		return this._getRelatedUniqueNodes(null, function(node, ary){
 			do{
-				if(self._filterQueryResult([node], query).length){
+				if(dojo._filterQueryResult([node], query, root).length){
 					return node;
 				}
-			}while((node = node.parentNode) && node.nodeType == 1);
+			}while(node != root && (node = node.parentNode) && node.nodeType == 1);
 			return null; //To make rhino strict checking happy.
 		}); //dojo.NodeList
 	},
@@ -452,7 +442,7 @@ dojo.extend(dojo.NodeList, {
 		//	|	</div>
 		//		Running this code:
 		//	|	dojo.query(".blue").last();
-		//		returns the last div with class "blue", 
+		//		returns the last div with class "blue",
 		return this._wrap((this.length ? [this[this.length - 1]] : []), this); //dojo.NodeList
 	},
 
@@ -504,3 +494,6 @@ dojo.extend(dojo.NodeList, {
 		}); //dojo.NodeList
 	}
 });
+
+return dojo.NodeList;
+});
diff --git a/dojo/OpenAjax.js b/dojo/OpenAjax.js
index 32cf358..03c810f 100644
--- a/dojo/OpenAjax.js
+++ b/dojo/OpenAjax.js
@@ -2,18 +2,18 @@
  * OpenAjax.js
  *
  * Reference implementation of the OpenAjax Hub, as specified by OpenAjax Alliance.
- * Specification is under development at: 
+ * Specification is under development at:
  *
  *   http://www.openajax.org/member/wiki/OpenAjax_Hub_Specification
  *
  * Copyright 2006-2007 OpenAjax Alliance
  *
- * 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 
+ * 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.
  *
  ******************************************************************************/
@@ -44,7 +44,7 @@ if(!window["OpenAjax"]){
 				prefix: prefix,
 				namespaceURI: nsURL,
 				version: version,
-				extraData: extra 
+				extraData: extra
 			};
 			this.publish(ooh+"registerLibrary", libs[prefix]);
 		}
@@ -75,7 +75,7 @@ if(!window["OpenAjax"]){
 			this._publish(this._subscriptions, path, 0, name, message);
 			this._pubDepth--;
 			if((this._cleanup.length > 0) && (this._pubDepth == 0)){
-				for(var i = 0; i < this._cleanup.length; i++){ 
+				for(var i = 0; i < this._cleanup.length; i++){
 					this.unsubscribe(this._cleanup[i].hdl);
 				}
 				delete(this._cleanup);
@@ -93,12 +93,12 @@ if(!window["OpenAjax"]){
 			var token = path[index];
 			if(index == path.length){
 				tree.s.push(sub);
-			}else{ 
+			}else{
 				if(typeof tree.c == "undefined"){
 					 tree.c = {};
 				}
 				if(typeof tree.c[token] == "undefined"){
-					tree.c[token] = { c: {}, s: [] }; 
+					tree.c[token] = { c: {}, s: [] };
 					this._subscribe(tree.c[token], path, index + 1, sub);
 				}else{
 					this._subscribe( tree.c[token], path, index + 1, sub);
@@ -113,7 +113,7 @@ if(!window["OpenAjax"]){
 					node = tree;
 				}else{
 					this._publish(tree.c[path[index]], path, index + 1, name, msg);
-					this._publish(tree.c["*"], path, index + 1, name, msg);			
+					this._publish(tree.c["*"], path, index + 1, name, msg);
 					node = tree.c["**"];
 				}
 				if(typeof node != "undefined"){
@@ -133,7 +133,7 @@ if(!window["OpenAjax"]){
 								// get a function object
 								fcb = sc[fcb];
 							}
-							if((!fcb) || 
+							if((!fcb) ||
 							   (fcb.call(sc, name, msg, d))) {
 								cb.call(sc, name, msg, d);
 							}
@@ -149,24 +149,24 @@ if(!window["OpenAjax"]){
 					var childNode = tree.c[path[index]];
 					this._unsubscribe(childNode, path, index + 1, sid);
 					if(childNode.s.length == 0) {
-						for(var x in childNode.c) 
-					 		return;		
-						delete tree.c[path[index]];	
+						for(var x in childNode.c)
+					 		return;
+						delete tree.c[path[index]];
 					}
 					return;
 				}
 				else {
 					var callbacks = tree.s;
 					var max = callbacks.length;
-					for(var i = 0; i < max; i++) 
+					for(var i = 0; i < max; i++)
 						if(sid == callbacks[i].sid) {
 							if(this._pubDepth > 0) {
-								callbacks[i].cb = null;	
-								this._cleanup.push(callbacks[i]);						
+								callbacks[i].cb = null;
+								this._cleanup.push(callbacks[i]);
 							}
 							else
 								callbacks.splice(i, 1);
-							return; 	
+							return;
 						}
 				}
 			}
diff --git a/dojo/Stateful.js b/dojo/Stateful.js
index e213490..603e4cb 100644
--- a/dojo/Stateful.js
+++ b/dojo/Stateful.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.Stateful");
+define("dojo/Stateful", ["dojo"], function(dojo) {
 
 dojo.declare("dojo.Stateful", null, {
 	// summary:
@@ -24,7 +24,7 @@ dojo.declare("dojo.Stateful", null, {
 		// description:
 		//		Get a named property on a Stateful object. The property may
 		//		potentially be retrieved via a getter method in subclasses. In the base class
-		// 		this just retrieves the object's property. 
+		// 		this just retrieves the object's property.
 		// 		For example:
 		//	|	stateful = new dojo.Stateful({foo: 3});
 		//	|	stateful.get("foo") // returns 3
@@ -36,11 +36,11 @@ dojo.declare("dojo.Stateful", null, {
 		// summary:
 		//		Set a property on a Stateful instance
 		//	name:
-		//		The property to set. 
+		//		The property to set.
 		//	value:
 		//		The value to set in the property.
 		// description:
-		//		Sets named properties on a stateful object and notifies any watchers of 
+		//		Sets named properties on a stateful object and notifies any watchers of
 		// 		the property. A programmatic setter may be defined in subclasses.
 		// 		For example:
 		//	|	stateful = new dojo.Stateful();
@@ -57,7 +57,7 @@ dojo.declare("dojo.Stateful", null, {
 		//	This is equivalent to calling set(foo, "Howdy") and set(bar, 3)
 		if(typeof name === "object"){
 			for(var x in name){
-				this.set(x, name[x]); 
+				this.set(x, name[x]);
 			}
 			return this;
 		}
@@ -72,17 +72,17 @@ dojo.declare("dojo.Stateful", null, {
 		// summary:
 		//		Watches a property for changes
 		//	name:
-		//		Indicates the property to watch. This is optional (the callback may be the 
+		//		Indicates the property to watch. This is optional (the callback may be the
 		// 		only parameter), and if omitted, all the properties will be watched
 		// returns:
-		//		An object handle for the watch. The unwatch method of this object 
+		//		An object handle for the watch. The unwatch method of this object
 		// 		can be used to discontinue watching this property:
 		//		|	var watchHandle = obj.watch("foo", callback);
 		//		|	watchHandle.unwatch(); // callback won't be called now
 		//	callback:
 		//		The function to execute when the property changes. This will be called after
 		//		the property has been changed. The callback will be called with the |this|
-		//		set to the instance, the first argument as the name of the property, the 
+		//		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;
@@ -90,15 +90,18 @@ dojo.declare("dojo.Stateful", null, {
 			var self = this;
 			callbacks = this._watchCallbacks = function(name, oldValue, value, ignoreCatchall){
 				var notify = function(propertyCallbacks){
-					for(var i = 0, l = propertyCallbacks && propertyCallbacks.length; i < l; i++){
-						try{
-							propertyCallbacks[i].call(self, name, oldValue, value);
-						}catch(e){
-							console.error(e);
+					if(propertyCallbacks){
+                        propertyCallbacks = propertyCallbacks.slice();
+						for(var i = 0, l = propertyCallbacks.length; i < l; i++){
+							try{
+								propertyCallbacks[i].call(self, name, oldValue, value);
+							}catch(e){
+								console.error(e);
+							}
 						}
 					}
 				};
-				notify(callbacks[name]);
+				notify(callbacks['_' + name]);
 				if(!ignoreCatchall){
 					notify(callbacks["*"]); // the catch-all
 				}
@@ -107,6 +110,9 @@ dojo.declare("dojo.Stateful", null, {
 		if(!callback && typeof name === "function"){
 			callback = name;
 			name = "*";
+		}else{
+			// prepend with dash to prevent name conflicts with function (like "name" property)
+			name = '_' + name;
 		}
 		var propertyCallbacks = callbacks[name];
 		if(typeof propertyCallbacks !== "object"){
@@ -120,4 +126,7 @@ dojo.declare("dojo.Stateful", null, {
 		};
 	}
 	
-});
\ No newline at end of file
+});
+
+return dojo.Stateful;
+});
diff --git a/dojo/_base.js b/dojo/_base.js
index 8219259..04a496c 100644
--- a/dojo/_base.js
+++ b/dojo/_base.js
@@ -1,9 +1,11 @@
-dojo.provide("dojo._base");
-dojo.require("dojo._base.lang");
-dojo.require("dojo._base.array");
-dojo.require("dojo._base.declare");
-dojo.require("dojo._base.connect");
-dojo.require("dojo._base.Deferred");
-dojo.require("dojo._base.json");
-dojo.require("dojo._base.Color");
-dojo.requireIf(dojo.isBrowser, "dojo._base.browser");
+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 7509f16..2319025 100644
--- a/dojo/_base/Color.js
+++ b/dojo/_base/Color.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo._base.Color");
-dojo.require("dojo._base.array");
-dojo.require("dojo._base.lang");
+define("dojo/_base/Color", ["dojo/lib/kernel", "dojo/_base/array", "dojo/_base/lang"], function(dojo){
 
 (function(){
 
@@ -190,7 +188,7 @@ dojo.require("dojo._base.lang");
 		//		Builds a `dojo.Color` from a 3 or 4 element array, mapping each
 		//		element in sequence to the rgb(a) values of the color.
 		// example:
-		//		| var myColor = dojo.colorFromArray([237,237,237,0.5]); // grey, 50% alpha 
+		//		| 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();
@@ -214,3 +212,6 @@ dojo.require("dojo._base.lang");
 		return a && d.colorFromArray(a, obj) || d.colorFromRgb(str, obj) || d.colorFromHex(str, obj);
 	};
 })();
+
+return dojo.Color;
+});
diff --git a/dojo/_base/Deferred.js b/dojo/_base/Deferred.js
index bb22bf7..00a09b4 100644
--- a/dojo/_base/Deferred.js
+++ b/dojo/_base/Deferred.js
@@ -1,42 +1,41 @@
-dojo.provide("dojo._base.Deferred");
-dojo.require("dojo._base.lang");
+define("dojo/_base/Deferred", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
 
 (function(){
-	var mutator = 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. 
+	// 		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 
+	//		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 
+	//
+	//  	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 
+	//
+	//		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:
@@ -46,7 +45,7 @@ dojo.require("dojo._base.lang");
 	//			* callback(result)
 	//			* errback(result)
 	//
-	//		Callbacks are allowed to return promisesthemselves, so
+	//		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
@@ -106,7 +105,7 @@ dojo.require("dojo._base.lang");
 	//		|				renderDataitem(data[x]);
 	//		|			}
 	//		|			d.callback(true);
-	//		|		}catch(e){ 
+	//		|		}catch(e){
 	//		|			d.errback(new Error("rendering failed"));
 	//		|		}
 	//		|		return d;
@@ -120,7 +119,7 @@ dojo.require("dojo._base.lang");
 	//		|	// 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 syncrhonous and so both
+	//		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:
 	//
@@ -133,7 +132,7 @@ dojo.require("dojo._base.lang");
 	//		|					renderDataitem(data[x]);
 	//		|				}
 	//		|				d.callback(true);
-	//		|			}catch(e){ 
+	//		|			}catch(e){
 	//		|				d.errback(new Error("rendering failed"));
 	//		|			}
 	//		|		}, 100);
@@ -148,11 +147,11 @@ dojo.require("dojo._base.lang");
 	//		Note that the caller doesn't have to change his code at all to
 	//		handle the asynchronous case.
 		var result, finished, isError, head, nextListener;
-		var promise = this.promise = {};
+		var promise = (this.promise = {});
 		
 		function complete(value){
 			if(finished){
-				throw new Error("This deferred has already been resolved");				
+				throw new Error("This deferred has already been resolved");
 			}
 			result = value;
 			finished = true;
@@ -163,7 +162,7 @@ dojo.require("dojo._base.lang");
 			while(!mutated && nextListener){
 				var listener = nextListener;
 				nextListener = nextListener.next;
-				if(mutated = (listener.progress == mutator)){ // assignment and check
+				if((mutated = (listener.progress == mutator))){ // assignment and check
 					finished = false;
 				}
 				var func = (isError ? listener.error : listener.resolved);
@@ -175,6 +174,9 @@ dojo.require("dojo._base.lang");
 							continue;
 						}
 						var unchanged = mutated && newResult === undefined;
+						if(mutated && !unchanged){
+							isError = newResult instanceof Error;
+						}
 						listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult);
 					}
 					catch (e) {
@@ -187,7 +189,7 @@ dojo.require("dojo._base.lang");
 						listener.deferred.resolve(result);
 					}
 				}
-			}	
+			}
 		}
 		// calling resolve will resolve the promise
 		this.resolve = this.callback = function(value){
@@ -202,7 +204,7 @@ dojo.require("dojo._base.lang");
 		// calling error will indicate that the promise failed
 		this.reject = this.errback = function(error){
 			// summary:
-			//		Fulfills the Deferred instance as an error with the provided error 
+			//		Fulfills the Deferred instance as an error with the provided error
 			isError = true;
 			this.fired = 1;
 			complete(error);
@@ -219,7 +221,7 @@ dojo.require("dojo._base.lang");
 			while(listener){
 				var progress = listener.progress;
 				progress && progress(update);
-				listener = listener.next;	
+				listener = listener.next;
 			}
 		};
 		this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){
@@ -228,35 +230,35 @@ dojo.require("dojo._base.lang");
 		};
 		// provide the implementation of the promise
 		this.then = promise.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 
+			// 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.
-			// 
-			// 		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 
+			//
+			// 		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.
-			//	
+			//
 			// example:
 			// 		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 = {
-				resolved: resolvedCallback, 
-				error: errorCallback, 
-				progress: progressCallback, 
+				resolved: resolvedCallback,
+				error: errorCallback,
+				progress: progressCallback,
 				deferred: returnDeferred
-			}; 
+			};
 			if(nextListener){
 				head = head.next = listener;
 			}
@@ -282,7 +284,7 @@ dojo.require("dojo._base.lang");
 					deferred.reject(error);
 				}
 			}
-		}
+		};
 		freeze(promise);
 	};
 	dojo.extend(dojo.Deferred, {
@@ -303,7 +305,7 @@ dojo.require("dojo._base.lang");
 })();
 dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){
 	// summary:
-	//		This provides normalization between normal synchronous values and 
+	//		This provides normalization between normal synchronous values and
 	//		asynchronous promises, so you can interact with them in a common way
 	//	example:
 	//		|	function printFirstAndList(items){
@@ -329,3 +331,6 @@ dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback
 	}
 	return callback(promiseOrValue);
 };
+
+return dojo.Deferred;
+});
diff --git a/dojo/_base/NodeList.js b/dojo/_base/NodeList.js
index 279ace4..2f4a63d 100644
--- a/dojo/_base/NodeList.js
+++ b/dojo/_base/NodeList.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo._base.NodeList");
-dojo.require("dojo._base.lang");
-dojo.require("dojo._base.array");
+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(){
@@ -241,7 +239,7 @@ dojo.require("dojo._base.array");
 	});
 
 	// add forEach actions
-	d.forEach(["connect", "addClass", "removeClass", "toggleClass", "empty", "removeAttr"], function(name){
+	d.forEach(["connect", "addClass", "removeClass", "replaceClass", "toggleClass", "empty", "removeAttr"], function(name){
 		nlp[name] = adaptAsForEach(d[name]);
 	});
 
@@ -299,7 +297,7 @@ dojo.require("dojo._base.array");
 
 		_cloneNode: function(/*DOMNode*/ node){
 			// summary:
-			// 		private utiltity to clone a node. Not very interesting in the vanilla
+			// 		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);
@@ -393,7 +391,7 @@ dojo.require("dojo._base.array");
 			if(this._parent){
 				return this._parent;
 			}else{
-				//Just return empy list.
+				//Just return empty list.
 				return new this._NodeListCtor();
 			}
 		},
@@ -461,12 +459,12 @@ dojo.require("dojo._base.array");
 
 		indexOf: function(value, fromIndex){
 			//	summary:
-			//		see dojo.indexOf(). The primary difference is that the acted-on 
+			//		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 loction to start searching from. Optional. Defaults to 0.
+			//		The location to start searching from. Optional. Defaults to 0.
 			//	description:
 			//		For more details on the behavior of indexOf, see Mozilla's
 			//		(indexOf
@@ -487,7 +485,7 @@ dojo.require("dojo._base.array");
 			// value: Object
 			//		The value to search for.
 			// fromIndex: Integer?
-			//		The loction to start searching from. Optional. Defaults to 0.
+			//		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
@@ -565,12 +563,12 @@ dojo.require("dojo._base.array");
 
 		forEach: function(callback, thisObj){
 			//	summary:
-			//		see `dojo.forEach()`. The primary difference is that the acted-on 
+			//		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 
+			return this; // dojo.NodeList
 		},
 
 		/*=====
@@ -587,7 +585,7 @@ dojo.require("dojo._base.array");
 			//	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. 
+			//		assumes the node passed is each node in this list.
 
 			return d.map(this, d.position); // Array
 		},
@@ -610,7 +608,7 @@ dojo.require("dojo._base.array");
 			//		Disable a group of buttons:
 			//	|	dojo.query("button.group").attr("disabled", true);
 			//	example:
-			//		innerHTML can be assigned or retreived as well:
+			//		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
@@ -675,7 +673,7 @@ dojo.require("dojo._base.array");
 			//		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 
+			//		(methodName, objOrFunc, funcName), objOrFunc must be the scope to
 			//		locate the bound function in
 			//	funcName: String?
 			//		optional. A string naming the function in objOrFunc to bind to the
@@ -721,7 +719,7 @@ dojo.require("dojo._base.array");
 			//		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 
+			//		In the selector case, only the first matching element will be used
 			//		for relative positioning.
 			//	position:
 			//		can be one of:
@@ -736,18 +734,15 @@ dojo.require("dojo._base.array");
 			return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList
 		},
 
-		orphan: function(/*String?*/ simpleFilter){
+		orphan: function(/*String?*/ filter){
 			//	summary:
-			//		removes elements in this list that match the simple filter
+			//		removes elements in this list that match the filter
 			//		from their parents and returns them as a new NodeList.
-			//	simpleFilter:
-			//		single-expression CSS rule. For example, ".thinger" or
-			//		"#someId[attrName='value']" but not "div > span". In short,
-			//		anything which does not invoke a descent to evaluate but
-			//		can instead be used to test a single node is acceptable.
+			//	filter:
+			//		CSS selector like ".foo" or "div > span"
 			//	returns:
-			//		`dojo.NodeList` containing the orpahned elements 
-			return (simpleFilter ? d._filterQueryResult(this, simpleFilter) : this).forEach(orphan); // dojo.NodeList
+			//		`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){
@@ -774,7 +769,7 @@ dojo.require("dojo._base.array");
 		// FIXME: do we need this?
 		query: function(/*String*/ queryStr){
 			//	summary:
-			//		Returns a new list whose memebers match the passed query,
+			//		Returns a new list whose members match the passed query,
 			//		assuming elements of the current NodeList as the root for
 			//		each search.
 			//	example:
@@ -785,9 +780,9 @@ dojo.require("dojo._base.array");
 			//	|		</p>
 			//	|	</div>
 			//	|	<div id="bar">
-			//	|		<p>great commedians may not be funny <span>in person</span></p>
+			//	|		<p>great comedians may not be funny <span>in person</span></p>
 			//	|	</div>
-			//		If we are presented with the following defintion for a NodeList:
+			//		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:
@@ -802,18 +797,14 @@ dojo.require("dojo._base.array");
 			return this._wrap(apc.apply([], ret), this);	// dojo.NodeList
 		},
 
-		filter: function(/*String|Function*/ simpleFilter){
+		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.
-			//	simpleFilter:
-			//		If a string, a single-expression CSS rule. For example,
-			//		".thinger" or "#someId[attrName='value']" but not "div >
-			//		span". In short, anything which does not invoke a descent
-			//		to evaluate but can instead be used to test a single node
-			//		is acceptable.
+			//	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){
@@ -825,7 +816,7 @@ dojo.require("dojo._base.array");
 			//		|	dojo.query("*").filter("p").styles("backgroundColor", "yellow");
 
 			var a = arguments, items = this, start = 0;
-			if(typeof simpleFilter == "string"){ // inline'd type check
+			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
@@ -873,10 +864,10 @@ dojo.require("dojo._base.array");
 			//		|	"before"
 			//		|	"after"
 			//		|	"replace" (replaces nodes in this NodeList with new content)
-			//		|	"only" (removes other children of the nodes so new content is hte only child)
+			//		|	"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 ommitted
+			//		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
@@ -907,7 +898,7 @@ dojo.require("dojo._base.array");
 			//  		text: "Send"
 			//  	});
 			content = this._normalize(content, this[0]);
-			for(var i = 0, node; node = this[i]; i++){
+			for(var i = 0, node; (node = this[i]); i++){
 				this._place(content, node, position, i > 0);
 			}
 			return this; //dojo.NodeList
@@ -936,11 +927,11 @@ dojo.require("dojo._base.array");
 			//	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. 
+			//		list and go backwards.
 			//
 			//	example:
 			//	Shorten the list to the first, second, and third elements
-			//	|	dojo.query("a").at(0, 1, 2).forEach(fn); 
+			//	|	dojo.query("a").at(0, 1, 2).forEach(fn);
 			//
 			//	example:
 			//	Retrieve the first and last elements of a unordered list:
@@ -950,13 +941,13 @@ dojo.require("dojo._base.array");
 			//	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. 
-			//	|	})	
+			//	|		console.log(n); // all anchors on the page.
+			//	|	})
 			//
 			//	returns:
 			//		dojo.NodeList
 			var t = new this._NodeListCtor();
-			d.forEach(arguments, function(i){ 
+			d.forEach(arguments, function(i){
 				if(i < 0){ i = this.length + i }
 				if(this[i]){ t.push(this[i]); }
 			}, this);
@@ -966,7 +957,8 @@ dojo.require("dojo._base.array");
 	});
 
 	nl.events = [
-		// summary: list of all DOM events used in NodeList
+		// 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"
@@ -979,7 +971,7 @@ dojo.require("dojo._base.array");
 			var _oe = "on" + evt;
 			nlp[_oe] = function(a, b){
 				return this.connect(_oe, a, b);
-			}
+			};
 				// FIXME: should these events trigger publishes?
 				/*
 				return (a ? this.connect(_oe, a, b) :
@@ -1007,3 +999,6 @@ dojo.require("dojo._base.array");
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 })();
 //>>excludeEnd("webkitMobile");
+
+return dojo.NodeList;
+});
diff --git a/dojo/_base/_loader/bootstrap.js b/dojo/_base/_loader/bootstrap.js
index 419d55d..5789def 100644
--- a/dojo/_base/_loader/bootstrap.js
+++ b/dojo/_base/_loader/bootstrap.js
@@ -1,3 +1,9 @@
+//>>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
@@ -69,7 +75,7 @@ djConfig = {
 	//		of calling `dojo.registerModulePath("foo", "../../bar");`. Multiple
 	//		modules may be configured via `djConfig.modulePaths`.
 	modulePaths: {},
-	// afterOnLoad: Boolean 
+	// 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
@@ -96,7 +102,7 @@ djConfig = {
 	// 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 
+	//		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.
@@ -144,7 +150,7 @@ djConfig = {
 			"groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
 			"trace", "warn", "log"
 		];
-		var i=0, tn;
+		var i = 0, tn;
 		while((tn=cn[i++])){
 			if(!console[tn]){
 				(function(){
@@ -204,9 +210,13 @@ dojo.global = {
 		debugAtAllCosts: false
 	};
 
-	if(typeof djConfig != "undefined"){
-		for(var opt in djConfig){
-			d.config[opt] = djConfig[opt];
+	// 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];
 		}
 	}
 
@@ -218,7 +228,7 @@ dojo.global = {
 =====*/
 	dojo.locale = d.config.locale;
 
-	var rev = "$Rev: 22487 $".match(/\d+/);
+	var rev = "$Rev: 24595 $".match(/\d+/);
 
 /*=====
 	dojo.version = function(){
@@ -242,7 +252,7 @@ dojo.global = {
 	}
 =====*/
 	dojo.version = {
-		major: 1, minor: 5, patch: 0, flag: "",
+		major: 1, minor: 6, patch: 1, flag: "",
 		revision: rev ? +rev[0] : NaN,
 		toString: function(){
 			with(d.version){
@@ -322,7 +332,7 @@ dojo.global = {
 		//	|		constructor: function(properties){
 		//	|			// property configuration:
 		//	|			dojo.mixin(this, properties);
-		//	|	
+		//	|
 		//	|			console.log(this.quip);
 		//	|			//  ...
 		//	|		},
@@ -343,7 +353,7 @@ dojo.global = {
 		//	|			name: "Carl Brutanananadilewski"
 		//	|		}
 		//	|	);
-		//	|	
+		//	|
 		//	|	// will print "Carl Brutanananadilewski"
 		//	|	console.log(flattened.name);
 		//	|	// will print "true"
@@ -418,10 +428,7 @@ dojo.global = {
 		//		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 only for object and method detection.
-		//		Not useful for testing generic properties on an object.
-		//		In particular, dojo.exists("foo.bar") when foo.bar = ""
-		//		will return false. Use ("bar" in foo) to test for those cases.
+		//		the chain. Useful for object and method detection.
 		//	name:
 		//		Path to an object, in the form "A.B.C".
 		//	obj:
@@ -440,7 +447,7 @@ dojo.global = {
 		//	|	// search from a particular scope
 		//	|	dojo.exists("bar", foo); // true
 		//	|	dojo.exists("bar.baz", foo); // false
-		return !!d.getObject(name, false, obj); // Boolean
+		return d.getObject(name, false, obj) !== undefined; // Boolean
 	}
 
 	dojo["eval"] = function(/*String*/ scriptFragment){
@@ -503,3 +510,59 @@ dojo.global = {
 })();
 //>>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
index 0b6808e..d092a92 100644
--- a/dojo/_base/_loader/hostenv_browser.js
+++ b/dojo/_base/_loader/hostenv_browser.js
@@ -1,3 +1,14 @@
+//>>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:
@@ -19,9 +30,9 @@ dojo.isIE = {
 dojo.isSafari = {
 	//	example:
 	//	|	if(dojo.isSafari){ ... }
-	//	example: 
+	//	example:
 	//		Detect iPhone:
-	//	|	if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){ 
+	//	|	if(dojo.isSafari && navigator.userAgent.indexOf("iPhone") != -1){
 	//	|		// we are iPhone. Note, iPod touch reports "iPod" above and fails this test.
 	//	|	}
 };
@@ -64,7 +75,6 @@ dojo = {
 	//		True if the client runs on Mac
 }
 =====*/
-
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 if(typeof window != 'undefined'){
 //>>excludeEnd("webkitMobile");
@@ -95,7 +105,7 @@ if(typeof window != 'undefined'){
 						d.config.baseUrl = src.substring(0, m.index);
 					}
 					// and find out if we need to modify our behavior
-					var cfg = scripts[i].getAttribute("djConfig");
+					var cfg = (scripts[i].getAttribute("djConfig") || scripts[i].getAttribute("data-dojo-config"));
 					if(cfg){
 						var cfgo = eval("({ "+cfg+" })");
 						for(var x in cfgo){
@@ -173,7 +183,7 @@ if(typeof window != 'undefined'){
 		//>>excludeEnd("webkitMobile");
 
 		d._xhrObj = function(){
-			// summary: 
+			// summary:
 			//		does the work of portably generating a new XMLHTTPRequest object.
 			var http, last_e;
 			//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
@@ -210,10 +220,11 @@ if(typeof window != 'undefined'){
 			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
+				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:") );
+				(!stat && (lp == "file:" || lp == "chrome:" || lp == "chrome-extension:" || lp == "app:"));
 		}
 
 		//See if base tag is in use.
@@ -308,7 +319,7 @@ if(typeof window != 'undefined'){
 		d.addOnWindowUnload = function(/*Object?|Function?*/obj, /*String|Function?*/functionName){
 			// summary:
 			//		registers a function to be triggered when window.onunload
-			//		fires. 
+			//		fires.
 			//	description:
 			//		The first time that addOnWindowUnload is called Dojo
 			//		will register a page listener to trigger your unload
@@ -339,7 +350,7 @@ if(typeof window != 'undefined'){
 			//	description:
 			//		The first time that addOnUnload is called Dojo will
 			//		register a page listener to trigger your unload handler
-			//		with. 
+			//		with.
 			//
 			//		In a browser enviroment, the functions will be triggered
 			//		during the window.onbeforeunload event. Be careful of doing
@@ -352,7 +363,7 @@ if(typeof window != 'undefined'){
 			//
 			//		Further note that calling dojo.addOnUnload will prevent
 			//		browsers from using a "fast back" cache to make page
-			//		loading via back button instantaneous. 
+			//		loading via back button instantaneous.
 			// example:
 			//	|	dojo.addOnUnload(functionPointer)
 			//	|	dojo.addOnUnload(object, "functionName")
@@ -391,7 +402,7 @@ if(typeof window != 'undefined'){
 		}
 	}
 
-	if(!dojo.config.afterOnLoad){		
+	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
@@ -408,10 +419,10 @@ if(typeof window != 'undefined'){
 			if(!dojo.config.skipIeDomLoaded && self === self.top){
 				dojo._scrollIntervalId = setInterval(function (){
 					try{
-						//When dojo is loaded into an iframe in an IE HTML Application 
+						//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 
+						//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){
@@ -480,8 +491,15 @@ if(dojo.config.isDebug){
 }
 
 if(dojo.config.debugAtAllCosts){
-	dojo.config.useXDomain = true;
-	dojo.require("dojo._base._loader.loader_xd");
+	// 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
index d99cf1a..a360a4c 100644
--- a/dojo/_base/_loader/hostenv_ff_ext.js
+++ b/dojo/_base/_loader/hostenv_ff_ext.js
@@ -234,7 +234,7 @@ if(typeof window != 'undefined'){
 			return oc;
 		};
 
-		// FIXME: 
+		// 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){
@@ -295,7 +295,7 @@ if(typeof window != 'undefined'){
 	// 		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){ 
+		window.addEventListener("DOMContentLoaded",function(e){
 			dojo._loadInit(e);
 			// console.log("DOM content loaded", e);
 		}, false);
diff --git a/dojo/_base/_loader/hostenv_rhino.js b/dojo/_base/_loader/hostenv_rhino.js
index df66ad3..205a9d9 100644
--- a/dojo/_base/_loader/hostenv_rhino.js
+++ b/dojo/_base/_loader/hostenv_rhino.js
@@ -51,6 +51,9 @@ dojo._isLocalUrl = function(/*String*/ uri) {
 
 // see comments in spidermonkey loadUri
 dojo._loadUri = function(uri, cb){
+	if(dojo._loadedUrls[uri]){
+		return true; // Boolean
+	}
 	try{
 		var local;
 		try{
@@ -60,29 +63,32 @@ dojo._loadUri = function(uri, cb){
 			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 = String(contents).replace(/[\u200E\u200F\u202A-\u202E]/g, function(match){
+					return "\\u" + match.charCodeAt(0).toString(16);
 				})
 			}
-
-			cb(eval('('+contents+')'));
+			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){ 
+dojo.exit = function(exitcode){
 	quit(exitcode);
 }
 
@@ -150,7 +156,7 @@ dojo._getText = function(/*URI*/ uri, /*Boolean*/ fail_ok){
 dojo.doc = typeof document != "undefined" ? document : null;
 
 dojo.body = function(){
-	return document.body;	
+	return document.body;
 }
 
 // Supply setTimeout/clearTimeout implementations if they aren't already there
diff --git a/dojo/_base/_loader/hostenv_spidermonkey.js b/dojo/_base/_loader/hostenv_spidermonkey.js
index 9203bbf..649f40e 100644
--- a/dojo/_base/_loader/hostenv_spidermonkey.js
+++ b/dojo/_base/_loader/hostenv_spidermonkey.js
@@ -12,13 +12,13 @@ dojo._name = 'spidermonkey';
 
 /*=====
 dojo.isSpidermonkey = {
-	// summary: Detect spidermonkey 
+	// summary: Detect spidermonkey
 };
 =====*/
 
 dojo.isSpidermonkey = true;
-dojo.exit = function(exitcode){ 
-	quit(exitcode); 
+dojo.exit = function(exitcode){
+	quit(exitcode);
 }
 
 if(typeof print == "function"){
@@ -30,15 +30,15 @@ if(typeof line2pc == 'undefined'){
 }
 
 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");
@@ -47,23 +47,23 @@ dojo._spidermonkeyCurrentFile = function(depth){
 	}
     // lines are like: bu_getCurrentScriptURI_spidermonkey("ScriptLoader.js")@burst/Runtime.js:101
     var matches = s.match(/[^@]*\.js/gi);
-    if(!matches){ 
+    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){ 
+    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)); 
+// 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. 
+	// 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);
diff --git a/dojo/_base/_loader/loader.js b/dojo/_base/_loader/loader.js
index 48a6b10..ec15a03 100644
--- a/dojo/_base/_loader/loader.js
+++ b/dojo/_base/_loader/loader.js
@@ -2,10 +2,9 @@
  * 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;
+	var d = dojo, currentModule;
 //>>excludeEnd("webkitMobile");
 
 	d.mixin(d, {
@@ -38,11 +37,11 @@
 
 		_loadedUrls: [],
 
-		//WARNING: 
+		//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: [],
@@ -62,21 +61,24 @@
 		//		not caught by us, so the caller will see it.  We return a true
 		//		value if and only if the script is found.
 		//
-		// relpath: 
+		// relpath:
 		//		A relative path to a script (no leading '/', and typically ending
 		//		in '.js').
-		// module: 
+		// module:
 		//		A module whose existance to check for after loading a path.  Can be
 		//		used to determine success or failure of the load.
-		// cb: 
+		// 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;
 		}
 	}
 
@@ -89,7 +91,7 @@
 		//		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: 
+		//	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
@@ -103,7 +105,8 @@
 			d._loadedUrls[uri] = true;
 			d._loadedUrls.push(uri);
 			if(cb){
-				contents = '('+contents+')';
+				//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.
@@ -115,16 +118,16 @@
 		}
 		// 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. 
+			// 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 
+			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){ 
+				if(d._inFlightCount == 0){
 					d._callLoaded();
 				}
 			}, 0);
@@ -148,10 +151,10 @@
 	dojo.loaded = function(){
 		// summary:
 		//		signal fired when initial environment and package loading is
-		//		complete. You should use dojo.addOnLoad() instead of doing a 
+		//		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 
+		//		initialized. In a browser host,	declarative widgets will
 		//		be constructed when this function finishes runing.
 		d._loadNotifying = true;
 		d._postLoad = true;
@@ -178,8 +181,8 @@
 	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() 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){
@@ -198,13 +201,13 @@
 
 	dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){
 		// summary:
-		//		Registers a function to be triggered after the DOM and dojo.require() calls 
+		//		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. 
+		//		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
@@ -247,7 +250,7 @@
 
 	dojo._modulesLoaded = function(){
 		if(d._postLoad){ return; }
-		if(d._inFlightCount > 0){ 
+		if(d._inFlightCount > 0){
 			console.warn("files still in flight!");
 			return;
 		}
@@ -279,8 +282,8 @@
 		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 
+			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);
@@ -315,87 +318,95 @@
 	dojo._loadModule = dojo.require = function(/*String*/moduleName, /*Boolean?*/omitModuleCheck){
 		//	summary:
 		//		loads a Javascript module from the appropriate URI
-		//	moduleName:
+		//
+		//	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:
+		//
+		//	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 
+		// 		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. Example:
-		// 
-		//	   	|	<script type="text/javascript">
-		//		|	dojo.require("foo");
-		//		|	dojo.require("bar");
-		//	   	|	dojo.addOnLoad(function(){
-		//	   	|		//you can now safely do something with foo and bar
-		//	   	|	});
-		//	   	|	</script>
-		// 
+		// 		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 excpetion if it cannot find a file
+		//
+		//		`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. For example, to import all symbols into a
-		//		local block, you might write:
-		//	
+		//		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
+		//
+		//	returns:
+		//		the required namespace object
 		omitModuleCheck = d._global_omit_module_check || omitModuleCheck;
 
 		//Check if it is already loaded.
@@ -406,10 +417,8 @@
 
 		// 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 + "'");
 		}
@@ -420,7 +429,7 @@
 			// 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 + "'"); 
+				throw new Error("symbol '" + moduleName + "' is not defined after loading '" + relpath + "'");
 			}
 		}
 
@@ -441,14 +450,14 @@
 		//		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 
+		//		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
@@ -457,11 +466,11 @@
 		//		note that it includes multiple resources.
 		//
 		// resourceName: String
-		//		A dot-sperated string identifying a resource. 
+		//		A dot-sperated string identifying a resource.
 		//
 		// example:
 		//	Safely create a `my` object, and make dojo.require("my.CustomModule") work
-		//	|	dojo.provide("my.CustomModule"); 
+		//	|	dojo.provide("my.CustomModule");
 
 		//Make sure we have a string.
 		resourceName = resourceName + "";
@@ -518,7 +527,7 @@
 		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++){ 
+			for(var i = 1; i < arguments.length; i++){
 				args.push(arguments[i]);
 			}
 			d.require.apply(d, args);
@@ -528,13 +537,13 @@
 	dojo.requireAfterIf = d.requireIf;
 
 	dojo.registerModulePath = function(/*String*/module, /*String*/prefix){
-		//	summary: 
+		//	summary:
 		//		Maps a module name to a path
-		//	description: 
+		//	description:
 		//		An unregistered module is given the default path of ../[module],
 		//		relative to Dojo root. For example, module acme is mapped to
 		//		../acme.  If you want to use a different module name, use
-		//		dojo.registerModulePath. 
+		//		dojo.registerModulePath.
 		//	example:
 		//		If your dojo.js is located at this location in the web root:
 		//	|	/myapp/js/dojo/dojo/dojo.js
@@ -547,7 +556,7 @@
 		//		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" 
+		//	|	<script type="text/javascript"
 		//	|		src="/myapp/js/dojo/dojo/dojo.js"></script>
 		//	|	<script type="text/javascript">
 		//	|		dojo.registerModulePath("foo", "../../foo");
@@ -556,8 +565,8 @@
 		//	|		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
@@ -568,7 +577,7 @@
 		// 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.  
+		//		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.
@@ -583,21 +592,21 @@
 		//		preload the bundles to avoid data redundancy and the multiple
 		//		network hits normally required to load these resources.
 		//
-		// moduleName: 
+		// moduleName:
 		//		name of the package containing the "nls" directory in which the
 		//		bundle is found
 		//
-		// bundleName: 
+		// 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: 
+		// locale:
 		//		the locale to load (optional)  By default, the browser's user
 		//		locale as defined by dojo.locale
 		//
-		// availableFlatLocales: 
+		// availableFlatLocales:
 		//		A comma-separated list of the available, flattened locales for this
 		//		bundle. This argument should only be set by the build process.
 		//
@@ -639,11 +648,11 @@
 		ire = new RegExp("^((([^\\[:]+):)?([^@]+)@)?(\\[([^\\]]+)\\]|([^\\[:]*))(:([0-9]+))?$");
 
 	dojo._Url = function(/*dojo._Url|String...*/){
-		// summary: 
+		// summary:
 		//		Constructor to create an object representing a URL.
 		//		It is marked as private, since we might consider removing
 		//		or simplifying it.
-		// description: 
+		// 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:
@@ -710,7 +719,7 @@
 			}
 
 			uri = [];
-			if(relobj.scheme){ 
+			if(relobj.scheme){
 				uri.push(relobj.scheme, ":");
 			}
 			if(relobj.authority){
@@ -750,7 +759,7 @@
 	dojo._Url.prototype.toString = function(){ return this.uri; };
 
 	dojo.moduleUrl = function(/*String*/module, /*dojo._Url||String*/url){
-		//	summary: 
+		//	summary:
 		//		Returns a `dojo._Url` object relative to a module.
 		//	example:
 		//	|	var pngPath = dojo.moduleUrl("acme","images/small.png");
@@ -758,10 +767,10 @@
 		//	|	// 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(); 
+		//	|	img.src = pngPath.toString();
 		//	|	// add our image to the document
 		//	|	dojo.body().appendChild(img);
-		//	example: 
+		//	example:
 		//		you may de-reference as far as you like down the package
 		//		hierarchy.  This is sometimes handy to avoid lenghty relative
 		//		urls or for building portable sub-packages. In this example,
@@ -772,9 +781,9 @@
 		//	|	// 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");
@@ -793,7 +802,103 @@
 		}
 
 		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_xd.js b/dojo/_base/_loader/loader_xd.js
index f8dca7d..7f8f728 100644
--- a/dojo/_base/_loader/loader_xd.js
+++ b/dojo/_base/_loader/loader_xd.js
@@ -161,23 +161,27 @@ dojo._xdIsXDomainPath = function(/*string*/relpath) {
 	var colonIndex = relpath.indexOf(":");
 	var slashIndex = relpath.indexOf("/");
 
-	if(colonIndex > 0 && colonIndex < slashIndex){
+	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) or if the baseUrl does not match the
-		//current window's domain.
+		//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(colonIndex > 0 && colonIndex < slashIndex && (!location.host || url.indexOf("http://" + location.host) != 0)){
+		if(url.indexOf("//") === 0 || (colonIndex > 0 && colonIndex < slashIndex && (!location.host || url.indexOf("http://" + location.host) != 0))){
 			return true;
 		}
 	}
-    return false;     
+    return false;
 }
 
 dojo._loadPath = function(/*String*/relpath, /*String?*/module, /*Function?*/cb){
@@ -209,8 +213,8 @@ dojo._loadUri = function(/*String*/uri, /*Function?*/cb, /*boolean*/currentIsXDo
 	}
 
 	//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 
+	//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"){
@@ -377,7 +381,7 @@ dojo._xdResourceLoaded = function(/*Object*/res){
 		}
 
 		//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 
+		//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;
@@ -481,7 +485,7 @@ dojo.xdRequireLocalization = function(/*String*/moduleName, /*String*/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 
+    // 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();
@@ -516,7 +520,7 @@ dojo._xdUnpackDependency = function(/*Array*/dep){
 		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"]||[]);	
+			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.
@@ -553,7 +557,7 @@ dojo._xdUnpackDependency = function(/*Array*/dep){
 }
 
 dojo._xdWalkReqs = function(){
-	//summary: Internal xd loader function. 
+	//summary: Internal xd loader function.
 	//Walks the requires and evaluates module resource contents in
 	//the right order.
 	var reqChain = null;
@@ -569,7 +573,7 @@ dojo._xdWalkReqs = function(){
 }
 
 dojo._xdEvalReqs = function(/*Array*/reqChain){
-	//summary: Internal xd loader function. 
+	//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];
@@ -664,7 +668,7 @@ dojo._xdWatchInFlight = function(){
 			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.	
+			//Pass in scope args to allow multiple versions of modules in a page.
 			content.apply(dojo.global, dojo._scopeArgs);
 		}
 	}
@@ -676,7 +680,7 @@ dojo._xdWatchInFlight = function(){
 	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.	
+			//Pass in scope args to allow multiple versions of modules in a page.
 			current.content.apply(dojo.global, dojo._scopeArgs);
 		}
 	}
@@ -703,10 +707,10 @@ dojo._xdNotifyLoaded = function(){
 		}
 	}
 
-	dojo._inFlightCount = 0; 
+	dojo._inFlightCount = 0;
 
-	//Only trigger call loaded if dj_load_init has run. 
-	if(dojo._initFired && !dojo._loadNotifying){ 
+	//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 4aca04f..7b70349 100644
--- a/dojo/_base/array.js
+++ b/dojo/_base/array.js
@@ -1,11 +1,10 @@
-dojo.require("dojo._base.lang");
-dojo.provide("dojo._base.array");
+define("dojo/_base/array", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
 
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 (function(){
 	var _getParts = function(arr, obj, cb){
-		return [ 
-			(typeof arr == "string") ? arr.split("") : arr, 
+		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
@@ -24,7 +23,7 @@ dojo.provide("dojo._base.array");
 	};
 
 	dojo.mixin(dojo, {
-		indexOf: function(	/*Array*/		array, 
+		indexOf: function(	/*Array*/		array,
 							/*Object*/		value,
 							/*Integer?*/	fromIndex,
 							/*Boolean?*/	findLast){
@@ -33,7 +32,7 @@ dojo.provide("dojo._base.array");
 			//		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 
+			//		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
@@ -58,7 +57,7 @@ dojo.provide("dojo._base.array");
 			//		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 
+			//		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
@@ -77,7 +76,7 @@ dojo.provide("dojo._base.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 
+			//		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:
@@ -100,21 +99,21 @@ dojo.provide("dojo._base.array");
 			//	|	);
 			//	example:
 			//	|	// use a scoped object member as the callback
-			//	|	
+			//	|
 			//	|	var obj = {
-			//	|		prefix: "logged via obj.callback:", 
+			//	|		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 ],
@@ -127,7 +126,7 @@ dojo.provide("dojo._base.array");
 			// 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){ 
+			for(var i=0,l=arr.length; i<l; ++i){
 				_p[2].call(_p[1], arr[i], i, arr);
 			}
 		},
@@ -144,7 +143,7 @@ dojo.provide("dojo._base.array");
 			// 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 
+			//		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:
@@ -153,7 +152,7 @@ dojo.provide("dojo._base.array");
 			//	|	// returns false
 			//	|	dojo.every([1, 2, 3, 4], function(item){ return item>1; });
 			// example:
-			//	|	// returns true 
+			//	|	// returns true
 			//	|	dojo.every([1, 2, 3, 4], function(item){ return item>0; });
 			return everyOrSome(true, arr, callback, thisObject); // Boolean
 		},
@@ -170,7 +169,7 @@ dojo.provide("dojo._base.array");
 			// 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 
+			//		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:
@@ -197,7 +196,7 @@ dojo.provide("dojo._base.array");
 			// 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 
+			//		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:
@@ -228,9 +227,9 @@ dojo.provide("dojo._base.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 
+			//		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. 
+			//		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:
@@ -267,3 +266,6 @@ dojo.provide("dojo._base.array");
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 */
 //>>excludeEnd("webkitMobile");
+
+return dojo;
+});
diff --git a/dojo/_base/browser.js b/dojo/_base/browser.js
index 68500ab..0d22201 100644
--- a/dojo/_base/browser.js
+++ b/dojo/_base/browser.js
@@ -1,18 +1,20 @@
-dojo.provide("dojo._base.browser");
+define("dojo/_base/browser",[
 
-dojo.require("dojo._base.window");
-dojo.require("dojo._base.connect");
-dojo.require("dojo._base.event");
-dojo.require("dojo._base.html");
-dojo.require("dojo._base.NodeList");
-dojo.require("dojo._base.query");
-dojo.require("dojo._base.xhr");
-dojo.require("dojo._base.fx");
-
-//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);
+"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);
+	});
+	return dojo;
 });
diff --git a/dojo/_base/connect.js b/dojo/_base/connect.js
index 3e29885..81d97a1 100644
--- a/dojo/_base/connect.js
+++ b/dojo/_base/connect.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo._base.connect");
-dojo.require("dojo._base.lang");
+define("dojo/_base/connect", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
 
 // this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
 
@@ -7,37 +6,20 @@ dojo.require("dojo._base.lang");
 dojo._listener = {
 	// create a dispatcher function
 	getDispatcher: function(){
-		// following comments pulled out-of-line to prevent cloning them 
+		// 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 
+		// - 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 
+		//   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;
+			var ap = Array.prototype, c = arguments.callee, ls = c._listeners, t = c.target,
 			// return value comes from original target function
-			var r = t && t.apply(this, arguments);
+				r = t && t.apply(this, arguments),
 			// make local copy of listener array so it is immutable during processing
-			var i, lls;
-			//>>includeStart("connectRhino", kwArgs.profileProperties.hostenvType == "rhino");
-			if(!dojo.isRhino){
-			//>>includeEnd("connectRhino");
-				//>>includeStart("connectBrowser", kwArgs.profileProperties.hostenvType != "rhino");
-				lls = [].concat(ls);
-				//>>includeEnd("connectBrowser");
-			//>>includeStart("connectRhino", kwArgs.profileProperties.hostenvType == "rhino");
-			}else{
-				// FIXME: in Rhino, using concat on a sparse Array results in a dense Array.
-				// IOW, if an array A has elements [0, 2, 4], then under Rhino, "concat [].A"
-				// results in [0, 1, 2, 3, 4], where element 1 and 3 have value 'undefined'
-				// "A.slice(0)" has the same behavior.
-				lls = [];
-				for(i in ls){
-					lls[i] = ls[i];
-				}
-			}
-			//>>includeEnd("connectRhino");
+				i, lls = [].concat(ls)
+			;
 
 			// invoke listeners after target function
 			for(i in lls){
@@ -52,12 +34,12 @@ dojo._listener = {
 	// 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. 
+		// 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. 
+		// be equivalent.
 		source = source || dojo.global;
 		// The source method is either null, a dispatcher, or some other function
 		var f = source[method];
@@ -67,15 +49,15 @@ dojo._listener = {
 			// original target function is special
 			d.target = f;
 			// dispatcher holds a list of listeners
-			d._listeners = []; 
+			d._listeners = [];
 			// redirect source to dispatcher
 			f = source[method] = d;
 		}
-		// The contract is that a handle is returned that can 
-		// identify this listener for disconnect. 
+		// 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 
+		// 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.
@@ -97,9 +79,9 @@ dojo._listener = {
 // and dontFix argument here to help the autodocs. Actual DOM aware code is in
 // event.js.
 
-dojo.connect = function(/*Object|null*/ obj, 
-						/*String*/ event, 
-						/*Object|null*/ context, 
+dojo.connect = function(/*Object|null*/ obj,
+						/*String*/ event,
+						/*Object|null*/ context,
 						/*String|Function*/ method,
 						/*Boolean?*/ dontFix){
 	// summary:
@@ -134,37 +116,37 @@ dojo.connect = function(/*Object|null*/ obj,
 	//		arguments may simply be omitted such that fewer than 4 arguments
 	//		may be required to set up a connection See the examples for details.
 	//
-	//		The return value is a handle that is needed to 
+	//		The return value is a handle that is needed to
 	//		remove this connection with `dojo.disconnect`.
 	//
-	// obj: 
-	//		The source object for the event function. 
+	// obj:
+	//		The source object for the event function.
 	//		Defaults to `dojo.global` if null.
-	//		If obj is a DOM node, the connection is delegated 
+	//		If obj is a DOM node, the connection is delegated
 	//		to the DOM event manager (unless dontFix is true).
 	//
 	// event:
-	//		String name of the event function in obj. 
+	//		String name of the event function in obj.
 	//		I.e. identifies a property `obj[event]`.
 	//
-	// context: 
+	// context:
 	//		The object that method will receive as "this".
 	//
 	//		If context is null and method is a function, then method
 	//		inherits the context of event.
-	//	
-	//		If method is a string then context must be the source 
+	//
+	//		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.
 	//
 	// method:
-	//		A function reference, or name of a function in context. 
-	//		The function identified by method fires after event does. 
+	//		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:
-	//		If obj is a DOM node, set dontFix to true to prevent delegation 
+	//		If obj is a DOM node, set dontFix to true to prevent delegation
 	//		of this connection to the DOM event manager.
 	//
 	// example:
@@ -214,9 +196,9 @@ dojo.connect = function(/*Object|null*/ obj,
 
 // 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)); 
+	var l=dojo._listener, h=l.add(obj, event, dojo.hitch(context, method));
 	return [obj, event, h, l]; // Handle
-}
+};
 
 dojo.disconnect = function(/*Handle*/ handle){
 	// summary:
@@ -230,11 +212,11 @@ dojo.disconnect = function(/*Handle*/ 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
 
@@ -252,15 +234,15 @@ dojo.subscribe = function(/*String*/ topic, /*Object|null*/ context, /*String|Fu
 	//		is invoked when topic is published.
 	//	example:
 	//	|	dojo.subscribe("alerts", null, function(caption, message){ alert(caption + "\n" + message); });
-	//	|	dojo.publish("alerts", [ "read this", "hello world" ]);																	
+	//	|	dojo.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){
 	//	summary:
-	//	 	Remove a topic listener. 
+	//	 	Remove a topic listener.
 	//	handle:
 	//	 	The handle returned from a call to subscribe.
 	//	example:
@@ -270,7 +252,7 @@ dojo.unsubscribe = function(/*Handle*/ handle){
 	if(handle){
 		dojo._listener.remove(dojo._topics, handle[0], handle[1]);
 	}
-}
+};
 
 dojo.publish = function(/*String*/ topic, /*Array*/ args){
 	//	summary:
@@ -278,11 +260,11 @@ dojo.publish = function(/*String*/ topic, /*Array*/ args){
 	//	topic:
 	//	 	The name of the topic to publish.
 	//	args:
-	//	 	An array of arguments. The arguments will be applied 
+	//	 	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" ]);	
+	//	|	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
@@ -291,10 +273,10 @@ dojo.publish = function(/*String*/ topic, /*Array*/ args){
 	if(f){
 		f.apply(this, args||[]);
 	}
-}
+};
 
-dojo.connectPublisher = function(	/*String*/ topic, 
-									/*Object|null*/ obj, 
+dojo.connectPublisher = function(	/*String*/ topic,
+									/*Object|null*/ obj,
 									/*String*/ event){
 	//	summary:
 	//	 	Ensure that every time obj.event() is called, a message is published
@@ -303,14 +285,17 @@ dojo.connectPublisher = function(	/*String*/ topic,
 	//	 	the topic.
 	//	topic:
 	//	 	The name of the topic to publish.
-	//	obj: 
+	//	obj:
 	//	 	The source object for the event function. Defaults to dojo.global
 	//	 	if null.
 	//	event:
-	//	 	The name of the event function in obj. 
+	//	 	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
 };
+
+return dojo.connect;
+});
diff --git a/dojo/_base/declare.js b/dojo/_base/declare.js
index 3e7c1f6..1b17377 100644
--- a/dojo/_base/declare.js
+++ b/dojo/_base/declare.js
@@ -1,16 +1,13 @@
-dojo.provide("dojo._base.declare");
-
-dojo.require("dojo._base.lang");
-dojo.require("dojo._base.array");
+define("dojo/_base/declare", ["dojo/lib/kernel", "dojo/_base/lang", "dojo/_base/array"], function(dojo){
 
 (function(){
 	var d = dojo, mix = d._mixin, op = Object.prototype, opts = op.toString,
 		xtor = new Function, counter = 0, cname = "constructor";
 
-	function err(msg){ throw new Error("declare: " + msg); }
+	function err(msg, cls){ throw new Error("declare" + (cls ? " " + cls : "") + ": " + msg); }
 
 	// C3 Method Resolution Order (see http://www.python.org/download/releases/2.3/mro/)
-	function c3mro(bases){
+	function c3mro(bases, className){
 		var result = [], roots = [{cls: 0, refs: []}], nameMap = {}, clsCount = 1,
 			l = bases.length, i = 0, j, lin, base, top, proto, rec, name, refs;
 
@@ -18,9 +15,9 @@ dojo.require("dojo._base.array");
 		for(; i < l; ++i){
 			base = bases[i];
 			if(!base){
-				err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?");
+				err("mixin #" + i + " is unknown. Did you use dojo.require to pull it in?", className);
 			}else if(opts.call(base) != "[object Function]"){
-				err("mixin #" + i + " is not a callable constructor.");
+				err("mixin #" + i + " is not a callable constructor.", className);
 			}
 			lin = base._meta ? base._meta.bases : [base];
 			top = 0;
@@ -73,7 +70,7 @@ dojo.require("dojo._base.array");
 			}
 		}
 		if(clsCount){
-			err("can't build consistent linearization");
+			err("can't build consistent linearization", className);
 		}
 
 		// calculate the superclass offset
@@ -100,7 +97,7 @@ dojo.require("dojo._base.array");
 		caller = args.callee;
 		name = name || caller.nom;
 		if(!name){
-			err("can't deduce a name to call inherited()");
+			err("can't deduce a name to call inherited()", this.declaredClass);
 		}
 
 		meta = this.constructor._meta;
@@ -118,7 +115,7 @@ dojo.require("dojo._base.array");
 					// error detection
 					chains = meta.chains;
 					if(chains && typeof chains[name] == "string"){
-						err("calling chained method with inherited: " + name);
+						err("calling chained method with inherited: " + name, this.declaredClass);
 					}
 					// find caller
 					do{
@@ -159,7 +156,7 @@ dojo.require("dojo._base.array");
 					// error detection
 					chains = meta.chains;
 					if(!chains || chains.constructor !== "manual"){
-						err("calling chained constructor with inherited");
+						err("calling chained constructor with inherited", this.declaredClass);
 					}
 					// find caller
 					while(base = bases[++pos]){ // intentional assignment
@@ -455,7 +452,7 @@ dojo.require("dojo._base.array");
 		// build a prototype
 		if(opts.call(superclass) == "[object Array]"){
 			// C3 MRO
-			bases = c3mro(superclass);
+			bases = c3mro(superclass, className);
 			t = bases[0];
 			mixins = bases.length - t;
 			superclass = bases[mixins];
@@ -466,10 +463,10 @@ dojo.require("dojo._base.array");
 					t = superclass._meta;
 					bases = bases.concat(t ? t.bases : superclass);
 				}else{
-					err("base class is not a callable constructor.");
+					err("base class is not a callable constructor.", className);
 				}
 			}else if(superclass !== null){
-				err("unknown base class. Did you use dojo.require to pull it in?")
+				err("unknown base class. Did you use dojo.require to pull it in?", className);
 			}
 		}
 		if(superclass){
@@ -1035,3 +1032,6 @@ dojo.require("dojo._base.array");
 	};
 	=====*/
 })();
+
+return dojo.declare;
+});
diff --git a/dojo/_base/event.js b/dojo/_base/event.js
index 408da37..c0a6405 100644
--- a/dojo/_base/event.js
+++ b/dojo/_base/event.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo._base.event");
-dojo.require("dojo._base.connect");
+define("dojo/_base/event", ["dojo/lib/kernel", "dojo/_base/connect"], function(dojo){
 
 // this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
 
@@ -9,23 +8,21 @@ dojo.require("dojo._base.connect");
 	// DOM event listener machinery
 	var del = (dojo._event_listener = {
 		add: function(/*DOMNode*/ node, /*String*/ name, /*Function*/ fp){
-			if(!node){return;} 
+			if(!node){return;}
 			name = del._normalizeEventName(name);
 			fp = del._fixCallback(name, fp);
-			var oname = name;
 			if(
 				//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-				!dojo.isIE && 
+				!dojo.isIE &&
 				//>>excludeEnd("webkitMobile");
 				(name == "mouseenter" || name == "mouseleave")
 			){
 				var ofp = fp;
-				//oname = name;
 				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); 
+						return ofp.call(this, e);
 					}
 				}
 			}
@@ -66,7 +63,7 @@ dojo.require("dojo._base.connect");
 		},
 		_fixEvent: function(evt, sender){
 			// _fixCallback only attaches us to keypress.
-			// Switch on evt.type anyway because we might 
+			// Switch on evt.type anyway because we might
 			// be called directly from dojo.fixEvent.
 			switch(evt.type){
 				case "keypress":
@@ -76,26 +73,26 @@ dojo.require("dojo._base.connect");
 			return evt;
 		},
 		_setKeyChar: function(evt){
-			evt.keyChar = evt.charCode ? String.fromCharCode(evt.charCode) : '';
+			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 
+		_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
 		}
 	});
 
@@ -110,7 +107,7 @@ dojo.require("dojo._base.connect");
 		// sender: DOMNode
 		//		node to treat as "currentTarget"
 		return del._fixEvent(evt, sender);
-	}
+	};
 
 	dojo.stopEvent = function(/*Event*/ evt){
 		// summary:
@@ -121,7 +118,7 @@ dojo.require("dojo._base.connect");
 		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;
@@ -136,16 +133,16 @@ dojo.require("dojo._base.connect");
 		// 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" 
+		// 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
 
@@ -276,7 +273,7 @@ dojo.require("dojo._base.connect");
 =====*/
 
 	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-	if(dojo.isIE){
+	if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
 		dojo.mouseButtons = {
 			LEFT:   1,
 			MIDDLE: 4,
@@ -305,7 +302,7 @@ dojo.require("dojo._base.connect");
 
 	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	// IE event normalization
-	if(dojo.isIE){ 
+	if(dojo.isIE){
 		var _trySetKeyCode = function(e, code){
 			try{
 				// squelch errors when keyCode is read-only
@@ -314,7 +311,7 @@ dojo.require("dojo._base.connect");
 			}catch(e){
 				return 0;
 			}
-		}
+		};
 
 		// by default, use the standard listener
 		var iel = dojo._listener;
@@ -323,7 +320,7 @@ dojo.require("dojo._base.connect");
 		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 
+				// support handler indirection: event handler functions are
 				// referenced here. Event dispatchers hold only indices.
 				handlers: [],
 				// add a listener to an object
@@ -376,7 +373,7 @@ dojo.require("dojo._base.connect");
 			},
 			remove: function(/*DOMNode*/ node, /*String*/ event, /*Handle*/ handle){
 				event = del._normalizeEventName(event);
-				iel.remove(node, event, handle); 
+				iel.remove(node, event, handle);
 				if(event=="onkeypress"){
 					var kd = node.onkeydown;
 					if(--kd._stealthKeydownRefs <= 0){
@@ -402,11 +399,11 @@ dojo.require("dojo._base.connect");
 				//		node to treat as "currentTarget"
 				if(!evt){
 					var w = sender && (sender.ownerDocument || sender.document || sender).parentWindow || window;
-					evt = w.event; 
+					evt = w.event;
 				}
 				if(!evt){return(evt);}
-				evt.target = evt.srcElement; 
-				evt.currentTarget = (sender || evt.srcElement); 
+				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
@@ -419,14 +416,16 @@ dojo.require("dojo._base.connect");
 				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"){ 
+				if(evt.type == "mouseover"){
 					evt.relatedTarget = evt.fromElement;
 				}
-				if(evt.type == "mouseout"){ 
+				if(evt.type == "mouseout"){
 					evt.relatedTarget = evt.toElement;
 				}
-				evt.stopPropagation = del._stopPropagation;
-				evt.preventDefault = del._preventDefault;
+				if (dojo.isIE < 9 || dojo.isQuirks) {
+					evt.stopPropagation = del._stopPropagation;
+					evt.preventDefault = del._preventDefault;
+				}
 				return del._fixKeys(evt);
 			},
 			_fixKeys: function(evt){
@@ -460,38 +459,41 @@ dojo.require("dojo._base.connect");
 				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!=27 && (k<48||k>90) && (k<96||k>111) && (k<186||k>192) && (k<219||k>222);
+				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){ 
+							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)){ 
+						}else if((!evt.shiftKey)&&(c>=65&&c<=90)){
 							c += 32; // map CTRL-[A-Z] to lowercase
-						}else{ 
+						}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);
-					evt.cancelBubble = faux.cancelBubble;
+					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; 
+				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 
+				// 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;
@@ -501,24 +503,24 @@ dojo.require("dojo._base.connect");
 		});
 				
 		// override stopEvent for IE
-		dojo.stopEvent = function(evt){
+		dojo.stopEvent = (dojo.isIE < 9 || dojo.isQuirks) ? function(evt){
 			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); 
+			// 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(); }; 
+			faux.preventDefault = function(){ evt.preventDefault(); };
+			faux.stopPropagation = function(){ evt.stopPropagation(); };
 			return faux;
-	}
+	};
 	
 	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	// Opera event normalization
@@ -573,12 +575,12 @@ dojo.require("dojo._base.connect");
 							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){ 
+									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){ 
+								}else if(!evt.shiftKey && c>=65 && c<=90){
 									c += 32; // map CTRL-[A-Z] to lowercase
-								}else{ 
+								}else{
 									c = del._punctMap[c] || c; // map other problematic CTRL combinations to ASCII
 								}
 							}
@@ -640,15 +642,18 @@ if(dojo.isIE){
 			}
 		}
 		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;
+});
diff --git a/dojo/_base/fx.js b/dojo/_base/fx.js
index 2a7ccb1..55f71c8 100644
--- a/dojo/_base/fx.js
+++ b/dojo/_base/fx.js
@@ -1,8 +1,4 @@
-dojo.provide("dojo._base.fx");
-dojo.require("dojo._base.Color");
-dojo.require("dojo._base.connect");
-dojo.require("dojo._base.lang");
-dojo.require("dojo._base.html");
+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:
@@ -662,3 +658,6 @@ dojo.require("dojo._base.html");
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 })();
 //>>excludeEnd("webkitMobile");
+
+return dojo.animateProperty;
+});
diff --git a/dojo/_base/html.js b/dojo/_base/html.js
index 1542fe2..b179a15 100644
--- a/dojo/_base/html.js
+++ b/dojo/_base/html.js
@@ -1,5 +1,4 @@
-dojo.require("dojo._base.lang");
-dojo.provide("dojo._base.html");
+define("dojo/_base/html", ["dojo/lib/kernel", "dojo/_base/lang"], function(dojo){
 
 // FIXME: need to add unit tests for all the semi-public methods
 
@@ -47,13 +46,13 @@ dojo.byId = function(id, doc){
 =====*/
 
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-if(dojo.isIE || dojo.isOpera){
+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 
+		// 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;
@@ -75,8 +74,9 @@ if(dojo.isIE || dojo.isOpera){
 }else{
 //>>excludeEnd("webkitMobile");
 	dojo.byId = function(id, doc){
-		// inline'd type check
-		return (typeof id == "string") ? (doc || dojo.doc).getElementById(id) : id; // DomNode
+		// 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);
 }
@@ -165,16 +165,16 @@ if(dojo.isIE || dojo.isOpera){
 	};
 
 	dojo.setSelectable = function(/*DomNode|String*/node, /*Boolean*/selectable){
-		//	summary: 
+		//	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 
+		//		state to put the node in. false indicates unselectable, true
 		//		allows selection.
 		//	example:
 		//	Make the node id="bar" unselectable
-		//	|	dojo.setSelectable("bar"); 
+		//	|	dojo.setSelectable("bar");
 		//	example:
 		//	Make the node id="bar" selectable
 		//	|	dojo.setSelectable("bar", true);
@@ -261,7 +261,7 @@ if(dojo.isIE || dojo.isOpera){
 
 		refNode = byId(refNode);
 		if(typeof node == "string"){ // inline'd type check
-			node = node.charAt(0) == "<" ? d._toDom(node, refNode.ownerDocument) : byId(node);
+			node = /^\s*</.test(node) ? d._toDom(node, refNode.ownerDocument) : byId(node);
 		}
 		if(typeof position == "number"){ // inline'd type check
 			var cn = refNode.childNodes;
@@ -296,7 +296,7 @@ if(dojo.isIE || dojo.isOpera){
 			}
 		}
 		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.
@@ -308,7 +308,7 @@ if(dojo.isIE || dojo.isOpera){
 	dojo.boxModel = "content-box";
 
 	// We punt per-node box mode testing completely.
-	// If anybody cares, we can provide an additional (optional) unit 
+	// 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.
@@ -330,10 +330,10 @@ if(dojo.isIE || dojo.isOpera){
 	// getComputedStyle drives most of the style code.
 	// Wherever possible, reuse the returned object.
 	//
-	// API functions below that need to access computed styles accept an 
+	// 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 
+	// This way, calling code can access computedStyle once, and then pass the reference to
 	// multiple API functions.
 
 /*=====
@@ -372,7 +372,7 @@ if(dojo.isIE || dojo.isOpera){
 	// 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 
+	// it is frequently sent to this function even
 	// though it is not Element.
 	var gcs;
 	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
@@ -440,7 +440,7 @@ if(dojo.isIE || dojo.isOpera){
 				runtimeStyle.left = rsLeft;
 			}
 			return avalue;
-		}
+		};
 	}
 	//>>excludeEnd("webkitMobile");
 	var px = d._toPixelValue;
@@ -472,7 +472,7 @@ if(dojo.isIE || dojo.isOpera){
 	//>>excludeEnd("webkitMobile");
 	dojo._getOpacity =
 	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE ? function(node){
+		d.isIE < 9 ? function(node){
 			try{
 				return af(node).Opacity / 100; // Number
 			}catch(e){
@@ -501,7 +501,7 @@ if(dojo.isIE || dojo.isOpera){
 
 	dojo._setOpacity =
 		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-		d.isIE ? function(/*DomNode*/node, /*Number*/opacity){
+		d.isIE < 9 ? function(/*DomNode*/node, /*Number*/opacity){
 			var ov = opacity * 100, opaque = opacity == 1;
 			node.style.zoom = opaque ? "" : 1;
 
@@ -576,7 +576,7 @@ if(dojo.isIE || dojo.isOpera){
 		//		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()`, 
+		//		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
@@ -645,7 +645,7 @@ if(dojo.isIE || dojo.isOpera){
 			return s;
 		}
 		return (args == 1) ? s : _toStyleValue(n, style, s[style] || n.style[style]); /* CSS2Properties||String||Number */
-	}
+	};
 
 	// =============================
 	// Box Functions
@@ -658,13 +658,13 @@ if(dojo.isIE || dojo.isOpera){
 		//	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 
+		//	|		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 
+		var
 			s = computedStyle||gcs(n),
 			l = px(n, s.paddingLeft),
 			t = px(n, s.paddingTop);
@@ -674,7 +674,7 @@ if(dojo.isIE || dojo.isOpera){
 			w: l+px(n, s.paddingRight),
 			h: t+px(n, s.paddingBottom)
 		};
-	}
+	};
 
 	dojo._getBorderExtents = function(/*DomNode*/n, /*Object*/computedStyle){
 		//	summary:
@@ -688,7 +688,7 @@ if(dojo.isIE || dojo.isOpera){
 		//		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 
+		var
 			ne = "none",
 			s = computedStyle||gcs(n),
 			bl = (s.borderLeftStyle != ne ? px(n, s.borderLeftWidth) : 0),
@@ -699,7 +699,7 @@ if(dojo.isIE || dojo.isOpera){
 			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:
@@ -713,7 +713,7 @@ if(dojo.isIE || dojo.isOpera){
 		//		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 
+		var
 			s = computedStyle||gcs(n),
 			p = d._getPadExtents(n, s),
 			b = d._getBorderExtents(n, s);
@@ -723,7 +723,7 @@ if(dojo.isIE || dojo.isOpera){
 			w: p.w + b.w,
 			h: p.h + b.h
 		};
-	}
+	};
 
 	dojo._getMarginExtents = function(n, computedStyle){
 		//	summary:
@@ -737,7 +737,7 @@ if(dojo.isIE || dojo.isOpera){
 		//		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 
+		var
 			s = computedStyle||gcs(n),
 			l = px(n, s.marginLeft),
 			t = px(n, s.marginTop),
@@ -745,9 +745,9 @@ if(dojo.isIE || dojo.isOpera){
 			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 
+			// 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 
+			// 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;
@@ -758,7 +758,7 @@ if(dojo.isIE || dojo.isOpera){
 			w: l+r,
 			h: t+b
 		};
-	}
+	};
 
 	// Box getters work in any box context because offsetWidth/clientWidth
 	// are invariant wrt box context
@@ -766,10 +766,10 @@ if(dojo.isIE || dojo.isOpera){
 	// 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 
+	// 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 
+	// 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)
@@ -815,9 +815,23 @@ if(dojo.isIE || dojo.isOpera){
 			l: l,
 			t: t,
 			w: node.offsetWidth + me.w,
-			h: node.offsetHeight + me.h 
+			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:
@@ -848,7 +862,7 @@ if(dojo.isIE || dojo.isOpera){
 			w: w - pe.w - be.w,
 			h: h - pe.h - be.h
 		};
-	}
+	};
 
 	dojo._getBorderBox = function(node, computedStyle){
 		var s = computedStyle || gcs(node),
@@ -861,7 +875,7 @@ if(dojo.isIE || dojo.isOpera){
 			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.
@@ -872,12 +886,12 @@ if(dojo.isIE || dojo.isOpera){
 	// 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 
+	// 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 
+	// 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){
@@ -903,14 +917,14 @@ if(dojo.isIE || dojo.isOpera){
 		if(!isNaN(t)){ s.top = t + u; }
 		if(w >= 0){ s.width = w + u; }
 		if(h >= 0){ s.height = h + u; }
-	}
+	};
 
 	dojo._isButtonTag = function(/*DomNode*/node) {
 		// 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:
@@ -925,7 +939,7 @@ if(dojo.isIE || dojo.isOpera){
 
 		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:
@@ -937,7 +951,7 @@ if(dojo.isIE || dojo.isOpera){
 			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,
@@ -969,7 +983,7 @@ if(dojo.isIE || dojo.isOpera){
 		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 };
 
@@ -1004,7 +1018,7 @@ if(dojo.isIE || dojo.isOpera){
 		
 		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
-	}
+	};
 
 	dojo.contentBox = function(/*DomNode|String*/node, /*Object?*/box){
 		//	summary:
@@ -1029,14 +1043,14 @@ if(dojo.isIE || dojo.isOpera){
 		//		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 
+	// Positioning
 	// =============================
 
 	var _sumAncestorProperties = function(node, prop){
-		if(!(node = (node||0).parentNode)){return 0}
+		if(!(node = (node||0).parentNode)){return 0;}
 		var val, retVal = 0, _b = d.body();
 		while(node && node.style){
 			if(gcs(node).position == "fixed"){
@@ -1052,19 +1066,19 @@ if(dojo.isIE || dojo.isOpera){
 			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.doc.documentElement, n.clientHeight? { x:d._fixIeBiDiScrollLeft(n.scrollLeft), y:n.scrollTop } :
-			(n=d.body(), { x:n.scrollLeft||0, y:n.scrollTop||0 }));
+		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 
-	}
+			d._bodyLtr = (d.body().dir || d.doc.documentElement.dir || "ltr").toLowerCase() == "ltr"; // Boolean
+	};
 
 	//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 	dojo._getIeDocumentElementOffset = function(){
@@ -1086,7 +1100,7 @@ if(dojo.isIE || dojo.isOpera){
 
 		//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 
+		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+
@@ -1112,20 +1126,24 @@ if(dojo.isIE || dojo.isOpera){
 	//>>excludeEnd("webkitMobile");
 
 	dojo._fixIeBiDiScrollLeft = function(/*Integer*/ scrollLeft){
-		// In RTL direction, scrollLeft should be a negative value, but IE < 8
+		// 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 dd = d.doc;
-		if(d.isIE < 8 && !d._isBodyLtr()){
-			var de = d.isQuirks ? dd.body : dd.documentElement;
-			return scrollLeft + de.clientWidth - de.scrollWidth; // Integer
+		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){
@@ -1143,10 +1161,9 @@ if(dojo.isIE || dojo.isOpera){
 		//		Uses the border-box model (inclusive of border and padding but
 		//		not margin).  Does not act as a setter.
 
-		var db = d.body(), dh = db.parentNode, ret;
 		node = byId(node);
-		if(node["getBoundingClientRect"]){
-			// IE6+, FF3+, super-modern WebKit, and Opera 9.6+ all take this branch
+		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);
@@ -1165,66 +1182,7 @@ if(dojo.isIE || dojo.isOpera){
 				ret.y -= px(dh, cs.marginTop) + px(dh, cs.borderTopWidth);
 			}
 		//>>excludeEnd("webkitMobile");
-		}else{
-			// FF2 and older WebKit
-			ret = {
-				x: 0,
-				y: 0,
-				w: node.offsetWidth,
-				h: node.offsetHeight
-			};
-			if(node["offsetParent"]){
-				ret.x -= _sumAncestorProperties(node, "scrollLeft");
-				ret.y -= _sumAncestorProperties(node, "scrollTop");
-
-				var curnode = node;
-				do{
-					var n = curnode.offsetLeft,
-						t = curnode.offsetTop;
-					ret.x += isNaN(n) ? 0 : n;
-					ret.y += isNaN(t) ? 0 : t;
-
-					cs = gcs(curnode);
-					if(curnode != node){
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-						if(d.isMoz){
-							// tried left+right with differently sized left/right borders
-							// it really is 2xleft border in FF, not left+right, even in RTL!
-							ret.x += 2 * px(curnode,cs.borderLeftWidth);
-							ret.y += 2 * px(curnode,cs.borderTopWidth);
-						}else{
-		//>>excludeEnd("webkitMobile");
-							ret.x += px(curnode, cs.borderLeftWidth);
-							ret.y += px(curnode, cs.borderTopWidth);
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-						}
-		//>>excludeEnd("webkitMobile");
-					}
-					// static children in a static div in FF2 are affected by the div's border as well
-					// but offsetParent will skip this div!
-		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-					if(d.isMoz && cs.position=="static"){
-						var parent=curnode.parentNode;
-						while(parent!=curnode.offsetParent){
-							var pcs=gcs(parent);
-							if(pcs.position=="static"){
-								ret.x += px(curnode,pcs.borderLeftWidth);
-								ret.y += px(curnode,pcs.borderTopWidth);
-							}
-							parent=parent.parentNode;
-						}
-					}
-		//>>excludeEnd("webkitMobile");
-					curnode = curnode.offsetParent;
-				}while((curnode != dh) && curnode);
-			}else if(node.x && node.y){
-				ret.x += isNaN(node.x) ? 0 : node.x;
-				ret.y += isNaN(node.y) ? 0 : node.y;
-			}
-		}
 		// 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 = d._docScroll();
 			ret.x += scroll.x;
@@ -1232,7 +1190,7 @@ if(dojo.isIE || dojo.isOpera){
 		}
 
 		return ret; // Object
-	}
+	};
 
 	dojo.coords = function(/*DomNode|String*/node, /*Boolean?*/includeScroll){
 		//	summary:
@@ -1254,7 +1212,7 @@ if(dojo.isIE || dojo.isOpera){
 		mb.x = abs.x;
 		mb.y = abs.y;
 		return mb;
-	}
+	};
 
 	// =============================
 	// Element attribute Functions
@@ -1316,7 +1274,7 @@ if(dojo.isIE || dojo.isOpera){
 		//		given element, and false otherwise
 		var lc = name.toLowerCase();
 		return _forcePropNames[_propNames[lc] || name] || _hasAttr(byId(node), _attrNames[lc] || name);	// Boolean
-	}
+	};
 
 	var _evtHdlrMap = {}, _ctr = 0,
 		_attrId = dojo._scopeName + "attrid",
@@ -1490,7 +1448,7 @@ if(dojo.isIE || dojo.isOpera){
 		// 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:
@@ -1500,7 +1458,7 @@ if(dojo.isIE || dojo.isOpera){
 		//	name:
 		//		the name of the attribute to remove
 		byId(node).removeAttribute(_fixAttrName(name));
-	}
+	};
 
 	dojo.getNodeProp = function(/*DomNode|String*/ node, /*String*/ name){
 		//	summary:
@@ -1519,7 +1477,7 @@ if(dojo.isIE || dojo.isOpera){
 		// node's attribute
 		var attrName = _attrNames[lc] || name;
 		return _hasAttr(node, attrName) ? node.getAttribute(attrName) : null; // Anything
-	}
+	};
 
 	dojo.create = function(tag, attrs, refNode, pos){
 		//	summary:
@@ -1534,7 +1492,7 @@ if(dojo.isIE || dojo.isOpera){
 		//		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 
+		//		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
@@ -1572,7 +1530,7 @@ if(dojo.isIE || dojo.isOpera){
 		//	|	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 
+		//	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"];
@@ -1602,7 +1560,7 @@ if(dojo.isIE || dojo.isOpera){
 		if(attrs){ d.attr(tag, attrs); }
 		if(refNode){ d.place(tag, refNode, pos); }
 		return tag; // DomNode
-	}
+	};
 
 	/*=====
 	dojo.empty = function(node){
@@ -1672,11 +1630,13 @@ if(dojo.isIE || dojo.isOpera){
 	// generate start/end tag strings to use
 	// for the injection for each special tag wrap case.
 	for(var param in tagWrap){
-		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
+		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){
@@ -1719,7 +1679,7 @@ if(dojo.isIE || dojo.isOpera){
 			df.appendChild(fc);
 		}
 		return df; // DOMNode
-	}
+	};
 
 	// =============================
 	// (CSS) Class Functions
@@ -1745,6 +1705,7 @@ if(dojo.isIE || dojo.isOpera){
 	};
 
 	var spaces = /\s+/, a1 = [""],
+		fakeNode = {},
 		str2array = function(s){
 			if(typeof s == "string" || s instanceof String){
 				if(s.indexOf(" ") < 0){
@@ -1850,6 +1811,39 @@ if(dojo.isIE || dojo.isOpera){
 		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.
@@ -1877,3 +1871,6 @@ if(dojo.isIE || dojo.isOpera){
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 })();
 //>>excludeEnd("webkitMobile");
+
+return dojo;
+});
diff --git a/dojo/_base/json.js b/dojo/_base/json.js
index 5430636..cea5b59 100644
--- a/dojo/_base/json.js
+++ b/dojo/_base/json.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo._base.json");
+define("dojo/_base/json", ["dojo/lib/kernel"], function(dojo){
 
 dojo.fromJson = function(/*String*/ json){
 	// summary:
@@ -7,12 +7,12 @@ dojo.fromJson = function(/*String*/ json){
 	// 		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
 	//		from a trusted source.
-	// json: 
+	// json:
 	//		a string literal of a JSON item, for instance:
 	//			`'{ "foo": [ "bar", 1, { "baz": "thud" } ] }'`
 
 	return eval("(" + json + ")"); // Object
-}
+};
 
 dojo._escapeString = function(/*String*/str){
 	//summary:
@@ -22,7 +22,7 @@ dojo._escapeString = function(/*String*/str){
 	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.toJsonIndentStr = "\t";
 dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _indentStr){
@@ -66,8 +66,8 @@ dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _ind
 	if(it === null){
 		return "null";
 	}
-	if(dojo.isString(it)){ 
-		return dojo._escapeString(it); 
+	if(dojo.isString(it)){
+		return dojo._escapeString(it);
 	}
 	// recurse
 	var recurse = arguments.callee;
@@ -140,4 +140,7 @@ dojo.toJson = function(/*Object*/ it, /*Boolean?*/ prettyPrint, /*String?*/ _ind
 		output.push(newLine + nextIndent + keyStr + ":" + sep + val);
 	}
 	return "{" + output.join("," + sep) + newLine + _indentStr + "}"; // String
-}
+};
+
+return dojo;
+});
diff --git a/dojo/_base/lang.js b/dojo/_base/lang.js
index 839ee4d..3389991 100644
--- a/dojo/_base/lang.js
+++ b/dojo/_base/lang.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo._base.lang");
+define("dojo/_base/lang", ["dojo/lib/kernel"], function(dojo){
 
 (function(){
 	var d = dojo, opts = Object.prototype.toString;
@@ -9,14 +9,14 @@ dojo.provide("dojo._base.lang");
 		//	summary:
 		//		Return true if it is a String
 		return (typeof it == "string" || it instanceof String); // Boolean
-	}
+	};
 
 	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:
@@ -30,7 +30,7 @@ dojo.provide("dojo._base.lang");
 		//		or null)
 		return it !== undefined &&
 			(it === null || typeof it == "object" || d.isArray(it) || d.isFunction(it)); // Boolean
-	}
+	};
 
 	dojo.isArrayLike = function(/*anything*/ it){
 		//	summary:
@@ -49,14 +49,14 @@ dojo.provide("dojo._base.lang");
 			!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:
@@ -67,7 +67,7 @@ dojo.provide("dojo._base.lang");
 			d._mixin(constructor.prototype, arguments[i]);
 		}
 		return constructor; // Object
-	}
+	};
 
 	dojo._hitchArgs = function(scope, method /*,...*/){
 		var pre = d._toArray(arguments, 2);
@@ -79,8 +79,8 @@ dojo.provide("dojo._base.lang");
 			var f = named ? (scope||d.global)[method] : method;
 			// invoke with collected args
 			return f && f.apply(scope || this, pre.concat(args)); // mixed
-		} // Function
-	}
+		}; // Function
+	};
 
 	dojo.hitch = function(/*Object*/scope, /*Function|String*/method /*,...*/){
 		//	summary:
@@ -88,7 +88,7 @@ dojo.provide("dojo._base.lang");
 		//		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 
+		//		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.
@@ -128,7 +128,7 @@ dojo.provide("dojo._base.lang");
 			return function(){ return scope[method].apply(scope, arguments || []); }; // Function
 		}
 		return !scope ? method : function(){ return method.apply(scope, arguments || []); }; // Function
-	}
+	};
 
 	/*=====
 	dojo.delegate = function(obj, props){
@@ -172,7 +172,7 @@ dojo.provide("dojo._base.lang");
 				d._mixin(tmp, props);
 			}
 			return tmp; // Object
-		}
+		};
 	})();
 
 	/*=====
@@ -225,7 +225,7 @@ dojo.provide("dojo._base.lang");
 		//		|	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 = {};
 
@@ -245,6 +245,10 @@ dojo.provide("dojo._base.lang");
 			// 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
@@ -285,7 +289,7 @@ dojo.provide("dojo._base.lang");
 		}
 		//>>excludeEnd("webkitMobile");
 		return r; // Object
-	}
+	};
 
 	/*=====
 	dojo.trim = function(str){
@@ -314,7 +318,7 @@ dojo.provide("dojo._base.lang");
 	dojo.replace = function(tmpl, map, pattern){
 		//	summary:
 		//		Performs parameterized substitutions on a string. Throws an
-		//		exception if any parameter is unmatched. 
+		//		exception if any parameter is unmatched.
 		//	tmpl: String
 		//		String to be used as a template.
 		//	map: Object|Function
@@ -385,3 +389,6 @@ dojo.provide("dojo._base.lang");
 			map : function(_, k){ return d.getObject(k, false, map); });
 	};
 })();
+
+return dojo;
+});
diff --git a/dojo/_base/query-sizzle.js b/dojo/_base/query-sizzle.js
index ba7fe3e..9411c0c 100644
--- a/dojo/_base/query-sizzle.js
+++ b/dojo/_base/query-sizzle.js
@@ -11,11 +11,7 @@
  *  Finally, dojo.provide/require added.
  */
 
-//This file gets copied to dojo/_base/query.js, so set the provide accordingly.
-if(typeof dojo != "undefined"){
-	dojo.provide("dojo._base.query");
-	dojo.require("dojo._base.NodeList");
-
+var startDojoMappings= function(dojo) {
 	//Start Dojo mappings.
 	dojo.query = function(/*String*/ query, /*String|DOMNode?*/ root, /*Function?*/listCtor){
 		listCtor = listCtor || dojo.NodeList;
@@ -36,16 +32,16 @@ if(typeof dojo != "undefined"){
 		}
 
 		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.
-;(function(ns){
+var defineSizzle= function(ns){
 
 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|[^[\]]+)+\]|\\.|[^ >+~,(\[]+)+|[>+~])(\s*,\s*)?/g,
 	done = 0,
@@ -853,6 +849,27 @@ var contains = document.compareDocumentPosition ?  function(a, b){
 
 // EXPOSE
 
-(ns || window).Sizzle = Sizzle;
+ns.Sizzle = Sizzle;
 
-})(typeof dojo == "undefined" ? null : dojo);
+};
+
+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 5b045d8..0f3d55f 100644
--- a/dojo/_base/query.js
+++ b/dojo/_base/query.js
@@ -1,84 +1,5 @@
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-if(typeof dojo != "undefined"){
-//>>excludeEnd("webkitMobile");
-	dojo.provide("dojo._base.query");
-	dojo.require("dojo._base.NodeList");
-	dojo.require("dojo._base.lang");
-
-//>>excludeStart("acmeExclude", fileName.indexOf("dojo") != -1);
-
-}else if(!this["acme"] && !this["queryPortability"]){
-	// NOTE: 
-	//		the functions and properties are duplicates of things found
-	//		elsewhere in Dojo. They've been copied here to make query.js a
-	//		stand-alone system.  The "acmeExclude" ensures that it *never*
-	//		shows up in builds of Dojo.
-	(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; };
-	})();
-
-//>>excludeEnd("acmeExclude");
-//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
-}
+(function(){
 
 /*
 	dojo.query() architectural overview:
@@ -112,7 +33,7 @@ if(typeof dojo != "undefined"){
 			5.) matched nodes are pruned to ensure they are unique (if necessary)
 */
 
-;(function(d){
+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").
 
@@ -120,7 +41,7 @@ if(typeof dojo != "undefined"){
 	// Toolkit aliases
 	////////////////////////////////////////////////////////////////////////
 
-	// if you are extracing dojo.query for use in your own system, you will
+	// 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
@@ -131,7 +52,7 @@ if(typeof dojo != "undefined"){
 	// 					d.isOpera; // float
 	// 					d.isWebKit; // float
 	// 					d.doc ; // document element
-	var qlc = d._NodeListCtor = 		d.NodeList;
+	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
@@ -162,7 +83,7 @@ if(typeof dojo != "undefined"){
 	////////////////////////////////////////////////////////////////////////
 
 	var getQueryParts = function(query){
-		//	summary: 
+		//	summary:
 		//		state machine for query tokenization
 		//	description:
 		//		instead of using a brittle and slow regex-based CSS parser,
@@ -171,16 +92,16 @@ if(typeof dojo != "undefined"){
 		//		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) charachter and returns an
+		//		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: 
+		// NOTE:
 		//		this code is designed to run fast and compress well. Sacrifices
-		//		to readibility and maintainability have been made.  Your best
+		//		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
@@ -196,7 +117,7 @@ if(typeof dojo != "undefined"){
 		}
 
 		var ts = function(/*Integer*/ s, /*Integer*/ e){
-			// trim and slice. 
+			// 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
@@ -204,12 +125,12 @@ if(typeof dojo != "undefined"){
 		}
 
 		// the overall data graph of the full query, as represented by queryPart objects
-		var queryParts = []; 
+		var queryParts = [];
 
 
 		// state keeping vars
-		var inBrackets = -1, inParens = -1, inMatchFor = -1, 
-			inPseudo = -1, inClass = -1, inId = -1, inTag = -1, 
+		var inBrackets = -1, inParens = -1, inMatchFor = -1,
+			inPseudo = -1, inClass = -1, inId = -1, inTag = -1,
 			lc = "", cc = "", pStart;
 
 		// iteration vars
@@ -218,7 +139,7 @@ if(typeof dojo != "undefined"){
 			currentPart = null, // data structure representing the entire clause
 			_cp = null; // the current pseudo or attr matcher
 
-		// several temporary variables are assigned to this structure durring a
+		// 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
@@ -273,9 +194,9 @@ if(typeof dojo != "undefined"){
 			// 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.loops = (
+					currentPart.pseudos.length ||
+					currentPart.attrs.length ||
 					currentPart.classes.length	);
 
 			currentPart.oquery = currentPart.query = ts(pStart, x); // save the full expression as a string
@@ -305,9 +226,9 @@ if(typeof dojo != "undefined"){
 				currentPart.infixOper = queryParts.pop();
 				currentPart.query = currentPart.infixOper.query + " " + currentPart.query;
 				/*
-				console.debug(	"swapping out the infix", 
-								currentPart.infixOper, 
-								"and attaching it to", 
+				console.debug(	"swapping out the infix",
+								currentPart.infixOper,
+								"and attaching it to",
 								currentPart);
 				*/
 			}
@@ -316,15 +237,15 @@ if(typeof dojo != "undefined"){
 			currentPart = null;
 		}
 
-		// iterate over the query, charachter by charachter, building up a 
+		// 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 charachter (if any)
+			//		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(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;
@@ -367,7 +288,7 @@ if(typeof dojo != "undefined"){
 				// 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; 
+				inTag = x;
 			}
 
 			if(inBrackets >= 0){
@@ -375,7 +296,7 @@ if(typeof dojo != "undefined"){
 				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 existance match in the
+						// assume this is an attribute existence match in the
 						// form of [someAttributeName]
 						_cp.attr = ts(inBrackets+1, x);
 					}else{
@@ -386,19 +307,19 @@ if(typeof dojo != "undefined"){
 					var cmf = _cp.matchFor;
 					if(cmf){
 						// try to strip quotes from the matchFor value. We want
-						// [attrName=howdy] to match the same 
+						// [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. 
+					// 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. 
+					// record it along with the "=" operator.
 					var addToCc = ("|~^$*".indexOf(lc) >=0 ) ? lc : "";
 					_cp.type = addToCc+cc;
 					_cp.attr = ts(inBrackets+1, x-addToCc.length);
@@ -407,7 +328,7 @@ if(typeof dojo != "undefined"){
 				// 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 pseduo-selector rule like
+				// out if it's attached to a pseudo-selector rule like
 				// :nth-child(1)
 				if(cc == ")"){
 					if(inPseudo >= 0){
@@ -428,7 +349,7 @@ if(typeof dojo != "undefined"){
 				endAll();
 				inPseudo = x;
 			}else if(cc == "["){
-				// start of an attribute match. 
+				// start of an attribute match.
 				endAll();
 				inBrackets = x;
 				// provide a new structure for the attribute match to fill-in
@@ -442,15 +363,15 @@ if(typeof dojo != "undefined"){
 				// 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), 
+					_cp = {
+						name: ts(inPseudo+1, x),
 						value: null
 					}
 					currentPart.pseudos.push(_cp);
 				}
 				inParens = x;
 			}else if(
-				(cc == " ") && 
+				(cc == " ") &&
 				// if it's a space char and the last char is too, consume the
 				// current one without doing more work
 				(lc != cc)
@@ -470,7 +391,7 @@ if(typeof dojo != "undefined"){
 		// 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 possed, the other is used exclusively.
+		// either are not passed, the other is used exclusively.
 		if(!first){ return second; }
 		if(!second){ return first; }
 
@@ -522,7 +443,7 @@ if(typeof dojo != "undefined"){
 			}
 		},
 		"$=": function(attr, value){
-			// E[foo$="bar"]	
+			// E[foo$="bar"]
 			//		an E element whose "foo" attribute value ends exactly
 			//		with the string "bar"
 			var tval = " "+value;
@@ -532,7 +453,7 @@ if(typeof dojo != "undefined"){
 			}
 		},
 		"~=": function(attr, value){
-			// E[foo~="bar"]	
+			// 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"
@@ -598,7 +519,7 @@ if(typeof dojo != "undefined"){
 		if(!tret){ return -1; }
 		var l = tret.length;
 
-		// we calcuate the parent length as a cheap way to invalidate the
+		// 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 ){
@@ -610,11 +531,11 @@ if(typeof dojo != "undefined"){
 		root["_l"] = l;
 		ci = -1;
 		for(var te = root["firstElementChild"]||root["firstChild"]; te; te = te[_ns]){
-			if(_simpleNodeTest(te)){ 
+			if(_simpleNodeTest(te)){
 				te["_i"] = ++i;
-				if(node === te){ 
+				if(node === te){
 					// NOTE:
-					// 	shortcuting the return at this step in indexing works
+					// 	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
@@ -645,7 +566,7 @@ if(typeof dojo != "undefined"){
 		"first-child": function(){ return _lookLeft; },
 		"last-child": function(){ return _lookRight; },
 		"only-child": function(name, condition){
-			return function(node){ 
+			return function(node){
 				if(!_lookLeft(node)){ return false; }
 				if(!_lookRight(node)){ return false; }
 				return true;
@@ -676,7 +597,7 @@ if(typeof dojo != "undefined"){
 		},
 		"not": function(name, condition){
 			var p = getQueryParts(condition)[0];
-			var ignores = { el: 1 }; 
+			var ignores = { el: 1 };
 			if(p.tag != "*"){
 				ignores.tag = 1;
 			}
@@ -736,7 +657,7 @@ if(typeof dojo != "undefined"){
 		}
 	};
 
-	var defaultGetter = (d.isIE) ? function(cond){
+	var defaultGetter = (d.isIE < 9 || (dojo.isIE && dojo.isQuirks)) ? function(cond){
 		var clc = cond.toLowerCase();
 		if(clc == "class"){ cond = "className"; }
 		return function(elem){
@@ -750,7 +671,7 @@ if(typeof dojo != "undefined"){
 
 	var getSimpleFilterFunc = function(query, ignores){
 		// generates a node tester function based on the passed query part. The
-		// query part is one of the structures generatd by the query parser
+		// 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
@@ -781,7 +702,7 @@ if(typeof dojo != "undefined"){
 				if(isWildcard){
 					cname = cname.substr(0, cname.length-1);
 				}
-				// I dislike the regex thing, even if memozied in a cache, but it's VERY short
+				// 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|$)");
@@ -819,7 +740,7 @@ if(typeof dojo != "undefined"){
 
 		if(!("id" in ignores)){
 			if(query.id){
-				ff = agree(ff, function(elem){ 
+				ff = agree(ff, function(elem){
 					return (!!elem && (elem.id == query.id));
 				});
 			}
@@ -827,7 +748,7 @@ if(typeof dojo != "undefined"){
 
 		if(!ff){
 			if(!("default" in ignores)){
-				ff = yesman; 
+				ff = yesman;
 			}
 		}
 		return ff;
@@ -878,7 +799,7 @@ if(typeof dojo != "undefined"){
 					_simpleNodeTest(te) &&
 					(!bag || _isUnique(te, bag)) &&
 					(filterFunc(te, x))
-				){ 
+				){
 					ret.push(te);
 				}
 			}
@@ -920,7 +841,7 @@ if(typeof dojo != "undefined"){
 		//		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
-		//		founde, a test function is applied to weed out the ones we
+		//		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
@@ -973,7 +894,7 @@ if(typeof dojo != "undefined"){
 		var filterFunc = getSimpleFilterFunc(query, { el: 1 });
 		var qt = query.tag;
 		var wildcardTag = ("*" == qt);
-		var ecs = getDoc()["getElementsByClassName"]; 
+		var ecs = getDoc()["getElementsByClassName"];
 
 		if(!oper){
 			// if there's no infix operator, then it's a descendant query. ID
@@ -983,8 +904,8 @@ if(typeof dojo != "undefined"){
 				// 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 : 
+				filterFunc = (!query.loops && wildcardTag) ?
+					yesman :
 					getSimpleFilterFunc(query, { el: 1, id: 1 });
 
 				retFunc = function(root, arr){
@@ -999,9 +920,9 @@ if(typeof dojo != "undefined"){
 					}
 				}
 			}else if(
-				ecs && 
+				ecs &&
 				// isAlien check. Workaround for Prototype.js being totally evil/dumb.
-				/\{\s*\[native code\]\s*\}/.test(String(ecs)) && 
+				/\{\s*\[native code\]\s*\}/.test(String(ecs)) &&
 				query.classes.length &&
 				!cssCaseBug
 			){
@@ -1167,8 +1088,8 @@ if(typeof dojo != "undefined"){
 	// We need te detect the right "internal" webkit version to make this work.
 	var wk = "WebKit/";
 	var is525 = (
-		d.isWebKit && 
-		(nua.indexOf(wk) > 0) && 
+		d.isWebKit &&
+		(nua.indexOf(wk) > 0) &&
 		(parseFloat(nua.split(wk)[1]) > 528)
 	);
 
@@ -1179,7 +1100,7 @@ if(typeof dojo != "undefined"){
 
 	var qsa = "querySelectorAll";
 	var qsaAvail = (
-		!!getDoc()[qsa] && 
+		!!getDoc()[qsa] &&
 		// see #5832
 		(!d.isSafari || (d.isSafari > 3.1) || is525 )
 	);
@@ -1208,7 +1129,7 @@ if(typeof dojo != "undefined"){
 		var domCached = _queryFuncCacheDOM[query];
 		if(domCached){ return domCached; }
 
-		// TODO: 
+		// 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.
@@ -1222,11 +1143,11 @@ if(typeof dojo != "undefined"){
 			forceDOM = true;
 		}
 
-		var useQSA = ( 
+		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) && 
+			(specials.indexOf(qcz) == -1) &&
 			// IE's QSA impl sucks on pseudos
 			(!d.isIE || (query.indexOf(":") == -1)) &&
 
@@ -1239,11 +1160,11 @@ if(typeof dojo != "undefined"){
 			//		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(":contains") == -1) && (query.indexOf(":checked") == -1) &&
 			(query.indexOf("|=") == -1) // some browsers don't grok it
 		);
 
-		// TODO: 
+		// 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
@@ -1252,7 +1173,7 @@ if(typeof dojo != "undefined"){
 
 
 		if(useQSA){
-			var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ? 
+			var tq = (specials.indexOf(query.charAt(query.length-1)) >= 0) ?
 						(query + " *") : query;
 			return _queryFuncCacheQSA[query] = function(root){
 				try{
@@ -1279,9 +1200,9 @@ if(typeof dojo != "undefined"){
 		}else{
 			// DOM branch
 			var parts = query.split(/\s*,\s*/);
-			return _queryFuncCacheDOM[query] = ((parts.length < 2) ? 
+			return _queryFuncCacheDOM[query] = ((parts.length < 2) ?
 				// if not a compound query (e.g., ".foo, .bar"), cache and return a dispatcher
-				getStepQueryFunc(query) : 
+				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
@@ -1311,7 +1232,7 @@ if(typeof dojo != "undefined"){
 		}else{
 			return node.uniqueID;
 		}
-	} : 
+	} :
 	function(node){
 		return (node._uid || (node._uid = ++_zipIdx));
 	};
@@ -1320,7 +1241,7 @@ if(typeof dojo != "undefined"){
 	// 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. 
+	// the upside, it gives us a built in unique ID function.
 	var _isUnique = function(node, bag){
 		if(!bag){ return 1; }
 		var id = _nodeUID(node);
@@ -1332,7 +1253,7 @@ if(typeof dojo != "undefined"){
 	// returning a list of "uniques", hopefully in doucment order
 	var _zipIdxName = "_zipIdx";
 	var _zip = function(arr){
-		if(arr && arr.nozip){ 
+		if(arr && arr.nozip){
 			return (qlc._wrap) ? qlc._wrap(arr) : arr;
 		}
 		// var ret = new d._NodeListCtor();
@@ -1351,7 +1272,7 @@ if(typeof dojo != "undefined"){
 			var szidx = _zipIdx+"";
 			arr[0].setAttribute(_zipIdxName, szidx);
 			for(var x = 1, te; te = arr[x]; x++){
-				if(arr[x].getAttribute(_zipIdxName) != szidx){ 
+				if(arr[x].getAttribute(_zipIdxName) != szidx){
 					ret.push(te);
 				}
 				te.setAttribute(_zipIdxName, szidx);
@@ -1359,7 +1280,7 @@ if(typeof dojo != "undefined"){
 		}else if(d.isIE && arr.commentStrip){
 			try{
 				for(var x = 1, te; te = arr[x]; x++){
-					if(_isElement(te)){ 
+					if(_isElement(te)){
 						ret.push(te);
 					}
 				}
@@ -1367,7 +1288,7 @@ if(typeof dojo != "undefined"){
 		}else{
 			if(arr[0]){ arr[0][_zipIdxName] = _zipIdx; }
 			for(var x = 1, te; te = arr[x]; x++){
-				if(arr[x][_zipIdxName] != _zipIdx){ 
+				if(arr[x][_zipIdxName] != _zipIdx){
 					ret.push(te);
 				}
 				te[_zipIdxName] = _zipIdx;
@@ -1397,11 +1318,11 @@ if(typeof dojo != "undefined"){
 		//			* class selectors (e.g., `.foo`)
 		//			* node type selectors like `span`
 		//			* ` ` descendant selectors
-		//			* `>` child element selectors 
+		//			* `>` child element selectors
 		//			* `#foo` style ID selectors
 		//			* `*` universal selector
-		//			* `~`, the immediately preceeded-by sibling selector
-		//			* `+`, the preceeded-by sibling selector
+		//			* `~`, the preceded-by sibling selector
+		//			* `+`, the immediately preceded-by sibling selector
 		//			* attribute queries:
 		//			|	* `[foo]` attribute presence selector
 		//			|	* `[foo='bar']` attribute value exact match
@@ -1422,14 +1343,14 @@ if(typeof dojo != "undefined"){
 		//		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 resaonable for a programmatic node querying engine to
+		//		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:
@@ -1438,10 +1359,10 @@ if(typeof dojo != "undefined"){
 		//			|	* `: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
@@ -1551,12 +1472,12 @@ if(typeof dojo != "undefined"){
 		// 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") || 
+		caseSensitive = (root.contentType && root.contentType=="application/xml") ||
 						(d.isOpera && (root.doctype || od.toString() == "[object XMLDocument]")) ||
-						(!!od) && 
+						(!!od) &&
 						(d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
 
-		// NOTE: 
+		// 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.
@@ -1573,24 +1494,120 @@ if(typeof dojo != "undefined"){
 	// FIXME: need to add infrastructure for post-filtering pseudos, ala :last
 	d.query.pseudos = pseudos;
 
-	// one-off function for filtering a NodeList based on a simple selector
-	d._filterQueryResult = function(nodeList, simpleFilter){
-		var tmpNodeList = new d._NodeListCtor();
-		var filterFunc = getSimpleFilterFunc(getQueryParts(simpleFilter)[0]);
+	// 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;
 	}
-})(this["queryPortability"]||this["acme"]||dojo);
+};//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);
-if(!dojo["query"]){
-	(function(){
+(function() {
+  function qdef() {
+    if (dojo.query) {
+      return;
+    }
 		var ctr = 0;
 		// QSA-only for webkit mobile. Welcome to the future.
 		dojo.query = function(query, root){
@@ -1632,8 +1649,18 @@ if(!dojo["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);
 */
diff --git a/dojo/_base/window.js b/dojo/_base/window.js
index 5705614..7908969 100644
--- a/dojo/_base/window.js
+++ b/dojo/_base/window.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo._base.window");
+define("dojo/_base/window", ["dojo/lib/kernel"], function(dojo){
 
 /*=====
 dojo.doc = {
@@ -25,7 +25,7 @@ dojo.body = function(){
 	// Note: document.body is not defined for a strict xhtml document
 	// Would like to memoize this, but dojo.doc can change vi dojo.withDoc().
 	return dojo.doc.body || dojo.doc.getElementsByTagName("body")[0]; // Node
-}
+};
 
 dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocument){
 	// summary:
@@ -38,9 +38,9 @@ dojo.setContext = function(/*Object*/globalObject, /*DocumentElement*/globalDocu
 	dojo.doc = globalDocument;
 };
 
-dojo.withGlobal = function(	/*Object*/globalObject, 
-							/*Function*/callback, 
-							/*Object?*/thisObject, 
+dojo.withGlobal = function(	/*Object*/globalObject,
+							/*Function*/callback,
+							/*Object?*/thisObject,
 							/*Array?*/cbArguments){
 	// summary:
 	//		Invoke callback with globalObject as dojo.global and
@@ -59,11 +59,11 @@ dojo.withGlobal = function(	/*Object*/globalObject,
 	}finally{
 		dojo.global = oldGlob;
 	}
-}
+};
 
-dojo.withDoc = function(	/*DocumentElement*/documentObject, 
-							/*Function*/callback, 
-							/*Object?*/thisObject, 
+dojo.withDoc = function(	/*DocumentElement*/documentObject,
+							/*Function*/callback,
+							/*Object?*/thisObject,
 							/*Array?*/cbArguments){
 	// summary:
 	//		Invoke callback with documentObject as dojo.doc.
@@ -94,4 +94,6 @@ dojo.withDoc = function(	/*DocumentElement*/documentObject,
 		dojo.isQuirks = oldQ;
 	}
 };
-	
+
+return dojo;
+});
diff --git a/dojo/_base/xhr.js b/dojo/_base/xhr.js
index b797cf0..fc3c04e 100644
--- a/dojo/_base/xhr.js
+++ b/dojo/_base/xhr.js
@@ -1,8 +1,4 @@
-dojo.provide("dojo._base.xhr");
-dojo.require("dojo._base.Deferred");
-dojo.require("dojo._base.json");
-dojo.require("dojo._base.lang");
-dojo.require("dojo._base.query");
+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(){
@@ -46,7 +42,7 @@ dojo.require("dojo._base.query");
 			var type = (item.type||"").toLowerCase();
 			if(_in && type && !item.disabled){
 				if(type == "radio" || type == "checkbox"){
-					if(item.checked){ ret = item.value }
+					if(item.checked){ ret = item.value; }
 				}else if(item.multiple){
 					ret = [];
 					_d.query("option", item).forEach(function(opt){
@@ -60,7 +56,7 @@ dojo.require("dojo._base.query");
 			}
 		}
 		return ret; // Object
-	}
+	};
 
 	dojo.formToObject = function(/*DOMNode||String*/ formNode){
 		// summary:
@@ -87,7 +83,7 @@ dojo.require("dojo._base.query");
 		//		yields this object structure as the result of a call to
 		//		formToObject():
 		//
-		//		|	{ 
+		//		|	{
 		//		|		blah: "blah",
 		//		|		multi: [
 		//		|			"thud",
@@ -108,7 +104,7 @@ dojo.require("dojo._base.query");
 			}
 		});
 		return ret; // Object
-	}
+	};
 
 	dojo.objectToQuery = function(/*Object*/ map){
 		//	summary:
@@ -117,7 +113,7 @@ dojo.require("dojo._base.query");
 		//	example:
 		//		this object:
 		//
-		//		|	{ 
+		//		|	{
 		//		|		blah: "blah",
 		//		|		multi: [
 		//		|			"thud",
@@ -126,7 +122,7 @@ dojo.require("dojo._base.query");
 		//		|	};
 		//
 		//	yields the following query string:
-		//	
+		//
 		//	|	"blah=blah&multi=thud&multi=thonk"
 
 		// FIXME: need to implement encodeAscii!!
@@ -147,21 +143,21 @@ dojo.require("dojo._base.query");
 			}
 		}
 		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:
@@ -172,7 +168,7 @@ dojo.require("dojo._base.query");
 		//		This string:
 		//
 		//	|		"foo=bar&foo=baz&thinger=%20spaces%20=blah&zonk=blarg&"
-		//		
+		//
 		//		results in this object structure:
 		//
 		//	|		{
@@ -180,7 +176,7 @@ dojo.require("dojo._base.query");
 		//	|			thinger: " spaces =blah",
 		//	|			zonk: "blarg"
 		//	|		}
-		//	
+		//
 		//		Note that spaces and other urlencoded entities are correctly
 		//		handled.
 
@@ -205,7 +201,7 @@ dojo.require("dojo._base.query");
 			}
 		});
 		return ret; // Object
-	}
+	};
 
 	// 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
@@ -215,7 +211,7 @@ dojo.require("dojo._base.query");
 
 	// MOW: remove dojo._contentHandlers alias in 2.0
 	var handlers = _d._contentHandlers = dojo.contentHandlers = {
-		// summary: 
+		// summary:
 		//		A map of availble XHR transport handle types. Name matches the
 		//		`handleAs` attribute passed to XHR calls.
 		//
@@ -223,41 +219,41 @@ dojo.require("dojo._base.query");
 		//		A map of availble XHR transport handle types. Name matches the
 		//		`handleAs` attribute passed to XHR calls. Each contentHandler is
 		//		called, passing the xhr object for manipulation. The return value
-		//		from the contentHandler will be passed to the `load` or `handle` 
-		//		functions defined in the original xhr call. 
-		//		
+		//		from the contentHandler will be passed to the `load` or `handle`
+		//		functions defined in the original xhr call.
+		//
 		// example:
 		//		Creating a custom content-handler:
 		//	|	dojo.contentHandlers.makeCaps = function(xhr){
 		//	|		return xhr.responseText.toUpperCase();
 		//	|	}
 		//	|	// and later:
-		//	|	dojo.xhrGet({ 
+		//	|	dojo.xhrGet({
 		//	|		url:"foo.txt",
 		//	|		handleAs:"makeCaps",
 		//	|		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; 
+			return xhr.responseText;
 		},
 		json: function(xhr){
 			// summary: A contentHandler which returns a JavaScript object created from the response data
 			return _d.fromJson(xhr.responseText || null);
 		},
-		"json-comment-filtered": function(xhr){ 
-			// summary: A contentHandler which expects comment-filtered JSON. 
-			// description: 
-			//		A contentHandler which expects comment-filtered JSON. 
+		"json-comment-filtered": function(xhr){
+			// summary: A contentHandler which expects comment-filtered JSON.
+			// description:
+			//		A contentHandler which expects comment-filtered JSON.
 			//		the json-comment-filtered option was implemented to prevent
 			//		"JavaScript Hijacking", but it is less secure than standard JSON. Use
 			//		standard JSON instead. JSON prefixing can be used to subvert hijacking.
-			//		
+			//
 			//		Will throw a notice suggesting to use application/json mimetype, as
 			//		json-commenting can introduce security issues. To decrease the chances of hijacking,
-			//		use the standard `json` contentHandler, and prefix your "JSON" with: {}&& 
-			//		
+			//		use the standard `json` contentHandler, and prefix your "JSON" with: {}&&
+			//
 			//		use djConfig.useCommentedJson = true to turn off the notice
 			if(!dojo.config.useCommentedJson){
 				console.warn("Consider using the standard mimetype:application/json."
@@ -275,7 +271,7 @@ dojo.require("dojo._base.query");
 			}
 			return _d.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?
@@ -288,7 +284,7 @@ dojo.require("dojo._base.query");
 			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 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{
@@ -304,7 +300,7 @@ dojo.require("dojo._base.query");
 			return result; // DOMDocument
 		},
 		"json-comment-optional": function(xhr){
-			// summary: A contentHandler which checks the presence of comment-filtered JSON and 
+			// summary: A contentHandler which checks the presence of comment-filtered JSON and
 			//		alternates between the `json` and `json-comment-filtered` contentHandlers.
 			if(xhr.responseText && /^[^{\[]*\/\*/.test(xhr.responseText)){
 				return handlers["json-comment-filtered"](xhr);
@@ -336,7 +332,7 @@ dojo.require("dojo._base.query");
 		//	handleAs: String?
 		//		Acceptable values depend on the type of IO
 		//		transport (see specific IO calls for more information).
-		// 	rawBody: String?
+		//	rawBody: String?
 		// 		Sets the raw body for an HTTP request. If this is used, then the content
 		// 		property is ignored. This is mostly useful for HTTP methods that have
 		// 		a body to their requests, like PUT or POST. This property can be used instead
@@ -481,7 +477,7 @@ dojo.require("dojo._base.query");
 			/*Function*/canceller,
 			/*Function*/okHandler,
 			/*Function*/errHandler){
-		//	summary: 
+		//	summary:
 		//		sets up the Deferred and ioArgs property on the Deferred so it
 		//		can be used in an io call.
 		//	args:
@@ -497,19 +493,19 @@ dojo.require("dojo._base.query");
 		//		object returned from this function.
 		//	errHandler:
 		//		The first error callback to be registered with Deferred. It has the opportunity
-		//		to do cleanup on an error. It will receive two arguments: error (the 
+		//		to do cleanup on an error. It will receive two arguments: error (the
 		//		Error object) and dfd, the Deferred object returned from this function.
 
 		var ioArgs = {args: args, url: args.url};
 
 		//Get values from form if requestd.
 		var formObject = null;
-		if(args.form){ 
+		if(args.form){
 			var form = _d.byId(args.form);
-			//IE requires going through getAttributeNode instead of just getAttribute in some form cases, 
+			//IE requires going through getAttributeNode instead of just getAttribute in some form cases,
 			//so use it for all.  See #2844
 			var actnNode = form.getAttributeNode("action");
-			ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null); 
+			ioArgs.url = ioArgs.url || (actnNode ? actnNode.value : null);
 			formObject = _d.formToObject(form);
 		}
 
@@ -582,7 +578,7 @@ dojo.require("dojo._base.query");
 		// FIXME: need to wire up the xhr object's abort method to something
 		// analagous in the Deferred
 		return d;
-	}
+	};
 
 	var _deferredCancel = function(/*Deferred*/dfd){
 		// summary: canceller function for dojo._ioSetArgs call.
@@ -599,13 +595,13 @@ dojo.require("dojo._base.query");
 			err.dojoType="cancel";
 		}
 		return err;
-	}
+	};
 	var _deferredOk = function(/*Deferred*/dfd){
 		// summary: okHandler function for dojo._ioSetArgs call.
 
 		var ret = handlers[dfd.ioArgs.handleAs](dfd.ioArgs.xhr);
 		return ret === undefined ? null : ret;
-	}
+	};
 	var _deferError = function(/*Error*/error, /*Deferred*/dfd){
 		// summary: errHandler function for dojo._ioSetArgs call.
 
@@ -613,7 +609,7 @@ dojo.require("dojo._base.query");
 			console.error(error);
 		}
 		return error;
-	}
+	};
 
 	// avoid setting a timer per request. It degrades performance on IE
 	// something fierece if we don't use unified loops.
@@ -637,7 +633,7 @@ dojo.require("dojo._base.query");
 	};
 
 	var _watchInFlight = function(){
-		//summary: 
+		//summary:
 		//		internal method that checks each inflight XMLHttpRequest to see
 		//		if it has completed or if the timeout situation applies.
 		
@@ -652,7 +648,7 @@ dojo.require("dojo._base.query");
 				var dfd = tif.dfd;
 				var func = function(){
 					if(!dfd || dfd.canceled || !tif.validCheck(dfd)){
-						_inFlight.splice(i--, 1); 
+						_inFlight.splice(i--, 1);
 						_pubCount -= 1;
 					}else if(tif.ioCheck(dfd)){
 						_inFlight.splice(i--, 1);
@@ -690,7 +686,7 @@ dojo.require("dojo._base.query");
 			_inFlightIntvl = null;
 			return;
 		}
-	}
+	};
 
 	dojo._ioCancelAll = function(){
 		//summary: Cancels all pending IO requests, regardless of IO type
@@ -702,7 +698,7 @@ dojo.require("dojo._base.query");
 				}catch(e){/*squelch*/}
 			});
 		}catch(e){/*squelch*/}
-	}
+	};
 
 	//Automatically call cancel all io calls on unload
 	//in IE for trac issue #2357.
@@ -727,10 +723,10 @@ dojo.require("dojo._base.query");
 			_pubCount += 1;
 			_d.publish("/dojo/io/send", [dfd]);
 		}
-	}
+	};
 
 	_d._ioWatch = function(dfd, validCheck, ioCheck, resHandle){
-		// summary: 
+		// summary:
 		//		Watches the io request represented by dfd to see if it completes.
 		// dfd: Deferred
 		//		The Deferred object to watch.
@@ -760,16 +756,16 @@ dojo.require("dojo._base.query");
 		if(args.sync){
 			_watchInFlight();
 		}
-	}
+	};
 
 	var _defaultContentType = "application/x-www-form-urlencoded";
 
 	var _validCheck = function(/*Deferred*/dfd){
 		return dfd.ioArgs.xhr.readyState; //boolean
-	}
+	};
 	var _ioCheck = function(/*Deferred*/dfd){
 		return 4 == dfd.ioArgs.xhr.readyState; //boolean
-	}
+	};
 	var _resHandle = function(/*Deferred*/dfd){
 		var xhr = dfd.ioArgs.xhr;
 		if(_d._isDocumentOk(xhr)){
@@ -780,7 +776,7 @@ dojo.require("dojo._base.query");
 			err.responseText = xhr.responseText;
 			dfd.errback(err);
 		}
-	}
+	};
 
 	dojo._ioAddQueryToUrl = function(/*dojo.__IoCallbackArgs*/ioArgs){
 		//summary: Adds query params discovered by the io deferred construction to the URL.
@@ -788,8 +784,8 @@ dojo.require("dojo._base.query");
 		if(ioArgs.query.length){
 			ioArgs.url += (ioArgs.url.indexOf("?") == -1 ? "?" : "&") + ioArgs.query;
 			ioArgs.query = null;
-		}		
-	}
+		}
+	};
 
 	/*=====
 	dojo.declare("dojo.__XhrArgs", dojo.__IoArgs, {
@@ -890,13 +886,13 @@ dojo.require("dojo._base.query");
 		_d._ioWatch(dfd, _validCheck, _ioCheck, _resHandle);
 		xhr = null;
 		return dfd; // dojo.Deferred
-	}
+	};
 
 	dojo.xhrGet = function(/*dojo.__XhrArgs*/ args){
-		//	summary: 
+		//	summary:
 		//		Sends an HTTP GET request to the server.
 		return _d.xhr("GET", args); // dojo.Deferred
-	}
+	};
 
 	dojo.rawXhrPost = dojo.xhrPost = function(/*dojo.__XhrArgs*/ args){
 		//	summary:
@@ -905,7 +901,7 @@ dojo.require("dojo._base.query");
 		//	postData:
 		//		String. Send raw data in the body of the POST request.
 		return _d.xhr("POST", args, true); // dojo.Deferred
-	}
+	};
 
 	dojo.rawXhrPut = dojo.xhrPut = function(/*dojo.__XhrArgs*/ args){
 		//	summary:
@@ -914,13 +910,13 @@ dojo.require("dojo._base.query");
 		//	putData:
 		//		String. Send raw data in the body of the PUT request.
 		return _d.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
-	}
+	};
 
 	/*
 	dojo.wrapForm = function(formNode){
@@ -936,3 +932,6 @@ dojo.require("dojo._base.query");
 //>>excludeStart("webkitMobile", kwArgs.webkitMobile);
 })();
 //>>excludeEnd("webkitMobile");
+
+return dojo.xhr;
+});
diff --git a/dojo/_firebug/firebug.js b/dojo/_firebug/firebug.js
index 77efaf4..dad6329 100644
--- a/dojo/_firebug/firebug.js
+++ b/dojo/_firebug/firebug.js
@@ -1,11 +1,11 @@
-dojo.provide("dojo._firebug.firebug");
+define("dojo/_firebug/firebug", ["dojo"], function(dojo) {
 	
 dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/ removal){
-	// summary: 
+	// summary:
 	//		Log a debug message to indicate that a behavior has been
 	//		deprecated.
 	// extra: Text to append to the message.
-	// removal: 
+	// removal:
 	//		Text to indicate when in the future the behavior will be removed.
 	var message = "DEPRECATED: " + behaviour;
 	if(extra){ message += " " + extra; }
@@ -15,16 +15,16 @@ dojo.deprecated = function(/*String*/ behaviour, /*String?*/ extra, /*String?*/
 
 dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	// summary: Marks code as experimental.
-	// description: 
+	// 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: 
+	// moduleName:
 	//		The name of a module, or the name of a module file or a specific
 	//		function
-	// extra: 
+	// extra:
 	//		some additional message for the user
 	// example:
 	//	|	dojo.experimental("dojo.data.Result");
@@ -40,10 +40,10 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	// description:
 	//		Opens a console for logging, debugging, and error messages.
 	//		Contains partial functionality to Firebug. See function list below.
-	//	NOTE: 
+	//	NOTE:
 	//			Firebug is a Firefox extension created by Joe Hewitt (see license). You do not need Dojo to run Firebug.
 	//			Firebug Lite is included in Dojo by permission from Joe Hewitt
-	//			If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug 
+	//			If you are new to Firebug, or used to the Dojo 0.4 dojo.debug, you can learn Firebug
 	//				functionality by reading the function comments below or visiting http://www.getfirebug.com/docs.html
 	//	NOTE:
 	//		To test Firebug Lite in Firefox:
@@ -71,13 +71,13 @@ 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];
-			var n = "_"+calls[i]
+			var n = "_"+calls[i];
 			console[n] = console[m];
 			console[m] = (function(){
 				var type = n;
 				return function(){
 					console[type](Array.prototype.slice.call(arguments).join(" "));
-				}
+				};
 			})();
 		}
 		// clear the console on load. This is more than a convenience - too many logs crashes it.
@@ -87,8 +87,8 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	
 	if(
 		!dojo.isFF &&								// Firefox has Firebug
-		(!dojo.isChrome || dojo.isChrome < 3) &&
-		(!dojo.isSafari || dojo.isSafari < 4) &&	// Safari 4 has a console
+		!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
@@ -99,17 +99,17 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	
 	// don't build firebug in iframes
 	try{
-		if(window != window.parent){ 
+		if(window != window.parent){
 			// but if we've got a parent logger, connect to it
 			if(window.parent["console"]){
 				window.console = window.parent.console;
 			}
-			return; 
+			return;
 		}
 	}catch(e){/*squelch*/}
 
 	// ***************************************************************************
-	// Placing these variables before the functions that use them to avoid a 
+	// 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
@@ -146,38 +146,38 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	window.console = {
 		_connects: [],
 		log: function(){
-			// summary: 
+			// summary:
 			//		Sends arguments to console.
 			logFormatted(arguments, "");
 		},
 		
 		debug: function(){
-			// summary: 
+			// summary:
 			//		Sends arguments to console. Missing finctionality to show script line of trace.
 			logFormatted(arguments, "debug");
 		},
 		
 		info: function(){
-			// summary: 
+			// summary:
 			//		Sends arguments to console, highlighted with (I) icon.
 			logFormatted(arguments, "info");
 		},
 		
 		warn: function(){
-			// summary: 
+			// summary:
 			//		Sends warning arguments to console, highlighted with (!) icon and blue style.
 			logFormatted(arguments, "warning");
 		},
 		
 		error: function(){
-			// summary: 
+			// 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: 
+			// summary:
 			//		Tests for true. Throws exception if false.
 			if(!truth){
 				var args = [];
@@ -198,7 +198,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		},
 		
 		dirxml: function(node){
-			// summary: 
+			// summary:
 			//
 			var html = [];
 			appendNode(node, html);
@@ -206,20 +206,20 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		},
 		
 		group: function(){
-			// summary: 
-			//		collects log messages into a group, starting with this call and ending with 
+			// 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: 
+			// summary:
 			//		Closes group. See above
 			logRow(arguments, "", popGroup);
 		},
 		
 		time: function(name){
-			// summary: 
+			// summary:
 			//		Starts timers assigned to name given in argument. Timer stops and displays on timeEnd(title);
 			//	example:
 			//	|	console.time("load");
@@ -230,7 +230,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		},
 		
 		timeEnd: function(name){
-			// summary: 
+			// summary:
 			//		See above.
 			if(name in timeMap){
 				var delta = (new Date()).getTime() - timeMap[name];
@@ -240,7 +240,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		},
 		
 		count: function(name){
-			// summary: 
+			// summary:
 			//		Not supported
 			if(!countMap[name]) countMap[name] = 0;
 			countMap[name]++;
@@ -255,20 +255,20 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				var func = f.toString();
 				var args=[];
 				for (var a = 0; a < f.arguments.length; a++) {
-					args.push(f.arguments[a])
+					args.push(f.arguments[a]);
 				}
 				if(f.arguments.length){
-					console.dir({"function":func, "arguments":args});	
+					console.dir({"function":func, "arguments":args});
 				}else{
 					console.dir({"function":func});
 				}
 				
 				f = f.caller;
-			}	
+			}
 		},
 		
 		profile: function(){
-			// summary: 
+			// summary:
 			//		Not supported
 			this.warn(["profile() not supported."]);
 		},
@@ -276,24 +276,24 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		profileEnd: function(){ },
 
 		clear: function(){
-			// summary: 
+			// summary:
 			//		Clears message console. Do not call this directly
 			if(consoleBody){
 				while(consoleBody.childNodes.length){
-					dojo.destroy(consoleBody.firstChild);	
+					dojo.destroy(consoleBody.firstChild);
 				}
 			}
 			dojo.forEach(this._connects,dojo.disconnect);
 		},
 
-		open: function(){ 
-			// summary: 
+		open: function(){
+			// summary:
 			//		Opens message console. Do not call this directly
-			toggleConsole(true); 
+			toggleConsole(true);
 		},
 		
 		close: function(){
-			// summary: 
+			// summary:
 			//		Closes message console. Do not call this directly
 			if(frameVisible){
 				toggleConsole();
@@ -334,7 +334,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			setTimeout(function(){
 				_inspectionClickConnection = dojo.connect(document, "click", function(evt){
 					document.body.style.cursor = "";
-					_inspectionEnabled = !_inspectionEnabled;																  
+					_inspectionEnabled = !_inspectionEnabled;
 					dojo.disconnect(_inspectionClickConnection);
 					// console._restoreBorder();
 				});
@@ -348,7 +348,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			console._restoreBorder();
 		},
 		openConsole:function(){
-			// summary: 
+			// summary:
 			//		Closes object inspector and opens message console. Do not call this directly
 			consoleBody.style.display = "block";
 			consoleDomInspector.style.display = "none";
@@ -374,7 +374,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				}
 			}
 		}
-	}
+	};
 
 	// ***************************************************************************
 
@@ -439,7 +439,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 			}
 			
 
-		window.onFirebugResize = function(){ 
+		window.onFirebugResize = function(){
 			
 			//resize the height of the console log body
 			layout(getViewport().h);
@@ -511,12 +511,12 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		}
 		consoleFrame.className += " firebug";
 		consoleFrame.style.height = containerHeight;
-		consoleFrame.style.display = (frameVisible ? "block" : "none");	  
+		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 = 
+		consoleFrame.innerHTML =
 			  '<div id="firebugToolbar">'
 			+ '  <ul id="fireBugTabs" class="tabs">'
 			
@@ -589,8 +589,8 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	
 	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" : 
+		var height = h ?
+			h  - (tHeight + commandLine.offsetHeight +25 + (h*.01)) + "px" :
 			(consoleFrame.offsetHeight - tHeight - commandLine.offsetHeight) + "px";
 		
 		consoleBody.style.top = tHeight + "px";
@@ -601,7 +601,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		consoleDomInspector.style.top = tHeight + "px";
 		commandLine.style.bottom = 0;
 		
-		dojo.addOnWindowUnload(clearFrame)
+		dojo.addOnWindowUnload(clearFrame);
 	}
 	
 	function logRow(message, className, handler){
@@ -746,7 +746,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	function parseFormat(format){
 		var parts = [];
 
-		var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;	  
+		var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
 		var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
 
 		for(var m = reg.exec(format); m; m = reg.exec(format)){
@@ -891,7 +891,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 					appendNode(child, html);
 				}
 					
-				html.push('</div><div class="objectBox-element"></<span class="nodeTag">', 
+				html.push('</div><div class="objectBox-element"></<span class="nodeTag">',
 					node.nodeName.toLowerCase(), '></span></div>');
 			}else{
 				html.push('/></div>');
@@ -924,7 +924,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		if(document.all){
 			event.cancelBubble = true;
 		}else{
-			event.stopPropagation();		
+			event.stopPropagation();
 		}
 	}
 
@@ -933,7 +933,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 		var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);
 
 		var html = [
-			'<span class="errorMessage">', msg, '</span>', 
+			'<span class="errorMessage">', msg, '</span>',
 			'<div class="objectBox-sourceLink">', fileName, ' (line ', lineNo, ')</div>'
 		];
 
@@ -956,7 +956,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 				toggleConsole();
 			}else if(
 				(ekc == keys.NUMPAD_ENTER || ekc == 76) &&
-				event.shiftKey && 
+				event.shiftKey &&
 				(event.metaKey || event.ctrlKey)
 			){
 				focusCommandLine();
@@ -1063,7 +1063,7 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 	function objectLength(o){
 		var cnt = 0;
 		for(var nm in o){
-			cnt++	
+			cnt++;
 		}
 		return cnt;
 	}
@@ -1213,3 +1213,5 @@ dojo.experimental = function(/* String */ moduleName, /* String? */ extra){
 
 })();
 
+return dojo;
+});
diff --git a/dojo/back.js b/dojo/back.js
index c8d0a29..ee0c9e7 100644
--- a/dojo/back.js
+++ b/dojo/back.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.back");
+define("dojo/back", ["dojo"], function(dojo) {
+dojo.getObject("back", true, dojo);
 
 /*=====
 dojo.back = {
@@ -7,29 +8,23 @@ dojo.back = {
 =====*/
 
 
-(function(){ 
-	var back = dojo.back;
+(function(){
+	var back = dojo.back,
 
 	// everyone deals with encoding the hash slightly differently
 
-	function getHash(){ 
+	getHash= back.getHash= function(){
 		var h = window.location.hash;
 		if(h.charAt(0) == "#"){ h = h.substring(1); }
-		return dojo.isMozilla ? h : decodeURIComponent(h); 
-	}
+		return dojo.isMozilla ? h : decodeURIComponent(h);
+	},
 	
-	function setHash(h){
+	setHash= back.setHash= function(h){
 		if(!h){ h = ""; }
 		window.location.hash = encodeURIComponent(h);
 		historyCounter = history.length;
-	}
-	
-	// if we're in the test for these methods, expose them on dojo.back. ok'd with alex.
-	if(dojo.exists("tests.back-hash")){
-		back.getHash = getHash;
-		back.setHash = setHash;		
-	}
-	
+	};
+
 	var initialHref = (typeof(window) !== "undefined") ? window.location.href : "";
 	var initialHash = (typeof(window) !== "undefined") ? getHash() : "";
 	var initialState = null;
@@ -141,18 +136,11 @@ dojo.back = {
 					return;
 				}
 			}
-			
-			if(dojo.isSafari && dojo.isSafari < 3){
-				var hisLen = history.length;
-				if(hisLen > historyCounter) handleForwardButton();
-				else if(hisLen < historyCounter) handleBackButton();
-			  historyCounter = hisLen;
-			}
 		}
 	};
 	
 	back.init = function(){
-		//summary: Initializes the undo stack. This must be called from a <script> 
+		//summary: Initializes the undo stack. This must be called from a <script>
 		//         block that lives inside the <body> tag to prevent bugs on IE.
 		// description:
 		// 		Only call this method before the page's DOM is finished loading. Otherwise
@@ -170,7 +158,7 @@ dojo.back = {
 	};
 
 	back.setInitialState = function(/*Object*/args){
-		//summary: 
+		//summary:
 		//		Sets the state object and back callback for the very first page
 		//		that is loaded.
 		//description:
@@ -204,14 +192,14 @@ dojo.back = {
 	=====*/
 
 	back.addToHistory = function(/*dojo.__backArgs*/ args){
-		//	summary: 
-		//		adds a state object (args) to the history list. 
+		//	summary:
+		//		adds a state object (args) to the history list.
 		//	description:
 		//		To support getting back button notifications, the object
 		//		argument should implement a function called either "back",
 		//		"backButton", or "handle". The string "back" will be passed as
 		//		the first and only argument to this callback.
-		//	
+		//
 		//		To support getting forward button notifications, the object
 		//		argument should implement a function called either "forward",
 		//		"forwardButton", or "handle". The string "forward" will be
@@ -238,7 +226,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.
@@ -252,10 +240,10 @@ dojo.back = {
 		//	previous hash value, but to the last full page load. This suggests
 		//	that the iframe is the correct way to capture the back button in
 		//	these cases.
-		//	Don't test this page using local disk for MSIE. MSIE will not create 
-		//	a history list for iframe_history.html if served from a file: URL. 
-		//	The XML served back from the XHR tests will also not be properly 
-		//	created if served from local disk. Serve the test pages from a web 
+		//	Don't test this page using local disk for MSIE. MSIE will not create
+		//	a history list for iframe_history.html if served from a file: URL.
+		//	The XML served back from the XHR tests will also not be properly
+		//	created if served from local disk. Serve the test pages from a web
 		//	server to test in that browser.
 		//	IE 6.0:
 		//	same behavior as IE 5.5 SP2
@@ -267,7 +255,7 @@ dojo.back = {
 		//If addToHistory is called, then that means we prune the
 		//forward stack -- the user went back, then wanted to
 		//start a new forward path.
-		forwardStack = []; 
+		forwardStack = [];
 
 		var hash = null;
 		var url = null;
@@ -301,9 +289,9 @@ dojo.back = {
 			}
 
 			changingUrl = true;
-			setTimeout(function() { 
-					setHash(hash); 
-					changingUrl = false; 					
+			setTimeout(function() {
+					setHash(hash);
+					changingUrl = false;
 				}, 1);
 			bookmarkAnchor.href = hash;
 			
@@ -371,10 +359,10 @@ dojo.back = {
 	};
 
 	back._iframeLoaded = function(evt, ifrLoc){
-		//summary: 
+		//summary:
 		//		private method. Do not call this directly.
 		var query = getUrlQuery(ifrLoc.href);
-		if(query == null){ 
+		if(query == null){
 			// alert("iframeLoaded");
 			// we hit the end of the history, so we should go back
 			if(historyStack.length == 1){
@@ -397,3 +385,6 @@ dojo.back = {
 		}
 	};
  })();
+
+return dojo.back;
+});
diff --git a/dojo/behavior.js b/dojo/behavior.js
index 34c5e54..3bc022b 100644
--- a/dojo/behavior.js
+++ b/dojo/behavior.js
@@ -1,22 +1,22 @@
-dojo.provide("dojo.behavior");
+define("dojo/behavior", ["dojo"], function(dojo) {
 
 dojo.behavior = new function(){
-	// summary: 
+	// summary:
 	//		Utility for unobtrusive/progressive event binding, DOM traversal,
 	//		and manipulation.
 	//
 	// description:
-	//		
-	//		A very simple, lightweight mechanism for applying code to 
-	//		existing documents, based around `dojo.query` (CSS3 selectors) for node selection, 
+	//
+	//		A very simple, lightweight mechanism for applying code to
+	//		existing documents, based around `dojo.query` (CSS3 selectors) for node selection,
 	//		and a simple two-command API: `dojo.behavior.add()` and `dojo.behavior.apply()`;
-	//	
-	//		Behaviors apply to a given page, and are registered following the syntax 
+	//
+	//		Behaviors apply to a given page, and are registered following the syntax
 	//		options described by `dojo.behavior.add` to match nodes to actions, or "behaviors".
-	//		
+	//
 	//		Added behaviors are applied to the current DOM when .apply() is called,
-	//		matching only new nodes found since .apply() was last called. 
-	//		
+	//		matching only new nodes found since .apply() was last called.
+	//
 	function arrIn(obj, name){
 		if(!obj[name]){ obj[name] = []; }
 		return obj[name];
@@ -42,7 +42,7 @@ dojo.behavior = new function(){
 	this.add = function(/* Object */behaviorObj){
 		//	summary:
 		//		Add the specified behavior to the list of behaviors, ignoring existing
-		//		matches. 
+		//		matches.
 		//
 		//	description:
 		//		Add the specified behavior to the list of behaviors which will
@@ -50,26 +50,26 @@ dojo.behavior = new function(){
 		//		an already existing behavior do not replace the previous rules,
 		//		but are instead additive. New nodes which match the rule will
 		//		have all add()-ed behaviors applied to them when matched.
-		//		
+		//
 		//		The "found" method is a generalized handler that's called as soon
 		//		as the node matches the selector. Rules for values that follow also
 		//		apply to the "found" key.
-		//		
-		//		The "on*" handlers are attached with `dojo.connect()`, using the 
+		//
+		//		The "on*" handlers are attached with `dojo.connect()`, using the
 		//		matching node
-		//		
+		//
 		//		If the value corresponding to the ID key is a function and not a
 		//		list, it's treated as though it was the value of "found".
 		//
-		// 		dojo.behavior.add() can be called any number of times before 
+		// 		dojo.behavior.add() can be called any number of times before
 		//		the DOM is ready. `dojo.behavior.apply()` is called automatically
 		//		by `dojo.addOnLoad`, though can be called to re-apply previously added
 		//		behaviors anytime the DOM changes.
 		//
 		//		There are a variety of formats permitted in the behaviorObject
-		//	
+		//
 		//	example:
-		//		Simple list of properties. "found" is special. "Found" is assumed if 
+		//		Simple list of properties. "found" is special. "Found" is assumed if
 		//		no property object for a given selector, and property is a function.
 		//
 		//	|	dojo.behavior.add({
@@ -86,7 +86,7 @@ dojo.behavior = new function(){
 		//	|		}
 		//	|	});
 		//
-		//	example: 
+		//	example:
 		//		 If property is a string, a dojo.publish will be issued on the channel:
 		//
 		//	|	dojo.behavior.add({
@@ -97,15 +97,15 @@ dojo.behavior = new function(){
 		//	|		}
 		//	|	});
 		//	|	dojo.subscribe("/got/newAnchor", function(node){
-		//	|		// handle node finding when dojo.behavior.apply() is called, 
+		//	|		// handle node finding when dojo.behavior.apply() is called,
 		//	|		// provided a newly matched node is found.
 		//	|	});
 		//
 		//	example:
-		//		Scoping can be accomplished by passing an object as a property to 
+		//		Scoping can be accomplished by passing an object as a property to
 		//		a connection handle (on*):
-		//	
-		//	|	dojo.behavior.add({ 
+		//
+		//	|	dojo.behavior.add({
 		//	|		 	"#id": {
 		//	|				// like calling dojo.hitch(foo,"bar"). execute foo.bar() in scope of foo
 		//	|				"onmouseenter": { targetObj: foo, targetFunc: "bar" },
@@ -113,7 +113,7 @@ dojo.behavior = new function(){
 		//	|			}
 		//	|	});
 		//
-		//	example: 
+		//	example:
 		//		Bahaviors match on CSS3 Selectors, powered by dojo.query. Example selectors:
 		//
 		//	|	dojo.behavior.add({
@@ -121,31 +121,31 @@ dojo.behavior = new function(){
 		//	|		"#id4 > *": function(element){
 		//	|			// ...
 		//	|		},
-		//	|		
+		//	|
 		//	|		// match the first child node that's an element
 		//	|		"#id4 > :first-child": { ... },
-		//	|		
+		//	|
 		//	|		// match the last child node that's an element
 		//	|		"#id4 > :last-child":  { ... },
-		//	|		
+		//	|
 		//	|		// all elements of type tagname
 		//	|		"tagname": {
 		//	|			// ...
 		//	|		},
-		//	|		
+		//	|
 		//	|		"tagname1 tagname2 tagname3": {
 		//	|			// ...
 		//	|		},
-		//	|		
+		//	|
 		//	|		".classname": {
 		//	|			// ...
 		//	|		},
-		//	|		
+		//	|
 		//	|		"tagname.classname": {
 		//	|			// ...
 		//	|		}
 		//	|	});
-		//   
+		//
 
 		var tmpObj = {};
 		forIn(behaviorObj, this, function(behavior, name){
@@ -162,7 +162,7 @@ dojo.behavior = new function(){
 				arrIn(cversion, ruleName).push(rule);
 			});
 		});
-	}
+	};
 
 	var _applyToNode = function(node, action, ruleSetName){
 		if(dojo.isString(action)){
@@ -180,33 +180,33 @@ dojo.behavior = new function(){
 				dojo.connect(node, ruleSetName, action);
 			}
 		}
-	}
+	};
 
 	this.apply = function(){
 		// summary:
 		//		Applies all currently registered behaviors to the document.
-		// 
+		//
 		// description:
 		//		Applies all currently registered behaviors to the document,
 		//		taking care to ensure that only incremental updates are made
-		//		since the last time add() or apply() were called. 
-		//	
+		//		since the last time add() or apply() were called.
+		//
 		//		If new matching nodes have been added, all rules in a behavior will be
 		//		applied to that node. For previously matched nodes, only
 		//		behaviors which have been added since the last call to apply()
 		//		will be added to the nodes.
 		//
-		//		apply() is called once automatically by `dojo.addOnLoad`, so 
+		//		apply() is called once automatically by `dojo.addOnLoad`, so
 		//		registering behaviors with `dojo.behavior.add` before the DOM is
 		//		ready is acceptable, provided the dojo.behavior module is ready.
-		//		
-		//		Calling appy() manually after manipulating the DOM is required 
+		//
+		//		Calling appy() manually after manipulating the DOM is required
 		//		to rescan the DOM and apply newly .add()ed behaviors, or to match
-		//		nodes that match existing behaviors when those nodes are added to 
+		//		nodes that match existing behaviors when those nodes are added to
 		//		the DOM.
-		//		
+		//
 		forIn(this._behaviors, function(tBehavior, id){
-			dojo.query(id).forEach( 
+			dojo.query(id).forEach(
 				function(elem){
 					var runFrom = 0;
 					var bid = "_dj_behavior_"+tBehavior.id;
@@ -233,7 +233,10 @@ dojo.behavior = new function(){
 				}
 			);
 		});
-	}
-}
+	};
+};
 
 dojo.addOnLoad(dojo.behavior, "apply");
+
+return dojo.behavior;
+});
diff --git a/dojo/cache.js b/dojo/cache.js
index 94dd2b5..6a9fd4f 100644
--- a/dojo/cache.js
+++ b/dojo/cache.js
@@ -1,13 +1,12 @@
-dojo.provide("dojo.cache");
+define("dojo/cache", ["dojo"], function(dojo){
 
 /*=====
-dojo.cache = { 
+dojo.cache = {
 	// summary:
 	// 		A way to cache string content that is fetchable via `dojo.moduleUrl`.
 };
 =====*/
 
-(function(){
 	var cache = {};
 	dojo.cache = function(/*String||Object*/module, /*String*/url, /*String||Object?*/value){
 		// summary:
@@ -46,7 +45,7 @@ dojo.cache = {
 		//		|	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 
+		// 		 (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
@@ -96,7 +95,7 @@ dojo.cache = {
 	};
 
 	dojo.cache._sanitize = function(/*String*/val){
-		// summary: 
+		// 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.
@@ -113,4 +112,5 @@ dojo.cache = {
 		}
 		return val; //String
 	};
-})();
+	return dojo.cache;
+});
diff --git a/dojo/cldr/monetary.js b/dojo/cldr/monetary.js
index adc68de..ffb6cb7 100644
--- a/dojo/cldr/monetary.js
+++ b/dojo/cldr/monetary.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.cldr.monetary");
+define("dojo/cldr/monetary", ["dojo"], function(dojo) {
+dojo.getObject("cldr.monetary", true, dojo);
 
 dojo.cldr.monetary.getData = function(/*String*/code){
 // summary: A mapping of currency code to currency-specific formatting information. Returns a unique object with properties: places, round.
@@ -24,3 +25,6 @@ dojo.cldr.monetary.getData = function(/*String*/code){
 
 	return {places: places, round: round}; // Object
 };
+
+return dojo.cldr.monetary;
+});
diff --git a/dojo/cldr/nls/ar/buddhist.js b/dojo/cldr/nls/ar/buddhist.js
new file mode 100644
index 0000000..67b0f65
--- /dev/null
+++ b/dojo/cldr/nls/ar/buddhist.js
@@ -0,0 +1,115 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M‏/y G",
+	"dateFormatItem-yQ": "yyyy Q",
+	"dayPeriods-format-wide-pm": "م",
+	"eraNames": [
+		"التقويم البوذي"
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-MMdd": "dd‏/MM",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"ي",
+		"ف",
+		"م",
+		"أ",
+		"و",
+		"ن",
+		"ل",
+		"غ",
+		"س",
+		"ك",
+		"ب",
+		"د"
+	],
+	"dayPeriods-format-wide-am": "ص",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "zzzz h:mm:ss a",
+	"dateFormatItem-Ed": "E، d",
+	"dateFormatItem-yMMM": "MMM y G",
+	"days-standAlone-narrow": [
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
+		"س"
+	],
+	"eraAbbr": [
+		"التقويم البوذي"
+	],
+	"dateFormatItem-yyyyMM": "MM‏/y G",
+	"dateFormatItem-yyyyMMMM": "MMMM، y G",
+	"dateFormat-long": "d MMMM، y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "dd‏/MM‏/y G",
+	"dateFormatItem-yMd": "d/‏M/‏y G",
+	"dateFormatItem-yMMMM": "MMMM y G",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-standAlone-narrow": [
+		"١",
+		"٢",
+		"٣",
+		"٤"
+	],
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormatItem-MMMd": "d MMM",
+	"timeFormat-long": "z h:mm:ss a",
+	"timeFormat-short": "h:mm a",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"days-format-abbr": [
+		"أحد",
+		"إثنين",
+		"ثلاثاء",
+		"أربعاء",
+		"خميس",
+		"جمعة",
+		"سبت"
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yMMMd": "d MMMM y G",
+	"dateFormat-short": "d‏/M‏/y G",
+	"dateFormatItem-yMMMEd": "EEE، d MMMM y G",
+	"dateFormat-full": "EEEE، d MMMM، y G",
+	"dateFormatItem-Md": "d/‏M",
+	"dateFormatItem-yMEd": "EEE، d/‏M/‏y G",
+	"months-format-wide": [
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
+		"ديسمبر"
+	],
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
+		"الربع الرابع"
+	],
+	"eraNarrow": [
+		"التقويم البوذي"
+	],
+	"days-format-wide": [
+		"الأحد",
+		"الإثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
+		"السبت"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/currency.js b/dojo/cldr/nls/ar/currency.js
index 7351b83..6ea7d6b 100644
--- a/dojo/cldr/nls/ar/currency.js
+++ b/dojo/cldr/nls/ar/currency.js
@@ -1,14 +1,16 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"دولار أسترالي",
-	CAD_displayName:"دولار كندي",
-	CHF_displayName:"فرنك سويسري",
-	CNY_displayName:"يوان صيني",
-	CNY_symbol:"ي.ص",
-	EUR_displayName:"يورو",
-	GBP_displayName:"جنيه إسترليني",
-	HKD_displayName:"دولار هونج كونج",
-	JPY_displayName:"ين ياباني",
-	USD_displayName:"دولار أمريكي"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "دولار هونج كونج",
+	"CHF_displayName": "فرنك سويسري",
+	"CAD_displayName": "دولار كندي",
+	"CNY_displayName": "يوان صيني",
+	"AUD_displayName": "دولار أسترالي",
+	"JPY_displayName": "ين ياباني",
+	"USD_displayName": "دولار أمريكي",
+	"CNY_symbol": "ي.ص",
+	"GBP_displayName": "جنيه إسترليني",
+	"EUR_displayName": "يورو"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/gregorian.js b/dojo/cldr/nls/ar/gregorian.js
index 4ab460d..5c6eb62 100644
--- a/dojo/cldr/nls/ar/gregorian.js
+++ b/dojo/cldr/nls/ar/gregorian.js
@@ -1,235 +1,240 @@
-({
-	"dateFormatItem-yM": "M‏/yyyy", 
-	"field-dayperiod": "ص/م", 
-	"dayPeriods-format-wide-pm": "م", 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"field-minute": "الدقائق", 
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M‏/yyyy",
+	"field-dayperiod": "ص/م",
+	"dateFormatItem-yQ": "yyyy Q",
+	"dayPeriods-format-wide-pm": "م",
+	"field-minute": "الدقائق",
 	"eraNames": [
-		"قبل الميلاد", 
+		"قبل الميلاد",
 		"ميلادي"
-	], 
-	"dateFormatItem-MMMEd": "E d MMM", 
-	"field-day-relative+-1": "أمس", 
-	"dateFormatItem-MMdd": "dd‏/MM", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"field-weekday": "اليوم", 
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
+	"field-day-relative+-1": "أمس",
+	"field-weekday": "اليوم",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-MMdd": "dd‏/MM",
 	"days-standAlone-wide": [
-		"الأحد", 
-		"الإثنين", 
-		"الثلاثاء", 
-		"الأربعاء", 
-		"الخميس", 
-		"الجمعة", 
+		"الأحد",
+		"الإثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
 		"السبت"
-	], 
-	"dateFormatItem-MMM": "LLL", 
+	],
+	"dateFormatItem-MMM": "LLL",
 	"months-standAlone-narrow": [
-		"ي", 
-		"ف", 
-		"م", 
-		"أ", 
-		"و", 
-		"ن", 
-		"ل", 
-		"غ", 
-		"س", 
-		"ك", 
-		"ب", 
+		"ي",
+		"ف",
+		"م",
+		"أ",
+		"و",
+		"ن",
+		"ل",
+		"غ",
+		"س",
+		"ك",
+		"ب",
 		"د"
-	], 
-	"dayPeriods-format-wide-am": "ص", 
-	"field-era": "العصر", 
-	"field-hour": "الساعات", 
+	],
+	"field-era": "العصر",
+	"field-hour": "الساعات",
+	"dayPeriods-format-wide-am": "ص",
 	"quarters-standAlone-abbr": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
-	"dateFormatItem-y": "y", 
-	"timeFormat-full": "zzzz h:mm:ss a", 
+	],
+	"dateFormatItem-y": "y",
+	"timeFormat-full": "zzzz h:mm:ss a",
 	"months-standAlone-abbr": [
-		"يناير", 
-		"فبراير", 
-		"مارس", 
-		"أبريل", 
-		"مايو", 
-		"يونيو", 
-		"يوليو", 
-		"أغسطس", 
-		"سبتمبر", 
-		"أكتوبر", 
-		"نوفمبر", 
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
 		"ديسمبر"
-	], 
-	"dateFormatItem-yMMM": "MMM y", 
-	"field-day-relative+0": "اليوم", 
+	],
+	"dateFormatItem-Ed": "E، d",
+	"dateFormatItem-yMMM": "MMM y",
+	"field-day-relative+0": "اليوم",
+	"field-day-relative+1": "غدًا",
 	"days-standAlone-narrow": [
-		"ح", 
-		"ن", 
-		"ث", 
-		"ر", 
-		"خ", 
-		"ج", 
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
 		"س"
-	], 
-	"field-day-relative+1": "غدًا", 
+	],
 	"eraAbbr": [
-		"ق.م", 
+		"ق.م",
 		"م"
-	], 
-	"field-day-relative+2": "بعد الغد", 
-	"dateFormatItem-yyyyMM": "MM‏/yyyy", 
-	"dateFormatItem-yyyyMMMM": "MMMM، y", 
-	"dateFormat-long": "d MMMM، y", 
-	"timeFormat-medium": "h:mm:ss a", 
-	"field-zone": "التوقيت", 
-	"dateFormatItem-Hm": "HH:mm", 
-	"dateFormat-medium": "dd‏/MM‏/yyyy", 
+	],
+	"field-day-relative+2": "بعد الغد",
+	"dateFormatItem-yyyyMM": "MM‏/yyyy",
+	"dateFormatItem-yyyyMMMM": "MMMM، y",
+	"dateFormat-long": "d MMMM، y",
+	"timeFormat-medium": "h:mm:ss a",
+	"field-zone": "التوقيت",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "dd‏/MM‏/yyyy",
 	"quarters-standAlone-wide": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
-	"dateFormatItem-yMMMM": "MMMM y", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-year": "السنة", 
+	],
+	"dateFormatItem-yMMMM": "MMMM y",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "السنة",
 	"quarters-standAlone-narrow": [
-		"١", 
-		"٢", 
-		"٣", 
+		"١",
+		"٢",
+		"٣",
 		"٤"
-	], 
-	"field-week": "الأسبوع", 
+	],
+	"field-week": "الأسبوع",
 	"months-standAlone-wide": [
-		"يناير", 
-		"فبراير", 
-		"مارس", 
-		"أبريل", 
-		"مايو", 
-		"يونيو", 
-		"يوليو", 
-		"أغسطس", 
-		"سبتمبر", 
-		"أكتوبر", 
-		"نوفمبر", 
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
 		"ديسمبر"
-	], 
-	"dateFormatItem-MMMMEd": "E d MMMM", 
-	"dateFormatItem-MMMd": "d MMM", 
+	],
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormatItem-MMMd": "d MMM",
 	"quarters-format-narrow": [
-		"١", 
-		"٢", 
-		"٣", 
+		"١",
+		"٢",
+		"٣",
 		"٤"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-long": "z h:mm:ss a", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-long": "z h:mm:ss a",
 	"months-format-abbr": [
-		"يناير", 
-		"فبراير", 
-		"مارس", 
-		"أبريل", 
-		"مايو", 
-		"يونيو", 
-		"يوليو", 
-		"أغسطس", 
-		"سبتمبر", 
-		"أكتوبر", 
-		"نوفمبر", 
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
 		"ديسمبر"
-	], 
-	"timeFormat-short": "h:mm a", 
-	"field-month": "الشهر", 
-	"dateFormatItem-MMMMd": "d MMMM", 
+	],
+	"timeFormat-short": "h:mm a",
+	"field-month": "الشهر",
+	"dateFormatItem-MMMMd": "d MMMM",
 	"quarters-format-abbr": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
+	],
 	"days-format-abbr": [
-		"أحد", 
-		"إثنين", 
-		"ثلاثاء", 
-		"أربعاء", 
-		"خميس", 
-		"جمعة", 
+		"أحد",
+		"إثنين",
+		"ثلاثاء",
+		"أربعاء",
+		"خميس",
+		"جمعة",
 		"سبت"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-format-narrow": [
-		"ح", 
-		"ن", 
-		"ث", 
-		"ر", 
-		"خ", 
-		"ج", 
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
 		"س"
-	], 
-	"field-second": "الثواني", 
-	"field-day": "يوم", 
+	],
+	"field-second": "الثواني",
+	"field-day": "يوم",
 	"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", 
+	],
+	"dateFormat-short": "d‏/M‏/yyyy",
+	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
+	"dateFormat-full": "EEEE، d MMMM، y",
+	"dateFormatItem-Md": "d/‏M",
+	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy",
 	"months-format-wide": [
-		"يناير", 
-		"فبراير", 
-		"مارس", 
-		"أبريل", 
-		"مايو", 
-		"يونيو", 
-		"يوليو", 
-		"أغسطس", 
-		"سبتمبر", 
-		"أكتوبر", 
-		"نوفمبر", 
+		"يناير",
+		"فبراير",
+		"مارس",
+		"أبريل",
+		"مايو",
+		"يونيو",
+		"يوليو",
+		"أغسطس",
+		"سبتمبر",
+		"أكتوبر",
+		"نوفمبر",
 		"ديسمبر"
-	], 
-	"dateFormatItem-d": "d", 
+	],
+	"dateFormatItem-d": "d",
 	"quarters-format-wide": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
+	],
 	"days-format-wide": [
-		"الأحد", 
-		"الإثنين", 
-		"الثلاثاء", 
-		"الأربعاء", 
-		"الخميس", 
-		"الجمعة", 
+		"الأحد",
+		"الإثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
 		"السبت"
-	], 
+	],
 	"eraNarrow": [
-		"ق.م", 
+		"ق.م",
 		"م"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/hebrew.js b/dojo/cldr/nls/ar/hebrew.js
index 5cf62de..156edb5 100644
--- a/dojo/cldr/nls/ar/hebrew.js
+++ b/dojo/cldr/nls/ar/hebrew.js
@@ -1,120 +1,124 @@
-({
-	"dateFormat-medium": "dd‏/MM‏/yyyy", 
-	"dateFormatItem-MMMEd": "E d MMM", 
-	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy", 
-	"timeFormat-full": "zzzz h:mm:ss a", 
-	"dateFormatItem-Md": "d/‏M", 
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd‏/MM‏/yyyy",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy",
+	"timeFormat-full": "zzzz h:mm:ss a",
+	"dateFormatItem-Md": "d/‏M",
 	"months-standAlone-wide": [
-		"تشري", 
-		"مرحشوان", 
-		"كيسلو", 
-		"طيفت", 
-		"شباط", 
-		"آذار الأول", 
-		"آذار", 
-		"نيسان", 
-		"أيار", 
-		"سيفان", 
-		"تموز", 
-		"آب", 
+		"تشري",
+		"مرحشوان",
+		"كيسلو",
+		"طيفت",
+		"شباط",
+		"آذار الأول",
+		"آذار",
+		"نيسان",
+		"أيار",
+		"سيفان",
+		"تموز",
+		"آب",
 		"أيلول"
-	], 
-	"months-format-wide-leap": "آذار الثاني", 
+	],
+	"months-format-wide-leap": "آذار الثاني",
 	"days-standAlone-narrow": [
-		"ح", 
-		"ن", 
-		"ث", 
-		"ر", 
-		"خ", 
-		"ج", 
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
 		"س"
-	], 
-	"dayPeriods-format-wide-pm": "م", 
+	],
+	"dayPeriods-format-wide-pm": "م",
 	"months-standAlone-abbr": [
-		"تشري", 
-		"مرحشوان", 
-		"كيسلو", 
-		"طيفت", 
-		"شباط", 
-		"آذار الأول", 
-		"آذار", 
-		"نيسان", 
-		"أيار", 
-		"سيفان", 
-		"تموز", 
-		"آب", 
+		"تشري",
+		"مرحشوان",
+		"كيسلو",
+		"طيفت",
+		"شباط",
+		"آذار الأول",
+		"آذار",
+		"نيسان",
+		"أيار",
+		"سيفان",
+		"تموز",
+		"آب",
 		"أيلول"
-	], 
-	"dayPeriods-format-wide-am": "ص", 
+	],
+	"dayPeriods-format-wide-am": "ص",
 	"quarters-standAlone-narrow": [
-		"١", 
-		"٢", 
-		"٣", 
+		"١",
+		"٢",
+		"٣",
 		"٤"
-	], 
-	"timeFormat-medium": "h:mm:ss a", 
-	"dateFormat-long": "d MMMM، y", 
-	"dateFormat-short": "d‏/M‏/yyyy", 
-	"dateFormatItem-yMMMEd": "EEE، d MMMM y", 
+	],
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormat-long": "d MMMM، y",
+	"dateFormat-short": "d‏/M‏/yyyy",
+	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
 	"months-format-wide": [
-		"تشري", 
-		"مرحشوان", 
-		"كيسلو", 
-		"طيفت", 
-		"شباط", 
-		"آذار الأول", 
-		"آذار", 
-		"نيسان", 
-		"أيار", 
-		"سيفان", 
-		"تموز", 
-		"آب", 
+		"تشري",
+		"مرحشوان",
+		"كيسلو",
+		"طيفت",
+		"شباط",
+		"آذار الأول",
+		"آذار",
+		"نيسان",
+		"أيار",
+		"سيفان",
+		"تموز",
+		"آب",
 		"أيلول"
-	], 
-	"dateFormatItem-yM": "M‏/yyyy", 
-	"timeFormat-short": "h:mm a", 
+	],
+	"dateFormatItem-yM": "M‏/yyyy",
+	"timeFormat-short": "h:mm a",
 	"months-format-abbr": [
-		"تشري", 
-		"مرحشوان", 
-		"كيسلو", 
-		"طيفت", 
-		"شباط", 
-		"آذار الأول", 
-		"آذار", 
-		"نيسان", 
-		"أيار", 
-		"سيفان", 
-		"تموز", 
-		"آب", 
+		"تشري",
+		"مرحشوان",
+		"كيسلو",
+		"طيفت",
+		"شباط",
+		"آذار الأول",
+		"آذار",
+		"نيسان",
+		"أيار",
+		"سيفان",
+		"تموز",
+		"آب",
 		"أيلول"
-	], 
-	"timeFormat-long": "z h:mm:ss a", 
+	],
+	"timeFormat-long": "z h:mm:ss a",
 	"days-format-wide": [
-		"الأحد", 
-		"الإثنين", 
-		"الثلاثاء", 
-		"الأربعاء", 
-		"الخميس", 
-		"الجمعة", 
+		"الأحد",
+		"الإثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
 		"السبت"
-	], 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dateFormatItem-yMMM": "MMM y", 
+	],
+	"dateFormatItem-yQ": "yyyy Q",
+	"dateFormatItem-yMMM": "MMM y",
 	"quarters-format-wide": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
-	"dateFormat-full": "EEEE، d MMMM، y", 
-	"dateFormatItem-MMMd": "d MMM", 
+	],
+	"dateFormat-full": "EEEE، d MMMM، y",
+	"dateFormatItem-MMMd": "d MMM",
 	"days-format-abbr": [
-		"أحد", 
-		"إثنين", 
-		"ثلاثاء", 
-		"أربعاء", 
-		"خميس", 
-		"جمعة", 
+		"أحد",
+		"إثنين",
+		"ثلاثاء",
+		"أربعاء",
+		"خميس",
+		"جمعة",
 		"سبت"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/islamic-civil.js b/dojo/cldr/nls/ar/islamic-civil.js
index 61c2692..3eb14e5 100644
--- a/dojo/cldr/nls/ar/islamic-civil.js
+++ b/dojo/cldr/nls/ar/islamic-civil.js
@@ -1,221 +1,225 @@
+define(
+//begin v1.x content
 ({
-	"dateFormatItem-yM": "M‏/yyyy", 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dayPeriods-format-wide-pm": "م", 
+	"dateFormatItem-yM": "M‏/yyyy",
+	"dateFormatItem-yQ": "yyyy Q",
+	"dayPeriods-format-wide-pm": "م",
 	"eraNames": [
 		"ه"
-	], 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
 	"days-standAlone-wide": [
-		"الأحد", 
-		"الإثنين", 
-		"الثلاثاء", 
-		"الأربعاء", 
-		"الخميس", 
-		"الجمعة", 
+		"الأحد",
+		"الإثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
 		"السبت"
-	], 
-	"patternChars": "GanjkHmsSEDFwWxhKzAeugXZvcL", 
+	],
+	"patternChars": "GanjkHmsSEDFwWxhKzAeugXZvcL",
 	"months-standAlone-narrow": [
-		"م", 
-		"ص", 
-		"ر", 
-		"ر", 
-		"ج", 
-		"ج", 
-		"ر", 
-		"ش", 
-		"ر", 
-		"ش", 
-		"ذ", 
+		"م",
+		"ص",
+		"ر",
+		"ر",
+		"ج",
+		"ج",
+		"ر",
+		"ش",
+		"ر",
+		"ش",
+		"ذ",
 		"ذ"
-	], 
-	"dayPeriods-format-wide-am": "ص", 
-	"dayPeriods-am-format-wide": "ص", 
+	],
+	"dayPeriods-format-wide-am": "ص",
+	"dayPeriods-am-format-wide": "ص",
 	"quarters-standAlone-abbr": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
-	"timeFormat-full": "zzzz h:mm:ss a", 
-	"dayPeriods-pm-format-wide": "م", 
+	],
+	"timeFormat-full": "zzzz h:mm:ss a",
+	"dayPeriods-pm-format-wide": "م",
 	"dayPeriods-format-wide": [
-		"ص", 
+		"ص",
 		"م"
-	], 
+	],
 	"months-standAlone-abbr": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
-	"dateFormatItem-yMMM": "MMM y", 
+	],
+	"dateFormatItem-yMMM": "MMM y",
 	"days-standAlone-narrow": [
-		"ح", 
-		"ن", 
-		"ث", 
-		"ر", 
-		"خ", 
-		"ج", 
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
 		"س"
-	], 
+	],
 	"eraAbbr": [
 		"ه"
-	], 
-	"dateFormat-long": "d MMMM، y", 
-	"timeFormat-medium": "h:mm:ss a", 
-	"dateFormat-medium": "dd‏/MM‏/yyyy", 
+	],
+	"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", 
+	],
+	"dateFormatItem-yMMMM": "MMMM y",
 	"quarters-standAlone-narrow": [
-		"١", 
-		"٢", 
-		"٣", 
+		"١",
+		"٢",
+		"٣",
 		"٤"
-	], 
+	],
 	"months-standAlone-wide": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
-	"dateFormatItem-MMMMEd": "E d MMMM", 
-	"dateFormatItem-MMMd": "d MMM", 
+	],
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormatItem-MMMd": "d MMM",
 	"quarters-format-narrow": [
-		"١", 
-		"٢", 
-		"٣", 
+		"١",
+		"٢",
+		"٣",
 		"٤"
-	], 
-	"timeFormat-long": "z h:mm:ss a", 
+	],
+	"timeFormat-long": "z h:mm:ss a",
 	"months-format-abbr": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
-	"timeFormat-short": "h:mm a", 
-	"dateFormatItem-MMMMd": "d MMMM", 
+	],
+	"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", 
+	],
+	"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": [
 		"ه"
 	]
-})
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojo/cldr/nls/ar/islamic.js b/dojo/cldr/nls/ar/islamic.js
index 3fc24d9..4a67656 100644
--- a/dojo/cldr/nls/ar/islamic.js
+++ b/dojo/cldr/nls/ar/islamic.js
@@ -1,152 +1,156 @@
-({
-	"dateFormat-medium": "dd‏/MM‏/yyyy", 
-	"dateFormatItem-MMMEd": "E d MMM", 
-	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy", 
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd‏/MM‏/yyyy",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-yMEd": "EEE، d/‏M/‏yyyy",
 	"eraNarrow": [
 		"هـ"
-	], 
+	],
 	"months-format-narrow": [
-		"م", 
-		"ص", 
-		"ر", 
-		"ر", 
-		"ج", 
-		"ج", 
-		"ر", 
-		"ش", 
-		"ر", 
-		"ش", 
-		"ذ", 
+		"م",
+		"ص",
+		"ر",
+		"ر",
+		"ج",
+		"ج",
+		"ر",
+		"ش",
+		"ر",
+		"ش",
+		"ذ",
 		"ذ"
-	], 
-	"timeFormat-full": "zzzz h:mm:ss a", 
-	"dateFormatItem-Md": "d/‏M", 
+	],
+	"timeFormat-full": "zzzz h:mm:ss a",
+	"dateFormatItem-Md": "d/‏M",
 	"months-standAlone-narrow": [
-		"م", 
-		"ص", 
-		"ر", 
-		"ر", 
-		"ج", 
-		"ج", 
-		"ر", 
-		"ش", 
-		"ر", 
-		"ش", 
-		"ذ", 
+		"م",
+		"ص",
+		"ر",
+		"ر",
+		"ج",
+		"ج",
+		"ر",
+		"ش",
+		"ر",
+		"ش",
+		"ذ",
 		"ذ"
-	], 
+	],
 	"months-standAlone-wide": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
+	],
 	"eraNames": [
 		"هـ"
-	], 
+	],
 	"days-standAlone-narrow": [
-		"ح", 
-		"ن", 
-		"ث", 
-		"ر", 
-		"خ", 
-		"ج", 
+		"ح",
+		"ن",
+		"ث",
+		"ر",
+		"خ",
+		"ج",
 		"س"
-	], 
-	"dayPeriods-format-wide-pm": "م", 
+	],
+	"dayPeriods-format-wide-pm": "م",
 	"months-standAlone-abbr": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
-	"dayPeriods-format-wide-am": "ص", 
+	],
+	"dayPeriods-format-wide-am": "ص",
 	"quarters-standAlone-narrow": [
-		"١", 
-		"٢", 
-		"٣", 
+		"١",
+		"٢",
+		"٣",
 		"٤"
-	], 
-	"timeFormat-medium": "h:mm:ss a", 
-	"dateFormat-long": "d MMMM، y", 
-	"dateFormat-short": "d‏/M‏/yyyy", 
-	"dateFormatItem-yMMMEd": "EEE، d MMMM y", 
+	],
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormat-long": "d MMMM، y",
+	"dateFormat-short": "d‏/M‏/yyyy",
+	"dateFormatItem-yMMMEd": "EEE، d MMMM y",
 	"months-format-wide": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
-	"dateFormatItem-yM": "M‏/yyyy", 
-	"timeFormat-short": "h:mm a", 
+	],
+	"dateFormatItem-yM": "M‏/yyyy",
+	"timeFormat-short": "h:mm a",
 	"months-format-abbr": [
-		"محرم", 
-		"صفر", 
-		"ربيع الأول", 
-		"ربيع الآخر", 
-		"جمادى الأولى", 
-		"جمادى الآخرة", 
-		"رجب", 
-		"شعبان", 
-		"رمضان", 
-		"شوال", 
-		"ذو القعدة", 
+		"محرم",
+		"صفر",
+		"ربيع الأول",
+		"ربيع الآخر",
+		"جمادى الأولى",
+		"جمادى الآخرة",
+		"رجب",
+		"شعبان",
+		"رمضان",
+		"شوال",
+		"ذو القعدة",
 		"ذو الحجة"
-	], 
+	],
 	"eraAbbr": [
 		"هـ"
-	], 
-	"timeFormat-long": "z h:mm:ss a", 
+	],
+	"timeFormat-long": "z h:mm:ss a",
 	"days-format-wide": [
-		"الأحد", 
-		"الإثنين", 
-		"الثلاثاء", 
-		"الأربعاء", 
-		"الخميس", 
-		"الجمعة", 
+		"الأحد",
+		"الإثنين",
+		"الثلاثاء",
+		"الأربعاء",
+		"الخميس",
+		"الجمعة",
 		"السبت"
-	], 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dateFormatItem-yMMM": "MMM y", 
+	],
+	"dateFormatItem-yQ": "yyyy Q",
+	"dateFormatItem-yMMM": "MMM y",
 	"quarters-format-wide": [
-		"الربع الأول", 
-		"الربع الثاني", 
-		"الربع الثالث", 
+		"الربع الأول",
+		"الربع الثاني",
+		"الربع الثالث",
 		"الربع الرابع"
-	], 
-	"dateFormat-full": "EEEE، d MMMM، y", 
-	"dateFormatItem-MMMd": "d MMM", 
+	],
+	"dateFormat-full": "EEEE، d MMMM، y",
+	"dateFormatItem-MMMd": "d MMM",
 	"days-format-abbr": [
-		"أحد", 
-		"إثنين", 
-		"ثلاثاء", 
-		"أربعاء", 
-		"خميس", 
-		"جمعة", 
+		"أحد",
+		"إثنين",
+		"ثلاثاء",
+		"أربعاء",
+		"خميس",
+		"جمعة",
 		"سبت"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ar/number.js b/dojo/cldr/nls/ar/number.js
index abfaca3..9c1f41f 100644
--- a/dojo/cldr/nls/ar/number.js
+++ b/dojo/cldr/nls/ar/number.js
@@ -1,25 +1,18 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'decimal':"٫",
-	'group':".",
-	'group':"٬",
-	'list':";",
-	'list':"؛",
-	'percentSign':"%",
-	'percentSign':"٪",
-	'nativeZeroDigit':"0",
-	'nativeZeroDigit':"٠",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'exponential':"اس",
-	'perMille':"‰",
-	'perMille':"؉",
-	'infinity':"∞",
-	'nan':"NaN",
-	'nan':"ليس رقم",
-	'decimalFormat':"#,##0.###;#,##0.###-",
-	'currencyFormat':"¤ #,##0.00;¤ #,##0.00-"
-})
+define(
+//begin v1.x content
+{
+	"group": "٬",
+	"percentSign": "٪",
+	"exponential": "اس",
+	"list": "؛",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": "٫",
+	"nan": "ليس رقم",
+	"perMille": "؉",
+	"decimalFormat": "#,##0.###;#,##0.###-",
+	"currencyFormat": "¤ #,##0.00;¤ #,##0.00-",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/buddhist.js b/dojo/cldr/nls/buddhist.js
index 3369f45..d5d193a 100644
--- a/dojo/cldr/nls/buddhist.js
+++ b/dojo/cldr/nls/buddhist.js
@@ -1,236 +1,267 @@
-({
+define({ root:
+
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
+	],
 	"quarters-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, y-M-d", 
-	"dateFormatItem-MMMEd": "E MMM d", 
+	],
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, y-M-d",
+	"dateFormatItem-MMMEd": "E MMM d",
 	"eraNarrow": [
 		"BE"
-	], 
-	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}", 
-	"dateFormat-long": "MMMM d, y G", 
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "MMMM d, y G",
 	"months-format-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dateFormatItem-EEEd": "d EEE", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE, MMMM d, y G", 
-	"dateFormatItem-Md": "M-d", 
-	"dayPeriods-format-abbr-am": "AM", 
-	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})", 
-	"dateFormatItem-yM": "y-M", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-EEEd": "d EEE",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"dateFormatItem-Md": "M-d",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dateFormatItem-yM": "y-M",
 	"months-standAlone-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"dateFormatItem-yMMM": "y MMM", 
-	"dateFormatItem-yQ": "y Q", 
-	"dateTimeFormats-appendItem-Era": "{0} {1}", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"dateFormatItem-yMMM": "y MMM",
+	"dateFormatItem-yQ": "y Q",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
 	"months-format-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})", 
-	"dateFormatItem-H": "HH", 
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"eraAbbr": [
 		"BE"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateFormatItem-h": "h a", 
-	"dateTimeFormat-long": "{1} {0}", 
-	"dayPeriods-format-narrow-am": "AM", 
-	"dateFormatItem-MMMd": "MMM d", 
-	"dateFormatItem-MEd": "E, M-d", 
-	"dateTimeFormat-full": "{1} {0}", 
+	],
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "E, M-d",
+	"dateTimeFormat-full": "{1} {0}",
 	"days-format-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})", 
-	"dateFormatItem-y": "y", 
+	],
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"dateFormatItem-hm": "h:mm a", 
-	"dateTimeFormats-appendItem-Year": "{0} {1}", 
-	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})", 
-	"dayPeriods-format-abbr-pm": "PM", 
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"eraNames": [
 		"BE"
-	], 
+	],
 	"days-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"days-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})", 
-	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})", 
-	"dateFormat-short": "M/d/yyyy", 
-	"dateFormatItem-yMMMEd": "EEE, y MMM d", 
-	"dateTimeFormats-appendItem-Timezone": "{0} {1}", 
-	"dateFormat-medium": "MMM d, y G", 
-	"dayPeriods-format-narrow-pm": "PM", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "M/d/yyyy",
+	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"dateFormat-medium": "MMM d, y G",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+,
+	"ar": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ro": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/currency.js b/dojo/cldr/nls/ca/currency.js
index cc8ec4d..bfce5de 100644
--- a/dojo/cldr/nls/ca/currency.js
+++ b/dojo/cldr/nls/ca/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"dòlar australià",
-	CAD_displayName:"dòlar canadenc",
-	CHF_displayName:"franc suís",
-	CNY_displayName:"iuan renmimbi xinès",
-	EUR_displayName:"euro",
-	GBP_displayName:"lliura esterlina britànica",
-	HKD_displayName:"dòlar de Hong Kong",
-	JPY_displayName:"ien japonès",
-	USD_displayName:"dòlar dels Estats Units"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "dòlar de Hong Kong",
+	"CHF_displayName": "franc suís",
+	"CAD_displayName": "dòlar canadenc",
+	"CNY_displayName": "iuan renmimbi xinès",
+	"AUD_displayName": "dòlar australià",
+	"JPY_displayName": "ien japonès",
+	"USD_displayName": "dòlar dels Estats Units",
+	"GBP_displayName": "lliura esterlina britànica",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/gregorian.js b/dojo/cldr/nls/ca/gregorian.js
index b0bcfc6..c84fc3a 100644
--- a/dojo/cldr/nls/ca/gregorian.js
+++ b/dojo/cldr/nls/ca/gregorian.js
@@ -1,231 +1,235 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"g", 
-		"f", 
-		"m", 
-		"a", 
-		"m", 
-		"j", 
-		"j", 
-		"a", 
-		"s", 
-		"o", 
-		"n", 
+		"g",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
 		"d"
-	], 
-	"field-weekday": "dia de la setmana", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "E d/M/yyyy", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"field-weekday": "dia de la setmana",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "E d/M/yyyy",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"aC", 
+		"aC",
 		"dC"
-	], 
-	"dateFormat-long": "d MMMM 'de' y", 
+	],
+	"dateFormat-long": "d MMMM 'de' y",
 	"months-format-wide": [
-		"de gener", 
-		"de febrer", 
-		"de març", 
-		"d’abril", 
-		"de maig", 
-		"de juny", 
-		"de juliol", 
-		"d’agost", 
-		"de setembre", 
-		"d’octubre", 
-		"de novembre", 
+		"de gener",
+		"de febrer",
+		"de març",
+		"d’abril",
+		"de maig",
+		"de juny",
+		"de juliol",
+		"d’agost",
+		"de setembre",
+		"d’octubre",
+		"de novembre",
 		"de desembre"
-	], 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dayPeriods-format-wide-pm": "p.m.", 
-	"dateFormat-full": "EEEE d MMMM 'de' y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "era", 
-	"dateFormatItem-yM": "M/yyyy", 
+	],
+	"dateFormatItem-EEEd": "EEE d",
+	"dayPeriods-format-wide-pm": "p.m.",
+	"dateFormat-full": "EEEE d MMMM 'de' y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "era",
+	"dateFormatItem-yM": "M/yyyy",
 	"months-standAlone-wide": [
-		"gener", 
-		"febrer", 
-		"març", 
-		"abril", 
-		"maig", 
-		"juny", 
-		"juliol", 
-		"agost", 
-		"setembre", 
-		"octubre", 
-		"novembre", 
+		"gener",
+		"febrer",
+		"març",
+		"abril",
+		"maig",
+		"juny",
+		"juliol",
+		"agost",
+		"setembre",
+		"octubre",
+		"novembre",
 		"desembre"
-	], 
-	"timeFormat-short": "H:mm", 
+	],
+	"timeFormat-short": "H:mm",
 	"quarters-format-wide": [
-		"1r trimestre", 
-		"2n trimestre", 
-		"3r trimestre", 
+		"1r trimestre",
+		"2n trimestre",
+		"3r trimestre",
 		"4t trimestre"
-	], 
-	"timeFormat-long": "H:mm:ss z", 
-	"field-year": "any", 
-	"dateFormatItem-yMMM": "LLL y", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"field-hour": "hora", 
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "any",
+	"dateFormatItem-yMMM": "LLL y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"field-hour": "hora",
 	"months-format-abbr": [
-		"de gen.", 
-		"de febr.", 
-		"de març", 
-		"d’abr.", 
-		"de maig", 
-		"de juny", 
-		"de jul.", 
-		"d’ag.", 
-		"de set.", 
-		"d’oct.", 
-		"de nov.", 
+		"de gen.",
+		"de febr.",
+		"de març",
+		"d’abr.",
+		"de maig",
+		"de juny",
+		"de jul.",
+		"d’ag.",
+		"de set.",
+		"d’oct.",
+		"de nov.",
 		"de des."
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "H:mm:ss zzzz", 
-	"field-day-relative+0": "avui", 
-	"field-day-relative+1": "demà", 
-	"field-day-relative+2": "demà passat", 
-	"dateFormatItem-H": "H", 
-	"field-day-relative+3": "d'aquí a tres dies", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"field-day-relative+0": "avui",
+	"field-day-relative+1": "demà",
+	"field-day-relative+2": "demà passat",
+	"dateFormatItem-H": "H",
+	"field-day-relative+3": "d'aquí a tres dies",
 	"months-standAlone-abbr": [
-		"gen.", 
-		"febr.", 
-		"març", 
-		"abr.", 
-		"maig", 
-		"juny", 
-		"jul.", 
-		"ag.", 
-		"set.", 
-		"oct.", 
-		"nov.", 
+		"gen.",
+		"febr.",
+		"març",
+		"abr.",
+		"maig",
+		"juny",
+		"jul.",
+		"ag.",
+		"set.",
+		"oct.",
+		"nov.",
 		"des."
-	], 
+	],
 	"quarters-format-abbr": [
-		"1T", 
-		"2T", 
-		"3T", 
+		"1T",
+		"2T",
+		"3T",
 		"4T"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1r trimestre", 
-		"2n trimestre", 
-		"3r trimestre", 
+		"1r trimestre",
+		"2n trimestre",
+		"3r trimestre",
 		"4t trimestre"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"diumenge", 
-		"dilluns", 
-		"dimarts", 
-		"dimecres", 
-		"dijous", 
-		"divendres", 
+		"diumenge",
+		"dilluns",
+		"dimarts",
+		"dimecres",
+		"dijous",
+		"divendres",
 		"dissabte"
-	], 
-	"dateFormatItem-MMMMd": "d MMMM", 
-	"timeFormat-medium": "H:mm:ss", 
-	"dateFormatItem-Hm": "H:mm", 
+	],
+	"dateFormatItem-MMMMd": "d MMMM",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
 	"quarters-standAlone-abbr": [
-		"1T", 
-		"2T", 
-		"3T", 
+		"1T",
+		"2T",
+		"3T",
 		"4T"
-	], 
+	],
 	"eraAbbr": [
-		"aC", 
+		"aC",
 		"dC"
-	], 
-	"field-minute": "minut", 
-	"field-dayperiod": "a.m./p.m.", 
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "a.m./p.m.",
 	"days-standAlone-abbr": [
-		"dg", 
-		"dl", 
-		"dt", 
-		"dc", 
-		"dj", 
-		"dv", 
+		"dg",
+		"dl",
+		"dt",
+		"dc",
+		"dj",
+		"dv",
 		"ds"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "ahir", 
-	"field-day-relative+-2": "abans d'ahir", 
-	"field-day-relative+-3": "fa tres dies", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "E d/M", 
-	"dateFormatItem-yMMMM": "LLLL 'del' y", 
-	"field-day": "dia", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "ahir",
+	"field-day-relative+-2": "abans d'ahir",
+	"field-day-relative+-3": "fa tres dies",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"dateFormatItem-yMMMM": "LLLL 'del' y",
+	"field-day": "dia",
 	"days-format-wide": [
-		"diumenge", 
-		"dilluns", 
-		"dimarts", 
-		"dimecres", 
-		"dijous", 
-		"divendres", 
+		"diumenge",
+		"dilluns",
+		"dimarts",
+		"dimecres",
+		"dijous",
+		"divendres",
 		"dissabte"
-	], 
-	"field-zone": "zona", 
-	"dateFormatItem-yyyyMM": "MM/yyyy", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "zona",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"g", 
-		"f", 
-		"m", 
-		"a", 
-		"m", 
-		"j", 
-		"j", 
-		"a", 
-		"s", 
-		"o", 
-		"n", 
+		"g",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
 		"d"
-	], 
-	"dateFormatItem-hm": "h:mm a", 
+	],
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
-		"dg.", 
-		"dl.", 
-		"dt.", 
-		"dc.", 
-		"dj.", 
-		"dv.", 
+		"dg.",
+		"dl.",
+		"dt.",
+		"dc.",
+		"dj.",
+		"dv.",
 		"ds."
-	], 
+	],
 	"eraNames": [
-		"aC", 
+		"aC",
 		"dC"
-	], 
+	],
 	"days-format-narrow": [
-		"g", 
-		"l", 
-		"t", 
-		"c", 
-		"j", 
-		"v", 
+		"g",
+		"l",
+		"t",
+		"c",
+		"j",
+		"v",
 		"s"
-	], 
-	"field-month": "mes", 
+	],
+	"field-month": "mes",
 	"days-standAlone-narrow": [
-		"g", 
-		"l", 
-		"t", 
-		"c", 
-		"j", 
-		"v", 
+		"g",
+		"l",
+		"t",
+		"c",
+		"j",
+		"v",
 		"s"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "a.m.", 
-	"dateFormatItem-MMMMEd": "E d MMMM", 
-	"dateFormat-short": "dd/MM/yy", 
-	"field-second": "segon", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"field-week": "setmana", 
-	"dateFormat-medium": "dd/MM/yyyy", 
-	"dateFormatItem-mmss": "mm:ss", 
-	"dateFormatItem-Hms": "H:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "a.m.",
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormat-short": "dd/MM/yy",
+	"field-second": "segon",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"field-week": "setmana",
+	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-Hms": "H:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ca/number.js b/dojo/cldr/nls/ca/number.js
index d0f0a5f..c6539c1 100644
--- a/dojo/cldr/nls/ca/number.js
+++ b/dojo/cldr/nls/ca/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/currency.js b/dojo/cldr/nls/cs/currency.js
index 63bd725..6ee7cb6 100644
--- a/dojo/cldr/nls/cs/currency.js
+++ b/dojo/cldr/nls/cs/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Dolar australský",
-	CAD_displayName:"Dolar kanadský",
-	CHF_displayName:"Frank švýcarský",
-	CNY_displayName:"Juan renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Libra šterlinků",
-	HKD_displayName:"Dolar hongkongský",
-	JPY_displayName:"Jen",
-	USD_displayName:"Dolar americký"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Dolar hongkongský",
+	"CHF_displayName": "Frank švýcarský",
+	"CAD_displayName": "Dolar kanadský",
+	"CNY_displayName": "Juan renminbi",
+	"AUD_displayName": "Dolar australský",
+	"JPY_displayName": "Jen",
+	"USD_displayName": "Dolar americký",
+	"GBP_displayName": "Libra šterlinků",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/gregorian.js b/dojo/cldr/nls/cs/gregorian.js
index ec58625..4e6351d 100644
--- a/dojo/cldr/nls/cs/gregorian.js
+++ b/dojo/cldr/nls/cs/gregorian.js
@@ -1,194 +1,215 @@
-({
-	"dayPeriods-format-wide-pm": "odp.", 
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M.y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dayPeriods-format-wide-pm": "odp.",
 	"eraNames": [
-		"př.Kr.", 
+		"př.Kr.",
 		"po Kr."
-	], 
-	"field-day-relative+-1": "Včera", 
-	"field-day-relative+-2": "Předevčírem", 
+	],
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"field-day-relative+-1": "Včera",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"field-day-relative+-2": "Předevčírem",
 	"days-standAlone-wide": [
-		"neděle", 
-		"pondělí", 
-		"úterý", 
-		"středa", 
-		"čtvrtek", 
-		"pátek", 
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
 		"sobota"
-	], 
+	],
 	"months-standAlone-narrow": [
-		"l", 
-		"ú", 
-		"b", 
-		"d", 
-		"k", 
-		"č", 
-		"č", 
-		"s", 
-		"z", 
-		"ř", 
-		"l", 
+		"l",
+		"ú",
+		"b",
+		"d",
+		"k",
+		"č",
+		"č",
+		"s",
+		"z",
+		"ř",
+		"l",
 		"p"
-	], 
-	"dayPeriods-format-wide-am": "dop.", 
+	],
+	"dayPeriods-format-wide-am": "dop.",
 	"quarters-standAlone-abbr": [
-		"1. čtvrtletí", 
-		"2. čtvrtletí", 
-		"3. čtvrtletí", 
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
 		"4. čtvrtletí"
-	], 
-	"timeFormat-full": "H:mm:ss zzzz", 
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y",
 	"months-standAlone-abbr": [
-		"1.", 
-		"2.", 
-		"3.", 
-		"4.", 
-		"5.", 
-		"6.", 
-		"7.", 
-		"8.", 
-		"9.", 
-		"10.", 
-		"11.", 
+		"1.",
+		"2.",
+		"3.",
+		"4.",
+		"5.",
+		"6.",
+		"7.",
+		"8.",
+		"9.",
+		"10.",
+		"11.",
 		"12."
-	], 
-	"field-day-relative+0": "Dnes", 
-	"field-day-relative+1": "Zítra", 
+	],
+	"dateFormatItem-yMMM": "LLL y",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zítra",
 	"days-standAlone-narrow": [
-		"N", 
-		"P", 
-		"Ú", 
-		"S", 
-		"Č", 
-		"P", 
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
 		"S"
-	], 
+	],
 	"eraAbbr": [
-		"př.Kr.", 
+		"př.Kr.",
 		"po Kr."
-	], 
-	"field-day-relative+2": "Pozítří", 
-	"dateFormat-long": "d. MMMM y", 
-	"timeFormat-medium": "H:mm:ss", 
-	"dateFormatItem-Hm": "H:mm", 
-	"dateFormat-medium": "d.M.yyyy", 
-	"dateFormatItem-Hms": "H:mm:ss", 
+	],
+	"field-day-relative+2": "Pozítří",
+	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"dateFormat-long": "d. MMMM y",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-EEEd": "EEE, d.",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormat-medium": "d.M.yyyy",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-yMd": "d.M.y",
 	"quarters-standAlone-wide": [
-		"1. čtvrtletí", 
-		"2. čtvrtletí", 
-		"3. čtvrtletí", 
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
 		"4. čtvrtletí"
-	], 
+	],
 	"months-standAlone-wide": [
-		"leden", 
-		"únor", 
-		"březen", 
-		"duben", 
-		"květen", 
-		"červen", 
-		"červenec", 
-		"srpen", 
-		"září", 
-		"říjen", 
-		"listopad", 
+		"leden",
+		"únor",
+		"březen",
+		"duben",
+		"květen",
+		"červen",
+		"červenec",
+		"srpen",
+		"září",
+		"říjen",
+		"listopad",
 		"prosinec"
-	], 
-	"timeFormat-long": "H:mm:ss z", 
+	],
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-long": "H:mm:ss z",
 	"months-format-abbr": [
-		"ledna", 
-		"února", 
-		"března", 
-		"dubna", 
-		"května", 
-		"června", 
-		"července", 
-		"srpna", 
-		"září", 
-		"října", 
-		"listopadu", 
+		"ledna",
+		"února",
+		"března",
+		"dubna",
+		"května",
+		"června",
+		"července",
+		"srpna",
+		"září",
+		"října",
+		"listopadu",
 		"prosince"
-	], 
-	"timeFormat-short": "H:mm", 
-	"dateFormatItem-H": "H", 
+	],
+	"timeFormat-short": "H:mm",
+	"dateFormatItem-H": "H",
 	"quarters-format-abbr": [
-		"1. čtvrtletí", 
-		"2. čtvrtletí", 
-		"3. čtvrtletí", 
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
 		"4. čtvrtletí"
-	], 
+	],
 	"days-format-abbr": [
-		"ne", 
-		"po", 
-		"út", 
-		"st", 
-		"čt", 
-		"pá", 
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
 		"so"
-	], 
+	],
 	"days-format-narrow": [
-		"N", 
-		"P", 
-		"Ú", 
-		"S", 
-		"Č", 
-		"P", 
+		"N",
+		"P",
+		"Ú",
+		"S",
+		"Č",
+		"P",
 		"S"
-	], 
+	],
+	"dateFormatItem-MEd": "E, d.M",
 	"months-format-narrow": [
-		"l", 
-		"ú", 
-		"b", 
-		"d", 
-		"k", 
-		"č", 
-		"č", 
-		"s", 
-		"z", 
-		"ř", 
-		"l", 
+		"l",
+		"ú",
+		"b",
+		"d",
+		"k",
+		"č",
+		"č",
+		"s",
+		"z",
+		"ř",
+		"l",
 		"p"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"ne", 
-		"po", 
-		"út", 
-		"st", 
-		"čt", 
-		"pá", 
+		"ne",
+		"po",
+		"út",
+		"st",
+		"čt",
+		"pá",
 		"so"
-	], 
-	"dateFormat-short": "d.M.yy", 
-	"dateFormat-full": "EEEE, d. MMMM y", 
+	],
+	"dateFormat-short": "d.M.yy",
+	"dateFormatItem-yyyyM": "M.yyyy",
+	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
+	"dateFormat-full": "EEEE, d. MMMM y",
+	"dateFormatItem-Md": "d.M",
+	"dateFormatItem-yMEd": "EEE, d.M.y",
 	"months-format-wide": [
-		"ledna", 
-		"února", 
-		"března", 
-		"dubna", 
-		"května", 
-		"června", 
-		"července", 
-		"srpna", 
-		"září", 
-		"října", 
-		"listopadu", 
+		"ledna",
+		"února",
+		"března",
+		"dubna",
+		"května",
+		"června",
+		"července",
+		"srpna",
+		"září",
+		"října",
+		"listopadu",
 		"prosince"
-	], 
+	],
+	"dateFormatItem-d": "d.",
 	"quarters-format-wide": [
-		"1. čtvrtletí", 
-		"2. čtvrtletí", 
-		"3. čtvrtletí", 
+		"1. čtvrtletí",
+		"2. čtvrtletí",
+		"3. čtvrtletí",
 		"4. čtvrtletí"
-	], 
+	],
 	"days-format-wide": [
-		"neděle", 
-		"pondělí", 
-		"úterý", 
-		"středa", 
-		"čtvrtek", 
-		"pátek", 
+		"neděle",
+		"pondělí",
+		"úterý",
+		"středa",
+		"čtvrtek",
+		"pátek",
 		"sobota"
-	], 
+	],
 	"eraNarrow": [
-		"př.Kr.", 
+		"př.Kr.",
 		"po Kr."
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/cs/number.js b/dojo/cldr/nls/cs/number.js
index 33c9d64..be5c98c 100644
--- a/dojo/cldr/nls/cs/number.js
+++ b/dojo/cldr/nls/cs/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/currency.js b/dojo/cldr/nls/currency.js
index 0c3ad16..f00cb7a 100644
--- a/dojo/cldr/nls/currency.js
+++ b/dojo/cldr/nls/currency.js
@@ -1,12 +1,48 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_symbol:"AU$",
-	CAD_symbol:"CA$",
-	CNY_symbol:"CN¥",
-	EUR_symbol:"€",
-	GBP_symbol:"£",
-	HKD_symbol:"HK$",
-	JPY_symbol:"JP¥",
-	USD_symbol:"US$"
-})
-                 
\ No newline at end of file
+define({ root:
+
+//begin v1.x content
+{
+	"USD_symbol": "US$",
+	"CAD_symbol": "CA$",
+	"GBP_symbol": "£",
+	"HKD_symbol": "HK$",
+	"JPY_symbol": "JP¥",
+	"AUD_symbol": "AU$",
+	"CNY_symbol": "CN¥",
+	"EUR_symbol": "€"
+}
+//end v1.x content
+,
+	"ar": true,
+	"ca": true,
+	"cs": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"en-au": true,
+	"en-ca": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"he": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"ro": true,
+	"ru": true,
+	"sk": true,
+	"sl": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true,
+	"zh-hk": true,
+	"zh-tw": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/buddhist.js b/dojo/cldr/nls/da/buddhist.js
new file mode 100644
index 0000000..48d308b
--- /dev/null
+++ b/dojo/cldr/nls/da/buddhist.js
@@ -0,0 +1,141 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y G",
+	"dateFormatItem-yQ": "Q y G",
+	"dayPeriods-format-wide-pm": "e.m.",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-yQQQ": "QQQ y G",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-MMM": "MMM",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dayPeriods-format-wide-am": "f.m.",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "HH.mm.ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
+		"dec"
+	],
+	"dateFormatItem-Ed": "E d.",
+	"dateFormatItem-yMMM": "MMM y G",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormatItem-yyyyMM": "MM/y G",
+	"dateFormat-long": "d. MMMM y G",
+	"timeFormat-medium": "HH.mm.ss",
+	"dateFormatItem-Hm": "HH.mm",
+	"dateFormatItem-yyMM": "MM/y G",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"dateFormatItem-yyMMM": "MMM y G",
+	"dateFormatItem-yMd": "d/M/y G",
+	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q. 'kvartal' y G",
+	"timeFormat-long": "HH.mm.ss z",
+	"months-format-abbr": [
+		"jan.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"maj",
+		"jun.",
+		"jul.",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
+	"timeFormat-short": "HH.mm",
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"søn",
+		"man",
+		"tir",
+		"ons",
+		"tor",
+		"fre",
+		"lør"
+	],
+	"dateFormatItem-M": "M",
+	"dateFormatItem-MEd": "E. d/M",
+	"dateFormatItem-hm": "h.mm a",
+	"dateFormat-short": "d/M/yyyy",
+	"dateFormatItem-yMMMEd": "EEE. d. MMM y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "EEE. d/M/y G",
+	"months-format-wide": [
+		"januar",
+		"februar",
+		"marts",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
+		"december"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d.",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"days-format-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/currency.js b/dojo/cldr/nls/da/currency.js
index dabbb43..0b69b27 100644
--- a/dojo/cldr/nls/da/currency.js
+++ b/dojo/cldr/nls/da/currency.js
@@ -1,14 +1,16 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Australsk dollar",
-	CAD_displayName:"Canadisk dollar",
-	CHF_displayName:"Schweizisk franc",
-	CNY_displayName:"Kinesisk yuan renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Britisk pund",
-	HKD_displayName:"Hongkong dollar",
-	JPY_displayName:"Japansk yen",
-	USD_displayName:"Amerikansk dollar",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkong dollar",
+	"CHF_displayName": "Schweizisk franc",
+	"CAD_displayName": "Canadisk dollar",
+	"CNY_displayName": "Kinesisk yuan renminbi",
+	"USD_symbol": "$",
+	"AUD_displayName": "Australsk dollar",
+	"JPY_displayName": "Japansk yen",
+	"USD_displayName": "Amerikansk dollar",
+	"GBP_displayName": "Britisk pund",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/gregorian.js b/dojo/cldr/nls/da/gregorian.js
index 5410b0a..5735714 100644
--- a/dojo/cldr/nls/da/gregorian.js
+++ b/dojo/cldr/nls/da/gregorian.js
@@ -1,232 +1,237 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "ugedag", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE. d/M/y", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"field-weekday": "ugedag",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE. d/M/y",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
-	"dateFormat-long": "d. MMM y", 
+	],
+	"dateFormat-long": "d. MMM y",
 	"months-format-wide": [
-		"januar", 
-		"februar", 
-		"marts", 
-		"april", 
-		"maj", 
-		"juni", 
-		"juli", 
-		"august", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januar",
+		"februar",
+		"marts",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
-	"dayPeriods-format-wide-pm": "e.m.", 
-	"dateFormat-full": "EEEE 'den' d. MMMM y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "æra", 
-	"dateFormatItem-yM": "M/y", 
+	],
+	"dayPeriods-format-wide-pm": "e.m.",
+	"dateFormat-full": "EEEE 'den' d. MMMM y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "æra",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
-		"januar", 
-		"februar", 
-		"marts", 
-		"april", 
-		"maj", 
-		"juni", 
-		"juli", 
-		"august", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januar",
+		"februar",
+		"marts",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
-	"timeFormat-short": "HH.mm", 
+	],
+	"timeFormat-short": "HH.mm",
 	"quarters-format-wide": [
-		"1. kvartal", 
-		"2. kvartal", 
-		"3. kvartal", 
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
 		"4. kvartal"
-	], 
-	"timeFormat-long": "HH.mm.ss z", 
-	"field-year": "år", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"field-hour": "time", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "HH.mm.ss z",
+	"field-year": "år",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"field-hour": "time",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"jan.", 
-		"feb.", 
-		"mar.", 
-		"apr.", 
-		"maj", 
-		"jun.", 
-		"jul.", 
-		"aug.", 
-		"sep.", 
-		"okt.", 
-		"nov.", 
+		"jan.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"maj",
+		"jun.",
+		"jul.",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
 		"dec."
-	], 
-	"dateFormatItem-yyQ": "Q. 'kvartal' yy", 
-	"timeFormat-full": "HH.mm.ss zzzz", 
-	"field-day-relative+0": "i dag", 
-	"field-day-relative+1": "i morgen", 
-	"field-day-relative+2": "i overmorgen", 
-	"dateFormatItem-H": "HH", 
-	"field-day-relative+3": "i overovermorgen", 
+	],
+	"dateFormatItem-yyQ": "Q. 'kvartal' yy",
+	"timeFormat-full": "HH.mm.ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"field-day-relative+2": "i overmorgen",
+	"dateFormatItem-H": "HH",
+	"field-day-relative+3": "i overovermorgen",
 	"months-standAlone-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"maj", 
-		"jun", 
-		"jul", 
-		"aug", 
-		"sep", 
-		"okt", 
-		"nov", 
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
 		"dec"
-	], 
+	],
 	"quarters-format-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1. kvartal", 
-		"2. kvartal", 
-		"3. kvartal", 
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
 		"4. kvartal"
-	], 
-	"dateFormatItem-M": "M", 
+	],
+	"dateFormatItem-M": "M",
 	"days-standAlone-wide": [
-		"søndag", 
-		"mandag", 
-		"tirsdag", 
-		"onsdag", 
-		"torsdag", 
-		"fredag", 
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
 		"lørdag"
-	], 
-	"dateFormatItem-yyyyMMM": "MMM y", 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "HH.mm.ss", 
-	"dateFormatItem-Hm": "HH.mm", 
+	],
+	"dateFormatItem-yyyyMMM": "MMM y",
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH.mm.ss",
+	"dateFormatItem-Hm": "HH.mm",
 	"quarters-standAlone-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"eraAbbr": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
-	"field-minute": "minut", 
-	"field-dayperiod": "dagtid", 
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "dagtid",
 	"days-standAlone-abbr": [
-		"søn", 
-		"man", 
-		"tir", 
-		"ons", 
-		"tor", 
-		"fre", 
+		"søn",
+		"man",
+		"tir",
+		"ons",
+		"tor",
+		"fre",
 		"lør"
-	], 
-	"dateFormatItem-d": "d.", 
-	"dateFormatItem-ms": "mm.ss", 
-	"field-day-relative+-1": "i går", 
-	"field-day-relative+-2": "i forgårs", 
-	"field-day-relative+-3": "i forforgårs", 
-	"dateFormatItem-MMMd": "d. MMM", 
-	"dateFormatItem-MEd": "E. d/M", 
-	"field-day": "dag", 
+	],
+	"dateFormatItem-d": "d.",
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"field-day-relative+-3": "i forforgårs",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E. d/M",
+	"field-day": "dag",
 	"days-format-wide": [
-		"søndag", 
-		"mandag", 
-		"tirsdag", 
-		"onsdag", 
-		"torsdag", 
-		"fredag", 
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
 		"lørdag"
-	], 
-	"field-zone": "zone", 
-	"dateFormatItem-yyyyMM": "MM/yyyy", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "zone",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
-	"dateFormatItem-hm": "h.mm a", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
+	"dateFormatItem-hm": "h.mm a",
 	"days-format-abbr": [
-		"søn", 
-		"man", 
-		"tir", 
-		"ons", 
-		"tor", 
-		"fre", 
+		"søn",
+		"man",
+		"tir",
+		"ons",
+		"tor",
+		"fre",
 		"lør"
-	], 
+	],
 	"eraNames": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
+	],
 	"days-format-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"O", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
 		"L"
-	], 
-	"field-month": "måned", 
+	],
+	"field-month": "måned",
 	"days-standAlone-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"O", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
 		"L"
-	], 
-	"dateFormatItem-MMM": "MMM", 
-	"dayPeriods-format-wide-am": "f.m.", 
-	"dateFormatItem-MMMMEd": "E, d. MMMM", 
-	"dateFormat-short": "dd/MM/yy", 
-	"field-second": "sekund", 
-	"dateFormatItem-yMMMEd": "EEE. d. MMM y", 
-	"field-week": "uge", 
-	"dateFormat-medium": "dd/MM/yyyy", 
-	"dateFormatItem-Hms": "HH.mm.ss", 
-	"dateFormatItem-hms": "h.mm.ss a", 
+	],
+	"dateFormatItem-MMM": "MMM",
+	"dayPeriods-format-wide-am": "f.m.",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"dateFormat-short": "dd/MM/yy",
+	"field-second": "sekund",
+	"dateFormatItem-yMMMEd": "EEE. d. MMM y",
+	"dateFormatItem-Ed": "E d.",
+	"field-week": "uge",
+	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"dateFormatItem-hms": "h.mm.ss a",
 	"dateFormatItem-yyyy": "y"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/islamic.js b/dojo/cldr/nls/da/islamic.js
new file mode 100644
index 0000000..64cb44f
--- /dev/null
+++ b/dojo/cldr/nls/da/islamic.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"dateFormatItem-yyyyMMMEd": "EEE. d. MMM y G",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dayPeriods-format-wide-pm": "e.m.",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-MMM": "MMM",
+	"dayPeriods-format-wide-am": "f.m.",
+	"timeFormat-full": "HH.mm.ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"dateFormatItem-Ed": "E d.",
+	"dateFormatItem-yMMM": "MMM y",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
+		"L"
+	],
+	"dateFormat-long": "d. MMMM y G",
+	"timeFormat-medium": "HH.mm.ss",
+	"dateFormatItem-Hm": "HH.mm",
+	"dateFormatItem-yyMM": "MM/y G",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH.mm.ss",
+	"dateFormatItem-yyMMM": "MMM y G",
+	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"dateFormatItem-yyyyMEd": "EEE. d/M/y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q. 'kvartal' y G",
+	"timeFormat-long": "HH.mm.ss z",
+	"timeFormat-short": "HH.mm",
+	"dateFormatItem-H": "HH",
+	"quarters-format-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"days-format-abbr": [
+		"søn",
+		"man",
+		"tir",
+		"ons",
+		"tor",
+		"fre",
+		"lør"
+	],
+	"dateFormatItem-M": "M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E. d/M",
+	"dateFormatItem-hm": "h.mm a",
+	"dateFormat-short": "d/M/y G",
+	"dateFormatItem-yyyyM": "M/y G",
+	"dateFormatItem-yMMMEd": "EEE. d. MMM y",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyQ": "Q y G",
+	"dateFormatItem-yMEd": "EEE. d/M/y",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d.",
+	"quarters-format-wide": [
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
+		"4. kvartal"
+	],
+	"days-format-wide": [
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
+		"lørdag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/da/number.js b/dojo/cldr/nls/da/number.js
index 6ff39a5..36148ce 100644
--- a/dojo/cldr/nls/da/number.js
+++ b/dojo/cldr/nls/da/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':",",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ",",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/buddhist.js b/dojo/cldr/nls/de/buddhist.js
new file mode 100644
index 0000000..3202129
--- /dev/null
+++ b/dojo/cldr/nls/de/buddhist.js
@@ -0,0 +1,130 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M.y G",
+	"dateFormatItem-yyMMdd": "dd.MM.y G",
+	"dateFormatItem-yQ": "Q y G",
+	"dayPeriods-format-wide-pm": "nachm.",
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"dateFormatItem-yQQQ": "QQQ y G",
+	"dateFormatItem-MMdd": "dd.MM.",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dayPeriods-format-wide-am": "vorm.",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Jan",
+		"Feb",
+		"Mär",
+		"Apr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Okt",
+		"Nov",
+		"Dez"
+	],
+	"dateFormatItem-Ed": "E d.",
+	"dateFormatItem-yMMM": "MMM y G",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-MMd": "d.MM.",
+	"dateFormatItem-yyMM": "MM.y G",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-yyMMM": "MMM y G",
+	"dateFormatItem-yyQQQQ": "QQQQ y G",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q y G",
+	"months-format-abbr": [
+		"Jan",
+		"Feb",
+		"Mär",
+		"Apr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Okt",
+		"Nov",
+		"Dez"
+	],
+	"dateFormatItem-H": "HH 'Uhr'",
+	"days-format-abbr": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"dateFormatItem-MMMMdd": "dd. MMMM",
+	"dateFormatItem-M": "L",
+	"dateFormatItem-MEd": "E, d.M.",
+	"dateFormat-short": "d.M.yyyy",
+	"dateFormatItem-yMMMEd": "EEE, d. MMM y G",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yMEd": "EEE, d.M.y G",
+	"months-format-wide": [
+		"Januar",
+		"Februar",
+		"März",
+		"April",
+		"Mai",
+		"Juni",
+		"Juli",
+		"August",
+		"September",
+		"Oktober",
+		"November",
+		"Dezember"
+	],
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
+		"4. Quartal"
+	],
+	"days-format-wide": [
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
+		"Samstag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/currency.js b/dojo/cldr/nls/de/currency.js
index f5f13c0..225e1ab 100644
--- a/dojo/cldr/nls/de/currency.js
+++ b/dojo/cldr/nls/de/currency.js
@@ -1,15 +1,17 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Australischer Dollar",
-	CAD_displayName:"Kanadischer Dollar",
-	CHF_displayName:"Schweizer Franken",
-	CNY_displayName:"Renminbi Yuan",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Pfund Sterling",
-	HKD_displayName:"Hongkong-Dollar",
-	JPY_displayName:"Yen",
-	JPY_symbol:"¥",
-	USD_displayName:"US-Dollar",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkong-Dollar",
+	"CHF_displayName": "Schweizer Franken",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "Kanadischer Dollar",
+	"CNY_displayName": "Renminbi Yuan",
+	"USD_symbol": "$",
+	"AUD_displayName": "Australischer Dollar",
+	"JPY_displayName": "Yen",
+	"USD_displayName": "US-Dollar",
+	"GBP_displayName": "Pfund Sterling",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/gregorian.js b/dojo/cldr/nls/de/gregorian.js
index 7a95c3a..22997c3 100644
--- a/dojo/cldr/nls/de/gregorian.js
+++ b/dojo/cldr/nls/de/gregorian.js
@@ -1,234 +1,237 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "Wochentag", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE, d.M.y", 
-	"dateFormatItem-MMMEd": "E d. MMM", 
+	],
+	"field-weekday": "Wochentag",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE, d.M.y",
+	"dateFormatItem-MMMEd": "E, d. MMM",
 	"eraNarrow": [
-		"v. Chr.", 
+		"v. Chr.",
 		"n. Chr."
-	], 
-	"dayPeriods-format-wide-earlyMorning": "morgens", 
-	"dayPeriods-format-wide-morning": "vormittags", 
-	"dateFormat-long": "d. MMMM y", 
+	],
+	"dayPeriods-format-wide-earlyMorning": "morgens",
+	"dayPeriods-format-wide-morning": "vormittags",
+	"dateFormat-long": "d. MMMM y",
 	"months-format-wide": [
-		"Januar", 
-		"Februar", 
-		"März", 
-		"April", 
-		"Mai", 
-		"Juni", 
-		"Juli", 
-		"August", 
-		"September", 
-		"Oktober", 
-		"November", 
+		"Januar",
+		"Februar",
+		"März",
+		"April",
+		"Mai",
+		"Juni",
+		"Juli",
+		"August",
+		"September",
+		"Oktober",
+		"November",
 		"Dezember"
-	], 
-	"dayPeriods-format-wide-evening": "abends", 
-	"dateFormatItem-EEEd": "d. EEE", 
-	"dayPeriods-format-wide-pm": "nachm.", 
-	"dateFormat-full": "EEEE, d. MMMM y", 
-	"dateFormatItem-Md": "d.M.", 
-	"dateFormatItem-yyMMdd": "dd.MM.yy", 
-	"dayPeriods-format-wide-noon": "Mittag", 
-	"field-era": "Epoche", 
-	"dateFormatItem-yM": "M.y", 
+	],
+	"dayPeriods-format-wide-evening": "abends",
+	"dayPeriods-format-wide-pm": "nachm.",
+	"dateFormat-full": "EEEE, d. MMMM y",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyMMdd": "dd.MM.yy",
+	"dayPeriods-format-wide-noon": "Mittag",
+	"field-era": "Epoche",
+	"dateFormatItem-yM": "M.y",
 	"months-standAlone-wide": [
-		"Januar", 
-		"Februar", 
-		"März", 
-		"April", 
-		"Mai", 
-		"Juni", 
-		"Juli", 
-		"August", 
-		"September", 
-		"Oktober", 
-		"November", 
+		"Januar",
+		"Februar",
+		"März",
+		"April",
+		"Mai",
+		"Juni",
+		"Juli",
+		"August",
+		"September",
+		"Oktober",
+		"November",
 		"Dezember"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1. Quartal", 
-		"2. Quartal", 
-		"3. Quartal", 
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
 		"4. Quartal"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "Jahr", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q y", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"dateFormatItem-MMdd": "dd.MM.", 
-	"field-hour": "Stunde", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Jahr",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q y",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "Stunde",
+	"dateFormatItem-MMdd": "dd.MM.",
 	"months-format-abbr": [
-		"Jan", 
-		"Feb", 
-		"Mär", 
-		"Apr", 
-		"Mai", 
-		"Jun", 
-		"Jul", 
-		"Aug", 
-		"Sep", 
-		"Okt", 
-		"Nov", 
+		"Jan",
+		"Feb",
+		"Mär",
+		"Apr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Okt",
+		"Nov",
 		"Dez"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "heute", 
-	"field-day-relative+1": "morgen", 
-	"field-day-relative+2": "übermorgen", 
-	"dateFormatItem-H": "HH", 
-	"field-day-relative+3": "überübermorgen", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "heute",
+	"field-day-relative+1": "morgen",
+	"field-day-relative+2": "übermorgen",
+	"dateFormatItem-H": "HH 'Uhr'",
+	"field-day-relative+3": "überübermorgen",
 	"months-standAlone-abbr": [
-		"Jan", 
-		"Feb", 
-		"Mär", 
-		"Apr", 
-		"Mai", 
-		"Jun", 
-		"Jul", 
-		"Aug", 
-		"Sep", 
-		"Okt", 
-		"Nov", 
+		"Jan",
+		"Feb",
+		"Mär",
+		"Apr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Okt",
+		"Nov",
 		"Dez"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1. Quartal", 
-		"2. Quartal", 
-		"3. Quartal", 
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
 		"4. Quartal"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"Sonntag", 
-		"Montag", 
-		"Dienstag", 
-		"Mittwoch", 
-		"Donnerstag", 
-		"Freitag", 
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
 		"Samstag"
-	], 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"eraAbbr": [
-		"v. Chr.", 
+		"v. Chr.",
 		"n. Chr."
-	], 
-	"field-minute": "Minute", 
-	"field-dayperiod": "Tageshälfte", 
-	"dayPeriods-format-wide-night": "nachts", 
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Tageshälfte",
 	"days-standAlone-abbr": [
-		"So.", 
-		"Mo.", 
-		"Di.", 
-		"Mi.", 
-		"Do.", 
-		"Fr.", 
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
 		"Sa."
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "gestern", 
-	"field-day-relative+-2": "vorgestern", 
-	"field-day-relative+-3": "vorvorgestern", 
-	"dateFormatItem-MMMd": "d. MMM", 
-	"dateFormatItem-MEd": "E, d.M.", 
-	"field-day": "Tag", 
+	],
+	"dayPeriods-format-wide-night": "nachts",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "gestern",
+	"field-day-relative+-2": "vorgestern",
+	"field-day-relative+-3": "vorvorgestern",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E, d.M.",
+	"field-day": "Tag",
 	"days-format-wide": [
-		"Sonntag", 
-		"Montag", 
-		"Dienstag", 
-		"Mittwoch", 
-		"Donnerstag", 
-		"Freitag", 
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
 		"Samstag"
-	], 
-	"field-zone": "Zone", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "Zone",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM.yy", 
+	],
+	"dateFormatItem-yyMM": "MM.yy",
 	"days-format-abbr": [
-		"So.", 
-		"Mo.", 
-		"Di.", 
-		"Mi.", 
-		"Do.", 
-		"Fr.", 
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
 		"Sa."
-	], 
+	],
 	"eraNames": [
-		"v. Chr.", 
+		"v. Chr.",
 		"n. Chr."
-	], 
+	],
 	"days-format-narrow": [
-		"S", 
-		"M", 
-		"D", 
-		"M", 
-		"D", 
-		"F", 
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
 		"S"
-	], 
-	"field-month": "Monat", 
+	],
+	"field-month": "Monat",
 	"days-standAlone-narrow": [
-		"S", 
-		"M", 
-		"D", 
-		"M", 
-		"D", 
-		"F", 
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
 		"S"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "vorm.", 
-	"dateFormatItem-MMMMdd": "dd. MMMM", 
-	"dateFormat-short": "dd.MM.yy", 
-	"dateFormatItem-MMd": "d.MM.", 
-	"dayPeriods-format-wide-afternoon": "nachmittags", 
-	"field-second": "Sekunde", 
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y", 
-	"dateFormatItem-Ed": "E d.", 
-	"field-week": "Woche", 
-	"dateFormat-medium": "dd.MM.yyyy", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "vorm.",
+	"dateFormatItem-MMMMdd": "dd. MMMM",
+	"dateFormat-short": "dd.MM.yy",
+	"dateFormatItem-MMd": "d.MM.",
+	"dayPeriods-format-wide-afternoon": "nachmittags",
+	"field-second": "Sekunde",
+	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
+	"dateFormatItem-Ed": "E, d.",
+	"field-week": "Woche",
+	"dateFormat-medium": "dd.MM.yyyy",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-yyyy": "y"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/islamic.js b/dojo/cldr/nls/de/islamic.js
new file mode 100644
index 0000000..07b9110
--- /dev/null
+++ b/dojo/cldr/nls/de/islamic.js
@@ -0,0 +1,172 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M.y",
+	"dateFormatItem-yyyyMMMEd": "EEE, d. MMM y G",
+	"dateFormatItem-yyMMdd": "dd.MM.y G",
+	"dateFormatItem-yQ": "Q y",
+	"dayPeriods-format-wide-pm": "nachm.",
+	"eraNames": [
+		"AH"
+	],
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-MMdd": "dd.MM.",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dayPeriods-format-wide-am": "vorm.",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"dateFormatItem-Ed": "E d.",
+	"dateFormatItem-yMMM": "MMM y",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"D",
+		"M",
+		"D",
+		"F",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormat-long": "d. MMMM y G",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-MMd": "d.MM.",
+	"dateFormatItem-yyMM": "MM.y G",
+	"dateFormat-medium": "d. MMM y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-yyMMM": "MMM y G",
+	"dateFormatItem-yyQQQQ": "QQQQ y G",
+	"dateFormatItem-ms": "mm:ss",
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyMEd": "EEE, d.M.y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q y G",
+	"months-format-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"dateFormatItem-H": "HH 'Uhr'",
+	"dateFormatItem-MMMMdd": "dd. MMMM",
+	"days-format-abbr": [
+		"So.",
+		"Mo.",
+		"Di.",
+		"Mi.",
+		"Do.",
+		"Fr.",
+		"Sa."
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-MEd": "E, d.M.",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormat-short": "d.M.y G",
+	"dateFormatItem-yyyyM": "M.y G",
+	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
+	"dateFormat-full": "EEEE d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyyyQ": "Q y G",
+	"dateFormatItem-yMEd": "EEE, d.M.y",
+	"months-format-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1. Quartal",
+		"2. Quartal",
+		"3. Quartal",
+		"4. Quartal"
+	],
+	"eraNarrow": [
+		"AH"
+	],
+	"days-format-wide": [
+		"Sonntag",
+		"Montag",
+		"Dienstag",
+		"Mittwoch",
+		"Donnerstag",
+		"Freitag",
+		"Samstag"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/de/number.js b/dojo/cldr/nls/de/number.js
index b59dd68..5634e80 100644
--- a/dojo/cldr/nls/de/number.js
+++ b/dojo/cldr/nls/de/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/buddhist.js b/dojo/cldr/nls/el/buddhist.js
new file mode 100644
index 0000000..bc2fcfb
--- /dev/null
+++ b/dojo/cldr/nls/el/buddhist.js
@@ -0,0 +1,120 @@
+define(
+//begin v1.x content
+{
+	"quarters-format-abbr": [
+		"Τ1",
+		"Τ2",
+		"Τ3",
+		"Τ4"
+	],
+	"dateFormat-medium": "d MMM, y G",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateFormatItem-Md": "d/M",
+	"months-standAlone-narrow": [
+		"Ι",
+		"Φ",
+		"Μ",
+		"Α",
+		"Μ",
+		"Ι",
+		"Ι",
+		"Α",
+		"Σ",
+		"Ο",
+		"Ν",
+		"Δ"
+	],
+	"months-standAlone-wide": [
+		"Ιανουάριος",
+		"Φεβρουάριος",
+		"Μάρτιος",
+		"Απρίλιος",
+		"Μάιος",
+		"Ιούνιος",
+		"Ιούλιος",
+		"Αύγουστος",
+		"Σεπτέμβριος",
+		"Οκτώβριος",
+		"Νοέμβριος",
+		"Δεκέμβριος"
+	],
+	"dateFormatItem-EEEd": "EEE d",
+	"days-standAlone-narrow": [
+		"Κ",
+		"Δ",
+		"Τ",
+		"Τ",
+		"Π",
+		"Π",
+		"Σ"
+	],
+	"dayPeriods-format-wide-pm": "μ.μ.",
+	"dayPeriods-format-wide-am": "π.μ.",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormat-long": "d MMMM, y G",
+	"dateFormat-short": "d/M/yyyy",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"months-format-wide": [
+		"Ιανουαρίου",
+		"Φεβρουαρίου",
+		"Μαρτίου",
+		"Απριλίου",
+		"Μαΐου",
+		"Ιουνίου",
+		"Ιουλίου",
+		"Αυγούστου",
+		"Σεπτεμβρίου",
+		"Οκτωβρίου",
+		"Νοεμβρίου",
+		"Δεκεμβρίου"
+	],
+	"dateFormatItem-yM": "M/yyyy",
+	"timeFormat-short": "h:mm a",
+	"months-format-abbr": [
+		"Ιαν",
+		"Φεβ",
+		"Μαρ",
+		"Απρ",
+		"Μαϊ",
+		"Ιουν",
+		"Ιουλ",
+		"Αυγ",
+		"Σεπ",
+		"Οκτ",
+		"Νοε",
+		"Δεκ"
+	],
+	"timeFormat-long": "h:mm:ss a z",
+	"days-format-wide": [
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
+		"Σάββατο"
+	],
+	"dateFormatItem-yMMM": "LLL y",
+	"quarters-format-wide": [
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
+		"4ο τρίμηνο"
+	],
+	"dateFormat-full": "EEEE, d MMMM, y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"days-format-abbr": [
+		"Κυρ",
+		"Δευ",
+		"Τρι",
+		"Τετ",
+		"Πεμ",
+		"Παρ",
+		"Σαβ"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/currency.js b/dojo/cldr/nls/el/currency.js
index 84f91ff..454ab1a 100644
--- a/dojo/cldr/nls/el/currency.js
+++ b/dojo/cldr/nls/el/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Δολάριο Αυστραλίας",
-	CAD_displayName:"Δολάριο Καναδά",
-	CHF_displayName:"Φράγκο Ελβετίας",
-	CNY_displayName:"Γιουάν Ρενμίμπι Κίνας",
-	EUR_displayName:"Ευρώ",
-	GBP_displayName:"Λίρα Στερλίνα Βρετανίας",
-	HKD_displayName:"Δολάριο Χονγκ Κονγκ",
-	JPY_displayName:"Γιεν Ιαπωνίας",
-	USD_displayName:"Δολάριο ΗΠΑ"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Δολάριο Χονγκ Κονγκ",
+	"CHF_displayName": "Φράγκο Ελβετίας",
+	"CAD_displayName": "Δολάριο Καναδά",
+	"CNY_displayName": "Γιουάν Ρενμίμπι Κίνας",
+	"AUD_displayName": "Δολάριο Αυστραλίας",
+	"JPY_displayName": "Γιεν Ιαπωνίας",
+	"USD_displayName": "Δολάριο ΗΠΑ",
+	"GBP_displayName": "Λίρα Στερλίνα Βρετανίας",
+	"EUR_displayName": "Ευρώ"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/gregorian.js b/dojo/cldr/nls/el/gregorian.js
index 5b5b2ad..8e86c15 100644
--- a/dojo/cldr/nls/el/gregorian.js
+++ b/dojo/cldr/nls/el/gregorian.js
@@ -1,238 +1,241 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"Ι", 
-		"Φ", 
-		"Μ", 
-		"Α", 
-		"Μ", 
-		"Ι", 
-		"Ι", 
-		"Α", 
-		"Σ", 
-		"Ο", 
-		"Ν", 
+		"Ι",
+		"Φ",
+		"Μ",
+		"Α",
+		"Μ",
+		"Ι",
+		"Ι",
+		"Α",
+		"Σ",
+		"Ο",
+		"Ν",
 		"Δ"
-	], 
-	"field-weekday": "Ημέρα εβδομάδας", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, d/M/yyyy", 
-	"dateFormatItem-MMMEd": "E, d MMM", 
+	],
+	"field-weekday": "Ημέρα εβδομάδας",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"dateFormatItem-MMMEd": "E, d MMM",
 	"eraNarrow": [
-		"π.Χ.", 
+		"π.Χ.",
 		"μ.Χ."
-	], 
-	"dateFormat-long": "d MMMM y", 
+	],
+	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
-		"Ιανουαρίου", 
-		"Φεβρουαρίου", 
-		"Μαρτίου", 
-		"Απριλίου", 
-		"Μαΐου", 
-		"Ιουνίου", 
-		"Ιουλίου", 
-		"Αυγούστου", 
-		"Σεπτεμβρίου", 
-		"Οκτωβρίου", 
-		"Νοεμβρίου", 
+		"Ιανουαρίου",
+		"Φεβρουαρίου",
+		"Μαρτίου",
+		"Απριλίου",
+		"Μαΐου",
+		"Ιουνίου",
+		"Ιουλίου",
+		"Αυγούστου",
+		"Σεπτεμβρίου",
+		"Οκτωβρίου",
+		"Νοεμβρίου",
 		"Δεκεμβρίου"
-	], 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dayPeriods-format-wide-pm": "μ.μ.", 
-	"dateFormat-full": "EEEE, d MMMM y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "Περίοδος", 
-	"dateFormatItem-yM": "M/yyyy", 
+	],
+	"dateFormatItem-EEEd": "EEE d",
+	"dayPeriods-format-wide-pm": "μ.μ.",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "Περίοδος",
+	"dateFormatItem-yM": "M/yyyy",
 	"months-standAlone-wide": [
-		"Ιανουάριος", 
-		"Φεβρουάριος", 
-		"Μάρτιος", 
-		"Απρίλιος", 
-		"Μάιος", 
-		"Ιούνιος", 
-		"Ιούλιος", 
-		"Αύγουστος", 
-		"Σεπτέμβριος", 
-		"Οκτώβριος", 
-		"Νοέμβριος", 
+		"Ιανουάριος",
+		"Φεβρουάριος",
+		"Μάρτιος",
+		"Απρίλιος",
+		"Μάιος",
+		"Ιούνιος",
+		"Ιούλιος",
+		"Αύγουστος",
+		"Σεπτέμβριος",
+		"Οκτώβριος",
+		"Νοέμβριος",
 		"Δεκέμβριος"
-	], 
-	"timeFormat-short": "h:mm a", 
+	],
+	"timeFormat-short": "h:mm a",
 	"quarters-format-wide": [
-		"1ο τρίμηνο", 
-		"2ο τρίμηνο", 
-		"3ο τρίμηνο", 
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
 		"4ο τρίμηνο"
-	], 
-	"timeFormat-long": "h:mm:ss a z", 
-	"field-year": "Έτος", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "y Q", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"field-hour": "Ώρα", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "h:mm:ss a z",
+	"field-year": "Έτος",
+	"dateFormatItem-yMMM": "LLL y",
+	"dateFormatItem-yQ": "y Q",
+	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"field-hour": "Ώρα",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"Ιαν", 
-		"Φεβ", 
-		"Μαρ", 
-		"Απρ", 
-		"Μαϊ", 
-		"Ιουν", 
-		"Ιουλ", 
-		"Αυγ", 
-		"Σεπ", 
-		"Οκτ", 
-		"Νοε", 
+		"Ιαν",
+		"Φεβ",
+		"Μαρ",
+		"Απρ",
+		"Μαϊ",
+		"Ιουν",
+		"Ιουλ",
+		"Αυγ",
+		"Σεπ",
+		"Οκτ",
+		"Νοε",
 		"Δεκ"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "h:mm:ss a zzzz", 
-	"field-day-relative+0": "Σήμερα", 
-	"field-day-relative+1": "Αύριο", 
-	"field-day-relative+2": "Μεθαύριο", 
-	"dateFormatItem-H": "HH", 
-	"field-day-relative+3": "Σε τρεις ημέρες από τώρα", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"field-day-relative+0": "Σήμερα",
+	"field-day-relative+1": "Αύριο",
+	"field-day-relative+2": "Μεθαύριο",
+	"dateFormatItem-H": "HH",
+	"field-day-relative+3": "Σε τρεις ημέρες από τώρα",
 	"months-standAlone-abbr": [
-		"Ιαν", 
-		"Φεβ", 
-		"Μαρ", 
-		"Απρ", 
-		"Μαϊ", 
-		"Ιουν", 
-		"Ιουλ", 
-		"Αυγ", 
-		"Σεπ", 
-		"Οκτ", 
-		"Νοε", 
+		"Ιαν",
+		"Φεβ",
+		"Μαρ",
+		"Απρ",
+		"Μαϊ",
+		"Ιουν",
+		"Ιουλ",
+		"Αυγ",
+		"Σεπ",
+		"Οκτ",
+		"Νοε",
 		"Δεκ"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Τ1", 
-		"Τ2", 
-		"Τ3", 
+		"Τ1",
+		"Τ2",
+		"Τ3",
 		"Τ4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1ο τρίμηνο", 
-		"2ο τρίμηνο", 
-		"3ο τρίμηνο", 
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
 		"4ο τρίμηνο"
-	], 
-	"dateFormatItem-HHmmss": "HH:mm:ss", 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-HHmmss": "HH:mm:ss",
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"Κυριακή", 
-		"Δευτέρα", 
-		"Τρίτη", 
-		"Τετάρτη", 
-		"Πέμπτη", 
-		"Παρασκευή", 
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
 		"Σάββατο"
-	], 
-	"dateFormatItem-MMMMd": "d MMMM", 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "h:mm:ss a", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-yyMMM": "LLL yy",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"Τ1", 
-		"Τ2", 
-		"Τ3", 
+		"Τ1",
+		"Τ2",
+		"Τ3",
 		"Τ4"
-	], 
+	],
 	"eraAbbr": [
-		"π.Χ.", 
+		"π.Χ.",
 		"μ.Χ."
-	], 
-	"field-minute": "Λεπτό", 
-	"field-dayperiod": "π.μ./μ.μ.", 
+	],
+	"field-minute": "Λεπτό",
+	"field-dayperiod": "π.μ./μ.μ.",
 	"days-standAlone-abbr": [
-		"Κυρ", 
-		"Δευ", 
-		"Τρι", 
-		"Τετ", 
-		"Πεμ", 
-		"Παρ", 
+		"Κυρ",
+		"Δευ",
+		"Τρι",
+		"Τετ",
+		"Πεμ",
+		"Παρ",
 		"Σαβ"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "Χθες", 
-	"field-day-relative+-2": "Προχθές", 
-	"field-day-relative+-3": "Πριν από τρεις ημέρες", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "E, d/M", 
-	"dateFormatItem-yMMMM": "LLLL y", 
-	"field-day": "Ημέρα", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "Χθες",
+	"field-day-relative+-2": "Προχθές",
+	"field-day-relative+-3": "Πριν από τρεις ημέρες",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"field-day": "Ημέρα",
 	"days-format-wide": [
-		"Κυριακή", 
-		"Δευτέρα", 
-		"Τρίτη", 
-		"Τετάρτη", 
-		"Πέμπτη", 
-		"Παρασκευή", 
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
 		"Σάββατο"
-	], 
-	"field-zone": "Ζώνη", 
-	"dateFormatItem-yyyyMM": "MM/yyyy", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "Ζώνη",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"Ι", 
-		"Φ", 
-		"Μ", 
-		"Α", 
-		"Μ", 
-		"Ι", 
-		"Ι", 
-		"Α", 
-		"Σ", 
-		"Ο", 
-		"Ν", 
+		"Ι",
+		"Φ",
+		"Μ",
+		"Α",
+		"Μ",
+		"Ι",
+		"Ι",
+		"Α",
+		"Σ",
+		"Ο",
+		"Ν",
 		"Δ"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
 	"days-format-abbr": [
-		"Κυρ", 
-		"Δευ", 
-		"Τρι", 
-		"Τετ", 
-		"Πεμ", 
-		"Παρ", 
+		"Κυρ",
+		"Δευ",
+		"Τρι",
+		"Τετ",
+		"Πεμ",
+		"Παρ",
 		"Σαβ"
-	], 
+	],
 	"eraNames": [
-		"π.Χ.", 
+		"π.Χ.",
 		"μ.Χ."
-	], 
+	],
 	"days-format-narrow": [
-		"Κ", 
-		"Δ", 
-		"Τ", 
-		"Τ", 
-		"Π", 
-		"Π", 
+		"Κ",
+		"Δ",
+		"Τ",
+		"Τ",
+		"Π",
+		"Π",
 		"Σ"
-	], 
-	"field-month": "Μήνας", 
+	],
+	"field-month": "Μήνας",
 	"days-standAlone-narrow": [
-		"Κ", 
-		"Δ", 
-		"Τ", 
-		"Τ", 
-		"Π", 
-		"Π", 
+		"Κ",
+		"Δ",
+		"Τ",
+		"Τ",
+		"Π",
+		"Π",
 		"Σ"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dateFormatItem-HHmm": "HH:mm", 
-	"dayPeriods-format-wide-am": "π.μ.", 
-	"dateFormatItem-MMMMEd": "E, d MMMM", 
-	"dateFormatItem-MMMMdd": "dd MMMM", 
-	"dateFormat-short": "d/M/yy", 
-	"field-second": "Δευτερόλεπτο", 
-	"dateFormatItem-yMMMEd": "EEE, d MMM y", 
-	"dateFormatItem-Ed": "E d", 
-	"field-week": "Εβδομάδα", 
-	"dateFormat-medium": "d MMM y", 
-	"dateFormatItem-mmss": "mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-HHmm": "HH:mm",
+	"dayPeriods-format-wide-am": "π.μ.",
+	"dateFormatItem-MMMMEd": "E, d MMMM",
+	"dateFormatItem-MMMMdd": "dd MMMM",
+	"dateFormat-short": "d/M/yy",
+	"field-second": "Δευτερόλεπτο",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "Εβδομάδα",
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-mmss": "mm:ss",
 	"dateFormatItem-yyyy": "y"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/hebrew.js b/dojo/cldr/nls/el/hebrew.js
new file mode 100644
index 0000000..f5dea6c
--- /dev/null
+++ b/dojo/cldr/nls/el/hebrew.js
@@ -0,0 +1,73 @@
+define(
+//begin v1.x content
+{
+	"quarters-format-abbr": [
+		"Τ1",
+		"Τ2",
+		"Τ3",
+		"Τ4"
+	],
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"eraNarrow": [
+		"π.μ."
+	],
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-EEEd": "EEE d",
+	"eraNames": [
+		"π.μ."
+	],
+	"days-standAlone-narrow": [
+		"Κ",
+		"Δ",
+		"Τ",
+		"Τ",
+		"Π",
+		"Π",
+		"Σ"
+	],
+	"dayPeriods-format-wide-pm": "μ.μ.",
+	"dayPeriods-format-wide-am": "π.μ.",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormat-long": "d MMMM y",
+	"dateFormat-short": "d/M/yy",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-yM": "M/yyyy",
+	"timeFormat-short": "h:mm a",
+	"eraAbbr": [
+		"π.μ."
+	],
+	"timeFormat-long": "h:mm:ss a z",
+	"days-format-wide": [
+		"Κυριακή",
+		"Δευτέρα",
+		"Τρίτη",
+		"Τετάρτη",
+		"Πέμπτη",
+		"Παρασκευή",
+		"Σάββατο"
+	],
+	"dateFormatItem-yMMM": "LLL y",
+	"quarters-format-wide": [
+		"1ο τρίμηνο",
+		"2ο τρίμηνο",
+		"3ο τρίμηνο",
+		"4ο τρίμηνο"
+	],
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-MMMd": "d MMM",
+	"days-format-abbr": [
+		"Κυρ",
+		"Δευ",
+		"Τρι",
+		"Τετ",
+		"Πεμ",
+		"Παρ",
+		"Σαβ"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/el/number.js b/dojo/cldr/nls/el/number.js
index dc8f31b..e8ef918 100644
--- a/dojo/cldr/nls/el/number.js
+++ b/dojo/cldr/nls/el/number.js
@@ -1,17 +1,20 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':",",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"e",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "e",
+	"percentFormat": "#,##0%",
+	"list": ",",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/currency.js b/dojo/cldr/nls/en-au/currency.js
index 9e256e1..3c35382 100644
--- a/dojo/cldr/nls/en-au/currency.js
+++ b/dojo/cldr/nls/en-au/currency.js
@@ -1,6 +1,8 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_symbol:"$",
-	USD_symbol:"US$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"AUD_symbol": "$",
+	"USD_symbol": "US$"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/gregorian.js b/dojo/cldr/nls/en-au/gregorian.js
index 2090a99..f980e6a 100644
--- a/dojo/cldr/nls/en-au/gregorian.js
+++ b/dojo/cldr/nls/en-au/gregorian.js
@@ -1,15 +1,17 @@
-// generated from ldml/main/*.xml, xpath: ldml/calendars/calendar-gregorian
-({
-	'dateFormat-full': "EEEE, d MMMM y",
-	'dateFormat-long': "d MMMM y",
-	'dateFormat-medium': "dd/MM/yyyy",
-	'dateFormat-short': "d/MM/yy",
-	'dateFormatItem-MEd':"E, d/M",
-	'dateFormatItem-MMdd':"dd/MM",
-	'dateFormatItem-MMMEd':"E, d MMM",
-	'dateFormatItem-MMMMd':"d MMMM",
-	'dateFormatItem-yMEd':"EEE, d/M/y",
-	'dateFormatItem-yyyyMM':"MM/yyyy",
-	'dateFormatItem-yyyyMMMM':"MMMM y"
-})
-                        
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yMEd": "EEE, d/M/y",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormat-short": "d/MM/yy",
+	"dateFormat-long": "d MMMM y",
+	"dateFormatItem-MMMEd": "E, d MMM"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-au/number.js b/dojo/cldr/nls/en-au/number.js
index eef8f4d..376cdeb 100644
--- a/dojo/cldr/nls/en-au/number.js
+++ b/dojo/cldr/nls/en-au/number.js
@@ -1,4 +1,7 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'currencyFormat':"¤#,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"currencyFormat": "¤#,##0.00"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-ca/currency.js b/dojo/cldr/nls/en-ca/currency.js
index a80668d..ff0a7d7 100644
--- a/dojo/cldr/nls/en-ca/currency.js
+++ b/dojo/cldr/nls/en-ca/currency.js
@@ -1,6 +1,8 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	CAD_symbol:"$",
-	USD_symbol:"US$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"CAD_symbol": "$",
+	"USD_symbol": "US$"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-ca/gregorian.js b/dojo/cldr/nls/en-ca/gregorian.js
index 987ecb5..5b4b77d 100644
--- a/dojo/cldr/nls/en-ca/gregorian.js
+++ b/dojo/cldr/nls/en-ca/gregorian.js
@@ -1,18 +1,20 @@
-// generated from ldml/main/*.xml, xpath: ldml/calendars/calendar-gregorian
-({
-	'dateFormat-full': "EEEE, d MMMM, y",
-	'dateFormat-long': "d MMMM, y",
-	'dateFormat-medium': "yyyy-MM-dd",
-	'dateFormat-short': "yy-MM-dd",
-	'dateFormatItem-Md':"M-d",
-	'dateFormatItem-MEd':"E, M-d",
-	'dateFormatItem-MMdd':"MM-dd",
-	'dateFormatItem-MMMd':"d MMM",
-	'dateFormatItem-MMMEd':"E, d MMM",
-	'dateFormatItem-MMMMd':"d MMMM",
-	'dateFormatItem-MMMMEd':"E, d MMMM",
-	'dateFormatItem-yMEd':"EEE, y-M-d",
-	'dateFormatItem-yMMMEd':"EEE, d MMM, y",
-	'dateFormatItem-yyMMM':"MMM-yy"
-})
-                        
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yMMMEd": "EEE, d MMM, y",
+	"dateFormatItem-yyMMM": "MMM-yy",
+	"dateFormatItem-Md": "M-d",
+	"dateFormatItem-yMEd": "EEE, y-M-d",
+	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-MMMMEd": "E, d MMMM",
+	"dateFormat-medium": "yyyy-MM-dd",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MMdd": "MM-dd",
+	"dateFormat-full": "EEEE, d MMMM, y",
+	"dateFormat-short": "yy-MM-dd",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormat-long": "d MMMM, y",
+	"dateFormatItem-MMMEd": "E, d MMM"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/buddhist.js b/dojo/cldr/nls/en-gb/buddhist.js
new file mode 100644
index 0000000..e75d023
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/buddhist.js
@@ -0,0 +1,101 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yMEd": "EEE, d/M/y G",
+	"dateFormatItem-yyMMM": "MMM y G",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-Md": "d/M",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yyyyMM": "MM/y G",
+	"dateFormat-long": "d MMMM y G",
+	"dateFormat-short": "dd/MM/y G",
+	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
+	"months-format-wide": [
+		"January",
+		"February",
+		"March",
+		"April",
+		"May",
+		"June",
+		"July",
+		"August",
+		"September",
+		"October",
+		"November",
+		"December"
+	],
+	"dateFormatItem-yM": "M/y",
+	"months-format-abbr": [
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"May",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Oct",
+		"Nov",
+		"Dec"
+	],
+	"days-format-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
+	],
+	"dateFormatItem-yQ": "Q y",
+	"dateFormatItem-yMMM": "MMM y",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
+	],
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/gregorian.js b/dojo/cldr/nls/en-gb/gregorian.js
index 3eb850e..9dd92d2 100644
--- a/dojo/cldr/nls/en-gb/gregorian.js
+++ b/dojo/cldr/nls/en-gb/gregorian.js
@@ -1,21 +1,23 @@
-// generated from ldml/main/*.xml, xpath: ldml/calendars/calendar-gregorian
-({
-	'dateFormat-full': "EEEE, d MMMM y",
-	'dateFormat-long': "d MMMM y",
-	'dateFormat-medium': "d MMM y",
-	'dateFormat-short': "dd/MM/yyyy",
-	'timeFormat-full': "HH:mm:ss zzzz",
-	'timeFormat-long': "HH:mm:ss z",
-	'timeFormat-medium': "HH:mm:ss",
-	'timeFormat-short': "HH:mm",
-	'dateFormatItem-Md':"d/M",
-	'dateFormatItem-MEd':"E, d/M",
-	'dateFormatItem-MMdd':"dd/MM",
-	'dateFormatItem-MMMEd':"E d MMM",
-	'dateFormatItem-MMMMd':"d MMMM",
-	'dateFormatItem-yMEd':"EEE, d/M/yyyy",
-	'dateFormatItem-yyMMM':"MMM yy",
-	'dateFormatItem-yyyyMM':"MM/yyyy",
-	'dateFormatItem-yyyyMMMM':"MMMM y"
-})
-                        
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yyMMM": "MMM yy",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"timeFormat-long": "HH:mm:ss z",
+	"timeFormat-short": "HH:mm",
+	"dateFormat-short": "dd/MM/yyyy",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormat-long": "d MMMM y",
+	"dateFormatItem-MMMEd": "E d MMM"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/islamic.js b/dojo/cldr/nls/en-gb/islamic.js
new file mode 100644
index 0000000..f0dceb9
--- /dev/null
+++ b/dojo/cldr/nls/en-gb/islamic.js
@@ -0,0 +1,153 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-MMdd": "dd/MM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"eraNarrow": [
+		"AH"
+	],
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-yyMMM": "MMM y G",
+	"dateFormatItem-Md": "d/M",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"eraNames": [
+		"AH"
+	],
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yyyyMEd": "EEE, d/M/y G",
+	"dateFormatItem-yyyyMMMM": "MMMM y G",
+	"dateFormatItem-MMMMd": "d MMMM",
+	"months-standAlone-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yyyyMM": "MM/y G",
+	"dateFormat-long": "d MMMM y G",
+	"dateFormat-short": "dd/MM/y G",
+	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
+	"months-format-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yM": "M/y",
+	"months-format-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"days-format-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
+	],
+	"dateFormatItem-yQ": "Q y",
+	"dateFormatItem-yMMM": "MMM y",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
+	],
+	"dateFormatItem-yyyyMd": "d/M/y G",
+	"dateFormat-full": "EEEE, d MMMM y G",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en-gb/number.js b/dojo/cldr/nls/en-gb/number.js
index eef8f4d..376cdeb 100644
--- a/dojo/cldr/nls/en-gb/number.js
+++ b/dojo/cldr/nls/en-gb/number.js
@@ -1,4 +1,7 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'currencyFormat':"¤#,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"currencyFormat": "¤#,##0.00"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/buddhist.js b/dojo/cldr/nls/en/buddhist.js
new file mode 100644
index 0000000..98d6067
--- /dev/null
+++ b/dojo/cldr/nls/en/buddhist.js
@@ -0,0 +1,109 @@
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "MMM d, y G",
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"dateFormatItem-MEd": "E, M/d",
+	"dateFormatItem-yMEd": "EEE, M/d/y G",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormatItem-Md": "M/d",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dateFormatItem-EEEd": "d EEE",
+	"dateFormatItem-M": "L",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"dateFormatItem-yQQQ": "QQQ y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormat-long": "MMMM d, y G",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormat-short": "M/d/yy G",
+	"dateFormatItem-yMMMEd": "EEE, MMM d, y G",
+	"months-format-wide": [
+		"January",
+		"February",
+		"March",
+		"April",
+		"May",
+		"June",
+		"July",
+		"August",
+		"September",
+		"October",
+		"November",
+		"December"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-yM": "M/y G",
+	"timeFormat-short": "h:mm a",
+	"months-format-abbr": [
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"May",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Oct",
+		"Nov",
+		"Dec"
+	],
+	"timeFormat-long": "h:mm:ss a z",
+	"days-format-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
+	],
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQ": "Q y G",
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-yMMM": "MMM y G",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
+	],
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"dateFormatItem-MMMd": "MMM d",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/currency.js b/dojo/cldr/nls/en/currency.js
index 8ee34ae..49186d3 100644
--- a/dojo/cldr/nls/en/currency.js
+++ b/dojo/cldr/nls/en/currency.js
@@ -1,15 +1,17 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Australian Dollar",
-	CAD_displayName:"Canadian Dollar",
-	CHF_displayName:"Swiss Franc",
-	CNY_displayName:"Chinese Yuan Renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"British Pound Sterling",
-	HKD_displayName:"Hong Kong Dollar",
-	JPY_displayName:"Japanese Yen",
-	JPY_symbol:"¥",
-	USD_displayName:"US Dollar",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hong Kong Dollar",
+	"CHF_displayName": "Swiss Franc",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "Canadian Dollar",
+	"CNY_displayName": "Chinese Yuan",
+	"USD_symbol": "$",
+	"AUD_displayName": "Australian Dollar",
+	"JPY_displayName": "Japanese Yen",
+	"USD_displayName": "US Dollar",
+	"GBP_displayName": "British Pound Sterling",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/gregorian.js b/dojo/cldr/nls/en/gregorian.js
index 8262b0f..b1e5f4b 100644
--- a/dojo/cldr/nls/en/gregorian.js
+++ b/dojo/cldr/nls/en/gregorian.js
@@ -1,225 +1,229 @@
-({
-	"dateFormatItem-yM": "M/y", 
-	"field-dayperiod": "AM/PM", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormatItem-yQ": "Q y", 
-	"field-minute": "Minute", 
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"field-dayperiod": "AM/PM",
+	"dateFormatItem-yQ": "Q y",
+	"dayPeriods-format-wide-pm": "PM",
+	"field-minute": "Minute",
 	"eraNames": [
-		"Before Christ", 
+		"Before Christ",
 		"Anno Domini"
-	], 
-	"dateFormatItem-MMMEd": "E, MMM d", 
-	"dateTimeFormat-full": "{1} {0}", 
-	"field-day-relative+-1": "Yesterday", 
-	"dateFormatItem-hms": "h:mm:ss a", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"field-weekday": "Day of the Week", 
+	],
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day-relative+-1": "Yesterday",
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
 	"days-standAlone-wide": [
-		"Sunday", 
-		"Monday", 
-		"Tuesday", 
-		"Wednesday", 
-		"Thursday", 
-		"Friday", 
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
 		"Saturday"
-	], 
-	"dateFormatItem-MMM": "LLL", 
+	],
+	"dateFormatItem-MMM": "LLL",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"field-era": "Era", 
-	"field-hour": "Hour", 
-	"dateFormatItem-y": "y", 
-	"timeFormat-full": "h:mm:ss a zzzz", 
+	],
+	"dateTimeFormat-short": "{1} {0}",
+	"field-era": "Era",
+	"field-hour": "Hour",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-y": "y",
+	"timeFormat-full": "h:mm:ss a zzzz",
 	"months-standAlone-abbr": [
-		"Jan", 
-		"Feb", 
-		"Mar", 
-		"Apr", 
-		"May", 
-		"Jun", 
-		"Jul", 
-		"Aug", 
-		"Sep", 
-		"Oct", 
-		"Nov", 
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"May",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Oct",
+		"Nov",
 		"Dec"
-	], 
-	"dateFormatItem-yMMM": "MMM y", 
-	"field-day-relative+0": "Today", 
+	],
+	"dateFormatItem-yMMM": "MMM y",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
 	"days-standAlone-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"W", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
 		"S"
-	], 
-	"field-day-relative+1": "Tomorrow", 
+	],
 	"eraAbbr": [
-		"BC", 
+		"BC",
 		"AD"
-	], 
-	"dateFormat-long": "MMMM d, y", 
-	"timeFormat-medium": "h:mm:ss a", 
-	"dateFormatItem-EEEd": "d EEE", 
-	"field-zone": "Zone", 
-	"dateFormatItem-Hm": "HH:mm", 
-	"dateFormat-medium": "MMM d, y", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormat-long": "MMMM d, y",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-EEEd": "d EEE",
+	"field-zone": "Zone",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "MMM d, y",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"quarters-standAlone-wide": [
-		"1st quarter", 
-		"2nd quarter", 
-		"3rd quarter", 
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
 		"4th quarter"
-	], 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-year": "Year", 
+	],
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "Year",
 	"quarters-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateTimeFormat-long": "{1} {0}", 
-	"field-week": "Week", 
+	],
+	"dateTimeFormat-long": "{1} {0}",
+	"field-week": "Week",
 	"months-standAlone-wide": [
-		"January", 
-		"February", 
-		"March", 
-		"April", 
-		"May", 
-		"June", 
-		"July", 
-		"August", 
-		"September", 
-		"October", 
-		"November", 
+		"January",
+		"February",
+		"March",
+		"April",
+		"May",
+		"June",
+		"July",
+		"August",
+		"September",
+		"October",
+		"November",
 		"December"
-	], 
-	"dateFormatItem-MMMd": "MMM d", 
-	"timeFormat-long": "h:mm:ss a z", 
+	],
+	"dateFormatItem-MMMd": "MMM d",
+	"timeFormat-long": "h:mm:ss a z",
 	"months-format-abbr": [
-		"Jan", 
-		"Feb", 
-		"Mar", 
-		"Apr", 
-		"May", 
-		"Jun", 
-		"Jul", 
-		"Aug", 
-		"Sep", 
-		"Oct", 
-		"Nov", 
+		"Jan",
+		"Feb",
+		"Mar",
+		"Apr",
+		"May",
+		"Jun",
+		"Jul",
+		"Aug",
+		"Sep",
+		"Oct",
+		"Nov",
 		"Dec"
-	], 
-	"dayPeriods-format-wide-noon": "noon", 
-	"timeFormat-short": "h:mm a", 
-	"field-month": "Month", 
+	],
+	"dayPeriods-format-wide-noon": "noon",
+	"timeFormat-short": "h:mm a",
+	"field-month": "Month",
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"days-format-abbr": [
-		"Sun", 
-		"Mon", 
-		"Tue", 
-		"Wed", 
-		"Thu", 
-		"Fri", 
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
 		"Sat"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-format-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"W", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
 		"S"
-	], 
-	"field-second": "Second", 
-	"field-day": "Day", 
-	"dateFormatItem-MEd": "E, M/d", 
+	],
+	"field-second": "Second",
+	"field-day": "Day",
+	"dateFormatItem-MEd": "E, M/d",
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-hm": "h:mm a", 
+	],
+	"dateFormatItem-hm": "h:mm a",
 	"days-standAlone-abbr": [
-		"Sun", 
-		"Mon", 
-		"Tue", 
-		"Wed", 
-		"Thu", 
-		"Fri", 
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
 		"Sat"
-	], 
-	"dateFormat-short": "M/d/yy", 
-	"dateFormatItem-yMMMEd": "EEE, MMM d, y", 
-	"dateFormat-full": "EEEE, MMMM d, y", 
-	"dateFormatItem-Md": "M/d", 
-	"dateFormatItem-yMEd": "EEE, M/d/y", 
+	],
+	"dateFormat-short": "M/d/yy",
+	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
+	"dateFormat-full": "EEEE, MMMM d, y",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yMEd": "EEE, M/d/y",
 	"months-format-wide": [
-		"January", 
-		"February", 
-		"March", 
-		"April", 
-		"May", 
-		"June", 
-		"July", 
-		"August", 
-		"September", 
-		"October", 
-		"November", 
+		"January",
+		"February",
+		"March",
+		"April",
+		"May",
+		"June",
+		"July",
+		"August",
+		"September",
+		"October",
+		"November",
 		"December"
-	], 
-	"dateFormatItem-d": "d", 
+	],
+	"dateFormatItem-d": "d",
 	"quarters-format-wide": [
-		"1st quarter", 
-		"2nd quarter", 
-		"3rd quarter", 
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
 		"4th quarter"
-	], 
+	],
 	"days-format-wide": [
-		"Sunday", 
-		"Monday", 
-		"Tuesday", 
-		"Wednesday", 
-		"Thursday", 
-		"Friday", 
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
 		"Saturday"
-	], 
+	],
 	"eraNarrow": [
-		"B", 
+		"B",
 		"A"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/islamic.js b/dojo/cldr/nls/en/islamic.js
new file mode 100644
index 0000000..f61fafb
--- /dev/null
+++ b/dojo/cldr/nls/en/islamic.js
@@ -0,0 +1,166 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"dateFormatItem-yyyyMMMEd": "EEE, MMM d, y G",
+	"dateFormatItem-yQ": "Q y",
+	"eraNames": [
+		"AH"
+	],
+	"dateFormatItem-MMMEd": "E, MMM d",
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"timeFormat-full": "h:mm:ss a zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"dateFormatItem-yMMM": "MMM y",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"W",
+		"T",
+		"F",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"dateFormat-long": "MMMM d, y G",
+	"timeFormat-medium": "h:mm:ss a",
+	"dateFormatItem-EEEd": "d EEE",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "MMM d, y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-ms": "mm:ss",
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyMEd": "EEE, M/d/y G",
+	"dateFormatItem-MMMd": "MMM d",
+	"timeFormat-long": "h:mm:ss a z",
+	"months-format-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"timeFormat-short": "h:mm a",
+	"days-format-abbr": [
+		"Sun",
+		"Mon",
+		"Tue",
+		"Wed",
+		"Thu",
+		"Fri",
+		"Sat"
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E, M/d",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateFormat-short": "M/d/yy G",
+	"dateFormatItem-yyyyM": "M/y G",
+	"dateFormatItem-yMMMEd": "EEE, MMM d, y",
+	"dateFormat-full": "EEEE, MMMM d, y G",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yyyyQ": "Q y G",
+	"dateFormatItem-yMEd": "EEE, M/d/y",
+	"months-format-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1st quarter",
+		"2nd quarter",
+		"3rd quarter",
+		"4th quarter"
+	],
+	"eraNarrow": [
+		"AH"
+	],
+	"days-format-wide": [
+		"Sunday",
+		"Monday",
+		"Tuesday",
+		"Wednesday",
+		"Thursday",
+		"Friday",
+		"Saturday"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/en/number.js b/dojo/cldr/nls/en/number.js
index 2b73f19..3f94169 100644
--- a/dojo/cldr/nls/en/number.js
+++ b/dojo/cldr/nls/en/number.js
@@ -1,19 +1,23 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤#,##0.00;(¤#,##0.00)"
-})
+define(
+//begin v1.x content
+{
+	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+",
+	"decimalFormat-short": "000T"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/buddhist.js b/dojo/cldr/nls/es/buddhist.js
new file mode 100644
index 0000000..426c223
--- /dev/null
+++ b/dojo/cldr/nls/es/buddhist.js
@@ -0,0 +1,125 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y G",
+	"dateFormatItem-yQ": "Q y G",
+	"dayPeriods-format-wide-pm": "p.m.",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y G",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"E",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dayPeriods-format-wide-am": "a.m.",
+	"dateFormatItem-y": "y G",
+	"dateFormatItem-MMMdd": "dd-MMM",
+	"dateFormatItem-yMMM": "MMM y G",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"dateFormatItem-yyyyMM": "MM/y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"dateFormatItem-EEEd": "EEE d",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-MMd": "d/MM",
+	"dateFormatItem-yyMM": "MM/y G",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-yyMMM": "MMM-y G",
+	"dateFormatItem-yyQQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-yMd": "d/M/y G",
+	"dateFormatItem-yMMMM": "MMMM 'de' y G",
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-yyQ": "Q y G",
+	"months-format-abbr": [
+		"ene",
+		"feb",
+		"mar",
+		"abr",
+		"may",
+		"jun",
+		"jul",
+		"ago",
+		"sep",
+		"oct",
+		"nov",
+		"dic"
+	],
+	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"lun",
+		"mar",
+		"mié",
+		"jue",
+		"vie",
+		"sáb"
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yMMMd": "d MMM y G",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/y G",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y G",
+	"dateFormat-full": "EEEE d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "EEE d/M/y G",
+	"months-format-wide": [
+		"enero",
+		"febrero",
+		"marzo",
+		"abril",
+		"mayo",
+		"junio",
+		"julio",
+		"agosto",
+		"septiembre",
+		"octubre",
+		"noviembre",
+		"diciembre"
+	],
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1er trimestre",
+		"2º trimestre",
+		"3er trimestre",
+		"4º trimestre"
+	],
+	"days-format-wide": [
+		"domingo",
+		"lunes",
+		"martes",
+		"miércoles",
+		"jueves",
+		"viernes",
+		"sábado"
+	],
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/currency.js b/dojo/cldr/nls/es/currency.js
index d150af7..1498e01 100644
--- a/dojo/cldr/nls/es/currency.js
+++ b/dojo/cldr/nls/es/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"dólar australiano",
-	CAD_displayName:"dólar canadiense",
-	CHF_displayName:"franco suizo",
-	CNY_displayName:"yuan renminbi chino",
-	EUR_displayName:"euro",
-	GBP_displayName:"libra esterlina británica",
-	HKD_displayName:"dólar de Hong Kong",
-	JPY_displayName:"yen japonés",
-	USD_displayName:"dólar estadounidense"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "dólar de Hong Kong",
+	"CHF_displayName": "franco suizo",
+	"CAD_displayName": "dólar canadiense",
+	"CNY_displayName": "yuan renminbi chino",
+	"AUD_displayName": "dólar australiano",
+	"JPY_displayName": "yen japonés",
+	"USD_displayName": "dólar estadounidense",
+	"GBP_displayName": "libra esterlina británica",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/gregorian.js b/dojo/cldr/nls/es/gregorian.js
index 7126948..d9b5c74 100644
--- a/dojo/cldr/nls/es/gregorian.js
+++ b/dojo/cldr/nls/es/gregorian.js
@@ -1,234 +1,238 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"E", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"E",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "día de la semana", 
-	"dateFormatItem-yyQQQQ": "QQQQ 'de' yy", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE d/M/y", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"field-weekday": "día de la semana",
+	"dateFormatItem-yyQQQQ": "QQQQ 'de' yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE d/M/y",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"a.C.", 
+		"a.C.",
 		"d.C."
-	], 
-	"dateFormatItem-MMMdd": "dd-MMM", 
-	"dateFormat-long": "d 'de' MMMM 'de' y", 
+	],
+	"dateFormatItem-MMMdd": "dd-MMM",
+	"dateFormat-long": "d 'de' MMMM 'de' y",
 	"months-format-wide": [
-		"enero", 
-		"febrero", 
-		"marzo", 
-		"abril", 
-		"mayo", 
-		"junio", 
-		"julio", 
-		"agosto", 
-		"septiembre", 
-		"octubre", 
-		"noviembre", 
+		"enero",
+		"febrero",
+		"marzo",
+		"abril",
+		"mayo",
+		"junio",
+		"julio",
+		"agosto",
+		"septiembre",
+		"octubre",
+		"noviembre",
 		"diciembre"
-	], 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dayPeriods-format-wide-pm": "p.m.", 
-	"dateFormat-full": "EEEE d 'de' MMMM 'de' y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "era", 
-	"dateFormatItem-yM": "M/y", 
+	],
+	"dateFormatItem-EEEd": "EEE d",
+	"dayPeriods-format-wide-pm": "p.m.",
+	"dateFormat-full": "EEEE d 'de' MMMM 'de' y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "era",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
-		"enero", 
-		"febrero", 
-		"marzo", 
-		"abril", 
-		"mayo", 
-		"junio", 
-		"julio", 
-		"agosto", 
-		"septiembre", 
-		"octubre", 
-		"noviembre", 
+		"enero",
+		"febrero",
+		"marzo",
+		"abril",
+		"mayo",
+		"junio",
+		"julio",
+		"agosto",
+		"septiembre",
+		"octubre",
+		"noviembre",
 		"diciembre"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1er trimestre", 
-		"2º trimestre", 
-		"3er trimestre", 
+		"1er trimestre",
+		"2º trimestre",
+		"3er trimestre",
 		"4º trimestre"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "año", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q y", 
-	"field-hour": "hora", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "año",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q y",
+	"field-hour": "hora",
 	"months-format-abbr": [
-		"ene", 
-		"feb", 
-		"mar", 
-		"abr", 
-		"may", 
-		"jun", 
-		"jul", 
-		"ago", 
-		"sep", 
-		"oct", 
-		"nov", 
+		"ene",
+		"feb",
+		"mar",
+		"abr",
+		"may",
+		"jun",
+		"jul",
+		"ago",
+		"sep",
+		"oct",
+		"nov",
 		"dic"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "hoy", 
-	"field-day-relative+1": "mañana", 
-	"field-day-relative+2": "pasado mañana", 
-	"field-day-relative+3": "Dentro de tres días", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "hoy",
+	"field-day-relative+1": "mañana",
+	"field-day-relative+2": "pasado mañana",
+	"field-day-relative+3": "Dentro de tres días",
 	"months-standAlone-abbr": [
-		"ene", 
-		"feb", 
-		"mar", 
-		"abr", 
-		"may", 
-		"jun", 
-		"jul", 
-		"ago", 
-		"sep", 
-		"oct", 
-		"nov", 
+		"ene",
+		"feb",
+		"mar",
+		"abr",
+		"may",
+		"jun",
+		"jul",
+		"ago",
+		"sep",
+		"oct",
+		"nov",
 		"dic"
-	], 
+	],
 	"quarters-format-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1er trimestre", 
-		"2º trimestre", 
-		"3er trimestre", 
+		"1er trimestre",
+		"2º trimestre",
+		"3er trimestre",
 		"4º trimestre"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"domingo", 
-		"lunes", 
-		"martes", 
-		"miércoles", 
-		"jueves", 
-		"viernes", 
+		"domingo",
+		"lunes",
+		"martes",
+		"miércoles",
+		"jueves",
+		"viernes",
 		"sábado"
-	], 
-	"dateFormatItem-MMMMd": "d 'de' MMMM", 
-	"dateFormatItem-yyMMM": "MMM-yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"dateFormatItem-yyMMM": "MMM-yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"eraAbbr": [
-		"a.C.", 
+		"a.C.",
 		"d.C."
-	], 
-	"field-minute": "minuto", 
-	"field-dayperiod": "periodo del día", 
+	],
+	"field-minute": "minuto",
+	"field-dayperiod": "periodo del día",
 	"days-standAlone-abbr": [
-		"dom", 
-		"lun", 
-		"mar", 
-		"mié", 
-		"jue", 
-		"vie", 
+		"dom",
+		"lun",
+		"mar",
+		"mié",
+		"jue",
+		"vie",
 		"sáb"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "ayer", 
-	"dateFormatItem-h": "hh a", 
-	"field-day-relative+-2": "antes de ayer", 
-	"field-day-relative+-3": "Hace tres días", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "E, d/M", 
-	"dateFormatItem-yMMMM": "MMMM 'de' y", 
-	"field-day": "día", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "ayer",
+	"dateFormatItem-h": "hh a",
+	"field-day-relative+-2": "antes de ayer",
+	"field-day-relative+-3": "Hace tres días",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yMMMM": "MMMM 'de' y",
+	"field-day": "día",
 	"days-format-wide": [
-		"domingo", 
-		"lunes", 
-		"martes", 
-		"miércoles", 
-		"jueves", 
-		"viernes", 
+		"domingo",
+		"lunes",
+		"martes",
+		"miércoles",
+		"jueves",
+		"viernes",
 		"sábado"
-	], 
-	"field-zone": "zona", 
-	"dateFormatItem-yyyyMM": "MM/yyyy", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "zona",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"E", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"E",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
-	"dateFormatItem-hm": "hh:mm a", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
+	"dateFormatItem-hm": "hh:mm a",
 	"days-format-abbr": [
-		"dom", 
-		"lun", 
-		"mar", 
-		"mié", 
-		"jue", 
-		"vie", 
+		"dom",
+		"lun",
+		"mar",
+		"mié",
+		"jue",
+		"vie",
 		"sáb"
-	], 
+	],
 	"eraNames": [
-		"antes de Cristo", 
+		"antes de Cristo",
 		"anno Dómini"
-	], 
+	],
 	"days-format-narrow": [
-		"D", 
-		"L", 
-		"M", 
-		"M", 
-		"J", 
-		"V", 
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
 		"S"
-	], 
-	"field-month": "mes", 
+	],
+	"field-month": "mes",
 	"days-standAlone-narrow": [
-		"D", 
-		"L", 
-		"M", 
-		"M", 
-		"J", 
-		"V", 
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
 		"S"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "a.m.", 
-	"dateFormat-short": "dd/MM/yy", 
-	"dateFormatItem-MMd": "d/MM", 
-	"field-second": "segundo", 
-	"dateFormatItem-yMMMEd": "EEE, d MMM y", 
-	"field-week": "semana", 
-	"dateFormat-medium": "dd/MM/yyyy", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "a.m.",
+	"dateFormat-short": "dd/MM/yy",
+	"dateFormatItem-MMd": "d/MM",
+	"field-second": "segundo",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"field-week": "semana",
+	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "hh:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/islamic.js b/dojo/cldr/nls/es/islamic.js
new file mode 100644
index 0000000..8d6f3dd
--- /dev/null
+++ b/dojo/cldr/nls/es/islamic.js
@@ -0,0 +1,179 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/y",
+	"dateFormatItem-yyyyMMMEd": "EEE, d MMM y G",
+	"dateFormatItem-yQ": "Q y",
+	"dayPeriods-format-wide-pm": "p.m.",
+	"eraNames": [
+		"AH"
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateFormatItem-hms": "hh:mm:ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dayPeriods-format-wide-am": "a.m.",
+	"dateFormatItem-MMMdd": "dd-MMM",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"dateFormatItem-yMMM": "MMM y",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"eraAbbr": [
+		"AH"
+	],
+	"dateFormatItem-yyyyMMMM": "MMMM 'de' y G",
+	"dateFormat-long": "d 'de' MMMM 'de' y G",
+	"dateFormatItem-EEEd": "EEE d",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormatItem-MMd": "d/MM",
+	"dateFormatItem-yyMM": "MM/y G",
+	"dateFormat-medium": "dd/MM/y G",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-yyMMM": "MMM-y G",
+	"dateFormatItem-yyQQQQ": "QQQQ 'de' y G",
+	"dateFormatItem-ms": "mm:ss",
+	"months-standAlone-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyMEd": "EEE d/M/y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-yyQ": "Q y G",
+	"months-format-abbr": [
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
+		"Dhuʻl-H."
+	],
+	"dateFormatItem-MMMMd": "d 'de' MMMM",
+	"quarters-format-abbr": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"days-format-abbr": [
+		"dom",
+		"lun",
+		"mar",
+		"mié",
+		"jue",
+		"vie",
+		"sáb"
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"months-format-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-hm": "hh:mm a",
+	"dateFormat-short": "dd/MM/y G",
+	"dateFormatItem-yyyyM": "M/y G",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormat-full": "EEEE d 'de' MMMM 'de' y G",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yyyyQ": "Q y G",
+	"dateFormatItem-yMEd": "EEE d/M/y",
+	"months-format-wide": [
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
+		"Dhuʻl-Hijjah"
+	],
+	"dateFormatItem-yyyyMMM": "MMM y G",
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1er trimestre",
+		"2º trimestre",
+		"3er trimestre",
+		"4º trimestre"
+	],
+	"eraNarrow": [
+		"AH"
+	],
+	"days-format-wide": [
+		"domingo",
+		"lunes",
+		"martes",
+		"miércoles",
+		"jueves",
+		"viernes",
+		"sábado"
+	],
+	"dateFormatItem-h": "hh a"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/es/number.js b/dojo/cldr/nls/es/number.js
index 4ca5f3c..06a3f68 100644
--- a/dojo/cldr/nls/es/number.js
+++ b/dojo/cldr/nls/es/number.js
@@ -1,18 +1,21 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤ #,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤ #,##0.00",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/buddhist.js b/dojo/cldr/nls/fi/buddhist.js
new file mode 100644
index 0000000..5c70514
--- /dev/null
+++ b/dojo/cldr/nls/fi/buddhist.js
@@ -0,0 +1,166 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "L.y G",
+	"dateFormatItem-yMMMMccccd": "cccc, d. MMMM y G",
+	"dateFormatItem-yQ": "Q/y G",
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-yQQQ": "QQQ y G",
+	"days-standAlone-wide": [
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
+		"lauantai"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"months-standAlone-narrow": [
+		"T",
+		"H",
+		"M",
+		"H",
+		"T",
+		"K",
+		"H",
+		"E",
+		"S",
+		"L",
+		"M",
+		"J"
+	],
+	"dateFormatItem-Gy": "y G",
+	"dayPeriods-format-wide-am": "ap.",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "H.mm.ss zzzz",
+	"months-standAlone-abbr": [
+		"tammi",
+		"helmi",
+		"maalis",
+		"huhti",
+		"touko",
+		"kesä",
+		"heinä",
+		"elo",
+		"syys",
+		"loka",
+		"marras",
+		"joulu"
+	],
+	"dateFormatItem-Ed": "ccc d.",
+	"dateFormatItem-yMMM": "LLLL y G",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dateFormatItem-yyyyMMMM": "LLLL y G",
+	"dateFormat-long": "d. MMMM y G",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
+	"dateFormatItem-yyyyMEEEd": "EEE d.M.y G",
+	"dateFormatItem-yyMM": "M.y G",
+	"dateFormat-medium": "d.M.y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-yyMMM": "LLLL y G",
+	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"tammikuu",
+		"helmikuu",
+		"maaliskuu",
+		"huhtikuu",
+		"toukokuu",
+		"kesäkuu",
+		"heinäkuu",
+		"elokuu",
+		"syyskuu",
+		"lokakuu",
+		"marraskuu",
+		"joulukuu"
+	],
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q/y G",
+	"timeFormat-long": "H.mm.ss z",
+	"months-format-abbr": [
+		"tammikuuta",
+		"helmikuuta",
+		"maaliskuuta",
+		"huhtikuuta",
+		"toukokuuta",
+		"kesäkuuta",
+		"heinäkuuta",
+		"elokuuta",
+		"syyskuuta",
+		"lokakuuta",
+		"marraskuuta",
+		"joulukuuta"
+	],
+	"dateFormatItem-H": "H",
+	"timeFormat-short": "H.mm",
+	"quarters-format-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"days-format-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-MEd": "E d.M.",
+	"dateFormatItem-hm": "h.mm a",
+	"dayPeriods-format-abbr-pm": "ip.",
+	"dateFormat-short": "d.M.y G",
+	"dateFormatItem-yyyyM": "M.y G",
+	"dateFormatItem-yMMMEd": "EEE d. MMM y G",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yMEd": "EEE d.M.y G",
+	"months-format-wide": [
+		"tammikuuta",
+		"helmikuuta",
+		"maaliskuuta",
+		"huhtikuuta",
+		"toukokuuta",
+		"kesäkuuta",
+		"heinäkuuta",
+		"elokuuta",
+		"syyskuuta",
+		"lokakuuta",
+		"marraskuuta",
+		"joulukuuta"
+	],
+	"dayPeriods-format-abbr-am": "ap.",
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
+	"days-format-wide": [
+		"sunnuntaina",
+		"maanantaina",
+		"tiistaina",
+		"keskiviikkona",
+		"torstaina",
+		"perjantaina",
+		"lauantaina"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/currency.js b/dojo/cldr/nls/fi/currency.js
index 66a1277..a343a24 100644
--- a/dojo/cldr/nls/fi/currency.js
+++ b/dojo/cldr/nls/fi/currency.js
@@ -1,20 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Australian dollari",
-	AUD_symbol:"AUD",
-	CAD_displayName:"Kanadan dollari",
-	CAD_symbol:"CAD",
-	CHF_displayName:"Sveitsin frangi",
-	CHF_symbol:"CHF",
-	CNY_displayName:"Kiinan yuan",
-	CNY_symbol:"CNY",
-	EUR_displayName:"euro",
-	GBP_displayName:"Englannin punta",
-	HKD_displayName:"Hongkongin dollari",
-	HKD_symbol:"HKD",
-	JPY_displayName:"Japanin jeni",
-	JPY_symbol:"¥",
-	USD_displayName:"Yhdysvaltain dollari",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkongin dollari",
+	"CHF_displayName": "Sveitsin frangi",
+	"CHF_symbol": "CHF",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "Kanadan dollari",
+	"HKD_symbol": "HKD",
+	"CNY_displayName": "Kiinan yuan",
+	"USD_symbol": "$",
+	"AUD_displayName": "Australian dollari",
+	"JPY_displayName": "Japanin jeni",
+	"CAD_symbol": "CAD",
+	"USD_displayName": "Yhdysvaltain dollari",
+	"CNY_symbol": "CNY",
+	"GBP_displayName": "Englannin punta",
+	"AUD_symbol": "AUD",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/gregorian.js b/dojo/cldr/nls/fi/gregorian.js
index b930b39..cff5051 100644
--- a/dojo/cldr/nls/fi/gregorian.js
+++ b/dojo/cldr/nls/fi/gregorian.js
@@ -1,235 +1,239 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"T", 
-		"H", 
-		"M", 
-		"H", 
-		"T", 
-		"K", 
-		"H", 
-		"E", 
-		"S", 
-		"L", 
-		"M", 
+		"T",
+		"H",
+		"M",
+		"H",
+		"T",
+		"K",
+		"H",
+		"E",
+		"S",
+		"L",
+		"M",
 		"J"
-	], 
-	"field-weekday": "viikonpäivä", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE d.M.yyyy", 
-	"dateFormatItem-MMMEd": "E d. MMM", 
+	],
+	"field-weekday": "viikonpäivä",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE d.M.yyyy",
+	"dateFormatItem-MMMEd": "E d. MMM",
 	"eraNarrow": [
-		"eKr.", 
+		"eKr.",
 		"jKr."
-	], 
-	"dateFormat-long": "d. MMMM y", 
+	],
+	"dateFormat-long": "d. MMMM y",
 	"months-format-wide": [
-		"tammikuuta", 
-		"helmikuuta", 
-		"maaliskuuta", 
-		"huhtikuuta", 
-		"toukokuuta", 
-		"kesäkuuta", 
-		"heinäkuuta", 
-		"elokuuta", 
-		"syyskuuta", 
-		"lokakuuta", 
-		"marraskuuta", 
+		"tammikuuta",
+		"helmikuuta",
+		"maaliskuuta",
+		"huhtikuuta",
+		"toukokuuta",
+		"kesäkuuta",
+		"heinäkuuta",
+		"elokuuta",
+		"syyskuuta",
+		"lokakuuta",
+		"marraskuuta",
 		"joulukuuta"
-	], 
-	"dateFormatItem-EEEd": "EEE d.", 
-	"dayPeriods-format-wide-pm": "ip.", 
-	"dateFormat-full": "EEEE d. MMMM y", 
-	"dateFormatItem-Md": "d.M.", 
-	"dayPeriods-standAlone-wide-pm": "ip.", 
-	"dayPeriods-format-abbr-am": "ap.", 
-	"field-era": "aikakausi", 
-	"dateFormatItem-yM": "L.yyyy", 
+	],
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormat-full": "cccc d. MMMM y",
+	"dateFormatItem-Md": "d.M.",
+	"dayPeriods-standAlone-wide-pm": "ip.",
+	"dayPeriods-format-abbr-am": "ap.",
+	"field-era": "aikakausi",
+	"dateFormatItem-yM": "L.yyyy",
 	"months-standAlone-wide": [
-		"tammikuu", 
-		"helmikuu", 
-		"maaliskuu", 
-		"huhtikuu", 
-		"toukokuu", 
-		"kesäkuu", 
-		"heinäkuu", 
-		"elokuu", 
-		"syyskuu", 
-		"lokakuu", 
-		"marraskuu", 
+		"tammikuu",
+		"helmikuu",
+		"maaliskuu",
+		"huhtikuu",
+		"toukokuu",
+		"kesäkuu",
+		"heinäkuu",
+		"elokuu",
+		"syyskuu",
+		"lokakuu",
+		"marraskuu",
 		"joulukuu"
-	], 
-	"timeFormat-short": "H.mm", 
+	],
+	"timeFormat-short": "H.mm",
 	"quarters-format-wide": [
-		"1. neljännes", 
-		"2. neljännes", 
-		"3. neljännes", 
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
 		"4. neljännes"
-	], 
-	"timeFormat-long": "H.mm.ss z", 
-	"field-year": "vuosi", 
-	"dateFormatItem-yMMM": "LLL y", 
-	"dateFormatItem-yQ": "Q/yyyy", 
-	"dateFormatItem-yyyyMMMM": "LLLL y", 
-	"field-hour": "tunti", 
+	],
+	"timeFormat-long": "H.mm.ss z",
+	"field-year": "vuosi",
+	"dateFormatItem-yMMM": "LLL y",
+	"dateFormatItem-yQ": "Q/yyyy",
+	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"field-hour": "tunti",
 	"months-format-abbr": [
-		"tammikuuta", 
-		"helmikuuta", 
-		"maaliskuuta", 
-		"huhtikuuta", 
-		"toukokuuta", 
-		"kesäkuuta", 
-		"heinäkuuta", 
-		"elokuuta", 
-		"syyskuuta", 
-		"lokakuuta", 
-		"marraskuuta", 
+		"tammikuuta",
+		"helmikuuta",
+		"maaliskuuta",
+		"huhtikuuta",
+		"toukokuuta",
+		"kesäkuuta",
+		"heinäkuuta",
+		"elokuuta",
+		"syyskuuta",
+		"lokakuuta",
+		"marraskuuta",
 		"joulukuuta"
-	], 
-	"dateFormatItem-yyQ": "Q/yy", 
-	"timeFormat-full": "H.mm.ss zzzz", 
-	"dateFormatItem-yyyyMEEEd": "EEE d.M.yyyy", 
-	"field-day-relative+0": "tänään", 
-	"field-day-relative+1": "huomenna", 
-	"field-day-relative+2": "ylihuomenna", 
-	"dateFormatItem-H": "H", 
+	],
+	"dateFormatItem-yyQ": "Q/yy",
+	"timeFormat-full": "H.mm.ss zzzz",
+	"dateFormatItem-yyyyMEEEd": "EEE d.M.yyyy",
+	"field-day-relative+0": "tänään",
+	"field-day-relative+1": "huomenna",
+	"field-day-relative+2": "ylihuomenna",
+	"dateFormatItem-H": "H",
 	"months-standAlone-abbr": [
-		"tammi", 
-		"helmi", 
-		"maalis", 
-		"huhti", 
-		"touko", 
-		"kesä", 
-		"heinä", 
-		"elo", 
-		"syys", 
-		"loka", 
-		"marras", 
+		"tammi",
+		"helmi",
+		"maalis",
+		"huhti",
+		"touko",
+		"kesä",
+		"heinä",
+		"elo",
+		"syys",
+		"loka",
+		"marras",
 		"joulu"
-	], 
+	],
 	"quarters-format-abbr": [
-		"1. nelj.", 
-		"2. nelj.", 
-		"3. nelj.", 
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
 		"4. nelj."
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1. neljännes", 
-		"2. neljännes", 
-		"3. neljännes", 
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
 		"4. neljännes"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"sunnuntai", 
-		"maanantai", 
-		"tiistai", 
-		"keskiviikko", 
-		"torstai", 
-		"perjantai", 
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
 		"lauantai"
-	], 
-	"dateFormatItem-yyMMM": "LLLL yy", 
-	"timeFormat-medium": "H.mm.ss", 
-	"dateFormatItem-Hm": "H.mm", 
+	],
+	"dateFormatItem-yyMMM": "LLLL yy",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
 	"quarters-standAlone-abbr": [
-		"1. nelj.", 
-		"2. nelj.", 
-		"3. nelj.", 
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
 		"4. nelj."
-	], 
+	],
 	"eraAbbr": [
-		"eKr.", 
+		"eKr.",
 		"jKr."
-	], 
-	"field-minute": "minuutti", 
-	"field-dayperiod": "ap./ip.", 
+	],
+	"field-minute": "minuutti",
+	"field-dayperiod": "ap./ip.",
 	"days-standAlone-abbr": [
-		"su", 
-		"ma", 
-		"ti", 
-		"ke", 
-		"to", 
-		"pe", 
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
 		"la"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm.ss", 
-	"field-day-relative+-1": "eilen", 
-	"field-day-relative+-2": "toissapäivänä", 
-	"dateFormatItem-MMMd": "d. MMM", 
-	"dateFormatItem-MEd": "E d.M.", 
-	"field-day": "päivä", 
-	"dateFormatItem-yMMMMccccd": "cccc, d. MMMM y", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "eilen",
+	"field-day-relative+-2": "toissapäivänä",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d.M.",
+	"field-day": "päivä",
+	"dateFormatItem-yMMMMccccd": "cccc, d. MMMM y",
 	"days-format-wide": [
-		"sunnuntaina", 
-		"maanantaina", 
-		"tiistaina", 
-		"keskiviikkona", 
-		"torstaina", 
-		"perjantaina", 
+		"sunnuntaina",
+		"maanantaina",
+		"tiistaina",
+		"keskiviikkona",
+		"torstaina",
+		"perjantaina",
 		"lauantaina"
-	], 
-	"field-zone": "aikavyöhyke", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "aikavyöhyke",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"T", 
-		"H", 
-		"M", 
-		"H", 
-		"T", 
-		"K", 
-		"H", 
-		"E", 
-		"S", 
-		"L", 
-		"M", 
+		"T",
+		"H",
+		"M",
+		"H",
+		"T",
+		"K",
+		"H",
+		"E",
+		"S",
+		"L",
+		"M",
 		"J"
-	], 
-	"dateFormatItem-yyMM": "M/yy", 
-	"dateFormatItem-hm": "h.mm a", 
-	"dayPeriods-format-abbr-pm": "ip.", 
+	],
+	"dateFormatItem-yyMM": "M/yy",
+	"dateFormatItem-hm": "h.mm a",
+	"dayPeriods-format-abbr-pm": "ip.",
 	"days-format-abbr": [
-		"su", 
-		"ma", 
-		"ti", 
-		"ke", 
-		"to", 
-		"pe", 
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
 		"la"
-	], 
+	],
 	"eraNames": [
-		"ennen Kristuksen syntymää", 
+		"ennen Kristuksen syntymää",
 		"jälkeen Kristuksen syntymän"
-	], 
+	],
 	"days-format-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"K", 
-		"T", 
-		"P", 
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
 		"L"
-	], 
-	"field-month": "kuukausi", 
+	],
+	"field-month": "kuukausi",
 	"days-standAlone-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"K", 
-		"T", 
-		"P", 
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
 		"L"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "ap.", 
-	"dayPeriods-standAlone-wide-am": "ap.", 
-	"dateFormat-short": "d.M.yyyy", 
-	"field-second": "sekunti", 
-	"dateFormatItem-yMMMEd": "EEE d. MMM y", 
-	"field-week": "viikko", 
-	"dateFormat-medium": "d.M.yyyy", 
-	"dateFormatItem-yyyyM": "M/yyyy", 
-	"dateFormatItem-yyyyQQQQ": "QQQQ y", 
-	"dateFormatItem-Hms": "H.mm.ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "ap.",
+	"dayPeriods-standAlone-wide-am": "ap.",
+	"dateFormat-short": "d.M.yyyy",
+	"field-second": "sekunti",
+	"dateFormatItem-yMMMEd": "EEE d. MMM y",
+	"dateFormatItem-Ed": "ccc d.",
+	"field-week": "viikko",
+	"dateFormat-medium": "d.M.yyyy",
+	"dateFormatItem-yyyyM": "M/yyyy",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"dateFormatItem-Hms": "H.mm.ss",
 	"dateFormatItem-hms": "h.mm.ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/hebrew.js b/dojo/cldr/nls/fi/hebrew.js
new file mode 100644
index 0000000..7c60e23
--- /dev/null
+++ b/dojo/cldr/nls/fi/hebrew.js
@@ -0,0 +1,176 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "L.yyyy",
+	"dateFormatItem-yQ": "Q/yyyy",
+	"months-standAlone-abbr-leap": "adár II",
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"days-standAlone-wide": [
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
+		"lauantai"
+	],
+	"months-standAlone-narrow": [
+		"T",
+		"H",
+		"K",
+		"T",
+		"S",
+		"A",
+		"A",
+		"N",
+		"I",
+		"S",
+		"T",
+		"A",
+		"E"
+	],
+	"dayPeriods-format-wide-am": "ap.",
+	"timeFormat-full": "H.mm.ss zzzz",
+	"months-standAlone-narrow-leap": "A",
+	"months-standAlone-abbr": [
+		"tišrí",
+		"hešván",
+		"kislév",
+		"tevét",
+		"ševát",
+		"adár I",
+		"adár",
+		"nisán",
+		"ijjár",
+		"siván",
+		"tammúz",
+		"ab",
+		"elúl"
+	],
+	"dateFormatItem-yMMM": "LLL y",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dateFormat-long": "d. MMMM y",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
+	"dateFormat-medium": "d.M.yyyy",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-ms": "mm.ss",
+	"months-standAlone-wide": [
+		"tišríkuu",
+		"hešvánkuu",
+		"kislévkuu",
+		"tevétkuu",
+		"ševátkuu",
+		"adárkuu I",
+		"adárkuu",
+		"nisánkuu",
+		"ijjárkuu",
+		"sivánkuu",
+		"tammúzkuu",
+		"abkuu",
+		"elúlkuu"
+	],
+	"dateFormatItem-MMMd": "d. MMM",
+	"timeFormat-long": "H.mm.ss z",
+	"months-format-abbr": [
+		"tišríkuuta",
+		"hešvánkuuta",
+		"kislévkuuta",
+		"tevétkuuta",
+		"ševátkuuta",
+		"adárkuuta I",
+		"adárkuuta",
+		"nisánkuuta",
+		"ijjárkuuta",
+		"sivánkuuta",
+		"tammúzkuuta",
+		"abkuuta",
+		"elúlkuuta"
+	],
+	"timeFormat-short": "H.mm",
+	"dateFormatItem-H": "H",
+	"quarters-format-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"days-format-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"dateFormatItem-MEd": "E d.M.",
+	"months-format-narrow": [
+		"T",
+		"H",
+		"K",
+		"T",
+		"S",
+		"A",
+		"A",
+		"N",
+		"I",
+		"S",
+		"T",
+		"A",
+		"E"
+	],
+	"dateFormatItem-hm": "h.mm a",
+	"months-standAlone-wide-leap": "adárkuu II",
+	"dayPeriods-format-abbr-pm": "ip.",
+	"dateFormat-short": "d.M.yyyy",
+	"dateFormatItem-yMMMEd": "EEE d. MMM y",
+	"dateFormat-full": "cccc d. MMMM y",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yMEd": "EEE d.M.yyyy",
+	"months-format-wide": [
+		"tišríkuuta",
+		"hešvánkuuta",
+		"kislévkuuta",
+		"tevétkuuta",
+		"ševátkuuta",
+		"adárkuuta I",
+		"adárkuuta",
+		"nisánkuuta",
+		"ijjárkuuta",
+		"sivánkuuta",
+		"tammúzkuuta",
+		"abkuuta",
+		"elúlkuuta"
+	],
+	"dayPeriods-format-abbr-am": "ap.",
+	"quarters-format-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
+	"months-format-wide-leap": "adárkuuta II",
+	"days-format-wide": [
+		"sunnuntaina",
+		"maanantaina",
+		"tiistaina",
+		"keskiviikkona",
+		"torstaina",
+		"perjantaina",
+		"lauantaina"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/islamic.js b/dojo/cldr/nls/fi/islamic.js
new file mode 100644
index 0000000..a8a8686
--- /dev/null
+++ b/dojo/cldr/nls/fi/islamic.js
@@ -0,0 +1,155 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "L.yyyy",
+	"dateFormatItem-yyyyMMMEd": "EEE d. MMM y G",
+	"dateFormatItem-yQ": "Q/yyyy",
+	"dayPeriods-format-wide-pm": "ip.",
+	"dateFormatItem-MMMEd": "E d. MMM",
+	"dateFormatItem-hms": "h.mm.ss a",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"days-standAlone-wide": [
+		"sunnuntai",
+		"maanantai",
+		"tiistai",
+		"keskiviikko",
+		"torstai",
+		"perjantai",
+		"lauantai"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-Gy": "y G",
+	"dayPeriods-format-wide-am": "ap.",
+	"dateFormatItem-y": "y G",
+	"timeFormat-full": "H.mm.ss zzzz",
+	"dateFormatItem-yyyy": "y G",
+	"months-standAlone-abbr": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"džumada-l-ula",
+		"džumada-l-akhira",
+		"radžab",
+		"ša’ban",
+		"ramadan",
+		"šawwal",
+		"dhu-l-qa’da",
+		"dhu-l-hiddža"
+	],
+	"dateFormatItem-Ed": "ccc d.",
+	"dateFormatItem-yMMM": "LLL y",
+	"days-standAlone-narrow": [
+		"S",
+		"M",
+		"T",
+		"K",
+		"T",
+		"P",
+		"L"
+	],
+	"dateFormatItem-yyyyMMMMccccd": "cccc, d. MMMM y G",
+	"dateFormatItem-yyyyMM": "M.y G",
+	"dateFormatItem-yyyyMMMM": "LLLL y G",
+	"dateFormat-long": "d. MMMM y G",
+	"timeFormat-medium": "H.mm.ss",
+	"dateFormatItem-Hm": "H.mm",
+	"dateFormat-medium": "d.M.y G",
+	"dateFormatItem-Hms": "H.mm.ss",
+	"dateFormatItem-ms": "mm.ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y G",
+	"months-standAlone-wide": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"džumada-l-ula",
+		"džumada-l-akhira",
+		"radžab",
+		"ša’ban",
+		"ramadan",
+		"šawwal",
+		"dhu-l-qa’da",
+		"dhu-l-hiddža"
+	],
+	"dateFormatItem-yyyyMEd": "EEE d.M.y G",
+	"dateFormatItem-MMMd": "d. MMM",
+	"timeFormat-long": "H.mm.ss z",
+	"months-format-abbr": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"džumada-l-ula",
+		"džumada-l-akhira",
+		"radžab",
+		"ša’ban",
+		"ramadan",
+		"šawwal",
+		"dhu-l-qa’da",
+		"dhu-l-hiddža"
+	],
+	"timeFormat-short": "H.mm",
+	"dateFormatItem-H": "H",
+	"quarters-format-abbr": [
+		"1. nelj.",
+		"2. nelj.",
+		"3. nelj.",
+		"4. nelj."
+	],
+	"days-format-abbr": [
+		"su",
+		"ma",
+		"ti",
+		"ke",
+		"to",
+		"pe",
+		"la"
+	],
+	"dateFormatItem-M": "L",
+	"dateFormatItem-yyyyQQQ": "QQQ y G",
+	"dateFormatItem-MEd": "E d.M.",
+	"dateFormatItem-hm": "h.mm a",
+	"dayPeriods-format-abbr-pm": "ip.",
+	"dateFormat-short": "d.M.y G",
+	"dateFormatItem-yyyyM": "M.y G",
+	"dateFormatItem-yMMMEd": "EEE d. MMM y",
+	"dateFormat-full": "cccc d. MMMM y G",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yyyyQ": "Q/y G",
+	"dateFormatItem-yMEd": "EEE d.M.yyyy",
+	"months-format-wide": [
+		"muharram",
+		"safar",
+		"rabi’ al-awwal",
+		"rabi’ al-akhir",
+		"džumada-l-ula",
+		"džumada-l-akhira",
+		"radžab",
+		"ša’ban",
+		"ramadan",
+		"šawwal",
+		"dhu-l-qa’da",
+		"dhu-l-hiddža"
+	],
+	"dayPeriods-format-abbr-am": "ap.",
+	"dateFormatItem-yyyyMMM": "LLLL y G",
+	"dateFormatItem-d": "d",
+	"quarters-format-wide": [
+		"1. neljännes",
+		"2. neljännes",
+		"3. neljännes",
+		"4. neljännes"
+	],
+	"days-format-wide": [
+		"sunnuntaina",
+		"maanantaina",
+		"tiistaina",
+		"keskiviikkona",
+		"torstaina",
+		"perjantaina",
+		"lauantaina"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fi/number.js b/dojo/cldr/nls/fi/number.js
index 4c1f6d4..1d0eda5 100644
--- a/dojo/cldr/nls/fi/number.js
+++ b/dojo/cldr/nls/fi/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"epäluku",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "epäluku",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr-ch/gregorian.js b/dojo/cldr/nls/fr-ch/gregorian.js
new file mode 100644
index 0000000..0845d97
--- /dev/null
+++ b/dojo/cldr/nls/fr-ch/gregorian.js
@@ -0,0 +1,9 @@
+define(
+//begin v1.x content
+{
+	"timeFormat-full": "HH.mm:ss 'h' zzzz",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormat-short": "dd.MM.yy"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr-ch/number.js b/dojo/cldr/nls/fr-ch/number.js
new file mode 100644
index 0000000..75f5422
--- /dev/null
+++ b/dojo/cldr/nls/fr-ch/number.js
@@ -0,0 +1,9 @@
+define(
+//begin v1.x content
+{
+	"currencyFormat": "¤ #,##0.00;¤-#,##0.00",
+	"group": "'",
+	"decimal": "."
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/currency.js b/dojo/cldr/nls/fr/currency.js
index d539624..e454a0b 100644
--- a/dojo/cldr/nls/fr/currency.js
+++ b/dojo/cldr/nls/fr/currency.js
@@ -1,21 +1,23 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"dollar australien",
-	AUD_symbol:"$AU",
-	CAD_displayName:"dollar canadien",
-	CAD_symbol:"$CA",
-	CHF_displayName:"franc suisse",
-	CHF_symbol:"CHF",
-	CNY_displayName:"yuan renminbi chinois",
-	CNY_symbol:"Ұ",
-	EUR_displayName:"euro",
-	GBP_displayName:"livre sterling",
-	GBP_symbol:"£UK",
-	HKD_displayName:"dollar de Hong Kong",
-	HKD_symbol:"$HK",
-	JPY_displayName:"yen japonais",
-	JPY_symbol:"¥JP",
-	USD_displayName:"dollar des États-Unis",
-	USD_symbol:"$US"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "dollar de Hong Kong",
+	"CHF_displayName": "franc suisse",
+	"CHF_symbol": "CHF",
+	"JPY_symbol": "¥JP",
+	"CAD_displayName": "dollar canadien",
+	"HKD_symbol": "$HK",
+	"CNY_displayName": "yuan renminbi chinois",
+	"USD_symbol": "$US",
+	"AUD_displayName": "dollar australien",
+	"JPY_displayName": "yen japonais",
+	"CAD_symbol": "$CA",
+	"USD_displayName": "dollar des États-Unis",
+	"CNY_symbol": "Ұ",
+	"GBP_displayName": "livre sterling",
+	"GBP_symbol": "£UK",
+	"AUD_symbol": "$AU",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/gregorian.js b/dojo/cldr/nls/fr/gregorian.js
index f835423..ec37fb2 100644
--- a/dojo/cldr/nls/fr/gregorian.js
+++ b/dojo/cldr/nls/fr/gregorian.js
@@ -1,243 +1,247 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "jour de la semaine", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE d/M/yyyy", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"field-weekday": "jour de la semaine",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE d/M/yyyy",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"av. J.-C.", 
+		"av. J.-C.",
 		"ap. J.-C."
-	], 
-	"dayPeriods-format-wide-morning": "matin", 
-	"dateFormatItem-MMMdd": "dd MMM", 
-	"dateFormat-long": "d MMMM y", 
+	],
+	"dayPeriods-format-wide-morning": "matin",
+	"dateFormatItem-MMMdd": "dd MMM",
+	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
-		"janvier", 
-		"février", 
-		"mars", 
-		"avril", 
-		"mai", 
-		"juin", 
-		"juillet", 
-		"août", 
-		"septembre", 
-		"octobre", 
-		"novembre", 
+		"janvier",
+		"février",
+		"mars",
+		"avril",
+		"mai",
+		"juin",
+		"juillet",
+		"août",
+		"septembre",
+		"octobre",
+		"novembre",
 		"décembre"
-	], 
-	"dateFormatItem-EEEd": "d EEE", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE d MMMM y", 
-	"dateFormatItem-Md": "d/M", 
-	"dayPeriods-format-wide-noon": "midi", 
-	"field-era": "ère", 
-	"dateFormatItem-yM": "M/yyyy", 
+	],
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE d MMMM y",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-wide-noon": "midi",
+	"field-era": "ère",
+	"dateFormatItem-yM": "M/yyyy",
 	"months-standAlone-wide": [
-		"janvier", 
-		"février", 
-		"mars", 
-		"avril", 
-		"mai", 
-		"juin", 
-		"juillet", 
-		"août", 
-		"septembre", 
-		"octobre", 
-		"novembre", 
+		"janvier",
+		"février",
+		"mars",
+		"avril",
+		"mai",
+		"juin",
+		"juillet",
+		"août",
+		"septembre",
+		"octobre",
+		"novembre",
 		"décembre"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1er trimestre", 
-		"2e trimestre", 
-		"3e trimestre", 
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
 		"4e trimestre"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "année", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "'T'Q y", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"field-hour": "heure", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "année",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "'T'Q y",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "heure",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"janv.", 
-		"févr.", 
-		"mars", 
-		"avr.", 
-		"mai", 
-		"juin", 
-		"juil.", 
-		"août", 
-		"sept.", 
-		"oct.", 
-		"nov.", 
+		"janv.",
+		"févr.",
+		"mars",
+		"avr.",
+		"mai",
+		"juin",
+		"juil.",
+		"août",
+		"sept.",
+		"oct.",
+		"nov.",
 		"déc."
-	], 
-	"dateFormatItem-yyQ": "'T'Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "aujourd’hui", 
-	"field-day-relative+1": "demain", 
-	"field-day-relative+2": "après-demain", 
-	"field-day-relative+3": "après-après-demain", 
+	],
+	"dateFormatItem-yyQ": "'T'Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "aujourd’hui",
+	"field-day-relative+1": "demain",
+	"field-day-relative+2": "après-demain",
+	"field-day-relative+3": "après-après-demain",
 	"months-standAlone-abbr": [
-		"janv.", 
-		"févr.", 
-		"mars", 
-		"avr.", 
-		"mai", 
-		"juin", 
-		"juil.", 
-		"août", 
-		"sept.", 
-		"oct.", 
-		"nov.", 
+		"janv.",
+		"févr.",
+		"mars",
+		"avr.",
+		"mai",
+		"juin",
+		"juil.",
+		"août",
+		"sept.",
+		"oct.",
+		"nov.",
 		"déc."
-	], 
+	],
 	"quarters-format-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1er trimestre", 
-		"2e trimestre", 
-		"3e trimestre", 
+		"1er trimestre",
+		"2e trimestre",
+		"3e trimestre",
 		"4e trimestre"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"dimanche", 
-		"lundi", 
-		"mardi", 
-		"mercredi", 
-		"jeudi", 
-		"vendredi", 
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
 		"samedi"
-	], 
-	"dateFormatItem-yyMMMEEEd": "EEE d MMM yy", 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-yyMMMEEEd": "EEE d MMM yy",
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"eraAbbr": [
-		"av. J.-C.", 
+		"av. J.-C.",
 		"ap. J.-C."
-	], 
-	"field-minute": "minute", 
-	"field-dayperiod": "cadran", 
-	"dayPeriods-format-wide-night": "soir", 
+	],
+	"field-minute": "minute",
+	"field-dayperiod": "cadran",
 	"days-standAlone-abbr": [
-		"dim.", 
-		"lun.", 
-		"mar.", 
-		"mer.", 
-		"jeu.", 
-		"ven.", 
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
 		"sam."
-	], 
-	"dateFormatItem-yyMMMd": "d MMM yy", 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
+	],
+	"dayPeriods-format-wide-night": "soir",
+	"dateFormatItem-yyMMMd": "d MMM yy",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
-	"field-day-relative+-1": "hier", 
-	"field-day-relative+-2": "avant-hier", 
-	"field-day-relative+-3": "avant-avant-hier", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "EEE d/M", 
-	"field-day": "jour", 
+	],
+	"field-day-relative+-1": "hier",
+	"field-day-relative+-2": "avant-hier",
+	"field-day-relative+-3": "avant-avant-hier",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "EEE d/M",
+	"field-day": "jour",
 	"days-format-wide": [
-		"dimanche", 
-		"lundi", 
-		"mardi", 
-		"mercredi", 
-		"jeudi", 
-		"vendredi", 
+		"dimanche",
+		"lundi",
+		"mardi",
+		"mercredi",
+		"jeudi",
+		"vendredi",
 		"samedi"
-	], 
-	"field-zone": "fuseau horaire", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "fuseau horaire",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
 	"days-format-abbr": [
-		"dim.", 
-		"lun.", 
-		"mar.", 
-		"mer.", 
-		"jeu.", 
-		"ven.", 
+		"dim.",
+		"lun.",
+		"mar.",
+		"mer.",
+		"jeu.",
+		"ven.",
 		"sam."
-	], 
+	],
 	"eraNames": [
-		"avant Jésus-Christ", 
+		"avant Jésus-Christ",
 		"après Jésus-Christ"
-	], 
+	],
 	"days-format-narrow": [
-		"D", 
-		"L", 
-		"M", 
-		"M", 
-		"J", 
-		"V", 
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
 		"S"
-	], 
-	"field-month": "mois", 
+	],
+	"field-month": "mois",
 	"days-standAlone-narrow": [
-		"D", 
-		"L", 
-		"M", 
-		"M", 
-		"J", 
-		"V", 
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
 		"S"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateFormatItem-MMMMEd": "EEE d MMMM", 
-	"dateFormat-short": "dd/MM/yy", 
-	"dateFormatItem-MMd": "d/MM", 
-	"dayPeriods-format-wide-afternoon": "après-midi", 
-	"field-second": "seconde", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"field-week": "semaine", 
-	"dateFormat-medium": "d MMM y", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormatItem-MMMMEd": "EEE d MMMM",
+	"dateFormat-short": "dd/MM/yy",
+	"dateFormatItem-MMd": "d/MM",
+	"dayPeriods-format-wide-afternoon": "après-midi",
+	"field-second": "seconde",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "semaine",
+	"dateFormat-medium": "d MMM y",
 	"dateFormatItem-Hms": "HH:mm:ss"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/fr/number.js b/dojo/cldr/nls/fr/number.js
index 33c9d64..be5c98c 100644
--- a/dojo/cldr/nls/fr/number.js
+++ b/dojo/cldr/nls/fr/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/gregorian.js b/dojo/cldr/nls/gregorian.js
index c7a7186..45e7fc2 100644
--- a/dojo/cldr/nls/gregorian.js
+++ b/dojo/cldr/nls/gregorian.js
@@ -1,253 +1,294 @@
-({
+define({ root:
+
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
+	],
 	"quarters-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"field-weekday": "Day of the Week", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, y-M-d", 
-	"dateFormatItem-MMMEd": "E MMM d", 
+	],
+	"field-weekday": "Day of the Week",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, y-M-d",
+	"dateFormatItem-MMMEd": "E MMM d",
 	"eraNarrow": [
-		"BCE", 
+		"BCE",
 		"CE"
-	], 
-	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}", 
-	"dateFormat-long": "y MMMM d", 
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "y MMMM d",
 	"months-format-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dateFormatItem-EEEd": "d EEE", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE, y MMMM dd", 
-	"dateFormatItem-Md": "M-d", 
-	"dayPeriods-format-abbr-am": "AM", 
-	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})", 
-	"field-era": "Era", 
-	"dateFormatItem-yM": "y-M", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-EEEd": "d EEE",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, y MMMM dd",
+	"dateFormatItem-Md": "M-d",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"field-era": "Era",
+	"dateFormatItem-yM": "y-M",
 	"months-standAlone-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "Year", 
-	"dateFormatItem-yMMM": "y MMM", 
-	"dateFormatItem-yQ": "y Q", 
-	"dateTimeFormats-appendItem-Era": "{0} {1}", 
-	"field-hour": "Hour", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Year",
+	"dateFormatItem-yMMM": "y MMM",
+	"dateFormatItem-yQ": "y Q",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"field-hour": "Hour",
 	"months-format-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})", 
-	"field-day-relative+0": "Today", 
-	"field-day-relative+1": "Tomorrow", 
-	"dateFormatItem-H": "HH", 
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"field-day-relative+0": "Today",
+	"field-day-relative+1": "Tomorrow",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"eraAbbr": [
-		"BCE", 
+		"BCE",
 		"CE"
-	], 
-	"field-minute": "Minute", 
-	"field-dayperiod": "Dayperiod", 
+	],
+	"field-minute": "Minute",
+	"field-dayperiod": "Dayperiod",
 	"days-standAlone-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"field-day-relative+-1": "Yesterday", 
-	"dateFormatItem-h": "h a", 
-	"dateTimeFormat-long": "{1} {0}", 
-	"dayPeriods-format-narrow-am": "AM", 
-	"dateFormatItem-MMMd": "MMM d", 
-	"dateFormatItem-MEd": "E, M-d", 
-	"dateTimeFormat-full": "{1} {0}", 
-	"field-day": "Day", 
+	],
+	"field-day-relative+-1": "Yesterday",
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "E, M-d",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "Day",
 	"days-format-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"field-zone": "Zone", 
-	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "Zone",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"dateFormatItem-hm": "h:mm a", 
-	"dateTimeFormats-appendItem-Year": "{0} {1}", 
-	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})", 
-	"dayPeriods-format-abbr-pm": "PM", 
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"eraNames": [
-		"BCE", 
+		"BCE",
 		"CE"
-	], 
+	],
 	"days-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"days-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"field-month": "Month", 
-	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})", 
-	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})", 
-	"dateFormat-short": "yyyy-MM-dd", 
-	"field-second": "Second", 
-	"dateFormatItem-yMMMEd": "EEE, y MMM d", 
-	"dateTimeFormats-appendItem-Timezone": "{0} {1}", 
-	"field-week": "Week", 
-	"dateFormat-medium": "y MMM d", 
-	"dayPeriods-format-narrow-pm": "PM", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"field-month": "Month",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "yyyy-MM-dd",
+	"field-second": "Second",
+	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"field-week": "Week",
+	"dateFormat-medium": "y MMM d",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+,
+	"ar": true,
+	"ca": true,
+	"cs": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"en-au": true,
+	"en-ca": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"fr-ch": true,
+	"he": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ro": true,
+	"ru": true,
+	"sk": true,
+	"sl": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true,
+	"zh-hk": true,
+	"zh-tw": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/currency.js b/dojo/cldr/nls/he/currency.js
index d0a7e38..75ca390 100644
--- a/dojo/cldr/nls/he/currency.js
+++ b/dojo/cldr/nls/he/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"דולר אוסטרלי",
-	CAD_displayName:"דולר קנדי",
-	CHF_displayName:"פרנק שוויצרי",
-	CNY_displayName:"יואן רנמינבי סיני",
-	EUR_displayName:"אירו",
-	GBP_displayName:"לירה שטרלינג",
-	HKD_displayName:"דולר הונג קונגי",
-	JPY_displayName:"ין יפני",
-	USD_displayName:"דולר אמריקאי"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "דולר הונג קונגי",
+	"CHF_displayName": "פרנק שוויצרי",
+	"CAD_displayName": "דולר קנדי",
+	"CNY_displayName": "יואן רנמינבי סיני",
+	"AUD_displayName": "דולר אוסטרלי",
+	"JPY_displayName": "ין יפני",
+	"USD_displayName": "דולר אמריקאי",
+	"GBP_displayName": "לירה שטרלינג",
+	"EUR_displayName": "אירו"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/gregorian.js b/dojo/cldr/nls/he/gregorian.js
index 3e74dfe..2643bfd 100644
--- a/dojo/cldr/nls/he/gregorian.js
+++ b/dojo/cldr/nls/he/gregorian.js
@@ -1,209 +1,213 @@
-({
-	"field-weekday": "יום בשבוע", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy", 
-	"dateFormatItem-MMMEd": "E, d בMMM", 
+define(
+//begin v1.x content
+{
+	"field-weekday": "יום בשבוע",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
+	"dateFormatItem-MMMEd": "E, d בMMM",
 	"eraNarrow": [
-		"לפנה״ס", 
+		"לפנה״ס",
 		"לסה״נ"
-	], 
-	"dateFormat-long": "d בMMMM y", 
+	],
+	"dateFormat-long": "d בMMMM y",
 	"months-format-wide": [
-		"ינואר", 
-		"פברואר", 
-		"מרס", 
-		"אפריל", 
-		"מאי", 
-		"יוני", 
-		"יולי", 
-		"אוגוסט", 
-		"ספטמבר", 
-		"אוקטובר", 
-		"נובמבר", 
+		"ינואר",
+		"פברואר",
+		"מרס",
+		"אפריל",
+		"מאי",
+		"יוני",
+		"יולי",
+		"אוגוסט",
+		"ספטמבר",
+		"אוקטובר",
+		"נובמבר",
 		"דצמבר"
-	], 
-	"dateFormatItem-EEEd": "EEE ה-d", 
-	"dayPeriods-format-wide-pm": "אחה״צ", 
-	"dateFormat-full": "EEEE, d בMMMM y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "תקופה", 
-	"dateFormatItem-yM": "M.yyyy", 
+	],
+	"dateFormatItem-EEEd": "EEE ה-d",
+	"dayPeriods-format-wide-pm": "אחה״צ",
+	"dateFormat-full": "EEEE, d בMMMM y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "תקופה",
+	"dateFormatItem-yM": "M.yyyy",
 	"months-standAlone-wide": [
-		"ינואר", 
-		"פברואר", 
-		"מרס", 
-		"אפריל", 
-		"מאי", 
-		"יוני", 
-		"יולי", 
-		"אוגוסט", 
-		"ספטמבר", 
-		"אוקטובר", 
-		"נובמבר", 
+		"ינואר",
+		"פברואר",
+		"מרס",
+		"אפריל",
+		"מאי",
+		"יוני",
+		"יולי",
+		"אוגוסט",
+		"ספטמבר",
+		"אוקטובר",
+		"נובמבר",
 		"דצמבר"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"רבעון 1", 
-		"רבעון 2", 
-		"רבעון 3", 
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
 		"רבעון 4"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "שנה", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"field-hour": "שעה", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "שנה",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "yyyy Q",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "שעה",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"ינו", 
-		"פבר", 
-		"מרס", 
-		"אפר", 
-		"מאי", 
-		"יונ", 
-		"יול", 
-		"אוג", 
-		"ספט", 
-		"אוק", 
-		"נוב", 
+		"ינו",
+		"פבר",
+		"מרס",
+		"אפר",
+		"מאי",
+		"יונ",
+		"יול",
+		"אוג",
+		"ספט",
+		"אוק",
+		"נוב",
 		"דצמ"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "היום", 
-	"field-day-relative+1": "מחר", 
-	"field-day-relative+2": "מחרתיים", 
-	"dateFormatItem-H": "HH", 
-	"field-day-relative+3": "בעוד שלושה ימים", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "היום",
+	"field-day-relative+1": "מחר",
+	"field-day-relative+2": "מחרתיים",
+	"dateFormatItem-H": "HH",
+	"field-day-relative+3": "בעוד שלושה ימים",
 	"months-standAlone-abbr": [
-		"ינו׳", 
-		"פבר׳", 
-		"מרס", 
-		"אפר׳", 
-		"מאי", 
-		"יונ׳", 
-		"יול׳", 
-		"אוג׳", 
-		"ספט׳", 
-		"אוק׳", 
-		"נוב׳", 
+		"ינו׳",
+		"פבר׳",
+		"מרס",
+		"אפר׳",
+		"מאי",
+		"יונ׳",
+		"יול׳",
+		"אוג׳",
+		"ספט׳",
+		"אוק׳",
+		"נוב׳",
 		"דצמ׳"
-	], 
-	"quarters-standAlone-wide": [
-		"רבעון 1", 
-		"רבעון 2", 
-		"רבעון 3", 
-		"רבעון 4"
-	], 
+	],
 	"quarters-format-abbr": [
-		"רבעון 1", 
-		"רבעון 2", 
-		"רבעון 3", 
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
+		"רבעון 4"
+	],
+	"quarters-standAlone-wide": [
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
 		"רבעון 4"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"יום ראשון", 
-		"יום שני", 
-		"יום שלישי", 
-		"יום רביעי", 
-		"יום חמישי", 
-		"יום שישי", 
+		"יום ראשון",
+		"יום שני",
+		"יום שלישי",
+		"יום רביעי",
+		"יום חמישי",
+		"יום שישי",
 		"יום שבת"
-	], 
-	"dateFormatItem-MMMMd": "d בMMMM", 
-	"dateFormatItem-yyMMM": "MMM yyyy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-MMMMd": "d בMMMM",
+	"dateFormatItem-yyMMM": "MMM yyyy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"רבעון 1", 
-		"רבעון 2", 
-		"רבעון 3", 
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
 		"רבעון 4"
-	], 
+	],
 	"eraAbbr": [
-		"לפנה״ס", 
+		"לפנה״ס",
 		"לסה״נ"
-	], 
-	"field-minute": "דקה", 
-	"field-dayperiod": "לפה״צ/אחה״צ", 
+	],
+	"field-minute": "דקה",
+	"field-dayperiod": "לפה״צ/אחה״צ",
 	"days-standAlone-abbr": [
-		"יום א׳", 
-		"יום ב׳", 
-		"יום ג׳", 
-		"יום ד׳", 
-		"יום ה׳", 
-		"יום ו׳", 
+		"יום א׳",
+		"יום ב׳",
+		"יום ג׳",
+		"יום ד׳",
+		"יום ה׳",
+		"יום ו׳",
 		"שבת"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "אתמול", 
-	"field-day-relative+-2": "שלשום", 
-	"field-day-relative+-3": "לפני שלושה ימים", 
-	"dateFormatItem-MMMd": "d בMMM", 
-	"dateFormatItem-MEd": "E, M-d", 
-	"dateFormatItem-yMMMM": "MMMM y", 
-	"field-day": "יום", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "אתמול",
+	"field-day-relative+-2": "שלשום",
+	"field-day-relative+-3": "לפני שלושה ימים",
+	"dateFormatItem-MMMd": "d בMMM",
+	"dateFormatItem-MEd": "E, M-d",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"field-day": "יום",
 	"days-format-wide": [
-		"יום ראשון", 
-		"יום שני", 
-		"יום שלישי", 
-		"יום רביעי", 
-		"יום חמישי", 
-		"יום שישי", 
+		"יום ראשון",
+		"יום שני",
+		"יום שלישי",
+		"יום רביעי",
+		"יום חמישי",
+		"יום שישי",
 		"יום שבת"
-	], 
-	"field-zone": "אזור", 
-	"dateFormatItem-yyyyMM": "MM/yyyy", 
-	"dateFormatItem-y": "y", 
-	"dateFormatItem-yyMM": "MM/yy", 
-	"dateFormatItem-hm": "h:mm a", 
+	],
+	"field-zone": "אזור",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormatItem-y": "y",
+	"dateFormatItem-yyMM": "MM/yy",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
-		"יום א׳", 
-		"יום ב׳", 
-		"יום ג׳", 
-		"יום ד׳", 
-		"יום ה׳", 
-		"יום ו׳", 
+		"יום א׳",
+		"יום ב׳",
+		"יום ג׳",
+		"יום ד׳",
+		"יום ה׳",
+		"יום ו׳",
 		"שבת"
-	], 
+	],
 	"eraNames": [
-		"לפני הספירה", 
+		"לפני הספירה",
 		"לספירה"
-	], 
+	],
 	"days-format-narrow": [
-		"א", 
-		"ב", 
-		"ג", 
-		"ד", 
-		"ה", 
-		"ו", 
+		"א",
+		"ב",
+		"ג",
+		"ד",
+		"ה",
+		"ו",
 		"ש"
-	], 
-	"field-month": "חודש", 
+	],
+	"field-month": "חודש",
 	"days-standAlone-narrow": [
-		"א", 
-		"ב", 
-		"ג", 
-		"ד", 
-		"ה", 
-		"ו", 
+		"א",
+		"ב",
+		"ג",
+		"ד",
+		"ה",
+		"ו",
 		"ש"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "לפנה״צ", 
-	"dateFormatItem-MMMMEd": "E, d בMMMM", 
-	"dateFormat-short": "dd/MM/yy", 
-	"field-second": "שנייה", 
-	"dateFormatItem-yMMMEd": "EEE, d בMMM y", 
-	"dateFormatItem-Ed": "E ה-d", 
-	"field-week": "שבוע", 
-	"dateFormat-medium": "d בMMM yyyy", 
-	"dateFormatItem-mmss": "mm:ss", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
-	"dateFormatItem-hms": "h:mm:ss a", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "לפנה״צ",
+	"dateFormatItem-MMMMEd": "E, d בMMMM",
+	"dateFormat-short": "dd/MM/yy",
+	"field-second": "שנייה",
+	"dateFormatItem-yMMMEd": "EEE, d בMMM y",
+	"dateFormatItem-Ed": "E ה-d",
+	"field-week": "שבוע",
+	"dateFormat-medium": "d בMMM yyyy",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
 	"dateFormatItem-yyyy": "y"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/hebrew.js b/dojo/cldr/nls/he/hebrew.js
index 7a9e0ba..e11a97e 100644
--- a/dojo/cldr/nls/he/hebrew.js
+++ b/dojo/cldr/nls/he/hebrew.js
@@ -1,121 +1,125 @@
-({
-	"dateFormat-medium": "dd/MM/yyyy", 
-	"dateFormatItem-MMMEd": "E, d בMMM", 
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy", 
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "dd/MM/yyyy",
+	"dateFormatItem-MMMEd": "E, d בMMM",
+	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
 	"eraNarrow": [
 		"לבה״ע"
-	], 
-	"dateFormatItem-Md": "d/M", 
+	],
+	"dateFormatItem-Md": "d/M",
 	"months-standAlone-wide": [
-		"תשרי", 
-		"חשון", 
-		"כסלו", 
-		"טבת", 
-		"שבט", 
-		"אדר א׳", 
-		"אדר", 
-		"ניסן", 
-		"אייר", 
-		"סיון", 
-		"תמוז", 
-		"אב", 
+		"תשרי",
+		"חשון",
+		"כסלו",
+		"טבת",
+		"שבט",
+		"אדר א׳",
+		"אדר",
+		"ניסן",
+		"אייר",
+		"סיון",
+		"תמוז",
+		"אב",
 		"אלול"
-	], 
-	"months-format-wide-leap": "אדר ב׳", 
-	"dateFormatItem-EEEd": "EEE ה-d", 
+	],
+	"months-format-wide-leap": "אדר ב׳",
+	"dateFormatItem-EEEd": "EEE ה-d",
 	"eraNames": [
 		"לבה״ע"
-	], 
-	"dateFormatItem-MMMMEd": "E, d בMMMM", 
+	],
 	"days-standAlone-narrow": [
-		"א", 
-		"ב", 
-		"ג", 
-		"ד", 
-		"ה", 
-		"ו", 
+		"א",
+		"ב",
+		"ג",
+		"ד",
+		"ה",
+		"ו",
 		"ש"
-	], 
-	"dayPeriods-format-wide-pm": "אחה״צ", 
+	],
+	"dateFormatItem-MMMMEd": "E, d בMMMM",
+	"dayPeriods-format-wide-pm": "אחה״צ",
 	"months-standAlone-abbr": [
-		"תשרי", 
-		"חשון", 
-		"כסלו", 
-		"טבת", 
-		"שבט", 
-		"אדר א׳", 
-		"אדר", 
-		"ניסן", 
-		"אייר", 
-		"סיון", 
-		"תמוז", 
-		"אב", 
+		"תשרי",
+		"חשון",
+		"כסלו",
+		"טבת",
+		"שבט",
+		"אדר א׳",
+		"אדר",
+		"ניסן",
+		"אייר",
+		"סיון",
+		"תמוז",
+		"אב",
 		"אלול"
-	], 
-	"dayPeriods-format-wide-am": "לפנה״צ", 
-	"dateFormat-long": "d בMMMM y", 
-	"dateFormat-short": "dd/MM/yy", 
-	"dateFormatItem-yMMMEd": "EEE, d בMMM y", 
+	],
+	"dayPeriods-format-wide-am": "לפנה״צ",
+	"dateFormat-long": "d בMMMM y",
+	"dateFormat-short": "dd/MM/yy",
+	"dateFormatItem-yMMMEd": "EEE, d בMMM y",
 	"months-format-wide": [
-		"תשרי", 
-		"חשון", 
-		"כסלו", 
-		"טבת", 
-		"שבט", 
-		"אדר א׳", 
-		"אדר", 
-		"ניסן", 
-		"אייר", 
-		"סיון", 
-		"תמוז", 
-		"אב", 
+		"תשרי",
+		"חשון",
+		"כסלו",
+		"טבת",
+		"שבט",
+		"אדר א׳",
+		"אדר",
+		"ניסן",
+		"אייר",
+		"סיון",
+		"תמוז",
+		"אב",
 		"אלול"
-	], 
-	"dateFormatItem-yM": "M.yyyy", 
+	],
+	"dateFormatItem-yM": "M.yyyy",
 	"months-format-abbr": [
-		"תשרי", 
-		"חשון", 
-		"כסלו", 
-		"טבת", 
-		"שבט", 
-		"אדר א׳", 
-		"אדר", 
-		"ניסן", 
-		"אייר", 
-		"סיון", 
-		"תמוז", 
-		"אב", 
+		"תשרי",
+		"חשון",
+		"כסלו",
+		"טבת",
+		"שבט",
+		"אדר א׳",
+		"אדר",
+		"ניסן",
+		"אייר",
+		"סיון",
+		"תמוז",
+		"אב",
 		"אלול"
-	], 
+	],
 	"eraAbbr": [
 		"לבה״ע"
-	], 
+	],
 	"days-format-wide": [
-		"יום ראשון", 
-		"יום שני", 
-		"יום שלישי", 
-		"יום רביעי", 
-		"יום חמישי", 
-		"יום שישי", 
+		"יום ראשון",
+		"יום שני",
+		"יום שלישי",
+		"יום רביעי",
+		"יום חמישי",
+		"יום שישי",
 		"יום שבת"
-	], 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dateFormatItem-yMMM": "MMM y", 
+	],
+	"dateFormatItem-yQ": "yyyy Q",
+	"dateFormatItem-yMMM": "MMM y",
 	"quarters-format-wide": [
-		"רבעון 1", 
-		"רבעון 2", 
-		"רבעון 3", 
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
 		"רבעון 4"
-	], 
-	"dateFormat-full": "EEEE, d בMMMM y", 
-	"dateFormatItem-MMMd": "d בMMM", 
+	],
+	"dateFormat-full": "EEEE, d בMMMM y",
+	"dateFormatItem-MMMd": "d בMMM",
 	"days-format-abbr": [
-		"יום א׳", 
-		"יום ב׳", 
-		"יום ג׳", 
-		"יום ד׳", 
-		"יום ה׳", 
-		"יום ו׳", 
+		"יום א׳",
+		"יום ב׳",
+		"יום ג׳",
+		"יום ד׳",
+		"יום ה׳",
+		"יום ו׳",
 		"שבת"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/islamic.js b/dojo/cldr/nls/he/islamic.js
index 59119d0..a34fe99 100644
--- a/dojo/cldr/nls/he/islamic.js
+++ b/dojo/cldr/nls/he/islamic.js
@@ -1,115 +1,119 @@
-({
-	"dateFormat-medium": "d בMMM yyyy", 
-	"dateFormatItem-MMMEd": "E, d בMMM", 
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy", 
+define(
+//begin v1.x content
+{
+	"dateFormat-medium": "d בMMM yyyy",
+	"dateFormatItem-MMMEd": "E, d בMMM",
+	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
 	"eraNarrow": [
 		"שנת היג׳רה"
-	], 
-	"dateFormatItem-Md": "d/M", 
+	],
+	"dateFormatItem-Md": "d/M",
 	"months-standAlone-wide": [
-		"מוחרם", 
-		"ספר", 
-		"רביע אל-אוואל", 
-		"רביע אל-תני", 
-		"ג׳ומדה אל-אוואל", 
-		"ג׳ומדה אל-תני", 
-		"רג׳אב", 
-		"שעבאן", 
-		"ראמדן", 
-		"שוואל", 
-		"זו אל-QI'DAH", 
+		"מוחרם",
+		"ספר",
+		"רביע אל-אוואל",
+		"רביע אל-תני",
+		"ג׳ומדה אל-אוואל",
+		"ג׳ומדה אל-תני",
+		"רג׳אב",
+		"שעבאן",
+		"ראמדן",
+		"שוואל",
+		"זו אל-QI'DAH",
 		"זו אל-חיג׳ה"
-	], 
-	"dateFormatItem-EEEd": "EEE ה-d", 
+	],
+	"dateFormatItem-EEEd": "EEE ה-d",
 	"eraNames": [
 		"שנת היג׳רה"
-	], 
+	],
 	"days-standAlone-narrow": [
-		"א", 
-		"ב", 
-		"ג", 
-		"ד", 
-		"ה", 
-		"ו", 
+		"א",
+		"ב",
+		"ג",
+		"ד",
+		"ה",
+		"ו",
 		"ש"
-	], 
-	"dayPeriods-format-wide-pm": "אחה״צ", 
+	],
+	"dayPeriods-format-wide-pm": "אחה״צ",
 	"months-standAlone-abbr": [
-		"מוחרם", 
-		"ספר", 
-		"רביע אל-אוואל", 
-		"רביע אל-תני", 
-		"ג׳ומדה אל-אוואל", 
-		"ג׳ומדה אל-תני", 
-		"רג׳אב", 
-		"שעבאן", 
-		"ראמדן", 
-		"שוואל", 
-		"זו אל-QI'DAH", 
+		"מוחרם",
+		"ספר",
+		"רביע אל-אוואל",
+		"רביע אל-תני",
+		"ג׳ומדה אל-אוואל",
+		"ג׳ומדה אל-תני",
+		"רג׳אב",
+		"שעבאן",
+		"ראמדן",
+		"שוואל",
+		"זו אל-QI'DAH",
 		"זו אל-חיג׳ה"
-	], 
-	"dayPeriods-format-wide-am": "לפנה״צ", 
-	"dateFormat-long": "d בMMMM y", 
-	"dateFormat-short": "dd/MM/yy", 
-	"dateFormatItem-yMMMEd": "EEE, d בMMM y", 
+	],
+	"dayPeriods-format-wide-am": "לפנה״צ",
+	"dateFormat-long": "d בMMMM y",
+	"dateFormat-short": "dd/MM/yy",
+	"dateFormatItem-yMMMEd": "EEE, d בMMM y",
 	"months-format-wide": [
-		"מוחרם", 
-		"ספר", 
-		"רביע אל-אוואל", 
-		"רביע אל-תני", 
-		"ג׳ומדה אל-אוואל", 
-		"ג׳ומדה אל-תני", 
-		"רג׳אב", 
-		"שעבאן", 
-		"ראמדן", 
-		"שוואל", 
-		"זו אל-QI'DAH", 
+		"מוחרם",
+		"ספר",
+		"רביע אל-אוואל",
+		"רביע אל-תני",
+		"ג׳ומדה אל-אוואל",
+		"ג׳ומדה אל-תני",
+		"רג׳אב",
+		"שעבאן",
+		"ראמדן",
+		"שוואל",
+		"זו אל-QI'DAH",
 		"זו אל-חיג׳ה"
-	], 
-	"dateFormatItem-yM": "M.yyyy", 
+	],
+	"dateFormatItem-yM": "M.yyyy",
 	"months-format-abbr": [
-		"מוחרם", 
-		"ספר", 
-		"רביע אל-אוואל", 
-		"רביע אל-תני", 
-		"ג׳ומדה אל-אוואל", 
-		"ג׳ומדה אל-תני", 
-		"רג׳אב", 
-		"שעבאן", 
-		"ראמדן", 
-		"שוואל", 
-		"זו אל-QI'DAH", 
+		"מוחרם",
+		"ספר",
+		"רביע אל-אוואל",
+		"רביע אל-תני",
+		"ג׳ומדה אל-אוואל",
+		"ג׳ומדה אל-תני",
+		"רג׳אב",
+		"שעבאן",
+		"ראמדן",
+		"שוואל",
+		"זו אל-QI'DAH",
 		"זו אל-חיג׳ה"
-	], 
+	],
 	"eraAbbr": [
 		"שנת היג׳רה"
-	], 
+	],
 	"days-format-wide": [
-		"יום ראשון", 
-		"יום שני", 
-		"יום שלישי", 
-		"יום רביעי", 
-		"יום חמישי", 
-		"יום שישי", 
+		"יום ראשון",
+		"יום שני",
+		"יום שלישי",
+		"יום רביעי",
+		"יום חמישי",
+		"יום שישי",
 		"יום שבת"
-	], 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dateFormatItem-yMMM": "MMM y", 
+	],
+	"dateFormatItem-yQ": "yyyy Q",
+	"dateFormatItem-yMMM": "MMM y",
 	"quarters-format-wide": [
-		"רבעון 1", 
-		"רבעון 2", 
-		"רבעון 3", 
+		"רבעון 1",
+		"רבעון 2",
+		"רבעון 3",
 		"רבעון 4"
-	], 
-	"dateFormat-full": "EEEE, d בMMMM y", 
-	"dateFormatItem-MMMd": "d בMMM", 
+	],
+	"dateFormat-full": "EEEE, d בMMMM y",
+	"dateFormatItem-MMMd": "d בMMM",
 	"days-format-abbr": [
-		"יום א׳", 
-		"יום ב׳", 
-		"יום ג׳", 
-		"יום ד׳", 
-		"יום ה׳", 
-		"יום ו׳", 
+		"יום א׳",
+		"יום ב׳",
+		"יום ג׳",
+		"יום ד׳",
+		"יום ה׳",
+		"יום ו׳",
 		"שבת"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/he/number.js b/dojo/cldr/nls/he/number.js
index aac6735..7dedbd9 100644
--- a/dojo/cldr/nls/he/number.js
+++ b/dojo/cldr/nls/he/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hebrew.js b/dojo/cldr/nls/hebrew.js
index 4ed106d..29ae041 100644
--- a/dojo/cldr/nls/hebrew.js
+++ b/dojo/cldr/nls/hebrew.js
@@ -1,248 +1,265 @@
-({
+define({ root:
+
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"Tishri", 
-		"Heshvan", 
-		"Kislev", 
-		"Tevet", 
-		"Shevat", 
-		"Adar I", 
-		"Adar", 
-		"Nisan", 
-		"Iyar", 
-		"Sivan", 
-		"Tamuz", 
-		"Av", 
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
 		"Elul"
-	], 
+	],
 	"quarters-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"months-standAlone-narrow-leap": "Adar II", 
-	"dateFormatItem-yMEd": "EEE, y-M-d", 
-	"dateFormatItem-MMMEd": "E MMM d", 
+	],
+	"dateFormatItem-yQQQ": "y QQQ",
+	"months-standAlone-narrow-leap": "Adar II",
+	"dateFormatItem-yMEd": "EEE, y-M-d",
+	"dateFormatItem-MMMEd": "E MMM d",
 	"eraNarrow": [
 		"AM"
-	], 
-	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}", 
-	"dateFormat-long": "y MMMM d", 
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "y MMMM d",
 	"months-format-wide": [
-		"Tishri", 
-		"Heshvan", 
-		"Kislev", 
-		"Tevet", 
-		"Shevat", 
-		"Adar I", 
-		"Adar", 
-		"Nisan", 
-		"Iyar", 
-		"Sivan", 
-		"Tamuz", 
-		"Av", 
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
 		"Elul"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dateFormatItem-EEEd": "d EEE", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE, y MMMM dd", 
-	"dateFormatItem-Md": "M-d", 
-	"dayPeriods-format-abbr-am": "AM", 
-	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})", 
-	"dateFormatItem-yM": "y-M", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-EEEd": "d EEE",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, y MMMM dd",
+	"dateFormatItem-Md": "M-d",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dateFormatItem-yM": "y-M",
 	"months-standAlone-wide": [
-		"Tishri", 
-		"Heshvan", 
-		"Kislev", 
-		"Tevet", 
-		"Shevat", 
-		"Adar I", 
-		"Adar", 
-		"Nisan", 
-		"Iyar", 
-		"Sivan", 
-		"Tamuz", 
-		"Av", 
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
 		"Elul"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"dateFormatItem-yMMM": "y MMM", 
-	"dateFormatItem-yQ": "y Q", 
-	"dateTimeFormats-appendItem-Era": "{0} {1}", 
-	"months-format-abbr-leap": "Adar II", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"dateFormatItem-yMMM": "y MMM",
+	"dateFormatItem-yQ": "y Q",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
+	"months-format-abbr-leap": "Adar II",
 	"months-format-abbr": [
-		"Tishri", 
-		"Heshvan", 
-		"Kislev", 
-		"Tevet", 
-		"Shevat", 
-		"Adar I", 
-		"Adar", 
-		"Nisan", 
-		"Iyar", 
-		"Sivan", 
-		"Tamuz", 
-		"Av", 
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
 		"Elul"
-	], 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})", 
-	"dateFormatItem-H": "HH", 
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"Tishri", 
-		"Heshvan", 
-		"Kislev", 
-		"Tevet", 
-		"Shevat", 
-		"Adar I", 
-		"Adar", 
-		"Nisan", 
-		"Iyar", 
-		"Sivan", 
-		"Tamuz", 
-		"Av", 
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
 		"Elul"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"months-standAlone-wide-leap": "Adar II", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"months-standAlone-wide-leap": "Adar II",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"months-format-narrow-leap": "Adar II", 
+	],
+	"months-format-narrow-leap": "Adar II",
 	"eraAbbr": [
 		"AM"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateFormatItem-h": "h a", 
-	"dateTimeFormat-long": "{1} {0}", 
-	"dayPeriods-format-narrow-am": "AM", 
-	"dateFormatItem-MMMd": "MMM d", 
-	"dateFormatItem-MEd": "E, M-d", 
-	"dateTimeFormat-full": "{1} {0}", 
+	],
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "E, M-d",
+	"dateTimeFormat-full": "{1} {0}",
 	"days-format-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"months-standAlone-abbr-leap": "Adar II", 
-	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})", 
-	"dateFormatItem-y": "y", 
+	],
+	"months-standAlone-abbr-leap": "Adar II",
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"Tishri", 
-		"Heshvan", 
-		"Kislev", 
-		"Tevet", 
-		"Shevat", 
-		"Adar I", 
-		"Adar", 
-		"Nisan", 
-		"Iyar", 
-		"Sivan", 
-		"Tamuz", 
-		"Av", 
+		"Tishri",
+		"Heshvan",
+		"Kislev",
+		"Tevet",
+		"Shevat",
+		"Adar I",
+		"Adar",
+		"Nisan",
+		"Iyar",
+		"Sivan",
+		"Tamuz",
+		"Av",
 		"Elul"
-	], 
-	"dateFormatItem-hm": "h:mm a", 
-	"dateTimeFormats-appendItem-Year": "{0} {1}", 
-	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})", 
-	"dayPeriods-format-abbr-pm": "PM", 
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"eraNames": [
 		"AM"
-	], 
+	],
 	"days-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"days-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})", 
-	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})", 
-	"dateFormat-short": "yyyy-MM-dd", 
-	"dateFormatItem-yMMMEd": "EEE, y MMM d", 
-	"dateTimeFormats-appendItem-Timezone": "{0} {1}", 
-	"dateFormat-medium": "y MMM d", 
-	"dayPeriods-format-narrow-pm": "PM", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
-	"dateFormatItem-hms": "h:mm:ss a", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "yyyy-MM-dd",
+	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"dateFormat-medium": "y MMM d",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
 	"months-format-wide-leap": "Adar II"
-})
\ No newline at end of file
+}
+//end v1.x content
+,
+	"ar": true,
+	"el": true,
+	"fi": true,
+	"fr": true,
+	"he": true,
+	"hu": true,
+	"nl": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/currency.js b/dojo/cldr/nls/hu/currency.js
index fc8ac15..73da330 100644
--- a/dojo/cldr/nls/hu/currency.js
+++ b/dojo/cldr/nls/hu/currency.js
@@ -1,15 +1,17 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Ausztrál dollár",
-	CAD_displayName:"Kanadai dollár",
-	CHF_displayName:"Svájci frank",
-	CNY_displayName:"Kínai jüan renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Brit font sterling",
-	HKD_displayName:"Hongkongi dollár",
-	JPY_displayName:"Japán jen",
-	JPY_symbol:"¥",
-	USD_displayName:"USA dollár",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkongi dollár",
+	"CHF_displayName": "Svájci frank",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "Kanadai dollár",
+	"CNY_displayName": "Kínai jüan renminbi",
+	"USD_symbol": "$",
+	"AUD_displayName": "Ausztrál dollár",
+	"JPY_displayName": "Japán jen",
+	"USD_displayName": "USA dollár",
+	"GBP_displayName": "Brit font sterling",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/gregorian.js b/dojo/cldr/nls/hu/gregorian.js
index d091582..040c862 100644
--- a/dojo/cldr/nls/hu/gregorian.js
+++ b/dojo/cldr/nls/hu/gregorian.js
@@ -1,219 +1,227 @@
-({
-	"field-dayperiod": "napszak", 
-	"dayPeriods-format-wide-pm": "du.", 
-	"field-minute": "perc", 
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "napszak",
+	"dayPeriods-format-wide-pm": "du.",
+	"field-minute": "perc",
 	"eraNames": [
-		"időszámításunk előtt", 
+		"időszámításunk előtt",
 		"időszámításunk szerint"
-	], 
-	"field-day-relative+-1": "tegnap", 
-	"dateFormatItem-MMdd": "MM.dd.", 
-	"field-day-relative+-2": "tegnapelőtt", 
-	"field-weekday": "hét napja", 
-	"field-day-relative+-3": "három nappal ezelőtt", 
+	],
+	"dateFormatItem-MMMEd": "MMM d., E",
+	"field-day-relative+-1": "tegnap",
+	"field-weekday": "hét napja",
+	"field-day-relative+-2": "tegnapelőtt",
+	"dateFormatItem-MMdd": "MM.dd.",
+	"field-day-relative+-3": "három nappal ezelőtt",
 	"days-standAlone-wide": [
-		"vasárnap", 
-		"hétfő", 
-		"kedd", 
-		"szerda", 
-		"csütörtök", 
-		"péntek", 
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
 		"szombat"
-	], 
-	"dateFormatItem-MMM": "LLL", 
+	],
+	"dateFormatItem-MMM": "LLL",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"Á", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"Sz", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"Á",
+		"M",
+		"J",
+		"J",
+		"A",
+		"Sz",
+		"O",
+		"N",
 		"D"
-	], 
-	"dayPeriods-format-wide-am": "de.", 
-	"field-era": "éra", 
-	"field-hour": "óra", 
+	],
+	"field-era": "éra",
+	"field-hour": "óra",
+	"dayPeriods-format-wide-am": "de.",
 	"quarters-standAlone-abbr": [
-		"N1", 
-		"N2", 
-		"N3", 
+		"N1",
+		"N2",
+		"N3",
 		"N4"
-	], 
-	"timeFormat-full": "H:mm:ss zzzz", 
+	],
+	"timeFormat-full": "H:mm:ss zzzz",
 	"months-standAlone-abbr": [
-		"jan.", 
-		"febr.", 
-		"márc.", 
-		"ápr.", 
-		"máj.", 
-		"jún.", 
-		"júl.", 
-		"aug.", 
-		"szept.", 
-		"okt.", 
-		"nov.", 
+		"jan.",
+		"febr.",
+		"márc.",
+		"ápr.",
+		"máj.",
+		"jún.",
+		"júl.",
+		"aug.",
+		"szept.",
+		"okt.",
+		"nov.",
 		"dec."
-	], 
-	"field-day-relative+0": "ma", 
+	],
+	"dateFormatItem-Ed": "d., E",
+	"field-day-relative+0": "ma",
+	"field-day-relative+1": "holnap",
 	"days-standAlone-narrow": [
-		"V", 
-		"H", 
-		"K", 
-		"Sz", 
-		"Cs", 
-		"P", 
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
 		"Sz"
-	], 
-	"field-day-relative+1": "holnap", 
+	],
 	"eraAbbr": [
-		"i. e.", 
+		"i. e.",
 		"i. sz."
-	], 
-	"field-day-relative+2": "holnapután", 
-	"field-day-relative+3": "három nap múlva", 
-	"dateFormatItem-yyyyMM": "yyyy.MM", 
-	"dateFormatItem-yyyyMMMM": "y. MMMM", 
-	"dateFormat-long": "y. MMMM d.", 
-	"timeFormat-medium": "H:mm:ss", 
-	"field-zone": "zóna", 
-	"dateFormatItem-Hm": "H:mm", 
-	"dateFormat-medium": "yyyy.MM.dd.", 
-	"dateFormatItem-Hms": "H:mm:ss", 
+	],
+	"field-day-relative+2": "holnapután",
+	"field-day-relative+3": "három nap múlva",
+	"dateFormatItem-yyyyMM": "yyyy.MM",
+	"dateFormatItem-yyyyMMMM": "y. MMMM",
+	"dateFormat-long": "y. MMMM d.",
+	"timeFormat-medium": "H:mm:ss",
+	"field-zone": "zóna",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormat-medium": "yyyy.MM.dd.",
+	"dateFormatItem-Hms": "H:mm:ss",
 	"quarters-standAlone-wide": [
-		"I. negyedév", 
-		"II. negyedév", 
-		"III. negyedév", 
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
 		"IV. negyedév"
-	], 
-	"field-year": "év", 
-	"field-week": "hét", 
+	],
+	"field-year": "év",
+	"field-week": "hét",
 	"months-standAlone-wide": [
-		"január", 
-		"február", 
-		"március", 
-		"április", 
-		"május", 
-		"június", 
-		"július", 
-		"augusztus", 
-		"szeptember", 
-		"október", 
-		"november", 
+		"január",
+		"február",
+		"március",
+		"április",
+		"május",
+		"június",
+		"július",
+		"augusztus",
+		"szeptember",
+		"október",
+		"november",
 		"december"
-	], 
-	"dateFormatItem-MMMd": "MMM d.", 
-	"dateFormatItem-yyQ": "yy/Q", 
-	"timeFormat-long": "H:mm:ss z", 
+	],
+	"dateFormatItem-MMMd": "MMM d.",
+	"dateFormatItem-yyQ": "yy/Q",
+	"timeFormat-long": "H:mm:ss z",
 	"months-format-abbr": [
-		"jan.", 
-		"febr.", 
-		"márc.", 
-		"ápr.", 
-		"máj.", 
-		"jún.", 
-		"júl.", 
-		"aug.", 
-		"szept.", 
-		"okt.", 
-		"nov.", 
+		"jan.",
+		"febr.",
+		"márc.",
+		"ápr.",
+		"máj.",
+		"jún.",
+		"júl.",
+		"aug.",
+		"szept.",
+		"okt.",
+		"nov.",
 		"dec."
-	], 
-	"timeFormat-short": "H:mm", 
-	"dateFormatItem-H": "H", 
-	"field-month": "hónap", 
-	"dateFormatItem-MMMMd": "MMMM d.", 
+	],
+	"timeFormat-short": "H:mm",
+	"dateFormatItem-H": "H",
+	"field-month": "hónap",
+	"dateFormatItem-MMMMd": "MMMM d.",
 	"quarters-format-abbr": [
-		"N1", 
-		"N2", 
-		"N3", 
+		"N1",
+		"N2",
+		"N3",
 		"N4"
-	], 
+	],
 	"days-format-abbr": [
-		"V", 
-		"H", 
-		"K", 
-		"Sze", 
-		"Cs", 
-		"P", 
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
 		"Szo"
-	], 
-	"dateFormatItem-mmss": "mm:ss", 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-M": "L",
 	"days-format-narrow": [
-		"V", 
-		"H", 
-		"K", 
-		"Sz", 
-		"Cs", 
-		"P", 
+		"V",
+		"H",
+		"K",
+		"Sz",
+		"Cs",
+		"P",
 		"Sz"
-	], 
-	"field-second": "másodperc", 
-	"field-day": "nap", 
-	"dateFormatItem-MEd": "M. d., E", 
+	],
+	"field-second": "másodperc",
+	"field-day": "nap",
+	"dateFormatItem-MEd": "M. d., E",
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"Á", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"Sz", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"Á",
+		"M",
+		"J",
+		"J",
+		"A",
+		"Sz",
+		"O",
+		"N",
 		"D"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"V", 
-		"H", 
-		"K", 
-		"Sze", 
-		"Cs", 
-		"P", 
+		"V",
+		"H",
+		"K",
+		"Sze",
+		"Cs",
+		"P",
 		"Szo"
-	], 
-	"dateFormat-short": "yyyy.MM.dd.", 
-	"dateFormat-full": "y. MMMM d., EEEE", 
-	"dateFormatItem-Md": "M. d.", 
+	],
+	"dateFormat-short": "yyyy.MM.dd.",
+	"dateFormatItem-yMMMEd": "y. MMM d., E",
+	"dateFormat-full": "y. MMMM d., EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"dateFormatItem-yMEd": "yyyy.MM.dd., E",
 	"months-format-wide": [
-		"január", 
-		"február", 
-		"március", 
-		"április", 
-		"május", 
-		"június", 
-		"július", 
-		"augusztus", 
-		"szeptember", 
-		"október", 
-		"november", 
+		"január",
+		"február",
+		"március",
+		"április",
+		"május",
+		"június",
+		"július",
+		"augusztus",
+		"szeptember",
+		"október",
+		"november",
 		"december"
-	], 
-	"dateFormatItem-d": "d", 
+	],
+	"dateFormatItem-d": "d",
 	"quarters-format-wide": [
-		"I. negyedév", 
-		"II. negyedév", 
-		"III. negyedév", 
+		"I. negyedév",
+		"II. negyedév",
+		"III. negyedév",
 		"IV. negyedév"
-	], 
+	],
 	"days-format-wide": [
-		"vasárnap", 
-		"hétfő", 
-		"kedd", 
-		"szerda", 
-		"csütörtök", 
-		"péntek", 
+		"vasárnap",
+		"hétfő",
+		"kedd",
+		"szerda",
+		"csütörtök",
+		"péntek",
 		"szombat"
-	], 
+	],
 	"eraNarrow": [
-		"i. e.", 
+		"i. e.",
 		"i. sz."
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/hu/number.js b/dojo/cldr/nls/hu/number.js
index 0dff8f1..7400fec 100644
--- a/dojo/cldr/nls/hu/number.js
+++ b/dojo/cldr/nls/hu/number.js
@@ -1,18 +1,21 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/islamic.js b/dojo/cldr/nls/islamic.js
index 7f131c4..0c0c3ee 100644
--- a/dojo/cldr/nls/islamic.js
+++ b/dojo/cldr/nls/islamic.js
@@ -1,236 +1,264 @@
-({
+define({ root:
+
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
+	],
 	"quarters-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, y-M-d", 
-	"dateFormatItem-MMMEd": "E MMM d", 
+	],
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, y-M-d",
+	"dateFormatItem-MMMEd": "E MMM d",
 	"eraNarrow": [
 		"AH"
-	], 
-	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}", 
-	"dateFormat-long": "y MMMM d", 
+	],
+	"dateTimeFormats-appendItem-Day-Of-Week": "{0} {1}",
+	"dateFormat-long": "y MMMM d",
 	"months-format-wide": [
-		"Muharram", 
-		"Safar", 
-		"Rabiʻ I", 
-		"Rabiʻ II", 
-		"Jumada I", 
-		"Jumada II", 
-		"Rajab", 
-		"Shaʻban", 
-		"Ramadan", 
-		"Shawwal", 
-		"Dhuʻl-Qiʻdah", 
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
 		"Dhuʻl-Hijjah"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dateFormatItem-EEEd": "d EEE", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE, y MMMM dd", 
-	"dateFormatItem-Md": "M-d", 
-	"dayPeriods-format-abbr-am": "AM", 
-	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})", 
-	"dateFormatItem-yM": "y-M", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-EEEd": "d EEE",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, y MMMM dd",
+	"dateFormatItem-Md": "M-d",
+	"dayPeriods-format-abbr-am": "AM",
+	"dateTimeFormats-appendItem-Second": "{0} ({2}: {1})",
+	"dateFormatItem-yM": "y-M",
 	"months-standAlone-wide": [
-		"Muharram", 
-		"Safar", 
-		"Rabiʻ I", 
-		"Rabiʻ II", 
-		"Jumada I", 
-		"Jumada II", 
-		"Rajab", 
-		"Shaʻban", 
-		"Ramadan", 
-		"Shawwal", 
-		"Dhuʻl-Qiʻdah", 
+		"Muharram",
+		"Safar",
+		"Rabiʻ I",
+		"Rabiʻ II",
+		"Jumada I",
+		"Jumada II",
+		"Rajab",
+		"Shaʻban",
+		"Ramadan",
+		"Shawwal",
+		"Dhuʻl-Qiʻdah",
 		"Dhuʻl-Hijjah"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"dateFormatItem-yMMM": "y MMM", 
-	"dateFormatItem-yQ": "y Q", 
-	"dateTimeFormats-appendItem-Era": "{0} {1}", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"dateFormatItem-yMMM": "y MMM",
+	"dateFormatItem-yQ": "y Q",
+	"dateTimeFormats-appendItem-Era": "{0} {1}",
 	"months-format-abbr": [
-		"Muh.", 
-		"Saf.", 
-		"Rab. I", 
-		"Rab. II", 
-		"Jum. I", 
-		"Jum. II", 
-		"Raj.", 
-		"Sha.", 
-		"Ram.", 
-		"Shaw.", 
-		"Dhuʻl-Q.", 
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
 		"Dhuʻl-H."
-	], 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})", 
-	"dateFormatItem-H": "HH", 
+	],
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"dateTimeFormats-appendItem-Week": "{0} ({2}: {1})",
+	"dateFormatItem-H": "HH",
 	"months-standAlone-abbr": [
-		"Muh.", 
-		"Saf.", 
-		"Rab. I", 
-		"Rab. II", 
-		"Jum. I", 
-		"Jum. II", 
-		"Raj.", 
-		"Sha.", 
-		"Ram.", 
-		"Shaw.", 
-		"Dhuʻl-Q.", 
+		"Muh.",
+		"Saf.",
+		"Rab. I",
+		"Rab. II",
+		"Jum. I",
+		"Jum. II",
+		"Raj.",
+		"Sha.",
+		"Ram.",
+		"Shaw.",
+		"Dhuʻl-Q.",
 		"Dhuʻl-H."
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"eraAbbr": [
 		"AH"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
 	"quarters-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"dateFormatItem-h": "h a", 
-	"dateTimeFormat-long": "{1} {0}", 
-	"dayPeriods-format-narrow-am": "AM", 
-	"dateFormatItem-MMMd": "MMM d", 
-	"dateFormatItem-MEd": "E, M-d", 
-	"dateTimeFormat-full": "{1} {0}", 
+	],
+	"dateFormatItem-h": "h a",
+	"dateTimeFormat-long": "{1} {0}",
+	"dayPeriods-format-narrow-am": "AM",
+	"dateFormatItem-MMMd": "MMM d",
+	"dateFormatItem-MEd": "E, M-d",
+	"dateTimeFormat-full": "{1} {0}",
 	"days-format-wide": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})", 
-	"dateFormatItem-y": "y", 
+	],
+	"dateTimeFormats-appendItem-Day": "{0} ({2}: {1})",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"dateFormatItem-hm": "h:mm a", 
-	"dateTimeFormats-appendItem-Year": "{0} {1}", 
-	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})", 
-	"dayPeriods-format-abbr-pm": "PM", 
+	],
+	"dateFormatItem-hm": "h:mm a",
+	"dateTimeFormats-appendItem-Year": "{0} {1}",
+	"dateTimeFormats-appendItem-Hour": "{0} ({2}: {1})",
+	"dayPeriods-format-abbr-pm": "PM",
 	"days-format-abbr": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"eraNames": [
 		"AH"
-	], 
+	],
 	"days-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
+	],
 	"days-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
 		"7"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})", 
-	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})", 
-	"dateFormat-short": "yyyy-MM-dd", 
-	"dateFormatItem-yMMMEd": "EEE, y MMM d", 
-	"dateTimeFormats-appendItem-Timezone": "{0} {1}", 
-	"dateFormat-medium": "y MMM d", 
-	"dayPeriods-format-narrow-pm": "PM", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dateTimeFormats-appendItem-Quarter": "{0} ({2}: {1})",
+	"dayPeriods-format-wide-am": "AM",
+	"dateTimeFormats-appendItem-Month": "{0} ({2}: {1})",
+	"dateTimeFormats-appendItem-Minute": "{0} ({2}: {1})",
+	"dateFormat-short": "yyyy-MM-dd",
+	"dateFormatItem-yMMMEd": "EEE, y MMM d",
+	"dateTimeFormats-appendItem-Timezone": "{0} {1}",
+	"dateFormat-medium": "y MMM d",
+	"dayPeriods-format-narrow-pm": "PM",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+,
+	"ar": true,
+	"da": true,
+	"de": true,
+	"en": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"he": true,
+	"hu": true,
+	"it": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ru": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/currency.js b/dojo/cldr/nls/it/currency.js
index 2ea10ba..520a731 100644
--- a/dojo/cldr/nls/it/currency.js
+++ b/dojo/cldr/nls/it/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Dollaro Australiano",
-	CAD_displayName:"Dollaro Canadese",
-	CHF_displayName:"Franco Svizzero",
-	CNY_displayName:"Renmimbi Cinese",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Sterlina Inglese",
-	HKD_displayName:"Dollaro di Hong Kong",
-	JPY_displayName:"Yen Giapponese",
-	USD_displayName:"Dollaro Statunitense"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Dollaro di Hong Kong",
+	"CHF_displayName": "Franco Svizzero",
+	"CAD_displayName": "Dollaro Canadese",
+	"CNY_displayName": "Renmimbi Cinese",
+	"AUD_displayName": "Dollaro Australiano",
+	"JPY_displayName": "Yen Giapponese",
+	"USD_displayName": "Dollaro Statunitense",
+	"GBP_displayName": "Sterlina Inglese",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/gregorian.js b/dojo/cldr/nls/it/gregorian.js
index 237bdb4..c10ef3c 100644
--- a/dojo/cldr/nls/it/gregorian.js
+++ b/dojo/cldr/nls/it/gregorian.js
@@ -1,230 +1,235 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"G", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"G", 
-		"L", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"G",
+		"F",
+		"M",
+		"A",
+		"M",
+		"G",
+		"L",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "giorno della settimana", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE, d/M/y", 
-	"dateFormatItem-MMMEd": "EEE d MMM", 
+	],
+	"field-weekday": "giorno della settimana",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE, d/M/y",
+	"dateFormatItem-MMMEd": "EEE d MMM",
 	"eraNarrow": [
-		"aC", 
+		"aC",
 		"dC"
-	], 
-	"dateFormat-long": "dd MMMM y", 
+	],
+	"dateFormat-long": "dd MMMM y",
 	"months-format-wide": [
-		"gennaio", 
-		"febbraio", 
-		"marzo", 
-		"aprile", 
-		"maggio", 
-		"giugno", 
-		"luglio", 
-		"agosto", 
-		"settembre", 
-		"ottobre", 
-		"novembre", 
+		"gennaio",
+		"febbraio",
+		"marzo",
+		"aprile",
+		"maggio",
+		"giugno",
+		"luglio",
+		"agosto",
+		"settembre",
+		"ottobre",
+		"novembre",
 		"dicembre"
-	], 
-	"dayPeriods-format-wide-pm": "p.", 
-	"dateFormat-full": "EEEE d MMMM y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "era", 
-	"dateFormatItem-yM": "M/y", 
+	],
+	"dayPeriods-format-wide-pm": "p.",
+	"dateFormat-full": "EEEE d MMMM y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "era",
+	"dateFormatItem-yM": "M/y",
 	"months-standAlone-wide": [
-		"Gennaio", 
-		"Febbraio", 
-		"Marzo", 
-		"Aprile", 
-		"Maggio", 
-		"Giugno", 
-		"Luglio", 
-		"Agosto", 
-		"Settembre", 
-		"Ottobre", 
-		"Novembre", 
+		"Gennaio",
+		"Febbraio",
+		"Marzo",
+		"Aprile",
+		"Maggio",
+		"Giugno",
+		"Luglio",
+		"Agosto",
+		"Settembre",
+		"Ottobre",
+		"Novembre",
 		"Dicembre"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1o trimestre", 
-		"2o trimestre", 
-		"3o trimestre", 
+		"1o trimestre",
+		"2o trimestre",
+		"3o trimestre",
 		"4o trimestre"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "anno", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q-yyyy", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"field-hour": "ora", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "anno",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q-yyyy",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "ora",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"gen", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"mag", 
-		"giu", 
-		"lug", 
-		"ago", 
-		"set", 
-		"ott", 
-		"nov", 
+		"gen",
+		"feb",
+		"mar",
+		"apr",
+		"mag",
+		"giu",
+		"lug",
+		"ago",
+		"set",
+		"ott",
+		"nov",
 		"dic"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "oggi", 
-	"field-day-relative+1": "domani", 
-	"field-day-relative+2": "dopodomani", 
-	"field-day-relative+3": "tra tre giorni", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "oggi",
+	"field-day-relative+1": "domani",
+	"field-day-relative+2": "dopodomani",
+	"field-day-relative+3": "tra tre giorni",
 	"months-standAlone-abbr": [
-		"gen", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"mag", 
-		"giu", 
-		"lug", 
-		"ago", 
-		"set", 
-		"ott", 
-		"nov", 
+		"gen",
+		"feb",
+		"mar",
+		"apr",
+		"mag",
+		"giu",
+		"lug",
+		"ago",
+		"set",
+		"ott",
+		"nov",
 		"dic"
-	], 
+	],
 	"quarters-format-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1o trimestre", 
-		"2o trimestre", 
-		"3o trimestre", 
+		"1o trimestre",
+		"2o trimestre",
+		"3o trimestre",
 		"4o trimestre"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"Domenica", 
-		"Lunedì", 
-		"Martedì", 
-		"Mercoledì", 
-		"Giovedì", 
-		"Venerdì", 
+		"Domenica",
+		"Lunedì",
+		"Martedì",
+		"Mercoledì",
+		"Giovedì",
+		"Venerdì",
 		"Sabato"
-	], 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"eraAbbr": [
-		"aC", 
+		"aC",
 		"dC"
-	], 
-	"field-minute": "minuto", 
-	"field-dayperiod": "periodo del giorno", 
+	],
+	"field-minute": "minuto",
+	"field-dayperiod": "periodo del giorno",
 	"days-standAlone-abbr": [
-		"dom", 
-		"lun", 
-		"mar", 
-		"mer", 
-		"gio", 
-		"ven", 
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
 		"sab"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "ieri", 
-	"dateFormatItem-h": "hh a", 
-	"field-day-relative+-2": "l'altro ieri", 
-	"field-day-relative+-3": "tre giorni fa", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "EEE d/M", 
-	"field-day": "giorno", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "ieri",
+	"dateFormatItem-h": "hh a",
+	"field-day-relative+-2": "l'altro ieri",
+	"field-day-relative+-3": "tre giorni fa",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "EEE d/M",
+	"field-day": "giorno",
 	"days-format-wide": [
-		"domenica", 
-		"lunedì", 
-		"martedì", 
-		"mercoledì", 
-		"giovedì", 
-		"venerdì", 
+		"domenica",
+		"lunedì",
+		"martedì",
+		"mercoledì",
+		"giovedì",
+		"venerdì",
 		"sabato"
-	], 
-	"field-zone": "zona", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "zona",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"G", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"G", 
-		"L", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"G",
+		"F",
+		"M",
+		"A",
+		"M",
+		"G",
+		"L",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
-	"dateFormatItem-hm": "hh:mm a", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
+	"dateFormatItem-hm": "hh:mm a",
 	"days-format-abbr": [
-		"dom", 
-		"lun", 
-		"mar", 
-		"mer", 
-		"gio", 
-		"ven", 
+		"dom",
+		"lun",
+		"mar",
+		"mer",
+		"gio",
+		"ven",
 		"sab"
-	], 
+	],
 	"eraNames": [
-		"a.C.", 
+		"a.C.",
 		"d.C"
-	], 
+	],
 	"days-format-narrow": [
-		"D", 
-		"L", 
-		"M", 
-		"M", 
-		"G", 
-		"V", 
+		"D",
+		"L",
+		"M",
+		"M",
+		"G",
+		"V",
 		"S"
-	], 
-	"field-month": "mese", 
+	],
+	"field-month": "mese",
 	"days-standAlone-narrow": [
-		"D", 
-		"L", 
-		"M", 
-		"M", 
-		"G", 
-		"V", 
+		"D",
+		"L",
+		"M",
+		"M",
+		"G",
+		"V",
 		"S"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "m.", 
-	"dateFormatItem-MMMMdd": "dd MMMM", 
-	"dateFormat-short": "dd/MM/yy", 
-	"field-second": "secondo", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"field-week": "settimana", 
-	"dateFormat-medium": "dd/MMM/y", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "m.",
+	"dateFormatItem-MMMMdd": "dd MMMM",
+	"dateFormat-short": "dd/MM/yy",
+	"field-second": "secondo",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "settimana",
+	"dateFormat-medium": "dd/MMM/y",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "hh:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/it/number.js b/dojo/cldr/nls/it/number.js
index 3b94127..370261f 100644
--- a/dojo/cldr/nls/it/number.js
+++ b/dojo/cldr/nls/it/number.js
@@ -1,9 +1,12 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤ #,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"decimalFormat": "#,##0.###",
+	"group": ".",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"currencyFormat": "¤ #,##0.00",
+	"decimal": ","
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/currency.js b/dojo/cldr/nls/ja/currency.js
index 43d9ec5..4955625 100644
--- a/dojo/cldr/nls/ja/currency.js
+++ b/dojo/cldr/nls/ja/currency.js
@@ -1,16 +1,18 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"オーストラリア ドル",
-	CAD_displayName:"カナダ ドル",
-	CHF_displayName:"スイス フラン",
-	CNY_displayName:"中国人民元",
-	CNY_symbol:"元",
-	EUR_displayName:"ユーロ",
-	GBP_displayName:"英国ポンド",
-	HKD_displayName:"香港ドル",
-	JPY_displayName:"日本円",
-	JPY_symbol:"¥",
-	USD_displayName:"米ドル",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "香港ドル",
+	"CHF_displayName": "スイス フラン",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "カナダ ドル",
+	"CNY_displayName": "中国人民元",
+	"USD_symbol": "$",
+	"AUD_displayName": "オーストラリア ドル",
+	"JPY_displayName": "日本円",
+	"USD_displayName": "米ドル",
+	"CNY_symbol": "元",
+	"GBP_displayName": "英国ポンド",
+	"EUR_displayName": "ユーロ"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/gregorian.js b/dojo/cldr/nls/ja/gregorian.js
index 372f6c9..241c82b 100644
--- a/dojo/cldr/nls/ja/gregorian.js
+++ b/dojo/cldr/nls/ja/gregorian.js
@@ -1,218 +1,222 @@
-({
-	"field-weekday": "曜日", 
-	"dateFormatItem-yQQQ": "yQQQ", 
-	"dateFormatItem-yMEd": "y/M/d(EEE)", 
-	"dateFormatItem-MMMEd": "M月d日(E)", 
+define(
+//begin v1.x content
+{
+	"field-weekday": "曜日",
+	"dateFormatItem-yQQQ": "yQQQ",
+	"dateFormatItem-yMEd": "y/M/d(EEE)",
+	"dateFormatItem-MMMEd": "M月d日(E)",
 	"eraNarrow": [
-		"BC", 
+		"BC",
 		"AD"
-	], 
-	"dateFormat-long": "y年M月d日", 
+	],
+	"dateFormat-long": "y年M月d日",
 	"months-format-wide": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dayPeriods-format-wide-pm": "午後", 
-	"dateFormat-full": "y年M月d日EEEE", 
-	"dateFormatItem-Md": "M/d", 
-	"dateFormatItem-yMd": "y/M/d", 
-	"field-era": "時代", 
-	"dateFormatItem-yM": "y/M", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "午後",
+	"dateFormat-full": "y年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yMd": "y/M/d",
+	"field-era": "時代",
+	"dateFormatItem-yM": "y/M",
 	"months-standAlone-wide": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"timeFormat-short": "H:mm", 
+	],
+	"timeFormat-short": "H:mm",
 	"quarters-format-wide": [
-		"第1四半期", 
-		"第2四半期", 
-		"第3四半期", 
+		"第1四半期",
+		"第2四半期",
+		"第3四半期",
 		"第4四半期"
-	], 
-	"timeFormat-long": "H:mm:ss z", 
-	"field-year": "年", 
-	"dateFormatItem-yMMM": "y年M月", 
-	"dateFormatItem-yQ": "y/Q", 
-	"field-hour": "時", 
-	"dateFormatItem-MMdd": "MM/dd", 
-	"dateFormatItem-yyQ": "yy/Q", 
+	],
+	"timeFormat-long": "H:mm:ss z",
+	"field-year": "年",
+	"dateFormatItem-yMMM": "y年M月",
+	"dateFormatItem-yQ": "y/Q",
+	"field-hour": "時",
+	"dateFormatItem-MMdd": "MM/dd",
 	"months-format-abbr": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"timeFormat-full": "H時mm分ss秒 zzzz", 
-	"field-day-relative+0": "今日", 
-	"field-day-relative+1": "明日", 
-	"field-day-relative+2": "明後日", 
-	"dateFormatItem-H": "H時", 
-	"field-day-relative+3": "3日後", 
+	],
+	"dateFormatItem-yyQ": "yy/Q",
+	"timeFormat-full": "H時mm分ss秒 zzzz",
+	"field-day-relative+0": "今日",
+	"field-day-relative+1": "明日",
+	"field-day-relative+2": "明後日",
+	"dateFormatItem-H": "H時",
+	"field-day-relative+3": "3日後",
 	"months-standAlone-abbr": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"第1四半期", 
-		"第2四半期", 
-		"第3四半期", 
+		"第1四半期",
+		"第2四半期",
+		"第3四半期",
 		"第4四半期"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "M月",
 	"days-standAlone-wide": [
-		"日曜日", 
-		"月曜日", 
-		"火曜日", 
-		"水曜日", 
-		"木曜日", 
-		"金曜日", 
+		"日曜日",
+		"月曜日",
+		"火曜日",
+		"水曜日",
+		"木曜日",
+		"金曜日",
 		"土曜日"
-	], 
-	"dateFormatItem-yyMMM": "y年M月", 
-	"timeFormat-medium": "H:mm:ss", 
-	"dateFormatItem-Hm": "H:mm", 
+	],
+	"dateFormatItem-yyMMM": "y年M月",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
 	"eraAbbr": [
-		"BC", 
+		"BC",
 		"AD"
-	], 
-	"field-minute": "分", 
-	"field-dayperiod": "午前/午後", 
+	],
+	"field-minute": "分",
+	"field-dayperiod": "午前/午後",
 	"days-standAlone-abbr": [
-		"日", 
-		"月", 
-		"火", 
-		"水", 
-		"木", 
-		"金", 
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
 		"土"
-	], 
-	"dateFormatItem-d": "d日", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "昨日", 
-	"dateFormatItem-h": "ah", 
-	"dateTimeFormat-long": "{1}{0}", 
-	"field-day-relative+-2": "一昨日", 
-	"field-day-relative+-3": "3日前", 
-	"dateFormatItem-MMMd": "M月d日", 
-	"dateFormatItem-MEd": "M/d(E)", 
-	"dateTimeFormat-full": "{1}{0}", 
-	"field-day": "日", 
+	],
+	"dateFormatItem-d": "d日",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "昨日",
+	"dateFormatItem-h": "ah時",
+	"dateTimeFormat-long": "{1}{0}",
+	"field-day-relative+-2": "一昨日",
+	"field-day-relative+-3": "3日前",
+	"dateFormatItem-MMMd": "M月d日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
 	"days-format-wide": [
-		"日曜日", 
-		"月曜日", 
-		"火曜日", 
-		"水曜日", 
-		"木曜日", 
-		"金曜日", 
+		"日曜日",
+		"月曜日",
+		"火曜日",
+		"水曜日",
+		"木曜日",
+		"金曜日",
 		"土曜日"
-	], 
-	"field-zone": "タイムゾーン", 
-	"dateFormatItem-yyyyMM": "yyyy/MM", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "タイムゾーン",
+	"dateFormatItem-yyyyMM": "yyyy/MM",
+	"dateFormatItem-y": "y年",
 	"months-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
 		"12"
-	], 
-	"dateFormatItem-hm": "ah:mm", 
-	"dateFormatItem-GGGGyMd": "GGGGy年M月d日", 
+	],
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormatItem-GGGGyMd": "GGGGy年M月d日",
 	"days-format-abbr": [
-		"日", 
-		"月", 
-		"火", 
-		"水", 
-		"木", 
-		"金", 
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
 		"土"
-	], 
-	"dateFormatItem-yMMMd": "y年M月d日", 
+	],
+	"dateFormatItem-yMMMd": "y年M月d日",
 	"eraNames": [
-		"紀元前", 
+		"紀元前",
 		"西暦"
-	], 
+	],
 	"days-format-narrow": [
-		"日", 
-		"月", 
-		"火", 
-		"水", 
-		"木", 
-		"金", 
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
 		"土"
-	], 
-	"field-month": "月", 
+	],
+	"field-month": "月",
 	"days-standAlone-narrow": [
-		"日", 
-		"月", 
-		"火", 
-		"水", 
-		"木", 
-		"金", 
+		"日",
+		"月",
+		"火",
+		"水",
+		"木",
+		"金",
 		"土"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "午前", 
-	"dateFormat-short": "yy/MM/dd", 
-	"field-second": "秒", 
-	"dateFormatItem-yMMMEd": "y年M月d日(EEE)", 
-	"dateFormatItem-Ed": "d日(EEE)", 
-	"field-week": "週", 
-	"dateFormat-medium": "yyyy/MM/dd", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "H:mm:ss", 
-	"dateFormatItem-hms": "ah:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "午前",
+	"dateFormat-short": "yy/MM/dd",
+	"field-second": "秒",
+	"dateFormatItem-yMMMEd": "y年M月d日(EEE)",
+	"dateFormatItem-Ed": "d日(EEE)",
+	"field-week": "週",
+	"dateFormat-medium": "yyyy/MM/dd",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
 	"dateFormatItem-yyyy": "y年"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ja/number.js b/dojo/cldr/nls/ja/number.js
index 018f6e8..afbe6ca 100644
--- a/dojo/cldr/nls/ja/number.js
+++ b/dojo/cldr/nls/ja/number.js
@@ -1,9 +1,12 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤#,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"decimalFormat": "#,##0.###",
+	"group": ",",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"currencyFormat": "¤#,##0.00",
+	"decimal": "."
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/currency.js b/dojo/cldr/nls/ko/currency.js
index e30ea1b..41d6247 100644
--- a/dojo/cldr/nls/ko/currency.js
+++ b/dojo/cldr/nls/ko/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"호주 달러",
-	CAD_displayName:"캐나다 달러",
-	CHF_displayName:"스위스 프랑",
-	CNY_displayName:"중국 위안 인민폐",
-	EUR_displayName:"유로화",
-	GBP_displayName:"영국령 파운드 스털링",
-	HKD_displayName:"홍콩 달러",
-	JPY_displayName:"일본 엔화",
-	USD_displayName:"미국 달러"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "홍콩 달러",
+	"CHF_displayName": "스위스 프랑",
+	"CAD_displayName": "캐나다 달러",
+	"CNY_displayName": "중국 위안 인민폐",
+	"AUD_displayName": "호주 달러",
+	"JPY_displayName": "일본 엔화",
+	"USD_displayName": "미국 달러",
+	"GBP_displayName": "영국령 파운드 스털링",
+	"EUR_displayName": "유로화"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/gregorian.js b/dojo/cldr/nls/ko/gregorian.js
index 06b27f8..ee950b9 100644
--- a/dojo/cldr/nls/ko/gregorian.js
+++ b/dojo/cldr/nls/ko/gregorian.js
@@ -1,238 +1,243 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"1월", 
-		"2월", 
-		"3월", 
-		"4월", 
-		"5월", 
-		"6월", 
-		"7월", 
-		"8월", 
-		"9월", 
-		"10월", 
-		"11월", 
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
 		"12월"
-	], 
-	"field-weekday": "요일", 
-	"dateFormatItem-yQQQ": "y년 QQQ", 
-	"dateFormatItem-yMEd": "yyyy. M. d. EEE", 
-	"dateFormatItem-MMMEd": "MMM d일 (E)", 
+	],
+	"field-weekday": "요일",
+	"dateFormatItem-yQQQ": "y년 QQQ",
+	"dateFormatItem-yMEd": "yyyy. M. d. EEE",
+	"dateFormatItem-MMMEd": "MMM d일 (E)",
 	"eraNarrow": [
-		"기원전", 
+		"기원전",
 		"서기"
-	], 
-	"dateFormat-long": "y년 M월 d일", 
+	],
+	"dateFormat-long": "y년 M월 d일",
 	"months-format-wide": [
-		"1월", 
-		"2월", 
-		"3월", 
-		"4월", 
-		"5월", 
-		"6월", 
-		"7월", 
-		"8월", 
-		"9월", 
-		"10월", 
-		"11월", 
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
 		"12월"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dateFormatItem-EEEd": "d일 EEE", 
-	"dayPeriods-format-wide-pm": "오후", 
-	"dateFormat-full": "y년 M월 d일 EEEE", 
-	"dateFormatItem-Md": "M. d.", 
-	"field-era": "연호", 
-	"dateFormatItem-yM": "yyyy. M.", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dateFormatItem-EEEd": "d일 EEE",
+	"dayPeriods-format-wide-pm": "오후",
+	"dateFormat-full": "y년 M월 d일 EEEE",
+	"dateFormatItem-Md": "M. d.",
+	"field-era": "연호",
+	"dateFormatItem-yM": "yyyy. M.",
 	"months-standAlone-wide": [
-		"1월", 
-		"2월", 
-		"3월", 
-		"4월", 
-		"5월", 
-		"6월", 
-		"7월", 
-		"8월", 
-		"9월", 
-		"10월", 
-		"11월", 
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
 		"12월"
-	], 
-	"timeFormat-short": "a h:mm", 
+	],
+	"timeFormat-short": "a h:mm",
 	"quarters-format-wide": [
-		"제 1/4분기", 
-		"제 2/4분기", 
-		"제 3/4분기", 
+		"제 1/4분기",
+		"제 2/4분기",
+		"제 3/4분기",
 		"제 4/4분기"
-	], 
-	"timeFormat-long": "a h시 m분 s초 z", 
-	"field-year": "년", 
-	"dateFormatItem-yMMM": "y년 MMM", 
-	"dateFormatItem-yQ": "y년 Q분기", 
-	"field-hour": "시", 
-	"dateFormatItem-MMdd": "MM. dd", 
-	"dateFormatItem-yyQ": "yy년 Q분기", 
+	],
+	"timeFormat-long": "a h시 m분 s초 z",
+	"field-year": "년",
+	"dateFormatItem-yMMM": "y년 MMM",
+	"dateFormatItem-yQ": "y년 Q분기",
+	"field-hour": "시",
+	"dateFormatItem-MMdd": "MM. dd",
 	"months-format-abbr": [
-		"1월", 
-		"2월", 
-		"3월", 
-		"4월", 
-		"5월", 
-		"6월", 
-		"7월", 
-		"8월", 
-		"9월", 
-		"10월", 
-		"11월", 
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
 		"12월"
-	], 
-	"timeFormat-full": "a h시 m분 s초 zzzz", 
-	"field-day-relative+0": "오늘", 
-	"field-day-relative+1": "내일", 
-	"field-day-relative+2": "모레", 
-	"field-day-relative+3": "3일후", 
+	],
+	"dateFormatItem-yyQ": "yy년 Q분기",
+	"timeFormat-full": "a h시 m분 s초 zzzz",
+	"field-day-relative+0": "오늘",
+	"field-day-relative+1": "내일",
+	"field-day-relative+2": "모레",
+	"dateFormatItem-H": "H시",
+	"field-day-relative+3": "3일후",
 	"months-standAlone-abbr": [
-		"1월", 
-		"2월", 
-		"3월", 
-		"4월", 
-		"5월", 
-		"6월", 
-		"7월", 
-		"8월", 
-		"9월", 
-		"10월", 
-		"11월", 
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
 		"12월"
-	], 
+	],
 	"quarters-format-abbr": [
-		"1분기", 
-		"2분기", 
-		"3분기", 
+		"1분기",
+		"2분기",
+		"3분기",
 		"4분기"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"제 1/4분기", 
-		"제 2/4분기", 
-		"제 3/4분기", 
+		"제 1/4분기",
+		"제 2/4분기",
+		"제 3/4분기",
 		"제 4/4분기"
-	], 
-	"dateFormatItem-HHmmss": "HH:mm:ss", 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-HHmmss": "HH:mm:ss",
+	"dateFormatItem-M": "M월",
 	"days-standAlone-wide": [
-		"일요일", 
-		"월요일", 
-		"화요일", 
-		"수요일", 
-		"목요일", 
-		"금요일", 
+		"일요일",
+		"월요일",
+		"화요일",
+		"수요일",
+		"목요일",
+		"금요일",
 		"토요일"
-	], 
-	"dateFormatItem-yyMMM": "yy년 MMM", 
-	"timeFormat-medium": "a h:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-yyMMM": "yy년 MMM",
+	"timeFormat-medium": "a h:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"1분기", 
-		"2분기", 
-		"3분기", 
+		"1분기",
+		"2분기",
+		"3분기",
 		"4분기"
-	], 
+	],
 	"eraAbbr": [
-		"기원전", 
+		"기원전",
 		"서기"
-	], 
-	"field-minute": "분", 
-	"field-dayperiod": "오전/오후", 
+	],
+	"field-minute": "분",
+	"field-dayperiod": "오전/오후",
 	"days-standAlone-abbr": [
-		"일", 
-		"월", 
-		"화", 
-		"수", 
-		"목", 
-		"금", 
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
 		"토"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "어제", 
-	"dateFormatItem-h": "a h", 
-	"dateTimeFormat-long": "{1} {0}", 
-	"field-day-relative+-2": "그저께", 
-	"field-day-relative+-3": "그끄제", 
-	"dateFormatItem-MMMd": "MMM d일", 
-	"dateFormatItem-MEd": "M. d. (E)", 
-	"dateTimeFormat-full": "{1} {0}", 
-	"field-day": "일", 
+	],
+	"dateFormatItem-d": "d일",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "어제",
+	"dateFormatItem-h": "a h시",
+	"dateTimeFormat-long": "{1} {0}",
+	"field-day-relative+-2": "그저께",
+	"field-day-relative+-3": "그끄제",
+	"dateFormatItem-MMMd": "MMM d일",
+	"dateFormatItem-MEd": "M. d. (E)",
+	"dateTimeFormat-full": "{1} {0}",
+	"field-day": "일",
 	"days-format-wide": [
-		"일요일", 
-		"월요일", 
-		"화요일", 
-		"수요일", 
-		"목요일", 
-		"금요일", 
+		"일요일",
+		"월요일",
+		"화요일",
+		"수요일",
+		"목요일",
+		"금요일",
 		"토요일"
-	], 
-	"field-zone": "시간대", 
-	"dateFormatItem-yyyyMM": "yyyy. MM", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "시간대",
+	"dateFormatItem-yyyyMM": "yyyy. MM",
+	"dateFormatItem-y": "y년",
 	"months-standAlone-narrow": [
-		"1월", 
-		"2월", 
-		"3월", 
-		"4월", 
-		"5월", 
-		"6월", 
-		"7월", 
-		"8월", 
-		"9월", 
-		"10월", 
-		"11월", 
+		"1월",
+		"2월",
+		"3월",
+		"4월",
+		"5월",
+		"6월",
+		"7월",
+		"8월",
+		"9월",
+		"10월",
+		"11월",
 		"12월"
-	], 
-	"dateFormatItem-yyMM": "YY. M.", 
-	"dateFormatItem-hm": "a h:mm", 
+	],
+	"dateFormatItem-yyMM": "YY. M.",
+	"dateFormatItem-hm": "a h:mm",
 	"days-format-abbr": [
-		"일", 
-		"월", 
-		"화", 
-		"수", 
-		"목", 
-		"금", 
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
 		"토"
-	], 
-	"dateFormatItem-yMMMd": "y년 MMM d일", 
+	],
+	"dateFormatItem-yMMMd": "y년 MMM d일",
 	"eraNames": [
-		"서력기원전", 
+		"서력기원전",
 		"서력기원"
-	], 
+	],
 	"days-format-narrow": [
-		"일", 
-		"월", 
-		"화", 
-		"수", 
-		"목", 
-		"금", 
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
 		"토"
-	], 
-	"field-month": "월", 
+	],
+	"field-month": "월",
 	"days-standAlone-narrow": [
-		"일", 
-		"월", 
-		"화", 
-		"수", 
-		"목", 
-		"금", 
+		"일",
+		"월",
+		"화",
+		"수",
+		"목",
+		"금",
 		"토"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "오전", 
-	"dateFormat-short": "yy. M. d.", 
-	"field-second": "초", 
-	"dateFormatItem-yMMMEd": "y년 MMM d일 EEE", 
-	"dateFormatItem-Ed": "d일 (E)", 
-	"field-week": "주", 
-	"dateFormat-medium": "yyyy. M. d.", 
-	"dateFormatItem-mmss": "mm:ss", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "H시 m분 s초", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "오전",
+	"dateFormat-short": "yy. M. d.",
+	"field-second": "초",
+	"dateFormatItem-yMMMEd": "y년 MMM d일 EEE",
+	"dateFormatItem-Ed": "d일 (E)",
+	"field-week": "주",
+	"dateFormat-medium": "yyyy. M. d.",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H시 m분 s초",
 	"dateFormatItem-hms": "a h:mm:ss"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ko/number.js b/dojo/cldr/nls/ko/number.js
index e06848f..7305f35 100644
--- a/dojo/cldr/nls/ko/number.js
+++ b/dojo/cldr/nls/ko/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤#,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤#,##0.00",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/currency.js b/dojo/cldr/nls/nb/currency.js
index 569148f..2f3d646 100644
--- a/dojo/cldr/nls/nb/currency.js
+++ b/dojo/cldr/nls/nb/currency.js
@@ -1,21 +1,23 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"australske dollar",
-	AUD_symbol:"AUD",
-	CAD_displayName:"kanadiske dollar",
-	CAD_symbol:"CAD",
-	CHF_displayName:"sveitsiske franc",
-	CHF_symbol:"CHF",
-	CNY_displayName:"kinesiske yuan renminbi",
-	CNY_symbol:"CNY",
-	EUR_displayName:"euro",
-	EUR_symbol:"EUR",
-	GBP_displayName:"britiske pund sterling",
-	GBP_symbol:"GBP",
-	HKD_displayName:"Hongkong-dollar",
-	JPY_displayName:"japanske yen",
-	JPY_symbol:"JPY",
-	USD_displayName:"amerikanske dollar",
-	USD_symbol:"USD"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkong-dollar",
+	"CHF_displayName": "sveitsiske franc",
+	"CHF_symbol": "CHF",
+	"JPY_symbol": "JPY",
+	"CAD_displayName": "kanadiske dollar",
+	"CNY_displayName": "kinesiske yuan renminbi",
+	"USD_symbol": "USD",
+	"AUD_displayName": "australske dollar",
+	"JPY_displayName": "japanske yen",
+	"CAD_symbol": "CAD",
+	"USD_displayName": "amerikanske dollar",
+	"EUR_symbol": "EUR",
+	"CNY_symbol": "CNY",
+	"GBP_displayName": "britiske pund sterling",
+	"GBP_symbol": "GBP",
+	"AUD_symbol": "AUD",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/gregorian.js b/dojo/cldr/nls/nb/gregorian.js
index 7ca1300..662c95a 100644
--- a/dojo/cldr/nls/nb/gregorian.js
+++ b/dojo/cldr/nls/nb/gregorian.js
@@ -1,230 +1,234 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "ukedag", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE d.M.yyyy", 
-	"dateFormatItem-MMMEd": "E d. MMM", 
+	],
+	"field-weekday": "ukedag",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE d.M.yyyy",
+	"dateFormatItem-MMMEd": "E d. MMM",
 	"eraNarrow": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
-	"dateFormat-long": "d. MMMM y", 
+	],
+	"dateFormat-long": "d. MMMM y",
 	"months-format-wide": [
-		"januar", 
-		"februar", 
-		"mars", 
-		"april", 
-		"mai", 
-		"juni", 
-		"juli", 
-		"august", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januar",
+		"februar",
+		"mars",
+		"april",
+		"mai",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
 		"desember"
-	], 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE d. MMMM y", 
-	"dateFormatItem-Md": "d.M.", 
-	"field-era": "tidsalder", 
-	"dateFormatItem-yM": "M y", 
+	],
+	"dateFormatItem-EEEd": "EEE d.",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE d. MMMM y",
+	"dateFormatItem-Md": "d.M.",
+	"field-era": "tidsalder",
+	"dateFormatItem-yM": "M y",
 	"months-standAlone-wide": [
-		"januar", 
-		"februar", 
-		"mars", 
-		"april", 
-		"mai", 
-		"juni", 
-		"juli", 
-		"august", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januar",
+		"februar",
+		"mars",
+		"april",
+		"mai",
+		"juni",
+		"juli",
+		"august",
+		"september",
+		"oktober",
+		"november",
 		"desember"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1. kvartal", 
-		"2. kvartal", 
-		"3. kvartal", 
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
 		"4. kvartal"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "år", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"field-hour": "time", 
-	"dateFormatItem-MMdd": "dd.MM", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "år",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "time",
+	"dateFormatItem-MMdd": "dd.MM",
 	"months-format-abbr": [
-		"jan.", 
-		"feb.", 
-		"mars", 
-		"apr.", 
-		"mai", 
-		"juni", 
-		"juli", 
-		"aug.", 
-		"sep.", 
-		"okt.", 
-		"nov.", 
+		"jan.",
+		"feb.",
+		"mars",
+		"apr.",
+		"mai",
+		"juni",
+		"juli",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
 		"des."
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "'kl'. HH:mm:ss zzzz", 
-	"field-day-relative+0": "i dag", 
-	"field-day-relative+1": "i morgen", 
-	"field-day-relative+2": "i overmorgen", 
-	"field-day-relative+3": "i overovermorgen", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgen",
+	"field-day-relative+2": "i overmorgen",
+	"field-day-relative+3": "i overovermorgen",
 	"months-standAlone-abbr": [
-		"jan.", 
-		"feb.", 
-		"mars", 
-		"apr.", 
-		"mai", 
-		"juni", 
-		"juli", 
-		"aug.", 
-		"sep.", 
-		"okt.", 
-		"nov.", 
+		"jan.",
+		"feb.",
+		"mars",
+		"apr.",
+		"mai",
+		"juni",
+		"juli",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
 		"des."
-	], 
+	],
 	"quarters-format-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1. kvartal", 
-		"2. kvartal", 
-		"3. kvartal", 
+		"1. kvartal",
+		"2. kvartal",
+		"3. kvartal",
 		"4. kvartal"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"søndag", 
-		"mandag", 
-		"tirsdag", 
-		"onsdag", 
-		"torsdag", 
-		"fredag", 
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
 		"lørdag"
-	], 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"eraAbbr": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
-	"field-minute": "minutt", 
-	"field-dayperiod": "AM/PM", 
+	],
+	"field-minute": "minutt",
+	"field-dayperiod": "AM/PM",
 	"days-standAlone-abbr": [
-		"søn.", 
-		"man.", 
-		"tir.", 
-		"ons.", 
-		"tor.", 
-		"fre.", 
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
 		"lør."
-	], 
-	"dateFormatItem-d": "d.", 
-	"dateFormatItem-ms": "mm.ss", 
-	"field-day-relative+-1": "i går", 
-	"field-day-relative+-2": "i forgårs", 
-	"field-day-relative+-3": "i forforgårs", 
-	"dateFormatItem-MMMd": "d. MMM", 
-	"dateFormatItem-MEd": "E d.M", 
-	"field-day": "dag", 
+	],
+	"dateFormatItem-d": "d.",
+	"dateFormatItem-ms": "mm.ss",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i forgårs",
+	"field-day-relative+-3": "i forforgårs",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-MEd": "E d.M",
+	"field-day": "dag",
 	"days-format-wide": [
-		"søndag", 
-		"mandag", 
-		"tirsdag", 
-		"onsdag", 
-		"torsdag", 
-		"fredag", 
+		"søndag",
+		"mandag",
+		"tirsdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
 		"lørdag"
-	], 
-	"field-zone": "sone", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "sone",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM.yy", 
-	"dateFormatItem-hm": "h:mm a", 
+	],
+	"dateFormatItem-yyMM": "MM.yy",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
-		"søn.", 
-		"man.", 
-		"tir.", 
-		"ons.", 
-		"tor.", 
-		"fre.", 
+		"søn.",
+		"man.",
+		"tir.",
+		"ons.",
+		"tor.",
+		"fre.",
 		"lør."
-	], 
+	],
 	"eraNames": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
+	],
 	"days-format-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"O", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
 		"L"
-	], 
-	"field-month": "måned", 
+	],
+	"field-month": "måned",
 	"days-standAlone-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"O", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
 		"L"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateFormat-short": "dd.MM.yy", 
-	"field-second": "sekund", 
-	"dateFormatItem-yMMMEd": "EEE d. MMM y", 
-	"field-week": "uke", 
-	"dateFormat-medium": "d. MMM y", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormat-short": "dd.MM.yy",
+	"field-second": "sekund",
+	"dateFormatItem-yMMMEd": "EEE d. MMM y",
+	"field-week": "uke",
+	"dateFormat-medium": "d. MMM y",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nb/number.js b/dojo/cldr/nls/nb/number.js
index 6477bf6..b44260a 100644
--- a/dojo/cldr/nls/nb/number.js
+++ b/dojo/cldr/nls/nb/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"¤ #,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤ #,##0.00",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/currency.js b/dojo/cldr/nls/nl/currency.js
index 5ca5f1c..7cb9e68 100644
--- a/dojo/cldr/nls/nl/currency.js
+++ b/dojo/cldr/nls/nl/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Australische dollar",
-	CAD_displayName:"Canadese dollar",
-	CHF_displayName:"Zwitserse franc",
-	CNY_displayName:"Chinese yuan renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Brits pond sterling",
-	HKD_displayName:"Hongkongse dollar",
-	JPY_displayName:"Japanse yen",
-	USD_displayName:"Amerikaanse dollar"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkongse dollar",
+	"CHF_displayName": "Zwitserse franc",
+	"CAD_displayName": "Canadese dollar",
+	"CNY_displayName": "Chinese yuan renminbi",
+	"AUD_displayName": "Australische dollar",
+	"JPY_displayName": "Japanse yen",
+	"USD_displayName": "Amerikaanse dollar",
+	"GBP_displayName": "Brits pond sterling",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/gregorian.js b/dojo/cldr/nls/nl/gregorian.js
index 765d408..a3cde89 100644
--- a/dojo/cldr/nls/nl/gregorian.js
+++ b/dojo/cldr/nls/nl/gregorian.js
@@ -1,228 +1,233 @@
-({
-	"dateFormatItem-yM": "M-y", 
-	"field-dayperiod": "AM/PM", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"field-minute": "Minuut", 
-	"eraNames": [
-		"Voor Christus", 
-		"na Christus"
-	], 
-	"dateFormatItem-MMMEd": "E d MMM", 
-	"field-day-relative+-1": "gisteren", 
-	"dateFormatItem-MMdd": "dd-MM", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"field-day-relative+-2": "eergisteren", 
-	"field-weekday": "Dag van de week", 
-	"field-day-relative+-3": "eereergisteren", 
-	"days-standAlone-wide": [
-		"zondag", 
-		"maandag", 
-		"dinsdag", 
-		"woensdag", 
-		"donderdag", 
-		"vrijdag", 
-		"zaterdag"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+define(
+//begin v1.x content
+{
+	"months-format-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dayPeriods-format-wide-am": "AM", 
-	"field-era": "Tijdperk", 
-	"field-hour": "Uur", 
-	"quarters-standAlone-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
-		"K4"
-	], 
-	"dateFormatItem-y": "y", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"months-standAlone-abbr": [
-		"jan.", 
-		"feb.", 
-		"mrt.", 
-		"apr.", 
-		"mei", 
-		"jun.", 
-		"jul.", 
-		"aug.", 
-		"sep.", 
-		"okt.", 
-		"nov.", 
-		"dec."
-	], 
-	"dateFormatItem-yMMM": "MMM y", 
-	"field-day-relative+0": "vandaag", 
-	"days-standAlone-narrow": [
-		"Z", 
-		"M", 
-		"D", 
-		"W", 
-		"D", 
-		"V", 
-		"Z"
-	], 
-	"field-day-relative+1": "morgen", 
-	"eraAbbr": [
-		"v. Chr.", 
+	],
+	"field-weekday": "Dag van de week",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE d-M-y",
+	"dateFormatItem-MMMEd": "E d MMM",
+	"eraNarrow": [
+		"v. Chr.",
 		"n. Chr."
-	], 
-	"field-day-relative+2": "overmorgen", 
-	"field-day-relative+3": "overovermorgen", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"dateFormat-long": "d MMMM y", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"field-zone": "Zone", 
-	"dateFormatItem-Hm": "HH:mm", 
-	"dateFormatItem-MMd": "d-MM", 
-	"dateFormat-medium": "d MMM y", 
-	"dateFormatItem-yyMM": "MM-yy", 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"quarters-standAlone-wide": [
-		"1e kwartaal", 
-		"2e kwartaal", 
-		"3e kwartaal", 
-		"4e kwartaal"
-	], 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-year": "Jaar", 
-	"field-week": "Week", 
+	],
+	"dateFormat-long": "d MMMM y",
+	"months-format-wide": [
+		"januari",
+		"februari",
+		"maart",
+		"april",
+		"mei",
+		"juni",
+		"juli",
+		"augustus",
+		"september",
+		"oktober",
+		"november",
+		"december"
+	],
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE d MMMM y",
+	"dateFormatItem-Md": "d-M",
+	"field-era": "Tijdperk",
+	"dateFormatItem-yM": "M-y",
 	"months-standAlone-wide": [
-		"januari", 
-		"februari", 
-		"maart", 
-		"april", 
-		"mei", 
-		"juni", 
-		"juli", 
-		"augustus", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januari",
+		"februari",
+		"maart",
+		"april",
+		"mei",
+		"juni",
+		"juli",
+		"augustus",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
-	"dateFormatItem-MMMd": "d-MMM", 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-long": "HH:mm:ss z", 
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Jaar",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "Uur",
+	"dateFormatItem-MMdd": "dd-MM",
 	"months-format-abbr": [
-		"jan.", 
-		"feb.", 
-		"mrt.", 
-		"apr.", 
-		"mei", 
-		"jun.", 
-		"jul.", 
-		"aug.", 
-		"sep.", 
-		"okt.", 
-		"nov.", 
+		"jan.",
+		"feb.",
+		"mrt.",
+		"apr.",
+		"mei",
+		"jun.",
+		"jul.",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
 		"dec."
-	], 
-	"timeFormat-short": "HH:mm", 
-	"field-month": "Maand", 
-	"dateFormatItem-MMMMd": "d MMMM", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "vandaag",
+	"field-day-relative+1": "morgen",
+	"field-day-relative+2": "overmorgen",
+	"field-day-relative+3": "overovermorgen",
+	"months-standAlone-abbr": [
+		"jan.",
+		"feb.",
+		"mrt.",
+		"apr.",
+		"mei",
+		"jun.",
+		"jul.",
+		"aug.",
+		"sep.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
 	"quarters-format-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
-	"days-format-abbr": [
-		"zo", 
-		"ma", 
-		"di", 
-		"wo", 
-		"do", 
-		"vr", 
-		"za"
-	], 
-	"dateFormatItem-M": "L", 
-	"days-format-narrow": [
-		"Z", 
-		"M", 
-		"D", 
-		"W", 
-		"D", 
-		"V", 
-		"Z"
-	], 
-	"field-second": "Seconde", 
-	"field-day": "Dag", 
-	"dateFormatItem-MEd": "E d-M", 
-	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
-		"D"
-	], 
+	],
+	"quarters-standAlone-wide": [
+		"1e kwartaal",
+		"2e kwartaal",
+		"3e kwartaal",
+		"4e kwartaal"
+	],
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
+		"zaterdag"
+	],
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"K1",
+		"K2",
+		"K3",
+		"K4"
+	],
+	"eraAbbr": [
+		"v. Chr.",
+		"n. Chr."
+	],
+	"field-minute": "Minuut",
+	"field-dayperiod": "AM/PM",
 	"days-standAlone-abbr": [
-		"zo", 
-		"ma", 
-		"di", 
-		"wo", 
-		"do", 
-		"vr", 
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
 		"za"
-	], 
-	"dateFormat-short": "dd-MM-yy", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"dateFormat-full": "EEEE d MMMM y", 
-	"dateFormatItem-Md": "d-M", 
-	"dateFormatItem-yMEd": "EEE d-M-y", 
-	"months-format-wide": [
-		"januari", 
-		"februari", 
-		"maart", 
-		"april", 
-		"mei", 
-		"juni", 
-		"juli", 
-		"augustus", 
-		"september", 
-		"oktober", 
-		"november", 
-		"december"
-	], 
-	"dateFormatItem-d": "d", 
-	"quarters-format-wide": [
-		"1e kwartaal", 
-		"2e kwartaal", 
-		"3e kwartaal", 
-		"4e kwartaal"
-	], 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "gisteren",
+	"field-day-relative+-2": "eergisteren",
+	"field-day-relative+-3": "eereergisteren",
+	"dateFormatItem-MMMd": "d-MMM",
+	"dateFormatItem-MEd": "E d-M",
+	"field-day": "Dag",
 	"days-format-wide": [
-		"zondag", 
-		"maandag", 
-		"dinsdag", 
-		"woensdag", 
-		"donderdag", 
-		"vrijdag", 
+		"zondag",
+		"maandag",
+		"dinsdag",
+		"woensdag",
+		"donderdag",
+		"vrijdag",
 		"zaterdag"
-	], 
-	"eraNarrow": [
-		"v. Chr.", 
-		"n. Chr."
-	]
-})
\ No newline at end of file
+	],
+	"field-zone": "Zone",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dateFormatItem-yyMM": "MM-yy",
+	"days-format-abbr": [
+		"zo",
+		"ma",
+		"di",
+		"wo",
+		"do",
+		"vr",
+		"za"
+	],
+	"eraNames": [
+		"Voor Christus",
+		"na Christus"
+	],
+	"days-format-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"field-month": "Maand",
+	"days-standAlone-narrow": [
+		"Z",
+		"M",
+		"D",
+		"W",
+		"D",
+		"V",
+		"Z"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormat-short": "dd-MM-yy",
+	"dateFormatItem-MMd": "d-MM",
+	"field-second": "Seconde",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormatItem-Ed": "E d",
+	"field-week": "Week",
+	"dateFormat-medium": "d MMM y"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/nl/number.js b/dojo/cldr/nls/nl/number.js
index 020b67b..1aac8f7 100644
--- a/dojo/cldr/nls/nl/number.js
+++ b/dojo/cldr/nls/nl/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤ #,##0.00;¤ #,##0.00-"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤ #,##0.00;¤ #,##0.00-",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/number.js b/dojo/cldr/nls/number.js
index 8c0abb6..f62a3d1 100644
--- a/dojo/cldr/nls/number.js
+++ b/dojo/cldr/nls/number.js
@@ -1,25 +1,64 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencySpacing-beforeCurrency-currencyMatch':"[:letter:]",
-	'currencySpacing-beforeCurrency-surroundingMatch':"[:digit:]",
-	'currencySpacing-beforeCurrency-insertBetween':" ",
-	'currencySpacing-afterCurrency-currencyMatch':"[:letter:]",
-	'currencySpacing-afterCurrency-surroundingMatch':"[:digit:]",
-	'currencySpacing-afterCurrency-insertBetween':" ",
-	'currencyFormat':"¤ #,##0.00"
-})
+define({ root:
+
+//begin v1.x content
+{
+	"scientificFormat": "#E0",
+	"currencySpacing-afterCurrency-currencyMatch": "[:letter:]",
+	"infinity": "∞",
+	"list": ";",
+	"percentSign": "%",
+	"minusSign": "-",
+	"currencySpacing-beforeCurrency-surroundingMatch": "[:digit:]",
+	"decimalFormat-short": "000T",
+	"currencySpacing-afterCurrency-insertBetween": " ",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"plusSign": "+",
+	"currencySpacing-afterCurrency-surroundingMatch": "[:digit:]",
+	"currencySpacing-beforeCurrency-currencyMatch": "[:letter:]",
+	"currencyFormat": "¤ #,##0.00",
+	"perMille": "‰",
+	"group": ",",
+	"percentFormat": "#,##0%",
+	"decimalFormat": "#,##0.###",
+	"decimal": ".",
+	"patternDigit": "#",
+	"currencySpacing-beforeCurrency-insertBetween": " ",
+	"exponential": "E"
+}
+//end v1.x content
+,
+	"ar": true,
+	"ca": true,
+	"cs": true,
+	"da": true,
+	"de": true,
+	"el": true,
+	"en": true,
+	"en-au": true,
+	"en-gb": true,
+	"es": true,
+	"fi": true,
+	"fr": true,
+	"fr-ch": true,
+	"he": true,
+	"hu": true,
+	"it": true,
+	"ja": true,
+	"ko": true,
+	"nb": true,
+	"nl": true,
+	"pl": true,
+	"pt": true,
+	"pt-pt": true,
+	"ro": true,
+	"ru": true,
+	"sk": true,
+	"sl": true,
+	"sv": true,
+	"th": true,
+	"tr": true,
+	"zh": true,
+	"zh-hant": true,
+	"zh-hk": true
+});
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/currency.js b/dojo/cldr/nls/pl/currency.js
index 2497f2b..2393e22 100644
--- a/dojo/cldr/nls/pl/currency.js
+++ b/dojo/cldr/nls/pl/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"dolar australijski",
-	CAD_displayName:"dolar kanadyjski",
-	CHF_displayName:"frank szwajcarski",
-	CNY_displayName:"juan renminbi",
-	EUR_displayName:"euro",
-	GBP_displayName:"funt szterling",
-	HKD_displayName:"dolar hongkoński",
-	JPY_displayName:"jen japoński",
-	USD_displayName:"dolar amerykański "
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "dolar hongkoński",
+	"CHF_displayName": "frank szwajcarski",
+	"CAD_displayName": "dolar kanadyjski",
+	"CNY_displayName": "juan renminbi",
+	"AUD_displayName": "dolar australijski",
+	"JPY_displayName": "jen japoński",
+	"USD_displayName": "dolar amerykański ",
+	"GBP_displayName": "funt szterling",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/gregorian.js b/dojo/cldr/nls/pl/gregorian.js
index aba5519..d87be4c 100644
--- a/dojo/cldr/nls/pl/gregorian.js
+++ b/dojo/cldr/nls/pl/gregorian.js
@@ -1,238 +1,242 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"s", 
-		"l", 
-		"m", 
-		"k", 
-		"m", 
-		"c", 
-		"l", 
-		"s", 
-		"w", 
-		"p", 
-		"l", 
+		"s",
+		"l",
+		"m",
+		"k",
+		"m",
+		"c",
+		"l",
+		"s",
+		"w",
+		"p",
+		"l",
 		"g"
-	], 
-	"field-weekday": "Dzień tygodnia", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, d-M-y", 
-	"dateFormatItem-MMMEd": "d MMM E", 
+	],
+	"field-weekday": "Dzień tygodnia",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, d.MM.yyyy",
+	"dateFormatItem-MMMEd": "E, d MMM",
 	"eraNarrow": [
-		"p.n.e.", 
+		"p.n.e.",
 		"n.e."
-	], 
-	"dayPeriods-format-wide-earlyMorning": "nad ranem", 
-	"dayPeriods-format-wide-morning": "rano", 
-	"dateFormat-long": "d MMMM y", 
+	],
+	"dayPeriods-format-wide-earlyMorning": "nad ranem",
+	"dayPeriods-format-wide-morning": "rano",
+	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
-		"stycznia", 
-		"lutego", 
-		"marca", 
-		"kwietnia", 
-		"maja", 
-		"czerwca", 
-		"lipca", 
-		"sierpnia", 
-		"września", 
-		"października", 
-		"listopada", 
+		"stycznia",
+		"lutego",
+		"marca",
+		"kwietnia",
+		"maja",
+		"czerwca",
+		"lipca",
+		"sierpnia",
+		"września",
+		"października",
+		"listopada",
 		"grudnia"
-	], 
-	"dayPeriods-format-wide-evening": "wieczorem", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "EEEE, d MMMM y", 
-	"dateFormatItem-Md": "d-M", 
-	"dayPeriods-format-wide-noon": "w południe", 
-	"field-era": "Era", 
-	"dateFormatItem-yM": "M-y", 
+	],
+	"dayPeriods-format-wide-evening": "wieczorem",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-Md": "d.MM",
+	"dayPeriods-format-wide-noon": "w południe",
+	"field-era": "Era",
+	"dateFormatItem-yM": "MM.yyyy",
 	"months-standAlone-wide": [
-		"styczeń", 
-		"luty", 
-		"marzec", 
-		"kwiecień", 
-		"maj", 
-		"czerwiec", 
-		"lipiec", 
-		"sierpień", 
-		"wrzesień", 
-		"październik", 
-		"listopad", 
+		"styczeń",
+		"luty",
+		"marzec",
+		"kwiecień",
+		"maj",
+		"czerwiec",
+		"lipiec",
+		"sierpień",
+		"wrzesień",
+		"październik",
+		"listopad",
 		"grudzień"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"I kwartał", 
-		"II kwartał", 
-		"III kwartał", 
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
 		"IV kwartał"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "Rok", 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"dateFormatItem-yyyyMMMM": "LLLL y", 
-	"field-hour": "Godzina", 
-	"dateFormatItem-MMdd": "dd-MM", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Rok",
+	"dateFormatItem-yQ": "yyyy Q",
+	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"field-hour": "Godzina",
+	"dateFormatItem-MMdd": "d.MM",
 	"months-format-abbr": [
-		"sty", 
-		"lut", 
-		"mar", 
-		"kwi", 
-		"maj", 
-		"cze", 
-		"lip", 
-		"sie", 
-		"wrz", 
-		"paź", 
-		"lis", 
+		"sty",
+		"lut",
+		"mar",
+		"kwi",
+		"maj",
+		"cze",
+		"lip",
+		"sie",
+		"wrz",
+		"paź",
+		"lis",
 		"gru"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "Dzisiaj", 
-	"field-day-relative+1": "Jutro", 
-	"field-day-relative+2": "Pojutrze", 
-	"field-day-relative+3": "Za trzy dni", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "Dzisiaj",
+	"field-day-relative+1": "Jutro",
+	"field-day-relative+2": "Pojutrze",
+	"field-day-relative+3": "Za trzy dni",
 	"months-standAlone-abbr": [
-		"sty", 
-		"lut", 
-		"mar", 
-		"kwi", 
-		"maj", 
-		"cze", 
-		"lip", 
-		"sie", 
-		"wrz", 
-		"paź", 
-		"lis", 
+		"sty",
+		"lut",
+		"mar",
+		"kwi",
+		"maj",
+		"cze",
+		"lip",
+		"sie",
+		"wrz",
+		"paź",
+		"lis",
 		"gru"
-	], 
+	],
 	"quarters-format-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"I kwartał", 
-		"II kwartał", 
-		"III kwartał", 
+		"I kwartał",
+		"II kwartał",
+		"III kwartał",
 		"IV kwartał"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"niedziela", 
-		"poniedziałek", 
-		"wtorek", 
-		"środa", 
-		"czwartek", 
-		"piątek", 
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
 		"sobota"
-	], 
-	"dateFormatItem-MMMMd": "d MMMM", 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"1 kw.", 
-		"2 kw.", 
-		"3 kw.", 
+		"1 kw.",
+		"2 kw.",
+		"3 kw.",
 		"4 kw."
-	], 
+	],
 	"eraAbbr": [
-		"p.n.e.", 
+		"p.n.e.",
 		"n.e."
-	], 
-	"field-minute": "Minuta", 
-	"field-dayperiod": "Dayperiod", 
-	"dayPeriods-format-wide-night": "w nocy", 
+	],
+	"field-minute": "Minuta",
+	"field-dayperiod": "Dayperiod",
 	"days-standAlone-abbr": [
-		"niedz.", 
-		"pon.", 
-		"wt.", 
-		"śr.", 
-		"czw.", 
-		"pt.", 
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
 		"sob."
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "Wczoraj", 
-	"dateFormatItem-h": "hh a", 
-	"field-day-relative+-2": "Przedwczoraj", 
-	"field-day-relative+-3": "Trzy dni temu", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "E, d-M", 
-	"dayPeriods-format-wide-lateMorning": "przed południem", 
-	"dateFormatItem-yMMMM": "LLLL y", 
-	"field-day": "Dzień", 
+	],
+	"dayPeriods-format-wide-night": "w nocy",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "Wczoraj",
+	"dateFormatItem-h": "hh a",
+	"field-day-relative+-2": "Przedwczoraj",
+	"field-day-relative+-3": "Trzy dni temu",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d.MM",
+	"dayPeriods-format-wide-lateMorning": "przed południem",
+	"dateFormatItem-yMMMM": "LLLL y",
+	"field-day": "Dzień",
 	"days-format-wide": [
-		"niedziela", 
-		"poniedziałek", 
-		"wtorek", 
-		"środa", 
-		"czwartek", 
-		"piątek", 
+		"niedziela",
+		"poniedziałek",
+		"wtorek",
+		"środa",
+		"czwartek",
+		"piątek",
 		"sobota"
-	], 
-	"field-zone": "Strefa", 
-	"dateFormatItem-yyyyMM": "yyyy-MM", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "Strefa",
+	"dateFormatItem-yyyyMM": "MM.yyyy",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"s", 
-		"l", 
-		"m", 
-		"k", 
-		"m", 
-		"c", 
-		"l", 
-		"s", 
-		"w", 
-		"p", 
-		"l", 
+		"s",
+		"l",
+		"m",
+		"k",
+		"m",
+		"c",
+		"l",
+		"s",
+		"w",
+		"p",
+		"l",
 		"g"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
-	"dateFormatItem-hm": "hh:mm a", 
+	],
+	"dateFormatItem-hm": "hh:mm a",
 	"days-format-abbr": [
-		"niedz.", 
-		"pon.", 
-		"wt.", 
-		"śr.", 
-		"czw.", 
-		"pt.", 
+		"niedz.",
+		"pon.",
+		"wt.",
+		"śr.",
+		"czw.",
+		"pt.",
 		"sob."
-	], 
+	],
 	"eraNames": [
-		"p.n.e.", 
+		"p.n.e.",
 		"n.e."
-	], 
+	],
 	"days-format-narrow": [
-		"N", 
-		"P", 
-		"W", 
-		"Ś", 
-		"C", 
-		"P", 
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
 		"S"
-	], 
-	"field-month": "Miesiąc", 
+	],
+	"field-month": "Miesiąc",
 	"days-standAlone-narrow": [
-		"N", 
-		"P", 
-		"W", 
-		"Ś", 
-		"C", 
-		"P", 
+		"N",
+		"P",
+		"W",
+		"Ś",
+		"C",
+		"P",
 		"S"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateFormat-short": "dd-MM-yyyy", 
-	"dayPeriods-format-wide-afternoon": "po południu", 
-	"field-second": "Sekunda", 
-	"dateFormatItem-yMMMEd": "EEE, d MMM y", 
-	"field-week": "Tydzień", 
-	"dateFormat-medium": "dd-MM-yyyy", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormat-short": "dd.MM.yyyy",
+	"dayPeriods-format-wide-afternoon": "po południu",
+	"field-second": "Sekunda",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateFormatItem-Ed": "E, d",
+	"field-week": "Tydzień",
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "hh:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pl/number.js b/dojo/cldr/nls/pl/number.js
index 5d516a6..f16715c 100644
--- a/dojo/cldr/nls/pl/number.js
+++ b/dojo/cldr/nls/pl/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/gregorian.js b/dojo/cldr/nls/pt-pt/gregorian.js
index db26b56..7152396 100644
--- a/dojo/cldr/nls/pt-pt/gregorian.js
+++ b/dojo/cldr/nls/pt-pt/gregorian.js
@@ -1,132 +1,141 @@
-({
+define(
+//begin v1.x content
+{
 	"quarters-standAlone-wide": [
-		"1.º trimestre", 
-		"2.º trimestre", 
-		"3.º trimestre", 
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
 		"4.º trimestre"
-	], 
-	"dayPeriods-standAlone-wide-am": "a.m.", 
+	],
 	"quarters-format-abbr": [
-		"1.º trimestre", 
-		"2.º trimestre", 
-		"3.º trimestre", 
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
 		"4.º trimestre"
-	], 
-	"dateFormat-medium": "d 'de' MMM 'de' yyyy", 
+	],
+	"dayPeriods-standAlone-wide-am": "a.m.",
+	"dateFormat-medium": "d 'de' MMM 'de' yyyy",
 	"quarters-standAlone-abbr": [
-		"1.º trimestre", 
-		"2.º trimestre", 
-		"3.º trimestre", 
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
 		"4.º trimestre"
-	], 
-	"dayPeriods-standAlone-abbr-pm": "p.m.", 
-	"dateFormatItem-hm": "h:mm", 
+	],
+	"dateFormatItem-Hm": "HH:mm",
+	"dayPeriods-standAlone-abbr-pm": "p.m.",
+	"dateFormatItem-HHmmss": "HH:mm:ss",
+	"dateFormatItem-hm": "h:mm a",
 	"months-standAlone-wide": [
-		"Janeiro", 
-		"Fevereiro", 
-		"Março", 
-		"Abril", 
-		"Maio", 
-		"Junho", 
-		"Julho", 
-		"Agosto", 
-		"Setembro", 
-		"Outubro", 
-		"Novembro", 
+		"Janeiro",
+		"Fevereiro",
+		"Março",
+		"Abril",
+		"Maio",
+		"Junho",
+		"Julho",
+		"Agosto",
+		"Setembro",
+		"Outubro",
+		"Novembro",
 		"Dezembro"
-	], 
-	"dayPeriods-standAlone-abbr-am": "a.m.", 
-	"dayPeriods-format-wide-pm": "Depois do meio-dia", 
+	],
+	"dayPeriods-standAlone-abbr-am": "a.m.",
+	"dayPeriods-format-wide-pm": "Depois do meio-dia",
 	"months-standAlone-abbr": [
-		"Jan", 
-		"Fev", 
-		"Mar", 
-		"Abr", 
-		"Mai", 
-		"Jun", 
-		"Jul", 
-		"Ago", 
-		"Set", 
-		"Out", 
-		"Nov", 
+		"Jan",
+		"Fev",
+		"Mar",
+		"Abr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Ago",
+		"Set",
+		"Out",
+		"Nov",
 		"Dez"
-	], 
-	"dateFormatItem-yQQQ": "QQQ 'de' y", 
-	"dayPeriods-format-wide-am": "Antes do meio-dia", 
-	"dayPeriods-format-abbr-pm": "p.m.", 
-	"dateFormatItem-yyQ": "QQQ 'de' yy", 
-	"dayPeriods-format-abbr-am": "a.m.", 
+	],
+	"dateFormatItem-yQQQ": "QQQ 'de' y",
+	"dayPeriods-format-wide-am": "Antes do meio-dia",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dayPeriods-format-abbr-pm": "p.m.",
+	"dateFormatItem-yyQ": "QQQ 'de' yy",
+	"dateFormatItem-ms": "mm:ss",
+	"dayPeriods-format-abbr-am": "a.m.",
 	"months-format-wide": [
-		"Janeiro", 
-		"Fevereiro", 
-		"Março", 
-		"Abril", 
-		"Maio", 
-		"Junho", 
-		"Julho", 
-		"Agosto", 
-		"Setembro", 
-		"Outubro", 
-		"Novembro", 
+		"Janeiro",
+		"Fevereiro",
+		"Março",
+		"Abril",
+		"Maio",
+		"Junho",
+		"Julho",
+		"Agosto",
+		"Setembro",
+		"Outubro",
+		"Novembro",
 		"Dezembro"
-	], 
+	],
 	"days-standAlone-wide": [
-		"Domingo", 
-		"Segunda-feira", 
-		"Terça-feira", 
-		"Quarta-feira", 
-		"Quinta-feira", 
-		"Sexta-feira", 
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
 		"Sábado"
-	], 
+	],
+	"dateFormatItem-HHmm": "HH:mm",
 	"months-format-abbr": [
-		"Jan", 
-		"Fev", 
-		"Mar", 
-		"Abr", 
-		"Mai", 
-		"Jun", 
-		"Jul", 
-		"Ago", 
-		"Set", 
-		"Out", 
-		"Nov", 
+		"Jan",
+		"Fev",
+		"Mar",
+		"Abr",
+		"Mai",
+		"Jun",
+		"Jul",
+		"Ago",
+		"Set",
+		"Out",
+		"Nov",
 		"Dez"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"Domingo", 
-		"Segunda-feira", 
-		"Terça-feira", 
-		"Quarta-feira", 
-		"Quinta-feira", 
-		"Sexta-feira", 
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
 		"Sábado"
-	], 
+	],
 	"days-format-wide": [
-		"Domingo", 
-		"Segunda-feira", 
-		"Terça-feira", 
-		"Quarta-feira", 
-		"Quinta-feira", 
-		"Sexta-feira", 
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
 		"Sábado"
-	], 
-	"dateFormatItem-yQ": "QQQ 'de' yyyy", 
-	"dateFormatItem-hms": "h:mm:ss", 
+	],
+	"dateFormatItem-hms": "h:mm:ss a",
+	"dateFormatItem-yQ": "QQQ 'de' yyyy",
 	"quarters-format-wide": [
-		"1.º trimestre", 
-		"2.º trimestre", 
-		"3.º trimestre", 
+		"1.º trimestre",
+		"2.º trimestre",
+		"3.º trimestre",
 		"4.º trimestre"
-	], 
-	"dayPeriods-standAlone-wide-pm": "p.m.", 
+	],
+	"dayPeriods-standAlone-wide-pm": "p.m.",
 	"days-format-abbr": [
-		"Domingo", 
-		"Segunda-feira", 
-		"Terça-feira", 
-		"Quarta-feira", 
-		"Quinta-feira", 
-		"Sexta-feira", 
+		"Domingo",
+		"Segunda-feira",
+		"Terça-feira",
+		"Quarta-feira",
+		"Quinta-feira",
+		"Sexta-feira",
 		"Sábado"
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt-pt/number.js b/dojo/cldr/nls/pt-pt/number.js
index 75b3981..d9ed12d 100644
--- a/dojo/cldr/nls/pt-pt/number.js
+++ b/dojo/cldr/nls/pt-pt/number.js
@@ -1,5 +1,8 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'group':" ",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"currencyFormat": "#,##0.00 ¤",
+	"group": " "
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/currency.js b/dojo/cldr/nls/pt/currency.js
index 688ebe6..5bd918c 100644
--- a/dojo/cldr/nls/pt/currency.js
+++ b/dojo/cldr/nls/pt/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Dólar australiano",
-	CAD_displayName:"Dólar canadense",
-	CHF_displayName:"Franco suíço",
-	CNY_displayName:"Yuan Renminbi chinês",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Libra esterlina britânica",
-	HKD_displayName:"Dólar de Hong Kong",
-	JPY_displayName:"Iene japonês",
-	USD_displayName:"Dólar norte-americano"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Dólar de Hong Kong",
+	"CHF_displayName": "Franco suíço",
+	"CAD_displayName": "Dólar canadense",
+	"CNY_displayName": "Yuan Renminbi chinês",
+	"AUD_displayName": "Dólar australiano",
+	"JPY_displayName": "Iene japonês",
+	"USD_displayName": "Dólar norte-americano",
+	"GBP_displayName": "Libra esterlina britânica",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/gregorian.js b/dojo/cldr/nls/pt/gregorian.js
index d7916e0..20ed629 100644
--- a/dojo/cldr/nls/pt/gregorian.js
+++ b/dojo/cldr/nls/pt/gregorian.js
@@ -1,233 +1,237 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"field-weekday": "Dia da semana", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, dd/MM/yyyy", 
-	"dateFormatItem-MMMEd": "EEE, d 'de' MMM", 
+	],
+	"field-weekday": "Dia da semana",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, dd/MM/yyyy",
+	"dateFormatItem-MMMEd": "EEE, d 'de' MMM",
 	"eraNarrow": [
-		"a.C.", 
+		"a.C.",
 		"d.C."
-	], 
-	"dayPeriods-format-wide-morning": "manhã", 
-	"dateFormat-long": "d 'de' MMMM 'de' y", 
+	],
+	"dayPeriods-format-wide-morning": "manhã",
+	"dateFormat-long": "d 'de' MMMM 'de' y",
 	"months-format-wide": [
-		"janeiro", 
-		"fevereiro", 
-		"março", 
-		"abril", 
-		"maio", 
-		"junho", 
-		"julho", 
-		"agosto", 
-		"setembro", 
-		"outubro", 
-		"novembro", 
+		"janeiro",
+		"fevereiro",
+		"março",
+		"abril",
+		"maio",
+		"junho",
+		"julho",
+		"agosto",
+		"setembro",
+		"outubro",
+		"novembro",
 		"dezembro"
-	], 
-	"dateFormatItem-EEEd": "EEE, d", 
-	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y", 
-	"dateFormatItem-Md": "d/M", 
-	"dayPeriods-format-wide-noon": "meio-dia", 
-	"field-era": "Era", 
-	"dateFormatItem-yM": "MM/yyyy", 
+	],
+	"dateFormatItem-EEEd": "EEE, d",
+	"dateFormat-full": "EEEE, d 'de' MMMM 'de' y",
+	"dateFormatItem-Md": "d/M",
+	"dayPeriods-format-wide-noon": "meio-dia",
+	"field-era": "Era",
+	"dateFormatItem-yM": "MM/yyyy",
 	"months-standAlone-wide": [
-		"janeiro", 
-		"fevereiro", 
-		"março", 
-		"abril", 
-		"maio", 
-		"junho", 
-		"julho", 
-		"agosto", 
-		"setembro", 
-		"outubro", 
-		"novembro", 
+		"janeiro",
+		"fevereiro",
+		"março",
+		"abril",
+		"maio",
+		"junho",
+		"julho",
+		"agosto",
+		"setembro",
+		"outubro",
+		"novembro",
 		"dezembro"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1º trimestre", 
-		"2º trimestre", 
-		"3º trimestre", 
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
 		"4º trimestre"
-	], 
-	"timeFormat-long": "HH'h'mm'min'ss's' z", 
-	"field-year": "Ano", 
-	"dateFormatItem-yMMM": "MMM 'de' y", 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"field-hour": "Hora", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "HH'h'mm'min'ss's' z",
+	"field-year": "Ano",
+	"dateFormatItem-yMMM": "MMM 'de' y",
+	"dateFormatItem-yQ": "yyyy Q",
+	"field-hour": "Hora",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"jan", 
-		"fev", 
-		"mar", 
-		"abr", 
-		"mai", 
-		"jun", 
-		"jul", 
-		"ago", 
-		"set", 
-		"out", 
-		"nov", 
+		"jan",
+		"fev",
+		"mar",
+		"abr",
+		"mai",
+		"jun",
+		"jul",
+		"ago",
+		"set",
+		"out",
+		"nov",
 		"dez"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH'h'mm'min'ss's' zzzz", 
-	"field-day-relative+0": "Hoje", 
-	"field-day-relative+1": "Amanhã", 
-	"field-day-relative+2": "Depois de amanhã", 
-	"field-day-relative+3": "Daqui a três dias", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH'h'mm'min'ss's' zzzz",
+	"field-day-relative+0": "Hoje",
+	"field-day-relative+1": "Amanhã",
+	"field-day-relative+2": "Depois de amanhã",
+	"field-day-relative+3": "Daqui a três dias",
 	"months-standAlone-abbr": [
-		"jan", 
-		"fev", 
-		"mar", 
-		"abr", 
-		"mai", 
-		"jun", 
-		"jul", 
-		"ago", 
-		"set", 
-		"out", 
-		"nov", 
+		"jan",
+		"fev",
+		"mar",
+		"abr",
+		"mai",
+		"jun",
+		"jul",
+		"ago",
+		"set",
+		"out",
+		"nov",
 		"dez"
-	], 
+	],
 	"quarters-format-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1º trimestre", 
-		"2º trimestre", 
-		"3º trimestre", 
+		"1º trimestre",
+		"2º trimestre",
+		"3º trimestre",
 		"4º trimestre"
-	], 
-	"dateFormatItem-HHmmss": "HH'h'mm'min'ss's'", 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-HHmmss": "HH'h'mm'min'ss's'",
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"domingo", 
-		"segunda-feira", 
-		"terça-feira", 
-		"quarta-feira", 
-		"quinta-feira", 
-		"sexta-feira", 
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
 		"sábado"
-	], 
-	"dateFormatItem-yyyyMMM": "MMM 'de' y", 
-	"dateFormatItem-yyMMMEEEd": "EEE, d 'de' MMM 'de' yy", 
-	"dateFormatItem-yyMMM": "MMM 'de' yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH'h'mm", 
+	],
+	"dateFormatItem-yyyyMMM": "MMM 'de' y",
+	"dateFormatItem-yyMMMEEEd": "EEE, d 'de' MMM 'de' yy",
+	"dateFormatItem-yyMMM": "MMM 'de' yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH'h'mm",
 	"quarters-standAlone-abbr": [
-		"T1", 
-		"T2", 
-		"T3", 
+		"T1",
+		"T2",
+		"T3",
 		"T4"
-	], 
+	],
 	"eraAbbr": [
-		"a.C.", 
+		"a.C.",
 		"d.C."
-	], 
-	"field-minute": "Minuto", 
-	"field-dayperiod": "Período do dia", 
+	],
+	"field-minute": "Minuto",
+	"field-dayperiod": "Período do dia",
 	"days-standAlone-abbr": [
-		"dom", 
-		"seg", 
-		"ter", 
-		"qua", 
-		"qui", 
-		"sex", 
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
 		"sáb"
-	], 
-	"dayPeriods-format-wide-night": "noite", 
-	"dateFormatItem-yyMMMd": "d 'de' MMM 'de' yy", 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm'min'ss's'", 
-	"field-day-relative+-1": "Ontem", 
-	"field-day-relative+-2": "Anteontem", 
-	"field-day-relative+-3": "Há três dias", 
-	"dateFormatItem-MMMd": "d 'de' MMM", 
-	"dateFormatItem-MEd": "EEE, dd/MM", 
-	"field-day": "Dia", 
+	],
+	"dayPeriods-format-wide-night": "noite",
+	"dateFormatItem-yyMMMd": "d 'de' MMM 'de' yy",
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm'min'ss's'",
+	"field-day-relative+-1": "Ontem",
+	"field-day-relative+-2": "Anteontem",
+	"field-day-relative+-3": "Há três dias",
+	"dateFormatItem-MMMd": "d 'de' MMM",
+	"dateFormatItem-MEd": "EEE, dd/MM",
+	"field-day": "Dia",
 	"days-format-wide": [
-		"domingo", 
-		"segunda-feira", 
-		"terça-feira", 
-		"quarta-feira", 
-		"quinta-feira", 
-		"sexta-feira", 
+		"domingo",
+		"segunda-feira",
+		"terça-feira",
+		"quarta-feira",
+		"quinta-feira",
+		"sexta-feira",
 		"sábado"
-	], 
-	"field-zone": "Fuso", 
-	"dateFormatItem-yyyyMM": "MM/yyyy", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "Fuso",
+	"dateFormatItem-yyyyMM": "MM/yyyy",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
 	"days-format-abbr": [
-		"dom", 
-		"seg", 
-		"ter", 
-		"qua", 
-		"qui", 
-		"sex", 
+		"dom",
+		"seg",
+		"ter",
+		"qua",
+		"qui",
+		"sex",
 		"sáb"
-	], 
+	],
 	"eraNames": [
-		"Antes de Cristo", 
+		"Antes de Cristo",
 		"Ano do Senhor"
-	], 
+	],
 	"days-format-narrow": [
-		"D", 
-		"S", 
-		"T", 
-		"Q", 
-		"Q", 
-		"S", 
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
 		"S"
-	], 
-	"field-month": "Mês", 
+	],
+	"field-month": "Mês",
 	"days-standAlone-narrow": [
-		"D", 
-		"S", 
-		"T", 
-		"Q", 
-		"Q", 
-		"S", 
+		"D",
+		"S",
+		"T",
+		"Q",
+		"Q",
+		"S",
 		"S"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dateFormatItem-HHmm": "HH'h'mm", 
-	"dateFormat-short": "dd/MM/yy", 
-	"dayPeriods-format-wide-afternoon": "tarde", 
-	"field-second": "Segundo", 
-	"dateFormatItem-yMMMEd": "EEE, d 'de' MMM 'de' y", 
-	"field-week": "Semana", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dateFormatItem-HHmm": "HH'h'mm",
+	"dateFormat-short": "dd/MM/yy",
+	"dayPeriods-format-wide-afternoon": "tarde",
+	"field-second": "Segundo",
+	"dateFormatItem-yMMMEd": "EEE, d 'de' MMM 'de' y",
+	"field-week": "Semana",
 	"dateFormat-medium": "dd/MM/yyyy"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/pt/number.js b/dojo/cldr/nls/pt/number.js
index 8f15b61..fe2d142 100644
--- a/dojo/cldr/nls/pt/number.js
+++ b/dojo/cldr/nls/pt/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤#,##0.00;(¤#,##0.00)"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤#,##0.00;(¤#,##0.00)",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/buddhist.js b/dojo/cldr/nls/ro/buddhist.js
new file mode 100644
index 0000000..a8c8769
--- /dev/null
+++ b/dojo/cldr/nls/ro/buddhist.js
@@ -0,0 +1,121 @@
+define(
+//begin v1.x content
+{
+	"quarters-format-abbr": [
+		"trim. I",
+		"trim. II",
+		"trim. III",
+		"trim. IV"
+	],
+	"dateFormat-medium": "d MMM y G",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"dateFormatItem-MEd": "E, d MMM",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"eraNarrow": [
+		"e.b."
+	],
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-Md": "d.M",
+	"months-standAlone-narrow": [
+		"I",
+		"F",
+		"M",
+		"A",
+		"M",
+		"I",
+		"I",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dateFormatItem-EEEd": "EEE d",
+	"eraNames": [
+		"era budistă"
+	],
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"dateTimeFormat-long": "{1}, {0}",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"quarters-standAlone-narrow": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"dateFormat-long": "d MMMM y G",
+	"dateFormat-short": "d/M/yyyy",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"dateTimeFormat-short": "{1}, {0}",
+	"months-format-wide": [
+		"ianuarie",
+		"februarie",
+		"martie",
+		"aprilie",
+		"mai",
+		"iunie",
+		"iulie",
+		"august",
+		"septembrie",
+		"octombrie",
+		"noiembrie",
+		"decembrie"
+	],
+	"dateTimeFormat-full": "{1}, {0}",
+	"dateFormatItem-yM": "M.yyyy",
+	"months-format-abbr": [
+		"ian.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"mai",
+		"iun.",
+		"iul.",
+		"aug.",
+		"sept.",
+		"oct.",
+		"nov.",
+		"dec."
+	],
+	"eraAbbr": [
+		"e.b."
+	],
+	"days-format-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	],
+	"dateFormatItem-yQ": "'trimestrul' Q y",
+	"dateFormatItem-yMMM": "MMM y",
+	"quarters-format-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"dateFormat-full": "EEEE, d MMMM, y G",
+	"dateFormatItem-MMMd": "d MMM",
+	"days-format-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	]
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/currency.js b/dojo/cldr/nls/ro/currency.js
new file mode 100644
index 0000000..da2ff10
--- /dev/null
+++ b/dojo/cldr/nls/ro/currency.js
@@ -0,0 +1,15 @@
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "dolar Hong Kong",
+	"CHF_displayName": "franc elvețian",
+	"CAD_displayName": "dolar canadian",
+	"CNY_displayName": "yuan renminbi chinezesc",
+	"AUD_displayName": "dolar australian",
+	"JPY_displayName": "yen japonez",
+	"USD_displayName": "dolar american",
+	"GBP_displayName": "liră sterlină",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/gregorian.js b/dojo/cldr/nls/ro/gregorian.js
new file mode 100644
index 0000000..9485520
--- /dev/null
+++ b/dojo/cldr/nls/ro/gregorian.js
@@ -0,0 +1,251 @@
+define(
+//begin v1.x content
+{
+	"months-format-narrow": [
+		"I",
+		"F",
+		"M",
+		"A",
+		"M",
+		"I",
+		"I",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"quarters-standAlone-narrow": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"field-weekday": "zi a săptămânii",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE, d/M/yyyy",
+	"dateFormatItem-MMMEd": "E, d MMM",
+	"eraNarrow": [
+		"î.Hr.",
+		"d.Hr."
+	],
+	"dateFormat-long": "d MMMM y",
+	"months-format-wide": [
+		"ianuarie",
+		"februarie",
+		"martie",
+		"aprilie",
+		"mai",
+		"iunie",
+		"iulie",
+		"august",
+		"septembrie",
+		"octombrie",
+		"noiembrie",
+		"decembrie"
+	],
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-EEEd": "EEE d",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "EEEE, d MMMM y",
+	"dateFormatItem-Md": "d.M",
+	"field-era": "eră",
+	"dateFormatItem-yM": "M.yyyy",
+	"months-standAlone-wide": [
+		"ianuarie",
+		"februarie",
+		"martie",
+		"aprilie",
+		"mai",
+		"iunie",
+		"iulie",
+		"august",
+		"septembrie",
+		"octombrie",
+		"noiembrie",
+		"decembrie"
+	],
+	"timeFormat-short": "HH:mm",
+	"quarters-format-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "an",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "'trimestrul' Q y",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "oră",
+	"dateFormatItem-MMdd": "dd.MM",
+	"months-format-abbr": [
+		"ian.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"mai",
+		"iun.",
+		"iul.",
+		"aug.",
+		"sept.",
+		"oct.",
+		"nov.",
+		"dec."
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "azi",
+	"field-day-relative+1": "mâine",
+	"field-day-relative+2": "poimâine",
+	"field-day-relative+3": "răspoimâine",
+	"months-standAlone-abbr": [
+		"ian.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"mai",
+		"iun.",
+		"iul.",
+		"aug.",
+		"sept.",
+		"oct.",
+		"nov.",
+		"dec."
+	],
+	"quarters-format-abbr": [
+		"trim. I",
+		"trim. II",
+		"trim. III",
+		"trim. IV"
+	],
+	"quarters-standAlone-wide": [
+		"trimestrul I",
+		"trimestrul al II-lea",
+		"trimestrul al III-lea",
+		"trimestrul al IV-lea"
+	],
+	"dateFormatItem-M": "L",
+	"days-standAlone-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	],
+	"dateFormatItem-MMMMd": "d MMMM",
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
+	"quarters-standAlone-abbr": [
+		"trim. I",
+		"trim. II",
+		"trim. III",
+		"trim. IV"
+	],
+	"eraAbbr": [
+		"î.Hr.",
+		"d.Hr."
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "perioada zilei",
+	"days-standAlone-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"quarters-format-narrow": [
+		"T1",
+		"T2",
+		"T3",
+		"T4"
+	],
+	"field-day-relative+-1": "ieri",
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-day-relative+-2": "alaltăieri",
+	"field-day-relative+-3": "răsalaltăieri",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"field-day": "zi",
+	"days-format-wide": [
+		"duminică",
+		"luni",
+		"marți",
+		"miercuri",
+		"joi",
+		"vineri",
+		"sâmbătă"
+	],
+	"field-zone": "zonă",
+	"dateFormatItem-yyyyMM": "MM.yyyy",
+	"dateFormatItem-y": "y",
+	"months-standAlone-narrow": [
+		"I",
+		"F",
+		"M",
+		"A",
+		"M",
+		"I",
+		"I",
+		"A",
+		"S",
+		"O",
+		"N",
+		"D"
+	],
+	"dateFormatItem-yyMM": "MM.yy",
+	"days-format-abbr": [
+		"Du",
+		"Lu",
+		"Ma",
+		"Mi",
+		"Jo",
+		"Vi",
+		"Sâ"
+	],
+	"eraNames": [
+		"înainte de Hristos",
+		"după Hristos"
+	],
+	"days-format-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"field-month": "lună",
+	"days-standAlone-narrow": [
+		"D",
+		"L",
+		"M",
+		"M",
+		"J",
+		"V",
+		"S"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormatItem-MMMMEd": "E, d MMMM",
+	"dateFormat-short": "dd.MM.yyyy",
+	"field-second": "secundă",
+	"dateFormatItem-yMMMEd": "EEE, d MMM y",
+	"field-week": "săptămână",
+	"dateFormat-medium": "dd.MM.yyyy",
+	"dateTimeFormat-short": "{1}, {0}",
+	"dateFormatItem-MMMEEEd": "EEE, d MMM"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ro/number.js b/dojo/cldr/nls/ro/number.js
new file mode 100644
index 0000000..c6539c1
--- /dev/null
+++ b/dojo/cldr/nls/ro/number.js
@@ -0,0 +1,22 @@
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/currency.js b/dojo/cldr/nls/ru/currency.js
index d9f61cb..e5b2b20 100644
--- a/dojo/cldr/nls/ru/currency.js
+++ b/dojo/cldr/nls/ru/currency.js
@@ -1,14 +1,16 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Австралийский доллар",
-	CAD_displayName:"Канадский доллар",
-	CHF_displayName:"Швейцарский франк",
-	CNY_displayName:"Юань Ренминби",
-	EUR_displayName:"Евро",
-	GBP_displayName:"Английский фунт стерлингов",
-	HKD_displayName:"Гонконгский доллар",
-	JPY_displayName:"Японская иена",
-	USD_displayName:"Доллар США",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Гонконгский доллар",
+	"CHF_displayName": "Швейцарский франк",
+	"CAD_displayName": "Канадский доллар",
+	"CNY_displayName": "Юань Ренминби",
+	"USD_symbol": "$",
+	"AUD_displayName": "Австралийский доллар",
+	"JPY_displayName": "Японская иена",
+	"USD_displayName": "Доллар США",
+	"GBP_displayName": "Английский фунт стерлингов",
+	"EUR_displayName": "Евро"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/gregorian.js b/dojo/cldr/nls/ru/gregorian.js
index edd6bf4..83db44d 100644
--- a/dojo/cldr/nls/ru/gregorian.js
+++ b/dojo/cldr/nls/ru/gregorian.js
@@ -1,228 +1,232 @@
-({
-	"dateFormatItem-yM": "M.y", 
-	"field-dayperiod": "AM/PM", 
-	"field-minute": "Минута", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M.y",
+	"field-dayperiod": "AM/PM",
+	"field-minute": "Минута",
 	"eraNames": [
-		"до н.э.", 
+		"до н.э.",
 		"н.э."
-	], 
-	"field-day-relative+-1": "Вчера", 
-	"dateFormatItem-MMdd": "dd.MM", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"field-day-relative+-2": "Позавчера", 
-	"field-weekday": "День недели", 
+	],
+	"dateFormatItem-MMMEd": "ccc, d MMM",
+	"field-day-relative+-1": "Вчера",
+	"field-weekday": "День недели",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"field-day-relative+-2": "Позавчера",
+	"dateFormatItem-MMdd": "dd.MM",
 	"days-standAlone-wide": [
-		"Воскресенье", 
-		"Понедельник", 
-		"Вторник", 
-		"Среда", 
-		"Четверг", 
-		"Пятница", 
+		"Воскресенье",
+		"Понедельник",
+		"Вторник",
+		"Среда",
+		"Четверг",
+		"Пятница",
 		"Суббота"
-	], 
-	"dateFormatItem-MMM": "LLL", 
+	],
+	"dateFormatItem-MMM": "LLL",
 	"months-standAlone-narrow": [
-		"Я", 
-		"Ф", 
-		"М", 
-		"А", 
-		"М", 
-		"И", 
-		"И", 
-		"А", 
-		"С", 
-		"О", 
-		"Н", 
+		"Я",
+		"Ф",
+		"М",
+		"А",
+		"М",
+		"И",
+		"И",
+		"А",
+		"С",
+		"О",
+		"Н",
 		"Д"
-	], 
-	"field-era": "Эра", 
-	"field-hour": "Час", 
+	],
+	"field-era": "Эра",
+	"field-hour": "Час",
 	"quarters-standAlone-abbr": [
-		"1-й кв.", 
-		"2-й кв.", 
-		"3-й кв.", 
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
 		"4-й кв."
-	], 
-	"dateFormatItem-y": "y", 
-	"dateFormatItem-yyMMMEEEd": "EEE, d MMM yy", 
-	"timeFormat-full": "H:mm:ss zzzz", 
-	"dateFormatItem-yyyy": "y", 
+	],
+	"dateFormatItem-yyMMMEEEd": "EEE, d MMM yy",
+	"dateFormatItem-y": "y",
+	"timeFormat-full": "H:mm:ss zzzz",
+	"dateFormatItem-yyyy": "y",
 	"months-standAlone-abbr": [
-		"янв.", 
-		"февр.", 
-		"март", 
-		"апр.", 
-		"май", 
-		"июнь", 
-		"июль", 
-		"авг.", 
-		"сент.", 
-		"окт.", 
-		"нояб.", 
+		"янв.",
+		"февр.",
+		"март",
+		"апр.",
+		"май",
+		"июнь",
+		"июль",
+		"авг.",
+		"сент.",
+		"окт.",
+		"нояб.",
 		"дек."
-	], 
-	"dateFormatItem-Ed": "E d", 
-	"dateFormatItem-yMMM": "LLL y", 
-	"dateFormatItem-yyyyLLLL": "LLLL y", 
-	"field-day-relative+0": "Сегодня", 
+	],
+	"dateFormatItem-Ed": "E, d",
+	"dateFormatItem-yMMM": "LLL y",
+	"field-day-relative+0": "Сегодня",
+	"dateFormatItem-yyyyLLLL": "LLLL y",
+	"field-day-relative+1": "Завтра",
 	"days-standAlone-narrow": [
-		"В", 
-		"П", 
-		"В", 
-		"С", 
-		"Ч", 
-		"П", 
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
 		"С"
-	], 
-	"field-day-relative+1": "Завтра", 
+	],
 	"eraAbbr": [
-		"до н.э.", 
+		"до н.э.",
 		"н.э."
-	], 
-	"field-day-relative+2": "Послезавтра", 
-	"dateFormatItem-yyyyMM": "MM.yyyy", 
-	"dateFormatItem-yyyyMMMM": "LLLL y", 
-	"dateFormat-long": "d MMMM y 'г'.", 
-	"timeFormat-medium": "H:mm:ss", 
-	"field-zone": "Часовой пояс", 
-	"dateFormatItem-Hm": "H:mm", 
-	"dateFormat-medium": "dd.MM.yyyy", 
-	"dateFormatItem-yyMM": "MM.yy", 
-	"dateFormatItem-Hms": "H:mm:ss", 
-	"dateFormatItem-yyMMM": "LLL yy", 
+	],
+	"field-day-relative+2": "Послезавтра",
+	"dateFormatItem-yyyyMM": "MM.yyyy",
+	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"dateFormat-long": "d MMMM y 'г'.",
+	"timeFormat-medium": "H:mm:ss",
+	"field-zone": "Часовой пояс",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormat-medium": "dd.MM.yyyy",
+	"dateFormatItem-yyMM": "MM.yy",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-yyMMM": "LLL yy",
 	"quarters-standAlone-wide": [
-		"1-й квартал", 
-		"2-й квартал", 
-		"3-й квартал", 
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
 		"4-й квартал"
-	], 
-	"dateFormatItem-ms": "mm:ss", 
-	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'.", 
-	"field-year": "Год", 
+	],
+	"dateFormatItem-ms": "mm:ss",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y 'г'.",
+	"field-year": "Год",
 	"months-standAlone-wide": [
-		"Январь", 
-		"Февраль", 
-		"Март", 
-		"Апрель", 
-		"Май", 
-		"Июнь", 
-		"Июль", 
-		"Август", 
-		"Сентябрь", 
-		"Октябрь", 
-		"Ноябрь", 
+		"Январь",
+		"Февраль",
+		"Март",
+		"Апрель",
+		"Май",
+		"Июнь",
+		"Июль",
+		"Август",
+		"Сентябрь",
+		"Октябрь",
+		"Ноябрь",
 		"Декабрь"
-	], 
-	"field-week": "Неделя", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-long": "H:mm:ss z", 
+	],
+	"field-week": "Неделя",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-long": "H:mm:ss z",
 	"months-format-abbr": [
-		"янв.", 
-		"февр.", 
-		"марта", 
-		"апр.", 
-		"мая", 
-		"июня", 
-		"июля", 
-		"авг.", 
-		"сент.", 
-		"окт.", 
-		"нояб.", 
+		"янв.",
+		"февр.",
+		"марта",
+		"апр.",
+		"мая",
+		"июня",
+		"июля",
+		"авг.",
+		"сент.",
+		"окт.",
+		"нояб.",
 		"дек."
-	], 
-	"timeFormat-short": "H:mm", 
-	"dateFormatItem-H": "H", 
-	"field-month": "Месяц", 
+	],
+	"timeFormat-short": "H:mm",
+	"dateFormatItem-H": "H",
+	"field-month": "Месяц",
 	"quarters-format-abbr": [
-		"1-й кв.", 
-		"2-й кв.", 
-		"3-й кв.", 
+		"1-й кв.",
+		"2-й кв.",
+		"3-й кв.",
 		"4-й кв."
-	], 
+	],
 	"days-format-abbr": [
-		"Вс", 
-		"Пн", 
-		"Вт", 
-		"Ср", 
-		"Чт", 
-		"Пт", 
-		"Сб"
-	], 
-	"dateFormatItem-M": "L", 
+		"вс",
+		"пн",
+		"вт",
+		"ср",
+		"чт",
+		"пт",
+		"сб"
+	],
+	"dateFormatItem-M": "L",
 	"days-format-narrow": [
-		"В", 
-		"П", 
-		"В", 
-		"С", 
-		"Ч", 
-		"П", 
+		"В",
+		"П",
+		"В",
+		"С",
+		"Ч",
+		"П",
 		"С"
-	], 
-	"field-second": "Секунда", 
-	"field-day": "День", 
-	"dateFormatItem-MEd": "E, d.M", 
+	],
+	"field-second": "Секунда",
+	"field-day": "День",
+	"dateFormatItem-MEd": "E, d.M",
 	"months-format-narrow": [
-		"Я", 
-		"Ф", 
-		"М", 
-		"А", 
-		"М", 
-		"И", 
-		"И", 
-		"А", 
-		"С", 
-		"О", 
-		"Н", 
+		"Я",
+		"Ф",
+		"М",
+		"А",
+		"М",
+		"И",
+		"И",
+		"А",
+		"С",
+		"О",
+		"Н",
 		"Д"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"Вс", 
-		"Пн", 
-		"Вт", 
-		"Ср", 
-		"Чт", 
-		"Пт", 
+		"Вс",
+		"Пн",
+		"Вт",
+		"Ср",
+		"Чт",
+		"Пт",
 		"Сб"
-	], 
-	"dateFormat-short": "dd.MM.yy", 
-	"dateFormatItem-yMMMEd": "E, d MMM y", 
-	"dateFormat-full": "EEEE, d MMMM y 'г'.", 
-	"dateFormatItem-Md": "d.M", 
-	"dateFormatItem-yMEd": "EEE, d.M.y", 
+	],
+	"dateFormat-short": "dd.MM.yy",
+	"dateFormatItem-yMMMEd": "E, d MMM y",
+	"dateFormat-full": "EEEE, d MMMM y 'г'.",
+	"dateFormatItem-Md": "d.M",
+	"dateFormatItem-yMEd": "EEE, d.M.y",
 	"months-format-wide": [
-		"января", 
-		"февраля", 
-		"марта", 
-		"апреля", 
-		"мая", 
-		"июня", 
-		"июля", 
-		"августа", 
-		"сентября", 
-		"октября", 
-		"ноября", 
+		"января",
+		"февраля",
+		"марта",
+		"апреля",
+		"мая",
+		"июня",
+		"июля",
+		"августа",
+		"сентября",
+		"октября",
+		"ноября",
 		"декабря"
-	], 
-	"dateFormatItem-d": "d", 
+	],
+	"dateFormatItem-d": "d",
 	"quarters-format-wide": [
-		"1-й квартал", 
-		"2-й квартал", 
-		"3-й квартал", 
+		"1-й квартал",
+		"2-й квартал",
+		"3-й квартал",
 		"4-й квартал"
-	], 
+	],
 	"days-format-wide": [
-		"воскресенье", 
-		"понедельник", 
-		"вторник", 
-		"среда", 
-		"четверг", 
-		"пятница", 
+		"воскресенье",
+		"понедельник",
+		"вторник",
+		"среда",
+		"четверг",
+		"пятница",
 		"суббота"
-	], 
+	],
 	"eraNarrow": [
-		"до н.э.", 
+		"до н.э.",
 		"н.э."
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/ru/number.js b/dojo/cldr/nls/ru/number.js
index 8a311c7..18182dd 100644
--- a/dojo/cldr/nls/ru/number.js
+++ b/dojo/cldr/nls/ru/number.js
@@ -1,18 +1,21 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/currency.js b/dojo/cldr/nls/sk/currency.js
index 301673d..9e01d3c 100644
--- a/dojo/cldr/nls/sk/currency.js
+++ b/dojo/cldr/nls/sk/currency.js
@@ -1,13 +1,15 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Austrálsky dolár",
-	CAD_displayName:"Kanadský dolár",
-	CHF_displayName:"Švajčiarský frank",
-	CNY_displayName:"Čínsky Yuan Renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"Britská libra",
-	HKD_displayName:"Hong Kongský dolár",
-	JPY_displayName:"Japonský yen",
-	USD_displayName:"US dolár"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hong Kongský dolár",
+	"CHF_displayName": "Švajčiarský frank",
+	"CAD_displayName": "Kanadský dolár",
+	"CNY_displayName": "Čínsky Yuan Renminbi",
+	"AUD_displayName": "Austrálsky dolár",
+	"JPY_displayName": "Japonský yen",
+	"USD_displayName": "US dolár",
+	"GBP_displayName": "Britská libra",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/gregorian.js b/dojo/cldr/nls/sk/gregorian.js
index 9ffb4c6..8d6b3e7 100644
--- a/dojo/cldr/nls/sk/gregorian.js
+++ b/dojo/cldr/nls/sk/gregorian.js
@@ -1,221 +1,225 @@
-({
-	"field-dayperiod": "Časť dňa", 
-	"dayPeriods-format-wide-pm": "popoludní", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"field-minute": "Minúta", 
-	"dateFormatItem-MMMEd": "E, d. MMM", 
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Časť dňa",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dayPeriods-format-wide-pm": "popoludní",
+	"field-minute": "Minúta",
 	"eraNames": [
-		"pred n.l.", 
+		"pred n.l.",
 		"n.l."
-	], 
-	"field-day-relative+-1": "Včera", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"field-day-relative+-2": "Predvčerom", 
-	"field-weekday": "Deň v týždni", 
-	"field-day-relative+-3": "Pred tromi dňami", 
+	],
+	"dateFormatItem-MMMEd": "E, d. MMM",
+	"field-day-relative+-1": "Včera",
+	"field-weekday": "Deň v týždni",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"field-day-relative+-2": "Predvčerom",
+	"field-day-relative+-3": "Pred tromi dňami",
 	"days-standAlone-wide": [
-		"nedeľa", 
-		"pondelok", 
-		"utorok", 
-		"streda", 
-		"štvrtok", 
-		"piatok", 
+		"nedeľa",
+		"pondelok",
+		"utorok",
+		"streda",
+		"štvrtok",
+		"piatok",
 		"sobota"
-	], 
+	],
 	"months-standAlone-narrow": [
-		"j", 
-		"f", 
-		"m", 
-		"a", 
-		"m", 
-		"j", 
-		"j", 
-		"a", 
-		"s", 
-		"o", 
-		"n", 
+		"j",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
 		"d"
-	], 
-	"dayPeriods-format-wide-am": "dopoludnia", 
-	"field-era": "Éra", 
-	"field-hour": "Hodina", 
-	"timeFormat-full": "H:mm:ss zzzz", 
+	],
+	"field-era": "Éra",
+	"field-hour": "Hodina",
+	"dayPeriods-format-wide-am": "dopoludnia",
+	"timeFormat-full": "H:mm:ss zzzz",
 	"months-standAlone-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"máj", 
-		"jún", 
-		"júl", 
-		"aug", 
-		"sep", 
-		"okt", 
-		"nov", 
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"máj",
+		"jún",
+		"júl",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
 		"dec"
-	], 
-	"dateFormatItem-yMMM": "LLL y", 
-	"field-day-relative+0": "Dnes", 
+	],
+	"dateFormatItem-yMMM": "LLL y",
+	"field-day-relative+0": "Dnes",
+	"field-day-relative+1": "Zajtra",
 	"days-standAlone-narrow": [
-		"N", 
-		"P", 
-		"U", 
-		"S", 
-		"Š", 
-		"P", 
+		"N",
+		"P",
+		"U",
+		"S",
+		"Š",
+		"P",
 		"S"
-	], 
-	"field-day-relative+1": "Zajtra", 
+	],
 	"eraAbbr": [
-		"pred n.l.", 
+		"pred n.l.",
 		"n.l."
-	], 
-	"field-day-relative+2": "Pozajtra", 
-	"field-day-relative+3": "O tri dni", 
-	"dateFormatItem-yyyyMMMM": "LLLL y", 
-	"dateFormat-long": "d. MMMM y", 
-	"timeFormat-medium": "H:mm:ss", 
-	"dateFormatItem-EEEd": "EEE, d.", 
-	"field-zone": "Pásmo", 
-	"dateFormatItem-Hm": "H:mm", 
-	"dateFormat-medium": "d.M.yyyy", 
-	"dateFormatItem-Hms": "H:mm:ss", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
+	],
+	"field-day-relative+2": "Pozajtra",
+	"field-day-relative+3": "O tri dni",
+	"dateFormatItem-yyyyMMMM": "LLLL y",
+	"dateFormat-long": "d. MMMM y",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-EEEd": "EEE, d.",
+	"field-zone": "Pásmo",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormat-medium": "d.M.yyyy",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
 	"quarters-standAlone-wide": [
-		"1. štvrťrok", 
-		"2. štvrťrok", 
-		"3. štvrťrok", 
+		"1. štvrťrok",
+		"2. štvrťrok",
+		"3. štvrťrok",
 		"4. štvrťrok"
-	], 
-	"dateFormatItem-yMMMM": "LLLL y", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-year": "Rok", 
+	],
+	"dateFormatItem-yMMMM": "LLLL y",
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "Rok",
 	"months-standAlone-wide": [
-		"január", 
-		"február", 
-		"marec", 
-		"apríl", 
-		"máj", 
-		"jún", 
-		"júl", 
-		"august", 
-		"september", 
-		"október", 
-		"november", 
+		"január",
+		"február",
+		"marec",
+		"apríl",
+		"máj",
+		"jún",
+		"júl",
+		"august",
+		"september",
+		"október",
+		"november",
 		"december"
-	], 
-	"field-week": "Týždeň", 
-	"dateFormatItem-MMMMEd": "E, d. MMMM", 
-	"dateFormatItem-MMMd": "d. MMM", 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-long": "H:mm:ss z", 
+	],
+	"field-week": "Týždeň",
+	"dateFormatItem-MMMMEd": "E, d. MMMM",
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-long": "H:mm:ss z",
 	"months-format-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"máj", 
-		"jún", 
-		"júl", 
-		"aug", 
-		"sep", 
-		"okt", 
-		"nov", 
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"máj",
+		"jún",
+		"júl",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
 		"dec"
-	], 
-	"timeFormat-short": "H:mm", 
-	"dateFormatItem-H": "H", 
-	"field-month": "Mesiac", 
-	"dateFormatItem-MMMMd": "d. MMMM", 
+	],
+	"timeFormat-short": "H:mm",
+	"dateFormatItem-H": "H",
+	"field-month": "Mesiac",
+	"dateFormatItem-MMMMd": "d. MMMM",
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"days-format-abbr": [
-		"ne", 
-		"po", 
-		"ut", 
-		"st", 
-		"št", 
-		"pi", 
+		"ne",
+		"po",
+		"ut",
+		"st",
+		"št",
+		"pi",
 		"so"
-	], 
-	"dateFormatItem-mmss": "mm:ss", 
+	],
+	"dateFormatItem-mmss": "mm:ss",
 	"days-format-narrow": [
-		"N", 
-		"P", 
-		"U", 
-		"S", 
-		"Š", 
-		"P", 
+		"N",
+		"P",
+		"U",
+		"S",
+		"Š",
+		"P",
 		"S"
-	], 
-	"field-second": "Sekunda", 
-	"field-day": "Deň", 
-	"dateFormatItem-MEd": "E, d.M.", 
+	],
+	"field-second": "Sekunda",
+	"field-day": "Deň",
+	"dateFormatItem-MEd": "E, d.M.",
 	"months-format-narrow": [
-		"j", 
-		"f", 
-		"m", 
-		"a", 
-		"m", 
-		"j", 
-		"j", 
-		"a", 
-		"s", 
-		"o", 
-		"n", 
+		"j",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
 		"d"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"ne", 
-		"po", 
-		"ut", 
-		"st", 
-		"št", 
-		"pi", 
+		"ne",
+		"po",
+		"ut",
+		"st",
+		"št",
+		"pi",
 		"so"
-	], 
-	"dateFormat-short": "d.M.yyyy", 
-	"dateFormatItem-yyyyM": "M.yyyy", 
-	"dateFormatItem-yMMMEd": "EEE, d. MMM y", 
-	"dateFormat-full": "EEEE, d. MMMM y", 
-	"dateFormatItem-Md": "d.M.", 
-	"dateFormatItem-yMEd": "EEE, d.M.yyyy", 
+	],
+	"dateFormat-short": "d.M.yyyy",
+	"dateFormatItem-yyyyM": "M.yyyy",
+	"dateFormatItem-yMMMEd": "EEE, d. MMM y",
+	"dateFormat-full": "EEEE, d. MMMM y",
+	"dateFormatItem-Md": "d.M.",
+	"dateFormatItem-yMEd": "EEE, d.M.yyyy",
 	"months-format-wide": [
-		"januára", 
-		"februára", 
-		"marca", 
-		"apríla", 
-		"mája", 
-		"júna", 
-		"júla", 
-		"augusta", 
-		"septembra", 
-		"októbra", 
-		"novembra", 
+		"januára",
+		"februára",
+		"marca",
+		"apríla",
+		"mája",
+		"júna",
+		"júla",
+		"augusta",
+		"septembra",
+		"októbra",
+		"novembra",
 		"decembra"
-	], 
-	"dateFormatItem-d": "d.", 
+	],
+	"dateFormatItem-d": "d.",
 	"quarters-format-wide": [
-		"1. štvrťrok", 
-		"2. štvrťrok", 
-		"3. štvrťrok", 
+		"1. štvrťrok",
+		"2. štvrťrok",
+		"3. štvrťrok",
 		"4. štvrťrok"
-	], 
+	],
 	"days-format-wide": [
-		"nedeľa", 
-		"pondelok", 
-		"utorok", 
-		"streda", 
-		"štvrtok", 
-		"piatok", 
+		"nedeľa",
+		"pondelok",
+		"utorok",
+		"streda",
+		"štvrtok",
+		"piatok",
 		"sobota"
-	], 
+	],
 	"eraNarrow": [
-		"pred n.l.", 
+		"pred n.l.",
 		"n.l."
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sk/number.js b/dojo/cldr/nls/sk/number.js
index a9e09c1..2d80075 100644
--- a/dojo/cldr/nls/sk/number.js
+++ b/dojo/cldr/nls/sk/number.js
@@ -1,6 +1,9 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"currencyFormat": "#,##0.00 ¤",
+	"group": " ",
+	"decimal": ","
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/currency.js b/dojo/cldr/nls/sl/currency.js
index 490d9f3..1a3549e 100644
--- a/dojo/cldr/nls/sl/currency.js
+++ b/dojo/cldr/nls/sl/currency.js
@@ -1,15 +1,17 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"avstralski dolar",
-	CAD_displayName:"kanadski dolar",
-	CHF_displayName:"švicarski frank",
-	CNY_displayName:"kitajski juan renminbi",
-	EUR_displayName:"evro",
-	GBP_displayName:"britanski funt",
-	HKD_displayName:"hongkonški dolar",
-	JPY_displayName:"japonski jen",
-	JPY_symbol:"¥",
-	USD_displayName:"ameriški dolar",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "hongkonški dolar",
+	"CHF_displayName": "švicarski frank",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "kanadski dolar",
+	"CNY_displayName": "kitajski juan renminbi",
+	"USD_symbol": "$",
+	"AUD_displayName": "avstralski dolar",
+	"JPY_displayName": "japonski jen",
+	"USD_displayName": "ameriški dolar",
+	"GBP_displayName": "britanski funt",
+	"EUR_displayName": "evro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/gregorian.js b/dojo/cldr/nls/sl/gregorian.js
index 00d831b..8344c00 100644
--- a/dojo/cldr/nls/sl/gregorian.js
+++ b/dojo/cldr/nls/sl/gregorian.js
@@ -1,209 +1,218 @@
-({
-	"field-dayperiod": "Čas dneva", 
-	"dayPeriods-format-wide-pm": "pop.", 
-	"field-minute": "Minuta", 
+define(
+//begin v1.x content
+{
+	"field-dayperiod": "Čas dneva",
+	"dayPeriods-format-wide-pm": "pop.",
+	"field-minute": "Minuta",
 	"eraNames": [
-		"pred našim štetjem", 
+		"pred našim štetjem",
 		"naše štetje"
-	], 
-	"field-day-relative+-1": "Včeraj", 
-	"field-day-relative+-2": "Predvčerajšnjim", 
-	"field-weekday": "Dan v tednu", 
-	"field-day-relative+-3": "Pred tremi dnevi", 
+	],
+	"dateFormatItem-MMMEd": "E., d. MMM",
+	"field-day-relative+-1": "Včeraj",
+	"field-weekday": "Dan v tednu",
+	"field-day-relative+-2": "Predvčerajšnjim",
+	"field-day-relative+-3": "Pred tremi dnevi",
 	"days-standAlone-wide": [
-		"nedelja", 
-		"ponedeljek", 
-		"torek", 
-		"sreda", 
-		"četrtek", 
-		"petek", 
+		"nedelja",
+		"ponedeljek",
+		"torek",
+		"sreda",
+		"četrtek",
+		"petek",
 		"sobota"
-	], 
+	],
 	"months-standAlone-narrow": [
-		"j", 
-		"f", 
-		"m", 
-		"a", 
-		"m", 
-		"j", 
-		"j", 
-		"a", 
-		"s", 
-		"o", 
-		"n", 
+		"j",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
 		"d"
-	], 
-	"field-era": "Doba", 
-	"dayPeriods-format-wide-am": "dop.", 
-	"field-hour": "Ura", 
-	"dateFormatItem-y": "y", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
+	],
+	"field-era": "Doba",
+	"field-hour": "Ura",
+	"dayPeriods-format-wide-am": "dop.",
+	"dateFormatItem-y": "y",
+	"timeFormat-full": "HH:mm:ss zzzz",
 	"months-standAlone-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"maj", 
-		"jun", 
-		"jul", 
-		"avg", 
-		"sep", 
-		"okt", 
-		"nov", 
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"avg",
+		"sep",
+		"okt",
+		"nov",
 		"dec"
-	], 
-	"field-day-relative+0": "Danes", 
+	],
+	"dateFormatItem-Ed": "E., d.",
+	"dateFormatItem-yMMM": "MMM y",
+	"field-day-relative+0": "Danes",
+	"field-day-relative+1": "Jutri",
 	"days-standAlone-narrow": [
-		"n", 
-		"p", 
-		"t", 
-		"s", 
-		"č", 
-		"p", 
+		"n",
+		"p",
+		"t",
+		"s",
+		"č",
+		"p",
 		"s"
-	], 
-	"field-day-relative+1": "Jutri", 
+	],
 	"eraAbbr": [
-		"pr. n. št.", 
+		"pr. n. št.",
 		"po Kr."
-	], 
-	"field-day-relative+2": "Pojutrišnjem", 
-	"field-day-relative+3": "Čez tri dni", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"dateFormat-long": "dd. MMMM y", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"field-zone": "Območje", 
-	"dateFormatItem-Hm": "HH:mm", 
-	"dateFormat-medium": "d. MMM. yyyy", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"field-day-relative+2": "Pojutrišnjem",
+	"field-day-relative+3": "Čez tri dni",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"dateFormat-long": "dd. MMMM y",
+	"timeFormat-medium": "HH:mm:ss",
+	"field-zone": "Območje",
+	"dateFormatItem-Hm": "HH:mm",
+	"dateFormat-medium": "d. MMM yyyy",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"quarters-standAlone-wide": [
-		"1. četrtletje", 
-		"2. četrtletje", 
-		"3. četrtletje", 
+		"1. četrtletje",
+		"2. četrtletje",
+		"3. četrtletje",
 		"4. četrtletje"
-	], 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-year": "Leto", 
-	"field-week": "Teden", 
+	],
+	"dateFormatItem-ms": "mm:ss",
+	"field-year": "Leto",
+	"field-week": "Teden",
 	"months-standAlone-wide": [
-		"januar", 
-		"februar", 
-		"marec", 
-		"april", 
-		"maj", 
-		"junij", 
-		"julij", 
-		"avgust", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januar",
+		"februar",
+		"marec",
+		"april",
+		"maj",
+		"junij",
+		"julij",
+		"avgust",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
-	"dateFormatItem-yyQ": "Q/yy", 
-	"timeFormat-long": "HH:mm:ss z", 
+	],
+	"dateFormatItem-MMMd": "d. MMM",
+	"dateFormatItem-yyQ": "Q/yy",
+	"timeFormat-long": "HH:mm:ss z",
 	"months-format-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"maj", 
-		"jun", 
-		"jul", 
-		"avg", 
-		"sep", 
-		"okt", 
-		"nov", 
-		"dec"
-	], 
-	"timeFormat-short": "HH:mm", 
-	"field-month": "Mesec", 
-	"dateFormatItem-MMMMd": "d. MMMM", 
+		"jan.",
+		"feb.",
+		"mar.",
+		"apr.",
+		"maj",
+		"jun.",
+		"jul.",
+		"avg.",
+		"sep.",
+		"okt.",
+		"nov.",
+		"dec."
+	],
+	"timeFormat-short": "HH:mm",
+	"field-month": "Mesec",
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"days-format-abbr": [
-		"ned", 
-		"pon", 
-		"tor", 
-		"sre", 
-		"čet", 
-		"pet", 
+		"ned",
+		"pon",
+		"tor",
+		"sre",
+		"čet",
+		"pet",
 		"sob"
-	], 
-	"dateFormatItem-MMMMdd": "dd. MMMM", 
-	"dateFormatItem-mmss": "mm:ss", 
+	],
+	"dateFormatItem-mmss": "mm:ss",
 	"days-format-narrow": [
-		"n", 
-		"p", 
-		"t", 
-		"s", 
-		"č", 
-		"p", 
+		"n",
+		"p",
+		"t",
+		"s",
+		"č",
+		"p",
 		"s"
-	], 
-	"field-second": "Sekunda", 
-	"field-day": "Dan", 
+	],
+	"field-second": "Sekunda",
+	"field-day": "Dan",
+	"dateFormatItem-MEd": "E., d. MM.",
 	"months-format-narrow": [
-		"j", 
-		"f", 
-		"m", 
-		"a", 
-		"m", 
-		"j", 
-		"j", 
-		"a", 
-		"s", 
-		"o", 
-		"n", 
+		"j",
+		"f",
+		"m",
+		"a",
+		"m",
+		"j",
+		"j",
+		"a",
+		"s",
+		"o",
+		"n",
 		"d"
-	], 
+	],
 	"days-standAlone-abbr": [
-		"ned", 
-		"pon", 
-		"tor", 
-		"sre", 
-		"čet", 
-		"pet", 
+		"ned",
+		"pon",
+		"tor",
+		"sre",
+		"čet",
+		"pet",
 		"sob"
-	], 
-	"dateFormat-short": "d. MM. yy", 
-	"dateFormatItem-yyyyM": "M/yyyy", 
-	"dateFormat-full": "EEEE, dd. MMMM y", 
-	"dateFormatItem-Md": "d. M.", 
+	],
+	"dateFormat-short": "d. MM. yy",
+	"dateFormatItem-yyyyM": "M/yyyy",
+	"dateFormatItem-yMMMEd": "E., d. MMM y",
+	"dateFormat-full": "EEEE, dd. MMMM y",
+	"dateFormatItem-Md": "d. M.",
+	"dateFormatItem-yMEd": "E., d. M. y",
 	"months-format-wide": [
-		"januar", 
-		"februar", 
-		"marec", 
-		"april", 
-		"maj", 
-		"junij", 
-		"julij", 
-		"avgust", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januar",
+		"februar",
+		"marec",
+		"april",
+		"maj",
+		"junij",
+		"julij",
+		"avgust",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
+	],
 	"quarters-format-wide": [
-		"1. četrtletje", 
-		"2. četrtletje", 
-		"3. četrtletje", 
+		"1. četrtletje",
+		"2. četrtletje",
+		"3. četrtletje",
 		"4. četrtletje"
-	], 
+	],
 	"days-format-wide": [
-		"nedelja", 
-		"ponedeljek", 
-		"torek", 
-		"sreda", 
-		"četrtek", 
-		"petek", 
+		"nedelja",
+		"ponedeljek",
+		"torek",
+		"sreda",
+		"četrtek",
+		"petek",
 		"sobota"
-	], 
+	],
 	"eraNarrow": [
-		"pr. n. št.", 
+		"pr. n. št.",
 		"po Kr."
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sl/number.js b/dojo/cldr/nls/sl/number.js
index a5d47fe..c6d268d 100644
--- a/dojo/cldr/nls/sl/number.js
+++ b/dojo/cldr/nls/sl/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"e",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "e",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/currency.js b/dojo/cldr/nls/sv/currency.js
index cbe0710..54f152e 100644
--- a/dojo/cldr/nls/sv/currency.js
+++ b/dojo/cldr/nls/sv/currency.js
@@ -1,16 +1,18 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"australisk dollar",
-	CAD_displayName:"kanadensisk dollar",
-	CAD_symbol:"CAD",
-	CHF_displayName:"schweizisk franc",
-	CHF_symbol:"CHF",
-	CNY_displayName:"kinesisk yuan renminbi",
-	CNY_symbol:"CNY",
-	EUR_displayName:"euro",
-	GBP_displayName:"brittiskt pund sterling",
-	HKD_displayName:"Hongkong-dollar",
-	JPY_displayName:"japansk yen",
-	USD_displayName:"US-dollar"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hongkong-dollar",
+	"CHF_displayName": "schweizisk franc",
+	"CHF_symbol": "CHF",
+	"CAD_displayName": "kanadensisk dollar",
+	"CNY_displayName": "kinesisk yuan renminbi",
+	"AUD_displayName": "australisk dollar",
+	"JPY_displayName": "japansk yen",
+	"CAD_symbol": "CAD",
+	"USD_displayName": "US-dollar",
+	"CNY_symbol": "CNY",
+	"GBP_displayName": "brittiskt pund sterling",
+	"EUR_displayName": "euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/gregorian.js b/dojo/cldr/nls/sv/gregorian.js
index a77799d..a616dfe 100644
--- a/dojo/cldr/nls/sv/gregorian.js
+++ b/dojo/cldr/nls/sv/gregorian.js
@@ -1,241 +1,245 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
+	],
 	"quarters-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
+		"1",
+		"2",
+		"3",
 		"4"
-	], 
-	"field-weekday": "veckodag", 
-	"dateFormatItem-yQQQ": "y QQQ", 
-	"dateFormatItem-yMEd": "EEE, yyyy-MM-dd", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"field-weekday": "veckodag",
+	"dateFormatItem-yQQQ": "y QQQ",
+	"dateFormatItem-yMEd": "EEE, yyyy-MM-dd",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
-	"dateFormat-long": "d MMMM y", 
+	],
+	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
-		"januari", 
-		"februari", 
-		"mars", 
-		"april", 
-		"maj", 
-		"juni", 
-		"juli", 
-		"augusti", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januari",
+		"februari",
+		"mars",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"augusti",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dayPeriods-format-wide-pm": "em", 
-	"dateFormat-full": "EEEE'en' 'den' d:'e' MMMM y", 
-	"dateFormatItem-Md": "d/M", 
-	"dateFormatItem-MMMMEEEd": "EEE d MMMM", 
-	"field-era": "era", 
-	"dateFormatItem-yM": "yyyy-MM", 
+	],
+	"dateFormatItem-EEEd": "EEE d",
+	"dayPeriods-format-wide-pm": "em",
+	"dateFormat-full": "EEEE'en' 'den' d:'e' MMMM y",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-MMMMEEEd": "EEE d MMMM",
+	"field-era": "era",
+	"dateFormatItem-yM": "yyyy-MM",
 	"months-standAlone-wide": [
-		"januari", 
-		"februari", 
-		"mars", 
-		"april", 
-		"maj", 
-		"juni", 
-		"juli", 
-		"augusti", 
-		"september", 
-		"oktober", 
-		"november", 
+		"januari",
+		"februari",
+		"mars",
+		"april",
+		"maj",
+		"juni",
+		"juli",
+		"augusti",
+		"september",
+		"oktober",
+		"november",
 		"december"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1:a kvartalet", 
-		"2:a kvartalet", 
-		"3:e kvartalet", 
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
 		"4:e kvartalet"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "år", 
-	"dateFormatItem-yMMM": "y MMM", 
-	"dateFormatItem-yQ": "yyyy Q", 
-	"field-hour": "timme", 
-	"dateFormatItem-MMdd": "dd/MM", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "år",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "yyyy Q",
+	"field-hour": "timme",
+	"dateFormatItem-MMdd": "dd/MM",
 	"months-format-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"maj", 
-		"jun", 
-		"jul", 
-		"aug", 
-		"sep", 
-		"okt", 
-		"nov", 
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
 		"dec"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "'kl'. HH:mm:ss zzzz", 
-	"field-day-relative+0": "i dag", 
-	"field-day-relative+1": "i morgon", 
-	"field-day-relative+2": "i övermorgon", 
-	"field-day-relative+3": "i överövermorgon", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "'kl'. HH:mm:ss zzzz",
+	"field-day-relative+0": "i dag",
+	"field-day-relative+1": "i morgon",
+	"field-day-relative+2": "i övermorgon",
+	"field-day-relative+3": "i överövermorgon",
 	"months-standAlone-abbr": [
-		"jan", 
-		"feb", 
-		"mar", 
-		"apr", 
-		"maj", 
-		"jun", 
-		"jul", 
-		"aug", 
-		"sep", 
-		"okt", 
-		"nov", 
+		"jan",
+		"feb",
+		"mar",
+		"apr",
+		"maj",
+		"jun",
+		"jul",
+		"aug",
+		"sep",
+		"okt",
+		"nov",
 		"dec"
-	], 
+	],
 	"quarters-format-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1:a kvartalet", 
-		"2:a kvartalet", 
-		"3:e kvartalet", 
+		"1:a kvartalet",
+		"2:a kvartalet",
+		"3:e kvartalet",
 		"4:e kvartalet"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"söndag", 
-		"måndag", 
-		"tisdag", 
-		"onsdag", 
-		"torsdag", 
-		"fredag", 
+		"söndag",
+		"måndag",
+		"tisdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
 		"lördag"
-	], 
-	"dateFormatItem-yyyyMMM": "MMM y", 
-	"dateFormatItem-MMMMd": "d:'e' MMMM", 
-	"dateFormatItem-yyMMM": "MMM -yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-yyyyMMM": "MMM y",
+	"dateFormatItem-MMMMd": "d:'e' MMMM",
+	"dateFormatItem-yyMMM": "MMM -yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"K1", 
-		"K2", 
-		"K3", 
+		"K1",
+		"K2",
+		"K3",
 		"K4"
-	], 
+	],
 	"eraAbbr": [
-		"f.Kr.", 
+		"f.Kr.",
 		"e.Kr."
-	], 
-	"field-minute": "minut", 
-	"field-dayperiod": "fm/em", 
+	],
+	"field-minute": "minut",
+	"field-dayperiod": "fm/em",
 	"days-standAlone-abbr": [
-		"sön", 
-		"mån", 
-		"tis", 
-		"ons", 
-		"tors", 
-		"fre", 
+		"sön",
+		"mån",
+		"tis",
+		"ons",
+		"tors",
+		"fre",
 		"lör"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "i går", 
-	"field-day-relative+-2": "i förrgår", 
-	"field-day-relative+-3": "i förrförrgår", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "E d/M", 
-	"field-day": "dag", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "i går",
+	"field-day-relative+-2": "i förrgår",
+	"field-day-relative+-3": "i förrförrgår",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E d/M",
+	"field-day": "dag",
 	"days-format-wide": [
-		"söndag", 
-		"måndag", 
-		"tisdag", 
-		"onsdag", 
-		"torsdag", 
-		"fredag", 
+		"söndag",
+		"måndag",
+		"tisdag",
+		"onsdag",
+		"torsdag",
+		"fredag",
 		"lördag"
-	], 
-	"field-zone": "tidszon", 
-	"dateFormatItem-yyyyMM": "yyyy-MM", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "tidszon",
+	"dateFormatItem-yyyyMM": "yyyy-MM",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"J", 
-		"F", 
-		"M", 
-		"A", 
-		"M", 
-		"J", 
-		"J", 
-		"A", 
-		"S", 
-		"O", 
-		"N", 
+		"J",
+		"F",
+		"M",
+		"A",
+		"M",
+		"J",
+		"J",
+		"A",
+		"S",
+		"O",
+		"N",
 		"D"
-	], 
-	"dateFormatItem-yyMM": "yy-MM", 
-	"dateFormatItem-hm": "h:mm a", 
+	],
+	"dateFormatItem-yyMM": "yy-MM",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
-		"sön", 
-		"mån", 
-		"tis", 
-		"ons", 
-		"tors", 
-		"fre", 
+		"sön",
+		"mån",
+		"tis",
+		"ons",
+		"tors",
+		"fre",
 		"lör"
-	], 
+	],
 	"eraNames": [
-		"före Kristus", 
+		"före Kristus",
 		"efter Kristus"
-	], 
+	],
 	"days-format-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"O", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
 		"L"
-	], 
-	"field-month": "månad", 
+	],
+	"field-month": "månad",
 	"days-standAlone-narrow": [
-		"S", 
-		"M", 
-		"T", 
-		"O", 
-		"T", 
-		"F", 
+		"S",
+		"M",
+		"T",
+		"O",
+		"T",
+		"F",
 		"L"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "fm", 
-	"dateFormatItem-MMMMEd": "E d:'e' MMMM", 
-	"dateFormat-short": "yyyy-MM-dd", 
-	"dateFormatItem-MMd": "d/M", 
-	"field-second": "sekund", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"field-week": "vecka", 
-	"dateFormat-medium": "d MMM y", 
-	"dateFormatItem-yyyyQQQQ": "QQQQ y", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "fm",
+	"dateFormatItem-MMMMEd": "E d:'e' MMMM",
+	"dateFormat-short": "yyyy-MM-dd",
+	"dateFormatItem-MMd": "d/M",
+	"field-second": "sekund",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"field-week": "vecka",
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-yyyyQQQQ": "QQQQ y",
+	"dateFormatItem-Hms": "HH:mm:ss",
 	"dateFormatItem-hms": "h:mm:ss a"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/sv/number.js b/dojo/cldr/nls/sv/number.js
index 49d869f..675248a 100644
--- a/dojo/cldr/nls/sv/number.js
+++ b/dojo/cldr/nls/sv/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':" ",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"−",
-	'exponential':"×10^",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"¤¤¤",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0 %",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": " ",
+	"percentSign": "%",
+	"exponential": "×10^",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0 %",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "−",
+	"decimal": ",",
+	"nan": "¤¤¤",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/buddhist.js b/dojo/cldr/nls/th/buddhist.js
index 5d0a41e..3475261 100644
--- a/dojo/cldr/nls/th/buddhist.js
+++ b/dojo/cldr/nls/th/buddhist.js
@@ -1,114 +1,118 @@
-({
-	"dateFormatItem-yM": "M/yyyy", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"dayPeriods-format-wide-pm": "หลังเที่ยง", 
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "M/yyyy",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dayPeriods-format-wide-pm": "หลังเที่ยง",
 	"eraNames": [
 		"พุทธศักราช"
-	], 
-	"dateFormatItem-MMMEd": "E d MMM", 
-	"dateTimeFormat-full": "{1}, {0}", 
-	"dateFormatItem-yQQQ": "QQQ y", 
+	],
+	"dateFormatItem-MMMEd": "E d MMM",
+	"dateTimeFormat-full": "{1}, {0}",
+	"dateFormatItem-yQQQ": "QQQ y",
 	"months-standAlone-narrow": [
-		"ม.ค.", 
-		"ก.พ.", 
-		"มี.ค.", 
-		"เม.ย.", 
-		"พ.ค.", 
-		"มิ.ย.", 
-		"ก.ค.", 
-		"ส.ค.", 
-		"ก.ย.", 
-		"ต.ค.", 
-		"พ.ย.", 
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
 		"ธ.ค."
-	], 
-	"dateTimeFormat-short": "{1}, {0}", 
-	"dayPeriods-format-wide-am": "ก่อนเที่ยง", 
-	"dateTimeFormat-medium": "{1}, {0}", 
-	"timeFormat-full": "H นาฬิกา m นาที ss วินาที zzzz", 
-	"dateFormatItem-yMMM": "MMM y", 
+	],
+	"dateTimeFormat-short": "{1}, {0}",
+	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
+	"dateTimeFormat-medium": "{1}, {0}",
+	"timeFormat-full": "H นาฬิกา m นาที ss วินาที zzzz",
+	"dateFormatItem-yMMM": "MMM y",
 	"days-standAlone-narrow": [
-		"อ", 
-		"จ", 
-		"อ", 
-		"พ", 
-		"พ", 
-		"ศ", 
+		"อ",
+		"จ",
+		"อ",
+		"พ",
+		"พ",
+		"ศ",
 		"ส"
-	], 
+	],
 	"eraAbbr": [
 		"พ.ศ."
-	], 
-	"dateFormat-long": "d MMMM y", 
-	"timeFormat-medium": "H:mm:ss", 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dateFormatItem-Hm": "H:mm", 
-	"dateFormat-medium": "d MMM y", 
-	"dateFormatItem-Hms": "H:mm:ss", 
-	"dateTimeFormat-long": "{1}, {0}", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"timeFormat-long": "H นาฬิกา m นาที ss วินาที z", 
+	],
+	"dateFormat-long": "d MMMM y",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-EEEd": "EEE d",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateTimeFormat-long": "{1}, {0}",
+	"dateFormatItem-MMMd": "d MMM",
+	"timeFormat-long": "H นาฬิกา m นาที ss วินาที z",
 	"months-format-abbr": [
-		"ม.ค.", 
-		"ก.พ.", 
-		"มี.ค.", 
-		"เม.ย.", 
-		"พ.ค.", 
-		"มิ.ย.", 
-		"ก.ค.", 
-		"ส.ค.", 
-		"ก.ย.", 
-		"ต.ค.", 
-		"พ.ย.", 
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
 		"ธ.ค."
-	], 
-	"timeFormat-short": "H:mm", 
-	"dateFormatItem-H": "H", 
+	],
+	"timeFormat-short": "H:mm",
+	"dateFormatItem-H": "H",
 	"days-format-abbr": [
-		"อา.", 
-		"จ.", 
-		"อ.", 
-		"พ.", 
-		"พฤ.", 
-		"ศ.", 
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
 		"ส."
-	], 
-	"dateFormatItem-MEd": "E, d/M", 
-	"dateFormat-short": "d/M/yyyy", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"dateFormat-full": "EEEEที่ d MMMM G y", 
-	"dateFormatItem-Md": "d/M", 
-	"dateFormatItem-yMEd": "EEE d/M/yyyy", 
+	],
+	"dateFormatItem-MEd": "E, d/M",
+	"dateFormat-short": "d/M/yyyy",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-Md": "d/M",
+	"dateFormatItem-yMEd": "EEE d/M/yyyy",
 	"months-format-wide": [
-		"มกราคม", 
-		"กุมภาพันธ์", 
-		"มีนาคม", 
-		"เมษายน", 
-		"พฤษภาคม", 
-		"มิถุนายน", 
-		"กรกฎาคม", 
-		"สิงหาคม", 
-		"กันยายน", 
-		"ตุลาคม", 
-		"พฤศจิกายน", 
+		"มกราคม",
+		"กุมภาพันธ์",
+		"มีนาคม",
+		"เมษายน",
+		"พฤษภาคม",
+		"มิถุนายน",
+		"กรกฎาคม",
+		"สิงหาคม",
+		"กันยายน",
+		"ตุลาคม",
+		"พฤศจิกายน",
 		"ธันวาคม"
-	], 
+	],
 	"quarters-format-wide": [
-		"ไตรมาส 1", 
-		"ไตรมาส 2", 
-		"ไตรมาส 3", 
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
 		"ไตรมาส 4"
-	], 
+	],
 	"days-format-wide": [
-		"วันอาทิตย์", 
-		"วันจันทร์", 
-		"วันอังคาร", 
-		"วันพุธ", 
-		"วันพฤหัสบดี", 
-		"วันศุกร์", 
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
 		"วันเสาร์"
-	], 
+	],
 	"eraNarrow": [
 		"พ.ศ."
 	]
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/currency.js b/dojo/cldr/nls/th/currency.js
index f731df1..2991077 100644
--- a/dojo/cldr/nls/th/currency.js
+++ b/dojo/cldr/nls/th/currency.js
@@ -1,14 +1,16 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"ดอลลาร์ออสเตรเลีย",
-	CAD_displayName:"ดอลลาร์แคนาดา",
-	CHF_displayName:"ฟรังก์สวิส",
-	CNY_displayName:"หยวนเหรินหมินปี้ (สาธารณรัฐประชาชนจีน)",
-	EUR_displayName:"ยูโร",
-	GBP_displayName:"ปอนด์สเตอร์ลิง (สหราชอาณาจักร)",
-	HKD_displayName:"ดอลลาร์ฮ่องกง",
-	JPY_displayName:"เยนญี่ปุ่น",
-	JPY_symbol:"¥",
-	USD_displayName:"ดอลลาร์สหรัฐ"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "ดอลลาร์ฮ่องกง",
+	"CHF_displayName": "ฟรังก์สวิส",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "ดอลลาร์แคนาดา",
+	"CNY_displayName": "หยวนเหรินหมินปี้ (สาธารณรัฐประชาชนจีน)",
+	"AUD_displayName": "ดอลลาร์ออสเตรเลีย",
+	"JPY_displayName": "เยนญี่ปุ่น",
+	"USD_displayName": "ดอลลาร์สหรัฐ",
+	"GBP_displayName": "ปอนด์สเตอร์ลิง (สหราชอาณาจักร)",
+	"EUR_displayName": "ยูโร"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/gregorian.js b/dojo/cldr/nls/th/gregorian.js
index 7bea3c1..f104297 100644
--- a/dojo/cldr/nls/th/gregorian.js
+++ b/dojo/cldr/nls/th/gregorian.js
@@ -1,228 +1,232 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"ม.ค.", 
-		"ก.พ.", 
-		"มี.ค.", 
-		"เม.ย.", 
-		"พ.ค.", 
-		"มิ.ย.", 
-		"ก.ค.", 
-		"ส.ค.", 
-		"ก.ย.", 
-		"ต.ค.", 
-		"พ.ย.", 
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
 		"ธ.ค."
-	], 
-	"field-weekday": "วันในสัปดาห์", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "EEE d/M/yyyy", 
-	"dateFormatItem-MMMEd": "E d MMM", 
+	],
+	"field-weekday": "วันในสัปดาห์",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "EEE d/M/yyyy",
+	"dateFormatItem-MMMEd": "E d MMM",
 	"eraNarrow": [
-		"ก่อน ค.ศ.", 
+		"ก่อน ค.ศ.",
 		"ค.ศ."
-	], 
-	"dateFormat-long": "d MMMM y", 
+	],
+	"dateFormat-long": "d MMMM y",
 	"months-format-wide": [
-		"มกราคม", 
-		"กุมภาพันธ์", 
-		"มีนาคม", 
-		"เมษายน", 
-		"พฤษภาคม", 
-		"มิถุนายน", 
-		"กรกฎาคม", 
-		"สิงหาคม", 
-		"กันยายน", 
-		"ตุลาคม", 
-		"พฤศจิกายน", 
+		"มกราคม",
+		"กุมภาพันธ์",
+		"มีนาคม",
+		"เมษายน",
+		"พฤษภาคม",
+		"มิถุนายน",
+		"กรกฎาคม",
+		"สิงหาคม",
+		"กันยายน",
+		"ตุลาคม",
+		"พฤศจิกายน",
 		"ธันวาคม"
-	], 
-	"dateTimeFormat-medium": "{1}, {0}", 
-	"dateFormatItem-EEEd": "EEE d", 
-	"dayPeriods-format-wide-pm": "หลังเที่ยง", 
-	"dateFormat-full": "EEEEที่ d MMMM G y", 
-	"dateFormatItem-Md": "d/M", 
-	"field-era": "สมัย", 
-	"dateFormatItem-yM": "M/yyyy", 
+	],
+	"dateTimeFormat-medium": "{1}, {0}",
+	"dateFormatItem-EEEd": "EEE d",
+	"dayPeriods-format-wide-pm": "หลังเที่ยง",
+	"dateFormat-full": "EEEEที่ d MMMM G y",
+	"dateFormatItem-Md": "d/M",
+	"field-era": "สมัย",
+	"dateFormatItem-yM": "M/yyyy",
 	"months-standAlone-wide": [
-		"มกราคม", 
-		"กุมภาพันธ์", 
-		"มีนาคม", 
-		"เมษายน", 
-		"พฤษภาคม", 
-		"มิถุนายน", 
-		"กรกฎาคม", 
-		"สิงหาคม", 
-		"กันยายน", 
-		"ตุลาคม", 
-		"พฤศจิกายน", 
+		"มกราคม",
+		"กุมภาพันธ์",
+		"มีนาคม",
+		"เมษายน",
+		"พฤษภาคม",
+		"มิถุนายน",
+		"กรกฎาคม",
+		"สิงหาคม",
+		"กันยายน",
+		"ตุลาคม",
+		"พฤศจิกายน",
 		"ธันวาคม"
-	], 
-	"timeFormat-short": "H:mm", 
+	],
+	"timeFormat-short": "H:mm",
 	"quarters-format-wide": [
-		"ไตรมาส 1", 
-		"ไตรมาส 2", 
-		"ไตรมาส 3", 
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
 		"ไตรมาส 4"
-	], 
-	"timeFormat-long": "H นาฬิกา m นาที ss วินาที z", 
-	"field-year": "ปี", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"dateFormatItem-yyyyMMMM": "MMMM y", 
-	"field-hour": "ชั่วโมง", 
+	],
+	"timeFormat-long": "H นาฬิกา m นาที ss วินาที z",
+	"field-year": "ปี",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"dateFormatItem-yyyyMMMM": "MMMM y",
+	"field-hour": "ชั่วโมง",
 	"months-format-abbr": [
-		"ม.ค.", 
-		"ก.พ.", 
-		"มี.ค.", 
-		"เม.ย.", 
-		"พ.ค.", 
-		"มิ.ย.", 
-		"ก.ค.", 
-		"ส.ค.", 
-		"ก.ย.", 
-		"ต.ค.", 
-		"พ.ย.", 
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
 		"ธ.ค."
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "H นาฬิกา m นาที ss วินาที zzzz", 
-	"field-day-relative+0": "วันนี้", 
-	"field-day-relative+1": "พรุ่งนี้", 
-	"field-day-relative+2": "มะรืนนี้", 
-	"dateFormatItem-H": "H", 
-	"field-day-relative+3": "สามวันต่อจากนี้", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "H นาฬิกา m นาที ss วินาที zzzz",
+	"field-day-relative+0": "วันนี้",
+	"field-day-relative+1": "พรุ่งนี้",
+	"field-day-relative+2": "มะรืนนี้",
+	"dateFormatItem-H": "H",
+	"field-day-relative+3": "สามวันต่อจากนี้",
 	"months-standAlone-abbr": [
-		"ม.ค.", 
-		"ก.พ.", 
-		"มี.ค.", 
-		"เม.ย.", 
-		"พ.ค.", 
-		"มิ.ย.", 
-		"ก.ค.", 
-		"ส.ค.", 
-		"ก.ย.", 
-		"ต.ค.", 
-		"พ.ย.", 
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
 		"ธ.ค."
-	], 
+	],
 	"quarters-format-abbr": [
-		"Q1", 
-		"Q2", 
-		"Q3", 
+		"Q1",
+		"Q2",
+		"Q3",
 		"Q4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"ไตรมาส 1", 
-		"ไตรมาส 2", 
-		"ไตรมาส 3", 
+		"ไตรมาส 1",
+		"ไตรมาส 2",
+		"ไตรมาส 3",
 		"ไตรมาส 4"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"วันอาทิตย์", 
-		"วันจันทร์", 
-		"วันอังคาร", 
-		"วันพุธ", 
-		"วันพฤหัสบดี", 
-		"วันศุกร์", 
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
 		"วันเสาร์"
-	], 
-	"dateFormatItem-MMMMd": "d MMMM", 
-	"timeFormat-medium": "H:mm:ss", 
-	"dateFormatItem-Hm": "H:mm", 
+	],
+	"dateFormatItem-MMMMd": "d MMMM",
+	"timeFormat-medium": "H:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
 	"eraAbbr": [
-		"ปีก่อน ค.ศ.", 
+		"ปีก่อน ค.ศ.",
 		"ค.ศ."
-	], 
-	"field-minute": "นาที", 
-	"field-dayperiod": "ช่วงวัน", 
+	],
+	"field-minute": "นาที",
+	"field-dayperiod": "ช่วงวัน",
 	"days-standAlone-abbr": [
-		"อา.", 
-		"จ.", 
-		"อ.", 
-		"พ.", 
-		"พฤ.", 
-		"ศ.", 
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
 		"ส."
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "เมื่อวาน", 
-	"dateTimeFormat-long": "{1}, {0}", 
-	"field-day-relative+-2": "เมื่อวานซืน", 
-	"field-day-relative+-3": "สามวันก่อน", 
-	"dateFormatItem-MMMd": "d MMM", 
-	"dateFormatItem-MEd": "E, d/M", 
-	"dateTimeFormat-full": "{1}, {0}", 
-	"dateFormatItem-yMMMM": "MMMM y", 
-	"field-day": "วัน", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "เมื่อวาน",
+	"dateTimeFormat-long": "{1}, {0}",
+	"field-day-relative+-2": "เมื่อวานซืน",
+	"field-day-relative+-3": "สามวันก่อน",
+	"dateFormatItem-MMMd": "d MMM",
+	"dateFormatItem-MEd": "E, d/M",
+	"dateTimeFormat-full": "{1}, {0}",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"field-day": "วัน",
 	"days-format-wide": [
-		"วันอาทิตย์", 
-		"วันจันทร์", 
-		"วันอังคาร", 
-		"วันพุธ", 
-		"วันพฤหัสบดี", 
-		"วันศุกร์", 
+		"วันอาทิตย์",
+		"วันจันทร์",
+		"วันอังคาร",
+		"วันพุธ",
+		"วันพฤหัสบดี",
+		"วันศุกร์",
 		"วันเสาร์"
-	], 
-	"field-zone": "เขต", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "เขต",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"ม.ค.", 
-		"ก.พ.", 
-		"มี.ค.", 
-		"เม.ย.", 
-		"พ.ค.", 
-		"มิ.ย.", 
-		"ก.ค.", 
-		"ส.ค.", 
-		"ก.ย.", 
-		"ต.ค.", 
-		"พ.ย.", 
+		"ม.ค.",
+		"ก.พ.",
+		"มี.ค.",
+		"เม.ย.",
+		"พ.ค.",
+		"มิ.ย.",
+		"ก.ค.",
+		"ส.ค.",
+		"ก.ย.",
+		"ต.ค.",
+		"พ.ย.",
 		"ธ.ค."
-	], 
+	],
 	"days-format-abbr": [
-		"อา.", 
-		"จ.", 
-		"อ.", 
-		"พ.", 
-		"พฤ.", 
-		"ศ.", 
+		"อา.",
+		"จ.",
+		"อ.",
+		"พ.",
+		"พฤ.",
+		"ศ.",
 		"ส."
-	], 
+	],
 	"eraNames": [
-		"ปีก่อนคริสต์ศักราช", 
+		"ปีก่อนคริสต์ศักราช",
 		"คริสต์ศักราช"
-	], 
+	],
 	"days-format-narrow": [
-		"อ", 
-		"จ", 
-		"อ", 
-		"พ", 
-		"พ", 
-		"ศ", 
+		"อ",
+		"จ",
+		"อ",
+		"พ",
+		"พ",
+		"ศ",
 		"ส"
-	], 
-	"field-month": "เดือน", 
+	],
+	"field-month": "เดือน",
 	"days-standAlone-narrow": [
-		"อ", 
-		"จ", 
-		"อ", 
-		"พ", 
-		"พ", 
-		"ศ", 
+		"อ",
+		"จ",
+		"อ",
+		"พ",
+		"พ",
+		"ศ",
 		"ส"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "ก่อนเที่ยง", 
-	"dateFormatItem-MMMMEd": "E d MMMM", 
-	"dateFormat-short": "d/M/yyyy", 
-	"field-second": "วินาที", 
-	"dateFormatItem-yMMMEd": "EEE d MMM y", 
-	"field-week": "สัปดาห์", 
-	"dateFormat-medium": "d MMM y", 
-	"dateFormatItem-yyyyM": "M/yyyy", 
-	"dateFormatItem-mmss": "mm:ss", 
-	"dateTimeFormat-short": "{1}, {0}", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "ก่อนเที่ยง",
+	"dateFormatItem-MMMMEd": "E d MMMM",
+	"dateFormat-short": "d/M/yyyy",
+	"field-second": "วินาที",
+	"dateFormatItem-yMMMEd": "EEE d MMM y",
+	"field-week": "สัปดาห์",
+	"dateFormat-medium": "d MMM y",
+	"dateFormatItem-yyyyM": "M/yyyy",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateTimeFormat-short": "{1}, {0}",
 	"dateFormatItem-Hms": "H:mm:ss"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/th/number.js b/dojo/cldr/nls/th/number.js
index 3e391eb..ba17d2c 100644
--- a/dojo/cldr/nls/th/number.js
+++ b/dojo/cldr/nls/th/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤#,##0.00;¤-#,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"group": ",",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ".",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "¤#,##0.00;¤-#,##0.00",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/currency.js b/dojo/cldr/nls/tr/currency.js
index 475a49b..786cbe0 100644
--- a/dojo/cldr/nls/tr/currency.js
+++ b/dojo/cldr/nls/tr/currency.js
@@ -1,15 +1,17 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"Avustralya Doları",
-	CAD_displayName:"Kanada Doları",
-	CHF_displayName:"İsviçre Frangı",
-	CNY_displayName:"Çin Yuanı Renminbi",
-	EUR_displayName:"Euro",
-	GBP_displayName:"İngiliz Sterlini",
-	HKD_displayName:"Hong Kong Doları",
-	JPY_displayName:"Japon Yeni",
-	JPY_symbol:"¥",
-	USD_displayName:"ABD Doları",
-	USD_symbol:"$"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "Hong Kong Doları",
+	"CHF_displayName": "İsviçre Frangı",
+	"JPY_symbol": "¥",
+	"CAD_displayName": "Kanada Doları",
+	"CNY_displayName": "Çin Yuanı Renminbi",
+	"USD_symbol": "$",
+	"AUD_displayName": "Avustralya Doları",
+	"JPY_displayName": "Japon Yeni",
+	"USD_displayName": "ABD Doları",
+	"GBP_displayName": "İngiliz Sterlini",
+	"EUR_displayName": "Euro"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/gregorian.js b/dojo/cldr/nls/tr/gregorian.js
index a951340..b23088f 100644
--- a/dojo/cldr/nls/tr/gregorian.js
+++ b/dojo/cldr/nls/tr/gregorian.js
@@ -1,235 +1,239 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"O", 
-		"Ş", 
-		"M", 
-		"N", 
-		"M", 
-		"H", 
-		"T", 
-		"A", 
-		"E", 
-		"E", 
-		"K", 
+		"O",
+		"Ş",
+		"M",
+		"N",
+		"M",
+		"H",
+		"T",
+		"A",
+		"E",
+		"E",
+		"K",
 		"A"
-	], 
-	"field-weekday": "Haftanın Günü", 
-	"dateFormatItem-yyQQQQ": "QQQQ yy", 
-	"dateFormatItem-yQQQ": "QQQ y", 
-	"dateFormatItem-yMEd": "dd.MM.yyyy EEE", 
-	"dateFormatItem-MMMEd": "dd MMM E", 
+	],
+	"field-weekday": "Haftanın Günü",
+	"dateFormatItem-yyQQQQ": "QQQQ yy",
+	"dateFormatItem-yQQQ": "QQQ y",
+	"dateFormatItem-yMEd": "dd.MM.yyyy EEE",
+	"dateFormatItem-MMMEd": "dd MMM E",
 	"eraNarrow": [
-		"MÖ", 
+		"MÖ",
 		"MS"
-	], 
-	"dateFormat-long": "dd MMMM y", 
+	],
+	"dateFormat-long": "dd MMMM y",
 	"months-format-wide": [
-		"Ocak", 
-		"Şubat", 
-		"Mart", 
-		"Nisan", 
-		"Mayıs", 
-		"Haziran", 
-		"Temmuz", 
-		"Ağustos", 
-		"Eylül", 
-		"Ekim", 
-		"Kasım", 
+		"Ocak",
+		"Şubat",
+		"Mart",
+		"Nisan",
+		"Mayıs",
+		"Haziran",
+		"Temmuz",
+		"Ağustos",
+		"Eylül",
+		"Ekim",
+		"Kasım",
 		"Aralık"
-	], 
-	"dateFormatItem-EEEd": "d EEE", 
-	"dayPeriods-format-wide-pm": "PM", 
-	"dateFormat-full": "dd MMMM y EEEE", 
-	"dateFormatItem-Md": "dd/MM", 
-	"field-era": "Miladi Dönem", 
-	"dateFormatItem-yM": "M/yyyy", 
+	],
+	"dateFormatItem-EEEd": "d EEE",
+	"dayPeriods-format-wide-pm": "PM",
+	"dateFormat-full": "dd MMMM y EEEE",
+	"dateFormatItem-Md": "dd/MM",
+	"field-era": "Miladi Dönem",
+	"dateFormatItem-yM": "M/yyyy",
 	"months-standAlone-wide": [
-		"Ocak", 
-		"Şubat", 
-		"Mart", 
-		"Nisan", 
-		"Mayıs", 
-		"Haziran", 
-		"Temmuz", 
-		"Ağustos", 
-		"Eylül", 
-		"Ekim", 
-		"Kasım", 
+		"Ocak",
+		"Şubat",
+		"Mart",
+		"Nisan",
+		"Mayıs",
+		"Haziran",
+		"Temmuz",
+		"Ağustos",
+		"Eylül",
+		"Ekim",
+		"Kasım",
 		"Aralık"
-	], 
-	"timeFormat-short": "HH:mm", 
+	],
+	"timeFormat-short": "HH:mm",
 	"quarters-format-wide": [
-		"1. çeyrek", 
-		"2. çeyrek", 
-		"3. çeyrek", 
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
 		"4. çeyrek"
-	], 
-	"timeFormat-long": "HH:mm:ss z", 
-	"field-year": "Yıl", 
-	"dateFormatItem-yMMM": "MMM y", 
-	"dateFormatItem-yQ": "Q yyyy", 
-	"field-hour": "Saat", 
+	],
+	"timeFormat-long": "HH:mm:ss z",
+	"field-year": "Yıl",
+	"dateFormatItem-yMMM": "MMM y",
+	"dateFormatItem-yQ": "Q yyyy",
+	"field-hour": "Saat",
 	"months-format-abbr": [
-		"Oca", 
-		"Şub", 
-		"Mar", 
-		"Nis", 
-		"May", 
-		"Haz", 
-		"Tem", 
-		"Ağu", 
-		"Eyl", 
-		"Eki", 
-		"Kas", 
+		"Oca",
+		"Şub",
+		"Mar",
+		"Nis",
+		"May",
+		"Haz",
+		"Tem",
+		"Ağu",
+		"Eyl",
+		"Eki",
+		"Kas",
 		"Ara"
-	], 
-	"dateFormatItem-yyQ": "Q yy", 
-	"timeFormat-full": "HH:mm:ss zzzz", 
-	"field-day-relative+0": "Bugün", 
-	"field-day-relative+1": "Yarın", 
-	"field-day-relative+2": "Yarından sonraki gün", 
-	"dateFormatItem-H": "HH", 
-	"field-day-relative+3": "Üç gün sonra", 
+	],
+	"dateFormatItem-yyQ": "Q yy",
+	"timeFormat-full": "HH:mm:ss zzzz",
+	"field-day-relative+0": "Bugün",
+	"field-day-relative+1": "Yarın",
+	"field-day-relative+2": "Yarından sonraki gün",
+	"dateFormatItem-H": "HH",
+	"field-day-relative+3": "Üç gün sonra",
 	"months-standAlone-abbr": [
-		"Oca", 
-		"Şub", 
-		"Mar", 
-		"Nis", 
-		"May", 
-		"Haz", 
-		"Tem", 
-		"Ağu", 
-		"Eyl", 
-		"Eki", 
-		"Kas", 
+		"Oca",
+		"Şub",
+		"Mar",
+		"Nis",
+		"May",
+		"Haz",
+		"Tem",
+		"Ağu",
+		"Eyl",
+		"Eki",
+		"Kas",
 		"Ara"
-	], 
+	],
 	"quarters-format-abbr": [
-		"Ç1", 
-		"Ç2", 
-		"Ç3", 
+		"Ç1",
+		"Ç2",
+		"Ç3",
 		"Ç4"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"1. çeyrek", 
-		"2. çeyrek", 
-		"3. çeyrek", 
+		"1. çeyrek",
+		"2. çeyrek",
+		"3. çeyrek",
 		"4. çeyrek"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "L",
 	"days-standAlone-wide": [
-		"Pazar", 
-		"Pazartesi", 
-		"Salı", 
-		"Çarşamba", 
-		"Perşembe", 
-		"Cuma", 
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
 		"Cumartesi"
-	], 
-	"dateFormatItem-MMMMd": "dd MMMM", 
-	"dateFormatItem-yyMMM": "MMM yy", 
-	"timeFormat-medium": "HH:mm:ss", 
-	"dateFormatItem-Hm": "HH:mm", 
+	],
+	"dateFormatItem-MMMMd": "dd MMMM",
+	"dateFormatItem-yyMMM": "MMM yy",
+	"timeFormat-medium": "HH:mm:ss",
+	"dateFormatItem-Hm": "HH:mm",
 	"quarters-standAlone-abbr": [
-		"Ç1", 
-		"Ç2", 
-		"Ç3", 
+		"Ç1",
+		"Ç2",
+		"Ç3",
 		"Ç4"
-	], 
+	],
 	"eraAbbr": [
-		"MÖ", 
+		"MÖ",
 		"MS"
-	], 
-	"field-minute": "Dakika", 
-	"field-dayperiod": "AM/PM", 
+	],
+	"field-minute": "Dakika",
+	"field-dayperiod": "AM/PM",
 	"days-standAlone-abbr": [
-		"Paz", 
-		"Pzt", 
-		"Sal", 
-		"Çar", 
-		"Per", 
-		"Cum", 
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
 		"Cmt"
-	], 
-	"dateFormatItem-d": "d", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "Dün", 
-	"field-day-relative+-2": "Evvelsi gün", 
-	"field-day-relative+-3": "Üç gün önce", 
-	"dateFormatItem-MMMd": "dd MMM", 
-	"dateFormatItem-MEd": "dd/MM E", 
-	"dateFormatItem-yMMMM": "MMMM y", 
-	"field-day": "Gün", 
+	],
+	"dateFormatItem-d": "d",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "Dün",
+	"field-day-relative+-2": "Evvelsi gün",
+	"field-day-relative+-3": "Üç gün önce",
+	"dateFormatItem-MMMd": "dd MMM",
+	"dateFormatItem-MEd": "dd/MM E",
+	"dateFormatItem-yMMMM": "MMMM y",
+	"field-day": "Gün",
 	"days-format-wide": [
-		"Pazar", 
-		"Pazartesi", 
-		"Salı", 
-		"Çarşamba", 
-		"Perşembe", 
-		"Cuma", 
+		"Pazar",
+		"Pazartesi",
+		"Salı",
+		"Çarşamba",
+		"Perşembe",
+		"Cuma",
 		"Cumartesi"
-	], 
-	"field-zone": "Saat Dilimi", 
-	"dateFormatItem-y": "y", 
+	],
+	"field-zone": "Saat Dilimi",
+	"dateFormatItem-y": "y",
 	"months-standAlone-narrow": [
-		"O", 
-		"Ş", 
-		"M", 
-		"N", 
-		"M", 
-		"H", 
-		"T", 
-		"A", 
-		"E", 
-		"E", 
-		"K", 
+		"O",
+		"Ş",
+		"M",
+		"N",
+		"M",
+		"H",
+		"T",
+		"A",
+		"E",
+		"E",
+		"K",
 		"A"
-	], 
-	"dateFormatItem-yyMM": "MM/yy", 
-	"dateFormatItem-hm": "h:mm a", 
+	],
+	"dateFormatItem-yyMM": "MM/yy",
+	"dateFormatItem-hm": "h:mm a",
 	"days-format-abbr": [
-		"Paz", 
-		"Pzt", 
-		"Sal", 
-		"Çar", 
-		"Per", 
-		"Cum", 
+		"Paz",
+		"Pzt",
+		"Sal",
+		"Çar",
+		"Per",
+		"Cum",
 		"Cmt"
-	], 
+	],
 	"eraNames": [
-		"Milattan Önce", 
+		"Milattan Önce",
 		"Milattan Sonra"
-	], 
+	],
 	"days-format-narrow": [
-		"P", 
-		"P", 
-		"S", 
-		"Ç", 
-		"P", 
-		"C", 
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
 		"C"
-	], 
-	"field-month": "Ay", 
+	],
+	"field-month": "Ay",
 	"days-standAlone-narrow": [
-		"P", 
-		"P", 
-		"S", 
-		"Ç", 
-		"P", 
-		"C", 
+		"P",
+		"P",
+		"S",
+		"Ç",
+		"P",
+		"C",
 		"C"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "AM", 
-	"dateFormatItem-MMMMEd": "dd MMMM E", 
-	"dateFormat-short": "dd.MM.yyyy", 
-	"field-second": "Saniye", 
-	"dateFormatItem-yMMMEd": "dd MMM y EEE", 
-	"dateFormatItem-Ed": "d E", 
-	"field-week": "Hafta", 
-	"dateFormat-medium": "dd MMM y", 
-	"dateFormatItem-mmss": "mm:ss", 
-	"dateFormatItem-Hms": "HH:mm:ss", 
-	"dateFormatItem-hms": "h:mm:ss a", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "AM",
+	"dateFormatItem-MMMMEd": "dd MMMM E",
+	"dateFormat-short": "dd.MM.yyyy",
+	"field-second": "Saniye",
+	"dateFormatItem-yMMMEd": "dd MMM y EEE",
+	"dateFormatItem-Ed": "d E",
+	"field-week": "Hafta",
+	"dateFormat-medium": "dd MMM y",
+	"dateFormatItem-mmss": "mm:ss",
+	"dateFormatItem-Hms": "HH:mm:ss",
+	"dateFormatItem-hms": "h:mm:ss a",
 	"dateFormatItem-yyyy": "y"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/tr/number.js b/dojo/cldr/nls/tr/number.js
index bdd4385..1b20f28 100644
--- a/dojo/cldr/nls/tr/number.js
+++ b/dojo/cldr/nls/tr/number.js
@@ -1,19 +1,22 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':",",
-	'group':".",
-	'list':";",
-	'percentSign':"%",
-	'nativeZeroDigit':"0",
-	'patternDigit':"#",
-	'plusSign':"+",
-	'minusSign':"-",
-	'exponential':"E",
-	'perMille':"‰",
-	'infinity':"∞",
-	'nan':"NaN",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"% #,##0",
-	'currencyFormat':"#,##0.00 ¤"
-})
+define(
+//begin v1.x content
+{
+	"group": ".",
+	"percentSign": "%",
+	"exponential": "E",
+	"scientificFormat": "#E0",
+	"percentFormat": "% #,##0",
+	"list": ";",
+	"infinity": "∞",
+	"patternDigit": "#",
+	"minusSign": "-",
+	"decimal": ",",
+	"nan": "NaN",
+	"nativeZeroDigit": "0",
+	"perMille": "‰",
+	"decimalFormat": "#,##0.###",
+	"currencyFormat": "#,##0.00 ¤",
+	"plusSign": "+"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/buddhist.js b/dojo/cldr/nls/zh-hant/buddhist.js
new file mode 100644
index 0000000..57d9aa7
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/buddhist.js
@@ -0,0 +1,146 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "Gy/M",
+	"dateFormatItem-yQ": "Gy年QQQ",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormatItem-MMMEd": "MMMd日E",
+	"dateTimeFormat-full": "{1}{0}",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-yQQQ": "Gy年QQQ",
+	"dateFormatItem-MMdd": "MM/dd",
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormatItem-y": "Gy年",
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"dateFormatItem-yyyy": "y年",
+	"months-standAlone-abbr": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-Ed": "d日(E)",
+	"dateFormatItem-yMMM": "Gy年M月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-yyyyMMMM": "y年MMMM",
+	"dateFormat-long": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-EEEd": "d EEE",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormatItem-yyMM": "Gyy/MM",
+	"dateFormat-medium": "Gy/M/d",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-yyMMM": "Gyy年MMM",
+	"dateFormatItem-yMd": "Gy/M/d",
+	"dateFormatItem-ms": "mm:ss",
+	"dateTimeFormat-long": "{1}{0}",
+	"months-standAlone-wide": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"dateFormatItem-MMMd": "MMMd日",
+	"dateFormatItem-yyQ": "Gyy年第Q季度",
+	"timeFormat-long": "zah時mm分ss秒",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateFormatItem-H": "H時",
+	"timeFormat-short": "ah:mm",
+	"quarters-format-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"dateFormatItem-MMMMdd": "MMMMdd日",
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"dateFormatItem-M": "M月",
+	"dateFormatItem-yMMMd": "Gy年MMMd日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormat-short": "Gy/M/d",
+	"dateFormatItem-yyyyM": "y年M月",
+	"dateFormatItem-yMMMEd": "Gy年M月d日EEE",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yMEd": "Gy/M/d(EEE)",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateFormatItem-d": "d日",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-h": "ah時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/currency.js b/dojo/cldr/nls/zh-hant/currency.js
new file mode 100644
index 0000000..4dc8c57
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/currency.js
@@ -0,0 +1,16 @@
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "港幣",
+	"CHF_displayName": "瑞士法郎",
+	"CAD_displayName": "加幣",
+	"CNY_displayName": "人民幣",
+	"USD_symbol": "$",
+	"AUD_displayName": "澳幣",
+	"JPY_displayName": "日圓",
+	"CNY_symbol": "¥",
+	"GBP_displayName": "英鎊",
+	"EUR_displayName": "歐元"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/gregorian.js b/dojo/cldr/nls/zh-hant/gregorian.js
new file mode 100644
index 0000000..e82332c
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/gregorian.js
@@ -0,0 +1,228 @@
+define(
+//begin v1.x content
+{
+	"field-weekday": "週天",
+	"dateFormatItem-yQQQ": "y年QQQ",
+	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
+	"dateFormatItem-MMMEd": "MMMd日E",
+	"eraNarrow": [
+		"西元前",
+		"西元"
+	],
+	"dateFormat-long": "y年M月d日",
+	"months-format-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "y年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"field-era": "年代",
+	"dateFormatItem-yM": "yyyy/M",
+	"months-standAlone-wide": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"timeFormat-short": "ah:mm",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"timeFormat-long": "zah時mm分ss秒",
+	"field-year": "年",
+	"dateFormatItem-yMMM": "y年M月",
+	"dateFormatItem-yQ": "y年QQQ",
+	"field-hour": "小時",
+	"dateFormatItem-MMdd": "MM/dd",
+	"months-format-abbr": [
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
+		"12月"
+	],
+	"dateFormatItem-yyQ": "yy年第Q季度",
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "後天",
+	"dateFormatItem-H": "H時",
+	"field-day-relative+3": "大後天",
+	"months-standAlone-abbr": [
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
+		"十二月"
+	],
+	"quarters-format-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"quarters-standAlone-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"dateFormatItem-M": "M月",
+	"days-standAlone-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-yyMMM": "yy年MMM",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"quarters-standAlone-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"eraAbbr": [
+		"西元前",
+		"西元"
+	],
+	"field-minute": "分鐘",
+	"field-dayperiod": "上午/下午",
+	"days-standAlone-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"dateFormatItem-d": "d日",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah時",
+	"dateTimeFormat-long": "{1}{0}",
+	"field-day-relative+-2": "前天",
+	"field-day-relative+-3": "大前天",
+	"dateFormatItem-MMMd": "MMMd日",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"field-zone": "區域",
+	"dateFormatItem-y": "y年",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateFormatItem-yyMM": "yy-MM",
+	"dateFormatItem-hm": "ah:mm",
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"dateFormatItem-yMMMd": "y年MMMd日",
+	"eraNames": [
+		"西元前",
+		"西元"
+	],
+	"days-format-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"field-month": "月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormatItem-MMMMdd": "MMMMdd日",
+	"dateFormat-short": "yy/M/d",
+	"field-second": "秒",
+	"dateFormatItem-yMMMEd": "y年M月d日EEE",
+	"dateFormatItem-Ed": "d日(E)",
+	"field-week": "週",
+	"dateFormat-medium": "yyyy/M/d",
+	"dateFormatItem-yyyyM": "y年M月",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-yyyy": "y年"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/islamic.js b/dojo/cldr/nls/zh-hant/islamic.js
new file mode 100644
index 0000000..5d43414
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/islamic.js
@@ -0,0 +1,87 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "yyyy/M",
+	"dateFormatItem-yQ": "y年QQQ",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormatItem-MMMEd": "MMMd日E",
+	"dateTimeFormat-full": "{1}{0}",
+	"dateFormatItem-hms": "ah:mm:ss",
+	"dateFormatItem-yQQQ": "y年QQQ",
+	"dateFormatItem-MMdd": "MM/dd",
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormatItem-y": "y年",
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"dateFormatItem-yyyy": "Gy年",
+	"dateFormatItem-Ed": "d日(E)",
+	"dateFormatItem-yMMM": "y年M月",
+	"days-standAlone-narrow": [
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
+		"六"
+	],
+	"dateFormat-long": "Gy年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
+	"dateFormat-medium": "Gy/M/d",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-ms": "mm:ss",
+	"dateTimeFormat-long": "{1}{0}",
+	"dateFormatItem-yyyyMd": "Gy/M/d",
+	"dateFormatItem-yyyyMMMd": "Gy年M月d日",
+	"dateFormatItem-MMMd": "MMMd日",
+	"timeFormat-long": "zah時mm分ss秒",
+	"timeFormat-short": "ah:mm",
+	"dateFormatItem-H": "H時",
+	"quarters-format-abbr": [
+		"1季",
+		"2季",
+		"3季",
+		"4季"
+	],
+	"days-format-abbr": [
+		"週日",
+		"週一",
+		"週二",
+		"週三",
+		"週四",
+		"週五",
+		"週六"
+	],
+	"dateFormatItem-MMMMdd": "MMMMdd日",
+	"dateFormatItem-M": "M月",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-hm": "ah:mm",
+	"dateFormat-short": "Gy/M/d",
+	"dateFormatItem-yyyyM": "Gy/M",
+	"dateFormatItem-yMMMEd": "y年M月d日EEE",
+	"dateFormat-full": "Gy年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yyyyQ": "Gy年QQQ",
+	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
+	"dateFormatItem-yyyyMMM": "Gy年M月",
+	"dateFormatItem-d": "d日",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"days-format-wide": [
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
+		"星期六"
+	],
+	"dateFormatItem-h": "ah時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hant/number.js b/dojo/cldr/nls/zh-hant/number.js
new file mode 100644
index 0000000..376cdeb
--- /dev/null
+++ b/dojo/cldr/nls/zh-hant/number.js
@@ -0,0 +1,7 @@
+define(
+//begin v1.x content
+{
+	"currencyFormat": "¤#,##0.00"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hk/currency.js b/dojo/cldr/nls/zh-hk/currency.js
new file mode 100644
index 0000000..0e07210
--- /dev/null
+++ b/dojo/cldr/nls/zh-hk/currency.js
@@ -0,0 +1,15 @@
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "港幣",
+	"HKD_symbol": "HK$",
+	"CAD_displayName": "加幣",
+	"CNY_displayName": "人民幣",
+	"USD_symbol": "$",
+	"AUD_displayName": "澳幣",
+	"JPY_displayName": "日圓",
+	"GBP_displayName": "英鎊",
+	"EUR_displayName": "歐元"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hk/gregorian.js b/dojo/cldr/nls/zh-hk/gregorian.js
new file mode 100644
index 0000000..ff70fea
--- /dev/null
+++ b/dojo/cldr/nls/zh-hk/gregorian.js
@@ -0,0 +1,85 @@
+define(
+//begin v1.x content
+{
+	"dateFormatItem-yM": "yyyy/M",
+	"field-minute": "分鐘",
+	"eraNames": [
+		"西元前",
+		"西元"
+	],
+	"field-weekday": "週天",
+	"dateFormatItem-MMdd": "MM/dd",
+	"field-day-relative+-3": "大前天",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"dateTimeFormat-short": "{1} {0}",
+	"field-era": "年代",
+	"field-hour": "小時",
+	"dateTimeFormat-medium": "{1} {0}",
+	"quarters-standAlone-abbr": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"dateFormatItem-Ed": "d日(E)",
+	"dateFormatItem-yMMM": "y年M月",
+	"eraAbbr": [
+		"西元前",
+		"西元"
+	],
+	"field-day-relative+2": "後天",
+	"field-day-relative+3": "大後天",
+	"dateFormat-long": "y年M月d日",
+	"timeFormat-medium": "ah:mm:ss",
+	"field-zone": "區域",
+	"dateFormat-medium": "yyyy/M/d",
+	"quarters-standAlone-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"field-week": "週",
+	"timeFormat-long": "zah時mm分ss秒",
+	"dateFormatItem-H": "H時",
+	"quarters-format-abbr": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"field-second": "秒",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormat-short": "yy/M/d",
+	"dateFormatItem-yMMMEd": "y年M月d日EEE",
+	"dateFormat-full": "y年M月d日EEEE",
+	"dateFormatItem-Md": "M/d",
+	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"eraNarrow": [
+		"西元前",
+		"西元"
+	],
+	"dateFormatItem-h": "ah時"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-hk/number.js b/dojo/cldr/nls/zh-hk/number.js
new file mode 100644
index 0000000..376cdeb
--- /dev/null
+++ b/dojo/cldr/nls/zh-hk/number.js
@@ -0,0 +1,7 @@
+define(
+//begin v1.x content
+{
+	"currencyFormat": "¤#,##0.00"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/currency.js b/dojo/cldr/nls/zh-tw/currency.js
index fa48735..0962c79 100644
--- a/dojo/cldr/nls/zh-tw/currency.js
+++ b/dojo/cldr/nls/zh-tw/currency.js
@@ -1,345 +1,14 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	"BRE_displayName": "巴西克魯賽羅 (1990-1993)", 
-	"DEM_displayName": "德國馬克", 
-	"KGS_symbol": "som", 
-	"CUP_displayName": "古巴披索", 
-	"HUF_symbol": "Ft", 
-	"BDT_symbol": "Tk", 
-	"LSL_symbol": "M", 
-	"VEF_symbol": "BsF", 
-	"MDL_displayName": "摩杜雲列伊", 
-	"DOP_displayName": "多明尼加披索", 
-	"MTL_symbol": "Lm", 
-	"NGN_displayName": "奈及利亞奈拉", 
-	"KZT_displayName": "卡扎克斯坦坦吉", 
-	"BGL_symbol": "lev", 
-	"LTT_displayName": "立陶宛特羅", 
-	"LAK_displayName": "寮國基普", 
-	"LKR_displayName": "斯里蘭卡盧布", 
-	"AOR_displayName": "安哥拉新寬扎 Reajustado (1995-1999)", 
-	"XEU_displayName": "歐洲貨幣單位 XEU", 
-	"SYP_symbol": "LS", 
-	"USS_displayName": "美元 (同一天)", 
-	"MNT_displayName": "蒙古圖格里克", 
-	"AMD_symbol": "dram", 
-	"MOP_displayName": "澳門元", 
-	"TJR_displayName": "塔吉克斯坦盧布", 
-	"LUC_displayName": "盧森堡可兌換法郎", 
-	"LUL_displayName": "盧森堡金融法郎", 
-	"MRO_symbol": "UM", 
-	"AON_displayName": "安哥拉新寬扎 (1990-2000)", 
-	"BEF_displayName": "比利時法郎", 
-	"IEP_displayName": "愛爾蘭鎊", 
-	"SBD_displayName": "索羅門群島元", 
-	"GRD_displayName": "希臘德拉克馬", 
-	"AZM_displayName": "阿塞拜彊馬特納", 
-	"MTP_displayName": "馬爾他鎊", 
-	"UGX_symbol": "U Sh", 
-	"ARS_symbol": "Arg$", 
-	"LVR_displayName": "拉脫維亞盧布", 
-	"GNF_displayName": "幾內亞法郎", 
-	"GIP_displayName": "直布羅陀鎊", 
-	"SRG_displayName": "蘇里南盾", 
-	"BAD_displayName": "波士尼亞-黑塞哥維那第納爾", 
-	"FJD_displayName": "斐濟元", 
-	"BAM_displayName": "波士尼亞-黑塞哥維那可轉換馬克", 
-	"XBB_displayName": "歐洲貨幣單位 XBB", 
-	"CDF_displayName": "剛果法郎", 
-	"HRD_displayName": "克羅地亞第納爾", 
-	"EQE_displayName": "埃奎維勒", 
-	"BZD_displayName": "伯利茲元", 
-	"MLF_displayName": "馬里法郎", 
-	"VEB_symbol": "Be", 
-	"EGP_displayName": "埃及鎊", 
-	"MVR_displayName": "馬爾地夫海島盧非亞", 
-	"KWD_symbol": "KD", 
-	"TRL_symbol": "TL", 
-	"ALL_symbol": "lek", 
-	"SDP_displayName": "蘇丹鎊", 
-	"NPR_displayName": "尼泊爾盧布", 
-	"PHP_displayName": "菲律賓披索", 
-	"DJF_symbol": "DF", 
-	"WST_displayName": "西薩摩亞塔拉", 
-	"JPY_displayName": "日圓", 
-	"TMM_displayName": "土庫曼馬納特", 
-	"STD_symbol": "Db", 
-	"BGN_displayName": "保加利亞新列弗", 
-	"KYD_displayName": "開曼群島美元", 
-	"VUV_displayName": "萬那杜萬杜", 
-	"IRR_displayName": "伊朗里亞爾", 
-	"DJF_displayName": "吉布地法郎", 
-	"BTN_symbol": "Nu", 
-	"XDR_displayName": "特殊提款權", 
-	"ECS_displayName": "厄瓜多蘇克雷", 
-	"LSM_displayName": "馬洛蒂", 
-	"MNT_symbol": "Tug", 
-	"NLG_displayName": "荷蘭盾", 
-	"MWK_displayName": "馬拉維克瓦查", 
-	"IRR_symbol": "RI", 
-	"OMR_symbol": "RO", 
-	"JMD_symbol": "J$", 
-	"PES_displayName": "秘魯太陽幣", 
-	"SRG_symbol": "Sf", 
-	"LYD_displayName": "利比亞第納爾", 
-	"BRR_displayName": "巴西克魯賽羅", 
-	"ETB_symbol": "Br", 
-	"KMF_symbol": "CF", 
-	"DKK_symbol": "DKr", 
-	"XXX_displayName": "XXX", 
-	"IDR_displayName": "印尼 - 盧布", 
-	"DZD_symbol": "DA", 
-	"TZS_symbol": "T Sh", 
-	"SGD_symbol": "SGD", 
-	"KGS_displayName": "吉爾吉斯索馬", 
-	"BRN_displayName": "巴西克如爾達農瓦", 
-	"AFN_symbol": "Af", 
-	"ISK_displayName": "冰島克朗", 
-	"LUF_displayName": "盧森堡法郎", 
-	"MXN_symbol": "MEX$", 
-	"GYD_symbol": "G$", 
-	"TOP_symbol": "T$", 
-	"SVC_displayName": "薩爾瓦多科郎", 
-	"ZMK_displayName": "尚比亞克瓦查", 
-	"TOP_displayName": "東加潘加", 
-	"ITL_displayName": "義大利里拉", 
-	"USN_displayName": "美元 (第二天)", 
-	"KWD_displayName": "科威特第納爾", 
-	"GEL_symbol": "lari", 
-	"KMF_displayName": "科摩羅法郎", 
-	"COP_symbol": "Col$", 
-	"MYR_displayName": "馬來西亞 - 林吉特", 
-	"XFU_displayName": "法國 UIC 法郎", 
-	"GMD_displayName": "甘比亞達拉西", 
-	"LVL_displayName": "拉脫維亞拉特銀幣", 
-	"AUD_displayName": "澳幣", 
-	"XPF_displayName": "CFP 法郎", 
-	"LBP_displayName": "黎巴嫩鎊", 
-	"SKK_symbol": "Sk", 
-	"BYB_displayName": "白俄羅斯新盧布 (1994-1999)", 
-	"MKD_displayName": "馬其頓第納爾", 
-	"GWP_displayName": "幾內亞披索披索", 
-	"CNY_displayName": "人民幣", 
-	"HNL_symbol": "L", 
-	"BOB_symbol": "Bs", 
-	"JOD_displayName": "約旦第納爾", 
-	"OMR_displayName": "阿曼里奧", 
-	"BOV_displayName": "玻利維亞幕多", 
-	"XPT_displayName": "白金", 
-	"AUD_symbol": "AU$", 
-	"NOK_displayName": "挪威克羅納", 
-	"SCR_displayName": "塞舌爾群島盧布", 
-	"XBA_displayName": "歐洲綜合單位", 
-	"CSK_displayName": "捷克斯洛伐克硬克朗", 
-	"PLZ_displayName": "波蘭茲羅提 (1950-1995)", 
-	"UAK_displayName": "烏克蘭卡本瓦那茲", 
-	"MGF_displayName": "馬達加斯加法郎", 
-	"GNS_displayName": "幾內亞西里", 
-	"YUN_displayName": "南斯拉夫 可轉換第納爾", 
-	"UYU_symbol": "Ur$", 
-	"GYD_displayName": "圭亞那元", 
-	"QAR_displayName": "卡達爾里亞爾", 
-	"BZD_symbol": "BZ$", 
-	"JOD_symbol": "JD", 
-	"ALL_displayName": "阿爾巴尼亞列克", 
-	"BBD_displayName": "巴貝多元", 
-	"RON_displayName": "羅馬尼亞列伊", 
-	"XCD_symbol": "EC$", 
-	"AMD_displayName": "亞美尼亞德拉姆", 
-	"CYP_displayName": "賽浦路斯鎊", 
-	"GBP_symbol": "£", 
-	"SEK_displayName": "瑞典克羅納", 
-	"MZN_symbol": "MTn", 
-	"MMK_displayName": "緬甸元", 
-	"ZAR_displayName": "南非蘭特", 
-	"ECV_displayName": "厄瓜多爾由里達瓦康斯坦 (UVC)", 
-	"LYD_symbol": "LD", 
-	"VUV_symbol": "VT", 
-	"AWG_displayName": "阿魯巴盾", 
-	"CVE_symbol": "CVEsc", 
-	"STD_displayName": "聖多美島和普林西比島多布拉", 
-	"CAD_displayName": "加幣", 
-	"ADP_displayName": "安道爾陪士特", 
-	"MRO_displayName": "茅利塔尼亞烏吉亞", 
-	"LSL_displayName": "賴索托羅蒂", 
-	"TND_displayName": "突尼西亞第納爾", 
-	"USD_symbol": "$", 
-	"BMD_symbol": "Ber$", 
-	"BAM_symbol": "KM", 
-	"BRC_displayName": "巴西克魯賽羅 (1986-1989)", 
-	"BMD_displayName": "百慕達幣", 
-	"BRL_displayName": "巴西里拉", 
-	"JMD_displayName": "牙買加元", 
-	"SOS_displayName": "索馬利亞先令", 
-	"SAR_displayName": "沙烏地里雅", 
-	"PEI_displayName": "祕魯因蒂", 
-	"ESP_displayName": "西班牙陪士特", 
-	"HKD_displayName": "港幣", 
-	"ESP_symbol": "₧", 
-	"BWP_displayName": "波札那 - 普拉", 
-	"TTD_displayName": "千里達及托巴哥元", 
-	"BSD_displayName": "巴哈馬元", 
-	"BIF_displayName": "蒲隆地法郎", 
-	"FRF_displayName": "法國法郎", 
-	"DKK_displayName": "丹麥克羅納", 
-	"AED_displayName": "阿拉伯聯合大公國迪爾汗", 
-	"GHS_symbol": "GH¢", 
-	"AOK_displayName": "安哥拉寬扎(1977-1990)", 
-	"ATS_displayName": "奧地利先令", 
-	"PEN_displayName": "秘魯新太陽幣", 
-	"CRC_displayName": "哥斯大黎加科郎", 
-	"PAB_displayName": "巴拿馬巴波亞", 
-	"CHE_displayName": "WIR 歐元", 
-	"GQE_displayName": "赤道幾內亞埃奎勒", 
-	"DZD_displayName": "阿爾及利亞第納爾", 
-	"EEK_displayName": "愛沙尼亞克朗", 
-	"YDD_displayName": "葉門第納爾", 
-	"GHC_displayName": "迦納仙蔕", 
-	"YER_symbol": "YRl", 
-	"PLN_symbol": "Zl", 
-	"NPR_symbol": "Nrs", 
-	"MXP_displayName": "墨西哥銀披索 (1861-1992)", 
-	"XAG_displayName": "XAG", 
-	"XFO_displayName": "法國金法郎", 
-	"GWE_displayName": "葡屬幾內亞埃斯庫多", 
-	"BOB_displayName": "玻利維亞貨幣單位", 
-	"CAD_symbol": "CA$", 
-	"ZWD_displayName": "辛巴威元", 
-	"SRD_displayName": "蘇利南元", 
-	"ZRN_displayName": "薩伊新扎伊爾", 
-	"XAU_displayName": "黃金", 
-	"GTQ_symbol": "Q", 
-	"KRW_symbol": "KRW", 
-	"BOP_displayName": "玻利維亞披索", 
-	"LBP_symbol": "LL", 
-	"XBD_displayName": "歐洲會計單位(XBD)", 
-	"TZS_displayName": "坦尚尼亞先令", 
-	"XPF_symbol": "CFPF", 
-	"TTD_symbol": "TT$", 
-	"LRD_displayName": "賴比瑞亞元", 
-	"KRW_displayName": "韓國圜", 
-	"SHP_displayName": "聖赫勒拿鎊", 
-	"NAD_symbol": "N$", 
-	"MZE_displayName": "莫桑比克埃斯庫多", 
-	"SDD_displayName": "蘇丹第納爾", 
-	"HRK_displayName": "克羅地亞庫納", 
-	"FKP_displayName": "福克蘭群島鎊", 
-	"COP_displayName": "哥倫比亞披索", 
-	"YUD_displayName": "南斯拉夫第納爾硬幣", 
-	"YUM_displayName": "南斯拉夫挪威亞第納爾", 
-	"BYR_symbol": "Rbl", 
-	"THB_displayName": "泰銖", 
-	"MGA_displayName": "馬達加斯加艾瑞爾", 
-	"TWD_displayName": "新臺幣", 
-	"UGS_displayName": "烏干達先令 (1966-1987)", 
-	"SBD_symbol": "SI$", 
-	"ZAL_displayName": "南非 - 蘭特 (金融)", 
-	"GEL_displayName": "喬治拉里", 
-	"ILP_displayName": "以色列鎊", 
-	"MKD_symbol": "MDen", 
-	"KES_displayName": "肯尼亞先令", 
-	"CZK_displayName": "捷克克朗", 
-	"UGX_displayName": "烏干達先令", 
-	"KZT_symbol": "T", 
-	"BGL_displayName": "保加利亞硬列弗", 
-	"ARP_displayName": "阿根廷披索(1983-1985)", 
-	"BBD_symbol": "BDS$", 
-	"MYR_symbol": "RM", 
-	"RUR_displayName": "俄羅斯盧布 (1991-1998)", 
-	"ERN_displayName": "厄立特里亞納克法", 
-	"BEF_symbol": "BF", 
-	"CLF_displayName": "卡林油達佛曼跎", 
-	"BRB_displayName": "巴西克魯薩多農瓦(1967-1986)", 
-	"IDR_symbol": "Rp", 
-	"IEP_symbol": "IR£", 
-	"BHD_displayName": "巴林第納爾", 
-	"SYP_displayName": "敘利亞鎊", 
-	"BIF_symbol": "Fbu", 
-	"SZL_displayName": "史瓦濟蘭里朗吉尼", 
-	"INR_displayName": "印度盧布", 
-	"PTE_displayName": "葡萄牙埃斯庫多", 
-	"KPW_displayName": "北朝鮮幣", 
-	"XOF_displayName": "西非法郎 BCEAO", 
-	"DOP_symbol": "RD$", 
-	"MXN_displayName": "墨西哥 - 披索", 
-	"RWF_displayName": "盧安達法郎", 
-	"ETB_displayName": "衣索比亞比爾", 
-	"LTL_displayName": "立陶宛里塔", 
-	"SZL_symbol": "E", 
-	"QAR_symbol": "QR", 
-	"SOS_symbol": "Sh.", 
-	"BND_displayName": "汶萊元", 
-	"SUR_displayName": "蘇聯盧布", 
-	"AOA_displayName": "安哥拉寬扎", 
-	"FJD_symbol": "F$", 
-	"CVE_displayName": "維德角埃斯庫多", 
-	"XTS_displayName": "XTS", 
-	"CLP_displayName": "智利披索", 
-	"HUF_displayName": "匈牙利 - 福林", 
-	"LKR_symbol": "SL Re", 
-	"SCR_symbol": "SR", 
-	"TJS_displayName": "塔吉克索莫尼", 
-	"MWK_symbol": "MK", 
-	"GBP_displayName": "英鎊", 
-	"TPE_displayName": "帝汶埃斯庫多", 
-	"GNF_symbol": "GF", 
-	"SGD_displayName": "新加坡幣", 
-	"SLL_displayName": "獅子山利昂", 
-	"MZM_symbol": "Mt", 
-	"PHP_symbol": "Php", 
-	"CYP_symbol": "£C", 
-	"XAF_displayName": "西非法郎 BEAC", 
-	"MTL_displayName": "馬爾他里拉", 
-	"KHR_displayName": "柬埔寨瑞爾", 
-	"ZRZ_displayName": "扎伊爾扎伊爾", 
-	"KES_symbol": "K Sh", 
-	"PKR_symbol": "Pra", 
-	"IQD_symbol": "ID", 
-	"BEC_displayName": "比利時法郎 (可轉換)", 
-	"BEL_displayName": "比利時法郎 (金融)", 
-	"AZN_displayName": "亞塞拜然蒙納特", 
-	"FIM_displayName": "芬蘭馬克", 
-	"PKR_displayName": "巴基斯坦盧布", 
-	"UYP_displayName": "烏拉圭披索 (1975-1993)", 
-	"ANG_symbol": "NA f.", 
-	"CHW_displayName": "WIR 法郎", 
-	"PLN_displayName": "波蘭茲羅提", 
-	"RON_symbol": "0≤lei|1≤leu|1", 
-	"BTN_displayName": "不丹那特倫", 
-	"UAH_displayName": "烏克蘭格里夫那", 
-	"YER_displayName": "也門里亞爾", 
-	"UYU_displayName": "烏拉圭披索", 
-	"CRC_symbol": "C", 
-	"PGK_displayName": "巴布亞紐幾內亞基那", 
-	"XBC_displayName": "歐洲會計單位(XBC)", 
-	"EUR_displayName": "歐元", 
-	"MUR_displayName": "模里西斯盧布", 
-	"BYR_displayName": "白俄羅斯盧布", 
-	"SEK_symbol": "SKr", 
-	"BHD_symbol": "BD", 
-	"IQD_displayName": "伊拉克第納爾", 
-	"VEB_displayName": "委內瑞拉博利瓦", 
-	"CLP_symbol": "Ch$", 
-	"MZM_displayName": "莫三比克梅蒂卡爾", 
-	"NZD_symbol": "$NZ", 
-	"CHF_symbol": "Fr.", 
-	"SIT_displayName": "斯洛維尼亞托勒", 
-	"NOK_symbol": "NKr", 
-	"XCD_displayName": "格瑞那達元", 
-	"RUB_displayName": "俄羅斯盧布", 
-	"BUK_displayName": "緬甸元 BUK", 
-	"ILS_displayName": "以色列新謝克爾", 
-	"KHR_symbol": "CR", 
-	"NAD_displayName": "納米比亞元", 
-	"HNL_displayName": "洪都拉斯倫皮拉", 
-	"GTQ_displayName": "瓜地馬拉格查爾", 
-	"EUR_symbol": "€", 
-	"NZD_displayName": "紐西蘭幣", 
-	"ARA_displayName": "阿根廷奧斯特納爾", 
-	"ARS_displayName": "阿根廷披索", 
-	"ANG_displayName": "荷屬安地列斯盾", 
-	"MOP_symbol": "MOP", 
-	"ZWD_symbol": "Z$", 
-	"ITL_symbol": "₤", 
-	"ZAR_symbol": "R"
-})
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"USD_symbol": "$",
+	"EUR_displayName": "歐元",
+	"HKD_displayName": "港幣",
+	"CAD_displayName": "加幣",
+	"JPY_displayName": "日圓",
+	"GBP_displayName": "英鎊",
+	"AUD_displayName": "澳幣",
+	"CNY_displayName": "人民幣"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh-tw/gregorian.js b/dojo/cldr/nls/zh-tw/gregorian.js
index d770486..7f62583 100644
--- a/dojo/cldr/nls/zh-tw/gregorian.js
+++ b/dojo/cldr/nls/zh-tw/gregorian.js
@@ -1,176 +1,80 @@
-// generated from ldml/main/*.xml, xpath: ldml/calendars/calendar-gregorian
-({
-	"dateFormatItem-yM": "yyyy/M", 
-	"field-minute": "分鐘", 
-	"eraNames": [
-		"西元前", 
-		"西元"
-	], 
-	"field-weekday": "週天", 
-	"dateFormatItem-MMdd": "MM/dd", 
-	"field-day-relative+-3": "大前天", 
-	"field-relative-day": "大後天", 
-	"months-standAlone-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
-		"12"
-	], 
-	"field-era": "年代", 
-	"field-hour": "小時", 
-	"quarters-standAlone-abbr": [
-		"第1季", 
-		"第2季", 
-		"第3季", 
-		"第4季"
-	], 
-	"timeFormat-full": "zzzzah時mm分ss秒", 
-	"months-standAlone-abbr": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
-		"12月"
-	], 
-	"dateFormatItem-Ed": "d日(E)", 
-	"dateFormatItem-yMMM": "y年M月", 
-	"eraAbbr": [
-		"西元前", 
-		"西元"
-	], 
-	"field-day-relative+2": "後天", 
-	"field-day-relative+3": "大後天", 
-	"timeFormat-medium": "ah:mm:ss", 
-	"field-zone": "區域", 
-	"dateFormatItem-yyMM": "yy-MM", 
-	"dateFormat-medium": "yyyy/M/d", 
+define(
+//begin v1.x content
+{
 	"quarters-standAlone-wide": [
-		"第1季", 
-		"第2季", 
-		"第3季", 
+		"第1季",
+		"第2季",
+		"第3季",
 		"第4季"
-	], 
-	"dateFormatItem-yMMMM": "y年M月", 
-	"dateFormatItem-HHmmss": "H:mm:ss", 
-	"months-standAlone-wide": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
-		"12月"
-	], 
-	"field-week": "週", 
-	"dateFormatItem-HHmm": "H:mm", 
-	"timeFormat-long": "zah時mm分ss秒", 
-	"dateFormatItem-H": "H時", 
+	],
 	"quarters-format-abbr": [
-		"第1季", 
-		"第2季", 
-		"第3季", 
+		"第1季",
+		"第2季",
+		"第3季",
 		"第4季"
-	], 
-	"days-format-abbr": [
-		"週日", 
-		"週一", 
-		"週二", 
-		"週三", 
-		"週四", 
-		"週五", 
-		"週六"
-	], 
-	"field-second": "秒", 
-	"dateFormatItem-MEd": "M/d(E)", 
-	"months-format-narrow": [
-		"1", 
-		"2", 
-		"3", 
-		"4", 
-		"5", 
-		"6", 
-		"7", 
-		"8", 
-		"9", 
-		"10", 
-		"11", 
-		"12"
-	], 
-	"days-standAlone-abbr": [
-		"週日", 
-		"週一", 
-		"週二", 
-		"週三", 
-		"週四", 
-		"週五", 
-		"週六"
-	], 
-	"dateFormat-short": "yy/M/d", 
-	"dateFormatItem-yMMMEd": "y年M月d日EEE", 
-	"dateFormatItem-Md": "M/d", 
-	"dateFormatItem-yMEd": "yyyy/M/d(EEE)", 
-	"dateTimeAvailableFormats": [
-		"d日(E)", 
-		"H:mm", 
-		"H:mm:ss", 
-		"M-d(E)", 
-		"MM/dd", 
-		"M/d", 
-		"yyyy/M", 
-		"yyyy/M/d(EEE)", 
-		"yyyy年M月", 
-		"yyyy年M月", 
-		"yyyy/MM", 
-		"MMMMdd日", 
-		"MMMd日", 
-		"MM-dd", 
-		"M-d", 
-		"d日", 
-		"mm:ss", 
-		"mm:ss", 
-		"yyyy年", 
-		"yyyy-M", 
-		"yyyy年M月d日,E", 
-		"yyyy年MMM", 
-		"yyyy年MMMd日EEE", 
-		"yyyy年MMMM", 
-		"yyyy年QQQ", 
-		"y年QQQ", 
-		"yy-MM", 
-		"yy年MMM", 
-		"yy年第Q季度", 
-		"yyyy年", 
-		"yyyy年M月", 
-		"yyyy年MMMM"
-	], 
-	"quarters-format-wide": [
-		"第1季", 
-		"第2季", 
-		"第3季", 
+	],
+	"dateFormat-medium": "yyyy/M/d",
+	"field-second": "秒",
+	"quarters-standAlone-abbr": [
+		"第1季",
+		"第2季",
+		"第3季",
 		"第4季"
-	], 
+	],
+	"dateFormatItem-MMdd": "MM/dd",
+	"dateFormatItem-MEd": "M/d(E)",
+	"dateFormatItem-yMEd": "yyyy/M/d(EEE)",
+	"field-week": "週",
+	"dateFormatItem-H": "H時",
 	"eraNarrow": [
-		"西元前", 
+		"西元前",
+		"西元"
+	],
+	"field-day-relative+-3": "大前天",
+	"timeFormat-full": "zzzzah時mm分ss秒",
+	"dateFormatItem-Md": "M/d",
+	"months-standAlone-narrow": [
+		"1",
+		"2",
+		"3",
+		"4",
+		"5",
+		"6",
+		"7",
+		"8",
+		"9",
+		"10",
+		"11",
+		"12"
+	],
+	"eraNames": [
+		"西元前",
 		"西元"
-	]
-})
\ No newline at end of file
+	],
+	"field-minute": "分鐘",
+	"field-hour": "小時",
+	"field-day-relative+2": "後天",
+	"field-day-relative+3": "大後天",
+	"dateFormat-short": "yy/M/d",
+	"dateFormatItem-yMMMEd": "y年M月d日EEE",
+	"field-era": "年代",
+	"dateFormatItem-yM": "yyyy/M",
+	"timeFormat-long": "zah時mm分ss秒",
+	"eraAbbr": [
+		"西元前",
+		"西元"
+	],
+	"dateFormatItem-h": "ah時",
+	"dateFormatItem-yMMM": "y年M月",
+	"quarters-format-wide": [
+		"第1季",
+		"第2季",
+		"第3季",
+		"第4季"
+	],
+	"field-weekday": "週天",
+	"field-zone": "區域",
+	"dateFormatItem-Ed": "d日(E)"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/currency.js b/dojo/cldr/nls/zh/currency.js
index 0a8f781..3bff810 100644
--- a/dojo/cldr/nls/zh/currency.js
+++ b/dojo/cldr/nls/zh/currency.js
@@ -1,14 +1,16 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers/currencies
-({
-	AUD_displayName:"澳大利亚元",
-	CAD_displayName:"加拿大元",
-	CHF_displayName:"瑞士法郎",
-	CNY_displayName:"人民币",
-	CNY_symbol:"¥",
-	EUR_displayName:"欧元",
-	GBP_displayName:"英镑",
-	HKD_displayName:"港元",
-	JPY_displayName:"日元",
-	USD_displayName:"美元"
-})
-                 
\ No newline at end of file
+define(
+//begin v1.x content
+{
+	"HKD_displayName": "港元",
+	"CHF_displayName": "瑞士法郎",
+	"CAD_displayName": "加拿大元",
+	"CNY_displayName": "人民币",
+	"AUD_displayName": "澳大利亚元",
+	"JPY_displayName": "日元",
+	"USD_displayName": "美元",
+	"CNY_symbol": "¥",
+	"GBP_displayName": "英镑",
+	"EUR_displayName": "欧元"
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/gregorian.js b/dojo/cldr/nls/zh/gregorian.js
index 24a60ab..8548b42 100644
--- a/dojo/cldr/nls/zh/gregorian.js
+++ b/dojo/cldr/nls/zh/gregorian.js
@@ -1,243 +1,247 @@
-({
+define(
+//begin v1.x content
+{
 	"months-format-narrow": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"field-weekday": "周天", 
-	"dateFormatItem-yQQQ": "y年QQQ", 
-	"dateFormatItem-yMEd": "y年M月d日,E", 
-	"dateFormatItem-MMMEd": "MMMd日E", 
+	],
+	"field-weekday": "周天",
+	"dateFormatItem-yQQQ": "y年QQQ",
+	"dateFormatItem-yMEd": "y年M月d日,E",
+	"dateFormatItem-MMMEd": "MMMd日E",
 	"eraNarrow": [
-		"公元前", 
+		"公元前",
 		"公元"
-	], 
-	"dayPeriods-format-wide-earlyMorning": "清晨", 
-	"dayPeriods-format-wide-morning": "上午", 
-	"dateFormat-long": "y年M月d日", 
+	],
+	"dayPeriods-format-wide-earlyMorning": "清晨",
+	"dayPeriods-format-wide-morning": "上午",
+	"dateFormat-long": "y年M月d日",
 	"months-format-wide": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"dateTimeFormat-medium": "{1} {0}", 
-	"dayPeriods-format-wide-pm": "下午", 
-	"dateFormat-full": "y年M月d日EEEE", 
-	"dateFormatItem-Md": "M-d", 
-	"field-era": "时期", 
-	"dateFormatItem-yM": "yyyy-M", 
+	],
+	"dateTimeFormat-medium": "{1} {0}",
+	"dayPeriods-format-wide-pm": "下午",
+	"dateFormat-full": "y年M月d日EEEE",
+	"dateFormatItem-Md": "M-d",
+	"field-era": "时期",
+	"dateFormatItem-yM": "yyyy-M",
 	"months-standAlone-wide": [
-		"一月", 
-		"二月", 
-		"三月", 
-		"四月", 
-		"五月", 
-		"六月", 
-		"七月", 
-		"八月", 
-		"九月", 
-		"十月", 
-		"十一月", 
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
 		"十二月"
-	], 
-	"timeFormat-short": "ah:mm", 
+	],
+	"timeFormat-short": "ah:mm",
 	"quarters-format-wide": [
-		"第1季度", 
-		"第2季度", 
-		"第3季度", 
+		"第1季度",
+		"第2季度",
+		"第3季度",
 		"第4季度"
-	], 
-	"timeFormat-long": "zah时mm分ss秒", 
-	"field-year": "年", 
-	"dateFormatItem-yMMM": "y年MMM", 
-	"dateFormatItem-yQ": "y年QQQ", 
-	"dateFormatItem-yyyyMMMM": "y年MMMM", 
-	"dateFormatItem-MMdd": "MM-dd", 
-	"field-hour": "小时", 
+	],
+	"timeFormat-long": "zah时mm分ss秒",
+	"field-year": "年",
+	"dateFormatItem-yMMM": "y年MMM",
+	"dateFormatItem-yQ": "y年QQQ",
+	"dateFormatItem-yyyyMMMM": "y年MMMM",
+	"field-hour": "小时",
+	"dateFormatItem-MMdd": "MM-dd",
 	"months-format-abbr": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"dateFormatItem-yyQ": "yy年第Q季度", 
-	"timeFormat-full": "zzzzah时mm分ss秒", 
-	"field-day-relative+0": "今天", 
-	"field-day-relative+1": "明天", 
-	"field-day-relative+2": "后天", 
-	"dateFormatItem-H": "H时", 
+	],
+	"dateFormatItem-yyQ": "yy年第Q季度",
+	"timeFormat-full": "zzzzah时mm分ss秒",
+	"field-day-relative+0": "今天",
+	"field-day-relative+1": "明天",
+	"field-day-relative+2": "后天",
+	"dateFormatItem-H": "H时",
 	"months-standAlone-abbr": [
-		"一月", 
-		"二月", 
-		"三月", 
-		"四月", 
-		"五月", 
-		"六月", 
-		"七月", 
-		"八月", 
-		"九月", 
-		"十月", 
-		"十一月", 
+		"一月",
+		"二月",
+		"三月",
+		"四月",
+		"五月",
+		"六月",
+		"七月",
+		"八月",
+		"九月",
+		"十月",
+		"十一月",
 		"十二月"
-	], 
+	],
 	"quarters-format-abbr": [
-		"1季", 
-		"2季", 
-		"3季", 
+		"1季",
+		"2季",
+		"3季",
 		"4季"
-	], 
+	],
 	"quarters-standAlone-wide": [
-		"第1季度", 
-		"第2季度", 
-		"第3季度", 
+		"第1季度",
+		"第2季度",
+		"第3季度",
 		"第4季度"
-	], 
-	"dateFormatItem-M": "L", 
+	],
+	"dateFormatItem-M": "M月",
 	"days-standAlone-wide": [
-		"星期日", 
-		"星期一", 
-		"星期二", 
-		"星期三", 
-		"星期四", 
-		"星期五", 
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
 		"星期六"
-	], 
-	"dateFormatItem-yyMMM": "yy年MMM", 
-	"timeFormat-medium": "ah:mm:ss", 
-	"dateFormatItem-Hm": "H:mm", 
+	],
+	"dateFormatItem-yyMMM": "yy年MMM",
+	"timeFormat-medium": "ah:mm:ss",
+	"dateFormatItem-Hm": "H:mm",
 	"quarters-standAlone-abbr": [
-		"1季", 
-		"2季", 
-		"3季", 
+		"1季",
+		"2季",
+		"3季",
 		"4季"
-	], 
+	],
 	"eraAbbr": [
-		"公元前", 
+		"公元前",
 		"公元"
-	], 
-	"field-minute": "分钟", 
-	"field-dayperiod": "上午/下午", 
-	"dayPeriods-format-wide-night": "晚上", 
+	],
+	"field-minute": "分钟",
+	"field-dayperiod": "上午/下午",
 	"days-standAlone-abbr": [
-		"周日", 
-		"周一", 
-		"周二", 
-		"周三", 
-		"周四", 
-		"周五", 
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
 		"周六"
-	], 
-	"dateFormatItem-d": "d日", 
-	"dateFormatItem-ms": "mm:ss", 
-	"field-day-relative+-1": "昨天", 
-	"dateFormatItem-h": "ah", 
-	"dateTimeFormat-long": "{1}{0}", 
-	"field-day-relative+-2": "前天", 
-	"dateFormatItem-MMMd": "MMMd日", 
-	"dayPeriods-format-wide-midDay": "中午", 
-	"dateFormatItem-MEd": "M-dE", 
-	"dateTimeFormat-full": "{1}{0}", 
-	"field-day": "日", 
+	],
+	"dayPeriods-format-wide-night": "晚上",
+	"dateFormatItem-d": "d日",
+	"dateFormatItem-ms": "mm:ss",
+	"field-day-relative+-1": "昨天",
+	"dateFormatItem-h": "ah时",
+	"dateTimeFormat-long": "{1}{0}",
+	"field-day-relative+-2": "前天",
+	"dateFormatItem-MMMd": "MMMd日",
+	"dayPeriods-format-wide-midDay": "中午",
+	"dateFormatItem-MEd": "M-dE",
+	"dateTimeFormat-full": "{1}{0}",
+	"field-day": "日",
 	"days-format-wide": [
-		"星期日", 
-		"星期一", 
-		"星期二", 
-		"星期三", 
-		"星期四", 
-		"星期五", 
+		"星期日",
+		"星期一",
+		"星期二",
+		"星期三",
+		"星期四",
+		"星期五",
 		"星期六"
-	], 
-	"field-zone": "区域", 
-	"dateFormatItem-y": "y年", 
+	],
+	"field-zone": "区域",
+	"dateFormatItem-y": "y年",
 	"months-standAlone-narrow": [
-		"1月", 
-		"2月", 
-		"3月", 
-		"4月", 
-		"5月", 
-		"6月", 
-		"7月", 
-		"8月", 
-		"9月", 
-		"10月", 
-		"11月", 
+		"1月",
+		"2月",
+		"3月",
+		"4月",
+		"5月",
+		"6月",
+		"7月",
+		"8月",
+		"9月",
+		"10月",
+		"11月",
 		"12月"
-	], 
-	"dateFormatItem-yyMM": "yy-MM", 
-	"dateFormatItem-hm": "ah:mm", 
+	],
+	"dateFormatItem-yyMM": "yy-MM",
+	"dateFormatItem-hm": "ah:mm",
 	"days-format-abbr": [
-		"周日", 
-		"周一", 
-		"周二", 
-		"周三", 
-		"周四", 
-		"周五", 
+		"周日",
+		"周一",
+		"周二",
+		"周三",
+		"周四",
+		"周五",
 		"周六"
-	], 
-	"dateFormatItem-yMMMd": "y年MMMd日", 
+	],
+	"dateFormatItem-yMMMd": "y年MMMd日",
 	"eraNames": [
-		"公元前", 
+		"公元前",
 		"公元"
-	], 
+	],
 	"days-format-narrow": [
-		"日", 
-		"一", 
-		"二", 
-		"三", 
-		"四", 
-		"五", 
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
 		"六"
-	], 
-	"field-month": "月", 
+	],
+	"field-month": "月",
 	"days-standAlone-narrow": [
-		"日", 
-		"一", 
-		"二", 
-		"三", 
-		"四", 
-		"五", 
+		"日",
+		"一",
+		"二",
+		"三",
+		"四",
+		"五",
 		"六"
-	], 
-	"dateFormatItem-MMM": "LLL", 
-	"dayPeriods-format-wide-am": "上午", 
-	"dateFormatItem-MMMMdd": "MMMMdd日", 
-	"dayPeriods-format-wide-weeHours": "凌晨", 
-	"dateFormat-short": "yy-M-d", 
-	"dayPeriods-format-wide-afternoon": "下午", 
-	"field-second": "秒钟", 
-	"dateFormatItem-yMMMEd": "y年MMMd日EEE", 
-	"dateFormatItem-Ed": "d日E", 
-	"field-week": "周", 
-	"dateFormat-medium": "yyyy-M-d", 
-	"dateFormatItem-yyyyM": "y年M月", 
-	"dateTimeFormat-short": "{1} {0}", 
-	"dateFormatItem-Hms": "H:mm:ss", 
-	"dateFormatItem-hms": "ah:mm:ss", 
+	],
+	"dateFormatItem-MMM": "LLL",
+	"dayPeriods-format-wide-am": "上午",
+	"dateFormatItem-MMMMdd": "MMMMdd日",
+	"dayPeriods-format-wide-weeHours": "凌晨",
+	"dateFormat-short": "yy-M-d",
+	"dayPeriods-format-wide-afternoon": "下午",
+	"field-second": "秒钟",
+	"dateFormatItem-yMMMEd": "y年MMMd日EEE",
+	"dateFormatItem-Ed": "d日E",
+	"field-week": "周",
+	"dateFormat-medium": "yyyy-M-d",
+	"dateFormatItem-yyyyM": "y年M月",
+	"dateTimeFormat-short": "{1} {0}",
+	"dateFormatItem-Hms": "H:mm:ss",
+	"dateFormatItem-hms": "ah:mm:ss",
 	"dateFormatItem-yyyy": "y年"
-})
\ No newline at end of file
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/nls/zh/number.js b/dojo/cldr/nls/zh/number.js
index 018f6e8..afbe6ca 100644
--- a/dojo/cldr/nls/zh/number.js
+++ b/dojo/cldr/nls/zh/number.js
@@ -1,9 +1,12 @@
-// generated from ldml/main/*.xml, xpath: ldml/numbers
-({
-	'decimal':".",
-	'group':",",
-	'decimalFormat':"#,##0.###",
-	'scientificFormat':"#E0",
-	'percentFormat':"#,##0%",
-	'currencyFormat':"¤#,##0.00"
-})
+define(
+//begin v1.x content
+{
+	"decimalFormat": "#,##0.###",
+	"group": ",",
+	"scientificFormat": "#E0",
+	"percentFormat": "#,##0%",
+	"currencyFormat": "¤#,##0.00",
+	"decimal": "."
+}
+//end v1.x content
+);
\ No newline at end of file
diff --git a/dojo/cldr/supplemental.js b/dojo/cldr/supplemental.js
index 739acd5..5b7ca3b 100644
--- a/dojo/cldr/supplemental.js
+++ b/dojo/cldr/supplemental.js
@@ -1,6 +1,5 @@
-dojo.provide("dojo.cldr.supplemental");
-
-dojo.require("dojo.i18n");
+define("dojo/cldr/supplemental", ["dojo", "dojo/i18n"], function(dojo) {
+dojo.getObject("cldr.supplemental", true, dojo);
 
 dojo.cldr.supplemental.getFirstDayOfWeek = function(/*String?*/locale){
 // summary: Returns a zero-based index for first day of the week
@@ -11,11 +10,11 @@ dojo.cldr.supplemental.getFirstDayOfWeek = function(/*String?*/locale){
 	// from http://www.unicode.org/cldr/data/common/supplemental/supplementalData.xml:supplementalData/weekData/firstDay
 	var firstDay = {/*default is 1=Monday*/
 		mv:5,
-		af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,
-		ly:6,ma:6,om:6,qa:6,sa:6,sd:6,so:6,tn:6,ye:6,
-		ar:0,as:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,ie:0,
-		il:0,'in':0,is:0,jm:0,jp:0,kg:0,kr:0,la:0,mh:0,mn:0,mo:0,mp:0,
-		mt:0,nz:0,ph:0,pk:0,sg:0,sy:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,
+		ae:6,af:6,bh:6,dj:6,dz:6,eg:6,er:6,et:6,iq:6,ir:6,jo:6,ke:6,kw:6,
+		ly:6,ma:6,om:6,qa:6,sa:6,sd:6,so:6,sy:6,tn:6,ye:6,
+		ar:0,as:0,az:0,bw:0,ca:0,cn:0,fo:0,ge:0,gl:0,gu:0,hk:0,
+		il:0,'in':0,jm:0,jp:0,kg:0,kr:0,la:0,mh:0,mn:0,mo:0,mp:0,
+		mt:0,nz:0,ph:0,pk:0,sg:0,th:0,tt:0,tw:0,um:0,us:0,uz:0,
 		vi:0,zw:0
 // variant. do not use?		gb:0,
 	};
@@ -40,7 +39,7 @@ dojo.cldr.supplemental._region = function(/*String?*/locale){
 		region = tags[2];
 	}
 	return region;
-}
+};
 
 dojo.cldr.supplemental.getWeekend = function(/*String?*/locale){
 // summary: Returns a hash containing the start and end days of the weekend
@@ -68,3 +67,6 @@ dojo.cldr.supplemental.getWeekend = function(/*String?*/locale){
 	if(end === undefined){end=0;}
 	return {start:start, end:end}; /*Object {start,end}*/
 };
+
+return dojo.cldr.supplemental;
+});
diff --git a/dojo/colors.js b/dojo/colors.js
index 602d65c..14d5283 100644
--- a/dojo/colors.js
+++ b/dojo/colors.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.colors");
+define("dojo/colors", ["dojo"], function(dojo) {
+dojo.getObject("colors", true, dojo);
 
 //TODO: this module appears to break naming conventions
 
@@ -46,9 +47,9 @@ dojo.colors = {
 				var H = ((parseFloat(c[0]) % 360) + 360) % 360 / 360,
 					S = parseFloat(c[1]) / 100,
 					L = parseFloat(c[2]) / 100,
-					// calculate rgb according to the algorithm 
-					// recommended by the CSS3 Color Module 
-					m2 = L <= 0.5 ? L * (S + 1) : L + S - L * S, 
+					// calculate rgb according to the algorithm
+					// recommended by the CSS3 Color Module
+					m2 = L <= 0.5 ? L * (S + 1) : L + S - L * S,
 					m1 = 2 * L - m2;
 				a = [
 					hue2rgb(m1, m2, H + 1 / 3) * 256,
@@ -223,3 +224,6 @@ dojo.mixin(dojo.Color.named, {
 	whitesmoke:	[245,245,245],
 	yellowgreen:	[154,205,50]
 });
+
+return dojo.colors;
+});
diff --git a/dojo/cookie.js b/dojo/cookie.js
index 983918a..0c30f2c 100644
--- a/dojo/cookie.js
+++ b/dojo/cookie.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo.cookie");
-
-dojo.require("dojo.regexp");
+define("dojo/cookie", ["dojo", "dojo/regexp"], function(dojo) {
 
 /*=====
 dojo.__cookieProps = function(){
@@ -24,7 +22,7 @@ dojo.__cookieProps = function(){
 
 
 dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/props){
-	//	summary: 
+	//	summary:
 	//		Get or set a cookie.
 	//	description:
 	// 		If one argument is passed, returns the value of the cookie
@@ -33,17 +31,17 @@ dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/
 	//		Name of the cookie
 	//	value:
 	//		Value for the cookie
-	//	props: 
+	//	props:
 	//		Properties for the cookie
 	//	example:
 	//		set a cookie with the JSON-serialized contents of an object which
 	//		will expire 5 days from now:
 	//	|	dojo.cookie("configObj", dojo.toJson(config), { expires: 5 });
-	//	
+	//
 	//	example:
 	//		de-serialize a cookie back into a JavaScript object:
 	//	|	var config = dojo.fromJson(dojo.cookie("configObj"));
-	//	
+	//
 	//	example:
 	//		delete a cookie:
 	//	|	dojo.cookie("configObj", null, {expires: -1});
@@ -55,7 +53,7 @@ dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/
 		props = props || {};
 // FIXME: expires=0 seems to disappear right away, not on close? (FF3)  Change docs?
 		var exp = props.expires;
-		if(typeof exp == "number"){ 
+		if(typeof exp == "number"){
 			var d = new Date();
 			d.setTime(d.getTime() + exp*24*60*60*1000);
 			exp = props.expires = d;
@@ -76,7 +74,7 @@ dojo.cookie = function(/*String*/name, /*String?*/value, /*dojo.__cookieProps?*/
 dojo.cookie.isSupported = function(){
 	//	summary:
 	//		Use to determine if the current browser supports cookies or not.
-	//		
+	//
 	//		Returns true if user allows cookies.
 	//		Returns false if user doesn't allow cookies.
 
@@ -89,3 +87,6 @@ dojo.cookie.isSupported = function(){
 	}
 	return navigator.cookieEnabled;
 };
+
+return dojo.cookie;
+});
diff --git a/dojo/currency.js b/dojo/currency.js
index 79a0ecf..eefbeab 100644
--- a/dojo/currency.js
+++ b/dojo/currency.js
@@ -1,9 +1,5 @@
-dojo.provide("dojo.currency");
-
-dojo.require("dojo.number");
-dojo.require("dojo.i18n");
-dojo.requireLocalization("dojo.cldr", "currency");
-dojo.require("dojo.cldr.monetary");
+define("dojo/currency", ["dojo", "dojo/number", "dojo/i18n", "i18n!dojo/cldr/nls/currency", "dojo/cldr/monetary"], function(dojo) {
+dojo.getObject("currency", true, dojo);
 
 /*=====
 dojo.currency = {
@@ -38,7 +34,7 @@ dojo.currency._mixInDefaults = function(options){
 
 	// Mixin with provided options
 	return dojo.mixin(data, options);
-}
+};
 
 /*=====
 dojo.declare("dojo.currency.__FormatOptions", [dojo.number.__FormatOptions], {
@@ -73,7 +69,7 @@ dojo.currency.format = function(/*Number*/value, /*dojo.currency.__FormatOptions
 //		the number to be formatted.
 
 	return dojo.number.format(value, dojo.currency._mixInDefaults(options));
-}
+};
 
 dojo.currency.regexp = function(/*dojo.number.__RegexpOptions?*/options){
 //
@@ -84,7 +80,7 @@ dojo.currency.regexp = function(/*dojo.number.__RegexpOptions?*/options){
 //		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
-}
+};
 
 /*=====
 dojo.declare("dojo.currency.__ParseOptions", [dojo.number.__ParseOptions], {
@@ -125,4 +121,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 dojo.currency;
+});
diff --git a/dojo/data/ItemFileReadStore.js b/dojo/data/ItemFileReadStore.js
index 4dc1dde..3454a35 100644
--- a/dojo/data/ItemFileReadStore.js
+++ b/dojo/data/ItemFileReadStore.js
@@ -1,8 +1,4 @@
-dojo.provide("dojo.data.ItemFileReadStore");
-
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.date.stamp");
+define("dojo/data/ItemFileReadStore", ["dojo", "dojo/data/util/filter", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo) {
 
 dojo.declare("dojo.data.ItemFileReadStore", null,{
 	//	summary:
@@ -13,7 +9,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	//			{ name:'Fozzie Bear', wears:['hat', 'tie']},
 	//			{ name:'Miss Piggy', pets:'Foo-Foo'}
 	//		]}
-	//		Note that it can also contain an 'identifer' property that specified which attribute on the items 
+	//		Note that it can also contain an 'identifer' property that specified which attribute on the items
 	//		in the array of items that acts as the unique identifier for that item.
 	//
 	constructor: function(/* Object */ keywordParameters){
@@ -28,7 +24,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//			...
 		//			typeN: function || object
 		//		}
-		//		Where if it is a function, it is assumed to be an object constructor that takes the 
+		//		Where if it is a function, it is assumed to be an object constructor that takes the
 		//		value of _value as the initialization parameters.  If it is an object, then it is assumed
 		//		to be an object of general form:
 		//		{
@@ -94,7 +90,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	//all item handles will become invalid and a new fetch must be issued.
 	clearOnClose: false,
 
-	//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.  
+	//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
 	//Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option.
 	//Added for tracker: #6072
 	urlPreventCache: false,
@@ -102,19 +98,19 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	//Parameter for specifying that it is OK for the xhrGet call to fail silently.
 	failOk: false,
 
-	//Parameter to indicate to process data from the url as hierarchical 
-	//(data items can contain other data items in js form).  Default is true 
-	//for backwards compatibility.  False means only root items are processed 
-	//as items, all child objects outside of type-mapped objects and those in 
+	//Parameter to indicate to process data from the url as hierarchical
+	//(data items can contain other data items in js form).  Default is true
+	//for backwards compatibility.  False means only root items are processed
+	//as items, all child objects outside of type-mapped objects and those in
 	//specific reference format, are left straight JS data objects.
 	hierarchical: true,
 
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojo.data.ItemFileReadStore: Invalid item argument.");
 		}
 	},
@@ -122,25 +118,25 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		//	summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojo.data.ItemFileReadStore: Invalid attribute argument.");
 		}
 	},
 
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		return (values.length > 0)?values[0]:defaultValue; // mixed
 	},
 
-	getValues: function(/* item */ item, 
+	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 
 		this._assertIsItem(item);
@@ -150,7 +146,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -165,17 +161,17 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		return (attribute in item);
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -184,22 +180,22 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -216,7 +212,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		if(something && something[this._storeRefPropName] === this){
 			if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){
@@ -227,25 +223,25 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return this._features; //Object
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this._labelAttr && this.isItem(item)){
 			return this.getValue(item,this._labelAttr); //String
@@ -254,7 +250,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		if(this._labelAttr){
 			return [this._labelAttr]; //array
@@ -262,10 +258,10 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		return null; //null
 	},
 
-	_fetchItems: function(	/* Object */ keywordArgs, 
-							/* Function */ findCallback, 
+	_fetchItems: function(	/* Object */ keywordArgs,
+							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		var self = this,
 		    filter = function(requestArgs, arrayOfItems){
@@ -305,8 +301,8 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				}
 				findCallback(items, requestArgs);
 			}else{
-				// We want a copy to pass back in case the parent wishes to sort the array. 
-				// We shouldn't allow resort of the internal list, so that multiple callers 
+				// We want a copy to pass back in case the parent wishes to sort the array.
+				// We shouldn't allow resort of the internal list, so that multiple callers
 				// can get lists and sort without affecting each other.  We also need to
 				// filter out any null values that have been left as a result of deleteItem()
 				// calls in ItemFileWriteStore.
@@ -326,11 +322,11 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			//Do a check on the JsonFileUrl and crosscheck it.
 			//If it doesn't match the cross-check, it needs to be updated
 			//This allows for either url or _jsonFileUrl to he changed to
-			//reset the store load location.  Done this way for backwards 
+			//reset the store load location.  Done this way for backwards
 			//compatibility.  People use _jsonFileUrl (even though officially
 			//private.
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojo.data.ItemFileReadStore: ", 
+				dojo.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;
@@ -341,21 +337,21 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			}
 
 			//See if there was any forced reset of data.
-			if(this.data != null && this._jsonData == null){
+			if(this.data != null){
 				this._jsonData = this.data;
 				this.data = null;
 			}
 
 			if(this._jsonFileUrl){
 				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be 
+				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
 					this._queuedFetches.push({args: keywordArgs, filter: filter});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self._jsonFileUrl, 
+							url: self._jsonFileUrl,
 							handleAs: "json-comment-optional",
 							preventCache: this.urlPreventCache,
 							failOk: this.failOk
@@ -415,7 +411,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	_handleQueuedFetches: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function to execute delayed request in the store.
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
@@ -424,7 +420,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				    delayedQuery = fData.args,
 				    delayedFilter = fData.filter;
 				if(delayedFilter){
-					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions)); 
+					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
 				}else{
 					this.fetchItemByIdentity(delayedQuery);
 				}
@@ -434,31 +430,31 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	_getItemsArray: function(/*object?*/queryOptions){
-		//	summary: 
+		//	summary:
 		//		Internal function to determine which list of items to search over.
 		//	queryOptions: The query options parameter, if any.
 		if(queryOptions && queryOptions.deep){
-			return this._arrayOfAllItems; 
+			return this._arrayOfAllItems;
 		}
 		return this._arrayOfTopLevelItems;
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Read.close()
-		 if(this.clearOnClose && 
-			this._loadFinished && 
+		 if(this.clearOnClose &&
+			this._loadFinished &&
 			!this._loadInProgress){
 			 //Reset all internalsback to default state.  This will force a reload
-			 //on next fetch.  This also checks that the data or url param was set 
+			 //on next fetch.  This also checks that the data or url param was set
 			 //so that the store knows it can get data.  Without one of those being set,
 			 //the next fetch will trigger an error.
 
-			 if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) && 
+			 if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
 				 (this.url == "" || this.url == null)
 				) && this.data == null){
 				 console.debug("dojo.data.ItemFileReadStore: WARNING!  Data reload " +
-					" information has not been provided." + 
+					" information has not been provided." +
 					"  Please set 'url' or 'data' to the appropriate value before" +
 					" the next fetch");
 			 }
@@ -496,7 +492,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			// 	|	false == valueIsAnItem("Kermit");
 			// 	|	false == valueIsAnItem(42);
 			// 	|	false == valueIsAnItem(new Date());
-			// 	|	false == valueIsAnItem({_type:'Date', _value:'May 14, 1802'});
+			// 	|	false == valueIsAnItem({_type:'Date', _value:'1802-05-14'});
 			// 	|	false == valueIsAnItem({_reference:'Kermit'});
 			// 	|	true == valueIsAnItem({name:'Kermit', color:'green'});
 			// 	|	true == valueIsAnItem({iggy:'pop'});
@@ -507,8 +503,8 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				(!dojo.isArray(aValue) || addingArrays) &&
 				(!dojo.isFunction(aValue)) &&
 				(aValue.constructor == Object || dojo.isArray(aValue)) &&
-				(typeof aValue._reference === "undefined") && 
-				(typeof aValue._type === "undefined") && 
+				(typeof aValue._reference === "undefined") &&
+				(typeof aValue._type === "undefined") &&
 				(typeof aValue._value === "undefined") &&
 				self.hierarchical
 			);
@@ -558,13 +554,13 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			item[this._rootItemPropName]=true;
 		}
 
-		// Step 2: Walk through all the attribute values of all the items, 
+		// Step 2: Walk through all the attribute values of all the items,
 		// and replace single values with arrays.  For example, we change this:
 		//		{ name:'Miss Piggy', pets:'Foo-Foo'}
 		// into this:
 		//		{ name:['Miss Piggy'], pets:['Foo-Foo']}
-		// 
-		// We also store the attribute names so we can validate our store  
+		//
+		// We also store the attribute names so we can validate our store
 		// reference and item id special properties for the O(1) isItem
 		var allAttributeNames = {},
 		    key;
@@ -598,9 +594,9 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			this._reverseRefMap += "_";
 		}
 
-		// Step 4: Some data files specify an optional 'identifier', which is 
-		// the name of an attribute that holds the identity of each item. 
-		// If this data file specified an identifier attribute, then build a 
+		// Step 4: Some data files specify an optional 'identifier', which is
+		// the name of an attribute that holds the identity of each item.
+		// If this data file specified an identifier attribute, then build a
 		// hash table of items keyed by the identity of the items.
 		var arrayOfValues;
 
@@ -612,7 +608,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				item = this._arrayOfAllItems[i];
 				arrayOfValues = item[identifier];
 				var identity = arrayOfValues[0];
-				if(!this._itemsByIdentity[identity]){
+				if(!Object.hasOwnProperty.call(this._itemsByIdentity, identity)){
 					this._itemsByIdentity[identity] = item;
 				}else{
 					if(this._jsonFileUrl){
@@ -626,7 +622,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			this._features['dojo.data.api.Identity'] = Number;
 		}
 
-		// Step 5: Walk through all the items, and set each item's properties 
+		// Step 5: Walk through all the items, and set each item's properties
 		// for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true.
 		for(i = 0; i < this._arrayOfAllItems.length; ++i){
 			item = this._arrayOfAllItems[i];
@@ -640,13 +636,13 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		// We replace item-references with pointers to items.  For example, we change:
 		//		{ name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
 		// into this:
-		//		{ name:['Kermit'], friends:[miss_piggy] } 
+		//		{ name:['Kermit'], friends:[miss_piggy] }
 		// (where miss_piggy is the object representing the 'Miss Piggy' item).
 		//
 		// We replace type/value pairs with typed-literals.  For example, we change:
-		//		{ name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] }
+		//		{ name:['Nelson Mandela'], born:[{_type:'Date', _value:'1918-07-18'}] }
 		// into this:
-		//		{ name:['Kermit'], born:(new Date('July 18, 1918')) } 
+		//		{ name:['Kermit'], born:(new Date(1918, 6, 18)) }
 		//
 		// We also generate the associate map for all items for the O(1) isItem function.
 		for(i = 0; i < this._arrayOfAllItems.length; ++i){
@@ -659,7 +655,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 						if(("_type" in value) && ("_value" in value)){
 							var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber'
 							var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}}
-							if(!mappingObj){ 
+							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)){
 								arrayOfValues[j] = new mappingObj(value._value);
@@ -682,12 +678,12 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 									var candidateItem = this._arrayOfAllItems[k],
 									    found = true;
 									for(var refKey in referenceDescription){
-										if(candidateItem[refKey] != referenceDescription[refKey]){ 
-											found = false; 
+										if(candidateItem[refKey] != referenceDescription[refKey]){
+											found = false;
 										}
 									}
-									if(found){ 
-										arrayOfValues[j] = candidateItem; 
+									if(found){
+										arrayOfValues[j] = candidateItem;
 									}
 								}
 							}
@@ -698,7 +694,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 								}
 							}
 						}else if(this.isItem(value)){
-							//It's a child item (not one referenced through _reference).  
+							//It's a child item (not one referenced through _reference).
 							//We need to treat this as a referenced item, so it can be cleaned up
 							//in a write store easily.
 							if(this.referenceIntegrity){
@@ -727,7 +723,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		var identifier = this._features['dojo.data.api.Identity'];
 		if(identifier === Number){
@@ -742,7 +738,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 
 		// Hasn't loaded yet, we have to trigger the load.
@@ -753,11 +749,11 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			//Do a check on the JsonFileUrl and crosscheck it.
 			//If it doesn't match the cross-check, it needs to be updated
 			//This allows for either url or _jsonFileUrl to he changed to
-			//reset the store load location.  Done this way for backwards 
+			//reset the store load location.  Done this way for backwards
 			//compatibility.  People use _jsonFileUrl (even though officially
 			//private.
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojo.data.ItemFileReadStore: ", 
+				dojo.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;
@@ -780,7 +776,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self._jsonFileUrl, 
+							url: self._jsonFileUrl,
 							handleAs: "json-comment-optional",
 							preventCache: this.urlPreventCache,
 							failOk: this.failOk
@@ -823,7 +819,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 					scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
 					keywordArgs.onItem.call(scope, item);
 				}
-			} 
+			}
 		}else{
 			// Already loaded.  We can just look it up and call back.
 			item = this._getItemByIdentity(keywordArgs.identity);
@@ -838,9 +834,10 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		//	summary:
 		//		Internal function to look an item up by its identity map.
 		var item = null;
-		if(this._itemsByIdentity){
+		if(this._itemsByIdentity &&
+		   Object.hasOwnProperty.call(this._itemsByIdentity, identity)){
 			item = this._itemsByIdentity[identity];
-		}else{
+		}else if (Object.hasOwnProperty.call(this._arrayOfAllItems, identity)){
 			item = this._arrayOfAllItems[identity];
 		}
 		if(item === undefined){
@@ -850,15 +847,15 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		//	summary: 
-		//		See dojo.data.api.Identity.getIdentifierAttributes()
+		//	summary:
+		//		See dojo.data.api.Identity.getIdentityAttributes()
 		 
 		var identifier = this._features['dojo.data.api.Identity'];
 		if(identifier === Number){
 			// If (identifier === Number) it means getIdentity() just returns
 			// an integer item-number for each item.  The dojo.data.api.Identity
-			// spec says we need to return null if the identity is not composed 
-			// of attributes 
+			// spec says we need to return null if the identity is not composed
+			// of attributes
 			return null; // null
 		}else{
 			return [identifier]; // Array
@@ -866,18 +863,18 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 	},
 	
 	_forceLoad: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function to force a load of the store if it hasn't occurred yet.  This is required
-		//		for specific functions to work properly.  
+		//		for specific functions to work properly.
 		var self = this;
 		//Do a check on the JsonFileUrl and crosscheck it.
 		//If it doesn't match the cross-check, it needs to be updated
 		//This allows for either url or _jsonFileUrl to he changed to
-		//reset the store load location.  Done this way for backwards 
+		//reset the store load location.  Done this way for backwards
 		//compatibility.  People use _jsonFileUrl (even though officially
 		//private.
 		if(this._jsonFileUrl !== this._ccUrl){
-			dojo.deprecated("dojo.data.ItemFileReadStore: ", 
+			dojo.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;
@@ -888,14 +885,14 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 		}
 
 		//See if there was any forced reset of data.
-		if(this.data != null && this._jsonData == null){
+		if(this.data != null){
 			this._jsonData = this.data;
 			this.data = null;
 		}
 
 		if(this._jsonFileUrl){
 				var getArgs = {
-					url: this._jsonFileUrl, 
+					url: this._jsonFileUrl,
 					handleAs: "json-comment-optional",
 					preventCache: this.urlPreventCache,
 					failOk: this.failOk,
@@ -904,7 +901,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			var getHandler = dojo.xhrGet(getArgs);
 			getHandler.addCallback(function(data){
 				try{
-					//Check to be sure there wasn't another load going on concurrently 
+					//Check to be sure there wasn't another load going on concurrently
 					//So we don't clobber data that comes in on it.  If there is a load going on
 					//then do not save this data.  It will potentially clobber current data.
 					//We mainly wanted to sync/wait here.
@@ -917,7 +914,7 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 						//Okay, we hit an error state we can't recover from.  A forced load occurred
 						//while an async load was occurring.  Since we cannot block at this point, the best
 						//that can be managed is to throw an error.
-						throw new Error("dojo.data.ItemFileReadStore:  Unable to perform a synchronous load, an async load is in progress."); 
+						throw new Error("dojo.data.ItemFileReadStore:  Unable to perform a synchronous load, an async load is in progress.");
 					}
 				}catch(e){
 					console.log(e);
@@ -931,8 +928,11 @@ dojo.declare("dojo.data.ItemFileReadStore", null,{
 			self._getItemsFromLoadedData(self._jsonData);
 			self._jsonData = null;
 			self._loadFinished = true;
-		} 
+		}
 	}
 });
 //Mix in the simple fetch implementation to this class.
 dojo.extend(dojo.data.ItemFileReadStore,dojo.data.util.simpleFetch);
+
+return dojo.data.ItemFileReadStore;
+});
diff --git a/dojo/data/ItemFileWriteStore.js b/dojo/data/ItemFileWriteStore.js
index c8a1ed0..12ac71b 100644
--- a/dojo/data/ItemFileWriteStore.js
+++ b/dojo/data/ItemFileWriteStore.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo.data.ItemFileWriteStore");
-dojo.require("dojo.data.ItemFileReadStore");
+define("dojo/data/ItemFileWriteStore", ["dojo", "dojo/data/ItemFileReadStore"], function(dojo) {
 
 dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 	constructor: function(/* object */ keywordParameters){
@@ -11,7 +10,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		//			...
 		//			typeN: function || object
 		//		}
-		//		Where if it is a function, it is assumed to be an object constructor that takes the 
+		//		Where if it is a function, it is assumed to be an object constructor that takes the
 		//		value of _value as the initialization parameters.  It is serialized assuming object.toString()
 		//		serialization.  If it is an object, then it is assumed
 		//		to be an object of general form:
@@ -27,8 +26,8 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		
 		// For keeping track of changes so that we can implement isDirty and revert
 		this._pending = {
-			_newItems:{}, 
-			_modifiedItems:{}, 
+			_newItems:{},
+			_modifiedItems:{},
 			_deletedItems:{}
 		};
 
@@ -91,8 +90,8 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 			}
 		}
 		
-		// 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, 
+		// make sure this identity is not already in use by another item, if identifiers were
+		// defined in the file.  Otherwise it would be the item count,
 		// which should always be unique in this case.
 		if(this._itemsByIdentity){
 			this._assert(typeof this._itemsByIdentity[newIdentity] === "undefined");
@@ -101,7 +100,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		this._assert(typeof this._pending._deletedItems[newIdentity] === "undefined");
 		
 		var newItem = {};
-		newItem[this._storeRefPropName] = this;		
+		newItem[this._storeRefPropName] = this;
 		newItem[this._itemNumPropName] = this._arrayOfAllItems.length;
 		if(this._itemsByIdentity){
 			this._itemsByIdentity[newIdentity] = newItem;
@@ -154,14 +153,14 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				// Bummer, the user is trying to do something like
 				// newItem({_S:"foo"}).  Unfortunately, our superclass,
 				// ItemFileReadStore, is already using _S in each of our items
-				// to hold private info.  To avoid a naming collision, we 
-				// need to move all our private info to some other property 
+				// to hold private info.  To avoid a naming collision, we
+				// need to move all our private info to some other property
 				// of all the items/objects.  So, we need to iterate over all
-				// the items and do something like: 
+				// the items and do something like:
 				//    item.__S = item._S;
 				//    item._S = undefined;
-				// But first we have to make sure the new "__S" variable is 
-				// not in use, which means we have to iterate over all the 
+				// But first we have to make sure the new "__S" variable is
+				// not in use, which means we have to iterate over all the
 				// items checking for that.
 				throw new Error("encountered bug in ItemFileWriteStore.newItem");
 			}
@@ -198,17 +197,17 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		this._assertIsItem(item);
 
 		// Remove this item from the _arrayOfAllItems, but leave a null value in place
-		// of the item, so as not to change the length of the array, so that in newItem() 
+		// of the item, so as not to change the length of the array, so that in newItem()
 		// we can still safely do: newIdentity = this._arrayOfAllItems.length;
 		var indexInArrayOfAllItems = item[this._itemNumPropName];
 		var identity = this.getIdentity(item);
 
 		//If we have reference integrity on, we need to do reference cleanup for the deleted item
 		if(this.referenceIntegrity){
-			//First scan all the attributes of this items for references and clean them up in the map 
+			//First scan all the attributes of this items for references and clean them up in the map
 			//As this item is going away, no need to track its references anymore.
 
-			//Get the attributes list before we generate the backup so it 
+			//Get the attributes list before we generate the backup so it
 			//doesn't pollute the attributes list.
 			var attributes = this.getAttributes(item);
 
@@ -254,7 +253,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 								return !(this.isItem(possibleItem) && this.getIdentity(possibleItem) == identity);
 							}, this);
 							//Remove the note of the reference to the item and set the values on the modified attribute.
-							this._removeReferenceFromMap(item, containingItem, attribute); 
+							this._removeReferenceFromMap(item, containingItem, attribute);
 							if(newValues.length < oldValues.length){
 								this._setValueOrValues(containingItem, attribute, newValues, true);
 							}
@@ -316,11 +315,11 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 		var identity = this.getIdentity(item);
 		if(!this._pending._modifiedItems[identity]){
-			// Before we actually change the item, we make a copy of it to 
-			// record the original state, so that we'll be able to revert if 
+			// Before we actually change the item, we make a copy of it to
+			// record the original state, so that we'll be able to revert if
 			// the revert method gets called.  If the item has already been
 			// modified then there's no need to do this now, since we already
-			// have a record of the original state.						
+			// have a record of the original state.
 			var copyOfItemState = {};
 			for(var key in item){
 				if((key === this._storeRefPropName) || (key === this._itemNumPropName) || (key === this._rootItemPropName)){
@@ -341,7 +340,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		if(dojo.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 
+			// as "unsetting" the attribute, so we need to remove this
 			// attribute from the item.
 			success = delete item[attribute];
 			newValueOrValues = undefined; // used in the onSet Notification call below
@@ -365,7 +364,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				// Unfortunately, it's not safe to just do this:
 				//    newValueArray = newValues;
 				// Instead, we need to copy the array, which slice() does very nicely.
-				// This is so that our internal data structure won't  
+				// This is so that our internal data structure won't
 				// get corrupted if the user mucks with the values array *after*
 				// calling setValues().
 				newValueArray = newValueOrValues.slice(0, newValueOrValues.length);
@@ -373,7 +372,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				newValueArray = [newValueOrValues];
 			}
 
-			//We need to handle reference integrity if this is on. 
+			//We need to handle reference integrity if this is on.
 			//In the case of set, we need to see if references were added or removed
 			//and update the reference tracking map accordingly.
 			if(this.referenceIntegrity){
@@ -400,7 +399,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 							if(map[id.toString()]){
 								delete map[id.toString()];
 							}else{
-								this._addReferenceToMap(possibleItem, item, attribute); 
+								this._addReferenceToMap(possibleItem, item, attribute);
 							}
 						}
 					}, this);
@@ -430,7 +429,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 		// Now we make the dojo.data.api.Notification call
 		if(callOnSet){
-			this.onSet(item, attribute, oldValueOrValues, newValueOrValues); 
+			this.onSet(item, attribute, oldValueOrValues, newValueOrValues);
 		}
 		return success; // boolean
 	},
@@ -465,7 +464,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		//		Method to remove an reference map entry for an item and attribute.
 		//	description:
 		//		Method to remove an reference map entry for an item and attribute.  This will
-		//		also perform cleanup on the map such that if there are no more references at all to 
+		//		also perform cleanup on the map such that if there are no more references at all to
 		//		the item, its reference object and entry are removed.
 		//
 		//	refItem:
@@ -522,7 +521,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 	_flatten: function(/* anything */ value){
 		if(this.isItem(value)){
 			var item = value;
-			// Given an item, return an serializable object that provides a 
+			// 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"});
@@ -553,7 +552,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 	},
 	
 	_getNewFileContentString: function(){
-		// summary: 
+		// 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
@@ -594,7 +593,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 	},
 
 	_isEmpty: function(something){
-		//	summary: 
+		//	summary:
 		//		Function to determine if an array or object has no properties or values.
 		//	something:
 		//		The array or object to examine.
@@ -623,7 +622,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		var self = this;
 		var saveCompleteCallback = function(){
 			self._pending = {
-				_newItems:{}, 
+				_newItems:{},
 				_modifiedItems:{},
 				_deletedItems:{}
 			};
@@ -672,7 +671,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 				modifiedItem = this._arrayOfAllItems[identity];
 			}
 	
-			// Restore the original item into a full-fledged item again, we want to try to 
+			// 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){
@@ -713,7 +712,7 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 					}
 					this._addReferenceToMap(refItem, deletedItem, reference.attr);
 				}, this);
-				delete deletedItem["backupRefs_" + this._reverseRefMap]; 
+				delete deletedItem["backupRefs_" + this._reverseRefMap];
 			}
 		}
 
@@ -732,8 +731,8 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		}
 
 		this._pending = {
-			_newItems:{}, 
-			_modifiedItems:{}, 
+			_newItems:{},
+			_modifiedItems:{},
 			_deletedItems:{}
 		};
 		return true; // boolean
@@ -744,13 +743,13 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		if(item){
 			// return true if the item is dirty
 			var identity = this.getIdentity(item);
-			return new Boolean(this._pending._newItems[identity] || 
+			return new Boolean(this._pending._newItems[identity] ||
 				this._pending._modifiedItems[identity] ||
 				this._pending._deletedItems[identity]).valueOf(); // boolean
 		}else{
 			// return true if the store is dirty -- which means return true
 			// if there are any new items, dirty items, or modified items
-			if(!this._isEmpty(this._pending._newItems) || 
+			if(!this._isEmpty(this._pending._newItems) ||
 				!this._isEmpty(this._pending._modifiedItems) ||
 				!this._isEmpty(this._pending._deletedItems)){
 				return true;
@@ -761,28 +760,28 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 
 /* dojo.data.api.Notification */
 
-	onSet: function(/* item */ item, 
-					/*attribute-name-string*/ attribute, 
+	onSet: function(/* item */ item,
+					/*attribute-name-string*/ attribute,
 					/*object | array*/ oldValue,
 					/*object | array*/ newValue){
 		// summary: See dojo.data.api.Notification.onSet()
 		
-		// No need to do anything. This method is here just so that the 
+		// 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. 
+		// 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. 
+		// No need to do anything. This method is here just so that the
+		// client code can connect observers to it.
 	},
 
 	close: function(/* object? */ request){
@@ -804,3 +803,6 @@ dojo.declare("dojo.data.ItemFileWriteStore", dojo.data.ItemFileReadStore, {
 		 }
 	}
 });
+
+return dojo.data.ItemFileWriteStore;
+});
diff --git a/dojo/data/ObjectStore.js b/dojo/data/ObjectStore.js
new file mode 100644
index 0000000..f675769
--- /dev/null
+++ b/dojo/data/ObjectStore.js
@@ -0,0 +1,477 @@
+define("dojo/data/ObjectStore", ["dojo", "dojo/regexp"], function(dojo) {
+
+
+dojo.declare("dojo.data.ObjectStore", null,{
+		objectStore: null,
+		constructor: function(options){
+			// summary:
+			//		A Dojo Data implementation that wraps Dojo object stores for backwards
+			//		compatibility.
+			//	options:
+			//		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);
+		},
+		labelProperty: "label",
+
+		getValue: function(/*Object*/ item, /*String*/property, /*value?*/defaultValue){
+			// summary:
+			//	Gets the value of an item's 'property'
+			//
+			//	item:
+			//		The item to get the value from
+			//	property:
+			//		property to look up value for
+			//	defaultValue:
+			//		the default value
+			
+			return typeof item.get === "function" ? item.get(property) :
+				property in item ?
+					item[property] : defaultValue;
+		},
+		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,
+			//		if not, the value is added to an array and that is returned.
+			//
+			//	item: /* object */
+			//	property: /* string */
+			//		property to look up value for
+
+			var val = this.getValue(item,property);
+			return val instanceof Array ? val : val === undefined ? [] : [val];
+		},
+
+		getAttributes: function(item){
+			// summary:
+			//	Gets the available attributes of an item's 'property' and returns
+			//	it as an array.
+			//
+			//	item: /* object */
+
+			var res = [];
+			for(var i in item){
+				if(item.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_')){
+					res.push(i);
+				}
+			}
+			return res;
+		},
+
+		hasAttribute: function(item,attribute){
+			// summary:
+			//		Checks to see if item has attribute
+			//
+			//	item: /* object */
+			//	attribute: /* string */
+			return attribute in item;
+		},
+
+		containsValue: function(item, attribute, value){
+			// summary:
+			//		Checks to see if 'item' has 'value' at 'attribute'
+			//
+			//	item: /* object */
+			//	attribute: /* string */
+			//	value: /* anything */
+			return dojo.indexOf(this.getValues(item,attribute),value) > -1;
+		},
+
+
+		isItem: function(item){
+			// summary:
+			//		Checks to see if the argument is an item
+			//
+			//	item: /* object */
+			//	attribute: /* string */
+
+			// we have no way of determining if it belongs, we just have object returned from
+			// 	service queries
+			return (typeof item == 'object') && item && !(item instanceof Date);
+		},
+
+		isItemLoaded: function(item){
+			// summary:
+			//		Checks to see if the item is loaded.
+			//
+			//		item: /* object */
+
+			return item && typeof item.load !== "function";
+		},
+
+		loadItem: function(args){
+			// summary:
+			// 		Loads an item and calls the callback handler. Note, that this will call the callback
+			// 		handler even if the item is loaded. Consequently, you can use loadItem to ensure
+			// 		that an item is loaded is situations when the item may or may not be loaded yet.
+			// 		If you access a value directly through property access, you can use this to load
+			// 		a lazy value as well (doesn't need to be an item).
+			//
+			//	example:
+			//		store.loadItem({
+			//			item: item, // this item may or may not be loaded
+			//			onItem: function(item){
+			// 				// do something with the item
+			//			}
+			//		});
+
+			var item;
+			if(typeof args.item.load === "function"){
+				dojo.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){
+						func.call(args.scope, result);
+					}
+				});
+			}else if(args.onItem){
+				// even if it is already loaded, we will use call the callback, this makes it easier to
+				// use when it is not known if the item is loaded (you can always safely call loadItem).
+				args.onItem.call(args.scope, args.item);
+			}
+			return item;
+		},
+		close: function(request){
+			return request && request.abort && request.abort();
+		},
+		fetch: function(args){
+			// summary:
+			//		See dojo.data.api.Read.fetch
+			//
+			
+			args = args || {};
+			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
+				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].toString = (function(original){
+							return function(){
+								return original;
+							}
+						})(required);
+					}
+				}
+			}
+			
+			var results = this.objectStore.query(query, args);
+			dojo.when(results.total, function(totalCount){
+				dojo.when(results, function(results){
+					if(args.onBegin){
+						args.onBegin.call(scope, totalCount || results.length, args);
+					}
+					if(args.onItem){
+						for(var i=0; i<results.length;i++){
+							args.onItem.call(scope, results[i], args);
+						}
+					}
+					if(args.onComplete){
+						args.onComplete.call(scope, args.onItem ? null : results, args);
+					}
+					return results;
+				}, errorHandler);
+			}, errorHandler);
+			function errorHandler(error){
+				if(args.onError){
+					args.onError.call(scope, error, args);
+				}
+			}
+			args.abort = function(){
+				// abort the request
+				if(results.cancel){
+					results.cancel();
+				}
+			};
+			args.store = this;
+			return args;
+		},
+		getFeatures: function(){
+			// summary:
+			// 		return the store feature set
+
+			return {
+				"dojo.data.api.Read": !!this.objectStore.get,
+				"dojo.data.api.Identity": true,
+				"dojo.data.api.Write": !!this.objectStore.put,
+				"dojo.data.api.Notification": true
+			};
+		},
+
+		getLabel: function(/* item */ item){
+			//	summary:
+			//		See dojo.data.api.Read.getLabel()
+			if(this.isItem(item)){
+				return this.getValue(item,this.labelProperty); //String
+			}
+			return undefined; //undefined
+		},
+
+		getLabelAttributes: function(/* item */ item){
+			//	summary:
+			//		See dojo.data.api.Read.getLabelAttributes()
+			return [this.labelProperty]; //array
+		},
+
+		//Identity API Support
+
+
+		getIdentity: function(item){
+			return item.getId ? item.getId() : item[this.objectStore.idProperty || "id"];
+		},
+
+		getIdentityAttributes: function(item){
+			// summary:
+			//		returns the attributes which are used to make up the
+			//		identity of an item.	Basically returns this.objectStore.idProperty
+
+			return [this.objectStore.idProperty];
+		},
+
+		fetchItemByIdentity: function(args){
+			// 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),
+				function(result){
+					item = result;
+					args.onItem.call(args.scope, result);
+				},
+				function(error){
+					args.onError.call(args.scope, error);
+				}
+			);
+			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 */
+			//		The data to be added in as an item.
+			if(parentInfo){
+				// get the previous value or any empty array
+				var values = this.getValue(parentInfo.parent,parentInfo.attribute,[]);
+				// set the new value
+				values = values.concat([data]);
+				data.__parent = values;
+				this.setValue(parentInfo.parent, parentInfo.attribute, values);
+			}
+			this._dirtyObjects.push({object:data, save: true});
+			this.onNew(data);
+			return data;
+		},
+		deleteItem: function(item){
+			// summary:
+			//		deletes item and any references to that item from the store.
+			//
+			//	item:
+			//		item to delete
+			//
+
+			//	If the desire is to delete only one reference, unsetAttribute or
+			//	setValue is the way to go.
+			this.changing(item, true);
+
+			this.onDelete(item);
+		},
+		setValue: function(item, attribute, value){
+			// summary:
+			//		sets 'attribute' on 'item' to 'value'
+
+			var old = item[attribute];
+			this.changing(item);
+			item[attribute]=value;
+			this.onSet(item,attribute,old,value);
+		},
+		setValues: function(item, attribute, values){
+			// summary:
+			//	sets 'attribute' on 'item' to 'value' value
+			//	must be an array.
+
+
+			if(!dojo.isArray(values)){
+				throw new Error("setValues expects to be passed an Array object as its value");
+			}
+			this.setValue(item,attribute,values);
+		},
+
+		unsetAttribute: function(item, attribute){
+			// summary:
+			//		unsets 'attribute' on 'item'
+
+			this.changing(item);
+			var old = item[attribute];
+			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
+			//		contains a reference to the object itself as well as a
+			//		cloned and trimmed version of old object for use with
+			//		revert.
+			object.__isDirty = true;
+			//if an object is already in the list of dirty objects, don't add it again
+			//or it will overwrite the premodification data set.
+			for(var i=0; i<this._dirtyObjects.length; i++){
+				var dirty = this._dirtyObjects[i];
+				if(object==dirty.object){
+					if(_deleting){
+						// we are deleting, no object is an indicator of deletiong
+						dirty.object = false;
+						if(!this._saveNotNeeded){
+							dirty.save = true;
+						}
+					}
+					return;
+				}
+			}
+			var old = object instanceof Array ? [] : {};
+			for(i in object){
+				if(object.hasOwnProperty(i)){
+					old[i] = object[i];
+				}
+			}
+			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.
+			//
+			//	kwArgs.revertOnError
+			//		This will cause the changes to be reverted if there is an
+			//		error on the save. By default a revert is executed unless
+			//		a value of false is provide for this parameter.
+
+			kwArgs = kwArgs || {};
+			var result, actions = [];
+			var alreadyRecorded = {};
+			var savingObjects = [];
+			var self;
+			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(){
+					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._dirtyObjects = postCommitDirtyObjects;
+					}
+					else{
+						self._dirtyObjects = dirtyObject.concat(savingObjects);
+					}
+				});
+				if(this.objectStore.transaction){
+					var transaction = this.objectStore.transaction();
+				}
+				for(var i = 0; i < dirtyObjects.length; i++){
+					var dirty = dirtyObjects[i];
+					var object = dirty.object;
+					var old = dirty.old;
+					delete object.__isDirty;
+					if(object){
+						result = this.objectStore.put(object, {overwrite: !!old});
+					}
+					else{
+						result = this.objectStore.remove(this.getIdentity(old));
+					}
+					savingObjects.push(dirty);
+					dirtyObjects.splice(i--,1);
+					dojo.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();
+				}
+			}catch(e){
+				kwArgs.onError.call(kwArgs.scope, value);
+			}
+			
+			
+		},
+
+		revert: function(kwArgs){
+			// summary
+			//		returns any modified data to its original state prior to a save();
+			//
+			var dirtyObjects = this._dirtyObjects;
+			for(var i = dirtyObjects.length; i > 0;){
+				i--;
+				var dirty = dirtyObjects[i];
+				var object = dirty.object;
+				var old = dirty.old;
+				if(object && old){
+					// changed
+					for(var j in old){
+						if(old.hasOwnProperty(j) && object[j] !== old[j]){
+							this.onSet(object, j, object[j], old[j]);
+							object[j] = old[j];
+						}
+					}
+					for(j in object){
+						if(!old.hasOwnProperty(j)){
+							this.onSet(object, j, object[j]);
+							delete object[j];
+						}
+					}
+				}else if(!old){
+					// was an addition, remove it
+					this.onDelete(object);
+				}else{
+					// was a deletion, we will add it back
+					this.onNew(old);
+				}
+				delete (object || old).__isDirty;
+				dirtyObjects.splice(i, 1);
+			}
+			
+			
+		},
+		isDirty: function(item){
+			// summary
+			//		returns true if the item is marked as dirty or true if there are any dirty items
+			if(!item){
+				return !!this._dirtyObjects.length;
+			}
+			return item.__isDirty;
+		},
+		//Notifcation Support
+
+		onSet: function(){},
+		onNew: function(){},
+		onDelete: 	function(){}
+	}
+);
+
+return dojo.data.ObjectStore;
+});
diff --git a/dojo/data/api/Identity.js b/dojo/data/api/Identity.js
index 2db1dd8..cae4c30 100644
--- a/dojo/data/api/Identity.js
+++ b/dojo/data/api/Identity.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo.data.api.Identity");
-dojo.require("dojo.data.api.Read");
+define("dojo/data/api/Identity", ["dojo", "dojo/data/api/Read"], function(dojo) {
 
 dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 	//	summary:
@@ -8,7 +7,7 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 	//		methods unimplemented.
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			 'dojo.data.api.Read': true,
@@ -36,16 +35,16 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 
 	getIdentityAttributes: function(/* item */ item){
 		//	summary:
-		//		Returns an array of attribute names that are used to generate the identity. 
+		//		Returns an array of attribute names that are used to generate the identity.
 		//		For most stores, this is a single attribute, but for some complex stores
 		//		such as RDB backed stores that use compound (multi-attribute) identifiers
 		//		it can be more than one.  If the identity is not composed of attributes
 		//		on the item, it will return null.  This function is intended to identify
 		//		the attributes that comprise the identity so that so that during a render
-		//		of all attributes, the UI can hide the the identity information if it 
+		//		of all attributes, the UI can hide the the identity information if it
 		//		chooses.
 		//	item:
-		//		The item from the store from which to obtain the array of public attributes that 
+		//		The item from the store from which to obtain the array of public attributes that
 		//		compose the identifier, if any.
 		//	example:
 		//	|	var itemId = store.getIdentity(kermit);
@@ -58,14 +57,14 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
 		//	summary:
-		//		Given the identity of an item, this method returns the item that has 
-		//		that identity through the onItem callback.  Conforming implementations 
-		//		should return null if there is no item with the given identity.  
-		//		Implementations of fetchItemByIdentity() may sometimes return an item 
-		//		from a local cache and may sometimes fetch an item from a remote server, 
+		//		Given the identity of an item, this method returns the item that has
+		//		that identity through the onItem callback.  Conforming implementations
+		//		should return null if there is no item with the given identity.
+		//		Implementations of fetchItemByIdentity() may sometimes return an item
+		//		from a local cache and may sometimes fetch an item from a remote server,
 		//
 		// 	keywordArgs:
-		//		An anonymous object that defines the item to locate and callbacks to invoke when the 
+		//		An anonymous object that defines the item to locate and callbacks to invoke when the
 		//		item has been located and load has completed.  The format of the object is as follows:
 		//		{
 		//			identity: string|object,
@@ -75,9 +74,9 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 		//		}
 		//	The *identity* parameter.
 		//		The identity parameter is the identity of the item you wish to locate and load
-		//		This attribute is required.  It should be a string or an object that toString() 
+		//		This attribute is required.  It should be a string or an object that toString()
 		//		can be called on.
-		//		
+		//
 		//	The *onItem* parameter.
 		//		Function(item)
 		//		The onItem parameter is the callback to invoke when the item has been loaded.  It takes only one
@@ -89,15 +88,18 @@ dojo.declare("dojo.data.api.Identity", dojo.data.api.Read, {
 		//		parameter, the error object
 		//
 		//	The *scope* parameter.
-		//		If a scope object is provided, all of the callback functions (onItem, 
+		//		If a scope object is provided, all of the callback functions (onItem,
 		//		onError, etc) will be invoked in the context of the scope object.
 		//		In the body of the callback function, the value of the "this"
 		//		keyword will be the scope object.   If no scope object is provided,
 		//		the callback functions will be called in the context of dojo.global.
-		//		For example, onItem.call(scope, item, request) vs. 
+		//		For example, onItem.call(scope, item, request) vs.
 		//		onItem.call(dojo.global, item, request)
 		if(!this.isItemLoaded(keywordArgs.item)){
 			throw new Error('Unimplemented API: dojo.data.api.Identity.fetchItemByIdentity');
 		}
 	}
 });
+
+return dojo.data.api.Identity;
+});
diff --git a/dojo/data/api/Notification.js b/dojo/data/api/Notification.js
index 6ad77dc..4621095 100644
--- a/dojo/data/api/Notification.js
+++ b/dojo/data/api/Notification.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo.data.api.Notification");
-dojo.require("dojo.data.api.Read");
+define("dojo/data/api/Notification", ["dojo", "dojo/data/api/Read"], function(dojo) {
 
 dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 	//	summary:
@@ -9,12 +8,12 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 	//
 	//	description:
 	//		This API defines a set of APIs that all datastores that conform to the
-	//		Notifications API must implement.  In general, most stores will implement 
+	//		Notifications API must implement.  In general, most stores will implement
 	//		these APIs as no-op functions for users who wish to monitor them to be able
-	//		to connect to then via dojo.connect().  For non-users of dojo.connect, 
+	//		to connect to then via dojo.connect().  For non-users of dojo.connect,
 	//		they should be able to just replace the function on the store to obtain
 	//		 notifications.  Both read-only and read-write stores may implement
-	//		this feature.  In the case of a read-only store, this feature makes sense if 
+	//		this feature.  In the case of a read-only store, this feature makes sense if
 	//		the store itself does internal polling to a back-end server and periodically updates
 	//		its cache of items (deletes, adds, and updates).
 	//
@@ -27,7 +26,7 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 	//	|	dojo.connect(store, "onSet", onSet);
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
@@ -35,16 +34,16 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 		};
 	},
 
-	onSet: function(/* item */ item, 
-					/* attribute-name-string */ attribute, 
+	onSet: function(/* item */ item,
+					/* attribute-name-string */ attribute,
 					/* object | array */ oldValue,
 					/* object | array */ newValue){
 		//	summary:
-		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.  
+		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
 		//	description:
-		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.  
-		//		Its purpose is to provide a hook point for those who wish to monitor actions on items in the store 
-		//		in a simple manner.  The general expected usage is to dojo.connect() to the store's 
+		//		This function is called any time an item is modified via setValue, setValues, unsetAttribute, etc.
+		//		Its purpose is to provide a hook point for those who wish to monitor actions on items in the store
+		//		in a simple manner.  The general expected usage is to dojo.connect() to the store's
 		//		implementation and be called after the store function is called.
 		//
 		//	item:
@@ -53,11 +52,11 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 		//		The attribute being changed represented as a string name.
 		//	oldValue:
 		//		The old value of the attribute.  In the case of single value calls, such as setValue, unsetAttribute, etc,
-		//		this value will be generally be an atomic value of some sort (string, int, etc, object).  In the case of 
+		//		this value will be generally be an atomic value of some sort (string, int, etc, object).  In the case of
 		//		multi-valued attributes, it will be an array.
 		//	newValue:
-		//		The new value of the attribute.  In the case of single value calls, such as setValue, this value will be 
-		//		generally be an atomic value of some sort (string, int, etc, object).  In the case of multi-valued attributes, 
+		//		The new value of the attribute.  In the case of single value calls, such as setValue, this value will be
+		//		generally be an atomic value of some sort (string, int, etc, object).  In the case of multi-valued attributes,
 		//		it will be an array.  In the case of unsetAttribute, the new value will be 'undefined'.
 		//
 		//	returns:
@@ -84,12 +83,12 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 		//		{
 		//			item: someItem,							//The parent item
 		//			attribute:	"attribute-name-string",	//The attribute the new item was assigned to.
-		//			oldValue: something	//Whatever was the previous value for the attribute.  
+		//			oldValue: something	//Whatever was the previous value for the attribute.
 		//						//If it is a single-value attribute only, then this value will be a single value.
 		//						//If it was a multi-valued attribute, then this will be an array of all the values minues the new one.
 		//			newValue: something	//The new value of the attribute.  In the case of single value calls, such as setValue, this value will be
 		//						//generally be an atomic value of some sort (string, int, etc, object).  In the case of multi-valued attributes,
-		//						//it will be an array.  
+		//						//it will be an array.
 		//		}
 		//
 		//	returns:
@@ -113,3 +112,6 @@ dojo.declare("dojo.data.api.Notification", dojo.data.api.Read, {
 		throw new Error('Unimplemented API: dojo.data.api.Notification.onDelete');
 	}
 });
+
+return dojo.data.api.Notification;
+});
diff --git a/dojo/data/api/Read.js b/dojo/data/api/Read.js
index 1f943a2..9af377f 100644
--- a/dojo/data/api/Read.js
+++ b/dojo/data/api/Read.js
@@ -1,26 +1,25 @@
-dojo.provide("dojo.data.api.Read");
-dojo.require("dojo.data.api.Request");
+define("dojo/data/api/Read", ["dojo", "dojo/data/api/Request"], function(dojo) {
 
 dojo.declare("dojo.data.api.Read", null, {
 	//	summary:
-	//		This is an abstract API that data provider implementations conform to.  
+	//		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, 
+	//		methods unimplemented.  For more information on the dojo.data APIs,
 	//		please visit: http://www.dojotoolkit.org/node/98
 
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
 		//	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.
 		//		Returns undefined if and only if the item does not have a value for the
-		//		given attribute (which is the same as saying the item does not have the attribute). 
+		//		given attribute (which is the same as saying the item does not have the attribute).
 		// description:
 		//		Saying that an "item x does not have a value for an attribute y"
-		//		is identical to saying that an "item x does not have attribute y". 
-		//		It is an oxymoron to say "that attribute is present but has no values" 
+		//		is identical to saying that an "item x does not have attribute y".
+		//		It is an oxymoron to say "that attribute is present but has no values"
 		//		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.
@@ -103,7 +102,7 @@ dojo.declare("dojo.data.api.Read", null, {
 	},
 
 	containsValue: function(/* item */ item,
-							/* attribute-name-string */ attribute, 
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
 		//	summary:
 		//		Returns true if the given *value* is one of the values that getValues()
@@ -126,8 +125,8 @@ dojo.declare("dojo.data.api.Read", null, {
 
 	isItem: function(/* anything */ something){
 		//	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, 
+		//		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:
@@ -164,9 +163,9 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		isItemLoaded() returns true before loadItem() is even called,
 		//		then loadItem() need not do any work at all and will not even invoke
 		//		the callback handlers.  So, before invoking this method, check that
-		//		the item has not already been loaded.  
+		//		the item has not already been loaded.
 		// 	keywordArgs:
-		//		An anonymous object that defines the item to load and callbacks to invoke when the 
+		//		An anonymous object that defines the item to load and callbacks to invoke when the
 		//		load has completed.  The format of the object is as follows:
 		//		{
 		//			item: object,
@@ -189,12 +188,12 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		parameter, the error object
 		//
 		//	The *scope* parameter.
-		//		If a scope object is provided, all of the callback functions (onItem, 
+		//		If a scope object is provided, all of the callback functions (onItem,
 		//		onError, etc) will be invoked in the context of the scope object.
 		//		In the body of the callback function, the value of the "this"
 		//		keyword will be the scope object.   If no scope object is provided,
 		//		the callback functions will be called in the context of dojo.global().
-		//		For example, onItem.call(scope, item, request) vs. 
+		//		For example, onItem.call(scope, item, request) vs.
 		//		onItem.call(dojo.global(), item, request)
 		if(!this.isItemLoaded(keywordArgs.item)){
 			throw new Error('Unimplemented API: dojo.data.api.Read.loadItem');
@@ -205,25 +204,25 @@ dojo.declare("dojo.data.api.Read", null, {
 		//	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 
+		//		The format and expectations of stores is that they operate in a generally asynchronous
 		//		manner, therefore callbacks are always used to return items located by the fetch parameters.
 		//
 		//	description:
 		//		A Request object will always be returned and is returned immediately.
-		//		The basic request is nothing more than the keyword args passed to fetch and 
-		//		an additional function attached, abort().  The returned request object may then be used 
-		//		to cancel a fetch.  All data items returns are passed through the callbacks defined in the 
+		//		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
+		//		to cancel a fetch.  All data items returns are passed through the callbacks defined in the
 		//		fetch parameters and are not present on the 'request' object.
 		//
 		//		This does not mean that custom stores can not add methods and properties to the request object
-		//		returned, only that the API does not require it.  For more info about the Request API, 
+		//		returned, only that the API does not require it.  For more info about the Request API,
 		//		see dojo.data.api.Request
 		//
 		//	keywordArgs:
-		//		The keywordArgs parameter may either be an instance of 
+		//		The keywordArgs parameter may either be an instance of
 		//		conforming to dojo.data.api.Request or may be a simple anonymous object
 		//		that may contain any of the following:
-		//		{ 
+		//		{
 		//			query: query-object or query-string,
 		//			queryOptions: object,
 		//			onBegin: Function,
@@ -236,10 +235,10 @@ dojo.declare("dojo.data.api.Read", null, {
 		//			sort: array
 		//		}
 		//		All implementations should accept keywordArgs objects with any of
-		//		the 9 standard properties: query, onBegin, onItem, onComplete, onError 
-		//		scope, sort, start, and count.  Some implementations may accept additional 
-		//		properties in the keywordArgs object as valid parameters, such as 
-		//		{includeOutliers:true}.         
+		//		the 9 standard properties: query, onBegin, onItem, onComplete, onError
+		//		scope, sort, start, and count.  Some implementations may accept additional
+		//		properties in the keywordArgs object as valid parameters, such as
+		//		{includeOutliers:true}.
 		//
 		//	The *query* parameter.
 		//		The query may be optional in some data store implementations.
@@ -247,28 +246,28 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		of the query itself -- each different data store implementation
 		//		may have its own notion of what a query should look like.
 		//		However, as of dojo 0.9, 1.0, and 1.1, all the provided datastores in dojo.data
-		//		and dojox.data support an object structure query, where the object is a set of 
+		//		and dojox.data support an object structure query, where the object is a set of
 		//		name/value parameters such as { attrFoo: valueBar, attrFoo1: valueBar1}.  Most of the
-		//		dijit widgets, such as ComboBox assume this to be the case when working with a datastore 
-		//		when they dynamically update the query.  Therefore, for maximum compatibility with dijit 
+		//		dijit widgets, such as ComboBox assume this to be the case when working with a datastore
+		//		when they dynamically update the query.  Therefore, for maximum compatibility with dijit
 		//		widgets the recommended query parameter is a key/value object.  That does not mean that the
-		//		the datastore may not take alternative query forms, such as a simple string, a Date, a number, 
-		//		or a mix of such.  Ultimately, The dojo.data.api.Read API is agnostic about what the query 
-		//		format.  
-		//		Further note:  In general for query objects that accept strings as attribute 
-		//		value matches, the store should also support basic filtering capability, such as * 
+		//		the datastore may not take alternative query forms, such as a simple string, a Date, a number,
+		//		or a mix of such.  Ultimately, The dojo.data.api.Read API is agnostic about what the query
+		//		format.
+		//		Further note:  In general for query objects that accept strings as attribute
+		//		value matches, the store should also support basic filtering capability, such as *
 		//		(match any character) and ? (match single character).  An example query that is a query object
-		//		would be like: { attrFoo: "value*"}.  Which generally means match all items where they have 
+		//		would be like: { attrFoo: "value*"}.  Which generally means match all items where they have
 		//		an attribute named attrFoo, with a value that starts with 'value'.
 		//
 		//	The *queryOptions* parameter
 		//		The queryOptions parameter is an optional parameter used to specify optiosn that may modify
 		//		the query in some fashion, such as doing a case insensitive search, or doing a deep search
-		//		where all items in a hierarchical representation of data are scanned instead of just the root 
+		//		where all items in a hierarchical representation of data are scanned instead of just the root
 		//		items.  It currently defines two options that all datastores should attempt to honor if possible:
 		//		{
 		//			ignoreCase: boolean, //Whether or not the query should match case sensitively or not.  Default behaviour is false.
-		//			deep: boolean 	//Whether or not a fetch should do a deep search of items and all child 
+		//			deep: boolean 	//Whether or not a fetch should do a deep search of items and all child
 		//							//items instead of just root-level items in a datastore.  Default is false.
 		//		}
 		//
@@ -278,14 +277,14 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		will be called just once, before the first onItem callback is called.
 		//		The onBegin callback function will be passed two arguments, the
 		//		the total number of items identified and the Request object.  If the total number is
-		//		unknown, then size will be -1.  Note that size is not necessarily the size of the 
-		//		collection of items returned from the query, as the request may have specified to return only a 
+		//		unknown, then size will be -1.  Note that size is not necessarily the size of the
+		//		collection of items returned from the query, as the request may have specified to return only a
 		//		subset of the total set of items through the use of the start and count parameters.
 		//
 		//	The *onItem* parameter.
 		//		function(item, request);
 		//		If an onItem callback function is provided, the callback function
-		//		will be called as each item in the result is received. The callback 
+		//		will be called as each item in the result is received. The callback
 		//		function will be passed two arguments: the item itself, and the
 		//		Request object.
 		//
@@ -295,12 +294,12 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		If an onComplete callback function is provided, the callback function
 		//		will be called just once, after the last onItem callback is called.
 		//		Note that if the onItem callback is not present, then onComplete will be passed
-		//		an array containing all items which matched the query and the request object.  
-		//		If the onItem callback is present, then onComplete is called as: 
+		//		an array containing all items which matched the query and the request object.
+		//		If the onItem callback is present, then onComplete is called as:
 		//		onComplete(null, request).
 		//
 		//	The *onError* parameter.
-		//		function(errorData, request); 
+		//		function(errorData, request);
 		//		If an onError callback function is provided, the callback function
 		//		will be called if there is any sort of error while attempting to
 		//		execute the query.
@@ -308,29 +307,29 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		an Error object and the Request object.
 		//
 		//	The *scope* parameter.
-		//		If a scope object is provided, all of the callback functions (onItem, 
+		//		If a scope object is provided, all of the callback functions (onItem,
 		//		onComplete, onError, etc) will be invoked in the context of the scope
 		//		object.  In the body of the callback function, the value of the "this"
 		//		keyword will be the scope object.   If no scope object is provided,
-		//		the callback functions will be called in the context of dojo.global().  
-		//		For example, onItem.call(scope, item, request) vs. 
+		//		the callback functions will be called in the context of dojo.global().
+		//		For example, onItem.call(scope, item, request) vs.
 		//		onItem.call(dojo.global(), item, request)
 		//
 		//	The *start* parameter.
-		//		If a start parameter is specified, this is a indication to the datastore to 
+		//		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
-		//		to page across queries with millions of hits by only returning subsets of the 
+		//		to page across queries with millions of hits by only returning subsets of the
 		//		hits for each query
 		//
 		//	The *count* parameter.
-		//		If a count parameter is specified, this is a indication to the datastore to 
-		//		only return up to that many items.  This allows a fetch call that may have 
-		//		millions of item matches to be paired down to something reasonable.  
+		//		If a count parameter is specified, this is a indication to the datastore to
+		//		only return up to that many items.  This allows a fetch call that may have
+		//		millions of item matches to be paired down to something reasonable.
 		//
 		//	The *sort* parameter.
-		//		If a sort parameter is specified, this is a indication to the datastore to 
-		//		sort the items in some manner before returning the items.  The array is an array of 
+		//		If a sort parameter is specified, this is a indication to the datastore to
+		//		sort the items in some manner before returning the items.  The array is an array of
 		//		javascript objects that must conform to the following format to be applied to the
 		//		fetching of items:
 		//		{
@@ -338,18 +337,18 @@ dojo.declare("dojo.data.api.Read", null, {
 		//			descending: true|false;   // Optional.  Default is false.
 		//		}
 		//		Note that when comparing attributes, if an item contains no value for the attribute
-		//		(undefined), then it the default ascending sort logic should push it to the bottom 
+		//		(undefined), then it the default ascending sort logic should push it to the bottom
 		//		of the list.  In the descending order case, it such items should appear at the top of the list.
-		// 
+		//
 		//	returns:
 		//		The fetch() method will return a javascript object conforming to the API
 		//		defined in dojo.data.api.Request.  In general, it will be the keywordArgs
 		//		object returned with the required functions in Request.js attached.
 		//		Its general purpose is to provide a convenient way for a caller to abort an
-		//		ongoing fetch.  
-		// 
+		//		ongoing fetch.
+		//
 		//		The Request object may also have additional properties when it is returned
-		//		such as request.store property, which is a pointer to the datastore object that 
+		//		such as request.store property, which is a pointer to the datastore object that
 		//		fetch() is a method of.
 		//
 		//	exceptions:
@@ -364,7 +363,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		|	var request = store.fetch(onComplete: showEverything);
 		//	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.  
+		//		This demonstrates how paging can be done for specific queries.
 		//		|	var request = store.fetch({query:"all books", start: 4, count: 10, onComplete: showBooks});
 		//	example:
 		//		Fetch all items that match the query, calling 'callback' each time an item is located.
@@ -403,21 +402,21 @@ 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; 
+		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:
-		//		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 
+		//		The getFeatures() method returns an simple keyword values object
+		//		that specifies what interface features the datastore implements.
+		//		A simple CsvStore may be read-only, and the only feature it
 		//		implements will be the 'dojo.data.api.Read' interface, so the
 		//		getFeatures() method will return an object like this one:
 		//		{'dojo.data.api.Read': true}.
 		//		A more sophisticated datastore might implement a variety of
-		//		interface features, like 'dojo.data.api.Read', 'dojo.data.api.Write', 
+		//		interface features, like 'dojo.data.api.Read', 'dojo.data.api.Write',
 		//		'dojo.data.api.Identity', and 'dojo.data.api.Attribution'.
 		return {
 			'dojo.data.api.Read': true
@@ -426,14 +425,14 @@ dojo.declare("dojo.data.api.Read", null, {
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
 		//	summary:
-		//		The close() method is intended for instructing the store to 'close' out 
+		//		The close() method is intended for instructing the store to 'close' out
 		//		any information associated with a particular request.
 		//
 		//	description:
-		//		The close() method is intended for instructing the store to 'close' out 
+		//		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.  
-		//		It will then close out anything associated with that request, such as 
+		//		expects to recieve as a parameter a request object returned from a fetch.
+		//		It will then close out anything associated with that request, such as
 		//		clearing any internal datastore caches and closing any 'open' connections.
 		//		For some store implementations, this call may be a no-op.
 		//
@@ -441,7 +440,7 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		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 
+		//		there on, it merely cleans out any current data and resets the store to initial
 		//		state.
 		//
 		//	example:
@@ -454,7 +453,7 @@ dojo.declare("dojo.data.api.Read", null, {
 	getLabel: function(/* item */ item){
 		//	summary:
 		//		Method to inspect the item and return a user-readable 'label' for the item
-		//		that provides a general/adequate description of what the item is. 
+		//		that provides a general/adequate description of what the item is.
 		//
 		//	description:
 		//		Method to inspect the item and return a user-readable 'label' for the item
@@ -462,17 +461,17 @@ dojo.declare("dojo.data.api.Read", null, {
 		//		most labels will be a specific attribute value or collection of the attribute
 		//		values that combine to label the item in some manner.  For example for an item
 		//		that represents a person it may return the label as:  "firstname lastlame" where
-		//		the firstname and lastname are attributes on the item.  If the store is unable 
+		//		the firstname and lastname are attributes on the item.  If the store is unable
 		//		to determine an adequate human readable label, it should return undefined.  Users that wish
-		//		to customize how a store instance labels items should replace the getLabel() function on 
-		//		their instance of the store, or extend the store and replace the function in 
+		//		to customize how a store instance labels items should replace the getLabel() function on
+		//		their instance of the store, or extend the store and replace the function in
 		//		the extension class.
 		//
 		//	item:
 		//		The item to return the label for.
 		//
-		//	returns: 
-		//		A user-readable string representing the item or undefined if no user-readable label can 
+		//	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;
@@ -480,23 +479,26 @@ dojo.declare("dojo.data.api.Read", null, {
 
 	getLabelAttributes: function(/* item */ item){
 		//	summary:
-		//		Method to inspect the item and return an array of what attributes of the item were used 
+		//		Method to inspect the item and return an array of what attributes of the item were used
 		//		to generate its label, if any.
 		//
 		//	description:
-		//		Method to inspect the item and return an array of what attributes of the item were used 
+		//		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 
+		//		where the UI is using the label as an overall identifer should they wish to hide
 		//		redundant information.
 		//
 		//	item:
 		//		The item to return the list of label attributes for.
 		//
-		//	returns: 
-		//		An array of attribute names that were used to generate the label, or null if public attributes 
+		//	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;
 	}
 });
+
+return dojo.data.api.Read;
+});
diff --git a/dojo/data/api/Request.js b/dojo/data/api/Request.js
index 5490e25..504b4e7 100644
--- a/dojo/data/api/Request.js
+++ b/dojo/data/api/Request.js
@@ -1,15 +1,15 @@
-dojo.provide("dojo.data.api.Request");
+define("dojo/data/api/Request", ["dojo"], function(dojo) {
 
 dojo.declare("dojo.data.api.Request", null, {
 	//	summary:
 	//		This class defines out the semantics of what a 'Request' object looks like
 	//		when returned from a fetch() method.  In general, a request object is
-	//		nothing more than the original keywordArgs from fetch with an abort function 
-	//		attached to it to allow users to abort a particular request if they so choose. 
+	//		nothing more than the original keywordArgs from fetch with an abort function
+	//		attached to it to allow users to abort a particular request if they so choose.
 	//		No other functions are required on a general Request object return.  That does not
 	//		inhibit other store implementations from adding extentions to it, of course.
 	//
-	//		This is an abstract API that data provider implementations conform to.  
+	//		This is an abstract API that data provider implementations conform to.
 	//		This file defines methods signatures and intentionally leaves all the
 	//		methods unimplemented.
 	//
@@ -17,12 +17,15 @@ dojo.declare("dojo.data.api.Request", null, {
 
 	abort: function(){
 		//	summary:
-		//		This function is a hook point for stores to provide as a way for 
+		//		This function is a hook point for stores to provide as a way for
 		//		a fetch to be halted mid-processing.
 		//	description:
-		//		This function is a hook point for stores to provide as a way for 
+		//		This function is a hook point for stores to provide as a way for
 		//		a fetch to be halted mid-processing.  For more details on the fetch() api,
 		//		please see dojo.data.api.Read.fetch().
 		throw new Error('Unimplemented API: dojo.data.api.Request.abort');
 	}
 });
+
+return dojo.data.api.Request;
+});
diff --git a/dojo/data/api/Write.js b/dojo/data/api/Write.js
index b197404..05e50d2 100644
--- a/dojo/data/api/Write.js
+++ b/dojo/data/api/Write.js
@@ -1,14 +1,13 @@
-dojo.provide("dojo.data.api.Write");
-dojo.require("dojo.data.api.Read");
+define("dojo/data/api/Write", ["dojo", "dojo/data/api/Read"], function(dojo) {
 
 dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 	//	summary:
-	//		This is an abstract API that data provider implementations conform to.  
+	//		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,
@@ -22,16 +21,16 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		item based on the *keywordArgs* provided.  In general, the attribute
 		//		names in the keywords become the attributes in the new item and as for
 		//		the attribute values in keywordArgs, they become the values of the attributes
-		//		in the new item.  In addition, for stores that support hierarchical item 
+		//		in the new item.  In addition, for stores that support hierarchical item
 		//		creation, an optional second parameter is accepted that defines what item is the parent
 		//		of the new item and what attribute of that item should the new item be assigned to.
 		//		In general, this will assume that the attribute targetted is multi-valued and a new item
-		//		is appended onto the list of values for that attribute.  
+		//		is appended onto the list of values for that attribute.
 		//
 		//	keywordArgs:
 		//		A javascript object defining the initial content of the item as a set of JavaScript 'property name: value' pairs.
 		//	parentInfo:
-		//		An optional javascript object defining what item is the parent of this item (in a hierarchical store.  Not all stores do hierarchical items), 
+		//		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
 		//		of the object is as follows:
@@ -42,7 +41,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//
 		//	exceptions:
 		//		Throws an exception if *keywordArgs* is a string or a number or
-		//		anything other than a simple anonymous object.  
+		//		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:
@@ -57,11 +56,11 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//	summary:
 		//		Deletes an item from the store.
 		//
-		//	item: 
+		//	item:
 		//		The item to delete.
 		//
 		//	exceptions:
-		//		Throws an exception if the argument *item* is not an item 
+		//		Throws an exception if the argument *item* is not an item
 		//		(if store.isItem(item) returns false).
 		//	example:
 		//	|	var success = store.deleteItem(kermit);
@@ -69,7 +68,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		return false; // boolean
 	},
 
-	setValue: function(	/* item */ item, 
+	setValue: function(	/* item */ item,
 						/* string */ attribute,
 						/* almost anything */ value){
 		//	summary:
@@ -94,7 +93,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 	},
 
 	setValues: function(/* item */ item,
-						/* string */ attribute, 
+						/* string */ attribute,
 						/* array */ values){
 		//	summary:
 		//		Adds each value in the *values* array as a value of the given
@@ -121,7 +120,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		return false; // boolean
 	},
 
-	unsetAttribute: function(	/* item */ item, 
+	unsetAttribute: function(	/* item */ item,
 								/* string */ attribute){
 		//	summary:
 		//		Deletes all the values of an attribute on an item.
@@ -145,9 +144,9 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//	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 
+		//		in an asynchronous fashion.  The outcome of the save action is
 		//		is passed into the set of supported callbacks for the save.
-		//   
+		//
 		//	keywordArgs:
 		//		{
 		//			onComplete: function
@@ -163,7 +162,7 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		are generally passed to the onComplete.
 		//
 		//	The *onError* parameter.
-		//		function(errorData); 
+		//		function(errorData);
 		//
 		//		If an onError callback function is provided, the callback function
 		//		will be called if there is any sort of error while attempting to
@@ -175,12 +174,12 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		//		onComplete, onError, etc) will be invoked in the context of the scope
 		//		object.  In the body of the callback function, the value of the "this"
 		//		keyword will be the scope object.   If no scope object is provided,
-		//		the callback functions will be called in the context of dojo.global.  
-		//		For example, onComplete.call(scope) vs. 
+		//		the callback functions will be called in the context of dojo.global.
+		//		For example, onComplete.call(scope) vs.
 		//		onComplete.call(dojo.global)
 		//
 		//	returns:
-		//		Nothing.  Since the saves are generally asynchronous, there is 
+		//		Nothing.  Since the saves are generally asynchronous, there is
 		//		no need to return anything.  All results are passed via callbacks.
 		//	example:
 		//	|	store.save({onComplete: onSave});
@@ -202,8 +201,8 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 
 	isDirty: function(/* item? */ item){
 		//	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,  
+		//		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().
 		//
@@ -220,3 +219,6 @@ dojo.declare("dojo.data.api.Write", dojo.data.api.Read, {
 		return false; // boolean
 	}
 });
+
+return dojo.data.api.Write;
+});
diff --git a/dojo/data/util/filter.js b/dojo/data/util/filter.js
index 0ecf1ca..f618d80 100644
--- a/dojo/data/util/filter.js
+++ b/dojo/data/util/filter.js
@@ -1,11 +1,12 @@
-dojo.provide("dojo.data.util.filter");
+define("dojo/data/util/filter", ["dojo"], function(dojo) {
+dojo.getObject("data.util.filter", true, dojo);
 
 dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/ ignoreCase){
-	//	summary:  
+	//	summary:
 	//		Helper function to convert a simple pattern to a regular expression for matching.
 	//	description:
 	//		Returns a regular expression object that conforms to the defined conversion rules.
-	//		For example:  
+	//		For example:
 	//			ca*   -> /^ca.*$/
 	//			*ca*  -> /^.*ca.*$/
 	//			*c\*a*  -> /^.*c\*a.*$/
@@ -17,7 +18,7 @@ dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/
 	//			* Means match anything, so ca* means match anything starting with ca
 	//			? Means match single character.  So, b?b will match to bob and bab, and so on.
 	//      	\ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
-	//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be 
+	//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
 	//				represented by \\ to be treated as an ordinary \ character instead of an escape.
 	//
 	//	ignoreCase:
@@ -63,3 +64,6 @@ dojo.data.util.filter.patternToRegExp = function(/*String*/pattern, /*boolean?*/
 	}
 	
 };
+
+return dojo.data.util.filter;
+});
diff --git a/dojo/data/util/simpleFetch.js b/dojo/data/util/simpleFetch.js
index 4b2dbf8..82b2670 100644
--- a/dojo/data/util/simpleFetch.js
+++ b/dojo/data/util/simpleFetch.js
@@ -1,30 +1,30 @@
-dojo.provide("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.sorter");
+define("dojo/data/util/simpleFetch", ["dojo", "dojo/data/util/sorter"], function(dojo) {
+dojo.getObject("data.util.simpleFetch", true, dojo);
 
 dojo.data.util.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.  
-	//		The simpleFetch mixin should work well for any datastore that can respond to a _fetchItems() 
+	//		be mixed into other datastore implementations to accelerate their development.
+	//		The simpleFetch mixin should work well for any datastore that can respond to a _fetchItems()
 	//		call by returning an array of all the found items that matched the query.  The simpleFetch mixin
 	//		is not designed to work for datastores that respond to a fetch() call by incrementally
 	//		loading items, or sequentially loading partial batches of the result
-	//		set.  For datastores that mixin simpleFetch, simpleFetch 
+	//		set.  For datastores that mixin simpleFetch, simpleFetch
 	//		implements a fetch method that automatically handles eight of the fetch()
 	//		arguments -- onBegin, onItem, onComplete, onError, start, count, sort and scope
 	//		The class mixing in simpleFetch should not implement fetch(),
-	//		but should instead implement a _fetchItems() method.  The _fetchItems() 
-	//		method takes three arguments, the keywordArgs object that was passed 
+	//		but should instead implement a _fetchItems() method.  The _fetchItems()
+	//		method takes three arguments, the keywordArgs object that was passed
 	//		to fetch(), a callback function to be called when the result array is
 	//		available, and an error callback to be called if something goes wrong.
 	//		The _fetchItems() method should ignore any keywordArgs parameters for
-	//		start, count, onBegin, onItem, onComplete, onError, sort, and scope.  
+	//		start, count, onBegin, onItem, onComplete, onError, sort, and scope.
 	//		The _fetchItems() method needs to correctly handle any other keywordArgs
-	//		parameters, including the query parameter and any optional parameters 
-	//		(such as includeChildren).  The _fetchItems() method should create an array of 
-	//		result items and pass it to the fetchHandler along with the original request object 
-	//		-- or, the _fetchItems() method may, if it wants to, create an new request object 
-	//		with other specifics about the request that are specific to the datastore and pass 
+	//		parameters, including the query parameter and any optional parameters
+	//		(such as includeChildren).  The _fetchItems() method should create an array of
+	//		result items and pass it to the fetchHandler along with the original request object
+	//		-- or, the _fetchItems() method may, if it wants to, create an new request object
+	//		with other specifics about the request that are specific to the datastore and pass
 	//		that as the request object to the handler.
 	//
 	//		For more information on this specific function, see dojo.data.api.Read.fetch()
@@ -84,3 +84,6 @@ dojo.data.util.simpleFetch.fetch = function(/* Object? */ request){
 	this._fetchItems(request, _fetchHandler, _errorHandler);
 	return request;	// Object
 };
+
+return dojo.data.util.simpleFetch;
+});
diff --git a/dojo/data/util/sorter.js b/dojo/data/util/sorter.js
index a96d64b..f367b81 100644
--- a/dojo/data/util/sorter.js
+++ b/dojo/data/util/sorter.js
@@ -1,10 +1,11 @@
-dojo.provide("dojo.data.util.sorter");
+define("dojo/data/util/sorter", ["dojo"], function(dojo) {
+dojo.getObject("data.util.sorter", true, dojo);
 
-dojo.data.util.sorter.basicComparator = function(	/*anything*/ a, 
+dojo.data.util.sorter.basicComparator = function(	/*anything*/ a,
 													/*anything*/ b){
-	//	summary:  
+	//	summary:
 	//		Basic comparision function that compares if an item is greater or less than another item
-	//	description:  
+	//	description:
 	//		returns 1 if a > b, -1 if a < b, 0 if equal.
 	//		'null' values (null, undefined) are treated as larger values so that they're pushed to the end of the list.
 	//		And compared to each other, null is equivalent to undefined.
@@ -21,18 +22,18 @@ dojo.data.util.sorter.basicComparator = function(	/*anything*/ a,
 		b = undefined;
 	}
 	if(a == b){
-		r = 0; 
+		r = 0;
 	}else if(a > b || a == null){
-		r = 1; 
+		r = 1;
 	}
 	return r; //int {-1,0,1}
 };
 
 dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortSpec,
 														/*dojo.data.core.Read*/ store){
-	//	summary:  
+	//	summary:
 	//		Helper function to generate the sorting function based off the list of sort attributes.
-	//	description:  
+	//	description:
 	//		The sort function creation will look for a property on the store called 'comparatorMap'.  If it exists
 	//		it will look in the mapping for comparisons function for the attributes.  If one is found, it will
 	//		use it instead of the basic comparator, which is typically used for strings, ints, booleans, and dates.
@@ -74,7 +75,7 @@ dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortS
 				}
 				comp = map[attr] || bc;
 			}
-			sortFunctions.push(createSortFunction(attr, 
+			sortFunctions.push(createSortFunction(attr,
 				dir, comp, store));
 		}
 	}
@@ -86,6 +87,9 @@ dojo.data.util.sorter.createSortFunction = function(	/* attributes array */sortS
 				return ret;//int
 			}
 		}
-		return 0; //int  
+		return 0; //int
 	}; // Function
 };
+
+return dojo.data.util.sorter;
+});
diff --git a/dojo/date.js b/dojo/date.js
index 8b54d32..532d7d9 100644
--- a/dojo/date.js
+++ b/dojo/date.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.date");
+define("dojo/date", ["dojo"], function(dojo) {
+dojo.getObject("date", true, dojo);
 
 /*=====
 dojo.date = {
@@ -13,7 +14,7 @@ dojo.date.getDaysInMonth = function(/*Date*/dateObject){
 	var days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
 	if(month == 1 && dojo.date.isLeapYear(dateObject)){ return 29; } // Number
 	return days[month]; // Number
-}
+};
 
 dojo.date.isLeapYear = function(/*Date*/dateObject){
 	//	summary:
@@ -27,7 +28,7 @@ dojo.date.isLeapYear = function(/*Date*/dateObject){
 
 	var year = dateObject.getFullYear();
 	return !(year%400) || (!(year%4) && !!(year%100)); // Boolean
-}
+};
 
 // FIXME: This is not localized
 dojo.date.getTimezoneName = function(/*Date*/dateObject){
@@ -52,7 +53,7 @@ dojo.date.getTimezoneName = function(/*Date*/dateObject){
 	}else{
 		// If at first you don't succeed ...
 		// If IE knows about the TZ, it appears before the year
-		// Capital letters or slash before a 4-digit year 
+		// Capital letters or slash before a 4-digit year
 		// at the end of string
 		var pat = /([A-Z\/]+) \d{4}$/;
 		if((match = str.match(pat))){
@@ -61,7 +62,7 @@ dojo.date.getTimezoneName = function(/*Date*/dateObject){
 		// Some browsers (e.g. Safari) glue the TZ on the end
 		// of toLocaleString instead of putting it in toString
 			str = dateObject.toLocaleString();
-			// Capital letters or slash -- end of string, 
+			// Capital letters or slash -- end of string,
 			// after space
 			pat = / ([A-Z\/]+)$/;
 			if((match = str.match(pat))){
@@ -72,7 +73,7 @@ dojo.date.getTimezoneName = function(/*Date*/dateObject){
 
 	// Make sure it doesn't somehow end up return AM or PM
 	return (tz == 'AM' || tz == 'PM') ? '' : tz; // String
-}
+};
 
 // Utility methods to do arithmetic calculations with Dates
 
@@ -336,3 +337,6 @@ dojo.date.difference = function(/*Date*/date1, /*Date?*/date2, /*String?*/interv
 	// Round for fractional values and DST leaps
 	return Math.round(delta); // Number (integer)
 };
+
+return dojo.date;
+});
diff --git a/dojo/date/locale.js b/dojo/date/locale.js
index 8b296fc..5d670e2 100644
--- a/dojo/date/locale.js
+++ b/dojo/date/locale.js
@@ -1,16 +1,11 @@
-dojo.provide("dojo.date.locale");
+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);
 
 // Localization methods for Date.   Honor local customs using locale-dependent dojo.cldr data.
 
-dojo.require("dojo.date");
-dojo.require("dojo.cldr.supplemental");
-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", "gregorian");
 
 //NOTE: Everything in this module assumes Gregorian calendars.
 // Other calendars will be implemented in separate modules.
@@ -82,7 +77,7 @@ dojo.requireLocalization("dojo.cldr", "gregorian");
 					break;
 				case 'a':
 					var timePeriod = (dateObject.getHours() < 12) ? 'am' : 'pm';
-					s = bundle['dayPeriods-format-wide-' + timePeriod];
+					s = options[timePeriod] || bundle['dayPeriods-format-wide-' + timePeriod];
 					break;
 				case 'h':
 				case 'H':
@@ -283,20 +278,23 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 	//		formatting lengths may be chosen, with "full" used by default.
 	//		Custom patterns may be used or registered with translations using
 	//		the dojo.date.locale.addCustomFormats method.
-	//	
+	//
 	//		Formatting patterns are implemented using [the syntax described at
 	//		unicode.org](http://www.unicode.org/reports/tr35/tr35-4.html#Date_Format_Patterns)
-	//		When two digit years are used, a century is chosen according to a sliding 
+	//		When two digit years are used, a century is chosen according to a sliding
 	//		window of 80 years before and 20 years after present year, for both `yy` and `yyyy` patterns.
 	//		year < 100CE requires strict mode.
 	//
 	// value:
 	//		A string representation of a date
 
-	var info = dojo.date.locale._parseInfo(options),
+	// remove non-printing bidi control chars from input and pattern
+	var controlChars = /[\u200E\u200F\u202A\u202E]/g,
+		info = dojo.date.locale._parseInfo(options),
 		tokens = info.tokens, bundle = info.bundle,
-		re = new RegExp("^" + info.regexp + "$", info.strict ? "" : "i"),
-		match = re.exec(value);
+		re = new RegExp("^" + info.regexp.replace(controlChars, "") + "$",
+			info.strict ? "" : "i"),
+		match = re.exec(value && value.replace(controlChars, ""));
 
 	if(!match){ return null; } // null
 
@@ -435,7 +433,7 @@ dojo.date.locale.parse = function(/*String*/value, /*dojo.date.locale.__FormatOp
 		result[3] = 0; //12am -> 0
 	}
 
-	//TODO: implement a getWeekday() method in order to test 
+	//TODO: implement a getWeekday() method in order to test
 	//validity of input strings containing 'EEE' or 'EEEE'...
 
 	var dateObject = new Date(result[0], result[1], result[2], result[3], result[4], result[5], result[6]); // Date
@@ -475,7 +473,7 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 	applyLiteral = applyLiteral || identity;
 	applyAll = applyAll || identity;
 
-	//split on single quotes (which escape literals in date format strings) 
+	//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),
 		literal = pattern.charAt(0) == "'";
@@ -511,31 +509,31 @@ function _buildDateTimeRE(tokens, bundle, options, pattern){
 				s = '\\d{2,4}';
 				break;
 			case 'M':
-				s = (l>2) ? '\\S+?' : p2+'[1-9]|1[0-2]';
+				s = (l>2) ? '\\S+?' : '1[0-2]|'+p2+'[1-9]';
 				break;
 			case 'D':
-				s = p2+'[1-9]|'+p3+'[1-9][0-9]|[12][0-9][0-9]|3[0-5][0-9]|36[0-6]';
+				s = '[12][0-9][0-9]|3[0-5][0-9]|36[0-6]|'+p3+'[1-9][0-9]|'+p2+'[1-9]';
 				break;
 			case 'd':
 				s = '3[01]|[12]\\d|'+p2+'[1-9]';
 				break;
 			case 'w':
-				s = p2+'[1-9]|[1-4][0-9]|5[0-3]';
+				s = '[1-4][0-9]|5[0-3]|'+p2+'[1-9]';
 				break;
 			case 'E':
 				s = '\\S+';
 				break;
 			case 'h': //hour (1-12)
-				s = p2+'[1-9]|1[0-2]';
+				s = '1[0-2]|'+p2+'[1-9]';
 				break;
 			case 'k': //hour (0-11)
-				s = p2+'\\d|1[01]';
+				s = '1[01]|'+p2+'\\d';
 				break;
 			case 'H': //hour (0-23)
-				s = p2+'\\d|1\\d|2[0-3]';
+				s = '1\\d|2[0-3]|'+p2+'\\d';
 				break;
 			case 'K': //hour (1-24)
-				s = p2+'[1-9]|1\\d|2[0-4]';
+				s = '1\\d|2[0-4]|'+p2+'[1-9]';
 				break;
 			case 'm':
 			case 's':
@@ -547,10 +545,8 @@ 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'];
-				if(options.strict){
-					s = am + '|' + pm;
-				}else{
-					s = am + '|' + pm;
+				s = am + '|' + pm;
+				if(!options.strict){
 					if(am != am.toLowerCase()){ s += '|' + am.toLowerCase(); }
 					if(pm != pm.toLowerCase()){ s += '|' + pm.toLowerCase(); }
 					if(s.indexOf('.') != -1){ s += '|' + s.replace(/\./g, ""); }
@@ -661,3 +657,6 @@ dojo.date.locale._getWeekOfYear = function(/*Date*/dateObject, /*Number*/firstDa
 
 	return week; // Number
 };
+
+return dojo.date.locale;
+});
diff --git a/dojo/date/stamp.js b/dojo/date/stamp.js
index 7b6b55a..ece3e6b 100644
--- a/dojo/date/stamp.js
+++ b/dojo/date/stamp.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.date.stamp");
+define("dojo/date/stamp", ["dojo"], function(dojo) {
+dojo.getObject("date.stamp", true, dojo);
 
 // Methods to convert dates to or from a wire (string) format using well-known conventions
 
@@ -78,7 +79,7 @@ dojo.date.stamp.fromISOString = function(/*String*/formattedString, /*Number?*/d
 	}
 
 	return result; // Date or null
-}
+};
 
 /*=====
 	dojo.date.stamp.__Options = function(){
@@ -128,10 +129,13 @@ dojo.date.stamp.toISOString = function(/*Date*/dateObject, /*dojo.date.stamp.__O
 		}else if(options.selector != "time"){
 			var timezoneOffset = dateObject.getTimezoneOffset();
 			var absOffset = Math.abs(timezoneOffset);
-			time += (timezoneOffset > 0 ? "-" : "+") + 
+			time += (timezoneOffset > 0 ? "-" : "+") +
 				_(Math.floor(absOffset/60)) + ":" + _(absOffset%60);
 		}
 		formattedDate.push(time);
 	}
 	return formattedDate.join('T'); // String
-}
+};
+
+return dojo.date.stamp;
+});
diff --git a/dojo/dnd/Avatar.js b/dojo/dnd/Avatar.js
index a6415d6..5d75762 100644
--- a/dojo/dnd/Avatar.js
+++ b/dojo/dnd/Avatar.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo.dnd.Avatar");
-
-dojo.require("dojo.dnd.common");
+define("dojo/dnd/Avatar", ["dojo", "dojo/dnd/common"], function(dojo) {
 
 dojo.declare("dojo.dnd.Avatar", null, {
 	// summary:
@@ -84,7 +82,7 @@ dojo.declare("dojo.dnd.Avatar", null, {
 			var icon = dojo.byId("a11yIcon");
 			var text = '+';   // assume canDrop && copy
 			if (this.manager.canDropFlag && !this.manager.copy) {
-				text = '< '; // canDrop && move 
+				text = '< '; // canDrop && move
 			}else if (!this.manager.canDropFlag && !this.manager.copy) {
 				text = "o"; //!canDrop && move
 			}else if(!this.manager.canDropFlag){
@@ -103,3 +101,6 @@ dojo.declare("dojo.dnd.Avatar", null, {
 		return this.manager.nodes.length.toString();
 	}
 });
+
+return dojo.dnd.Avatar;
+});
diff --git a/dojo/dnd/Container.js b/dojo/dnd/Container.js
index 2b4bfab..d9b43a0 100644
--- a/dojo/dnd/Container.js
+++ b/dojo/dnd/Container.js
@@ -1,7 +1,4 @@
-dojo.provide("dojo.dnd.Container");
-
-dojo.require("dojo.dnd.common");
-dojo.require("dojo.parser");
+define("dojo/dnd/Container", ["dojo", "dojo/dnd/common", "dojo/parser"], function(dojo) {
 
 /*
 	Container states:
@@ -54,7 +51,7 @@ dojo.dnd.Item = function(){
 
 dojo.declare("dojo.dnd.Container", null, {
 	// summary:
-	//		a Container object, which knows when mouse hovers over it, 
+	//		a Container object, which knows when mouse hovers over it,
 	//		and over which element it hovers
 	
 	// object attributes (for markup)
@@ -131,7 +128,7 @@ dojo.declare("dojo.dnd.Container", null, {
 	},
 	forInItems: function(/*Function*/ f, /*Object?*/ o){
 		// summary:
-		//		iterates over a data map skipping members that 
+		//		iterates over a data map skipping members that
 		//		are present in the empty object (IE and/or 3rd-party libraries).
 		o = o || dojo.global;
 		var m = this.map, e = dojo.dnd._empty;
@@ -318,8 +315,7 @@ dojo.declare("dojo.dnd.Container", null, {
 		var prefix = "dojoDnd" + type;
 		var state  = type.toLowerCase() + "State";
 		//dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
-		dojo.removeClass(this.node, prefix + this[state]);
-		dojo.addClass(this.node, prefix + newState);
+		dojo.replaceClass(this.node, prefix + newState, prefix + this[state]);
 		this[state] = newState;
 	},
 	_addItemClass: function(node, type){
@@ -366,7 +362,7 @@ dojo.declare("dojo.dnd.Container", null, {
 
 dojo.dnd._createNode = function(tag){
 	// summary:
-	//		returns a function, which creates an element of given tag 
+	//		returns a function, which creates an element of given tag
 	//		(SPAN by default) and sets its innerHTML to given text
 	// tag: String
 	//		a tag name or empty for SPAN
@@ -426,3 +422,6 @@ dojo.dnd._defaultCreator = function(node){
 		return {node: n, data: data, type: type};
 	};
 };
+
+return dojo.dnd.Container;
+});
diff --git a/dojo/dnd/Manager.js b/dojo/dnd/Manager.js
index 8df4fe9..6ce56c4 100644
--- a/dojo/dnd/Manager.js
+++ b/dojo/dnd/Manager.js
@@ -1,8 +1,4 @@
-dojo.provide("dojo.dnd.Manager");
-
-dojo.require("dojo.dnd.common");
-dojo.require("dojo.dnd.autoscroll");
-dojo.require("dojo.dnd.Avatar");
+define("dojo/dnd/Manager", ["dojo", "dojo/dnd/common", "dojo/dnd/autoscroll", "dojo/dnd/Avatar"], function(dojo) {
 
 dojo.declare("dojo.dnd.Manager", null, {
 	// summary:
@@ -75,7 +71,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 			dojo.connect(dojo.body(), "onselectstart", dojo.stopEvent)
 		];
 		var c = "dojoDnd" + (copy ? "Copy" : "Move");
-		dojo.addClass(dojo.body(), c); 
+		dojo.addClass(dojo.body(), c);
 	},
 	canDrop: function(flag){
 		// summary:
@@ -89,8 +85,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 	stopDrag: function(){
 		// summary:
 		//		stop the DnD in progress
-		dojo.removeClass(dojo.body(), "dojoDndCopy");
-		dojo.removeClass(dojo.body(), "dojoDndMove");
+		dojo.removeClass(dojo.body(), ["dojoDndCopy", "dojoDndMove"]);
 		dojo.forEach(this.events, dojo.disconnect);
 		this.events = [];
 		this.avatar.destroy();
@@ -123,7 +118,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 			s.left = (e.pageX + this.OFFSET_X) + "px";
 			s.top  = (e.pageY + this.OFFSET_Y) + "px";
 			var copy = Boolean(this.source.copyState(dojo.isCopyKey(e)));
-			if(this.copy != copy){ 
+			if(this.copy != copy){
 				this._setCopyStatus(copy);
 			}
 		}
@@ -157,7 +152,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 			switch(e.keyCode){
 				case dojo.keys.CTRL:
 					var copy = Boolean(this.source.copyState(true));
-					if(this.copy != copy){ 
+					if(this.copy != copy){
 						this._setCopyStatus(copy);
 					}
 					break;
@@ -175,7 +170,7 @@ dojo.declare("dojo.dnd.Manager", null, {
 		//		keyboard event
 		if(this.avatar && e.keyCode == dojo.keys.CTRL){
 			var copy = Boolean(this.source.copyState(false));
-			if(this.copy != copy){ 
+			if(this.copy != copy){
 				this._setCopyStatus(copy);
 			}
 		}
@@ -190,8 +185,9 @@ dojo.declare("dojo.dnd.Manager", null, {
 		this.copy = copy;
 		this.source._markDndStatus(this.copy);
 		this.updateAvatar();
-		dojo.removeClass(dojo.body(), "dojoDnd" + (this.copy ? "Move" : "Copy"));
-		dojo.addClass(dojo.body(), "dojoDnd" + (this.copy ? "Copy" : "Move"));
+		dojo.replaceClass(dojo.body(),
+			"dojoDnd" + (this.copy ? "Copy" : "Move"),
+			"dojoDnd" + (this.copy ? "Move" : "Copy"));
 	}
 });
 
@@ -207,3 +203,6 @@ dojo.dnd.manager = function(){
 	}
 	return dojo.dnd._manager;	// Object
 };
+
+return dojo.dnd.Manager;
+});
diff --git a/dojo/dnd/Moveable.js b/dojo/dnd/Moveable.js
index 84ded8c..9674883 100644
--- a/dojo/dnd/Moveable.js
+++ b/dojo/dnd/Moveable.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo.dnd.Moveable");
-
-dojo.require("dojo.dnd.Mover");
+define("dojo/dnd/Moveable", ["dojo", "dojo/dnd/Mover"], function(dojo) {
 
 /*=====
 dojo.declare("dojo.dnd.__MoveableArgs", [], {
@@ -45,6 +43,7 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		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"),
 			// cancel text selection and text dragging
 			dojo.connect(this.handle, "ondragstart",   this, "onSelectStart"),
 			dojo.connect(this.handle, "onselectstart", this, "onSelectStart")
@@ -67,17 +66,20 @@ dojo.declare("dojo.dnd.Moveable", null, {
 	// mouse event processors
 	onMouseDown: function(e){
 		// summary:
-		//		event processor for onmousedown, creates a Mover for the node
+		//		event processor for onmousedown/ontouchstart, creates a Mover for the node
 		// e: Event
-		//		mouse event
+		//		mouse/touch event
 		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, "onmouseup", this, "onMouseUp")
+				dojo.connect(this.handle, "ontouchmove", this, "onMouseMove"),
+				dojo.connect(this.handle, "onmouseup", this, "onMouseUp"),
+				dojo.connect(this.handle, "ontouchend", this, "onMouseUp")
 			);
-			this._lastX = e.pageX;
-			this._lastY = e.pageY;
+			var pos = e.touches ? e.touches[0] : e;
+			this._lastX = pos.pageX;
+			this._lastY = pos.pageY;
 		}else{
 			this.onDragDetected(e);
 		}
@@ -85,10 +87,11 @@ dojo.declare("dojo.dnd.Moveable", null, {
 	},
 	onMouseMove: function(e){
 		// summary:
-		//		event processor for onmousemove, used only for delayed drags
+		//		event processor for onmousemove/ontouchmove, used only for delayed drags
 		// e: Event
-		//		mouse event
-		if(Math.abs(e.pageX - this._lastX) > this.delay || Math.abs(e.pageY - this._lastY) > this.delay){
+		//		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){
 			this.onMouseUp(e);
 			this.onDragDetected(e);
 		}
@@ -125,8 +128,8 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		// summary:
 		//		called before every move operation
 		dojo.publish("/dnd/move/start", [mover]);
-		dojo.addClass(dojo.body(), "dojoMove"); 
-		dojo.addClass(this.node, "dojoMoveItem"); 
+		dojo.addClass(dojo.body(), "dojoMove");
+		dojo.addClass(this.node, "dojoMoveItem");
 	},
 	onMoveStop: function(/* dojo.dnd.Mover */ mover){
 		// summary:
@@ -165,3 +168,6 @@ dojo.declare("dojo.dnd.Moveable", null, {
 		// default implementation does nothing
 	}
 });
+
+return dojo.dnd.Moveable;
+});
diff --git a/dojo/dnd/Mover.js b/dojo/dnd/Mover.js
index 1a904b9..790821b 100644
--- a/dojo/dnd/Mover.js
+++ b/dojo/dnd/Mover.js
@@ -1,12 +1,9 @@
-dojo.provide("dojo.dnd.Mover");
-
-dojo.require("dojo.dnd.common");
-dojo.require("dojo.dnd.autoscroll");
+define("dojo/dnd/Mover", ["dojo", "dojo/dnd/common", "dojo/dnd/autoscroll"], function(dojo) {
 
 dojo.declare("dojo.dnd.Mover", null, {
 	constructor: function(node, e, host){
 		// summary:
-		//		an object, which makes a node follow the mouse. 
+		//		an object which makes a node follow the mouse, or touch-drag on touch devices.
 		//		Used as a default mover, and as a base class for custom movers.
 		// node: Node
 		//		a node (or node's id) to be moved
@@ -17,17 +14,27 @@ 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);
-		this.marginBox = {l: e.pageX, t: e.pageY};
+		var pos = e.touches ? e.touches[0] : e;
+		this.marginBox = {l: pos.pageX, t: pos.pageY};
 		this.mouseButton = e.button;
-		var h = this.host = host, d = node.ownerDocument, 
-			firstEvent = dojo.connect(d, "onmousemove", this, "onFirstMove");
+		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"),
+
+			// These are called continually during the drag
 			dojo.connect(d, "onmousemove", this, "onMouseMove"),
+			dojo.connect(d, "ontouchmove", this, "onMouseMove"),
+
+			// And these are called at the end of the drag
 			dojo.connect(d, "onmouseup",   this, "onMouseUp"),
+			dojo.connect(d, "ontouchend", this, "onMouseUp"),
+
 			// cancel text selection and text dragging
 			dojo.connect(d, "ondragstart",   dojo.stopEvent),
-			dojo.connect(d.body, "onselectstart", dojo.stopEvent),
-			firstEvent
+			dojo.connect(d.body, "onselectstart", dojo.stopEvent)
 		];
 		// notify that the move has started
 		if(h && h.onMoveStart){
@@ -37,17 +44,18 @@ dojo.declare("dojo.dnd.Mover", null, {
 	// mouse event processors
 	onMouseMove: function(e){
 		// summary:
-		//		event processor for onmousemove
+		//		event processor for onmousemove/ontouchmove
 		// e: Event
-		//		mouse event
+		//		mouse/touch event
 		dojo.dnd.autoScroll(e);
-		var m = this.marginBox;
-		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, 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);
 		dojo.stopEvent(e);
 	},
 	onMouseUp: function(e){
-		if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ? 
-				e.button == 0 : this.mouseButton == e.button){
+		if(dojo.isWebKit && dojo.isMac && this.mouseButton == 2 ?
+				e.button == 0 : this.mouseButton == e.button){ // TODO Should condition be met for touch devices, too?
 			this.destroy();
 		}
 		dojo.stopEvent(e);
@@ -55,7 +63,7 @@ dojo.declare("dojo.dnd.Mover", null, {
 	// utilities
 	onFirstMove: function(e){
 		// summary:
-		//		makes the node absolute; it is meant to be called only once. 
+		//		makes the node absolute; it is meant to be called only once.
 		// 		relative and absolutely positioned nodes are assumed to use pixel units
 		var s = this.node.style, l, t, h = this.host;
 		switch(s.position){
@@ -75,7 +83,7 @@ dojo.declare("dojo.dnd.Mover", null, {
 				// space into account - so we need to subtract the combined
 				// padding and margin.  We use getComputedStyle and
 				// _getMarginBox/_getContentBox to avoid the extra lookup of
-				// the computed style. 
+				// the computed style.
 				var b = dojo.doc.body;
 				var bs = dojo.getComputedStyle(b);
 				var bm = dojo._getMarginBox(b, bs);
@@ -89,7 +97,10 @@ dojo.declare("dojo.dnd.Mover", null, {
 		if(h && h.onFirstMove){
 			h.onFirstMove(this, e);
 		}
-		dojo.disconnect(this.events.pop());
+		
+		// Disconnect onmousemove and ontouchmove events that call this function
+		dojo.disconnect(this.events.shift());
+		dojo.disconnect(this.events.shift());
 	},
 	destroy: function(){
 		// summary:
@@ -104,3 +115,6 @@ dojo.declare("dojo.dnd.Mover", null, {
 		this.events = this.node = this.host = null;
 	}
 });
+
+return dojo.dnd.Mover;
+});
diff --git a/dojo/dnd/Selector.js b/dojo/dnd/Selector.js
index 49a7a69..dc83950 100644
--- a/dojo/dnd/Selector.js
+++ b/dojo/dnd/Selector.js
@@ -1,7 +1,4 @@
-dojo.provide("dojo.dnd.Selector");
-
-dojo.require("dojo.dnd.common");
-dojo.require("dojo.dnd.Container");
+define("dojo/dnd/Selector", ["dojo", "dojo/dnd/common", "dojo/dnd/Container"], function(dojo) {
 
 /*
 	Container item states:
@@ -323,3 +320,6 @@ dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
 		return this;	// self
 	}
 });
+
+return dojo.dnd.Selector;
+});
diff --git a/dojo/dnd/Source.js b/dojo/dnd/Source.js
index beb06fa..ce03d2c 100644
--- a/dojo/dnd/Source.js
+++ b/dojo/dnd/Source.js
@@ -1,7 +1,4 @@
-dojo.provide("dojo.dnd.Source");
-
-dojo.require("dojo.dnd.Selector");
-dojo.require("dojo.dnd.Manager");
+define("dojo/dnd/Source", ["dojo", "dojo/dnd/Selector", "dojo/dnd/Manager"], function(dojo) {
 
 /*
 	Container property:
@@ -80,11 +77,11 @@ dojo.declare("dojo.dnd.Source", dojo.dnd.Selector, {
 	generateText: true,
 	
 	constructor: function(/*DOMNode|String*/node, /*dojo.dnd.__SourceArgs?*/params){
-		// summary: 
+		// summary:
 		//		a constructor of the Source
 		// node:
 		//		node or node's id to build the source on
-		// params: 
+		// params:
 		//		any property of this class may be configured via the params
 		//		object which is mixed-in to the `dojo.dnd.Source` instance
 		dojo.mixin(this, dojo.mixin({}, params));
@@ -536,3 +533,6 @@ dojo.declare("dojo.dnd.AutoSource", dojo.dnd.Source, {
 		return new dojo.dnd.AutoSource(node, params);
 	}
 });
+
+return dojo.dnd.Source;
+});
diff --git a/dojo/dnd/TimedMoveable.js b/dojo/dnd/TimedMoveable.js
index aa40370..178aaf2 100644
--- a/dojo/dnd/TimedMoveable.js
+++ b/dojo/dnd/TimedMoveable.js
@@ -1,6 +1,4 @@
-dojo.provide("dojo.dnd.TimedMoveable");
-
-dojo.require("dojo.dnd.Moveable");
+define("dojo/dnd/TimedMoveable", ["dojo", "dojo/dnd/Moveable"], function(dojo) {
 
 /*=====
 dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
@@ -18,7 +16,7 @@ dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
 	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 
+		//		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.
 		
@@ -68,3 +66,6 @@ dojo.declare("dojo.dnd.__TimedMoveableArgs", [dojo.dnd.__MoveableArgs], {
 		}
 	});
 })();
+
+return dojo.dnd.TimedMoveable;
+});
diff --git a/dojo/dnd/autoscroll.js b/dojo/dnd/autoscroll.js
index 7ddeff9..8c96947 100644
--- a/dojo/dnd/autoscroll.js
+++ b/dojo/dnd/autoscroll.js
@@ -1,24 +1,7 @@
-dojo.provide("dojo.dnd.autoscroll");
+define("dojo/dnd/autoscroll", ["dojo", "dojo/window"], function(dojo) {
+dojo.getObject("dnd", true, dojo);
 
-dojo.dnd.getViewport = function(){
-	// summary:
-	//		Returns a viewport size (visible part of the window)
-
-	// TODO: remove this when getViewport() moved to dojo core, see #7028
-
-	// FIXME: need more docs!!
-	var d = dojo.doc, dd = d.documentElement, w = window, b = dojo.body();
-	if(dojo.isMozilla){
-		return {w: dd.clientWidth, h: w.innerHeight};	// Object
-	}else if(!dojo.isOpera && w.innerWidth){
-		return {w: w.innerWidth, h: w.innerHeight};		// Object
-	}else if (!dojo.isOpera && dd && dd.clientWidth){
-		return {w: dd.clientWidth, h: dd.clientHeight};	// Object
-	}else if (b.clientWidth){
-		return {w: b.clientWidth, h: b.clientHeight};	// Object
-	}
-	return null;	// Object
-};
+dojo.dnd.getViewport = dojo.window.getBox;
 
 dojo.dnd.V_TRIGGER_AUTOSCROLL = 32;
 dojo.dnd.H_TRIGGER_AUTOSCROLL = 32;
@@ -34,7 +17,7 @@ dojo.dnd.autoScroll = function(e){
 	//		onmousemove event
 
 	// FIXME: needs more docs!
-	var v = dojo.dnd.getViewport(), dx = 0, dy = 0;
+	var v = dojo.window.getBox(), dx = 0, dy = 0;
 	if(e.clientX < dojo.dnd.H_TRIGGER_AUTOSCROLL){
 		dx = -dojo.dnd.H_AUTOSCROLL_VALUE;
 	}else if(e.clientX > v.w - dojo.dnd.H_TRIGGER_AUTOSCROLL){
@@ -65,14 +48,15 @@ dojo.dnd.autoScrollNodes = function(e){
 			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), 
+				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;
 				if(dojo.isWebKit || dojo.isOpera){
-					// FIXME: this code should not be here, it should be taken into account 
+					// 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;
+					rx += dojo.body().scrollLeft;
+					ry += dojo.body().scrollTop;
 				}
 				if(rx > 0 && rx < b.w){
 					if(rx < w){
@@ -103,3 +87,6 @@ dojo.dnd.autoScrollNodes = function(e){
 	}
 	dojo.dnd.autoScroll(e);
 };
+
+return dojo.dnd;
+});
diff --git a/dojo/dnd/common.js b/dojo/dnd/common.js
index 88878ce..969a60d 100644
--- a/dojo/dnd/common.js
+++ b/dojo/dnd/common.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.dnd.common");
+define("dojo/dnd/common", ["dojo"], function(dojo) {
+dojo.getObject("dnd", true, dojo);
 
 dojo.dnd.getCopyKeyState = dojo.isCopyKey;
 
@@ -24,3 +25,6 @@ dojo.dnd.isFormElement = function(/*Event*/ e){
 	}
 	return " button textarea input select option ".indexOf(" " + t.tagName.toLowerCase() + " ") >= 0;	// Boolean
 };
+
+return dojo.dnd;
+});
diff --git a/dojo/dnd/move.js b/dojo/dnd/move.js
index fdf4dc0..b0216cc 100644
--- a/dojo/dnd/move.js
+++ b/dojo/dnd/move.js
@@ -1,7 +1,4 @@
-dojo.provide("dojo.dnd.move");
-
-dojo.require("dojo.dnd.Mover");
-dojo.require("dojo.dnd.Moveable");
+define("dojo/dnd/move", ["dojo", "dojo/dnd/Mover", "dojo/dnd/Moveable"], function(dojo) {
 
 /*=====
 dojo.declare("dojo.dnd.move.__constrainedMoveableArgs", [dojo.dnd.__MoveableArgs], {
@@ -46,7 +43,7 @@ dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
 		c.r = c.l + c.w;
 		c.b = c.t + c.h;
 		if(this.within){
-			var mb = dojo.marginBox(mover.node);
+			var mb = dojo._getMarginSize(mover.node);
 			c.r -= mb.w;
 			c.b -= mb.h;
 		}
@@ -56,8 +53,12 @@ dojo.declare("dojo.dnd.move.constrainedMoveable", dojo.dnd.Moveable, {
 		//		called during every move notification;
 		//		should actually move the node; can be overwritten.
 		var c = this.constraintBox, s = mover.node.style;
-		s.left = (leftTop.l < c.l ? c.l : c.r < leftTop.l ? c.r : leftTop.l) + "px";
-		s.top  = (leftTop.t < c.t ? c.t : c.b < leftTop.t ? c.b : leftTop.t) + "px";
+		this.onMoving(mover, leftTop);
+		leftTop.l = leftTop.l < c.l ? c.l : c.r < leftTop.l ? c.r : leftTop.l;
+		leftTop.t = leftTop.t < c.t ? c.t : c.b < leftTop.t ? c.b : leftTop.t;
+		s.left = leftTop.l + "px";
+		s.top  = leftTop.t + "px";
+		this.onMoved(mover, leftTop);
 	}
 });
 
@@ -119,8 +120,8 @@ dojo.declare("dojo.dnd.move.parentConstrainedMoveable", dojo.dnd.move.constraine
 		//		an optional object with parameters
 		var area = params && params.area;
 		this.constraints = function(){
-			var n = this.node.parentNode, 
-				s = dojo.getComputedStyle(n), 
+			var n = this.node.parentNode,
+				s = dojo.getComputedStyle(n),
 				mb = dojo._getMarginBox(n, s);
 			if(area == "margin"){
 				return mb;	// Object
@@ -142,102 +143,11 @@ dojo.declare("dojo.dnd.move.parentConstrainedMoveable", dojo.dnd.move.constraine
 	}
 });
 
-// WARNING: below are obsolete objects, instead of custom movers use custom moveables (above)
-
-dojo.dnd.move.constrainedMover = function(fun, within){
-	// summary:
-	//		returns a constrained version of dojo.dnd.Mover
-	// description:
-	//		this function produces n object, which will put a constraint on 
-	//		the margin box of dragged object in absolute coordinates
-	// fun: Function
-	//		called on drag, and returns a constraint box
-	// within: Boolean
-	//		if true, constraints the whole dragged object withtin the rectangle, 
-	//		otherwise the constraint is applied to the left-top corner
-
-	dojo.deprecated("dojo.dnd.move.constrainedMover, use dojo.dnd.move.constrainedMoveable instead");
-	var mover = function(node, e, notifier){
-		dojo.dnd.Mover.call(this, node, e, notifier);
-	};
-	dojo.extend(mover, dojo.dnd.Mover.prototype);
-	dojo.extend(mover, {
-		onMouseMove: function(e){
-			// summary: event processor for onmousemove
-			// e: Event: mouse event
-			dojo.dnd.autoScroll(e);
-			var m = this.marginBox, c = this.constraintBox,
-				l = m.l + e.pageX, t = m.t + e.pageY;
-			l = l < c.l ? c.l : c.r < l ? c.r : l;
-			t = t < c.t ? c.t : c.b < t ? c.b : t;
-			this.host.onMove(this, {l: l, t: t});
-		},
-		onFirstMove: function(){
-			// summary: called once to initialize things; it is meant to be called only once
-			dojo.dnd.Mover.prototype.onFirstMove.call(this);
-			var c = this.constraintBox = fun.call(this);
-			c.r = c.l + c.w;
-			c.b = c.t + c.h;
-			if(within){
-				var mb = dojo.marginBox(this.node);
-				c.r -= mb.w;
-				c.b -= mb.h;
-			}
-		}
-	});
-	return mover;	// Object
-};
-
-dojo.dnd.move.boxConstrainedMover = function(box, within){
-	// summary:
-	//		a specialization of dojo.dnd.constrainedMover, which constrains to the specified box
-	// box: Object
-	//		a constraint box (l, t, w, h)
-	// within: Boolean
-	//		if true, constraints the whole dragged object withtin the rectangle, 
-	//		otherwise the constraint is applied to the left-top corner
-
-	dojo.deprecated("dojo.dnd.move.boxConstrainedMover, use dojo.dnd.move.boxConstrainedMoveable instead");
-	return dojo.dnd.move.constrainedMover(function(){ return box; }, within);	// Object
-};
-
-dojo.dnd.move.parentConstrainedMover = function(area, within){
-	// summary:
-	//		a specialization of dojo.dnd.constrainedMover, which constrains to the parent node
-	// area: String
-	//		"margin" to constrain within the parent's margin box, "border" for the border box,
-	//		"padding" for the padding box, and "content" for the content box; "content" is the default value.
-	// within: Boolean
-	//		if true, constraints the whole dragged object within the rectangle, 
-	//		otherwise the constraint is applied to the left-top corner
-
-	dojo.deprecated("dojo.dnd.move.parentConstrainedMover, use dojo.dnd.move.parentConstrainedMoveable instead");
-	var fun = function(){
-		var n = this.node.parentNode, 
-			s = dojo.getComputedStyle(n), 
-			mb = dojo._getMarginBox(n, s);
-		if(area == "margin"){
-			return mb;	// Object
-		}
-		var t = dojo._getMarginExtents(n, s);
-		mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
-		if(area == "border"){
-			return mb;	// Object
-		}
-		t = dojo._getBorderExtents(n, s);
-		mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
-		if(area == "padding"){
-			return mb;	// Object
-		}
-		t = dojo._getPadExtents(n, s);
-		mb.l += t.l, mb.t += t.t, mb.w -= t.w, mb.h -= t.h;
-		return mb;	// Object
-	};
-	return dojo.dnd.move.constrainedMover(fun, within);	// Object
-};
-
 // patching functions one level up for compatibility
 
 dojo.dnd.constrainedMover = dojo.dnd.move.constrainedMover;
 dojo.dnd.boxConstrainedMover = dojo.dnd.move.boxConstrainedMover;
 dojo.dnd.parentConstrainedMover = dojo.dnd.move.parentConstrainedMover;
+
+return dojo.dnd.move;
+});
diff --git a/dojo/dojo.js b/dojo/dojo.js
index cbef3ab..55da409 100644
--- a/dojo/dojo.js
+++ b/dojo/dojo.js
@@ -24,7 +24,7 @@
 //				- 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 
+//				- 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
@@ -60,8 +60,8 @@ if(typeof dojo == "undefined"){
 					if(!src){ continue; }
 					var m = src.match(rePkg);
 					if(m){
-						return { 
-							node: scripts[i], 
+						return {
+							node: scripts[i],
 							root: src.substring(0, m.index)
 						};
 						/*
@@ -76,9 +76,14 @@ if(typeof dojo == "undefined"){
 		}
 
 		// we default to a browser environment if we can't figure it out
-		var hostEnv = "browser";
-		if(typeof djConfig !== "undefined" && djConfig.hostEnv){
-			hostEnv = djConfig.hostEnv;
+		var hostEnv = "browser", cfg = "dojoConfig";
+		
+		 // FIXME, 2.0: remove backwards compat djConfig global
+		if(typeof this[cfg] === "undefined" && typeof djConfig !== "undefined"){
+			this[cfg] = djConfig;
+		}
+		if(typeof dojoConfig !== "undefined" && dojoConfig.hostEnv){
+			hostEnv = dojoConfig.hostEnv;
 		}else if(
 			typeof this["load"] == "function" &&
 			(
@@ -102,39 +107,39 @@ if(typeof dojo == "undefined"){
 		}
 	
 		if(
-			this["djConfig"]&&
+			this[cfg]&&
 			(
-				djConfig["forceXDomain"] ||
-				djConfig["useXDomain"]
+				dojoConfig["forceXDomain"] ||
+				dojoConfig["useXDomain"]
 			)
 		){
 			tmps.push("loader_xd.js");
 		}
 	
-		if(this["djConfig"] && djConfig["baseUrl"]){
+		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 = djConfig["baseUrl"];
+			var root = dojoConfig["baseUrl"];
 		}else{
 			var root = "./";
 			if(hostEnv === "spidermonkey"){
 				// auto-detect the base path via an exception. Hack!
 				try{
-					throw new Error(""); 
-				}catch(e){ 
+					throw new Error("");
+				}catch(e){
 					root = String(e.fileName || e.sourceURL).split("dojo.js")[0];
 				}
 			}
-			if(!this["djConfig"]){
-				djConfig = { baseUrl: root };
+			if(!this[cfg]){
+				dojoConfig = { baseUrl: root };
 			}
 	
 			// 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["djConfig"]){ djConfig = {}; }
-				djConfig["baseUrl"] = root;
+				var root = getRootNode().root;
+				if(!this[cfg]){ dojoConfig = {}; }
+				dojoConfig["baseUrl"] = root;
 			}
 		}
 		// FIXME: should we be adding the lang stuff here so we can count on it
diff --git a/dojo/fx.js b/dojo/fx.js
index 9f0625e..bf56136 100644
--- a/dojo/fx.js
+++ b/dojo/fx.js
@@ -1,5 +1,5 @@
-dojo.provide("dojo.fx");
-dojo.require("dojo.fx.Toggler"); // FIXME: remove this back-compat require in 2.0 
+define("dojo/fx", ["dojo", "dojo/fx/Toggler"], function(dojo) {
+
 /*=====
 dojo.fx = {
 	// summary: Effects library on top of Base animations
@@ -7,7 +7,7 @@ dojo.fx = {
 =====*/
 (function(){
 	
-	var d = dojo, 
+	var d = dojo,
 		_baseObj = {
 			_fire: function(evt, args){
 				if(this[evt]){
@@ -126,14 +126,14 @@ dojo.fx = {
 	d.extend(_chain, _baseObj);
 
 	dojo.fx.chain = function(/*dojo.Animation[]*/ animations){
-		// summary: 
+		// summary:
 		//		Chain a list of `dojo.Animation`s to run in sequence
 		//
 		// description:
 		//		Return a `dojo.Animation` which will play all passed
 		//		`dojo.Animation` instances in sequence, firing its own
 		//		synthesized events simulating a single animation. (eg:
-		//		onEnd of this animation means the end of the chain, 
+		//		onEnd of this animation means the end of the chain,
 		//		not the individual animations within)
 		//
 		// example:
@@ -161,7 +161,7 @@ dojo.fx = {
 		
 		this._pseudoAnimation = new d.Animation({curve: [0, 1], duration: this.duration});
 		var self = this;
-		d.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"], 
+		d.forEach(["beforeBegin", "onBegin", "onPlay", "onAnimate", "onPause", "onStop", "onEnd"],
 			function(evt){
 				self._connects.push(d.connect(self._pseudoAnimation, evt,
 					function(){ self._fire(evt, arguments); }
@@ -219,11 +219,11 @@ dojo.fx = {
 	d.extend(_combine, _baseObj);
 
 	dojo.fx.combine = function(/*dojo.Animation[]*/ animations){
-		// summary: 
+		// summary:
 		//		Combine a list of `dojo.Animation`s to run in parallel
 		//
 		// description:
-		//		Combine an array of `dojo.Animation`s to run in parallel, 
+		//		Combine an array of `dojo.Animation`s to run in parallel,
 		//		providing a new `dojo.Animation` instance encompasing each
 		//		animation, firing standard animation events.
 		//
@@ -294,17 +294,17 @@ dojo.fx = {
 			}
 		}, args));
 
-		d.connect(anim, "onEnd", function(){ 
+		d.connect(anim, "onEnd", function(){
 			s.height = "auto";
 			s.overflow = o;
 		});
 
 		return anim; // dojo.Animation
-	}
+	};
 
 	dojo.fx.wipeOut = function(/*Object*/ args){
 		// summary:
-		//		Shrink a node to nothing and hide it. 
+		//		Shrink a node to nothing and hide it.
 		//
 		// description:
 		//		Returns an animation that will shrink node defined in "args"
@@ -313,7 +313,7 @@ dojo.fx = {
 		// args: Object
 		//		A hash-map of standard `dojo.Animation` constructor properties
 		//		(such as easing: node: duration: and so on)
-		// 
+		//
 		// example:
 		//	|	dojo.fx.wipeOut({ node:"someId" }).play()
 		
@@ -339,14 +339,14 @@ dojo.fx = {
 		});
 
 		return anim; // dojo.Animation
-	}
+	};
 
 	dojo.fx.slideTo = function(/*Object*/ args){
 		// summary:
 		//		Slide a node to a new top/left position
 		//
 		// description:
-		//		Returns an animation that will slide "node" 
+		//		Returns an animation that will slide "node"
 		//		defined in args Object from its current position to
 		//		the position defined by (args.left, args.top).
 		//
@@ -358,7 +358,7 @@ dojo.fx = {
 		// example:
 		//	|	dojo.fx.slideTo({ node: node, left:"40", top:"50", units:"px" }).play()
 
-		var node = args.node = d.byId(args.node), 
+		var node = args.node = d.byId(args.node),
 			top = null, left = null;
 
 		var init = (function(n){
@@ -388,6 +388,9 @@ dojo.fx = {
 		d.connect(anim, "beforeBegin", anim, init);
 
 		return anim; // dojo.Animation
-	}
+	};
+
+})();
 
-})();
\ No newline at end of file
+return dojo.fx;
+});
diff --git a/dojo/fx/Toggler.js b/dojo/fx/Toggler.js
index 7ff0223..775dc8b 100644
--- a/dojo/fx/Toggler.js
+++ b/dojo/fx/Toggler.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.fx.Toggler");
+define("dojo/fx/Toggler", ["dojo"], function(dojo) {
 
 dojo.declare("dojo.fx.Toggler", null, {
 	// summary:
@@ -7,16 +7,16 @@ dojo.declare("dojo.fx.Toggler", null, {
 	// description:
 	//		class constructor for an animation toggler. It accepts a packed
 	//		set of arguments about what type of animation to use in each
-	//		direction, duration, etc. All available members are mixed into 
-	//		these animations from the constructor (for example, `node`, 
-	//		`showDuration`, `hideDuration`). 
+	//		direction, duration, etc. All available members are mixed into
+	//		these animations from the constructor (for example, `node`,
+	//		`showDuration`, `hideDuration`).
 	//
 	// example:
 	//	|	var t = new dojo.fx.Toggler({
 	//	|		node: "nodeId",
 	//	|		showDuration: 500,
 	//	|		// hideDuration will default to "200"
-	//	|		showFunc: dojo.fx.wipeIn, 
+	//	|		showFunc: dojo.fx.wipeIn,
 	//	|		// hideFunc will default to "fadeOut"
 	//	|	});
 	//	|	t.show(100); // delay showing for 100ms
@@ -31,7 +31,7 @@ dojo.declare("dojo.fx.Toggler", null, {
 	//		The function that returns the `dojo.Animation` to show the node
 	showFunc: dojo.fadeIn,
 
-	// hideFunc: Function	
+	// hideFunc: Function
 	//		The function that returns the `dojo.Animation` to hide the node
 	hideFunc: dojo.fadeOut,
 
@@ -47,7 +47,7 @@ dojo.declare("dojo.fx.Toggler", null, {
 	// time show/hide are called if we're stopped somewhere in the
 	// middle.
 	// FIXME: also would be nice to specify individual showArgs/hideArgs mixed into
-	// each animation individually. 
+	// each animation individually.
 	// FIXME: also would be nice to have events from the animations exposed/bridged
 
 	/*=====
@@ -94,3 +94,6 @@ dojo.declare("dojo.fx.Toggler", null, {
 		return this.hideAnim.play(delay || 0);
 	}
 });
+
+return dojo.fx.Toggler;
+});
diff --git a/dojo/fx/easing.js b/dojo/fx/easing.js
index 69af935..c71411a 100644
--- a/dojo/fx/easing.js
+++ b/dojo/fx/easing.js
@@ -1,10 +1,11 @@
-dojo.provide("dojo.fx.easing");
+define("dojo/fx/easing", ["dojo"], function(dojo) {
+dojo.getObject("fx.easing", true, dojo);
 
 dojo.fx.easing = {
-	// summary: 
-	//		Collection of easing functions to use beyond the default 
+	// summary:
+	//		Collection of easing functions to use beyond the default
 	//		`dojo._defaultEasing` function.
-	// 
+	//
 	// description:
 	//
 	//		Easing functions are used to manipulate the iteration through
@@ -12,22 +13,22 @@ dojo.fx.easing = {
 	//		and the easing function progresses through that Line determing
 	//		how quickly (or slowly) it should go. Or more accurately: modify
 	//		the value of the _Line based on the percentage of animation completed.
-	//	
+	//
 	//		All functions follow a simple naming convention of "ease type" + "when".
 	//		If the name of the function ends in Out, the easing described appears
 	//		towards the end of the animation. "In" means during the beginning,
 	//		and InOut means both ranges of the Animation will applied, both
-	//		beginning and end. 
+	//		beginning and end.
 	//
-	//		One does not call the easing function directly, it must be passed to 
+	//		One does not call the easing function directly, it must be passed to
 	//		the `easing` property of an animation.
 	//
 	//	example:
 	//	|	dojo.require("dojo.fx.easing");
 	//	|	var anim = dojo.fadeOut({
-	//	|		node: 'node',	
+	//	|		node: 'node',
 	//	|		duration: 2000,
-	//	|		//	note there is no () 
+	//	|		//	note there is no ()
 	//	|		easing: dojo.fx.easing.quadIn
 	//	|	}).play();
 	//
@@ -142,24 +143,24 @@ dojo.fx.easing = {
 	},
 
 	backIn: function(/* Decimal? */n){
-		// summary: 
-		//		An easing function that starts away from the target, 
+		// summary:
+		//		An easing function that starts away from the target,
 		//		and quickly accelerates towards the end value.
-		// 
-		//		Use caution when the easing will cause values to become 
+		//
+		//		Use caution when the easing will cause values to become
 		//		negative as some properties cannot be set to negative values.
 		var s = 1.70158;
 		return Math.pow(n, 2) * ((s + 1) * n - s);
 	},
 
 	backOut: function(/* Decimal? */n){
-		// summary: 
-		//		An easing function that pops past the range briefly, and slowly comes back. 
+		// summary:
+		//		An easing function that pops past the range briefly, and slowly comes back.
 		//
 		// description:
-		//		An easing function that pops past the range briefly, and slowly comes back. 
+		//		An easing function that pops past the range briefly, and slowly comes back.
 		//
-		//		Use caution when the easing will cause values to become negative as some 
+		//		Use caution when the easing will cause values to become negative as some
 		//		properties cannot be set to negative values.
 		
 		n = n - 1;
@@ -168,12 +169,12 @@ dojo.fx.easing = {
 	},
 
 	backInOut: function(/* Decimal? */n){
-		// summary: 
+		// summary:
 		//		An easing function combining the effects of `backIn` and `backOut`
 		//
 		// description:
 		//		An easing function combining the effects of `backIn` and `backOut`.
-		//		Use caution when the easing will cause values to become negative 
+		//		Use caution when the easing will cause values to become negative
 		//		as some properties cannot be set to negative values.
 		var s = 1.70158 * 1.525;
 		n = n * 2;
@@ -183,13 +184,13 @@ dojo.fx.easing = {
 	},
 
 	elasticIn: function(/* Decimal? */n){
-		// summary: 
+		// summary:
 		//		An easing function the elastically snaps from the start value
 		//
 		// description:
 		//		An easing function the elastically snaps from the start value
-		//	
-		//		Use caution when the elasticity will cause values to become negative 
+		//
+		//		Use caution when the elasticity will cause values to become negative
 		//		as some properties cannot be set to negative values.
 		if(n == 0 || n == 1){ return n; }
 		var p = .3;
@@ -199,7 +200,7 @@ dojo.fx.easing = {
 	},
 
 	elasticOut: function(/* Decimal? */n){
-		// summary: 
+		// summary:
 		//		An easing function that elasticly snaps around the target value,
 		//		near the end of the Animation
 		//
@@ -207,7 +208,7 @@ dojo.fx.easing = {
 		//		An easing function that elasticly snaps around the target value,
 		//		near the end of the Animation
 		//
-		//		Use caution when the elasticity will cause values to become 
+		//		Use caution when the elasticity will cause values to become
 		//		negative as some properties cannot be set to negative values.
 		if(n==0 || n == 1){ return n; }
 		var p = .3;
@@ -216,7 +217,7 @@ dojo.fx.easing = {
 	},
 
 	elasticInOut: function(/* Decimal? */n){
-		// summary: 
+		// summary:
 		//		An easing function that elasticly snaps around the value, near
 		//		the beginning and end of the Animation.
 		//
@@ -224,7 +225,7 @@ dojo.fx.easing = {
 		//		An easing function that elasticly snaps around the value, near
 		//		the beginning and end of the Animation.
 		//
-		//		Use caution when the elasticity will cause values to become 
+		//		Use caution when the elasticity will cause values to become
 		//		negative as some properties cannot be set to negative values.
 		if(n == 0) return 0;
 		n = n * 2;
@@ -240,7 +241,7 @@ dojo.fx.easing = {
 	},
 
 	bounceIn: function(/* Decimal? */n){
-		// summary: 
+		// summary:
 		//		An easing function that 'bounces' near the beginning of an Animation
 		return (1 - dojo.fx.easing.bounceOut(1 - n)); // Decimal
 	},
@@ -250,7 +251,7 @@ dojo.fx.easing = {
 		//		An easing function that 'bounces' near the end of an Animation
 		var s = 7.5625;
 		var p = 2.75;
-		var l; 
+		var l;
 		if(n < (1 / p)){
 			l = s * Math.pow(n, 2);
 		}else if(n < (2 / p)){
@@ -267,9 +268,12 @@ dojo.fx.easing = {
 	},
 
 	bounceInOut: function(/* Decimal? */n){
-		// summary: 
+		// 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
 	}
 };
+
+return dojo.fx.easing;
+});
diff --git a/dojo/gears.js b/dojo/gears.js
index 7819eea..213f259 100644
--- a/dojo/gears.js
+++ b/dojo/gears.js
@@ -1,7 +1,8 @@
-dojo.provide("dojo.gears");
+define("dojo/gears", ["dojo"], function(dojo) {
+dojo.getObject("gears", true, dojo);
 
 dojo.gears._gearsObject = function(){
-	// summary: 
+	// summary:
 	//		factory method to get a Google Gears plugin instance to
 	//		expose in the browser runtime environment, if present
 	var factory;
@@ -50,3 +51,6 @@ dojo.gears.available = {
 // so, make it available in the runtime environment
 // and in the Google standard 'google.gears' global object
 dojo.gears.available = (!!dojo.gears._gearsObject())||0;
+
+return dojo.gears;
+});
diff --git a/dojo/hash.js b/dojo/hash.js
index 149e2b6..0395309 100644
--- a/dojo/hash.js
+++ b/dojo/hash.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.hash");
+define("dojo/hash", ["dojo"], function(dojo) {
+
 //TODOC: where does this go?
 // summary:
 //		Methods for monitoring and updating the hash in the browser URL.
@@ -18,11 +19,11 @@ dojo.provide("dojo.hash");
 		//		Handles getting and setting of location.hash.
 		//		 - If no arguments are passed, acts as a getter.
 		//		 - If a string is passed, acts as a setter.
-		//	hash: 
-		//		String: the hash is set - #string.
+		//	hash:
+		//		the hash is set - #string.
 		//	replace:
-		//		Boolean: If true, updates the hash value in the current history 
-		//			state instead of creating a new history state.
+		//		If true, updates the hash value in the current history
+		//		state instead of creating a new history state.
 		//	returns:
 		//		when used as a getter, returns the current hash string.
 		//		when used as a setter, returns the new hash string.
@@ -41,17 +42,16 @@ dojo.provide("dojo.hash");
 			location.href = "#" + hash;
 		}
 		return hash; // String
-	}
+	};
 
 	// Global vars
-	var _recentHash = null,
-		_ieUriMonitor = null,
+	var _recentHash, _ieUriMonitor, _connect,
 		_pollFrequency = dojo.config.hashPollFrequency || 100;
 
 	//Internal functions
 	function _getSegment(str, delimiter){
 		var i = str.indexOf(delimiter);
-		return (i >= 0) ? str.substring(i+1) : "";  
+		return (i >= 0) ? str.substring(i+1) : "";
 	}
 	
 	function _getHash(){
@@ -83,12 +83,12 @@ dojo.provide("dojo.hash");
 			return;
 		}
 		location.replace("#"+hash);
-		_pollLocation();
+		!_connect && _pollLocation();
 	}
 
 	function IEUriMonitor(){
 		// summary:
-		//		Determine if the browser's URI has changed or if the user has pressed the 
+		//		Determine if the browser's URI has changed or if the user has pressed the
 		//		back or forward button. If so, call _dispatchEvent.
 		//
 		//	description:
@@ -138,6 +138,13 @@ dojo.provide("dojo.hash");
 		var ifr = document.createElement("iframe"),
 			IFRAME_ID = "dojo-hash-iframe",
 			ifrSrc = dojo.config.dojoBlankHtmlUrl || dojo.moduleUrl("dojo", "resources/blank.html");
+
+		if(dojo.config.useXDomain && !dojo.config.dojoBlankHtmlUrl){
+			console.warn("dojo.hash: When using cross-domain Dojo builds,"
+				+ " please save dojo/resources/blank.html to your domain and set djConfig.dojoBlankHtmlUrl"
+				+ " to the path on your domain to blank.html");
+		}
+
 		ifr.id = IFRAME_ID;
 		ifr.src = ifrSrc + "?" + _getHash();
 		ifr.style.display = "none";
@@ -156,7 +163,7 @@ dojo.provide("dojo.hash");
 
 		this.isTransitioning = function(){
 			return transitioning;
-		}
+		};
 		
 		this.pollLocation = function(){
 			if(!ifrOffline) {
@@ -207,13 +214,13 @@ dojo.provide("dojo.hash");
 				}
 			}
 			setTimeout(dojo.hitch(this,this.pollLocation), _pollFrequency);
-		}
+		};
 		resetState(); // initialize state (transition to s1)
 		setTimeout(dojo.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
-			dojo.connect(dojo.global,"onhashchange",_dispatchEvent);
+			_connect = dojo.connect(dojo.global,"onhashchange",_dispatchEvent);
 		}else{
 			if(document.addEventListener){ // Non-IE
 				_recentHash = _getHash();
@@ -221,8 +228,11 @@ dojo.provide("dojo.hash");
 			}else if(document.attachEvent){ // IE7-
 				//Use hidden iframe in versions of IE that don't have onhashchange event
 				_ieUriMonitor = new IEUriMonitor();
-			} 
+			}
 			// else non-supported browser, do nothing.
 		}
 	});
-})();
\ No newline at end of file
+})();
+
+  return dojo.hash;
+});
diff --git a/dojo/html.js b/dojo/html.js
index f401a63..03519d0 100644
--- a/dojo/html.js
+++ b/dojo/html.js
@@ -1,23 +1,22 @@
-dojo.provide("dojo.html");
+define("dojo/html", ["dojo", "dojo/parser"], function(dojo) {
+dojo.getObject("html", true, dojo);
 
 // the parser might be needed..
-dojo.require("dojo.parser"); 
-
 (function(){ // private scope, sort of a namespace
 
 	// idCounter is incremented with each instantiation to allow asignment of a unique id for tracking, logging purposes
-	var idCounter = 0, 
+	var idCounter = 0,
 		d = dojo;
 	
 	dojo.html._secureForInnerHtml = function(/*String*/ cont){
 		// summary:
 		//		removes !DOCTYPE and title elements from the html string.
-		// 
+		//
 		//		khtml is picky about dom faults, you can't attach a style or <title> node as child of body
 		//		must go into head, so we need to cut out those tags
 		//	cont:
 		//		An html string for insertion into the dom
-		//	
+		//
 		return cont.replace(/(?:\s*<!DOCTYPE\s[^>]+>|<title[^>]*>[\s\S]*?<\/title>)/ig, ""); // String
 	};
 
@@ -37,7 +36,7 @@ dojo.require("dojo.parser");
 		//	node:
 		//		the parent element
 		//	content:
-		//		the content to be set on the parent element. 
+		//		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
@@ -63,7 +62,7 @@ dojo.require("dojo.parser");
 	};
 
 	// we wrap up the content-setting operation in a object
-	dojo.declare("dojo.html._ContentSetter", null, 
+	dojo.declare("dojo.html._ContentSetter", null,
 		{
 			// node: DomNode|String
 			//		An node which will be the parent element that we set content into
@@ -74,11 +73,11 @@ dojo.require("dojo.parser");
 			content: "",
 			
 			// id: String?
-			//		Usually only used internally, and auto-generated with each instance 
+			//		Usually only used internally, and auto-generated with each instance
 			id: "",
 
 			// cleanContent: Boolean
-			//		Should the content be treated as a full html document, 
+			//		Should the content be treated as a full html document,
 			//		and the real content stripped of <html>, <body> wrapper before injection
 			cleanContent: false,
 			
@@ -89,6 +88,17 @@ dojo.require("dojo.parser");
 			// parseContent: Boolean
 			//		Should the node by passed to the parser after the new content is set
 			parseContent: false,
+
+			// parserScope: String
+			//		Flag passed to parser.  Root for attribute names to search for.   If scopeName is dojo,
+			//		will search for data-dojo-type (or dojoType).  For backwards compatibility
+			//		reasons defaults to dojo._scopeName (which is "dojo" except when
+			//		multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+			parserScope: dojo._scopeName,
+
+			// startup: Boolean
+			//		Start the child widgets after parsing them.   Only obeyed if parseContent is true.
+			startup: true,
 			
 			// lifecyle methods
 			constructor: function(/* Object */params, /* String|DomNode */node){
@@ -106,14 +116,14 @@ dojo.require("dojo.parser");
 				if(!this.id){
 					this.id = [
 						"Setter",
-						(node) ? node.id || node.tagName : "", 
+						(node) ? node.id || node.tagName : "",
 						idCounter++
 					].join("_");
 				}
 			},
 			set: function(/* String|DomNode|NodeList? */ cont, /* Object? */ params){
 				// summary:
-				//		front-end to the set-content sequence 
+				//		front-end to the set-content sequence
 				//	cont:
 				//		An html string, node or enumerable list of nodes for insertion into the dom
 				//		If not provided, the object's content property will be used
@@ -133,9 +143,9 @@ dojo.require("dojo.parser");
 			},
 			setContent: function(){
 				// summary:
-				//		sets the content on the node 
+				//		sets the content on the node
 
-				var node = this.node; 
+				var node = this.node;
 				if(!node) {
 				    // can't proceed
 					throw new Error(this.declaredClass + ": setContent given no node");
@@ -147,7 +157,7 @@ dojo.require("dojo.parser");
 					// 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); 
+					var errMess = this.onContentError(e);
 					try{
 						node.innerHTML = errMess;
 					}catch(e){
@@ -163,7 +173,7 @@ dojo.require("dojo.parser");
 				//	cleanly empty out existing content
 
 				// destroy any widgets from a previous run
-				// NOTE: if you dont want this you'll need to empty 
+				// 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) {
@@ -173,17 +183,17 @@ dojo.require("dojo.parser");
 					});
 					delete this.parseResults;
 				}
-				// this is fast, but if you know its already empty or safe, you could 
+				// this is fast, but if you know its already empty or safe, you could
 				// override empty to skip this step
 				dojo.html._emptyNode(this.node);
 			},
 	
 			onBegin: function(){
 				// summary
-				//		Called after instantiation, but before set(); 
-				//		It allows modification of any of the object properties 
+				//		Called after instantiation, but before set();
+				//		It allows modification of any of the object properties
 				//		- including the node and content provided - before the set operation actually takes place
-				//		This default implementation checks for cleanContent and extractContent flags to 
+				//		This default implementation checks for cleanContent and extractContent flags to
 				//		optionally pre-process html string content
 				var cont = this.content;
 	
@@ -221,21 +231,21 @@ dojo.require("dojo.parser");
 				// summary
 				//		manually reset the Setter instance if its being re-used for example for another set()
 				// description
-				//		tearDown() is not called automatically. 
+				//		tearDown() is not called automatically.
 				//		In normal use, the Setter instance properties are simply allowed to fall out of scope
 				//		but the tearDown method can be called to explicitly reset this instance.
-				delete this.parseResults; 
-				delete this.node; 
-				delete this.content; 
+				delete this.parseResults;
+				delete this.node;
+				delete this.content;
 			},
   
 			onContentError: function(err){
-				return "Error occured setting content: " + 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 
+				// TODO: the intention with tearDown is to put the Setter's state
 				// back to that of the original constructor (vs. deleting/resetting everything regardless of ctor params)
 				// so we could do something here to move the original properties aside for later restoration
 				var empty = {}, key;
@@ -243,21 +253,28 @@ dojo.require("dojo.parser");
 					if(key in empty){ continue; }
 					// TODO: here's our opportunity to mask the properties we dont consider configurable/overridable
 					// .. but history shows we'll almost always guess wrong
-					this[key] = params[key]; 
+					this[key] = params[key];
 				}
 			},
 			_parse: function(){
-				// summary: 
+				// summary:
 				//		runs the dojo parser over the node contents, storing any results in this.parseResults
 				//		Any errors resulting from parsing are passed to _onError for handling
 
 				var rootNode = this.node;
 				try{
 					// store the results (widgets, whatever) for potential retrieval
+					var inherited = {};
+					dojo.forEach(["dir", "lang", "textDir"], function(name){
+						if(this[name]){
+							inherited[name] = this[name];
+						}
+					}, this);
 					this.parseResults = dojo.parser.parse({
 						rootNode: rootNode,
-						dir: this.dir,
-						lang: this.lang
+						noStart: !this.startup,
+						inherited: inherited,
+						scope: this.parserScope
 					});
 				}catch(e){
 					this._onError('Content', e, "Error parsing in _ContentSetter#"+this.id);
@@ -290,31 +307,34 @@ dojo.require("dojo.parser");
 			//	node:
 			//		the parent element that will receive the content
 			//	cont:
-			//		the content to be set on the parent element. 
+			//		the content to be set on the parent element.
 			//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
-			//	params: 
+			//	params:
 			//		Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter
 			//	example:
 			//		A safe string/node/nodelist content replacement/injection with hooks for extension
-			//		Example Usage: 
-			//		dojo.html.set(node, "some string"); 
-			//		dojo.html.set(node, contentNode, {options}); 
-			//		dojo.html.set(node, myNode.childNodes, {options}); 
+			//		Example Usage:
+			//		dojo.html.set(node, "some string");
+			//		dojo.html.set(node, contentNode, {options});
+			//		dojo.html.set(node, myNode.childNodes, {options});
 		if(undefined == cont){
 			console.warn("dojo.html.set: no cont argument provided, using empty string");
 			cont = "";
-		}	
+		}
 		if(!params){
 			// simple and fast
 			return dojo.html._setNodeContent(node, cont, true);
-		}else{ 
+		}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( 
-					params, 
-					{ content: cont, node: node } 
+			var op = new dojo.html._ContentSetter(dojo.mixin(
+					params,
+					{ content: cont, node: node }
 			));
 			return op.set();
 		}
 	};
 })();
+
+return dojo.html;
+});
diff --git a/dojo/i18n.js b/dojo/i18n.js
index e83ac60..b6ca244 100644
--- a/dojo/i18n.js
+++ b/dojo/i18n.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.i18n");
+define("dojo/i18n", ["require", "dojo"], function(require, dojo){
+dojo.getObject("i18n", true, dojo);
 
 /*=====
 dojo.i18n = {
@@ -6,7 +7,8 @@ dojo.i18n = {
 };
 =====*/
 
-dojo.i18n.getLocalization = function(/*String*/packageName, /*String*/bundleName, /*String?*/locale){
+// 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.
@@ -34,6 +36,13 @@ dojo.i18n.getLocalization = function(/*String*/packageName, /*String*/bundleName
 	// 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;
@@ -84,7 +93,7 @@ dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundle
 
 	var targetLocale = dojo.i18n.normalizeLocale(locale);
  	var bundlePackage = [moduleName, "nls", bundleName].join(".");
-	// NOTE: 
+	// 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.
@@ -94,7 +103,7 @@ dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundle
 	//		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){
@@ -111,7 +120,7 @@ dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundle
 		}
 		if(!bestLocale){
 			bestLocale = "ROOT";
-		}		
+		}
 	}
 
 	//See if the desired locale is already loaded.
@@ -143,6 +152,7 @@ dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundle
 				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;
@@ -157,7 +167,7 @@ dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundle
 			}else{
 				bundle[jsLoc] = parent;
 			}
-			
+
 			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.
@@ -175,8 +185,8 @@ dojo.i18n._requireLocalization = function(/*String*/moduleName, /*String*/bundle
 
 (function(){
 	// If other locales are used, dojo.requireLocalization should load them as
-	// well, by default. 
-	// 
+	// 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.
@@ -245,3 +255,6 @@ dojo.i18n._preloadLocalizations = function(/*String*/bundlePrefix, /*Array*/loca
 		preload(extra[i]);
 	}
 };
+
+return dojo.i18n;
+});
\ No newline at end of file
diff --git a/dojo/io/iframe.js b/dojo/io/iframe.js
index 04221a3..050e6ad 100644
--- a/dojo/io/iframe.js
+++ b/dojo/io/iframe.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.io.iframe");
+define("dojo/io/iframe", ["dojo"], function(dojo) {
+dojo.getObject("io", true, dojo);
 
 /*=====
 dojo.declare("dojo.io.iframe.__ioArgs", dojo.__IoArgs, {
@@ -40,7 +41,7 @@ dojo.declare("dojo.io.iframe.__ioArgs", dojo.__IoArgs, {
 =====*/
 
 dojo.io.iframe = {
-	// summary: 
+	// summary:
 	//		Sends an Ajax I/O call using and Iframe (for instance, to upload files)
 	
 	create: function(/*String*/fname, /*String*/onloadstr, /*String?*/uri){
@@ -70,30 +71,12 @@ dojo.io.iframe = {
 			}
 			turi = (dojo.config["dojoBlankHtmlUrl"]||dojo.moduleUrl("dojo", "resources/blank.html"));
 		}
-		var ifrstr = dojo.isIE ? '<iframe name="'+fname+'" src="'+turi+'" onload="'+onloadstr+'">' : 'iframe';
-		cframe = dojo.doc.createElement(ifrstr);
-		with(cframe){
-			name = fname;
-			setAttribute("name", fname);
-			id = fname;
-		}
-		dojo.body().appendChild(cframe);
-		window[fname] = cframe;
-	
-		with(cframe.style){
-			if(!(dojo.isSafari < 3)){
-				//We can't change the src in Safari 2.0.3 if absolute position. Bizarro.
-				position = "absolute";
-			}
-			left = top = "1px";
-			height = width = "1px";
-			visibility = "hidden";
-		}
+		var cframe = dojo.place(
+			'<iframe id="'+fname+'" name="'+fname+'" src="'+turi+'" onload="'+onloadstr+
+			'" style="position: absolute; left: 1px; top: 1px; height: 1px; width: 1px; visibility: hidden">',
+		dojo.body());
 
-		if(!dojo.isIE){
-			this.setSrc(cframe, turi, true);
-			cframe.onload = new Function(onloadstr);
-		}
+		window[fname] = cframe;
 
 		return cframe;
 	},
@@ -113,11 +96,8 @@ dojo.io.iframe = {
 			}else{
 				// Fun with DOM 0 incompatibilities!
 				var idoc;
-				//WebKit > 521 corresponds with Safari 3, which started with 522 WebKit version.
-				if(dojo.isIE || dojo.isWebKit > 521){
+				if(dojo.isIE || dojo.isWebKit){
 					idoc = iframe.contentWindow.document;
-				}else if(dojo.isSafari){
-					idoc = iframe.document;
 				}else{ //  if(d.isMozilla){
 					idoc = iframe.contentWindow;
 				}
@@ -133,8 +113,8 @@ dojo.io.iframe = {
 					idoc.location.replace(src);
 				}
 			}
-		}catch(e){ 
-			console.log("dojo.io.iframe.setSrc: ", e); 
+		}catch(e){
+			console.log("dojo.io.iframe.setSrc: ", e);
 		}
 	},
 
@@ -143,7 +123,7 @@ dojo.io.iframe = {
 		var doc = iframeNode.contentDocument || // W3
 			(
 				(
-					(iframeNode.name) && (iframeNode.document) && 
+					(iframeNode.name) && (iframeNode.document) &&
 					(dojo.doc.getElementsByTagName("iframe")[iframeNode.name].contentWindow) &&
 					(dojo.doc.getElementsByTagName("iframe")[iframeNode.name].contentWindow.document)
 				)
@@ -156,7 +136,7 @@ dojo.io.iframe = {
 	},
 
 	send: function(/*dojo.io.iframe.__ioArgs*/args){
-		//summary: 
+		//summary:
 		//		Function that sends the request to the server.
 		//		This transport can only process one send() request at a time, so if send() is called
 		//multiple times, it will queue up the calls and only process one at a time.
@@ -186,8 +166,8 @@ dojo.io.iframe = {
 					if(handleAs != "html"){
 						if(handleAs == "xml"){
 							//	FF, Saf 3+ and Opera all seem to be fine with ifd being xml.  We have to
-							//	do it manually for IE.  Refs #6334.
-							if(dojo.isIE){
+							//	do it manually for IE6-8.  Refs #6334.
+							if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
 								dojo.query("a", dii._frame.contentWindow.document.documentElement).orphan();
 								var xmlText=(dii._frame.contentWindow.document).documentElement.innerText;
 								xmlText=xmlText.replace(/>\s+</g, "><");
@@ -209,7 +189,7 @@ dojo.io.iframe = {
 				}catch(e){
 					value = e;
 				}finally{
-					ioArgs._callNext();				
+					ioArgs._callNext();
 				}
 				return value;
 			},
@@ -229,7 +209,7 @@ dojo.io.iframe = {
 				dojo.io.iframe._currentDfd = null;
 				dojo.io.iframe._fireNextRequest();
 			}
-		}
+		};
 
 		this._dfdQueue.push(dfd);
 		this._fireNextRequest();
@@ -288,16 +268,7 @@ dojo.io.iframe = {
 					// if we have things in content, we need to add them to the form
 					// before submission
 					var pHandler = function(name, value) {
-						var tn;
-						if(dojo.isIE){
-							tn = dojo.doc.createElement("<input type='hidden' name='"+name+"'>");
-						}else{
-							tn = dojo.doc.createElement("input");
-							tn.type = "hidden";
-							tn.name = name;
-						}
-						tn.value = value;
-						fn.appendChild(tn);
+						dojo.create("input", {type: "hidden", name: name, value: value}, fn);
 						ioArgs._contentToClean.push(name);
 					};
 					for(var x in content){
@@ -316,7 +287,7 @@ dojo.io.iframe = {
 						}
 					}
 				}
-				//IE requires going through getAttributeNode instead of just getAttribute in some form cases, 
+				//IE requires going through getAttributeNode instead of just getAttribute in some form cases,
 				//so use it for all.  See #2844
 				var actnNode = fn.getAttributeNode("action");
 				var mthdNode = fn.getAttributeNode("method");
@@ -397,4 +368,7 @@ dojo.io.iframe = {
 
 		ioArgs._finished = true;
 	}
-}
+};
+
+return dojo.io.iframe;
+});
diff --git a/dojo/io/script.js b/dojo/io/script.js
index 2265c1b..fc2675d 100644
--- a/dojo/io/script.js
+++ b/dojo/io/script.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.io.script");
+define("dojo/io/script", ["dojo"], function(dojo) {
+dojo.getObject("io", true, dojo);
 
 /*=====
 dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
@@ -15,13 +16,13 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 		// 		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, 
-		//		jsonp: "callback". For AOL JSONP calls it is normally 
+		//		For instance, when using Yahoo JSONP calls it is normally,
+		//		jsonp: "callback". For AOL JSONP calls it is normally
 		//		jsonp: "c".
 		//	checkString: String
-		//		A string of JavaScript that when evaluated like so: 
+		//		A string of JavaScript that when evaluated like so:
 		//		"typeof(" + checkString + ") != 'undefined'"
-		//		being true means that the script fetched has been loaded. 
+		//		being true means that the script fetched has been loaded.
 		//		Do not use this if doing a JSONP type of call (use callbackParamName instead).
 		//	frameDoc: Document
 		//		The Document object for a child iframe. If this is passed in, the script
@@ -34,7 +35,7 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 	}
 });
 =====*/
-;(function(){
+(function(){
 	var loadEvent = dojo.isIE ? "onreadystatechange" : "load",
 		readyRegExp = /complete|loaded/;
 
@@ -96,7 +97,7 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 		},
 	
 		_makeScriptDeferred: function(/*Object*/args){
-			//summary: 
+			//summary:
 			//		sets up a Deferred object for an IO request.
 			var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
 	
@@ -143,7 +144,7 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 			//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.		
+			//Add script to list of things that can be removed.
 			if(ioArgs.canDelete){
 				dojo.io.script._addDeadScript(ioArgs);
 			}
@@ -238,12 +239,15 @@ dojo.declare("dojo.io.script.__ioArgs", dojo.__IoArgs, {
 		},
 		
 		_jsonpCallback: function(/*JSON Object*/json){
-			//summary: 
+			//summary:
 			//		generic handler for jsonp callback. A pointer to this function
 			//		is used for all jsonp callbacks.  NOTE: the "this" in this
 			//		function will be the Deferred object that represents the script
 			//		request.
 			this.ioArgs.json = json;
 		}
-	}
-})();
\ No newline at end of file
+	};
+})();
+
+return dojo.io.script;
+});
diff --git a/dojo/jaxer.js b/dojo/jaxer.js
index feffcad..42de56a 100644
--- a/dojo/jaxer.js
+++ b/dojo/jaxer.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.jaxer");
+define("dojo/jaxer", ["dojo"], function(dojo) {
 
 if(typeof print == "function"){
 	console.debug = Jaxer.Log.debug;
@@ -9,3 +9,6 @@ if(typeof print == "function"){
 }
 
 onserverload = dojo._loadInit;
+
+return dojo;
+});
diff --git a/dojo/lib/backCompat.js b/dojo/lib/backCompat.js
new file mode 100644
index 0000000..0779018
--- /dev/null
+++ b/dojo/lib/backCompat.js
@@ -0,0 +1,276 @@
+// 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
new file mode 100644
index 0000000..e31eb2d
--- /dev/null
+++ b/dojo/lib/kernel.js
@@ -0,0 +1,19 @@
+// 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
new file mode 100644
index 0000000..4ee63cf
--- /dev/null
+++ b/dojo/lib/main-browser.js
@@ -0,0 +1,54 @@
+// 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
new file mode 100644
index 0000000..77c996d
--- /dev/null
+++ b/dojo/lib/plugins/i18n.js
@@ -0,0 +1,87 @@
+//
+// 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
new file mode 100644
index 0000000..2bded2d
--- /dev/null
+++ b/dojo/lib/plugins/text.js
@@ -0,0 +1,63 @@
+//
+// 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/nls/ar/colors.js b/dojo/nls/ar/colors.js
index a3306c6..7ad453f 100644
--- a/dojo/nls/ar/colors.js
+++ b/dojo/nls/ar/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "أزرق فاتح",
 antiquewhite: "أبيض عتيق",
@@ -152,3 +154,5 @@ whitesmoke: "دخان أبيض",
 yellow: "أصفر",
 yellowgreen: "أخضر مائل للأصفر"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/ca/colors.js b/dojo/nls/ca/colors.js
index 656402f..2539d8a 100644
--- a/dojo/nls/ca/colors.js
+++ b/dojo/nls/ca/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "blau cian clar",
 antiquewhite: "blanc antic",
@@ -153,3 +155,5 @@ yellow: "groc",
 yellowgreen: "verd grogós"
 })
 
+//end v1.x content
+);
diff --git a/dojo/nls/colors.js b/dojo/nls/colors.js
index 07562cc..2ce7469 100644
--- a/dojo/nls/colors.js
+++ b/dojo/nls/colors.js
@@ -1,8 +1,10 @@
+define({ root:
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "alice blue",
 antiquewhite: "antique white",
@@ -152,3 +154,35 @@ whitesmoke: "white smoke",
 yellow: "yellow",
 yellowgreen: "yellow green"
 })
+//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,
+"he": true,
+"fr": true,
+"fi": true,
+"es": true,
+"el": true,
+"de": true,
+"da": true,
+"cs": true,
+"ca": true,
+"ar": true
+});
diff --git a/dojo/nls/cs/colors.js b/dojo/nls/cs/colors.js
index cd8536c..c642555 100644
--- a/dojo/nls/cs/colors.js
+++ b/dojo/nls/cs/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "modravá",
 antiquewhite: "krémově bílá",
@@ -152,3 +154,5 @@ whitesmoke: "kouřově bílá",
 yellow: "žlutá",
 yellowgreen: "žlutozelená"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/da/colors.js b/dojo/nls/da/colors.js
index d346e56..45ddba4 100644
--- a/dojo/nls/da/colors.js
+++ b/dojo/nls/da/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "babyblå",
 antiquewhite: "antikhvid",
@@ -152,3 +154,5 @@ whitesmoke: "hvid røg",
 yellow: "gul",
 yellowgreen: "gulgrøn"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/de/colors.js b/dojo/nls/de/colors.js
index beccf65..24bfc87 100644
--- a/dojo/nls/de/colors.js
+++ b/dojo/nls/de/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "Alice-blau",
 antiquewhite: "Antikweiß",
@@ -152,3 +154,5 @@ whitesmoke: "Rauchweiß",
 yellow: "Gelb",
 yellowgreen: "Gelbgrün"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/el/colors.js b/dojo/nls/el/colors.js
index 8805ad1..277cf65 100644
--- a/dojo/nls/el/colors.js
+++ b/dojo/nls/el/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "σιέλ",
 antiquewhite: "ξεθωριασμένο λευκό",
@@ -152,3 +154,5 @@ whitesmoke: "λευκός καπνός",
 yellow: "κίτρινο",
 yellowgreen: "κιτρινοπράσινο"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/es/colors.js b/dojo/nls/es/colors.js
index 8a46937..0366f56 100644
--- a/dojo/nls/es/colors.js
+++ b/dojo/nls/es/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "blanco azulado",
 antiquewhite: "blanco antiguo",
@@ -152,3 +154,5 @@ whitesmoke: "blanco ahumado",
 yellow: "amarillo",
 yellowgreen: "verde amarillento"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/fi/colors.js b/dojo/nls/fi/colors.js
index 07562cc..08c796b 100644
--- a/dojo/nls/fi/colors.js
+++ b/dojo/nls/fi/colors.js
@@ -1,154 +1,158 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
-aliceblue: "alice blue",
-antiquewhite: "antique white",
-aqua: "aqua",
-aquamarine: "aquamarine",
-azure: "azure",
-beige: "beige",
-bisque: "bisque",
-black: "black",
-blanchedalmond: "blanched almond",
-blue: "blue",
-blueviolet: "blue-violet",
-brown: "brown",
-burlywood: "burlywood",
-cadetblue: "cadet blue",
-chartreuse: "chartreuse",
-chocolate: "chocolate",
-coral: "coral",
-cornflowerblue: "cornflower blue",
-cornsilk: "cornsilk",
-crimson: "crimson",
-cyan: "cyan",
-darkblue: "dark blue",
-darkcyan: "dark cyan",
-darkgoldenrod: "dark goldenrod",
-darkgray: "dark gray",
-darkgreen: "dark green",
-darkgrey: "dark gray", // same as darkgray
-darkkhaki: "dark khaki",
-darkmagenta: "dark magenta",
-darkolivegreen: "dark olive green",
-darkorange: "dark orange",
-darkorchid: "dark orchid",
-darkred: "dark red",
-darksalmon: "dark salmon",
-darkseagreen: "dark sea green",
-darkslateblue: "dark slate blue",
-darkslategray: "dark slate gray",
-darkslategrey: "dark slate gray", // same as darkslategray
-darkturquoise: "dark turquoise",
-darkviolet: "dark violet",
-deeppink: "deep pink",
-deepskyblue: "deep sky blue",
-dimgray: "dim gray",
-dimgrey: "dim gray", // same as dimgray
-dodgerblue: "dodger blue",
-firebrick: "fire brick",
-floralwhite: "floral white",
-forestgreen: "forest green",
-fuchsia: "fuchsia",
+aliceblue: "vaaleanharmaansininen",
+antiquewhite: "antiikinvalkoinen",
+aqua: "sinivihreä",
+aquamarine: "vedenvihreä",
+azure: "taivaansininen",
+beige: "vaaleanruskea",
+bisque: "vaaleanruskea",
+black: "musta",
+blanchedalmond: "kuorittu manteli",
+blue: "sininen",
+blueviolet: "sinivioletti",
+brown: "ruskea",
+burlywood: "puunruskea",
+cadetblue: "meren vihreä",
+chartreuse: "kellanvihreä",
+chocolate: "suklaanruskea",
+coral: "koralli",
+cornflowerblue: "syvänsininen",
+cornsilk: "maissinkeltainen",
+crimson: "karmiininpunainen",
+cyan: "syaani",
+darkblue: "tummansininen",
+darkcyan: "tumma turkoosi",
+darkgoldenrod: "tumma kultapiisku",
+darkgray: "tummanharmaa",
+darkgreen: "tummanvihreä",
+darkgrey: "tummanharmaa", // same as darkgray
+darkkhaki: "tumma khaki",
+darkmagenta: "tumma magenta",
+darkolivegreen: "tummanoliivinvihreä",
+darkorange: "tummanoranssi",
+darkorchid: "tumma orkidea",
+darkred: "tummanpunainen",
+darksalmon: "tumma lohenpunainen",
+darkseagreen: "tumma merenvihreä",
+darkslateblue: "tumma siniharmaa",
+darkslategray: "tummanharmaa",
+darkslategrey: "tummanharmaa", // same as darkslategray
+darkturquoise: "tumma turkoosi",
+darkviolet: "tummanvioletti",
+deeppink: "syvä vaaleanpunainen",
+deepskyblue: "tumma taivaansininen",
+dimgray: "himmeänharmaa",
+dimgrey: "himmeänharmaa", // same as dimgray
+dodgerblue: "Dodger-sininen",
+firebrick: "poltetun tiilen punainen",
+floralwhite: "kukanvalkoinen",
+forestgreen: "metsänvihreä",
+fuchsia: "purppura",
 gainsboro: "gainsboro",
-ghostwhite: "ghost white",
-gold: "gold",
-goldenrod: "goldenrod",
-gray: "gray",
-green: "green",
-greenyellow: "green-yellow",
-grey: "gray", // same as gray
-honeydew: "honeydew",
-hotpink: "hot pink",
-indianred: "indian red",
+ghostwhite: "lakananvalkoinen",
+gold: "kulta",
+goldenrod: "kullanruskea",
+gray: "harmaa",
+green: "vihreä",
+greenyellow: "vihreänkeltainen",
+grey: "harmaa", // same as gray
+honeydew: "hunajameloninvihreä",
+hotpink: "pinkki",
+indianred: "kirkkaanpunainen",
 indigo: "indigo",
-ivory: "ivory",
+ivory: "norsunluu",
 khaki: "khaki",
-lavender: "lavender",
-lavenderblush: "lavender blush",
-lawngreen: "lawn green",
-lemonchiffon: "lemon chiffon",
-lightblue: "light blue",
-lightcoral: "light coral",
-lightcyan: "light cyan",
-lightgoldenrodyellow: "light goldenrod yellow",
-lightgray: "light gray",
-lightgreen: "light green",
-lightgrey: "light gray", // same as lightgray
-lightpink: "light pink",
-lightsalmon: "light salmon",
-lightseagreen: "light sea green",
-lightskyblue: "light sky blue",
-lightslategray: "light slate gray",
-lightslategrey: "light slate gray", // same as lightslategray
-lightsteelblue: "light steel blue",
-lightyellow: "light yellow",
-lime: "lime",
-limegreen: "lime green",
-linen: "linen",
+lavender: "laventeli",
+lavenderblush: "laventelinpunainen",
+lawngreen: "ruohonvihreä",
+lemonchiffon: "sitruunankeltainen",
+lightblue: "vaaleansininen",
+lightcoral: "vaalea koralli",
+lightcyan: "vaalea syaani",
+lightgoldenrodyellow: "vaalea kultapiiskunkeltainen",
+lightgray: "vaaleanharmaa",
+lightgreen: "vaaleanvihreä",
+lightgrey: "vaaleanharmaa", // same as lightgray
+lightpink: "vaaleanpunainen",
+lightsalmon: "vaalea lohenpunainen",
+lightseagreen: "vaalea merenvihreä",
+lightskyblue: "vaalea taivaansininen",
+lightslategray: "vaaleanharmaa",
+lightslategrey: "vaaleanharmaa", // same as lightslategray
+lightsteelblue: "vaalea teräksensininen",
+lightyellow: "vaaleankeltainen",
+lime: "vaaleanvihreä",
+limegreen: "limetinvihreä",
+linen: "pellavanvaalea",
 magenta: "magenta",
-maroon: "maroon",
-mediumaquamarine: "medium aquamarine",
-mediumblue: "medium blue",
-mediumorchid: "medium orchid",
-mediumpurple: "medium purple",
-mediumseagreen: "medium sea green",
-mediumslateblue: "medium slate blue",
-mediumspringgreen: "medium spring green",
-mediumturquoise: "medium turquoise",
-mediumvioletred: "medium violet-red",
-midnightblue: "midnight blue",
-mintcream: "mint cream",
-mistyrose: "misty rose",
-moccasin: "moccasin",
-navajowhite: "navajo white",
-navy: "navy",
-oldlace: "old lace",
-olive: "olive",
-olivedrab: "olive drab",
-orange: "orange",
-orangered: "orange red",
-orchid: "orchid",
-palegoldenrod: "pale goldenrod",
-palegreen: "pale green",
-paleturquoise: "pale turquoise",
-palevioletred: "pale violet-red",
-papayawhip: "papaya whip",
-peachpuff: "peach puff",
+maroon: "kastanjanruskea",
+mediumaquamarine: "keskivaalea vedenvihreä",
+mediumblue: "keskisininen",
+mediumorchid: "keskivaalea orkidea",
+mediumpurple: "keskivaalea violetti",
+mediumseagreen: "keskivaalea merenvihreä",
+mediumslateblue: "keskivaalea siniharmaa",
+mediumspringgreen: "keskivaalea keväänvihreä",
+mediumturquoise: "keskivaalea turkoosi",
+mediumvioletred: "keskivaalea lila",
+midnightblue: "yönsininen",
+mintcream: "minttukreemi",
+mistyrose: "utuinen ruusu",
+moccasin: "nahanruskea",
+navajowhite: "navajonvalkoinen",
+navy: "laivastonsininen",
+oldlace: "vanha pitsi",
+olive: "oliivinvihreä",
+olivedrab: "oliivinruskea",
+orange: "oranssi",
+orangered: "oranssinpunainen",
+orchid: "orkidea",
+palegoldenrod: "haalea kultapiisku",
+palegreen: "haalea vihreä",
+paleturquoise: "haalea turkoosi",
+palevioletred: "haalea lila",
+papayawhip: "papaijavaahto",
+peachpuff: "persikka",
 peru: "peru",
-pink: "pink",
-plum: "plum",
-powderblue: "powder blue",
-purple: "purple",
-red: "red",
-rosybrown: "rosy brown",
-royalblue: "royal blue",
-saddlebrown: "saddle brown",
-salmon: "salmon",
-sandybrown: "sandy brown",
-seagreen: "sea green",
-seashell: "seashell",
-sienna: "sienna",
-silver: "silver",
-skyblue: "sky blue",
-slateblue: "slate blue",
-slategray: "slate gray",
-slategrey: "slate gray", // same as slategray
-snow: "snow",
-springgreen: "spring green",
-steelblue: "steel blue",
-tan: "tan",
-teal: "teal",
-thistle: "thistle",
-tomato: "tomato",
-turquoise: "turquoise",
-violet: "violet",
-wheat: "wheat",
-white: "white",
-whitesmoke: "white smoke",
-yellow: "yellow",
-yellowgreen: "yellow green"
+pink: "vaaleanpunainen",
+plum: "luumunpunainen",
+powderblue: "harmaansininen",
+purple: "violetti",
+red: "punainen",
+rosybrown: "punertavanruskea",
+royalblue: "syvänsininen",
+saddlebrown: "satulanruskea",
+salmon: "lohenpunainen",
+sandybrown: "hiekanruskea",
+seagreen: "merenvihreä",
+seashell: "simpukankuori",
+sienna: "siena",
+silver: "hopea",
+skyblue: "taivaansininen",
+slateblue: "savensininen",
+slategray: "savenharmaa",
+slategrey: "savenharmaa", // same as slategray
+snow: "lumivalkoinen",
+springgreen: "keväänvihreä",
+steelblue: "teräksensininen",
+tan: "kellanruskea",
+teal: "sinivihreä",
+thistle: "ohdake",
+tomato: "tomaatinpunainen",
+turquoise: "turkoosi",
+violet: "violetti",
+wheat: "vehnänkeltainen",
+white: "valkoinen",
+whitesmoke: "savunvalkea",
+yellow: "keltainen",
+yellowgreen: "kellanvihreä"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/fr/colors.js b/dojo/nls/fr/colors.js
index df31eac..e7a48bb 100644
--- a/dojo/nls/fr/colors.js
+++ b/dojo/nls/fr/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "bleu gris",
 antiquewhite: "blanc antique",
@@ -152,3 +154,5 @@ whitesmoke: "blanc cendré",
 yellow: "jaune",
 yellowgreen: "vert jaunâtre"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/he/colors.js b/dojo/nls/he/colors.js
index eaa8748..a6831a2 100644
--- a/dojo/nls/he/colors.js
+++ b/dojo/nls/he/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "כחול פלדה",
 antiquewhite: "לבן עתיק",
@@ -152,3 +154,5 @@ whitesmoke: "עשן לבן",
 yellow: "צהוב",
 yellowgreen: "ירוק צהוב"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/hu/colors.js b/dojo/nls/hu/colors.js
index b04b2c7..d34dcc0 100644
--- a/dojo/nls/hu/colors.js
+++ b/dojo/nls/hu/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "Alice kék",
 antiquewhite: "antik fehér",
@@ -152,3 +154,5 @@ whitesmoke: "fehér füst",
 yellow: "sárga",
 yellowgreen: "sárgászöld"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/it/colors.js b/dojo/nls/it/colors.js
index 7920c52..89729dd 100644
--- a/dojo/nls/it/colors.js
+++ b/dojo/nls/it/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "blu alice",
 antiquewhite: "bianco antico",
@@ -152,3 +154,5 @@ whitesmoke: "bianco fumo",
 yellow: "giallo",
 yellowgreen: "giallo verde"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/ja/colors.js b/dojo/nls/ja/colors.js
index b68b04c..166bde5 100644
--- a/dojo/nls/ja/colors.js
+++ b/dojo/nls/ja/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "アリス・ブルー",
 antiquewhite: "アンティーク・ホワイト",
@@ -152,3 +154,5 @@ whitesmoke: "ホワイト・スモーク",
 yellow: "黄",
 yellowgreen: "黄緑"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/kk/colors.js b/dojo/nls/kk/colors.js
new file mode 100644
index 0000000..edd06d5
--- /dev/null
+++ b/dojo/nls/kk/colors.js
@@ -0,0 +1,159 @@
+define(
+//begin v1.x content
+({
+// local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
+// is required for each color, such as a palette widget, and not for specifying color programatically.
+
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
+//TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
+aliceblue: "бозғылт көк",
+antiquewhite: "ақ антик",
+aqua: "су түсі",
+aquamarine: "жасылдау-көк",
+azure: "көкшіл",
+beige: "сарғыш",
+bisque: "бисквит",
+black: "қара",
+blanchedalmond: "ағартылған бадам",
+blue: "көк",
+blueviolet: "көк-ақшыл көк",
+brown: "қоңыр",
+burlywood: "ағаш тамыры",
+cadetblue: "кадет көк",
+chartreuse: "жасылдау-сары",
+chocolate: "шоколад",
+coral: "коралл",
+cornflowerblue: "көктікен көк",
+cornsilk: "жібек",
+crimson: "таңқұрай",
+cyan: "циан",
+darkblue: "күңгірт көк",
+darkcyan: "күңгірт циан",
+darkgoldenrod: "қара алтын",
+darkgray: "қою сұры",
+darkgreen: "қою жасыл",
+darkgrey: "қою сұры", // same as darkgray
+darkkhaki: "қою хаки",
+darkmagenta: "қою күлгін",
+darkolivegreen: "қою қоңырлау жасыл",
+darkorange: "қою қызғылт сары",
+darkorchid: "күңгірт орсель",
+darkred: "күңгірт қызыл",
+darksalmon: "қою сарылау қызғылт",
+darkseagreen: "қою теңіз толқыны",
+darkslateblue: "күңгірт грифель көк",
+darkslategray: "күңгірт көкшіл сұры",
+darkslategrey: "күңгірт көкшіл сұры", // same as darkslategray
+darkturquoise: "күңгірт көгілдір",
+darkviolet: "күңгірт күлгін",
+deeppink: "қою қызғылт",
+deepskyblue: "қою аспан көк",
+dimgray: "күңгірт сұры",
+dimgrey: "күңгірт сұры", // same as dimgray
+dodgerblue: "көк доджер",
+firebrick: "қызыл кірпіш",
+floralwhite: "гүлді ақ",
+forestgreen: "шөпті жасыл",
+fuchsia: "фуксия",
+gainsboro: "gainsboro",
+ghostwhite: "елесті ақ",
+gold: "сары түсті",
+goldenrod: "алтын",
+gray: "сұры",
+green: "жасыл",
+greenyellow: "жасыл-сары",
+grey: "сұры", // same as gray
+honeydew: "балдай",
+hotpink: "ашық қызғылт",
+indianred: "үнділік қызыл",
+indigo: "индиго",
+ivory: "піл сүйег",
+khaki: "хаки",
+lavender: "бозғылт ақшыл көк",
+lavenderblush: "күңгірт ақшыл қызыл",
+lawngreen: "көгал жасыл",
+lemonchiffon: "лимон шиффон",
+lightblue: "ақшыл көк",
+lightcoral: "ашық коралл",
+lightcyan: "ашық көгілдір",
+lightgoldenrodyellow: "ашық сары түсті сары",
+lightgray: "ашық сұры",
+lightgreen: "ақшыл жасыл",
+lightgrey: "ашық сұры", // same as lightgray
+lightpink: "ақшыл қызғылт",
+lightsalmon: "ашық сарғыш қызғылт",
+lightseagreen: "ашық теңіз толқыны",
+lightskyblue: "ашық аспан көк",
+lightslategray: "ашық көкшіл сұры",
+lightslategrey: "ашық көкшіл сұры", // same as lightslategray
+lightsteelblue: "ашық сұрғылт көк",
+lightyellow: "ашық сары",
+lime: "әк",
+limegreen: "әк жасыл",
+linen: "зығыр",
+magenta: "фуксин",
+maroon: "сарғылт",
+mediumaquamarine: "орташа жасылдау көк",
+mediumblue: "орташа көк",
+mediumorchid: "орташа ақшыл",
+mediumpurple: "орташа күлгін",
+mediumseagreen: "орташа теңіз толқыны",
+mediumslateblue: "орташа көкшіл сұры",
+mediumspringgreen: "орташа ашық жасыл",
+mediumturquoise: "орташа көгілдір",
+mediumvioletred: "орташа ақшыл көк-қызыл",
+midnightblue: "түн ортасы көк",
+mintcream: "жалбыз майы",
+mistyrose: "көмескі қызғылт",
+moccasin: "мокасин",
+navajowhite: "навахо ақ",
+navy: "қара-көк",
+oldlace: "ескі бау",
+olive: "зәйтүнді",
+olivedrab: "жасылдау сары",
+orange: "қызғылт сары",
+orangered: "қызғылт сары қызыл",
+orchid: "орхидея",
+palegoldenrod: "бозғылт алтын",
+palegreen: "бозғылт жасыл",
+paleturquoise: "бозғылт көгілдір",
+palevioletred: "бозғылт ақшыл көк-қызыл",
+papayawhip: "папайя қамшысы",
+peachpuff: "шабдалы",
+peru: "перу",
+pink: "қызғылт",
+plum: "алхоры",
+powderblue: "жасылдау көк",
+purple: "күлгін",
+red: "қызыл",
+rosybrown: "қызғылт қоңыр",
+royalblue: "патша көк",
+saddlebrown: "тоқым қоңыр",
+salmon: "сомон",
+sandybrown: "құмды қоңыр",
+seagreen: "теңіз толқыны",
+seashell: "теңіз қабыршағы",
+sienna: "сиенна",
+silver: "күміс түстес",
+skyblue: "аспан көк",
+slateblue: "грифель көк",
+slategray: "көкшіл сұры",
+slategrey: "көкшіл сұры", // same as slategray
+snow: "қар",
+springgreen: "көктем жасыл",
+steelblue: "көкшіл сұрғылт",
+tan: "сарғыш қоңыр",
+teal: "шүрегей",
+thistle: "артишок",
+tomato: "қызанақ",
+turquoise: "көгілдір",
+violet: "күлгін",
+wheat: "бидай",
+white: "ақ",
+whitesmoke: "ақ түтін",
+yellow: "сары",
+yellowgreen: "сарғыш жасыл"
+})
+//end v1.x content
+);
+
diff --git a/dojo/nls/ko/colors.js b/dojo/nls/ko/colors.js
index 9894a5f..3fd26f7 100644
--- a/dojo/nls/ko/colors.js
+++ b/dojo/nls/ko/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "앨리스 블루(alice blue)",
 antiquewhite: "앤틱 화이트(antique white)",
@@ -152,3 +154,5 @@ whitesmoke: "화이트 스모크(white smoke)",
 yellow: "옐로우(yellow)",
 yellowgreen: "옐로우 그린(yellow green)"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/nb/colors.js b/dojo/nls/nb/colors.js
index e347cbe..ad32efc 100644
--- a/dojo/nls/nb/colors.js
+++ b/dojo/nls/nb/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "blåhvit",
 antiquewhite: "antikk hvit",
@@ -152,3 +154,5 @@ whitesmoke: "røykhvit",
 yellow: "gul",
 yellowgreen: "gulgrønn"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/nl/colors.js b/dojo/nls/nl/colors.js
index cbcb95f..221f41a 100644
--- a/dojo/nls/nl/colors.js
+++ b/dojo/nls/nl/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "lichtblauw",
 antiquewhite: "antiekwit",
@@ -152,3 +154,5 @@ whitesmoke: "rookwit",
 yellow: "geel",
 yellowgreen: "geelgroen"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/pl/colors.js b/dojo/nls/pl/colors.js
index c4cc3cd..b8ce369 100644
--- a/dojo/nls/pl/colors.js
+++ b/dojo/nls/pl/colors.js
@@ -1,106 +1,108 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "bladoniebieski",
 antiquewhite: "biel antyczna",
-aqua: "wodny",
+aqua: "morski",
 aquamarine: "akwamaryna",
-azure: "lazur",
+azure: "lazurowy",
 beige: "beżowy",
 bisque: "biszkoptowy",
 black: "czarny",
 blanchedalmond: "migdałowy",
 blue: "niebieski",
-blueviolet: "niebieskofioletowy",
+blueviolet: "błękitnofiołkowy",
 brown: "brązowy",
 burlywood: "kolor drewna",
 cadetblue: "niebieskoszary",
-chartreuse: "jaskrawozielony",
+chartreuse: "żółtooliwkowy",
 chocolate: "czekoladowy",
 coral: "koralowy",
 cornflowerblue: "chabrowy",
 cornsilk: "kukurydziany",
 crimson: "karmazynowy",
-cyan: "cyjan",
+cyan: "niebieskozielony",
 darkblue: "ciemnoniebieski",
-darkcyan: "ciemny cyjan",
-darkgoldenrod: "ciemnogliniany",
+darkcyan: "ciemnoniebieskozielony",
+darkgoldenrod: "ciemne stare złoto",
 darkgray: "ciemnoszary",
 darkgreen: "ciemnozielony",
 darkgrey: "ciemnoszary", // same as darkgray
 darkkhaki: "ciemny khaki",
-darkmagenta: "ciemna magenta",
+darkmagenta: "ciemnoamarantowy",
 darkolivegreen: "ciemnooliwkowy",
 darkorange: "ciemnopomarańczowy",
 darkorchid: "ciemna orchidea",
 darkred: "ciemnoczerwony",
 darksalmon: "ciemnołososiowy",
-darkseagreen: "ciemna morska zieleń",
-darkslateblue: "ciemny łupkowy niebieski",
-darkslategray: "ciemny łupkowy szary",
-darkslategrey: "ciemny łupkowy szary", // same as darkslategray
-darkturquoise: "ciemnoturkusowy",
-darkviolet: "ciemnofioletowy",
+darkseagreen: "ciemna zieleń morska",
+darkslateblue: "ciemny gołębi",
+darkslategray: "ciemny mysi",
+darkslategrey: "ciemny mysi", // same as darkslategray
+darkturquoise: "mlecznoturkusowy",
+darkviolet: "ciemnofiołkowy",
 deeppink: "głęboki różowy",
 deepskyblue: "intensywny błękit nieba",
-dimgray: "przytłumiony szary",
-dimgrey: "przytłumiony szary", // same as dimgray
+dimgray: "przyciemniony szary",
+dimgrey: "przyciemniony szary", // same as dimgray
 dodgerblue: "błękit Dodgers",
 firebrick: "ceglasty",
 floralwhite: "kwiatowa biel",
 forestgreen: "leśna zieleń",
-fuchsia: "fuksja",
+fuchsia: "fuksjowy",
 gainsboro: "bladoszary",
 ghostwhite: "bladobiały",
 gold: "złoty",
-goldenrod: "gliniany",
+goldenrod: "stare złoto",
 gray: "szary",
 green: "zielony",
 greenyellow: "zielonożółty",
 grey: "szary", // same as gray
-honeydew: "melon",
-hotpink: "intensywny różowy",
+honeydew: "miodowy",
+hotpink: "odblaskoworóżowy",
 indianred: "kasztanowy",
 indigo: "indygo",
 ivory: "kość słoniowa",
 khaki: "khaki",
 lavender: "lawendowy",
-lavenderblush: "lawendoworóżowy",
+lavenderblush: "lawendowocielisty",
 lawngreen: "trawiasty",
 lemonchiffon: "cytrynowy",
 lightblue: "jasnoniebieski",
 lightcoral: "jasnokoralowy",
-lightcyan: "jasny cyjan",
-lightgoldenrodyellow: "jasnogliniana żółć",
+lightcyan: "jasnoniebieskozielony",
+lightgoldenrodyellow: "jasnożółte stare złoto",
 lightgray: "jasnoszary",
 lightgreen: "jasnozielony",
 lightgrey: "jasnoszary", // same as lightgray
 lightpink: "jasnoróżowy",
 lightsalmon: "jasnołososiowy",
-lightseagreen: "jasna morska zieleń",
+lightseagreen: "jasna zieleń morska",
 lightskyblue: "jasny błękit nieba",
-lightslategray: "jasny łupkowy szary",
-lightslategrey: "jasny łupkowy szary", // same as lightslategray
-lightsteelblue: "jasny stalowoniebieski",
+lightslategray: "jasny mysi",
+lightslategrey: "jasny mysi", // same as lightslategray
+lightsteelblue: "jasnostalowoniebieski",
 lightyellow: "jasnożółty",
-lime: "limetkowy",
-limegreen: "limetkowozielony",
+lime: "limonkowy",
+limegreen: "zielony limonkowy",
 linen: "lniany",
-magenta: "magenta",
-maroon: "bordowy",
+magenta: "amarantowy",
+maroon: "kasztanowy",
 mediumaquamarine: "średnia akwamaryna",
-mediumblue: "średni niebieski",
+mediumblue: "ciemnochabrowy",
 mediumorchid: "średnia orchidea",
-mediumpurple: "średnia purpura",
-mediumseagreen: "średnia morska zieleń",
-mediumslateblue: "średni łupkowy niebieski",
+mediumpurple: "średni fioletowy",
+mediumseagreen: "średnia zieleń morska",
+mediumslateblue: "średni gołębi",
 mediumspringgreen: "średnia wiosenna zieleń",
 mediumturquoise: "średni turkusowy",
-mediumvioletred: "średni fioletowoczerwony",
-midnightblue: "ciemnogranatowy",
+mediumvioletred: "średni fiołkowowoczerwony",
+midnightblue: "granatowoczarny",
 mintcream: "jasnomiętowy",
 mistyrose: "bladoróżany",
 moccasin: "mokasynowy",
@@ -112,43 +114,45 @@ olivedrab: "oliwkowa zieleń",
 orange: "pomarańczowy",
 orangered: "pomarańczowoczerwony",
 orchid: "orchidea",
-palegoldenrod: "bladogliniany",
+palegoldenrod: "blade stare złoto",
 palegreen: "bladozielony",
 paleturquoise: "bladoturkusowy",
-palevioletred: "blady fioletowoczerwony",
+palevioletred: "blady fiołkowoczerwony",
 papayawhip: "papaja",
 peachpuff: "brzoskwiniowy",
 peru: "jasnobrązowy",
 pink: "różowy",
 plum: "śliwkowy",
-powderblue: "pudrowy niebieski",
-purple: "purpurowy",
+powderblue: "jasnobladobłękitny",
+purple: "fioletowy",
 red: "czerwony",
 rosybrown: "różowobrązowy",
-royalblue: "błękit królewski",
-saddlebrown: "skórzany brązowy",
+royalblue: "królewski błękit",
+saddlebrown: "brąz skórzany",
 salmon: "łososiowy",
 sandybrown: "piaskowy brąz",
-seagreen: "morska zieleń",
-seashell: "muszla",
+seagreen: "zieleń morska",
+seashell: "matowoliliowy",
 sienna: "siena",
 silver: "srebrny",
 skyblue: "błękit nieba",
-slateblue: "łupkowy niebieski",
-slategray: "łupkowy szary",
-slategrey: "łupkowy szary", // same as slategray
+slateblue: "gołębi",
+slategray: "mysi",
+slategrey: "mysi", // same as slategray
 snow: "śnieżny",
 springgreen: "wiosenna zieleń",
-steelblue: "stalowy niebieski",
-tan: "kawowy",
-teal: "cyrankowy",
+steelblue: "stalowoniebieski",
+tan: "śniady",
+teal: "zielonomodry",
 thistle: "bladofioletowy",
 tomato: "pomidorowy",
 turquoise: "turkusowy",
-violet: "fioletowy",
+violet: "fiołkowy",
 wheat: "pszeniczny",
 white: "biały",
 whitesmoke: "przydymiony biały",
 yellow: "żółty",
 yellowgreen: "żółtozielony"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/pt-pt/colors.js b/dojo/nls/pt-pt/colors.js
index 62be391..0aed4f5 100644
--- a/dojo/nls/pt-pt/colors.js
+++ b/dojo/nls/pt-pt/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "azul alice",
 antiquewhite: "branco antigo",
@@ -41,13 +43,13 @@ darksalmon: "salmão escuro",
 darkseagreen: "verde marinho escuro",
 darkslateblue: "azul ardósia escuro",
 darkslategray: "cinzento ardósia escuro",
-darkslategrey: "cinzento ardósia escuro",// same as darkslategray
+darkslategrey: "cinzento ardósia escuro", // same as darkslategray
 darkturquoise: "turquesa escuro",
 darkviolet: "violeta escuro",
 deeppink: "rosa profundo",
 deepskyblue: "azul céu profundo",
-dimgray: "cinzento escuro",
-dimgrey: "cinzento escuro", // same as dimgray
+dimgray: "cinzento esbatido",
+dimgrey: "cinzento esbatido", // same as dimgray
 dodgerblue: "azul furtivo",
 firebrick: "tijolo fogo",
 floralwhite: "branco floral",
@@ -151,4 +153,6 @@ white: "branco",
 whitesmoke: "fumo branco",
 yellow: "amarelo",
 yellowgreen: "verde amarelado"
-}) 
\ No newline at end of file
+})
+//end v1.x content
+);
diff --git a/dojo/nls/pt/colors.js b/dojo/nls/pt/colors.js
index 12471fa..e58d51b 100644
--- a/dojo/nls/pt/colors.js
+++ b/dojo/nls/pt/colors.js
@@ -1,20 +1,22 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "azul alice",
 antiquewhite: "branco antigo",
 aqua: "aqua",
-aquamarine: "água-marinha",
-azure: "azul-celeste",
+aquamarine: "água marinha",
+azure: "azul celeste",
 beige: "bege",
 bisque: "bisque",
 black: "preto",
 blanchedalmond: "amêndoa pelada",
 blue: "azul",
-blueviolet: "azul-violeta",
+blueviolet: "azul violeta",
 brown: "marrom",
 burlywood: "burlywood",
 cadetblue: "azul cadet",
@@ -39,13 +41,13 @@ darkorchid: "orquídea escuro",
 darkred: "vermelho escuro",
 darksalmon: "salmão escuro",
 darkseagreen: "verde marinho escuro",
-darkslateblue: "azul-ardósia escuro",
-darkslategray: "cinza-ardósia escuro",
-darkslategrey: "cinza-ardósia escuro", // same as darkslategray
+darkslateblue: "azul ardósia escuro",
+darkslategray: "cinza ardósia escuro",
+darkslategrey: "cinza ardósia escuro", // same as darkslategray
 darkturquoise: "turquesa escuro",
 darkviolet: "violeta escuro",
 deeppink: "rosa profundo",
-deepskyblue: "azul-céu intenso",
+deepskyblue: "azul céu intenso",
 dimgray: "cinza turvo",
 dimgrey: "cinza turvo", // same as dimgray
 dodgerblue: "azul dodger",
@@ -81,25 +83,25 @@ lightgrey: "cinza claro", // same as lightgray
 lightpink: "rosa claro",
 lightsalmon: "salmão claro",
 lightseagreen: "verde marinho claro",
-lightskyblue: "azul-céu claro",
-lightslategray: "cinza-ardósia claro",
-lightslategrey: "cinza-ardósia claro", // same as lightslategray
-lightsteelblue: "azul-aço claro",
+lightskyblue: "azul céu claro",
+lightslategray: "cinza ardósia claro",
+lightslategrey: "cinza ardósia claro", // same as lightslategray
+lightsteelblue: "azul aço claro",
 lightyellow: "amarelo claro",
 lime: "lima",
-limegreen: "verde-lima",
+limegreen: "verde lima",
 linen: "linho",
 magenta: "magenta",
-maroon: "marrom",
-mediumaquamarine: "água-marinha médio",
+maroon: "castanho",
+mediumaquamarine: "água marinha médio",
 mediumblue: "azul médio",
 mediumorchid: "orquídea médio",
 mediumpurple: "roxo médio",
-mediumseagreen: "verde-marinho médio",
-mediumslateblue: "azul-ardósia médio",
-mediumspringgreen: "verde-primavera médio",
+mediumseagreen: "verde marinho médio",
+mediumslateblue: "azul ardósia médio",
+mediumspringgreen: "verde primavera médio",
 mediumturquoise: "turquesa médio",
-mediumvioletred: "vermelho-violeta médio",
+mediumvioletred: "vermelho violeta médio",
 midnightblue: "azul meia-noite",
 mintcream: "creme de menta",
 mistyrose: "rosa enevoado",
@@ -115,13 +117,13 @@ orchid: "orquídea",
 palegoldenrod: "goldenrod esbranquiçado",
 palegreen: "verde esbranquiçado",
 paleturquoise: "turquesa esbranquiçado",
-palevioletred: "vermelho-violeta esbranquiçado",
+palevioletred: "vermelho violeta esbranquiçado",
 papayawhip: "creme de papaya",
 peachpuff: "peach puff",
 peru: "peru",
 pink: "rosa",
 plum: "ameixa",
-powderblue: "azul-talco",
+powderblue: "azul talco",
 purple: "roxo",
 red: "vermelho",
 rosybrown: "marrom rosado",
@@ -129,17 +131,17 @@ royalblue: "azul royal",
 saddlebrown: "marrom saddle",
 salmon: "salmão",
 sandybrown: "marrom cor de areia",
-seagreen: "verde-marinho",
+seagreen: "verde marinho",
 seashell: "seashell",
 sienna: "sienna",
 silver: "prateado",
-skyblue: "azul-céu",
-slateblue: "azul-ardósia",
-slategray: "cinza-ardósia",
-slategrey: "cinza-ardósia", // same as slategray
+skyblue: "azul céu",
+slateblue: "azul ardósia",
+slategray: "cinza ardósia",
+slategrey: "cinza ardósia", // same as slategray
 snow: "branco neve",
 springgreen: "verde primavera",
-steelblue: "azul-aço",
+steelblue: "azul aço",
 tan: "tan",
 teal: "azul esverdeado",
 thistle: "thistle",
@@ -152,3 +154,5 @@ whitesmoke: "fumaça branca",
 yellow: "amarelo",
 yellowgreen: "verde amarelado"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/ro/colors.js b/dojo/nls/ro/colors.js
index 52a05a4..6b27c40 100644
--- a/dojo/nls/ro/colors.js
+++ b/dojo/nls/ro/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "alice blue",
 antiquewhite: "antique white",
@@ -153,3 +155,5 @@ yellow: "galben",
 yellowgreen: "verde galben"
 })
 
+//end v1.x content
+);
diff --git a/dojo/nls/ru/colors.js b/dojo/nls/ru/colors.js
index ce0b438..019b2ef 100644
--- a/dojo/nls/ru/colors.js
+++ b/dojo/nls/ru/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "серо-голубой",
 antiquewhite: "белый антик",
@@ -152,3 +154,5 @@ whitesmoke: "дымчато-белый",
 yellow: "желтый",
 yellowgreen: "желто-зеленый"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/sk/colors.js b/dojo/nls/sk/colors.js
index b290091..f362f8e 100644
--- a/dojo/nls/sk/colors.js
+++ b/dojo/nls/sk/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "modrá alice",
 antiquewhite: "antická biela",
@@ -153,3 +155,5 @@ yellow: "žltá",
 yellowgreen: "žltozelená"
 })
 
+//end v1.x content
+);
diff --git a/dojo/nls/sl/colors.js b/dojo/nls/sl/colors.js
index c0ecbf3..dd4d805 100644
--- a/dojo/nls/sl/colors.js
+++ b/dojo/nls/sl/colors.js
@@ -1,41 +1,43 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray 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 modra",
+aliceblue: "alice blue modra",
 antiquewhite: "antično bela",
 aqua: "akva",
 aquamarine: "akvamarin",
-azure: "azurna",
+azure: "azurno modra",
 beige: "bež",
 bisque: "porcelanasta",
 black: "črna",
-blanchedalmond: "mandljeva",
+blanchedalmond: "obledelo mandljeva",
 blue: "modra",
 blueviolet: "modro vijolična",
 brown: "rjava",
-burlywood: "grčav les",
-cadetblue: "zelenkasto modra",
-chartreuse: "svetlo rumena zelena",
+burlywood: "peščeno sivo-rjava",
+cadetblue: "kadetsko modra",
+chartreuse: "chartreuse",
 chocolate: "čokoladna",
 coral: "koralna",
-cornflowerblue: "plavično modra",
-cornsilk: "koruzni laski",
+cornflowerblue: "plavičasto modra",
+cornsilk: "koruzna",
 crimson: "karminasta",
 cyan: "cijan",
 darkblue: "temno modra",
 darkcyan: "temno cijan",
-darkgoldenrod: "temno zlata rozga",
+darkgoldenrod: "temna zlata rozga",
 darkgray: "temno siva",
 darkgreen: "temno zelena",
 darkgrey: "temno siva", // same as darkgray
-darkkhaki: "temno rumenkasto rjava",
-darkmagenta: "temno magenta",
-darkolivegreen: "temno olivno zelena",
+darkkhaki: "temno kaki",
+darkmagenta: "temna magenta",
+darkolivegreen: "temna olivno zelena",
 darkorange: "temno oranžna",
-darkorchid: "temno orhidejna",
+darkorchid: "temno orhidejasta",
 darkred: "temno rdeča",
 darksalmon: "temno lososova",
 darkseagreen: "temno morsko zelena",
@@ -44,17 +46,17 @@ darkslategray: "temno skrilasto siva",
 darkslategrey: "temno skrilasto siva", // same as darkslategray
 darkturquoise: "temno turkizna",
 darkviolet: "temno vijolična",
-deeppink: "temno roza",
-deepskyblue: "temno nebesno modra",
-dimgray: "umazano siva",
-dimgrey: "umazano siva", // same as dimgray
-dodgerblue: "koruzno modra",
+deeppink: "temno rožnata",
+deepskyblue: "temno nebeško modra",
+dimgray: "pepelnato siva",
+dimgrey: "pepelnato siva", // same as dimgray
+dodgerblue: "dodgersko modra",
 firebrick: "opečnata",
 floralwhite: "cvetno bela",
 forestgreen: "gozdno zelena",
 fuchsia: "fuksija",
-gainsboro: "pepelnato siva",
-ghostwhite: "prosojno bela",
+gainsboro: "gainsboro",
+ghostwhite: "senčnato bela",
 gold: "zlata",
 goldenrod: "zlata rozga",
 gray: "siva",
@@ -62,15 +64,15 @@ green: "zelena",
 greenyellow: "zeleno-rumena",
 grey: "siva", // same as gray
 honeydew: "medena rosa",
-hotpink: "živo roza",
+hotpink: "kričeče rožnata",
 indianred: "indijansko rdeča",
 indigo: "indigo",
 ivory: "slonokoščena",
-khaki: "rumenkasto rjava",
+khaki: "kaki",
 lavender: "sivka",
-lavenderblush: "bleščeča sivka",
-lawngreen: "travnato zelena",
-lemonchiffon: "limonina",
+lavenderblush: "rožnato sivka",
+lawngreen: "travniško zelena",
+lemonchiffon: "limonast šifon",
 lightblue: "svetlo modra",
 lightcoral: "svetlo koralna",
 lightcyan: "svetlo cijan",
@@ -78,40 +80,40 @@ lightgoldenrodyellow: "svetlo rumena zlata rozga",
 lightgray: "svetlo siva",
 lightgreen: "svetlo zelena",
 lightgrey: "svetlo siva", // same as lightgray
-lightpink: "svetlo roza",
+lightpink: "svetlo rožnata",
 lightsalmon: "svetlo lososova",
 lightseagreen: "svetlo morsko zelena",
-lightskyblue: "svetlo nebesno modra",
+lightskyblue: "svetlo nebeško modra",
 lightslategray: "svetlo skrilasto siva",
 lightslategrey: "svetlo skrilasto siva", // same as lightslategray
-lightsteelblue: "svetlo jeklena modra",
+lightsteelblue: "svetlo kovinsko modra",
 lightyellow: "svetlo rumena",
-lime: "rumeno zelena",
-limegreen: "citronsko zelena",
+lime: "limetasta",
+limegreen: "apneno zelena",
 linen: "lanena",
 magenta: "magenta",
 maroon: "kostanjeva",
-mediumaquamarine: "srednje akvamarin",
+mediumaquamarine: "srednji akvamarin",
 mediumblue: "srednje modra",
-mediumorchid: "srednje orhidejna",
+mediumorchid: "srednje orhidejasta",
 mediumpurple: "srednje škrlatna",
 mediumseagreen: "srednje morsko zelena",
 mediumslateblue: "srednje skrilasto modra",
 mediumspringgreen: "srednje pomladno zelena",
 mediumturquoise: "srednje turkizna",
-mediumvioletred: "srednje vijolično-rdeča",
+mediumvioletred: "srednje vijolično rdeča",
 midnightblue: "polnočno modra",
-mintcream: "mentolno smetanasta",
+mintcream: "metina krema",
 mistyrose: "megleno rožnata",
 moccasin: "mokasinasta",
-navajowhite: "navajsko bela",
-navy: "mornarsko modra",
+navajowhite: "navajo bela",
+navy: "mornarska",
 oldlace: "stara čipka",
 olive: "olivna",
-olivedrab: "olivno sivo rjava",
+olivedrab: "umazano olivna",
 orange: "oranžna",
 orangered: "oranžno-rdeča",
-orchid: "orhidejna",
+orchid: "orhidejasta",
 palegoldenrod: "bleda zlata rozga",
 palegreen: "bledo zelena",
 paleturquoise: "bledo turkizna",
@@ -119,9 +121,9 @@ palevioletred: "bledo vijolično-rdeča",
 papayawhip: "papaja",
 peachpuff: "breskova",
 peru: "perujska",
-pink: "roza",
+pink: "rožnata",
 plum: "slivova",
-powderblue: "smodniško modra",
+powderblue: "kobaltovo modra",
 purple: "škrlatna",
 red: "rdeča",
 rosybrown: "rožnato rjava",
@@ -130,26 +132,27 @@ saddlebrown: "sedlasto rjava",
 salmon: "lososova",
 sandybrown: "peščeno rjava",
 seagreen: "morsko zelena",
-seashell: "morska školjka",
-sienna: "siena",
+seashell: "morska lupina",
+sienna: "sienna",
 silver: "srebrna",
-skyblue: "nebesno modra",
+skyblue: "nebeško modra",
 slateblue: "skrilasto modra",
 slategray: "skrilasto siva",
 slategrey: "skrilasto siva", // same as slategray
 snow: "snežena",
 springgreen: "pomladno zelena",
-steelblue: "jekleno modra",
-tan: "kožno rjava",
-teal: "zeleno modra",
+steelblue: "kovinsko modra",
+tan: "rumeno-rjava",
+teal: "modrozelena",
 thistle: "osatna",
 tomato: "paradižnikova",
 turquoise: "turkizna",
 violet: "vijolična",
-wheat: "žitna",
+wheat: "pšenična",
 white: "bela",
-whitesmoke: "umazano bela",
+whitesmoke: "megleno bela",
 yellow: "rumena",
-yellowgreen: "rumeno zelena"
+yellowgreen: "rumeno-zelena"
 })
-
+//end v1.x content
+);
diff --git a/dojo/nls/sv/colors.js b/dojo/nls/sv/colors.js
index 5121db0..7041399 100644
--- a/dojo/nls/sv/colors.js
+++ b/dojo/nls/sv/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "aliceblå",
 antiquewhite: "antikvitt",
@@ -152,3 +154,5 @@ whitesmoke: "vit rök",
 yellow: "gult",
 yellowgreen: "gulgrönt"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/th/colors.js b/dojo/nls/th/colors.js
index e06c805..71576d3 100644
--- a/dojo/nls/th/colors.js
+++ b/dojo/nls/th/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "alice blue",
 antiquewhite: "antique white",
@@ -153,3 +155,5 @@ yellow: "เหลือง",
 yellowgreen: "เหลืองแกมเขียว"
 })
 
+//end v1.x content
+);
diff --git a/dojo/nls/tr/colors.js b/dojo/nls/tr/colors.js
index 027b679..9c422eb 100644
--- a/dojo/nls/tr/colors.js
+++ b/dojo/nls/tr/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "alice mavisi",
 antiquewhite: "antik beyaz",
@@ -152,3 +154,5 @@ whitesmoke: "beyaz duman",
 yellow: "sarı",
 yellowgreen: "sarı yeşil"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/zh-tw/colors.js b/dojo/nls/zh-tw/colors.js
index 336e713..aaba93b 100644
--- a/dojo/nls/zh-tw/colors.js
+++ b/dojo/nls/zh-tw/colors.js
@@ -1,8 +1,10 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray.
 //TODO: should we be using unique rgb values as keys instead and avoid these duplicates, or rely on the caller to do the reverse mapping?
 aliceblue: "愛麗絲藍",
 antiquewhite: "米白色",
@@ -152,3 +154,5 @@ whitesmoke: "白煙色",
 yellow: "黃色",
 yellowgreen: "黃綠色"
 })
+//end v1.x content
+);
diff --git a/dojo/nls/zh/colors.js b/dojo/nls/zh/colors.js
index c14cfb6..acea325 100644
--- a/dojo/nls/zh/colors.js
+++ b/dojo/nls/zh/colors.js
@@ -1,154 +1,158 @@
+define(
+//begin v1.x content
 ({
 // local representation of all CSS3 named colors, companion to dojo.colors.  To be used where descriptive information
 // is required for each color, such as a palette widget, and not for specifying color programatically.
 
-//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray vs. gray. 
+//Note: due to the SVG 1.0 spec additions, some of these are alternate spellings for the same color e.g. gray 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: "爱丽丝蓝",
+aliceblue: "艾莉斯蓝",
 antiquewhite: "古董白",
-aqua: "浅绿色",
+aqua: "水绿色",
 aquamarine: "碧绿色",
-azure: "天蓝色",
+azure: "浅天蓝",
 beige: "米色",
-bisque: "桔黄色",
+bisque: "乳黄色",
 black: "黑色",
-blanchedalmond: "白杏色",
+blanchedalmond: "杏仁白",
 blue: "蓝色",
 blueviolet: "蓝紫色",
-brown: "棕色",
-burlywood: "实木色",
-cadetblue: "灰蓝色",
-chartreuse: "黄绿色",
+brown: "褐色",
+burlywood: "原木色",
+cadetblue: "军队蓝",
+chartreuse: "浅黄绿色",
 chocolate: "巧克力色",
-coral: "珊瑚色",
-cornflowerblue: "浅蓝色",
-cornsilk: "米绸色",
+coral: "珊瑚红",
+cornflowerblue: "藏蓝色",
+cornsilk: "玉米黄",
 crimson: "绯红色",
-cyan: "青蓝色",
-darkblue: "深蓝",
-darkcyan: "深青绿",
-darkgoldenrod: "深金黄",
+cyan: "青色",
+darkblue: "深蓝色",
+darkcyan: "深青色",
+darkgoldenrod: "深金黄色",
 darkgray: "深灰色",
 darkgreen: "深绿色",
 darkgrey: "深灰色", // same as darkgray
-darkkhaki: "深卡其色",
+darkkhaki: "深褐色",
 darkmagenta: "深洋红色",
-darkolivegreen: "深橄榄绿",
+darkolivegreen: "深橄榄绿色",
 darkorange: "深橙色",
-darkorchid: "深紫色",
+darkorchid: "暗兰花紫",
 darkred: "深红色",
 darksalmon: "深橙红",
-darkseagreen: "深海藻绿",
-darkslateblue: "深青蓝",
-darkslategray: "深青灰",
-darkslategrey: "深青灰", // same as darkslategray
-darkturquoise: "深粉蓝",
-darkviolet: "深紫色",
-deeppink: "深粉红色",
+darkseagreen: "深海绿色",
+darkslateblue: "深石板蓝",
+darkslategray: "深石板灰",
+darkslategrey: "深石板灰", // same as darkslategray
+darkturquoise: "深青绿色",
+darkviolet: "深紫罗兰",
+deeppink: "深粉色",
 deepskyblue: "深天蓝色",
 dimgray: "暗灰色",
 dimgrey: "暗灰色", // same as dimgray
-dodgerblue: "闪蓝色",
-firebrick: "砖红",
-floralwhite: "花白色",
+dodgerblue: "宝蓝",
+firebrick: "砖红色",
+floralwhite: "花白",
 forestgreen: "森林绿",
 fuchsia: "紫红色",
-gainsboro: "淡灰色",
+gainsboro: "亮灰色",
 ghostwhite: "苍白",
 gold: "金黄色",
-goldenrod: "金麒麟色",
+goldenrod: "鲜黄",
 gray: "灰色",
 green: "绿色",
 greenyellow: "绿黄色",
 grey: "灰色", // same as gray
-honeydew: "蜜汁色",
-hotpink: "深粉红",
+honeydew: "蜜色",
+hotpink: "暗粉",
 indianred: "印度红",
-indigo: "靛青",
+indigo: "靛蓝色",
 ivory: "象牙色",
-khaki: "卡其色",
+khaki: "黄褐色",
 lavender: "淡紫色",
-lavenderblush: "淡紫红",
+lavenderblush: "淡紫红色",
 lawngreen: "草绿色",
-lemonchiffon: "柠檬绸色",
+lemonchiffon: "柠檬色",
 lightblue: "淡蓝色",
-lightcoral: "浅珊瑚色",
+lightcoral: "浅珊瑚红",
 lightcyan: "浅青色",
 lightgoldenrodyellow: "浅金黄色",
 lightgray: "浅灰色",
 lightgreen: "浅绿色",
 lightgrey: "浅灰色", // same as lightgray
-lightpink: "浅粉红色",
-lightsalmon: "淡橙色",
-lightseagreen: "浅海藻绿",
+lightpink: "浅粉色",
+lightsalmon: "浅橙红色",
+lightseagreen: "浅海绿色",
 lightskyblue: "浅天蓝色",
-lightslategray: "浅青灰",
-lightslategrey: "浅青灰", // same as lightslategray
+lightslategray: "浅石板灰",
+lightslategrey: "浅石板灰", // same as lightslategray
 lightsteelblue: "浅钢蓝色",
 lightyellow: "浅黄色",
-lime: "淡黄绿色",
-limegreen: "橙绿色",
-linen: "亚麻色",
+lime: "酸橙色",
+limegreen: "暗黄绿色",
+linen: "亚麻布色",
 magenta: "洋红色",
-maroon: "栗色",
-mediumaquamarine: "间绿色",
-mediumblue: "间蓝色",
-mediumorchid: "间紫色",
-mediumpurple: "间紫色",
-mediumseagreen: "间海蓝色",
-mediumslateblue: "间暗蓝色",
-mediumspringgreen: "间春绿色",
-mediumturquoise: "间绿宝石色",
-mediumvioletred: "间紫罗兰色",
-midnightblue: "深蓝色",
-mintcream: "薄荷色",
-mistyrose: "浅玫瑰色",
-moccasin: "鹿皮色",
-navajowhite: "纳瓦白",
+maroon: "褐紫红色",
+mediumaquamarine: "淡碧绿色",
+mediumblue: "淡蓝色",
+mediumorchid: "淡兰花紫",
+mediumpurple: "淡紫色",
+mediumseagreen: "淡海绿色",
+mediumslateblue: "淡灰蓝色",
+mediumspringgreen: "淡草绿色",
+mediumturquoise: "淡青绿色",
+mediumvioletred: "淡紫罗兰",
+midnightblue: "蓝黑色",
+mintcream: "薄荷乳白",
+mistyrose: "粉红玫瑰",
+moccasin: "鹿皮黄",
+navajowhite: "印地安黄",
 navy: "藏青色",
-oldlace: "老白色",
-olive: "橄榄绿",
-olivedrab: "草绿色",
+oldlace: "旧布黄",
+olive: "橄榄色",
+olivedrab: "暗橄榄色",
 orange: "橙色",
-orangered: "橙红色",
-orchid: "紫色",
-palegoldenrod: "淡金黄色",
+orangered: "桔红色",
+orchid: "兰花紫",
+palegoldenrod: "浅金黄色",
 palegreen: "淡绿色",
-paleturquoise: "苍绿色",
-palevioletred: "苍紫罗兰色",
-papayawhip: "木瓜色",
-peachpuff: "桃色",
-peru: "秘鲁色",
+paleturquoise: "淡青绿色",
+palevioletred: "浅紫罗兰",
+papayawhip: "粉木瓜橙",
+peachpuff: "粉桃红",
+peru: "秘鲁棕",
 pink: "粉红色",
-plum: "杨李色",
-powderblue: "铁蓝",
+plum: "梅红色",
+powderblue: "粉蓝色",
 purple: "紫色",
 red: "红色",
-rosybrown: "褐玫瑰红",
-royalblue: "品蓝",
-saddlebrown: "重褐色",
-salmon: "橙红",
-sandybrown: "沙褐色",
+rosybrown: "玫瑰褐色",
+royalblue: "亮蓝色",
+saddlebrown: "鞍具褐色",
+salmon: "橙红色",
+sandybrown: "浅褐色",
 seagreen: "海绿色",
-seashell: "海贝色",
+seashell: "贝壳白",
 sienna: "赭色",
 silver: "银白色",
 skyblue: "天蓝色",
-slateblue: "石蓝色",
-slategray: "灰石色",
-slategrey: "灰石色", // same as slategray
-snow: "雪白色",
-springgreen: "春绿色",
+slateblue: "石板蓝",
+slategray: "石板灰",
+slategrey: "石板灰", // same as slategray
+snow: "雪白",
+springgreen: "浅草绿色",
 steelblue: "钢蓝色",
-tan: "棕褐色",
-teal: "水鸭色",
+tan: "茶色",
+teal: "青色",
 thistle: "蓟色",
-tomato: "西红柿色",
-turquoise: "绿宝石色",
-violet: "紫色",
-wheat: "浅黄色",
+tomato: "番茄色",
+turquoise: "青绿色",
+violet: "紫罗兰色",
+wheat: "淡黄色",
 white: "白色",
 whitesmoke: "烟白色",
 yellow: "黄色",
 yellowgreen: "黄绿色"
 })
+//end v1.x content
+);
diff --git a/dojo/number.js b/dojo/number.js
index b83d121..b0a09af 100644
--- a/dojo/number.js
+++ b/dojo/number.js
@@ -1,10 +1,5 @@
-dojo.provide("dojo.number");
-
-dojo.require("dojo.i18n");
-dojo.requireLocalization("dojo.cldr", "number");
-dojo.require("dojo.string");
-dojo.require("dojo.regexp");
-
+define("dojo/number", ["dojo", "dojo/i18n", "i18n!dojo/cldr/nls/number", "dojo/string", "dojo/regexp"], function(dojo) {
+dojo.getObject("number", true, dojo);
 
 /*=====
 dojo.number = {
@@ -109,7 +104,7 @@ dojo.number._applyPattern = function(/*Number*/value, /*String*/pattern, /*dojo.
 	if(options.fractional === false){ options.places = 0; }
 	return pattern.replace(numberPatternRE,
 		dojo.number._formatAbsolute(value, numberPattern[0], {decimal: decimal, group: group, places: options.places, round: options.round}));
-}
+};
 
 dojo.number.round = function(/*Number*/value, /*Number?*/places, /*Number?*/increment){
 	//	summary:
@@ -135,7 +130,7 @@ dojo.number.round = function(/*Number*/value, /*Number?*/places, /*Number?*/incr
 	//		10.75
 	var factor = 10 / (increment || 10);
 	return (factor * +value).toFixed(places) / factor; // Number
-}
+};
 
 if((0.9).toFixed() == 0){
 	// (isIE) toFixed() bug workaround: Rounding fails on IE when most significant digit
@@ -148,7 +143,7 @@ if((0.9).toFixed() == 0){
 				d = 0;
 			}
 			return round(v, p, m) + (v > 0 ? d : -d);
-		}
+		};
 	})();
 }
 
@@ -171,7 +166,7 @@ dojo.number.__FormatAbsoluteOptions = function(){
 =====*/
 
 dojo.number._formatAbsolute = function(/*Number*/value, /*String*/pattern, /*dojo.number.__FormatAbsoluteOptions?*/options){
-	// summary: 
+	// summary:
 	//		Apply numeric pattern to absolute value using options. Gives no
 	//		consideration to local customs.
 	// value:
@@ -286,7 +281,7 @@ dojo.number.regexp = function(/*dojo.number.__RegexpOptions?*/options){
 	//		Returns regular expression with positive and negative match, group
 	//		and decimal separators
 	return dojo.number._parseInfo(options).regexp; // String
-}
+};
 
 dojo.number._parseInfo = function(/*Object?*/options){
 	options = options || {};
@@ -374,7 +369,7 @@ dojo.number._parseInfo = function(/*Object?*/options){
 
 	// normalize whitespace and return
 	return {regexp: re.replace(/[\xa0 ]/g, "[\\s\\xa0]"), group: group, decimal: decimal, factor: factor}; // Object
-}
+};
 
 /*=====
 dojo.number.__ParseOptions = function(){
@@ -485,10 +480,10 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 			var re = "";
 			if(q && (flags.places!==0)){
 				re = "\\" + flags.decimal;
-				if(flags.places == Infinity){ 
-					re = "(?:" + re + "\\d+)?"; 
+				if(flags.places == Infinity){
+					re = "(?:" + re + "\\d+)?";
 				}else{
-					re += "\\d{" + flags.places + "}"; 
+					re += "\\d{" + flags.places + "}";
 				}
 			}
 			return re;
@@ -497,9 +492,9 @@ dojo.number._realNumberRegexp = function(/*dojo.number.__RealNumberRegexpFlags?*
 	);
 
 	var exponentRE = dojo.regexp.buildGroupRE(flags.exponent,
-		function(q){ 
+		function(q){
 			if(q){ return "([eE]" + dojo.number._integerRegexp({ signed: flags.eSigned}) + ")"; }
-			return ""; 
+			return "";
 		}
 	);
 
@@ -531,7 +526,7 @@ dojo.number.__IntegerRegexpFlags = function(){
 =====*/
 
 dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags){
-	// summary: 
+	// summary:
 	//		Builds a regular expression that matches an integer
 
 	// assign default values to missing parameters
@@ -570,4 +565,7 @@ dojo.number._integerRegexp = function(/*dojo.number.__IntegerRegexpFlags?*/flags
 	);
 
 	return signRE + numberRE; // String
-}
+};
+
+return dojo.number;
+});
diff --git a/dojo/package.json b/dojo/package.json
new file mode 100644
index 0000000..5855be5
--- /dev/null
+++ b/dojo/package.json
@@ -0,0 +1,21 @@
+{
+  "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
diff --git a/dojo/parser.js b/dojo/parser.js
index 08dea88..b151c2a 100644
--- a/dojo/parser.js
+++ b/dojo/parser.js
@@ -1,14 +1,12 @@
-dojo.provide("dojo.parser");
-dojo.require("dojo.date.stamp");
+define("dojo/parser", ["dojo", "dojo/date/stamp"], function(dojo) {
 
 new Date("X"); // workaround for #11279, new Date("") == NaN
 
 dojo.parser = new function(){
-	// summary: The Dom/Widget parsing package
+	// summary:
+	//		The Dom/Widget parsing package
 
 	var d = dojo;
-	this._attrName = d._scopeName + "Type";
-	this._query = "[" + this._attrName + "]";
 
 	function val2type(/*Object*/ value){
 		// summary:
@@ -33,13 +31,13 @@ dojo.parser = new function(){
 			case "number":
 				return value.length ? Number(value) : NaN;
 			case "boolean":
-				// for checked/disabled value might be "" or "checked".  interpret as true.
+				// 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
+					// (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));
 				}
@@ -68,7 +66,7 @@ dojo.parser = new function(){
 		}
 	}
 
-	var instanceClasses = {
+	var dummyClass = {}, instanceClasses = {
 		// map from fully qualified name (like "dijit.Button") to structure like
 		// { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
 	};
@@ -76,45 +74,70 @@ dojo.parser = new function(){
 	// 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).
-	dojo.connect(dojo, "extend", function(){
+	// TODO: remove this in 2.0, when we stop caching parameters.
+	d.connect(d, "extend", function(){
 		instanceClasses = {};
 	});
 
-	function getClassInfo(/*String*/ className){
+	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;
+	}
+
+	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, 
+		//			{
+		//				cls: dijit.Button,
 		//				params: { label: "string", disabled: "boolean"}
 		//			}
 
-		if(!instanceClasses[className]){
+		var c = instanceClasses[className];
+		if(!c){
 			// get pointer to widget class
-			var cls = d.getObject(className);
+			var cls = d.getObject(className), params = null;
 			if(!cls){ return null; }		// class not defined [yet]
-
-			var proto = cls.prototype;
-	
-			// get table of parameter names & types
-			var params = {}, dummyClass = {};
-			for(var name in proto){
-				if(name.charAt(0)=="_"){ continue; } 	// skip internal properties
-				if(name in dummyClass){ continue; }		// skip "constructor" and "toString"
-				var defVal = proto[name];
-				params[name]=val2type(defVal);
+			if(!skipParamsLookup){ // from fastpath, we don't need to lookup the attrs on the proto because they are explicit
+				params = getProtoInfo(cls.prototype, {})
 			}
-
-			instanceClasses[className] = { cls: cls, params: params };
+			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 instanceClasses[className];
+		
+		return c;
 	}
 
-	this._functionFromScript = function(script){
+	this._functionFromScript = function(script, attrData){
+		// summary:
+		//		Convert a <script type="dojo/method" args="a, b, c"> ... </script>
+		//		into a function
+		// script: DOMNode
+		//		The <script> DOMNode
+		// attrData: String
+		//		For HTML5 compliance, searches for attrData + "args" (typically
+		//		"data-dojo-args") instead of "args"
 		var preamble = "";
 		var suffix = "";
-		var argsStr = script.getAttribute("args");
+		var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
 		if(argsStr){
 			d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
 				preamble += "var "+part+" = arguments["+idx+"]; ";
@@ -128,7 +151,7 @@ dojo.parser = new function(){
 			});
 		}
 		return new Function(preamble+script.innerHTML+suffix);
-	}
+	};
 
 	this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
 		// summary:
@@ -149,69 +172,106 @@ dojo.parser = new function(){
 		//		exist.
 		// args: Object?
 		//		An object used to hold kwArgs for instantiation.
-		//		Supports 'noStart' and inherited.
-		var thelist = [], dp = dojo.parser;
+		//		See parse.args argument for details.
+
+		var thelist = [],
 		mixin = mixin||{};
 		args = args||{};
-		
+
+		// 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-"
+
 		d.forEach(nodes, function(obj){
 			if(!obj){ return; }
 
-			// Get pointers to DOMNode, dojoType string, and clsInfo (metadata about the dojoType), etc.s
-			var node, type, clsInfo, clazz, scripts;
+			// 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;
-				clsInfo = obj.clsInfo || (type && getClassInfo(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
+				// old (backwards compatible) format of nodes[] array, simple array of DOMNodes. no fastpath/data-dojo-type support here.
 				node = obj;
-				type = dp._attrName in mixin ? mixin[dp._attrName] : node.getAttribute(dp._attrName);
+				type = attrName in mixin ? mixin[attrName] : node.getAttribute(attrName);
 				clsInfo = type && getClassInfo(type);
 				clazz = clsInfo && clsInfo.cls;
-				scripts = (clazz && (clazz._noScript || clazz.prototype._noScript) ? [] : 
+				scripts = (clazz && (clazz._noScript || clazz.prototype._noScript) ? [] :
 							d.query("> script[type^='dojo/']", node));
 			}
 			if(!clsInfo){
 				throw new Error("Could not load class '" + type);
 			}
 
-			// Setup hash to hold parameter settings for this widget.   Start with the parameter
+			// Setup hash to hold parameter settings for this widget.	Start with the parameter
 			// settings inherited from ancestors ("dir" and "lang").
 			// Inherited setting may later be overridden by explicit settings on node itself.
-			var params = {},
-				attributes = node.attributes;
+			var params = {};
+				
 			if(args.defaults){
 				// settings for the document itself (or whatever subtree is being parsed)
-				dojo.mixin(params, args.defaults);
+				d._mixin(params, args.defaults);
 			}
 			if(obj.inherited){
 				// settings from dir=rtl or lang=... on a node above this node
-				dojo.mixin(params, obj.inherited);
+				d._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 + "'");
+					}
+				}
 
-			// read parameters (ie, attributes) specified on DOMNode
-			// 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){
-				case "class":
-					value = "className" in mixin?mixin.className:node.className;
-					break;
-				case "style":
-					value = "style" in mixin?mixin.style:(node.style && node.style.cssText); // FIXME: Opera?
+				// 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 _type = clsInfo.params[name];
-				if(typeof value == "string"){
-					params[name] = str2obj(value, _type);
-				}else{
-					params[name] = value;
+				var attachEvent = node.getAttribute(attrData + "attach-event");
+				if(attachEvent){
+					params.dojoAttachEvent = attachEvent;
+				}
+				dojo.mixin(params, mixin);
+			}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){
+					case "class":
+						value = "className" in mixin ? mixin.className : node.className;
+						break;
+					case "style":
+						value = "style" in mixin ? mixin.style : (node.style && node.style.cssText); // FIXME: Opera?
+					}
+					var _type = clsInfo.params[name];
+					if(typeof value == "string"){
+						params[name] = str2obj(value, _type);
+					}else{
+						params[name] = value;
+					}
 				}
 			}
 
@@ -226,9 +286,10 @@ dojo.parser = new function(){
 
 			d.forEach(scripts, function(script){
 				node.removeChild(script);
-				var event = script.getAttribute("event"),
+				// 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);
+					nf = d.parser._functionFromScript(script, attrData);
 				if(event){
 					if(type == "dojo/connect"){
 						connects.push({event: event, func: nf});
@@ -246,7 +307,8 @@ dojo.parser = new function(){
 			thelist.push(instance);
 
 			// map it to the JS namespace if that makes sense
-			var jsname = node.getAttribute("jsId");
+			// 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);
 			}
@@ -270,9 +332,9 @@ dojo.parser = new function(){
 			// ContentPane is the parent widget (so that the parse doesn't call startup() on the
 			// ContentPane's children)
 			d.forEach(thelist, function(instance){
-				if(	!args.noStart && instance  && 
-					instance.startup &&
-					!instance._started && 
+				if( !args.noStart && instance  &&
+					dojo.isFunction(instance.startup) &&
+					!instance._started &&
 					(!instance.getParent || !instance.getParent())
 				){
 					instance.startup();
@@ -282,34 +344,57 @@ dojo.parser = new function(){
 		return thelist;
 	};
 
-	this.parse = function(/*DomNode?*/ rootNode, /* Object? */ args){
+	this.parse = function(rootNode, args){
 		// summary:
 		//		Scan the DOM for class instances, and instantiate them.
 		//
 		// description:
 		//		Search specified node (or root node) recursively for class instances,
-		//		and instantiate them Searches for
-		//		dojoType="qualified.class.name"
+		//		and instantiate them. Searches for either data-dojo-type="Class" or
+		//		dojoType="Class" where "Class" is a a fully qualified class name,
+		//		like `dijit.form.Button`
+		//
+		//		Using `data-dojo-type`:
+		//		Attributes using can be mixed into the parameters used to instantitate the
+		//		Class by using a `data-dojo-props` attribute on the node being converted.
+		//		`data-dojo-props` should be a string attribute to be converted from JSON.
+		//
+		//		Using `dojoType`:
+		//		Attributes are read from the original domNode and converted to appropriate
+		//		types by looking up the Class prototype values. This is the default behavior
+		//		from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
+		//		go away in Dojo 2.0.
 		//
 		// rootNode: DomNode?
 		//		A default starting root node from which to start the parsing. Can be
 		//		omitted, defaulting to the entire document. If omitted, the `args`
-		//		object can be passed in this place. If the `args` object has a 
+		//		object can be passed in this place. If the `args` object has a
 		//		`rootNode` member, that is used.
 		//
-		// args:
+		// args: Object
 		//		a kwArgs object passed along to instantiate()
-		//		
+		//
 		//			* noStart: Boolean?
 		//				when set will prevent the parser from calling .startup()
-		//				when locating the nodes. 
+		//				when locating the nodes.
 		//			* rootNode: DomNode?
 		//				identical to the function's `rootNode` argument, though
-		//				allowed to be passed in via this `args object. 
+		//				allowed to be passed in via this `args object.
+		//			* template: Boolean
+		//				If true, ignores ContentPane's stopParser flag and parses contents inside of
+		//				a ContentPane inside of a template.   This allows dojoAttachPoint on widgets/nodes
+		//				nested inside the ContentPane to work.
 		//			* inherited: Object
 		//				Hash possibly containing dir and lang settings to be applied to
 		//				parsed widgets, unless there's another setting on a sub-node that overrides
-		//
+		//			* scope: String
+		//				Root for attribute names to search for.   If scopeName is dojo,
+		//				will search for data-dojo-type (or dojoType).   For backwards compatibility
+		//				reasons defaults to dojo._scopeName (which is "dojo" except when
+		//				multi-version support is used, when it will be something like dojo16, dojo20, etc.)
+		//			* propsThis: Object
+		//				If specified, "this" referenced from data-dojo-props will refer to propsThis.
+		//				Intended for use from the widgets-in-template feature of `dijit._Templated`
 		//
 		// example:
 		//		Parse all widgets on a page:
@@ -317,10 +402,10 @@ dojo.parser = new function(){
 		//
 		// example:
 		//		Parse all classes within the node with id="foo"
-		//	|		dojo.parser.parse(dojo.byId(foo));
+		//	|		dojo.parser.parse(dojo.byId('foo'));
 		//
 		// example:
-		//		Parse all classes in a page, but do not call .startup() on any 
+		//		Parse all classes in a page, but do not call .startup() on any
 		//		child
 		//	|		dojo.parser.parse({ noStart: true })
 		//
@@ -328,7 +413,7 @@ dojo.parser = new function(){
 		//		Parse all classes in a node, but do not call .startup()
 		//	|		dojo.parser.parse(someNode, { noStart:true });
 		//	|		// or
-		// 	|		dojo.parser.parse({ noStart:true, rootNode: someNode });
+		//	|		dojo.parser.parse({ noStart:true, rootNode: someNode });
 
 		// determine the root node based on the passed arguments.
 		var root;
@@ -338,8 +423,12 @@ dojo.parser = new function(){
 		}else{
 			root = rootNode;
 		}
+		root = root ? dojo.byId(root) : dojo.body();
+		args = args || {};
+
+		var attrName = (args.scope || d._scopeName) + "Type",		// typically "dojoType"
+			attrData = "data-" + (args.scope || d._scopeName) + "-";	// typically "data-dojo-"
 
-		var attrName = this._attrName;
 		function scan(parent, list){
 			// summary:
 			//		Parent is an Object representing a DOMNode, with or without a dojoType specified.
@@ -348,7 +437,7 @@ dojo.parser = new function(){
 			// parent: Object
 			//		Object representing the parent node, like
 			//	|	{
-			//	|		node: DomNode, 			// scan children of this node
+			//	|		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
@@ -361,6 +450,7 @@ dojo.parser = new function(){
 			// 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;
@@ -368,20 +458,31 @@ dojo.parser = new function(){
 			});
 
 			// if parent is a widget, then search for <script type=dojo/*> tags and put them in scripts[].
-			var scripts = parent.scripts;
+			var scripts = parent.clsInfo && !parent.clsInfo.cls.prototype._noScript ? parent.scripts : null;
 
 			// unless parent is a widget with the stopParser flag set, continue search for dojoType, recursively
-			var recurse = !parent.clsInfo || !parent.clsInfo.cls.prototype.stopParser;
+			var recurse = (!parent.clsInfo || !parent.clsInfo.cls.prototype.stopParser) || (args && args.template);
 
 			// 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){
-					var type = recurse && child.getAttribute(attrName);
+					// 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 specified, add to output array of nodes to instantiate
+						// if dojoType/data-dojo-type specified, add to output array of nodes to instantiate
 						var params = {
 							"type": type,
-							clsInfo: getClassInfo(type),	// note: won't find classes declared via dojo.Declaration
+							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
@@ -394,7 +495,7 @@ dojo.parser = new function(){
 					}else if(scripts && child.nodeName.toLowerCase() == "script"){
 						// if <script type="dojo/...">, save in scripts[]
 						type = child.getAttribute("type");
-						if (type && /^dojo\//i.test(type)) {
+						if (type && /^dojo\/\w/i.test(type)) {
 							scripts.push(child);
 						}
 					}else if(recurse){
@@ -408,17 +509,24 @@ dojo.parser = new function(){
 			}
 		}
 
+		// 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]; }
+			}
+		}
+
 		// Make list of all nodes on page w/dojoType specified
 		var list = [];
 		scan({
-			node: root ? dojo.byId(root) : dojo.body(),
-			inherited: (args && args.inherited) || {
-				dir: dojo._isBodyLtr() ? "ltr" : "rtl"
-			}
+			node: root,
+			inherited: inherited
 		}, list);
 
 		// go build the object instances
-		return this.instantiate(list, null, args); // Array
+		var mixin = args && args.template ? {template: true} : null;
+		return this.instantiate(list, mixin, args); // Array
 	};
 }();
 
@@ -426,16 +534,19 @@ dojo.parser = new function(){
 //after the a11y test.
 
 (function(){
-	var parseRunner = function(){ 
+	var parseRunner = function(){
 		if(dojo.config.parseOnLoad){
-			dojo.parser.parse(); 
+			dojo.parser.parse();
 		}
 	};
 
 	// FIXME: need to clobber cross-dependency!!
-	if(dojo.exists("dijit.wai.onload") && (dijit.wai.onload === dojo._loaders[0])){
+	if(dojo.getObject("dijit.wai.onload") === dojo._loaders[0]){
 		dojo._loaders.splice(1, 0, parseRunner);
 	}else{
 		dojo._loaders.unshift(parseRunner);
 	}
 })();
+
+return dojo.parser;
+});
diff --git a/dojo/regexp.js b/dojo/regexp.js
index a670193..6159649 100644
--- a/dojo/regexp.js
+++ b/dojo/regexp.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.regexp");
+define("dojo/regexp", ["dojo"], function(dojo) {
+dojo.getObject("regexp", true, dojo);
 
 /*=====
 dojo.regexp = {
@@ -18,7 +19,7 @@ dojo.regexp.escapeString = function(/*String*/str, /*String?*/except){
 		}
 		return "\\" + ch;
 	}); // String
-}
+};
 
 dojo.regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boolean?*/nonCapture){
 	//	summary:
@@ -33,7 +34,7 @@ dojo.regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boole
 	//		A single value or an array of values.
 	// re:
 	//		A function. Takes one parameter and converts it to a regular
-	//		expression. 
+	//		expression.
 	// nonCapture:
 	//		If true, uses non-capturing match, otherwise matches are retained
 	//		by regular expression. Defaults to false
@@ -52,13 +53,16 @@ dojo.regexp.buildGroupRE = function(/*Object|Array*/arr, /*Function*/re, /*Boole
 
 	 // join the REs as alternatives in a RE group.
 	return dojo.regexp.group(b.join("|"), nonCapture); // String
-}
+};
 
 dojo.regexp.group = function(/*String*/expression, /*Boolean?*/nonCapture){
 	// summary:
 	//		adds group match to expression
 	// nonCapture:
 	//		If true, uses non-capturing match, otherwise matches are retained
-	//		by regular expression. 
+	//		by regular expression.
 	return "(" + (nonCapture ? "?:":"") + expression + ")"; // String
-}
+};
+
+return dojo.regexp;
+});
diff --git a/dojo/resources/_modules.js b/dojo/resources/_modules.js
index bfc6c76..e093a58 100644
--- a/dojo/resources/_modules.js
+++ b/dojo/resources/_modules.js
@@ -29,7 +29,7 @@ dojo.rpc = {
 
 dojo.baseUrl = {
 	// summary: The root relative path to dojo.js (as a string)
-	// example: 
+	// example:
 	//	if(typeof dojo != "undefined"){ console.log(dojo.baseUrl); }
 };
 
diff --git a/dojo/robot.js b/dojo/robot.js
index c7db864..c442ac5 100644
--- a/dojo/robot.js
+++ b/dojo/robot.js
@@ -1,7 +1,6 @@
-dojo.provide("dojo.robot");
+define("dojo/robot", ["dojo", "doh/robot", "dojo/window"], function(dojo) {
+
 dojo.experimental("dojo.robot");
-dojo.require("doh.robot");
-dojo.require("dojo.window");
 
 (function(){
 // users who use doh+dojo get the added convenience of dojo.mouseMoveAt,
@@ -172,3 +171,6 @@ dojo.mixin(doh.robot,{
 });
 
 })();
+
+return doh.robot;
+});
diff --git a/dojo/robotx.js b/dojo/robotx.js
index 3fd5f2e..649e061 100644
--- a/dojo/robotx.js
+++ b/dojo/robotx.js
@@ -1,5 +1,5 @@
-dojo.provide("dojo.robotx");
-dojo.require("dojo.robot");
+define("dojo/robotx", ["dojo", "dojo/robot"], function(dojo) {
+
 dojo.experimental("dojo.robotx");
 
 // loads an external app into an iframe and points dojo.doc to the iframe document, allowing the robot to control it
@@ -7,18 +7,48 @@ dojo.experimental("dojo.robotx");
 // dojo.require this file
 
 (function(){
-// have to wait for test page to load before testing!
-doh.robot._runsemaphore.lock.push("dojo.robotx.lock");
 
-var iframe = document.getElementById('robotapplication');
+var iframe = null;
 
 var groupStarted=dojo.connect(doh, '_groupStarted', function(){
 	dojo.disconnect(groupStarted);
 	iframe.style.visibility="visible";
 });
 
+var attachIframe = function(){
+	dojo.addOnLoad(function(){
+		var emptyStyle = {
+			overflow: dojo.isWebKit? 'hidden' : 'visible',
+			margin: '0px',
+			borderWidth: '0px',
+			height: '100%',
+			width: '100%'
+		};
+		dojo.style(document.documentElement, emptyStyle);
+		dojo.style(document.body, emptyStyle);
+		document.body.appendChild(iframe);
+		var base=document.createElement('base');
+		base.href=iframe.src;
+		document.getElementsByTagName("head")[0].appendChild(base);
+	});
+};
+
+// Prevent race conditions between iframe loading and robot init.
+// If iframe is allowed to load while the robot is typing, sync XHRs can prevent the robot from completing its initialization.
+var robotReady=false;
+var robotFrame=null;
+var _run=doh.robot._run;
+doh.robot._run=function(frame){
+	// Called from robot when the robot completed its initialization.
+	robotReady = true;
+	robotFrame = frame;
+	doh.robot._run=_run;
+	// If initRobot was already called, then attach the iframe.
+	if(iframe.src){ attachIframe(); }
+}
+
 var onIframeLoad=function(){
-	//iframe = document.getElementById('robotapplication');
+	// initial load handler: update the document and start the tests
 	doh.robot._updateDocument();
 	onIframeLoad = null;
 	var scrollRoot = (document.compatMode == 'BackCompat')? document.body : document.documentElement;
@@ -26,7 +56,15 @@ var onIframeLoad=function(){
 	if(consoleHeight){
 		iframe.style.height = (scrollRoot.clientHeight - consoleHeight)+"px";
 	}
-	doh.run();
+	// If dojo is present in the test case, then at least make a best effort to wait for it to load.
+	// The test must handle other race conditions like initial data queries by itself.
+	if(iframe.contentWindow.dojo){
+		iframe.contentWindow.dojo.addOnLoad(function(){
+			doh.robot._run(robotFrame);
+		});
+	}else{
+		doh.robot._run(robotFrame);
+	}
 };
 
 var iframeLoad=function(){
@@ -57,6 +95,9 @@ if(iframe['attachEvent'] !== undefined){
 	dojo.connect(iframe, 'onload', iframeLoad);
 }
 
+
+
+
 dojo.mixin(doh.robot,{
 	_updateDocument: function(){
 		dojo.setContext(iframe.contentWindow, iframe.contentWindow.document);
@@ -75,22 +116,13 @@ dojo.mixin(doh.robot,{
 		// url:
 		//		URL to open. Any of the test's dojo.doc calls (e.g. dojo.byId()), and any dijit.registry calls (e.g. dijit.byId()) will point to elements and widgets inside this application.
 		//
+
 		iframe.src=url;
-		dojo.addOnLoad(function(){
-			var emptyStyle = {
-				overflow: dojo.isWebKit? 'hidden' : 'visible',
-				margin: '0px',
-				borderWidth: '0px',
-				height: '100%',
-				width: '100%'
-			};
-			dojo.style(document.documentElement, emptyStyle);
-			dojo.style(document.body, emptyStyle);
-			document.body.appendChild(iframe);
-			var base=document.createElement('base');
-			base.href=url;
-			document.getElementsByTagName("head")[0].appendChild(base);
-		});
+		// see above note about race conditions
+		if(robotReady){
+			attachIframe();
+			
+		}
 	},
 
 	waitForPageToLoad: function(/*Function*/ submitActions){
@@ -125,5 +157,7 @@ dojo.mixin(doh.robot,{
 	}
 
 });
-
 })();
+
+return doh.robot;
+});
diff --git a/dojo/rpc/JsonService.js b/dojo/rpc/JsonService.js
index fc2f5b6..19c244f 100644
--- a/dojo/rpc/JsonService.js
+++ b/dojo/rpc/JsonService.js
@@ -1,5 +1,4 @@
-dojo.provide("dojo.rpc.JsonService");
-dojo.require("dojo.rpc.RpcService");
+define("dojo/rpc/JsonService", ["dojo", "dojo/rpc/RpcService"], function(dojo) {
 
 dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 		bustCache: false,
@@ -36,7 +35,7 @@ dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 				url: url||this.serviceUrl,
 				postData: this.createRequest(method, parameters),
 				contentType: this.contentType,
-				timeout: this.timeout, 
+				timeout: this.timeout,
 				handleAs: "json-comment-optional"
 			});
 			def.addCallbacks(this.resultCallback(deferredRequestHandler), this.errorCallback(deferredRequestHandler));
@@ -77,3 +76,6 @@ dojo.declare("dojo.rpc.JsonService", dojo.rpc.RpcService, {
 		}
 	}
 );
+
+return dojo.rpc.JsonService;
+});
diff --git a/dojo/rpc/JsonpService.js b/dojo/rpc/JsonpService.js
index 8adcd38..839f333 100644
--- a/dojo/rpc/JsonpService.js
+++ b/dojo/rpc/JsonpService.js
@@ -1,10 +1,8 @@
-dojo.provide("dojo.rpc.JsonpService");
-dojo.require("dojo.rpc.RpcService");
-dojo.require("dojo.io.script");
+define("dojo/rpc/JsonpService", ["dojo", "dojo/rpc/RpcService", "dojo/io/script"], function(dojo) {
 
 dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 	// summary:
-	//	Generic JSONP service.  Minimally extends RpcService to allow 
+	//	Generic JSONP service.  Minimally extends RpcService to allow
 	//	easy definition of nearly any JSONP style service. Example
 	//	SMD files exist in dojox.data
 
@@ -16,10 +14,10 @@ dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 
 			dojo.forEach(this.required, function(req){
 				if(req=="" || req==undefined){
-					throw new Error("Required Service Argument not found: "+req); 
+					throw new Error("Required Service Argument not found: "+req);
 				}
 			});
-		}		
+		}
 	},
 
 	strictArgChecks: false,
@@ -41,7 +39,7 @@ dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 			callbackParamName: this.callbackParamName||"callback",
 			content: this.createRequest(parameters),
 			timeout: this.timeout,
-			handleAs: "json",	
+			handleAs: "json",
 			preventCache: true
 		});
 		def.addCallbacks(this.resultCallback(deferredRequestHandler), this.errorCallback(deferredRequestHandler));
@@ -59,3 +57,6 @@ dojo.declare("dojo.rpc.JsonpService", dojo.rpc.RpcService, {
 		return params;
 	}
 });
+
+return dojo.rpc.JsonpService;
+});
diff --git a/dojo/rpc/RpcService.js b/dojo/rpc/RpcService.js
index 4bd2995..847c8d5 100644
--- a/dojo/rpc/RpcService.js
+++ b/dojo/rpc/RpcService.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.rpc.RpcService");
+define("dojo/rpc/RpcService", ["dojo"], function(dojo) {
 
 dojo.declare("dojo.rpc.RpcService", null, {
 	constructor: function(args){
@@ -16,7 +16,7 @@ dojo.declare("dojo.rpc.RpcService", null, {
 		//		matches those defined in the smd.  smdString allows a developer to pass
 		//		a jsonString directly, which will be converted into an object or alternatively
 		//		smdObject is accepts an smdObject directly.
-		//				
+		//
 		if(args){
 			//if the arg is a string, we assume it is a url to retrieve an smd definition from
 			if( (dojo.isString(args)) || (args instanceof dojo._Url)){
@@ -90,7 +90,7 @@ dojo.declare("dojo.rpc.RpcService", null, {
 		//	deferredRequestHandler: Deferred
 		//		The deferred object handling a request.
 
-		var tf = dojo.hitch(this, 
+		var tf = dojo.hitch(this,
 			function(obj){
 				if(obj.error!=null){
 					var err;
@@ -105,7 +105,7 @@ dojo.declare("dojo.rpc.RpcService", null, {
 					err.errorObject = obj;
 					deferredRequestHandler.errback(err);
 				}else{
-					deferredRequestHandler.callback(this.parseResults(obj)); 
+					deferredRequestHandler.callback(this.parseResults(obj));
 				}
 			}
 		);
@@ -151,7 +151,7 @@ dojo.declare("dojo.rpc.RpcService", null, {
 			dojo.forEach(object.methods, function(m){
 				if(m && m.name){
 					this[m.name] = this.generateMethod(	m.name,
-										m.parameters, 
+										m.parameters,
 										m.url||m.serviceUrl||m.serviceURL);
 					if(!dojo.isFunction(this[m.name])){
 						throw new Error("RpcService: Failed to create" + m.name + "()");
@@ -166,3 +166,6 @@ dojo.declare("dojo.rpc.RpcService", null, {
 		this.smd = object;
 	}
 });
+
+return dojo.rpc.RpcService;
+});
diff --git a/dojo/store/Cache.js b/dojo/store/Cache.js
new file mode 100644
index 0000000..4897ecb
--- /dev/null
+++ b/dojo/store/Cache.js
@@ -0,0 +1,142 @@
+define("dojo/store/Cache", ["dojo"], function(dojo) {
+dojo.getObject("store", true, dojo);
+
+/*=====
+dojo.declare("dojo.store.__CacheArgs", null, {
+	constructor: function(){
+		// summary:
+		//		These are additional options for how caching is handled.
+		// isLoaded: Function?
+		//		This is a function that will be called for each item in a query response to determine
+		//		if it is cacheable. If isLoaded returns true, the item will be cached, otherwise it
+		//		will not be cached. If isLoaded is not provided, all items will be cached.
+		this.isLoaded = isLoaded;
+	}
+});
+=====*/
+dojo.store.Cache = function(masterStore, cachingStore, /*dojo.store.__CacheArgs*/ options){
+	// summary:
+	//		The Cache store wrapper takes a master store and a caching store,
+	//		caches data from the master into the caching store for faster
+	//		lookup. Normally one would use a memory store for the caching
+	//		store and a server store like JsonRest for the master store.
+	// masterStore:
+	//		This is the authoritative store, all uncached requests or non-safe requests will
+	//		be made against this store.
+	// cachingStore:
+	//		This is the caching store that will be used to store responses for quick access.
+	//		Typically this should be a local store.
+	// options:
+	//		These are additional options for how caching is handled.
+	options = options || {};
+	return dojo.delegate(masterStore, {
+		query: function(query, directives){
+			var results = masterStore.query(query, directives);
+			results.forEach(function(object){
+				if(!options.isLoaded || options.isLoaded(object)){
+					cachingStore.put(object);
+				}
+			});
+			return results;
+		},
+		// 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){
+					if(result){
+						cachingStore.put(result, {id: id});
+					}
+					return result;
+				});
+			});
+		},
+		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);
+            });
+        },
+		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);
+            });
+        },
+		remove: function(id, directives){
+            return dojo.when(masterStore.remove(id, directives), function(result){
+                return cachingStore.remove(id, directives);
+            });
+        },
+		evict: function(id){
+			return cachingStore.remove(id);
+		}
+	});
+};
+/*=====
+dojo.declare("dojo.store.Cache", null, {
+	// example:
+	//	|	var master = new dojo.store.Memory(data);
+	//	|	var cacher = new dojo.store.Memory();
+	//	|	var store = new dojo.store.Cache(master, cacher);
+	//
+	query: function(query, directives){
+		// summary:
+		//		Query the underlying master store and cache any results.
+		// query: Object|String
+		//		The object or string containing query information. Dependent on the query engine used.
+		// directives: dojo.store.util.SimpleQueryEngine.__queryOptions?
+		//		An optional keyword arguments object with additional parameters describing the query.
+		// returns: dojo.store.util.QueryResults
+		//		A QueryResults object that can be used to iterate over.
+	},
+	get: function(id, directives){
+		// summary:
+		//		Get the object with the specific id.
+		// id: Number
+		//		The identifier for the object in question.
+		// directives: dojo.store.__GetOptions?
+		//		Any additional parameters needed to describe how the get should be performed.
+		// returns: dojo.store.util.QueryResults
+		//		A QueryResults object.
+	},
+	add: function(object, directives){
+		// summary:
+		//		Add the given object to the store.
+		// object: Object
+		//		The object to add to the store.
+		// directives: dojo.store.__AddOptions?
+		//		Any additional parameters needed to describe how the add should be performed.
+		// returns: Number
+		//		The new id for the object.
+	},
+	put: function(object, directives){
+		// summary:
+		//		Put the object into the store (similar to an HTTP PUT).
+		// object: Object
+		//		The object to put to the store.
+		// directives: dojo.store.__PutOptions?
+		//		Any additional parameters needed to describe how the put should be performed.
+		// returns: Number
+		//		The new id for the object.
+	},
+	remove: function(id, directives){
+		// summary:
+		//		Remove the object with the specific id.
+		// id: Number
+		//		The identifier for the object in question.
+		// directives: dojo.store.__RemoveOptions?
+		//		Any additional parameters needed to describe how the remove should be performed.
+	},
+	evict: function(id){
+		// summary:
+		//		Remove the object with the given id from the underlying caching store.
+		// id: Number
+		//		The identifier for the object in question.
+	}
+});
+=====*/
+return dojo.store.Cache;
+});
diff --git a/dojo/store/DataStore.js b/dojo/store/DataStore.js
new file mode 100644
index 0000000..f682d10
--- /dev/null
+++ b/dojo/store/DataStore.js
@@ -0,0 +1,132 @@
+define("dojo/store/DataStore", ["dojo", "dojo/store/util/QueryResults"], function(dojo) {
+
+dojo.declare("dojo.store.DataStore", null, {
+	target: "",
+	constructor: function(options){
+		// summary:
+		//		This is an adapter for using Dojo Data stores with an object store consumer.
+		//		You can provide a Dojo data store and use this adapter to interact with it through
+		//		the Dojo object store API
+		// options: Object?
+		//		This provides any configuration information that will be mixed into the store,
+		//		including a reference to the Dojo data store under the property "store".
+		dojo.mixin(this, options);
+	},
+	_objectConverter: function(callback){
+		var store = this.store;
+		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]);
+			}
+			return callback(object);
+		};
+	},
+	get: function(id, options){
+		// summary:
+		//		Retrieves an object by it's identity. This will trigger a fetchItemByIdentity
+		// id: Object?
+		//		The identity to use to lookup the object
+		var returnedObject, returnedError;
+		var deferred = new dojo.Deferred();
+		this.store.fetchItemByIdentity({
+			identity: id,
+			onItem: this._objectConverter(function(object){
+				deferred.resolve(returnedObject = object);
+			}),
+			onError: function(error){
+				deferred.reject(returnedError = error);
+			}
+		});
+		if(returnedObject){
+			// if it was returned synchronously
+			return returnedObject;
+		}
+		if(returnedError){
+			throw returnedError;
+		}
+		return deferred.promise;
+	},
+	put: function(object, options){
+		// summary:
+		//		Stores an object by its identity.
+		// object: Object
+		//		The object to store.
+		// options: Object?
+		//		Additional metadata for storing the data.  Includes a reference to an id
+		//		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;
+		if(typeof id == "undefined"){
+			store.newItem(object);
+		}else{
+			store.fetchItemByIdentity({
+				identity: id,
+				onItem: function(item){
+					if(item){
+						for(var i in object){
+							if(store.getValue(item, i) != object[i]){
+								store.setValue(item, i, object[i]);
+							}
+						}
+					}else{
+						store.newItem(object);
+					}
+				}
+			});
+		}
+	},
+	remove: function(id){
+		// summary:
+		//		Deletes an object by its identity.
+		// id: Object
+		//		The identity to use to delete the object
+		var store = this.store;
+		this.store.fetchItemByIdentity({
+			identity: id,
+			onItem: function(item){
+				store.deleteItem(item);
+			}
+		});
+	},
+	query: function(query, options){
+		// summary:
+		//		Queries the store for objects.
+		// query: Object
+		//		The query to use for retrieving objects from the store
+		// options: Object?
+		//		Optional options object as used by the underlying dojo.data Store.
+		// returns: dojo.store.util.QueryResults
+		//		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 converter = this._objectConverter(function(object){return object;});
+		this.store.fetch(dojo.mixin({
+			query: query,
+			onBegin: function(count){
+				deferred.total.resolve(count);
+			},
+			onComplete: function(results){
+				deferred.resolve(dojo.map(results, converter));
+			},
+			onError: function(error){
+				deferred.reject(error);
+			}
+		}, options));
+		return dojo.store.util.QueryResults(deferred);
+	},
+	getIdentity: function(object){
+		// summary:
+		//		Fetch the identity for the given object.
+		// object: Object
+		//		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 dojo.store.DataStore;
+});
diff --git a/dojo/store/JsonRest.js b/dojo/store/JsonRest.js
new file mode 100644
index 0000000..05723fe
--- /dev/null
+++ b/dojo/store/JsonRest.js
@@ -0,0 +1,136 @@
+define("dojo/store/JsonRest", ["dojo", "dojo/store/util/QueryResults"], function(dojo) {
+
+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);
+	},
+	// target: String
+	//		The target base URL to use for all requests to the server. This string will be
+	// 	prepended to the id to generate the URL (relative or absolute) for requests
+	// 	sent to the server
+	target: "",
+	// idProperty: String
+	//		Indicates the property to use as the identity property. The values of this
+	//		property should be unique.
+	idProperty: "id",
+
+	get: function(id, options){
+		//	summary:
+		//		Retrieves an object by its identity. This will trigger a GET request to the server using
+		//		the url `this.target + id`.
+		//	id: Number
+		//		The identity to use to lookup the object
+		//	returns: Object
+		//		The object in the store that matches the given id.
+		var headers = options || {};
+		headers.Accept = "application/javascript, application/json";
+		return dojo.xhrGet({
+			url:this.target + id,
+			handleAs: "json",
+			headers: headers
+		});
+	},
+	getIdentity: function(object){
+		// summary:
+		//		Returns an object's identity
+		// object: Object
+		//		The object to get the identity from
+		//	returns: Number
+		return object[this.idProperty];
+	},
+	put: function(object, options){
+		// summary:
+		//		Stores an object. This will trigger a PUT request to the server
+		//		if the object has an id, otherwise it will trigger a POST request.
+		// object: Object
+		//		The object to store.
+		// options: dojo.store.api.Store.PutDirectives?
+		//		Additional metadata for storing the data.  Includes an "id"
+		//		property if a specific id is to be used.
+		//	returns: Number
+		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", {
+				url: hasId ? this.target + id : this.target,
+				postData: dojo.toJson(object),
+				handleAs: "json",
+				headers:{
+					"Content-Type": "application/json",
+					"If-Match": options.overwrite === true ? "*" : null,
+					"If-None-Match": options.overwrite === false ? "*" : null
+				}
+			});
+	},
+	add: function(object, options){
+		// summary:
+		//		Adds an object. This will trigger a PUT request to the server
+		//		if the object has an id, otherwise it will trigger a POST request.
+		// object: Object
+		//		The object to store.
+		// options: dojo.store.api.Store.PutDirectives?
+		//		Additional metadata for storing the data.  Includes an "id"
+		//		property if a specific id is to be used.
+		options = options || {};
+		options.overwrite = false;
+		return this.put(object, options);
+	},
+	remove: function(id){
+		// summary:
+		//		Deletes an object by its identity. This will trigger a DELETE request to the server.
+		// id: Number
+		//		The identity to use to delete the object
+		return dojo.xhrDelete({
+			url:this.target + id
+		});
+	},
+	query: function(query, options){
+		// summary:
+		//		Queries the store for objects. This will trigger a GET request to the server, with the
+		//		query added as a query string.
+		// query: Object
+		//		The query to use for retrieving objects from the store.
+		// options: dojo.store.api.Store.QueryOptions?
+		//		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"};
+		options = options || {};
+
+		if(options.start >= 0 || options.count >= 0){
+			headers.Range = "items=" + (options.start || '0') + '-' +
+				(("count" in options && options.count != Infinity) ?
+					(options.count + (options.start || 0) - 1) : '');
+		}
+		if(dojo.isObject(query)){
+			query = dojo.objectToQuery(query);
+			query = query ? "?" + query: "";
+		}
+		if(options && options.sort){
+			query += (query ? "&" : "?") + "sort(";
+			for(var i = 0; i<options.sort.length; i++){
+				var sort = options.sort[i];
+				query += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
+			}
+			query += ")";
+		}
+		var results = dojo.xhrGet({
+			url: this.target + (query || ""),
+			handleAs: "json",
+			headers: headers
+		});
+		results.total = results.then(function(){
+			var range = results.ioArgs.xhr.getResponseHeader("Content-Range");
+			return range && (range=range.match(/\/(.*)/)) && +range[1];
+		});
+		return dojo.store.util.QueryResults(results);
+	}
+});
+
+return dojo.store.JsonRest;
+});
\ No newline at end of file
diff --git a/dojo/store/Memory.js b/dojo/store/Memory.js
new file mode 100644
index 0000000..87e57cb
--- /dev/null
+++ b/dojo/store/Memory.js
@@ -0,0 +1,153 @@
+define("dojo/store/Memory", ["dojo", "dojo/store/util/QueryResults", "dojo/store/util/SimpleQueryEngine"], function(dojo) {
+
+dojo.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){
+		// summary:
+		//		Creates a memory object store.
+		// 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);
+		this.setData(this.data || []);
+	},
+	// data: Array
+	//		The array of all the objects in the memory store
+	data:null,
+
+	// idProperty: String
+	//		Indicates the property to use as the identity property. The values of this
+	//		property should be unique.
+	idProperty: "id",
+
+	// index: Object
+	//		An index of data by id
+	index:null,
+
+	// queryEngine: Function
+	//		Defines the query engine to use for querying the data store
+	queryEngine: dojo.store.util.SimpleQueryEngine,
+	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.
+		return this.index[id];
+	},
+	getIdentity: function(object){
+		// 	summary:
+		//		Returns an object's identity
+		// 	object: Object
+		//		The object to get the identity from
+		//	returns: Number
+		return object[this.idProperty];
+	},
+	put: function(object, options){
+		// 	summary:
+		//		Stores an object
+		// 	object: Object
+		//		The object to store.
+		// 	options: dojo.store.api.Store.PutDirectives??
+		//		Additional metadata for storing the data.  Includes an "id"
+		//		property if a specific id is to be used.
+		//	returns: Number
+		var id = options && options.id || object[this.idProperty] || Math.random();
+		this.index[id] = object;
+		var data = this.data,
+			idProperty = this.idProperty;
+		for(var i = 0, l = data.length; i < l; i++){
+			if(data[i][idProperty] == id){
+				data[i] = object;
+				return id;
+			}
+		}
+		this.data.push(object);
+		return id;
+	},
+	add: function(object, options){
+		// 	summary:
+		//		Creates an object, throws an error if the object already exists
+		// 	object: Object
+		//		The object to store.
+		// 	options: dojo.store.api.Store.PutDirectives??
+		//		Additional metadata for storing the data.  Includes an "id"
+		//		property if a specific id is to be used.
+		//	returns: Number
+		if(this.index[options && options.id || object[this.idProperty]]){
+			throw new Error("Object already exists");
+		}
+		return this.put(object, options);
+	},
+	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.
+		// 	query: Object
+		//		The query to use for retrieving objects from the store.
+		//	options: dojo.store.api.Store.QueryOptions?
+		//		The optional arguments to apply to the resultset.
+		//	returns: dojo.store.api.Store.QueryResults
+		//		The results of the query, extended with iterative methods.
+		//
+		// 	example:
+		// 		Given the following store:
+		//
+		// 	|	var store = new dojo.store.Memory({
+		// 	|		data: [
+		// 	|			{id: 1, name: "one", prime: false },
+		//	|			{id: 2, name: "two", even: true, prime: true},
+		//	|			{id: 3, name: "three", prime: true},
+		//	|			{id: 4, name: "four", even: true, prime: false},
+		//	|			{id: 5, name: "five", prime: true}
+		//	|		]
+		//	|	});
+		//
+		//	...find all items where "prime" is true:
+		//
+		//	|	var results = store.query({ prime: true });
+		//
+		//	...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));
+	},
+	setData: function(data){
+		// 	summary:
+		//		Sets the given data as the source for this store, and indexes it
+		//	data: Object[]
+		//		An array of objects to use as the source of data.
+		if(data.items){
+			// just for convenience with the data format IFRS expects
+			this.idProperty = data.identifier;
+			data = this.data = data.items;
+		}else{
+			this.data = data;
+		}
+
+		for(var i = 0, l = data.length; i < l; i++){
+			var object = data[i];
+			this.index[object[this.idProperty]] = object;
+		}
+	}
+});
+
+return dojo.store.Memory;
+});
diff --git a/dojo/store/Observable.js b/dojo/store/Observable.js
new file mode 100644
index 0000000..c3d23b0
--- /dev/null
+++ b/dojo/store/Observable.js
@@ -0,0 +1,164 @@
+define("dojo/store/Observable", ["dojo"], function(dojo) {
+dojo.getObject("store", true, dojo);
+
+dojo.store.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.
+	//
+	// description:
+	//		Observable wraps an existing store so that notifications can be made when a query
+	//		is performed.
+	//
+	// example:
+	//		Create a Memory store that returns an observable query, and then log some
+	//		information about that query.
+	//
+	//	|	var store = dojo.store.Observable(new dojo.store.Memory({
+	//	|		data: [
+	//	|			{id: 1, name: "one", prime: false},
+	//	|			{id: 2, name: "two", even: true, prime: true},
+	//	|			{id: 3, name: "three", prime: true},
+	//	|			{id: 4, name: "four", even: true, prime: false},
+	//	|			{id: 5, name: "five", prime: true}
+	//	|		]
+	//	|	}));
+	//	|	var changes = [], results = store.query({ prime: true });
+	//	|	var observer = results.observe(function(object, previousIndex, newIndex){
+	//	|		changes.push({previousIndex:previousIndex, newIndex:newIndex, object:object});
+	//	|	});
+	//
+	//		See the Observable tests for more information.
+
+	var 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){
+		revision++;
+		var updaters = queryUpdaters.slice();
+		for(var i = 0, l = updaters.length; i < l; i++){
+			updaters[i](object, existingId);
+		}
+	};
+	var originalQuery = store.query;
+	store.query = function(query, options){
+		options = options || {};
+		var results = originalQuery.apply(this, arguments);
+		if(results && results.forEach){
+			var nonPagedOptions = dojo.mixin({}, options);
+			delete nonPagedOptions.start;
+			delete nonPagedOptions.count;
+
+			var queryExecutor = store.queryEngine && store.queryEngine(query, nonPagedOptions);
+			var queryRevision = revision;
+			var listeners = [], queryUpdater;
+			results.observe = function(listener, includeObjectUpdates){
+				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){
+							var atEnd = resultsArray.length != options.count;
+							var i;
+							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){
+								// remove the old one
+								for(i = 0, l = resultsArray.length; i < l; i++){
+									var object = resultsArray[i];
+									if(store.getIdentity(object) == existingId){
+										removedObject = object;
+										removedFrom = i;
+										if(queryExecutor || !changed){// if it was changed and we don't have a queryExecutor, we shouldn't remove it because updated objects would be eliminated
+											resultsArray.splice(i, 1);
+										}
+										break;
+									}
+								}
+							}
+							if(queryExecutor){
+								// add the new one
+								if(changed &&
+										// 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);
+									if((options.start && insertedInto == 0) ||
+										(!atEnd && insertedInto == resultsArray.length -1)){
+										// if it is at the end of the page, assume it goes into the prev or next page
+										insertedInto = -1;
+									}
+								}
+							}else if(changed){
+								// we don't have a queryEngine, so we can't provide any information
+								// about where it was inserted, but we can at least indicate a new object
+								insertedInto = removedFrom >= 0 ? removedFrom : (store.defaultIndex || 0);
+							}
+							if((removedFrom > -1 || insertedInto > -1) &&
+									(includeObjectUpdates || !queryExecutor || (removedFrom != insertedInto))){
+								var copyListeners = listeners.slice();
+								for(i = 0;listener = copyListeners[i]; i++){
+									listener(changed || removedObject, removedFrom, insertedInto);
+								}
+							}
+						});
+					});
+				}
+				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);
+						}
+					}
+				};
+			};
+		}
+		return results;
+	};
+	var inMethod;
+	function whenFinished(method, action){
+		var original = store[method];
+		if(original){
+			store[method] = function(value){
+				if(inMethod){
+					// if one method calls another (like add() calling put()) we don't want two events
+					return original.apply(this, arguments);
+				}
+				inMethod = true;
+				try{
+					return dojo.when(original.apply(this, arguments), function(results){
+						action((typeof results == "object" && results) || value);
+						return results;
+					});
+				}finally{
+					inMethod = false;
+				}
+			};
+		}
+	}
+	// monitor for updates by listening to these methods
+	whenFinished("put", function(object){
+		store.notify(object, store.getIdentity(object));
+	});
+	whenFinished("add", function(object){
+		store.notify(object);
+	});
+	whenFinished("remove", function(id){
+		store.notify(undefined, id);
+	});
+
+	return store;
+};
+
+return dojo.store.Observable;
+});
diff --git a/dojo/store/README b/dojo/store/README
new file mode 100644
index 0000000..cb33da0
--- /dev/null
+++ b/dojo/store/README
@@ -0,0 +1,10 @@
+This folder contains the stores and utilities implementing the proposed new Dojo Object Store API,
+a successor and unifier to Dojo Data, Dojo Storage, and potentially Dojo Model. These
+stores are brand new, and designed to provide simple lightweight implementations 
+providing core functionality for typical applications. These modules are under active 
+development, and exist here at this time to provide maximum visibility to the 
+efforts to design and develop this new API and set of base stores. The goal is 
+to have these stores ready for Dojo 1.6. In the meantime, these stores are likely to
+have API changes, may be missing some functionality, tests, and/or documentation.
+If these modules are not deemed suitably stable by the 1.6 release, this directory (or
+individual modules) will be removed and be given a later release target.  
\ No newline at end of file
diff --git a/dojo/store/api/Store.js b/dojo/store/api/Store.js
new file mode 100644
index 0000000..f48f821
--- /dev/null
+++ b/dojo/store/api/Store.js
@@ -0,0 +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.
+	}
+});
+	
+});
diff --git a/dojo/store/util/QueryResults.js b/dojo/store/util/QueryResults.js
new file mode 100644
index 0000000..139152f
--- /dev/null
+++ b/dojo/store/util/QueryResults.js
@@ -0,0 +1,58 @@
+define("dojo/store/util/QueryResults", ["dojo"], function(dojo) {
+dojo.getObject("store.util", true, dojo);
+
+dojo.store.util.QueryResults = function(results){
+	// summary:
+	//		A function that wraps the results of a store query with additional
+	//		methods.
+	//
+	// description:
+	//		QueryResults is a basic wrapper that allows for array-like iteration
+	//		over any kind of returned data from a query.  While the simplest store
+	//		will return a plain array of data, other stores may return deferreds or
+	//		promises; this wrapper makes sure that *all* results can be treated
+	//		the same.
+	//
+	//		Additional methods include `forEach`, `filter` and `map`.
+	//
+	// returns: Object
+	//		An array-like object that can be used for iterating over.
+	//
+	// example:
+	//		Query a store and iterate over the 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);
+	}
+	function addIterativeMethod(method){
+		if(!results[method]){
+			results[method] = function(){
+				var args = arguments;
+				return dojo.when(results, function(results){
+					Array.prototype.unshift.call(args, results);
+					return dojo.store.util.QueryResults(dojo[method].apply(dojo, args));
+				});
+			};
+		}
+	}
+	addIterativeMethod("forEach");
+	addIterativeMethod("filter");
+	addIterativeMethod("map");
+	if(!results.total){
+		results.total = dojo.when(results, function(results){
+			return results.length;
+		});
+	}
+	return results;
+};
+
+return dojo.store.util.QueryResults;
+});
diff --git a/dojo/store/util/SimpleQueryEngine.js b/dojo/store/util/SimpleQueryEngine.js
new file mode 100644
index 0000000..b747a5f
--- /dev/null
+++ b/dojo/store/util/SimpleQueryEngine.js
@@ -0,0 +1,107 @@
+define("dojo/store/util/SimpleQueryEngine", ["dojo"], function(dojo) {
+dojo.getObject("store.util", true, dojo);
+
+dojo.store.util.SimpleQueryEngine = 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
+	//
+	// description:
+	//		The SimpleQueryEngine provides a way of getting a QueryResults through
+	//		the use of a simple object hash as a filter.  The hash will be used to
+	//		match properties on data objects with the corresponding value given. In
+	//		other words, only exact matches will be returned.
+	//
+	//		This function can be used as a template for more complex query engines;
+	//		for example, an engine can be created that accepts an object hash that
+	//		contains filtering functions, or a string that gets evaluated, etc.
+	//
+	//		When creating a new dojo.store, simply set the store's queryEngine
+	//		field as a reference to this function.
+	//
+	// query: Object
+	//		An object hash with fields that may match fields of items in the store.
+	//		Values in the hash will be compared by normal == operator, but regular expressions
+	//		or any object that provides a test() method are also supported and can be
+	// 		used to match strings by more complex expressions
+	// 		(and then the regex's or object's test() method will be used to match values).
+	//
+	// options: dojo.store.util.SimpleQueryEngine.__queryOptions?
+	//		An object that contains optional information such as sort, start, and count.
+	//
+	// returns: Function
+	//		A function that caches the passed query under the field "matches".  See any
+	//		of the "query" methods on dojo.stores.
+	//
+	// example:
+	//		Define a store with a reference to this engine, and set up a query method.
+	//
+	//	|	var myStore = function(options){
+	//	|		//	...more properties here
+	//	|		this.queryEngine = dojo.store.util.SimpleQueryEngine;
+	//	|		//	define our query method
+	//	|		this.query = function(query, options){
+	//	|			return dojo.store.util.QueryResults(this.queryEngine(query, options)(this.data));
+	//	|		};
+	//	|	};
+
+	// create our matching query function
+	switch(typeof query){
+		default:
+			throw new Error("Can not query with a " + typeof query);
+		case "object": case "undefined":
+			var queryObject = query;
+			query = function(object){
+				for(var key in queryObject){
+					var required = queryObject[key];
+					if(required && required.test){
+						if(!required.test(object[key])){
+							return false;
+						}
+					}else if(required != object[key]){
+						return false;
+					}
+				}
+				return true;
+			};
+			break;
+		case "string":
+			// named query
+			if(!this[query]){
+				throw new Error("No filter function " + query + " was found in store");
+			}
+			query = this[query];
+			// fall through
+		case "function":
+			// fall through
+	}
+	function execute(array){
+		// execute the whole query, first we filter
+		var results = dojo.filter(array, query);
+		// next we sort
+		if(options && options.sort){
+			results.sort(function(a, b){
+				for(var sort, i=0; sort = options.sort[i]; i++){
+					var aValue = a[sort.attribute];
+					var bValue = b[sort.attribute];
+					if (aValue != bValue) {
+						return !!sort.descending == aValue > bValue ? -1 : 1;
+					}
+				}
+				return 0;
+			});
+		}
+		// now we paginate
+		if(options && (options.start || options.count)){
+			var total = results.length;
+			results = results.slice(options.start || 0, (options.start || 0) + (options.count || Infinity));
+			results.total = total;
+		}
+		return results;
+	}
+	execute.matches = query;
+	return execute;
+};
+
+return dojo.store.util.SimpleQueryEngine;
+});
diff --git a/dojo/string.js b/dojo/string.js
index 331433e..545a418 100644
--- a/dojo/string.js
+++ b/dojo/string.js
@@ -1,7 +1,8 @@
-dojo.provide("dojo.string");
+define("dojo/string", ["dojo"], function(dojo) {
+dojo.getObject("string", true, dojo);
 
 /*=====
-dojo.string = { 
+dojo.string = {
 	// summary: String utilities for Dojo
 };
 =====*/
@@ -52,22 +53,22 @@ dojo.string.pad = function(/*String*/text, /*Integer*/size, /*String?*/ch, /*Boo
 	return end ? out + pad : pad + out;	// String
 };
 
-dojo.string.substitute = function(	/*String*/		template, 
-									/*Object|Array*/map, 
-									/*Function?*/	transform, 
+dojo.string.substitute = function(	/*String*/		template,
+									/*Object|Array*/map,
+									/*Function?*/	transform,
 									/*Object?*/		thisObject){
 	//	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. 
+	//		`${key:format}` which specifies a format function. keys are case-sensitive.
 	//	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:
@@ -110,7 +111,7 @@ dojo.string.substitute = function(	/*String*/		template,
 	//	|	);
 
 	thisObject = thisObject || dojo.global;
-	transform = transform ? 
+	transform = transform ?
 		dojo.hitch(thisObject, transform) : function(v){ return v; };
 
 	return template.replace(/\$\{([^\s\:\}]+)(?:\:([^\s\:\}]+))?\}/g,
@@ -151,3 +152,6 @@ dojo.string.trim = String.prototype.trim ?
 		}
 		return str;
 	};
+
+return dojo.string;
+});
diff --git a/dojo/tests/AdapterRegistry.js b/dojo/tests/AdapterRegistry.js
index c4bbc62..a471db8 100644
--- a/dojo/tests/AdapterRegistry.js
+++ b/dojo/tests/AdapterRegistry.js
@@ -1,7 +1,7 @@
 dojo.provide("tests.AdapterRegistry");
 dojo.require("dojo.AdapterRegistry");
 
-doh.register("tests.AdapterRegistry", 
+doh.register("tests.AdapterRegistry",
 	[
 		function ctor(t){
 			var taa = new dojo.AdapterRegistry();
@@ -14,7 +14,7 @@ doh.register("tests.AdapterRegistry",
 
 		function register(t){
 			var taa = new dojo.AdapterRegistry();
-			taa.register("blah", 
+			taa.register("blah",
 				function(str){ return str == "blah"; },
 				function(){ return "blah"; }
 			);
@@ -45,7 +45,7 @@ doh.register("tests.AdapterRegistry",
 
 		function returnWrappers(t){
 			var taa = new dojo.AdapterRegistry();
-			taa.register("blah", 
+			taa.register("blah",
 				function(str){ return str == "blah"; },
 				function(){ return "blah"; }
 			);
@@ -57,7 +57,7 @@ doh.register("tests.AdapterRegistry",
 
 		function unregister(t){
 			var taa = new dojo.AdapterRegistry();
-			taa.register("blah", 
+			taa.register("blah",
 				function(str){ return str == "blah"; },
 				function(){ return "blah"; }
 			);
diff --git a/dojo/tests/DeferredList.js b/dojo/tests/DeferredList.js
index 3bfa829..0328bf6 100644
--- a/dojo/tests/DeferredList.js
+++ b/dojo/tests/DeferredList.js
@@ -2,7 +2,7 @@ dojo.provide("tests.DeferredList");
 
 dojo.require("dojo.DeferredList");
 
-doh.register("tests.DeferredList", 
+doh.register("tests.DeferredList",
 	[
 		function callback(t){
 			var d1 = new dojo.Deferred();
@@ -81,7 +81,7 @@ doh.register("tests.DeferredList",
 			d1.errback(e);
 			d2.callback("bar");
             t.assertTrue(fired);
-		}, 
+		},
 
         function gather(t){
 			var d1 = new dojo.Deferred();
@@ -104,7 +104,7 @@ dojo.provide("tests.DeferredList");
 
 dojo.require("dojo.DeferredList");
 
-doh.register("tests.DeferredList", 
+doh.register("tests.DeferredList",
 	[
 		function callback(t){
 			var d1 = new dojo.Deferred();
@@ -181,7 +181,7 @@ doh.register("tests.DeferredList",
 			d1.errback(e);
 			d2.callback("bar");
             t.assertTrue(fired);
-		}, 
+		},
 
         function gather(t){
 			var d1 = new dojo.Deferred();
diff --git a/dojo/tests/NodeList-data.html b/dojo/tests/NodeList-data.html
new file mode 100644
index 0000000..9e4e425
--- /dev/null
+++ b/dojo/tests/NodeList-data.html
@@ -0,0 +1,209 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Testing dojo._data / NodeList.data</title>
+		
+		<script type="text/javascript" src="../dojo.js" djConfig="isDebug: true"></script>
+		<script type="text/javascript">
+			dojo.require("doh.runner");
+			dojo.require("dojo.NodeList-data");
+			dojo.addOnLoad(function(){
+				
+				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"
+							});
+							
+							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");
+						}
+					]
+				);
+				doh.run();
+			});
+		</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>
+		</div>
+	</body>
+</html>
diff --git a/dojo/tests/NodeList-data.js b/dojo/tests/NodeList-data.js
new file mode 100644
index 0000000..d9dd148
--- /dev/null
+++ b/dojo/tests/NodeList-data.js
@@ -0,0 +1,4 @@
+dojo.provide("tests.NodeList-data");
+if(dojo.isBrowser){
+	doh.registerUrl("tests.NodeList-data", dojo.moduleUrl("tests", "NodeList-data.html"));
+}
diff --git a/dojo/tests/NodeList-traverse.html b/dojo/tests/NodeList-traverse.html
index 55b602e..0955323 100644
--- a/dojo/tests/NodeList-traverse.html
+++ b/dojo/tests/NodeList-traverse.html
@@ -14,12 +14,13 @@
 			dojo.require("doh.runner");
 			dojo.require("dojo.NodeList-traverse");
 
-			function verify(/*dojo.NodeList*/nl, /*Array*/ids){
-				for(var i = 0, node; node = nl[i]; i++){
-					doh.is(ids[i], node.id);
+			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);
+				doh.is(ids.length, i, comment + " length");
 			}
 
 			dojo.addOnLoad(function(){
@@ -32,10 +33,43 @@
 						},
 
 						function closest(t){
+							// test simple selector
 							var classy = dojo.query("#classy");
 							var closestDiv = classy.closest("div");
-							verify(closestDiv, ["third"]);
-							verify(closestDiv.end().closest(".classy"), ["classy"]);
+							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){
@@ -117,6 +151,17 @@
 			<!-- Another comment -->
 			<span id="yeah">Yeah, baby</span>
 		</div>
+		<div id="level1" class="foo">
+			<div id="level2" class="bar">
+				<div id="level3" class="foo">
+					<div id="level4" class="bar">
+						<div id="level5" class="bar">
+							<div id="level6" class="bang">foo bar bar bang</div>
+						</div>
+					</div>			
+				</div>
+			</div>
+		</div>
 	</body>
 </html>
 
diff --git a/dojo/tests/Stateful.js b/dojo/tests/Stateful.js
index 1b253f8..bb9d14c 100644
--- a/dojo/tests/Stateful.js
+++ b/dojo/tests/Stateful.js
@@ -2,7 +2,7 @@ dojo.provide("tests.Stateful");
 
 dojo.require("dojo.Stateful");
 
-doh.register("tests.Stateful", 
+doh.register("tests.Stateful",
 	[
 		function getSetWatch(t){
 			var s = new dojo.Stateful({
@@ -10,16 +10,16 @@ doh.register("tests.Stateful",
 			});
 			doh.is(s.get("foo"), 3);
 			var watching = s.watch("foo", function(name, oldValue, value){
-				doh.is(name, "foo");
-				doh.is(oldValue, 3);
-				doh.is(value, 4);
-				doh.is(s.get("foo"), 4);
+				doh.is("foo", name);
+				doh.is(3, oldValue);
+				doh.is(4, value);
+				doh.is(4, s.get("foo"));
 			});
 			s.set("foo", 4);
-			doh.is(s.get("foo"), 4);
+			doh.is(4, s.get("foo"));
 			watching.unwatch();
 			s.set("foo", 5);
-			doh.is(s.get("foo"), 5);
+			doh.is(5, s.get("foo"));
 		},
 		function setHash(t){
 			var s = new dojo.Stateful();
@@ -27,9 +27,28 @@ doh.register("tests.Stateful",
 				foo:3,
 				bar: 5
 			});
-			doh.is(s.get("foo"), 3);
-			doh.is(s.get("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);
+		}
 
 
 	]
diff --git a/dojo/tests/_base.js b/dojo/tests/_base.js
index 9de29aa..263f8d8 100644
--- a/dojo/tests/_base.js
+++ b/dojo/tests/_base.js
@@ -9,7 +9,7 @@ try{
 
 if(doh.selfTest){
 
-	doh.register("doh.smokeTest", 
+	doh.register("doh.smokeTest",
 		[
 			function sanityCheckHarness(t){
 				// sanity checks
@@ -19,7 +19,7 @@ if(doh.selfTest){
 				t.assertFalse(null);
 				var tObj = { w00t: false, blarg: true };
 				t.assertEqual(
-					["thinger", "blah", tObj], 
+					["thinger", "blah", tObj],
 					["thinger", "blah", tObj]
 				);
 				t.assertEqual(tObj, tObj);
@@ -55,7 +55,7 @@ if(doh.selfTest){
 	);
 
 	if(testGlobal["dojo"]){
-		doh.register("tests._base", 
+		doh.register("tests._base",
 			[
 				function dojoIsAvailable(t){
 					t.assertTrue(testGlobal["dojo"]);
@@ -66,7 +66,7 @@ if(doh.selfTest){
 
 	if(testGlobal["setTimeout"]){
 		// a stone-stupid async test
-		doh.register("tests.async", 
+		doh.register("tests.async",
 			[
 				{
 					name: "deferredSuccess",
@@ -110,6 +110,12 @@ 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"],
diff --git a/dojo/tests/_base/AMD-build-transform/t1.js b/dojo/tests/_base/AMD-build-transform/t1.js
new file mode 100644
index 0000000..1ad5b11
--- /dev/null
+++ b/dojo/tests/_base/AMD-build-transform/t1.js
@@ -0,0 +1,38 @@
+// 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
new file mode 100644
index 0000000..1a767dd
--- /dev/null
+++ b/dojo/tests/_base/AMD-build-transform/t2.js
@@ -0,0 +1,14 @@
+// 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
new file mode 100644
index 0000000..3be57af
--- /dev/null
+++ b/dojo/tests/_base/AMD-build-transform/t3.js
@@ -0,0 +1,8 @@
+//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
new file mode 100644
index 0000000..a046668
--- /dev/null
+++ b/dojo/tests/_base/AMD-build-transform/t4.js
@@ -0,0 +1,13 @@
+// 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
new file mode 100644
index 0000000..59f09ee
--- /dev/null
+++ b/dojo/tests/_base/AMD-build-transform/t5.js
@@ -0,0 +1,13 @@
+// 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 a0e85aa..b7ccbb4 100644
--- a/dojo/tests/_base/Color.js
+++ b/dojo/tests/_base/Color.js
@@ -9,7 +9,7 @@ dojo.provide("tests._base.Color");
 		dojo.forEach(color.toRgba(), function(n){ t.is("number", typeof(n)); });
 	}
 
-	doh.register("tests._base.Color", 
+	doh.register("tests._base.Color",
 		[
 			function testColor1(t){ verifyColor(t, "maroon", maroon); },
 			function testColor2(t){ verifyColor(t, "white", white); },
diff --git a/dojo/tests/_base/Deferred.js b/dojo/tests/_base/Deferred.js
index b9c1505..c1117b3 100644
--- a/dojo/tests/_base/Deferred.js
+++ b/dojo/tests/_base/Deferred.js
@@ -2,6 +2,7 @@ dojo.provide("tests._base.Deferred");
 
 var delay = function(ms){
 	var d = new dojo.Deferred();
+	ms = ms || 20;
 	setTimeout(function(){
 		d.progress(0.5);
 	},ms/2);
@@ -10,7 +11,7 @@ var delay = function(ms){
 	},ms);
 	return d.promise;
 };
-doh.register("tests._base.Deferred", 
+doh.register("tests._base.Deferred",
 	[
 
 		function callback(t){
@@ -175,6 +176,84 @@ doh.register("tests._base.Deferred",
 			def.resolve(true);
 			t.is(dojo.global.results, undefined, "results is leaking into global");
 			t.is(dojo.global.fired, undefined, "fired is leaking into global");
+		},
+		function backAndForthProcess(t){
+			var def = new dojo.Deferred();
+			var retval = "fail";
+
+			def.addErrback(function(){
+				return "ignore error and throw this good string";
+			}).addCallback(function(){
+				throw new Error("error1");
+			}).addErrback(function(){
+				return "ignore second error and make it good again";
+			}).addCallback(function(){
+				retval = "succeed";
+			});
+
+			def.errback("");
+
+			t.assertEqual("succeed", retval);
+		},
+		function backAndForthProcessThen(t){
+			var def = new dojo.Deferred;
+			var retval = "fail";
+
+			def.then(null, function(){
+				return "ignore error and throw this good string";
+			}).then(function(){
+				throw "error1";
+			}).then(null, function(){
+				return "ignore second error and make it good again";
+			}).then(function(){
+				retval = "succeed";
+			});
+
+			def.reject("");
+
+			t.assertEqual("succeed", retval);
+		},
+		function returnErrorObject(t){
+			var def = new dojo.Deferred();
+			var retval = "fail";
+
+			def.addCallback(function(){
+				return new Error("returning an error should work same as throwing");
+			}).addErrback(function(){
+				retval = "succeed";
+			});
+
+			def.callback();
+
+			t.assertEqual("succeed", retval);
+		},
+		function returnErrorObjectThen(t){
+			var def = new dojo.Deferred();
+			var retval = "fail";
+
+			def.then(function(){
+				return new Error("returning an error should NOT work same as throwing");
+			}).then(function(){
+				retval = "succeed";
+			});
+
+			def.resolve();
+
+			t.assertEqual("succeed", retval);
+		},
+		function errbackWithPromise(t){
+			var def = new dojo.Deferred();
+			var retval;
+
+			def.addCallbacks(function(){}, function(err){
+				return err;
+			});
+			def.promise.then(
+					function(){ retval = "fail"; },
+					function(){ retval = "succeed"; });
+			def.errback(new Error);
+
+			t.assertEqual("succeed", retval);
 		}
-	]
+ ]
 );
diff --git a/dojo/tests/_base/NodeList.html b/dojo/tests/_base/NodeList.html
index 64343b4..c1d3d9a 100644
--- a/dojo/tests/_base/NodeList.html
+++ b/dojo/tests/_base/NodeList.html
@@ -34,6 +34,9 @@
 			djConfig="isDebug: false"></script>
 		<script type="text/javascript">
 			dojo.require("doh.runner");
+			dojo.require("dojo.string");
+			dojo.require("dojo.parser");
+
 			dojo.addOnLoad(function(){
 				var c = dojo.byId("c1");
 				var t = dojo.byId("t");
@@ -330,6 +333,19 @@
 							tnl.removeClass(["a", "c"]);
 							doh.is("", s.className);
 							doh.is("", t.className);
+							tnl.addClass("a b c");
+							tnl.replaceClass("d e", "a b");
+							doh.is("c d e", s.className, "class is c d e after replacing a b with d e");
+							doh.is("c d e", t.className, "class is c d e after replacing a b with d e");
+							tnl.replaceClass("f", "d");
+							doh.is("c e f", s.className, "class is c e f after replacing d with f");
+							doh.is("c e f", t.className, "class is c e f after replacing d with f");
+							tnl.replaceClass("d");
+							doh.is("d", s.className);
+							doh.is("d", t.className);
+							tnl.removeClass();
+							doh.is("", s.className, "empty class");
+							doh.is("", t.className, "empty class");
 						},
 
 						function concat(){
@@ -445,7 +461,6 @@
 							});
 
 							//template with dojo.string.substitute used.
-							dojo.require("dojo.string");
 							templs.addContent({
 								template: "<p>${name}</p>",
 								name: "baz"
@@ -458,7 +473,6 @@
 							});
 
 							//Try a dojo.declared thing.
-							dojo.require("dojo.parser");
 							dojo.declare("dojo.tests.Mini", null, {
 								constructor: function(args, node){
 									dojo.mixin(this, args);
diff --git a/dojo/tests/_base/_loader/8976.html b/dojo/tests/_base/_loader/8976.html
index c8d55d1..0706ebf 100644
--- a/dojo/tests/_base/_loader/8976.html
+++ b/dojo/tests/_base/_loader/8976.html
@@ -5,7 +5,10 @@
 </head>
 <body>
 <h1>Testcase for #8976</h1>
-<p>Test case for <a href="http://bugs.dojotoolkit.org/ticket/8976">#8976</a>, an async load issue with Firefox even though the loading should be synchronous. Click the button then check console log for output of test. If "count = 1, worked" shows up instead of an error, then the test is successful.</p>
+<p>Test case for <a href="http://bugs.dojotoolkit.org/ticket/8976">#8976</a>, an async load issue with Firefox even 
+    though the loading should be synchronous. Click the button then check console log for output of test. If "count = 1, worked" 
+    shows up instead of an error, then the test is successful.
+</p>
 
 <script>
 var count = 0;
diff --git a/dojo/tests/_base/_loader/a.js b/dojo/tests/_base/_loader/a.js
new file mode 100644
index 0000000..0ee2372
--- /dev/null
+++ b/dojo/tests/_base/_loader/a.js
@@ -0,0 +1,3 @@
+define({
+	number: 42
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/_loader/afterOnLoad.html b/dojo/tests/_base/_loader/afterOnLoad.html
index c5c0a2f..ed4c7a0 100644
--- a/dojo/tests/_base/_loader/afterOnLoad.html
+++ b/dojo/tests/_base/_loader/afterOnLoad.html
@@ -4,9 +4,9 @@
 	<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">
+		<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(){
diff --git a/dojo/tests/_base/_loader/bootstrap.js b/dojo/tests/_base/_loader/bootstrap.js
index 24ae382..1e6ef9b 100644
--- a/dojo/tests/_base/_loader/bootstrap.js
+++ b/dojo/tests/_base/_loader/bootstrap.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base._loader.bootstrap");
 
-tests.register("tests._base._loader.bootstrap", 
+tests.register("tests._base._loader.bootstrap",
 	[
 
 		function hasConsole(t){
@@ -65,12 +65,23 @@ tests.register("tests._base._loader.bootstrap",
 			name: "exists",
 			setUp: function(){
 				this.foo = {
-					bar: {}
+					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));
 			}
 		},
 
diff --git a/dojo/tests/_base/_loader/config-data-global.html b/dojo/tests/_base/_loader/config-data-global.html
new file mode 100644
index 0000000..611ce8b
--- /dev/null
+++ b/dojo/tests/_base/_loader/config-data-global.html
@@ -0,0 +1,31 @@
+<!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
new file mode 100644
index 0000000..641a90b
--- /dev/null
+++ b/dojo/tests/_base/_loader/config-data.html
@@ -0,0 +1,24 @@
+<!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
new file mode 100644
index 0000000..af3cc53
--- /dev/null
+++ b/dojo/tests/_base/_loader/config-dj-elemt.html
@@ -0,0 +1,24 @@
+<!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
new file mode 100644
index 0000000..bd08b62
--- /dev/null
+++ b/dojo/tests/_base/_loader/config-dj-global.html
@@ -0,0 +1,29 @@
+<!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/hostenv_browser.js b/dojo/tests/_base/_loader/hostenv_browser.js
index a05318d..2699d43 100644
--- a/dojo/tests/_base/_loader/hostenv_browser.js
+++ b/dojo/tests/_base/_loader/hostenv_browser.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base._loader.hostenv_browser");
 
-tests.register("tests._base._loader.hostenv_browser", 
+tests.register("tests._base._loader.hostenv_browser",
 	[
 		function getText(t){
 			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
@@ -9,3 +9,9 @@ tests.register("tests._base._loader.hostenv_browser",
 		}
 	]
 );
+
+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
index 35e0ac1..6648c16 100644
--- a/dojo/tests/_base/_loader/hostenv_rhino.js
+++ b/dojo/tests/_base/_loader/hostenv_rhino.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base._loader.hostenv_rhino");
 
-tests.register("tests._base._loader.hostenv_rhino", 
+tests.register("tests._base._loader.hostenv_rhino",
 	[
 		function getText(t){
 			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
diff --git a/dojo/tests/_base/_loader/hostenv_spidermonkey.js b/dojo/tests/_base/_loader/hostenv_spidermonkey.js
index 80e91a9..599df2d 100644
--- a/dojo/tests/_base/_loader/hostenv_spidermonkey.js
+++ b/dojo/tests/_base/_loader/hostenv_spidermonkey.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base._loader.hostenv_spidermonkey");
 
-tests.register("tests._base._loader.hostenv_spidermonkey", 
+tests.register("tests._base._loader.hostenv_spidermonkey",
 	[
 		function getText(t){
 			var filePath = dojo.moduleUrl("tests._base._loader", "getText.txt");
diff --git a/dojo/tests/_base/_loader/loader.js b/dojo/tests/_base/_loader/loader.js
index 0067f5e..693dc35 100644
--- a/dojo/tests/_base/_loader/loader.js
+++ b/dojo/tests/_base/_loader/loader.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base._loader.loader");
 
-tests.register("tests._base._loader.loader", 
+tests.register("tests._base._loader.loader",
 	[
 		function baseUrl(t){
 			var originalBaseUrl = dojo.config["baseUrl"] || "./";
diff --git a/dojo/tests/_base/_loader/modules.js b/dojo/tests/_base/_loader/modules.js
new file mode 100644
index 0000000..9385af4
--- /dev/null
+++ b/dojo/tests/_base/_loader/modules.js
@@ -0,0 +1,21 @@
+// 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/anon.js b/dojo/tests/_base/_loader/modules/anon.js
new file mode 100644
index 0000000..1bfeb82
--- /dev/null
+++ b/dojo/tests/_base/_loader/modules/anon.js
@@ -0,0 +1,6 @@
+define(["../a", "./wrapped"], function (a, wrapped) {
+	return {
+		theAnswer: a.number,
+		five: wrapped.five
+	};
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/_loader/modules/data.js b/dojo/tests/_base/_loader/modules/data.js
new file mode 100644
index 0000000..9874c89
--- /dev/null
+++ b/dojo/tests/_base/_loader/modules/data.js
@@ -0,0 +1,4 @@
+define({
+	greeting: "Hello",
+	five: 5
+});
\ No newline at end of file
diff --git a/dojo/tests/_base/_loader/modules/factoryArity.js b/dojo/tests/_base/_loader/modules/factoryArity.js
new file mode 100644
index 0000000..75f0839
--- /dev/null
+++ b/dojo/tests/_base/_loader/modules/factoryArity.js
@@ -0,0 +1,2 @@
+// make sure that module.exports doesn't kill factory result since factory has arity<3
+define(function() { return {i : 5} ; });
\ No newline at end of file
diff --git a/dojo/tests/_base/_loader/modules/full.js b/dojo/tests/_base/_loader/modules/full.js
new file mode 100644
index 0000000..7ff222b
--- /dev/null
+++ b/dojo/tests/_base/_loader/modules/full.js
@@ -0,0 +1,7 @@
+// 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
new file mode 100644
index 0000000..626a508
--- /dev/null
+++ b/dojo/tests/_base/_loader/modules/wrapped.js
@@ -0,0 +1,4 @@
+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
index b1dff98..c3a5bb1 100644
--- a/dojo/tests/_base/_loader/scope/scope04.html
+++ b/dojo/tests/_base/_loader/scope/scope04.html
@@ -4,9 +4,9 @@
 	<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">
+		<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.
diff --git a/dojo/tests/_base/_loader/scope/scopeContained.html b/dojo/tests/_base/_loader/scope/scopeContained.html
index 67b74de..490087c 100644
--- a/dojo/tests/_base/_loader/scope/scopeContained.html
+++ b/dojo/tests/_base/_loader/scope/scopeContained.html
@@ -4,9 +4,9 @@
 	<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">
+		<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.
diff --git a/dojo/tests/_base/_loader/scope/scopeContainedXd.html b/dojo/tests/_base/_loader/scope/scopeContainedXd.html
index 8f4b15e..a0a99a0 100644
--- a/dojo/tests/_base/_loader/scope/scopeContainedXd.html
+++ b/dojo/tests/_base/_loader/scope/scopeContainedXd.html
@@ -4,9 +4,9 @@
 	<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">
+		<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.
diff --git a/dojo/tests/_base/_loader/scope/scopeDjConfig.html b/dojo/tests/_base/_loader/scope/scopeDjConfig.html
index 022b513..58b9cf9 100644
--- a/dojo/tests/_base/_loader/scope/scopeDjConfig.html
+++ b/dojo/tests/_base/_loader/scope/scopeDjConfig.html
@@ -4,9 +4,9 @@
 	<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">
+		<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.
diff --git a/dojo/tests/_base/_loader/scope/scopeSingle.html b/dojo/tests/_base/_loader/scope/scopeSingle.html
index 98fc637..1268050 100644
--- a/dojo/tests/_base/_loader/scope/scopeSingle.html
+++ b/dojo/tests/_base/_loader/scope/scopeSingle.html
@@ -4,9 +4,9 @@
 	<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">
+		<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.
diff --git a/dojo/tests/_base/_loader/scope/scopeSingleDaac.html b/dojo/tests/_base/_loader/scope/scopeSingleDaac.html
index 4dc3ecc..9852a01 100644
--- a/dojo/tests/_base/_loader/scope/scopeSingleDaac.html
+++ b/dojo/tests/_base/_loader/scope/scopeSingleDaac.html
@@ -4,9 +4,9 @@
 	<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">
+		<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.
diff --git a/dojo/tests/_base/array.js b/dojo/tests/_base/array.js
index c07a8c6..18e4803 100644
--- a/dojo/tests/_base/array.js
+++ b/dojo/tests/_base/array.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base.array");
 
-tests.register("tests._base.array", 
+tests.register("tests._base.array",
 	[
 		function testIndexOf(t){
 			var foo = [128, 256, 512];
diff --git a/dojo/tests/_base/connect.js b/dojo/tests/_base/connect.js
index d825bc0..ed5eeef 100644
--- a/dojo/tests/_base/connect.js
+++ b/dojo/tests/_base/connect.js
@@ -12,7 +12,7 @@ good = function(){
 }
 
 // make 'iterations' connections to hub
-// roughly half of which will be to 'good' and 
+// roughly half of which will be to 'good' and
 // half to 'bad'
 // all connections to 'bad' are disconnected
 // test can then be performed on the values
@@ -35,8 +35,8 @@ markAndSweepTest = function(iterations){
 			rm.push(marked[m]);
 			marked.splice(m, 1);
 		}
-		marked = rm;				
-	} 
+		marked = rm;
+	}
 	for(var m=0; m<marked.length; m++){
 		dojo.disconnect(marked[m]);
 	}
@@ -66,8 +66,8 @@ markAndSweepSubscribersTest = function(iterations){
 			rm.push(marked[m]);
 			marked.splice(m, 1);
 		}
-		marked = rm;				
-	} 
+		marked = rm;
+	}
 	for(var m=0; m<marked.length; m++){
 		dojo.unsubscribe(marked[m]);
 	}
@@ -158,7 +158,7 @@ tests.register("tests._base.connect",
 			gFoo();
 			dojo.disconnect(link);
 			t.is(true, ok);
-			// verify disconnections 
+			// verify disconnections
 			gFoo();
 			t.is(false, ok);
 		},
@@ -167,12 +167,12 @@ tests.register("tests._base.connect",
 			var ok;
 			dojo.global["gFoo"] = function(){ok=false;};
 			dojo.global["gOk"] = function(){ok=true;};
-			// 2 arg shorthand for globals 
+			// 2 arg shorthand for globals
 			var link = dojo.connect("gFoo", "gOk");
 			gFoo();
 			dojo.disconnect(link);
 			t.is(true, ok);
-			// 2 arg shorthand for globals, alternate scoping 
+			// 2 arg shorthand for globals, alternate scoping
 			link = dojo.connect("gFoo", gOk);
 			gFoo();
 			dojo.disconnect(link);
@@ -186,7 +186,7 @@ tests.register("tests._base.connect",
 			foo.foo();
 			t.is(false, foo.ok);
 			t.is(true, bar.ok);
-		},		
+		},
 		function scopeTest2(t){
 			var foo = { ok: true, foo: function(){this.ok=false;} };
 			var bar = { ok: false, bar: function(){this.ok=true} };
diff --git a/dojo/tests/_base/declare.js b/dojo/tests/_base/declare.js
index 10dea88..2963fc0 100644
--- a/dojo/tests/_base/declare.js
+++ b/dojo/tests/_base/declare.js
@@ -188,7 +188,7 @@ tests.register("tests._base.declare",
 		},
 
 		function basicMixin(t){
-			// testing if a plain Class-like object can be inherited 
+			// testing if a plain Class-like object can be inherited
 			// by dojo.declare
 			var d = new doh.Deferred;
 
diff --git a/dojo/tests/_base/html.html b/dojo/tests/_base/html.html
index 04e6285..4a38dff 100644
--- a/dojo/tests/_base/html.html
+++ b/dojo/tests/_base/html.html
@@ -54,6 +54,8 @@
 
 						"doh.is(100, dojo.marginBox('sq100').w);",
 						"doh.is(100, dojo.marginBox('sq100').h);",
+						"doh.is(100, dojo._getMarginSize('sq100').w);",
+						"doh.is(100, dojo._getMarginSize('sq100').h);",
 
 						"doh.is(120, dojo.marginBox('sq100margin10').w);",
 						"doh.is(120, dojo.marginBox('sq100margin10').h);",
@@ -62,6 +64,8 @@
 
 						"doh.is(140, dojo.marginBox('sq100margin10pad10').w);",
 						"doh.is(140, dojo.marginBox('sq100margin10pad10').h);",
+						"doh.is(140, dojo._getMarginSize('sq100margin10pad10').w);",
+						"doh.is(140, dojo._getMarginSize('sq100margin10pad10').h);",
 
 						"doh.is(120, dojo.marginBox('sq100pad10').w);",
 						"doh.is(120, dojo.marginBox('sq100pad10').h);",
@@ -114,7 +118,7 @@
 						"doh.is(40, dojo._getPadBorderExtents(dojo.byId('sq100border10margin10pad10')).h);",
 
 						function scrollUp(){
-							dojo.doc.documentElement.scrollTop = 0;
+							scrollTo(0, 0);
 						},
 
 						function coordsBasic(t){
@@ -242,6 +246,7 @@
 						},
 						function testClassFunctions(t){
 							var node = dojo.byId("sq100");
+							dojo.removeClass(node);
 							dojo.addClass(node, "a");
 							doh.is("a", node.className, "class is a");
 							dojo.removeClass(node, "c");
@@ -277,9 +282,24 @@
 								acuWorked = false;
 							}
 							doh.is(true, acuWorked, "addClass handles undefined class");
+							dojo.addClass(node, "a");
+							dojo.replaceClass(node, "b", "a");
+							t.assertTrue(dojo.hasClass(node, "b"), "class is b after replacing a, test for b");
+							t.assertFalse(dojo.hasClass(node, "a"), "class is b after replacing a, test for not a");
+							
+							dojo.replaceClass(node, "", "b");
+							t.assertFalse(dojo.hasClass(node, "b"), "class b should be removed, with no class added");
+							t.is("", node.className, "The className is empty");
+							
+							dojo.addClass(node, "b a");
+							dojo.replaceClass(node, "c", "");
+							t.is("b a c", node.className, 
+								"The className is  is 'b a c' after using an empty string in replaceClass");
+							
 						},
 						function testAddRemoveClassMultiple(t){
 							var node = dojo.byId("sq100");
+							dojo.removeClass(node);
 							dojo.addClass(node, "a");
 							t.is("a", node.className, "class is a");
 							dojo.addClass(node, "a b");
@@ -298,6 +318,12 @@
 							t.is("a", node.className, "class is a");
 							dojo.removeClass(node, ["a", "c"]);
 							t.is("", node.className, "empty class");
+							dojo.addClass(node, "a b");
+							dojo.replaceClass(node, "c", "a b");
+							t.is("c", node.className, "class is c");
+							dojo.replaceClass(node, "");
+							t.is("", node.className, "empty class");
+							node.className = "";
 						},
 						function getTypeInput(t){
 							doh.f(dojo.hasAttr(dojo.byId("input-no-type"), "type"));
@@ -565,6 +591,32 @@
 						}
 					]
 				);
+				
+				// 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,
+							runTest: function(t){
+								var d = new doh.Deferred(),
+									s = document.createElement('SPAN');
+								s.loaded = function(iframe){
+									// resultReady is called from inside the iframe
+									iframe.resultReady = d.getTestCallback(function(){
+										t.is('EQUAL', iframe.testResult);
+									});
+									iframe.runScrollingTest(iframe);
+								};
+								s.innerHTML = '<iframe class="iframeTest" id="' + id + '" src="scrolling' + doctype + 'Iframe.html?ltr&' + scroll + '&large" frameborder="0" onload="this.parentNode.loaded(this)" style="background-color:gray;" allowtransparency></iframe>';
+								dojo.byId("iframeContainer").appendChild(s);
+								return d;
+							}
+						});
+					});
+				});
+
 				doh.run();
 			});
 		</script>
@@ -719,6 +771,10 @@
 				margin: 0px;
 			}
 
+			#scrollingStrictIframe,
+			#scrollingQuirksIframe {
+				border: 10px solid black;
+			}
 		</style>
 	</head>
 	<body>
@@ -792,6 +848,7 @@
 			<label id="label-no-for">label with no for </label><input type="text" id="label-test-input">
 			<label id="label-with-for" for="input-with-label">label with for </label><input type="text" id="input-with-label">
 		</div>
+
+		<div id="iframeContainer"></div>
 	</body>
 </html>
-
diff --git a/dojo/tests/_base/html_rtl.html b/dojo/tests/_base/html_rtl.html
index 8925c59..e5d3214 100644
--- a/dojo/tests/_base/html_rtl.html
+++ b/dojo/tests/_base/html_rtl.html
@@ -13,91 +13,105 @@
 			dojo.require("doh.runner");
 			
 			dojo.addOnLoad(function(){
-				doh.register("t", 
+				doh.register("rtl", 
 					[
-						function coordsWithVertScrollbar(t){
-							// show vertical scrollbar
-							dojo.byId("rect_vert").style.display = "";
-							scrollTo(0, 50);
-							var d = new doh.Deferred();
-							setTimeout(function(){ // need time to render
-								try{
-									t.is(100, dojo.position('rect100').x, "x pos should be 100 after vertical scroll");
-									t.is(50, dojo.position('rect100').y, "y pos should be 50 after vertical scroll");
-									d.callback(true);
-								}catch(e){
-									d.errback(e);
-								}finally{
-									dojo.byId("rect_vert").style.display = "none";
-								}
-							}, 100);
-							return d;
-						},
-
-						function coordsWithHorzScrollbar(t){
-							// show horizonal scrollbar & scroll a bit left
-							dojo.byId("rect_horz").style.display = "";
-							scrollTo(0, 0);
-							var d = new doh.Deferred();
-							setTimeout(function(){ // need time to render
-								try{
-									var pos = dojo.position('rect100');
-									t.is(100, pos.y, "position().y="+pos.y+" but should be 100 after horizontal scroll");
-									scrollBy(100, 0); // funny scrolling to account for different browsers
-									scrollBy(-50, 0);
-									t.is(50, Math.abs(dojo.position('rect100').x-pos.x), "position().x should have changed by 50 after horizontal scroll (actual change was " + Math.abs(dojo.position('rect100').x-pos.x) + ")");
-									scrollTo(0, 0); // reset horizontal scroll before hiding scrollbar for IE8's benefit
-									d.callback(true);
-								}catch(e){
-									d.errback(e);
-								}finally{
-									dojo.byId("rect_horz").style.display = "none";
-								}
-							}, 100);
-							return d;
+						{
+							name: "coordsWithScrolling",
+							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
+									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
+										var pos = dojo.position('rect100', true);
+										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);
+								return d;
+							}
 						},
 
-						function eventClientXY(t){ // IE only test
-							if(dojo.isIE){
-								// show vertical scrollbar
-								dojo.byId("rect_vert").style.display = "";
+						{
+							name: "eventClientXY_IE",
+							timeout: 1000,
+							runTest: function(t){
+								if(!dojo.isIE){ return; }
 
-								var rect = dojo.byId("rect100");
-								var assertException = null;
-
-								function rect_onclick(e){
-									// move the rectangle to the mouse point
-									rect.style.left = e.pageX + "px";
-									rect.style.top = e.pageY + "px";
-									window.alert("Do NOT move your mouse!!!\n\n" + 
-												"The black rectangle's top-left point should be under the mouse point.\n\n" +
-												"If not, you will see a failure in the test report later.\n\n" +
-												"Now press the space bar, but do NOT move your mouse.");
-									rect.fireEvent('ondblclick');
-								}
-
-								function rect_ondblclick(){
-									// test if the rectangle is really under the mouse point
-									try{
-										t.is(0, event.offsetX);
-										t.is(0, event.offsetY);
-									}catch(e){ // allow the exception in a event handler go to the event firer 
-										assertException = e;
-									}
-								}
+								var
+								d = new doh.Deferred(),
+								rect = dojo.byId("rect100"),
+								handler = dojo.connect(dojo.body(), "onclick", null,
+									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;
+												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
+								return d;
+							}
+						},
 
-								dojo.connect(rect, "onclick", null, rect_onclick);
-								dojo.connect(rect, "ondblclick", null, rect_ondblclick);
-								window.alert("Move the mouse to anywhere in this page, and then press the space bar.");
-								rect.fireEvent('onclick');
-								if(assertException != null){
-									throw assertException;
-								}
+						{
+							name: "testScrolledPosition",
+							timeout: 10000,
+							runTest: function(t){
+								var d = new doh.Deferred(),
+									control = dojo.doc.getElementById('control');
+								control.resultReady = d.getTestCallback(function(){
+									t.is("EQUAL", control.testResult);
+								});
+								runScrollingTest(control);
+								return d;
 							}
 						}
-						
 					]
 				);
+				
+				// 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){
+						dojo.forEach(["Small", "Large"], function(size){
+							var id = "scrolling" + doctype + "Iframe" + scroll + size;
+							doh.register(id, {
+								name: "test_" + id,
+								timeout: 3000,
+								runTest: function(t){
+									var d = new doh.Deferred(),
+										s = document.createElement('SPAN');
+									s.loaded = function(iframe){
+										// resultReady is called from inside the iframe
+										iframe.resultReady = d.getTestCallback(function(){
+											t.is('EQUAL', iframe.testResult);
+										});
+										iframe.runScrollingTest(iframe);
+									};
+									s.innerHTML = '<iframe class="iframeTest" id="' + id + '" src="scrolling' + doctype + 'Iframe.html?rtl&' + scroll + '&' + size +'" frameborder="0" onload="this.parentNode.loaded(this)" style="background-color:gray;" allowtransparency></iframe>';
+									dojo.byId("iframeContainer").appendChild(s);
+									return d;
+								}
+							});
+						});
+					});
+				});
+
 				doh.run();
 			});
 		</script>
@@ -115,6 +129,10 @@
 				margin: 0px;
 				overflow: hidden;
 			}
+
+			.iframeTest {
+				border: 5px solid black;
+			}
 		</style>
 	</head>
 	<body>
@@ -123,8 +141,10 @@
 			100px rect, abs, 
 			mouse point is at top-left after the test "eventClientXY"
 		</div>
-		<div id="rect_vert" style="height:1600px;display:none">show vertical scrollbar</div>
-		<div id="rect_horz" style="width:1600px;position:relative;right:-200px;display:none">show horizonal scrollbar</div>
+		<div id="rect_vert" style="height:1600px;">show vertical scrollbar</div>
+		<div id="rect_horz" style="width:1600px;position:relative;right:-200px;">show horizonal scrollbar</div>
+		<br>
+		<script type="text/javascript" src="scrollingIframe.js"></script>
+		<div id="iframeContainer"></div>
 	</body>
 </html>
-
diff --git a/dojo/tests/_base/json.js b/dojo/tests/_base/json.js
index 157a5e0..687622c 100644
--- a/dojo/tests/_base/json.js
+++ b/dojo/tests/_base/json.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base.json");
 
-tests.register("tests._base.json", 
+tests.register("tests._base.json",
 	[
 		//Not testing dojo.toJson() on its own since Rhino will output the object properties in a different order.
 		//Still valid json, but just in a different order than the source string.
diff --git a/dojo/tests/_base/lang.js b/dojo/tests/_base/lang.js
index 7017ba8..3f526a8 100644
--- a/dojo/tests/_base/lang.js
+++ b/dojo/tests/_base/lang.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base.lang");
 
-tests.register("tests._base.lang", 
+tests.register("tests._base.lang",
 	[
 		function mixin(t){
 			t.assertEqual("object", typeof dojo.mixin());
@@ -173,13 +173,13 @@ tests.register("tests._base.lang",
 			}
 		},
 		
-		function clone(t) { 
+		function clone(t) {
 			var obj1 = {
 				foo: 'bar',
 				answer: 42,
-				jan102007: new Date(2007, 0, 10), 
+				jan102007: new Date(2007, 0, 10),
 				baz: {
-					a: null, 
+					a: null,
 					b: [1, "b", 2.3, true, false],
 					c: {
 						d: undefined,
@@ -189,7 +189,7 @@ tests.register("tests._base.lang",
 					}
 				},
 				toString: function(){ return "meow"; }
-			}; 
+			};
 			var obj2 = dojo.clone(obj1);
 			t.assertEqual(obj1.foo, obj2.foo);
 			t.assertEqual(obj1.answer, obj2.answer);
diff --git a/dojo/tests/_base/query.html b/dojo/tests/_base/query.html
index 55c3f3c..86bc09b 100644
--- a/dojo/tests/_base/query.html
+++ b/dojo/tests/_base/query.html
@@ -12,6 +12,7 @@
 		<script type="text/javascript" src="../../../util/doh/runner.js"></script>
 		<script type="text/javascript">
 			dojo.require("doh.runner");
+			dojo.require("dojo.io.iframe");
 
 			function createDocument(xml){
 				var fauxXhr = { responseText: xml };
@@ -191,7 +192,6 @@
 
 							name: "crossDocumentQuery",
 							setUp: function(){
-								dojo.require("dojo.io.iframe");
 								this.t3 = window.frames["t3"];
 								this.doc = dojo.io.iframe.doc(t3);
 								this.doc.open();
diff --git a/dojo/tests/_base/query.js b/dojo/tests/_base/query.js
index 3cd6738..1cc3f16 100644
--- a/dojo/tests/_base/query.js
+++ b/dojo/tests/_base/query.js
@@ -1,5 +1,5 @@
 dojo.provide("tests._base.query");
 if(dojo.isBrowser){
-	doh.registerUrl("tests._base.query", dojo.moduleUrl("tests", "_base/query.html"));
-	doh.registerUrl("tests._base.NodeList", dojo.moduleUrl("tests", "_base/NodeList.html"));
+	doh.registerUrl("tests._base.query", dojo.moduleUrl("tests", "_base/query.html"), 60000);
+	doh.registerUrl("tests._base.NodeList", dojo.moduleUrl("tests", "_base/NodeList.html"), 60000);
 }
diff --git a/dojo/tests/_base/runTests.html b/dojo/tests/_base/runTests.html
new file mode 100644
index 0000000..9a77dff
--- /dev/null
+++ b/dojo/tests/_base/runTests.html
@@ -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?testModule=dojo.tests.baseonly"></HEAD>
+    <BODY>
+        Redirecting to D.O.H runner.
+    </BODY>
+</HTML> 
diff --git a/dojo/tests/_base/scrollingIframe.js b/dojo/tests/_base/scrollingIframe.js
new file mode 100644
index 0000000..8a2cac8
--- /dev/null
+++ b/dojo/tests/_base/scrollingIframe.js
@@ -0,0 +1,104 @@
+var isQuirks = document.compatMode == "BackCompat";
+
+function runScrollingTest(resultNode){
+	// reposition the absolute-positioned tag to the top/left of the static control
+	//	element and check to make sure each has the same offsetLeft/Top
+	if(!("dojo" in window)){
+		var doc = frameElement.ownerDocument;
+		var win = doc.parentWindow || doc.defaultView;
+		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");
+	var abs1 = document.getElementById("abs1");
+	window.scrollTo(0, 0); // start with standarized placement
+	setTimeout(function(){
+		var cw = dojo.hitch(dojo, "withGlobal")(window, "position", dojo, [clientWidth, false]);
+		if(cw.x != 0){
+			scrollBy(cw.x, 0); // scroll width:100% control element fully into view
+		}
+		var p = dojo.hitch(dojo, "withGlobal")(window, "position", dojo, [control, true]);
+		abs1.style.left = p.x + "px";
+		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(abs1.offsetLeft == control.offsetLeft){
+					if(abs1.offsetTop == control.offsetTop){
+						resultNode.testResult = "EQUAL";
+					}else{
+						resultNode.testResult = "abs1.offsetTop="+abs1.offsetTop + " control.offsetTop="+control.offsetTop;
+					}
+				}else{
+					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;
+			}
+			if(resultNode.resultReady){ resultNode.resultReady(); }
+		}, 100);
+	}, 100);
+}
+
+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
+			? (
+				(hScroll ? '<DIV style="float:left;position:relative;width:600px;"> </DIV>' : '') +
+				(hScroll ? '<DIV style="float:right;position:relative;width:600px;"> </DIV>' : '') +
+				(vScroll ? '<CENTER style="width:1px;height:600px;"> </CENTER>' : '')
+			)
+			: ''
+		) +
+	'');
+}
+
+function genScrollingTestBody(){
+	var options = window.location.search.substr(1).toLowerCase().split(/&/);
+	options.dir = "ltr";
+	for(var i=0; i < options.length; i++){
+		var option = options[i];
+		switch(option){
+			case "ltr":
+			case "rtl":
+				options.dir = option;
+				break;
+			case"both":
+				options.horz = 1;
+				options.vert = 1;
+				break;
+			default: options[option] = 1;
+		}
+	}
+	var html = document.getElementsByTagName("HTML")[0];
+	html.dir = options.dir;
+	// the setTimeout in the onload allows the browser time to scroll the iframe to the previous position
+	var scroll = options.large ? '' : 'scroll';
+	if(!options.horz){
+		html.style.overflowX = "hidden";
+	}else if(!isQuirks && !options.large){
+		html.style.overflowX = scroll;
+	}
+	if(!options.vert){
+		html.style.overflowY = "hidden";
+	}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') : '') + ';">');
+	genScrollingTestNodes(options.horz, options.vert, options.large);
+	document.write('</BODY>');
+}
+
+if(!document.body){
+	frameElement.runScrollingTest = runScrollingTest;
+	genScrollingTestBody();
+}else{
+	genScrollingTestNodes();
+}
diff --git a/dojo/tests/_base/scrollingQuirksIframe.html b/dojo/tests/_base/scrollingQuirksIframe.html
new file mode 100644
index 0000000..9a3b453
--- /dev/null
+++ b/dojo/tests/_base/scrollingQuirksIframe.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Transitional//EN'>
+<HTML>
+<HEAD>
+	<SCRIPT type="text/javascript" src="scrollingIframe.js"></SCRIPT>
+</HEAD>
+</HTML>
diff --git a/dojo/tests/_base/scrollingStrictIframe.html b/dojo/tests/_base/scrollingStrictIframe.html
new file mode 100644
index 0000000..945a2a7
--- /dev/null
+++ b/dojo/tests/_base/scrollingStrictIframe.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<HTML>
+<HEAD>
+	<SCRIPT type="text/javascript" src="scrollingIframe.js"></SCRIPT>
+</HEAD>
+</HTML>
diff --git a/dojo/tests/_base/window.js b/dojo/tests/_base/window.js
index f57e37e..c0f6941 100644
--- a/dojo/tests/_base/window.js
+++ b/dojo/tests/_base/window.js
@@ -1,6 +1,6 @@
 dojo.provide("tests._base.window");
 
-tests.register("tests._base.window", 
+tests.register("tests._base.window",
 	[
 		function withGlobal(t){
 			var arg1, arg2, innerThis, innerGlobal, innerDoc, finished,
diff --git a/dojo/tests/amd/backCompat.js b/dojo/tests/amd/backCompat.js
new file mode 100644
index 0000000..1768fa2
--- /dev/null
+++ b/dojo/tests/amd/backCompat.js
@@ -0,0 +1,118 @@
+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
new file mode 100644
index 0000000..51d6ae6
--- /dev/null
+++ b/dojo/tests/amd/main.js
@@ -0,0 +1,26 @@
+// 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
new file mode 100644
index 0000000..a3d3f02
--- /dev/null
+++ b/dojo/tests/amd/smoke-bdLoad.html
@@ -0,0 +1,42 @@
+<!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
new file mode 100644
index 0000000..b9da96d
--- /dev/null
+++ b/dojo/tests/amd/smoke-requirejs.html
@@ -0,0 +1,46 @@
+<!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
new file mode 100644
index 0000000..041831f
--- /dev/null
+++ b/dojo/tests/amd/smoke.txt
@@ -0,0 +1 @@
+This is some text.
diff --git a/dojo/tests/amd/text.html b/dojo/tests/amd/text.html
new file mode 100644
index 0000000..9ec8b00
--- /dev/null
+++ b/dojo/tests/amd/text.html
@@ -0,0 +1 @@
+<html><head><title>some text</title></head><body><h1>some text</h1></body></html>
diff --git a/dojo/tests/baseonly.js b/dojo/tests/baseonly.js
new file mode 100644
index 0000000..5a459b8
--- /dev/null
+++ b/dojo/tests/baseonly.js
@@ -0,0 +1,7 @@
+dojo.provide("dojo.tests.baseonly");
+
+try{
+	dojo.require("tests._base");
+}catch(e){
+	doh.debug(e);
+}
diff --git a/dojo/tests/behavior.html b/dojo/tests/behavior.html
index 280fc29..d491bfc 100644
--- a/dojo/tests/behavior.html
+++ b/dojo/tests/behavior.html
@@ -10,7 +10,7 @@
 			src="../dojo.js" djConfig="isDebug: true, popup: true"></script>
 		<script type="text/javascript">
 			dojo.require("doh.runner");
-			dojo.require("dojo.behavior");
+			define("dojo/tests/bahavior/script", ["dojo", "dojo/behavior"], function(dojo) {
 
 			var applyCount = 0;
 
@@ -92,6 +92,7 @@
 				);
 				doh.run();
 			});
+      });
 		</script>
 	</head>
 	<body>
diff --git a/dojo/tests/cache.js b/dojo/tests/cache.js
index b721899..027374a 100644
--- a/dojo/tests/cache.js
+++ b/dojo/tests/cache.js
@@ -2,7 +2,7 @@ dojo.provide("tests.cache");
 
 dojo.require("dojo.cache");
 
-tests.register("tests.cache", 
+tests.register("tests.cache",
 	[
 		{
 			runTest: function(t){
diff --git a/dojo/tests/cldr.js b/dojo/tests/cldr.js
index 2655f8f..0944fd9 100644
--- a/dojo/tests/cldr.js
+++ b/dojo/tests/cldr.js
@@ -3,7 +3,7 @@ dojo.provide("tests.cldr");
 dojo.require("dojo.cldr.supplemental");
 dojo.require("dojo.cldr.monetary");
 
-tests.register("tests.cldr", 
+tests.register("tests.cldr",
 	[
 		function test_date_getWeekend(t){
 			t.is(6, dojo.cldr.supplemental.getWeekend('en-us').start);
diff --git a/dojo/tests/colors.js b/dojo/tests/colors.js
index d081271..a80435d 100644
--- a/dojo/tests/colors.js
+++ b/dojo/tests/colors.js
@@ -9,7 +9,7 @@ dojo.require("dojo.colors");
 		dojo.forEach(source.toRgba(), function(n){ t.is("number", typeof(n)); });
 	}
 
-	doh.register("tests.colors", 
+	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]); },
diff --git a/dojo/tests/currency.js b/dojo/tests/currency.js
index 63c5901..025e408 100644
--- a/dojo/tests/currency.js
+++ b/dojo/tests/currency.js
@@ -1,8 +1,63 @@
+(function() {
+
+  var runTest= function(dojo, t) {
+		t.is("\u20ac123.45", dojo.currency.format(123.45, {currency: "EUR", locale: "en-us"}));
+		t.is("$123.45", dojo.currency.format(123.45, {currency: "USD", locale: "en-us"}));
+		t.is("$1,234.56", dojo.currency.format(1234.56, {currency: "USD", locale: "en-us"}));
+		t.is("US$123.45", dojo.currency.format(123.45, {currency: "USD", locale: "en-ca"}));
+		t.is("$123.45", dojo.currency.format(123.45, {currency: "CAD", locale: "en-ca"}));
+		t.is("CA$123.45", dojo.currency.format(123.45, {currency: "CAD", locale: "en-us"}));
+		t.is("123,45\xa0\u20ac", dojo.currency.format(123.45, {currency: "EUR", locale: "de-de"}));
+		t.is("1.234,56\xa0\u20ac", dojo.currency.format(1234.56, {currency: "EUR", locale: "de-de"}));
+		// There is no special currency symbol for ADP, so expect the ISO code instead
+		t.is("ADP123", dojo.currency.format(123, {currency: "ADP", locale: "en-us"}));
+		t.is("$1,234", dojo.currency.format(1234, {currency: "USD", fractional: false, locale: "en-us"}));
+
+		t.is(123.45, dojo.currency.parse("$123.45", {currency: "USD", locale: "en-us"}));
+		t.is(1234.56, dojo.currency.parse("$1,234.56", {currency: "USD", locale: "en-us"}));
+		t.is(123.45, dojo.currency.parse("123,45 \u20ac", {currency: "EUR", locale: "de-de"}));
+		t.is(123.45, dojo.currency.parse("123,45\xa0\u20ac", {currency: "EUR", locale: "de-de"}));
+		t.is(1234.56, dojo.currency.parse("1.234,56 \u20ac", {currency: "EUR", locale: "de-de"}));
+		t.is(1234.56, dojo.currency.parse("1.234,56\u20ac", {currency: "EUR", locale: "de-de"}));
+
+		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", 
+tests.register("tests.currency",
 	[
 		{
 			// Test formatting and parsing of currencies in various locales pre-built in dojo.cldr
@@ -18,29 +73,13 @@ tests.register("tests.currency",
 				}
 			},
 			runTest: function(t){
-				t.is("\u20ac123.45", dojo.currency.format(123.45, {currency: "EUR", locale: "en-us"}));
-				t.is("$123.45", dojo.currency.format(123.45, {currency: "USD", locale: "en-us"}));
-				t.is("$1,234.56", dojo.currency.format(1234.56, {currency: "USD", locale: "en-us"}));
-				t.is("US$123.45", dojo.currency.format(123.45, {currency: "USD", locale: "en-ca"}));
-				t.is("$123.45", dojo.currency.format(123.45, {currency: "CAD", locale: "en-ca"}));
-				t.is("CA$123.45", dojo.currency.format(123.45, {currency: "CAD", locale: "en-us"}));
-				t.is("123,45\xa0\u20ac", dojo.currency.format(123.45, {currency: "EUR", locale: "de-de"}));
-				t.is("1.234,56\xa0\u20ac", dojo.currency.format(1234.56, {currency: "EUR", locale: "de-de"}));
-				// There is no special currency symbol for ADP, so expect the ISO code instead
-				t.is("ADP123", dojo.currency.format(123, {currency: "ADP", locale: "en-us"}));
-				t.is("$1,234", dojo.currency.format(1234, {currency: "USD", fractional: false, locale: "en-us"}));
-
-				t.is(123.45, dojo.currency.parse("$123.45", {currency: "USD", locale: "en-us"}));
-				t.is(1234.56, dojo.currency.parse("$1,234.56", {currency: "USD", locale: "en-us"}));
-				t.is(123.45, dojo.currency.parse("123,45 \u20ac", {currency: "EUR", locale: "de-de"}));
-				t.is(123.45, dojo.currency.parse("123,45\xa0\u20ac", {currency: "EUR", locale: "de-de"}));
-				t.is(1234.56, dojo.currency.parse("1.234,56 \u20ac", {currency: "EUR", locale: "de-de"}));
-				t.is(1234.56, dojo.currency.parse("1.234,56\u20ac", {currency: "EUR", locale: "de-de"}));
-
-				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"})));
+        runTest(dojo, t);
 			}
 		}
 	]
 );
+}
+
+})();
+
+
diff --git a/dojo/tests/data.js b/dojo/tests/data.js
index 40cc7e1..e66f48d 100644
--- a/dojo/tests/data.js
+++ b/dojo/tests/data.js
@@ -1,8 +1,5 @@
-dojo.provide("tests.data");
-//Squelch any json comment messages for now, since the UT allows for both.
-dojo.config.usePlainJson = true;
-dojo.require("tests.data.utils");
-dojo.require("tests.data.ItemFileReadStore");
-dojo.require("tests.data.ItemFileWriteStore");
+define("tests/data", ["dojo", "tests/data/utils", "tests/data/ItemFileReadStore", "tests/data/ItemFileWriteStore"], function(dojo) {
+  dojo.config.usePlainJson = true;
+});
 
 
diff --git a/dojo/tests/data/ItemFileReadStore.js b/dojo/tests/data/ItemFileReadStore.js
index dc61e39..0a4cde6 100644
--- a/dojo/tests/data/ItemFileReadStore.js
+++ b/dojo/tests/data/ItemFileReadStore.js
@@ -1,6 +1,4 @@
-dojo.provide("tests.data.ItemFileReadStore");
-dojo.require("tests.data.readOnlyItemFileTestTemplates");
-dojo.require("dojo.data.ItemFileReadStore");
-
-tests.data.readOnlyItemFileTestTemplates.registerTestsForDatastore("dojo.data.ItemFileReadStore");
+define("tests/data/ItemFileReadStore", ["tests/data/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 9c18fa7..18d567e 100644
--- a/dojo/tests/data/ItemFileWriteStore.js
+++ b/dojo/tests/data/ItemFileWriteStore.js
@@ -1,14 +1,8 @@
-dojo.provide("tests.data.ItemFileWriteStore");
-dojo.require("tests.data.readOnlyItemFileTestTemplates");
+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) {
 
-dojo.require("dojo.data.ItemFileWriteStore");
-dojo.require("dojo.data.api.Read");
-dojo.require("dojo.data.api.Identity");
-dojo.require("dojo.data.api.Write");
-dojo.require("dojo.data.api.Notification");
+dojo.getObject("data.ItemFileWriteStore", true, tests);
 
-
-// First, make sure ItemFileWriteStore can still pass all the same unit tests 
+// First, make sure ItemFileWriteStore can still pass all the same unit tests
 // that we use for its superclass, ItemFileReadStore:
 tests.data.readOnlyItemFileTestTemplates.registerTestsForDatastore("dojo.data.ItemFileWriteStore");
 
@@ -18,8 +12,8 @@ tests.data.ItemFileWriteStore.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/reference_integrity.json").toString() };
 		}else{
-			data = 
-				{ data: { 
+			data =
+				{ data: {
 					"identifier": "id",
 					"label": "name",
 					"items": [
@@ -48,16 +42,16 @@ tests.data.ItemFileWriteStore.getTestData = function(name){
 
 
 // Now run some tests that are specific to the write-access features:
-doh.register("tests.data.ItemFileWriteStore", 
+doh.register("tests.data.ItemFileWriteStore",
 	[
 		function test_getFeatures(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 			var store = new dojo.data.ItemFileWriteStore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 
 			// make sure we have the expected features:
 			doh.assertTrue(features["dojo.data.api.Read"] !== null);
@@ -69,16 +63,16 @@ doh.register("tests.data.ItemFileWriteStore",
 			// and only the expected features:
 			var count = 0;
 			for(var i in features){
-				doh.assertTrue((i === "dojo.data.api.Read" || 
-					i === "dojo.data.api.Identity" || 
-					i === "dojo.data.api.Write" || 
+				doh.assertTrue((i === "dojo.data.api.Read" ||
+					i === "dojo.data.api.Identity" ||
+					i === "dojo.data.api.Write" ||
 					i === "dojo.data.api.Notification"));
 				count++;
 			}
 			doh.assertEqual(count, 4);
 		},
 		function testWriteAPI_setValue(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the setValue API
 			//	description:
 			//		Simple test of the setValue API
@@ -90,7 +84,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				var item = items[0];
 				doh.assertTrue(store.containsValue(item, "capital", "Cairo"));
 				
-				// FIXME:  
+				// FIXME:
 				//    Okay, so this seems very odd.  Maybe I'm just being dense.
 				//    These tests works:
 				doh.assertEqual(store.isDirty(item), false);
@@ -98,7 +92,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				//    But these seemingly equivalent tests will not work:
 				// doh.assertFalse(store.isDirty(item));
 				// doh.assertTrue(!(store.isDirty(item)));
-				//   
+				//
 				//    All of which seems especially weird, given that this *does* work:
 				doh.assertFalse(store.isDirty());
 				
@@ -117,7 +111,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_setValues(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the setValues API
 			//	description:
 			//		Simple test of the setValues API
@@ -145,7 +139,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_unsetAttribute(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the unsetAttribute API
 			//	description:
 			//		Simple test of the unsetAttribute API
@@ -171,7 +165,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_newItem(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the newItem API
 			//	description:
 			//		Simple test of the newItem API
@@ -207,7 +201,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_newItem_withParent(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the newItem API with a parent assignment
 			//	description:
 			//		Simple test of the newItem API with a parent assignment
@@ -266,7 +260,7 @@ doh.register("tests.data.ItemFileWriteStore",
 		},
 		
 		function testWriteAPI_newItem_multiple_withParent(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the newItem API with a parent assignment multiple times.
 			//	description:
 			//		Simple test of the newItem API with a parent assignment multiple times.
@@ -331,7 +325,7 @@ doh.register("tests.data.ItemFileWriteStore",
 		},
 
 		function testWriteAPI_deleteItem(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the deleteItem API
 			//	description:
 			//		Simple test of the deleteItem API
@@ -362,7 +356,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_isDirty(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isDirty API
 			//	description:
 			//		Simple test of the isDirty API
@@ -385,7 +379,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_revert(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the revert API
 			//	description:
 			//		Simple test of the revert API
@@ -422,7 +416,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_save(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API
 			//	description:
 			//		Simple test of the save API
@@ -443,7 +437,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveVerifyState(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API
 			//	description:
 			//		Simple test of the save API
@@ -467,7 +461,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API
 			//	description:
 			//		Simple test of the save API
@@ -507,7 +501,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_HierarchyOff(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API
 			//	description:
 			//		Simple test of the save API
@@ -543,7 +537,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_withDateType(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
 			//	description:
 			//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
@@ -557,7 +551,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				var newStore = new dojo.data.ItemFileWriteStore({data: dataset});
 
 				function gotItem(item){
-					var independenceDate = newStore.getValue(item,"independence"); 
+					var independenceDate = newStore.getValue(item,"independence");
 					doh.assertTrue(independenceDate instanceof Date);
 					doh.assertTrue(dojo.date.compare(new Date(1993,4,24), independenceDate, "date") === 0);
 					saveCompleteCallback();
@@ -583,7 +577,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_withCustomColorTypeSimple(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 			//	description:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
@@ -614,7 +608,7 @@ doh.register("tests.data.ItemFileWriteStore",
 
 				var deferred = new doh.Deferred();
 				function gotItem(item){
-					var hairColor = newStore.getValue(item,"hairColor"); 
+					var hairColor = newStore.getValue(item,"hairColor");
 					doh.assertTrue(hairColor instanceof dojo.Color);
 					doh.assertEqual("rgba(255, 255, 0, 1)", hairColor.toString());
 					saveCompleteCallback();
@@ -639,7 +633,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_saveEverything_withCustomColorTypeGeneral(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 			//	description:
 			//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
@@ -655,7 +649,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				]
 			};
 
-			var customTypeMap = {'Color': 	{	
+			var customTypeMap = {'Color': 	{
 												type: dojo.Color,
 												deserialize: function(value){
 													return new dojo.Color(value);
@@ -677,7 +671,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				var newStore = new dojo.data.ItemFileWriteStore({data: dataset, typeMap: customTypeMap});
 
 				var gotItem = function(item){
-					var hairColor = newStore.getValue(item,"hairColor"); 
+					var hairColor = newStore.getValue(item,"hairColor");
 					doh.assertTrue(hairColor instanceof dojo.Color);
 					doh.assertEqual("rgba(255, 255, 0, 1)", hairColor.toString());
 					saveCompleteCallback();
@@ -702,7 +696,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_newItem_revert(){
-			//	summary: 
+			//	summary:
 			//		Test for bug #5357.  Ensure that the revert properly nulls the identity position
 			//      for a new item after revert.
 			var args = {data: {
@@ -716,7 +710,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					{name:'Estonia', capital:'Tallinn'},
 					{name:'Ethiopia', capital:'Addis Ababa'}
 				]
-			} }; 
+			} };
 			var store = new dojo.data.ItemFileWriteStore(args);
 
 			var newCountry = store.newItem({name: "Utopia", capitol: "Perfect"});
@@ -728,7 +722,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(store._arrayOfAllItems[itemEntryNum] === null);
 		},
 		function testWriteAPI_new_modify_revert(){
-			//	summary: 
+			//	summary:
 			//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
 			//	description:
 			//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
@@ -762,7 +756,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testWriteAPI_new_modify_delete_revert(){
-			//	summary: 
+			//	summary:
 			//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
 			//	description:
 			//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
@@ -788,7 +782,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					doh.assertEqual(afterNewCount, (initialCount + 1));
 					store.deleteItem(canada);
 					
-					//Check that after delete, the total items count goes back to initial count.  
+					//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){
 						var afterDeleteCount = items.length;
@@ -796,7 +790,7 @@ doh.register("tests.data.ItemFileWriteStore",
 
 						for(i=0; i < items.length; i++){
 							found = (store.getIdentity(items[i]) === "ca");
-							if(found){ 
+							if(found){
 								break;
 							}
 						}
@@ -804,14 +798,14 @@ doh.register("tests.data.ItemFileWriteStore",
 							deferred.errback(new Error("Error: Found the supposedly deleted item!"));
 						}else{
 							store.revert();
-							//Check that after revert, we still have the same item count as the 
+							//Check that after revert, we still have the same item count as the
 							//original fetch.  Also verify the item with abbr of ca is gone.
 							var afterRevertFetch = function(items, request){
 								var afterRevertCount = items.length;
 								doh.assertEqual(afterRevertCount, initialCount);
 								for(i=0; i < items.length; i++){
 									found = (store.getIdentity(items[i]) === "ca");
-									if(found){ 
+									if(found){
 										break;
 									}
 								}
@@ -832,7 +826,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred; //Object
 		},
 		function testNotificationAPI_onSet(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the onSet API
 			//	description:
 			//		Simple test of the onSet API
@@ -860,7 +854,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
 		},
 		function testNotificationAPI_onNew(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the onNew API
 			//	description:
 			//		Simple test of the onNew API
@@ -878,7 +872,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			var canada = store.newItem({name:"Canada", abbr:"ca", capital:"Ottawa"});
 		},
 		function testNotificationAPI_onDelete(){
-			//	summary: 
+			//	summary:
 			//		Simple test of the onDelete API
 			//	description:
 			//		Simple test of the onDelete API
@@ -903,7 +897,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			store.fetchItemByIdentity({identity:"eg", onItem:onItem, onError:onError});
 		},
 		function testReadAPI_functionConformanceToo(){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -925,7 +919,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(passed);
 		},
 		function testWriteAPI_functionConformance(){
-			//	summary: 
+			//	summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -947,7 +941,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(passed);
 		},
 		function testNotificationAPI_functionConformance(){
-			//	summary: 
+			//	summary:
 			//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -969,9 +963,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			doh.assertTrue(passed);
 		},
 		function testIdentityAPI_noIdentifierSpecified(){
-			//	summary: 
+			//	summary:
 			//		Test for bug #3873. Given a datafile that does not specify an
-			//		identifier, make sure ItemFileWriteStore auto-creates identities 
+			//		identifier, make sure ItemFileWriteStore auto-creates identities
 			//		that are unique even after calls to deleteItem() and newItem()
 			var args = {data: {
 				label:"name",
@@ -984,7 +978,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					{name:'Estonia', capital:'Tallinn'},
 					{name:'Ethiopia', capital:'Addis Ababa'}
 				]
-			} }; 
+			} };
 			var store = new dojo.data.ItemFileWriteStore(args);
 			var deferred = new doh.Deferred();
 			
@@ -1022,9 +1016,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testIdentityAPI_noIdentifierSpecified_revert(){
-			//	summary: 
+			//	summary:
 			//		Test for bug #4691  Given a datafile that does not specify an
-			//		identifier, make sure ItemFileWriteStore auto-creates identities 
+			//		identifier, make sure ItemFileWriteStore auto-creates identities
 			//		that are unique even after calls to deleteItem() and newItem()
 			var args = {data: {
 				label:"name",
@@ -1037,7 +1031,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					{name:'Estonia', capital:'Tallinn'},
 					{name:'Ethiopia', capital:'Addis Ababa'}
 				]
-			} }; 
+			} };
 			var store = new dojo.data.ItemFileWriteStore(args);
 			var deferred = new doh.Deferred();
 			
@@ -1082,7 +1076,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_checkReferences(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify the references were properly resolved.
 			//	description:
 			//		Simple test to verify the references were properly resolved.
@@ -1151,7 +1145,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteReferencedItem(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify the references were properly deleted.
 			//	description:
 			//		Simple test to verify the references were properly deleted.
@@ -1206,7 +1200,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteReferencedItemThenRevert(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify the references were properly deleted.
 			//	description:
 			//		Simple test to verify the references were properly deleted.
@@ -1220,7 +1214,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			}
 			function onItem(item, request){
 				try{
-					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 					//THIS IS FOR TESTING INTERNAL STATE!
 					console.log("Map before delete:");
 					store._dumpReferenceMap();
@@ -1246,7 +1240,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteMultipleItemsWithReferencesAndRevert(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
 			//		Created for tracker bug: #5743
 			//	description:
@@ -1291,7 +1285,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_removeReferenceFromAttribute(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify the reference removal updates the internal map.
 			//	description:
 			//		Simple test to verify the reference removal updates the internal map.
@@ -1309,7 +1303,7 @@ doh.register("tests.data.ItemFileWriteStore",
 					store.setValues(item, "friends", [null]);
 
 					function onItem2(item10, request){
-						//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+						//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 						//THIS IS FOR TESTING INTERNAL STATE!
 						var refMap = item10[store._reverseRefMap];
 						store._dumpReferenceMap();
@@ -1335,7 +1329,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_deleteReferencedItemNonParent(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify the references to a non-parent item was properly deleted.
 			//	description:
 			//		Simple test to verify the references to a non-parent item was properly deleted.
@@ -1389,7 +1383,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_addReferenceToAttribute(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify the reference additions can happen.
 			//	description:
 			//		Simple test to verify the reference additions can happen.
@@ -1409,7 +1403,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				var item1 = items[0];
 				var item2 = items[1];
 
-				//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+				//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 				//THIS IS FOR TESTING INTERNAL STATE!
 				console.log("Map state for Item 1 is: " + dojo.toJson(item1[store._reverseRefMap]));
 				console.log("Map state for Item 2 is: " + dojo.toJson(item2[store._reverseRefMap]));
@@ -1431,7 +1425,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_newItemWithParentReference(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
 			//	description:
 			//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
@@ -1447,9 +1441,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			function onItem(item, request){
 				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"}); 
+					var newItem = store.newItem({id: 17, name: "Item 17"}, {parent: item, attribute: "uncles"});
 					
-					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+					//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'
 					var refs = newItem[store._reverseRefMap];
@@ -1472,7 +1466,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_newItemWithReferenceToExistingItem(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify that a new item with references to existing items properly record the references in the map.
 			//	description:
 			//		Simple test to verify that a new item with references to existing items properly record the references in the map.
@@ -1487,14 +1481,14 @@ doh.register("tests.data.ItemFileWriteStore",
 			}
 			function onItem(item, request){
 				try{
-					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+					//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!  
+					//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];
@@ -1517,7 +1511,7 @@ doh.register("tests.data.ItemFileWriteStore",
 			return deferred;
 		},
 		function testReferenceIntegrity_disableReferenceIntegrity(){
-			//	summary: 
+			//	summary:
 			//		Simple test to verify reference integrity can be disabled.
 			//	description:
 			//		Simple test to verify reference integrity can be disabled.
@@ -1532,7 +1526,7 @@ doh.register("tests.data.ItemFileWriteStore",
 				doh.assertTrue(false);
 			}
 			function onItem(item, request){
-				//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+				//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 				//THIS IS FOR TESTING INTERNAL STATE!
 				if(item[store._reverseRefMap] === undefined){
 					deferred.callback(true);
@@ -1542,9 +1536,9 @@ doh.register("tests.data.ItemFileWriteStore",
 			}
 			store.fetchItemByIdentity({identity: 10, onError: onError, onItem: onItem});
 			return deferred;
-		}, 
+		},
 		function testReadAPI_close_dirty_failure(){
-			//	summary: 
+			//	summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 			if (dojo.isBrowser) {
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
@@ -1584,3 +1578,4 @@ doh.register("tests.data.ItemFileWriteStore",
 );
 
 
+});
\ No newline at end of file
diff --git a/dojo/tests/data/ObjectStore.js b/dojo/tests/data/ObjectStore.js
new file mode 100644
index 0000000..e511ede
--- /dev/null
+++ b/dojo/tests/data/ObjectStore.js
@@ -0,0 +1,98 @@
+dojo.provide("dojo.tests.data.ObjectStore");
+dojo.require("dojo.data.ObjectStore");
+dojo.require("dojo.store.JsonRest");
+dojo.require("dojo.store.Memory");
+
+(function(){
+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},
+		{id: 2, name: "two", even: true, prime: true},
+		{id: 3, name: "three", prime: true},
+		{id: 4, name: "four", even: true, prime: false},
+		{id: 5, name: "five", prime: true}
+	]
+});
+
+var dataStore = new dojo.data.ObjectStore({objectStore: restStore});
+var memoryDataStore = new dojo.data.ObjectStore({objectStore: memoryStore});
+tests.register("tests.data.ObjectStore",
+	[
+		function testFetchByIdentity(t){
+			var d = new doh.Deferred();
+			dataStore.fetchItemByIdentity({identity: "node1.1", onItem: function(object){
+				t.is(object.name, "node1.1");
+				t.is(object.someProperty, "somePropertyA1");
+				d.callback(true);
+			}});
+			return d;
+		},
+		function testQuery(t){
+			var d = new doh.Deferred();
+			dataStore.fetch({query:"treeTestRoot", onComplete: function(results){
+				var object = results[0];
+				t.is(object.name, "node1");
+				t.is(object.someProperty, "somePropertyA");
+				d.callback(true);
+			}});
+			return d;
+		},
+		function testNewItem(t){
+			var newItem = memoryDataStore.newItem({
+				foo: "bar",
+				id: Math.random()
+			});
+			memoryDataStore.setValue(newItem, "prop1", 1);
+			memoryDataStore.save();
+			memoryDataStore.fetchItemByIdentity({
+				identity: memoryDataStore.getIdentity(newItem),
+				onItem: function(item){
+					t.is(memoryDataStore.getValue(item, "foo"), "bar");
+					memoryDataStore.setValue(newItem, "prop2", 2);
+					t.is(memoryDataStore.getValue(item, "prop1"), 1);
+					t.is(memoryDataStore.getValue(item, "prop2"), 2);
+				}});
+		},
+		function testMemoryQuery(t){
+			var d = new doh.Deferred();
+			memoryDataStore.fetch({query:{name:"one"}, onComplete: function(results){
+				var object = results[0];
+				t.is(results.length, 1);
+				t.is(object.name, "one");
+				d.callback(true);
+			}});
+			return d;
+		},
+		function testMemoryQueryEmpty(t){
+			var d = new doh.Deferred();
+			memoryDataStore.fetch({query:{name:"o"}, onComplete: function(results){
+				t.is(results.length, 0);
+				d.callback(true);
+			}});
+			return d;
+		},
+		function testMemoryQueryWithWildcard(t){
+			var d = new doh.Deferred();
+			memoryDataStore.fetch({query:{name:"f*"}, onComplete: function(results){
+				var object = results[0];
+				t.is(results.length, 2);
+				t.is(object.name, "four");
+				d.callback(true);
+			}});
+			return d;
+		},
+		function testMemoryQueryWithWildcardCaseInsensitive(t){
+			var d = new doh.Deferred();
+			memoryDataStore.fetch({query:{name:"F*"}, queryOptions: {ignoreCase: true}, onComplete: function(results){
+				var object = results[0];
+				t.is(results.length, 2);
+				t.is(object.name, "four");
+				d.callback(true);
+			}});
+			return d;
+		}
+	]
+);
+
+})();
\ No newline at end of file
diff --git a/dojo/tests/data/readOnlyItemFileTestTemplates.js b/dojo/tests/data/readOnlyItemFileTestTemplates.js
index 848fc23..e50f8f4 100644
--- a/dojo/tests/data/readOnlyItemFileTestTemplates.js
+++ b/dojo/tests/data/readOnlyItemFileTestTemplates.js
@@ -1,12 +1,10 @@
-dojo.provide("tests.data.readOnlyItemFileTestTemplates");
-dojo.require("dojo.data.api.Read");
-dojo.require("dojo.data.api.Identity");
-dojo.require("dojo.date");
-dojo.require("dojo.date.stamp");
+define("tests/data/readOnlyItemFileTestTemplates", ["dojo/data/api/Read", "dojo/data/api/Identity", "dojo/date", "dojo/date/stamp"], function() {
+
+dojo.getObject("data.readOnlyItemFileTestTemplates", true, tests);
 
 dojo.declare("tests.data.Wrapper", null, {
 	//	summary:
-	//		Simple class to use for typeMap in order to	test out 
+	//		Simple class to use for typeMap in order to	test out
 	//		'falsy' values for _value.
 	_wrapped: null,
 
@@ -60,7 +58,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/countries.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				identifier:"abbr",
 				label:"name",
 				items:[
@@ -73,12 +71,12 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 					{abbr:'et', name:'Ethiopia', capital:'Addis Ababa'}
 				]
 			} };
-		}	
+		}
 	}else if(name === "countries_withNull"){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/countries_withNull.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				identifier:"abbr",
 				items:[
 					{abbr:"ec", name:null, capital:"Quito"},
@@ -95,7 +93,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/countries_withoutid.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				label: "name",
 				items:[
 					{abbr:"ec", name:null, capital:"Quito"},
@@ -112,7 +110,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/countries_withBoolean.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				identifier:"abbr",
 				items:[
 					{abbr:"ec", name:"Ecuador", capital:"Quito", real:true},
@@ -130,7 +128,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/countries_withDates.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				identifier:"abbr",
 				items:[
 					{abbr:"ec", name:"Ecuador", capital:"Quito"},
@@ -147,7 +145,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/geography_hierarchy_small.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				items:[
 					{ name:'Africa', countries:[
 						{ name:'Egypt', capital:'Cairo' },
@@ -171,9 +169,9 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("tests", "data/data_multitype.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 							"identifier": "count",
-							"label": "count", 
+							"label": "count",
 							items: [
 								{ count: 1,    value: "true" },
 								{ count: 2,    value: true   },
@@ -188,7 +186,7 @@ tests.data.readOnlyItemFileTestTemplates.getTestData = function(name){
 								{ count: 11,   value: [false, false]},
 								{ count: "12", value: [false, "true"]}
 						   ]
-						} 
+						}
 					};
 		}
 	}else if (name === "countries_references"){
@@ -252,7 +250,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity()",
 		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 
@@ -276,7 +274,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() preventCache",
 		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			var args = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
 			args.urlPreventCache = true;
@@ -302,7 +300,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() notFound",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -324,7 +322,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: getIdentityAttributes()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getIdentityAttributes function.
 			//	description:
 			//		Simple test of the getIdentityAttributes function.
@@ -350,7 +348,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() commentFilteredJson",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -380,7 +378,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() nullValue",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store, checling a null value.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store, checking a null value.
@@ -406,7 +404,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() booleanValue",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
@@ -432,7 +430,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: fetchItemByIdentity() withoutSpecifiedIdInData",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
 			//	description:
 			//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
@@ -454,9 +452,91 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 		}
 	},
 	{
+        name: "Identity API: fetchItemByIdentity() Object.prototype item identifier",
+        runTest: function(datastore, t){
+			//      summary:
+			//          Simple test of bug where store would raise an error
+			//          if the item identifier was the same as an Object property name.
+			var data = {identifier: 'id', items: [{id: 'toString', value: 'aha'}]};
+			var store = new datastore({data: data});
+			var d = new doh.Deferred();
+			function onitem(item) {
+				t.assertTrue(item.value == 'aha');
+				d.callback(true);
+			}
+			function onError(errData){
+				t.assertTrue(false);
+				d.errback(errData);
+			}
+			store.fetchItemByIdentity({identity: 'toString', onItem: onitem, onError: onError});
+			return d; // Deferred
+		}
+	},
+	{
+        name: "Identity API: fetchItemByIdentity() Object.prototype item identifier 2",
+        runTest: function(datastore, t){
+			//      summary:
+			//          Simple test of bug where store would raise an error
+			//          if the item identifier was the same as an Object property name.
+			var data = {identifier: 'id', items: [{id: 'hasOwnProperty', value: 'yep'}]};
+			var store = new datastore({data: data});
+			var d = new doh.Deferred();
+			function onitem(item) {
+				t.assertTrue(item.value == 'yep');
+				d.callback(true);
+			}
+			function onError(errData){
+				t.assertTrue(false);
+				d.errback(errData);
+			}
+			store.fetchItemByIdentity({identity: 'hasOwnProperty', onItem: onitem, onError: onError});
+			return d; // Deferred
+		}
+	},
+	{
+        name: "Identity API: fetchItemByIdentity() Object.prototype identity",
+        runTest: function(datastore, t){
+			//      summary:
+			//          Simple test of bug where fetchItemByIdentity would return
+			//          an object property.
+			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withoutid"));
+			var d = new doh.Deferred();
+			function onItem(item){
+				t.assertTrue(item === null);
+				d.callback(true);
+			}
+			function onError(errData){
+				t.assertTrue(false);
+				d.errback(errData);
+			}
+			store.fetchItemByIdentity({identity: 'toString', onItem: onItem, onError: onError});
+			return d; // Deferred
+		}
+	},
+	{
+        name: "Identity API: fetchItemByIdentity() Object.prototype identity 2",
+        runTest: function(datastore, t){
+			//      summary:
+			//          Simple test of bug where fetchItemByIdentity would return
+			//          an object property.
+			var store = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries_withoutid"));
+			var d = new doh.Deferred();
+			function onItem(item){
+				t.assertTrue(item === null);
+				d.callback(true);
+			}
+			function onError(errData){
+				t.assertTrue(false);
+				d.errback(errData);
+			}
+			store.fetchItemByIdentity({identity: 'hasOwnProperty', onItem: onItem, onError: onError});
+			return d; // Deferred
+		}
+	},
+	{
 		name: "Identity API: getIdentity()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getIdentity function of the store.
 			//	description:
 			//		Simple test of the getIdentity function of the store.
@@ -479,7 +559,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: getIdentity() withoutSpecifiedId",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the #4691 bug
 			//	description:
 			//		Simple test of the #4691 bug
@@ -502,7 +582,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
@@ -526,7 +606,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all failOk",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore that fails quietly.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore that fails quietly.
@@ -555,7 +635,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() abort",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch abort on ItemFileReadStore.
 			//	description:
 			//		Simple test of a basic fetch abort on ItemFileReadStore.
@@ -595,7 +675,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all (count === Infinity)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore and with a count of Infinity.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore and with a count of Infinity.
@@ -619,7 +699,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all PreventCache",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
@@ -645,7 +725,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() one",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
@@ -660,8 +740,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {abbr: "ec"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {abbr: "ec"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -670,7 +750,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() shallow",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of only toplevel items
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of only toplevel items.
@@ -686,8 +766,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				d.errback(errData);
 			}
 			//Find all items starting with A, only toplevel (root) items.
-			store.fetch({ 	query: {name: "A*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {name: "A*"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -696,7 +776,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() Multiple",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 			//	description:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -723,14 +803,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				d.errback(errData);
 			}
 			//Find all items starting with A, only toplevel (root) items.
-			store.fetch({ 	query: {name: "A*"}, 
-									onComplete: onCompleteOne, 
+			store.fetch({ 	query: {name: "A*"},
+									onComplete: onCompleteOne,
 									onError: onError
 								});
 
 			//Find all items starting with A, only toplevel (root) items.
-			store.fetch({ 	query: {name: "N*"}, 
-									onComplete: onCompleteTwo, 
+			store.fetch({ 	query: {name: "N*"},
+									onComplete: onCompleteTwo,
 									onError: onError
 								});
 
@@ -740,7 +820,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() MultipleMixedFetch",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 			//	description:
 			//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -773,8 +853,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			}
 			
 			//Find all items starting with A, only toplevel (root) items.
-			store.fetch({ 	query: {name: "El*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {name: "El*"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			
@@ -785,7 +865,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() deep",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items (including children (nested))
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items (including children (nested))
@@ -801,8 +881,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				d.errback(errData);
 			}
 			//Find all items starting with A, including child (nested) items.
-			store.fetch({ 	query: {name: "A*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {name: "A*"},
+									onComplete: onComplete,
 									onError: onError,
 									queryOptions: {deep:true}
 								});
@@ -812,7 +892,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() hierarchy off",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items with hierarchy disabled
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
@@ -859,8 +939,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				d.errback(errData);
 			}
 			//Find all items starting with A, including child (nested) items.
-			store.fetch({ 	query: {name: "A*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {name: "A*"},
+									onComplete: onComplete,
 									onError: onError,
 									queryOptions: {deep:true}
 								});
@@ -870,7 +950,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() hierarchy off refs still parse",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of all items with hierarchy disabled
 			//		This should turn off processing child objects as data store items.  It will still process
 			//		references and type maps.
@@ -917,8 +997,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				d.errback(errData);
 			}
 			//Find all items starting with A, including child (nested) items.
-			store.fetch({ 	query: {name: "A*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {name: "A*"},
+									onComplete: onComplete,
 									onError: onError,
 									queryOptions: {deep:true}
 								});
@@ -928,7 +1008,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() one_commentFilteredJson",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item.
@@ -947,8 +1027,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 					t.assertTrue(false);
 					d.errback(errData);
 				}
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -958,7 +1038,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() withNull",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item where some attributes are null.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore of a single item where some attributes are null.
@@ -974,8 +1054,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {name: "E*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {name: "E*"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -984,7 +1064,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() all_streaming",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on ItemFileReadStore.
 			//	description:
 			//		Simple test of a basic fetch on ItemFileReadStore.
@@ -1012,7 +1092,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 
 			//Get everything...
 			store.fetch({	onBegin: onBegin,
-									onItem: onItem, 
+									onItem: onItem,
 									onComplete: onComplete,
 									onError: onError
 								});
@@ -1022,7 +1102,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() paging",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Test of multiple fetches on a single result.  Paging, if you will.
 			//	description:
 			//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -1093,7 +1173,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with MultiType Match",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 			//	description:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1109,8 +1189,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {count: "1*"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {count: "1*"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -1119,7 +1199,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with RegExp Match",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
 			//	description:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
@@ -1134,8 +1214,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {count: new RegExp("^1.*$", "gi")}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {count: new RegExp("^1.*$", "gi")},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -1144,7 +1224,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with RegExp Match Inline",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
 			//	description:
 			//		Simple test of a basic fetch using a RegExp works with IFRS
@@ -1159,8 +1239,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {count: /^1.*$/gi}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {count: /^1.*$/gi},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -1169,7 +1249,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() with MultiType, MultiValue Match",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 			//	description:
 			//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1185,8 +1265,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {value: "true"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {value: "true"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -1195,7 +1275,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getLabel()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -1213,8 +1293,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {abbr: "ec"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {abbr: "ec"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -1223,7 +1303,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getLabelAttributes()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -1241,8 +1321,8 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(false);
 				d.errback(errData);
 			}
-			store.fetch({ 	query: {abbr: "ec"}, 
-									onComplete: onComplete, 
+			store.fetch({ 	query: {abbr: "ec"},
+									onComplete: onComplete,
 									onError: onError
 								});
 			return d;
@@ -1251,7 +1331,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getValue()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -1275,7 +1355,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getValues()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValues function of the store.
 			//	description:
 			//		Simple test of the getValues function of the store.
@@ -1301,7 +1381,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: isItem()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//	description:
 			//		Simple test of the isItem function of the store
@@ -1325,7 +1405,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: isItem() multistore",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//		to verify two different store instances do not accept
 			//		items from each other.
@@ -1334,7 +1414,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			//		to verify two different store instances do not accept
 			//		items from each other.
 
-			// Two different instances, even  if they read from the same URL 
+			// Two different instances, even  if they read from the same URL
 			// should not accept items between each other!
 			var store1 = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
 			var store2 = new datastore(tests.data.readOnlyItemFileTestTemplates.getTestData("countries"));
@@ -1366,7 +1446,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: hasAttribute()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute function of the store
 			//	description:
 			//		Simple test of the hasAttribute function of the store
@@ -1404,7 +1484,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: containsValue()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue function of the store
 			//	description:
 			//		Simple test of the containsValue function of the store
@@ -1438,7 +1518,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getAttributes()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -1467,7 +1547,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: getFeatures()",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
@@ -1481,7 +1561,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch0",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything starting with lowercase e
 			//	description:
 			//		Function to test pattern matching of everything starting with lowercase e
@@ -1516,14 +1596,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch1",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything with $ in it.
 			//	description:
 			//		Function to test pattern matching of everything with $ in it.
 
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 1, value:"foo*bar"},
-												   {uniqueId: 2, value:"bar*foo"}, 
+												   {uniqueId: 2, value:"bar*foo"},
 												   {uniqueId: 3, value:"boomBam"},
 												   {uniqueId: 4, value:"bit$Bite"},
 												   {uniqueId: 5, value:"ouagadogou"},
@@ -1564,14 +1644,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch2",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match
 			//	description:
 			//		Function to test exact pattern match
 
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 1, value:"foo*bar"},
-												   {uniqueId: 2, value:"bar*foo"}, 
+												   {uniqueId: 2, value:"bar*foo"},
 												   {uniqueId: 3, value:"boomBam"},
 												   {uniqueId: 4, value:"bit$Bite"},
 												   {uniqueId: 5, value:"ouagadogou"},
@@ -1612,14 +1692,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch_caseSensitive",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of a pattern case-sensitively
 			//	description:
 			//		Function to test pattern matching of a pattern case-sensitively
 
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 1, value:"foo*bar"},
-												   {uniqueId: 2, value:"bar*foo"}, 
+												   {uniqueId: 2, value:"bar*foo"},
 												   {uniqueId: 3, value:"BAR*foo"},
 												   {uniqueId: 4, value:"BARBananafoo"}
 												 ]
@@ -1655,14 +1735,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() patternMatch_caseInsensitive",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of a pattern case-insensitively
 			//	description:
 			//		Function to test pattern matching of a pattern case-insensitively
 
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 1, value:"foo*bar"},
-												   {uniqueId: 2, value:"bar*foo"}, 
+												   {uniqueId: 2, value:"bar*foo"},
 												   {uniqueId: 3, value:"BAR*foo"},
 												   {uniqueId: 4, value:"BARBananafoo"}
 												 ]
@@ -1698,14 +1778,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortNumeric",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically.
 			//	description:
 			//		Function to test sorting numerically.
 			
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-												   {uniqueId: 1, value:"ba|r*foo"}, 
+												   {uniqueId: 1, value:"ba|r*foo"},
 												   {uniqueId: 2, value:"boomBam"},
 												   {uniqueId: 3, value:"bit$Bite"},
 												   {uniqueId: 4, value:"ouagadogou"},
@@ -1751,14 +1831,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortNumericDescending",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically.
 			//	description:
 			//		Function to test sorting numerically.
 
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-												   {uniqueId: 1, value:"ba|r*foo"}, 
+												   {uniqueId: 1, value:"ba|r*foo"},
 												   {uniqueId: 2, value:"boomBam"},
 												   {uniqueId: 3, value:"bit$Bite"},
 												   {uniqueId: 4, value:"ouagadogou"},
@@ -1803,14 +1883,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortNumericWithCount",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			//	description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 		
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-												  {uniqueId: 1, value:"ba|r*foo"}, 
+												  {uniqueId: 1, value:"ba|r*foo"},
 												  {uniqueId: 2, value:"boomBam"},
 												  {uniqueId: 3, value:"bit$Bite"},
 												  {uniqueId: 4, value:"ouagadogou"},
@@ -1858,14 +1938,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortAlphabetic",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
 		
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"abc"},
-												  {uniqueId: 1, value:"bca"}, 
+												  {uniqueId: 1, value:"bca"},
 												  {uniqueId: 2, value:"abcd"},
 												  {uniqueId: 3, value:"abcdefg"},
 												  {uniqueId: 4, value:"lmnop"},
@@ -1925,14 +2005,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortAlphabeticDescending",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
 		
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"abc"},
-												  {uniqueId: 1, value:"bca"}, 
+												  {uniqueId: 1, value:"bca"},
 												  {uniqueId: 2, value:"abcd"},
 												  {uniqueId: 3, value:"abcdefg"},
 												  {uniqueId: 4, value:"lmnop"},
@@ -1993,14 +2073,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortDate",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting date.
 			//	description:
 			//		Function to test sorting date.
 		
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value: new Date(0)},
-												  {uniqueId: 1, value: new Date(100)}, 
+												  {uniqueId: 1, value: new Date(100)},
 												  {uniqueId: 2, value:new Date(1000)},
 												  {uniqueId: 3, value:new Date(2000)},
 												  {uniqueId: 4, value:new Date(3000)},
@@ -2048,14 +2128,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortDateDescending",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting date in descending order.
 			//	description:
 			//		Function to test sorting date in descending order.
 		
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value: new Date(0)},
-												  {uniqueId: 1, value: new Date(100)}, 
+												  {uniqueId: 1, value: new Date(100)},
 												  {uniqueId: 2, value:new Date(1000)},
 												  {uniqueId: 3, value:new Date(2000)},
 												  {uniqueId: 4, value:new Date(3000)},
@@ -2104,14 +2184,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortMultiple",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting on multiple attributes.
 			//	description:
 			//		Function to test sorting on multiple attributes.
 			
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 1, value:"fo|o*b.ar"},
-												  {uniqueId: 2, value:"ba|r*foo"}, 
+												  {uniqueId: 2, value:"ba|r*foo"},
 												  {uniqueId: 3, value:"boomBam"},
 												  {uniqueId: 4, value:"bit$Bite"},
 												  {uniqueId: 5, value:"ouagadogou"},
@@ -2173,14 +2253,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortMultipleSpecialComparator",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 			//	description:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 1, status:"CLOSED"},
-												  {uniqueId: 2,  status:"OPEN"}, 
+												  {uniqueId: 2,  status:"OPEN"},
 												  {uniqueId: 3,  status:"PENDING"},
 												  {uniqueId: 4,  status:"BLOCKED"},
 												  {uniqueId: 5,  status:"CLOSED"},
@@ -2197,7 +2277,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 		
 		
 			store.comparatorMap = {};
-			store.comparatorMap["status"] = function(a,b) { 
+			store.comparatorMap["status"] = function(a,b) {
 				var ret = 0;
 				// We want to map these by what the priority of these items are, not by alphabetical.
 				// So, custom comparator.
@@ -2243,14 +2323,14 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch() sortAlphabeticWithUndefined",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
 		
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											 items: [ {uniqueId: 0, value:"abc"},
-												  {uniqueId: 1, value:"bca"}, 
+												  {uniqueId: 1, value:"bca"},
 												  {uniqueId: 2, value:"abcd"},
 												  {uniqueId: 3, value:"abcdefg"},
 												  {uniqueId: 4, value:"lmnop"},
@@ -2298,16 +2378,16 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: errorCondition_idCollision_inMemory",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
 			//	description:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
 
-			var store = new datastore({	data: { identifier: "uniqueId", 
+			var store = new datastore({	data: { identifier: "uniqueId",
 																items: [{uniqueId: 12345, value:"foo"},
-																		{uniqueId: 123456, value:"bar"}, 
+																		{uniqueId: 123456, value:"bar"},
 																		{uniqueId: 12345, value:"boom"},
 																		{uniqueId: 123457, value:"bit"}
 																	]
@@ -2332,7 +2412,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: errorCondition_idCollision_xhr",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the errors thrown when there is an id collision in the data.
 			//		Added because of tracker: #2546
 			//	description:
@@ -2369,7 +2449,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 				t.assertTrue(item !== null);
 				var independenceDate = store.getValue(item, "independence");
 				t.assertTrue(independenceDate instanceof Date);
-				//Check to see if the value was deserialized properly.  Since the store stores in UTC/GMT, it 
+				//Check to see if the value was deserialized properly.  Since the store stores in UTC/GMT, it
 				//should also be compared in the UTC/GMT mode
 				t.assertTrue(dojo.date.stamp.toISOString(independenceDate, {zulu:true}) === "1993-05-24T00:00:00Z");
 				d.callback(true);
@@ -2385,7 +2465,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_Color_SimpleMapping",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test using literal values with custom datatypes
 			var dataset = {
 				identifier:'name',
@@ -2417,7 +2497,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_Color_GeneralMapping",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test using literal values with custom datatypes
 			var dataset = {
 				identifier:'name',
@@ -2428,7 +2508,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			};
 			var store = new datastore({
 					data:dataset,
-					typeMap:{'Color': 	{	
+					typeMap:{'Color': 	{
 											type: dojo.Color,
 											deserialize: function(value){
 												return new dojo.Color(value);
@@ -2455,7 +2535,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject 0 (False) value",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2466,7 +2546,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			};
 			var store = new datastore({
 					data:dataset,
-					typeMap:{'tests.data.Wrapper': 	{	
+					typeMap:{'tests.data.Wrapper': 	{
 											type: tests.data.Wrapper,
 											deserialize: function(value){
 												return new tests.data.Wrapper(value);
@@ -2493,7 +2573,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject Boolean False values",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2504,7 +2584,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			};
 			var store = new datastore({
 					data:dataset,
-					typeMap:{'tests.data.Wrapper': 	{	
+					typeMap:{'tests.data.Wrapper': 	{
 											type: tests.data.Wrapper,
 											deserialize: function(value){
 												return new tests.data.Wrapper(value);
@@ -2531,7 +2611,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject Empty String values",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2542,7 +2622,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			};
 			var store = new datastore({
 					data:dataset,
-					typeMap:{'tests.data.Wrapper': 	{	
+					typeMap:{'tests.data.Wrapper': 	{
 											type: tests.data.Wrapper,
 											deserialize: function(value){
 												return new tests.data.Wrapper(value);
@@ -2569,7 +2649,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject explicit null values",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2580,7 +2660,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			};
 			var store = new datastore({
 					data:dataset,
-					typeMap:{'tests.data.Wrapper': 	{	
+					typeMap:{'tests.data.Wrapper': 	{
 											type: tests.data.Wrapper,
 											deserialize: function(value){
 												return new tests.data.Wrapper(value);
@@ -2607,7 +2687,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: custom_datatype_CustomObject explicit undefined value",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test type mapping and _values that are false-like
 			var dataset = {
 				identifier:'name',
@@ -2618,7 +2698,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 			};
 			var store = new datastore({
 					data:dataset,
-					typeMap:{'tests.data.Wrapper': 	{	
+					typeMap:{'tests.data.Wrapper': 	{
 											type: tests.data.Wrapper,
 											deserialize: function(value){
 												return new tests.data.Wrapper(value);
@@ -2672,7 +2752,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 			if (dojo.isBrowser) {
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
@@ -2713,7 +2793,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true, reset url.)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 			if (dojo.isBrowser) {
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
@@ -2770,7 +2850,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: fetch, close (clearOnClose: true, reset url.)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 			if (dojo.isBrowser) {
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
@@ -2829,7 +2909,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true, reset _jsonFileUrl.)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 			if (dojo.isBrowser) {
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
@@ -2886,7 +2966,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: false)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 			if (dojo.isBrowser) {
 				var params = tests.data.readOnlyItemFileTestTemplates.getTestData("countries");
@@ -2926,13 +3006,13 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: close (clearOnClose: true, reset data.)",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Function to test that clear on close and reset of data works.
 			//	description:
 			//		Function to test that clear on close and reset of data works.
-			var store = new datastore({data: { identifier: "uniqueId", 
+			var store = new datastore({data: { identifier: "uniqueId",
 											  items: [ {uniqueId: 1, value:"foo*bar"},
-												   {uniqueId: 2, value:"bar*foo"}, 
+												   {uniqueId: 2, value:"bar*foo"},
 												   {uniqueId: 3, value:"boomBam"},
 												   {uniqueId: 4, value:"bit$Bite"},
 												   {uniqueId: 5, value:"ouagadogou"},
@@ -2951,9 +3031,9 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 
 				//Set the store clearing options and the new data
 				store.clearOnClose = true;
-				store.data = { identifier: "uniqueId", 
+				store.data = { identifier: "uniqueId",
 					items: [ {uniqueId: 1, value:"foo*bar"},
-						{uniqueId: 2, value:"bar*foo"}, 
+						{uniqueId: 2, value:"bar*foo"},
 						{uniqueId: 3, value:"boomBam"},
 						{uniqueId: 4, value:"bit$Bite"},
 						{uniqueId: 5, value:"ouagadogou"},
@@ -2994,7 +3074,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
  		runTest: function(datastore, t){
 			var arrayOfItems = [
 				{name:"Kermit", color:"green"},
-				{name:"Miss Piggy", likes:"Kermit"}, 
+				{name:"Miss Piggy", likes:"Kermit"},
 				{name:"Beaker", hairColor:"red"}
 			];
 			var store = new datastore({data:{items:arrayOfItems}});
@@ -3047,7 +3127,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Read API: functionConformance",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -3075,7 +3155,7 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	{
 		name: "Identity API: functionConformance",
  		runTest: function(datastore, t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -3103,3 +3183,4 @@ tests.data.readOnlyItemFileTestTemplates.testTemplates = [
 	}
 ];
 
+});
\ No newline at end of file
diff --git a/dojo/tests/data/utils.js b/dojo/tests/data/utils.js
index 5af02ce..92dadec 100644
--- a/dojo/tests/data/utils.js
+++ b/dojo/tests/data/utils.js
@@ -2,7 +2,7 @@ dojo.provide("tests.data.utils");
 dojo.require("dojo.data.util.filter");
 dojo.require("dojo.data.util.sorter");
 
-tests.register("tests.data.utils", 
+tests.register("tests.data.utils",
 	[
 		function testWildcardFilter_1(t){
 			var pattern = "ca*";
diff --git a/dojo/tests/date.js b/dojo/tests/date.js
index b75702a..5d8c0ea 100644
--- a/dojo/tests/date.js
+++ b/dojo/tests/date.js
@@ -2,7 +2,7 @@ dojo.provide("tests.date");
 
 dojo.require("dojo.date");
 
-tests.register("tests.date.util", 
+tests.register("tests.date.util",
 	[
 
 /* Informational Functions
@@ -44,7 +44,7 @@ function test_date_isLeapYear(t){
 
 // The getTimezone function pulls from either the date's toString or
 // toLocaleString method -- it's really just a string-processing
-// function (assuming the Date obj passed in supporting both toString 
+// function (assuming the Date obj passed in supporting both toString
 // and toLocaleString) and as such can be tested for multiple browsers
 // by manually settting up fake Date objects with the actual strings
 // produced by various browser/OS combinations.
@@ -90,7 +90,7 @@ function test_date_getTimezoneName(t){
 	dt.strLocale = 'Monday, September 18, 2006 11:21:07 AM';
 	t.is('CDT', dojo.date.getTimezoneName(dt));
 
-	// Opera 9 Ubuntu Linux (Breezy) -- no TZ data expect empty string return 
+	// Opera 9 Ubuntu Linux (Breezy) -- no TZ data expect empty string return
 	dt.str = 'Mon, 18 Sep 2006 13:30:32 GMT-0500';
 	dt.strLocale = 'Monday September 18, 13:30:32 GMT-0500 2006';
 	t.is('', dojo.date.getTimezoneName(dt));
@@ -103,7 +103,7 @@ function test_date_getTimezoneName(t){
 	]
 );
 
-tests.register("tests.date.math", 
+tests.register("tests.date.math",
 	[
 function test_date_compare(t){
 	var d1=new Date();
diff --git a/dojo/tests/date/locale.js b/dojo/tests/date/locale.js
index a7c0115..cb37e92 100644
--- a/dojo/tests/date/locale.js
+++ b/dojo/tests/date/locale.js
@@ -2,7 +2,7 @@ dojo.provide("tests.date.locale");
 
 dojo.require("dojo.date.locale");
 
-tests.register("tests.date.locale", 
+tests.register("tests.date.locale",
 	[
 		{
 			// Test formatting and parsing of dates in various locales pre-built in dojo.cldr
@@ -10,19 +10,29 @@ tests.register("tests.date.locale",
 			// load resources here for specific locales:
 
 			name: "date.locale",
-			setUp: function(){
-				var partLocaleList = ["en-us", "fr-fr", "es", "de-at", "ja-jp", "zh-cn"];
-
-				dojo.forEach(partLocaleList, function(locale){
-					dojo.requireLocalization("dojo.cldr", "gregorian", 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);
+		  		});
+        }
 			},
 			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;
 			}
 		},
 		{
@@ -73,6 +83,8 @@ tests.register("tests.date.locale",
 
 	t.is("12 o'clock AM", dojo.date.locale.format(date, {datePattern:"hh 'o''clock' a", selector:"date", locale: 'en'}));
 
+	t.is("11/08/2006 12:55am", dojo.date.locale.format(date, {datePattern:"dd/MM/yyyy", timePattern:"hh:mma", locale: 'en', am:"am", pm:"pm"}));
+
 	// compare without timezone
 	t.is("\u4e0a\u534812\u65f655\u520612\u79d2", dojo.date.locale.format(date, {formatLength:'full',selector:'time', locale:'zh-cn'}).replace(/^.*(\u4e0a\u5348.*)/,"$1"));
 			}
@@ -86,7 +98,7 @@ tests.register("tests.date.locale",
 	//en: 'short' fmt: M/d/yy
 	// Tolerate either 8 or 08 for month part.
 	t.is( aug_11_2006, dojo.date.locale.parse("08/11/06", {formatLength:'short', selector:'date', locale:'en'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("8/11/06", {formatLength:'short', selector:'date', locale:'en'}));	
+	t.is( aug_11_2006, dojo.date.locale.parse("8/11/06", {formatLength:'short', selector:'date', locale:'en'}));
 	// Tolerate yyyy input in yy part...
 	t.is( aug_11_2006, dojo.date.locale.parse("8/11/2006", {formatLength:'short', selector:'date', locale:'en'}));
 	// ...but not in strict mode
@@ -95,11 +107,12 @@ tests.register("tests.date.locale",
 	// test dates with no spaces
 	t.is( aug_11_2006, dojo.date.locale.parse("11Aug2006", {selector: 'date', datePattern: 'ddMMMyyyy', locale: 'en'}));
 	t.is( new Date(2006, 7, 1), dojo.date.locale.parse("Aug2006", {selector: 'date', datePattern: 'MMMyyyy', locale: 'en'}));
+	t.is( new Date(2010, 10, 19), dojo.date.locale.parse("111910", {fullyear: false, datePattern: "MMddyy", selector: "date"}));
 
 	//en: 'medium' fmt: MMM d, yyyy
 	// Tolerate either 8 or 08 for month part.
 	t.is( aug_11_2006, dojo.date.locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));	
+	t.is( aug_11_2006, dojo.date.locale.parse("Aug 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
 	// Tolerate abbreviating period in month part...
 	t.is( aug_11_2006, dojo.date.locale.parse("Aug. 11, 2006", {formatLength:'medium', selector:'date', locale:'en'}));
 	// ...but not in strict mode
@@ -141,14 +154,14 @@ tests.register("tests.date.locale",
 	//Spanish (es)
 	//es: 'short' fmt: d/MM/yy
 	t.is( aug_11_2006, dojo.date.locale.parse("11/08/06", {formatLength:'short', selector:'date', locale:'es'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("11/8/06", {formatLength:'short', selector:'date', locale:'es'}));	
+	t.is( aug_11_2006, dojo.date.locale.parse("11/8/06", {formatLength:'short', selector:'date', locale:'es'}));
 	// Tolerate yyyy input in yy part...
 	t.is( aug_11_2006, dojo.date.locale.parse("11/8/2006", {formatLength:'short', selector:'date', locale:'es'}));
 	// ...but not in strict mode
 	t.f( Boolean(dojo.date.locale.parse("11/8/2006", {formatLength:'short', selector:'date', locale:'es', strict:true})));
 	//es: 'medium' fmt: dd-MMM-yy (not anymore as of CLDR 1.5.1)
 //	t.is( aug_11_2006, dojo.date.locale.parse("11-ago-06", {formatLength:'medium', selector:'date', locale:'es'}));
-//	t.is( aug_11_2006, dojo.date.locale.parse("11-ago-2006", {formatLength:'medium', selector:'date', locale:'es'}));	
+//	t.is( aug_11_2006, dojo.date.locale.parse("11-ago-2006", {formatLength:'medium', selector:'date', locale:'es'}));
 	// Tolerate abbreviating period in month part...
 //	t.is( aug_11_2006, dojo.date.locale.parse("11-ago.-2006", {formatLength:'medium', selector:'date', locale:'es'}));
 	// ...but not in strict mode
@@ -167,7 +180,7 @@ tests.register("tests.date.locale",
 	t.f( Boolean(dojo.date.locale.parse("Viernes 11 de agosto de 2006", {formatLength:'full', selector:'date', locale:'es', strict:true})));
 
 	//Japanese (ja)
-	//note: to avoid garbling from non-utf8-aware editors that may touch this file, using the \uNNNN format 
+	//note: to avoid garbling from non-utf8-aware editors that may touch this file, using the \uNNNN format
 	//for expressing double-byte chars.
 	//toshi (year): \u5e74
 	//getsu (month): \u6708
@@ -177,14 +190,14 @@ tests.register("tests.date.locale",
 	
 	//ja: 'short' fmt: yy/MM/dd (note: the "short" fmt isn't actually defined in the CLDR data...)
 	t.is( aug_11_2006, dojo.date.locale.parse("06/08/11", {formatLength:'short', selector:'date', locale:'ja'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("06/8/11", {formatLength:'short', selector:'date', locale:'ja'}));	
+	t.is( aug_11_2006, dojo.date.locale.parse("06/8/11", {formatLength:'short', selector:'date', locale:'ja'}));
  	// Tolerate yyyy input in yy part...
 	t.is( aug_11_2006, dojo.date.locale.parse("2006/8/11", {formatLength:'short', selector:'date', locale:'ja'}));
 	// ...but not in strict mode
 	t.f( Boolean(dojo.date.locale.parse("2006/8/11", {formatLength:'short', selector:'date', locale:'ja', strict:true})));
 	//ja: 'medium' fmt: yyyy/MM/dd
 	t.is( aug_11_2006, dojo.date.locale.parse("2006/08/11", {formatLength:'medium', selector:'date', locale:'ja'}));
-	t.is( aug_11_2006, dojo.date.locale.parse("2006/8/11", {formatLength:'medium', selector:'date', locale:'ja'}));		
+	t.is( aug_11_2006, dojo.date.locale.parse("2006/8/11", {formatLength:'medium', selector:'date', locale:'ja'}));
 	//ja: 'long' fmt: yyyy'\u5e74'\u6708'd'\u65e5'
 	t.is( aug_11_2006, dojo.date.locale.parse("2006\u5e748\u670811\u65e5", {formatLength:'long', selector:'date', locale:'ja'}));
 	//ja 'full' fmt: yyyy'\u5e74'M'\u6708'd'\u65e5'EEEE
@@ -223,7 +236,7 @@ tests.register("tests.date.locale",
 	var aug_11_2006_12_30_pm = new Date(2006, 7, 11, 12, 30);
 
 	//en: 'short' datetime fmt: M/d/yy h:mm a
-	//note: this is concatenation of dateFormat-short and timeFormat-short, 
+	//note: this is concatenation of dateFormat-short and timeFormat-short,
 	//cldr provisionally defines datetime fmts as well, but we're not using them at the moment
 	t.is( aug_11_2006_12_30_pm, dojo.date.locale.parse("08/11/06 12:30 PM", {formatLength:'short', locale:'en'}));
 	//case-insensitive
diff --git a/dojo/tests/date/stamp.js b/dojo/tests/date/stamp.js
index a0db859..d3c6036 100644
--- a/dojo/tests/date/stamp.js
+++ b/dojo/tests/date/stamp.js
@@ -2,7 +2,7 @@ dojo.provide("tests.date.stamp");
 
 dojo.require("dojo.date.stamp");
 
-tests.register("tests.date.stamp", 
+tests.register("tests.date.stamp",
 	[
 function test_date_iso(t){
 	var rfc  = "2005-06-29T08:05:00-07:00";
diff --git a/dojo/tests/dnd/test_box_constraints.html b/dojo/tests/dnd/test_box_constraints.html
index 6d08d99..b45097c 100644
--- a/dojo/tests/dnd/test_box_constraints.html
+++ b/dojo/tests/dnd/test_box_constraints.html
@@ -15,6 +15,7 @@
 			border: 1px solid black;
 			width: 300px;
 			padding: 10px 20px;
+			margin: 0;
 			cursor: pointer;
 		}
 	</style>
@@ -49,13 +50,8 @@
 </head>
 <body>
 	<h1>Dojo box constraint test</h1>
-	<p class="moveable" id="moveable5"><strong>Paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor s [...]
-	<p class="moveable" id="moveable6"><strong>Paragraph restricted to (100,100:500,500) box, it cannot go outside of this box:</strong> In hac habitasse platea dictumst. Etiam rhoncus, leo quis hendrerit vestibulum, ipsum felis porta massa, vitae posuere nunc lorem ac enim. Nam neque turpis, aliquet quis, sollicitudin sit amet, dapibus sed, eros. Duis volutpat porttitor velit. Vivamus nibh metus, iaculis eget, malesuada eget, facilisis id, lorem. Sed turpis. Vestibulum aliquam mauris. Inte [...]
-	<p class="moveable" dojoType="dojo.dnd.move.boxConstrainedMoveable" box="{l: 100, t: 100, w: 500, h: 500}"><strong>Marked up paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo  [...]
-	</p>
-	<p class="moveable" dojoType="dojo.dnd.Moveable"><strong>Marked up paragraph restricted to (100,100:500,500) box, it cannot go outside of this box:</strong> In hac habitasse platea dictumst. Etiam rhoncus, leo quis hendrerit vestibulum, ipsum felis porta massa, vitae posuere nunc lorem ac enim. Nam neque turpis, aliquet quis, sollicitudin sit amet, dapibus sed, eros. Duis volutpat porttitor velit. Vivamus nibh metus, iaculis eget, malesuada eget, facilisis id, lorem. Sed turpis. Vestibu [...]
-		<!-- this is the obsolete way to do it -->
-		<script type="dojo/method">this.mover = dojo.dnd.boxConstrainedMover({l: 100, t: 100, w: 500, h: 500}, true);</script>
-	</p>
+	<div class="moveable" id="moveable5"><strong>Paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor [...]
+	<div class="moveable" id="moveable6"><strong>Paragraph restricted to (100,100:500,500) box, it cannot go outside of this box:</strong> In hac habitasse platea dictumst. Etiam rhoncus, leo quis hendrerit vestibulum, ipsum felis porta massa, vitae posuere nunc lorem ac enim. Nam neque turpis, aliquet quis, sollicitudin sit amet, dapibus sed, eros. Duis volutpat porttitor velit. Vivamus nibh metus, iaculis eget, malesuada eget, facilisis id, lorem. Sed turpis. Vestibulum aliquam mauris. In [...]
+	<div class="moveable" dojoType="dojo.dnd.move.boxConstrainedMoveable" box="{l: 100, t: 100, w: 500, h: 500}"><strong>Marked up paragraph restricted to (100,100:500,500) box:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum le [...]
 </body>
 </html>
diff --git a/dojo/tests/dnd/test_custom_constraints.html b/dojo/tests/dnd/test_custom_constraints.html
index bd261bb..ec71844 100644
--- a/dojo/tests/dnd/test_custom_constraints.html
+++ b/dojo/tests/dnd/test_custom_constraints.html
@@ -14,7 +14,7 @@
 			border: 1px solid black;
 			width: 300px;
 			padding: 10px 20px;
-			margin: 0px;
+			margin: 0;
 			cursor: pointer;
 		}
 	</style>
@@ -45,7 +45,7 @@
 </head>
 <body>
 	<h1>Dojo custom constraint test</h1>
-	<p class="moveable" id="moveable1"><strong>This paragraph stops at 50x50 grid knots:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor sit am [...]
-	<p class="moveable" id="moveable2"><strong>This paragraph stops at 50x50 grid knots:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor sit am [...]
+	<div class="moveable" id="moveable1"><strong>This paragraph stops at 50x50 grid knots:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor sit  [...]
+	<div class="moveable" id="moveable2"><strong>This paragraph stops at 50x50 grid knots:</strong> Donec ac odio sed pede aliquet auctor. Donec et lectus. Praesent feugiat ultrices enim. Morbi lectus. Donec vestibulum posuere libero. Donec quam enim, nonummy a, auctor vitae, placerat id, massa. Vivamus vulputate luctus nibh. Donec dolor orci, sagittis ac, pretium sed, ornare sit amet, pede. Vestibulum leo justo, pellentesque sit amet, tristique sed, tempor eu, felis. Lorem ipsum dolor sit  [...]
 </body>
 </html>
diff --git a/dojo/tests/dnd/test_parent_constraints_margins.html b/dojo/tests/dnd/test_parent_constraints_margins.html
index 8c9d6dc..0e92422 100644
--- a/dojo/tests/dnd/test_parent_constraints_margins.html
+++ b/dojo/tests/dnd/test_parent_constraints_margins.html
@@ -15,7 +15,6 @@
 			width: 300px;
 			padding: 10px 20px;
 			cursor: pointer;
-			margin: 20px;
 		}
 
 		.parent {
diff --git a/dojo/tests/hash.js b/dojo/tests/hash.js
index 408e3f7..b0d361d 100644
--- a/dojo/tests/hash.js
+++ b/dojo/tests/hash.js
@@ -319,6 +319,6 @@ dojo.require("dojo.hash");
 				dojo.unsubscribe(this._s);
 				setHash();
 			}
-		}	
+		}
 	]);
 })();
diff --git a/dojo/tests/html/test_set.html b/dojo/tests/html/test_set.html
index 9f312b7..aeb48f9 100644
--- a/dojo/tests/html/test_set.html
+++ b/dojo/tests/html/test_set.html
@@ -48,374 +48,432 @@
 			targetNode = null; 
 			
 			doh.register("basicChecks", [
-					{
-						name: 'set',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.byId("pane1");
-							var msg = "Simple No-params Test";
-							console.log("targetNode has content: ", targetNode.innerHTML);
-							var result = "";
-							dojo.html.set(
-								targetNode,
-								msg
-							);
-							console.log("after set, targetNode has content: ", targetNode.innerHTML);
-							t.assertEqual(msg, targetNode.innerHTML);
-						}
-					},
-					{
-						name: 'setContentWithOnEnd',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.byId("pane1");
-							var msg = "setContentWithOnEnd Test";
-							var result = false;
-							dojo.html.set(
-								targetNode,
-								msg, 
-								{
-									onEnd: function() {
-										dojo.getObject(this.declaredClass).prototype.onEnd.call(this);
-										result = true;
-									}
+				{
+					name: 'set',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.byId("pane1");
+						var msg = "Simple No-params Test";
+						console.log("targetNode has content: ", targetNode.innerHTML);
+						var result = "";
+						dojo.html.set(
+							targetNode,
+							msg
+						);
+						console.log("after set, targetNode has content: ", targetNode.innerHTML);
+						doh.is(msg, targetNode.innerHTML);
+					}
+				},
+				{
+					name: 'setContentWithOnEnd',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.byId("pane1");
+						var msg = "setContentWithOnEnd Test";
+						var result = false;
+						dojo.html.set(
+							targetNode,
+							msg,
+							{
+								onEnd: function() {
+									dojo.getObject(this.declaredClass).prototype.onEnd.call(this);
+									result = true;
 								}
-							);
-							t.assertEqual(msg, targetNode.innerHTML);
-							t.assertTrue(result);
-						}
+							}
+						);
+						doh.is(msg, targetNode.innerHTML);
+						doh.t(result);
+					}
+				},
+				{
+					name: 'setContent_with_parsing',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
+						dojo.html.set(
+							dojo.byId("pane1"),
+							cont,
+							{
+								postscript: function() {
+									this.set();
+
+									doh.t(typeof ifrs != "undefined" && ifrs.declaredClass=="dojo.html.test.SimpleThing");
+									doh.t(this.parseResults.length > 0);
+								},
+								parseContent: true
+							}
+						);
+					}
+				},
+				{
+					name: 'emptyElement',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						var msg = "setContentWithOnEnd Test";
+						var node = dojo.byId("pane1");
+						node.innerHTML = '<div><span>just</span>some test<br/></div>text';
+						var cNodes = node.childNodes.length;
+
+						dojo.html._emptyNode(dojo.byId("pane1"));
+						doh.t(node.childNodes.length == 0 && node.innerHTML == "");
+					}
+				},
+				// the following tests use the _emptyNode function, so ensure it passes before
+				// head-scratching over any failures that follow
+				{
+					name: 'changeContentTRHead',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.query('table#tableTest > thead > tr')[0];
+
+						var html = "<td><div>This</div>Should<u>Work</u></td>";
+						dojo.html.set(
+							targetNode,
+							html,
+							{
+								"testname": "basicChecks changeContentTRHead"
+							}
+						);
+						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
+						doh.is(html.toLowerCase(), res);
 					},
-					{
-						name: 'setContent_with_parsing',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
-							dojo.html.set(
-								dojo.byId("pane1"),
-								cont,
-								{	
-									postscript: function() {
-										this.set();
-
-										t.assertTrue(typeof ifrs != "undefined" && ifrs.declaredClass=="dojo.html.test.SimpleThing");
-										t.assertTrue(this.parseResults.length > 0);
-									},
-									parseContent: true
-								}
-							);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'changeContentTHead',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.query('table#tableTest > thead')[0];
+
+						var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
+						dojo.html.set(
+							targetNode,
+							html,
+							{
+								"testname": "basicChecks changeContentTHead"
+							}
+						);
+						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
+						doh.is(html.toLowerCase(), res);
 					},
-					{
-						name: 'emptyElement',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							var msg = "setContentWithOnEnd Test";
-							var node = dojo.byId("pane1");
-							node.innerHTML = '<div><span>just</span>some test<br/></div>text';
-							var cNodes = node.childNodes.length;
-							
-							dojo.html._emptyNode(dojo.byId("pane1"));
-							t.assertTrue(node.childNodes.length == 0 && node.innerHTML == "");
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'changeContentTRBody',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.query('table#tableTest > tbody > tr')[0];
+						var html = "<td><div>This</div>Should<u>Work</u></td>";
+						dojo.html.set(
+							targetNode,
+							html,
+							{
+								"testname": "basicChecks changeContentTRBody"
+							});
+						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
+						doh.is(html.toLowerCase(), res);
 					},
-					// the following tests use the _emptyNode function, so ensure it passes before
-					// head-scratching over any failures that follow
-					{
-						name: 'changeContentTRHead',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.query('table#tableTest > thead > tr')[0];
-							
-							var html = "<td><div>This</div>Should<u>Work</u></td>";
-							dojo.html.set(
-								targetNode, 
-								html, 
-								{
-									"testname": "basicChecks changeContentTRHead"
-								}
-							);
-							var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'changeContentTBody',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.query('table#tableTest > tbody')[0];
+						var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
+						dojo.html.set(
+							targetNode, html,
+							{
+								"testname": "basicChecks changeContentTBody"
+							});
+						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
+						doh.is(html.toLowerCase(), res);
 					},
-					{
-						name: 'changeContentTHead',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.query('table#tableTest > thead')[0];
-
-							var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
-							dojo.html.set(
-								targetNode, 
-								html, 
-								{
-									"testname": "basicChecks changeContentTHead"
-								}
-							);
-							var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'changeContentTable',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.query('table#tableTest')[0];
+						var html = "<tbody><tr><td><div>This</div>Should<u>Work</u></td></tr></tbody>";
+						dojo.html.set(
+							targetNode, html,
+							{
+								"testname": "basicChecks changeContentTable"
+							});
+						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
+						doh.is(html.toLowerCase(), res);
 					},
-					{
-						name: 'changeContentTRBody',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.query('table#tableTest > tbody > tr')[0];
-							var html = "<td><div>This</div>Should<u>Work</u></td>";
-							dojo.html.set(
-								targetNode,
-								html, 
-								{
-									"testname": "basicChecks changeContentTRBody"
-								});
-							var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'setNodeList',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						var tmpUL = dojo.create("ul");
+						dojo.create("li", { innerHTML: "item 1" }, tmpUL);
+						dojo.create("li", { innerHTML: "item 2" }, tmpUL);
+						console.log("ul content: ", tmpUL.innerHTML, tmpUL.childNodes.length);
+						targetNode = dojo.byId("pane1");
+						dojo.html.set(
+							targetNode, tmpUL.childNodes,
+							{
+								"testname": "basicChecks setNodeList"
+							});
+						var res = dojo.query("li", dojo.byId("pane1")).length
+						doh.is(2, res);
 					},
-					{
-						name: 'changeContentTBody',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.query('table#tableTest > tbody')[0];
-							var html = "<tr><td><div>This</div>Should<u>Work</u></td></tr>";
-							dojo.html.set(
-								targetNode, html, 
-								{
-									"testname": "basicChecks changeContentTBody"
-								});
-							var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'setMixedContent',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+
+						targetNode = dojo.byId("pane1");
+						var html = '<h4>See Jane</h4>'
+						 + 'Look at her <span>Run</span>!';
+						dojo.html.set(
+							targetNode, html,
+							{
+								"testname": "basicChecks setMixedContent"
+							});
+						var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
+						doh.is(html.toLowerCase(), res);
 					},
-					{
-						name: 'changeContentTable',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.query('table#tableTest')[0];
-							var html = "<tbody><tr><td><div>This</div>Should<u>Work</u></td></tr></tbody>";
-							dojo.html.set(
-								targetNode, html, 
-								{
-									"testname": "basicChecks changeContentTable"
-								});
-							var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: 'extractContent',
+					runTest: function(t){
+						console.log("basicChecks: " + this.name);
+						targetNode = dojo.byId("pane1");
+						var html = ''
+						+'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">'
+						+'<html>											'
+						+'	<head>											'
+						+'		<title>										'
+						+'			the title									 '
+						+'		</title>									'
+						+'	</head>											'
+						+'	<body>											'
+						+'		<p>											'
+						+'			This is the <b>Good Stuff</b><br>		'
+						+'		</p>										'
+						+'	</body>											'
+						+'</html>											';
+
+						dojo.html.set(
+							targetNode, html,
+							{
+								"testname": "basicChecks changeContentTable",
+								extractContent: true
+							});
+						doh.t(targetNode.innerHTML.indexOf("title") == -1);
+						doh.t(dojo.query("*", targetNode).length == 3);
 					},
-					{
-						name: 'setNodeList',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							var tmpUL = dojo.create("ul");
-							dojo.create("li", { innerHTML: "item 1" }, tmpUL);
-							dojo.create("li", { innerHTML: "item 2" }, tmpUL);
-							console.log("ul content: ", tmpUL.innerHTML, tmpUL.childNodes.length);
-							targetNode = dojo.byId("pane1");
-							dojo.html.set(
-								targetNode, tmpUL.childNodes, 
-								{
-									"testname": "basicChecks setNodeList"
-								});
-							var res = dojo.query("li", dojo.byId("pane1")).length
-							t.assertEqual(2, res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.html._emptyNode(targetNode);
+					}
+				}
+			]);
+			doh.register("nodelistExtension", [
+				{
+					name: 'nodelistHtml',
+					runTest: function(t){
+						console.log("nodelistExtension: " + this.name);
+
+						dojo.query(".zork").html("<li dojoType='dojo.html.test.ParserInstantiateTester'>1</li><li dojoType='dojo.html.test.ParserInstantiateTester'>2</li><li dojoType='dojo.html.test.ParserInstantiateTester'>3</li>",
+						{
+							parseContent: true,
+							onBegin: function() {
+								this.content = this.content.replace(/([0-9])/g, "MOOO");
+								this.inherited("onBegin", arguments);
+							}
+						}).removeClass("notdone").addClass("done");
+
+						var liNodes = dojo.query(".zork > li");
+
+						// test to make sure three li's were added to class="zork" node (3x 3 set li's)
+						doh.is(9, liNodes.length);
+
+						// test the innerHTML's got replaced in our onBegin
+						doh.t( liNodes.every(function(n) { return n.innerHTML.match(/MOOO/) }) );
+						console.log(this.name + ": innerHTML.match subtest was ok");
+
+						// test the parent elements got the correct className
+						doh.t( dojo.query(".zork").every(function(n) { return n.className == "zork done"; }) );
+						console.log(this.name + ": li.className subtest was ok");
+
+						// and test the parser correctly created object from the child nodes
+						// ...they should all have a test attribute now
+						doh.t( liNodes.every(function(n) { return n.getAttribute("test") == "ok"; }) );
+						console.log(this.name + ": Tester instantiation subtest(getAttribute) was ok");
+
 					},
-					{
-						name: 'setMixedContent',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							
-							targetNode = dojo.byId("pane1");
-							var html = '<h4>See Jane</h4>'
-							 + 'Look at her <span>Run</span>!';
-							dojo.html.set(
-								targetNode, html, 
-								{
-									"testname": "basicChecks setMixedContent"
-								});
-							var res = ieTrimSpaceBetweenTags(targetNode.innerHTML.toLowerCase());
-							t.assertEqual(html.toLowerCase(), res);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						// dojo.html._emptyNode(targetNode);
+					}
+				},
+				{
+					name: "nodeListSimple",
+					runTest: function(t){
+						var txt = "foo";
+						dojo.query("#simpleText").html("<p>"+txt+"</p>");
+
+						// check if its there at all
+						var len = dojo.query("#simpleText p").length;
+						doh.is(1, len);
+
+						// check the inner html is right:
+						var p = dojo.query("#simpleText p")[0];
+						doh.t( p && p.innerHTML == txt );
+					}
+				}
+			]);
+			doh.register("fromMarkup", [
+				{
+					name: 'contentOpFromMarkup',
+					runTest: function(t){
+						console.log("fromMarkup: " + this.name);
+
+						dojo.parser.parse("markupSetContentOp");
+						doh.t(dojo.byId("markupPane").innerHTML == "markupSetContentOp: new node content");
 					},
-					{
-						name: 'extractContent',
-						runTest: function(t){
-							console.log("basicChecks: " + this.name);
-							targetNode = dojo.byId("pane1");
-							var html = ''
-							+'<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">'
-							+'<html>											'
-							+'	<head>											'
-							+'		<title>										'
-							+'			the title									 '
-							+'		</title>									'
-							+'	</head>											'
-							+'	<body>											'
-							+'		<p>											'
-							+'			This is the <b>Good Stuff</b><br>		'
-							+'		</p>										'
-							+'	</body>											'
-							+'</html>											';
-							
-							dojo.html.set(
-								targetNode, html, 
-								{
-									"testname": "basicChecks changeContentTable", 
-									extractContent: true
-								});
-							t.assertTrue(targetNode.innerHTML.indexOf("title") == -1);
-							t.assertTrue(dojo.query("*", targetNode).length == 3);
-						},
-						tearDown: function(){
-							dojo.html._emptyNode(targetNode);
-						}
+					tearDown: function(){
+						dojo.byId("markupPane").innerHTML = "initial content";
 					}
-				]); 
-				doh.register("nodelistExtension", [
-					{
-						name: 'nodelistHtml',
-						runTest: function(t){
-							console.log("nodelistExtension: " + this.name);
-
-							dojo.query(".zork").html("<li dojoType='dojo.html.test.ParserInstantiateTester'>1</li><li dojoType='dojo.html.test.ParserInstantiateTester'>2</li><li dojoType='dojo.html.test.ParserInstantiateTester'>3</li>", 
-							{ 
-								parseContent: true, 
-								onBegin: function() {
-									this.content = this.content.replace(/([0-9])/g, "MOOO");
-									this.inherited("onBegin", arguments);
-								}
-							}).removeClass("notdone").addClass("done");
-							
-							var liNodes = dojo.query(".zork > li");
-							
-							// test to make sure three li's were added to class="zork" node (3x 3 set li's)
-							t.assertEqual(9, liNodes.length);
-
-							// test the innerHTML's got replaced in our onBegin
-							t.assertTrue( liNodes.every(function(n) { return n.innerHTML.match(/MOOO/) }) ); 
-							console.log(this.name + ": innerHTML.match subtest was ok");
-							
-							// test the parent elements got the correct className
-							t.assertTrue( dojo.query(".zork").every(function(n) { return n.className == "zork done"; }) );
-							console.log(this.name + ": li.className subtest was ok");
-							
-							// and test the parser correctly created object from the child nodes 
-							// ...they should all have a test attribute now
-							t.assertTrue( liNodes.every(function(n) { return n.getAttribute("test") == "ok"; }) );
-							console.log(this.name + ": Tester instantiation subtest(getAttribute) was ok");
-							
-						},
-						tearDown: function(){
-							// dojo.html._emptyNode(targetNode);
-						}
-					}, 
-					{
-						name: "nodeListSimple",
-						runTest: function(t){
-							var txt = "foo";
-							dojo.query("#simpleText").html("<p>"+txt+"</p>");
-
-							// check if its there at all
-							var len = dojo.query("#simpleText p").length;
-							t.assertEqual(1, len);
-							
-							// check the inner html is right:
-							var p = dojo.query("#simpleText p")[0];
-							t.assertTrue( p && p.innerHTML == txt );
-						}
+				},
+				{
+					name: 'extendedContentOpFromMarkup',
+					runTest: function(t){
+						console.log("fromMarkup: " + this.name);
+
+						dojo.parser.parse("markupSetContentOpX");
+
+						doh.t(dojo.byId("markupPane").innerHTML == "markupSetContentOpX: new node content".toUpperCase());
+					},
+					tearDown: function(){
+						dojo.byId("markupPane").innerHTML = "initial content";
 					}
-				]);
-				doh.register("fromMarkup", [
-					{
-						name: 'contentOpFromMarkup',
-						runTest: function(t){
-							console.log("fromMarkup: " + this.name);
-
-							dojo.parser.parse("markupSetContentOp");
-							t.assertTrue(dojo.byId("markupPane").innerHTML == "markupSetContentOp: new node content");
-						},
-						tearDown: function(){
-							dojo.byId("markupPane").innerHTML = "initial content";
-						}
+				}
+			]);
+			doh.register("reuse", [
+				{
+					name: 'ContentSetterReUse',
+					runTest: function(t){
+						console.log("fromMarkup: " + this.name);
+
+						targetNode = dojo.byId('pane1');
+						var args = [
+							[
+								"simple"
+							],
+							[
+								'<div dojoType="dojo.html.test.SimpleThing" jsId="id00">parsed content</div>',
+								{
+									parseContent: true
+								}
+							],
+							[
+								'<div dojoType="dojo.html.test.SimpleThing" jsId="id01">parsed content</div>',
+								{
+									parseContent: true
+								}
+							]
+						];
+						var setter = new dojo.html._ContentSetter({
+							node: targetNode
+						});
+						dojo.forEach(args, function(applyArgs) {
+							setter.node = targetNode;
+							setter.set.apply(setter, applyArgs);
+							setter.tearDown();
+						});
+						doh.t(id00 && id01);
+						// check we cleaned up after ourselves
+						doh.f(setter.parseResults);
 					},
-					{
-						name: 'extendedContentOpFromMarkup',
-						runTest: function(t){
-							console.log("fromMarkup: " + this.name);
-
-							dojo.parser.parse("markupSetContentOpX");
-
-							t.assertTrue(dojo.byId("markupPane").innerHTML == "markupSetContentOpX: new node content".toUpperCase());
-						},
-						tearDown: function(){
-							dojo.byId("markupPane").innerHTML = "initial content";
-						}
+					tearDown: function(){
+						dojo.byId("markupPane").innerHTML = "initial content";
 					}
-				]);
-				doh.register("reuse", [
-					{
-						name: 'ContentSetterReUse',
-						runTest: function(t){
-							console.log("fromMarkup: " + this.name);
-
-							targetNode = dojo.byId('pane1');
-							var args = [
-								[
-									"simple"
-								], 
-								[
-									'<div dojoType="dojo.html.test.SimpleThing" jsId="id00">parsed content</div>', 
-									{
-										parseContent: true
-									}
-								],
-								[
-									'<div dojoType="dojo.html.test.SimpleThing" jsId="id01">parsed content</div>',
-									{
-										parseContent: true
-									}
-								]
-							];
-							var setter = new dojo.html._ContentSetter({
-								node: targetNode
-							});
-							dojo.forEach(args, function(applyArgs) {
-								setter.node = targetNode; 
-								setter.set.apply(setter, applyArgs); 
-								setter.tearDown();
-							});
-							t.assertTrue(id00 && id01); 
-							// check we cleaned up after ourselves
-							t.assertFalse(setter.parseResults);
-						},
-						tearDown: function(){
-							dojo.byId("markupPane").innerHTML = "initial content";
-						}
+				}
+			]);
+
+			// Test specification of inherited attributes dir, lang, etc.
+			var handle;
+			doh.register("inherited", [
+				{
+					name: 'unspecified',
+					runTest: function(t){
+						var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
+
+						var parserCalled, inherited;
+						handle = dojo.connect(dojo.parser, "parse", function(args){
+							parserCalled = true;
+							inherited = args.inherited;
+						});
+
+						dojo.html.set(
+							dojo.byId("pane1"),
+							cont,
+							{
+								parseContent: true
+							}
+						);
+						doh.t(parserCalled, "parser was called");
+						doh.f("dir" in inherited, "no dir specified");
+						doh.f("lang" in inherited, "no lang specified");
+					},
+					tearDown: function(){
+						dojo.disconnect(handle);
 					}
-				]);
+				},
+				{
+					name: 'specified',
+					runTest: function(t){
+						var cont = '<div dojoType="dojo.html.test.SimpleThing" jsId="ifrs" data="{}"></div>';
+
+						var parserCalled, inherited;
+						handle = dojo.connect(dojo.parser, "parse", function(args){
+							parserCalled = true;
+							inherited = args.inherited;
+						});
 
+						dojo.html.set(
+							dojo.byId("pane1"),
+							cont,
+							{
+								dir: "rtl",
+								lang: "it_it",
+								parseContent: true
+							}
+						);
+						doh.t(parserCalled, "parser was called");
+						doh.is("rtl", inherited.dir, "dir");
+						doh.is("it_it", inherited.lang, "lang");
+					},
+					tearDown: function(){
+						dojo.disconnect(handle);
+					}
+				}
 
+			]);
 
 			doh.run();
 		}); 
diff --git a/dojo/tests/i18n.js b/dojo/tests/i18n.js
index 7997755..f24a5fc 100644
--- a/dojo/tests/i18n.js
+++ b/dojo/tests/i18n.js
@@ -1,3 +1,54 @@
+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");
@@ -42,7 +93,7 @@ dojo.require("dojo.i18n");
 				if (!dojo.i18n.isLeftToRight(loc)) {
 					var RLE = "\u202b";
 					var PDF = "\u202c";
-					hello_dojo = RLE + hello_dojo + PDF;					
+					hello_dojo = RLE + hello_dojo + PDF;
 				}
 				hello_dojo += "\t[" + loc + "]";
 				if(language_as_english){hello_dojo += " " + language_as_english;}
@@ -82,3 +133,5 @@ dojo.require("dojo.i18n");
 	};
 	tests.register("tests.i18n", testSet);
 })();
+
+}
diff --git a/dojo/tests/module.js b/dojo/tests/module.js
index 80e29f3..579b85c 100644
--- a/dojo/tests/module.js
+++ b/dojo/tests/module.js
@@ -2,10 +2,11 @@ dojo.provide("dojo.tests.module");
 
 try{
 	dojo.require("tests._base");
-	dojo.require("tests.i18n"); 
+	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");
@@ -26,6 +27,7 @@ try{
 	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");
diff --git a/dojo/tests/nls/ar/salutations.js b/dojo/tests/nls/ar/salutations.js
index 9b871bb..9bd0656 100644
--- a/dojo/tests/nls/ar/salutations.js
+++ b/dojo/tests/nls/ar/salutations.js
@@ -1,3 +1,5 @@
+define(
+//begin v1.x content
 /*<?xml version="1.0" encoding="UTF-8" ?>*/
 // The above is a workaround for Konqueror and Safari (see bug #1010)
 // The parentheses are optional, but make this file a valid JS expression for
@@ -6,3 +8,5 @@
  ar: "العربية",
  hello: "ﺎﺑﺣﺮﻣ"
 })
+//end v1.x content
+);
diff --git a/dojo/tests/nls/cs/salutations.js b/dojo/tests/nls/cs/salutations.js
index 7be97cd..79c44df 100644
--- a/dojo/tests/nls/cs/salutations.js
+++ b/dojo/tests/nls/cs/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  cs: "česky",
  hello: "Ahoj"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/de/salutations.js b/dojo/tests/nls/de/salutations.js
index fe9a8c3..7c25ff9 100644
--- a/dojo/tests/nls/de/salutations.js
+++ b/dojo/tests/nls/de/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  de: "Deutsch",
  hello: "Hallo"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/el/salutations.js b/dojo/tests/nls/el/salutations.js
index 89ab77a..6688262 100644
--- a/dojo/tests/nls/el/salutations.js
+++ b/dojo/tests/nls/el/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  el: "Ελληνικά",
  hello: "Γειά"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/en-au/salutations.js b/dojo/tests/nls/en-au/salutations.js
index a6bded0..78d9ca6 100644
--- a/dojo/tests/nls/en-au/salutations.js
+++ b/dojo/tests/nls/en-au/salutations.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 {
  hello: "G'day"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/en-us-hawaii/salutations.js b/dojo/tests/nls/en-us-hawaii/salutations.js
index 1c182d2..018524b 100644
--- a/dojo/tests/nls/en-us-hawaii/salutations.js
+++ b/dojo/tests/nls/en-us-hawaii/salutations.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 {
  hello: "Aloha"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/en-us-new_york-brooklyn/salutations.js b/dojo/tests/nls/en-us-new_york-brooklyn/salutations.js
index df00353..13e995a 100644
--- a/dojo/tests/nls/en-us-new_york-brooklyn/salutations.js
+++ b/dojo/tests/nls/en-us-new_york-brooklyn/salutations.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 {
  hello: "Yo"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/en-us-texas/salutations.js b/dojo/tests/nls/en-us-texas/salutations.js
index 70bdfa4..7aae7a2 100644
--- a/dojo/tests/nls/en-us-texas/salutations.js
+++ b/dojo/tests/nls/en-us-texas/salutations.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 {
  hello: "Howdy"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/es/salutations.js b/dojo/tests/nls/es/salutations.js
index 1bc5155..e91e6ba 100644
--- a/dojo/tests/nls/es/salutations.js
+++ b/dojo/tests/nls/es/salutations.js
@@ -1,5 +1,9 @@
+define(
+//begin v1.x content
 {
  es: "Español",
  hello: "Hola",
  hello_dojo: "¡${hello}, ${dojo}!"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/fa/salutations.js b/dojo/tests/nls/fa/salutations.js
index ca32a4d..9f98575 100644
--- a/dojo/tests/nls/fa/salutations.js
+++ b/dojo/tests/nls/fa/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  fa: "فارسی",
  hello: "درود"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/fr/salutations.js b/dojo/tests/nls/fr/salutations.js
index 8c4b74f..f87d354 100644
--- a/dojo/tests/nls/fr/salutations.js
+++ b/dojo/tests/nls/fr/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  fr: "Français",
  hello: "Bonjour"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/he/salutations.js b/dojo/tests/nls/he/salutations.js
index 0b2c441..7243d26 100644
--- a/dojo/tests/nls/he/salutations.js
+++ b/dojo/tests/nls/he/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  he: "עברית",
  hello: "שלום"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/hi/salutations.js b/dojo/tests/nls/hi/salutations.js
index 5f67686..81a114c 100644
--- a/dojo/tests/nls/hi/salutations.js
+++ b/dojo/tests/nls/hi/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  hi: "हिन्दी",
  hello: "नमस्ते"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/it/salutations.js b/dojo/tests/nls/it/salutations.js
index 19cb22d..aa77123 100644
--- a/dojo/tests/nls/it/salutations.js
+++ b/dojo/tests/nls/it/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  it: "italiano",
  hello: "Ciao"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/ja/salutations.js b/dojo/tests/nls/ja/salutations.js
index e009aa0..314c9dd 100644
--- a/dojo/tests/nls/ja/salutations.js
+++ b/dojo/tests/nls/ja/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  ja: "\u65E5\u672C\u8A9E",
  hello: "こにちは"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/ko/salutations.js b/dojo/tests/nls/ko/salutations.js
index 84f7010..72d78c9 100644
--- a/dojo/tests/nls/ko/salutations.js
+++ b/dojo/tests/nls/ko/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  ko: "\uD55C\uAD6D\uC5B4",
  hello: "\uc548\ub155"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/pl/salutations.js b/dojo/tests/nls/pl/salutations.js
index 440e24a..1a59470 100644
--- a/dojo/tests/nls/pl/salutations.js
+++ b/dojo/tests/nls/pl/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  pl: "Polski",
  hello: "Dzièn dobry"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/pt/salutations.js b/dojo/tests/nls/pt/salutations.js
index 436b69d..a607689 100644
--- a/dojo/tests/nls/pt/salutations.js
+++ b/dojo/tests/nls/pt/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  pt: "Português",
  hello: "Olá"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/ru/salutations.js b/dojo/tests/nls/ru/salutations.js
index 5f8f073..56aac0e 100644
--- a/dojo/tests/nls/ru/salutations.js
+++ b/dojo/tests/nls/ru/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  ru: "русский",
  hello: "Привет"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/salutations.js b/dojo/tests/nls/salutations.js
index b268a60..9b515cb 100644
--- a/dojo/tests/nls/salutations.js
+++ b/dojo/tests/nls/salutations.js
@@ -1,3 +1,5 @@
+define({ root:
+//begin v1.x content
 {
  ar: "Arabic",
  cs: "Czech",
@@ -30,3 +32,31 @@
  hello_dojo: "${hello}, ${dojo}!",
  file_not_found:"The file you requested, ${0}, is not found."
 }
+//end v1.x content
+,
+"zh-tw":1,
+"zh-cn":1,
+"yi":1,
+"tr":1,
+"th":1,
+"sw":1,
+"ru":1,
+"pt":1,
+"pl":1,
+"ko":1,
+"ja":1,
+"it":1,
+"hi":1,
+"he":1,
+"fr":1,
+"fa":1,
+"es":1,
+"en-us-texas":1,
+"en-us-new_york-brooklyn":1,
+"en-us-hawaii":1,
+"en-au":1,
+"el":1,
+"de":1,
+"cs":1,
+"ar":1
+});
diff --git a/dojo/tests/nls/sw/salutations.js b/dojo/tests/nls/sw/salutations.js
index 8399757..af66723 100644
--- a/dojo/tests/nls/sw/salutations.js
+++ b/dojo/tests/nls/sw/salutations.js
@@ -1,3 +1,7 @@
+define(
+//begin v1.x content
 {
  hello: "Hujambo"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/th/salutations.js b/dojo/tests/nls/th/salutations.js
index 2482533..70fbcd9 100644
--- a/dojo/tests/nls/th/salutations.js
+++ b/dojo/tests/nls/th/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  th: "ქართული ენაქართული ენაქართული ენაสวัสดีครับ/คะ",
  hello: "ภาษาไทย"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/tr/salutations.js b/dojo/tests/nls/tr/salutations.js
index a8da48f..192b3f2 100644
--- a/dojo/tests/nls/tr/salutations.js
+++ b/dojo/tests/nls/tr/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  tr: "Türkçe",
  hello: "Merhaba"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/yi/salutations.js b/dojo/tests/nls/yi/salutations.js
index 826a997..5f242cc 100644
--- a/dojo/tests/nls/yi/salutations.js
+++ b/dojo/tests/nls/yi/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  yi: "ייִדיש",
  hello: "אַ גוטן טאָג"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/zh-cn/salutations.js b/dojo/tests/nls/zh-cn/salutations.js
index 51b55ac..7181e3d 100644
--- a/dojo/tests/nls/zh-cn/salutations.js
+++ b/dojo/tests/nls/zh-cn/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  'zh-cn': "汉语",
  hello: "你好"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/nls/zh-tw/salutations.js b/dojo/tests/nls/zh-tw/salutations.js
index f00c43e..08e091f 100644
--- a/dojo/tests/nls/zh-tw/salutations.js
+++ b/dojo/tests/nls/zh-tw/salutations.js
@@ -1,4 +1,8 @@
+define(
+//begin v1.x content
 {
  'zh-tw': "漢語",
  hello: "你好"
 }
+//end v1.x content
+);
diff --git a/dojo/tests/number.js b/dojo/tests/number.js
index a76a841..4393b51 100644
--- a/dojo/tests/number.js
+++ b/dojo/tests/number.js
@@ -3,11 +3,11 @@ dojo.provide("tests.number");
 dojo.require("dojo.number");
 
 /**
- * Refer to ICU4J's NumberFormatTest.expect(...) 
+ * 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);	
+	tests.number.checkParse(t, t,options,expectResult,sourceInput);
 }
 
 /**
@@ -16,7 +16,7 @@ tests.number.check=function(t,options,sourceInput,expectResult){
  * then number should == number2; string1 should == string2
  */
 tests.number.checkFormatParseCycle=function(t,options,sourceInput,expectResult,
-		 backwardCheck/*boolean,indicates whether need a backward chain check,like formate->parse->format*/){	
+		 backwardCheck/*boolean,indicates whether need a backward chain check,like formate->parse->format*/){
 	if(null != options){
 		var pattern = options.pattern;
 		var locale = options.locale;
@@ -34,16 +34,16 @@ tests.number.checkFormatParseCycle=function(t,options,sourceInput,expectResult,
 	}
 	if(backwardCheck){
 		var resultParsed = dojo.number.parse(result,options);
-		//print("resultParsed:" + resultParsed);		
-		if(!tests.number._decimalNumberDiff(sourceInput,resultParsed)){	
+		//print("resultParsed:" + resultParsed);
+		if(!tests.number._decimalNumberDiff(sourceInput,resultParsed)){
 		    t.is(sourceInput,resultParsed);
-		}		
+		}
 		var resultParsedReformatted = dojo.number.format(resultParsed,options);
 		//print("resultParsedReformatted:" + resultParsedReformatted);
 	    if(!tests.number._decimalNumberDiff(result,resultParsedReformatted)){
 			t.is(result,resultParsedReformatted);
 		}
-	}	
+	}
 }
 
 /**
@@ -51,7 +51,7 @@ tests.number.checkFormatParseCycle=function(t,options,sourceInput,expectResult,
  */
 tests.number.checkParse=function(t,options,sourceInput,expectResult){
 	var str = "default";
-	if(null != options && null != options.pattern){	
+	if(null != options && null != options.pattern){
 		str = options.pattern;
 	}
 	//print("input:" + sourceInput);
@@ -69,7 +69,7 @@ tests.number.rounding = function(t,number,maxFractionDigits,expected){
 	var pattern="#0.";
 	for(var i=0; i<maxFractionDigits; i++){pattern += "#";}
 	var result = dojo.number.format(number,{locale:tests.number.locale, pattern:pattern});
-	t.is(expected,result);	
+	t.is(expected,result);
 }
 
 /**
@@ -85,11 +85,11 @@ function runBatchParse(options,dataArray/*array*/,pass/*boolean*/){
 	for(; i<dataArray.length; i++){
 		try{
 			//print("["+i+"]"+"input:"+dataArray[i]);
-			result = dojo.number.parse(dataArray[i],options);			
+			result = dojo.number.parse(dataArray[i],options);
 			if(isNaN(result)){
 				throw "\"" + dataArray[i] + "\" is parsed to NaN with pattern " + str;
 			}
-			//print("["+i+"]"+"output:"+result);	
+			//print("["+i+"]"+"output:"+result);
 		}catch(e){
 			exception = e;
 			break;
@@ -97,20 +97,20 @@ function runBatchParse(options,dataArray/*array*/,pass/*boolean*/){
 	}
 		
 	if(!pass && (exception == null)) {
-		throw "runBatchParse() - stric parse failed, no exception when parsing illegal data"; 
+		throw "runBatchParse() - stric parse failed, no exception when parsing illegal data";
 	}else if(exception != null){
 		if(!pass && i == 0){
 			//strict parsing should fail for all the dataArray elements as expected
 			//pass condition for strict parsing
 			return;
 		}
-		throw "runBatchParse() failed: " + exception;		
+		throw "runBatchParse() failed: " + exception;
 	}
 }
 
 /**
  * Check whether the given two numbers differ under the decimal bound
- * 
+ *
  */
 tests.number._decimalNumberDiff = function(num1,num2){
 	//TODO: should be more accurate when dojo.number finish rounding in the future
@@ -119,16 +119,16 @@ tests.number._decimalNumberDiff = function(num1,num2){
 	//print("Math.abs(diff) " + Math.abs(diff));
 	if(Math.abs(diff) < diffBound ){
 		return true;
-	}else if(isNaN(Math.abs(diff))){	
+	}else if(isNaN(Math.abs(diff))){
 		var s = num1.toString().split(num2);
 		s[1] = s[1].replace(",","0");
 		s[1] = s[1].replace('\u066b','0');
 		return (new Number(s[1])< diffBound);
 	}
-	return false;	
+	return false;
 }
 
-tests.register("tests.number", 
+tests.register("tests.number",
 	[
 		{
 			// Test formatting and parsing of currencies in various locales pre-built in dojo.cldr
@@ -136,14 +136,25 @@ tests.register("tests.number",
 			// load resources here for specific locales:
 
 			name: "number",
-			setUp: function(){
+			runTest: function(t){
 				var partLocaleList = ["en-us", "fr-fr", "de-de"];
 				tests.number.locale = "en-us";
-				for(var i = 0 ; i < partLocaleList.length; i ++){
-					dojo.requireLocalization("dojo.cldr","number",partLocaleList[i]);
-				}
-			},
-			runTest: function(t){
+        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]);
+		  		}
+        }
 			}
 		},
 		{
@@ -387,33 +398,33 @@ tests.register("tests.number",
 			runTest: function(t){
 
 /*************************************************************************************************
- * Evan:The following test cases are referred from ICU4J 3.6 (NumberFormatTest etc.) 
+ * Evan:The following test cases are referred from ICU4J 3.6 (NumberFormatTest etc.)
  * see http://icu.sourceforge.net/download/3.6.html#ICU4J
  *************************************************************************************************/
 
 
 /**
- * In ICU4J, testing logic for NumberFormat.format() is seperated into 
- * differernt single tese cases. So part of these logic are 
+ * In ICU4J, testing logic for NumberFormat.format() is seperated into
+ * differernt single tese cases. So part of these logic are
  * collected together in this single method.
- * 
+ *
  * !!Failed cases are as follows:
- * 1.1234567890987654321234567890987654321 should be formatted as 
+ * 1.1234567890987654321234567890987654321 should be formatted as
  *   1,234,567,890,987,654,321,234,567,890,987,654,321 with all the default parameters,
  *   but got 1.234 instead, may due to the unimplemeted exponent.
  * 2.\u00a4 and ' are not replaced
  * 	 with pattern "'*&'' '\u00a4' ''&*' #,##0.00"
  *   1.0 should be formatted to "*&' Re. '&* 1.00",but got "'*&'' '\u00a4' ''&*' 1.00" instead
- *   etc.   
- * 		
+ *   etc.
+ *
  */
 	//print("test_number_format_icu4j3_6() start..............");
 	/* !!Failed case, 1.234 returned instead
-	//refer to ICU4J's NumberFormatTest.TestCoverage() 
+	//refer to ICU4J's NumberFormatTest.TestCoverage()
 	var bigNum = 1234567890987654321234567890987654321;
 	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
@@ -424,7 +435,7 @@ tests.register("tests.number",
 	/*
 	var options = {pattern:"'*&'' '\u00a4' ''&*' #,##0.00",locale:"en-us"};
 	tests.number.check(t, options,1.0, "*&' Re. '&* 1.00");
-	tests.number.check(t, options,-2.0, "-*&' Rs. '&* 2.00");	
+	tests.number.check(t, options,-2.0, "-*&' Rs. '&* 2.00");
 
 	options = {pattern:"#,##0.00 '*&'' '\u00a4' ''&*'",locale:"en-us"};
 	tests.number.check(t, options,1.0,"1.00 *&' Re. '&*");
@@ -438,19 +449,19 @@ tests.register("tests.number",
 			runTest: function(t){
 
 /**
- * Refer to ICU4J's NumberFormatTest.TestPatterns() which now only coveres us locale	
+ * Refer to ICU4J's NumberFormatTest.TestPatterns() which now only coveres us locale
  */
 	//print("test_number_format_Patterns() start..............");
 	var patterns = (["#0.#", "#0.", "#.0", "#"]);
-	var patternsLength = patterns.length;    
+	var patternsLength = patterns.length;
 	var num = (["0","0", "0.0", "0"]);
 	var options;
 	//icu4j result seems doesn't work as:
-	//var num = (["0","0.", ".0", "0"]);      
+	//var num = (["0","0.", ".0", "0"]);
 	for (var i=0; i<patternsLength; ++i)
-	{	
+	{
 		options = {pattern:patterns[i], locale: 'en-us'};
-		tests.number.checkFormatParseCycle(t, options,0,num[i],false);       
+		tests.number.checkFormatParseCycle(t, options,0,num[i],false);
 	}
 	
 	//!!Failed case
@@ -479,7 +490,7 @@ tests.register("tests.number",
 		}else if(!exception && i==0){
 			throw "["+i+"]Failed when formatting 1.2 using illegal pattern  " + patterns[i];
 		}
-	}*/	
+	}*/
 	//print("test_number_format_Patterns() end..............\n");
 			}
 		},
@@ -487,7 +498,7 @@ tests.register("tests.number",
 			name: "exponential",
 			runTest: function(t){
 /**
- * TODO: For dojo.number future version 
+ * TODO: For dojo.number future version
  * Refer to ICU4J's NumberFormatTest.TestExponential()
  */
 			}
@@ -500,18 +511,18 @@ tests.register("tests.number",
  * Refer to ICU4J's NumberFormatTest.TestQuotes()
  */
 	//print("test_number_format_Quotes() start..............");
-	//TODO: add more locales 
+	//TODO: add more locales
 	
-	//TODO:!!Failed case	
+	//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?
 	/*
-	var pattern = "s'aa''s'c#";   
+	var pattern = "s'aa''s'c#";
 	var result = dojo.number.format(6666,{pattern:pattern,locale:"en-us"});
 	var expectResult = "saa'sc6666";
 	t.is(expectResult,result);
 	*/
-	//print("test_number_format_Quotes() end..............");     
+	//print("test_number_format_Quotes() end..............");
 			}
 		},
 		{
@@ -537,8 +548,8 @@ tests.register("tests.number",
 			runTest: function(t){
 /**
  * TODO: For dojo.number future version
- * Refer to ICU4J's NumberFormatTest.TestScientific()- Exponential testing 
- * Refer to ICU4J's NumberFormatTest.TestScientific2() 
+ * Refer to ICU4J's NumberFormatTest.TestScientific()- Exponential testing
+ * Refer to ICU4J's NumberFormatTest.TestScientific2()
  * Refer to ICU4J's NumberFormatTest.TestScientificGrouping()
  */
 			}
@@ -547,7 +558,7 @@ tests.register("tests.number",
 			name: "format_perMill",
 			runTest: function(t){
 /**
- * TODO: Failed case 
+ * TODO: Failed case
  * Refer to ICU4J's NumberFormatTest.TestPerMill()
  */
 	//print("test_number_format_PerMill() start..............");
@@ -556,7 +567,7 @@ tests.register("tests.number",
 	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 should format 0.4857 as 485.7\u2030,but got 485.700\u2030 instead
 	pattern = "###.###\u2030";
 	expectResult = "485.7\u2030";
 	result = dojo.number.format(0.4857,{pattern:pattern, locale: 'en-us'});
@@ -568,7 +579,7 @@ tests.register("tests.number",
 	pattern = "###.###m";
 	expectResult = "485.7m";
 	result = dojo.number.format(0.4857,{pattern:pattern,locale:"en"});
-	t.is(expectResult,result);	
+	t.is(expectResult,result);
 	*/
 	//print("test_number_format_PerMill() end..............\n");
 			}
@@ -577,21 +588,21 @@ tests.register("tests.number",
 			name: "format_grouping",
 			runTest: function(t){
 /**
- * Only test en-us and en-in 
+ * Only test en-us and en-in
  * Refer to ICU4J's NumberFormatTest.TestSecondaryGrouping()
  */
 	//print("test_number_format_Grouping() start..............");
 	//primary grouping
 	var sourceInput = 123456789;
 	var expectResult = "12,34,56,789";
-	var options = {pattern:"#,##,###",locale:"en-us"};	
+	var options = {pattern:"#,##,###",locale:"en-us"};
 
 	//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"			
+	//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)
@@ -599,9 +610,9 @@ tests.register("tests.number",
 	sourceInput = 1876543210;
 	expectResult = "1,87,65,43,210";
 	var result = dojo.number.format(sourceInput,{locale:"en-in"});
-	t.is(expectResult,result);   
+	t.is(expectResult,result);
 */
-	//print("test_number_format_Grouping() end..............\n");    
+	//print("test_number_format_Grouping() end..............\n");
 			}
 		},
 		{
@@ -613,11 +624,11 @@ tests.register("tests.number",
  * 1.with pattern "*^##.##":
  * 	 0 should be formatted to "^^^^0",but got "*^0" instead,
  *   -1.3 should be formatted to "^-1.3",but got "-*^1.3" instead.
- *   
+ *
  * 2.with pattern "##0.0####*_ 'g-m/s^2'" :
  *   0 should be formatted to "0.0______ g-m/s^2",but got ":0.0*_ 'g-m/s^2'" instead
  *   1.0/3 should be formatted to "0.33333__ g-m/s^2",but got "0.33333*_ 'g-m/s^2'" instead
- *   
+ *
  * 3.with pattern "*x#,###,###,##0.0#;*x(###,###,##0.0#)":
  * 	 -10 should be formatted to "xxxxxxxxxx(10.0)",but got "*x(10.0)" instead.
  *   10 should be formatted to "xxxxxxxxxxxx10.0",but got "*x10.0" instead.
@@ -626,7 +637,7 @@ tests.register("tests.number",
  *   1120456.37 should be formatted to "xxxx1,120,456.37",but got "*x1,120,456.37" instead.
  *   -1252045600.37 should be formatted to "(1,252,045,600.37)",but got "*x(1,252,045,600.37)" instead.
  *   1252045600.37 should be formatted to "10,252,045,600.37",but got "*x10,252,045,600.37" instead.
- *   
+ *
  * 4.with pattern "#,###,###,##0.0#*x;(###,###,##0.0#*x)"
  * 	 -10 should be formatted to (10.0xxxxxxxxxx),but got "(10.0*x)" instead.
  *   10 should be formatted to "10.0xxxxxxxxxxxx",but got "10.0*x" instead.
@@ -634,8 +645,8 @@ tests.register("tests.number",
  *   -1120456.37 should be formatted to "(1,120,456.37xx)",but got "(1,120,456.37*x)" instead.
  *   1120456.37 should be formatted to "xxxx1,120,456.37",but got "1,120,456.37*x" instead.
  *   -1252045600.37 should be formatted to "(1,252,045,600.37)",but got "(1,252,045,600.37*x)" instead.
- *   1252045600.37 should be formatted to ""10,252,045,600.37"",but got "10,252,045,600.37*x" instead.*   
- * 
+ *   1252045600.37 should be formatted to ""10,252,045,600.37"",but got "10,252,045,600.37*x" instead.*
+ *
  * Refer to ICU4J's NumberFormatTest.TestPad()
  */
 /*
@@ -645,12 +656,12 @@ function test_number_format_pad(){
 	var options = {pattern:"*^##.##",locale:locale};
 
 	tests.number.check(t, options,0,"^^^^0");
-	tests.number.check(t, options,-1.3,"^-1.3");	
+	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);	
+	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};
@@ -666,7 +677,7 @@ function test_number_format_pad(){
 	tests.number.check(t, options,-100.37, "xxxxxxxx(100.37)");
 	tests.number.check(t, options,-10456.37, "xxxxx(10,456.37)");
 	tests.number.check(t, options,-1120456.37, "xx(1,120,456.37)");
-	tests.number.check(t, options,-112045600.37, "(112,045,600.37)");    
+	tests.number.check(t, options,-112045600.37, "(112,045,600.37)");
 	tests.number.check(t, options,-1252045600.37, "(1,252,045,600.37)");
 
 
@@ -674,7 +685,7 @@ function test_number_format_pad(){
 	tests.number.check(t, options,1000, "xxxxxxxxx1,000.0");
 	tests.number.check(t, options,1000000, "xxxxx1,000,000.0");
 	tests.number.check(t, options,100.37, "xxxxxxxxxx100.37");
-	tests.number.check(t, options,10456.37, "xxxxxxx10,456.37");        
+	tests.number.check(t, options,10456.37, "xxxxxxx10,456.37");
 	tests.number.check(t, options,1120456.37, "xxxx1,120,456.37");
 	tests.number.check(t, options,112045600.37, "xx112,045,600.37");
 	tests.number.check(t, options,10252045600.37, "10,252,045,600.37");
@@ -685,10 +696,10 @@ function test_number_format_pad(){
 	tests.number.check(t, options, -1000, "(1,000.0xxxxxxx)");
 	tests.number.check(t, options, -1000000, "(1,000,000.0xxx)");
 	tests.number.check(t, options, -100.37, "(100.37xxxxxxxx)");
-	tests.number.check(t, options, -10456.37, "(10,456.37xxxxx)");    
+	tests.number.check(t, options, -10456.37, "(10,456.37xxxxx)");
 	tests.number.check(t, options, -1120456.37, "(1,120,456.37xx)");
-	tests.number.check(t, options, -112045600.37, "(112,045,600.37)");   
-	tests.number.check(t, options, -1252045600.37, "(1,252,045,600.37)");  
+	tests.number.check(t, options, -112045600.37, "(112,045,600.37)");
+	tests.number.check(t, options, -1252045600.37, "(1,252,045,600.37)");
 
 	tests.number.check(t, options, 10, "10.0xxxxxxxxxxxx");
 	tests.number.check(t, options, 1000, "1,000.0xxxxxxxxx");
@@ -697,7 +708,7 @@ function test_number_format_pad(){
 	tests.number.check(t, options, 10456.37, "10,456.37xxxxxxx");
 	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");	
+	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
@@ -710,14 +721,14 @@ function test_number_format_pad(){
 			name: "parse_icu4j3_6",
 			runTest: function(t){
 /**
- * In ICU4J, testing logic for NumberFormat.parse() is seperated into 
- * differernt single tese cases. So part of these logic are 
- * collected together in this test case. * 
+ * In ICU4J, testing logic for NumberFormat.parse() is seperated into
+ * differernt single tese cases. So part of these logic are
+ * collected together in this test case. *
  */
 	//print("test_number_parse_icu4j3_6() start..............");
 	//Refer to ICU4J's NumberFormatTest.TestParse() which is only a rudimentary version
 	var pattern = "00";
-	var str = "0.0";	
+	var str = "0.0";
 	var result = dojo.number.parse(str,{pattern:pattern, locale: 'en-us'});
 	//TODO: add more locales
 //FIXME: is this a valid test?
@@ -725,14 +736,14 @@ function test_number_format_pad(){
 
 	/**************************************** tolerant parse *****************************************
 	 * refers to ICU4J's NumberFormatTest.TestStrictParse()??
-	 * TODO: Seems dojo.number parses string in a tolerant way.  
+	 * TODO: Seems dojo.number parses string in a tolerant way.
 	 */
 	 var options = {locale:"en-us"};
 	/*
 	 * TODO: !!Failed case,Should all pass,
 	 * but the following elements failed (all parsed to NaN):
 	 * [1]-"0 ",[2]-"0.",[3]-"0,",[5]-"0. ",[6]-"0.100,5",
-	 * [7]-".00",[9]-"12345, ",[10]-"1,234, ",[12]-"0E" 
+	 * [7]-".00",[9]-"12345, ",[10]-"1,234, ",[12]-"0E"
 	 */
 	var passData = ([
 		"0",           //[0] single zero before end of text is not leading
@@ -747,17 +758,17 @@ function test_number_format_pad(){
         //"12345, ",   //[9] comma not followed by digit is not a group separator, but end of number
         //"1,234, ",   //[10] if group separator is present, group sizes must be appropriate
         "1,234,567"   //[11] ...secondary too
-        //,"0E"         //[12]not implemented yet,an exponnent not followed by zero or digits is not an exponent 
+        //,"0E"         //[12]not implemented yet,an exponnent not followed by zero or digits is not an exponent
          ]);
-	runBatchParse(options,passData,true/*tolerant parse*/);	
+	runBatchParse(options,passData,true/*tolerant parse*/);
 	
-	/* 
+	/*
 	 * TODO:!!Failed case,should all pass,
 	 * but the following failed,
 	 * [10]-"1,45 that" implies that we partially parse input
 	 */
-	var failData = ([        
-// leading zeros without separators are tolerated #6933   
+	var failData = ([
+// leading zeros without separators are tolerated #6933
 //		"00",          //[0] leading zero before zero
 //		"012",         //[1] leading zero before digit
         "0,456",       //[2] leading zero before group separator
@@ -781,14 +792,14 @@ function test_number_format_pad(){
 	 * TODO:!!Failed case,shoudl all pass.
 	 
 	 * but [1] [2] and [3] failed
-	 * should be parsed to 1234567,but NaN instead 
+	 * should be parsed to 1234567,but NaN instead
 	 */
-	var mixedPassData = ([            
+	var mixedPassData = ([
 		"12,34,567"    	//[0]
         //,"12,34,567,"		//[1]
         //"12,34,567, that",//[2]
         //"12,34,567 that"	//[3]
-		]);	
+		]);
 	runBatchParse(options,mixedPassData,true/*tolerant parse*/);
 	
 	/*
@@ -801,13 +812,13 @@ function test_number_format_pad(){
         "12,34,56,"		//[1]
         //,"12,34,56, that ",//[2]
         //"12,34,56 that",	//[3]
-		]);			
+		]);
 	runBatchParse(options,mixedFailData,false);
 	
 
 	/**************************************** strict parse ******************************************
 	 * TODO:May need to test strict parsing in the future?
-	 * e.g. A strict parsing like (with pattern "#,##0.#") 
+	 * e.g. A strict parsing like (with pattern "#,##0.#")
 	 * 1.Leading zeros
 	 * 		'00', '0123' fail the parse, but '0' and '0.001' pass
 	 * 2.Leading or doubled grouping separators
@@ -816,14 +827,14 @@ function test_number_format_pad(){
 	 * 		'1,23' and '1234,567' fail, but '1234' passes
 	 * 4.Grouping separators used in numbers followed by exponents
 	 * 		'1,234E5' fails, but '1234E5' and '1,234E' pass
-	 */	
+	 */
 	//options={locale:"en",strict:true};
 	//runBatchParse(options,passData,false/*strict parse*/);
-	//runBatchParse(options,failData,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*/);		
+	//runBatchParse(options,mixedFailData,false/*strict parse*/);
 
 	//print("test_number_parse_icu4j3_6() end..............\n");
 			}
@@ -834,26 +845,26 @@ function test_number_format_pad(){
 /**
  * TODO:!!Failed case
  * With pattern "a  b#0c  ",both "a b3456c " and and "a   b1234c   " should be parsed to 3456,but got NaN instead.
- * 
+ *
  * Refer to ICU4J's NumberFormatTest.TestWhiteSpaceParsing
  */
     /*
 	print("test_number_parse_WhiteSpace() start..............");
    	var pattern = "a  b#0c  ";
-	var expectResult = 3456;   
+	var expectResult = 3456;
 	result =  dojo.number.parse("a b3456c ",{pattern:pattern,locale:"en-us"});
-   	t.is(expectResult,result);	
+   	t.is(expectResult,result);
 	result =  dojo.number.parse("a   b3456c   ",{pattern:pattern,locale:"en-us"});
 	t.is(expectResult,result);
 	print("test_number_parse_WhiteSpace() end..............\n");
-	*/   
+	*/
 			}
 		},
 /*************************************************************************************************
  *                            Regression test cases
  * These test cases are referred to ICU4J's NumberFormatRegressionTest and NumberFormatRegression.
- * The regression cases in ICU4J are used as unit test cases for bug fixing, 
- * They are inluced here so that dojo.number may avoid those similar bugs. 
+ * The regression cases in ICU4J are used as unit test cases for bug fixing,
+ * They are inluced here so that dojo.number may avoid those similar bugs.
  *************************************************************************************************/
 		{
 			name: "number_regression_1",
@@ -872,9 +883,9 @@ function test_number_format_pad(){
  * Refer to ICU4J's NumberFormatRegressionTest.Test4408066()
  */
 	/*
-	var data =   ([-3.75, -2.5, -1.5, 
-                   -1.25, 0,    1.0, 
-                   1.25,  1.5,  2.5, 
+	var data =   ([-3.75, -2.5, -1.5,
+                   -1.25, 0,    1.0,
+                   1.25,  1.5,  2.5,
                    3.75,  10.0, 255.5]);
 	var expected = (["-4", "-2", "-2",
                     "-1", "0",  "1",
@@ -883,11 +894,11 @@ function test_number_format_pad(){
 	var options = {locale:"zh-cn",round:true};
 	for(var i =0; i < data.length; i++){
 		tests.number.checkFormatParseCycle(t, options,data[i],expected[i],false);
-	}	
+	}
 
-	data = ([ 	"-3.75", "-2.5", "-1.5", 
-              	"-1.25", "0",    "1.0", 
-              	"1.25",  "1.5",  "2.5", 
+	data = ([ 	"-3.75", "-2.5", "-1.5",
+              	"-1.25", "0",    "1.0",
+              	"1.25",  "1.5",  "2.5",
               	"3.75",  "10.0", "255.5"]);
 	expected =([ -3, -2, -1,
                  -1, 0,  1,
@@ -908,12 +919,12 @@ function test_number_format_pad(){
  */
 	tests.number.checkFormatParseCycle(t, {places:0},0,"0",false);
 	//TODO:in icu4j,0.1 should be formatted to ".1" when minimumIntegerDigits=0
-	tests.number.checkFormatParseCycle(t, {places:0},0.1,"0",false);	
+	tests.number.checkFormatParseCycle(t, {places:0},0.1,"0",false);
 	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 
+	//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);
 	tests.number.checkFormatParseCycle(t, {pattern:"#.#"},0.0,"0",false);
@@ -925,8 +936,8 @@ function test_number_format_pad(){
 /**
  * TODO:
  * In ICU -0.0 and -0.0001 should be formatted to "-0" with FieldPosition(0)
- * dojo.i18n.number format -0.0 to "-0"; -0.0001 to "-0.000100" 
- * 
+ * dojo.i18n.number format -0.0 to "-0"; -0.0001 to "-0.000100"
+ *
  * Refer to ICU4J's NumberRegression.Test4088503() and Test4106658()
  */
 	tests.number.checkFormatParseCycle(t, {places:0},123,"123",false);
@@ -946,7 +957,7 @@ function test_number_format_pad(){
  * 0.00159999 should be formatted as 0.0016 but got 0.0015 instead.
  * Refer to ICU4J's NumberRegression.Test4071492()
  */
-	//tests.number.checkFormatParseCycle(t, {places:4,round:true},0.00159999,"0.0016",false);	
+	//tests.number.checkFormatParseCycle(t, {places:4,round:true},0.00159999,"0.0016",false);
 			}
 		},
 		{
@@ -961,7 +972,7 @@ function test_number_format_pad(){
 	
 	//no group separator
 	tests.number.checkFormatParseCycle(t, options,1234,"1234,00",false);
-	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)";
@@ -974,17 +985,17 @@ function test_number_format_pad(){
 			name: "number_regression_7",
 			runTest: function(t){
 /**
- * !!Failed case - expontent has not implemented yet 
+ * !!Failed case - expontent has not implemented yet
  * shuold format 1.000000000000001E7 to 10000000.00000001, but got 10,000,000.000 instead
  * Refer to ICU4J's NumberRegression.Test4090489() - loses precision
  */
-	//tests.number.checkFormatParseCycle(t, null,1.000000000000001E7,"10000000.00000001",false);	
+	//tests.number.checkFormatParseCycle(t, null,1.000000000000001E7,"10000000.00000001",false);
 			}
 		},
 		{
 			name: "number_regression_8",
 			runTest: function(t){
-/** 
+/**
  * !!Failed case
  * 1.with pattern "#,#00.00 p''ieces;-#,#00.00 p''ieces"
  *   3456.78 should be formated to "3,456.78 p'ieces",
@@ -993,22 +1004,22 @@ function test_number_format_pad(){
  * 	 no error for the illegal pattern, and 3456.78 is formatted to 456.780
  * 3.with illegal pattern "0#0.000"
  * 	 no error for the illegal pattern, and 3456.78 is formatted to 3456.780
- * 
- * Refer to ICU4J's NumberRegression.Test4092480(),Test4074454() 
+ *
+ * Refer to ICU4J's NumberRegression.Test4092480(),Test4074454()
  */
 	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: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);	
+	//tests.number.checkFormatParseCycle(t, {pattern:"#,#00.00 p''ieces;-#,#00.00 p''ieces"},3456.78,"3,456.78 p'ieces",false);
 	//tests.number.checkFormatParseCycle(t, {pattern:"000.0#0"},3456.78,null,false);
-	//tests.number.checkFormatParseCycle(t, {pattern:"0#0.000"},3456.78,null,false);	
+	//tests.number.checkFormatParseCycle(t, {pattern:"0#0.000"},3456.78,null,false);
 			}
 		},
 		{
@@ -1018,15 +1029,15 @@ function test_number_format_pad(){
  * TODO
  * Refer to ICU4J's NumberRegression.Test4052223()
  */
-	//TODO:only got NaN,need an illegal pattern exception? 
-	tests.number.checkParse(t, {pattern:"#,#00.00"},"abc3");	
+	//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");	
+	tests.number.checkParse(t, null,"hello: ,.#$@^&**10x");
 			}
 		},
 		{
@@ -1052,7 +1063,7 @@ function test_number_format_pad(){
 /**
  * TODO:!!Failed case
  * Make sure that all special characters, when quoted in a suffix or prefix, lose their special meaning.
- * The detail error info :  
+ * The detail error info :
  * for input 123
  * pattern:'0'#0'0'; expect:"01230"; but got "'3'#0'0'" instead
  * pattern:','#0','; expect:",123,"; but got "','123','" instead
@@ -1060,20 +1071,20 @@ function test_number_format_pad(){
  * pattern:'‰'#0'‰'; expect:"‰123‰"; but got "'‰'123000'‰'" instead
  * pattern:'%'#0'%'; expect:"%123%"; but got "'%'12300'%'" instead
  * pattern:'#'#0'#'; expect:"#123#"; but got "'123'#0'#'" instead
- * pattern:';'#0';'; expect:";123;"; but got "[dojo-test] FATAL exception raised: 
+ * pattern:';'#0';'; expect:";123;"; but got "[dojo-test] FATAL exception raised:
  * 											  unable to find a number expression in pattern: '"
  * pattern:'E'#0'E'; expect:"E123E"; not implemeted yet
  * pattern:'*'#0'*'; expect:"*123*"; but got "'*'123'*'" instead
  * pattern:'+'#0'+'; expect:"+123+"; but got "'+'123'+'" instead
  * pattern:'-'#0'-'; expect:"-123-"; but got "'-'123'-'" instead
- * 
+ *
  * TODO: is it ok to remain "'" in the formatted result as above??
- * 
+ *
  * Refer to ICU4J's NumberRegression.Test4212072()
  */
 /*
 	var specials = ([ '0', ',', '.', '\u2030', '%', '#',';', 'E', '*', '+', '-']);
-	var pattern; 
+	var pattern;
 	var expect;
 	
 	for(var i=0; i < specials.length; i ++){
@@ -1088,12 +1099,12 @@ function test_number_format_pad(){
 			name: "number_regression_12",
 			runTest: function(t){
 /**
- * TODO: add more rounding test cases, refer to ICU4J's NumberRegression.Test4071005(),Test4071014() etc.. 
+ * TODO: add more rounding test cases, refer to ICU4J's NumberRegression.Test4071005(),Test4071014() etc..
  */
 
 /**
  * TODO:Decimal format doesnt round a double properly when the number is less than 1
- * 
+ *
  * Refer to ICU4J's NumberRegression.test4241880()
  */
 /*
diff --git a/dojo/tests/parser.html b/dojo/tests/parser.html
index 5e4f100..7b19b20 100644
--- a/dojo/tests/parser.html
+++ b/dojo/tests/parser.html
@@ -1,15 +1,21 @@
+<!DOCTYPE html>
 <html>
 	<head>
 		<title>Parser Unit Test</title>
-		<style type="text/css">
+		<style type="text/css">     
 			@import "../resources/dojo.css";
 		</style>
 		<script type="text/javascript"
 			src="../dojo.js"
-			djConfig="isDebug: true, parseOnLoad: true"></script>
+			data-dojo-config="isDebug: true, parseOnLoad: false"></script>
 		<script type="text/javascript">
-			dojo.require("dojo.parser");
-			dojo.require("doh.runner");
+		define("dojo/tests/parser/script", ["dojo", "dojo/parser", "doh/runner"], function(dojo) {
+
+			dojo.declare("tests.parser.Widget", null, {
+				constructor: function(args, node){
+					this.params = args;
+				}
+			});
 
 			dojo.declare("tests.parser.Class1", null, {
 				constructor: function(args, node){
@@ -73,10 +79,11 @@
 				checked: false
 			});
 
-			// Test that dir attribute can be inherited from ancestor node
-			dojo.declare("tests.parser.DirClass", null, {
+			// 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); },
 				dir: "",
+				lang: "",
 				name: ""
 			});
 
@@ -92,6 +99,33 @@
 				stopParser: true
 			});
 
+			dojo.declare("tests.parser.HTML5Props", null, {
+				constructor: function(args, node){ dojo.mixin(this, args); },
+				simple:false, 
+				a:2, 
+				b:null, c:null, d: null, e:null, f:null,
+				afn: function(){
+					return this.a * 2;
+				}
+			});
+			
+			// not on .prototype:
+			tests.parser.HTML5Props._aDefaultObj = {
+				a:1, b:2, simple:true
+			};
+
+			dojo.declare("tests.parser.HTML5withMethod", null, {
+				constructor: function(args, node){ dojo.mixin(this, args); },
+				baseValue: 10,
+				someMethod: function(a, b){
+					return this.baseValue; 
+				},
+				diffMethod: function(a){
+					this._ran = true;
+				}
+			})
+			
+
 			deepTestProp = {
 				blah: {
 					thinger: 1
@@ -99,8 +133,13 @@
 			};
 
 			dojo.addOnLoad(function(){
-				doh.register("t",
+				doh.register("basic",
 					[
+						function parse(){
+							// Running the parser here so that failures appear in test log
+							dojo.parser.parse("main");
+						},
+
 						function testJsId(t){
 							// console.debug(obj);
 							t.t(typeof obj == "object");
@@ -201,7 +240,7 @@
 							t.t(obj.func3Called);
 						},
 
-						// test <script> tags inside innerHTML of source node
+						// test script tags inside innerHTML of source node
 						"t.is(4, obj.preambleTestProp);",
 						"t.is(deepTestProp, obj.deepProp);",
 						function testConnect(t){
@@ -243,7 +282,7 @@
 							dojo.parser.parse("parsertest", { noStart:true });
 							
 							t.f(started);
-							
+
 							dojo.empty("parsertest");
 							
 							started = false;
@@ -289,15 +328,6 @@
 							doh.is(12345, widgets[0].params.newParam, "new parameter parsed");
 						},
 
-						// Test that dir=rtl or dir=ltr setting trickles down from root node
-						function dir(){				
-							doh.is("rtl", setRtl.dir, "direct setting of dir=rtl works");
-							doh.is("rtl", inheritRtl.dir, "inherited rtl works");
-							doh.is("ltr", inheritLtr.dir, "inherited ltr works (closest ancestor wins)");
-							doh.is("rtl", inheritRtl2.dir, "inherited rtl works, from grandparent");
-							doh.is("ltr", setLtr.dir, "direct setting of dir=ltr overrides inherited RTL");
-						},
-						
 						// Test that parser recurses correctly, except when there's a stopParser flag not to
 						function recurse(){
 							doh.t(container1, "normal container created");
@@ -309,100 +339,215 @@
 							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")
+						},
+						
+						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");
 						}
 					]
 				);
+
+				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");
+						doh.is("rtl", setRtl.dir, "direct setting of dir=rtl works");
+						doh.is("rtl", inheritRtl.dir, "inherited rtl works");
+						doh.is("ltr", inheritLtr.dir, "inherited ltr works (closest ancestor wins)");
+						doh.is("rtl", inheritRtl2.dir, "inherited rtl works, from grandparent");
+						doh.is("ltr", setLtr.dir, "direct setting of dir=ltr overrides inherited RTL");
+					},
+					function lang(){
+						dojo.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");
+					}
+				]);
+
 				doh.run();
 			})
+		});
 		</script>
 	</head>
 	<body>
 		<h1>Parser Unit Test</h1>
-		<script>
-			function foo(){ this.fooCalled=true; }
-		</script>
-		<div dojoType="tests.parser.Class1" jsId="obj" 
-			strProp1="text" strProp2=""
-			intProp="5"
-			arrProp="foo, bar, baz"
-			arrProp2=""
-			boolProp1="true" boolProp2="false"
-			dateProp1="2006-01-01" dateProp2="" dateProp3="now"
-			funcProp2="foo" funcProp3="this.func3Called=true;"
-		>
-			<script type="dojo/method" event="preamble">
-				this.preambleTestProp = 3;
-			</script>
-			<script type="dojo/method">
-				// this should be run immediately
-				this.deepProp = deepTestProp;
-			</script>
-			<script type="dojo/connect" event="callInc">
-				this.callCount++;
-			</script>
-			<script type="dojo/method" event="callInc2">
-				this.callCount2++;
+
+		<div id="main">
+			<script>
+				function foo(){ this.fooCalled=true; }
 			</script>
-		</div>
-		<div>
-			<div type="tests.parser.Class1" jsId="obj2" id="toParse">
+			<div dojoType="tests.parser.Class1" data-dojo-id="obj"
+				strProp1="text" strProp2=""
+				intProp="5"
+				arrProp="foo, bar, baz"
+				arrProp2=""
+				boolProp1="true" boolProp2="false"
+				dateProp1="2006-01-01" dateProp2="" dateProp3="now"
+				funcProp2="foo" funcProp3="this.func3Called=true;"
+			>
+				<script type="dojo/method" event="preamble">
+					this.preambleTestProp = 3;
+				</script>
+				<script type="dojo/method">
+					// this should be run immediately
+					this.deepProp = deepTestProp;
+				</script>
+				<script type="dojo/connect" event="callInc">
+					this.callCount++;
+				</script>
+				<script type="dojo/method" event="callInc2">
+					this.callCount2++;
+				</script>
 			</div>
+			<div>
+				<div type="tests.parser.Class1" jsId="obj2" id="toParse">
+				</div>
+			</div>
+			<div dojoType="tests.parser.Class2" jsId="obj3">
+			</div>
+			<div dojoType="tests.parser.Class3" jsId="obj4">
+			</div>
+			<input dojoType="tests.parser.inputClass" jsId="checkedObj" checked type="checkbox">
+			<button dojoType="tests.parser.inputClass" jsId="disabledObj" disabled>hi</button>
+
+			<div id="parsertest"></div>
+			<div id="parsertest2"></div>
+
+			<!-- section for testing parser recursion -->
+			<div>
+				<div dojoType="tests.parser.NormalContainer" jsId="container1">
+					<!-- this script tag should get passed as param to NormalContainer constructor -->
+					<script type="dojo/method" event="incr" args="x">
+						return x+1;
+					</script>
+
+					<!-- and these contained widgets should get instantiated -->
+					<div dojoType="tests.parser.Class1" jsId="contained1"></div>
+					<div>
+						<div dojoType="tests.parser.Class1" jsId="contained2"></div>
+					</div>
+				</div>
+			</div>
+
+			<div>
+				<div dojoType="tests.parser.ShieldedContainer" jsId="container2">
+					<!-- this script tag should get passed as param to NormalContainer constructor -->
+					<script type="dojo/method" event="incr" args="x">
+						return x+1;
+					</script>
+
+					<!-- but these contained widgets should *not* get instantiated -->
+					<div dojoType="tests.parser.Class1" jsId="contained3"></div>
+					<div>
+						<div dojoType="tests.parser.Class1" jsId="contained4"></div>
+					</div>
+				</div>
+			</div>
+
+			<div>
+				<div data-dojo-id="html5simple" data-dojo-type="tests.parser.HTML5Props" data-dojo-props="simple:true"></div>
+				<div data-dojo-id="html5simple2" data-dojo-type="tests.parser.HTML5Props"
+					data-dojo-props="simple:false, a:1, b:'two', c:[1,2,3], d:function(){ return this; }, e:{ f:'g' }"
+				></div>
+				<!-- note needing to use a named inherited lookup because we're just mixing in -->
+				<div data-dojo-id="html5simple3" data-dojo-type="tests.parser.HTML5Props"
+					data-dojo-props="afn: function(){ return this.inherited('afn', arguments); }"
+				></div>
+
+				<!-- not used for tests, but thinking out loud: what about a named-resource prop, via getObject -->
+				<div data-dojo-id="html5fromobjectns" data-dojo-type="tests.parser.HTML5Props"
+					data-dojo-obj="tests.parser.HTML5Props._aDefaultObj"
+				></div>
+				<div data-dojo-id="html5fromobjectns2" data-dojo-type="tests.parser.HTML5Props"
+					data-dojo-obj="tests.parser.HTML5Props._aDefaultObj" data-dojo-props="simple:false"
+				></div>
+
+			</div>
+
+			<div>
+				<div data-dojo-id="htmldojomethod" data-dojo-type="tests.parser.HTML5withMethod">
+					<p>Some random markup</p>
+					<script type="dojo/method" data-dojo-event="someMethod" data-dojo-args="a, b">
+						return this.baseValue + a + b;
+					</script>
+					<script type="dojo/connect" data-dojo-event="diffMethod" data-dojo-args="a">
+						this._fromvalue = a;
+					</script>
+					<script type="dojo/method">
+						this._methodRan = true;
+					</script>
+				</div>
+			</div>
+		</div> <!-- close <div id=main> -->
+
+		<!-- section for testing that dir, lang attribute trickles down from ancestor -->
+		<div id="dirSection1">
+			<div dojoType="tests.parser.BidiClass" jsId="setRtl" dir="rtl" name="RTL setting"></div>
+			<div dojoType="tests.parser.BidiClass" jsId="noDir" name="dir not inherited or set"></div>
 		</div>
-		<div dojoType="tests.parser.Class2" jsId="obj3">
-		</div>
-		<div dojoType="tests.parser.Class3" jsId="obj4">
-		</div>
-		<input dojoType="tests.parser.inputClass" jsId="checkedObj" checked type="checkbox">
-		<button dojoType="tests.parser.inputClass" jsId="disabledObj" disabled>hi</button>
-		
-		<div id="parsertest"></div>
-		<div id="parsertest2"></div>
-
-		<!-- section for testing that dir attribute trickles down from ancestor -->
-		<div dojoType="tests.parser.DirClass" jsId="setRtl" dir="rtl" name="RTL setting"></div>
-		<div dir="rtl">
-			<div dojoType="tests.parser.DirClass" jsId="inheritRtl" name="inherited RTL from parent"></div>
+		<div id="dirSection2" dir="rtl">
+			<div dojoType="tests.parser.BidiClass" jsId="inheritRtl" name="inherited RTL from parent"></div>
 			<div dir="ltr">
-				<div dojoType="tests.parser.DirClass" jsId="inheritLtr" name="inherited LTR from parent"></div>
+				<div dojoType="tests.parser.BidiClass" jsId="inheritLtr" name="inherited LTR from parent"></div>
 			</div>
 			<div>
-				<div dojoType="tests.parser.DirClass" jsId="inheritRtl2" name="inherited RTL from grandparent"></div>
+				<div dojoType="tests.parser.BidiClass" jsId="inheritRtl2" name="inherited RTL from grandparent"></div>
 			</div>
-			<div dojoType="tests.parser.DirClass" jsId="setLtr" dir="ltr" name="LTR setting overrides inherited RTL"></div>
+			<div dojoType="tests.parser.BidiClass" jsId="setLtr" dir="ltr" name="LTR setting overrides inherited RTL"></div>
 		</div>
-		<div dojoType="tests.parser.DirClass" jsId="noDir" name="dir not inherited or set"></div>
-		
-		<!-- section for testing parser recursion -->
-
-		<div>
-			<div dojoType="tests.parser.NormalContainer" jsId="container1">
-				<!-- this script tag should get passed as param to NormalContainer constructor -->
-				<script type="dojo/method" event="incr" args="x">
-					return x+1;
-				</script>
-				
-				<!-- and these contained widgets should get instantiated -->
-				<div dojoType="tests.parser.Class1" jsId="contained1"></div>
-				<div>
-					<div dojoType="tests.parser.Class1" jsId="contained2"></div>			
-				</div>
+		<div id="langSection">
+			<div dojoType="tests.parser.BidiClass" jsId="noLang" name="shouldn't get lang"></div>
+			<div lang="it_it">
+				<div dojoType="tests.parser.BidiClass" jsId="inheritedLang" name="inherited lang from parent"></div>
+				<div dojoType="tests.parser.BidiClass" jsId="specifiedLang" lang="en_us" name="specified lang overrides parent"></div>
 			</div>
 		</div>
-
-		<div>
-			<div dojoType="tests.parser.ShieldedContainer" jsId="container2">
-				<!-- this script tag should get passed as param to NormalContainer constructor -->
-				<script type="dojo/method" event="incr" args="x">
-					return x+1;
-				</script>
-				
-				<!-- but these contained widgets should *not* get instantiated -->
-				<div dojoType="tests.parser.Class1" jsId="contained3"></div>
-				<div>
-					<div dojoType="tests.parser.Class1" jsId="contained4"></div>			
-				</div>
+		<div id="textDirSection">
+			<div dojoType="tests.parser.BidiClass" jsId="noTextdir" name="shouldn't get textdir"></div>
+			<div data-dojo-textdir="rtl">
+				<div dojoType="tests.parser.BidiClass" jsId="inheritedTextdir" name="inherited textdir from parent"></div>
+				<div dojoType="tests.parser.BidiClass" jsId="specifiedTextdir" data-dojo-textdir="ltr" name="specified textdir overrides parent"></div>
 			</div>
 		</div>
-
+		<div id="bidiInheritanceFromHtml">
+			<div dojoType="tests.parser.BidiClass" jsId="inheritedFromHtml" name="should get dir/lang/textDir from HTML tag"></div>
+		</div>
 	</body>
 </html>
diff --git a/dojo/tests/regexp.js b/dojo/tests/regexp.js
index ea156d5..47aea23 100644
--- a/dojo/tests/regexp.js
+++ b/dojo/tests/regexp.js
@@ -2,7 +2,7 @@ dojo.provide("tests.regexp");
 
 dojo.require("dojo.regexp");
 
-tests.register("tests.regexp", 
+tests.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"));
diff --git a/dojo/tests/resources/test_css.html b/dojo/tests/resources/test_css.html
index 46617e5..c9cf333 100644
--- a/dojo/tests/resources/test_css.html
+++ b/dojo/tests/resources/test_css.html
@@ -1,7 +1,7 @@
 <html>
 	<head>
 		<title>Dojo CSS Stylesheet Test</title>
-		<link rel="stylesheet" type="text/css" href="../../resources/dojo.css">
+		<link rel="stylesheet" type="text/css" href="../../resources/dojo.css"/>
 	</head>
 	<body>
 		<h1>Lorem ipsum dolor sit amet.</h1>
diff --git a/dojo/tests/rpc.js b/dojo/tests/rpc.js
index 5dc3895..0336b36 100644
--- a/dojo/tests/rpc.js
+++ b/dojo/tests/rpc.js
@@ -4,8 +4,8 @@ dojo.require("dojo.rpc.RpcService");
 dojo.require("dojo.rpc.JsonService");
 dojo.require("dojo.rpc.JsonpService");
 
-doh.register("tests.rpc", 
-	[ 
+doh.register("tests.rpc",
+	[
 
 		{
 			name: "JsonRPC-EchoTest",
@@ -24,7 +24,7 @@ doh.register("tests.rpc",
 								}
 							]
 						}
-					]	
+					]
 				}
 			
 				this.svc = new dojo.rpc.JsonService(testSmd);
@@ -62,7 +62,7 @@ doh.register("tests.rpc",
 			setUp: function(){
 				var testSmd={
 					serviceURL:"../../dojo/tests/resources/test_JsonRPCMediator.php",
-					methods:[ { name:"contentB" } ]	
+					methods:[ { name:"contentB" } ]
 				}
 			
 				this.svc = new dojo.rpc.JsonService(testSmd);
diff --git a/dojo/tests/sie/all.js b/dojo/tests/sie/all.js
new file mode 100644
index 0000000..ae33603
--- /dev/null
+++ b/dojo/tests/sie/all.js
@@ -0,0 +1,22 @@
+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
new file mode 100644
index 0000000..d1c3441
--- /dev/null
+++ b/dojo/tests/sie/smoke-v15.html
@@ -0,0 +1,29 @@
+<!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
new file mode 100644
index 0000000..1b20af7
--- /dev/null
+++ b/dojo/tests/sie/smoke.html
@@ -0,0 +1,31 @@
+<!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/smoke-dojo-sie.html b/dojo/tests/smoke-dojo-sie.html
new file mode 100644
index 0000000..5649141
--- /dev/null
+++ b/dojo/tests/smoke-dojo-sie.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+	"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>Minimum Dojo Application</title>
+		<script type="text/javascript" src="../dojo-sie.js"></script>
+	</head>
+	<body>
+    <p>hello, world</p>
+	</body>
+</html>
diff --git a/dojo/tests/store.js b/dojo/tests/store.js
new file mode 100644
index 0000000..a8cf179
--- /dev/null
+++ b/dojo/tests/store.js
@@ -0,0 +1,4 @@
+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) {
+});
+
+
diff --git a/dojo/tests/store/Cache.js b/dojo/tests/store/Cache.js
new file mode 100644
index 0000000..1b2c0ac
--- /dev/null
+++ b/dojo/tests/store/Cache.js
@@ -0,0 +1,83 @@
+dojo.provide("dojo.tests.store.Cache");
+dojo.require("dojo.store.Memory");
+dojo.require("dojo.store.Cache");
+(function(){
+	var masterStore = new dojo.store.Memory({
+		data: [
+			{id: 1, name: "one", prime: false},
+			{id: 2, name: "two", even: true, prime: true},
+			{id: 3, name: "three", prime: true},
+			{id: 4, name: "four", even: true, prime: false},
+			{id: 5, name: "five", prime: true}
+		]
+	});
+	var cachingStore = new dojo.store.Memory();
+	var options = {};
+	var store = dojo.store.Cache(masterStore, cachingStore, options);
+	tests.register("dojo.tests.store.Cache",
+		[
+			function testGet(t){
+				t.is(store.get(1).name, "one");
+				t.is(cachingStore.get(1).name, "one"); // second one should be cached
+				t.is(store.get(1).name, "one");
+				t.is(store.get(4).name, "four");
+				t.is(cachingStore.get(4).name, "four");
+				t.is(store.get(4).name, "four");
+			},
+			function testQuery(t){
+				options.isLoaded = function(){ return false;};
+				t.is(store.query({prime: true}).length, 3);
+				t.is(store.query({even: true})[1].name, "four");
+				t.is(cachingStore.get(3), undefined);
+				options.isLoaded = function(){ return true;};
+				t.is(store.query({prime: true}).length, 3);
+				t.is(cachingStore.get(3).name, "three");
+			},
+			function testQueryWithSort(t){
+				t.is(store.query({prime: true}, {sort:[{attribute:"name"}]}).length, 3);
+				t.is(store.query({even: true}, {sort:[{attribute:"name"}]})[1].name, "two");
+			},
+			function testPutUpdate(t){
+				var four = store.get(4);
+				four.square = true;
+				store.put(four);
+				four = store.get(4);
+				t.t(four.square);
+				four = cachingStore.get(4);
+				t.t(four.square);
+				four = masterStore.get(4);
+				t.t(four.square);
+			},
+			function testPutNew(t){
+				store.put({
+					id: 6,
+					perfect: true
+				});
+				t.t(store.get(6).perfect);
+				t.t(cachingStore.get(6).perfect);
+				t.t(masterStore.get(6).perfect);
+			},
+			function testAddDuplicate(t){
+				var threw;
+				try{
+					store.add({
+						id: 6,
+						perfect: true
+					});
+				}catch(e){
+					threw = true;
+				}
+				t.t(threw);
+			},
+			function testAddNew(t){
+				store.add({
+					id: 7,
+					prime: true
+				});
+				t.t(store.get(7).prime);
+				t.t(cachingStore.get(7).prime);
+				t.t(masterStore.get(7).prime);
+			}
+		]
+	);
+})();
diff --git a/dojo/tests/store/DataStore.js b/dojo/tests/store/DataStore.js
new file mode 100644
index 0000000..5bf43bb
--- /dev/null
+++ b/dojo/tests/store/DataStore.js
@@ -0,0 +1,54 @@
+dojo.provide("dojo.tests.store.DataStore");
+dojo.require("dojo.store.DataStore");
+dojo.require("dojo.data.ItemFileWriteStore")
+var temp = function(){
+	var two, four;
+	var dataStore = new dojo.data.ItemFileWriteStore({data:{
+		items: [
+			{id: 1, name: "one", prime: false},
+			two = {id: 2, name: "two", even: true, prime: true},
+			{id: 3, name: "three", prime: true},
+			four = {id: 4, name: "four", even: true, prime: false},
+			{id: 5, name: "five", prime: true}
+		],
+		identifier:"id"
+	}});
+	dataStore.fetchItemByIdentity({identity:null});
+	var store = new dojo.store.DataStore({store:dataStore});
+	tests.register("dojo.tests.store.DataStore",
+		[
+			function testGet(t){
+				t.is(store.get(1).name, "one");
+				t.is(store.get(4).name, "four");
+				t.t(store.get(5).prime);
+			},
+			function testQuery(t){
+				store.query({prime: true}).then(function(results){
+					t.is(results.length, 3);
+				});
+				store.query({even: true}).map(function(object){
+					for(var i in object){
+						t.is(object[i], (object.id == 2 ? two : four)[i]);
+					}
+				}).then(function(results){
+					t.is(results[1].name, "four");
+				});
+			},
+			function testPutUpdate(t){
+				var four = store.get(4);
+				four.square = true;
+				store.put(four);
+				four = store.get(4);
+				t.t(four.square);
+			},
+			function testPutNew(t){
+				store.put({
+					id: 6,
+					perfect: true
+				});
+				t.t(store.get(6).perfect);
+			}
+		]
+	);
+};
+temp();
diff --git a/dojo/tests/store/JsonRest.js b/dojo/tests/store/JsonRest.js
new file mode 100644
index 0000000..df28b90
--- /dev/null
+++ b/dojo/tests/store/JsonRest.js
@@ -0,0 +1,40 @@
+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",
+		[
+			function testGet(t){
+				var d = new doh.Deferred();
+				store.get("node1.1").then(function(object){
+					t.is(object.name, "node1.1");
+					t.is(object.someProperty, "somePropertyA1");
+					d.callback(true);
+				});
+				return d;
+			},
+			function testQuery(t){
+				var d = new doh.Deferred();
+				store.query("treeTestRoot").then(function(results){
+					var object = results[0];
+					t.is(object.name, "node1");
+					t.is(object.someProperty, "somePropertyA");
+					d.callback(true);
+				});
+				return d;
+			},
+			function testQueryIterative(t){
+				var d = new doh.Deferred();
+				var i = 0;
+				store.query("treeTestRoot").forEach(function(object){
+					i++;
+					console.log(i);
+					t.is(object.name, "node" + i);
+				}).then(function(){
+					d.callback(true);
+				});
+				return d;
+			}
+		]
+	);
+})();
diff --git a/dojo/tests/store/Memory.js b/dojo/tests/store/Memory.js
new file mode 100644
index 0000000..38f8087
--- /dev/null
+++ b/dojo/tests/store/Memory.js
@@ -0,0 +1,99 @@
+dojo.provide("dojo.tests.store.Memory");
+dojo.require("dojo.store.Memory");
+(function(){
+	var store = new dojo.store.Memory({
+		data: [
+			{id: 1, name: "one", prime: false},
+			{id: 2, name: "two", even: true, prime: true},
+			{id: 3, name: "three", prime: true},
+			{id: 4, name: "four", even: true, prime: false},
+			{id: 5, name: "five", prime: true}
+		]
+	});
+	tests.register("dojo.tests.store.Memory",
+		[
+			function testGet(t){
+				t.is(store.get(1).name, "one");
+				t.is(store.get(4).name, "four");
+				t.t(store.get(5).prime);
+			},
+			function testQuery(t){
+				t.is(store.query({prime: true}).length, 3);
+				t.is(store.query({even: true})[1].name, "four");
+			},
+			function testQueryWithString(t){
+				t.is(store.query({name: "two"}).length, 1);
+				t.is(store.query({name: "two"})[0].name, "two");
+			},
+			function testQueryWithRegExp(t){
+				t.is(store.query({name: /^t/}).length, 2);
+				t.is(store.query({name: /^t/})[1].name, "three");
+				t.is(store.query({name: /^o/}).length, 1);
+				t.is(store.query({name: /o/}).length, 3);
+			},
+			function testQueryWithSort(t){
+				t.is(store.query({prime: true}, {sort:[{attribute:"name"}]}).length, 3);
+				t.is(store.query({even: true}, {sort:[{attribute:"name"}]})[1].name, "two");
+			},
+			function testQueryWithPaging(t){
+				t.is(store.query({prime: true}, {start: 1, count: 1}).length, 1);
+				t.is(store.query({even: true}, {start: 1, count: 1})[0].name, "four");
+			},
+			function testPutUpdate(t){
+				var four = store.get(4);
+				four.square = true;
+				store.put(four);
+				four = store.get(4);
+				t.t(four.square);
+			},
+			function testPutNew(t){
+				store.put({
+					id: 6,
+					perfect: true
+				});
+				t.t(store.get(6).perfect);
+			},
+			function testAddDuplicate(t){
+				var threw;
+				try{
+					store.add({
+						id: 6,
+						perfect: true
+					});
+				}catch(e){
+					threw = true;
+				}
+				t.t(threw);
+			},
+			function testAddNew(t){
+				store.add({
+					id: 7,
+					prime: true
+				});
+				t.t(store.get(7).prime);
+			},
+			function testRemove(t){
+				store.remove(7);
+				t.is(store.get(7), undefined);
+			},
+			function testQueryAfterChanges(t){
+				t.is(store.query({prime: true}).length, 3);
+				t.is(store.query({perfect: true}).length, 1);
+			},
+			function testIFRSStyleData(t){
+				var anotherStore = new dojo.store.Memory({
+					data: {
+						items:[
+							{name: "one", prime: false},
+							{name: "two", even: true, prime: true},
+							{name: "three", prime: true}
+						],
+						identifier: "name"
+					}
+				});
+				t.is(anotherStore.get("one").name,"one");
+				t.is(anotherStore.query({name:"one"})[0].name,"one");
+			}
+		]
+	);
+})();
diff --git a/dojo/tests/store/Observable.js b/dojo/tests/store/Observable.js
new file mode 100644
index 0000000..f287a5a
--- /dev/null
+++ b/dojo/tests/store/Observable.js
@@ -0,0 +1,92 @@
+dojo.provide("dojo.tests.store.Observable");
+dojo.require("dojo.store.Memory");
+dojo.require("dojo.store.Observable");
+(function(){
+	var store = dojo.store.Observable(new dojo.store.Memory({
+		data: [
+			{id: 1, name: "one", prime: false},
+			{id: 2, name: "two", even: true, prime: true},
+			{id: 3, name: "three", prime: true},
+			{id: 4, name: "four", even: true, prime: false},
+			{id: 5, name: "five", prime: true}
+		]
+	}));
+	tests.register("dojo.tests.store.Observable",
+		[
+			function testGet(t){
+				t.is(store.get(1).name, "one");
+				t.is(store.get(4).name, "four");
+				t.t(store.get(5).prime);
+			},
+			function testQuery(t){
+				var results = store.query({prime: true});
+				t.is(results.length, 3);
+				var changes = [], secondChanges = [];
+				var observer = results.observe(function(object, previousIndex, newIndex){
+					changes.push({previousIndex:previousIndex, newIndex:newIndex, object:object});
+				});
+				var secondObserver = results.observe(function(object, previousIndex, newIndex){
+					secondChanges.push({previousIndex:previousIndex, newIndex:newIndex, object:object});
+				});
+				var expectedChanges = [];
+				var two = results[0];
+				two.prime = false;
+				store.put(two); // should remove it from the array
+				t.is(results.length, 2);
+				expectedChanges.push({
+						previousIndex: 0,
+						newIndex: -1,
+						object:{
+							id: 2,
+							name: "two",
+							even: true,
+							prime: false
+						}
+					});
+				secondObserver.cancel();
+				var one = store.get(1);
+				one.prime = true;
+				store.put(one); // should add it
+				expectedChanges.push({
+						previousIndex: -1,
+						"newIndex":2,
+						object:{
+							id: 1,
+							name: "one",
+							prime: true
+						}
+					});
+				t.is(results.length, 3);
+				store.add({// shouldn't be added
+					id:6, name:"six"
+				});
+				t.is(results.length, 3);
+				store.add({// should be added
+					id:7, name:"seven", prime:true
+				});
+				t.is(results.length, 4);
+				
+				expectedChanges.push({
+						previousIndex: -1,
+						"newIndex":3,
+						"object":{
+							id:7, name:"seven", prime:true
+						}
+					});
+				store.remove(3);
+				expectedChanges.push({
+						"previousIndex":0,
+						newIndex: -1,
+						object: {id: 3, name: "three", prime: true}
+					});
+				t.is(results.length, 3);
+				
+				observer.cancel(); // shouldn't get any more calls
+				store.add({// should not be added
+					id:11, name:"eleven", prime:true
+				});
+				t.is(changes, expectedChanges);
+			}
+		]
+	);
+})();
diff --git a/dojo/tests/store/node1.1 b/dojo/tests/store/node1.1
new file mode 100644
index 0000000..21d1923
--- /dev/null
+++ b/dojo/tests/store/node1.1
@@ -0,0 +1,4 @@
+{ id: 'node1.1',name:'node1.1', someProperty:'somePropertyA1', children: [
+			{ $ref: 'node1.1.1', name: 'node1.1.1'},
+			{ $ref: 'node1.1.2', name: 'node1.1.2'}
+]}
diff --git a/dojo/tests/store/node1.2 b/dojo/tests/store/node1.2
new file mode 100644
index 0000000..b221fab
--- /dev/null
+++ b/dojo/tests/store/node1.2
@@ -0,0 +1 @@
+{ id: 'node1.2',name:'node1.2', someProperty:'somePropertyA2'}
diff --git a/dojo/tests/store/runTests.html b/dojo/tests/store/runTests.html
new file mode 100644
index 0000000..7fd9d51
--- /dev/null
+++ b/dojo/tests/store/runTests.html
@@ -0,0 +1,9 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+    <head>
+    <title>Dojo Store D.O.H. Unit Test Runner</title>
+    <meta http-equiv="REFRESH" content="0;url=../../../util/doh/runner.html?testModule=dojo.tests.store"></HEAD>
+    <BODY>
+        Redirecting to D.O.H runner.
+    </BODY>
+</HTML> 
diff --git a/dojo/tests/store/treeTestRoot b/dojo/tests/store/treeTestRoot
new file mode 100644
index 0000000..4a9adf1
--- /dev/null
+++ b/dojo/tests/store/treeTestRoot
@@ -0,0 +1,10 @@
+[ 
+	{ id: 'node1', name:'node1', someProperty:'somePropertyA', children:[
+			{ $ref: 'node1.1', name: 'node1.1', children: true},
+			{ $ref: 'node1.2', name: 'node1.2'}
+	]},
+	{ id: 'node2', name:'node2', someProperty:'somePropertyB'},
+	{ id: 'node3', name:'node3', someProperty:'somePropertyC'},
+	{ id: 'node4', name:'node4', someProperty:'somePropertyA'},
+	{ id: 'node5', name:'node5', someProperty:'somePropertyB'}
+]
diff --git a/dojo/tests/string.js b/dojo/tests/string.js
index bb69939..0d4b423 100644
--- a/dojo/tests/string.js
+++ b/dojo/tests/string.js
@@ -2,7 +2,7 @@ dojo.provide("tests.string");
 
 dojo.require("dojo.string");
 
-tests.register("tests.string", 
+tests.register("tests.string",
 	[
 		function test_string_pad(t){
 			t.is("00001", dojo.string.pad("1", 5));
@@ -11,13 +11,13 @@ tests.register("tests.string",
 		},
 
 		function test_string_substitute(t){
-			t.is("File 'foo.html' is not found in directory '/temp'.", 
+			t.is("File 'foo.html' is not found in directory '/temp'.",
 				dojo.string.substitute(
-					"File '${0}' is not found in directory '${1}'.", 
+					"File '${0}' is not found in directory '${1}'.",
 					["foo.html","/temp"]
 				)
 			);
-			t.is("File 'foo.html' is not found in directory '/temp'.", 
+			t.is("File 'foo.html' is not found in directory '/temp'.",
 				dojo.string.substitute(
 					"File '${name}' is not found in directory '${info.dir}'.",
 					{
@@ -45,7 +45,7 @@ tests.register("tests.string",
 				getPrefix: getPrefix
 			};
 
-			t.is("file 'foo.html' is not found in directory '/temp'.", 
+			t.is("file 'foo.html' is not found in directory '/temp'.",
 				dojo.string.substitute(
 					"${0} is not found in ${1}.",
 					["foo.html","/temp"],
@@ -53,7 +53,7 @@ tests.register("tests.string",
 				)
 			);
 
-			t.is("...file 'foo.html' is not found in ...directory '/temp'.", 
+			t.is("...file 'foo.html' is not found in ...directory '/temp'.",
 				dojo.string.substitute(
 					"${0} is not found in ${1}.",
 					["foo.html","/temp"],
@@ -63,7 +63,7 @@ tests.register("tests.string",
 		},
 
 		function test_string_substitute_formatter(t){
-			t.is("thinger -- howdy", 
+			t.is("thinger -- howdy",
 				dojo.string.substitute(
 					"${0:postfix}", ["thinger"], null, {
 						postfix: function(value, key){
diff --git a/dojo/tests/window/test_scroll.html b/dojo/tests/window/test_scroll.html
index 4a4d4ba..c5d8fc6 100644
--- a/dojo/tests/window/test_scroll.html
+++ b/dojo/tests/window/test_scroll.html
@@ -1,6 +1,6 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
                 "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html style="overflow-y:scroll;border:0px none;padding:0;margin:0;">
 <head>
         <title>dojo.window.scrollIntoView Test</title>
 
@@ -17,9 +17,22 @@
 		dojo.require("dojo.window");
 
 		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",
 	                [
+				{
+					name: "wait for iframes to load",
+					timeout: 20000,
+					runTest: function(){
+						return loading;
+					}
+				},
 				function checkAttrs(){
 					var body = dojo.body();
 					dojo.window.scrollIntoView(body);
@@ -34,7 +47,7 @@
 				},
 				function test_8284(){
 					var minScroll, maxScroll, fudge=0;
-					if(dojo.isIE){
+					if(dojo.isIE <= 8){
 						minScroll = maxScroll = 11;
 						if(dojo.isIE <= 6){
 							fudge = dojo.byId('8284_quirks').contentWindow.document.body.clientHeight-100; // needed for running inside DOH runner
@@ -44,49 +57,17 @@
 					}
 					generateTestXY('8284_quirks', "0", -maxScroll+fudge, "0", minScroll-fudge);
 					generateTestXY('8284_quirks_rtl', "0", -maxScroll+fudge, "0", minScroll-fudge);
-					if(dojo.isIE >= 8){
-						maxScroll--;
-						minScroll--;
+					if(dojo.isIE == 8){
+						minScroll = maxScroll = 10;
 					}
 					generateTestXY('8284_strict', "0", -maxScroll, "0", minScroll);
 					generateTestXY('8284_loose_rtl', "0", -maxScroll, "0", minScroll);
 				},
 				function test_absContent(){
-					var minScrollX, minScrollY, maxScrollX, maxScrollY;
-					if(dojo.isIE){
-						maxScrollX = -10 - sb;
-						maxScrollY = (dojo.isIE >= 8)? maxScrollX : (-38 - sb);
-					}else{
-						maxScrollX = maxScrollY = -10 - sb;
-					}
-					minScrollX = minScrollY = sb + 10;
-					generateTestXY('absContent_strict', maxScrollX, maxScrollY, minScrollX, minScrollY);
-					if(dojo.isIE < 7){
-						maxScrollX -= (sb & 1); // odd sized sb adds 1 more
-						minScrollX -= (sb & 1); // odd sized sb adds 1 more
-					}
-					if(dojo.isIE == 7){ minScrollX = -90; }
-					if(dojo.isOpera){
-						maxScrollX = 90;
-					}
-					generateTestXY('absContent_loose_rtl', maxScrollX, maxScrollY, minScrollX, minScrollY);
-					if(dojo.isIE){
-						maxScrollX = (dojo.isIE >= 7? -10 : -6) - sb;
-						maxScrollY = (dojo.isIE >= 7? -38 : -34) - sb;
-						minScrollY = minScrollX = -maxScrollX;
-					}else{
-						maxScrollX = maxScrollY = -(sb+10);
-						minScrollX = minScrollY = sb+10;
-					}
-					generateTestXY('absContent_quirks', maxScrollX, maxScrollY, minScrollX, minScrollY);
-					if(dojo.isIE < 8){
-						maxScrollX = (dojo.isIE >= 7 ? -10 : -6) - sb - (sb & 1);
-						minScrollX = "+" + ((dojo.isIE >= 7? 10 : 6) + sb - (sb & 1));
-					}
-					if(dojo.isOpera){
-						maxScrollX = 90;
-					}
-					generateTestXY('absContent_quirks_rtl', maxScrollX, maxScrollY, minScrollX, minScrollY);
+					generateTestXY('absContent_strict', 0, -10, 0, 10);
+					generateTestXY('absContent_loose_rtl', 0, -10, 0, 10);
+					generateTestXY('absContent_quirks', 0, -10, 0, 10);
+					generateTestXY('absContent_quirks_rtl', 0, -10, 0, 10);
 				},
 				function test_fixedNode(){
 					if(!(dojo.isIE <= 6)){
@@ -109,30 +90,20 @@
 					}
 				},
 				function test_7036_8665(){
-					var maxScroll;
-					var minScroll;
+					var maxScroll = 39;
+					var minScroll = 38;
 					if(dojo.isIE <= 7){
 						maxScroll = 54;
 						minScroll = 39;
-					}else{
-						maxScroll = 39;
-						minScroll = 38;
 					}
 					generateTest('7036_8665_strict', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
-					if(dojo.isIE){
+					generateTest('7036_8665_loose_rtl', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
+					if(dojo.isIE == 8){
 						maxScroll = 54;
 						minScroll = 39;
-					}else{
-						maxScroll = 39;
-						minScroll = 38;
 					}
 					generateTest('7036_8665_quirks', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
 					generateTest('7036_8665_quirks_rtl', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
-					if(dojo.isIE >= 8){
-						maxScroll = 39;
-						minScroll = 38;
-					}
-					generateTest('7036_8665_loose_rtl', "(0,-"+maxScroll+")(0,-1)", "(0,+"+minScroll+")(0,+1)");
 				},
 				function test_innerNoScrollBars(){
 					var scroll;
@@ -144,7 +115,7 @@
 						scroll = 39;
 					}
 					generateTestXY('innerNoScrollBars_strict', scroll, -29, scroll, -29);
-					if(dojo.isIE){
+					if(dojo.isIE <= 8){
 						scroll = -38;
 					}
 					generateTestXY('innerNoScrollBars_quirks', scroll, -29, scroll, -29);
@@ -160,7 +131,7 @@
 						scroll = 39;
 					}
 					generateTestXY('innerNoScrollBars_loose_rtl', scroll, -29, scroll, -29);
-					if(dojo.isIE){
+					if(dojo.isIE <= 8){
 						scroll = -38;
 					}
 					generateTestXY('innerNoScrollBars_quirks_rtl', scroll, -29, scroll, -29);
@@ -171,12 +142,6 @@
 					generateTest('noScrollBars_loose_rtl', "(0,0)", "(0,0)");
 					generateTest('noScrollBars_quirks_rtl', "(0,0)", "(0,0)");
 				},
-				function test_bottomFloated(){
-					generateTest('bottomFloated_strict', "(+0,-0)", "(+0,-0)");
-					generateTest('bottomFloated_quirks', "(+0,-0)", "(+0,-0)");
-					generateTest('bottomFloated_loose_rtl', "("+(dojo.isOpera? -1 : (((dojo.isIE >= 8 || dojo.isWebKit)? "+" : "-")+0))+",-0)", "("+(dojo.isOpera? (sb+20) : (((dojo.isIE < 8 || dojo.isMoz)?"-":"+")+0))+",-0)");
-					generateTest('bottomFloated_quirks_rtl', "("+(dojo.isOpera? -1 : ((dojo.isWebKit? "+" : "-")+0))+",-0)", "("+(dojo.isOpera? (sb+20) : (((dojo.isIE || dojo.isMoz)?"-":"+")+0))+",-0)");
-				},
 				function test_table(){
 					var minScroll, maxScroll;
 					minScroll = "(0,+15)";
@@ -192,7 +157,7 @@
 					generateTest('table_quirks_rtl', maxScroll, minScroll);
 				},
 				function test_innerScrollbars(){
-					var scroll = sb - 5;
+					var scroll = innerScrollBarSize - 5;
 					generateTestXY('innerScrollbars_strict', -scroll, -scroll, scroll, scroll);
 					generateTestXY('innerScrollbars_loose_rtl', -scroll, -scroll, dojo.isIE == 7 ? -25 : scroll, scroll);
 					generateTestXY('innerScrollbars_quirks', -scroll, -scroll, scroll, scroll);
@@ -211,38 +176,40 @@
 				function test_tooBig(){
 					var fudge = 0;
 					if(dojo.isIE <= 6){
-						fudge = dojo.byId('tooBig_quirks').contentWindow.document.body.clientHeight-100+sb; // needed for running inside DOH runner
+						fudge = dojo.byId('tooBig_quirks').contentWindow.document.body.clientHeight-100+innerScrollBarSize; // needed for running inside DOH runner
 					}
 					var minScroll, maxScroll;
-					generateTestXY('tooBig_strict', sb+10,sb+20, 1,1);
-					generateTestXY('tooBig_quirks', sb+10-fudge,sb+20-fudge, 1,1);
-					if(dojo.isIE <= 7 || dojo.isMoz){
+					generateTestXY('tooBig_strict', outerScrollBarSize+10,outerScrollBarSize+20, 1,1);
+					generateTestXY('tooBig_quirks', outerScrollBarSize+10-fudge,outerScrollBarSize+20-fudge, 1,1);
+					if(dojo.isIE <= 7 || dojo.isMoz || dojo.isChrome){
 						maxScroll = -1;
 					}else if(dojo.isIE){
 						maxScroll = +20;
 					}else if(dojo.isOpera){
 						maxScroll = -90;
 					}else{
-						maxScroll = sb+10;
+						maxScroll = outerScrollBarSize+10;
 					}
-					if(dojo.isIE <= 7 || dojo.isMoz){
+					if(dojo.isIE <= 7 || dojo.isMoz || dojo.isChrome){
 						minScroll = -20;
 					}else if(dojo.isOpera){
-						minScroll = 80 + sb;
+						minScroll = 80 + outerScrollBarSize;
 					}else{
 						minScroll = 1;
 					}
-					generateTestXY('tooBig_loose_rtl', maxScroll,sb+20, minScroll,1);
+					generateTestXY('tooBig_loose_rtl', maxScroll,outerScrollBarSize+20, minScroll,1);
 					if(dojo.isIE >= 8){
 						maxScroll = -1;
+					}
+					if(dojo.isIE == 8){
 						minScroll = -20;
 					}
-					generateTestXY('tooBig_quirks_rtl', maxScroll,sb+20-fudge, minScroll,1);
+					generateTestXY('tooBig_quirks_rtl', maxScroll,outerScrollBarSize+20-fudge, minScroll,1);
 				},
 				function test_htmlPadding(){
 					var fudge = 0;
 					if(dojo.isIE <= 6){
-						fudge = dojo.byId('tooBig_quirks').contentWindow.document.body.clientHeight-100+sb; // needed for running inside DOH runner
+						fudge = dojo.byId('tooBig_quirks').contentWindow.document.body.clientHeight-100+innerScrollBarSize; // needed for running inside DOH runner
 					}
 					var minScroll, maxScroll;
 					if(dojo.isIE <= 7){
@@ -252,7 +219,7 @@
 					}
 					generateTest('htmlPadding_strict', "(0,-"+maxScroll+")", "(0,+"+minScroll+")");
 					generateTest('htmlPadding_loose_rtl', "(0,-"+maxScroll+")", "(0,+"+minScroll+")");
-					if(dojo.isIE){
+					if(dojo.isIE <= 8){
 						maxScroll = minScroll = 34;
 					}
 					generateTest('htmlPadding_quirks', "(0,-"+(maxScroll-fudge)+")", "(0,+"+(minScroll-fudge)+")");
@@ -262,22 +229,23 @@
 		        doh.run();
 		});
 		function generateTest(id, maxVal, minVal){
-			var expectedScroll, actualScroll, compare = usingNative? "isNot" : "is";
+			var compare = usingNative? "isNot" : "is";
 			with(dojo.byId(id)){
 				scrollMin();
 				scrollMax();
 				scrollIntoView();
-				actualScroll = getScroll();
-				expectedScroll = usingNative? "(-1,-1)" : maxVal;
-				doh[compare](expectedScroll, actualScroll, id+" max failed");
+				var maxActualScroll = getScroll();
+				var maxExpectedScroll = usingNative? "(-1,-1)" : maxVal;
 				scrollIntoView(); // make sure the value sticks
-				actualScroll = getScroll();
-				doh[compare](expectedScroll, actualScroll, id+" repeat max failed");
+				var repMaxActualScroll = getScroll();
 				scrollMin();
 				scrollIntoView();
-				actualScroll = getScroll();
-				expectedScroll = usingNative? "(+1,+1)" : minVal;
-				doh[compare](expectedScroll, actualScroll, id+" min failed");
+				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){
@@ -296,10 +264,6 @@
 <tr><td><div id="nonscroll"  style="width:100px;overflow:hidden;border:1px solid blue;"> </div></td></tr>
 <tr><td><div id="withscroll" style="width:100px;overflow-x:hidden;overflow-y:scroll;border:1px solid red;"> </div></td></tr>
 </table>
-<script type="text/javascript">
-sb = dojo.byId("nonscroll").clientWidth - dojo.byId("withscroll").clientWidth;
-console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
-</script>
 <!--	The test templates are below -->
 <fieldset>
 <label for="8249">Scrollable parent != offsetParent:</label>
@@ -331,11 +295,9 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 <fieldset>
 <label for="absContent">Absolute-positioned content:</label>
 <div type="testIframe" id="absContent">
-	<iframestyle>INPUT { L_left:90px; R_right:90px; WKR_FF2R_left:90px; WKR_FF2R_right:auto; }
-		HTML { overflow:scroll !important; /*IE6*/ }</iframestyle>
-	<hr style="height:100px;width:200px;float:left;"/>
-	<hr style="height:100px;width:200px;float:right;"/>
-	<input id=it style="position:absolute;top:90px;">
+	<iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle>
+	<div style="height:200px;width:20px;"></div>
+	<input id=it style="position:absolute;left:10px;top:90px;">
 </div>
 </fieldset>
 <fieldset>
@@ -372,8 +334,9 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 <fieldset>
 <label for="innerNoScrollBars">Complex scrollable inner content, no scrollbars:</label>
 <div type="testIframe" id="innerNoScrollBars">
-	<iframestyle>DIV { width:20px; IEQ_width:26px; height:20px; IEQ_height:24px; }</iframestyle>
-	<div style="overflow:hidden; margin:10px;border:1px solid red;border-width:1px 2px 3px 4px;"
+	<iframestyle>BODY { overflow:hidden !important; /*IE9*/ }</iframestyle>
+	<fieldset style="overflow:hidden; margin:10px;border:1px solid red;border-width:1px 2px 3px 4px;display:inline;"
+	><div style="overflow:hidden; width:20px;height:20px;"
 		><fieldset style="width:59px;overflow:visible;"
 			><input style="background-color:green;height:15px;float:left;"
 			><nobr style="margin:7px;padding:3px;border:5px solid pink;overflow:visible;display:block;width:90px;float:left;"
@@ -383,25 +346,21 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 			></nobr
 			><input style="background-color:cyan;height:10px;float:left;"
 		></fieldset
-	></div>
+	></div
+	></fieldset>
 </div>
 </fieldset>
 <fieldset>
 <label for="noScrollBars">Nothing to do:</label>
 <div type="testIframe" id="noScrollBars">
+	<iframestyle>
+		HTML { overflow:hidden !important; /*IE6*/ }
+		BODY { overflow:hidden !important; /*IE9*/ }
+	</iframestyle>
 	<input id=it style="margin:25px;">
 </div>
 </fieldset>
 <fieldset>
-<label for="bottomFloated">Bottom, floated:</label>
-<div type="testIframe" id="bottomFloated">
-	<iframestyle>INPUT { L_float:left; R_float:right; WKR_FF2R_float:left; }</iframestyle>
-	<hr style="float:left;height:50px;"/>
-	<hr style="float:right;height:50px;"/>
-	<input id=it style="clear:both;">
-</div>
-</fieldset>
-<fieldset>
 <label for="table">Table:</label>
 <div type="testIframe" id="table">
 	<iframestyle>HTML { overflow-x:hidden !important; /*IE6*/ }</iframestyle>
@@ -474,7 +433,7 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 			n._scrollMinY = n.scrollTop;
 			n._scrollMinX = n.scrollLeft;
 			n.scrollTop++;
-			if(((n._scrollMaxX||0)-n._scrollMinX) == sb && (n.scrollWidth <= n.clientWidth || n.scrollWidth <= n.offsetWidth)){ // ignore fake scrolls
+			if(((n._scrollMaxX||0)-n._scrollMinX) == innerScrollBarSize && (n.scrollWidth <= n.clientWidth || n.scrollWidth <= n.offsetWidth)){ // ignore fake scrolls
 			}else if((n._scrollMaxX||0) > n._scrollMinX){
 				n.scrollLeft++;
 			}
@@ -490,7 +449,7 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 			n._scrollMaxY = n.scrollTop;
 			n._scrollMaxX = n.scrollLeft;
 			n.scrollTop--;
-			if((n._scrollMaxX-(n._scrollMinX||0)) == sb && (n.scrollWidth <= n.clientWidth || n.scrollWidth <= n.offsetWidth)){
+			if((n._scrollMaxX-(n._scrollMinX||0)) == innerScrollBarSize && (n.scrollWidth <= n.clientWidth || n.scrollWidth <= n.offsetWidth)){
 				n._scrollMaxX = n.scrollLeft = (n._scrollMinX || 0); // ignore fake scrolls
 			}else{
 				n.scrollLeft--;
@@ -523,6 +482,9 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 		_scrollIntoView(win);
 		alert(_getScroll(win));
 	}
+	function iframeLoaded(){
+		if(--count == 0){ loading.callback(true); }
+	}
 	function initIframeMethods(iframeWin, parentWin){
 		iframeWin.frameElement.findInput = function(){ return parentWin._findInput(iframeWin) };
 		iframeWin.frameElement.scrollMin = function(){ parentWin._scrollMin(iframeWin) };
@@ -583,13 +545,15 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 				'HR { width:120px;height:1px;visibility:hidden;display:block; }\n'+
 				style+
 			'<\/STYLE>'+
+		'<\/HEAD>'+
+		'<BODY BGCOLOR=#ffffff>'+
+			content+
 			'<SCRIPT type=text/javascript>'+
-				'var win = frameElement.ownerDocument.defaultView||frameElement.document.parentWindow;'+
+				'win=frameElement.ownerDocument.defaultView||frameElement.document.parentWindow;'+
 				'win.initIframeMethods(window, win);'+
+				'win.iframeLoaded();'+
+				'document.body.onclick=frameElement.onClick;'+
 			'<\/SCRIPT>'+
-		'<\/HEAD>'+
-		'<BODY BGCOLOR=#ffffff onclick=\'frameElement.onClick()\'>'+
-			content+
 		'<\/BODY>'+
 		'<\/HTML>"';
 		return iframeSrc;
@@ -604,19 +568,24 @@ console.debug('!!!!!!!!!!!! scrollbar size = ' + sb);
 		dojo.style(container, "cssText", "display:inline;border:1px ridge gray;padding:0px;margin:0px;background-color:"+color+";text-align:"+(rtl?"right;":"left;"));
 		container.appendChild(document.createTextNode(text));
 		var iframe = document.createElement('iframe');
-		if(dojo.isOpera){ iframe.setAttribute('src', iframeSrc); }
+		iframe.setAttribute('src', iframeSrc);
 		iframe.setAttribute('frameBorder', "0");
 		iframe.setAttribute('scrolling', "auto");
 		iframe.setAttribute('allowTransparency', "true");
 		iframe.setAttribute('id', id + idSuffix);
 		iframe.setAttribute('name', id + idSuffix);
 		iframe.className = className;
-		dojo.style(iframe, "cssText", "display:block;border:2px solid "+color+";background-color:transparent;margin:0px;padding:3px;"+style);
+		dojo.style(iframe, "cssText", "visibility:hidden;display:block;border:2px solid "+color+";background-color:transparent;margin:0px;padding:3px;"+style);
 		container.appendChild(iframe);
 		srcNode.appendChild(container);
-		if(!dojo.isOpera){ iframe.setAttribute('src', iframeSrc); }
+		var src = iframe.getAttribute("src");
+		if(!src || src.indexOf("javascript") == -1){
+			// set it again if it didn't stick the first time: esp. older Opera and WebKit
+			setTimeout(function(){ iframe.setAttribute('src', iframeSrc); }, 0);
+		}
 	}
 	var testIframes = dojo.query('DIV[type="testIframe"]');
+	count = testIframes.length * 4;
 	for(var i=0; i < testIframes.length; i++){
 		var srcNode = testIframes[i];
 		var content = srcNode.innerHTML || '';
diff --git a/dojo/uacss.js b/dojo/uacss.js
index f5da940..811ce44 100644
--- a/dojo/uacss.js
+++ b/dojo/uacss.js
@@ -1,4 +1,4 @@
-dojo.provide("dojo.uacss");
+define("dojo/uacss", ["dojo"], function(dojo) {
 
 (function(){
 	// summary:
@@ -24,6 +24,7 @@ dojo.provide("dojo.uacss");
 			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,
 
@@ -52,7 +53,7 @@ dojo.provide("dojo.uacss");
 	html.className = d.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).  
+	// 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()){
@@ -61,3 +62,6 @@ dojo.provide("dojo.uacss");
 		}
 	});
 })();
+
+  return dojo;
+});
diff --git a/dojo/window.js b/dojo/window.js
index e2c498b..97cc3d5 100644
--- a/dojo/window.js
+++ b/dojo/window.js
@@ -1,4 +1,5 @@
-dojo.provide("dojo.window");
+define("dojo/window", ["dojo"], function(dojo) {
+dojo.getObject("window", true, dojo);
 
 dojo.window.getBox = function(){
 	// summary:
@@ -53,7 +54,9 @@ dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 			return;
 		}
 		var backCompat = doc.compatMode == 'BackCompat',
-			clientAreaRoot = backCompat? body : html,
+			clientAreaRoot = (isIE >= 9 && node.ownerDocument.parentWindow.frameElement)
+				? ((html.clientHeight > 0 && html.clientWidth > 0 && (body.clientHeight == 0 || body.clientWidth == 0 || body.clientHeight > html.clientHeight || body.clientWidth > html.clientWidth)) ? html : body)
+				: (backCompat ? body : html),
 			scrollRoot = isWK ? body : clientAreaRoot,
 			rootWidth = clientAreaRoot.clientWidth,
 			rootHeight = clientAreaRoot.clientHeight,
@@ -78,14 +81,11 @@ dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 			}else{
 				var pb = dojo._getPadBorderExtents(el);
 				elPos.w -= pb.w; elPos.h -= pb.h; elPos.x += pb.l; elPos.y += pb.t;
-			}
-	
-			if(el != scrollRoot){ // body, html sizes already have the scrollbar removed
 				var clientSize = el.clientWidth,
 					scrollBarSize = elPos.w - clientSize;
 				if(clientSize > 0 && scrollBarSize > 0){
 					elPos.w = clientSize;
-					if(isIE && rtl){ elPos.x += scrollBarSize; }
+					elPos.x += (rtl && (isIE || el.clientLeft > pb.l/*Chrome*/)) ? scrollBarSize : 0;
 				}
 				clientSize = el.clientHeight;
 				scrollBarSize = elPos.h - clientSize;
@@ -114,8 +114,9 @@ dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 				bot = t + nodePos.h - elPos.h; // beyond bottom: > 0
 			if(r * l > 0){
 				var s = Math[l < 0? "max" : "min"](l, r);
+				if(rtl && ((isIE == 8 && !backCompat) || isIE >= 9)){ s = -s; }
 				nodePos.x += el.scrollLeft;
-				el.scrollLeft += (isIE >= 8 && !backCompat && rtl)? -s : s;
+				el.scrollLeft += s;
 				nodePos.x -= el.scrollLeft;
 			}
 			if(bot * t > 0){
@@ -124,9 +125,12 @@ dojo.window.scrollIntoView = function(/*DomNode*/ node, /*Object?*/ pos){
 				nodePos.y -= el.scrollTop;
 			}
 			el = (el != scrollRoot) && !fixedPos && el.parentNode;
-		}	
+		}
 	}catch(error){
 		console.error('scrollIntoView: ' + error);
 		node.scrollIntoView(false);
 	}
 };
+
+return dojo.window;
+});
diff --git a/dojox/LICENSE b/dojox/LICENSE
index 4c93ded..aa6b39f 100644
--- a/dojox/LICENSE
+++ b/dojox/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2010, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/dojox/NodeList/README b/dojox/NodeList/README
new file mode 100755
index 0000000..4f5af63
--- /dev/null
+++ b/dojox/NodeList/README
@@ -0,0 +1,33 @@
+-------------------------------------------------------------------------------
+Project Name:  NodeList
+-------------------------------------------------------------------------------
+Version 0.01
+Release date: 07/20/2010
+-------------------------------------------------------------------------------
+Project state:
+        experimental
+-------------------------------------------------------------------------------
+Credits:
+       Bill Keese
+-------------------------------------------------------------------------------
+Project description
+
+This project is meant to extend NodeList with various methods.   The first is
+delegate(), similar to jQuery's delegate method (http://api.jquery.com/delegate/)
+-------------------------------------------------------------------------------
+Dependencies:
+        dojo base
+		dojo.NodeList-traverse
+-------------------------------------------------------------------------------
+Documentation
+        Documentatation will reside at:
+        http://api.dojotoolkit.org/NodeList
+
+-------------------------------------------------------------------------------
+Installation instructions
+
+Just dojo.require("dojox.NodeList.delegate") in your application and then
+delegate() is added as a method to NodeList.  
+
+-------------------------------------------------------------------------------
+
diff --git a/dojox/NodeList/delegate.js b/dojox/NodeList/delegate.js
new file mode 100644
index 0000000..5c7dfbb
--- /dev/null
+++ b/dojox/NodeList/delegate.js
@@ -0,0 +1,56 @@
+dojo.provide("dojox.NodeList.delegate");
+
+dojo.require("dojo.NodeList-traverse");
+
+dojo.extend(dojo.NodeList, {
+	delegate: function(/*String*/ selector, /*String*/ eventName, /*Function*/ fn){
+		// summary:
+		//		Monitor nodes in this NodeList for [bubbled] events on nodes that match selector.
+		//		Calls fn(evt) for those events, where (inside of fn()), this == the node
+		//		that matches the selector.
+		// description:
+		//		Sets up event handlers that can catch events on any subnodes matching a given selector,
+		//		including nodes created after delegate() has been called.
+		//
+		//		This allows an app to setup a single event handler on a high level node, rather than many
+		//		event handlers on subnodes. For example, one onclick handler for a Tree widget, rather than separate
+		//		handlers for each node in the tree.
+		//		Since setting up many event handlers is expensive, this can increase performance.
+		//
+		//		Note that delegate() will not work for events that don't bubble, like focus.
+		//		onmouseenter/onmouseleave also don't currently work.
+		// selector:
+		//		CSS selector valid to `dojo.query`, like ".foo" or "div > span".  The
+		//		selector is relative to the nodes in this NodeList, not the document root.
+		//		For example myNodeList.delegate("> a", "onclick", ...) will catch events on
+		//		anchor nodes which are (immediate) children of the nodes in myNodeList.
+		// eventName:
+		//		Standard event name used as an argument to `dojo.connect`, like "onclick".
+		// fn:
+		//		Callback function passed the event object, and where this == the node that matches the selector.
+		//		That means that for example, after setting up a handler via
+		//			 dojo.query("body").delegate("fieldset", "onclick", ...)
+		//		clicking on a fieldset or *any nodes inside of a fieldset* will be reported
+		//		as a click on the fieldset itself.
+		// example:
+		//	|	dojo.query("navbar").delegate("a", "onclick", function(evt){
+		//	|			console.log("user clicked anchor ", this.node);
+		//	|	});
+
+		// Possible future tasks:
+		//	- change signature of callback to be fn(node, evt), and then have scope argument
+		//		to delegate(selector, eventName, scope, fn)?
+		//	- support non-bubbling events like focus
+		//	- support onmouseenter/onmouseleave
+		// 	- maybe should return an array of connect handles instead, to allow undelegate()?
+		//	- single node version
+
+		return this.connect(eventName, function(evt){
+			var closest = dojo.query(evt.target).closest(selector, this);
+			if(closest.length){
+				fn.call(closest[0], evt);
+			}
+		}); //dojo.NodeList
+	}
+});
+
diff --git a/dojox/NodeList/tests/delegate.html b/dojox/NodeList/tests/delegate.html
new file mode 100644
index 0000000..ff0d35b
--- /dev/null
+++ b/dojox/NodeList/tests/delegate.html
@@ -0,0 +1,70 @@
+<!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 "../../resources/dojo.css";
+		</style>
+		<script type="text/javascript" 
+			src="../../../dojo/dojo.js" djConfig="isDebug: true, popup: true"></script>
+		<script type="text/javascript">
+			dojo.require("dojox.NodeList.delegate");
+				
+			dojo.addOnLoad(function(){
+				// Monitor onclick events on div.blue nodes, or that bubble up to div.blue nodes
+				dojo.query("div.delegator").delegate("div.blue", "onclick", function(evt){
+					// "this" points to the div.blue node
+					dojo.style(this, "backgroundColor", "#aaf");
+				});
+				dojo.query("div.delegator").delegate("input", "onfocus", function(evt){
+					// "this" points to the input node
+					console.log("bubbled input event");
+					dojo.style(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"
+				dojo.query("div.wrapper").forEach(function(div){
+					for(var i=0; i<4; i++){
+						dojo.place(
+							"<div class=" + (i%2?"blue":"red") + ">" +
+								(i%2 && dojo.hasClass(div, "delegator") ? "click me to turn me blue" : "click will have no effect" )+
+								"<span>" + (i%2  && dojo.hasClass(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/Urchin.js b/dojox/analytics/Urchin.js
index 08e1625..7ebda80 100644
--- a/dojox/analytics/Urchin.js
+++ b/dojox/analytics/Urchin.js
@@ -4,30 +4,30 @@ dojo.provide("dojox.analytics.Urchin");
 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:"" 
+	//		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. 
+	// 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 
+	//		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 
+	//		`acct:` parameter, or via Markup / dojoType and defining a djConfig
 	//		parameter `urchin:`
 	//
-	//		IMPORTANT: 
-	//		This module will not work simultaneously with the core dojox.analytics 
+	//		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
 	//
@@ -35,7 +35,7 @@ dojo.declare("dojox.analytics.Urchin", null, {
 	//	|	// create the tracker programatically:
 	//	|	var tracker = new dojox.analytics.Urchin({ acct:"UA-123456-7" });
 	//
-	//	example: 
+	//	example:
 	//	|	// define the urchin djConfig option:
 	//	|	var djConfig = { urchin: "UA-123456-7" };
 	//	|
@@ -45,7 +45,7 @@ dojo.declare("dojox.analytics.Urchin", null, {
 	//	|	new dojox.analytics.Urchin();
 	//
 	//	example:
-	//	|	// create and define all analytics with one tag. 
+	//	|	// create and define all analytics with one tag.
 	//	|	<div dojoType="dojox.analytics.Urchin" acct="UA-12345-67"></div>
 	//
 	// acct: String
@@ -53,7 +53,7 @@ dojo.declare("dojox.analytics.Urchin", null, {
 	acct: "",
 
 	constructor: function(args){
-		// summary: 
+		// summary:
 		//		Initialize this Urchin instance. Immediately starts the load
 		//		sequence, so defer construction until (ideally) after onLoad and
 		//		potentially widget parsing.
@@ -85,12 +85,12 @@ dojo.declare("dojox.analytics.Urchin", null, {
 	},
 	
 	GAonLoad: function(){
-		// summary: 
+		// summary:
 		//		Stub function to fire when urchin is complete
 		//	description:
-		//		This function is executed when the tracker variable is 
+		//		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 
+		//		no arguments) is called here as well, so remeber to call
 		//		manually if overloading this method.
 		//
 		//	example:
@@ -98,7 +98,7 @@ dojo.declare("dojox.analytics.Urchin", null, {
 		//	after page load (or parsing, if parseOnLoad is true)
 		//	|	dojo.addOnLoad(function(){
 		//	|		new dojox.ananlytics.Urchin({
-		//	|			acct:"UA-12345-67", 
+		//	|			acct:"UA-12345-67",
 		//	|			GAonLoad: function(){
 		//	|				this.trackPageView("/custom-page");
 		//	|			}
@@ -109,8 +109,8 @@ dojo.declare("dojox.analytics.Urchin", null, {
 	},
 	
 	trackPageView: function(/* string */url){
-		// summary: A public API attached to this widget instance, allowing you 
-		//		Ajax-like notification of updates. 
+		// 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"
@@ -121,7 +121,7 @@ dojo.declare("dojox.analytics.Urchin", null, {
 		//	|	dojo.connect(container, "onclick", function(e){
 		//	|		var ref = dojo.attr(e.target, "href");
 		//	|		tracker.trackPageView(ref);
-		//	|		pane.attr("href", ref); 
+		//	|		pane.attr("href", ref);
 		//	|	});
 		
 		this.tracker._trackPageview.apply(this, arguments);
diff --git a/dojox/analytics/_base.js b/dojox/analytics/_base.js
index a22d9b4..6d0effb 100644
--- a/dojox/analytics/_base.js
+++ b/dojox/analytics/_base.js
@@ -27,7 +27,7 @@ dojox.analytics = function(){
 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); 
+		setTimeout(dojo.hitch(this, "checkData"), interval || this.sendInterval);
 	},
 
 	addData: function(dataType, data){
diff --git a/dojox/analytics/plugins/consoleMessages.js b/dojox/analytics/plugins/consoleMessages.js
index 5a47d70..7d21f61 100644
--- a/dojox/analytics/plugins/consoleMessages.js
+++ b/dojox/analytics/plugins/consoleMessages.js
@@ -15,7 +15,7 @@ dojox.analytics.plugins.consoleMessages = new (function(){
 		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]);	
+			console[lvls[i]] = dojo.hitch(this, "addData", lvls[i]);
 		}
 	}
 })();
diff --git a/dojox/analytics/plugins/idle.js b/dojox/analytics/plugins/idle.js
index b8572a8..1917546 100644
--- a/dojox/analytics/plugins/idle.js
+++ b/dojox/analytics/plugins/idle.js
@@ -16,7 +16,7 @@ dojox.analytics.plugins.idle = new (function(){
 	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){ 
+			dojo.connect(dojo.doc,idleResets[i],this, function(e){
 				if (this.idle){
 					this.idle=false;
 					this.addData("isActive");
diff --git a/dojox/analytics/plugins/mouseOver.js b/dojox/analytics/plugins/mouseOver.js
index 53cea9a..ff68020 100644
--- a/dojox/analytics/plugins/mouseOver.js
+++ b/dojox/analytics/plugins/mouseOver.js
@@ -12,18 +12,18 @@ dojox.analytics.plugins.mouseOver = new (function(){
 			dojo.disconnect(this._watchingMouse);
 			delete this._watchingMouse;
 			return;
-		}	
+		}
 		dojo.connect(dojo.doc, "onmousemove", this, "sampleMouse");
 	}
 
 	if (this.watchMouse){
-		dojo.connect(dojo.doc, "onmouseover", this, "toggleWatchMouse");	
+		dojo.connect(dojo.doc, "onmouseover", this, "toggleWatchMouse");
 		dojo.connect(dojo.doc, "onmouseout", this, "toggleWatchMouse");
 	}
 
 	this.sampleMouse=function(e){
 		if (!this._rateLimited){
-			this.addData("sample",this.trimMouseEvent(e));	
+			this.addData("sample",this.trimMouseEvent(e));
 			this._rateLimited=true;
 			setTimeout(dojo.hitch(this, function(){
 				if (this._rateLimited){
@@ -33,7 +33,7 @@ dojox.analytics.plugins.mouseOver = new (function(){
 					delete this._rateLimited;
 				}
 			}), this.mouseSampleDelay);
-		}	
+		}
 		this._lastMouseEvent = e;
 		return e;
 	}
@@ -74,14 +74,14 @@ dojox.analytics.plugins.mouseOver = new (function(){
 						//console.log("Attempting: " + i);
 						var val = e[i];
 						//console.log("val: " +  val); console.log(i + "e of i: " + val);
-						t[i]=val + '';							
+						t[i]=val + '';
 					}
 					break;
-				default: 
+				default:
 					//console.log("Skipping: ", i);
 					break;
 			}
 		}
 		return t;
-	}	
+	}
 })();
diff --git a/dojox/analytics/plugins/window.js b/dojox/analytics/plugins/window.js
index 48033cf..487339b 100644
--- a/dojox/analytics/plugins/window.js
+++ b/dojox/analytics/plugins/window.js
@@ -17,9 +17,9 @@ dojox.analytics.plugins.window = new (function(){
 				switch(i){
 					case "location":
 					case "console":
-						data[i]=window[i];	
+						data[i]=window[i];
 						break;
-					default:	
+					default:
 						break;
 				}
 			}else{
diff --git a/dojox/analytics/profiles/analytics.profile.js b/dojox/analytics/profiles/analytics.profile.js
index a484da2..a2ee2b1 100644
--- a/dojox/analytics/profiles/analytics.profile.js
+++ b/dojox/analytics/profiles/analytics.profile.js
@@ -11,7 +11,7 @@ dependencies = {
 				"dojox.analytics.plugins.mouseClick",
 				"dojox.analytics.plugins.idle"
                         ]
-                }        
+                }
 	],
 
 	prefixes: [
diff --git a/dojox/analytics/profiles/analyticsInBase.profile.js b/dojox/analytics/profiles/analyticsInBase.profile.js
index 22dbbd3..cf3c50e 100644
--- a/dojox/analytics/profiles/analyticsInBase.profile.js
+++ b/dojox/analytics/profiles/analyticsInBase.profile.js
@@ -12,7 +12,7 @@ dependencies = {
 				"dojox.analytics.plugins.mouseClick",
 				"dojox.analytics.plugins.idle"
                         ]
-                }        
+                }
 	],
 
 	prefixes: [
diff --git a/dojox/atom/io/Connection.js b/dojox/atom/io/Connection.js
index f950f5f..5ec6a9a 100755
--- a/dojox/atom/io/Connection.js
+++ b/dojox/atom/io/Connection.js
@@ -8,7 +8,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 	//   deleted, and modified.  It also provides access to the introspection data.
 
 	constructor: function(/* Boolean */sync, /* Boolean */preventCache){
-		// 	summary: 
+		// 	summary:
 		//		initializer
 		this.sync = sync;
 		this.preventCache = preventCache;
@@ -19,83 +19,83 @@ dojo.declare("dojox.atom.io.Connection",null,{
 	alertsEnabled: false, //Flag to turn on alerts instead of throwing errors.
 
 	getFeed: function(/*String*/url, /*Function*/callback, /*Function*/errorCallback, scope){
-		// 	summary: 
+		// 	summary:
 		//		Function to obtain a s specific ATOM feed from a given ATOM Feed url.
-		//	description: 
-		//		This function takes the URL for a specific ATOM feed and returns 
+		//	description:
+		//		This function takes the URL for a specific ATOM feed and returns
 		//		the data from that feed to the caller through the use of a callback
 		//		handler.
 		//
 		// 	url: String
 		//		The URL of the ATOM feed to fetch.
-		//	callback: 
+		//	callback:
 		//		Function
 		//		A function reference that will handle the feed when it has been retrieved.
 		//		The callback should accept two parameters:  The feed object and the original complete DOM object.
 		//	scope: Object
 		//		The scope to use for all callbacks.
 		//
-		//	returns:  
+		//	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);
 	},
 	
 	getService: function(url, callback, errorCallback, scope){
-		//	summary: 
+		//	summary:
 		//		Function to retrieve an introspection document from the given URL.
-		// 	description: 
-		//		This function takes the URL for an ATOM item and feed and returns 
+		// 	description:
+		//		This function takes the URL for an ATOM item and feed and returns
 		//		the introspection document.
 		//
-		//	url: 
+		//	url:
 		//		String
 		//		The URL of the ATOM document to obtain the introspection document of.
-		//	callback: 
-		//		Function 
+		//	callback:
+		//		Function
 		//		A function reference that will handle the introspection document when it has been retrieved.
 		//		The callback should accept two parameters:  The introspection document object and the original complete DOM object.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		this._getXmlDoc(url, "service", new dojox.atom.io.model.Service(url), dojox.atom.io.model._Constants.APP_NS, callback, errorCallback, scope);
 	},
 	
 	getEntry: function(url, callback, errorCallback, scope){
-		//	summary: 
+		//	summary:
 		//		Function to retrieve a single entry from an ATOM feed from the given URL.
-		//	description: 
+		//	description:
 		//		This function takes the URL for an ATOM entry and returns the constructed dojox.atom.io.model.Entry object through
 		//		the specified callback.
 		//
-		//	url: 
+		//	url:
 		//		String
 		//		The URL of the ATOM Entry document to parse.
-		//	callback: 
+		//	callback:
 		//		Function
-		//		A function reference that will handle the Entry object obtained.   
+		//		A function reference that will handle the Entry object obtained.
 		//		The callback should accept two parameters, the dojox.atom.io.model.Entry object and the original dom.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		this._getXmlDoc(url, "entry", new dojox.atom.io.model.Entry(), dojox.atom.io.model._Constants.ATOM_NS, callback, errorCallback, scope);
 	},
 
 	_getXmlDoc: function(url, nodeName, newNode, namespace, callback, errorCallback, scope){
-		//	summary: 
+		//	summary:
 		//		Internal Function to retrieve an XML document and pass the results to a callback.
-		//	description: 
-		//		This internal function takes the URL for an XML document and and passes the 
+		//	description:
+		//		This internal function takes the URL for an XML document and and passes the
 		//		parsed contents to a specified callback.
 		//
-		//	url: 
+		//	url:
 		//		String
 		//		The URL of the XML document to retrieve
-		//	callback: 
+		//	callback:
 		//		Function
 		//		A function reference that will handle the retrieved XML data.
 		//		The callback should accept one parameter, the DOM of the parsed XML document.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
 			scope = dojo.global;
@@ -121,7 +121,7 @@ dojo.declare("dojox.atom.io.Connection",null,{
 							// gooogle feeds often returns iTunes name_space qualifiers on elements)
 							// Treat this situation like name_spaces not enabled.
 							node = evaldObj.lastChild;
-						} 
+						}
 					}else if(typeof(evaldObj.getElementsByTagName)!= "undefined"){
 						// Find the first eith the correct tag name and correct namespace.
 						nodes = evaldObj.getElementsByTagName(nodeName);
@@ -171,33 +171,33 @@ dojo.declare("dojox.atom.io.Connection",null,{
 	},
 
 	updateEntry: function(entry, callback, errorCallback, retrieveUpdated, xmethod, scope){
-		//	summary: 
+		//	summary:
 		//		Function to update a specific ATOM entry by putting the new changes via APP.
-		//	description: 
-		//		This function takes a specific dojox.atom.io.model.Entry object and pushes the 
+		//	description:
+		//		This function takes a specific dojox.atom.io.model.Entry object and pushes the
 		//		changes back to the provider of the Entry.
 		//		The entry MUST have a link tag with rel="edit" for this to work.
 		//
-		//	entry: 
+		//	entry:
 		//		Object
 		//		The dojox.atom.io.model.Entry object to update.
-		//	callback: 
+		//	callback:
 		//		Function
 		//		A function reference that will handle the results from the entry update.
 		//		The callback should accept two parameters:  The first is an Entry object, and the second is the URL of that Entry
 		//		Either can be null, depending on the value of retrieveUpdated.
-		//	retrieveUpdated: 
+		//	retrieveUpdated:
 		//		boolean
-		//		A boolean flag denoting if the entry that was updated should then be 
+		//		A boolean flag denoting if the entry that was updated should then be
 		//		retrieved and returned to the caller via the callback.
-		//	xmethod: 
+		//	xmethod:
 		//		boolean
 		//		Whether to use POST for PUT/DELETE items and send the X-Method-Override header.
-		//	scope: 
+		//	scope:
 		//		Object
 		//		The scope to use for all callbacks.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
 			scope = dojo.global;
@@ -269,29 +269,29 @@ dojo.declare("dojox.atom.io.Connection",null,{
 	},
 
 	addEntry: function(entry, url, callback, errorCallback, retrieveEntry, scope){
-		//	summary: 
+		//	summary:
 		//		Function to add a new ATOM entry by posting the new entry via APP.
-		//	description: 
-		//		This function takes a specific dojox.atom.io.model.Entry object and pushes the 
+		//	description:
+		//		This function takes a specific dojox.atom.io.model.Entry object and pushes the
 		//		changes back to the provider of the Entry.
 		//
-		//	entry: 
+		//	entry:
 		//		Object
 		//		The dojox.atom.io.model.Entry object to publish.
-		//	callback: 
+		//	callback:
 		//		Function
 		//		A function reference that will handle the results from the entry publish.
 		//		The callback should accept two parameters:   The first is an dojox.atom.io.model.Entry object, and the second is the location of the entry
 		//		Either can be null, depending on the value of retrieveUpdated.
-		//	retrieveEntry: 
+		//	retrieveEntry:
 		//		boolean
-		//		A boolean flag denoting if the entry that was created should then be 
+		//		A boolean flag denoting if the entry that was created should then be
 		//		retrieved and returned to the caller via the callback.
-		//	scope: 
+		//	scope:
 		//		Object
 		//	 	The scope to use for all callbacks.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
 			scope = dojo.global;
@@ -365,22 +365,22 @@ dojo.declare("dojox.atom.io.Connection",null,{
 	},
 
 	deleteEntry: function(entry,callback,errorCallback,xmethod,scope){
-		//	summary: 
+		//	summary:
 		//		Function to delete a specific ATOM entry via APP.
-		//	description: 
+		//	description:
 		//		This function takes a specific dojox.atom.io.model.Entry object and calls for a delete on the
 		//		service housing the ATOM Entry database.
 		//		The entry MUST have a link tag with rel="edit" for this to work.
 		//
-		//	entry: 
+		//	entry:
 		//		Object
 		//		The dojox.atom.io.model.Entry object to delete.
-		//	callback: 
+		//	callback:
 		//		Function
 		//		A function reference that will handle the results from the entry delete.
 		//		The callback is called only if the delete is successful.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing. The return is handled through the callback handler.
 		if(!scope){
 			scope = dojo.global;
@@ -428,5 +428,5 @@ dojo.declare("dojox.atom.io.Connection",null,{
 		}else{
 			dojo.xhrDelete(xhrArgs);
 		}
-	} 
+	}
 });
diff --git a/dojox/atom/io/model.js b/dojox/atom/io/model.js
index ff0ea63..fe3e139 100644
--- a/dojox/atom/io/model.js
+++ b/dojox/atom/io/model.js
@@ -5,9 +5,9 @@ dojo.require("dojo.string");
 dojo.require("dojo.date.stamp");
 
 dojox.atom.io.model._Constants = {
-	//	summary: 
+	//	summary:
 	//		Container for general constants.
-	//	description: 
+	//	description:
 	//		Container for general constants.
 	"ATOM_URI": "http://www.w3.org/2005/Atom",
 	"ATOM_NS": "http://www.w3.org/2005/Atom",
@@ -16,9 +16,9 @@ dojox.atom.io.model._Constants = {
 };
 
 dojox.atom.io.model._actions = {
-	//	summary: 
+	//	summary:
 	//		Container for tag handling functions.
-	//	description: 
+	//	description:
 	//		Container for tag handling functions.  Each child of this container is
 	//		a handler function for the given type of node. Each accepts two parameters:
 	//	obj:  Object.
@@ -80,25 +80,25 @@ dojox.atom.io.model._actions = {
 		obj.modified = dojox.atom.io.model.util.createDate(node);
 	},
 	"published": function(obj,node){
-		obj.published = dojox.atom.io.model.util.createDate(node);	  
+		obj.published = dojox.atom.io.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();
 		entry.buildFromDom(node);
-		obj.entries.push(entry);	
-	}, 
+		obj.entries.push(entry);
+	},
 	"content": function(obj, node){
 		var cnt = new dojox.atom.io.model.Content("content");
 		cnt.buildFromDom(node);
 		obj.content = cnt;
-	}, 
+	},
 	"summary": function(obj, node){
 		var summary = new dojox.atom.io.model.Content("summary");
 		summary.buildFromDom(node);
 		obj.summary = summary;
-	}, 
+	},
 
 	"name": function(obj,node){
 		obj.name = dojox.xml.parser.textContent(node);
@@ -117,14 +117,14 @@ dojox.atom.io.model._actions = {
 
 dojox.atom.io.model.util = {
 	createDate: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Utility function to create a date from a DOM node's text content.
-		//	description: 
+		//	description:
 		//		Utility function to create a date from a DOM node's text content.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to inspect.
-		//	returns: 
+		//	returns:
 		//		Date object from a DOM Node containing a ISO-8610 string.
 		var textContent = dojox.xml.parser.textContent(node);
 		if(textContent){
@@ -133,42 +133,42 @@ dojox.atom.io.model.util = {
 		return null;
 	},
 	escapeHtml: function(/*String*/str){
-		//	summary: 
+		//	summary:
 		//		Utility function to escape XML special characters in an HTML string.
-		//	description: 
+		//	description:
 		//		Utility function to escape XML special characters in an HTML string.
 		//
-		//	str: 
+		//	str:
 		//		The string to escape
-		//	returns: 
+		//	returns:
 		//		HTML String with special characters (<,>,&, ", etc,) escaped.
 		return str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, """)
 			.replace(/'/gm, "'"); // String
 	},
 	unEscapeHtml: function(/*String*/str){
-		//	summary: 
+		//	summary:
 		//		Utility function to un-escape XML special characters in an HTML string.
-		//	description: 
+		//	description:
 		//		Utility function to un-escape XML special characters in an HTML string.
 		//
-		//	str: 
+		//	str:
 		//		The string to un-escape.
-		//	returns: 
+		//	returns:
 		//		HTML String converted back to the normal text (unescaped) characters (<,>,&, ", etc,).
 		return str.replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, "\"")
 			.replace(/'/gm, "'").replace(/&/gm, "&"); // String
 	},
 	getNodename: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Utility function to get a node name and deal with IE's bad handling of namespaces
 		//		on tag names.
-		//	description: 
+		//	description:
 		//		Utility function to get a node name and deal with IE's bad handling of namespaces
 		//		on tag names.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node whose name to retrieve.
-		//	returns: 
+		//	returns:
 		//		String
 		//	The name without namespace prefixes.
 		var name = null;
@@ -259,7 +259,7 @@ dojo.declare('dojox.atom.io.model.Node', null, {
 		var x;
 		var name = (this.shortNs?this.shortNs+":":'')+this.name;
 		var cdata = (this.name == "#cdata-section");
-		if(cdata){ 
+		if(cdata){
 			xml.push("<![CDATA[");
 			xml.push(this.textContent);
 			xml.push("]]>");
@@ -276,7 +276,7 @@ dojo.declare('dojox.atom.io.model.Node', null, {
 			}
 			if(this.content){
 				xml.push(">");
-				for(x in this.content){ 
+				for(x in this.content){
 					xml.push(this.content[x]);
 				}
 				xml.push("</" + name + ">\n");
@@ -298,7 +298,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		this.links = null;						//Array of Link
 		this.authors = null;					//Array of Person
 		this.categories = null;					//Array of Category
-		this.contributors = null;				//Array of Person   
+		this.contributors = null;				//Array of Person
 		this.icon = this.id = this.logo = this.xmlBase = this.rights = null; //String
 		this.subtitle = this.title = null;		//Content
 		this.updated = this.published = null;	//Date
@@ -345,7 +345,7 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 				}
 			}
 		}
-		this._saveAttributes(node); 
+		this._saveAttributes(node);
 		if(this._postBuild){this._postBuild();}
 	},
 	addNamespace: function(fullName, shortName){
@@ -354,63 +354,63 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		}
 	},
 	addAuthor: function(/*String*/name, /*String*/email, /*String*/uri){
-		//	summary: 
+		//	summary:
 		//		Function to add in an author to the list of authors.
-		//	description: 
+		//	description:
 		//		Function to add in an author to the list of authors.
 		//
-		//	name: 
+		//	name:
 		//		The author's name.
-		//	email: 
+		//	email:
 		//		The author's e-mail address.
-		//	uri: 
+		//	uri:
 		//		A URI associated with the author.
 		if(!this.authors){this.authors = [];}
 		this.authors.push(new dojox.atom.io.model.Person("author",name,email,uri));
 	},
 	addContributor: function(/*String*/name, /*String*/email, /*String*/uri){
-		//	summary: 
+		//	summary:
 		//		Function to add in an author to the list of authors.
-		//	description: 
+		//	description:
 		//		Function to add in an author to the list of authors.
 		//
-		//	name: 
+		//	name:
 		//		The author's name.
-		//	email: 
+		//	email:
 		//		The author's e-mail address.
-		//	uri: 
+		//	uri:
 		//		A URI associated with the author.
 		if(!this.contributors){this.contributors = [];}
 		this.contributors.push(new dojox.atom.io.model.Person("contributor",name,email,uri));
 	},
 	addLink: function(/*String*/href,/*String*/rel,/*String*/hrefLang,/*String*/title,/*String*/type){
-		//	summary: 
+		//	summary:
 		//		Function to add in a link to the list of links.
-		//	description: 
+		//	description:
 		//		Function to add in a link to the list of links.
 		//
-		//	href: 
+		//	href:
 		//		The href.
-		//	rel: 
+		//	rel:
 		//		String
-		//	hrefLang: 
+		//	hrefLang:
 		//		String
-		//	title: 
+		//	title:
 		//		A title to associate with the link.
-		//	type: 
+		//	type:
 		//		The type of link is is.
 		if(!this.links){this.links=[];}
 		this.links.push(new dojox.atom.io.model.Link(href,rel,hrefLang,title,type));
 	},
 	removeLink: function(/*String*/href, /*String*/rel){
-		//	summary: 
+		//	summary:
 		//		Function to remove a link from the list of links.
-		//	description: 
+		//	description:
 		//		Function to remove a link from the list of links.
 		//
-		//	href: 
+		//	href:
 		//		The href.
-		//	rel: 
+		//	rel:
 		//		String
 		if(!this.links || !dojo.isArray(this.links)){return;}
 		var count = 0;
@@ -422,9 +422,9 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		return count;
 	},
 	removeBasicLinks: function(){
-		//	summary: 
+		//	summary:
 		//		Function to remove all basic links from the list of links.
-		//	description: 
+		//	description:
 		//		Function to remove all basic link from the list of links.
 		if(!this.links){return;}
 		var count = 0;
@@ -434,27 +434,27 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		return count;
 	},
 	addCategory: function(/*String*/scheme, /*String*/term, /*String*/label){
-		//	summary: 
+		//	summary:
 		//		Function to add in a category to the list of categories.
-		//	description: 
+		//	description:
 		//		Function to add in a category to the list of categories.
 		//
-		//	scheme: 
+		//	scheme:
 		//		String
-		//	term: 
+		//	term:
 		//		String
-		//	label: 
+		//	label:
 		//		String
 		if(!this.categories){this.categories = [];}
 		this.categories.push(new dojox.atom.io.model.Category(scheme,term,label));
 	},
 	getCategories: function(/*String*/scheme){
-		//	summary: 
+		//	summary:
 		//		Function to get all categories that match a particular scheme.
-		//	description: 
+		//	description:
 		//		Function to get all categories that match a particular scheme.
 		//
-		//	scheme: 
+		//	scheme:
 		//		String
 		//		The scheme to filter on.
 		if(!scheme){return this.categories;}
@@ -466,14 +466,14 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		return arr;
 	},
 	removeCategories: function(/*String*/scheme, /*String*/term){
-		//	summary: 
+		//	summary:
 		//		Function to remove all categories that match a particular scheme and term.
-		//	description: 
+		//	description:
 		//		Function to remove all categories that match a particular scheme and term.
 		//
-		//	scheme: 
+		//	scheme:
 		//		The scheme to filter on.
-		//	term: 
+		//	term:
 		//		The term to filter on.
 		if(!this.categories){return;}
 		var count = 0;
@@ -485,14 +485,14 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		return count;
 	},
 	setTitle: function(/*String*/str, /*String*/type){
-		//	summary: 
+		//	summary:
 		//		Function to set the title of the item.
-		//	description: 
+		//	description:
 		//		Function to set the title of the item.
 		//
-		//	str: 
+		//	str:
 		//		The title to set.
-		//	type: 
+		//	type:
 		//		The type of title format, text, xml, xhtml, etc.
 		if(!str){return;}
 		this.title = new dojox.atom.io.model.Content("title");
@@ -500,31 +500,31 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		if(type){this.title.type = type;}
 	},
 	addExtension: function(/*String*/name_space,/*String*/name, /*Array*/attributes, /*String*/content, /*String*/shortNS){
-		//	summary: 
+		//	summary:
 		//		Function to add in an extension namespace into the item.
-		//	description: 
+		//	description:
 		//		Function to add in an extension namespace into the item.
 		//
-		//	name_space: 
+		//	name_space:
 		//		The namespace of the extension.
-		//	name: 
+		//	name:
 		//		The name of the extension
-		//	attributes: 
+		//	attributes:
 		//		The attributes associated with the extension.
-		//	content: 
+		//	content:
 		//		The content of the extension.
 		if(!this.extensions){this.extensions=[];}
 		this.extensions.push(new dojox.atom.io.model.Node(name_space,name,attributes,content, shortNS || "ns"+this.extensions.length));
 	},
 	getExtensions: function(/*String*/name_space, /*String*/name){
-		//	summary: 
+		//	summary:
 		//		Function to get extensions that match a namespace and name.
-		//	description: 
+		//	description:
 		//		Function to get extensions that match a namespace and name.
 		//
-		//	name_space: 
+		//	name_space:
 		//		The namespace of the extension.
-		//	name: 
+		//	name:
 		//		The name of the extension
 		var arr = [];
 		if(!this.extensions){return arr;}
@@ -536,14 +536,14 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 		return arr;
 	},
 	removeExtensions: function(/*String*/name_space, /*String*/name){
-		//	summary: 
+		//	summary:
 		//		Function to remove extensions that match a namespace and name.
-		//	description: 
+		//	description:
 		//		Function to remove extensions that match a namespace and name.
 		//
-		//	name_space: 
+		//	name_space:
 		//		The namespace of the extension.
-		//	name: 
+		//	name:
 		//		The name of the extension
 		if(!this.extensions){return;}
 		for(var i=0; i< this.extensions.length; i++){
@@ -570,9 +570,9 @@ dojo.declare("dojox.atom.io.model.AtomItem",dojox.atom.io.model.Node,{
 });
 
 dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
-	//	summary: 
-	//		Class container for 'Category' types. 
-	//	description: 
+	//	summary:
+	//		Class container for 'Category' types.
+	//	description:
 	//		Class container for 'Category' types.
 	constructor: function(/*String*/scheme, /*String*/term, /*String*/label){
 		this.scheme = scheme; this.term = term; this.label = label;
@@ -583,9 +583,9 @@ dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
 		return ["label","scheme","term"];
 	},
 	toString: function(){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the category tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the category tag, which is an XML structure.
 		var s = [];
 		s.push('<category ');
@@ -596,12 +596,12 @@ dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
 		return s.join('');
 	},
 	buildFromDom: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the Category data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the Category data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for content.
 		this._saveAttributes(node);//just get the attributes from the node
 		this.label = this.attributes.label;
@@ -612,9 +612,9 @@ dojo.declare("dojox.atom.io.model.Category",dojox.atom.io.model.Node,{
 });
 
 dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Content' types. Such as summary, content, username, and so on types of data.
-	//	description: 
+	//	description:
 	//		Class container for 'Content' types. Such as summary, content, username, and so on types of data.
 	constructor: function(tagName, value, src, type,xmlLang){
 		this.tagName = tagName; this.value = value; this.src = src; this.type=type; this.xmlLang = xmlLang;
@@ -624,12 +624,12 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 	_getAttributeNames: function(){return ["type","src"];},
 	_postBuild: function(){},
 	buildFromDom: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the Content data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the Content data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for content.
 		//Handle checking for XML content as the content type
 		var type = node.getAttribute("type");
@@ -676,9 +676,9 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 		if(this._postBuild){this._postBuild();}
 	},
 	toString: function(){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the content tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the content tag, which is an XML structure.
 		var s = [];
 		s.push('<'+this.tagName+' ');
@@ -699,9 +699,9 @@ dojo.declare("dojox.atom.io.model.Content",dojox.atom.io.model.Node,{
 });
 
 dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'link' types.
-	//	description: 
+	//	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;
@@ -709,12 +709,12 @@ dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{
 	_getAttributeNames: function(){return ["href","jrefLang","rel","title","type"];},
 	_postBuild: function(){},
 	buildFromDom: function(node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the link data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the link data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for link data.
 		this._saveAttributes(node);//just get the attributes from the node
 		this.href = this.attributes.href;
@@ -725,11 +725,11 @@ dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{
 		if(this._postBuild){this._postBuild();}
 	},
 	toString: function(){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the link tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the link tag, which is an XML structure.
-		var s = []; 
+		var s = [];
 		s.push('<link ');
 		if(this.href){s.push(' href="'+this.href+'" ');}
 		if(this.hrefLang){s.push(' hrefLang="'+this.hrefLang+'" ');}
@@ -742,9 +742,9 @@ dojo.declare("dojox.atom.io.model.Link",dojox.atom.io.model.Node,{
 });
 
 dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'person' types, such as Author, controbutors, and so on.
-	//	description: 
+	//	description:
 	//		Class container for 'person' types, such as Author, controbutors, and so on.
 	constructor: function(personType, name, email, uri){
 		this.author = "author";
@@ -762,12 +762,12 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 	_postBuild: function(){},
 	accept: function(tag){return Boolean(this._accepts[tag]);},
 	buildFromDom: function(node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the person data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the person data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for person data.
 		var c = node.childNodes;
 		for(var i = 0; i< c.length; i++){
@@ -789,7 +789,7 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 				fn(this,c[i]);
 			}
 		}
-		this._saveAttributes(node); 
+		this._saveAttributes(node);
 		if(this._postBuild){this._postBuild();}
 	},
 	_accepts: {
@@ -798,9 +798,9 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 		'email': true
 	},
 	toString: function(){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the Person tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the Person tag, which is an XML structure.
 		var s = [];
 		s.push('<'+this.personType+'>\n');
@@ -813,9 +813,9 @@ dojo.declare("dojox.atom.io.model.Person",dojox.atom.io.model.Node,{
 });
 
 dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Generator' types.
-	//	description: 
+	//	description:
 	//		Class container for 'Generator' types.
 	constructor: function(/*String*/uri, /*String*/version, /*String*/value){
 		this.uri = uri;
@@ -824,26 +824,26 @@ dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{
 	},
 	_postBuild: function(){},
 	buildFromDom: function(node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the generator data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the generator data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for link data.
 
 		this.value = dojox.xml.parser.textContent(node);
 		this._saveAttributes(node);
 
-		this.uri = this.attributes.uri; 
+		this.uri = this.attributes.uri;
 		this.version = this.attributes.version;
 
 		if(this._postBuild){this._postBuild();}
 	},
 	toString: function(){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the Generator tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the Generator tag, which is an XML structure.
 		var s = [];
 		s.push('<generator ');
@@ -856,9 +856,9 @@ dojo.declare("dojox.atom.io.model.Generator",dojox.atom.io.model.Node,{
 });
 
 dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Entry' types.
-	//	description: 
+	//	description:
 	//		Class container for 'Entry' types.
 	constructor: function(/*String*/id){
 		this.id = id; this._objName = "Entry"; this.feedUrl = null;
@@ -882,9 +882,9 @@ dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
 		'modified': true
 	},
 	toString: function(amPrimary){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the entry tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the entry tag, which is an XML structure.
 		var s = [];
 		var i;
@@ -895,7 +895,7 @@ dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
 		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'); 
+		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');}
@@ -923,12 +923,12 @@ dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
 		return s.join(''); //string
 	},
 	getEditHref: function(){
-		//	summary: 
+		//	summary:
 		//		Function to get the href that allows editing of this feed entry.
-		//	description: 
+		//	description:
 		//		Function to get the href that allows editing of this feed entry.
 		//
-		//	returns: 
+		//	returns:
 		//		The href that specifies edit capability.
 		if(this.links === null || this.links.length === 0){
 			return null;
@@ -955,9 +955,9 @@ dojo.declare("dojox.atom.io.model.Entry",dojox.atom.io.model.AtomItem,{
 });
 
 dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Feed' types.
-	//	description: 
+	//	description:
 	//		Class container for 'Feed' types.
 	_accepts: {
 		'author': true,
@@ -981,11 +981,11 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		'subtitle': true
 	},
 	addEntry: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Function to add an entry to this feed.
-		//	description: 
+		//	description:
 		//		Function to add an entry to this feed.
-		//	entry: 
+		//	entry:
 		//		The entry object to add.
 		if(!entry.id){
 			throw new Error("The entry object must be assigned an ID attribute.");
@@ -995,23 +995,23 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		this.entries.push(entry);
 	},
 	getFirstEntry: function(){
-		//	summary: 
+		//	summary:
 		//		Function to get the first entry of the feed.
-		//	description: 
+		//	description:
 		//		Function to get the first entry of the feed.
 		//
-		//	returns: 
+		//	returns:
 		//		The first entry in the feed.
 		if(!this.entries || this.entries.length === 0){return null;}
 		return this.entries[0]; //object
 	},
 	getEntry: function(/*String*/entryId){
-		//	summary: 
+		//	summary:
 		//		Function to get an entry by its id.
-		//	description: 
+		//	description:
 		//		Function to get an entry by its id.
 		//
-		//	returns: 
+		//	returns:
 		//		The entry desired, or null if none.
 		if(!this.entries){return null;}
 		for(var x in this.entries){
@@ -1022,12 +1022,12 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		return null;
 	},
 	removeEntry: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Function to remove an entry from the list of links.
-		//	description: 
+		//	description:
 		//		Function to remove an entry from the list of links.
 		//
-		//	entry: 
+		//	entry:
 		//		The entry.
 		if(!this.entries){return;}
 		var count = 0;
@@ -1040,21 +1040,21 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		return count;
 	},
 	setEntries: function(/*array*/arrayOfEntry){
-		//	summary: 
+		//	summary:
 		//		Function to add a set of entries to the feed.
-		//	description: 
+		//	description:
 		//		Function to get an entry by its id.
 		//
-		//	arrayOfEntry: 
+		//	arrayOfEntry:
 		//		An array of entry objects to add to the feed.
 		for(var x in arrayOfEntry){
 			this.addEntry(arrayOfEntry[x]);
 		}
 	},
 	toString: function(){
-		//	summary: 
+		//	summary:
 		//		Function to construct string form of the feed tag, which is an XML structure.
-		//	description: 
+		//	description:
 		//		Function to construct string form of the feed tag, which is an XML structure.
 		var s = [];
 		var i;
@@ -1063,7 +1063,7 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		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'); 
+		s.push('<id>' + (this.id ? this.id: '') + '</id>\n');
 		if(this.title){s.push(this.title);}
 		if(this.copyright && !this.rights){this.rights = this.copyright;}
 		if(this.rights){s.push('<rights>' + this.rights + '</rights>\n');}
@@ -1093,22 +1093,22 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 		return s.join('');
 	},
 	createEntry: function(){
-		//	summary: 
+		//	summary:
 		//		Function to Create a new entry object in the feed.
-		//	description: 
+		//	description:
 		//		Function to Create a new entry object in the feed.
-		//	returns: 
+		//	returns:
 		//		An empty entry object in the feed.
 		var entry = new dojox.atom.io.model.Entry();
 		entry.feedUrl = this.getSelfHref();
 		return entry; //object
 	},
 	getSelfHref: function(){
-		//	summary: 
+		//	summary:
 		//		Function to get the href that refers to this feed.
-		//	description: 
+		//	description:
 		//		Function to get the href that refers to this feed.
-		//	returns: 
+		//	returns:
 		//		The href that refers to this feed or null if none.
 		if(this.links === null || this.links.length === 0){
 			return null;
@@ -1123,23 +1123,23 @@ dojo.declare("dojox.atom.io.model.Feed",dojox.atom.io.model.AtomItem,{
 });
 
 dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Feed' types.
-	//	description: 
+	//	description:
 	//		Class container for 'Feed' types.
 	constructor: function(href){
 		this.href = href;
 	},
-	//builds a Service document.  each element of this, except for the namespace, is the href of 
+	//builds a Service document.  each element of this, except for the namespace, is the href of
 	//a service that the server supports.  Some of the common services are:
 	//"create-entry" , "user-prefs" , "search-entries" , "edit-template" , "categories"
 	buildFromDom: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the Service data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the Service data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for content.
 		var i;
 		this.workspaces = [];
@@ -1178,12 +1178,12 @@ dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
 		}
 	},
 	getCollection: function(/*String*/url){
-		//	summary: 
+		//	summary:
 		//		Function to collections that match a specific url.
-		//	description: 
+		//	description:
 		//		Function to collections that match a specific url.
 		//
-		//	url: 
+		//	url:
 		//		e URL to match collections against.
 		for(var i=0;i<this.workspaces.length;i++){
 			var coll=this.workspaces[i].collections;
@@ -1198,9 +1198,9 @@ dojo.declare("dojox.atom.io.model.Service",dojox.atom.io.model.AtomItem,{
 });
 
 dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Workspace' types.
-	//	description: 
+	//	description:
 	//		Class container for 'Workspace' types.
 	constructor: function(title){
 		this.title = title;
@@ -1208,12 +1208,12 @@ dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{
 	},
 
 	buildFromDom: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the Workspace data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the Workspace data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for content.
 		var name = dojox.atom.io.model.util.getNodename(node);
 		if(name != "workspace"){return;}
@@ -1242,9 +1242,9 @@ dojo.declare("dojox.atom.io.model.Workspace",dojox.atom.io.model.AtomItem,{
 });
 
 dojo.declare("dojox.atom.io.model.Collection",dojox.atom.io.model.AtomItem,{
-	//	summary: 
+	//	summary:
 	//		Class container for 'Collection' types.
-	//	description: 
+	//	description:
 	//		Class container for 'Collection' types.
 	constructor: function(href, title){
 		this.href = href;
@@ -1257,12 +1257,12 @@ dojo.declare("dojox.atom.io.model.Collection",dojox.atom.io.model.AtomItem,{
 	},
 
 	buildFromDom: function(/*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Function to do construction of the Collection data from the DOM node containing it.
-		//	description: 
+		//	description:
 		//		Function to do construction of the Collection data from the DOM node containing it.
 		//
-		//	node: 
+		//	node:
 		//		The DOM node to process for content.
 		this.href = node.getAttribute("href");
 		var c = node.childNodes;
diff --git a/dojox/atom/tests/io/module.js b/dojox/atom/tests/io/module.js
index c83e914..7e1ab68 100644
--- a/dojox/atom/tests/io/module.js
+++ b/dojox/atom/tests/io/module.js
@@ -54,8 +54,8 @@ doh.register("dojox.atom.tests.io.module", [
 	},
 
 	// Feed parsing, feed attributes (title, id, etc.) and functions, including all generic AtomItem methods
-	// Incidently, also tests AtomIO.getFeed success, as well as all members of the Category, Content, Link, 
-	// and Person classes.  
+	// Incidently, also tests AtomIO.getFeed success, as well as all members of the Category, Content, Link,
+	// and Person classes.
 	{
 		name: "checkFeed",
 		runTest: function(t){
diff --git a/dojox/atom/widget/FeedEntryEditor.js b/dojox/atom/widget/FeedEntryEditor.js
index b4eb5fa..c96e579 100644
--- a/dojox/atom/widget/FeedEntryEditor.js
+++ b/dojox/atom/widget/FeedEntryEditor.js
@@ -13,9 +13,9 @@ dojo.requireLocalization("dojox.atom.widget", "PeopleEditor");
 dojo.experimental("dojox.atom.widget.FeedEntryEditor");
 
 dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryViewer,{
-	//	summary:  
+	//	summary:
 	//		An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
-	//	description:  
+	//	description:
 	//		An ATOM feed entry editor that allows viewing of the individual attributes of an entry.
 	_contentEditor: null,
 	_oldContent: null,
@@ -52,12 +52,12 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 	
 	setEntry: function(/*object*/entry, /*object*/feed, /*boolean*/leaveMenuState){
-		//	summary:  
+		//	summary:
 		//		Function to set the current entry that is being edited.
 		//	description:
 		//		Function to set the current entry that is being edited.
 		//
-		//	entry: 
+		//	entry:
 		//		Instance of dojox.atom.io.model.Entry to display for reading/editing.
 		if(this._entry !== entry){
 			//If we swap entries, we don't want to keep the menu states and modes.
@@ -84,12 +84,12 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	_toggleEdit: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function for toggling/enabling the display of edit mode
-		//	description: 
+		//	description:
 		//		Internal function for toggling/enabling the display of edit mode
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing.
 		if(this._editable && this.enableEdit){
 			dojo.style(this.entryEditButton, 'display', 'none');
@@ -102,17 +102,17 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	_handleEvent: function(/*object*/entrySelectionEvent){
-		//	summary: 
+		//	summary:
 		//		Internal function for listening to a topic that will handle entry notification.
 		//	description:
 		//		Internal function for listening to a topic that will handle entry notification.
 		//
-		//	entrySelectionEvent: 
+		//	entrySelectionEvent:
 		//		The topic message containing the entry that was selected for view.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing.
-		if(entrySelectionEvent.source != this && entrySelectionEvent.action == "delete" && 
+		if(entrySelectionEvent.source != this && entrySelectionEvent.action == "delete" &&
 			entrySelectionEvent.entry && entrySelectionEvent.entry == this._entry){
 				dojo.style(this.entryEditButton, 'display', 'none');
 		}
@@ -120,7 +120,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	_isEditable: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Internal function for determining of a particular entry is editable.
 		//	description:
 		//		Internal function for determining of a particular entry is editable.
@@ -130,7 +130,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//		The dojox.atom.io.model.Entry object to examine
 		//
 		//	returns:
-		//		Boolean denoting if the entry seems editable or not.. 
+		//		Boolean denoting if the entry seems editable or not..
 		var retVal = false;
 		if(entry && entry !== null && entry.links && entry.links !== null){
 			for(var x in entry.links){
@@ -146,9 +146,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	// The following set<Attribute> functions override the corresponding functions in FeedEntryViewer.  These handle
 	// the editMode flag by inserting appropriate editor widgets inside of just splashing the content in the page.
 	setTitle: function(/*DOM node*/titleAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the title node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the title node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
@@ -181,17 +181,17 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	setAuthors: function(/*DOM node*/authorsAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the author node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the author node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
 		//	authorsAnchorNode:
 		//		The DOM node to attach the author data to.
-		//	editMode: 
+		//	editMode:
 		// 		Boolean to indicate if the display should be in edit mode or not.
-		//	entry: 
+		//	entry:
 		// 		The Feed Entry to work with.
 		if(!editMode){
 			dojox.atom.widget.FeedEntryEditor.superclass.setAuthors.call(this, authorsAnchorNode, editMode, entry);
@@ -208,9 +208,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 
 
 	setContributors: function(/*DOM node*/contributorsAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the contributor node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the contributor node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
@@ -235,9 +235,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 
 
 	setId: function(/*DOM node*/idAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the ID  node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the ID node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
@@ -261,9 +261,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	setUpdated: function(/*DOM node*/updatedAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the updated  node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the updated node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
@@ -288,9 +288,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 
 
 	setSummary: function(/*DOM node*/summaryAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the summary  node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the summary node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
@@ -322,9 +322,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	setContent: function(/*DOM node*/contentAnchorNode, /*boolean*/editMode, /*object*/entry){
-		//	summary:  
+		//	summary:
 		//		Function to set the contents of the content node in the template to some value from the entry.
-		//	description: 
+		//	description:
 		//		Function to set the contents of the content node in the template to some value from the entry.
 		//		This exists specifically so users can over-ride how the title data is filled out from an entry.
 		//
@@ -332,7 +332,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 		//		The DOM node to attach the content data to.
 		//	editMode:
 		//		Boolean to indicate if the display should be in edit mode or not.
-		// 	entry: 
+		// 	entry:
 		//		The Feed Entry to work with.
 		if(!editMode){
 			dojox.atom.widget.FeedEntryEditor.superclass.setContent.call(this, contentAnchorNode, editMode, entry);
@@ -355,37 +355,37 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 	
 	_createEditor: function(/*DOM node*/anchorNode, /*DOM node*/node, /*boolean*/multiline, /*object*/rte){
-		//	summary:  
+		//	summary:
 		//		Function to create an appropriate text editor widget based on the given parameters.
-		//	description: 
+		//	description:
 		//		Function to create an appropriate text editor widget based on the given parameters.
 		//
 		//	anchorNode:
 		//		The DOM node to attach the editor widget to.
-		//	node: 
+		//	node:
 		//		An object containing the value to be put into the editor.  This ranges from an anonymous object
 		//		with a value parameter to a dojox.atom.io.model.Content object.
 		//	multiline:
-		//		A boolean indicating whether the content should be multiline (such as a textarea) instead of a 
+		//		A boolean indicating whether the content should be multiline (such as a textarea) instead of a
 		//		single line (such as a textbox).
 		//	rte:
 		//		A boolean indicating whether the content should be a rich text editor widget.
 		//
 		//	returns:
-		//		Either a widget (for textarea or textbox widgets) or an anonymous object to be used to create a 
+		//		Either a widget (for textarea or textbox widgets) or an anonymous object to be used to create a
 		//		rich text area widget.
 		var viewNode;
 		var box;
 		if(!node){
 			if(rte){
-				// Returns an anonymous object which would then be loaded later, after the containing element 
+				// Returns an anonymous object which would then be loaded later, after the containing element
 				// exists on the page.
 				return {anchorNode: anchorNode,
 						entryValue: "",
 						editor: null,
 						generateEditor: function(){
-							// The only way I found I could get the editor to behave consistently was to 
-							// create the content on a span, and allow the content editor to replace it.  
+							// The only way I found I could get the editor to behave consistently was to
+							// create the content on a span, and allow the content editor to replace it.
 							// This gets around the dynamic/delayed way in which content editors get created.
 							var node = document.createElement("div");
 							node.innerHTML = this.entryValue;
@@ -393,7 +393,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 							var _editor = new dijit.Editor({}, node);
 							this.editor = _editor;
 							return _editor;
-						} 
+						}
 				};
 			}
 			if(multiline){
@@ -423,7 +423,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 			value = node;
 		}
 		if(rte){
-			// Returns an anonymous object which would then be loaded later, after the containing element 
+			// Returns an anonymous object which would then be loaded later, after the containing element
 			// exists on the page.
 			if(value.indexOf("<") != -1){
 				value = value.replace(/</g, "<");
@@ -432,8 +432,8 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 					entryValue: value,
 					editor: null,
 					generateEditor: function(){
-						// The only way I found I could get the editor to behave consistently was to 
-						// create the content on a span, and allow the content editor to replace it.  
+						// The only way I found I could get the editor to behave consistently was to
+						// create the content on a span, and allow the content editor to replace it.
 						// This gets around the dynamic/delayed way in which content editors get created.
 						var node = document.createElement("div");
 						node.innerHTML = this.entryValue;
@@ -462,9 +462,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 	
 	_switchEditor: function(/*object*/event){
-		//	summary:  
+		//	summary:
 		//		Function to switch between editor types.
-		//	description: 
+		//	description:
 		//		Function to switch between a rich text editor and a textarea widget.  Used for title, summary,
 		//		And content when switching between text and html/xhtml content.
 		//
@@ -528,15 +528,15 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 	
 	_createPeopleEditor: function(/*DOM node*/anchorNode, /*DOM node*/node){
-		//	summary: 
+		//	summary:
 		//		Creates a People Editor widget and returns it.
-		//	description: 
+		//	description:
 		//		Creates a People Editor widget, sets its value, and returns it.
 		//
 		//	anchorNode:
 		//		The node to attach the editor to.
 		//	node:
-		//		An object containing the value to be put into the editor. Typically, this is an 
+		//		An object containing the value to be put into the editor. Typically, this is an
 		//		dojox.atom.io.model.Person object.
 		//
 		// returns: A new People Editor object.
@@ -546,11 +546,11 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	saveEdits: function(){
-		//	summary: 
+		//	summary:
 		//		Saves edits submitted when the 'save' button is pressed.
-		//	description: 
+		//	description:
 		//		Saves edits submitted when the 'save' button is pressed.  Distinguishes between new and existing
-		//		entries and saves appropriately.  Fetches the values of the editors, and, if existing, compares them to 
+		//		entries and saves appropriately.  Fetches the values of the editors, and, if existing, compares them to
 		//		the existing values and submits the updates, otherwise creates a new entry and posts it as a new entry.
 		//
 		//	returns:
@@ -746,15 +746,15 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 	
 	_handleSave: function(/*object*/entry, /*string*/location){
-		//	summary: 
+		//	summary:
 		//		Function for handling the save of an entry, cleaning up the display after the edit is completed.
-		//	description: 
+		//	description:
 		//		Function for handling the save of an entry, cleaning up the display after the edit is completed.
 		//
 		//	entry: dojox.atom.io.model.Entry object
 		//		The entry that was saved.
 		//	Location: String
-		//		A URL to be used, not used here, but part of the call back from the AtomIO 
+		//		A URL to be used, not used here, but part of the call back from the AtomIO
 		//	returns:
 		//		Nothing.
 		//Close the editor and revert out.
@@ -766,7 +766,7 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	cancelEdits: function(){
-		//	summary: 
+		//	summary:
 		//		Cancels edits and reverts the editor to its previous state (display mode)
 		//	description:
 		//		Cancels edits and reverts the editor to its previous state (display mode)
@@ -787,15 +787,15 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	clear: function(){
-		//	summary: 
+		//	summary:
 		//		Clears the editor, destorys all editors, leaving the editor completely clear
-		//	description: 
+		//	description:
 		//		Clears the editor, destorys all editors, leaving the editor completely clear
 		this._editable=false;
 		this.clearEditors();
 		dojox.atom.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, 
+			// Note that the superclass clear destroys the widget since it's in the child widget list,
 			// so this is just ref clearing.
 			this._contentEditor = this._setObject = this._oldContent = this._contentEditorCreator = null;
 			this._editors = {};
@@ -813,15 +813,15 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	_enforceXhtml: function(/*string*/html){
-		//	summary: 
+		//	summary:
 		//		Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
-		//	description: 
+		//	description:
 		//		Function for cleaning up/enforcing the XHTML standard in HTML returned from the editor2 widget.
 		//
 		// 	html:
 		//		HTML string to be enforced as xhtml.
 		//
-		// 	returns:  
+		// 	returns:
 		//		string of cleaned up HTML.
 		var xhtml = null;
 		if(html){
@@ -839,9 +839,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 
 	_closeTag: function(/*string*/xhtml, /*string*/tag){
-		//	summary: 
+		//	summary:
 		//		Function for closing tags in a text of HTML/XHTML
-		//	description: 
+		//	description:
 		//		Function for closing tags in a text of HTML/XHTML
 		//
 		//	xhtml: String
@@ -880,9 +880,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 	},
 	
 	_toggleNew: function(){
-		//	summary: 
+		//	summary:
 		//		Function to put the editor into a state to create a new entry.
-		//	description: 
+		//	description:
 		//		Function to put the editor into a state to create a new entry.
 		
 		// Hide the edit/new buttons and show the save/cancel buttons.
@@ -989,9 +989,9 @@ dojo.declare("dojox.atom.widget.FeedEntryEditor",dojox.atom.widget.FeedEntryView
 });
 
 dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated, dijit._Container],{
-		//	summary: 
-		//		An editor for dojox.atom.io.model.Person objects. 
-		//	description: 
+		//	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"),
@@ -1037,9 +1037,9 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 		},
 		
 		_createEditors: function(/*string*/name, /*string*/email, /*string*/uri, /*int*/index, /*string*/widgetName){
-			//	summary: 
+			//	summary:
 			//		creates editor boxes (textbox widgets) for the individual values of a Person.
-			//	description: 
+			//	description:
 			//		creates editor boxes (textbox widgets) for the individual values of a Person.
 			//
 			//	name:
@@ -1048,7 +1048,7 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 			//		The email of this Person.
 			//	uri:
 			//		The Person's URI.
-			//	index: 
+			//	index:
 			//		The row index to use for this Person.
 			var row = document.createElement("tr");
 			this.peopleEditorEditors.appendChild(row);
@@ -1107,23 +1107,23 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 		},
 		
 		_createEditor: function(/*string*/value, /*string*/id, /*string*/name, /*DOM node*/labelNode, /*DOM node*/node){
-			//	summary: 
+			//	summary:
 			//		Creates an individual editor widget (textbox) for a value.
-			// 	description: 
+			// 	description:
 			//		Creates an individual editor widget (textbox) for a value.
 			//
-			// 	value: 
+			// 	value:
 			//		The initial value of the textbox
 			// 	id:
 			//		The id the textbox should have.
-			// 	name: 
+			// 	name:
 			//		The text to put in the label element for this textbox.
 			//	labelNode:
 			//		The node to attach the label to.
 			//	node:
 			//		The node to attach the editor rows to.
 			//
-			//	returns: 
+			//	returns:
 			//		Editor widget.
 			var row = document.createElement("tr");
 			labelNode.appendChild(row);
@@ -1152,10 +1152,10 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 		},
 		
 		_removeEditor: function(/*object*/event){
-			//	summary: 
+			//	summary:
 			//		Removes a Person from our list of editors.
-			//	description: 
-			//		Removes a Person from our list of editors by removing the block of editors that 
+			//	description:
+			//		Removes a Person from our list of editors by removing the block of editors that
 			//		make up that Person.
 			//
 			//	event:
@@ -1191,9 +1191,9 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 		},
 		
 		_add: function(){
-			//	summary: 
+			//	summary:
 			//		Adds a new block of blank editors to represent a Person.
-			//	description: 
+			//	description:
 			//		Adds a new block of blank editors to represent a Person.
 			this._createEditors(null, null, null, this._index);
 			this._index++;
@@ -1201,12 +1201,12 @@ dojo.declare("dojox.atom.widget.PeopleEditor",[dijit._Widget, dijit._Templated,
 		},
 		
 		getValues: function(){
-			//	summary: 
+			//	summary:
 			//		Gets the values of this editor in an array.
-			//	description: 
+			//	description:
 			//		Gets the values of this editor in an array, with each Person as an object within the array.
 			//
-			//	returns: 
+			//	returns:
 			//		An array of anonymous objects representing dojox.atom.io.model.Persons.
 			var values = [];
 			for(var i in this._editors){
diff --git a/dojox/atom/widget/FeedEntryViewer.js b/dojox/atom/widget/FeedEntryViewer.js
index 95c1e84..6a3656d 100644
--- a/dojox/atom/widget/FeedEntryViewer.js
+++ b/dojox/atom/widget/FeedEntryViewer.js
@@ -88,7 +88,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//		Function to clear all the display nodes for the ATOM entry from the viewer.
 
 		dojo.forEach([
-			"entryTitleRow", "entryAuthorRow", "entryContributorRow", "entrySummaryRow", "entryContentRow", 
+			"entryTitleRow", "entryAuthorRow", "entryContributorRow", "entrySummaryRow", "entryContentRow",
 			"entryIdRow", "entryUpdatedRow"
 			], function(node){
 				dojo.style(this[node], "display", "none");
@@ -155,27 +155,27 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 			}
 
 			if(this.entryUpdatedHeader){
-				this.setUpdatedHeader(this.entryUpdatedHeader, entry); 
+				this.setUpdatedHeader(this.entryUpdatedHeader, entry);
 			}
 
 			if(this.entryUpdatedNode){
-				this.setUpdated(this.entryUpdatedNode, this._editMode, entry); 
+				this.setUpdated(this.entryUpdatedNode, this._editMode, entry);
 			}
 
 			if(this.entrySummaryHeader){
-				this.setSummaryHeader(this.entrySummaryHeader, entry); 
+				this.setSummaryHeader(this.entrySummaryHeader, entry);
 			}
 
 			if(this.entrySummaryNode){
-				this.setSummary(this.entrySummaryNode, this._editMode, entry); 
+				this.setSummary(this.entrySummaryNode, this._editMode, entry);
 			}
 
 			if(this.entryContentHeader){
-				this.setContentHeader(this.entryContentHeader, entry); 
+				this.setContentHeader(this.entryContentHeader, entry);
 			}
 
 			if(this.entryContentNode){
-				this.setContent(this.entryContentNode, this._editMode, entry); 
+				this.setContent(this.entryContentNode, this._editMode, entry);
 			}
 		}
 		this._displaySections();
@@ -495,7 +495,7 @@ dojo.declare("dojox.atom.widget.FeedEntryViewer",[dijit._Widget, dijit._Template
 		//		Internal function for determining which sections of the view to actually display.
 		//
 		//	returns:
-		//		Nothing. 
+		//		Nothing.
 		dojo.style(this.entryTitleRow, 'display', 'none');
 		dojo.style(this.entryAuthorRow, 'display', 'none');
 		dojo.style(this.entryContributorRow, 'display', 'none');
diff --git a/dojox/atom/widget/FeedViewer.js b/dojox/atom/widget/FeedViewer.js
index b23129f..dc5dfe3 100644
--- a/dojox/atom/widget/FeedViewer.js
+++ b/dojox/atom/widget/FeedViewer.js
@@ -9,9 +9,9 @@ dojo.requireLocalization("dojox.atom.widget", "FeedViewerEntry");
 dojo.experimental("dojox.atom.widget.FeedViewer");
 
 dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, dijit._Container],{
-	//	summary:  
+	//	summary:
 	//		An ATOM feed viewer that allows for viewing a feed, deleting entries, and editing entries.
-	//	description:  
+	//	description:
 	//		An ATOM feed viewer that allows for viewing a feed, deleting entries, and editing entries.
 	feedViewerTableBody: null,	//The body of the feed viewer table so we can access it and populate it.  Will be assigned via template.
 	feedViewerTable: null,		//The overal table container which contains the feed viewer table.  Will be assigned via template.
@@ -31,10 +31,10 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	alertsEnabled: false,
 
 	postCreate: function(){
-		//	summary: 
-		//		The postCreate function.  
-		//	description: 
-		//		The postCreate function.  Creates our AtomIO object for future interactions and subscribes to the 
+		//	summary:
+		//		The postCreate function.
+		//	description:
+		//		The postCreate function.  Creates our AtomIO object for future interactions and subscribes to the
 		//		event given in markup/creation.
 		this._includeFilters = [];
 
@@ -46,9 +46,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 	
 	startup: function(){
-		//	summary: 
+		//	summary:
 		//		The startup function.
-		//	description: 
+		//	description:
 		//		The startup function.  Parses the filters and sets the feed based on the given url.
 		this.containerNode = this.feedViewerTableBody;
 		var children = this.getDescendants();
@@ -68,24 +68,24 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	clear: function(){
 		//	summary:
 		//		Function clearing all current entries in the feed view.
-		//	description: 
+		//	description:
 		//		Function clearing all current entries in the feed view.
 		//
-		//	returns:  
-		//		Nothing. 
+		//	returns:
+		//		Nothing.
 		this.destroyDescendants();
 	},
 
 	setFeedFromUrl: function(/*string*/url){
-		//	summary: 
+		//	summary:
 		//		Function setting the feed from a URL which to get the feed.
-		//	description: 
+		//	description:
 		//		Function setting the dojox.atom.io.model.Feed data into the view.
 		//
 		//	url:
 		//		The URL to the feed to load.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing.
 		if(url !== ""){
 			if(this._isRelativeURL(url)){
@@ -104,9 +104,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 
 
 	setFeed: function(/*object*/feed){
-		//	summary: 
+		//	summary:
 		//		Function setting the dojox.atom.io.model.Feed data into the view.
-		//	description: 
+		//	description:
 		//		Function setting the dojox.atom.io.model.Feed data into the view.
 		//
 		//	entry:
@@ -121,7 +121,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 			var dispB = this._displayDateForEntry(b);
 			if(dispA > dispB){return -1;}
 			if(dispA < dispB){return 1;}
-			return 0; 
+			return 0;
 		};
 
 		// This function may not be safe in different locales.
@@ -161,14 +161,14 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	_displayDateForEntry: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Internal function for determining the appropriate date to display.
 		//		description: Internal function for determining of a particular entry is editable.
 		//
 		//	entry:
 		//		The dojox.atom.io.model.Entry object to examine.
 		//
-		//	returns:  
+		//	returns:
 		//		An appropriate date for the feed viewer display.
 		if(entry.updated){return entry.updated;}
 		if(entry.modified){return entry.modified;}
@@ -177,16 +177,16 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	appendGrouping: function(/*string*/titleText){
-		//	summary: 
+		//	summary:
 		//		Function for appending a new grouping of entries to the feed view.
-		//	description: 
+		//	description:
 		//		Function for appending a grouping of entries to the feed view.
 		//
 		//	entry:
 		//		The title of the new grouping to create on the view.
 		//
-		//	returns:  
-		//		Nothing. 
+		//	returns:
+		//		Nothing.
 		var entryWidget = new dojox.atom.widget.FeedViewerGrouping({});
 		entryWidget.setText(titleText);
 		this.addChild(entryWidget);
@@ -194,9 +194,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	appendEntry: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Function for appending an entry to the feed view.
-		//	description: 
+		//	description:
 		//		Function for appending an entry to the feed view.
 		//
 		//	entry:
@@ -220,9 +220,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 	
 	deleteEntry: function(/*object*/entryRow){
-		//	summary: 
+		//	summary:
 		//		Function for deleting a row from the view
-		//	description: 
+		//	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);
@@ -233,16 +233,16 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	_removeEntry: function(/*FeedViewerEntry*/ entry, /* boolean */success){
-		//	summary: 
+		//	summary:
 		//		callback for when an entry is deleted from a feed.
-		//	description: 
+		//	description:
 		//		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 before = this.childWidgets[idx-1];
 			var after = this.childWidgets[idx+1];
-			if( before.declaredClass === 'dojox.atom.widget.FeedViewerGrouping' && 
+			if( before.declaredClass === 'dojox.atom.widget.FeedViewerGrouping' &&
 				(after === undefined || after.declaredClass === 'dojox.atom.widget.FeedViewerGrouping')){
 				before.destroy();
 			}
@@ -253,15 +253,15 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 	
 	_rowSelected: function(/*object*/evt){
-		//	summary: 
+		//	summary:
 		//		Internal function for handling the selection of feed entries.
-		//	description: 
+		//	description:
 		//		Internal function for handling the selection of feed entries.
 		//
 		//	evt:
 		//		The click event that triggered a selection.
 		//
-		//	returns:  
+		//	returns:
 		//		Nothing.
 		var selectedNode = evt.target;
 		while(selectedNode){
@@ -303,13 +303,13 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	_deselectCurrentSelection: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function for unselecting the current selection.
-		//	description: 
+		//	description:
 		//		Internal function for unselecting the current selection.
 		//
-		//	returns:  
-		//		Nothing. 
+		//	returns:
+		//		Nothing.
 		if(this._currentSelection){
 			dojo.addClass(this._currentSelection._entryWidget.timeNode, "feedViewerEntryUpdated");
 			dojo.removeClass(this._currentSelection.domNode, "feedViewerEntrySelected");
@@ -317,21 +317,21 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 			this._currentSelection._entryWidget.disableDelete();
 			this._currentSelection = null;
 		}
-	}, 
+	},
 
 
 	_isEditable: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Internal function for determining of a particular entry is editable.
-		//	description: 
+		//	description:
 		//		Internal function for determining of a particular entry is editable.
 		//		This is used for determining if the delete action should be displayed or not.
 		//
-		//	entry: 
+		//	entry:
 		//		The dojox.atom.io.model.Entry object to examine
 		//
-		//	returns:  
-		//		Boolean denoting if the entry seems editable or not.. 
+		//	returns:
+		//		Boolean denoting if the entry seems editable or not..
 		var retVal = false;
 		if(entry && entry !== null && entry.links && entry.links !== null){
 			for(var x in entry.links){
@@ -345,7 +345,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	onEntrySelected: function(/*object*/entry){
-		//	summary: 
+		//	summary:
 		//		Function intended for over-riding/replacement as an attachpoint to for other items to recieve
 		//		selection notification.
 		//	description: Function intended for over0-riding/replacement as an attachpoint to for other items to recieve
@@ -354,21 +354,21 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//	entry:
 		//		The dojox.atom.io.model.Entry object selected.
 		//
-		//	returns:  
-		//		Nothing. 
+		//	returns:
+		//		Nothing.
 	},
 
 	_isRelativeURL: function(/*string*/url){
-		//	summary: 
+		//	summary:
 		//		Method to determine if the URL is relative or absolute.
-		//	description: 
-		//		Method to determine if the URL is relative or absolute.  Basic assumption is if it doesn't start 
+		//	description:
+		//		Method to determine if the URL is relative or absolute.  Basic assumption is if it doesn't start
 		//		with http:// or file://, it's relative to the current document.
 		//
-		//	url: 
+		//	url:
 		//		The URL to inspect.
 		//
-		//	returns: 
+		//	returns:
 		//		boolean indicating whether it's a relative url or not.
 		var isFileURL = function(url){
 			var retVal = false;
@@ -396,9 +396,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	_calculateBaseURL: function(/*string*/fullURL, /*boolean*/currentPageRelative){
-		//	summary: 
+		//	summary:
 		//		Internal function to calculate a baseline URL from the provided full URL.
-		//	description: 
+		//	description:
 		//		Internal function to calculate a baseline URL from the provided full URL.
 		//
 		//	fullURL:
@@ -406,7 +406,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 		//	currentPageRelative:
 		//		Flag to denote of the base URL should be calculated as just the server base, or relative to the current page/location in the URL.
 		//
-		//	returns: 
+		//	returns:
 		//		String of the baseline URL
 		var baseURL = null;
 		if(fullURL !== null){
@@ -450,10 +450,10 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	_isFilterAccepted: function(/*object*/entry) {
 		//	summary:
 		//		Internal function to do matching of category filters to widgets.
-		//	description: 
+		//	description:
 		//		Internal function to do matching of category filters to widgets.
 		//
-		//	returns: 
+		//	returns:
 		//		boolean denoting if this entry matched one of the accept filters.
 		var accepted = false;
 		if (this._includeFilters && (this._includeFilters.length > 0)) {
@@ -472,16 +472,16 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	addCategoryIncludeFilter: function(/*object*/filter) {
-		//	summary: 
+		//	summary:
 		//		Function to add a filter for entry inclusion in the feed view.
-		//	description: 
+		//	description:
 		//		Function to add a filter for entry inclusion in the feed view.
-		// 
-		//	filter: 
-		//		The basic items to filter on and the values.  
+		//
+		//	filter:
+		//		The basic items to filter on and the values.
 		//		Should be of format: {scheme: <some text or null>, term: <some text or null>, label: <some text or null>}
 		//
-		//	returns: 
+		//	returns:
 		//		Nothing.
 		if (filter) {
 			var scheme = filter.scheme;
@@ -517,16 +517,16 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	removeCategoryIncludeFilter: function(/*object*/filter) {
-		//	summary: 
+		//	summary:
 		//		Function to remove a filter for entry inclusion in the feed view.
-		//	description: 
+		//	description:
 		//		Function to remove a filter for entry inclusion in the feed view.
-		// 
+		//
 		//	filter:
 		//		The basic items to identify the filter that is present.
 		//		Should be of format: {scheme: <some text or null>, term: <some text or null>, label: <some text or null>}
 		//
-		//	returns: 
+		//	returns:
 		//		Nothing.
 		if (filter) {
 			var scheme = filter.scheme;
@@ -558,9 +558,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	_handleEvent: function(/*object*/entrySelectionEvent) {
-		//	summary: 
+		//	summary:
 		//		Internal function for listening to a topic that will handle entry notification.
-		//	description: 
+		//	description:
 		//		Internal function for listening to a topic that will handle entry notification.
 		//
 		//	entrySelectionEvent:
@@ -587,9 +587,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 	
 	_addEntry: function(/*object*/entry) {
-		//	summary: 
+		//	summary:
 		//		callback function used when adding an entry to the feed.
-		//	description: 
+		//	description:
 		//		callback function used when adding an entry to the feed.  After the entry has been posted to the feed,
 		//		we add it to our feed representation (to show it on the page) and publish an event to update any entry viewers.
 		this._feed.addEntry(entry);
@@ -598,9 +598,9 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 	},
 
 	destroy: function(){
-		//	summary: 
+		//	summary:
 		//		Destroys this widget, including all descendants and subscriptions.
-		//	description: 
+		//	description:
 		//		Destroys this widget, including all descendants and subscriptions.
 		this.clear();
 		dojo.forEach(this._subscriptions, dojo.unsubscribe);
@@ -608,7 +608,7 @@ dojo.declare("dojox.atom.widget.FeedViewer",[dijit._Widget, dijit._Templated, di
 });
 
 dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Templated],{
-	//	summary: 
+	//	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.
 
@@ -626,16 +626,16 @@ dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Template
 	},
 
 	setTitle: function(/*string*/text){
-		//	summary: 
+		//	summary:
 		//		Function to set the title of the entry.
-		//	description: 
+		//	description:
 		//		Function to set the title of the entry.
 		//
-		//	text: 
+		//	text:
 		//		The title.
 		//
 		//	returns:
-		//		Nothing. 
+		//		Nothing.
 		if (this.titleNode.lastChild){this.titleNode.removeChild(this.titleNode.lastChild);}
 		
 		var titleTextNode = document.createElement("div");
@@ -644,29 +644,29 @@ dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Template
 	},
 
 	setTime: function(/*string*/timeText){
-		//	summary: 
+		//	summary:
 		//		Function to set the time of the entry.
-		//	description: 
+		//	description:
 		//		Function to set the time of the entry.
 		//
-		//	timeText: 
+		//	timeText:
 		//		The string form of the date.
 		//
 		//	returns:
-		//		Nothing. 
+		//		Nothing.
 		if (this.timeNode.lastChild){this.timeNode.removeChild(this.timeNode.lastChild);}
 		var timeTextNode = document.createTextNode(timeText);
 		this.timeNode.appendChild(timeTextNode);
 	},
 
 	enableDelete: function(){
-		//	summary: 
+		//	summary:
 		//		Function to enable the delete action on this entry.
 		//	description:
 		//		Function to enable the delete action on this entry.
 		//
 		//	returns:
-		//		Nothing. 
+		//		Nothing.
 		if (this.deleteButton !== null) {
 			//TODO Fix this
 			this.deleteButton.style.display = 'inline';
@@ -674,22 +674,22 @@ dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Template
 	},
 
 	disableDelete: function(){
-		//	summary: 
+		//	summary:
 		//		Function to disable the delete action on this entry.
-		//	description: 
+		//	description:
 		//		Function to disable the delete action on this entry.
 		//
-		// 	returns:  
-		//		Nothing. 
+		// 	returns:
+		//		Nothing.
 		if (this.deleteButton !== null) {
 			this.deleteButton.style.display = 'none';
 		}
 	},
 
 	deleteEntry: function(/*object*/event) {
-		//	summary: 
+		//	summary:
 		//		Function to handle the delete event and delete the entry.
-		// 	description: 
+		// 	description:
 		//		Function to handle the delete event and delete the entry.
 		//
 		//	returns:
@@ -700,20 +700,20 @@ dojo.declare("dojox.atom.widget.FeedViewerEntry",[dijit._Widget, dijit._Template
 	},
 
 	onClick: function(/*object*/e){
-		//	summary: 
+		//	summary:
 		//		Attach point for when a row is clicked on.
-		// 	description: 
+		// 	description:
 		//		Attach point for when a row is clicked on.
 		//
-		// 	e: 
+		// 	e:
 		//		The event generated by the click.
 	}
 });
 
 dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget, dijit._Templated],{
-	//	summary: 
+	//	summary:
 	//		Grouping of feed entries.
-	//	description: 
+	//	description:
 	//		Grouping of feed entries.
 	templateString: dojo.cache("dojox.atom", "widget/templates/FeedViewerGrouping.html"),
 	
@@ -721,9 +721,9 @@ dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget, dijit._Templ
 	titleNode: null,
 
 	setText: function(text){
-		//	summary: 
+		//	summary:
 		//		Sets the text to be shown above this grouping.
-		//	description: 
+		//	description:
 		//		Sets the text to be shown above this grouping.
 		//
 		//	text:
@@ -735,15 +735,15 @@ dojo.declare("dojox.atom.widget.FeedViewerGrouping",[dijit._Widget, dijit._Templ
 });
 
 dojo.declare("dojox.atom.widget.AtomEntryCategoryFilter",[dijit._Widget, dijit._Templated],{
-	//	summary: 
+	//	summary:
 	//		A filter to be applied to the list of entries.
-	//	description: 
+	//	description:
 	//		A filter to be applied to the list of entries.
 	scheme: "",
 	term: "",
 	label: "",
 	isFilter: true
-});			
+});
 
 dojo.declare("dojox.atom.widget.FeedViewer.CategoryIncludeFilter",null,{
 	constructor: function(scheme, term, label){
@@ -751,15 +751,15 @@ dojo.declare("dojox.atom.widget.FeedViewer.CategoryIncludeFilter",null,{
 		//		The initializer function.
 		//	description:
 		//		The initializer function.
-		this.scheme = scheme; 
-		this.term = term; 
+		this.scheme = scheme;
+		this.term = term;
 		this.label = label;
 	},
 
 	match: function(entry) {
-		//	summary: 
+		//	summary:
 		//		Function to determine if this category filter matches against a category on an atom entry
-		//	description: 
+		//	description:
 		//		Function to determine if this category filter matches against a category on an atom entry
 		//
 		//	returns:
diff --git a/dojox/atom/widget/nls/ar/FeedEntryViewer.js b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
index 234f9c9..a509fa9 100644
--- a/dojox/atom/widget/nls/ar/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ar/FeedEntryViewer.js
@@ -5,7 +5,7 @@
 	contributors: "المساهمين",
 	id: "الكود",
 	close: "[اغلاق]",
-	updated: "تعديل في",
+	updated: "تحديث في",
 	summary: "الملخص",
-	content: "محتويات"
+	content: "المحتويات"
 })
diff --git a/dojox/atom/widget/nls/ar/PeopleEditor.js b/dojox/atom/widget/nls/ar/PeopleEditor.js
index a5dee0c..83b4ce3 100644
--- a/dojox/atom/widget/nls/ar/PeopleEditor.js
+++ b/dojox/atom/widget/nls/ar/PeopleEditor.js
@@ -1,5 +1,6 @@
 ({
 	add: "اضافة",
 	addAuthor: "اضافة مؤلف",
-	addContributor: "اضافة مشارك "
+	addContributor: "اضافة مشارك"
 })
+
diff --git a/dojox/atom/widget/nls/ca/FeedEntryViewer.js b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
index f938907..c9a2b54 100644
--- a/dojox/atom/widget/nls/ca/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ca/FeedEntryViewer.js
@@ -1,5 +1,5 @@
 ({
-	displayOptions: "[opcions de visualització]",
+	displayOptions: "[mostra opcions]",
 	title: "Títol",
 	authors: "Autors",
 	contributors: "Col·laboradors",
diff --git a/dojox/atom/widget/nls/da/FeedEntryViewer.js b/dojox/atom/widget/nls/da/FeedEntryViewer.js
index cd2a6a6..ec18a7e 100644
--- a/dojox/atom/widget/nls/da/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/da/FeedEntryViewer.js
@@ -6,6 +6,7 @@
 	id: "Id",
 	close: "[luk]",
 	updated: "Opdateret",
-	summary: "Summary",
+	summary: "Resumé",
 	content: "Indhold"
 })
+
diff --git a/dojox/atom/widget/nls/fi/FeedEntryViewer.js b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
index 639b219..a2b5378 100644
--- a/dojox/atom/widget/nls/fi/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/fi/FeedEntryViewer.js
@@ -2,10 +2,11 @@
 	displayOptions: "[näyttöasetukset]",
 	title: "Otsikko",
 	authors: "Tekijät",
-	contributors: "Osallistujat",
+	contributors: "Lisääjät",
 	id: "Tunnus",
 	close: "[sulje]",
 	updated: "Päivitetty",
-	summary: "Yhteenveto",
+	summary: "Tiivistelmä",
 	content: "Sisältö"
 })
+
diff --git a/dojox/atom/widget/nls/fi/PeopleEditor.js b/dojox/atom/widget/nls/fi/PeopleEditor.js
index c8dd991..973d352 100644
--- a/dojox/atom/widget/nls/fi/PeopleEditor.js
+++ b/dojox/atom/widget/nls/fi/PeopleEditor.js
@@ -1,5 +1,6 @@
 ({
 	add: "Lisää",
 	addAuthor: "Lisää tekijä",
-	addContributor: "Lisää osallistuja"
+	addContributor: "Lisää lisääjä"
 })
+
diff --git a/dojox/atom/widget/nls/he/FeedEntryViewer.js b/dojox/atom/widget/nls/he/FeedEntryViewer.js
index 9e1bfd5..3dbd2c8 100644
--- a/dojox/atom/widget/nls/he/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/he/FeedEntryViewer.js
@@ -1,5 +1,5 @@
 ({
-	displayOptions: "[הצגת אפשרויות]",
+	displayOptions: "[אפשרויות הצגה]",
 	title: "כותרת",
 	authors: "מחברים",
 	contributors: "תורמים",
@@ -9,3 +9,4 @@
 	summary: "סיכום",
 	content: "תוכן"
 })
+
diff --git a/dojox/atom/widget/nls/kk/FeedEntryEditor.js b/dojox/atom/widget/nls/kk/FeedEntryEditor.js
new file mode 100644
index 0000000..4b9cd45
--- /dev/null
+++ b/dojox/atom/widget/nls/kk/FeedEntryEditor.js
@@ -0,0 +1,7 @@
+({
+	doNew: "[жаңа]",
+	edit: "[өңдеу]",
+	save: "[сақтау]",
+	cancel: "[болдырмау]"
+})
+
diff --git a/dojox/atom/widget/nls/kk/FeedEntryViewer.js b/dojox/atom/widget/nls/kk/FeedEntryViewer.js
new file mode 100644
index 0000000..4d85bde
--- /dev/null
+++ b/dojox/atom/widget/nls/kk/FeedEntryViewer.js
@@ -0,0 +1,12 @@
+({
+	displayOptions: "[көрсету параметрлері]",
+	title: "Тақырып",
+	authors: "Авторлар",
+	contributors: "Таратушылар",
+	id: "ID коды",
+	close: "[жабу]",
+	updated: "Жаңартылған",
+	summary: "Жиынтық",
+	content: "Мазмұн"
+})
+
diff --git a/dojox/atom/widget/nls/kk/FeedViewerEntry.js b/dojox/atom/widget/nls/kk/FeedViewerEntry.js
new file mode 100644
index 0000000..386f242
--- /dev/null
+++ b/dojox/atom/widget/nls/kk/FeedViewerEntry.js
@@ -0,0 +1,4 @@
+({
+	deleteButton: "[Жою]"
+})
+
diff --git a/dojox/atom/widget/nls/kk/PeopleEditor.js b/dojox/atom/widget/nls/kk/PeopleEditor.js
new file mode 100644
index 0000000..c83fc47
--- /dev/null
+++ b/dojox/atom/widget/nls/kk/PeopleEditor.js
@@ -0,0 +1,6 @@
+({
+	add: "Қосу",
+	addAuthor: "Авторды қосу",
+	addContributor: "Салымшыны қосу"
+})
+
diff --git a/dojox/atom/widget/nls/ko/FeedEntryViewer.js b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
index b7e07c5..32e7013 100644
--- a/dojox/atom/widget/nls/ko/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/ko/FeedEntryViewer.js
@@ -2,10 +2,10 @@
 	displayOptions: "[옵션 표시]",
 	title: "제목",
 	authors: "작성자",
-	contributors: "속성",
+	contributors: "기고자",
 	id: "ID",
 	close: "[닫기]",
-	updated: "갱신",
+	updated: "업데이트된 날짜",
 	summary: "요약",
 	content: "컨텐츠"
-})
\ No newline at end of file
+})
diff --git a/dojox/atom/widget/nls/pl/FeedEntryEditor.js b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
index 5780e6d..9fd4973 100644
--- a/dojox/atom/widget/nls/pl/FeedEntryEditor.js
+++ b/dojox/atom/widget/nls/pl/FeedEntryEditor.js
@@ -1,6 +1,7 @@
 ({
-	doNew: "[Nowy]",
-	edit: "[Edytuj]",
-	save: "[Zapisz]",
-	cancel: "[Anuluj]"
-})
\ No newline at end of file
+	doNew: "[nowy]",
+	edit: "[edytuj]",
+	save: "[zapisz]",
+	cancel: "[anuluj]"
+})
+
diff --git a/dojox/atom/widget/nls/pl/FeedEntryViewer.js b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
index 8dbf4d0..312e10c 100644
--- a/dojox/atom/widget/nls/pl/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/pl/FeedEntryViewer.js
@@ -1,11 +1,12 @@
 ({
-	displayOptions: "[Opcje wyświetlania]",
+	displayOptions: "[opcje wyświetlania]",
 	title: "Tytuł",
 	authors: "Autorzy",
 	contributors: "Kontrybutorzy",
 	id: "Identyfikator",
-	close: "[Zamknij]",
+	close: "[zamknij]",
 	updated: "Zaktualizowano",
 	summary: "Podsumowanie",
 	content: "Treść"
-})
\ No newline at end of file
+})
+
diff --git a/dojox/atom/widget/nls/sl/PeopleEditor.js b/dojox/atom/widget/nls/sl/PeopleEditor.js
index 28ad1fc..fb52910 100644
--- a/dojox/atom/widget/nls/sl/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sl/PeopleEditor.js
@@ -1,6 +1,6 @@
 ({
 	add: "Dodaj",
 	addAuthor: "Dodaj avtorja",
-	addContributor: "Dodaj kontributorja,"
+	addContributor: "Dodaj kontributorja"
 })
 
diff --git a/dojox/atom/widget/nls/sv/PeopleEditor.js b/dojox/atom/widget/nls/sv/PeopleEditor.js
index 379162d..83a7320 100644
--- a/dojox/atom/widget/nls/sv/PeopleEditor.js
+++ b/dojox/atom/widget/nls/sv/PeopleEditor.js
@@ -1,5 +1,5 @@
 ({
-	add: "Lägg til ",
+	add: "Lägg till",
 	addAuthor: "Lägg till författare",
 	addContributor: "Lägg till medverkande"
 })
diff --git a/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
index 22b3181..9da61f8 100644
--- a/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
+++ b/dojox/atom/widget/nls/zh-tw/FeedEntryViewer.js
@@ -2,10 +2,10 @@
 	displayOptions: "[顯示選項]",
 	title: "標題",
 	authors: "作者",
-	contributors: "提出者",
+	contributors: "貢獻者",
 	id: "ID",
 	close: "[關閉]",
 	updated: "已更新",
 	summary: "摘要",
 	content: "內容"
-})
\ No newline at end of file
+})
diff --git a/dojox/atom/widget/nls/zh-tw/PeopleEditor.js b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
index af77df9..e4c675d 100644
--- a/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
+++ b/dojox/atom/widget/nls/zh-tw/PeopleEditor.js
@@ -1,5 +1,5 @@
 ({
 	add: "新增",
 	addAuthor: "新增作者",
-	addContributor: "新增提出者"
-})
\ No newline at end of file
+	addContributor: "新增貢獻者"
+})
diff --git a/dojox/calc/FuncGen.js b/dojox/calc/FuncGen.js
new file mode 100644
index 0000000..a7634fe
--- /dev/null
+++ b/dojox/calc/FuncGen.js
@@ -0,0 +1,139 @@
+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) {
+
+dojo.experimental("dojox.calc.FuncGen");
+
+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?");
+			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");
+
+		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.deleteItem(item);
+				this.writeStore.save();
+
+				this.deleteFunction(name);
+				delete this.functions[name];
+				this.clear();
+			}
+		}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
+
+	/*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);
+	},*/
+
+	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
+		}
+	}
+});
+
+
+return dojox.calc.FuncGen;
+});
diff --git a/dojox/calc/GraphPro.js b/dojox/calc/GraphPro.js
new file mode 100644
index 0000000..c8deb12
--- /dev/null
+++ b/dojox/calc/GraphPro.js
@@ -0,0 +1,136 @@
+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) {
+
+dojo.experimental("dojox.calc.GraphPro");
+
+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,
+
+	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();
+
+		var pane = dojo.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.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();
+
+		var pane = dojo.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;
+
+		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';
+					}
+					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 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;
+});
diff --git a/dojox/calc/Grapher.js b/dojox/calc/Grapher.js
new file mode 100644
index 0000000..ff270b0
--- /dev/null
+++ b/dojox/calc/Grapher.js
@@ -0,0 +1,623 @@
+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) {
+
+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
+		epsilon = 1e-15 / 9,
+		bigNumber = 1e200,
+		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){
+		// 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);
+
+			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;
+			}
+			if(points[series].length < 4){
+				continue;
+			}
+
+			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]);
+				}
+				for(k = 1; k < a.length; k++){
+					points[++series] = a.pop();
+				}
+				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;
+				}
+				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;
+				}
+				// 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]);
+				}
+			}else{
+				points2[s].push(points[k]);
+			}
+		}
+		return points2;
+
+		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]);
+
+				if(minMaxY==mid[y]||mid[x]==right[x]||mid[x]==left[x]){
+					return mid;
+				}
+
+				var moveTowardsLarger = true;
+				if(minMaxY<mid[y]){
+					moveTowardsLarger = false;
+				}
+
+				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;
+		}
+
+		function asymptoteSearch(funcToGraph, pointStart, pointStop){
+			var
+				pointTemp = [ [], [] ],
+				left = pointStart,
+				right = pointStop,
+				midpoint;
+
+
+			while(left[x] <= right[x]){
+				var midX = (left[x] + right[x]) / 2;
+
+				midpoint = {};
+				midpoint[x] = midX;
+				midpoint[y] = funcToGraph(midX);
+
+				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;
+					}
+					right = midpoint;
+				}
+					
+			}
+			return pointTemp;
+		}
+
+		function getSlopePairTrend(slope1, slope2){
+			var
+				isInc = false,
+				isPos = false;
+
+			if (slope1 < slope2){
+				isInc = true;
+			}
+			if (slope2 > 0){
+				isPos = true;
+			}
+			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
+					}else{
+						delta = v / Math.ceil(v / epsilon); // divide distance to 0 into equal tiny chunks
+					}
+				}else{
+					delta = epsilon;
+				}
+			}else{
+				delta = Math.abs(v) * epsilon;
+			}
+			return v + delta;
+		}
+
+		function slope(p1, p2){
+			return (p2[y] - p1[y]) / (p2[x] - p1[x]);
+		}
+	};
+})();
+
+
+return dojox.calc.Grapher;
+});
diff --git a/dojox/calc/Readme.txt b/dojox/calc/Readme.txt
new file mode 100644
index 0000000..b70d1c7
--- /dev/null
+++ b/dojox/calc/Readme.txt
@@ -0,0 +1,175 @@
+Dojo Toolkit Graphing Calculator Project Readme
+Author: Jason Hays
+Trac ID: jason_hays22
+
+Contents:
+	Expressions
+	Variables, Functions, and uninitializing variables
+	toFrac in GraphPro
+	Numbers and bases
+	Graphing equations
+	Substitutes for hard to type characters
+	Making Functions
+	Decimal points, commas, and semicolons in different languages
+	Important mathematical functions
+
+
+
+---------------Expressions----------------
+The calculator has the ability to simplify a valid expression.
+With Augmented Mathematical Syntax, users are allowed to use nonstandard operators in their expressions.  Those operators include ^, !, and radical.
+
+^ is used for exponentiation.
+	It is a binary operator, which means it needs a number on both the left and right side (like multiplication and division)
+	2^5 is an example of valid use of ^, and represents two to the power of five.
+
+! is used for factorial.
+	It supports numbers that are not whole numbers through the use of the gamma function.  It uses the number on its left side.  Both 2! and 2.6! are examples of valid input in America. (2,6! is valid in some nations)
+
+radicals can be used for either square root or various other roots.
+	to use it as a square root sign, there should only be a number on its right.  If you put a number on the left as well, then it will use that number as the root.
+
+To evaluate an expression, type in a valid expression, such as 2*(10+5), into the input box.  If you are using GraphPro, then it is the smaller text box.
+	After you have chosen an expression, press Enter on either your keyboard or on the lower right of the calculator.
+		If it did not evaluate, make sure you correctly closed your parentheses.
+	In the Standard calculator, the answer will appear in the input box, in GraphPro, the answer will appear in the larger text box above.
+	On the keyboard, you can navigate through your previous inputs with the up and down arrow keys.
+
+If you enter an operator when the textbox is empty or highlighted (like *) then Ans* should appear.  That means the answer you got before will be multiplied by whatever you input next.
+So try Ans*3.  Whenever you start the calculator, Ans is set to zero.
+
+
+--------------Variables, Functions, and uninitializing variables----------------
+A variable is basically something that stores a value.  If you saw Ans in the previous example, you've also seen a variable.
+If you want to store your own number somewhere, you'll need to use the = operator.
+
+	Valid variable and function names include cannot start with numbers, do not include spaces, but can start with the alphabet (a-z or A-Z) and can have numbers within the names "var1" is a valid name
+
+	Input "myVar = 2" into the textbox and press "Enter."  You've just saved a variable.  Now if you ever type myVar into an expression, 2 will appear (unless you change it to something else).
+	Variables are best used to store Ans.  Ans is overridden whenever you evaluate an expression, so it is good to store the value of Ans somewhere else before it is overridden.
+
+	If you want a variable (like myVar) to become empty, or undefined, you just need to set it equal to undefined.
+	Now try "myVar = undefined"  Now myVar is no longer defined.
+
+	Functions are very useful for finding answers and gathering data.
+		You can use functions by inputting their name and their arguments.
+		For this example, I'll be using the functions named "sqrt" and "pow"
+
+		sqrt is a function with one argument.  That argument has a name too, its name is 'x.' x is a very common name amongst built in functions
+			So, let's run a function.  Input "sqrt" then input a left parenthesis (all arguments of a function go within parentheses).  Now type a value for x, like 2.
+			Now close the parentheses with the right parenthesis.  If you used 2, you should have "sqrt(2)" in the text box.  If you press enter, you should get the square root of 2 back from the calculator.
+
+		Now for "pow" it has two arguments 'x' and 'y'
+			Type in "pow(" and pick a value for 'x' (I am picking 2 again)
+			but now, you need to separate the value you gave x with a list separator.  Depending on your location, it is either a comma or a semicolon.  I'm in America, and I use commas.
+			by this point, I have "pow(2,"
+			Now we need a value for 'y' (I'm using 3).  Put a ')' and now I have 'pow(2,3)'
+			Press Enter, and, following my example, you should get 8
+
+		In this calculator, there are several ways to input arguments.
+			You've already seen the first way, just input numbers in a specific order based on the names.
+
+			The second way is with an arbitrary order, and storage.
+			With 'pow' I can input "pow(y=3, x=2)" and get the exact answer as before.  x and y will retain their assigned values, so you will need to set them to undefined it you want to try the next way.
+
+			The third way is to let the calculator ask you for the values.  Input "pow()"  If the values have been assigned globally, then it will use those values, but otherwise, it will ask for values of x and y.  They will not be stored globally this way.
+
+	I'll go ahead and mention that because of the way the calculator parses, underscores should not be used to name a variable like _#_ (where # is an integer of any length) 
+
+---------------toFrac()----------------
+toFrac is a function that takes one parameter, x, and converts it to a fraction for you.  It is only in GraphPro, not the Standard mode.
+	It will try to simplify pi, square roots, and rational numbers where the denominator is less than a set bound (100 right now).
+	Immediately after the calculator starts, toFrac may seen slow, but it just needs to finish loading when the calculator starts.  After that, it will respond without delay.
+	For an example, input "toFrac(.5)" or (,5 for some).  It will return "1/2"
+	For a more complicated example, input "toFrac(atan(1))" to get back "pi/4"  (atan is also known as "arc tangent" or "inverse tangent")
+
+--------------Numbers and bases----------------
+This calculator supports multiple bases, and not only that, but non integer versions of multiple bases.
+	What is a base?  Well, the numbers you know and love are base 10.  That means that you count to all of the numbers up until 10 before you move on to add to the tenths place.
+		So, what about base 2?  All of the numbers up until 2 are 0 and 1.  If you want to type a base 2 number into the calculator, simply input "0b" (meaning base 2) followed by some number of 1's and 0's. 0b101 is 5 in base 10
+
+		Hexadecimal is 0x, and octal is 0o, but i won't go into too much detail on those here.
+		If you want an arbitrary integer base, type the number in the correct base, insert '#' and put the radix on the end.  ".1#3" is the same as 1/3 in base 10
+			Because there is not yet cause for it, you cannot have a base that is not a whole number.
+
+--------------Graphing Equations----------------
+First thing is first, in GraphPro only, the "Graph" button in the top left corner opens the Graph Window
+	So, now you should see a single text box adjacent to "y="
+	Type the right side of the equation using 'x' as the independent variable.
+	"sin(x)" for example.  To Graph it, make sure the checkbox to the left of the equation is selected, and press the Draw Selected button.
+	You can change the color in the color tab.  By default, it is black.  Under window options, you can change the window size and x/y boundaries
+
+	Let's add a second function.  Go to the Add Function button, select the mode you want, and press Create.  Another input box will appear.
+	If you selected x= as the Mode, then y is the independent variable for the line (an example is "x=sin(y)").
+		If you want to erase, check the checkboxes you want to erase, and press "Erase Selected"
+		And similarly, Delete Selected will delete the chosen functions
+
+	"Close" will terminate the Graph Window completely
+
+---------------Substitutes for hard to type characters---------------
+Some characters are not simple to add in for keyboard users, so there are substitutes that are much easier to add into the text box.
+
+	pi or PI can be used in place of the special character for it.
+	For epsilon, eps or E can be used.
+	radical has replacement functions.  sqrt(x) or pow(x,y) can be used instead.
+
+--------------Making Functions-----------------
+My favorite part.  Before we start, I'll mention that Augmented Mathematical Syntax is allowed in the Function Generator (yay).
+	Ok, now the bad news: to prevent some security issues, keywords new and delete are forbidden.
+	Sorry, it is a math calculator, not a game container; not that that would be so bad, but it is to keep it from being used for some evil purposes.
+
+	Ok, onto function making.  Most JavaScript arithmetic is supported here, but, some syntax was overlapping mathematical syntax, so ++Variable no longer increases the contents of Variable because of ++1, but Variable++ does increase it (same deal with --)
+		Strings have incredibly limited support. Objects have near zero support
+	So, let's make a Function:
+		Press the "Func" button.  A Function Window should pop up.
+		Enter a name into the "functionName" box.  (it must follow the name guidelines in the variables section)  I'm putting myFunc
+		Enter the variables you want into the arguments box (I'll put "x,y" so I have two arguments x and y)
+		Now enter the giant text box.
+		Type "return " and then the expression you want to give to the calculator.  I'm putting "return x*2 + y/2"
+		Then press Save.  Now your function should appear in the functionName list and you can call it in the Calculator.
+
+		If you want to Delete a function you made, select it in the function Name list, and then press Delete.
+		If you altered a previously saved function (and haven't saved over the old one) you can reset the text back to its original state with the Reset button.
+		Clear will empty out all of the text boxes in the Function Window
+		Close terminates the Function Window
+
+---------------Decimal points, commas, and semicolons in different languages----------------
+In America, 3.5 is three and one half. Comma is used to separate function parameters and list members.
+
+In some nations, 3,5 is three and one half.  In lists, ;'s are used to separate its members.
+So, when you evaluate expressions, 3,5 will be valid, but in the function generator, some ambiguous texts prevent me from allowing the conversion of that format to JavaScript.  So I cannot parse it in the Function Generator.
+And here is my example:
+var	i = 3,5;
+	b = 2;
+I cannot discern whether the semicolon between i and b are list separators or the JavaScript character for end the line.  b could be intended as a global variable, and i is a local variable, but I don't know that.  So language conversion isn't supported in Function Making.
+
+--------------Important mathematical Functions---------------
+Here is a list of functions you may find useful and their variable arguments:
+
+sqrt(x)	returns the square root of x
+x is in radians for all trig functions
+sin(x)	returns the sine of x
+asin(x)	returns the arc sine of x
+cos(x)	returns the cosine of x
+acos(x)	returns the arc cosine of x
+tan(x)	returns the tangent of x
+atan(x)	returns the arc tangent of x
+
+atan2(y, x)	returns the arc tangent of y and x
+Round(x)	returns the rounded integer form of x
+Int(x)		Cuts off the decimal digits of x
+Ceil(x)		If x has decimal digits, get the next highest integer
+
+ln(x)	return the natural log of x
+log(x)	return log base 10 of x
+pow(x, y) return x to the power of y
+
+permutations(n, r)	get the permutations for n choose r
+P(n, r) see permutations
+combinations(n, r)	get the combinations for n choose r
+C(n, r) see combinations
+
+toRadix(number, baseOut)	convert a number to a different base (baseOut)
+toBin(number)			convert number to a binary number
+toOct(number)			convert number to an octal number
+toHex(number)			convert number to a hexadecimal number
diff --git a/dojox/calc/Standard.js b/dojox/calc/Standard.js
new file mode 100644
index 0000000..30be807
--- /dev/null
+++ b/dojox/calc/Standard.js
@@ -0,0 +1,356 @@
+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) {
+
+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"),
+
+	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);
+		}));
+	},
+
+	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]);
+			}
+		}
+		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)}
+			});
+		}
+	},
+
+	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);
+				}
+				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.commandIndex = this.commandList.length-1;
+			//this.displayBox.textbox.scrollTop=this.displayBox.textbox.scrollHeight;
+			if(this.hasDisplay){
+				this.displayBox.scrollTop=this.displayBox.scrollHeight;
+			}
+			//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;
+
+			}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();
+				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;
+
+				}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"
+				dijit.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;
+			}
+		}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 = 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;
+		}
+
+		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;
+			}
+			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;
+
+		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));
+
+
+		//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()
+	}
+});
+
+
+return dojox.calc.Standard;
+});
diff --git a/dojox/calc/_Executor.js b/dojox/calc/_Executor.js
new file mode 100644
index 0000000..eb487ef
--- /dev/null
+++ b/dojox/calc/_Executor.js
@@ -0,0 +1,146 @@
+define("dojox/calc/_Executor", ["dojo", "dijit/_Templated", "dojox/math/_base"], function(dojo) {
+
+dojo.experimental("dojox.calc._Executor");
+
+(function(){
+var calcEnv; // 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>',
+
+	_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 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
+
+
+		//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 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(){
+	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){
+			// 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;
+});
diff --git a/dojox/calc/_ExecutorIframe.html b/dojox/calc/_ExecutorIframe.html
new file mode 100644
index 0000000..d17d326
--- /dev/null
+++ b/dojox/calc/_ExecutorIframe.html
@@ -0,0 +1,525 @@
+<html><head>
+<script>
+Array.prototype._toString = Array.prototype.toString;
+Array.prototype.toString = function(){ return "[" + this._toString() + "]"; };
+
+Number.prototype._toString = Number.prototype.toString;
+Number.prototype.toString = function(radix){ if(!radix || radix==10){ return ""+this._toString() } if(radix==2){ return "0b"+this._toString(radix); } if(radix==8){ return "0o"+this._toString(radix); } if(radix==16){ return "0x"+this._toString(radix); } return this._toString(radix) + "#" + radix._toString(); };
+
+(function(){ // env is private
+	parseFloat = function(str){
+	var obj = null;
+	function getRadixObject(whole, numberStr, base){
+		obj = {number:numberStr, radix:base};
+		return "";
+	}
+	function getBaseString(whole, base, numberStr){
+		var baseNum = (base == '0b') ? 2 : (base == '0o') ? 8 : 16;
+		return numberStr+"#"+baseNum;
+	}
+
+
+	var str = str.replace(/(0b|0o|0x)(([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+))/, getBaseString);
+
+	var radix;
+
+	var poundRegExp = /([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+)\#([0-9a-zA-Z]+)/g;
+	if(poundRegExp.test(str)){
+		// define obj in getRadixObject
+		str.replace(poundRegExp, getRadixObject);
+		radix = obj.radix;
+		str = obj.number;
+	}
+	if(!radix){
+		radix = 10;
+	}
+	var decimal = str.indexOf('.');
+	if(decimal>=0){
+		var left = str.substring(0,decimal);
+		if(left == ""){
+			left = "0";
+		}
+		var right = str.substring(decimal+1, str.length);
+		if(right == ""){
+			right = "0";
+		}
+		var num = parseInt(left, radix);
+
+		var dec = parseInt(right, radix);
+		var length = dec._toString().length;
+		dec /= Math.pow(radix, right.length);
+		return num+dec;
+	}
+	return parseInt(str, radix);
+};
+
+	var env = {
+		window: undefined, "delete": undefined, "new": undefined, // invalidate access to the globals for security so that window.blah is invalid as is delete window
+
+		prompt: function(label, defaultValue){
+			// summary
+			//	prompt the user for input without making IE8 mad.
+			// params
+			//	label: the String name of the variable you are asking the user to input
+			//	defaultValue: primitive, the prompt will show this value initially
+
+			label = label || '';
+			defaultValue = defaultValue || '';
+			try{
+				return this.outerPrompt(label, defaultValue);
+			}catch(e){
+				return window.prompt(label, defaultValue);
+			}
+		},
+		val: function(local, name, obj){
+			// summary
+			//	allow the user to use locals, globals, or give input for undefined values
+			// params:
+			//	local, a primitive object, is what value might've been passed to val as a local parameter.
+			//	name is the String name of the object.  It is passed to see if there is an available global or to set the global.
+			var objValue = obj[name];
+			local = (objValue == undefined) ? (local == undefined ? window[name] : local) : objValue ;
+
+			if(typeof local == 'undefined'){
+				if(obj.graphing){
+					return undefined;
+				}
+				local=this.prompt('Enter the value for ' + name, undefined, name);
+
+				return local == null ? undefined : (isNaN(Number(local)) ? local : Number(local));
+			}
+			return local;
+		},
+		_makeKeywordsLiteral: function (text){
+			// summary
+			//	surround reserved words with hex characters
+			// ==, then >=. the <=, then !=, then = and surround them with \x0n first
+			text = text.replace(/(!=(?!=)|==|>=|<=|=)/g, "\x02$1\x02");
+			return text.replace(/\b(abstract|boolean|break|byte|case|catch|char|class|const|continue|debugger|default|do|double|else|enum|export|extends|false|final|finally|float|for|function|goto|if|implements|import|in| instanceof|int|interface|long|native|null|package|private|protected|public|return|short|static|super| switch|synchronized|this|throw|throws|transient|true|try|typeof|var|void|volatile|while|with)\b/g, "\x02$1\x02");
+		},
+		switchToGermanNumbers: function(text){
+			// summary
+			//	change the format of some javascript allowed numbers to an alternate form 3.5 goes to 3,5
+			var num = 0;
+			var numbers = [];
+			function substituteCommas(whole, junk, text){
+				numbers['_'+num+'_'] = text.replace(/\,/g, ';');
+				return junk+'_'+(num++)+'_';
+			}
+			function substituteNumbers(wholematch, stuff, junk, text, stuff2){
+				return stuff+numbers[text]+stuff2;
+			}
+			if(typeof text != "string"){
+				text = text.toString();
+			}
+			if(text.indexOf('\x02')<0){
+				text = this._makeKeywordsLiteral(text);
+				//text = text.replace(/(!=(?!=)|==|>=|<=|=)/g, "\x02$1\x02");
+			}
+
+			// same as semiColonRegExp
+			var commaRegExp = /([^\x02\s]*)(\([^\(\)]+\)|\[[^\[\]]+\])/;
+			while(commaRegExp.test(text)){
+				text = text.replace(commaRegExp , substituteCommas);
+			}
+
+			while(/((\W)*)(\_[0-9]+\_)((\W)*)/.test(text)){
+				text = text.replace(/((\W)*)(\_[0-9]+\_)((\W)*)/g, substituteNumbers);
+			}
+
+			text = text.replace(/([0-9]*)\.([0-9]+)/g, "$1"+','+"$2");
+
+			// get rid of keyword characters (duplicate code from parse())
+			return text.replace(/\x02((.|\s)*?)\x02/g, "$1");
+		},
+		normalizeTextLanguage: function(text){
+			// summary
+			//	change text to use javascript list separators and decimal points instead of commas
+			// params
+			//	text is a string like "pow(3,1; 4);"
+			//		for that input, this method should return "pow(3.1, 4);"
+
+			var num = 0;
+			var numbers = [];
+			function substituteSemicolons(whole, junk, text){
+				numbers['_'+num+'_'] = text.replace(/\;/g, ',');
+				return junk+'_'+(num++)+'_';
+			}
+			function substituteNumbers(wholematch, stuff, junk, text, stuff2){
+				return stuff+numbers[text]+stuff2;
+			}
+			if(text.indexOf('\x02')<0){
+				text = this._makeKeywordsLiteral(text);
+			}
+			// change all comma-type decimals into periods
+			text = text.replace(/([0-9]*)\,([0-9]+)/g, "$1"+'.'+"$2");
+			//alert(text);
+			var semiColonRegExp = /([^\x02\s]*)(\([^\(\)]+\)|\[[^\[\]]+\])/; // /([^\x02\s]+)(\([^\(\)]+\)|\[[^\[\]]+\])/; // /[^\x02\s]+\([^\(\)]+\)|[^\x02\s]+\[[^\[\]]+\]/; // /[^\x02]\s*\([^\(]+\)/;
+			while(semiColonRegExp.test(text)){
+				text = text.replace(semiColonRegExp, substituteSemicolons);
+			}
+			while(/((\W)*)(\_[0-9]+\_)((\W)*)/.test(text)){
+				text = text.replace(/((\W)*)(\_[0-9]+\_)((\W)*)/g, substituteNumbers);
+			}
+			// get rid of keyword characters (duplicate code from parse())
+			return text.replace(/\x02((.|\s)*?)\x02/g, "$1");
+		},
+		preparse: function(text){
+			// summary
+			//	change the numbers to javascript allowed numbers if it is from a different locale
+			if(!this.isJavaScriptLanguage){
+				text = this.normalizeTextLanguage(text);
+			}
+			return text;
+		},
+		// parseFloat(Number(4.5).toString(3)) should return 4.5
+
+		postparse: function(text){
+			// summary
+			//	make the javascript numbers match the locale
+			if(!this.isJavaScriptLanguage){
+				text = this.switchToGermanNumbers(text);
+			}
+			return text;
+		},
+		toDecimalRegExp: function(whole, base, number){
+			// summary
+			//	get the decimal number from a float
+			function getBase(base){
+				switch(base){
+					case '0b':
+						return 2;
+					case '0o':
+						return 8;
+					case '0x':
+						return 16;
+					default:
+						return 10;
+				}
+			}
+			//return parseInt(base, getBase(base));
+			return parseFloat(base+number);
+		},
+		parse: function(text){
+			// summary
+			//	This parses augmented mathematical syntax and converts it to executable JavaScript.
+			// params:
+			//	text should be a String which represents an expression, a function, a number, etc
+			//
+			// this array holds the substitutions that represent an expression's parentheses and functions in a simplified way.
+			var	numbers = [],
+				// characters
+				functionContentsChar = '\x03',
+			// these are the regular expression needed to find and replace operators
+				factorialRE = /((\w|\.)+)\s*\!/,
+				unaryRightsideRE = /(^|[\+\-\/\*\!\^\u221A]+\s*)([\+\-]+)\s*((\w|\.)+)(?!.*[\+\-])/,
+				unaryRE = /(^|[^a-zA-Z0-9_\.\s]+\s*)([\+\-]+|\u221A)\s*((\w|\.)+)/,		 // /(^|[^a-zA-Z0-9_\.]\s*)([\+\-]+|\u221A)\s*((\w|\.)+)/,
+				caretRE = /((\w|\.)+)\s*([\^])\s*((\w|\.)+)/, // /((\w|\.)+)\s*([\^])\s*(-?\s*(\w|\.)+)/, 
+				radicalRE = /((\w|\.)+)\s*(\u221A)\s*([+-]?\s*(\w|\.)+)/, // /((\w|\.)+)\s*(\u221A)\s*([+-]?\s*(\w|\.)+)(?!.*\u221A)/,
+				binaryHighRE = /((\w|\.)+)\s*([*/])\s*((\w|\.)+)/,
+				binaryLowRE = /((\w|\.)+)\s*([\+\-])+\s*((\w|\.)+)/;
+
+			// get rid of all new and delete statements
+			text = exterminateNewAndDelete(text);
+			// make all keywords and operators literal (like '!=' or 'return') by surrounding them with unprintable characters
+			text = this._makeKeywordsLiteral(text);
+
+
+			function getBaseTen(whole, numberStr, base){
+				return ""+parseFloat(numberStr+"#"+parseInt(base));
+			}
+			text = text.replace(/(0b)([0-1]+\.[0-1]*|\.[0-1]+|[0-1]+)/g, this.toDecimalRegExp);
+			text = text.replace(/(0o)([0-7]+\.[0-7]*|\.[0-7]+|[0-7]+)/g, this.toDecimalRegExp);
+			text = text.replace(/(0x)([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+)/g, this.toDecimalRegExp);
+
+			text = text.replace(/([0-9a-zA-Z]+\.[0-9a-zA-Z]*|\.[0-9a-zA-Z]+|[0-9a-zA-Z]+)\#([0-9a-zA-Z]+)/g, getBaseTen);
+
+			// parse the input to form JavaScript
+			return MathParser(text);
+
+			function MathParser(text){
+				// Pi is better represented by \u03C0, but isn't computable
+				text = text.replace(/\u03C0/g,"Math.PI");
+				text = text.replace(/\u03F5/g,"Math.E");
+
+				// Microsoft word will give you these '\u2013' for a subtraction sign sometimes, so I'll fix that here
+				text = text.replace(/\u2013/g, "-");
+				// add unreadable characters in front of functions so it is easier to manipulate
+				text = text.replace(/(((\w|\.)+\s*)\()/g,putFuncChar);
+
+				// change 10e-10 or 10e10 or 10e+10 to an constant right away
+				text = scientificNotationSimplifier(text);
+				// recursively track down and replace all simplified parts of the expression until everything is simple; then move the simple text into the correct JavaScript format
+				text = parseRecursive(text);
+				// now resubstitute the real text back into the string now that it is arranged correctly
+				while (hasArrayIndexBasedOnUnderscore(text)){
+					text  = text.replace(/\_(\d+)\_/g, function(whole, one){return numbers[parseInt(one)]});
+				}
+				// get rid of the function character from the functions now
+				text = text.replace(/\x01/g,"");
+				// get rid of keyword characters too
+				text = text.replace(/\x02((.|\s)*?)\x02/g, "$1");
+				return text;
+			}
+			function exterminateNewAndDelete(text){
+				return text.replace(/\b(delete|new|this\.*)\b/, "");
+			}
+			// A simple grouping has no parentheses inside the initial pair.
+			function isSimpleGrouping(text){
+				return (/^\([^()]*\)|\W\([^()]*\)/).test(text);
+			}
+			function ReplaceSimpleGrouping(text){
+				return text.replace((/(^|\W)(\([^()]*\))/), replaceWithNum);
+			}
+			function replaceWithNum(wholeMatch, partMatch1, partMatch2){
+				numbers.push(partMatch2);
+				return partMatch1+"_"+(numbers.length-1)+"_";
+			}
+			function replaceFuncWithNum(wholeMatch){
+				numbers.push(wholeMatch);
+				return "_"+(numbers.length-1)+"_";
+			}
+			// A simple function has no parentheses within its parentheses, and has the special character \x01 leading up to the name and (...)
+			function isSimpleFunction(text){
+				return (/\x01((\w|\.)+\s*)\([^()]*\)/).test(text);
+			}
+			function ReplaceSimpleFunction(text){
+				return text.replace(/\x01((\w|\.)+\s*)\([^()]*\)/, replaceFuncWithNum);
+			}
+			function FactorialParser(text){
+				// loop this untill all ! are gone (in main)
+				return text.replace(factorialRE, "\x01"+"factorial($1)");
+			}
+			function putFuncChar(wholematch){
+				return '\x01'+wholematch;
+			}
+			function putInPiece(wholematch){
+				return numbers[currentNum];
+			}
+
+			function caretParser(text){
+				return text.replace(caretRE, replaceBinaryOp);
+			}
+			// the unary radical is inside the unaryOperatorParse(text) function
+			function radicalOperatorParse(text){
+				return text.replace(radicalRE, replaceBinaryOp);
+			}
+			function replaceBinaryOp(wholeMatch, operand1, nothing1, operator, operand2){
+
+				switch(operator.charAt(0)){
+					case '^':
+						return "\x01"+"pow("+operand1+","+operand2+")";
+					case '\u221A':
+						return "\x01"+"pow("+operand2+", 1/"+operand1+")";
+					case '*':
+					case '/':
+						return replaceFuncWithNum(wholeMatch);
+					case '+':
+					case '-':
+					case 'e':
+						return replaceFuncWithNum(simplifyPlusAnsMinus(wholeMatch));
+				}
+			}
+			// e is treated as a binary operator
+			function scientificNotationSimplifier(text){
+				//return text.replace(/((\w|\.)+)\s*([\e])\s*([+-]*\s*(\w|\.)+)/g, replaceBinaryOp);
+				return text.replace(/(([0-9]+\.?[0-9]*))(e)([+-]*([0-9]+))/g, replaceBinaryOp);
+			}
+			// this handles * and /
+			function binaryHighPriorityOperatorParse(text){
+				return text.replace(binaryHighRE, replaceBinaryOp);
+			}
+			// this handles + and - with two operands
+			function binaryLowPriorityOperatorParse(text){
+				return text.replace(binaryLowRE, replaceBinaryOp);
+			}
+			// this replaces the one operand +'s, -'s, and radicals
+			function replaceUnaryOp(wholeMatch, garbage, operator0, operand0){
+				// see what operator it is
+				switch(operator0.charAt(0)){
+					case '\u221A':
+						return garbage+"\x01"+"sqrt("+operand0+")";
+					case '+':
+					case '-':
+						return garbage+replaceFuncWithNum(simplifyPlusAnsMinus(wholeMatch.substr(garbage.length)));
+				}
+			}
+			// this handles one operand operators -, +, radical
+			function unaryOperatorParse(text){
+				return text.replace(unaryRE, replaceUnaryOp);
+			}
+			// this handles one operand operators on the right side of everything
+			function unaryOperatorRightsideParse(text){
+				return text.replace(unaryRightsideRE, replaceUnaryOp);
+			}
+			function parseRecursive(text){
+				// keep going until there is nothing left that can be simplified
+				while (isSimpleGrouping(text)||isSimpleFunction(text)||factorialRE.test(text)||caretRE.test(text)||radicalRE.test(text)||unaryRE.test(text)||binaryHighRE.test(text)||binaryLowRE.test(text)){
+
+					var sTextOrginal = text;
+
+					if(isSimpleFunction(text)){
+						var debugText = text;
+
+						text = ReplaceSimpleFunction(text);
+						var	s = numbers[numbers.length-1],
+							pL = s.indexOf("("),
+							funcName = s.substring(s.indexOf("\x01")+1, pL),//take out the function character
+							content = s.substring(pL+1, s.length-1);
+
+						numbers[numbers.length-1] = funcName+"("+parseRecursive(functionContentsChar+content)+")";
+						continue;
+					}
+					if(isSimpleGrouping(text)){
+						text = ReplaceSimpleGrouping(text);
+						var	s = numbers[numbers.length-1],
+							content = s.substring(1, s.length-1);
+						numbers[numbers.length-1] = "("+parseRecursive(content)+")";
+						continue;
+					}
+
+					// factorials must come first for 5^2! cases, it equals 25
+					text = FactorialParser(text);
+					if(text!=sTextOrginal){
+						continue;
+					}
+
+					text = caretParser(text);
+					if(text!=sTextOrginal){
+						continue;
+					}
+
+					text = radicalOperatorParse(text);
+					if(text!=sTextOrginal){
+						continue;
+					}
+					text = unaryOperatorRightsideParse(text);
+					if(text!=sTextOrginal){
+						// put parentheses around the unary operators so 0--2 will pass
+						numbers[numbers.length-1] = "("+numbers[numbers.length-1]+")";
+						continue;
+					}
+					text = unaryOperatorParse(text);
+					if(text!=sTextOrginal){
+						// put parentheses around the unary operators so 0--2 will pass
+						numbers[numbers.length-1] = "("+numbers[numbers.length-1]+")";
+						continue;
+					}
+
+					text = binaryHighPriorityOperatorParse(text);
+					if(text!=sTextOrginal){
+						continue;
+					}
+					text = binaryLowPriorityOperatorParse(text);
+					if(text!=sTextOrginal){
+						continue;
+					}
+					// it should never ever make it to this point.  If it does, I'll want to know about it.
+					throw("Parse Error");
+				}
+				// make assignments within function calls be arranged to be (x=y, undefined)
+				if(text.charAt(0) == functionContentsChar){
+					text = text.substring(1, text.length);
+					if(text.indexOf('=') >= 0){
+						text = ReplaceFunctionContentAssignments(text);
+					}
+				}
+
+				return text;
+			}
+			function ReplaceFunctionContentAssignments(text){
+				return text.replace(/((\w|\.)+)\x02=\x02((\w|\.)+)/g, "("+"$1"+'\x02=\x02'+"$3"+", {_name:'"+"$1"+"', _value:"+"$3"+"})");
+			}
+			function hasArrayIndexBasedOnUnderscore(text){
+				return /\_\d+\_/.test(text);
+			}
+			
+			function simplifyPlusAnsMinus(text){
+				function hasUnsimplifiedPlusMinus(text){
+					return /\-\s*\-/.test(text)||/\+\s*\+/.test(text)||/\+\s*\-/.test(text)||/\-\s*\+/.test(text);
+				}
+				while(hasUnsimplifiedPlusMinus(text)){
+					text = text.replace(/((\-\s*\-)|(\+\s*\+))/g, "+");
+					text = text.replace(/((\+\s*\-)|(\-\s*\+))/g, "-");
+				}
+				return text;
+			}
+
+		},
+		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
+			// this try catch is necessary to ensure that any incorrect input will receive NaN (it won't cause a self destruct from a user typo)
+			try{
+				var value = this.Function(undefined, '', 'return ' + text).call(this); // make sure it is called within the correct scope.
+				//value = ((value instanceof Array || typeof value == "array") ? ("["+value+"]") : value.toString())
+				return this.postparse(value);
+			}catch(e){
+				return NaN;
+			}
+		},
+		normalizedFunction: function(name, args, body){
+			// summary
+			//	create an anonymous function to run the code the parser generates from the user input.
+			// params
+			//	name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+			//	args: the function arguments (a String)
+			//	body: the function body, also a String
+			var	argMultiVals = '',
+			// make an array of parameters with what's given (if nothing is given, make an empty array)
+				params = args ? (args||'').split(/\W+/) : [];
+
+			argMultiVals += 'var _localObjectContainer = {};\n'+
+						'for(var _objCnt = 0; _objCnt < arguments.length; _objCnt++){\n'+
+						'if(typeof arguments[_objCnt] == "object" && "_name" in arguments[_objCnt] && "_value" in arguments[_objCnt]){\n'+
+							'_localObjectContainer.graphing = arguments[_objCnt]._graphing;\n'+
+							'_localObjectContainer[arguments[_objCnt]._name]=arguments[_objCnt]._value;\n'+
+							'arguments[_objCnt]=undefined;\n}\n}\n';
+
+			// make the parameters fit into the val function so it can use either globals, locals, or if all are null, prompt the user for input
+			for(var i=0; i < params.length; i++){
+				var param = params[i];
+				argMultiVals += param + '=val(' + param + ',"' + param + '", _localObjectContainer);\n';
+				argMultiVals += 'if(typeof '+param+' == "undefined"){\n'+
+						'return null;}\n';
+			}
+			var _f_ = window.Function.apply(this,
+				[
+					args,
+					'with(Math){with(this.dojox.math){with(this){\n' +
+						argMultiVals +
+						this.parse(body) +
+					'\n}}}'
+				]
+			);
+			if(name){
+				return this[name] = _f_;
+			}
+			return _f_;
+		},
+		Function: function(name, args, body){
+			// summary
+			//	create an anonymous function to run the code the parser generates from the user input.  It also normalizes the language format.
+			// params
+			//	name: this argument is simply a String that represents the name of the function being evaluated. It can be undefined, but in that case the function is a one time use.
+			//	args: the function arguments (a String)
+			//	body: the function body, also a String
+
+			body = this.preparse(body);
+			return this.normalizedFunction(name, args, body);
+
+		}
+	};
+	for(var i in window){
+        	if(!(i in env) && i != "alert" && i != "confirm"){ env[i] = undefined; } // invalidate access to the window object's attributes for security so that document.blah is invalid
+	}
+	frameElement.onload(env);
+})();
+</script>
+</head><body>
+<script>
+	document.documentElement.removeChild(document.documentElement.firstChild); // remove HEAD to remove debugger access for extra security
+</script>
+</body></html>
diff --git a/dojox/calc/resources/Common.css b/dojox/calc/resources/Common.css
new file mode 100644
index 0000000..012a5ce
--- /dev/null
+++ b/dojox/calc/resources/Common.css
@@ -0,0 +1,146 @@
+.dojoxCalcLayout span.dijitButtonNode,
+.dojoxCalcLayout span.dijitButtonContents{
+	display:block;
+}
+.dojoxCalc .dojoxCalcLayout .dojoxCalcTextAreaContainer {
+	padding-left: 0.2em;
+	padding-right: 0.2em;
+	#border-right: .3em;
+}
+.dojoxCalcLayout .dojoxCalcInputContainer .dijitTextBox {
+	/* IE bug workaround where the input caret is not visible (extends into the table border) */
+	position: relative;
+	border-left: 0 none;
+	border-right: 0 none;
+	width:100%;
+}
+.dojoxCalcLayout .dojoxCalcInputContainer,
+.dojoxCalcLayout .dojoxCalcInputContainer .dijitInputField {
+	padding-left: 0;
+	padding-right: 0;
+}
+.dojoxCalcLayout .dojoxCalcInputContainer .dijitInputContainer {
+	padding-left: 0;
+	#padding-left: 0.5em;
+	padding-right: 0.3em;
+	#padding-right: 0;
+}
+.dojoxCalcLayout .dojoxCalcInputContainer .dijitInputInner {
+	text-align: left;
+	padding-left: 0.2em !important;
+	padding-right: 0 !important;
+	#padding-right: 0.3em !important; /* IE workaround to make sure the input caret is visible */
+	overflow: hidden;
+}
+.dojoxCalcMinusButtonContainer {
+	width: 4em;
+	min-width: 4em;
+	padding: 0;
+}
+.dojoxCalcMinusButtonContainer .dijitButton {
+	margin: 0.1em;
+	width: 3.8em;
+}
+.dojoxCalcMinusButtonContainer .dijitArrowButtonInner {
+	width:1.3em;
+}
+.dojoxCalcMinusButtonContainer .dijitButtonNode .dijitButtonContents {
+	width: 2.1em;
+	min-width: 2.1em;
+}
+.dojoxCalcLayout .dojoxCalcMinusButtonContainer .dijitButtonText,
+.dojoxCalcLayout .dojoxCalcMinusButtonContainer .dijitButtonNode {
+	padding-left: 0px;
+	padding-right: 0px;
+}
+
+.dojoxCalcButtonContainer {
+	width: 4em;
+	min-width: 4em;
+	padding: 0;
+}
+.dojoxCalcButtonContainer .dijitButton {
+	margin: 0.1em;
+	width: 3.8em;
+}
+
+.dojoxCalcLayout .dojoxCalcButtonContainer .dijitButtonText,
+.dojoxCalcLayout .dojoxCalcButtonContainer .dijitButtonNode {
+	padding-left: 0px;
+	padding-right: 0px;
+}
+.dojoxCalcLayout {
+	table-layout:fixed;
+	border-width: 0;
+	border-style: none;
+	width:16.0em;
+	font:monospace;
+}
+.dojoxCalc {
+	border: 0.4em ridge #909090;
+}
+
+.dojoxCalcGrapherLayout span.dijitButtonNode,
+.dojoxCalcGrapherLayout span.dijitButtonContents{
+	display:block;
+}
+.dojoxCalcGrapherButtonContainer {
+	width: 10em;
+	min-width: 10em;
+	padding: 0;
+}
+.dojoxCalcGrapherButton {
+	display:block;
+}
+.dojoxCalcGrapherLayout {
+	table-layout:fixed;
+	border-width: 0;
+	border-style: none;
+	width:20.0em;
+	font:monospace;
+}
+.dojoxCalcExpressionBox {
+	width:15em;
+}
+.dojoxCalcChartHolder {
+	position:absolute;
+	left:36em;
+	top:5em;
+}
+.dojoxCalcGraphOptionTable {
+	width:25em;
+}
+.dojoxCalcGraphWidth {
+	width:5em;
+}
+.dojoxCalcGraphHeight {
+	width:5em;
+}
+.dojoxCalcGraphMinX {
+	width:5em;
+}
+.dojoxCalcGraphMaxX {
+	width:5em;
+}
+.dojoxCalcGraphMinY {
+	width:5em;
+}
+.dojoxCalcGraphMaxY {
+	width:5em;
+}
+.dojoxCalcGrapherFuncOuterDiv {
+	width:35em;
+	height:15em;
+	overflow-y:scroll;
+}
+.dojoxCalcGrapherModeTable {
+	width:10em;
+}
+.dojoxCalcFunctionModeSelector {
+	width:5em;
+}
+.dojoxCalcStatusBox {
+	border:1px solid;
+	padding:1px;
+	display:inline;
+}
diff --git a/dojox/calc/resources/GraphPro.css b/dojox/calc/resources/GraphPro.css
new file mode 100644
index 0000000..7d1181d
--- /dev/null
+++ b/dojox/calc/resources/GraphPro.css
@@ -0,0 +1,7 @@
+/*
+	Adds cosmetic styling to the dojox.calc.GraphPro widget.  Users may swap with a custom theme CSS file.
+
+	NOTES:
+	---
+*/
+ at import url("Common.css");
diff --git a/dojox/calc/resources/Standard.css b/dojox/calc/resources/Standard.css
new file mode 100644
index 0000000..c4fdd94
--- /dev/null
+++ b/dojox/calc/resources/Standard.css
@@ -0,0 +1,7 @@
+/*
+	Adds cosmetic styling to the dojox.calc.Standard widget.  Users may swap with a custom theme CSS file.
+
+	NOTES:
+	---
+*/
+ at import url("Common.css");
diff --git a/dojox/calc/templates/FuncGen.html b/dojox/calc/templates/FuncGen.html
new file mode 100644
index 0000000..a669f17
--- /dev/null
+++ b/dojox/calc/templates/FuncGen.html
@@ -0,0 +1,17 @@
+<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' />
+	<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>
+	<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" />
+	<BR><BR>
+	<input dojoType="dijit.form.Button" class="dojoxCalcFuncGenDelete" dojoAttachPoint='deleteButton' label="Delete" dojoAttachEvent='onClick:onDelete' />
+	<BR>
+	<input dojoType="dijit.form.TextBox" style="width:45%;" dojoAttachPoint='status' class="dojoxCalcFuncGenStatusTextBox" readonly value="Ready" />
+</div>
diff --git a/dojox/calc/templates/GraphPro.html b/dojox/calc/templates/GraphPro.html
new file mode 100644
index 0000000..c76ec0c
--- /dev/null
+++ b/dojox/calc/templates/GraphPro.html
@@ -0,0 +1,165 @@
+<div class="dijitReset dijitInline dojoxCalc"
+><table class="dijitReset dijitInline dojoxCalcLayout" dojoAttachPoint="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
+		></td
+	></tr>
+	<tr
+		><td colspan="4" class="dojoxCalcInputContainer"
+			><input dojoType="dijit.form.TextBox" dojoAttachEvent="onBlur:onBlur,onKeyPress:onKeyPress" dojoAttachPoint='textboxWidget'
+		/></td
+	></tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="grapherMakerButton" label="Graph" dojoAttachEvent='onClick:makeGrapherWindow' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="functionMakerButton" label="Func" dojoAttachEvent='onClick:makeFunctionWindow' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="toFracButton" label="toFrac" value="toFrac(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td colspan="1" class="dojoxCalcButtonContainer">
+		</td>
+
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="seven" label="7" value='7' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="eight" label="8" value='8' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="nine" label="9" value='9' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="divide" label="/" value='/' dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="four" label="4" value='4' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="five" label="5" value='5' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="six" label="6" value='6' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="multiply" label="*" value='*' dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="one" label="1" value='1' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="two" label="2" value='2' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="three" label="3" value='3' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="add" label="+" value='+' dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="decimal" label="." value='.' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="zero" label="0" value='0' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="equals" label="x=y" value='=' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcMinusButtonContainer">
+			<span dojoType="dijit.form.ComboButton" dojoAttachPoint="subtract" label='-' value='-' dojoAttachEvent='onClick:insertOperator'>
+
+				<div dojoType="dijit.Menu" style="display:none;">
+					<div dojoType="dijit.MenuItem" dojoAttachEvent="onClick:insertMinus">
+						(-)
+					</div>
+				</div>
+			</span>
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="clear" label="Clear" dojoAttachEvent='onClick:clearText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="sqrt" label="&#x221A;" value="&#x221A;" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="power" label="^" value="^" dojoAttachEvent='onClick:insertOperator' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="factorialButton" label="!" value="!" dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="pi" label="&#x03C0;" value="&#x03C0;" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="sin" label="sin" value="sin(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="cos" label="cos" value="cos(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="tan" label="tan" value="tan(" dojoAttachEvent='onClick:insertText' />
+		</td>
+
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="e" label="&#x03F5;" value="&#x03F5;" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="log10" label="log" value="log(" value="log(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="lnE" label="ln" value="ln(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="round" label="Round" value="Round(" dojoAttachEvent='onClick:insertText' />
+		</td>
+
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="intButton" label="Int" value="Int(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="PermutationButton" label="P" value="P(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="CombinationButton" label="C" value="C(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="comma" label="," value=',' dojoAttachEvent='onClick:insertText' />
+		</td>
+
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="AnsButton" label="Ans" value="Ans" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="LeftParenButton" label="(" value="(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="RightParenButton" label=")" value=")" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="enter" label="Enter" dojoAttachEvent='onClick:parseTextbox' />
+		</td>
+	</tr>
+</table>
+<span dojoAttachPoint="executor" dojoType="dojox.calc._Executor" dojoAttachEvent="onLoad:executorLoaded"></span>
+</div>
diff --git a/dojox/calc/templates/Grapher.html b/dojox/calc/templates/Grapher.html
new file mode 100644
index 0000000..7323f3d
--- /dev/null
+++ b/dojox/calc/templates/Grapher.html
@@ -0,0 +1,117 @@
+<div>
+<div dojoAttachPoint="chartsParent" class="dojoxCalcChartHolder"></div>
+<span dojoAttachPoint="outerDiv">
+<div dojoType="dijit.form.DropDownButton" dojoAttachPoint="windowOptions" class="dojoxCalcDropDownForWindowOptions" title="Window Options">
+	<div>Window Options</div>
+	<div dojoType="dijit.TooltipDialog" dojoAttachPoint="windowOptionsInside" class="dojoxCalcTooltipDialogForWindowOptions" title="">
+		<table class="dojoxCalcGraphOptionTable">
+			<tr>
+				<td>
+					Width:
+				</td>
+				<td>
+					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphWidth" class="dojoxCalcGraphWidth" value="500" />
+				</td>
+				<td>
+					Height:
+				</td>
+				<td>
+					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphHeight" class="dojoxCalcGraphHeight" value="500" />
+				</td>
+			</tr>
+			<tr>
+				<td>
+					X >=
+				</td>
+				<td>
+					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMinX" class="dojoxCalcGraphMinX" value="-10" />
+				</td>
+
+				<td>
+					X <=
+				</td>
+				<td>
+					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMaxX" class="dojoxCalcGraphMaxX" value="10" />
+				</td>
+			</tr>
+			<tr>
+				<td>
+					Y >=
+				</td>
+				<td>
+					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMinY" class="dojoxCalcGraphMinY" value="-10" />
+				</td>
+
+				<td>
+					Y <=
+				</td>
+				<td>
+					<input dojoType="dijit.form.TextBox" dojoAttachPoint="graphMaxY" class="dojoxCalcGraphMaxY" value="10" />
+				</td>
+			</tr>
+		</table>
+	</div>
+</div>
+
+<BR>
+
+<div class="dojoxCalcGrapherFuncOuterDiv">
+	<table class="dojoxCalcGrapherFuncTable" dojoAttachPoint="graphTable">
+	</table>
+</div>
+
+<div dojoType="dijit.form.DropDownButton" dojoAttachPoint='addFuncButton' class="dojoxCalcDropDownAddingFunction">
+	<div>Add Function</div>
+	<div dojoType="dijit.TooltipDialog" dojoAttachPoint="addFuncInside" class="dojoxCalcTooltipDialogAddingFunction" title="">
+		<table class="dojoxCalcGrapherModeTable">
+			<tr>
+				<td>
+					Mode:
+				</td>
+				<td>
+					<select dojoType="dijit.form.Select" dojoAttachPoint="funcMode" class="dojoxCalcFunctionModeSelector">
+						<option value="y=" selected="selected">y=</option>
+						<option value="x=">x=</option>
+					</select>
+				</td>
+				<td>
+			</tr>
+	
+			<tr>
+				<td>
+					<input dojoType="dijit.form.Button" dojoAttachPoint="createFunc" class="dojoxCalcAddFunctionButton" label="Create" />
+				</td>
+			</tr>
+		</table>
+	</div>
+</div>
+<BR>
+<BR>
+<table class="dijitInline dojoxCalcGrapherLayout">
+	<tr>
+		<td class="dojoxCalcGrapherButtonContainer">
+			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='selectAllButton' label="Select All" />
+		</td>
+		<td class="dojoxCalcGrapherButtonContainer">
+			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='deselectAllButton' label="Deselect All" />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcGrapherButtonContainer">
+			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='drawButton'label="Draw Selected" />
+		</td>
+		<td class="dojoxCalcGrapherButtonContainer">
+			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='eraseButton' label="Erase Selected" />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcGrapherButtonContainer">
+			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='deleteButton' label="Delete Selected" />
+		</td>
+		<td class="dojoxCalcGrapherButtonContainer">
+			<input dojoType="dijit.form.Button" class="dojoxCalcGrapherButton" dojoAttachPoint='closeButton' label="Close" />
+		</td>
+	</tr>
+</table>
+</span>
+</div>
diff --git a/dojox/calc/templates/Standard.html b/dojox/calc/templates/Standard.html
new file mode 100644
index 0000000..5d95c86
--- /dev/null
+++ b/dojox/calc/templates/Standard.html
@@ -0,0 +1,101 @@
+<div class="dijitReset dijitInline dojoxCalc"
+><table class="dijitReset dijitInline dojoxCalcLayout" dojoAttachPoint="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'
+		/></td
+	></tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="seven" label="7" value='7' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="eight" label="8" value='8' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="nine" label="9" value='9' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="divide" label="/" value='/' dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="four" label="4" value='4' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="five" label="5" value='5' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="six" label="6" value='6' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="multiply" label="*" value='*' dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="one" label="1" value='1' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="two" label="2" value='2' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="three" label="3" value='3' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="add" label="+" value='+' dojoAttachEvent='onClick:insertOperator' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="decimal" label="." value='.' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="zero" label="0" value='0' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="equals" label="x=y" value='=' dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcMinusButtonContainer">
+			<span dojoType="dijit.form.ComboButton" dojoAttachPoint="subtract" label='-' value='-' dojoAttachEvent='onClick:insertOperator'>
+
+				<div dojoType="dijit.Menu" style="display:none;">
+					<div dojoType="dijit.MenuItem" dojoAttachEvent="onClick:insertMinus">
+						(-)
+					</div>
+				</div>
+			</span>
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="clear" label="Clear" dojoAttachEvent='onClick:clearText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="sqrt" label="&#x221A;" value="&#x221A;" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="power" label="^" value="^" dojoAttachEvent='onClick:insertOperator' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="comma" label="," value=',' dojoAttachEvent='onClick:insertText' />
+		</td>
+	</tr>
+	<tr>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="AnsButton" label="Ans" value="Ans" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="LeftParenButton" label="(" value="(" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="RightParenButton" label=")" value=")" dojoAttachEvent='onClick:insertText' />
+		</td>
+		<td class="dojoxCalcButtonContainer">
+			<button dojoType="dijit.form.Button" dojoAttachPoint="enter" label="Enter" dojoAttachEvent='onClick:parseTextbox' />
+		</td>
+	</tr>
+</table>
+<span dojoAttachPoint="executor" dojoType="dojox.calc._Executor" dojoAttachEvent="onLoad:executorLoaded"></span>
+</div>
diff --git a/dojox/calc/tests/test_Executor.html b/dojox/calc/tests/test_Executor.html
new file mode 100644
index 0000000..9a428b1
--- /dev/null
+++ b/dojox/calc/tests/test_Executor.html
@@ -0,0 +1,289 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<meta http-equiv="Content-type" content="text/html; charset=utf-8">
+	<title>Calculator Executor Test</title>
+
+	<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 = 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);
+			console.log("text is "+text);
+			doh.is(ans, dojox.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(){
+			function allTests(){
+				dojo.byId("status").innerHTML = "Testing...";
+				func = executor.Function("fcn1", "i,j","k=i+j+1;return k;");
+
+				executor.Function("prompt", "", "	return (arguments[2]=='j') ? 6 : NaN	");
+				test("fcn1(5)", 12);
+				test(func(4), 11);
+				executor.Function("fcn2", "i","return j=fcn1(k,i);");
+				test("fcn2(i=fcn1(6,7))", 29);
+				test("j+k", 58);
+
+				// number conversion tests
+				test("toRadix(5,2)", "0b101");
+				test("toRadix(toRadix(5,2), 10)", 5);
+				test("toRadix(toRadix(5,3), 10)", 5);
+				test("toRadix(0xf, 16)", "0xf");
+
+				test("toRadix(0xf, 15)", "10#15");
+				test("toRadix(0b1111, 15)", "10#15");
+				test("toRadix(0o17, 15)", "10#15");
+				test("toRadix(10#15, 16)", "0xf");
+				test("toRadix(10#15, 2)", "0b1111");
+				test("toRadix(10#15, 8)", "0o17");
+
+				test("toRadix(0xf, 10)", "15");
+				test("toRadix(0xf, 2)", "0b1111");
+				test("toRadix(0b1111, 16)", "0xf");
+				test("toRadix(0o111, 16)", "0x49");
+				
+				// unary tests
+				test("0--2", 2);
+				test("0 --2", 2);
+				test("0 - -2", 2);
+				test("0 - - 2", 2);
+				test("0- -2", 2);
+				test("0- - 2", 2);
+				test("0 -  -  2", 2);
+				test("0  --2", 2);
+				test("0  - - 2", 2);
+
+				// pi tests
+				// some browsers get 8105800789910702, some get 8105800789910700
+				test("Math.abs(pi^32-8105800789910701) <= 1", true);
+				test("32\u221A8105800789910700", Math.PI);
+				test("64\u221A65704006445717084572022626334541", Math.PI);
+
+				// new pow tests
+				test(" (-27)^(1/3) ", -3);
+				test(" (-36)^(1/2) ", NaN);
+
+				test("y=true", true);
+				test("y=!y", false);
+				test("y=(true||!true)", true);
+				test("x=5", 5);
+				test("x", 5);
+				test("x++", 5);
+				test("x", 6);
+						
+				test("x--", 6);
+				test("x", 5);
+				test("x==5", true);
+				test("5+x++", 10);
+
+				test("x", 6);
+
+				test("x=5", 5);
+				test("y=(x!=6)", true);// x != 6
+				test("x=3", 3);
+				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);
+				// factorial goes first, 2^3! = 2^6
+				test("\u221A3!", Math.sqrt(dojox.math.factorial(3))); // 2.4494897427831780981972840747059);
+				test("\u221A(3!^2)", 6);
+				test("3\u221A(3!^3)", 6);
+				test("4\u221A(4^4)", 4);
+				test("(4^(1/2))\u221A(4^2)", 4);
+				test("(4^(1/2))\u221A4^2", 4);
+				test("4^(1/2)\u221A(4^2)", 4);
+				test("4^(1/2)\u221A4^2", 4);
+
+				test("2^Math.sin(\u03C0)", 1);
+				test("\u221A\u221A"+"16", 2);
+				test("Math.sqrt(\u221A16, 2)", 2);
+				test("\u221AMath.sqrt(16, 2)", 2);
+
+				// New Radical tests
+				test("\u221A2\u221A4\u221A16", 2);
+				test("2\u221A4\u221A16", 4);
+				test("2^2\u221A16", 2);
+				test("2^-3^-4", Math.pow(2,(-Math.pow(3,(-4)))));
+				test("2^-2\u221A4", .25);
+
+
+				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^-\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", 4);
+				test("-\u221A4", -2);
+				test("2^-2", 1/4);
+				test("--2", 2);
+				test("pow(2^2, 2^2)", 256)
+				// extreme negative sign scenarios
+				test("2^--\u221A--4", 4);
+				test("---\u221A--4", -2);
+				test("---\u221A4", -2);
+				test("---2*(3-5)+1", 5);
+				test("---(2*(3-5))+1", 5);
+				// 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("--4.56443*2-4.56443", 4.56443);
+				// more arithmetic
+				test("4*2-(5+2*3-2)*6/-2", 35);
+				test("Math.floor(2^3^4)+Math.floor(2^Math.floor(2))", 4100);
+				// scientific notation
+				test("10e10", 10e10);
+				test("10e-10", 10e-10);
+				test("10e+10", 10e10);
+				test("10e+10*2", 10e10*2);
+				test("2*10e+10*2", 2*10e10*2);
+				test("2*10e10*2", 2*10e10*2);
+				// 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("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))));
+
+				// full space tests
+				test(" x = 5 ", 5);
+				test(" x ", 5);
+				test(" x ++ ", 5);
+				test(" x ", 6);
+				test(" x -- ", 6);
+				test(" x ", 5);
+				test(" x == 5 ", true);
+				test(" 5 ", 5);
+				test(" 3 !", 6);
+				test(" \u221A ( 3 ! )", Math.sqrt(dojox.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 ! ^ 2 ) ", 6);
+				test(" 3 \u221A ( 3 ! ^ 3 ) ", 6);
+				test(" 4 \u221A ( 4 ^ 4 ) ", 4);
+				test(" ( 4 ^ ( 1 / 2 ) ) \u221A ( 4 ^ 2 ) ", 4);
+				test(" ( 4 ^ ( 1 / 2 ) ) \u221A 4 ^ 2 ", 4);
+				test(" 4 ^ ( 1 / 2 ) \u221A ( 4 ^ 2 ) ", 4);
+				test(" 4 ^ ( 1 / 2 ) \u221A 4 ^ 2 ", 4);
+
+				test(" 2 ^ Math.sin ( \u03C0 ) ", 1);
+				test(" \u221A \u221A 16 ", 2);
+				test(" Math.sqrt ( \u221A 16 , 2 )", 2);
+				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 ^ - \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 ", 4);
+				test(" - \u221A 4 " , -2);
+				test(" 2 ^ - 2 ", 1/4);
+				test(" - - 2 ", 2);
+				test("pow( 2 ^ 2 ,  2 ^ 2)", 256)
+
+				// extreme negative sign scenarios
+				test(" 2 ^ - - \u221A - - 4 ", 4);
+				test(" - - - \u221A - - 4 ", -2);
+				test(" - - - \u221A 4 ", -2);
+				test(" - - - 2 * ( 3 - 5 ) + 1 ", 5);
+				test(" - - - ( 2 * ( 3 - 5 ) ) + 1 ", 5);
+				// 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(" - - 4.56443 * 2 - 4.56443 ", 4.56443);
+				// more arithmetic
+				test(" 4 * 2 - ( 5 + 2 * 3 - 2 ) * 6 / - 2 ", 35);
+				test("Math.floor( 2 ^ 3 ^ 4 )+Math.floor( 2 ^ Math.floor ( 2 ) ) ", 4100);
+				// scientific notation
+				test(" 2 * 10e+10 * 2 ", 2*10e10*2);
+				test(" 2 * 10e10 * 2 ", 2*10e10*2);
+				// 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(" 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("3!=6", true);
+				test("3!==6", true);
+
+				// try to break it on purpose; once upon a time, some might have caused infinite loops
+				test("2*2.4.5", NaN);
+
+				test("2^^3", NaN);
+				test("2^^^^^^3", NaN);
+				test("2^^^^^^^3", NaN);
+				test("^2^3", NaN);
+				test("!2^3", false);
+				test("!2!+3!", 6);
+				test("2+3\u221A", NaN);
+				test("2+3\u221A^", NaN);
+				test("!", NaN);
+				test("((23+4)", NaN);					
+				test("4+", NaN);
+				test("4++", NaN);
+
+				status = "Completed without errors";
+			}
+			doh.register("dojox.calc._Executor", [
+				{
+					name: "wait for Executor to load",
+					timeout: 5000,
+					runTest: function(){ if(!executor){ return waitForLoad; }}
+				},
+				{
+					name: "Executor tests",
+					timeout: 9000,
+					runTest: function(){ allTests() }
+
+				},
+				function done(){
+				       	dojo.byId("status").innerHTML = status;
+				}
+			]);
+			doh.run();
+		});
+	</script>
+</head>
+<body>
+	<b>dojox.calc._Executor tests</b>
+	<div id="status" style="direction:ltr">Loading...</div>
+	<span id="executor" data-dojo-type="dojox.calc._Executor" data-dojo-props='onLoad:function(){ executorLoaded() }'></span>
+</body>
+</html>
diff --git a/dojox/calc/tests/test_GraphPro.html b/dojox/calc/tests/test_GraphPro.html
new file mode 100644
index 0000000..b6c8547
--- /dev/null
+++ b/dojox/calc/tests/test_GraphPro.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>GraphPro Calculator Test</title>
+
+	<style>
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "../../../dojox/layout/resources/FloatingPane.css";
+		@import "../../../dojox/calc/resources/GraphPro.css";
+	</style>
+
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+
+	<script type="text/javascript">
+		//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");
+
+		});
+
+	</script>
+</head>
+<body class=claro>
+	<div id="calculator"></div>
+</body>
+</html>
diff --git a/dojox/calc/tests/test_Standard.html b/dojox/calc/tests/test_Standard.html
new file mode 100644
index 0000000..fa71851
--- /dev/null
+++ b/dojox/calc/tests/test_Standard.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Standard Calculator Test</title>
+
+	<style>
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "../../../dojox/layout/resources/FloatingPane.css";
+		@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">
+		//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");
+
+		});
+
+	</script>
+</head>
+<body class=claro>
+	<div id="calculator"></div>
+</body>
+</html>
diff --git a/dojox/calc/toFrac.js b/dojox/calc/toFrac.js
new file mode 100644
index 0000000..403915d
--- /dev/null
+++ b/dojox/calc/toFrac.js
@@ -0,0 +1,137 @@
+define("dojox/calc/toFrac", ["dojo"], function(dojo) {
+
+(function(){
+
+	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] + ")";
+		}
+		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
+				}
+			}
+			d++;
+			if(searchNumber == undefined){
+				setTimeout(function(){ _fracHashInit() }, 1);
+				return;
+			}
+		}
+		d = 2;
+		i++;
+	}
+	_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();
+
+// 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 };
+		}
+	}
+	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
+		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;
+		}
+	}
+}
+});
+/*
+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/Chart.js b/dojox/charting/Chart.js
new file mode 100644
index 0000000..161d4b9
--- /dev/null
+++ b/dojox/charting/Chart.js
@@ -0,0 +1,1108 @@
+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");
+
+	dojo.declare("dojox.charting.Chart", null, {
+		//	summary:
+		//		The main chart object in dojox.charting.  This will create a two dimensional
+		//		chart based on dojox.gfx.
+		//
+		//	description:
+		//		dojox.charting.Chart is the primary object used for any kind of charts.  It
+		//		is simple to create--just pass it a node reference, which is used as the
+		//		container for the chart--and a set of optional keyword arguments and go.
+		//
+		//		Note that like most of dojox.gfx, most of dojox.charting.Chart's methods are
+		//		designed to return a reference to the chart itself, to allow for functional
+		//		chaining.  This makes defining everything on a Chart very easy to do.
+		//
+		//	example:
+		//		Create an area chart, with smoothing.
+		//	|	new dojox.charting.Chart(node))
+		//	|		.addPlot("default", { type: "Areas", tension: "X" })
+		//	|		.setTheme(dojox.charting.themes.Shrooms)
+		//	|		.addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
+		//	|		.addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
+		//	|		.addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
+		//	|		.render();
+		//
+		//	example:
+		//		The form of data in a data series can take a number of forms: a simple array,
+		//		an array of objects {x,y}, or something custom (as determined by the plot).
+		//		Here's an example of a Candlestick chart, which expects an object of
+		//		{ open, high, low, close }.
+		//	|	new dojox.charting.Chart(node))
+		//	|		.addPlot("default", {type: "Candlesticks", gap: 1})
+		//	|		.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
+		//	|		.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
+		//	|		.addSeries("Series A", [
+		//	|				{ open: 20, close: 16, high: 22, low: 8 },
+		//	|				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
+		//	|				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
+		//	|				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
+		//	|				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
+		//	|				{ open: 24, close: 8, high: 24, low: 5 },
+		//	|				{ open: 8, close: 16, high: 22, low: 2 },
+		//	|				{ open: 16, close: 12, high: 19, low: 7 },
+		//	|				{ open: 12, close: 20, high: 22, low: 8 },
+		//	|				{ open: 20, close: 16, high: 22, low: 8 },
+		//	|				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
+		//	|				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
+		//	|				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
+		//	|				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
+		//	|				{ open: 24, close: 8, high: 24, low: 5 },
+		//	|				{ open: 8, close: 16, high: 22, low: 2 },
+		//	|				{ open: 16, close: 12, high: 19, low: 7 },
+		//	|				{ open: 12, close: 20, high: 22, low: 8 },
+		//	|				{ open: 20, close: 16, high: 22, low: 8 },
+		//	|				{ open: 16, close: 22, high: 26, low: 6 },
+		//	|				{ open: 22, close: 18, high: 22, low: 11 },
+		//	|				{ open: 18, close: 29, high: 32, low: 14 },
+		//	|				{ open: 29, close: 24, high: 29, low: 13 },
+		//	|				{ open: 24, close: 8, high: 24, low: 5 },
+		//	|				{ open: 8, close: 16, high: 22, low: 2 },
+		//	|				{ open: 16, close: 12, high: 19, low: 7 },
+		//	|				{ open: 12, close: 20, high: 22, low: 8 },
+		//	|				{ open: 20, close: 16, high: 22, low: 8 }
+		//	|			],
+		//	|			{ stroke: { color: "green" }, fill: "lightgreen" }
+		//	|		)
+		//	|		.render();
+		//
+		//	theme: dojox.charting.Theme?
+		//		An optional theme to use for styling the chart.
+		//	axes: dojox.charting.Axis{}?
+		//		A map of axes for use in plotting a chart.
+		//	stack: dojox.charting.plot2d.Base[]
+		//		A stack of plotters.
+		//	plots: dojox.charting.plot2d.Base{}
+		//		A map of plotter indices
+		//	series: dojox.charting.Series[]
+		//		The stack of data runs used to create plots.
+		//	runs: dojox.charting.Series{}
+		//		A map of series indices
+		//	margins: Object?
+		//		The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
+		//	stroke: dojox.gfx.Stroke?
+		//		The outline of the chart (stroke in vector graphics terms).
+		//	fill: dojox.gfx.Fill?
+		//		The color for the chart.
+		//	node: DOMNode
+		//		The container node passed to the constructor.
+		//	surface: dojox.gfx.Surface
+		//		The main graphics surface upon which a chart is drawn.
+		//	dirty: Boolean
+		//		A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
+		//	coords: Object
+		//		The coordinates on a page of the containing node, as returned from dojo.coords.
+
+		constructor: function(/* DOMNode */node, /* dojox.charting.__ChartCtorArgs? */kwArgs){
+			//	summary:
+			//		The constructor for a new Chart.  Initializes all parameters used for a chart.
+			//	returns: dojox.charting.Chart
+			//		The newly created chart.
+
+			// initialize parameters
+			if(!kwArgs){ kwArgs = {}; }
+			this.margins   = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
+			this.stroke    = kwArgs.stroke;
+			this.fill      = kwArgs.fill;
+			this.delayInMs = kwArgs.delayInMs || 200;
+			this.title     = kwArgs.title;
+			this.titleGap  = kwArgs.titleGap;
+			this.titlePos  = kwArgs.titlePos;
+			this.titleFont = kwArgs.titleFont;
+			this.titleFontColor = kwArgs.titleFontColor;
+			this.chartTitle = null;
+
+			// default initialization
+			this.theme = null;
+			this.axes = {};		// map of axes
+			this.stack = [];	// stack of plotters
+			this.plots = {};	// map of plotter indices
+			this.series = [];	// stack of data runs
+			this.runs = {};		// map of data run indices
+			this.dirty = true;
+			this.coords = null;
+
+			// create a surface
+			this.node = dojo.byId(node);
+			var box = dojo.marginBox(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);
+            }
+			this.surface.destroy();
+		},
+		getCoords: function(){
+			//	summary:
+			//		Get the coordinates and dimensions of the containing DOMNode, as
+			//		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
+		},
+		setTheme: function(theme){
+			//	summary:
+			//		Set a theme of the chart.
+			//	theme: dojox.charting.Theme
+			//		The theme to be used for visual rendering.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			this.theme = theme.clone();
+			this.dirty = true;
+			return this;	//	dojox.charting.Chart
+		},
+		addAxis: function(name, kwArgs){
+			//	summary:
+			//		Add an axis to the chart, for rendering.
+			//	name: String
+			//		The name of the axis.
+			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
+			//		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);
+            }
+			axis.name = name;
+			axis.dirty = true;
+			if(name in this.axes){
+				this.axes[name].destroy();
+			}
+			this.axes[name] = axis;
+			this.dirty = true;
+			return this;	//	dojox.charting.Chart
+		},
+		getAxis: function(name){
+			//	summary:
+			//		Get the given axis, by name.
+			//	name: String
+			//		The name the axis was defined by.
+			//	returns: dojox.charting.axis2d.Default
+			//		The axis as stored in the chart's axis map.
+			return this.axes[name];	//	dojox.charting.axis2d.Default
+		},
+		removeAxis: function(name){
+			//	summary:
+			//		Remove the axis that was defined using name.
+			//	name: String
+			//		The axis name, as defined in addAxis.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.axes){
+				// destroy the axis
+				this.axes[name].destroy();
+				delete this.axes[name];
+				// mark the chart as dirty
+				this.dirty = true;
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		addPlot: function(name, kwArgs){
+			//	summary:
+			//		Add a new plot to the chart, defined by name and using the optional keyword arguments object.
+			//		Note that dojox.charting assumes the main plot to be called "default"; if you do not have
+			//		a plot called "default" and attempt to add data series to the chart without specifying the
+			//		plot to be rendered on, you WILL get errors.
+			//	name: String
+			//		The name of the plot to be added to the chart.  If you only plan on using one plot, call it "default".
+			//	kwArgs: dojox.charting.plot2d.__PlotCtorArgs
+			//		An object with optional parameters for the plot in question.
+			//	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);
+            }
+			plot.name = name;
+			plot.dirty = true;
+			if(name in this.plots){
+				this.stack[this.plots[name]].destroy();
+				this.stack[this.plots[name]] = plot;
+			}else{
+				this.plots[name] = this.stack.length;
+				this.stack.push(plot);
+			}
+			this.dirty = true;
+			return this;	//	dojox.charting.Chart
+		},
+		removePlot: function(name){
+			//	summary:
+			//		Remove the plot defined using name from the chart's plot stack.
+			//	name: String
+			//		The name of the plot as defined using addPlot.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.plots){
+				// get the index and remove the name
+				var index = this.plots[name];
+				delete this.plots[name];
+				// destroy the plot
+				this.stack[index].destroy();
+				// 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){
+					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;
+                }
+				// mark the chart as dirty
+				this.dirty = true;
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		getPlotOrder: function(){
+			//	summary:
+			//		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
+		},
+		setPlotOrder: function(newOrder){
+			//	summary:
+			//		Sets new order of plots. newOrder cannot add or remove
+			//		plots. Wrong names, or dups are ignored.
+			//	newOrder: Array:
+			//		Array of plot names compatible with getPlotOrder().
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			var names = {},
+				order = df.filter(newOrder, function(name){
+					if(!(name in this.plots) || (name in names)){
+						return false;
+					}
+					names[name] = 1;
+					return true;
+				}, this);
+			if(order.length < this.stack.length){
+				df.forEach(this.stack, function(plot){
+					var name = plot.name;
+					if(!(name in names)){
+						order.push(name);
+					}
+				});
+			}
+			var newStack = df.map(order, function(name){
+					return this.stack[this.plots[name]];
+				}, this);
+			df.forEach(newStack, function(plot, i){
+				this.plots[plot.name] = i;
+			}, this);
+			this.stack = newStack;
+			this.dirty = true;
+			return this;	//	dojox.charting.Chart
+		},
+		movePlotToFront: function(name){
+			//	summary:
+			//		Moves a given plot to front.
+			//	name: String:
+			//		Plot's name to move.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.plots){
+				var index = this.plots[name];
+				if(index){
+					var newOrder = this.getPlotOrder();
+					newOrder.splice(index, 1);
+					newOrder.unshift(name);
+					return this.setPlotOrder(newOrder);	//	dojox.charting.Chart
+				}
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		movePlotToBack: function(name){
+			//	summary:
+			//		Moves a given plot to back.
+			//	name: String:
+			//		Plot's name to move.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.plots){
+				var index = this.plots[name];
+				if(index < this.stack.length - 1){
+					var newOrder = this.getPlotOrder();
+					newOrder.splice(index, 1);
+					newOrder.push(name);
+					return this.setPlotOrder(newOrder);	//	dojox.charting.Chart
+				}
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		addSeries: function(name, data, kwArgs){
+			//	summary:
+			//		Add a data series to the chart for rendering.
+			//	name: String:
+			//		The name of the data series to be plotted.
+			//	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 that will be mixed into
+			//		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);
+			run.name = name;
+			if(name in this.runs){
+				this.series[this.runs[name]].destroy();
+				this.series[this.runs[name]] = run;
+			}else{
+				this.runs[name] = this.series.length;
+				this.series.push(run);
+			}
+			this.dirty = true;
+			// fix min/max
+			if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
+			if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
+			return this;	//	dojox.charting.Chart
+		},
+		removeSeries: function(name){
+			//	summary:
+			//		Remove the series defined by name from the chart.
+			//	name: String
+			//		The name of the series as defined by addSeries.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.runs){
+				// get the index and remove the name
+				var index = this.runs[name];
+				delete this.runs[name];
+				// destroy the run
+				this.series[index].destroy();
+				// 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){
+					if(idx > index){
+						runs[name] = idx - 1;
+					}
+				});
+				this.dirty = true;
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		updateSeries: function(name, data){
+			//	summary:
+			//		Update the given series with a new set of data points.
+			//	name: String
+			//		The name of the series as defined in addSeries.
+			//	data: Array|Object:
+			//		The array of data points (either numbers or objects) that
+			//		represents the data to be drawn. Or it can be an object. In
+			//		the latter case, it should have a property "data" (an array),
+			//		destroy(), and setSeriesObject().
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.runs){
+				var run = this.series[this.runs[name]];
+				run.update(data);
+				this._invalidateDependentPlots(run.plot, false);
+				this._invalidateDependentPlots(run.plot, true);
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		getSeriesOrder: function(plotName){
+			//	summary:
+			//		Returns an array of series names in the current order
+			//		(the top-most series is the first) within a plot.
+			//	plotName: String:
+			//		Plot's name.
+			//	returns: Array
+			return df.map(df.filter(this.series, function(run){
+					return run.plot == plotName;
+				}), getName);
+		},
+		setSeriesOrder: function(newOrder){
+			//	summary:
+			//		Sets new order of series within a plot. newOrder cannot add
+			//		or remove series. Wrong names, or dups are ignored.
+			//	newOrder: Array:
+			//		Array of series names compatible with getPlotOrder(). All
+			//		series should belong to the same plot.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			var plotName, names = {},
+				order = df.filter(newOrder, function(name){
+					if(!(name in this.runs) || (name in names)){
+						return false;
+					}
+					var run = this.series[this.runs[name]];
+					if(plotName){
+						if(run.plot != plotName){
+							return false;
+						}
+					}else{
+						plotName = run.plot;
+					}
+					names[name] = 1;
+					return true;
+				}, this);
+			df.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){
+					return this.series[this.runs[name]];
+				}, this);
+			this.series = newSeries.concat(df.filter(this.series, function(run){
+				return run.plot != plotName;
+			}));
+			df.forEach(this.series, function(run, i){
+				this.runs[run.name] = i;
+			}, this);
+			this.dirty = true;
+			return this;	//	dojox.charting.Chart
+		},
+		moveSeriesToFront: function(name){
+			//	summary:
+			//		Moves a given series to front of a plot.
+			//	name: String:
+			//		Series' name to move.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.runs){
+				var index = this.runs[name],
+					newOrder = this.getSeriesOrder(this.series[index].plot);
+				if(name != newOrder[0]){
+					newOrder.splice(index, 1);
+					newOrder.unshift(name);
+					return this.setSeriesOrder(newOrder);	//	dojox.charting.Chart
+				}
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		moveSeriesToBack: function(name){
+			//	summary:
+			//		Moves a given series to back of a plot.
+			//	name: String:
+			//		Series' name to move.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(name in this.runs){
+				var index = this.runs[name],
+					newOrder = this.getSeriesOrder(this.series[index].plot);
+				if(name != newOrder[newOrder.length - 1]){
+					newOrder.splice(index, 1);
+					newOrder.push(name);
+					return this.setSeriesOrder(newOrder);	//	dojox.charting.Chart
+				}
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		resize: function(width, height){
+			//	summary:
+			//		Resize the chart to the dimensions of width and height.
+			//	description:
+			//		Resize the chart and its surface to the width and height dimensions.
+			//		If no width/height or box is provided, resize the surface to the marginBox of the chart.
+			//	width: Number
+			//		The new width of the chart.
+			//	height: Number
+			//		The new height of the chart.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			var box;
+			switch(arguments.length){
+				// case 0, do not resize the div, just the surface
+				case 1:
+					// argument, override node box
+					box = dojo.mixin({}, width);
+					dojo.marginBox(this.node, box);
+					break;
+				case 2:
+					box = {w: width, h: height};
+					// argument, override node box
+					dojo.marginBox(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
+		},
+		getGeometry: function(){
+			//	summary:
+			//		Returns a map of information about all axes in a chart and what they represent
+			//		in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
+			//	returns: Object
+			//		An map of geometry objects, a one-to-one mapping of axes.
+			var ret = {};
+			df.forIn(this.axes, function(axis){
+				if(axis.initialized()){
+					ret[axis.name] = {
+						name:		axis.name,
+						vertical:	axis.vertical,
+						scaler:		axis.scaler,
+						ticks:		axis.ticks
+					};
+				}
+			});
+			return ret;	//	Object
+		},
+		setAxisWindow: function(name, scale, offset, zoom){
+			//	summary:
+			//		Zooms an axis and all dependent plots. Can be used to zoom in 1D.
+			//	name: String
+			//		The name of the axis as defined by addAxis.
+			//	scale: Number
+			//		The scale on the target axis.
+			//	offset: Number
+			//		Any offest, as measured by axis tick
+			//	zoom: Boolean|Object?
+			//		The chart zooming animation trigger.  This is null by default,
+			//		e.g. {duration: 1200}, or just set true.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			var axis = this.axes[name];
+			if(axis){
+				axis.setWindow(scale, offset);
+				dojo.forEach(this.stack,function(plot){
+					if(plot.hAxis == name || plot.vAxis == name){
+						plot.zoom = zoom;
+					}
+				})
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		setWindow: function(sx, sy, dx, dy, zoom){
+			//	summary:
+			//		Zooms in or out any plots in two dimensions.
+			//	sx: Number
+			//		The scale for the x axis.
+			//	sy: Number
+			//		The scale for the y axis.
+			//	dx: Number
+			//		The pixel offset on the x axis.
+			//	dy: Number
+			//		The pixel offset on the y axis.
+			//	zoom: Boolean|Object?
+			//		The chart zooming animation trigger.  This is null by default,
+			//		e.g. {duration: 1200}, or just set true.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(!("plotArea" in this)){
+				this.calculateGeometry();
+			}
+			df.forIn(this.axes, function(axis){
+				var scale, offset, bounds = axis.getScaler().bounds,
+					s = bounds.span / (bounds.upper - bounds.lower);
+				if(axis.vertical){
+					scale  = sy;
+					offset = dy / s / scale;
+				}else{
+					scale  = sx;
+					offset = dx / s / scale;
+				}
+				axis.setWindow(scale, offset);
+			});
+			dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
+			return this;	//	dojox.charting.Chart
+		},
+		zoomIn:	function(name, range){
+			//	summary:
+			//		Zoom the chart to a specific range on one axis.  This calls render()
+			//		directly as a convenience method.
+			//	name: String
+			//		The name of the axis as defined by addAxis.
+			//	range: Array
+			//		The end points of the zoom range, measured in axis ticks.
+			var axis = this.axes[name];
+			if(axis){
+				var scale, offset, bounds = axis.getScaler().bounds;
+				var lower = Math.min(range[0],range[1]);
+				var upper = Math.max(range[0],range[1]);
+				lower = range[0] < bounds.lower ? bounds.lower : lower;
+				upper = range[1] > bounds.upper ? bounds.upper : upper;
+				scale = (bounds.upper - bounds.lower) / (upper - lower);
+				offset = lower - bounds.lower;
+				this.setAxisWindow(name, scale, offset);
+				this.render();
+			}
+		},
+		calculateGeometry: function(){
+			//	summary:
+			//		Calculate the geometry of the chart based on the defined axes of
+			//		a chart.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(this.dirty){
+				return this.fullGeometry();
+			}
+
+			// calculate geometry
+			var dirty = dojo.filter(this.stack, function(plot){
+					return plot.dirty ||
+						(plot.hAxis && this.axes[plot.hAxis].dirty) ||
+						(plot.vAxis && this.axes[plot.vAxis].dirty);
+				}, this);
+			calculateAxes(dirty, this.plotArea);
+
+			return this;	//	dojox.charting.Chart
+		},
+		fullGeometry: function(){
+			//	summary:
+			//		Calculate the full geometry of the chart.  This includes passing
+			//		over all major elements of a chart (plots, axes, series, container)
+			//		in order to ensure proper rendering.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			this._makeDirty();
+
+			// clear old values
+			dojo.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));
+			}
+
+			// assign series
+			dojo.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?");
+                    }
+					var plot = new dc.plot2d.Default(this, {});
+					plot.name = run.plot;
+					this.plots[run.plot] = this.stack.length;
+					this.stack.push(plot);
+				}
+				this.stack[this.plots[run.plot]].addSeries(run);
+			}, this);
+			// assign axes
+			dojo.forEach(this.stack, function(plot){
+				if(plot.hAxis){
+					plot.setAxis(this.axes[plot.hAxis]);
+				}
+				if(plot.vAxis){
+					plot.setAxis(this.axes[plot.vAxis]);
+				}
+			}, this);
+
+			// calculate geometry
+
+			// 1st pass
+			var dim = this.dim = this.surface.getDimensions();
+			dim.width  = g.normalizedLength(dim.width);
+			dim.height = g.normalizedLength(dim.height);
+			df.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; });
+			});
+			// add title area
+			if(this.title){
+				this.titleGap = (this.titleGap==0) ? 0 : this.titleGap || this.theme.chart.titleGap || 20;
+				this.titlePos = this.titlePos || this.theme.chart.titlePos || "top";
+				this.titleFont = this.titleFont || this.theme.chart.titleFont;
+				this.titleFontColor = this.titleFontColor || this.theme.chart.titleFontColor || "black";
+				var tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
+				offsets[this.titlePos=="top" ? "t":"b"] += (tsize + this.titleGap);
+			}
+			// add margins
+			df.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);
+			calculateAxes(this.stack, this.plotArea);
+
+			return this;	//	dojox.charting.Chart
+		},
+		render: function(){
+			//	summary:
+			//		Render the chart according to the current information defined.  This should
+			//		be the last call made when defining/creating a chart, or if data within the
+			//		chart has been changed.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(this.theme){
+				this.theme.clear();
+			}
+
+			if(this.dirty){
+				return this.fullRender();
+			}
+
+			this.calculateGeometry();
+
+			// go over the stack backwards
+			df.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);
+
+			this._makeClean();
+
+			// BEGIN FOR HTML CANVAS
+			if(this.surface.render){ this.surface.render(); };
+			// END FOR HTML CANVAS
+
+			return this;	//	dojox.charting.Chart
+		},
+		fullRender: function(){
+			//	summary:
+			//		Force a full rendering of the chart, including full resets on the chart itself.
+			//		You should not call this method directly unless absolutely necessary.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+
+			// calculate geometry
+			this.fullGeometry();
+			var offsets = this.offsets, dim = this.dim, rect;
+
+			// get required colors
+			//var requiredColors = df.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);
+            }
+			this.surface.clear();
+            this.chartTitle = null;
+
+			// generate shapes
+
+			// draw a plot background
+			var t = this.theme,
+				fill   = t.plotarea && t.plotarea.fill,
+				stroke = t.plotarea && t.plotarea.stroke,
+				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
+				};
+			if(fill){
+				fill = dc.Element.prototype._shapeFill(dc.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
+				}).setStroke(stroke);
+			}
+
+			// go over the stack backwards
+			df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);
+
+			// pseudo-clipping: matting
+			fill   = this.fill   !== undefined ? this.fill   : (t.chart && t.chart.fill);
+			stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);
+
+			//	TRT: support for "inherit" as a named value in a theme.
+			if(fill == "inherit"){
+				//	find the background color of the nearest ancestor node, and use that explicitly.
+				var node = this.node, fill = new dojo.Color(dojo.style(node, "backgroundColor"));
+				while(fill.a==0 && node!=document.documentElement){
+					fill = new dojo.Color(dojo.style(node, "backgroundColor"));
+					node = node.parentNode;
+				}
+			}
+
+			if(fill){
+				fill = dc.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));
+				}
+				if(offsets.r){	// right
+					rect = {
+						x: dim.width - offsets.r,
+						width:  offsets.r + 1,
+						height: dim.height + 2
+					};
+					this.surface.createRect(rect).setFill(dc.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));
+				}
+				if(offsets.b){	// bottom
+					rect = {
+						y: dim.height - offsets.b,
+						width:  dim.width + 1,
+						height: offsets.b + 2
+					};
+					this.surface.createRect(rect).setFill(dc.Element.prototype._shapeFill(fill, rect));
+				}
+			}
+			if(stroke){
+				this.surface.createRect({
+					width:  dim.width - 1,
+					height: dim.height - 1
+				}).setStroke(stroke);
+			}
+
+			//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",
+					tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
+				this.chartTitle = dc.axis2d.common.createText[labelType](
+					this,
+					this.surface,
+					dim.width/2,
+					this.titlePos=="top" ? tsize + this.margins.t : dim.height - this.margins.b,
+					"middle",
+					this.title,
+					this.titleFont,
+					this.titleFontColor
+				);
+			}
+
+			// go over axes
+			df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });
+
+			this._makeClean();
+
+			// BEGIN FOR HTML CANVAS
+			if(this.surface.render){ this.surface.render(); };
+			// END FOR HTML CANVAS
+
+			return this;	//	dojox.charting.Chart
+		},
+		delayedRender: function(){
+			//	summary:
+			//		Delayed render, which is used to collect multiple updates
+			//		within a delayInMs time window.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+
+			if(!this._delayedRenderHandle){
+				this._delayedRenderHandle = setTimeout(
+					dojo.hitch(this, function(){
+						clearTimeout(this._delayedRenderHandle);
+						this._delayedRenderHandle = null;
+						this.render();
+					}),
+					this.delayInMs
+				);
+			}
+
+			return this;	//	dojox.charting.Chart
+		},
+		connectToPlot: function(name, object, method){
+			//	summary:
+			//		A convenience method to connect a function to a plot.
+			//	name: String
+			//		The name of the plot as defined by addPlot.
+			//	object: Object
+			//		The object to be connected.
+			//	method: Function
+			//		The function to be executed.
+			//	returns: Array
+			//		A handle to the connection, as defined by dojo.connect (see dojo.connect).
+			return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null;	//	Array
+		},
+		fireEvent: function(seriesName, eventName, index){
+			//	summary:
+			//		Fires a synthetic event for a series item.
+			//	seriesName: String:
+			//		Series name.
+			//	eventName: String:
+			//		Event name to simulate: onmouseover, onmouseout, onclick.
+			//	index: Number:
+			//		Valid data value index for the event.
+			//	returns: dojox.charting.Chart
+			//		A reference to the current chart for functional chaining.
+			if(seriesName in this.runs){
+				var plotName = this.series[this.runs[seriesName]].plot;
+				if(plotName in this.plots){
+					var plot = this.stack[this.plots[plotName]];
+					if(plot){
+						plot.fireEvent(seriesName, eventName, index);
+					}
+				}
+			}
+			return this;	//	dojox.charting.Chart
+		},
+		_makeClean: function(){
+			// reset dirty flags
+			dojo.forEach(this.axes,   makeClean);
+			dojo.forEach(this.stack,  makeClean);
+			dojo.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);
+			this.dirty = true;
+		},
+		_invalidateDependentPlots: function(plotName, /* Boolean */ verticalAxis){
+			if(plotName in this.plots){
+				var plot = this.stack[this.plots[plotName]], axis,
+					axisName = verticalAxis ? "vAxis" : "hAxis";
+				if(plot[axisName]){
+					axis = this.axes[plot[axisName]];
+					if(axis && axis.dependOnData()){
+						axis.dirty = true;
+						// find all plots and mark them dirty
+						dojo.forEach(this.stack, function(p){
+							if(p[axisName] && p[axisName] == plot[axisName]){
+								p.dirty = true;
+							}
+						});
+					}
+				}else{
+					plot.dirty = true;
+				}
+			}
+		}
+	});
+
+	function hSection(stats){
+		return {min: stats.hmin, max: stats.hmax};
+	}
+
+	function vSection(stats){
+		return {min: stats.vmin, max: stats.vmax};
+	}
+
+	function hReplace(stats, h){
+		stats.hmin = h.min;
+		stats.hmax = h.max;
+	}
+
+	function vReplace(stats, v){
+		stats.vmin = v.min;
+		stats.vmax = v.max;
+	}
+
+	function combineStats(target, source){
+		if(target && source){
+			target.min = Math.min(target.min, source.min);
+			target.max = Math.max(target.max, source.max);
+		}
+		return target || source;
+	}
+
+	function calculateAxes(stack, plotArea){
+		var plots = {}, axes = {};
+		dojo.forEach(stack, function(plot){
+			var stats = plots[plot.name] = plot.getSeriesStats();
+			if(plot.hAxis){
+				axes[plot.hAxis] = combineStats(axes[plot.hAxis], hSection(stats));
+			}
+			if(plot.vAxis){
+				axes[plot.vAxis] = combineStats(axes[plot.vAxis], vSection(stats));
+			}
+		});
+		dojo.forEach(stack, function(plot){
+			var stats = plots[plot.name];
+			if(plot.hAxis){
+				hReplace(stats, axes[plot.hAxis]);
+			}
+			if(plot.vAxis){
+				vReplace(stats, axes[plot.vAxis]);
+			}
+			plot.initializeScalers(plotArea, stats);
+		});
+	}
+})();
diff --git a/dojox/charting/Chart2D.js b/dojox/charting/Chart2D.js
index 60244e7..438f934 100644
--- a/dojox/charting/Chart2D.js
+++ b/dojox/charting/Chart2D.js
@@ -1,12 +1,6 @@
 dojo.provide("dojox.charting.Chart2D");
 
-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.Theme");
-dojo.require("dojox.charting.Series");
+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");
@@ -33,1025 +27,9 @@ 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");
 
-/*=====
-dojox.charting.__Chart2DCtorArgs = function(margins, stroke, fill, delayInMs){
-	//	summary:
-	//		The keyword arguments that can be passed in a Chart2D 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,
-		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");
-
-	dojo.declare("dojox.charting.Chart2D", null, {
-		//	summary:
-		//		The main chart object in dojox.charting.  This will create a two dimensional
-		//		chart based on dojox.gfx.
-		//
-		//	description:
-		//		dojox.charting.Chart2D is the primary object used for any kind of charts.  It
-		//		is simple to create--just pass it a node reference, which is used as the
-		//		container for the chart--and a set of optional keyword arguments and go.
-		//
-		//		Note that like most of dojox.gfx, most of dojox.charting.Chart2D's methods are
-		//		designed to return a reference to the chart itself, to allow for functional
-		//		chaining.  This makes defining everything on a Chart very easy to do.
-		//
-		//	example:
-		//		Create an area chart, with smoothing.
-		//	|	new dojox.charting.Chart2D(node))
-		//	|		.addPlot("default", { type: "Areas", tension: "X" })
-		//	|		.setTheme(dojox.charting.themes.Shrooms)
-		//	|		.addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
-		//	|		.addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
-		//	|		.addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
-		//	|		.render();
-		//
-		//	example:
-		//		The form of data in a data series can take a number of forms: a simple array,
-		//		an array of objects {x,y}, or something custom (as determined by the plot).
-		//		Here's an example of a Candlestick chart, which expects an object of
-		//		{ open, high, low, close }.
-		//	|	new dojox.charting.Chart2D(node))
-		//	|		.addPlot("default", {type: "Candlesticks", gap: 1})
-		//	|		.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true})
-		//	|		.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true})
-		//	|		.addSeries("Series A", [
-		//	|				{ open: 20, close: 16, high: 22, low: 8 },
-		//	|				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
-		//	|				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
-		//	|				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
-		//	|				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
-		//	|				{ open: 24, close: 8, high: 24, low: 5 },
-		//	|				{ open: 8, close: 16, high: 22, low: 2 },
-		//	|				{ open: 16, close: 12, high: 19, low: 7 },
-		//	|				{ open: 12, close: 20, high: 22, low: 8 },
-		//	|				{ open: 20, close: 16, high: 22, low: 8 },
-		//	|				{ open: 16, close: 22, high: 26, low: 6, mid: 18 },
-		//	|				{ open: 22, close: 18, high: 22, low: 11, mid: 21 },
-		//	|				{ open: 18, close: 29, high: 32, low: 14, mid: 27 },
-		//	|				{ open: 29, close: 24, high: 29, low: 13, mid: 27 },
-		//	|				{ open: 24, close: 8, high: 24, low: 5 },
-		//	|				{ open: 8, close: 16, high: 22, low: 2 },
-		//	|				{ open: 16, close: 12, high: 19, low: 7 },
-		//	|				{ open: 12, close: 20, high: 22, low: 8 },
-		//	|				{ open: 20, close: 16, high: 22, low: 8 },
-		//	|				{ open: 16, close: 22, high: 26, low: 6 },
-		//	|				{ open: 22, close: 18, high: 22, low: 11 },
-		//	|				{ open: 18, close: 29, high: 32, low: 14 },
-		//	|				{ open: 29, close: 24, high: 29, low: 13 },
-		//	|				{ open: 24, close: 8, high: 24, low: 5 },
-		//	|				{ open: 8, close: 16, high: 22, low: 2 },
-		//	|				{ open: 16, close: 12, high: 19, low: 7 },
-		//	|				{ open: 12, close: 20, high: 22, low: 8 },
-		//	|				{ open: 20, close: 16, high: 22, low: 8 }
-		//	|			],
-		//	|			{ stroke: { color: "green" }, fill: "lightgreen" }
-		//	|		)
-		//	|		.render();
-		//
-		//	theme: dojox.charting.Theme?
-		//		An optional theme to use for styling the chart.
-		//	axes: dojox.charting.Axis{}?
-		//		A map of axes for use in plotting a chart.
-		//	stack: dojox.charting.plot2d.Base[]
-		//		A stack of plotters.
-		//	plots: dojox.charting.plot2d.Base{}
-		//		A map of plotter indices
-		//	series: dojox.charting.Series[]
-		//		The stack of data runs used to create plots.
-		//	runs: dojox.charting.Series{}
-		//		A map of series indices
-		//	margins: Object?
-		//		The margins around the chart. Default is { l:10, t:10, r:10, b:10 }.
-		//	stroke: dojox.gfx.Stroke?
-		//		The outline of the chart (stroke in vector graphics terms).
-		//	fill: dojox.gfx.Fill?
-		//		The color for the chart.
-		//	node: DOMNode
-		//		The container node passed to the constructor.
-		//	surface: dojox.gfx.Surface
-		//		The main graphics surface upon which a chart is drawn.
-		//	dirty: Boolean
-		//		A boolean flag indicating whether or not the chart needs to be updated/re-rendered.
-		//	coords: Object
-		//		The coordinates on a page of the containing node, as returned from dojo.coords.
-
-		constructor: function(/* DOMNode */node, /* dojox.charting.__Chart2DCtorArgs? */kwArgs){
-			//	summary:
-			//		The constructor for a new Chart2D.  Initializes all parameters used for a chart.
-			//	returns: dojox.charting.Chart2D
-			//		The newly created chart.
-
-			// initialize parameters
-			if(!kwArgs){ kwArgs = {}; }
-			this.margins   = kwArgs.margins ? kwArgs.margins : {l: 10, t: 10, r: 10, b: 10};
-			this.stroke    = kwArgs.stroke;
-			this.fill      = kwArgs.fill;
-			this.delayInMs = kwArgs.delayInMs || 200;
-
-			// default initialization
-			this.theme = null;
-			this.axes = {};		// map of axes
-			this.stack = [];	// stack of plotters
-			this.plots = {};	// map of plotter indices
-			this.series = [];	// stack of data runs
-			this.runs = {};		// map of data run indices
-			this.dirty = true;
-			this.coords = null;
-
-			// create a surface
-			this.node = dojo.byId(node);
-			var box = dojo.marginBox(node);
-			this.surface = dojox.gfx.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);
-			this.surface.destroy();
-		},
-		getCoords: function(){
-			//	summary:
-			//		Get the coordinates and dimensions of the containing DOMNode, as
-			//		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
-		},
-		setTheme: function(theme){
-			//	summary:
-			//		Set a theme of the chart.
-			//	theme: dojox.charting.Theme
-			//		The theme to be used for visual rendering.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			this.theme = theme.clone();
-			this.dirty = true;
-			return this;	//	dojox.charting.Chart2D
-		},
-		addAxis: function(name, kwArgs){
-			//	summary:
-			//		Add an axis to the chart, for rendering.
-			//	name: String
-			//		The name of the axis.
-			//	kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
-			//		An optional keyword arguments object for use in defining details of an axis.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			var axis;
-			if(!kwArgs || !("type" in kwArgs)){
-				axis = new dc.axis2d.Default(this, kwArgs);
-			}else{
-				axis = typeof kwArgs.type == "string" ?
-					new dc.axis2d[kwArgs.type](this, kwArgs) :
-					new kwArgs.type(this, kwArgs);
-			}
-			axis.name = name;
-			axis.dirty = true;
-			if(name in this.axes){
-				this.axes[name].destroy();
-			}
-			this.axes[name] = axis;
-			this.dirty = true;
-			return this;	//	dojox.charting.Chart2D
-		},
-		getAxis: function(name){
-			//	summary:
-			//		Get the given axis, by name.
-			//	name: String
-			//		The name the axis was defined by.
-			//	returns: dojox.charting.axis2d.Default
-			//		The axis as stored in the chart's axis map.
-			return this.axes[name];	//	dojox.charting.axis2d.Default
-		},
-		removeAxis: function(name){
-			//	summary:
-			//		Remove the axis that was defined using name.
-			//	name: String
-			//		The axis name, as defined in addAxis.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.axes){
-				// destroy the axis
-				this.axes[name].destroy();
-				delete this.axes[name];
-				// mark the chart as dirty
-				this.dirty = true;
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		addPlot: function(name, kwArgs){
-			//	summary:
-			//		Add a new plot to the chart, defined by name and using the optional keyword arguments object.
-			//		Note that dojox.charting assumes the main plot to be called "default"; if you do not have
-			//		a plot called "default" and attempt to add data series to the chart without specifying the
-			//		plot to be rendered on, you WILL get errors.
-			//	name: String
-			//		The name of the plot to be added to the chart.  If you only plan on using one plot, call it "default".
-			//	kwArgs: dojox.charting.plot2d.__PlotCtorArgs
-			//		An object with optional parameters for the plot in question.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			var plot;
-			if(!kwArgs || !("type" in kwArgs)){
-				plot = new dc.plot2d.Default(this, kwArgs);
-			}else{
-				plot = typeof kwArgs.type == "string" ?
-					new dc.plot2d[kwArgs.type](this, kwArgs) :
-					new kwArgs.type(this, kwArgs);
-			}
-			plot.name = name;
-			plot.dirty = true;
-			if(name in this.plots){
-				this.stack[this.plots[name]].destroy();
-				this.stack[this.plots[name]] = plot;
-			}else{
-				this.plots[name] = this.stack.length;
-				this.stack.push(plot);
-			}
-			this.dirty = true;
-			return this;	//	dojox.charting.Chart2D
-		},
-		removePlot: function(name){
-			//	summary:
-			//		Remove the plot defined using name from the chart's plot stack.
-			//	name: String
-			//		The name of the plot as defined using addPlot.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.plots){
-				// get the index and remove the name
-				var index = this.plots[name];
-				delete this.plots[name];
-				// destroy the plot
-				this.stack[index].destroy();
-				// 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){
-					if(idx > index){
-						plots[name] = idx - 1;
-					}
-				});
-				// mark the chart as dirty
-				this.dirty = true;
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		getPlotOrder: function(){
-			//	summary:
-			//		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
-		},
-		setPlotOrder: function(newOrder){
-			//	summary:
-			//		Sets new order of plots. newOrder cannot add or remove
-			//		plots. Wrong names, or dups are ignored.
-			//	newOrder: Array:
-			//		Array of plot names compatible with getPlotOrder().
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			var names = {},
-				order = df.filter(newOrder, function(name){
-					if(!(name in this.plots) || (name in names)){
-						return false;
-					}
-					names[name] = 1;
-					return true;
-				}, this);
-			if(order.length < this.stack.length){
-				df.forEach(this.stack, function(plot){
-					var name = plot.name;
-					if(!(name in names)){
-						order.push(name);
-					}
-				});
-			}
-			var newStack = df.map(order, function(name){
-					return this.stack[this.plots[name]];
-				}, this);
-			df.forEach(newStack, function(plot, i){
-				this.plots[plot.name] = i;
-			}, this);
-			this.stack = newStack;
-			this.dirty = true;
-			return this;	//	dojox.charting.Chart2D
-		},
-		movePlotToFront: function(name){
-			//	summary:
-			//		Moves a given plot to front.
-			//	name: String:
-			//		Plot's name to move.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.plots){
-				var index = this.plots[name];
-				if(index){
-					var newOrder = this.getPlotOrder();
-					newOrder.splice(index, 1);
-					newOrder.unshift(name);
-					return this.setPlotOrder(newOrder);	//	dojox.charting.Chart2D
-				}
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		movePlotToBack: function(name){
-			//	summary:
-			//		Moves a given plot to back.
-			//	name: String:
-			//		Plot's name to move.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.plots){
-				var index = this.plots[name];
-				if(index < this.stack.length - 1){
-					var newOrder = this.getPlotOrder();
-					newOrder.splice(index, 1);
-					newOrder.push(name);
-					return this.setPlotOrder(newOrder);	//	dojox.charting.Chart2D
-				}
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		addSeries: function(name, data, kwArgs){
-			//	summary:
-			//		Add a data series to the chart for rendering.
-			//	name: String:
-			//		The name of the data series to be plotted.
-			//	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 that will be mixed into
-			//		the resultant series object.
-			//	returns: dojox.charting.Chart2D:
-			//		A reference to the current chart for functional chaining.
-			var run = new dc.Series(this, data, kwArgs);
-			run.name = name;
-			if(name in this.runs){
-				this.series[this.runs[name]].destroy();
-				this.series[this.runs[name]] = run;
-			}else{
-				this.runs[name] = this.series.length;
-				this.series.push(run);
-			}
-			this.dirty = true;
-			// fix min/max
-			if(!("ymin" in run) && "min" in run){ run.ymin = run.min; }
-			if(!("ymax" in run) && "max" in run){ run.ymax = run.max; }
-			return this;	//	dojox.charting.Chart2D
-		},
-		removeSeries: function(name){
-			//	summary:
-			//		Remove the series defined by name from the chart.
-			//	name: String
-			//		The name of the series as defined by addSeries.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.runs){
-				// get the index and remove the name
-				var index = this.runs[name],
-					plotName = this.series[index].plot;
-				delete this.runs[name];
-				// destroy the run
-				this.series[index].destroy();
-				// 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){
-					if(idx > index){
-						runs[name] = idx - 1;
-					}
-				});
-				this.dirty = true;
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		updateSeries: function(name, data){
-			//	summary:
-			//		Update the given series with a new set of data points.
-			//	name: String
-			//		The name of the series as defined in addSeries.
-			//	data: Array|Object:
-			//		The array of data points (either numbers or objects) that
-			//		represents the data to be drawn. Or it can be an object. In
-			//		the latter case, it should have a property "data" (an array),
-			//		destroy(), and setSeriesObject().
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.runs){
-				var run = this.series[this.runs[name]];
-				run.update(data);
-				this._invalidateDependentPlots(run.plot, false);
-				this._invalidateDependentPlots(run.plot, true);
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		getSeriesOrder: function(plotName){
-			//	summary:
-			//		Returns an array of series names in the current order
-			//		(the top-most series is the first) within a plot.
-			//	plotName: String:
-			//		Plot's name.
-			//	returns: Array
-			return df.map(df.filter(this.series, function(run){
-					return run.plot == plotName;
-				}), getName);
-		},
-		setSeriesOrder: function(newOrder){
-			//	summary:
-			//		Sets new order of series within a plot. newOrder cannot add
-			//		or remove series. Wrong names, or dups are ignored.
-			//	newOrder: Array:
-			//		Array of series names compatible with getPlotOrder(). All
-			//		series should belong to the same plot.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			var plotName, names = {},
-				order = df.filter(newOrder, function(name){
-					if(!(name in this.runs) || (name in names)){
-						return false;
-					}
-					var run = this.series[this.runs[name]];
-					if(plotName){
-						if(run.plot != plotName){
-							return false;
-						}
-					}else{
-						plotName = run.plot;
-					}
-					names[name] = 1;
-					return true;
-				}, this);
-			df.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){
-					return this.series[this.runs[name]];
-				}, this);
-			this.series = newSeries.concat(df.filter(this.series, function(run){
-				return run.plot != plotName;
-			}));
-			df.forEach(this.series, function(run, i){
-				this.runs[run.name] = i;
-			}, this);
-			this.dirty = true;
-			return this;	//	dojox.charting.Chart2D
-		},
-		moveSeriesToFront: function(name){
-			//	summary:
-			//		Moves a given series to front of a plot.
-			//	name: String:
-			//		Series' name to move.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.runs){
-				var index = this.runs[name],
-					newOrder = this.getSeriesOrder(this.series[index].plot);
-				if(name != newOrder[0]){
-					newOrder.splice(index, 1);
-					newOrder.unshift(name);
-					return this.setSeriesOrder(newOrder);	//	dojox.charting.Chart2D
-				}
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		moveSeriesToBack: function(name){
-			//	summary:
-			//		Moves a given series to back of a plot.
-			//	name: String:
-			//		Series' name to move.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(name in this.runs){
-				var index = this.runs[name],
-					newOrder = this.getSeriesOrder(this.series[index].plot);
-				if(name != newOrder[newOrder.length - 1]){
-					newOrder.splice(index, 1);
-					newOrder.push(name);
-					return this.setSeriesOrder(newOrder);	//	dojox.charting.Chart2D
-				}
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		resize: function(width, height){
-			//	summary:
-			//		Resize the chart to the dimensions of width and height.
-			//	width: Number
-			//		The new width of the chart.
-			//	height: Number
-			//		The new height of the chart.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			var box;
-			switch(arguments.length){
-				case 0:
-					box = dojo.marginBox(this.node);
-					break;
-				case 1:
-					box = width;
-					break;
-				default:
-					box = { w: width, h: height };
-					break;
-			}
-			dojo.marginBox(this.node, box);
-			this.surface.setDimensions(box.w, box.h);
-			this.dirty = true;
-			this.coords = null;
-			return this.render();	//	dojox.charting.Chart2D
-		},
-		getGeometry: function(){
-			//	summary:
-			//		Returns a map of information about all axes in a chart and what they represent
-			//		in terms of scaling (see dojox.charting.axis2d.Default.getScaler).
-			//	returns: Object
-			//		An map of geometry objects, a one-to-one mapping of axes.
-			var ret = {};
-			df.forIn(this.axes, function(axis){
-				if(axis.initialized()){
-					ret[axis.name] = {
-						name:		axis.name,
-						vertical:	axis.vertical,
-						scaler:		axis.scaler,
-						ticks:		axis.ticks
-					};
-				}
-			});
-			return ret;	//	Object
-		},
-		setAxisWindow: function(name, scale, offset, zoom){
-			//	summary:
-			//		Zooms an axis and all dependent plots. Can be used to zoom in 1D.
-			//	name: String
-			//		The name of the axis as defined by addAxis.
-			//	scale: Number
-			//		The scale on the target axis.
-			//	offset: Number
-			//		Any offest, as measured by axis tick
-			//	zoom: Boolean|Object?
-			//		The chart zooming animation trigger.  This is null by default,
-			//		e.g. {duration: 1200}, or just set true.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			var axis = this.axes[name];
-			if(axis){
-				axis.setWindow(scale, offset);
-				dojo.forEach(this.stack,function(plot){
-					if(plot.hAxis == name || plot.vAxis == name){
-						plot.zoom = zoom;
-					}
-				})
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		setWindow: function(sx, sy, dx, dy, zoom){
-			//	summary:
-			//		Zooms in or out any plots in two dimensions.
-			//	sx: Number
-			//		The scale for the x axis.
-			//	sy: Number
-			//		The scale for the y axis.
-			//	dx: Number
-			//		The pixel offset on the x axis.
-			//	dy: Number
-			//		The pixel offset on the y axis.
-			//	zoom: Boolean|Object?
-			//		The chart zooming animation trigger.  This is null by default,
-			//		e.g. {duration: 1200}, or just set true.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(!("plotArea" in this)){
-				this.calculateGeometry();
-			}
-			df.forIn(this.axes, function(axis){
-				var scale, offset, bounds = axis.getScaler().bounds,
-					s = bounds.span / (bounds.upper - bounds.lower);
-				if(axis.vertical){
-					scale  = sy;
-					offset = dy / s / scale;
-				}else{
-					scale  = sx;
-					offset = dx / s / scale;
-				}
-				axis.setWindow(scale, offset);
-			});
-			dojo.forEach(this.stack, function(plot){ plot.zoom = zoom; });
-			return this;	//	dojox.charting.Chart2D
-		},
-		zoomIn:	function(name, range){
-			//	summary:
-			//		Zoom the chart to a specific range on one axis.  This calls render()
-			//		directly as a convenience method.
-			//	name: String
-			//		The name of the axis as defined by addAxis.
-			//	range: Array
-			//		The end points of the zoom range, measured in axis ticks.
-			var axis = this.axes[name];
-			if(axis){
-				var scale, offset, bounds = axis.getScaler().bounds;
-				var lower = Math.min(range[0],range[1]);
-				var upper = Math.max(range[0],range[1]);
-				lower = range[0] < bounds.lower ? bounds.lower : lower;
-				upper = range[1] > bounds.upper ? bounds.upper : upper;
-				scale = (bounds.upper - bounds.lower) / (upper - lower);
-				offset = lower - bounds.lower;
-				this.setAxisWindow(name, scale, offset);
-				this.render();
-			}
-		},
-		calculateGeometry: function(){
-			//	summary:
-			//		Calculate the geometry of the chart based on the defined axes of
-			//		a chart.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(this.dirty){
-				return this.fullGeometry();
-			}
-
-			// calculate geometry
-			var dirty = dojo.filter(this.stack, function(plot){
-					return plot.dirty ||
-						(plot.hAxis && this.axes[plot.hAxis].dirty) ||
-						(plot.vAxis && this.axes[plot.vAxis].dirty);
-				}, this);
-			calculateAxes(dirty, this.plotArea);
-
-			return this;	//	dojox.charting.Chart2D
-		},
-		fullGeometry: function(){
-			//	summary:
-			//		Calculate the full geometry of the chart.  This includes passing
-			//		over all major elements of a chart (plots, axes, series, container)
-			//		in order to ensure proper rendering.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			this._makeDirty();
-
-			// clear old values
-			dojo.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));
-			}
-
-			// assign series
-			dojo.forEach(this.series, function(run){
-				if(!(run.plot in this.plots)){
-					var plot = new dc.plot2d.Default(this, {});
-					plot.name = run.plot;
-					this.plots[run.plot] = this.stack.length;
-					this.stack.push(plot);
-				}
-				this.stack[this.plots[run.plot]].addSeries(run);
-			}, this);
-			// assign axes
-			dojo.forEach(this.stack, function(plot){
-				if(plot.hAxis){
-					plot.setAxis(this.axes[plot.hAxis]);
-				}
-				if(plot.vAxis){
-					plot.setAxis(this.axes[plot.vAxis]);
-				}
-			}, this);
-
-			// calculate geometry
-
-			// 1st pass
-			var dim = this.dim = this.surface.getDimensions();
-			dim.width  = dojox.gfx.normalizedLength(dim.width);
-			dim.height = dojox.gfx.normalizedLength(dim.height);
-			df.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; });
-			});
-			// add margins
-			df.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);
-			calculateAxes(this.stack, this.plotArea);
-
-			return this;	//	dojox.charting.Chart2D
-		},
-		render: function(){
-			//	summary:
-			//		Render the chart according to the current information defined.  This should
-			//		be the last call made when defining/creating a chart, or if data within the
-			//		chart has been changed.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(this.theme){
-				this.theme.clear();
-			}
-
-			if(this.dirty){
-				return this.fullRender();
-			}
-
-			this.calculateGeometry();
-
-			// go over the stack backwards
-			df.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);
-
-			this._makeClean();
-
-			// BEGIN FOR HTML CANVAS
-			if(this.surface.render){ this.surface.render(); };
-			// END FOR HTML CANVAS
-
-			return this;	//	dojox.charting.Chart2D
-		},
-		fullRender: function(){
-			//	summary:
-			//		Force a full rendering of the chart, including full resets on the chart itself.
-			//		You should not call this method directly unless absolutely necessary.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-
-			// calculate geometry
-			this.fullGeometry();
-			var offsets = this.offsets, dim = this.dim;
-
-			// get required colors
-			//var requiredColors = df.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);
-			this.surface.clear();
-
-			// generate shapes
-
-			// draw a plot background
-			var t = this.theme,
-				fill   = t.plotarea && t.plotarea.fill,
-				stroke = t.plotarea && t.plotarea.stroke;
-			if(fill){
-				this.surface.createRect({
-					x: offsets.l - 1, y: offsets.t - 1,
-					width:  dim.width  - offsets.l - offsets.r + 2,
-					height: dim.height - offsets.t - offsets.b + 2
-				}).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
-				}).setStroke(stroke);
-			}
-
-			// go over the stack backwards
-			df.foldr(this.stack, function(z, plot){ return plot.render(dim, offsets), 0; }, 0);
-
-			// pseudo-clipping: matting
-			fill   = this.fill   !== undefined ? this.fill   : (t.chart && t.chart.fill);
-			stroke = this.stroke !== undefined ? this.stroke : (t.chart && t.chart.stroke);
-
-			//	TRT: support for "inherit" as a named value in a theme.
-			if(fill == "inherit"){
-				//	find the background color of the nearest ancestor node, and use that explicitly.
-				var node = this.node, fill = new dojo.Color(dojo.style(node, "backgroundColor"));
-				while(fill.a==0 && node!=document.documentElement){
-					fill = new dojo.Color(dojo.style(node, "backgroundColor"));
-					node = node.parentNode;
-				}
-			}
-
-			if(fill){
-				if(offsets.l){	// left
-					this.surface.createRect({
-						width:  offsets.l,
-						height: dim.height + 1
-					}).setFill(fill);
-				}
-				if(offsets.r){	// right
-					this.surface.createRect({
-						x: dim.width - offsets.r,
-						width:  offsets.r + 1,
-						height: dim.height + 2
-					}).setFill(fill);
-				}
-				if(offsets.t){	// top
-					this.surface.createRect({
-						width:  dim.width + 1,
-						height: offsets.t
-					}).setFill(fill);
-				}
-				if(offsets.b){	// bottom
-					this.surface.createRect({
-						y: dim.height - offsets.b,
-						width:  dim.width + 1,
-						height: offsets.b + 2
-					}).setFill(fill);
-				}
-			}
-			if(stroke){
-				this.surface.createRect({
-					width:  dim.width - 1,
-					height: dim.height - 1
-				}).setStroke(stroke);
-			}
-
-			// go over axes
-			df.forIn(this.axes, function(axis){ axis.render(dim, offsets); });
-
-			this._makeClean();
-
-			// BEGIN FOR HTML CANVAS
-			if(this.surface.render){ this.surface.render(); };
-			// END FOR HTML CANVAS
-
-			return this;	//	dojox.charting.Chart2D
-		},
-		delayedRender: function(){
-			//	summary:
-			//		Delayed render, which is used to collect multiple updates
-			//		within a delayInMs time window.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-
-			if(!this._delayedRenderHandle){
-				this._delayedRenderHandle = setTimeout(
-					dojo.hitch(this, function(){
-						clearTimeout(this._delayedRenderHandle);
-						this._delayedRenderHandle = null;
-						this.render();
-					}),
-					this.delayInMs
-				);
-			}
-
-			return this;	//	dojox.charting.Chart2D
-		},
-		connectToPlot: function(name, object, method){
-			//	summary:
-			//		A convenience method to connect a function to a plot.
-			//	name: String
-			//		The name of the plot as defined by addPlot.
-			//	object: Object
-			//		The object to be connected.
-			//	method: Function
-			//		The function to be executed.
-			//	returns: Array
-			//		A handle to the connection, as defined by dojo.connect (see dojo.connect).
-			return name in this.plots ? this.stack[this.plots[name]].connect(object, method) : null;	//	Array
-		},
-		fireEvent: function(seriesName, eventName, index){
-			//	summary:
-			//		Fires a synthetic event for a series item.
-			//	seriesName: String:
-			//		Series name.
-			//	eventName: String:
-			//		Event name to simulate: onmouseover, onmouseout, onclick.
-			//	index: Number:
-			//		Valid data value index for the event.
-			//	returns: dojox.charting.Chart2D
-			//		A reference to the current chart for functional chaining.
-			if(seriesName in this.runs){
-				var plotName = this.series[this.runs[seriesName]].plot;
-				if(plotName in this.plots){
-					var plot = this.stack[this.plots[plotName]];
-					if(plot){
-						plot.fireEvent(seriesName, eventName, index);
-					}
-				}
-			}
-			return this;	//	dojox.charting.Chart2D
-		},
-		_makeClean: function(){
-			// reset dirty flags
-			dojo.forEach(this.axes,   makeClean);
-			dojo.forEach(this.stack,  makeClean);
-			dojo.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);
-			this.dirty = true;
-		},
-		_invalidateDependentPlots: function(plotName, /* Boolean */ verticalAxis){
-			if(plotName in this.plots){
-				var plot = this.stack[this.plots[plotName]], axis,
-					axisName = verticalAxis ? "vAxis" : "hAxis";
-				if(plot[axisName]){
-					axis = this.axes[plot[axisName]];
-					if(axis && axis.dependOnData()){
-						axis.dirty = true;
-						// find all plots and mark them dirty
-						dojo.forEach(this.stack, function(p){
-							if(p[axisName] && p[axisName] == plot[axisName]){
-								p.dirty = true;
-							}
-						});
-					}
-				}else{
-					plot.dirty = true;
-				}
-			}
-		}
-	});
-
-	function hSection(stats){
-		return {min: stats.hmin, max: stats.hmax};
-	}
-
-	function vSection(stats){
-		return {min: stats.vmin, max: stats.vmax};
-	}
-
-	function hReplace(stats, h){
-		stats.hmin = h.min;
-		stats.hmax = h.max;
-	}
-
-	function vReplace(stats, v){
-		stats.vmin = v.min;
-		stats.vmax = v.max;
-	}
-
-	function combineStats(target, source){
-		if(target && source){
-			target.min = Math.min(target.min, source.min);
-			target.max = Math.max(target.max, source.max);
-		}
-		return target || source;
-	}
+// require the main file
+dojo.require("dojox.charting.Chart");
 
-	function calculateAxes(stack, plotArea){
-		var plots = {}, axes = {};
-		dojo.forEach(stack, function(plot){
-			var stats = plots[plot.name] = plot.getSeriesStats();
-			if(plot.hAxis){
-				axes[plot.hAxis] = combineStats(axes[plot.hAxis], hSection(stats));
-			}
-			if(plot.vAxis){
-				axes[plot.vAxis] = combineStats(axes[plot.vAxis], vSection(stats));
-			}
-		});
-		dojo.forEach(stack, function(plot){
-			var stats = plots[plot.name];
-			if(plot.hAxis){
-				hReplace(stats, axes[plot.hAxis]);
-			}
-			if(plot.vAxis){
-				vReplace(stats, axes[plot.vAxis]);
-			}
-			plot.initializeScalers(plotArea, stats);
-		});
-	}
-})();
+dojox.charting.Chart2D = dojox.charting.Chart;
diff --git a/dojox/charting/Element.js b/dojox/charting/Element.js
index b640b61..9450396 100644
--- a/dojox/charting/Element.js
+++ b/dojox/charting/Element.js
@@ -29,6 +29,8 @@ dojo.declare("dojox.charting.Element", null, {
 		this.group = null;
 		this.htmlElements = [];
 		this.dirty = true;
+		this.trailingSymbol = "...";
+		this._events = [];
 	},
 	createGroup: function(creator){
 		//	summary:
@@ -55,6 +57,12 @@ dojo.declare("dojox.charting.Element", null, {
 			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){
@@ -87,6 +95,113 @@ dojo.declare("dojox.charting.Element", null, {
 		//		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;
+					}
+					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){
+			return {
+				text: s,
+				truncated: truncated || false
+			};
+		}
+		return {
+			text: s.substring(0, wcLimit) + this.trailingSymbol,
+			truncated: true
+		};
+	},
 	// fill utilities
 	_plotFill: function(fill, dim, offsets){
 		// process a plot-wide fill
diff --git a/dojox/charting/Series.js b/dojox/charting/Series.js
index edd1b44..812b29c 100644
--- a/dojox/charting/Series.js
+++ b/dojox/charting/Series.js
@@ -8,7 +8,7 @@ dojox.charting.__SeriesCtorArgs = function(plot){
 	//	plot: String?
 	//		The plot (by name) that this series belongs to.
 	this.plot = plot;
-} 
+}
 =====*/
 dojo.declare("dojox.charting.Series", dojox.charting.Element, {
 	//	summary:
diff --git a/dojox/charting/StoreSeries.js b/dojox/charting/StoreSeries.js
new file mode 100644
index 0000000..54d927d
--- /dev/null
+++ b/dojox/charting/StoreSeries.js
@@ -0,0 +1,98 @@
+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;
+				};
+			}else{
+				this.value = function(object){
+					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);
+			});
+			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 63703c8..3747523 100644
--- a/dojox/charting/Theme.js
+++ b/dojox/charting/Theme.js
@@ -89,6 +89,7 @@ dojo.declare("dojox.charting.Theme", null, {
 	//	|		fill:    "#ccc",							// fill, if appropriate
 	//	|		font:    "normal normal normal 8pt Tahoma",	// if there's a label
 	//	|		fontColor: "#000"							// color of labels
+	//	|		labelWiring: {width: 1, color: "#ccc"},		// connect marker and target data item(slice, column, bar...)
 	//	|	},
 	//	|	marker: {	// any markers on a series
 	//	|		symbol:  "m-3,3 l3,-6 3,6 z",				// symbol
@@ -134,7 +135,7 @@ dojo.declare("dojox.charting.Theme", null, {
 		if(kwArgs.markerThemes && kwArgs.markerThemes.length){
 			this.markerThemes = kwArgs.markerThemes.slice(0);
 		}
-		this.markers = dojo.delegate(dojox.charting.Theme.defaultMarkers, kwArgs.markers);
+		this.markers = kwArgs.markers ? dojo.clone(kwArgs.markers) : dojo.delegate(dojox.charting.Theme.defaultMarkers);
 
 		// set flags
 		this.noGradConv = kwArgs.noGradConv;
@@ -295,7 +296,7 @@ dojo.declare("dojox.charting.Theme", null, {
 					dojo.setObject("series.fill", mixin.color, t);
 				}
 			}
-			dojo.forEach(["stroke", "outline", "shadow", "fill", "font", "fontColor"], function(name){
+			dojo.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){
@@ -481,7 +482,11 @@ dojo.mixin(dojox.charting.Theme, {
 		chart:{
 			stroke: null,
 			fill: "white",
-			pageStyle: null
+			pageStyle: null,
+			titleGap:		20,
+			titlePos:		"top",
+			titleFont:      "normal normal bold 14pt Tahoma",	// labels on axis
+			titleFontColor: "#333"
 		},
 		plotarea:{
 			stroke: null,
@@ -497,7 +502,11 @@ dojo.mixin(dojox.charting.Theme, {
 				color:     "#666",
 				position:  "center",
 				font:      "normal normal normal 7pt Tahoma",	// labels on axis
-				fontColor: "#333"								// color of labels
+				fontColor: "#333",								// color of labels
+				titleGap:  15,
+				titleFont: "normal normal normal 11pt Tahoma",	// labels on axis
+				titleFontColor: "#333",							// color of labels
+				titleOrientation: "axis"						// "axis": facing the axis, "away": facing away
 			},
 			majorTick:	{ // major ticks on axis, and used for major gridlines
 				width:  1,
@@ -520,7 +529,8 @@ dojo.mixin(dojox.charting.Theme, {
 			shadow: null,								// no shadow
 			fill:    "#ccc",							// fill, if appropriate
 			font:    "normal normal normal 8pt Tahoma",	// if there's a label
-			fontColor: "#000"							// color of labels
+			fontColor: "#000",							// color of labels
+			labelWiring: {width: 1, color: "#ccc"}		// connect marker and target data item(slice, column, bar...)
 		},
 		marker: {	// any markers on a series
 			stroke:  {width: 1.5, color: "#333"},		// stroke
diff --git a/dojox/charting/action2d/Base.js b/dojox/charting/action2d/Base.js
index 598de23..175d9e6 100644
--- a/dojox/charting/action2d/Base.js
+++ b/dojox/charting/action2d/Base.js
@@ -10,9 +10,9 @@ dojox.charting.action2d.__BaseCtorArgs = function(duration, easing){
 	//		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: dojox.fx.easing.*?
+	//	easing: dojo.fx.easing.*?
 	//		An easing object (see dojo.fx.easing) for use in an animation.  The
-	//		default is dojox.fx.easing.backOut.
+	//		default is dojo.fx.easing.backOut.
 	this.duration = duration;
 	this.easing = easing;
 }
diff --git a/dojox/charting/action2d/Tooltip.js b/dojox/charting/action2d/Tooltip.js
index e619e34..b656226 100644
--- a/dojox/charting/action2d/Tooltip.js
+++ b/dojox/charting/action2d/Tooltip.js
@@ -1,8 +1,9 @@
 dojo.provide("dojox.charting.action2d.Tooltip");
 
+dojo.require("dijit.Tooltip");
+
 dojo.require("dojox.charting.action2d.Base");
 dojo.require("dojox.gfx.matrix");
-dojo.require("dijit.Tooltip");
 
 dojo.require("dojox.lang.functional");
 dojo.require("dojox.lang.functional.scan");
@@ -14,7 +15,7 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 	//		Additional arguments for tooltip actions.
 
 	//	text: Function?
-	//		The function that produces the text to be shown within a tooltip.  By default this will be 
+	//		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
 });
@@ -69,8 +70,11 @@ 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"){
-				hideChartingTooltip(this.aroundRect);
+                dijit.hideTooltip(this.aroundRect);
 				this.aroundRect = null;
+				if(o.type === "onplotreset"){
+					delete this.angles;
+				}
 				return;
 			}
 			
@@ -145,179 +149,11 @@ dojo.declare("dojox.charting.action2d.__TooltipCtorArgs", dojox.charting.action2
 			aroundRect.width = Math.ceil(aroundRect.width);
 			aroundRect.height = Math.ceil(aroundRect.height);
 			this.aroundRect = aroundRect;
-			
-			showChartingTooltip(this.text(o), this.aroundRect, position, "center");
-		}
-	});
-	
-	//TODO: make the charting tooltip a generic one so it can be used with
-	// dojox.gfx shapes without charting.
-	
-	var MasterTooltip = dojo.declare(dijit._MasterTooltip, {
-		
-		show: function(/*String*/ innerHTML, /*DomNode*/ aroundNode, /*String[]?*/ position, /*String*/alignment){
-			// summary:
-			//		Display tooltip w/specified contents to right of specified node
-			//		(To left if there's no space on the right, or if LTR==right)
-			// alignment: String
-			//		"center":   tooltip center alignment
-			//      "default":  tooltip default alignment (left, right, top, bottom)
 
-			if(this.aroundNode && this.aroundNode === aroundNode){
-				return;
+			var tooltip = this.text(o);
+			if(tooltip){
+                dijit.showTooltip(tooltip, this.aroundRect, position);
 			}
-
-			if(this.fadeOut.status() == "playing"){
-				// previous tooltip is being hidden; wait until the hide completes then show new one
-				this._onDeck=arguments;
-				return;
-			}
-			this.containerNode.innerHTML=innerHTML;
-
-			// Firefox bug. when innerHTML changes to be shorter than previous
-			// one, the node size will not be updated until it moves.
-			this.domNode.style.top = (this.domNode.offsetTop + 1) + "px";
-			
-			if(!this.connectorNode) this.connectorNode = dojo.query(".dijitTooltipConnector", this.domNode)[0];
-			var connectorPos = dojo.coords(this.connectorNode);
-			this.arrowWidth = connectorPos.w, this.arrowHeight = connectorPos.h;
-			this.place = (alignment && alignment == "center") ? this.placeChartingTooltip : dijit.placeOnScreenAroundElement,
-			this.place(
-				this.domNode,
-				aroundNode,
-				dijit.getPopupAroundAlignment(
-					(position && position.length) ? position : dijit.Tooltip.defaultPosition,
-					this.isLeftToRight()
-				),
-				dojo.hitch(this, "orient")
-			);
-
-			// show it
-			dojo.style(this.domNode, "opacity", 0);
-			this.fadeIn.play();
-			this.isShowingNow = true;
-			this.aroundNode = aroundNode;
-		},
-		
-		placeChartingTooltip: function(node, aroundRect, aroundCorners, layoutNode){
-			return this._placeOnScreenAroundRect(node, 
-				aroundRect.x, aroundRect.y, aroundRect.width, aroundRect.height,	// rectangle
-				aroundCorners, layoutNode);
-		},
-		
-		_placeOnScreenAroundRect: function(node, x, y, width, height, aroundCorners, layoutNode){
-			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),
-		                w: width,
-		                h: height
-		            }
-		        });
-		    }
-		    return this._place(node, choices, layoutNode);
-		},
-		
-		_place: function(/* DomNode */node, /* Array */ choices, /* Function */ layoutNode){
-		    var view = dijit.getViewport();
-		    
-		    if (!node.parentNode ||
-		    String(node.parentNode.tagName).toLowerCase() != "body") {
-		        dojo.body().appendChild(node);
-		    }
-		    
-		    var best = null;
-		    
-		    var arrowLeft = null, arrowTop = null;
-		    dojo.some(choices, function(choice){
-		        var corner = choice.corner;
-		        var aroundCorner = choice.aroundCorner;
-		        var pos = choice.pos;
-		        
-		        if (layoutNode) {
-		            layoutNode(node, choice.aroundCorner, corner);
-		        }
-		        
-		        // 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;
-		        
-		        var startX, startY, endX, endY, width, height, overflow;
-		        
-		        arrowLeft = null, arrowTop = null;
-		        if (aroundCorner.charAt(0) == corner.charAt(0)) { //left, right
-		            startX = (corner.charAt(1) == 'L' ? pos.x : Math.max(view.l, pos.x - mb.w)), 
-					startY = (corner.charAt(0) == 'T' ? (pos.y + pos.h / 2 - mb.h / 2) : (pos.y - pos.h / 2 - mb.h / 2)), 
-					endX = (corner.charAt(1) == 'L' ? Math.min(view.l + view.w, startX + mb.w) : pos.x), 
-					endY = startY + mb.h, 
-					width = endX - startX, 
-					height = endY - startY, 
-					overflow = (mb.w - width) + (mb.h - height);
-		            arrowTop = (mb.h - this.arrowHeight) / 2;
-		        }
-		        else { //top, bottom
-		            startX = (corner.charAt(1) == 'L' ? (pos.x + pos.w / 2 - mb.w / 2) : (pos.x - pos.w / 2 - mb.w / 2)), 
-					startY = (corner.charAt(0) == 'T' ? pos.y : Math.max(view.t, pos.y - mb.h)), 
-					endX = startX + mb.w, 
-					endY = (corner.charAt(0) == 'T' ? Math.min(view.t + view.h, startY + mb.h) : pos.y), 
-					width = endX - startX, 
-					height = endY - startY, 
-					overflow = (mb.w - width) + (mb.h - height);
-		            arrowLeft = (mb.w - this.arrowWidth) / 2;
-		        }
-		        
-		        if (best == null || overflow < best.overflow) {
-		            best = {
-		                corner: corner,
-		                aroundCorner: choice.aroundCorner,
-		                x: startX,
-		                y: startY,
-		                w: width,
-		                h: height,
-		                overflow: overflow
-		            };
-		        }
-		        return !overflow;
-		    }, this);
-		    
-		    node.style.left = best.x + "px";
-		    node.style.top = best.y + "px";
-		    
-			this.connectorNode.style.top = "";
-	        this.connectorNode.style.left = "";
-	        if (arrowTop){
-				this.connectorNode.style.top = arrowTop + "px";
-			}
-	        if (arrowLeft){
-				this.connectorNode.style.left = arrowLeft + "px";
-			}
-	        
-		    if (best.overflow && layoutNode) {
-		        layoutNode(node, best.aroundCorner, best.corner);
-		    }
-		    return best;
 		}
 	});
-	
-	var masterTT = null;
-	
-	function showChartingTooltip(innerHTML, aroundNode, position, alignment){
-		if(!masterTT){ masterTT = new MasterTooltip(); }
-		return masterTT.show(innerHTML, aroundNode, position, alignment);
-	}
-	
-	function hideChartingTooltip(aroundNode){
-		if(!masterTT){ masterTT = new MasterTooltip(); }
-		return masterTT.hide(aroundNode);
-	}
 })();
diff --git a/dojox/charting/axis2d/Default.js b/dojox/charting/axis2d/Default.js
index 894bd54..434dc05 100644
--- a/dojox/charting/axis2d/Default.js
+++ b/dojox/charting/axis2d/Default.js
@@ -123,7 +123,7 @@ dojo.require("dojox.lang.utils");
 
 	dojo.declare("dojox.charting.axis2d.Default", dojox.charting.axis2d.Invisible, {
 		//	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.
@@ -183,6 +183,8 @@ dojo.require("dojox.lang.utils");
 								// ordered by values
 			labelFunc:		null, // function to compute label values
 			maxLabelSize:	0,	// size in px. For use with labelFunc
+			maxLabelCharCount:	0,	// size in word count.
+			trailingSymbol:	null,
 
 			// TODO: add support for minRange!
 			// minRange:		1,	// smallest distance from min allowed on the axis
@@ -194,7 +196,12 @@ dojo.require("dojox.lang.utils");
 			microTick:		{},	// stroke + length for a tick
 			tick:           {},	// stroke + length for a tick
 			font:			"",	// font for labels
-			fontColor:		""	// color for labels as a string
+			fontColor:		"",	// color for labels as a string
+			title:		 		"",	// axis title
+			titleGap:	 		0,		// gap between axis title and axis label
+			titleFont:	 		"",		// axis title font
+			titleFontColor:	 	"",		// axis title font color
+			titleOrientation: 	""		// "axis" means the title facing the axis, "away" means facing away
 		},
 
 		constructor: function(chart, kwArgs){
@@ -204,8 +211,8 @@ dojo.require("dojox.lang.utils");
 			//		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.delegate(this.defaultParams, kwArgs);
-			// du.updateWithObject(this.opt, kwArgs);
+			this.opt = dojo.clone(this.defaultParams);
+            du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 		},
 		getOffsets: function(){
@@ -223,30 +230,33 @@ dojo.require("dojox.lang.utils");
 				ta = this.chart.theme.axis,
 				// TODO: we use one font --- of major tick, we need to use major and minor fonts
 				taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
+				taTitleFont = o.titleFont || (ta.tick && ta.tick.titleFont),
+				taTitleGap = (o.titleGap==0) ? 0 : o.titleGap || (ta.tick && ta.tick.titleGap) || 15,
 				taMajorTick = this.chart.theme.getTick("major", o),
 				taMinorTick = this.chart.theme.getTick("minor", o),
 				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
+				tsize = taTitleFont ? g.normalizedLength(g.splitFontString(taTitleFont).size) : 0,
 				rotation = o.rotation % 360, leftBottom = o.leftBottom,
 				cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
 				sinr = Math.abs(Math.sin(rotation * Math.PI / 180));
+			this.trailingSymbol = (o.trailingSymbol === undefined || o.trailingSymbol === null) ? this.trailingSymbol : o.trailingSymbol;
 			if(rotation < 0){
 				rotation += 360;
 			}
 
 			if(size){
 				// we need width of all labels
-				if(o.maxLabelSize){
-					labelWidth = o.maxLabelSize;
-				}else if(this.labels){
-					labelWidth = this._groupLabelWidth(this.labels, taFont);
+				if(this.labels){
+					labelWidth = this._groupLabelWidth(this.labels, taFont, o.maxLabelCharCount);
 				}else{
 					labelWidth = this._groupLabelWidth([
 						gl(ma.start, ma.prec, o),
 						gl(ma.start + ma.count * ma.tick, ma.prec, o),
 						gl(mi.start, mi.prec, o),
 						gl(mi.start + mi.count * mi.tick, mi.prec, o)
-					], taFont);
+					], taFont, o.maxLabelCharCount);
 				}
+				labelWidth = o.maxLabelSize ? Math.min(o.maxLabelSize, labelWidth) : labelWidth;
 				if(this.vertical){
 					var side = leftBottom ? "l" : "r";
 					switch(rotation){
@@ -278,7 +288,7 @@ dojo.require("dojox.lang.utils");
 							}
 							break;
 					}
-					offsets[side] += labelGap + Math.max(taMajorTick.length, taMinorTick.length);
+					offsets[side] += labelGap + Math.max(taMajorTick.length, taMinorTick.length) + (o.title ? (tsize + taTitleGap) : 0);
 				}else{
 					var side = leftBottom ? "b" : "t";
 					switch(rotation){
@@ -310,7 +320,7 @@ dojo.require("dojox.lang.utils");
 							}
 							break;
 					}
-					offsets[side] += labelGap + Math.max(taMajorTick.length, taMinorTick.length);
+					offsets[side] += labelGap + Math.max(taMajorTick.length, taMinorTick.length) + (o.title ? (tsize + taTitleGap) : 0);
 				}
 			}
 			if(labelWidth){
@@ -332,25 +342,34 @@ dojo.require("dojox.lang.utils");
 			}
 			// prepare variable
 			var o = this.opt, ta = this.chart.theme.axis, leftBottom = o.leftBottom, rotation = o.rotation % 360,
-				start, stop, axisVector, tickVector, anchorOffset, labelOffset, labelAlign,
+				start, stop, titlePos, titleRotation=0, titleOffset, axisVector, tickVector, anchorOffset, labelOffset, labelAlign,
 
 				// TODO: we use one font --- of major tick, we need to use major and minor fonts
 				taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
+				taTitleFont = o.titleFont || (ta.tick && ta.tick.titleFont),
 				// TODO: we use one font color --- we need to use different colors
 				taFontColor = o.fontColor || (ta.majorTick && ta.majorTick.fontColor) || (ta.tick && ta.tick.fontColor) || "black",
+				taTitleFontColor = o.titleFontColor || (ta.tick && ta.tick.titleFontColor) || "black",
+				taTitleGap = (o.titleGap==0) ? 0 : o.titleGap || (ta.tick && ta.tick.titleGap) || 15,
+				taTitleOrientation = o.titleOrientation || (ta.tick && ta.tick.titleOrientation) || "axis",
 				taMajorTick = this.chart.theme.getTick("major", o),
 				taMinorTick = this.chart.theme.getTick("minor", o),
 				taMicroTick = this.chart.theme.getTick("micro", o),
 
 				tickSize = Math.max(taMajorTick.length, taMinorTick.length, taMicroTick.length),
 				taStroke = "stroke" in o ? o.stroke : ta.stroke,
-				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0;
+				size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
+				cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
+				sinr = Math.abs(Math.sin(rotation * Math.PI / 180)),
+				tsize = taTitleFont ? g.normalizedLength(g.splitFontString(taTitleFont).size) : 0;
 			if(rotation < 0){
 				rotation += 360;
 			}
 			if(this.vertical){
 				start = {y: dim.height - offsets.b};
 				stop  = {y: offsets.t};
+				titlePos = {y: (dim.height - offsets.b + offsets.t)/2};
+				titleOffset = size * sinr + (this._cachedLabelWidth || 0) * cosr + labelGap + Math.max(taMajorTick.length, taMinorTick.length) + tsize + taTitleGap;
 				axisVector = {x: 0, y: -1};
 				labelOffset = {x: 0, y: 0};
 				tickVector = {x: 1, y: 0};
@@ -396,10 +415,14 @@ dojo.require("dojox.lang.utils");
 				}
 				if(leftBottom){
 					start.x = stop.x = offsets.l;
+					titleRotation = (taTitleOrientation && taTitleOrientation == "away") ? 90 : 270;
+					titlePos.x = offsets.l - titleOffset + (titleRotation == 270 ? tsize : 0);
 					tickVector.x = -1;
 					anchorOffset.x = -anchorOffset.x;
 				}else{
 					start.x = stop.x = dim.width - offsets.r;
+					titleRotation = (taTitleOrientation && taTitleOrientation == "axis") ? 90 : 270;
+					titlePos.x = dim.width - offsets.r + titleOffset - (titleRotation == 270 ? 0 : tsize);
 					switch(labelAlign){
 						case "start":
 							labelAlign = "end";
@@ -415,6 +438,8 @@ dojo.require("dojox.lang.utils");
 			}else{
 				start = {x: offsets.l};
 				stop  = {x: dim.width - offsets.r};
+				titlePos = {x: (dim.width - offsets.r + offsets.l)/2};
+				titleOffset = size * cosr + (this._cachedLabelWidth || 0) * sinr + labelGap + Math.max(taMajorTick.length, taMinorTick.length) + tsize + taTitleGap;
 				axisVector = {x: 1, y: 0};
 				labelOffset = {x: 0, y: 0};
 				tickVector = {x: 0, y: 1};
@@ -458,8 +483,12 @@ dojo.require("dojox.lang.utils");
 				}
 				if(leftBottom){
 					start.y = stop.y = dim.height - offsets.b;
+					titleRotation = (taTitleOrientation && taTitleOrientation == "axis") ? 180 : 0;
+					titlePos.y = dim.height - offsets.b + titleOffset - (titleRotation ? tsize : 0);
 				}else{
 					start.y = stop.y = offsets.t;
+					titleRotation = (taTitleOrientation && taTitleOrientation == "away") ? 180 : 0;
+					titlePos.y = offsets.t - titleOffset + (titleRotation ? 0 : tsize);
 					tickVector.y = -1;
 					anchorOffset.y = -anchorOffset.y;
 					switch(labelAlign){
@@ -486,8 +515,9 @@ dojo.require("dojox.lang.utils");
 					t = this.ticks,
 					canLabel,
 					f = lin.getTransformerFromModel(this.scaler),
-					forceHtmlLabels = (dojox.gfx.renderer == "canvas"),
-					labelType = forceHtmlLabels || !rotation && this.opt.htmlLabels && !dojo.isIE && !dojo.isOpera ? "html" : "gfx",
+					// 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",
 					dx = tickVector.x * taMajorTick.length,
 					dy = tickVector.y * taMajorTick.length;
 
@@ -497,6 +527,27 @@ dojo.require("dojox.lang.utils");
 					x2: stop.x,
 					y2: stop.y
 				}).setStroke(taStroke);
+				
+				//create axis title
+				if(o.title){
+					var axisTitle = dc.axis2d.common.createText[labelType](
+						this.chart,
+						s,
+						titlePos.x,
+						titlePos.y,
+						"middle",
+						o.title,
+						taTitleFont,
+						taTitleFontColor
+					);
+					if(labelType == "html"){
+						this.htmlElements.push(axisTitle);
+					}else{
+						//as soon as rotation is provided, labelType won't be "html"
+						//rotate gfx labels
+						axisTitle.setTransform(g.matrix.rotategAt(titleRotation, titlePos.x, titlePos.y));
+					}
+				}
 
 				dojo.forEach(t.major, function(tick){
 					var offset = f(tick.value), elem,
@@ -508,17 +559,23 @@ dojo.require("dojox.lang.utils");
 							y2: y + dy
 						}).setStroke(taMajorTick);
 						if(tick.label){
+							var label = o.maxLabelCharCount ? this.getTextWithLimitCharCount(tick.label, taFont, o.maxLabelCharCount) : {
+								text: tick.label,
+								truncated: false
+							};
+							label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
 							elem = dc.axis2d.common.createText[labelType](
 								this.chart,
 								s,
 								x + dx + anchorOffset.x + (rotation ? 0 : labelOffset.x),
 								y + dy + anchorOffset.y + (rotation ? 0 : labelOffset.y),
 								labelAlign,
-								tick.label,
+								label.text,
 								taFont,
 								taFontColor
 								//this._cachedLabelWidth
 							);
+							label.truncated && this.labelTooltip(elem, this.chart, tick.label, label.text, taFont, labelType);
 							if(labelType == "html"){
 								this.htmlElements.push(elem);
 							}else if(rotation){
@@ -547,17 +604,23 @@ dojo.require("dojox.lang.utils");
 							y2: y + dy
 						}).setStroke(taMinorTick);
 						if(canLabel && tick.label){
+							var label = o.maxLabelCharCount ? this.getTextWithLimitCharCount(tick.label, taFont, o.maxLabelCharCount) : {
+								text: tick.label,
+								truncated: false
+							};
+							label = o.maxLabelSize ? this.getTextWithLimitLength(label.text, taFont, o.maxLabelSize, label.truncated) : label;
 							elem = dc.axis2d.common.createText[labelType](
 								this.chart,
 								s,
 								x + dx + anchorOffset.x + (rotation ? 0 : labelOffset.x),
 								y + dy + anchorOffset.y + (rotation ? 0 : labelOffset.y),
 								labelAlign,
-								tick.label,
+								label.text,
 								taFont,
 								taFontColor
 								//this._cachedLabelWidth
 							);
+							label.truncated && this.labelTooltip(elem, this.chart, tick.label, label.text, taFont, labelType);
 							if(labelType == "html"){
 								this.htmlElements.push(elem);
 							}else if(rotation){
@@ -591,6 +654,58 @@ dojo.require("dojox.lang.utils");
 
 			this.dirty = false;
 			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 aroundRect = {type: "rect"}, position = ["above", "below"],
+				fontWidth = dojox.gfx._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));
+				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);
+					})
+				});
+				this._events.push({
+					shape:  dojo,
+					handle: dojo.connect(elem.firstChild, "onmouseout", this, function(e){
+						dijit.hideTooltip(aroundRect);
+					})
+				});
+			}else{
+				var shp = elem.getShape(),
+					lt = dojo.coords(chart.node, true);
+				aroundRect = dojo.mixin(aroundRect, {
+					x: shp.x - fontWidth / 2,
+					y: shp.y
+				});
+				aroundRect.x += lt.x;
+				aroundRect.y += lt.y;
+				aroundRect.x = Math.round(aroundRect.x);
+				aroundRect.y = Math.round(aroundRect.y);
+				aroundRect.width = Math.ceil(fontWidth);
+				aroundRect.height = Math.ceil(fontHeight);
+				this._events.push({
+					shape:  elem,
+					handle: elem.connect("onmouseenter", this, function(e){
+						dijit.showTooltip(label, aroundRect, position);
+					})
+				});
+				this._events.push({
+					shape:  elem,
+					handle: elem.connect("onmouseleave", this, function(e){
+						dijit.hideTooltip(aroundRect);
+					})
+				});
+			}
 		}
 	});
 })();
diff --git a/dojox/charting/axis2d/Invisible.js b/dojox/charting/axis2d/Invisible.js
index a54f800..d212cc6 100644
--- a/dojox/charting/axis2d/Invisible.js
+++ b/dojox/charting/axis2d/Invisible.js
@@ -79,7 +79,9 @@ dojo.require("dojox.lang.utils");
 								// with corresponding numeric values
 								// ordered by values
 			labelFunc:		null, // function to compute label values
-			maxLabelSize:	0	// size in px. For use with labelFunc
+			maxLabelSize:	0,	// size in px. For use with labelFunc
+			maxLabelCharCount:	0,	// size in word count.
+			trailingSymbol:			null
 
 			// TODO: add support for minRange!
 			// minRange:		1,	// smallest distance from min allowed on the axis
@@ -92,8 +94,8 @@ dojo.require("dojox.lang.utils");
 			//		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.delegate(this.defaultParams, kwArgs);
-			// du.updateWithObject(this.opt, kwArgs);
+			this.opt = dojo.clone(this.defaultParams);
+            du.updateWithObject(this.opt, kwArgs);
 			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 		},
 		dependOnData: function(){
@@ -141,13 +143,18 @@ dojo.require("dojox.lang.utils");
 			//		Get the current windowing offset for the axis.
 			return "offset" in this ? this.offset : 0;	//	Number
 		},
-		_groupLabelWidth: function(labels, font){
+		_groupLabelWidth: function(labels, font, wcLimit){
 			if(!labels.length){
 				return 0;
 			}
 			if(dojo.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;
+				}, this);
+			}
 			var s = labels.join("<br>");
 			return dojox.gfx._base._getTextBox(s, {font: font}).w || 0;
 		},
@@ -223,10 +230,8 @@ dojo.require("dojox.lang.utils");
 			if(size){
 				if(this.vertical ? rotation != 0 && rotation != 180 : rotation != 90 && rotation != 270){
 					// we need width of all labels
-					if(o.maxLabelSize){
-						labelWidth = o.maxLabelSize;
-					}else if(this.labels){
-						labelWidth = this._groupLabelWidth(this.labels, taFont);
+					if(this.labels){
+						labelWidth = this._groupLabelWidth(this.labels, taFont, o.maxLabelCharCount);
 					}else{
 						var labelLength = Math.ceil(
 								Math.log(
@@ -253,6 +258,7 @@ dojo.require("dojox.lang.utils");
 							{ font: taFont }
 						).w;
 					}
+					labelWidth = o.maxLabelSize ? Math.min(o.maxLabelSize, labelWidth) : labelWidth;
 				}else{
 					labelWidth = size;
 				}
diff --git a/dojox/charting/plot2d/Bubble.js b/dojox/charting/plot2d/Bubble.js
index 568ef5b..5fa613b 100644
--- a/dojox/charting/plot2d/Bubble.js
+++ b/dojox/charting/plot2d/Bubble.js
@@ -35,8 +35,9 @@ dojo.require("dojox.lang.functional");
 			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		Optional keyword arguments object to help define plot parameters.
 			this.opt = dojo.clone(this.defaultParams);
-			du.updateWithObject(this.opt, kwArgs);
-			this.series = [];
+            du.updateWithObject(this.opt, kwArgs);
+            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+            this.series = [];
 			this.hAxis = this.opt.hAxis;
 			this.vAxis = this.opt.vAxis;
 			this.animate = this.opt.animate;
diff --git a/dojox/charting/plot2d/Default.js b/dojox/charting/plot2d/Default.js
index 7ca5bbf..a965161 100644
--- a/dojox/charting/plot2d/Default.js
+++ b/dojox/charting/plot2d/Default.js
@@ -134,7 +134,8 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		An optional arguments object to help define this plot.
 			this.opt = dojo.clone(this.defaultParams);
-			du.updateWithObject(this.opt, kwArgs);
+            du.updateWithObject(this.opt, kwArgs);
+            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
 			this.hAxis = this.opt.hAxis;
 			this.vAxis = this.opt.vAxis;
@@ -299,6 +300,8 @@ dojo.declare("dojox.charting.plot2d.__DefaultCtorArgs", dojox.charting.plot2d.__
 							}
 							frontMarkers[i] = s.createPath(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){
 								var o = {
diff --git a/dojox/charting/plot2d/Pie.js b/dojox/charting/plot2d/Pie.js
index c3209c7..c455986 100644
--- a/dojox/charting/plot2d/Pie.js
+++ b/dojox/charting/plot2d/Pie.js
@@ -9,8 +9,6 @@ dojo.require("dojox.lang.functional");
 dojo.require("dojox.lang.utils");
 dojo.require("dojox.gfx");
 
-dojo.require("dojo.number");
-
 /*=====
 dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__DefaultCtorArgs, {
 	//	summary:
@@ -77,7 +75,7 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			fixed:			true,
 			precision:		1,
 			labelOffset:	20,
-			labelStyle:		"default",	// default/rows/auto
+			labelStyle:		"default",	// default/rows/auto/columns
 			htmlLabels:		true,		// use HTML to draw labels
 			radGrad:        "native",	// or "linear", or "fan"
 			fanSize:		5,			// maximum fan size in degrees
@@ -91,7 +89,8 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			shadow:		{},
 			fill:		{},
 			font:		"",
-			fontColor:	""
+			fontColor:	"",
+			labelWiring: {}
 		},
 
 		constructor: function(chart, kwArgs){
@@ -348,40 +347,86 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			}, this);
 			// draw labels
 			if(this.opt.labels){
-				start = startAngle;
-				dojo.some(slices, function(slice, i){
-					if(slice <= 0){
-						// degenerated slice
-						return false;	// continue
-					}
-					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"](
-								this.chart, s, circle.cx, circle.cy + size / 2, "middle", labels[i],
-								theme.series.font, theme.series.fontColor);
+				if(this.opt.labelStyle == "default"){
+					start = startAngle;
+					dojo.some(slices, function(slice, i){
+						if(slice <= 0){
+							// degenerated slice
+							return false;	// continue
+						}
+						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"](
+									this.chart, s, circle.cx, circle.cy + size / 2, "middle", labels[i],
+									theme.series.font, theme.series.fontColor);
+							if(this.opt.htmlLabels){
+								this.htmlElements.push(elem);
+							}
+							return true;	// stop iteration
+						}
+						// calculate the geometry of the slice
+						var end = start + slice * 2 * Math.PI, v = run[i];
+						if(i + 1 == slices.length){
+							end = startAngle + 2 * Math.PI;
+						}
+						var	labelAngle = (start + end) / 2,
+							x = circle.cx + labelR * Math.cos(labelAngle),
+							y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
+						// draw the label
+						var elem = da.createText[this.opt.htmlLabels && dojox.gfx.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);
 						}
-						return true;	// stop iteration
-					}
-					// calculate the geometry of the slice
-					var end = start + slice * 2 * Math.PI, v = run[i];
-					if(i + 1 == slices.length){
-						end = startAngle + 2 * Math.PI;
-					}
-					var	labelAngle = (start + end) / 2,
-						x = circle.cx + labelR * Math.cos(labelAngle),
-						y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
-					// draw the label
-					var elem = da.createText[this.opt.htmlLabels && dojox.gfx.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);
-					}
-					start = end;
-					return false;	// continue
-				}, this);
+						start = end;
+						return false;	// continue
+					}, this);
+				}else if(this.opt.labelStyle == "columns"){
+					start = startAngle;
+					//calculate label angles
+					var labeledSlices = [];
+					dojo.forEach(slices, function(slice, i){
+						var end = start + slice * 2 * Math.PI;
+						if(i + 1 == slices.length){
+							end = startAngle + 2 * Math.PI;
+						}
+						var labelAngle = (start + end) / 2;
+						labeledSlices.push({
+							angle: labelAngle,
+							left: Math.cos(labelAngle) < 0,
+							theme: themes[i],
+							index: i,
+							omit: end - start < 0.001
+						});
+						start = end;
+					});
+					//calculate label radius to each slice
+					var labelHeight = dojox.gfx._base._getTextBox("a",{font:taFont}).h;
+					this._getProperLabelRadius(labeledSlices, labelHeight, circle.r * 1.1);
+					//draw label and wiring
+					dojo.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,
+								x = circle.cx + slice.labelR * Math.cos(slice.angle),
+								y = circle.cy + slice.labelR * Math.sin(slice.angle),
+								jointX = (slice.left) ? (leftColumn + labelWidth) : (rightColumn - labelWidth),
+								labelX = (slice.left) ? leftColumn : jointX;
+							var wiring = s.createPath().moveTo(circle.cx + circle.r * Math.cos(slice.angle), circle.cy + circle.r * Math.sin(slice.angle))
+							if (Math.abs(slice.labelR * Math.cos(slice.angle)) < circle.r * 2 - labelWidth) {
+								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"](
+								this.chart, s, labelX, y, "left", labels[i], slice.theme.series.font, slice.theme.series.fontColor);
+							if (this.opt.htmlLabels) {
+								this.htmlElements.push(elem);
+							}
+						}
+					},this);
+				}
 			}
 			// post-process events to restore the original indexing
 			var esi = 0;
@@ -390,10 +435,59 @@ dojo.declare("dojox.charting.plot2d.__PieCtorArgs", dojox.charting.plot2d.__Defa
 			});
 			return this;	//	dojox.charting.plot2d.Pie
 		},
-
+		
+		_getProperLabelRadius: function(slices, labelHeight, minRidius){
+			var leftCenterSlice = {},rightCenterSlice = {},leftMinSIN = 1, rightMinSIN = 1;
+			if (slices.length == 1) {
+				slices[0].labelR = minRidius;
+				return;
+			}
+			for(var i = 0;i<slices.length;i++){
+				var tempSIN = Math.abs(Math.sin(slices[i].angle));
+				if(slices[i].left){
+					if(leftMinSIN > tempSIN){
+						leftMinSIN = tempSIN;
+						leftCenterSlice = slices[i];
+					}
+				}else{
+					if(rightMinSIN > tempSIN){
+						rightMinSIN = tempSIN;
+						rightCenterSlice = slices[i];
+					}
+				}
+			}
+			leftCenterSlice.labelR = rightCenterSlice.labelR = minRidius;
+			this._caculateLabelR(leftCenterSlice,slices,labelHeight);
+			this._caculateLabelR(rightCenterSlice,slices,labelHeight);
+		},
+		_caculateLabelR: function(firstSlice,slices,labelHeight){
+			var i = firstSlice.index,length = slices.length,
+				currentLabelR = firstSlice.labelR;
+			while(!(slices[i%length].left ^ slices[(i+1)%length].left)){
+				if (!slices[(i + 1) % length].omit) {
+					var nextLabelR = (Math.sin(slices[i % length].angle) * currentLabelR + ((slices[i % length].left) ? (-labelHeight) : labelHeight)) /
+					Math.sin(slices[(i + 1) % length].angle);
+					currentLabelR = (nextLabelR < firstSlice.labelR) ? firstSlice.labelR : nextLabelR;
+					slices[(i + 1) % length].labelR = currentLabelR;
+				}
+				i++;
+			}
+			i = firstSlice.index,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))) /
+					Math.sin(slices[j].angle);
+					currentLabelR = (nextLabelR < firstSlice.labelR) ? firstSlice.labelR : nextLabelR;
+					slices[j].labelR = currentLabelR;
+				}
+				i--;j--;
+				i = (i < 0)?i+slices.length:i;
+				j = (j < 0)?j+slices.length:j;
+			}
+		},
 		// utilities
 		_getLabel: function(number){
-			return this.opt.fixed ? dojo.number.format(number, {places: this.opt.precision}) : number.toString();
+			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 775fe8a..090d18d 100644
--- a/dojox/charting/plot2d/Scatter.js
+++ b/dojox/charting/plot2d/Scatter.js
@@ -42,7 +42,8 @@ dojo.require("dojox.gfx.gradutils");
 			//	kwArgs: dojox.charting.plot2d.__DefaultCtorArgs?
 			//		An optional keyword arguments object to help define this plot's parameters.
 			this.opt = dojo.clone(this.defaultParams);
-			du.updateWithObject(this.opt, kwArgs);
+            du.updateWithObject(this.opt, kwArgs);
+            du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
 			this.series = [];
 			this.hAxis = this.opt.hAxis;
 			this.vAxis = this.opt.vAxis;
diff --git a/dojox/charting/plot2d/Spider.js b/dojox/charting/plot2d/Spider.js
new file mode 100644
index 0000000..bfcbeab
--- /dev/null
+++ b/dojox/charting/plot2d/Spider.js
@@ -0,0 +1,640 @@
+dojo.provide("dojox.charting.plot2d.Spider");
+
+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], {
+		//	summary:
+		//		The plot that represents a typical Spider chart.
+		defaultParams: {
+			labels:			true,
+			ticks:			false,
+			fixed:			true,
+			precision:		1,
+			labelOffset:	-10,
+			labelStyle:		"default",	// default/rows/auto
+			htmlLabels:		true,		// use HTML to draw labels
+			startAngle:		-90,		// start angle for slices in degrees
+			divisions:		 3,			// radius tick count
+			axisColor:		 "",		// spider axis color
+			axisWidth:		 0,			// spider axis stroke width
+			spiderColor:	 "",		// spider web color
+			spiderWidth:	 0,			// spider web stroke width
+			seriesWidth:	 0,			// plot border with
+			seriesFillAlpha: 0.2,		// plot fill alpha
+			spiderOrigin:	 0.16,
+			markerSize:		 3,			// radius of plot vertex (px)
+			spiderType:		 "polygon", //"circle"
+			animationType:	 dojo.fx.easing.backOut,
+			axisTickFont:		"",
+			axisTickFontColor:	"",
+			axisFont:			"",
+			axisFontColor:		""
+		},
+		optionalParams: {
+			radius:		0,
+			font:		"",
+			fontColor:	""
+		},
+
+		constructor: function(chart, kwArgs){
+			//	summary:
+			//		Create a Spider plot.
+			this.opt = dojo.clone(this.defaultParams);
+			du.updateWithObject(this.opt, kwArgs);
+			du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
+			this.series = [];
+			this.dyn = [];
+			this.datas = {};
+			this.labelKey = [];
+			this.oldSeriePoints = {};
+			this.animations = {};
+		},
+		clear: function(){
+			//	summary:
+			//		Clear out all of the information tied to this plot.
+			//	returns: dojox.charting.plot2d.Spider
+			//		A reference to this plot for functional chaining.
+			this.dirty = true;
+			this.dyn = [];
+			this.series = [];
+			this.datas = {};
+			this.labelKey = [];
+			this.oldSeriePoints = {};
+			this.animations = {};
+			return this;	//	dojox.charting.plot2d.Spider
+		},
+		setAxis: function(axis){
+			//	summary:
+			//		Dummy method, since axes are irrelevant with a Spider chart.
+			//	returns: dojox.charting.plot2d.Spider
+			//		The reference to this plot for functional chaining.
+			return this;	//	dojox.charting.plot2d.Spider
+		},
+		addSeries: function(run){
+			//	summary:
+			//		Add a data series to this plot.
+			//	run: dojox.charting.Series
+			//		The series to be added.
+			//	returns: dojox.charting.plot2d.Base
+			//		A reference to this plot for functional chaining.
+			var matched = false;
+			this.series.push(run);
+			for(var key in run.data){
+				var val = run.data[key],
+					data = this.datas[key];
+				if(data){
+					data.vlist.push(val);
+					data.min = Math.min(data.min, val);
+					data.max = Math.max(data.max, val);
+				}else{
+					this.datas[key] = {min: val, max: val, vlist: [val]};
+				}
+			}
+			if (this.labelKey.length <= 0) {
+				for (var key in run.data) {
+					this.labelKey.push(key);
+				}
+			}
+			return this;	//	dojox.charting.plot2d.Base
+		},
+		getSeriesStats: function(){
+			//	summary:
+			//		Calculate the min/max on all attached series in both directions.
+			//	returns: Object
+			//		{hmin, hmax, vmin, vmax} min/max in both directions.
+			return dojox.charting.plot2d.common.collectSimpleStats(this.series);
+		},
+		calculateAxes: function(dim){
+			//	summary:
+			//		Stub function for running the axis calculations (depricated).
+			//	dim: Object
+			//		An object of the form { width, height }
+			//	returns: dojox.charting.plot2d.Base
+			//		A reference to this plot for functional chaining.
+			this.initializeScalers(dim, this.getSeriesStats());
+			return this;	//	dojox.charting.plot2d.Base
+		},
+		getRequiredColors: function(){
+			//	summary:
+			//		Get how many data series we have, so we know how many colors to use.
+			//	returns: Number
+			//		The number of colors needed.
+			return this.series.length;	//	Number
+		},
+		initializeScalers: function(dim, stats){
+			//	summary:
+			//		Initializes scalers using attached axes.
+			//	dim: Object:
+			//		Size of a plot area in pixels as {width, height}.
+			//	stats: Object:
+			//		Min/max of data in both directions as {hmin, hmax, vmin, vmax}.
+			//	returns: dojox.charting.plot2d.Base
+			//		A reference to this plot for functional chaining.
+			if(this._hAxis){
+				if(!this._hAxis.initialized()){
+					this._hAxis.calculate(stats.hmin, stats.hmax, dim.width);
+				}
+				this._hScaler = this._hAxis.getScaler();
+			}else{
+				this._hScaler = dojox.charting.scaler.primitive.buildScaler(stats.hmin, stats.hmax, dim.width);
+			}
+			if(this._vAxis){
+				if(!this._vAxis.initialized()){
+					this._vAxis.calculate(stats.vmin, stats.vmax, dim.height);
+				}
+				this._vScaler = this._vAxis.getScaler();
+			}else{
+				this._vScaler = dojox.charting.scaler.primitive.buildScaler(stats.vmin, stats.vmax, dim.height);
+			}
+			return this;	//	dojox.charting.plot2d.Base
+		},
+		render: function(dim, offsets){
+			//	summary:
+			//		Render the plot on the chart.
+			//	dim: Object
+			//		An object of the form { width, height }.
+			//	offsets: Object
+			//		An object of the form { l, r, t, b }.
+			//	returns: dojox.charting.plot2d.Spider
+			//		A reference to this plot for functional chaining.
+			if(!this.dirty){ return this; }
+			this.dirty = false;
+			this.cleanGroup();
+			var s = this.group, t = this.chart.theme;
+			this.resetEvents();
+
+			if(!this.series || !this.series.length){
+				return this;
+			}
+
+			// calculate the geometry
+			var o = this.opt, ta = t.axis,
+				rx = (dim.width	 - offsets.l - offsets.r) / 2,
+				ry = (dim.height - offsets.t - offsets.b) / 2,
+				r  = Math.min(rx, ry),
+				axisTickFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font) || "normal normal normal 7pt Tahoma",
+				axisFont = o.axisFont || (ta.tick && ta.tick.titleFont) || "normal normal normal 11pt Tahoma",
+				axisTickFontColor = o.axisTickFontColor || (ta.majorTick && ta.majorTick.fontColor) || (ta.tick && ta.tick.fontColor) || "silver",
+				axisFontColor = o.axisFontColor || (ta.tick && ta.tick.titleFontColor) || "black",
+				axisColor = o.axisColor || (ta.tick && ta.tick.axisColor) || "silver",
+				spiderColor = o.spiderColor || (ta.tick && ta.tick.spiderColor) || "silver",
+				axisWidth = o.axisWidth || (ta.stroke && ta.stroke.width) || 2,
+				spiderWidth = o.spiderWidth || (ta.stroke && ta.stroke.width) || 2,
+				seriesWidth = o.seriesWidth || (ta.stroke && ta.stroke.width) || 2,
+				asize = g.normalizedLength(g.splitFontString(axisFont).size),
+				startAngle = m._degToRad(o.startAngle),
+				start = startAngle, step, filteredRun, slices, labels, shift, labelR,
+				outerPoints, innerPoints, divisionPoints, divisionRadius, labelPoints,
+				ro = o.spiderOrigin, dv = o.divisions >= 3 ? o.divisions : 3, ms = o.markerSize,
+				spt = o.spiderType, at = o.animationType, lboffset = o.labelOffset < -10 ? o.labelOffset : -10,
+				axisExtra = 0.2;
+			
+			if(o.labels){
+				labels = dojo.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, {
+						font: font
+					}).w;
+				}, this), "Math.max(a, b)") / 2;
+				r = Math.min(rx - 2 * shift, ry - asize) + lboffset;
+				labelR = r - lboffset;
+			}
+			if ("radius" in o) {
+				r = o.radius;
+				labelR = r - lboffset;
+			}
+			r /= (1+axisExtra);
+			var circle = {
+				cx: offsets.l + rx,
+				cy: offsets.t + ry,
+				r: r
+			};
+			
+			for (var i = this.series.length - 1; i >= 0; i--) {
+				var serieEntry = this.series[i];
+				if (!this.dirty && !serieEntry.dirty) {
+					t.skip();
+					continue;
+				}
+				serieEntry.cleanGroup();
+				var run = serieEntry.data;
+				if (run !== null) {
+					var len = this._getObjectLength(run);
+					//construct connect points
+					if (!outerPoints || outerPoints.length <= 0) {
+						outerPoints = [], innerPoints = [], labelPoints = [];
+						this._buildPoints(outerPoints, len, circle, r, start, true);
+						this._buildPoints(innerPoints, len, circle, r*ro, start, true);
+						this._buildPoints(labelPoints, len, circle, labelR, start);
+						if(dv > 2){
+							divisionPoints = [], divisionRadius = [];
+							for (var j = 0; j < dv - 2; j++) {
+								divisionPoints[j] = [];
+								this._buildPoints(divisionPoints[j], len, circle, r*(ro + (1-ro)*(j+1)/(dv-1)), start, true);
+								divisionRadius[j] = r*(ro + (1-ro)*(j+1)/(dv-1));
+							}
+						}
+					}
+				}
+			}
+			
+			//draw Spider
+			//axis
+			var axisGroup = s.createGroup(), axisStroke = {color: axisColor, width: axisWidth},
+				spiderStroke = {color: spiderColor, width: spiderWidth};
+			for (var j = outerPoints.length - 1; j >= 0; --j) {
+				var point = outerPoints[j],
+					st = {
+						x: point.x + (point.x - circle.cx) * axisExtra,
+						y: point.y + (point.y - circle.cy) * axisExtra
+					},
+					nd = {
+						x: point.x + (point.x - circle.cx) * axisExtra / 2,
+						y: point.y + (point.y - circle.cy) * axisExtra / 2
+					};
+				axisGroup.createLine({
+					x1: circle.cx,
+					y1: circle.cy,
+					x2: st.x,
+					y2: st.y
+				}).setStroke(axisStroke);
+				//arrow
+				this._drawArrow(axisGroup, st, nd, axisStroke);
+			}
+			
+			// draw the label
+			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,
+							"middle", this.labelKey[j], axisFont, axisFontColor);
+				if (this.opt.htmlLabels) {
+					this.htmlElements.push(elem);
+				}
+			}
+			
+			//spider web: polygon or circle
+			var spiderGroup = s.createGroup();
+			if(spt == "polygon"){
+				spiderGroup.createPolyline(outerPoints).setStroke(spiderStroke);
+				spiderGroup.createPolyline(innerPoints).setStroke(spiderStroke);
+				if (divisionPoints.length > 0) {
+					for (var j = divisionPoints.length - 1; j >= 0; --j) {
+						spiderGroup.createPolyline(divisionPoints[j]).setStroke(spiderStroke);
+					}
+				}
+			}else{//circle
+				var ccount = this._getObjectLength(this.datas);
+				spiderGroup.createCircle({cx: circle.cx, cy: circle.cy, r: r}).setStroke(spiderStroke);
+				spiderGroup.createCircle({cx: circle.cx, cy: circle.cy, r: r*ro}).setStroke(spiderStroke);
+				if (divisionRadius.length > 0) {
+					for (var j = divisionRadius.length - 1; j >= 0; --j) {
+						spiderGroup.createCircle({cx: circle.cx, cy: circle.cy, r: divisionRadius[j]}).setStroke(spiderStroke);
+					}
+				}
+			}
+			//text
+			var textGroup = s.createGroup(), len = this._getObjectLength(this.datas), k = 0;
+			for(var key in this.datas){
+				var data = this.datas[key], min = data.min, max = data.max, distance = max - min,
+					end = start + 2 * Math.PI * k / len;
+				for (var i = 0; i < dv; i++) {
+					var text = min + distance*i/(dv-1), point = this._getCoordinate(circle, r*(ro + (1-ro)*i/(dv-1)), end);
+					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";
+					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,
+								"start", text, axisTickFont, axisTickFontColor));
+					}
+				}
+				k++;
+			}
+			
+			//draw series (animation)
+			this.chart.seriesShapes = {};
+			var animationConnections = [];
+			for (var i = this.series.length - 1; i >= 0; i--) {
+				var serieEntry = this.series[i], run = serieEntry.data;
+				if (run !== null) {
+					//series polygon
+					var seriePoints = [], k = 0, tipData = [];
+					for(var key in run){
+						var data = this.datas[key], min = data.min, max = data.max, distance = max - min,
+							entry = run[key], end = start + 2 * Math.PI * k / len,
+							point = this._getCoordinate(circle, r*(ro + (1-ro)*(entry-min)/distance), end);
+						seriePoints.push(point);
+						tipData.push({sname: serieEntry.name, key: key, data: entry});
+						k++;
+					}
+					seriePoints[seriePoints.length] = seriePoints[0];
+					tipData[tipData.length] = tipData[0];
+					var polygonBoundRect = this._getBoundary(seriePoints),
+						theme = t.next("spider", [o, serieEntry]), ts = serieEntry.group,
+						f = g.normalizeColor(theme.series.fill), sk = {color: theme.series.fill, width: seriesWidth};
+					f.a = o.seriesFillAlpha;
+					serieEntry.dyn = {fill: f, stroke: sk};
+					
+					var osps = this.oldSeriePoints[serieEntry.name];
+					var cs = this._createSeriesEntry(ts, (osps || innerPoints), seriePoints, f, sk, r, ro, ms, at);
+					this.chart.seriesShapes[serieEntry.name] = cs;
+					this.oldSeriePoints[serieEntry.name] = seriePoints;
+					
+					var po = {
+						element: "spider_poly",
+						index:	 i,
+						id:		 "spider_poly_"+serieEntry.name,
+						run:	 serieEntry,
+						plot:	 this,
+						shape:	 cs.poly,
+						parent:	 ts,
+						brect:	 polygonBoundRect,
+						cx:		 circle.cx,
+						cy:		 circle.cy,
+						cr:		 r,
+						f:		 f,
+						s:		 s
+					};
+					this._connectEvents(po);
+					
+					var so = {
+						element: "spider_plot",
+						index:	 i,
+						id:		 "spider_plot_"+serieEntry.name,
+						run:	 serieEntry,
+						plot:	 this,
+						shape:	 serieEntry.group
+					};
+					this._connectEvents(so);
+					
+					dojo.forEach(cs.circles, function(c, i){
+						var shape = c.getShape(),
+							co = {
+								element: "spider_circle",
+								index:	 i,
+								id:		 "spider_circle_"+serieEntry.name+i,
+								run:	 serieEntry,
+								plot:	 this,
+								shape:	 c,
+								parent:	 ts,
+								tdata:	 tipData[i],
+								cx:		 seriePoints[i].x,
+								cy:		 seriePoints[i].y,
+								f:		 f,
+								s:		 s
+							};
+						this._connectEvents(co);
+					}, this);
+				}
+			}
+			return this;	//	dojox.charting.plot2d.Spider
+		},
+		_createSeriesEntry: function(ts, osps, sps, f, sk, r, ro, ms, at){
+			//polygon
+			var spoly = ts.createPolyline(osps).setFill(f).setStroke(sk), scircle = [];
+			for (var j = 0; j < osps.length; j++) {
+				var point = osps[j], cr = ms;
+				var circle = ts.createCircle({cx: point.x, cy: point.y, r: cr}).setFill(f).setStroke(sk);
+				scircle.push(circle);
+			}
+			
+			var anims = dojo.map(sps, function(np, j){
+				// create animation
+				var sp = osps[j],
+					anim = new dojo._Animation({
+					duration: 1000,
+					easing:	  at,
+					curve:	  [sp.y, np.y]
+				});
+				var spl = spoly, sc = scircle[j];
+				dojo.connect(anim, "onAnimate", function(y){
+					//apply poly
+					var pshape = spl.getShape();
+					pshape.points[j].y = y;
+					spl.setShape(pshape);
+					//apply circle
+					var cshape = sc.getShape();
+					cshape.cy = y;
+					sc.setShape(cshape);
+				});
+				return anim;
+			});
+			
+			var anims1 = dojo.map(sps, function(np, j){
+				// create animation
+				var sp = osps[j],
+					anim = new dojo._Animation({
+					duration: 1000,
+					easing:	  at,
+					curve:	  [sp.x, np.x]
+				});
+				var spl = spoly, sc = scircle[j];
+				dojo.connect(anim, "onAnimate", function(x){
+					//apply poly
+					var pshape = spl.getShape();
+					pshape.points[j].x = x;
+					spl.setShape(pshape);
+					//apply circle
+					var cshape = sc.getShape();
+					cshape.cx = x;
+					sc.setShape(cshape);
+				});
+				return anim;
+			});
+			var masterAnimation = dojo.fx.combine(anims.concat(anims1)); //dojo.fx.chain(anims);
+			masterAnimation.play();
+			return {group :ts, poly: spoly, circles: scircle};
+		},
+		plotEvent: function(o){
+			//	summary:
+			//		Stub function for use by specific plots.
+			//	o: Object
+			//		An object intended to represent event parameters.
+			var runName = o.id ? o.id : "default", a;
+			if (runName in this.animations) {
+				a = this.animations[runName];
+				a.anim && a.anim.stop(true);
+			} else {
+				a = this.animations[runName] = {};
+			}
+			if(o.element == "spider_poly"){
+				if(!a.color){
+					var color = o.shape.getFill();
+					if(!color || !(color instanceof dojo.Color)){
+						return;
+					}
+					a.color = {
+						start: color,
+						end:   transColor(color)
+					};
+				}
+				var start = a.color.start, end = a.color.end;
+				if(o.type == "onmouseout"){
+					// swap colors
+					var t = start; start = end; end = t;
+				}
+				a.anim = dojox.gfx.fx.animateFill({
+					shape:	  o.shape,
+					duration: 800,
+					easing:	  dojo.fx.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;
+					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);
+					aroundRect.x += lt.x;
+					aroundRect.y += lt.y;
+					aroundRect.x = Math.round(aroundRect.x);
+					aroundRect.y = Math.round(aroundRect.y);
+					aroundRect.width = Math.ceil(aroundRect.width);
+					aroundRect.height = Math.ceil(aroundRect.height);
+					this.aroundRect = aroundRect;
+					var position = ["after", "before"];
+					if(dijit && dijit.Tooltip){
+						dijit.showTooltip(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);
+					scale = 1/defaultScale;
+					if(dijit && dijit.Tooltip){
+						this.aroundRect && dijit.hideTooltip(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,
+						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.play();
+			}else if(o.element == "spider_plot"){
+				//dojo gfx function "moveToFront" not work in IE
+				if (o.type == "onmouseover" && !dojo.isIE) {
+					o.shape.moveToFront();
+				}
+			}
+		},
+		_getBoundary: function(points){
+			var xmax = points[0].x,
+				xmin = points[0].x,
+				ymax = points[0].y,
+				ymin = points[0].y;
+			for(var i = 0; i < points.length; i++){
+				var point = points[i];
+				xmax = Math.max(point.x, xmax);
+				ymax = Math.max(point.y, ymax);
+				xmin = Math.min(point.x, xmin);
+				ymin = Math.min(point.y, ymin);
+			}
+			return {
+				x: xmin,
+				y: ymin,
+				width: xmax - xmin,
+				height: ymax - ymin
+			};
+		},
+		
+		_drawArrow: function(s, start, end, stroke){
+			var len = Math.sqrt(Math.pow(end.x - start.x, 2) + Math.pow(end.y - start.y, 2)),
+				sin = (end.y - start.y)/len, cos = (end.x - start.x)/len,
+				point2 = {x: end.x + (len/3)*(-sin), y: end.y + (len/3)*cos},
+				point3 = {x: end.x + (len/3)*sin, y: end.y + (len/3)*(-cos)};
+			s.createPolyline([start, point2, point3]).setFill(stroke.color).setStroke(stroke);
+		},
+		
+		_buildPoints: function(points, count, circle, radius, angle, recursive){
+			for (var i = 0; i < count; i++) {
+				var end = angle + 2 * Math.PI * i / count;
+				points.push(this._getCoordinate(circle, radius, end));
+			}
+			if(recursive){
+				points.push(this._getCoordinate(circle, radius, angle + 2 * Math.PI));
+			}
+		},
+		
+		_getCoordinate: function(circle, radius, angle){
+			return {
+				x: circle.cx + radius * Math.cos(angle),
+				y: circle.cy + radius * Math.sin(angle)
+			}
+		},
+		
+		_getObjectLength: function(obj){
+			var count = 0;
+			if(dojo.isObject(obj)){
+				for(var key in obj){
+					count++;
+				}
+			}
+			return count;
+		},
+
+		// utilities
+		_getLabel: function(number){
+			return dc.getLabel(number, this.opt.fixed, this.opt.precision);
+		}
+	});
+	
+	function transColor(color){
+		var a = new dojox.color.Color(color),
+			x = a.toHsl();
+		if(x.s == 0){
+			x.l = x.l < 50 ? 100 : 0;
+		}else{
+			x.s = 100;
+			if(x.l < 50){
+				x.l = 75;
+			}else if(x.l > 75){
+				x.l = 50;
+			}else{
+				x.l = x.l - 50 > 75 - x.l ?
+					50 : 75;
+			}
+		}
+		var color = dojox.color.fromHsl(x);
+		color.a = 0.7;
+		return color;
+	}
+	
+})();
diff --git a/dojox/charting/plot2d/StackedBars.js b/dojox/charting/plot2d/StackedBars.js
index b57b073..e3b5b63 100644
--- a/dojox/charting/plot2d/StackedBars.js
+++ b/dojox/charting/plot2d/StackedBars.js
@@ -5,6 +5,7 @@ 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,
diff --git a/dojox/charting/plot2d/StackedColumns.js b/dojox/charting/plot2d/StackedColumns.js
index 3bd4a71..0de2b8d 100644
--- a/dojox/charting/plot2d/StackedColumns.js
+++ b/dojox/charting/plot2d/StackedColumns.js
@@ -5,6 +5,7 @@ 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,
diff --git a/dojox/charting/plot2d/_PlotEvents.js b/dojox/charting/plot2d/_PlotEvents.js
index 0bd29a9..e1cfc67 100644
--- a/dojox/charting/plot2d/_PlotEvents.js
+++ b/dojox/charting/plot2d/_PlotEvents.js
@@ -83,14 +83,16 @@ dojo.declare("dojox.charting.plot2d._PlotEvents", null, {
 		});
 	},
 	_connectEvents: function(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");
+        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];
diff --git a/dojox/charting/plot2d/common.js b/dojox/charting/plot2d/common.js
index e464b0b..d03ba93 100644
--- a/dojox/charting/plot2d/common.js
+++ b/dojox/charting/plot2d/common.js
@@ -37,8 +37,8 @@ dojo.require("dojox.lang.functional");
 		},
 
 		defaultStats: {
-			hmin: Number.POSITIVE_INFINITY, hmax: Number.NEGATIVE_INFINITY,
-			vmin: Number.POSITIVE_INFINITY, vmax: Number.NEGATIVE_INFINITY
+			vmin: Number.POSITIVE_INFINITY, vmax: Number.NEGATIVE_INFINITY,
+			hmin: Number.POSITIVE_INFINITY, hmax: Number.NEGATIVE_INFINITY
 		},
 
 		collectSimpleStats: function(series){
@@ -120,10 +120,12 @@ dojo.require("dojox.lang.functional");
 				// 2nd pass: stack values
 				for(var i = 0; i < stats.hmax; ++i){
 					var v = series[0].data[i];
+                    v = v && (typeof v == "number" ? v : v.y);
 					if(isNaN(v)){ v = 0; }
 					stats.vmin = Math.min(stats.vmin, v);
 					for(var j = 1; j < series.length; ++j){
 						var t = series[j].data[i];
+                        t = t && (typeof t == "number" ? t : t.y);
 						if(isNaN(t)){ t = 0; }
 						v += t;
 					}
@@ -202,6 +204,14 @@ dojo.require("dojox.lang.functional");
 				return "C"+(bz1x+","+bz1y+" "+bz2x+","+bz2y+" "+p2.x+","+p2.y);
 			});
 			return p.join(" ");
+		},
+		
+		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();
 		}
 	});
 })();
diff --git a/dojox/charting/plot3d/Bars.js b/dojox/charting/plot3d/Bars.js
index efec9ea..88efc0c 100644
--- a/dojox/charting/plot3d/Bars.js
+++ b/dojox/charting/plot3d/Bars.js
@@ -6,7 +6,7 @@ dojo.require("dojox.charting.plot3d.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 
+		// 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;
 		var z = a[0];
@@ -52,7 +52,7 @@ dojo.require("dojox.charting.plot3d.Base");
 			for(var i = 0; i < this.data.length; ++i, org += step){
 				creator
 					.createCube({
-						bottom: {x: org + this.gap, y: 0, z: 0}, 
+						bottom: {x: org + this.gap, y: 0, z: 0},
 						top:    {x: org + step - this.gap, y: this.data[i] * scale, z: depth}
 					})
 					.setFill(this.material);
diff --git a/dojox/charting/plot3d/Cylinders.js b/dojox/charting/plot3d/Cylinders.js
index 4464abe..117250c 100644
--- a/dojox/charting/plot3d/Cylinders.js
+++ b/dojox/charting/plot3d/Cylinders.js
@@ -6,7 +6,7 @@ dojo.require("dojox.charting.plot3d.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 
+		// 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;
 		var z = a[0];
@@ -53,8 +53,8 @@ dojo.require("dojox.charting.plot3d.Base");
 			for(var i = 0; i < this.data.length; ++i, org += step){
 				creator
 					.createCylinder({
-						center: {x: org + step / 2, y: 0, z: 0}, 
-						radius: step / 2 - this.gap, 
+						center: {x: org + step / 2, y: 0, z: 0},
+						radius: step / 2 - this.gap,
 						height: this.data[i] * scale
 					})
 					.setTransform(dojox.gfx3d.matrix.rotateXg(-90))
diff --git a/dojox/charting/resources/Legend.css b/dojox/charting/resources/Legend.css
new file mode 100644
index 0000000..3eae82d
--- /dev/null
+++ b/dojox/charting/resources/Legend.css
@@ -0,0 +1,24 @@
+.dojoxLegendNode {
+	background-color:#F7F7F7;
+	border:1px solid #CCCCCC;
+	margin:0;
+	padding:0;	
+}
+.dojoxLegendNode td{
+	padding: 6px 4px 6px 6px;
+}
+.dojoxLegendIcon {
+	padding: 0px;
+	margin: 0 2px 0 4px;
+}
+.dojoxLegendIcon div{
+	float: left;
+}
+.dj_ie .dojoxLegendNode td{
+	padding: 5px;	
+}
+.dj_ie .dojoxLegendIcon {
+	padding: 0px;
+	margin: 0 2px 0 5px;
+	vertical-align: middle;
+}
diff --git a/dojox/charting/scaler/common.js b/dojox/charting/scaler/common.js
index 45c46ad..72b109f 100644
--- a/dojox/charting/scaler/common.js
+++ b/dojox/charting/scaler/common.js
@@ -15,9 +15,13 @@ dojo.provide("dojox.charting.scaler.common");
 			return false;
 		},
 		getNumericLabel: function(/*Number*/ number, /*Number*/ precision, /*Object*/ kwArgs){
-			var def = kwArgs.fixed ? 
-						number.toFixed(precision < 0 ? -precision : 0) : 
-						number.toString();
+			var def = "";
+			if(dojo.number){
+				def = (kwArgs.fixed ? dojo.number.format(number, {places : precision < 0 ? -precision : 0}) :
+					dojo.number.format(number)) || "";
+			}else{
+				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; }
diff --git a/dojox/charting/scaler/linear.js b/dojox/charting/scaler/linear.js
index be0408a..4a86dd4 100644
--- a/dojox/charting/scaler/linear.js
+++ b/dojox/charting/scaler/linear.js
@@ -56,7 +56,7 @@ dojo.require("dojox.charting.scaler.common");
 			microPerMinor  = microTick ? Math.round(minorTick / microTick) : 0,
 			majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,
 			minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,
-			scale = span / (max - min);	
+			scale = span / (max - min);
 		if(!isFinite(scale)){ scale = 1; }
 		
 		return {
@@ -128,7 +128,7 @@ dojo.require("dojox.charting.scaler.common");
 			}
 			
 			var mag = Math.floor(Math.log(max - min) / Math.LN10),
-				major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag), 
+				major = kwArgs && ("majorTickStep" in kwArgs) ? kwArgs.majorTickStep : Math.pow(10, mag),
 				minor = 0, micro = 0, ticks;
 				
 			// calculate minor ticks
@@ -184,8 +184,8 @@ dojo.require("dojox.charting.scaler.common");
 		},
 		buildTicks: function(/*Object*/ scaler, /*Object*/ kwArgs){
 			var step, next, tick,
-				nextMajor = scaler.major.start, 
-				nextMinor = scaler.minor.start, 
+				nextMajor = scaler.major.start,
+				nextMinor = scaler.minor.start,
 				nextMicro = scaler.micro.start;
 			if(kwArgs.microTicks && scaler.micro.tick){
 				step = scaler.micro.tick, next = nextMicro;
diff --git a/dojox/charting/tests/gradients/test_grad_bars1.html b/dojox/charting/tests/gradients/test_grad_bars1.html
index a6cd0a2..91b3c07 100644
--- a/dojox/charting/tests/gradients/test_grad_bars1.html
+++ b/dojox/charting/tests/gradients/test_grad_bars1.html
@@ -5,8 +5,12 @@
     <title>Gradient: Bars #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
-        
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bars");
+        dojo.require("dojox.charting.plot2d.ClusteredBars");
+        dojo.require("dojox.charting.plot2d.StackedBars");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
@@ -39,7 +43,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -48,7 +52,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -58,7 +62,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
diff --git a/dojox/charting/tests/gradients/test_grad_bars2.html b/dojox/charting/tests/gradients/test_grad_bars2.html
index 307e7e6..e6ea3db 100644
--- a/dojox/charting/tests/gradients/test_grad_bars2.html
+++ b/dojox/charting/tests/gradients/test_grad_bars2.html
@@ -5,7 +5,11 @@
     <title>Gradient: Bars #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bars");
+        dojo.require("dojox.charting.plot2d.ClusteredBars");
+        dojo.require("dojox.charting.plot2d.StackedBars");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +37,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.2}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -42,7 +46,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -52,7 +56,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
diff --git a/dojox/charting/tests/gradients/test_grad_bars3.html b/dojox/charting/tests/gradients/test_grad_bars3.html
index 120f7a2..7062f80 100644
--- a/dojox/charting/tests/gradients/test_grad_bars3.html
+++ b/dojox/charting/tests/gradients/test_grad_bars3.html
@@ -5,7 +5,11 @@
     <title>Gradient: Bars #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bars");
+        dojo.require("dojox.charting.plot2d.ClusteredBars");
+        dojo.require("dojox.charting.plot2d.StackedBars");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +37,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.2}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -42,7 +46,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -52,7 +56,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
diff --git a/dojox/charting/tests/gradients/test_grad_bars4.html b/dojox/charting/tests/gradients/test_grad_bars4.html
index 51fcf7a..97e3847 100644
--- a/dojox/charting/tests/gradients/test_grad_bars4.html
+++ b/dojox/charting/tests/gradients/test_grad_bars4.html
@@ -5,7 +5,11 @@
     <title>Gradient: Bars #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bars");
+        dojo.require("dojox.charting.plot2d.ClusteredBars");
+        dojo.require("dojox.charting.plot2d.StackedBars");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +37,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.2}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -42,7 +46,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -52,7 +56,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
diff --git a/dojox/charting/tests/gradients/test_grad_bars5.html b/dojox/charting/tests/gradients/test_grad_bars5.html
index acf98a0..a026ffc 100644
--- a/dojox/charting/tests/gradients/test_grad_bars5.html
+++ b/dojox/charting/tests/gradients/test_grad_bars5.html
@@ -5,7 +5,11 @@
     <title>Gradient: Bars #5</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bars");
+        dojo.require("dojox.charting.plot2d.ClusteredBars");
+        dojo.require("dojox.charting.plot2d.StackedBars");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -36,7 +40,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.2}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -45,7 +49,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -55,7 +59,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
diff --git a/dojox/charting/tests/gradients/test_grad_bubble1.html b/dojox/charting/tests/gradients/test_grad_bubble1.html
index 764779e..2c1af8f 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble1.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble1.html
@@ -5,7 +5,9 @@
     <title>Gradient: Bubble #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bubble");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -39,7 +41,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {minorLabels: false}).
                 addAxis("y", {vertical: true, minorLabels: false, max: 10}).
diff --git a/dojox/charting/tests/gradients/test_grad_bubble2.html b/dojox/charting/tests/gradients/test_grad_bubble2.html
index f2b2ba7..9c255f3 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble2.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble2.html
@@ -5,7 +5,9 @@
     <title>Gradient: Bubble #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bubble");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +35,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {minorLabels: false}).
                 addAxis("y", {vertical: true, minorLabels: false, max: 10}).
diff --git a/dojox/charting/tests/gradients/test_grad_bubble3.html b/dojox/charting/tests/gradients/test_grad_bubble3.html
index 814548a..0270586 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble3.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble3.html
@@ -5,7 +5,9 @@
     <title>Gradient: Bubble #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bubble");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -34,7 +36,7 @@
 					noRadialConv: true
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {minorLabels: false}).
                 addAxis("y", {vertical: true, minorLabels: false, max: 10}).
diff --git a/dojox/charting/tests/gradients/test_grad_bubble4.html b/dojox/charting/tests/gradients/test_grad_bubble4.html
index 1b5f057..b7c53d2 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble4.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble4.html
@@ -5,7 +5,9 @@
     <title>Gradient: Bubble #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bubble");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +35,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {minorLabels: false}).
                 addAxis("y", {vertical: true, minorLabels: false, max: 10}).
diff --git a/dojox/charting/tests/gradients/test_grad_bubble6.html b/dojox/charting/tests/gradients/test_grad_bubble6.html
index b49ec91..a7e1c92 100644
--- a/dojox/charting/tests/gradients/test_grad_bubble6.html
+++ b/dojox/charting/tests/gradients/test_grad_bubble6.html
@@ -5,7 +5,9 @@
     <title>Gradient: Bubble #6</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Bubble");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -39,7 +41,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {minorLabels: false}).
                 addAxis("y", {vertical: true, minorLabels: false, max: 10}).
diff --git a/dojox/charting/tests/gradients/test_grad_columns1.html b/dojox/charting/tests/gradients/test_grad_columns1.html
index 8f3506a..a14fb0d 100644
--- a/dojox/charting/tests/gradients/test_grad_columns1.html
+++ b/dojox/charting/tests/gradients/test_grad_columns1.html
@@ -5,8 +5,12 @@
     <title>Gradient: Columns #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
-        
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Columns");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedColumns");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
@@ -39,7 +43,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -48,7 +52,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -58,7 +62,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
diff --git a/dojox/charting/tests/gradients/test_grad_columns2.html b/dojox/charting/tests/gradients/test_grad_columns2.html
index 065b29b..f1e9a9b 100644
--- a/dojox/charting/tests/gradients/test_grad_columns2.html
+++ b/dojox/charting/tests/gradients/test_grad_columns2.html
@@ -5,7 +5,11 @@
     <title>Gradient: Columns #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Columns");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedColumns");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +37,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -42,7 +46,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -52,7 +56,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
diff --git a/dojox/charting/tests/gradients/test_grad_columns3.html b/dojox/charting/tests/gradients/test_grad_columns3.html
index 1dbd4f5..b8dfcd8 100644
--- a/dojox/charting/tests/gradients/test_grad_columns3.html
+++ b/dojox/charting/tests/gradients/test_grad_columns3.html
@@ -5,7 +5,11 @@
     <title>Gradient: Columns #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Columns");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedColumns");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +37,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -42,7 +46,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -52,7 +56,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
diff --git a/dojox/charting/tests/gradients/test_grad_columns4.html b/dojox/charting/tests/gradients/test_grad_columns4.html
index 366a19c..96103ee 100644
--- a/dojox/charting/tests/gradients/test_grad_columns4.html
+++ b/dojox/charting/tests/gradients/test_grad_columns4.html
@@ -5,7 +5,11 @@
     <title>Gradient: Columns #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Columns");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedColumns");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +37,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -42,7 +46,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -52,7 +56,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
diff --git a/dojox/charting/tests/gradients/test_grad_columns5.html b/dojox/charting/tests/gradients/test_grad_columns5.html
index b1bdc1b..3ac0366 100644
--- a/dojox/charting/tests/gradients/test_grad_columns5.html
+++ b/dojox/charting/tests/gradients/test_grad_columns5.html
@@ -5,7 +5,11 @@
     <title>Gradient: Columns #5</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Columns");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedColumns");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -36,7 +40,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -45,7 +49,7 @@
                 addSeries("Series B", [5, 4, 3, 2, 1]).
                 render();
 
-            var chart2 = new dojox.charting.Chart2D("c2").
+            var chart2 = new dojox.charting.Chart("c2").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
@@ -55,7 +59,7 @@
                 addSeries("Series C", [2, 1, 2, 1, 3]).
                 render();
 
-            var chart3 = new dojox.charting.Chart2D("c3").
+            var chart3 = new dojox.charting.Chart("c3").
                 setTheme(theme1).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true,  minorTickStep: 0.5}).
diff --git a/dojox/charting/tests/gradients/test_grad_pie1.html b/dojox/charting/tests/gradients/test_grad_pie1.html
index 838da9a..04b4c3c 100644
--- a/dojox/charting/tests/gradients/test_grad_pie1.html
+++ b/dojox/charting/tests/gradients/test_grad_pie1.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -39,7 +40,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pie2.html b/dojox/charting/tests/gradients/test_grad_pie2.html
index 85e9c04..ad9aad7 100644
--- a/dojox/charting/tests/gradients/test_grad_pie2.html
+++ b/dojox/charting/tests/gradients/test_grad_pie2.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +34,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pie3.html b/dojox/charting/tests/gradients/test_grad_pie3.html
index a66840a..d76f7aa 100644
--- a/dojox/charting/tests/gradients/test_grad_pie3.html
+++ b/dojox/charting/tests/gradients/test_grad_pie3.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #3</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -34,7 +35,7 @@
 					noRadialConv: true
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pie4.html b/dojox/charting/tests/gradients/test_grad_pie4.html
index 7e7665a..ad892e6 100644
--- a/dojox/charting/tests/gradients/test_grad_pie4.html
+++ b/dojox/charting/tests/gradients/test_grad_pie4.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #4</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +34,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pie7.html b/dojox/charting/tests/gradients/test_grad_pie7.html
index 96eb579..2c62b35 100644
--- a/dojox/charting/tests/gradients/test_grad_pie7.html
+++ b/dojox/charting/tests/gradients/test_grad_pie7.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #7</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +34,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180, radGrad: "linear"}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pie8.html b/dojox/charting/tests/gradients/test_grad_pie8.html
index e900ff8..4a79d1e 100644
--- a/dojox/charting/tests/gradients/test_grad_pie8.html
+++ b/dojox/charting/tests/gradients/test_grad_pie8.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #8</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +34,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180, radGrad: "linear"}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pie9.html b/dojox/charting/tests/gradients/test_grad_pie9.html
index 1a622b3..86f035a 100644
--- a/dojox/charting/tests/gradients/test_grad_pie9.html
+++ b/dojox/charting/tests/gradients/test_grad_pie9.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #9</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +34,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180, radGrad: "fan"}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_pieA.html b/dojox/charting/tests/gradients/test_grad_pieA.html
index 5115998..a365569 100644
--- a/dojox/charting/tests/gradients/test_grad_pieA.html
+++ b/dojox/charting/tests/gradients/test_grad_pieA.html
@@ -5,7 +5,8 @@
     <title>Gradient: Pie #A</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.plot2d.Pie");
 
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -33,7 +34,7 @@
                     ]
                 });
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addPlot("default", {type: "Pie", radius: 180, radGrad: "fan", fanSize: 3}).
                 addSeries("Series A", [2, 3, 4]).
diff --git a/dojox/charting/tests/gradients/test_grad_scatter1.html b/dojox/charting/tests/gradients/test_grad_scatter1.html
index 6a5c2a1..f4b018a 100644
--- a/dojox/charting/tests/gradients/test_grad_scatter1.html
+++ b/dojox/charting/tests/gradients/test_grad_scatter1.html
@@ -5,8 +5,10 @@
     <title>Gradient: Scatter #1</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
-        
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Scatter");
+
         run = function(){
             dojo.attr("start", "disabled", true);
             
@@ -48,7 +50,7 @@
 				}
 			}
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {includeZero: true,  minorLabels: false}).
                 addAxis("y", {vertical: true, includeZero: true,  minorLabels: false}).
diff --git a/dojox/charting/tests/gradients/test_grad_scatter2.html b/dojox/charting/tests/gradients/test_grad_scatter2.html
index 1d2fcb0..bd0d76c 100644
--- a/dojox/charting/tests/gradients/test_grad_scatter2.html
+++ b/dojox/charting/tests/gradients/test_grad_scatter2.html
@@ -5,7 +5,9 @@
     <title>Gradient: Scatter #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Scatter");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -42,7 +44,7 @@
 				}
 			}
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {includeZero: true,  minorLabels: false}).
                 addAxis("y", {vertical: true, includeZero: true,  minorLabels: false}).
diff --git a/dojox/charting/tests/gradients/test_grad_scatterB.html b/dojox/charting/tests/gradients/test_grad_scatterB.html
index ac4206b..dcef594 100644
--- a/dojox/charting/tests/gradients/test_grad_scatterB.html
+++ b/dojox/charting/tests/gradients/test_grad_scatterB.html
@@ -5,7 +5,9 @@
     <title>Gradient: Scatter #2</title>
 	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-		dojo.require("dojox.charting.Chart2D");
+		dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Scatter");
         
         run = function(){
             dojo.attr("start", "disabled", true);
@@ -31,7 +33,7 @@
 				}
 			}
 
-            var chart1 = new dojox.charting.Chart2D("c1").
+            var chart1 = new dojox.charting.Chart("c1").
                 setTheme(theme1).
                 addAxis("x", {includeZero: true,  minorLabels: false}).
                 addAxis("y", {vertical: true, includeZero: true,  minorLabels: false}).
diff --git a/dojox/charting/tests/test_DataSeries.html b/dojox/charting/tests/test_DataSeries.html
index 7ad9c44..f0a927a 100644
--- a/dojox/charting/tests/test_DataSeries.html
+++ b/dojox/charting/tests/test_DataSeries.html
@@ -67,10 +67,12 @@
 
 <script>
     
-    dojo.require("dojox.charting.Chart2D");
+    dojo.require("dojox.charting.Chart");
     dojo.require("dojox.charting.DataSeries");
     dojo.require("dojox.charting.themes.ThreeD");
     dojo.require("dojox.charting.widget.Legend");
+
+    dojo.require("dojox.charting.axis2d.Default");
     
     dojo.require("dojox.charting.plot2d.Markers");
     dojo.require("dojox.charting.plot2d.Columns");
@@ -113,7 +115,7 @@
     var chartL, chartC, chartP;
     
     makeCharts = function(){
-        chartL = new dojox.charting.Chart2D("lines").
+        chartL = new dojox.charting.Chart("lines").
                 setTheme(dojox.charting.themes.ThreeD).
                 addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 5}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
@@ -125,7 +127,7 @@
         new dojox.charting.action2d.Magnify(chartL);
         new dojox.charting.action2d.Tooltip(chartL);
 
-        chartC = new dojox.charting.Chart2D("cols").
+        chartC = new dojox.charting.Chart("cols").
                 setTheme(dojox.charting.themes.ThreeD).
                 addAxis("x", {natural: true}).
                 addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
@@ -141,7 +143,7 @@
         new dojox.charting.action2d.Shake(chartC, "default", {shiftY: 0});
         new dojox.charting.action2d.Tooltip(chartC);
         
-        chartP = new dojox.charting.Chart2D("pie").
+        chartP = new dojox.charting.Chart("pie").
                 setTheme(dojox.charting.themes.ThreeD).
                 addPlot("default", {type: dojox.charting.plot2d.Pie, radius: 125}).
                 addSeries("Price", new dojox.charting.DataSeries(
diff --git a/dojox/charting/tests/test_StoreSeries.html b/dojox/charting/tests/test_StoreSeries.html
new file mode 100644
index 0000000..c875411
--- /dev/null
+++ b/dojox/charting/tests/test_StoreSeries.html
@@ -0,0 +1,225 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7">
+<title>StoreSeries 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("dojox.charting.Chart");
+    dojo.require("dojox.charting.StoreSeries");
+    dojo.require("dojox.charting.themes.ThreeD");
+    dojo.require("dojox.charting.widget.Legend");
+
+    dojo.require("dojox.charting.axis2d.Default");
+
+    dojo.require("dojox.charting.plot2d.Markers");
+    dojo.require("dojox.charting.plot2d.Columns");
+    dojo.require("dojox.charting.plot2d.Pie");
+    
+    dojo.require("dojox.charting.action2d.Tooltip");
+    dojo.require("dojox.charting.action2d.MoveSlice");
+    dojo.require("dojox.charting.action2d.Magnify");
+    dojo.require("dojox.charting.action2d.Shake");
+
+    dojo.require("dojo.store.Memory");
+    dojo.require("dojo.store.Observable");
+
+    dojo.require("dijit.form.NumberSpinner");
+    
+    dojo.xhrGet({
+    	url: "stock.json",
+    	sync: true,
+    	handleAs: "json"
+    }).then(function(data){
+    	store = dojo.store.Observable(new dojo.store.Memory({data:data}));
+    });
+    
+    function addLegend(chart, node){
+        var legend = new dojox.charting.widget.Legend({chart: chart}, node);
+        dojo.connect(chart, "render", legend, "refresh");
+    }
+    
+    var templates = {
+        low:   "<strong>{0}</strong>: <strong>low {1}</strong> – {2} – {3}",
+        price: "<strong>{0}</strong>: {1} – <strong>price {2}</strong> – {3}",
+        high:  "<strong>{0}</strong>: {1} – {2} – <strong>high {3}</strong>"
+    };
+    
+    function valTrans(value, object){
+        return {
+            y: object[value],
+            tooltip: dojo.replace(
+                templates[value],
+                dojo.map(["symbol", "low", "price", "high"], function(field){
+                    return object[field];
+                })
+            )
+        };
+    }
+    
+    var chartL, chartC, chartP;
+    
+    makeCharts = function(){
+        chartL = new dojox.charting.Chart("lines").
+                setTheme(dojox.charting.themes.ThreeD).
+                addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 5}).
+                addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+                addPlot("default", {type: dojox.charting.plot2d.Markers}).
+                addSeries("Price", new dojox.charting.StoreSeries(
+                    store, {query: {}}, "price")).
+                render();
+        addLegend(chartL, "lines_legend");
+        new dojox.charting.action2d.Magnify(chartL);
+        new dojox.charting.action2d.Tooltip(chartL);
+
+        chartC = new dojox.charting.Chart("cols").
+                setTheme(dojox.charting.themes.ThreeD).
+                addAxis("x", {natural: true}).
+                addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", includeZero: true}).
+                addPlot("default", {type: dojox.charting.plot2d.Columns}).
+                addSeries("Low", new dojox.charting.StoreSeries(
+                    store, {query: {}}, dojo.hitch(null, valTrans, "low"))).
+                addSeries("Price", new dojox.charting.StoreSeries(
+                    store, {query: {}}, dojo.hitch(null, valTrans, "price"))).
+                addSeries("High", new dojox.charting.StoreSeries(
+                    store, {query: {}}, dojo.hitch(null, valTrans, "high"))).
+                render();
+        addLegend(chartC, "cols_legend");
+        new dojox.charting.action2d.Shake(chartC, "default", {shiftY: 0});
+        new dojox.charting.action2d.Tooltip(chartC);
+        
+        chartP = new dojox.charting.Chart("pie").
+                setTheme(dojox.charting.themes.ThreeD).
+                addPlot("default", {type: dojox.charting.plot2d.Pie, radius: 125}).
+                addSeries("Price", new dojox.charting.StoreSeries(
+                    store, {query: {}}, {y: "price", text: "symbol", tooltip: "price"})).
+                render();
+        addLegend(chartP, "pie_legend");
+        new dojox.charting.action2d.Tooltip(chartP);
+        new dojox.charting.action2d.MoveSlice(chartP);
+    };
+
+    makeSpinners = function(objects){
+        dojo.forEach(objects, function(m){
+            var nm = m.symbol;
+            var num = m.price;
+            console.log(nm, num);
+            var w = new dijit.form.NumberSpinner({
+                onChange: function(val){
+                    val = val===0 ? 0.01 : val; //HACKS the no label-when-zero bug
+                    console.log("OC:", nm, val);
+                    m.price = val;
+                    store.put(m);
+                    //store.setValues(m, "historicPrice", store.getValues("historicPrice").push(val));
+                    console.log("OC:", nm, val);
+                },
+                value: num,
+                constraints: {min:0, max:10,places:2},
+                className: "myField",
+                intermediateChanges: true
+            });
+            dojo.place('<label>'+nm+'</label>', dojo.byId("spinners"), "last")
+            dojo.place(w.domNode, "spinners", "last")
+        });
+        
+        var labels = dojo.map(objects, function(object, index){
+                return {
+                    value: index + 1,
+                    text:  object.symbol
+                }
+            });
+        chartC.addAxis("x", {natural: true, labels: labels}).render();
+    }
+
+    dojo.addOnLoad(function(){
+        makeCharts();
+        makeSpinners(store.query({}));
+    });
+</script>
+
+</head>
+
+<body class="tundra">
+	<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_anim2d.html b/dojox/charting/tests/test_anim2d.html
index b42db10..8490a18 100644
--- a/dojox/charting/tests/test_anim2d.html
+++ b/dojox/charting/tests/test_anim2d.html
@@ -8,41 +8,12 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../lang/functional.js"></script>
-	<script type="text/javascript" src="../../lang/utils.js"></script>
-	<script type="text/javascript" src="../Theme.js"></script>
-	<script type="text/javascript" src="../scaler/primitive.js"></script>
-	<script type="text/javascript" src="../scaler/linear.js"></script>
-	<script type="text/javascript" src="../Element.js"></script>
-	<script type="text/javascript" src="../axis2d/common.js"></script>
-	<script type="text/javascript" src="../axis2d/Base.js"></script>
-	<script type="text/javascript" src="../axis2d/Default.js"></script>
-	<script type="text/javascript" src="../plot2d/common.js"></script>
-	<script type="text/javascript" src="../plot2d/Base.js"></script>
-	<script type="text/javascript" src="../plot2d/Default.js"></script>
-	<script type="text/javascript" src="../plot2d/Lines.js"></script>
-	<script type="text/javascript" src="../plot2d/Areas.js"></script>
-	<script type="text/javascript" src="../plot2d/Markers.js"></script>
-	<script type="text/javascript" src="../plot2d/MarkersOnly.js"></script>
-	<script type="text/javascript" src="../plot2d/Scatter.js"></script>
-	<script type="text/javascript" src="../plot2d/Stacked.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedLines.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedAreas.js"></script>
-	<script type="text/javascript" src="../plot2d/Columns.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedColumns.js"></script>
-	<script type="text/javascript" src="../plot2d/ClusteredColumns.js"></script>
-	<script type="text/javascript" src="../plot2d/Bars.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedBars.js"></script>
-	<script type="text/javascript" src="../plot2d/ClusteredBars.js"></script>
-	<script type="text/javascript" src="../plot2d/Bubble.js"></script>
-	<script type="text/javascript" src="../plot2d/Grid.js"></script>
-	<script type="text/javascript" src="../plot2d/Pie.js"></script>
-	<script type="text/javascript" src="../Chart2D.js"></script>
-	-->
 	<script type="text/javascript">
 
-		dojo.require("dojox.charting.Chart2D");
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+
 		dojo.require("dojox.charting.themes.Shrooms");
 		dojo.require("dojox.charting.themes.PlotKit.blue");
 		dojo.require("dojox.charting.themes.PlotKit.cyan");
@@ -58,7 +29,7 @@
 			{
 				description: "Clustered columns with positive and negative values, readable theme, 1-second animate-in.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.Tufte).
 						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
 						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
diff --git a/dojox/charting/tests/test_axes.html b/dojox/charting/tests/test_axes.html
index f7af683..c143ff6 100644
--- a/dojox/charting/tests/test_axes.html
+++ b/dojox/charting/tests/test_axes.html
@@ -11,7 +11,10 @@
 <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 <script>
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Invisible");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Markers");
 dojo.require("dojox.charting.themes.ThreeD");
 
 makeObjects = function(){
@@ -20,7 +23,7 @@ makeObjects = function(){
     var customTheme = dojox.charting.themes.ThreeD.clone();
     customTheme.plotarea.fill = "#fed";
 
-	var chart1 = new dojox.charting.Chart2D("test1").
+	var chart1 = new dojox.charting.Chart("test1").
             setTheme(customTheme).
             addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
             addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
@@ -30,7 +33,7 @@ makeObjects = function(){
             addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
             render();
 
-	var chart2 = new dojox.charting.Chart2D("test2").
+	var chart2 = new dojox.charting.Chart("test2").
             setTheme(customTheme).
             addAxis("x", {fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
             addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
@@ -42,7 +45,7 @@ makeObjects = function(){
             addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}], {plot: "p3"}).
             render();
 
-	var chart3 = new dojox.charting.Chart2D("test3").
+	var chart3 = new dojox.charting.Chart("test3").
             setTheme(customTheme).
             addAxis("x", {type: "Invisible", fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
             addAxis("y", {type: "Invisible",vertical: true, fixLower: "major", fixUpper: "major", natural: true, includeZero: true}).
@@ -52,7 +55,7 @@ makeObjects = function(){
             addSeries("Series C", [{x: 5, y: 3}, {x: 6, y: 4}, {x: 7, y: 3}]).
             render();
 
-	var chart4 = new dojox.charting.Chart2D("test4").
+	var chart4 = new dojox.charting.Chart("test4").
             setTheme(customTheme).
             addPlot("default", {type: "Markers"}).
             addSeries("Series A", [{x: 1, y: 1}, {x: 2, y: 2}, {x: 3, y: 1}]).
diff --git a/dojox/charting/tests/test_axisZoomControl.html b/dojox/charting/tests/test_axisZoomControl.html
index 434d95e..8e4ed13 100644
--- a/dojox/charting/tests/test_axisZoomControl.html
+++ b/dojox/charting/tests/test_axisZoomControl.html
@@ -16,14 +16,12 @@
 			}
 		</style>
 		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-		<script type="text/javascript" src="../Theme.js"></script>
-		<script type="text/javascript" src="../axis2d/Default.js"></script>
-		<script type="text/javascript" src="../plot2d/Default.js"></script>
-		<script type="text/javascript" src="../plot2d/Grid.js"></script>
-		<script type="text/javascript" src="../Chart2D.js"></script>
 		<script type="text/javascript">
 			dojo.require("dojo.parser");
-			dojo.require("dojox.charting.Chart2D");
+			dojo.require("dojox.charting.Chart");
+            dojo.require("dojox.charting.axis2d.Default");
+            dojo.require("dojox.charting.plot2d.Lines");
+            dojo.require("dojox.charting.plot2d.Grid");
 			dojo.require("dojox.charting.themes.PlotKit.orange");
 			dojo.require("dojox.charting.action2d.Tooltip");
 			dojo.require("dojox.charting.action2d.Magnify");
@@ -33,7 +31,7 @@
 			
 			var chart;
 			makeObjects = function(){
-				chart = new dojox.charting.Chart2D("chart");
+				chart = new dojox.charting.Chart("chart");
 				chart.setTheme(dojox.charting.themes.PlotKit.orange);
 				chart.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
 					majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
diff --git a/dojox/charting/tests/test_bars.html b/dojox/charting/tests/test_bars.html
index 45d951b..15c212e 100644
--- a/dojox/charting/tests/test_bars.html
+++ b/dojox/charting/tests/test_bars.html
@@ -8,10 +8,6 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 <script type="text/javascript" src="../Chart3D.js"></script>
 <script type="text/javascript" src="../plot3d/Base.js"></script>
diff --git a/dojox/charting/tests/test_chart2d.html b/dojox/charting/tests/test_chart2d.html
index 5e27c71..ffd8a1d 100644
--- a/dojox/charting/tests/test_chart2d.html
+++ b/dojox/charting/tests/test_chart2d.html
@@ -8,41 +8,27 @@
 		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../lang/functional.js"></script>
-	<script type="text/javascript" src="../../lang/utils.js"></script>
-	<script type="text/javascript" src="../Theme.js"></script>
-	<script type="text/javascript" src="../scaler/primitive.js"></script>
-	<script type="text/javascript" src="../scaler/linear.js"></script>
-	<script type="text/javascript" src="../Element.js"></script>
-	<script type="text/javascript" src="../axis2d/common.js"></script>
-	<script type="text/javascript" src="../axis2d/Base.js"></script>
-	<script type="text/javascript" src="../axis2d/Default.js"></script>
-	<script type="text/javascript" src="../plot2d/common.js"></script>
-	<script type="text/javascript" src="../plot2d/Base.js"></script>
-	<script type="text/javascript" src="../plot2d/Default.js"></script>
-	<script type="text/javascript" src="../plot2d/Lines.js"></script>
-	<script type="text/javascript" src="../plot2d/Areas.js"></script>
-	<script type="text/javascript" src="../plot2d/Markers.js"></script>
-	<script type="text/javascript" src="../plot2d/MarkersOnly.js"></script>
-	<script type="text/javascript" src="../plot2d/Scatter.js"></script>
-	<script type="text/javascript" src="../plot2d/Stacked.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedLines.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedAreas.js"></script>
-	<script type="text/javascript" src="../plot2d/Columns.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedColumns.js"></script>
-	<script type="text/javascript" src="../plot2d/ClusteredColumns.js"></script>
-	<script type="text/javascript" src="../plot2d/Bars.js"></script>
-	<script type="text/javascript" src="../plot2d/StackedBars.js"></script>
-	<script type="text/javascript" src="../plot2d/ClusteredBars.js"></script>
-	<script type="text/javascript" src="../plot2d/Bubble.js"></script>
-	<script type="text/javascript" src="../plot2d/Grid.js"></script>
-	<script type="text/javascript" src="../plot2d/Pie.js"></script>
-	<script type="text/javascript" src="../Chart2D.js"></script>
-	-->
 	<script type="text/javascript">
 
-		dojo.require("dojox.charting.Chart2D");
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Default");
+        dojo.require("dojox.charting.plot2d.Areas");
+        dojo.require("dojox.charting.plot2d.Markers");
+        dojo.require("dojox.charting.plot2d.MarkersOnly");
+        dojo.require("dojox.charting.plot2d.StackedLines");
+        dojo.require("dojox.charting.plot2d.StackedAreas");
+        dojo.require("dojox.charting.plot2d.Bars");
+        dojo.require("dojox.charting.plot2d.ClusteredBars");
+        dojo.require("dojox.charting.plot2d.StackedBars");
+        dojo.require("dojox.charting.plot2d.ClusteredColumns");
+        dojo.require("dojox.charting.plot2d.StackedColumns");
+        dojo.require("dojox.charting.plot2d.Bubble");
+        dojo.require("dojox.charting.plot2d.Grid");
+        dojo.require("dojox.charting.plot2d.Candlesticks");
+        dojo.require("dojox.charting.plot2d.OHLC");
+        dojo.require("dojox.charting.plot2d.Scatter");
+
 		dojo.require("dojox.charting.themes.Shrooms");
 		dojo.require("dojox.charting.themes.PlotKit.blue");
 		dojo.require("dojox.charting.themes.PlotKit.cyan");
@@ -58,7 +44,7 @@
 			{
 				description: "Clustered columns with positive and negative values, readable theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.Tufte).
 						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
 						addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major", includeZero: true }).
@@ -73,7 +59,7 @@
 			{
 				description: "Bubble chart, green theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(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", {
@@ -106,7 +92,7 @@
 			{
 				description: "Lines, calculated labels",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", {
 							majorLabels: true, 
 							minorLabels: true, 
@@ -141,7 +127,7 @@
 			{
 				description: "Lines, pre-computed labels",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", {
 							majorLabels: true, 
 							minorLabels: true, 
@@ -180,7 +166,7 @@
 			{
 				description: "Defaults: lines, no axes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(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();
@@ -189,7 +175,7 @@
 			{
 				description: "Defaults: lines, no axes, and custom strokes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(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();
@@ -198,7 +184,7 @@
 			{
 				description: "Areas, Happy theme, no axes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addPlot("default", {type: "Areas", tension:"X"}).
 						setTheme(dojox.charting.themes.Shrooms).
 						addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4]).
@@ -210,7 +196,7 @@
 			{
 				description: "Areas, no axes, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addPlot("default", {type: "Areas"}).
 						addSeries("Series A",
 							[1, 2, 1, 2, 1, 2, 1],
@@ -232,7 +218,7 @@
 			{
 				description: "Lines, axes, blue theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.PlotKit.blue).
 						addAxis("x").
 						addAxis("y", {vertical: true}).
@@ -244,7 +230,7 @@
 			{
 				description: "Lines, axes (aligned on minor ticks), cyan theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.PlotKit.cyan).
 						addAxis("x", {
 							fixLower: "minor", fixUpper: "minor"
@@ -260,7 +246,7 @@
 			{
 				description: "Lines, axes (aligned on major ticks), green theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.PlotKit.green).
 						addAxis("x", {
 							fixLower: "major", fixUpper: "major"
@@ -276,7 +262,7 @@
 			{
 				description: "Lines and markers, no axes, purple theme, custom min/max.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.SageToLime).
 						addPlot("default", {type: "Markers"}).
 						addSeries("Series A", [1, 2, 1, 2, 1, 2, 1], {min: 0, max: 3}).
@@ -287,7 +273,7 @@
 			{
 				description: "Markers only, no axes, custom theme, custom markers, custom min/max.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addPlot("default", { type: "MarkersOnly" }).
 						addSeries("Series A",
 							[ 1, 2, 1, 2, 1, 2, 1 ],
@@ -313,7 +299,7 @@
 			{
 				description: "Lines and markers, shadows, no axes, custom theme, custom markers, custom min/max.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addPlot("default", {
 							type: "Markers", shadow:  {dx: 1, dy: 1, width: 2, color: [0, 0, 0, 0.3]}
 						}).
@@ -341,7 +327,7 @@
 			{
 				description: "Stacked lines, markers, shadows, no axes, custom strokes, fills, and markers.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addPlot("default", {
 							type: "StackedLines",
 							markers: true,
@@ -378,7 +364,7 @@
 			{
 				description: "Stacked areas, axes (aligned on major ticks), custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", {fixLower: "major", fixUpper: "major"}).
 						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", min: 0}).
 						addPlot("default", { type: "StackedAreas", tension:"S" }).
@@ -400,7 +386,7 @@
 			{
 				description: "Candlesticks with gaps, custom strokes and fills, optional mid points.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addPlot("default", {type: "Candlesticks", gap: 1}).
 						addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true}).
 						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
@@ -442,7 +428,7 @@
 			{
 				description: "Open/High/Low/Close with gaps, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.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}).
@@ -484,7 +470,7 @@
 			{
 				description: "Columns, no axes, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.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" }).
@@ -494,7 +480,7 @@
 			{
 				description: "Columns with gaps beetwen them, vertical axis aligned on major ticks, custom strokes, fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.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" }).
@@ -505,7 +491,7 @@
 			{
 				description: "Stacked columns, no axes, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.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" }).
@@ -515,7 +501,7 @@
 			{
 				description: "Bars, axes aligned on major ticks, no minor ticks, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true}).
 						addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true}).
 						addPlot("default", {type: "Bars"}).
@@ -533,7 +519,7 @@
 			{
 				description: "Stacked bars, no axes, custom strokes and fills.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.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" }).
@@ -543,7 +529,7 @@
 			{
 				description: "Clustered columns, custom axes, custom strokes, fills, and gap.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", {
 							fixLower: "minor", fixUpper: "minor", natural: true
 						}).
@@ -562,7 +548,7 @@
 			{
 				description: "Clustered bars, custom axes, custom strokes, fills, and gap.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.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 }).
@@ -574,7 +560,7 @@
 			{
 				description: "Columns with gaps beetwen them, grids, custom strokes, fills, axes.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", { fixLower: "minor", fixUpper: "minor", natural: true }).
 						addAxis("y", {
 							vertical: true,
@@ -600,7 +586,7 @@
 			{
 				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 dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x", {fixLower: "minor", fixUpper: "minor", natural: true}).
 						addAxis("y", {
 							vertical: true, fixLower: "major", fixUpper: "major",
@@ -629,7 +615,7 @@
 			{
 				description: "Columns with positive and negative values, axes, and grid.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x").
 						addAxis("y", { vertical: true }).
 						addPlot("default", { type: "Columns", gap: 10 }).
@@ -648,7 +634,7 @@
 			{
 				description: "Clustered columns with positive and negative values, axes, and grid.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x").
 						addAxis("y", { vertical: true }).
 						addPlot("default", { type: "ClusteredColumns", gap: 10 }).
@@ -671,7 +657,7 @@
 			{
 				description: "Bars with positive and negative values, axes, and grid.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x").
 						addAxis("y", { vertical: true }).
 						addPlot("default", { type: "Bars", gap: 10 }).
@@ -690,7 +676,7 @@
 			{
 				description: "Clustered bars with positive and negative values, axes, and grid.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						addAxis("x").
 						addAxis("y", { vertical: true }).
 						addPlot("default", { type: "ClusteredBars", gap: 10 }).
@@ -713,7 +699,7 @@
 			{
 				description: "Default lines with 2D data, custom axis, red theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.Minty).
 						addAxis("x", {
 							min: 0,
@@ -745,7 +731,7 @@
 			{
 				description: "Scatter chart, custom axis, purple theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.Ireland).
 						addPlot("default", {type: "Scatter"}).
 						addAxis("x", {
@@ -778,7 +764,7 @@
 			{
 				description: "Markers, lines, 2D data, custom axis, blue theme.",
 				makeChart: function(node){
-					(new dojox.charting.Chart2D(node)).
+					(new dojox.charting.Chart(node)).
 						setTheme(dojox.charting.themes.PlotKit.blue).
 						addPlot("default", {
 							type: "Default",
diff --git a/dojox/charting/tests/test_chart2d_dynamics.html b/dojox/charting/tests/test_chart2d_dynamics.html
index 98d5388..96d6398 100644
--- a/dojox/charting/tests/test_chart2d_dynamics.html
+++ b/dojox/charting/tests/test_chart2d_dynamics.html
@@ -13,13 +13,23 @@
 	.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-<script type="text/javascript" src="../Chart2D.js"></script>
 <script type="text/javascript">
 dojo.require("dijit.form.Button");
 dojo.require("dijit.form.CheckBox");
 dojo.require("dijit.form.ComboBox");
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.plot2d.Grid");
 dojo.require("dojox.charting.themes.CubanShirts");
 dojo.require("dojox.charting.widget.Legend");
 
@@ -40,29 +50,29 @@ var getZeroes = function(){
 };
 
 var makeObjects = function(){
-	chart = new dojox.charting.Chart2D("test");
+	chart = new dojox.charting.Chart("test");
 	chart.setTheme(dojox.charting.themes.CubanShirts);
 
-	if(dijit.byId("hAxis").attr("checked")){
+	if(dijit.byId("hAxis").get("checked")){
 		chart.addAxis("x", {natural: true, includeZero: true, fixUpper: "minor"});
 	}
 
-	if(dijit.byId("vAxis").attr("checked")){
+	if(dijit.byId("vAxis").get("checked")){
 		chart.addAxis("y", {vertical: true, natural: true, includeZero: true, fixUpper: "minor"});
 	}
 
-	chart.addPlot("default", {type: dijit.byId("plot").attr("value"), gap: 2});
+	chart.addPlot("default", {type: dijit.byId("plot").get("value"), gap: 2});
 
-	if(dijit.byId("grid").attr("checked")){
+	if(dijit.byId("grid").get("checked")){
 		chart.addPlot("grid", {type: "Grid", hMinorLines: true, vMinorLines: true});
 	}
 
 	for(var i = 1; i <= 5; ++i){
-		if(dijit.byId("s" + i).attr("checked")){
+		if(dijit.byId("s" + i).get("checked")){
 			chart.addSeries("Series " + i, getData(), {stroke: {color: "black", width: 1}});
 		}
 	}
-	if(dijit.byId("s6").attr("checked")){
+	if(dijit.byId("s6").get("checked")){
 		chart.addSeries("Series 6", getZeroes(), {stroke: {color: "black", width: 1}});
 	}
 
@@ -74,14 +84,14 @@ var makeObjects = function(){
 dojo.addOnLoad(makeObjects);
 
 changePlot = function(){
-	var type = dijit.byId("plot").attr("value");
+	var type = dijit.byId("plot").get("value");
 	chart.addPlot("default", {type: type, gap: 2});
 	chart.render();
 	legend.refresh();
 };
 
 changeGrid = function(){
-	if(dijit.byId("grid").attr("checked")){
+	if(dijit.byId("grid").get("checked")){
 		chart.addPlot("grid", {type: "Grid", hMinorLines: true, vMinorLines: true});
 	}else{
 		chart.removePlot("grid");
@@ -90,7 +100,7 @@ changeGrid = function(){
 };
 
 changeX = function(){
-	if(dijit.byId("hAxis").attr("checked")){
+	if(dijit.byId("hAxis").get("checked")){
 		chart.addAxis("x", {natural: true, includeZero: true, fixUpper: "minor"});
 	}else{
 		chart.removeAxis("x");
@@ -99,7 +109,7 @@ changeX = function(){
 };
 
 changeY = function(){
-	if(dijit.byId("vAxis").attr("checked")){
+	if(dijit.byId("vAxis").get("checked")){
 		chart.addAxis("y", {vertical: true, natural: true, includeZero: true, fixUpper: "minor"});
 	}else{
 		chart.removeAxis("y");
@@ -110,18 +120,18 @@ changeY = function(){
 changeSeries = function(n){
 	if(n == 6){
 		// special case
-		if(dijit.byId("s6").attr("checked")){
+		if(dijit.byId("s6").get("checked")){
 			chart.addSeries("Series 6", getZeroes(), {stroke: {color: "black", width: 1}});
 		}else{
 			chart.removeSeries("Series 6");
 		}
 	}else{
-		if(dijit.byId("s" + n).attr("checked")){
+		if(dijit.byId("s" + n).get("checked")){
 			chart.addSeries("Series " + n, getData(), {stroke: {color: "black", width: 1}});
-			dijit.byId("sb" + n).attr("disabled", false);
+			dijit.byId("sb" + n).get("disabled", false);
 		}else{
 			chart.removeSeries("Series " + n);
-			dijit.byId("sb" + n).attr("disabled", true);
+			dijit.byId("sb" + n).get("disabled", true);
 		}
 	}
 	chart.render();
diff --git a/dojox/charting/tests/test_chart2d_updating.html b/dojox/charting/tests/test_chart2d_updating.html
index ddb5ef0..b74ed07 100644
--- a/dojox/charting/tests/test_chart2d_updating.html
+++ b/dojox/charting/tests/test_chart2d_updating.html
@@ -9,16 +9,12 @@
 	</style>
 	<script type="text/javascript" src="../../../dojo/dojo.js" 
 		djConfig="isDebug: true"></script>
-	<!--
-	<script type="text/javascript" src="../../lang/functional.js"></script>
-	<script type="text/javascript" src="../Theme.js"></script>
-	<script type="text/javascript" src="../scaler/linear.js"></script>
-	<script type="text/javascript" src="../axis2d/Default.js"></script>
-	<script type="text/javascript" src="../Chart2D.js"></script>
-	-->
 	<script type="text/javascript">
 
-		dojo.require("dojox.charting.Chart2D");
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Areas");
+        dojo.require("dojox.charting.plot2d.Grid");
 		dojo.require("dojox.charting.themes.PlotKit.orange");
 		dojo.require("dojox.charting.themes.Tufte");
 
@@ -41,7 +37,7 @@
 			seriesC = makeSeries(limit, 2);
 
 		var makeObjects = function(){
-			chart = new dojox.charting.Chart2D("test");
+			chart = new dojox.charting.Chart("test");
 			chart.setTheme(dojox.charting.themes.Tufte);
 			chart.addAxis("x", {
 				fixLower: "minor", 
diff --git a/dojox/charting/tests/test_chartAxisTitle.html b/dojox/charting/tests/test_chartAxisTitle.html
new file mode 100644
index 0000000..1b59dda
--- /dev/null
+++ b/dojox/charting/tests/test_chartAxisTitle.html
@@ -0,0 +1,164 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<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";
+	@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("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Markers");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.cyan");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.orange");
+dojo.require("dojox.charting.themes.PlotKit.purple");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.NumberSpinner");
+
+var chart1;
+
+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 of 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: "4 Qtr"},{value: 5, text: "End"}
+				]
+			}).
+			addAxis("y", {
+				title: "Revenue(million)", 
+				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: "Two"},
+					{value: 3, text: "Three"},{value: 4, text: "Four"},{value: 5, text: "Five"},{value: 6, text: "Six"}
+				]
+			}).
+			addAxis("x2", {
+				title: "Quarter 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").
+		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").
+		addAxis("x", {
+			title: "Month 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: "Jan"},{value: 2, text: "Feb"},
+				{value: 3, text: "Mar"},{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(makeObjects);
+
+
+
+
+</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>
+<div id="test1" style="width: 500px; height: 400px;"></div>
+<p>Line chart with customized axis title</p>
+<div id="test2" style="width: 500px; height: 400px;"></div>
+</body>
+</html>
diff --git a/dojox/charting/tests/test_chartTitle.html b/dojox/charting/tests/test_chartTitle.html
new file mode 100644
index 0000000..e1becad
--- /dev/null
+++ b/dojox/charting/tests/test_chartTitle.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<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";
+	@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("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.themes.PlotKit.blue");
+dojo.require("dojox.charting.themes.PlotKit.cyan");
+dojo.require("dojox.charting.themes.PlotKit.green");
+dojo.require("dojox.charting.themes.PlotKit.orange");
+dojo.require("dojox.charting.themes.PlotKit.purple");
+dojo.require("dojox.charting.themes.PlotKit.red");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.NumberSpinner");
+
+var chart1;
+
+updateTitleGap = function(){
+	chart1.titleGap = dijit.byId("titleGap").get("value");
+	chart1.fullRender();
+}
+
+makeObjects = function(){
+	chart1 = new dojox.charting.Chart("test1", {title: "Production(ton)"}).
+			addAxis("x", {
+				includeZero: true, natural: true, fixLower: "major", fixUpper: "major",
+				labels: [
+					{value: 0, text: ""},{value: 1, text: "Jan"},{value: 2, text: "Feb"},
+					{value: 3, text: "Mar"},{value: 4, text: "Aprl"},{value: 5, text: "May"}
+				]
+			}).
+			addAxis("y", {
+				vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 2
+			}).
+			addPlot("default", {type: "Columns"}).
+			addSeries("Series A", [2, 6, 14, 3, 3], {stroke: {color: "orange"}, fill: "yellow"}).
+			addSeries("Series B", [2, 8, 8, 8, 6], {stroke: {color: "green"}, fill: "lightgreen"}).
+			render();
+
+	var chart2 = new dojox.charting.Chart("test2", {
+				title: "Production(Quantity)", 
+				titlePos: "bottom", 
+				titleGap: 25,
+				titleFont: "normal normal normal 15pt Arial",
+				titleFontColor: "orange"
+			}).
+			addAxis("x", {
+				includeZero: true, natural: true, fixLower: "major", fixUpper: "major",
+				labels: [
+					{value: 0, text: ""},{value: 1, text: "Jan"},{value: 2, text: "Feb"},
+					{value: 3, text: "Mar"},{value: 4, text: "Aprl"},{value: 5, text: "May"}
+				]
+			}).
+			addAxis("y", {
+				vertical: true, includeZero: true, natural: true, fixLower: "major", fixUpper: "major", majorTickStep: 200
+			}).
+			addPlot("default", {type: "Lines"}).
+			addSeries("Series A", [400, 800, 200, 600, 600], {stroke: {color: "red"}, fill: "lightpink"}).
+			addSeries("Series B", [200, 300, 500, 700, 800], {stroke: {color: "blue"}, fill: "lightblue"}).
+			render();
+};
+
+dojo.addOnLoad(makeObjects);
+
+</script>
+</head>
+<body class="tundra">
+<h1>Chart2D Title</h1>
+<p>Column chart with chart title</p>
+<p>
+    Title Gap: 
+    <input dojoType="dijit.form.NumberSpinner" id="titleGap" value="20" constraints="{min: 0, max: 100, fractional: false}" style="width: 8em;">
+     
+    <button dojoType="dijit.form.Button" onClick="updateTitleGap()">Apply</button>
+</p>
+<div id="test1" style="width: 400px; height: 300px;"></div>
+<p>Line chart with customized chart title</p>
+<div id="test2" style="width: 400px; height: 300px;"></div>
+
+</body>
+</html>
diff --git a/dojox/charting/tests/test_cylinders.html b/dojox/charting/tests/test_cylinders.html
index b7b6c42..c72c71a 100644
--- a/dojox/charting/tests/test_cylinders.html
+++ b/dojox/charting/tests/test_cylinders.html
@@ -8,10 +8,6 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 <script type="text/javascript" src="../Chart3D.js"></script>
 <script type="text/javascript" src="../plot3d/Base.js"></script>
diff --git a/dojox/charting/tests/test_event2d.html b/dojox/charting/tests/test_event2d.html
index f41233b..0e8a2fe 100644
--- a/dojox/charting/tests/test_event2d.html
+++ b/dojox/charting/tests/test_event2d.html
@@ -9,58 +9,28 @@
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
 <!-- required for Tooltip: a default dijit theme: -->
-<link rel="stylesheet" href="../../../dijit/themes/tundra/tundra.css">
+<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>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../../../dojo/_base/connect.js"></script>
-<script type="text/javascript" src="../../../dojo/fx.js"></script>
-<script type="text/javascript" src="../../lang/functional.js"></script>
-<script type="text/javascript" src="../../lang/utils.js"></script>
-<script type="text/javascript" src="../../gfx/fx.js"></script>
-<script type="text/javascript" src="../Theme.js"></script>
-<script type="text/javascript" src="../scaler/primitive.js"></script>
-<script type="text/javascript" src="../scaler/linear.js"></script>
-<script type="text/javascript" src="../Element.js"></script>
-<script type="text/javascript" src="../axis2d/common.js"></script>
-<script type="text/javascript" src="../axis2d/Base.js"></script>
-<script type="text/javascript" src="../axis2d/Default.js"></script>
-<script type="text/javascript" src="../plot2d/common.js"></script>
-<script type="text/javascript" src="../plot2d/Base.js"></script>
-<script type="text/javascript" src="../plot2d/Default.js"></script>
-<script type="text/javascript" src="../plot2d/Lines.js"></script>
-<script type="text/javascript" src="../plot2d/Areas.js"></script>
-<script type="text/javascript" src="../plot2d/Markers.js"></script>
-<script type="text/javascript" src="../plot2d/MarkersOnly.js"></script>
-<script type="text/javascript" src="../plot2d/Scatter.js"></script>
-<script type="text/javascript" src="../plot2d/Stacked.js"></script>
-<script type="text/javascript" src="../plot2d/StackedLines.js"></script>
-<script type="text/javascript" src="../plot2d/StackedAreas.js"></script>
-<script type="text/javascript" src="../plot2d/Columns.js"></script>
-<script type="text/javascript" src="../plot2d/StackedColumns.js"></script>
-<script type="text/javascript" src="../plot2d/ClusteredColumns.js"></script>
-<script type="text/javascript" src="../plot2d/Bars.js"></script>
-<script type="text/javascript" src="../plot2d/StackedBars.js"></script>
-<script type="text/javascript" src="../plot2d/ClusteredBars.js"></script>
-<script type="text/javascript" src="../plot2d/Bubble.js"></script>
-<script type="text/javascript" src="../plot2d/Grid.js"></script>
-<script type="text/javascript" src="../plot2d/Pie.js"></script>
-<script type="text/javascript" src="../Chart2D.js"></script>
-<script type="text/javascript" src="../action2d/Highlight.js"></script>
-<script type="text/javascript" src="../action2d/Magnify.js"></script>
-<script type="text/javascript" src="../action2d/MoveSlice.js"></script>
-<script type="text/javascript" src="../action2d/Shake.js"></script>
-<script type="text/javascript" src="../action2d/Tooltip.js"></script>
-<script type="text/javascript" src="../widget/Legend.js"></script>
 <script type="text/javascript">
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Default");
+dojo.require("dojox.charting.plot2d.StackedLines");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.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");
@@ -79,7 +49,7 @@ var dc = dojox.charting;
 var dur = 450;
 
 makeObjects = function(){
-	var chart1 = new dc.Chart2D("test1");
+	var chart1 = new dc.Chart("test1");
 	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}});
@@ -91,7 +61,7 @@ makeObjects = function(){
 	chart1.render();
 	var legend1 = new dojox.charting.widget.Legend({chart: chart1, horizontal: false}, "legend1");
 
-	var chart2 = new dc.Chart2D("test2");
+	var chart2 = new dc.Chart("test2");
 	chart2.setTheme(dc.themes.PlotKit.green);
 	chart2.addPlot("default", {type: "StackedLines", markers: true, tension:3, shadows: {dx: 2, dy: 2, dw: 2}});
 	chart2.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"});
@@ -104,7 +74,7 @@ makeObjects = function(){
 	chart2.render();
 	var legend2 = new dojox.charting.widget.Legend({chart: chart2}, "legend2");
 
-	var chart3 = new dc.Chart2D("test3");
+	var chart3 = new dc.Chart("test3");
 	chart3.setTheme(dc.themes.PlotKit.green);
 	chart3.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major"});
 	chart3.addPlot("default", {type: "Columns", gap: 2});
@@ -115,7 +85,7 @@ makeObjects = function(){
 	chart3.render();
 	var legend3 = new dojox.charting.widget.Legend({chart: chart3, horizontal: false}, "legend3");
 
-	var chart4 = new dc.Chart2D("test4");
+	var chart4 = new dc.Chart("test4");
 	chart4.setTheme(dc.themes.PlotKit.green);
 	chart4.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true});
 	chart4.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true});
@@ -129,7 +99,7 @@ makeObjects = function(){
 	chart4.render();
 	var legend4 = new dojox.charting.widget.Legend({chart: chart4}, "legend4");
 
-	var chart5 = new dc.Chart2D("test5");
+	var chart5 = new dc.Chart("test5");
 	chart5.setTheme(dc.themes.PlotKit.green);
 	chart5.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true});
 	chart5.addAxis("y", {vertical: true, fixLower: "minor", fixUpper: "minor", natural: true});
@@ -144,7 +114,7 @@ makeObjects = function(){
 	chart5.render();
 	var legend5 = new dojox.charting.widget.Legend({chart: chart5, horizontal: false}, "legend5");
 
-	var chart6 = new dc.Chart2D("test6");
+	var chart6 = new dc.Chart("test6");
 	chart6.setTheme(dc.themes.PlotKit.green);
 	chart6.addAxis("x");
 	chart6.addAxis("y", {vertical: true});
@@ -162,7 +132,7 @@ makeObjects = function(){
 	chart6.render();
 	var legend6 = new dojox.charting.widget.Legend({chart: chart6}, "legend6");
 
-	var chart7 = new dc.Chart2D("test7");
+	var chart7 = new dc.Chart("test7");
 	chart7.setTheme(dc.themes.PlotKit.green);
 	chart7.addPlot("default", {type: "StackedColumns"});
 	chart7.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "black"}, fill: "red"});
@@ -176,7 +146,7 @@ makeObjects = function(){
 	chart7.render();
 	var legend7 = new dojox.charting.widget.Legend({chart: chart7, horizontal: false}, "legend7");
 
-	var chart8 = new dc.Chart2D("test8");
+	var chart8 = new dc.Chart("test8");
 	chart8.setTheme(dc.themes.PlotKit.green);
 	chart8.addPlot("default", {type: "StackedBars"});
 	chart8.addSeries("Series A", [1, 2, 3, 4, 5], {stroke: {color: "black"}, fill: "red"});
@@ -187,7 +157,7 @@ makeObjects = function(){
 	chart8.render();
 	var legend8 = new dojox.charting.widget.Legend({chart: chart8}, "legend8");
 
-	var chart9 = new dc.Chart2D("test9");
+	var chart9 = new dc.Chart("test9");
 	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}});
@@ -204,7 +174,7 @@ makeObjects = function(){
 	chart9.render();
 	var legend9 = new dojox.charting.widget.Legend({chart: chart9, horizontal: false}, "legend9");
 
-	var chart10 = new dc.Chart2D("test10");
+	var chart10 = new dc.Chart("test10");
 	chart10.setTheme(dc.themes.PlotKit.green);
 	chart10.addPlot("default", {
 		type: "Pie", 
@@ -231,7 +201,7 @@ dojo.addOnLoad(makeObjects);
 
 </script>
 </head>
-<body class="tundra">
+<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>
diff --git a/dojox/charting/tests/test_fireEvent.html b/dojox/charting/tests/test_fireEvent.html
index e2b6f42..e83e5a5 100644
--- a/dojox/charting/tests/test_fireEvent.html
+++ b/dojox/charting/tests/test_fireEvent.html
@@ -17,13 +17,23 @@
     .events th {font-weight: bold;}
 </style>
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-<script type="text/javascript" src="../Chart2D.js"></script>
 <script type="text/javascript">
 dojo.require("dijit.form.Button");
 dojo.require("dijit.form.Select");
 dojo.require("dijit.form.NumberSpinner");
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Columns");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Pie");
+dojo.require("dojox.charting.plot2d.Grid");
 dojo.require("dojox.charting.themes.CubanShirts");
 dojo.require("dojox.charting.widget.Legend");
 
@@ -89,7 +99,7 @@ function addActions(chart){
 }
 
 function makeObjects(){
-	chart = new dojox.charting.Chart2D("test");
+	chart = new dojox.charting.Chart("test");
 	chart.setTheme(dojox.charting.themes.CubanShirts);
 
 	chart.addAxis("x", {natural: true, includeZero: true, fixUpper: "minor"});
diff --git a/dojox/charting/tests/test_label_shortening.html b/dojox/charting/tests/test_label_shortening.html
new file mode 100644
index 0000000..70255b2
--- /dev/null
+++ b/dojox/charting/tests/test_label_shortening.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<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";
+	@import "../../../dijit/tests/css/dijitTests.css";
+	@import "../../../dijit/themes/claro/claro.css";
+</style>
+<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+<script type="text/javascript">
+
+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");
+
+makeObjects = function(){
+
+	var chart1 = new dojox.charting.Chart("test1").
+			addAxis("x", {
+				fixLower: "major", fixUpper: "major", includeZero: true, 
+				labels: [
+					{value: 0, text: "first start point"},
+					{value: 2, text: "two"},
+					{value: 5, text: "last end point"}
+				],
+				maxLabelSize: 20,
+				trailingSymbol: "."
+			}).
+			addAxis("y", {
+				vertical: true, fixLower: "major", fixUpper: "major", natural: true,
+				labels: [{value: 0, text: ""},
+					{value: 1, text: "January"}, {value: 2, text: "February"},
+					{value: 3, text: "March"}, {value: 4, text: "April"},
+					{value: 5, text: "May"}, {value: 6, text: "June"}
+				],
+				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();
+
+	var 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: "last end point"}
+				],
+				rotation: 180,
+				maxLabelSize: 30
+			}).
+			addAxis("y", {
+				vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+				labels: [{value: 0, text: ""},
+					{value: 1, text: "January"}, {value: 2, text: "February"},
+					{value: 3, text: "March"}, {value: 4, text: "April"},
+					{value: 5, text: "May"}, {value: 6, text: "June"}
+				],
+				rotation: -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();
+			
+	var 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: "last end point"}
+				],
+				maxLabelCharCount: 5
+			}).
+			addAxis("y", {
+				vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+				labels: [{value: 0, text: ""},
+					{value: 1, text: "January"}, {value: 2, text: "February"},
+					{value: 3, text: "March"}, {value: 4, text: "April"},
+					{value: 5, text: "May"}, {value: 6, text: "June"}
+				],
+				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();
+			
+	var chart4 = new dojox.charting.Chart("test4").
+			addAxis("x", {
+				fixLower: "major", fixUpper: "major", includeZero: true, 
+				labels: [
+					{value: 0, text: "first start point"},
+					{value: 2, text: "second middle point"},
+					{value: 5, text: "last end point"}
+				],
+				maxLabelCharCount: 20,
+				maxLabelSize: 30
+			}).
+			addAxis("y", {
+				vertical: true, fixLower: "major", fixUpper: "major", natural: true, majorTickStep: 2,
+				labels: [{value: 0, text: ""},
+					{value: 1, text: "January"}, {value: 2, text: "February"},
+					{value: 3, text: "March"}, {value: 4, text: "April"},
+					{value: 5, text: "May"}, {value: 6, text: "June"}
+				],
+				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(makeObjects);
+
+</script>
+</head>
+<body class="claro">
+<h1>Chart 2D labels shortening</h1>
+<p>Hover on the truncated label(end with default trailing Symbol: "..." or your customized trailing symbols) you will see the whole label on tooltip</p>
+<p>1: Label shortening.(x axis customized trailing Symbol)</p>
+<div id="test1" style="width: 300px; height: 200px;"></div>
+<p>2: Label shortening with rotation.</p>
+<div id="test2" style="width: 300px; height: 200px;"></div>
+<p>3: Label shortening with limited character.(y axis customized trailing Symbol)</p>
+<div id="test3" style="width: 300px; height: 200px;"></div>
+<p>4: Label shortening with both limited character and limited length in px.</p>
+<div id="test4" style="width: 300px; height: 200px;"></div>
+<p>That's all Folks!</p>
+</body>
+</html>
diff --git a/dojox/charting/tests/test_labels2d.html b/dojox/charting/tests/test_labels2d.html
index 11736ca..add8c03 100644
--- a/dojox/charting/tests/test_labels2d.html
+++ b/dojox/charting/tests/test_labels2d.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -8,50 +8,15 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../../lang/functional.js"></script>
-<script type="text/javascript" src="../../lang/utils.js"></script>
-<script type="text/javascript" src="../Theme.js"></script>
-<script type="text/javascript" src="../scaler/linear.js"></script>
-<script type="text/javascript" src="../Element.js"></script>
-<script type="text/javascript" src="../axis2d/common.js"></script>
-<script type="text/javascript" src="../axis2d/Base.js"></script>
-<script type="text/javascript" src="../axis2d/Default.js"></script>
-<script type="text/javascript" src="../plot2d/common.js"></script>
-<script type="text/javascript" src="../plot2d/Base.js"></script>
-<script type="text/javascript" src="../plot2d/Default.js"></script>
-<script type="text/javascript" src="../plot2d/Lines.js"></script>
-<script type="text/javascript" src="../plot2d/Areas.js"></script>
-<script type="text/javascript" src="../plot2d/Markers.js"></script>
-<script type="text/javascript" src="../plot2d/MarkersOnly.js"></script>
-<script type="text/javascript" src="../plot2d/Stacked.js"></script>
-<script type="text/javascript" src="../plot2d/StackedLines.js"></script>
-<script type="text/javascript" src="../plot2d/StackedAreas.js"></script>
-<script type="text/javascript" src="../plot2d/Columns.js"></script>
-<script type="text/javascript" src="../plot2d/StackedColumns.js"></script>
-<script type="text/javascript" src="../plot2d/ClusteredColumns.js"></script>
-<script type="text/javascript" src="../plot2d/Bars.js"></script>
-<script type="text/javascript" src="../plot2d/StackedBars.js"></script>
-<script type="text/javascript" src="../plot2d/ClusteredBars.js"></script>
-<script type="text/javascript" src="../plot2d/Grid.js"></script>
-<script type="text/javascript" src="../plot2d/Pie.js"></script>
-<script type="text/javascript" src="../Chart2D.js"></script>
 <script type="text/javascript">
 
-dojo.require("dojox.charting.Chart2D");
-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("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Bars");
 
 makeObjects = function(){
-	var chart1 = new dojox.charting.Chart2D("test1");
+	var chart1 = new dojox.charting.Chart("test1");
 	chart1.addAxis("x", {fixLower: "major", fixUpper: "major", includeZero: true});
 	chart1.addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", natural: true});
 	chart1.addPlot("default", {type: "Bars"});
@@ -59,7 +24,7 @@ makeObjects = function(){
 	chart1.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"});
 	chart1.render();
 	
-	var chart2 = new dojox.charting.Chart2D("test2");
+	var chart2 = new dojox.charting.Chart("test2");
 	chart2.addAxis("x", {
 		fixLower: "major", fixUpper: "major", includeZero: true, 
 		labels: [
@@ -81,7 +46,7 @@ makeObjects = function(){
 	chart2.render();
 
 	
-	var chart3 = new dojox.charting.Chart2D("test3");
+	var chart3 = new dojox.charting.Chart("test3");
 	chart3.addAxis("x", {
 		fixLower: "major", fixUpper: "major", includeZero: true, 
 		labels: [{value: 0, text: "z e r o"}, {value: 2, text: "t w o"}, {value: 4, text: "f o u r"}]
@@ -98,7 +63,7 @@ makeObjects = function(){
 	chart3.addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"});
 	chart3.render();
 	
-	var chart4 = new dojox.charting.Chart2D("test4");
+	var chart4 = new dojox.charting.Chart("test4");
 	chart4.addAxis("x", {
 		majorLabels: false,
 		includeZero: true, 
@@ -141,7 +106,7 @@ makeObjects = function(){
 	);
 	chart4.render();
 
-	var chart5 = new dojox.charting.Chart2D("test5").
+	var chart5 = new dojox.charting.Chart("test5").
 			addAxis("x", {
 				fixLower: "major", fixUpper: "major", includeZero: true, 
 				labels: [
@@ -165,7 +130,7 @@ makeObjects = function(){
 			addSeries("Series B", [5, 4, 3, 2, 1], {stroke: {color: "blue"}, fill: "lightblue"}).
 			render();
 
-	var chart6 = new dojox.charting.Chart2D("test6").
+	var chart6 = new dojox.charting.Chart("test6").
 			addAxis("x", {
 				fixLower: "major", fixUpper: "major", includeZero: true, 
 				labels: [
diff --git a/dojox/charting/tests/test_nulls.html b/dojox/charting/tests/test_nulls.html
index 7423650..f18d781 100644
--- a/dojox/charting/tests/test_nulls.html
+++ b/dojox/charting/tests/test_nulls.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
 <html>
 <head>
 <title>Chart 2D nulls</title>
@@ -11,14 +11,28 @@
 <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 <script>
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Lines");
+dojo.require("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.Markers");
+dojo.require("dojox.charting.plot2d.StackedLines");
+dojo.require("dojox.charting.plot2d.StackedAreas");
+dojo.require("dojox.charting.plot2d.Bars");
+dojo.require("dojox.charting.plot2d.ClusteredBars");
+dojo.require("dojox.charting.plot2d.StackedBars");
+dojo.require("dojox.charting.plot2d.ClusteredColumns");
+dojo.require("dojox.charting.plot2d.StackedColumns");
+dojo.require("dojox.charting.plot2d.Bubble");
+dojo.require("dojox.charting.plot2d.Candlesticks");
+dojo.require("dojox.charting.plot2d.Pie");
 
 makeObjects = function(){
 
 	var types = [ "Areas", "Bars", "ClusteredBars", "ClusteredColumns", "Lines", "Markers", "StackedAreas", "StackedBars", "StackedColumns", "StackedLines" ];
 
 	dojo.forEach(types, function(type, i){
-		new dojox.charting.Chart2D("test" + (i + 1))
+		new dojox.charting.Chart("test" + (i + 1))
 		.addAxis("x", { vertical: false, min: 0, max: 15 })
 		.addAxis("y", { vertical: true, min: 0, max: 15 })
 		.addPlot("default", { type: type })
@@ -27,7 +41,7 @@ makeObjects = function(){
 		.render();
 	});
 	
-	new dojox.charting.Chart2D("test10")
+	new dojox.charting.Chart("test10")
 	.addAxis("x", { vertical: false, min: 0, max: 15 })
 	.addAxis("y", { vertical: true, min: 0, max: 15 })
 	.addPlot("default", { type: "Candlesticks" })
@@ -45,12 +59,12 @@ makeObjects = function(){
 	], { stroke: {color: "blue"}, fill: "lightblue" })
 	.render();
 	
-	new dojox.charting.Chart2D("test11")
+	new dojox.charting.Chart("test11")
 	.addPlot("default", { type: "Pie" })
 	.addSeries("Series A", [3, 5, null, 4, 0, 4, null, 1, 6, 5])
 	.render();
 	
-	new dojox.charting.Chart2D("test12")
+	new dojox.charting.Chart("test12")
 	.addAxis("x", { vertical: false, min: 0, max: 15 })
 	.addAxis("y", { vertical: true, min: 0, max: 15 })
 	.addPlot("default", { type: "Bubble" })
diff --git a/dojox/charting/tests/test_pie2d.html b/dojox/charting/tests/test_pie2d.html
index bc72f77..f4125a4 100644
--- a/dojox/charting/tests/test_pie2d.html
+++ b/dojox/charting/tests/test_pie2d.html
@@ -1,4 +1,4 @@
-<!DOCTYPE HTML>
+<!DOCTYPE HTML>
 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
@@ -8,22 +8,11 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../../lang/functional.js"></script>
-<script type="text/javascript" src="../../lang/functional/fold.js"></script>
-<script type="text/javascript" src="../../lang/utils.js"></script>
-<script type="text/javascript" src="../Theme.js"></script>
-<script type="text/javascript" src="../scaler/linear.js"></script>
-<script type="text/javascript" src="../Element.js"></script>
-<script type="text/javascript" src="../plot2d/Pie.js"></script>
-<script type="text/javascript" src="../Chart2D.js"></script>
 <script type="text/javascript">
 
-dojo.require("dojox.charting.Chart2D");
+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");
@@ -31,7 +20,7 @@ dojo.require("dojox.charting.themes.Adobebricks");
 dojo.require("dojox.charting.themes.Algae");
 
 makeObjects = function(){
-	var chart1 = new dojox.charting.Chart2D("test1");
+	var chart1 = new dojox.charting.Chart("test1");
 	chart1.setTheme(dojox.charting.themes.PlotKit.blue);
 	chart1.addPlot("default", {
 		type: "Pie",
@@ -42,7 +31,7 @@ makeObjects = function(){
 	chart1.addSeries("Series A", [4, 2, 1, 1]);
 	chart1.render();
 
-	var chart2 = new dojox.charting.Chart2D("test2");
+	var chart2 = new dojox.charting.Chart("test2");
 	chart2.setTheme(dojox.charting.themes.PlotKit.blue);
 	chart2.addPlot("default", {
 		type: "Pie",
@@ -54,7 +43,7 @@ makeObjects = function(){
 	chart2.addSeries("Series A", [4, 2, 1, 1]);
 	chart2.render();
 
-	var chart3 = new dojox.charting.Chart2D("test3");
+	var chart3 = new dojox.charting.Chart("test3");
 	chart3.setTheme(dojox.charting.themes.PlotKit.green);
 	chart3.addPlot("default", {
 		type: "Pie",
@@ -66,7 +55,7 @@ makeObjects = function(){
 	chart3.addSeries("Series A", [4, 2, 1, 1]);
 	chart3.render();
 
-	var chart4 = new dojox.charting.Chart2D("test4");
+	var chart4 = new dojox.charting.Chart("test4");
 	chart4.setTheme(dojox.charting.themes.PlotKit.green);
 	chart4.addPlot("default", {
 		type: "Pie",
@@ -78,7 +67,7 @@ makeObjects = function(){
 	chart4.addSeries("Series A", [4, 2, 1, 1]);
 	chart4.render();
 
-	var chart5 = new dojox.charting.Chart2D("test5");
+	var chart5 = new dojox.charting.Chart("test5");
 	chart5.setTheme(dojox.charting.themes.PlotKit.red);
 	chart5.addPlot("default", {
 		type: "Pie",
@@ -89,7 +78,7 @@ makeObjects = function(){
 	chart5.addSeries("Series A", [{y: 4, text: "Red"}, {y: 2, text: "Green"}, {y: 1, text: "Blue"}, {y: 1, text: "Other"}]);
 	chart5.render();
 
-	var chart6 = new dojox.charting.Chart2D("test6");
+	var chart6 = new dojox.charting.Chart("test6");
 	chart6.setTheme(dojox.charting.themes.PlotKit.red);
 	chart6.addPlot("default", {
 		type: "Pie",
@@ -106,7 +95,7 @@ makeObjects = function(){
 	]);
 	chart6.render();
 
-	var chart7 = new dojox.charting.Chart2D("test7");
+	var chart7 = new dojox.charting.Chart("test7");
 	chart7.setTheme(dojox.charting.themes.Adobebricks);
 	chart7.addPlot("default", {
 		type: "Pie",
@@ -117,7 +106,7 @@ makeObjects = function(){
 	chart7.addSeries("Series A", [4]);
 	chart7.render();
 
-	var chart8 = new dojox.charting.Chart2D("test8");
+	var chart8 = new dojox.charting.Chart("test8");
 	chart8.setTheme(dojox.charting.themes.Algae);
 	chart8.addPlot("default", {
 		type: "Pie",
diff --git a/dojox/charting/tests/test_pie_smart_label.html b/dojox/charting/tests/test_pie_smart_label.html
new file mode 100644
index 0000000..3f96c52
--- /dev/null
+++ b/dojox/charting/tests/test_pie_smart_label.html
@@ -0,0 +1,133 @@
+<!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>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("dojox.charting.Chart");
+            dojo.require("dojox.charting.plot2d.Pie");
+            dojo.require("dojox.charting.action2d.Highlight");
+            dojo.require("dojox.charting.action2d.MoveSlice");
+            dojo.require("dojox.charting.action2d.Tooltip");
+			dojo.require("dojox.charting.themes.Tom");
+            dojo.require("dojox.charting.widget.Legend");
+			
+            var pieChart = null;
+			var legend = null;
+            dojo.addOnLoad(function(){
+                var dc = dojox.charting;
+                pieChart = new dc.Chart("pieChart");
+                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: "China",
+                    tooltip: "1,210 million"
+                },{
+                    y: 9.52,
+                    text: "India",
+                    tooltip: "952 million"
+                }, {
+                    y: 2.66,
+                    text: "USA",
+                    tooltip: "266 million"
+                }, {
+                    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");
+            });
+			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/test_plot_order.html b/dojox/charting/tests/test_plot_order.html
index ecf61c5..cf27e14 100644
--- a/dojox/charting/tests/test_plot_order.html
+++ b/dojox/charting/tests/test_plot_order.html
@@ -13,7 +13,9 @@
 <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 <script>
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Bubble");
 dojo.require("dojox.charting.themes.ThreeD");
 dojo.require("dojox.charting.widget.Legend");
 
@@ -22,7 +24,7 @@ dojo.require("dojo.dnd.Source");
 makeObjects = function(){
     dojo.query("button").style("disabled", true);
     
-	var chart1 = new dojox.charting.Chart2D("chart1").
+	var chart1 = new dojox.charting.Chart("chart1").
             setTheme(dojox.charting.themes.ThreeD).
             addAxis("x", {min: 0, max: 10}).
             addAxis("y", {vertical: true, min: 0, max: 10}).
diff --git a/dojox/charting/tests/test_rotatedLabels.html b/dojox/charting/tests/test_rotatedLabels.html
index 1499a81..b4a2f95 100644
--- a/dojox/charting/tests/test_rotatedLabels.html
+++ b/dojox/charting/tests/test_rotatedLabels.html
@@ -15,13 +15,15 @@
 dojo.require("dijit.form.Button");
 dojo.require("dijit.form.NumberSpinner");
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Default");
 dojo.require("dojox.charting.themes.PrimaryColors");
 
 var chart;
 
 makeObjects = function(){
-	chart = new dojox.charting.Chart2D("test1").
+	chart = new dojox.charting.Chart("test1").
         setTheme(dojox.charting.themes.PrimaryColors).
         addPlot("default").
         addSeries("Series A", [1, 3, 2, 5, 4]).
diff --git a/dojox/charting/tests/test_scaler.html b/dojox/charting/tests/test_scaler.html
index c7812d3..1a49f73 100644
--- a/dojox/charting/tests/test_scaler.html
+++ b/dojox/charting/tests/test_scaler.html
@@ -8,12 +8,7 @@
 	@import "../../../dojo/resources/dojo.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
-<script type="text/javascript" src="../scaler/linear.js"></script>
 <script type="text/javascript">
 
 dojo.require("dojox.charting.scaler.linear");
diff --git a/dojox/charting/tests/test_selectableLegend.html b/dojox/charting/tests/test_selectableLegend.html
new file mode 100644
index 0000000..2b10dcd
--- /dev/null
+++ b/dojox/charting/tests/test_selectableLegend.html
@@ -0,0 +1,249 @@
+<!DOCTYPE HTML>
+<html>
+    <head>
+        <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("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.addOnLoad(function(){
+				var 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("A",[1,3,5,7,2,4,6]).
+					render();
+				var barsLegend = new dojox.charting.widget.SelectableLegend({chart: bars},"barsLegend");
+				
+				var clusteredBars = new dojox.charting.Chart("clusteredBars").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type:"ClusteredBars",gap:2}).
+					addAxis("x",{natural: true, includeZero: true}).
+					addAxis("y",{natural: true, vertical:true}).
+					addSeries("A",[1,3,5,7,2,4,6]).
+					addSeries("B",[2,4,6,8,3,5,7]).
+					addSeries("C",[6,4,2,7,5,3,1]);
+//					new dojox.charting.action2d.Highlight(clusteredBars, "default");
+					clusteredBars.render();
+				var clusteredBarsLegend = new dojox.charting.widget.SelectableLegend({chart: clusteredBars},"clusteredBarsLegend");
+				
+				var stackedBars = new dojox.charting.Chart("stackedBars").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default", {type:"StackedBars",gap:2}).
+					addAxis("x",{natual: true, includeZero: true, majorTickStep:1}).
+					addAxis("y",{natual: true, vertical: true}).
+					addSeries("A",[1,3,5,7,2,4,6]).
+					addSeries("B",[2,4,6,8,3,5,7]).
+					addSeries("C",[6,4,2,7,5,3,1]).
+					render();
+				var stackedBarsLegend = new dojox.charting.widget.SelectableLegend({chart: stackedBars},"stackedBarsLegend");
+				
+				var stackedArea = new dojox.charting.Chart("stackedArea").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default", {type:"StackedAreas",tension:4}).
+					addAxis("y",{natural: true, includeZero: true, vertical:true}).
+					addAxis("x",{natural: true}).
+					addSeries("A",[1,3,5,7,2,4,6]).
+					addSeries("B",[2,4,6,8,3,5,7]).
+					addSeries("C",[6,4,2,7,5,3,1]).
+					render();
+				var stackedAreaLegend = new dojox.charting.widget.SelectableLegend({chart: stackedArea},"stackedAreaLegend");
+				
+				var columns = new dojox.charting.Chart("columns").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type: "Columns",gap:2}).
+					addAxis("y",{natural: true, includeZero: true, vertical:true}).
+					addAxis("x",{natural: true}).
+					addSeries("A",[1,3,5,7,2,4,6]).
+					render();
+				var columnsLegend = new dojox.charting.widget.SelectableLegend({chart: columns},"columnsLegend");
+				
+				var clusteredColumns = new dojox.charting.Chart("clusteredColumns").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type:"ClusteredColumns",gap:2}).
+					addAxis("y",{natural: true, includeZero: true, vertical:true}).
+					addAxis("x",{natural: true}).
+					addSeries("A",[1,3,5,7,2,4,6]).
+					addSeries("B",[2,4,6,8,3,5,7]).
+					addSeries("C",[6,4,2,7,5,3,1]).
+					render();
+				var clusteredColumnsLegend = new dojox.charting.widget.SelectableLegend({chart: clusteredColumns},"clusteredColumnsLegend");
+				
+				var stackedColumns = new dojox.charting.Chart("stackedColumns").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default", {type:"StackedColumns",gap:2}).
+					addAxis("y",{natual: true, includeZero: true, majorTickStep:1, vertical: true}).
+					addAxis("x",{natual: true}).
+					addSeries("A",[1,3,5,7,2,4,6]).
+					addSeries("B",[2,4,6,8,3,5,7]).
+					addSeries("C",[6,4,2,7,5,3,1]).
+					render();
+				var stackedColumnsLegend = new dojox.charting.widget.SelectableLegend({chart: stackedColumns},"stackedColumnsLegend");	
+				
+				var linesColumns = new dojox.charting.Chart("linesColumns").
+					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("A",[2,4,6,8,3,5,7]).
+					addSeries("B",[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").
+					setTheme(dojox.charting.themes.MiamiNice).
+					addPlot("default",{type:"Pie",radius:100,font: "normal normal 10pt Tahoma",htmlLabels:true,labelOffset:-20}).
+					addSeries("A",[{
+	                    y: 12.1,
+	                    text: "China"
+	                },{
+	                    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("A",[{x:3,y:5,size:1},{x:1,y:7,size:1},{x:4,y:2,size:3}]).
+					addSeries("B",[{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");
+			})
+        
+        </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;">
+		<h2>2.Clustered Bars</h2>
+		<div id="clusteredBars" class="bars"></div>
+		<div id="clusteredBarsLegend"></div>
+		</div>
+		<div style="float:left;">
+		<h2>3.Stacked Bars</h2>
+		<div id="stackedBars" class="bars"></div>
+		<div id="stackedBarsLegend"></div>
+		</div>
+		<div style="float:left;">
+		<h2>4.Stacked Area</h2>
+		<div id="stackedArea" class="bars"></div>
+		<div id="stackedAreaLegend"></div>
+		</div>
+		</div>
+		
+		
+		<div style="clear:both;">
+		<div style="float:left;">
+		<h2>5.Columns</h2>
+		<div id="columns" class="columns"></div>
+		<div id="columnsLegend"></div>
+		</div>
+		<div style="float:left;">
+		<h2>6.Clustered Columns</h2>
+		<div id="clusteredColumns" class="columns"></div>
+		<div id="clusteredColumnsLegend"></div>
+		</div>
+		<div style="float:left;">
+		<h2>7.Stacked Columns</h2>
+		<div id="stackedColumns" class="columns"></div>
+		<div id="stackedColumnsLegend"></div>
+		</div>
+		<div style="float:left;">
+		<h2>8.Lines&Columns</h2>
+		<div id="linesColumns" class="columns"></div>
+		<div id="linesColumnsLegend"></div>
+		</div>
+		</div>
+		
+		<div style="clear:both;">
+		<div style="float:left;">
+		<h2>9.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>10.Bubble</h2>
+		<div id="bubble" class="bubble" style="float:left;"></div>
+		<div style="float:left;">
+		<div id="bubbleLegend"></div>
+		</div>
+		</div>
+		</div>
+
+    </body>
+</html>
diff --git a/dojox/charting/tests/test_series_order.html b/dojox/charting/tests/test_series_order.html
index 272554f..702dcfd 100644
--- a/dojox/charting/tests/test_series_order.html
+++ b/dojox/charting/tests/test_series_order.html
@@ -13,7 +13,9 @@
 <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 <script>
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Bubble");
 dojo.require("dojox.charting.themes.ThreeD");
 dojo.require("dojox.charting.widget.Legend");
 
@@ -22,7 +24,7 @@ dojo.require("dojo.dnd.Source");
 makeObjects = function(){
     dojo.query("button").style("disabled", true);
     
-	var chart1 = new dojox.charting.Chart2D("chart1").
+	var chart1 = new dojox.charting.Chart("chart1").
             setTheme(dojox.charting.themes.ThreeD).
             addAxis("x", {min: 0, max: 10}).
             addAxis("y", {vertical: true, min: 0, max: 10}).
diff --git a/dojox/charting/tests/test_sparklines.html b/dojox/charting/tests/test_sparklines.html
index 953383f..e155f66 100644
--- a/dojox/charting/tests/test_sparklines.html
+++ b/dojox/charting/tests/test_sparklines.html
@@ -16,7 +16,9 @@
 		<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.widget.Chart2D");
+            dojo.require("dojox.charting.plot2d.Lines");
+            dojo.require("dojox.charting.plot2d.Areas");
 			dojo.require("dojox.charting.widget.Sparkline");
 			dojo.require("dojox.charting.themes.Tufte");
 			dojo.require("dojox.data.HtmlStore");
diff --git a/dojox/charting/tests/test_spider2d.html b/dojox/charting/tests/test_spider2d.html
new file mode 100644
index 0000000..e48c1b6
--- /dev/null
+++ b/dojox/charting/tests/test_spider2d.html
@@ -0,0 +1,285 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<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";
+	@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("dojox.charting.Chart");
+	dojo.require("dojox.charting.plot2d.Spider");
+	dojo.require("dojox.charting.themes.PlotKit.blue");
+	dojo.require("dijit.Tooltip");
+	dojo.require("dijit.form.CheckBox");
+	dojo.require("dijit.form.RadioButton");
+	dojo.require("dijit.form.Form");
+	dojo.require("dojo.fx.easing");
+	dojo.require("dojox.gfx.fx");
+	dojo.require("dojox.charting.widget.SelectableLegend");
+	
+	var dc = dojox.charting,
+		divisions = 7,
+		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");
+		chart1.setTheme(dojox.charting.themes.PlotKit.blue);
+		chart1.addPlot("default", {
+			type: "Spider",
+			labelOffset: -10,
+			divisions: divisions,
+			axisColor:      "lightgray",
+			spiderColor:    "silver",
+            seriesFillAlpha: 0.2,
+			spiderOrigin:	 0.16,
+			markerSize:  	 3,
+			precision:		 0,
+			spiderType:	 	 stype
+		});
+		chart1.addSeries("China", {data: {"GDP": 2,"area": 6,"population": 2000,"inflation": 15,"growth": 12}}, { fill: "blue" });
+		chart1.addSeries("France", {data: {"GDP": 6,"area": 15,"population": 500,"inflation": 5,"growth": 6}}, { fill: "red" });
+		chart1.addSeries("USA", {data: {"GDP": 3,"area": 20,"population": 1500,"inflation": 10,"growth": 3}}, { fill: "green" });
+		chart1.addSeries("Japan", {data: {"GDP": 4,"area": 2,"population": 1000,"inflation": 20,"growth": 2}}, { fill: "yellow" });
+		chart1.addSeries("Korean", {data: {"GDP": 10,"area": 10,"population": 800,"inflation": 2,"growth": 18}}, { fill: "orange" });
+		chart1.addSeries("Canada", {data: {"GDP": 1,"area": 18,"population": 300,"inflation": 3,"growth": 15}}, { fill: "purple" });
+		chart1.render();
+		
+		legend1 = new dc.widget.SelectableLegend({chart: chart1, horizontal: true}, "legend1");
+		
+		// prepare and enable controls
+        populateSelect("dojo.fx.easing", "easing");
+	};
+	
+	dojo.addOnLoad(makeObjects);
+
+</script>
+
+<script type="text/javascript">
+	function switchData(val){
+		if(val == "b1"){
+			chart1.updateSeries("China", {data: {"GDP": 2,"area": 6,"population": 2000,"inflation": 15,"growth": 12}}, { fill: "blue" });
+			chart1.updateSeries("France", {data: {"GDP": 6,"area": 15,"population": 500,"inflation": 5,"growth": 6}}, { fill: "red" });
+			chart1.updateSeries("USA", {data: {"GDP": 3,"area": 20,"population": 1500,"inflation": 10,"growth": 3}}, { fill: "green" });
+			chart1.updateSeries("Japan", {data: {"GDP": 4,"area": 2,"population": 1000,"inflation": 20,"growth": 2}}, { fill: "yellow" });
+			chart1.updateSeries("Korean", {data: {"GDP": 10,"area": 10,"population": 800,"inflation": 2,"growth": 18}}, { fill: "orange" });
+			chart1.updateSeries("Canada", {data: {"GDP": 1,"area": 18,"population": 300,"inflation": 3,"growth": 15}}, { fill: "purple" });
+		}else{
+			chart1.updateSeries("China", {data: {"GDP": 8,"area": 2,"population": 500,"inflation": 2,"growth": 18}}, { fill: "blue" });
+			chart1.updateSeries("France", {data: {"GDP": 10,"area": 6,"population": 1000,"inflation": 20,"growth": 12}}, { fill: "red" });
+			chart1.updateSeries("USA", {data: {"GDP": 2,"area": 5,"population": 1500,"inflation": 12,"growth": 6}}, { fill: "green" });
+			chart1.updateSeries("Japan", {data: {"GDP": 1,"area": 20,"population": 500,"inflation": 5,"growth": 11}}, { fill: "yellow" });
+			chart1.updateSeries("Korean", {data: {"GDP": 4,"area": 2,"population": 2000,"inflation": 16,"growth": 8}}, { fill: "orange" });
+			chart1.updateSeries("Canada", {data: {"GDP": 6,"area": 10,"population": 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>
+<h5>
+A spider chart is a graphical method of displaying multivariate data in the form of a two-dimensional chart of three or more quantitative variables represented on axes starting from the same point. The relative position and angle of the axes is typically uninformative.
+</h5>
+<ul>
+	<li>
+	It consists of a sequence of equi-angular spokes, called radii, with each spoke representing one of the variables. The data length of a spoke is proportional to the magnitude of the variable for the data point relative to the maximum magnitude of the variable across all data points. 
+	A line is drawn connecting the data values for each spoke. This gives the plot a star-like appearance and the origin of the name of this plot.
+	</li>
+	<li>
+	Spider charts are useful when you want to look at several different factors all related to one item. spider charts have multiple axes along which data can be plotted
+	</li>
+</ul>
+
+<h5>
+Application
+</h5>
+<ul>
+
+	<li>
+	The "spider chart" can be a format commonly used by management consultants to show their clients how an organization compares with those in similar companies.
+	</li>
+	<li>
+	It also can be used as the control of quality improvement to display the performance metrics of any ongoing program.
+	</li>
+	<li>
+	Furthermore, it is also being used in sports to chart players' strengths and weaknesses.
+	</li>
+	<li>
+	For example, you could use a spider chart to compile data about a wide receiver on a professional football team. On one axis, you could plot the percentage of passes caught. 
+	Another axis would show his yards per completion; another, his completions per 100 plays; another, blocks made; and a final axis might show his interceptions
+	So far as we can see, the spider has a broad application area.
+	</li>
+</ul>
+<h5>
+Comparison with radar chart in dojox.charting
+</h5>
+<ul>
+	<li>
+	Spider charts differ from radar chart in that a spider chart is a chart that has N "y" axes while radar chart has only one "y" axis, all radiating from a central point, 
+	where each "y" axis represents a specific category. For example, there are 5 "y" axes: GDP, area, population, inflation and growth here.
+	</li>
+	<li>
+	The radar chart, however, instead of being drawn in a typical linear X/Y space, the radar chart is drawn using a circular plot, with specific X values being shown using an arbitrary number of spokes drawn from a center point. 
+	These charts are useful for showing data over a cyclical set of values (for instance, hours of a day, minutes in an hour, etc.). With a radar chart, data is plotted in much the same way as with a typical line or area chart.
+	</li>
+	<li><strong>
+	Actually, the radar chart is somewhat similar with line chart, the major difference between them is: line chart has a "straight" X axis while radar chart has a "circular" X axis, and the orientation of their Y axis is opposite.
+	</strong></li>
+</ul>
+<hr/>
+<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/test_tension.html b/dojox/charting/tests/test_tension.html
index 10ecc14..a33798f 100644
--- a/dojox/charting/tests/test_tension.html
+++ b/dojox/charting/tests/test_tension.html
@@ -15,7 +15,9 @@
     </style>
     <script src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
     <script>
-        dojo.require("dojox.charting.Chart2D");
+        dojo.require("dojox.charting.Chart");
+        dojo.require("dojox.charting.axis2d.Default");
+        dojo.require("dojox.charting.plot2d.Default");
         dojo.require("dojox.charting.widget.Legend");
         
         var data = [{x: 1, y: 1}, {x: 1, y: 2}, {x: 2, y: 2}, {x: 2, y: 1}];
@@ -26,7 +28,7 @@
                     plotarea: {fill: null}, // no background
                     colors: ["red", "green", "blue", "orange"]
                 });
-            var chart = new dojox.charting.Chart2D("test_chart").
+            var chart = new dojox.charting.Chart("test_chart").
                     setTheme(theme).
                     addAxis("x", {natural: true, min: 0, max: 3}).
                     addAxis("y", {vertical: true, natural: true, min: 0, max: 3}).
diff --git a/dojox/charting/tests/test_themes.html b/dojox/charting/tests/test_themes.html
index a7baab0..1558f33 100644
--- a/dojox/charting/tests/test_themes.html
+++ b/dojox/charting/tests/test_themes.html
@@ -34,7 +34,16 @@
 </style>
 <script src="../../../dojo/dojo.js" djConfig="isDebug: false, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
 <script>
-	dojo.require("dojox.charting.Chart2D");
+    dojo.require("dojox.charting.Chart");
+    dojo.require("dojox.charting.axis2d.Default");
+    dojo.require("dojox.charting.plot2d.ClusteredBars");
+    dojo.require("dojox.charting.plot2d.ClusteredColumns");
+    dojo.require("dojox.charting.plot2d.Default");
+    dojo.require("dojox.charting.plot2d.StackedAreas");
+    dojo.require("dojox.charting.plot2d.Bubble");
+    dojo.require("dojox.charting.plot2d.Candlesticks");
+    dojo.require("dojox.charting.plot2d.OHLC");
+    dojo.require("dojox.charting.plot2d.Pie");
 
 	var charts = {}, backgroundImage, backgroundColor, color, lastThemeName = "";
 
@@ -91,7 +100,7 @@
 		backgroundColor = dojo.style(dojo.body(), "backgroundColor");
 		color = dojo.style(dojo.body(), "color");
 
-		charts.bars = new dojox.charting.Chart2D("bars").
+		charts.bars = new dojox.charting.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}).
@@ -100,7 +109,7 @@
 			addSeries("Series C", [0.68, 0.95]).
 			addSeries("Series D", [0.77, 0.66]);
 
-		charts.columns = new dojox.charting.Chart2D("columns").
+		charts.columns = new dojox.charting.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}).
@@ -109,7 +118,7 @@
 			addSeries("Series C", [0.68, 0.95]).
 			addSeries("Series D", [0.77, 0.66]);
 
-		charts.lines = new dojox.charting.Chart2D("lines").
+		charts.lines = new dojox.charting.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: "Default", lines: true, markers: true, tension: "X"}).
@@ -118,11 +127,11 @@
 			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 dojox.charting.Chart2D("pieFan").
+		charts.pieFan = new dojox.charting.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 dojox.charting.Chart2D("bubbles").
+		charts.bubbles = new dojox.charting.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"}).
@@ -131,7 +140,7 @@
 			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 dojox.charting.Chart2D("area").
+		charts.area = new dojox.charting.Chart("area").
 			addAxis("x", {fixLower: "major", fixUpper: "major"}).
 			addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", min: 0}).
 			addPlot("default", {type: "StackedAreas", tension: "X"}).
@@ -139,11 +148,11 @@
 			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 dojox.charting.Chart2D("pieLin").
+		charts.pieLin = new dojox.charting.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 dojox.charting.Chart2D("candle").
+		charts.candle = new dojox.charting.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}).
@@ -176,7 +185,7 @@
 					{ 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 dojox.charting.Chart2D("ohlc").
+		charts.ohlc = new dojox.charting.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}).
@@ -236,6 +245,7 @@
 				<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>
diff --git a/dojox/charting/tests/test_widget2d.html b/dojox/charting/tests/test_widget2d.html
index 9a78f15..6d09fbb 100644
--- a/dojox/charting/tests/test_widget2d.html
+++ b/dojox/charting/tests/test_widget2d.html
@@ -14,24 +14,17 @@
 			.dojoxLegendNode {border: 1px solid #ccc; margin: 5px 10px 5px 10px; padding: 3px}
 			.dojoxLegendText {vertical-align: text-top; padding-right: 10px}
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug: true, parseOnLoad: true"></script>
-
-		<!--
-		<script type="text/javascript" src="../../lang/functional.js"></script>
-		<script type="text/javascript" src="../Theme.js"></script>
-		<script type="text/javascript" src="../scaler/linear.js"></script>
-		<script type="text/javascript" src="../action2d/Tooltip.js"></script>
-		<script type="text/javascript" src="../Chart2D.js"></script>
-		<script type="text/javascript" src="../widget/Chart2D.js"></script>
-		<script type="text/javascript" src="../widget/Sparkline.js"></script>
-		<script type="text/javascript" src="../widget/Legend.js"></script>
-		-->
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
 
 		<script type="text/javascript">
 			dojo.require("dijit.dijit");
-			dojo.require("dojox.charting.widget.Chart2D");
-			dojo.require("dojox.charting.widget.Sparkline");
+            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.plot2d.Pie");
+            dojo.require("dojox.charting.action2d.Tooltip");
+            dojo.require("dojox.charting.action2d.MoveSlice");
 			dojo.require("dojox.charting.widget.Legend");
 			dojo.require("dojox.charting.themes.PlotKit.orange");
 			dojo.require("dojox.charting.themes.PlotKit.blue");
@@ -65,7 +58,7 @@
 		<table border="0" cellspacing="30">
 			<tr>
 				<td>
-					<div dojoType="dojox.charting.widget.Chart2D" id="chart1" style="width: 300px; height: 300px;">
+					<div dojoType="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>
@@ -78,7 +71,7 @@
 					<div dojoType="dojox.charting.widget.Legend" chartRef="chart1"></div>
 				</td>
 				<td>
-					<div dojoType="dojox.charting.widget.Chart2D" id="chart2" theme="dojox.charting.themes.PlotKit.orange" 
+					<div dojoType="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" 
@@ -94,7 +87,7 @@
 			</tr>
 			<tr>
 				<td>
-					<div dojoType="dojox.charting.widget.Chart2D" id="chart3" theme="dojox.charting.themes.PlotKit.blue"
+					<div dojoType="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>
@@ -102,7 +95,7 @@
 					</div>
 				</td>
 				<td>
-					<div dojoType="dojox.charting.widget.Chart2D" id="chart4" theme="dojox.charting.themes.PlotKit.green"
+					<div dojoType="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>
@@ -111,13 +104,6 @@
 					</div>
 				</td>
 			</tr>
-			<tr>
-				<td>
-					<div dojoType="dojox.charting.widget.Sparkline"></div>
-				</td>
-				<td>
-				</td>
-			</tr>
 		</table>
 		<p>That's all Folks!</p>
 	</body>
diff --git a/dojox/charting/tests/test_widget2d_deprecated.html b/dojox/charting/tests/test_widget2d_deprecated.html
new file mode 100644
index 0000000..eda22d4
--- /dev/null
+++ b/dojox/charting/tests/test_widget2d_deprecated.html
@@ -0,0 +1,104 @@
+<!DOCTYPE HTML>
+<html>
+	<head>
+		<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";
+			@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("dijit.dijit");
+            dojo.require("dojox.charting.widget.Chart2D");
+			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");
+			dojo.require("dojox.data.HtmlStore");
+			
+			seriesB = [2.6, 1.8, 2, 1, 1.4, 0.7, 2];
+			
+			dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		</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.Chart2D" 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>
+					<div dojoType="dojox.charting.widget.Legend" chartRef="chart1"></div>
+				</td>
+				<td>
+					<div dojoType="dojox.charting.widget.Chart2D" 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>
+					<div dojoType="dojox.charting.widget.Legend" chartRef="chart2"></div>
+				</td>
+			</tr>
+			<tr>
+				<td>
+					<div dojoType="dojox.charting.widget.Chart2D" 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 dojoType="dojox.charting.widget.Chart2D" 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_win2d.html b/dojox/charting/tests/test_win2d.html
index e58f7dd..3dbb12c 100644
--- a/dojox/charting/tests/test_win2d.html
+++ b/dojox/charting/tests/test_win2d.html
@@ -9,19 +9,7 @@
 	@import "../../../dijit/themes/tundra/tundra.css";
 	@import "../../../dijit/tests/css/dijitTests.css";
 </style>
-<!--
-The next line should include Microsoft's Silverligth.js, if you plan to use the silverlight backend
-<script type="text/javascript" src="Silverlight.js"></script>
--->
 <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
-<script type="text/javascript" src="../Theme.js"></script>
-<script type="text/javascript" src="../scaler/linear.js"></script>
-<script type="text/javascript" src="../axis2d/Default.js"></script>
-<script type="text/javascript" src="../plot2d/Default.js"></script>
-<script type="text/javascript" src="../plot2d/Grid.js"></script>
-<script type="text/javascript" src="../Chart2D.js"></script>
-<script type="text/javascript" src="../../lang/functional/object.js"></script>
-
 <script type="text/javascript">
 
 dojo.require("dijit.form.HorizontalSlider");
@@ -29,7 +17,10 @@ dojo.require("dijit.form.HorizontalRule");
 dojo.require("dijit.form.HorizontalRuleLabels");
 dojo.require("dojo.parser"); // scan page for widgets
 
-dojo.require("dojox.charting.Chart2D");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.charting.axis2d.Default");
+dojo.require("dojox.charting.plot2d.Areas");
+dojo.require("dojox.charting.plot2d.Grid");
 dojo.require("dojox.charting.themes.PlotKit.orange");
 
 dojo.require("dojox.lang.functional.object");
@@ -112,7 +103,7 @@ var onMouseMove = function(e){
 };
 
 makeObjects = function(){
-	chart = new dojox.charting.Chart2D("test");
+	chart = new dojox.charting.Chart("test");
 	chart.setTheme(dojox.charting.themes.PlotKit.orange);
 	chart.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
 		majorTick: {stroke: "black", length: 4}, minorTick: {stroke: "gray", length: 2}});
diff --git a/dojox/charting/tests/theme_preview.html b/dojox/charting/tests/theme_preview.html
index 93afd0c..04793d6 100644
--- a/dojox/charting/tests/theme_preview.html
+++ b/dojox/charting/tests/theme_preview.html
@@ -33,10 +33,11 @@
 		</style>
 <script src="../../../dojo/dojo.js" djConfig="isDebug: false, gfxRenderer: 'svg,silverlight,vml,canvas'"></script>
 <script type="text/javascript">
-	dojo.require("dojox.charting.Chart2D");
+    dojo.require("dojox.charting.Chart");
+    dojo.require("dojox.charting.plot2d.Pie");
 
 	var themes = [
-		"Julie", "ThreeD", "Chris", "Tom", "PrimaryColors", "Electric", "Charged", "Renkoo",
+		"Julie", "ThreeD", "Chris", "Tom", "Claro", "PrimaryColors", "Electric", "Charged", "Renkoo",
 		"Adobebricks", "Algae", "Bahamation", "BlueDusk", "CubanShirts", "Desert", "Distinctive", "Dollar",
 		"Grasshopper", "Grasslands", "GreySkies", "Harmony", "IndigoNation", "Ireland", "MiamiNice",
 		"Minty", "PurpleRain", "RoyalPurples", "SageToLime", "Shrooms", "Tufte", "WatersEdge", "Wetland",
@@ -53,7 +54,7 @@
 				className: "title", 
 				innerHTML: 'See more of "<a href="test_themes.html?' + theme + '">' + theme + '</a>"' 
 			}, container);
-			var c = new dojox.charting.Chart2D(chart).
+			var c = new dojox.charting.Chart(chart).
 				setTheme(dojo.getObject("dojox.charting.themes." + theme)).
 				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]).
diff --git a/dojox/charting/themes/Charged.js b/dojox/charting/themes/Charged.js
index b213ff2..269c524 100644
--- a/dojox/charting/themes/Charged.js
+++ b/dojox/charting/themes/Charged.js
@@ -43,19 +43,19 @@ dojo.require("dojox.charting.Theme");
 		},
 		seriesThemes: [
 			{fill: g(defaultFill, "#004cbf", "#06f")},
-			{fill: g(defaultFill, "#bf004c", "#f06")},	
-			{fill: g(defaultFill, "#43bf00", "#6f0")},	
-			{fill: g(defaultFill, "#7300bf", "#90f")},	
-			{fill: g(defaultFill, "#bf7300", "#f90")},	
-			{fill: g(defaultFill, "#00bf73", "#0f9")}	
+			{fill: g(defaultFill, "#bf004c", "#f06")},
+			{fill: g(defaultFill, "#43bf00", "#6f0")},
+			{fill: g(defaultFill, "#7300bf", "#90f")},
+			{fill: g(defaultFill, "#bf7300", "#f90")},
+			{fill: g(defaultFill, "#00bf73", "#0f9")}
 		],
 		markerThemes: [
-			{fill: "#06f", stroke: {color: "#06f"}},	
+			{fill: "#06f", stroke: {color: "#06f"}},
 			{fill: "#f06", stroke: {color: "#f06"}},
-			{fill: "#6f0", stroke: {color: "#6f0"}},	
-			{fill: "#90f", stroke: {color: "#90f"}},	
-			{fill: "#f90", stroke: {color: "#f90"}},	
-			{fill: "#0f9", stroke: {color: "#0f9"}}	
+			{fill: "#6f0", stroke: {color: "#6f0"}},
+			{fill: "#90f", stroke: {color: "#90f"}},
+			{fill: "#f90", stroke: {color: "#f90"}},
+			{fill: "#0f9", stroke: {color: "#0f9"}}
 		]
 	});
 	
diff --git a/dojox/charting/themes/Claro.js b/dojox/charting/themes/Claro.js
new file mode 100644
index 0000000..00c3ae1
--- /dev/null
+++ b/dojox/charting/themes/Claro.js
@@ -0,0 +1,108 @@
+dojo.provide("dojox.charting.themes.Claro");
+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,
+		defaultFill = {type: "linear", space: "shape", x1: 0, y1: 0, x2: 0, y2: 100};
+	
+	themes.Claro = new dc.Theme({
+		chart: {
+			fill:	   {
+				type: "linear",
+				x1: 0, x2: 0, y1: 0, y2: 100,
+				colors: [
+					{ offset: 0, color: "#dbdbdb" },
+					{ offset: 1, color: "#efefef" }
+				]
+			},
+			stroke:    {color: "#b5bcc7"}
+		},
+		plotarea: {
+			fill:	   {
+				type: "linear",
+				x1: 0, x2: 0, y1: 0, y2: 100,
+				colors: [
+					{ offset: 0, color: "#dbdbdb" },
+					{ offset: 1, color: "#efefef" }
+				]
+			}
+		},
+		axis:{
+			stroke:	{ // the axis itself
+				color: "#888c76",
+				width: 1
+			},
+			tick: {	// used as a foundation for all ticks
+				color:     "#888c76",
+				position:  "center",
+				font:      "normal normal normal 7pt Verdana, Arial, sans-serif",	// labels on axis
+				fontColor: "#888c76"								// color of labels
+			}
+		},
+		series: {
+			stroke:  {width: 2.5, color: "#fff"},
+			outline: null,
+			font: "normal normal normal 7pt Verdana, Arial, sans-serif",
+			fontColor: "#131313"
+		},
+		marker: {
+			stroke:  {width: 1.25, color: "#131313"},
+			outline: {width: 1.25, color: "#131313"},
+			font: "normal normal normal 8pt Verdana, Arial, sans-serif",
+			fontColor: "#131313"
+		},
+		seriesThemes: [
+			{fill: g(defaultFill, "#2a6ead", "#3a99f2")},
+			{fill: g(defaultFill, "#613e04", "#996106")},
+			{fill: g(defaultFill, "#0e3961", "#155896")},
+			{fill: g(defaultFill, "#55aafa", "#3f7fba")},
+			{fill: g(defaultFill, "#ad7b2a", "#db9b35")}
+		],
+		markerThemes: [
+			{fill: "#2a6ead", stroke: {color: "#fff"}},
+			{fill: "#613e04", stroke: {color: "#fff"}},
+			{fill: "#0e3961", stroke: {color: "#fff"}},
+			{fill: "#55aafa", stroke: {color: "#fff"}},
+			{fill: "#ad7b2a", stroke: {color: "#fff"}}
+		]
+	});
+	
+	themes.Claro.next = function(elementType, mixin, doPost){
+		var isLine = elementType == "line";
+		if(isLine || elementType == "area"){
+			// custom processing for lines: substitute colors
+			var s = this.seriesThemes[this._current % this.seriesThemes.length],
+				m = this.markerThemes[this._current % this.markerThemes.length];
+			s.fill.space = "plot";
+			if(isLine){
+				s.stroke  = { width: 4, color: s.fill.colors[0].color};
+			}
+			m.outline = { width: 1.25, color: m.fill };
+			var theme = Theme.prototype.next.apply(this, arguments);
+			// cleanup
+			delete s.outline;
+			delete s.stroke;
+			s.fill.space = "shape";
+			return theme;
+		}
+		else if(elementType == "candlestick"){
+			var s = this.seriesThemes[this._current % this.seriesThemes.length];
+			s.fill.space = "plot";
+			s.stroke  = { width: 1, color: s.fill.colors[0].color};
+			var theme = Theme.prototype.next.apply(this, arguments);
+			return theme;
+		}
+		return Theme.prototype.next.apply(this, arguments);
+	};
+	
+	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);
+		}
+		return theme;
+	};
+})();
diff --git a/dojox/charting/themes/Distinctive.js b/dojox/charting/themes/Distinctive.js
index 6f4d9e2..8d8d62c 100644
--- a/dojox/charting/themes/Distinctive.js
+++ b/dojox/charting/themes/Distinctive.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.charting.themes.Distinctive");
 dojo.require("dojox.charting.Theme");
 (function(){
 	var dxc=dojox.charting;
-	dxc.themes.Distinctive=new dxc.Theme({  
+	dxc.themes.Distinctive=new dxc.Theme({
 		colors: [
 			"#497c91",
 			"#ada9d6",
@@ -35,7 +35,7 @@ dojo.require("dojox.charting.Theme");
 			"#efdeb0",
 			"#b17044",
 			"#ddc0c0",
-			"#a5a5a5" 
+			"#a5a5a5"
 		
 		]
 	});
diff --git a/dojox/charting/themes/ET/greys.js b/dojox/charting/themes/ET/greys.js
deleted file mode 100644
index 774d462..0000000
--- a/dojox/charting/themes/ET/greys.js
+++ /dev/null
@@ -1,55 +0,0 @@
-dojo.provide("dojox.charting.themes.ET.greys");
-dojo.require("dojox.charting.Theme");
-dojo.deprecated("dojox.charting.themes.ET.greys", "1.3");
-
-(function(){
-	var dxc=dojox.charting;
-	dxc.themes.ET.greys = new dxc.Theme({
-		antiAlias: false,
-		chart: {
-			stroke: null,
-			fill: "inherit"
-		},
-		plotarea: {
-			// stroke: { width: 0.2, color: "#666666" },
-			stroke: null,
-			fill: "transparent"
-		},
-		axis:{
-			stroke:{ width:	0 },
-			line:{ width:	0 },
-			majorTick:{ 
-				color:	"#666666", 
-				width:	1,
-				length: 5
-			},
-			minorTick: { 
-				color:	"black", 
-				width:	0.5, 
-				length:	2
-			},
-			font:"normal normal normal 8pt Tahoma",
-			fontColor:"#999999"
-		},
-		series:{
-			outline:{ width: 0, color: "black" },
-			stroke:	{ width: 1, color: "black" },
-			fill:	dojo.colorFromHex("#3b444b"),
-			font: "normal normal normal 7pt Tahoma",	//	label
-			fontColor: "#717171"
-		},
-		marker:{	//	any markers on a series.
-			stroke:{ width:1 },
-			fill:"#333",
-			font:"normal normal normal 7pt Tahoma",	//	label
-			fontColor:"#000"
-		},
-		colors:[
-			dojo.colorFromHex("#8a8c8f"), 
-			dojo.colorFromHex("#4b4b4b"),
-			dojo.colorFromHex("#3b444b"), 
-			dojo.colorFromHex("#2e2d30"),
-			dojo.colorFromHex("#000000") 
-		]
-	});
-})();
diff --git a/dojox/charting/themes/Electric.js b/dojox/charting/themes/Electric.js
index 652ae4c..e4929c2 100644
--- a/dojox/charting/themes/Electric.js
+++ b/dojox/charting/themes/Electric.js
@@ -44,19 +44,19 @@ dojo.require("dojox.charting.Theme");
 		},
 		seriesThemes: [
 			{fill: g(defaultFill, "#004cbf", "#06f")},
-			{fill: g(defaultFill, "#bf004c", "#f06")},	
-			{fill: g(defaultFill, "#43bf00", "#6f0")},	
-			{fill: g(defaultFill, "#7300bf", "#90f")},	
-			{fill: g(defaultFill, "#bf7300", "#f90")},	
-			{fill: g(defaultFill, "#00bf73", "#0f9")}	
+			{fill: g(defaultFill, "#bf004c", "#f06")},
+			{fill: g(defaultFill, "#43bf00", "#6f0")},
+			{fill: g(defaultFill, "#7300bf", "#90f")},
+			{fill: g(defaultFill, "#bf7300", "#f90")},
+			{fill: g(defaultFill, "#00bf73", "#0f9")}
 		],
 		markerThemes: [
-			{fill: "#06f", stroke: {color: "#06f"}},	
+			{fill: "#06f", stroke: {color: "#06f"}},
 			{fill: "#f06", stroke: {color: "#f06"}},
-			{fill: "#6f0", stroke: {color: "#6f0"}},	
-			{fill: "#90f", stroke: {color: "#90f"}},	
-			{fill: "#f90", stroke: {color: "#f90"}},	
-			{fill: "#0f9", stroke: {color: "#0f9"}}	
+			{fill: "#6f0", stroke: {color: "#6f0"}},
+			{fill: "#90f", stroke: {color: "#90f"}},
+			{fill: "#f90", stroke: {color: "#f90"}},
+			{fill: "#0f9", stroke: {color: "#0f9"}}
 		]
 	});
 	
diff --git a/dojox/charting/themes/Harmony.js b/dojox/charting/themes/Harmony.js
index 986f991..7d05a1c 100644
--- a/dojox/charting/themes/Harmony.js
+++ b/dojox/charting/themes/Harmony.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.charting.themes.Harmony");
 dojo.require("dojox.charting.Theme");
 (function(){
 	var dxc=dojox.charting;
-		dxc.themes.Harmony=new dxc.Theme({ 
+		dxc.themes.Harmony=new dxc.Theme({
 		colors: [
 			"#497c91",
 			"#59a0bd",
diff --git a/dojox/charting/themes/Midwest.js b/dojox/charting/themes/Midwest.js
index 0458c06..0594691 100644
--- a/dojox/charting/themes/Midwest.js
+++ b/dojox/charting/themes/Midwest.js
@@ -5,7 +5,7 @@ dojo.require("dojox.charting.Theme");
 	var dxc=dojox.charting;
 	dxc.themes.Midwest=new dxc.Theme({
 		colors: [
-			"#927b51", 
+			"#927b51",
 			"#a89166",
 			"#80c31c",
 			"#bcdd5a",
diff --git a/dojox/charting/themes/Minty.js b/dojox/charting/themes/Minty.js
index 18e03d9..9af6839 100644
--- a/dojox/charting/themes/Minty.js
+++ b/dojox/charting/themes/Minty.js
@@ -5,7 +5,7 @@ dojo.require("dojox.charting.Theme");
 	var dxc=dojox.charting;
 	dxc.themes.Minty=new dxc.Theme({
 		colors: [
-			"#80ccbb", 
+			"#80ccbb",
 			"#539e8b",
 			"#335f54",
 			"#8dd1c2",
diff --git a/dojox/charting/themes/Renkoo.js b/dojox/charting/themes/Renkoo.js
index cf602cb..e6c1cea 100644
--- a/dojox/charting/themes/Renkoo.js
+++ b/dojox/charting/themes/Renkoo.js
@@ -43,17 +43,17 @@ dojo.require("dojox.charting.Theme");
 		},
 		seriesThemes: [
 			{fill: g(defaultFill, "#e7e391", "#f8f7de")},
-			{fill: g(defaultFill, "#ffb6b6", "#ffe8e8")},	
-			{fill: g(defaultFill, "#bcda7d", "#eef7da")},	
-			{fill: g(defaultFill, "#d5d5d5", "#f4f4f4")},	
-			{fill: g(defaultFill, "#c1e3fd", "#e4f3ff")}	
+			{fill: g(defaultFill, "#ffb6b6", "#ffe8e8")},
+			{fill: g(defaultFill, "#bcda7d", "#eef7da")},
+			{fill: g(defaultFill, "#d5d5d5", "#f4f4f4")},
+			{fill: g(defaultFill, "#c1e3fd", "#e4f3ff")}
 		],
 		markerThemes: [
-			{fill: "#fcfcf3", stroke: {color: "#e7e391"}},	
-			{fill: "#fff1f1", stroke: {color: "#ffb6b6"}},	
+			{fill: "#fcfcf3", stroke: {color: "#e7e391"}},
+			{fill: "#fff1f1", stroke: {color: "#ffb6b6"}},
 			{fill: "#fafdf4", stroke: {color: "#bcda7d"}},
-			{fill: "#fbfbfb", stroke: {color: "#d5d5d5"}},	
-			{fill: "#f3faff", stroke: {color: "#c1e3fd"}}	
+			{fill: "#fbfbfb", stroke: {color: "#d5d5d5"}},
+			{fill: "#f3faff", stroke: {color: "#c1e3fd"}}
 		]
 	});
 	
diff --git a/dojox/charting/themes/SageToLime.js b/dojox/charting/themes/SageToLime.js
index 8391dea..6035f3c 100644
--- a/dojox/charting/themes/SageToLime.js
+++ b/dojox/charting/themes/SageToLime.js
@@ -5,7 +5,7 @@ dojo.require("dojox.charting.Theme");
 	var dxc=dojox.charting;
 	dxc.themes.SageToLime=new dxc.Theme({
 		colors: [
-			"#abdbcb", 
+			"#abdbcb",
 			"#435a51",
 			"#70998b",
 			"#5f8074",
diff --git a/dojox/charting/themes/Tom.js b/dojox/charting/themes/Tom.js
index 9426c85..a099379 100644
--- a/dojox/charting/themes/Tom.js
+++ b/dojox/charting/themes/Tom.js
@@ -44,17 +44,17 @@ dojo.require("dojox.charting.Theme");
 		},
 		seriesThemes: [
 			{fill: g(defaultFill, "#bf9e0a", "#ecc20c")},
-			{fill: g(defaultFill, "#73b086", "#95e5af")},	
-			{fill: g(defaultFill, "#c7212d", "#ed2835")},	
-			{fill: g(defaultFill, "#87ab41", "#b6e557")},	
-			{fill: g(defaultFill, "#b86c25", "#d37d2a")}	
+			{fill: g(defaultFill, "#73b086", "#95e5af")},
+			{fill: g(defaultFill, "#c7212d", "#ed2835")},
+			{fill: g(defaultFill, "#87ab41", "#b6e557")},
+			{fill: g(defaultFill, "#b86c25", "#d37d2a")}
 		],
 		markerThemes: [
-			{fill: "#bf9e0a", stroke: {color: "#ecc20c"}},	
+			{fill: "#bf9e0a", stroke: {color: "#ecc20c"}},
 			{fill: "#73b086", stroke: {color: "#95e5af"}},
-			{fill: "#c7212d", stroke: {color: "#ed2835"}},	
-			{fill: "#87ab41", stroke: {color: "#b6e557"}},	
-			{fill: "#b86c25", stroke: {color: "#d37d2a"}}	
+			{fill: "#c7212d", stroke: {color: "#ed2835"}},
+			{fill: "#87ab41", stroke: {color: "#b6e557"}},
+			{fill: "#b86c25", stroke: {color: "#d37d2a"}}
 		]
 	});
 	
diff --git a/dojox/charting/themes/Tufte.js b/dojox/charting/themes/Tufte.js
index 56ab4e1..1ced7cc 100644
--- a/dojox/charting/themes/Tufte.js
+++ b/dojox/charting/themes/Tufte.js
@@ -17,14 +17,14 @@ dojox.charting.themes.Tufte = new dojox.charting.Theme({
 	},
 	axis: {
 		stroke: {width: 1, color: "#ccc"},
-		majorTick:{ 
-			color:	"black", 
+		majorTick:{
+			color:	"black",
 			width:	1,
 			length: 5
 		},
-		minorTick: { 
-			color:	"#666", 
-			width:	1, 
+		minorTick: {
+			color:	"#666",
+			width:	1,
 			length:	2
 		},
 		font: "normal normal normal 8pt Tahoma",
@@ -45,10 +45,10 @@ dojox.charting.themes.Tufte = new dojox.charting.Theme({
 		fontColor: "black"
 	},
 	colors:[
-		dojo.colorFromHex("#8a8c8f"), 
+		dojo.colorFromHex("#8a8c8f"),
 		dojo.colorFromHex("#4b4b4b"),
-		dojo.colorFromHex("#3b444b"), 
+		dojo.colorFromHex("#3b444b"),
 		dojo.colorFromHex("#2e2d30"),
-		dojo.colorFromHex("#000000") 
+		dojo.colorFromHex("#000000")
 	]
 });
diff --git a/dojox/charting/widget/Chart.js b/dojox/charting/widget/Chart.js
new file mode 100644
index 0000000..72b8835
--- /dev/null
+++ b/dojox/charting/widget/Chart.js
@@ -0,0 +1,267 @@
+dojo.provide("dojox.charting.widget.Chart");
+
+dojo.require("dijit._Widget");
+dojo.require("dojox.charting.Chart");
+dojo.require("dojox.lang.functional");
+
+(function(){
+	var collectParams, collectAxisParams, collectPlotParams,
+		collectActionParams, collectDataParams,
+		notNull = function(o){ return o; },
+		df = dojox.lang.functional,
+		du = dojox.lang.utils,
+		dc = dojox.charting,
+		d = dojo;
+	
+	dojo.declare("dojox.charting.widget.Chart", dijit._Widget, {
+		// parameters for the markup
+		
+		// theme for the chart
+		theme: null,
+		
+		// margins for the chart: {l: 10, r: 10, t: 10, b: 10}
+		margins: null,
+		
+		// chart area
+		stroke: null,
+		fill:   null,
+		
+		// methods
+		
+		buildRendering: function(){
+			var n = this.domNode = this.srcNodeRef;
+			
+			// 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);
+			
+			// build the chart
+			n.innerHTML = "";
+			var c = this.chart = new dc.Chart(n, {
+				margins: this.margins,
+				stroke:  this.stroke,
+				fill:    this.fill
+			});
+			
+			// add collected parameters
+			if(this.theme){
+				c.setTheme(this.theme);
+			}
+			axes.forEach(function(axis){
+				c.addAxis(axis.name, axis.kwArgs);
+			});
+			plots.forEach(function(plot){
+				c.addPlot(plot.name, plot.kwArgs);
+			});
+			
+			this.actions = actions.map(function(action){
+				return new action.action(c, action.plot, action.kwArgs)
+			});
+			
+			var render = df.foldl(series, function(render, series){
+				if(series.type == "data"){
+					c.addSeries(series.name, series.data, series.kwArgs);
+					render = true;
+				}else{
+					c.addSeries(series.name, [0], series.kwArgs);
+					var kw = {};
+					du.updateWithPattern(
+						kw,
+						series.kwArgs,
+						{
+							"query": "",
+							"queryOptions": null,
+							"start": 0,
+							"count": 1 //,
+							// "sort": []
+						},
+						true
+					);
+					if(series.kwArgs.sort){
+						// sort is a complex object type and doesn't survive coercian
+						kw.sort = dojo.clone(series.kwArgs.sort);
+					}
+					d.mixin(kw, {
+						onComplete: function(data){
+							var values;
+							if("valueFn" in series.kwArgs){
+								var fn = series.kwArgs.valueFn;
+								values = d.map(data, function(x){
+									return fn(series.data.getValue(x, series.field, 0));
+								});
+							}else{
+								values = d.map(data, function(x){
+									return series.data.getValue(x, series.field, 0);
+								});
+							}
+							c.addSeries(series.name, values, series.kwArgs).render();
+						}
+					});
+					series.data.fetch(kw);
+				}
+				return render;
+			}, false);
+			if(render){ c.render(); }
+		},
+		destroy: function(){
+			// summary: properly destroy the widget
+			this.chart.destroy();
+			this.inherited(arguments);
+		},
+		resize: function(box){
+			//	summary:
+			//		Resize the widget.
+			//	description:
+			//		Resize the domNode and the widget surface to the dimensions of a box of the following form:
+			//			`{ l: 50, t: 200, w: 300: h: 150 }`
+			//		If no box is provided, resize the surface to the marginBox of the domNode.
+			//	box:
+			//		If passed, denotes the new size of the widget.
+			this.chart.resize(box);
+		}
+	});
+	
+	collectParams = function(node, type, kw){
+		var dp = eval("(" + type + ".prototype.defaultParams)");
+		var x, attr;
+		for(x in dp){
+			if(x in kw){ continue; }
+			attr = node.getAttribute(x);
+			kw[x] = du.coerceType(dp[x], attr == null || typeof attr == "undefined" ? dp[x] : attr);
+		}
+		var op = eval("(" + type + ".prototype.optionalParams)");
+		for(x in op){
+			if(x in kw){ continue; }
+			attr = node.getAttribute(x);
+			if(attr != null){
+				kw[x] = du.coerceType(op[x], attr);
+			}
+		}
+	};
+	
+	collectAxisParams = function(node){
+		var name = node.getAttribute("name"), type = node.getAttribute("type");
+		if(!name){ return null; }
+		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
+		if(type){
+			if(dc.axis2d[type]){
+				type = dojox._scopeName + ".charting.axis2d." + type;
+			}
+			var axis = eval("(" + type + ")");
+			if(axis){ kw.type = axis; }
+		}else{
+			type = dojox._scopeName + ".charting.axis2d.Default";
+		}
+		collectParams(node, type, kw);
+		// compatibility conversions
+		if(kw.font || kw.fontColor){
+			if(!kw.tick){
+				kw.tick = {};
+			}
+			if(kw.font){
+				kw.tick.font = kw.font;
+			}
+			if(kw.fontColor){
+				kw.tick.fontColor = kw.fontColor;
+			}
+		}
+		return o;
+	};
+	
+	collectPlotParams = function(node){
+		// var name = d.attr(node, "name"), type = d.attr(node, "type");
+		var name = node.getAttribute("name"), type = node.getAttribute("type");
+		if(!name){ return null; }
+		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
+		if(type){
+			if(dc.plot2d && dc.plot2d[type]){
+				type = dojox._scopeName + ".charting.plot2d." + type;
+			}
+			var plot = eval("(" + type + ")");
+			if(plot){ kw.type = plot; }
+		}else{
+			type = dojox._scopeName + ".charting.plot2d.Default";
+		}
+		collectParams(node, type, kw);
+		return o;
+	};
+	
+	collectActionParams = function(node){
+		// var plot = d.attr(node, "plot"), type = d.attr(node, "type");
+		var plot = node.getAttribute("plot"), type = node.getAttribute("type");
+		if(!plot){ plot = "default"; }
+		var o = {plot: plot, kwArgs: {}}, kw = o.kwArgs;
+		if(type){
+			if(dc.action2d[type]){
+				type = dojox._scopeName + ".charting.action2d." + type;
+			}
+			var action = eval("(" + type + ")");
+			if(!action){ return null; }
+			o.action = action;
+		}else{
+			return null;
+		}
+		collectParams(node, type, kw);
+		return o;
+	};
+
+	collectDataParams = function(node){
+		var ga = d.partial(d.attr, node);
+		var name = ga("name");
+		if(!name){ return null; }
+		var o = { name: name, kwArgs: {} }, kw = o.kwArgs, t;
+		t = ga("plot");
+		if(t != null){ kw.plot = t; }
+		t = ga("marker");
+		if(t != null){ kw.marker = t; }
+		t = ga("stroke");
+		if(t != null){ kw.stroke = eval("(" + t + ")"); }
+		t = ga("outline");
+		if(t != null){ kw.outline = eval("(" + t + ")"); }
+		t = ga("shadow");
+		if(t != null){ kw.shadow = eval("(" + t + ")"); }
+		t = ga("fill");
+		if(t != null){ kw.fill = eval("(" + t + ")"); }
+		t = ga("font");
+		if(t != null){ kw.font = t; }
+		t = ga("fontColor");
+		if(t != null){ kw.fontColor = eval("(" + t + ")"); }
+		t = ga("legend");
+		if(t != null){ kw.legend = t; }
+		t = ga("data");
+		if(t != null){
+			o.type = "data";
+			o.data = t ? dojo.map(String(t).split(','), Number) : [];
+			return o;
+		}
+		t = ga("array");
+		if(t != null){
+			o.type = "data";
+			o.data = eval("(" + t + ")");
+			return o;
+		}
+		t = ga("store");
+		if(t != null){
+			o.type = "store";
+			o.data = eval("(" + t + ")");
+			t = ga("field");
+			o.field = t != null ? t : "value";
+			t = ga("query");
+			if(!!t){ kw.query = t; }
+			t = ga("queryOptions");
+			if(!!t){ kw.queryOptions = eval("(" + t + ")"); }
+			t = ga("start");
+			if(!!t){ kw.start = Number(t); }
+			t = ga("count");
+			if(!!t){ kw.count = Number(t); }
+			t = ga("sort");
+			if(!!t){ kw.sort = eval("("+t+")"); }
+			t = ga("valueFn");
+			if(!!t){ kw.valueFn = df.lambda(t); }
+			return o;
+		}
+		return null;
+	};
+})();
diff --git a/dojox/charting/widget/Chart2D.js b/dojox/charting/widget/Chart2D.js
index 607b982..d21ebf7 100644
--- a/dojox/charting/widget/Chart2D.js
+++ b/dojox/charting/widget/Chart2D.js
@@ -1,8 +1,8 @@
 dojo.provide("dojox.charting.widget.Chart2D");
 
-dojo.require("dijit._Widget");
-dojo.require("dojox.charting.Chart2D");
-dojo.require("dojox.lang.functional");
+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");
@@ -11,260 +11,7 @@ dojo.require("dojox.charting.action2d.MoveSlice");
 dojo.require("dojox.charting.action2d.Shake");
 dojo.require("dojox.charting.action2d.Tooltip");
 
-(function(){
-	var collectParams, collectAxisParams, collectPlotParams,
-		collectActionParams, collectDataParams,
-		notNull = function(o){ return o; },
-		df = dojox.lang.functional,
-		du = dojox.lang.utils,
-		dc = dojox.charting,
-		d = dojo;
-	
-	dojo.declare("dojox.charting.widget.Chart2D", dijit._Widget, {
-		// parameters for the markup
-		
-		// theme for the chart
-		theme: null,
-		
-		// margins for the chart: {l: 10, r: 10, t: 10, b: 10}
-		margins: null,
-		
-		// chart area
-		stroke: null,
-		fill:   null,
-		
-		// methods
-		
-		buildRendering: function(){
-			var n = this.domNode = this.srcNodeRef;
-			
-			// 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);
-			
-			// build the chart
-			n.innerHTML = "";
-			var c = this.chart = new dc.Chart2D(n, {
-				margins: this.margins, 
-				stroke:  this.stroke,
-				fill:    this.fill
-			});
-			
-			// add collected parameters
-			if(this.theme){
-				c.setTheme(this.theme);
-			}
-			axes.forEach(function(axis){
-				c.addAxis(axis.name, axis.kwArgs);
-			});
-			plots.forEach(function(plot){
-				c.addPlot(plot.name, plot.kwArgs);
-			});
-			
-			this.actions = actions.map(function(action){
-				return new action.action(c, action.plot, action.kwArgs)
-			});
-			
-			var render = df.foldl(series, function(render, series){
-				if(series.type == "data"){
-					c.addSeries(series.name, series.data, series.kwArgs);
-					render = true;
-				}else{
-					c.addSeries(series.name, [0], series.kwArgs);
-					var kw = {};
-					du.updateWithPattern(
-						kw, 
-						series.kwArgs, 
-						{
-							"query": "", 
-							"queryOptions": null, 
-							"start": 0, 
-							"count": 1 //, 
-							// "sort": []
-						}, 
-						true
-					);
-					if(series.kwArgs.sort){
-						// sort is a complex object type and doesn't survive coercian
-						kw.sort = dojo.clone(series.kwArgs.sort);
-					}
-					d.mixin(kw, {
-						onComplete: function(data){
-							var values;
-							if("valueFn" in series.kwArgs){
-								var fn = series.kwArgs.valueFn;
-								values = d.map(data, function(x){
-									return fn(series.data.getValue(x, series.field, 0));
-								});
-							}else{
-								values = d.map(data, function(x){
-									return series.data.getValue(x, series.field, 0);
-								});
-							}
-							c.addSeries(series.name, values, series.kwArgs).render();
-						}
-					});
-					series.data.fetch(kw);
-				}
-				return render;
-			}, false);
-			if(render){ c.render(); }
-		},
-		destroy: function(){
-			// summary: properly destroy the widget
-			this.chart.destroy();
-			this.inherited(arguments);
-		},
-		resize: function(box){
-			// summary: resize the widget
-			if(box.w > 0 && box.h > 0){
-				dojo.marginBox(this.domNode, box);
-				this.chart.resize();
-			}
-		}
-	});
-	
-	collectParams = function(node, type, kw){
-		var dp = eval("(" + type + ".prototype.defaultParams)");
-		var x, attr;
-		for(x in dp){
-			if(x in kw){ continue; }
-			attr = node.getAttribute(x);
-			kw[x] = du.coerceType(dp[x], attr == null || typeof attr == "undefined" ? dp[x] : attr);
-		}
-		var op = eval("(" + type + ".prototype.optionalParams)");
-		for(x in op){
-			if(x in kw){ continue; }
-			attr = node.getAttribute(x);
-			if(attr != null){
-				kw[x] = du.coerceType(op[x], attr);
-			}
-		}
-	};
-	
-	collectAxisParams = function(node){
-		var name = node.getAttribute("name"), type = node.getAttribute("type");
-		if(!name){ return null; }
-		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
-		if(type){
-			if(dc.axis2d[type]){
-				type = dojox._scopeName + ".charting.axis2d." + type;
-			}
-			var axis = eval("(" + type + ")");
-			if(axis){ kw.type = axis; } 
-		}else{
-			type = dojox._scopeName + ".charting.axis2d.Default";
-		}
-		collectParams(node, type, kw);
-		// compatibility conversions
-		if(kw.font || kw.fontColor){
-			if(!kw.tick){
-				kw.tick = {};
-			}
-			if(kw.font){
-				kw.tick.font = kw.font;
-			}
-			if(kw.fontColor){
-				kw.tick.fontColor = kw.fontColor;
-			}
-		}
-		return o;
-	};
-	
-	collectPlotParams = function(node){
-		// var name = d.attr(node, "name"), type = d.attr(node, "type");
-		var name = node.getAttribute("name"), type = node.getAttribute("type");
-		if(!name){ return null; }
-		var o = {name: name, kwArgs: {}}, kw = o.kwArgs;
-		if(type){
-			if(dc.plot2d[type]){
-				type = dojox._scopeName + ".charting.plot2d." + type;
-			}
-			var plot = eval("(" + type + ")");
-			if(plot){ kw.type = plot; } 
-		}else{
-			type = dojox._scopeName + ".charting.plot2d.Default";
-		}
-		collectParams(node, type, kw);
-		return o;
-	};
-	
-	collectActionParams = function(node){
-		// var plot = d.attr(node, "plot"), type = d.attr(node, "type");
-		var plot = node.getAttribute("plot"), type = node.getAttribute("type");
-		if(!plot){ plot = "default"; }
-		var o = {plot: plot, kwArgs: {}}, kw = o.kwArgs;
-		if(type){
-			if(dc.action2d[type]){
-				type = dojox._scopeName + ".charting.action2d." + type;
-			}
-			var action = eval("(" + type + ")");
-			if(!action){ return null; }
-			o.action = action;
-		}else{
-			return null;
-		}
-		collectParams(node, type, kw);
-		return o;
-	};
+// require Chart2D to get compatibility on chart type reference by name
+dojo.require("dojox.charting.Chart2D");
 
-	collectDataParams = function(node){
-		var ga = d.partial(d.attr, node);
-		var name = ga("name");
-		if(!name){ return null; }
-		var o = { name: name, kwArgs: {} }, kw = o.kwArgs, t;
-		t = ga("plot");
-		if(t != null){ kw.plot = t; }
-		t = ga("marker");
-		if(t != null){ kw.marker = t; }
-		t = ga("stroke");
-		if(t != null){ kw.stroke = eval("(" + t + ")"); }
-		t = ga("outline");
-		if(t != null){ kw.outline = eval("(" + t + ")"); }
-		t = ga("shadow");
-		if(t != null){ kw.shadow = eval("(" + t + ")"); }
-		t = ga("fill");
-		if(t != null){ kw.fill = eval("(" + t + ")"); }
-		t = ga("font");
-		if(t != null){ kw.font = t; }
-		t = ga("fontColor");
-		if(t != null){ kw.fontColor = eval("(" + t + ")"); }
-		t = ga("legend");
-		if(t != null){ kw.legend = t; }
-		t = ga("data");
-		if(t != null){
-			o.type = "data";
-			o.data = t ? dojo.map(String(t).split(','), Number) : [];
-			return o;
-		}
-		t = ga("array");
-		if(t != null){
-			o.type = "data";
-			o.data = eval("(" + t + ")");
-			return o;
-		}
-		t = ga("store");
-		if(t != null){
-			o.type = "store";
-			o.data = eval("(" + t + ")");
-			t = ga("field");
-			o.field = t != null ? t : "value";
-			t = ga("query");
-			if(!!t){ kw.query = t; }
-			t = ga("queryOptions");
-			if(!!t){ kw.queryOptions = eval("(" + t + ")"); }
-			t = ga("start");
-			if(!!t){ kw.start = Number(t); }
-			t = ga("count");
-			if(!!t){ kw.count = Number(t); }
-			t = ga("sort");
-			if(!!t){ kw.sort = eval("("+t+")"); }
-			t = ga("valueFn");
-			if(!!t){ kw.valueFn = df.lambda(t); }
-			return o;
-		}
-		return null;
-	};
-})();
+dojox.charting.widget.Chart2D =  dojox.charting.widget.Chart;
diff --git a/dojox/charting/widget/Legend.js b/dojox/charting/widget/Legend.js
index 0cff803..a947248 100644
--- a/dojox/charting/widget/Legend.js
+++ b/dojox/charting/widget/Legend.js
@@ -7,7 +7,7 @@ dojo.require("dojox.lang.functional.array");
 dojo.require("dojox.lang.functional.fold");
 
 dojo.declare("dojox.charting.widget.Legend", [dijit._Widget, dijit._Templated], {
-	// summary: A legend for a chart. A legend contains summary labels for 
+	// 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.
@@ -24,7 +24,7 @@ dojo.declare("dojox.charting.widget.Legend", [dijit._Widget, dijit._Templated],
 	horizontal: true,
 	swatchSize: 18,
 	
-	templateString: "<table dojoAttachPoint='legendNode' class='dojoxLegendNode'><tbody dojoAttachPoint='legendBody'></tbody></table>",
+	templateString: "<table dojoAttachPoint='legendNode' class='dojoxLegendNode' role='group' aria-label='chart legend'><tbody dojoAttachPoint='legendBody'></tbody></table>",
 	
 	legendNode: null,
 	legendBody: null,
@@ -68,8 +68,7 @@ dojo.declare("dojox.charting.widget.Legend", [dijit._Widget, dijit._Templated],
 		if(this.horizontal){
 			dojo.addClass(this.legendNode, "dojoxLegendHorizontal");
 			// make a container <tr>
-			this._tr = dojo.doc.createElement("tr");
-			this.legendBody.appendChild(this._tr);
+			this._tr = dojo.create("tr", null, this.legendBody);
 			this._inrow = 0;
 		}
 		
@@ -101,32 +100,31 @@ dojo.declare("dojox.charting.widget.Legend", [dijit._Widget, dijit._Templated],
 	},
 	_addLabel: function(dyn, label){
 		// create necessary elements
-		var icon = dojo.doc.createElement("td"),
-			text = dojo.doc.createElement("td"),
-			div  = dojo.doc.createElement("div");
-		dojo.addClass(icon, "dojoxLegendIcon");
+		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"
+				}
+			}, icon);
+		dojo.addClass(icon, "dojoxLegendIcon dijitInline");
 		dojo.addClass(text, "dojoxLegendText");
-		div.style.width  = this.swatchSize + "px";
-		div.style.height = this.swatchSize + "px";
-		icon.appendChild(div);
-		
 		// create a skeleton
 		if(this._tr){
 			// horizontal
-			this._tr.appendChild(icon);
-			this._tr.appendChild(text);
+			this._tr.appendChild(wrapper);
 			if(++this._inrow === this.horizontal){
 				// make a fresh container <tr>
-				this._tr = dojo.doc.createElement("tr");
-				this.legendBody.appendChild(this._tr);
+				this._tr = dojo.create("tr", null, this.legendBody);
 				this._inrow = 0;
 			}
 		}else{
 			// vertical
-			var tr = dojo.doc.createElement("tr");
-			this.legendBody.appendChild(tr);
-			tr.appendChild(icon);
-			tr.appendChild(text);
+			var tr = dojo.create("tr", null, this.legendBody);
+			tr.appendChild(wrapper);
 		}
 		
 		// populate the skeleton
diff --git a/dojox/charting/widget/SelectableLegend.js b/dojox/charting/widget/SelectableLegend.js
new file mode 100644
index 0000000..b3ed6c8
--- /dev/null
+++ b/dojox/charting/widget/SelectableLegend.js
@@ -0,0 +1,237 @@
+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], {
+		//	summary:
+		//		An enhanced chart legend supporting interactive events on data series
+		
+		//	theme component
+		outline:			false,	//	outline of vanished data series
+		transitionFill:		null,	//	fill of deselected data series
+		transitionStroke:	null,	//	stroke of deselected data series
+		
+		postCreate: function(){
+			this.legends = [];
+			this.legendAnim = {};
+			this.inherited(arguments);
+		},
+		refresh: function(){
+			this.legends = [];
+			this.inherited(arguments);
+			this._applyEvents();
+			new dojox.charting.widget._FocusManager(this);
+		},
+		_addLabel: function(dyn, label){
+			this.inherited(arguments);
+			//	create checkbox
+			var legendNodes = dojo.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");
+			// connect checkbox and existed label
+			var label = dojo.query("label", currentLegendNode)[0];
+			dojo.attr(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){
+				var targetData, shapes = [], plotName, seriesName;
+				if(this._isPie()){
+					targetData = this.chart.stack[0];
+					shapes.push(targetData.group.children[i]);
+					plotName = targetData.name;
+					seriesName = this.chart.series[0].name;
+				}else{
+					targetData = this.chart.series[i];
+					shapes = targetData.group.children;
+					plotName = targetData.plot;
+					seriesName = targetData.name;
+				}
+				var originalDyn = {
+					fills : df.map(shapes, "x.getFill()"),
+					strokes: df.map(shapes, "x.getStroke()")
+				};
+				//	toggle action
+				var legendCheckBox = dojo.query(".dijitCheckBox", legend)[0];
+				dojo.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],
+					iconShape = this._getFilledShape(this._surfaces[i].children);
+				dojo.forEach(["onmouseenter", "onmouseleave"], function(event){
+					dojo.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){
+				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({
+							shape: shape,
+							color: {
+								start: isOff ? endFill : startFill,
+								end: isOff ? startFill : endFill
+							}
+						}).play();
+					}else{
+						shape.setFill(isOff ? startFill : endFill);
+					}
+				}
+				if(startStroke && !this.outline){
+					shape.setStroke(isOff ? startStroke : endStroke);
+				}
+			}, this);
+		},
+		_highlight: function(e, iconShape, shapes, index, isOff, dyn, seriesName, plotName){
+			if(!isOff){
+				var anim = this._getAnim(plotName),
+					isPie = this._isPie(),
+					type = formatEventType(e.type);
+				//	highlight the label icon,
+				var label = {
+					shape: iconShape,
+					index: isPie ? "legend" + index : "legend",
+					run: {name: seriesName},
+					type: type
+				};
+				anim.process(label);
+				//	highlight the data items
+				dojo.forEach(shapes, function(shape, i){
+					shape.setFill(dyn.fills[i]);
+					var o = {
+						shape: shape,
+						index: isPie ? index : i,
+						run: {name: seriesName},
+						type: type
+					};
+					anim.duration = 100;
+					anim.process(o);
+				});
+			}
+		},
+		_getAnim: function(plotName){
+			if(!this.legendAnim[plotName]){
+				this.legendAnim[plotName] = new dojox.charting.action2d.Highlight(this.chart, plotName);
+			}
+			return this.legendAnim[plotName];
+		},
+		_getTransitionFill: function(plotName){
+			// Since series of stacked charts all start from the base line,
+			// fill the "front" series with plotarea color to make it disappear .
+			if(this.chart.stack[this.chart.plots[plotName]].declaredClass.indexOf("dojox.charting.plot2d.Stacked") != -1){
+				return this.chart.theme.plotarea.fill;
+			}
+			return null;
+		},
+		_getFilledShape: function(shapes){
+			//	summary:
+			//		Get filled shape in legend icon which would be highlighted when hovered
+			var i = 0;
+			while(shapes[i]){
+				if(shapes[i].getFill())return shapes[i];
+				i++;
+			}
+		},
+		_isPie: function(){
+			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();
+		}
+	});
+})();
diff --git a/dojox/charting/widget/Sparkline.js b/dojox/charting/widget/Sparkline.js
index 61e5253..3c6a335 100644
--- a/dojox/charting/widget/Sparkline.js
+++ b/dojox/charting/widget/Sparkline.js
@@ -1,7 +1,9 @@
 dojo.provide("dojox.charting.widget.Sparkline");
 
 dojo.require("dojox.charting.widget.Chart2D");
-dojo.require("dojox.charting.themes.ET.greys");
+dojo.require("dojox.charting.themes.GreySkies");
+
+dojo.require("dojox.charting.plot2d.Lines");
 
 (function(){
 
@@ -10,7 +12,7 @@ dojo.require("dojox.charting.themes.ET.greys");
 	dojo.declare("dojox.charting.widget.Sparkline",
 		dojox.charting.widget.Chart2D,
 		{
-			theme: dojox.charting.themes.ET.greys,
+			theme: dojox.charting.themes.GreySkies,
 			margins: { l: 0, r: 0, t: 0, b: 0 },
 			type: "Lines",
 			valueFn: "Number(x)",
diff --git a/dojox/collections/BinaryTree.js b/dojox/collections/BinaryTree.js
index 57215d2..72c660d 100644
--- a/dojox/collections/BinaryTree.js
+++ b/dojox/collections/BinaryTree.js
@@ -10,7 +10,7 @@ dojox.collections.BinaryTree=function(data){
 			var c=new node();
 			if(this.value.value){
 				c.value=this.value.clone();
-			}else{ 
+			}else{
 				c.value=this.value;
 			}
 			if(this.left!=null){
@@ -94,7 +94,7 @@ dojox.collections.BinaryTree=function(data){
 			root=n;
 		}else{
 			i=parent.compare(n);
-			if(i>0){ 
+			if(i>0){
 				parent.left=n;
 			}else{
 				parent.right=n;
@@ -133,14 +133,14 @@ dojox.collections.BinaryTree=function(data){
 		if(!current){ return; }
 		this.count--;
 		if(!current.right){
-			if(!parent){ 
+			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;
@@ -160,7 +160,7 @@ dojox.collections.BinaryTree=function(data){
 			lmParent.left=leftmost.right;
 			leftmost.left=current.left;
 			leftmost.right=current.right;
-			if(!parent){ 
+			if(!parent){
 				root=leftmost;
 			}else{
 				i=parent.compare(current);
diff --git a/dojox/collections/Dictionary.js b/dojox/collections/Dictionary.js
index 27deee6..801380e 100644
--- a/dojox/collections/Dictionary.js
+++ b/dojox/collections/Dictionary.js
@@ -68,15 +68,15 @@ dojox.collections.Dictionary=function(/* dojox.collections.Dictionary? */diction
 	this.getKeyList=function(){
 		//	summary
 		//	Returns an array of the keys in the dictionary.
-		return (this.getIterator()).map(function(entry){ 
-			return entry.key; 
+		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; 
+		return (this.getIterator()).map(function(entry){
+			return entry.value;
 		});	//	array
 	};
 	this.item=function(/* string */k){
diff --git a/dojox/collections/SortedList.js b/dojox/collections/SortedList.js
index 002eefb..0885204 100644
--- a/dojox/collections/SortedList.js
+++ b/dojox/collections/SortedList.js
@@ -59,7 +59,7 @@ dojox.collections.SortedList=function(/* object? */ dictionary){
 		var e=this.getIterator();
 		while (!e.atEnd()){
 			var item=e.get();
-			if(item.value==o){ 
+			if(item.value==o){
 				return true;	//	bool
 			}
 		}
diff --git a/dojox/collections/_base.js b/dojox/collections/_base.js
index 47e24ec..c93e758 100644
--- a/dojox/collections/_base.js
+++ b/dojox/collections/_base.js
@@ -5,11 +5,11 @@ dojox.collections.DictionaryEntry=function(/* string */k, /* object */v){
 	//	return an object of type dojox.collections.DictionaryEntry
 	this.key=k;
 	this.value=v;
-	this.valueOf=function(){ 
+	this.valueOf=function(){
 		return this.value; 	//	object
 	};
-	this.toString=function(){ 
-		return String(this.value);	//	string 
+	this.toString=function(){
+		return String(this.value);	//	string
 	};
 }
 
@@ -87,10 +87,10 @@ dojox.collections.DictionaryIterator=function(/* object */obj){
 		//	Functional iteration with optional scope.
 		return dojo.map(a, fn, scope);
 	};
-	this.reset=function() { 
+	this.reset=function() {
 		//	summary
 		//	reset the internal cursor.
-		position=0; 
+		position=0;
 		this.element=a[position];
 	};
 };
diff --git a/dojox/color/Colorspace.js b/dojox/color/Colorspace.js
index 1295013..3422140 100644
--- a/dojox/color/Colorspace.js
+++ b/dojox/color/Colorspace.js
@@ -202,7 +202,7 @@ dojox.color.Colorspace=new (function(){
 		}
 	};
 	var converters={
-		"CMY":{ 
+		"CMY":{
 			"CMYK":function(obj, kwArgs){ return dxc.fromCmy(obj).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromCmy(obj).toHsl(); },
 			"HSV":function(obj, kwArgs){ return dxc.fromCmy(obj).toHsv(); },
@@ -214,7 +214,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return dxc.fromCmy(obj).toXYZ(kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromCmy(obj).toXYZ(kwArgs)); }
 		},
-		"CMYK":{ 
+		"CMYK":{
 			"CMY":function(obj, kwArgs){ return dxc.fromCmyk(obj).toCmy(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromCmyk(obj).toHsl(); },
 			"HSV":function(obj, kwArgs){ return dxc.fromCmyk(obj).toHsv(); },
@@ -226,7 +226,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return dxc.fromCmyk(obj).toXYZ(kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromCmyk(obj).toXYZ(kwArgs)); }
 		},
-		"HSL":{ 
+		"HSL":{
 			"CMY":function(obj, kwArgs){ return dxc.fromHsl(obj).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromHsl(obj).toCmyk(); },
 			"HSV":function(obj, kwArgs){ return dxc.fromHsl(obj).toHsv(); },
@@ -238,7 +238,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return dxc.fromHsl(obj).toXYZ(kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromHsl(obj).toXYZ(kwArgs)); }
 		},
-		"HSV":{ 
+		"HSV":{
 			"CMY":function(obj, kwArgs){ return dxc.fromHsv(obj).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromHsv(obj).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromHsv(obj).toHsl(); },
@@ -250,7 +250,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return dxc.fromHsv(obj).toXYZ(kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromHsv(obj).toXYZ(kwArgs)); }
 		},
-		"Lab":{ 
+		"Lab":{
 			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](obj, kwArgs)).toHsl(); },
@@ -262,7 +262,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return cMaps["Lab"]["XYZ"](obj, kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Lab"]["XYZ"](obj, kwArgs), kwArgs); }
 		},
-		"LCHab":{ 
+		"LCHab":{
 			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs).toHsl(); },
@@ -274,7 +274,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj, kwArgs), kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Lab"]["XYZ"](cMaps["LCHab"]["Lab"](obj), kwArgs), kwArgs); }
 		},
-		"LCHuv":{ 
+		"LCHuv":{
 			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs).toHsl(); },
@@ -286,7 +286,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Luv"]["XYZ"](cMaps["LCHuv"]["Luv"](obj), kwArgs), kwArgs); }
 		},
-		"Luv":{ 
+		"Luv":{
 			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs).toHsl(); },
@@ -298,7 +298,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return cMaps["Luv"]["XYZ"](obj, kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](cMaps["Luv"]["XYZ"](obj, kwArgs), kwArgs); }
 		},
-		"RGB":{ 
+		"RGB":{
 			"CMY":function(obj, kwArgs){ return obj.toCmy(); },
 			"CMYK":function(obj, kwArgs){ return obj.toCmyk(); },
 			"HSL":function(obj, kwArgs){ return obj.toHsl(); },
@@ -310,7 +310,7 @@ dojox.color.Colorspace=new (function(){
 			"XYZ":function(obj, kwArgs){ return obj.toXYZ(kwArgs); },
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](obj.toXYZ(kwArgs), kwArgs); }
 		},
-		"XYZ":{ 
+		"XYZ":{
 			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(obj, kwArgs).toHsl(); },
@@ -323,7 +323,7 @@ dojox.color.Colorspace=new (function(){
 			"xyY":function(obj, kwArgs){ return cMaps["XYZ"]["xyY"](dxc.fromXYZ(obj, kwArgs), kwArgs); }
 		},
 		// TODO: revisit this. xyY represents a single color, not a spectrum of colors.
-		"xyY":{ 
+		"xyY":{
 			"CMY":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toCmy(); },
 			"CMYK":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toCmyk(); },
 			"HSL":function(obj, kwArgs){ return dxc.fromXYZ(cMaps["xyY"]["XYZ"](obj, kwArgs), kwArgs).toHsl(); },
@@ -346,7 +346,7 @@ dojox.color.Colorspace=new (function(){
 			t=wpMap[observer][wpName].t;
 		} else {
 			console.warn(
-				"dojox.color.Colorspace::whitepoint: either the observer or the whitepoint name was not found. ", 
+				"dojox.color.Colorspace::whitepoint: either the observer or the whitepoint name was not found. ",
 				observer, wpName
 			);
 		}
@@ -389,13 +389,13 @@ dojox.color.Colorspace=new (function(){
 		} else {
 			console.warn(
 				"dojox.color.Colorspace::primaries: the passed profile was not found.  ",
-				"Available profiles include: ", profiles, 
+				"Available profiles include: ", profiles,
 				".  The profile passed was ", kwArgs.profile
 			);
 		}
 		var primary={
 			name:kwArgs.profile,
-			gamma:m[0], whitepoint:m[1], 
+			gamma:m[0], whitepoint:m[1],
 			xr:m[2], yr:m[3], Yr:m[4],
 			xg:m[5], yg:m[6], Yg:m[7],
 			xb:m[8], yb:m[9], Yb:m[10]
@@ -406,8 +406,8 @@ dojox.color.Colorspace=new (function(){
 			var r=this.convert(
 				this.adapt({
 					color:this.convert({ x:xr, y:yr, Y:Yr }, "xyY", "XYZ"),
-					adaptor:kwArgs.adaptor, 
-					source:primary.whitepoint, 
+					adaptor:kwArgs.adaptor,
+					source:primary.whitepoint,
 					destination:kwArgs.whitepoint
 				}),
 				"XYZ",
@@ -416,8 +416,8 @@ dojox.color.Colorspace=new (function(){
 			var g=this.convert(
 				this.adapt({
 					color:this.convert({ x:xg, y:yg, Y:Yg }, "xyY", "XYZ"),
-					adaptor:kwArgs.adaptor, 
-					source:primary.whitepoint, 
+					adaptor:kwArgs.adaptor,
+					source:primary.whitepoint,
 					destination:kwArgs.whitepoint
 				}),
 				"XYZ",
@@ -426,8 +426,8 @@ dojox.color.Colorspace=new (function(){
 			var b=this.convert(
 				this.adapt({
 					color:this.convert({ x:xb, y:yb, Y:Yb }, "xyY", "XYZ"),
-					adaptor:kwArgs.adaptor, 
-					source:primary.whitepoint, 
+					adaptor:kwArgs.adaptor,
+					source:primary.whitepoint,
 					destination:kwArgs.whitepoint
 				}),
 				"XYZ",
@@ -481,21 +481,21 @@ dojox.color.Colorspace=new (function(){
 	};
 
 	this.matrix=function(/* String */to, /* Object */primary){
-		var wp=this.whitepoint(primary.whitepoint);
+		var p=primary, wp=this.whitepoint(p.whitepoint);
 		var Xr = p.xr/p.yr, Yr = 1, Zr = (1-p.xr-p.yr)/p.yr;
 		var Xg = p.xg/p.yg, Yg = 1, Zg = (1-p.xg-p.yg)/p.yg;
-		var Xb = p.xb/p.yb, Yb = 1, Zr = (1-p.xb-p.yb)/p.yb;
+		var Xb = p.xb/p.yb, Yb = 1, Zb = (1-p.xb-p.yb)/p.yb;
 
 		var m1 = [[ Xr, Yr, Zr ], [ Xg, Yg, Zg ], [ Xb, Yb, Zb ]];
 		var m2 = [[ wp.X, wp.Y, wp.Z ]];
-		var sm = dojox.math.matrix.multiply(m2, dojox.math.matrix.inverse(m1));
+		var sm = dxm.multiply(m2, dxm.inverse(m1));
 		var Sr = sm[0][0], Sg = sm[0][1], Sb = sm[0][2];
 		var result=[
 			[Sr*Xr, Sr*Yr, Sr*Zr],
 			[Sg*Xg, Sg*Yg, Sg*Zg],
 			[Sb*Xb, Sb*Yb, Sb*Zb]
 		];
-		if(to=="RGB"){ return dojox.math.inverse(result); }
+		if(to=="RGB"){ return dxm.inverse(result); }
 		return result;
 	};
 
@@ -508,7 +508,7 @@ dojox.color.Colorspace=new (function(){
 
 	this.convert=function(/* Object */color, /* string */from, /* string */to, /* Object? */kwArgs){
 		if(converters[from] && converters[from][to]){
-			return converters[from][to](obj, kwArgs);
+			return converters[from][to](color, kwArgs);
 		}
 		console.warn("dojox.color.Colorspace::convert: Can't convert ", color, " from ", from, " to ", to, ".");
 	};
@@ -520,7 +520,7 @@ dojo.mixin(dojox.color, {
 		kwArgs=kwArgs||{};
 		var p=dojox.color.Colorspace.primaries(kwArgs);
 		var m=dojox.color.Colorspace.matrix("RGB", p);
-		var rgb=dojox.math.matrix.mutliply([[ xyz.X, xyz.Y, xyz.Z ]], m);
+		var rgb=dojox.math.matrix.multiply([[ xyz.X, xyz.Y, xyz.Z ]], m);
 		var r=rgb[0][0], g=rgb[0][1], b=rgb[0][2];
 		if(p.profile=="sRGB"){
 			var R = (r>0.0031308)?(1.055*Math.pow(r, 1/2.4))-0.055: 12.92*r;
diff --git a/dojox/color/Palette.js b/dojox/color/Palette.js
index 6aeb5c0..74a8697 100644
--- a/dojox/color/Palette.js
+++ b/dojox/color/Palette.js
@@ -80,7 +80,7 @@ dojo.require("dojox.color");
 		var ret = new dojox.color.Palette();
 		ret.colors = [];
 		dojo.forEach(p.colors, function(item){
-			var o=item.toCmy(), 
+			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;
@@ -97,7 +97,7 @@ dojo.require("dojox.color");
 		var ret = new dojox.color.Palette();
 		ret.colors = [];
 		dojo.forEach(p.colors, function(item){
-			var o=item.toCmyk(), 
+			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,
@@ -116,7 +116,7 @@ dojo.require("dojox.color");
 		var ret = new dojox.color.Palette();
 		ret.colors = [];
 		dojo.forEach(p.colors, function(item){
-			var o=item.toHsl(), 
+			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;
@@ -129,7 +129,7 @@ dojo.require("dojox.color");
 		var ret = new dojox.color.Palette();
 		ret.colors = [];
 		dojo.forEach(p.colors, function(item){
-			var o=item.toHsv(), 
+			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;
@@ -257,7 +257,7 @@ dojox.color.Palette.__generatorArgs = function(base){
 	//	base: dojo.Color
 	//		The base color to be used to generate the palette.
 	this.base = base;
-} 
+}
 dojox.color.Palette.__analogousArgs = function(base, high, low){
 	//	summary:
 	//		The keyword arguments object that is used to create a 5 color palette based on the
@@ -272,7 +272,7 @@ dojox.color.Palette.__analogousArgs = function(base, high, low){
 	this.base = base;
 	this.high = high;
 	this.low = low;
-} 
+}
 dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 	//	summary:
 	//		The keyword arguments object used to create a palette based on the split complementary rules
@@ -285,7 +285,7 @@ dojox.color.Palette.__splitComplementaryArgs = function(base, da){
 	//		In degrees, the default is 30.
 	this.base = base;
 	this.da = da;
-} 
+}
 =====*/
 	dojo.mixin(dxc.Palette, {
 		generators: {
diff --git a/dojox/cometd/HttpChannels.js b/dojox/cometd/HttpChannels.js
index 6724e3c..c350e2c 100644
--- a/dojox/cometd/HttpChannels.js
+++ b/dojox/cometd/HttpChannels.js
@@ -2,12 +2,12 @@ dojo.provide("dojox.cometd.HttpChannels");
  
 dojo.require("dojox.io.httpParse");
 dojo.require("dojox.cometd.RestChannels");
-// Note that cometd _base is _not_ required, this can run standalone, but ifyou want 
+// Note that cometd _base is _not_ required, this can run standalone, but ifyou want
 // cometd functionality, you must explicitly load/require it elsewhere, and cometd._base
 // MUST be loaded prior to HttpChannels ifyou use it.
 
 // summary:
-// 		HttpChannels - An HTTP Based approach to Comet transport with full HTTP messaging 
+// 		HttpChannels - An HTTP Based approach to Comet transport with full HTTP messaging
 // 		semantics including REST. HttpChannels is exactly the same as RestChannels, loading HttpChannels simply ensures that http parsing
 //		capabilities are present for application/http messages
 
@@ -19,7 +19,7 @@ dojo.require("dojox.cometd.RestChannels");
 // 		3. As a standalone transport. To use it as a standalone transport looks like this:
 // 	|		dojox.cometd.HttpChannels.open();
 // 	|		dojox.cometd.HttpChannels.get("/myResource",{callback:function(){
-// 	|			// this is called when the resource is first retrieved and any time the 
+// 	|			// this is called when the resource is first retrieved and any time the
 // 	|			// resource is changed in the future. This provides a means for retrieving a
 // 	|			// resource and subscribing to it in a single request
 // 	|		});
@@ -29,4 +29,4 @@ dojo.require("dojox.cometd.RestChannels");
 // 		Channels HTTP can be configured to a different delays:
 // 	|	dojox.cometd.HttpChannels.autoReconnectTime = 60000; // reconnect after one minute
 //
-dojox.cometd.HttpChannels = dojox.cometd.RestChannels;  
+dojox.cometd.HttpChannels = dojox.cometd.RestChannels;
diff --git a/dojox/cometd/RestChannels.js b/dojox/cometd/RestChannels.js
index f82d6a2..c3dcf94 100644
--- a/dojox/cometd/RestChannels.js
+++ b/dojox/cometd/RestChannels.js
@@ -3,12 +3,12 @@ dojo.provide("dojox.cometd.RestChannels");
 dojo.require("dojox.rpc.Client");
 dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener");
 
-// Note that cometd _base is _not_ required, this can run standalone, but ifyou want 
+// Note that cometd _base is _not_ required, this can run standalone, but ifyou want
 // cometd functionality, you must explicitly load/require it elsewhere, and cometd._base
 // MUST be loaded prior to RestChannels ifyou use it.
 
 // summary:
-// 		REST Channels - An HTTP/REST Based approach to Comet transport with full REST messaging 
+// 		REST Channels - An HTTP/REST Based approach to Comet transport with full REST messaging
 // 		semantics
 // 		REST Channels is a efficient, reliable duplex transport for Comet
 
@@ -20,7 +20,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 // 		3. As a standalone transport. To use it as a standalone transport looks like this:
 // 	|		dojox.cometd.RestChannels.open();
 // 	|		dojox.cometd.RestChannels.get("/myResource",{callback:function(){
-// 	|			// this is called when the resource is first retrieved and any time the 
+// 	|			// this is called when the resource is first retrieved and any time the
 // 	|			// resource is changed in the future. This provides a means for retrieving a
 // 	|			// resource and subscribing to it in a single request
 // 	|		});
@@ -49,10 +49,10 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 			// The *reloadDataOnReconnect* parameter:
 			// 		This indicates whether RestChannels should re-download data when a connection
 			// 		is restored (value of true), or if it should re-subscribe with retroactive subscriptions
-			// 		(Subscribe-Since header) using HEAD requests (value of false). The 
-			// 		default is true.	
+			// 		(Subscribe-Since header) using HEAD requests (value of false). The
+			// 		default is true.
 			dojo.mixin(this,options);
-			// If we have a Rest service available and we are auto subscribing, we will augment the Rest service 
+			// If we have a Rest service available and we are auto subscribing, we will augment the Rest service
 			if(dojox.rpc.Rest && this.autoSubscribeRoot){
 				// override the default Rest handler so we can add subscription requests
 				var defaultGet = dojox.rpc.Rest._get;
@@ -63,7 +63,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 					dojo.xhrGet = function(r){
 						var autoSubscribeRoot = self.autoSubscribeRoot;
 						return (autoSubscribeRoot && r.url.substring(0, autoSubscribeRoot.length) == autoSubscribeRoot) ?
-							self.get(r.url,r) : // auto-subscribe 
+							self.get(r.url,r) : // auto-subscribe
 							defaultXhrGet(r); // plain XHR request
 					};
 		
@@ -101,7 +101,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				headers[clientIdHeader] = this.connectionId;
 				var dfd = dojo.xhrPost({headers:headers, url: this.url, noStatus: true});
 		  		var self = this;
-		  		this.lastIndex = 0; 
+		  		this.lastIndex = 0;
 				var onerror, onprogress = function(data){ // get all the possible event handlers
 					if(typeof dojo == 'undefined'){
 						return null;// this can be called after dojo is unloaded, just do nothing in that case
@@ -155,7 +155,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 	  					if(typeof responseText=='string'){
 	  						onprogress(responseText);
 	  					}
-	  				} 
+	  				}
 			  	}
 			  	
 	  			 
@@ -186,20 +186,20 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				method = "POST";
 			}else{
 				args.postData = dojo.toJson(data);
-			}			
+			}
 			return dojo.xhr(method,args,args.postData);
-		}, 
+		},
 		subscribe: function(/*String*/channel, /*dojo.__XhrArgs?*/args){
 			// summary:
-			// 		Subscribes to a channel/uri, and returns a dojo.Deferred object for the response from 
+			// 		Subscribes to a channel/uri, and returns a dojo.Deferred object for the response from
 			// 		the subscription request
 			//
-			// channel: 
+			// channel:
 			// 		the uri for the resource you want to monitor
-			// 
-			// args: 
+			//
+			// args:
 			// 		See dojo.xhr
-			// 
+			//
 			// headers:
 			// 		These are the headers to be applied to the channel subscription request
 			//
@@ -213,12 +213,12 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 			// 		getAllResponseHeaders() : The response headers
 			// 		getResponseHeaders(headerName) : Retrieve a header by name
 			// 		responseText : The response body as text
-			// 			with the following additional Bayeux properties 
+			// 			with the following additional Bayeux properties
 			// 		data : The response body as JSON
 			// 		channel : The channel/url of the response
 			args = args || {};
 			args.url = this.absoluteUrl(this.url, channel);
-			if(args.headers){ 
+			if(args.headers){
 				// FIXME: combining Ranges with notifications is very complicated, we will save that for a future version
 				delete args.headers.Range;
 			}
@@ -234,7 +234,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 					oldCallback(m);
 					callback(m);
 				} : callback;
-			} 
+			}
 			if(!this.connected){
 				this.open();
 			}
@@ -248,7 +248,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				var dfd = this._send(method,args);
 				
 				var self = this;
-				dfd.addBoth(function(result){					
+				dfd.addBoth(function(result){
 					var xhr = dfd.ioArgs.xhr;
 					if(!(result instanceof Error)){
 						if(args.confirmation){
@@ -258,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){ 
+						if(xhr.responseText){
 							self.subscriptions[channel] = lastMod || new Date().toUTCString();
 						}else{
 							return null; // don't process the response, the response will be received in the main channels response
@@ -313,18 +313,18 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				message.result = message.result || dojo.fromJson(message.responseText);
 			}
 			catch(e){}
-			var self = this;	
+			var self = this;
 			var loc = message.channel = new dojo._Url(this.url, message.source || message.getResponseHeader('Content-Location'))+'';//for cometd
 			if(loc in this.subscriptions && message.getResponseHeader){
-				this.subscriptions[loc] = message.getResponseHeader('Last-Modified'); 
+				this.subscriptions[loc] = message.getResponseHeader('Last-Modified');
 			}
 			if(this.subCallbacks[loc]){
-				setTimeout(function(){ //give it it's own stack 
+				setTimeout(function(){ //give it it's own stack
 					self.subCallbacks[loc](message);
 				},0);
 			}
 			this.receive(message);
-			return null;		
+			return null;
 		},
 		onprogress: function(xhr,data,contentType){
 			// internal XHR progress handler
@@ -362,21 +362,21 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 				//no streaming and we didn't get any message, must be an error
 				return "error";
 			}
-			if(xhr.readyState != 4){ // we only want finished responses here if we are not streaming 
+			if(xhr.readyState != 4){ // we only want finished responses here if we are not streaming
 				return null;
 			}
 			if(xhr.__proto__){// firefox uses this property, so we create an instance to shadow this property
 				xhr = {channel:"channel",__proto__:xhr};
-			}			
+			}
 			return this._processMessage(xhr);
 		
 		},
 		
 		get: function(/*String*/channel, /*dojo.__XhrArgs?*/args){
 			// summary:
-			// 		GET the initial value of the resource and subscribe to it  
+			// 		GET the initial value of the resource and subscribe to it
 			//		See subscribe for parameter values
-			(args = args || {}).method = "GET"; 
+			(args = args || {}).method = "GET";
 			return this.subscribe(channel,args);
 		},
 		receive: function(message){
@@ -392,7 +392,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 			// summary:
 			// 		called when our channel gets disconnected
 			var self = this;
-			if(this.connected){ 
+			if(this.connected){
 				this.connected = false;
 				if(this.started){ // if we are started, we shall try to reconnect
 					setTimeout(function(){ // auto reconnect
@@ -415,27 +415,27 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 		},
 		unsubscribe: function(/*String*/channel, /*dojo.__XhrArgs?*/args){
 			// summary:
-			// 		unsubscribes from the resource  
-			//		See subscribe for parameter values 
+			// 		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 
+			this.subscribe(channel,args); // change the time frame to after 5000AD
 		},
 		disconnect: function(){
 			// summary:
-			// 		disconnect from the server  
+			// 		disconnect from the server
 			this.started = false;
 			this.xhr.abort();
 		}
 	});
 	var Channels = dojox.cometd.RestChannels.defaultInstance = new dojox.cometd.RestChannels();
-	if(dojox.cometd.connectionTypes){ 
+	if(dojox.cometd.connectionTypes){
 		// register as a dojox.cometd transport and wire everything for cometd handling
 		// below are the necessary adaptions for cometd
 		Channels.startup = function(data){ // must be able to handle objects or strings
 			Channels.open();
-			this._cometd._deliver({channel:"/meta/connect",successful:true}); // tell cometd we are connected so it can proceed to send subscriptions, even though we aren't yet 
+			this._cometd._deliver({channel:"/meta/connect",successful:true}); // tell cometd we are connected so it can proceed to send subscriptions, even though we aren't yet
 
 		};
 		Channels.check = function(types, version, xdomain){
@@ -446,7 +446,7 @@ dojo.requireIf(dojox.data && !!dojox.data.JsonRestStore,"dojox.data.restListener
 			}
 			return false;
 		};
-		Channels.deliver = function(message){ 
+		Channels.deliver = function(message){
 			// nothing to do
 		};
 		dojo.connect(this,"receive",null,function(message){
diff --git a/dojox/cometd/_base.js b/dojox/cometd/_base.js
index 0e4f300..7190c4b 100644
--- a/dojox/cometd/_base.js
+++ b/dojox/cometd/_base.js
@@ -12,9 +12,9 @@ dojo.require("dojo.AdapterRegistry");
  * extensions modules may be loaded (eg "dojox.cometd.timestamp", that use
  * the cometd._extendInList and cometd._extendOutList fields to provide functions
  * that extend and handling incoming and outgoing messages.
- * 
+ *
  * By default the long-polling and callback-polling transports will be required.
- * If specific or alternative transports are required, then they can be directly 
+ * If specific or alternative transports are required, then they can be directly
  * loaded. For example dojo.require('dojox.cometd.longPollTransportJsonEncoded')
  * will load cometd with only the json encoded variant of the long polling transport.
  */
@@ -23,7 +23,7 @@ dojox.cometd = {
 	Connection: function(prefix){ // This constructor is stored as dojox.cometd.Connection
 		// summary
 		// This constructor is used to create new cometd connections. Generally, you should use
-		// one cometd connection for each server you connect to. A default connection instance is 
+		// one cometd connection for each server you connect to. A default connection instance is
 		// created at dojox.cometd.
 		// To connect to a new server you can create an instance like:
 		// var cometd = new dojox.cometd.Connection("/otherServer");
@@ -84,8 +84,8 @@ dojox.cometd = {
 			//		until a handshake response is received and the first successful connect message
 			//		has returned.
 			//		The protocol state changes may be monitored
-			//		by subscribing to the dojo topic "/prefix/meta" (typically "/cometd/meta") where 
-			//		events are published in the form 
+			//		by subscribing to the dojo topic "/prefix/meta" (typically "/cometd/meta") where
+			//		events are published in the form
 			//		   {cometd:this,action:"handshake",successful:true,state:this.state()}
 			//	root:
 			//		The URL of the cometd server. If the root is absolute, the host
@@ -218,7 +218,7 @@ dojox.cometd = {
 			//		passing to `dojox.cometd.unsubscribe()` as a "subscription
 			//		handle" (much like the handle object that `dojo.connect()`
 			//		produces and which `dojo.disconnect()` expects).
-			//		
+			//
 			//		Note that of a subscription is registered before a connection
 			//		with the server is established, events sent before the
 			//		connection is established will not be delivered to this client.
@@ -281,9 +281,9 @@ dojox.cometd = {
 				}
 				
 				var topic = dojo.subscribe(tname, objOrFunc, funcName);
-				subs.push({ 
-					topic: topic, 
-					objOrFunc: objOrFunc, 
+				subs.push({
+					topic: topic,
+					objOrFunc: objOrFunc,
 					funcName: funcName
 				});
 				this._subscriptions[tname] = subs;
@@ -449,7 +449,7 @@ dojox.cometd = {
 
 
 			var wasHandshook = this._handshook;
-			var successful = false;	
+			var successful = false;
 			var metaMsg = {};
 
 			if (data instanceof Error) {
@@ -478,10 +478,10 @@ dojox.cometd = {
 					this._advice.reconnect="none";
 				}
 				dojo.mixin(metaMsg,{reestablish: successful && wasHandshook, response:data});
-			} 
+			}
 
 			this._publishMeta("handshake",successful,metaMsg);
-			//in the meta listeners, disconnect() may have been called, so recheck it now to 
+			//in the meta listeners, disconnect() may have been called, so recheck it now to
 			//prevent resends or continuing with initializing the protocol
 			if(this._status!="handshaking") {return;}
 
@@ -693,7 +693,7 @@ dojox.cometd = {
 }
 
 // create the default instance
-dojox.cometd.Connection.call(dojox.cometd,"/cometd"); 
+dojox.cometd.Connection.call(dojox.cometd,"/cometd");
 
 /*
 
diff --git a/dojox/cometd/ack.js b/dojox/cometd/ack.js
index 8c37156..4decdf3 100644
--- a/dojox/cometd/ack.js
+++ b/dojox/cometd/ack.js
@@ -9,7 +9,7 @@ dojo.require("dojox.cometd._base");
  * messages.
  *
  * To use, add dojo.require("dojox.cometd.ack"); and if the handshake will be sent
- * with ext:{ack:true}.  If the server supports the same extension, then the 
+ * with ext:{ack:true}.  If the server supports the same extension, then the
  * mechanism will be initialized.  The dojox.cometd.ackEnabled field may also be
  * used to optionally enable/disable the extension before init of cometd.
  *
@@ -31,13 +31,13 @@ dojox.cometd._ack = new function(){
 	this._out = function(msg){
 	
 		if (msg.channel == "/meta/handshake") {
-			if (!msg.ext) 
+			if (!msg.ext)
 				msg.ext = {};
 			msg.ext.ack = dojox.cometd.ackEnabled;
 			lastAck = -1;
 		}
 		if (supportAcks && msg.channel == "/meta/connect") {
-			if (!msg.ext) 
+			if (!msg.ext)
 				msg.ext = {};
 			msg.ext.ack = lastAck;
 		}
diff --git a/dojox/cometd/callbackPollTransport.js b/dojox/cometd/callbackPollTransport.js
index 2def71f..e9baf9c 100644
--- a/dojox/cometd/callbackPollTransport.js
+++ b/dojox/cometd/callbackPollTransport.js
@@ -20,7 +20,7 @@ dojox.cometd.callbackPollTransport = new function(){
 			connectionType: this._connectionType,
 			id:	"" + this._cometd.messageId++
 		};
-		message = this._cometd._extendOut(message);		
+		message = this._cometd._extendOut(message);
 		this.openTunnelWith([message]);
 	}
 
@@ -80,14 +80,14 @@ dojox.cometd.callbackPollTransport = new function(){
 	}
 
 	// FIXME: what is this supposed to do? ;)
-	this.disconnect = dojox.cometd.longPollTransport.disconnect;	
+	this.disconnect = dojox.cometd.longPollTransport.disconnect;
 	this.disconnect = function(){
 		var message = {
 			channel: "/meta/disconnect",
 			clientId: this._cometd.clientId,
 			id: "" + this._cometd.messageId++
 		};
-		message = this._cometd._extendOut(message);		
+		message = this._cometd._extendOut(message);
 		dojo.io.script.get({
 			url: this._cometd.url || dojo.config["cometdRoot"],
 			callbackParamName: "jsonp",
diff --git a/dojox/cometd/longPollTransportFormEncoded.js b/dojox/cometd/longPollTransportFormEncoded.js
index 14af240..ca0b640 100644
--- a/dojox/cometd/longPollTransportFormEncoded.js
+++ b/dojox/cometd/longPollTransportFormEncoded.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.cometd.longPollTransportFormEncoded");
 dojo.require("dojox.cometd._base");
 
 dojox.cometd.longPollTransportFormEncoded = new function(){
-	// This is an alternative implementation to that provided in logPollTransport.js that 
+	// This is an alternative implementation to that provided in logPollTransport.js that
 	// form encodes all messages instead of sending them as text/json
 	
 	this._connectionType = "long-polling";
@@ -56,7 +56,7 @@ dojox.cometd.longPollTransportFormEncoded = new function(){
 				id:	"" + this._cometd.messageId++
 			};
 			if(this._cometd.connectTimeout>=this._cometd.expectedNetworkDelay){
-				message.advice = { 
+				message.advice = {
 					timeout: this._cometd.connectTimeout - this._cometd.expectedNetworkDelay
 				};
 			}
diff --git a/dojox/cometd/longPollTransportJsonEncoded.js b/dojox/cometd/longPollTransportJsonEncoded.js
index 6859480..b343c63 100644
--- a/dojox/cometd/longPollTransportJsonEncoded.js
+++ b/dojox/cometd/longPollTransportJsonEncoded.js
@@ -2,8 +2,8 @@ dojo.provide("dojox.cometd.longPollTransportJsonEncoded");
 dojo.require("dojox.cometd._base");
 
 dojox.cometd.longPollTransportJsonEncoded = new function(){
-	// This is an alternative implementation to that provided in logPollTransportFormEncoded.js 
-	// that sends messages as text/json rather than form encoding them. 
+	// This is an alternative implementation to that provided in logPollTransportFormEncoded.js
+	// that sends messages as text/json rather than form encoding them.
 	
 	this._connectionType="long-polling";
 	this._cometd=null;
diff --git a/dojox/cometd/tests/_base.js b/dojox/cometd/tests/_base.js
index 1d836c7..ec33443 100644
--- a/dojox/cometd/tests/_base.js
+++ b/dojox/cometd/tests/_base.js
@@ -20,7 +20,7 @@ tests.register("dojox.cometd.tests._base", [
 		dojox.cometd.subscribe("/basic/unit/test", function(e){
 			console.log("message received", e);
 		});
-		t.assertTrue(true);		
+		t.assertTrue(true);
 	},
 
 	function basicPublishCheck(t){
diff --git a/dojox/cometd/timesync.js b/dojox/cometd/timesync.js
index d7e9b32..99a3cbb 100644
--- a/dojox/cometd/timesync.js
+++ b/dojox/cometd/timesync.js
@@ -3,11 +3,11 @@ dojo.require("dojox.cometd._base");
 
 /**
  * this file provides the time synchronization extension to cometd.
- * Timesync allows the client and server to exchange time information on every 
+ * Timesync allows the client and server to exchange time information on every
  * handshake and connect message so that the client may calculate an approximate
  * offset from it's own clock epoch to that of the server.
  *
- * With each handshake or connect, the extension sends timestamps within the 
+ * With each handshake or connect, the extension sends timestamps within the
  * ext field like: <code>{ext:{timesync:{tc:12345567890,l:23,o:4567},...},...}</code>
  * where:<ul>
  *  <li>tc is the client timestamp in ms since 1970 of when the message was sent.
@@ -27,10 +27,10 @@ dojo.require("dojox.cometd._base");
  *  <li>p is the poll duration in ms - ie the time the server took before sending the response.
  *  <li>a is the measured accuracy of the calculated offset and lag sent by the client
  * </ul>
- * 
+ *
  * On receipt of the response, the client is able to use current time to determine
  * the total trip time, from which p is subtracted to determine an approximate
- * two way network traversal time. The measured accuracy is used to adjust the assumption 
+ * two way network traversal time. The measured accuracy is used to adjust the assumption
  * that the network is symmetric for traversal time, so: <ul>
  * <li>lag = (now-tc-p)/2-a
  * <li>offset = ts-tc-lag
@@ -45,20 +45,20 @@ dojox.cometd.timesync = new function(){
 	this._lags = [];		// The samples used to calculate the average lag.
 	this._offsets = [];		// The samples used to calculate the average offset.
 	this.lag=0;				// The calculated network lag from client to server
-	this.offset = 0;		// The offset in ms between the clients clock and the servers clock. 
+	this.offset = 0;		// The offset in ms between the clients clock and the servers clock.
 	this.samples = 0; 		// The number of samples used to calculate the offset. If 0, the offset is not valid.
 	
 	this.getServerTime = function(){ // return: long
 		// Summary:
 		//	Calculate the current time on the server
-		// 
+		//
 		return new Date().getTime()+this.offset;
 	}
 	
 	this.getServerDate = function(){ // return: Date
 		// Summary:
 		//	Calculate the current time on the server
-		// 
+		//
 		return new Date(this.getServerTime());
 	}
 	
@@ -67,7 +67,7 @@ dojox.cometd.timesync = new function(){
 		//	Set a timeout function relative to server time
 		// call:
 		//	the function to call when the timeout occurs
-		// atTimeOrTime: 
+		// atTimeOrTime:
 		//	a long timestamp or a Date representing the server time at
 		//	which the timeout should occur.
 		
@@ -85,7 +85,7 @@ dojox.cometd.timesync = new function(){
 		//	Handle incoming messages for the timesync extension.
 		// description:
 		//	Look for ext:{timesync:{}} field and calculate offset if present.
-		// msg: 
+		// msg:
 		//	The incoming bayeux message
 		
 		var channel = msg.channel;
@@ -122,7 +122,7 @@ dojox.cometd.timesync = new function(){
 		//	Handle outgoing messages for the timesync extension.
 		// description:
 		//	Look for handshake and connect messages and add the ext:{timesync:{}} fields
-		// msg: 
+		// msg:
 		//	The outgoing bayeux message
 		
 		var channel = msg.channel;
diff --git a/dojox/css3/fx.js b/dojox/css3/fx.js
index e69cfbe..a128ee9 100644
--- a/dojox/css3/fx.js
+++ b/dojox/css3/fx.js
@@ -76,7 +76,7 @@ dojo.mixin(dojox.css3.fx, {
 		//	|	// half flip
 		//	|	dojox.css3.fx.flip({
 		//	|		node: domNode,
-		//	|		whichAnim: [0, 1] 
+		//	|		whichAnim: [0, 1]
 		//	|	}).play();
 		//
 		var anims = [],
diff --git a/dojox/data/AndOrReadStore.js b/dojox/data/AndOrReadStore.js
index 8dbe397..f955fb1 100755
--- a/dojox/data/AndOrReadStore.js
+++ b/dojox/data/AndOrReadStore.js
@@ -1,14 +1,10 @@
-dojo.provide("dojox.data.AndOrReadStore");
-
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.date.stamp");
+define("dojox/data/AndOrReadStore", ["dojo", "dojox", "dojo/data/util/filter", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo, dojox) {
 
 dojo.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*)"
-	//		Includes legacy/widget support via:  
+	//		Includes legacy/widget support via:
 	//			query:{complexQuery:"id:1* OR dept:'Sales Department' || (id:2* && NOT dept:S*)"}
 	//		The ItemFileReadStore implements the dojo.data.api.Read API and reads
 	//		data from JSON files that have contents in this format --
@@ -17,7 +13,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	//			{ name:'Fozzie Bear', wears:['hat', 'tie']},
 	//			{ name:'Miss Piggy', pets:'Foo-Foo'}
 	//		]}
-	//		Note that it can also contain an 'identifer' property that specified which attribute on the items 
+	//		Note that it can also contain an 'identifer' property that specified which attribute on the items
 	//		in the array of items that acts as the unique identifier for that item.
 	//
 	constructor: function(/* Object */ keywordParameters){
@@ -32,7 +28,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		//			...
 		//			typeN: function || object
 		//		}
-		//		Where if it is a function, it is assumed to be an object constructor that takes the 
+		//		Where if it is a function, it is assumed to be an object constructor that takes the
 		//		value of _value as the initialization parameters.  If it is an object, then it is assumed
 		//		to be an object of general form:
 		//		{
@@ -96,24 +92,24 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	//all item handles will become invalid and a new fetch must be issued.
 	clearOnClose: false,
 
-	//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.  
+	//Parameter to allow specifying if preventCache should be passed to the xhrGet call or not when loading data from a url.
 	//Note this does not mean the store calls the server on each fetch, only that the data load has preventCache set as an option.
 	//Added for tracker: #6072
 	urlPreventCache: false,
 
-	//Parameter to indicate to process data from the url as hierarchical 
-	//(data items can contain other data items in js form).  Default is true 
-	//for backwards compatibility.  False means only root items are processed 
-	//as items, all child objects outside of type-mapped objects and those in 
+	//Parameter to indicate to process data from the url as hierarchical
+	//(data items can contain other data items in js form).  Default is true
+	//for backwards compatibility.  False means only root items are processed
+	//as items, all child objects outside of type-mapped objects and those in
 	//specific reference format, are left straight JS data objects.
 	hierarchical: true,
 
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojox.data.AndOrReadStore: Invalid item argument.");
 		}
 	},
@@ -121,25 +117,25 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		//	summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.AndOrReadStore: Invalid attribute argument.");
 		}
 	},
 
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		return (values.length > 0)?values[0]:defaultValue; // mixed
 	},
 
-	getValues: function(/* item */ item, 
+	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 
 		this._assertIsItem(item);
@@ -150,7 +146,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -165,17 +161,17 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
 		return (attribute in item);
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -184,22 +180,22 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -216,7 +212,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		if(something && something[this._storeRefPropName] === this){
 			if(this._arrayOfAllItems[something[this._itemNumPropName]] === something){
@@ -227,25 +223,25 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return this._features; //Object
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this._labelAttr && this.isItem(item)){
 			return this.getValue(item,this._labelAttr); //String
@@ -254,7 +250,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		if(this._labelAttr){
 			return [this._labelAttr]; //array
@@ -262,15 +258,15 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		return null; //null
 	},
 
-	_fetchItems: function(	/* Object */ keywordArgs, 
-							/* Function */ findCallback, 
+	_fetchItems: function(	/* Object */ keywordArgs,
+							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		//		filter modified to permit complex queries where
-		//			logical operators are case insensitive:  
+		//			logical operators are case insensitive:
 		//			, NOT AND OR ( ) ! && ||
-		//			Note:  "," included for quoted/string legacy queries. 
+		//			Note:  "," included for quoted/string legacy queries.
 		var self = this;
 		var filter = function(requestArgs, arrayOfItems){
 			var items = [];
@@ -291,7 +287,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 						var cq = query.complexQuery;
 						var wrapped = false;
 						for(p in query){
-							if(p !== "complexQuery"){ 
+							if(p !== "complexQuery"){
 								//We should wrap this in () as it should and with the entire complex query
 								//Not just part of it.
 								if(!wrapped){
@@ -312,11 +308,11 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 					}
 				}
 
-				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; 
+				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
 				//for complex queries only:  pattern = query[:|=]"NOT id:23* AND (type:'test*' OR dept:'bob') && !filed:true"
 				//logical operators are case insensitive:  , NOT AND OR ( ) ! && ||  // "," included for quoted/string legacy queries.
 				if(typeof query != "string"){
-					query = dojo.toJson(query);	
+					query = dojo.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.
@@ -334,8 +330,8 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 						if(pos1 === 0 && pos2 != -1 && colon < pos2){
 							flag = true;
 							break;
-						} //first two sets of quotes don't occur before the first colon.	
-					}	
+						} //first two sets of quotes don't occur before the first colon.
+					}
 					if(flag){	//dojo.toJson, and maybe user, adds surrounding quotes, which we need to remove.
 						complexQuery = complexQuery.replace(/^\"|^\'|\"$|\'$/g,"");
 					}
@@ -371,7 +367,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 								complexQuery = dojo.trim(complexQuery.replace(op[0],""));
 								op = dojo.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 == "NOT" ? "!" : op == "AND" || op == "," ? "&&" : op == "OR" ? "||" : op;
 								op = " " + op + " ";
 								sQuery += op;
 								op = complexQuery.match(begRegExp);
@@ -394,7 +390,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 										if(pos2 == -1){
 											err = true;
 											break;
-										}	
+										}
 										value = complexQuery.substring(pos + 1,pos2);
 										if(pos2 == complexQuery.length - 1){ //quote is last character
 											complexQuery = "";
@@ -407,13 +403,13 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 										tok = complexQuery.match(/\s|\)|,/);
 										if(tok){
 											var pos3 = new Array(tok.length);
-											for(var j = 0;j<tok.length;j++){ 
+											for(var j = 0;j<tok.length;j++){
 												pos3[j] = complexQuery.indexOf(tok[j]);
 											}
 											pos = pos3[0];
 											if(pos3.length > 1){
 												for(var j=1;j<pos3.length;j++){
-													pos = Math.min(pos,pos3[j]);													
+													pos = Math.min(pos,pos3[j]);
 												}
 											}
 											value = dojo.trim(complexQuery.substring(0,pos));
@@ -441,8 +437,8 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				findCallback(items, requestArgs);
 			}else{
 				// No query...
-				// We want a copy to pass back in case the parent wishes to sort the array. 
-				// We shouldn't allow resort of the internal list, so that multiple callers 
+				// We want a copy to pass back in case the parent wishes to sort the array.
+				// We shouldn't allow resort of the internal list, so that multiple callers
 				// can get lists and sort without affecting each other.  We also need to
 				// filter out any null values that have been left as a result of deleteItem()
 				// calls in ItemFileWriteStore.
@@ -460,7 +456,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			filter(keywordArgs, this._getItemsArray(keywordArgs.queryOptions));
 		}else{
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojox.data.AndOrReadStore: ", 
+				dojo.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;
@@ -476,14 +472,14 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			}
 			if(this._jsonFileUrl){
 				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be 
+				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
 					this._queuedFetches.push({args: keywordArgs, filter: filter});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self._jsonFileUrl, 
+							url: self._jsonFileUrl,
 							handleAs: "json-comment-optional",
 							preventCache: this.urlPreventCache
 						};
@@ -542,7 +538,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	}, //end _fetchItems
 
 	_handleQueuedFetches: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function to execute delayed request in the store.
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
@@ -551,7 +547,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				var delayedQuery = fData.args;
 				var delayedFilter = fData.filter;
 				if(delayedFilter){
-					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions)); 
+					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
 				}else{
 					this.fetchItemByIdentity(delayedQuery);
 				}
@@ -561,31 +557,31 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	_getItemsArray: function(/*object?*/queryOptions){
-		//	summary: 
+		//	summary:
 		//		Internal function to determine which list of items to search over.
 		//	queryOptions: The query options parameter, if any.
 		if(queryOptions && queryOptions.deep){
-			return this._arrayOfAllItems; 
+			return this._arrayOfAllItems;
 		}
 		return this._arrayOfTopLevelItems;
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.close()
 		if(this.clearOnClose &&
 			this._loadFinished &&
 			!this._loadInProgress){
 			 //Reset all internalsback to default state.  This will force a reload
-			 //on next fetch.  This also checks that the data or url param was set 
+			 //on next fetch.  This also checks that the data or url param was set
 			 //so that the store knows it can get data.  Without one of those being set,
 			 //the next fetch will trigger an error.
 
-			 if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) && 
+			 if(((this._jsonFileUrl == "" || this._jsonFileUrl == null) &&
 				 (this.url == "" || this.url == null)
 				) && this.data == null){
 				 console.debug("dojox.data.AndOrReadStore: WARNING!  Data reload " +
-					" information has not been provided." + 
+					" information has not been provided." +
 					"  Please set 'url' or 'data' to the appropriate value before" +
 					" the next fetch");
 			 }
@@ -633,8 +629,8 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				(!dojo.isArray(aValue)) &&
 				(!dojo.isFunction(aValue)) &&
 				(aValue.constructor == Object) &&
-				(typeof aValue._reference === "undefined") && 
-				(typeof aValue._type === "undefined") && 
+				(typeof aValue._reference === "undefined") &&
+				(typeof aValue._type === "undefined") &&
 				(typeof aValue._value === "undefined") &&
 				self.hierarchical
 			);
@@ -681,13 +677,13 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			item[this._rootItemPropName]=true;
 		}
 
-		// Step 2: Walk through all the attribute values of all the items, 
+		// Step 2: Walk through all the attribute values of all the items,
 		// and replace single values with arrays.  For example, we change this:
 		//		{ name:'Miss Piggy', pets:'Foo-Foo'}
 		// into this:
 		//		{ name:['Miss Piggy'], pets:['Foo-Foo']}
-		// 
-		// We also store the attribute names so we can validate our store  
+		//
+		// We also store the attribute names so we can validate our store
 		// reference and item id special properties for the O(1) isItem
 		var allAttributeNames = {};
 		var key;
@@ -721,9 +717,9 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			this._reverseRefMap += "_";
 		}
 
-		// Step 4: Some data files specify an optional 'identifier', which is 
-		// the name of an attribute that holds the identity of each item. 
-		// If this data file specified an identifier attribute, then build a 
+		// Step 4: Some data files specify an optional 'identifier', which is
+		// the name of an attribute that holds the identity of each item.
+		// If this data file specified an identifier attribute, then build a
 		// hash table of items keyed by the identity of the items.
 		var arrayOfValues;
 
@@ -749,7 +745,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			this._features['dojo.data.api.Identity'] = Number;
 		}
 
-		// Step 5: Walk through all the items, and set each item's properties 
+		// Step 5: Walk through all the items, and set each item's properties
 		// for _storeRefPropName and _itemNumPropName, so that store.isItem() will return true.
 		for(i = 0; i < this._arrayOfAllItems.length; ++i){
 			item = this._arrayOfAllItems[i];
@@ -763,13 +759,13 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		// We replace item-references with pointers to items.  For example, we change:
 		//		{ name:['Kermit'], friends:[{_reference:{name:'Miss Piggy'}}] }
 		// into this:
-		//		{ name:['Kermit'], friends:[miss_piggy] } 
+		//		{ name:['Kermit'], friends:[miss_piggy] }
 		// (where miss_piggy is the object representing the 'Miss Piggy' item).
 		//
 		// We replace type/value pairs with typed-literals.  For example, we change:
 		//		{ name:['Nelson Mandela'], born:[{_type:'Date', _value:'July 18, 1918'}] }
 		// into this:
-		//		{ name:['Kermit'], born:(new Date('July 18, 1918')) } 
+		//		{ name:['Kermit'], born:(new Date('July 18, 1918')) }
 		//
 		// We also generate the associate map for all items for the O(1) isItem function.
 		for(i = 0; i < this._arrayOfAllItems.length; ++i){
@@ -782,7 +778,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 						if(("_type" in value) && ("_value" in value)){
 							var type = value._type; // examples: 'Date', 'Color', or 'ComplexNumber'
 							var mappingObj = this._datatypeMap[type]; // examples: Date, dojo.Color, foo.math.ComplexNumber, {type: dojo.Color, deserialize(value){ return new dojo.Color(value)}}
-							if(!mappingObj){ 
+							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)){
 								arrayOfValues[j] = new mappingObj(value._value);
@@ -805,12 +801,12 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 									var candidateItem = this._arrayOfAllItems[k];
 									var found = true;
 									for(var refKey in referenceDescription){
-										if(candidateItem[refKey] != referenceDescription[refKey]){ 
-											found = false; 
+										if(candidateItem[refKey] != referenceDescription[refKey]){
+											found = false;
 										}
 									}
-									if(found){ 
-										arrayOfValues[j] = candidateItem; 
+									if(found){
+										arrayOfValues[j] = candidateItem;
 									}
 								}
 							}
@@ -821,7 +817,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 								}
 							}
 						}else if(this.isItem(value)){
-							//It's a child item (not one referenced through _reference).  
+							//It's a child item (not one referenced through _reference).
 							//We need to treat this as a referenced item, so it can be cleaned up
 							//in a write store easily.
 							if(this.referenceIntegrity){
@@ -850,7 +846,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		var identifier = this._features['dojo.data.api.Identity'];
 		if(identifier === Number){
@@ -865,14 +861,14 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 
 		// Hasn't loaded yet, we have to trigger the load.
 		if(!this._loadFinished){
 			var self = this;
 			if(this._jsonFileUrl !== this._ccUrl){
-				dojo.deprecated("dojox.data.AndOrReadStore: ", 
+				dojo.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,7 +889,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self._jsonFileUrl, 
+							url: self._jsonFileUrl,
 							handleAs: "json-comment-optional",
 							preventCache: this.urlPreventCache
 					};
@@ -935,7 +931,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 					var scope = keywordArgs.scope?keywordArgs.scope:dojo.global;
 					keywordArgs.onItem.call(scope, item);
 				}
-			} 
+			}
 		}else{
 			// Already loaded.  We can just look it up and call back.
 			var item = this._getItemByIdentity(keywordArgs.identity);
@@ -962,15 +958,15 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentifierAttributes()
 		 
 		var identifier = this._features['dojo.data.api.Identity'];
 		if(identifier === Number){
 			// If (identifier === Number) it means getIdentity() just returns
 			// an integer item-number for each item.  The dojo.data.api.Identity
-			// spec says we need to return null if the identity is not composed 
-			// of attributes 
+			// spec says we need to return null if the identity is not composed
+			// of attributes
 			return null; // null
 		}else{
 			return [identifier]; // Array
@@ -978,12 +974,12 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 	},
 	
 	_forceLoad: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function to force a load of the store if it hasn't occurred yet.  This is required
-		//		for specific functions to work properly.  
+		//		for specific functions to work properly.
 		var self = this;
 		if(this._jsonFileUrl !== this._ccUrl){
-			dojo.deprecated("dojox.data.AndOrReadStore: ", 
+			dojo.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;
@@ -999,7 +995,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 		}
 		if(this._jsonFileUrl){
 				var getArgs = {
-					url: self._jsonFileUrl, 
+					url: self._jsonFileUrl,
 					handleAs: "json-comment-optional",
 					preventCache: this.urlPreventCache,
 					sync: true
@@ -1007,7 +1003,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			var getHandler = dojo.xhrGet(getArgs);
 			getHandler.addCallback(function(data){
 				try{
-					//Check to be sure there wasn't another load going on concurrently 
+					//Check to be sure there wasn't another load going on concurrently
 					//So we don't clobber data that comes in on it.  If there is a load going on
 					//then do not save this data.  It will potentially clobber current data.
 					//We mainly wanted to sync/wait here.
@@ -1020,7 +1016,7 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 						//Okay, we hit an error state we can't recover from.  A forced load occurred
 						//while an async load was occurring.  Since we cannot block at this point, the best
 						//that can be managed is to throw an error.
-						throw new Error("dojox.data.AndOrReadStore:  Unable to perform a synchronous load, an async load is in progress."); 
+						throw new Error("dojox.data.AndOrReadStore:  Unable to perform a synchronous load, an async load is in progress.");
 					}
 				}catch(e){
 					console.log(e);
@@ -1034,10 +1030,13 @@ dojo.declare("dojox.data.AndOrReadStore", null,{
 			self._getItemsFromLoadedData(self._jsonData);
 			self._jsonData = null;
 			self._loadFinished = true;
-		} 
+		}
 	}
 });
 //Mix in the simple fetch implementation to this class.
 dojo.extend(dojox.data.AndOrReadStore,dojo.data.util.simpleFetch);
 
+return dojox.data.AndOrReadStore;
+});
+
 
diff --git a/dojox/data/AndOrWriteStore.js b/dojox/data/AndOrWriteStore.js
index 195762d..363ddac 100755
--- a/dojox/data/AndOrWriteStore.js
+++ b/dojox/data/AndOrWriteStore.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.data.AndOrWriteStore");
-dojo.require("dojox.data.AndOrReadStore");
+define("dojox/data/AndOrWriteStore", ["dojo", "dojox", "dojox/data/AndOrReadStore"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 	constructor: function(/* object */ keywordParameters){
@@ -11,7 +10,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		//			...
 		//			typeN: function || object
 		//		}
-		//		Where if it is a function, it is assumed to be an object constructor that takes the 
+		//		Where if it is a function, it is assumed to be an object constructor that takes the
 		//		value of _value as the initialization parameters.  It is serialized assuming object.toString()
 		//		serialization.  If it is an object, then it is assumed
 		//		to be an object of general form:
@@ -28,8 +27,8 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		
 		// For keeping track of changes so that we can implement isDirty and revert
 		this._pending = {
-			_newItems:{}, 
-			_modifiedItems:{}, 
+			_newItems:{},
+			_modifiedItems:{},
 			_deletedItems:{}
 		};
 
@@ -92,8 +91,8 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 			}
 		}
 		
-		// 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, 
+		// make sure this identity is not already in use by another item, if identifiers were
+		// defined in the file.  Otherwise it would be the item count,
 		// which should always be unique in this case.
 		if(this._itemsByIdentity){
 			this._assert(typeof this._itemsByIdentity[newIdentity] === "undefined");
@@ -102,7 +101,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		this._assert(typeof this._pending._deletedItems[newIdentity] === "undefined");
 		
 		var newItem = {};
-		newItem[this._storeRefPropName] = this;		
+		newItem[this._storeRefPropName] = this;
 		newItem[this._itemNumPropName] = this._arrayOfAllItems.length;
 		if(this._itemsByIdentity){
 			this._itemsByIdentity[newIdentity] = newItem;
@@ -155,14 +154,14 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 				// Bummer, the user is trying to do something like
 				// newItem({_S:"foo"}).  Unfortunately, our superclass,
 				// ItemFileReadStore, is already using _S in each of our items
-				// to hold private info.  To avoid a naming collision, we 
-				// need to move all our private info to some other property 
+				// to hold private info.  To avoid a naming collision, we
+				// need to move all our private info to some other property
 				// of all the items/objects.  So, we need to iterate over all
-				// the items and do something like: 
+				// the items and do something like:
 				//    item.__S = item._S;
 				//    item._S = undefined;
-				// But first we have to make sure the new "__S" variable is 
-				// not in use, which means we have to iterate over all the 
+				// But first we have to make sure the new "__S" variable is
+				// not in use, which means we have to iterate over all the
 				// items checking for that.
 				throw new Error("encountered bug in ItemFileWriteStore.newItem");
 			}
@@ -199,17 +198,17 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		this._assertIsItem(item);
 
 		// Remove this item from the _arrayOfAllItems, but leave a null value in place
-		// of the item, so as not to change the length of the array, so that in newItem() 
+		// of the item, so as not to change the length of the array, so that in newItem()
 		// we can still safely do: newIdentity = this._arrayOfAllItems.length;
 		var indexInArrayOfAllItems = item[this._itemNumPropName];
 		var identity = this.getIdentity(item);
 
 		//If we have reference integrity on, we need to do reference cleanup for the deleted item
 		if(this.referenceIntegrity){
-			//First scan all the attributes of this items for references and clean them up in the map 
+			//First scan all the attributes of this items for references and clean them up in the map
 			//As this item is going away, no need to track its references anymore.
 
-			//Get the attributes list before we generate the backup so it 
+			//Get the attributes list before we generate the backup so it
 			//doesn't pollute the attributes list.
 			var attributes = this.getAttributes(item);
 
@@ -255,7 +254,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 								return !(this.isItem(possibleItem) && this.getIdentity(possibleItem) == identity);
 							}, this);
 							//Remove the note of the reference to the item and set the values on the modified attribute.
-							this._removeReferenceFromMap(item, containingItem, attribute); 
+							this._removeReferenceFromMap(item, containingItem, attribute);
 							if(newValues.length < oldValues.length){
 								this._setValueOrValues(containingItem, attribute, newValues);
 							}
@@ -317,11 +316,11 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 		var identity = this.getIdentity(item);
 		if(!this._pending._modifiedItems[identity]){
-			// Before we actually change the item, we make a copy of it to 
-			// record the original state, so that we'll be able to revert if 
+			// Before we actually change the item, we make a copy of it to
+			// record the original state, so that we'll be able to revert if
 			// the revert method gets called.  If the item has already been
 			// modified then there's no need to do this now, since we already
-			// have a record of the original state.						
+			// have a record of the original state.
 			var copyOfItemState = {};
 			for(var key in item){
 				if((key === this._storeRefPropName) || (key === this._itemNumPropName) || (key === this._rootItemPropName)){
@@ -342,7 +341,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		if(dojo.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 
+			// as "unsetting" the attribute, so we need to remove this
 			// attribute from the item.
 			success = delete item[attribute];
 			newValueOrValues = undefined; // used in the onSet Notification call below
@@ -366,7 +365,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 				// Unfortunately, it's not safe to just do this:
 				//    newValueArray = newValues;
 				// Instead, we need to copy the array, which slice() does very nicely.
-				// This is so that our internal data structure won't  
+				// This is so that our internal data structure won't
 				// get corrupted if the user mucks with the values array *after*
 				// calling setValues().
 				newValueArray = newValueOrValues.slice(0, newValueOrValues.length);
@@ -374,7 +373,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 				newValueArray = [newValueOrValues];
 			}
 
-			//We need to handle reference integrity if this is on. 
+			//We need to handle reference integrity if this is on.
 			//In the case of set, we need to see if references were added or removed
 			//and update the reference tracking map accordingly.
 			if(this.referenceIntegrity){
@@ -401,7 +400,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 							if(map[id.toString()]){
 								delete map[id.toString()];
 							}else{
-								this._addReferenceToMap(possibleItem, item, attribute); 
+								this._addReferenceToMap(possibleItem, item, attribute);
 							}
 						}
 					}, this);
@@ -431,7 +430,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 		// Now we make the dojo.data.api.Notification call
 		if(callOnSet){
-			this.onSet(item, attribute, oldValueOrValues, newValueOrValues); 
+			this.onSet(item, attribute, oldValueOrValues, newValueOrValues);
 		}
 		return success; // boolean
 	},
@@ -466,7 +465,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		//		Method to remove an reference map entry for an item and attribute.
 		//	description:
 		//		Method to remove an reference map entry for an item and attribute.  This will
-		//		also perform cleanup on the map such that if there are no more references at all to 
+		//		also perform cleanup on the map such that if there are no more references at all to
 		//		the item, its reference object and entry are removed.
 		//
 		//	refItem:
@@ -523,7 +522,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 	_flatten: function(/* anything */ value){
 		if(this.isItem(value)){
 			var item = value;
-			// Given an item, return an serializable object that provides a 
+			// 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"});
@@ -554,7 +553,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 	},
 	
 	_getNewFileContentString: function(){
-		// summary: 
+		// 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
@@ -595,7 +594,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 	},
 
 	_isEmpty: function(something){
-		//	summary: 
+		//	summary:
 		//		Function to determine if an array or object has no properties or values.
 		//	something:
 		//		The array or object to examine.
@@ -624,7 +623,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		var self = this;
 		var saveCompleteCallback = function(){
 			self._pending = {
-				_newItems:{}, 
+				_newItems:{},
 				_modifiedItems:{},
 				_deletedItems:{}
 			};
@@ -673,7 +672,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 				modifiedItem = this._arrayOfAllItems[identity];
 			}
 	
-			// Restore the original item into a full-fledged item again, we want to try to 
+			// 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){
@@ -714,7 +713,7 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 					}
 					this._addReferenceToMap(refItem, deletedItem, reference.attr);
 				}, this);
-				delete deletedItem["backupRefs_" + this._reverseRefMap]; 
+				delete deletedItem["backupRefs_" + this._reverseRefMap];
 			}
 		}
 		
@@ -733,8 +732,8 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		}
 
 		this._pending = {
-			_newItems:{}, 
-			_modifiedItems:{}, 
+			_newItems:{},
+			_modifiedItems:{},
 			_deletedItems:{}
 		};
 		return true; // boolean
@@ -745,13 +744,13 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 		if(item){
 			// return true if the item is dirty
 			var identity = this.getIdentity(item);
-			return new Boolean(this._pending._newItems[identity] || 
+			return new Boolean(this._pending._newItems[identity] ||
 				this._pending._modifiedItems[identity] ||
 				this._pending._deletedItems[identity]).valueOf(); // boolean
 		}else{
 			// return true if the store is dirty -- which means return true
 			// if there are any new items, dirty items, or modified items
-			if(!this._isEmpty(this._pending._newItems) || 
+			if(!this._isEmpty(this._pending._newItems) ||
 				!this._isEmpty(this._pending._modifiedItems) ||
 				!this._isEmpty(this._pending._deletedItems)){
 				return true;
@@ -762,28 +761,28 @@ dojo.declare("dojox.data.AndOrWriteStore", dojox.data.AndOrReadStore, {
 
 /* dojo.data.api.Notification */
 
-	onSet: function(/* item */ item, 
-					/*attribute-name-string*/ attribute, 
+	onSet: function(/* item */ item,
+					/*attribute-name-string*/ attribute,
 					/*object | array*/ oldValue,
 					/*object | array*/ newValue){
 		// summary: See dojo.data.api.Notification.onSet()
 		
-		// No need to do anything. This method is here just so that the 
+		// 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. 
+		// 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. 
+		// No need to do anything. This method is here just so that the
+		// client code can connect observers to it.
 	},
 
 	close: function(/* object? */ request){
@@ -805,3 +804,6 @@ 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 0dfd0e0..1273739 100644
--- a/dojox/data/AppStore.js
+++ b/dojox/data/AppStore.js
@@ -1,8 +1,4 @@
-dojo.provide("dojox.data.AppStore");
-
-dojo.require("dojox.atom.io.Connection");
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
+define("dojox/data/AppStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/atom/io/Connection"], function(dojo, dojox) {
 
 dojo.experimental("dojox.data.AppStore");
 
@@ -10,7 +6,7 @@ dojo.declare("dojox.data.AppStore",
 	null,{
 
 	// url: [public] string
-	//		So the parser can instantiate the store via markup.		
+	//		So the parser can instantiate the store via markup.
 	url: "",
 	
 	// urlPreventCache: [public] boolean
@@ -32,7 +28,7 @@ dojo.declare("dojox.data.AppStore",
 	
 	constructor: function(/*Object*/args){
 		// summary:
-		//		The APP data store.  
+		//		The APP data store.
 		// description:
 		//		The APP Store is instantiated either in markup or programmatically by supplying a
 		//		url of the Collection to be used.
@@ -54,12 +50,12 @@ dojo.declare("dojox.data.AppStore",
 	},
 	
 	_setFeed: function(feed, data){
-		// summary: 
+		// summary:
 		//		Sets the internal feed using a dojox.atom.io.model.Feed object.
 		// description:
 		//		Sets the internal feed using a dojox.atom.io.model.Feed object.  Also adds
-		//		a property to the entries to track that they belong to this store. It 
-		//		also parses stored requests (since we were waiting on a callback) and 
+		//		a property to the entries to track that they belong to this store. It
+		//		also parses stored requests (since we were waiting on a callback) and
 		//		executes those as well.
 		//
 		// feed: dojox.atom.io.model.Feed object
@@ -77,7 +73,7 @@ dojo.declare("dojox.data.AppStore",
 				if(request.request && request.fh && request.eh){
 					this._finishFetchItems(request.request, request.fh, request.eh);
 				}else if(request.clear){
-					this._feed = null;	
+					this._feed = null;
 				}else if(request.add){
 					this._feed.addEntry(request.add);
 				}else if(request.remove){
@@ -107,12 +103,12 @@ dojo.declare("dojox.data.AppStore",
 		// summary:
 		//		This function tests whether the item is an item.
 		// description:
-		//		This function tests whether the item passed in is indeed an item 
+		//		This function tests whether the item passed in is indeed an item
 		//		in the store.
 		//
 		// item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("This error message is provided when a function is called in the following form: "
 				+ "getAttribute(argument, attributeName).  The argument variable represents the member "
 				+ "or owner of the object. The error is created when an item that does not belong "
@@ -124,14 +120,14 @@ dojo.declare("dojox.data.AppStore",
 		// summary:
 		//		This function tests whether the item is an attribute.
 		// description:
-		//		This function tests whether the item passed in is indeed a valid 
+		//		This function tests whether the item passed in is indeed a valid
 		//		'attribute' like type for the store.
-		// attribute: 
+		// attribute:
 		//		The attribute to test for being contained by the store.
 		//
 		// returns:
 		//		Returns a boolean indicating whether this is a valid attribute.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("The attribute argument must be a string. The error is created "
 			+ "when a different type of variable is specified such as an array or object.");
 		}
@@ -163,18 +159,18 @@ dojo.declare("dojox.data.AppStore",
      dojo.data.api.Read API
 ***************************************/
 	
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
 	},
 
-	getValues: function(/* item */ item, 
+	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getValues()
 
 		this._assertIsItem(item);
@@ -190,7 +186,7 @@ dojo.declare("dojox.data.AppStore",
 			if(item[attribute]){
 				item = item[attribute];
 				if(item.declaredClass == "dojox.atom.io.model.Content"){
-					return [item.value];			
+					return [item.value];
 				}
 				return [item] ;
 			}
@@ -199,7 +195,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	getAttributes: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -213,15 +209,15 @@ dojo.declare("dojox.data.AppStore",
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		return this.getValues(item, attribute).length > 0;
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -230,23 +226,23 @@ dojo.declare("dojox.data.AppStore",
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp,
 								/* Boolean?*/ trim){
-		// summary: 
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		// description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		// description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		// item:
 		//		The data item to examine for attribute values.
 		// attribute:
 		//		The attribute to inspect.
-		// value:	
+		// value:
 		//		The value to match.
 		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -272,27 +268,27 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	isItem: function(/* anything */ something){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.isItem()
 		return something && something.store && something.store === this; //boolean
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		return this.isItem(something);
 	},
 
 	loadItem: function(/* Object */ keywordArgs){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 	
 	_fetchItems: function(request, fetchHandler, errorHandler){
-		// summary: 
+		// summary:
 		//		Fetch items (Atom entries) that match to a query
-		// description: 
+		// description:
 		//		Fetch items (Atom entries) that match to a query
 		// request:
 		//		A request object
@@ -317,9 +313,9 @@ dojo.declare("dojox.data.AppStore",
 	},
 		
 	_finishFetchItems: function(request, fetchHandler, errorHandler){
-		// summary: 
+		// summary:
 		//		Internal function for finishing a fetch request.
-		// description: 
+		// description:
 		//		Internal function for finishing a fetch request.  Needed since the feed
 		//		might not have been loaded, so we finish the fetch in a callback.
 		//
@@ -332,7 +328,7 @@ dojo.declare("dojox.data.AppStore",
 		var items = null;
 		var arrayOfAllItems = this._getAllItems();
 		if(request.query){
-			var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; 
+			var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;
 			items = [];
 
 			//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
@@ -361,10 +357,10 @@ dojo.declare("dojox.data.AppStore",
 				}
 			}
 		}else{
-			// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
+			// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
 			// of the internal list so that multiple callers can get listsand sort without affecting each other.
 			if(arrayOfAllItems.length> 0){
-				items = arrayOfAllItems.slice(0,arrayOfAllItems.length); 
+				items = arrayOfAllItems.slice(0,arrayOfAllItems.length);
 			}
 		}
 		try{
@@ -375,7 +371,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	getFeatures: function(){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
@@ -392,7 +388,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	getLabel: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this.isItem(item)){
 			return this.getValue(item, "title", "No Title");
@@ -401,7 +397,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		return ["title"];
 	},
@@ -411,20 +407,20 @@ dojo.declare("dojox.data.AppStore",
 ***************************************/
 
 	getIdentity: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		this._assertIsItem(item);
 		return this.getValue(item, "id");
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Identity.getIdentityAttributes()
 		 return ["id"];
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 
 		this._fetchItems({query:{id:keywordArgs.identity}, onItem: keywordArgs.onItem, scope: keywordArgs.scope},
@@ -446,7 +442,7 @@ dojo.declare("dojox.data.AppStore",
 ***************************************/
 
 	newItem: function(/* Object? */ keywordArgs){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.newItem()
 		var entry = new dojox.atom.io.model.Entry();
 		var value = null;
@@ -530,7 +526,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	deleteItem: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.deleteItem()
 		this._assertIsItem(item);
 
@@ -555,10 +551,10 @@ dojo.declare("dojox.data.AppStore",
 		return true;
 	},
 
-	setValue: function(	/* item */ item, 
+	setValue: function(	/* item */ item,
 						/* string */ attribute,
 						/* almost anything */ value){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.setValue()
 		this._assertIsItem(item);
 		
@@ -634,9 +630,9 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	setValues: function(/* item */ item,
-						/* string */ attribute, 
+						/* string */ attribute,
 						/* array */ values){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.setValues()
 		if(values.length === 0){
 			return this.unsetAttribute(item, attribute);
@@ -721,9 +717,9 @@ dojo.declare("dojox.data.AppStore",
 		return false;
 	},
 
-	unsetAttribute: function(	/* item */ item, 
+	unsetAttribute: function(	/* item */ item,
 								/* string */ attribute){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.unsetAttribute()
 		this._assertIsItem(item);
 		if(this._assertIsAttribute(attribute)){
@@ -752,7 +748,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	save: function(/* object */ keywordArgs){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.save()
 		// keywordArgs:
 		//		{
@@ -788,7 +784,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	revert: function(){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.revert()
 		var i;
 		for(i in this._adds){
@@ -817,7 +813,7 @@ dojo.declare("dojox.data.AppStore",
 	},
 
 	isDirty: function(/* item? */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Write.isDirty()
 		if(item){
 			this._assertIsItem(item);
@@ -827,3 +823,6 @@ dojo.declare("dojox.data.AppStore",
 	}
 });
 dojo.extend(dojox.data.AppStore,dojo.data.util.simpleFetch);
+
+return dojox.data.AppStore;
+});
diff --git a/dojox/data/AtomReadStore.js b/dojox/data/AtomReadStore.js
index c6a176d..a9c03f8 100644
--- a/dojox/data/AtomReadStore.js
+++ b/dojox/data/AtomReadStore.js
@@ -1,9 +1,4 @@
-dojo.provide("dojox.data.AtomReadStore");
-
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.date.stamp");
-
+define("dojox/data/AtomReadStore", ["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, {
@@ -474,8 +469,8 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 							case "name":
 								nameNode = child;
 								break;
-							case "uri": 
-								uriNode = child; 
+							case "uri":
+								uriNode = child;
 								break;
 						}
 					});
@@ -488,13 +483,13 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 					}
 					attribs[tagName] = author;
 					break;
-				case "id": 
-					attribs[tagName] = getNodeText(node); 
+				case "id":
+					attribs[tagName] = getNodeText(node);
 					break;
-				case "updated": 
+				case "updated":
 					attribs[tagName] = dojo.date.stamp.fromISOString(getNodeText(node) );
 					break;
-				case "published": 
+				case "published":
 					attribs[tagName] = dojo.date.stamp.fromISOString(getNodeText(node));
 					break;
 				case "category":
@@ -550,3 +545,6 @@ dojo.declare("dojox.data.AtomReadStore", null, {
 	}
 });
 dojo.extend(dojox.data.AtomReadStore,dojo.data.util.simpleFetch);
+
+return dojox.data.AtomReadStore;
+});
diff --git a/dojox/data/CdfStore.js b/dojox/data/CdfStore.js
index 20d414d..56a1af9 100755
--- a/dojox/data/CdfStore.js
+++ b/dojox/data/CdfStore.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.data.CdfStore");
-dojo.require("dojo.data.util.sorter");
+define("dojox/data/CdfStore", ["dojo", "dojox", "dojo/data/util/sorter"], function(dojo, dojox) {
 
 dojox.data.ASYNC_MODE = 0;
 dojox.data.SYNC_MODE = 1;
@@ -18,13 +17,13 @@ dojo.declare("dojox.data.CdfStore", null, {
 	//
 	//		While a CDF document is an XML file, other than the initial input, all data returned
 	//		from and written to this store should be in object format.
-	//		
+	//
 	// identity: [const] String
 	//		The unique identifier for each item. Defaults to "jsxid" which is standard for a CDF
 	//		document. Should not be changed.
 	identity: "jsxid",
 	//
-	//	url : String 
+	//	url : String
 	//		The location from which to fetch the XML (CDF) document.
 	url: "",
 	//
@@ -49,7 +48,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 	
 	constructor: function(/* Object */ args){
 		// summary:
-		//	Constructor for the CDF store. Instantiate a new CdfStore. 
+		//	Constructor for the CDF store. Instantiate a new CdfStore.
 		//
 		if(args){
 			this.url = args.url;
@@ -159,7 +158,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 
 	getLabel: function(/* jsx3.xml.Entity */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		//
 		if((this.label !== "") && this.isItem(item)){
@@ -221,7 +220,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 		//		|	"//record"
 		//		Only the records beneath the root (data) node:
 		//		|	"//data/record"
-		//		
+		//
 		//	See:
 		//	http://www.tibco.com/devnet/resources/gi/3_7/api/html/jsx3/xml/Entity.html#method:selectNodes
 		//	http://www.w3.org/TR/xpath
@@ -293,14 +292,14 @@ dojo.declare("dojox.data.CdfStore", null, {
 				if(!requestObject.onItem){
 					items = items.slice(startIndex, endIndex);
 					if(requestObject.byId){
-						items = items[0];	
+						items = items[0];
 					}
 				}
 				requestObject.onComplete.call(scope, items, requestObject);
 			}else{
 				items = items.slice(startIndex, endIndex);
 				if(requestObject.byId){
-					items = items[0];	
+					items = items[0];
 				}
 			}
 			return items;
@@ -313,7 +312,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 		var localRequest = request || "*"; // use request for _getItems()
 		
 		if(this.mode == dojox.data.SYNC_MODE){
-			// sync mode. items returned directly	
+			// sync mode. items returned directly
 			var res = this._loadCDF();
 			if(res instanceof Error){
 				if(request.onError){
@@ -335,7 +334,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 		
 		}else{
 			
-			// async mode. Return a Deferred.			
+			// async mode. Return a Deferred.
 			var dfd = this._loadCDF();
 			dfd.addCallbacks(dojo.hitch(this, function(cdfDoc){
 				var items = this._getItems(this.cdfDoc, localRequest);
@@ -410,7 +409,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Read.close()
 	},
 
@@ -516,7 +515,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 		//		Internal method.
 		//		Marks items as modified, deleted or new.
 		var id = this.getIdentity(item);
-		this._modifiedItems[id] = item;	
+		this._modifiedItems[id] = item;
 	},
 	
 	
@@ -557,7 +556,7 @@ dojo.declare("dojox.data.CdfStore", null, {
 	 *************************************/
 	getIdentity: function(/* jsx3.xml.Entity */ item){
 		//	summary:
-		//		Returns the identifier for an item.  
+		//		Returns the identifier for an item.
 		//
 		return this.getValue(item, this.identity); // String
 	},
@@ -595,3 +594,6 @@ dojo.declare("dojox.data.CdfStore", null, {
 	
 });
 
+return dojox.data.CdfStore;
+});
+
diff --git a/dojox/data/ClientFilter.js b/dojox/data/ClientFilter.js
index 0d90248..e1c0d31 100644
--- a/dojox/data/ClientFilter.js
+++ b/dojox/data/ClientFilter.js
@@ -1,5 +1,5 @@
-dojo.provide("dojox.data.ClientFilter");
-dojo.require("dojo.data.util.filter"); 
+define("dojox/data/ClientFilter", ["dojo", "dojox", "dojo/data/util/filter"], function(dojo, dojox) {
+
 // This is an abstract data store module for adding updateable result set functionality to an existing data store class
 (function(){
 	var cf;
@@ -34,15 +34,15 @@ dojo.require("dojo.data.util.filter");
 				// 		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 
+				// 		isUpdateable and if an item matches a query, it can return true from matchesQuery. Here is
 				//		definition of isUpdateable and matchesQuery
 				// 		isUpdateable(request)  - request is the keywords arguments as is passed to the fetch function.
 				// 		matchesQuery(item,request) - item is the item to test, and request is the value arguments object
 				//				for the fetch function.
 				//
-				//		You can define a property on this object instance "cacheByDefault" to a value of true that will 
+				//		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. 
+				// 		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:
@@ -54,7 +54,7 @@ dojo.require("dojo.data.util.filter");
 				this.onNew = addUpdate(this,true,false);
 				this.onDelete = addUpdate(this,false,true);
 				this._updates= [];
-				this._fetchCache = [];				
+				this._fetchCache = [];
 			},
 			clearCache: function(){
 				//	summary:
@@ -64,19 +64,19 @@ dojo.require("dojo.data.util.filter");
 			updateResultSet: function(/*Array*/ resultSet, /*Object*/ request){
 				//	summary:
 				//		Attempts to update the given result set based on previous notifications
-				//	resultSet:				
+				//	resultSet:
 				//		The result set array that should be updated
 				//	request:
 				//		This object follows the same meaning as the keywordArgs passed to a dojo.data.api.Read.fetch.
 				//	description:
-				// 		This will attempt to update the provide result based on previous notification, adding new items 
+				// 		This will attempt to update the provide result based on previous notification, adding new items
 				// 		from onNew calls, removing deleted items, and updating modified items, and properly removing
 				//  	and adding items as required by the query and sort parameters. This function will return:
 				//		0: Indicates it could not successfully update the result set
 				//		1: Indicates it could successfully handle all the notifications, but no changes were made to the result set
 				//		2: Indicates it successfully handled all the notifications and result set has been updated.
 				if(this.isUpdateable(request)){
-					// we try to avoid rerunning notification updates more than once on the same object for performance 
+					// we try to avoid rerunning notification updates more than once on the same object for performance
 					for(var i = request._version || 0; i < this._updates.length;i++){
 						// for each notification,we will update the result set
 						var create = this._updates[i].create;
@@ -89,7 +89,7 @@ dojo.require("dojo.data.util.filter");
 								}
 							}
 						}
-						if(create && this.matchesQuery(create,request) && // if there is a new/replacement item and it matches the query 
+						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
 							resultSet.push(create); // should this go at the beginning by default instead?
 							updated = true;
@@ -114,7 +114,7 @@ dojo.require("dojo.data.util.filter");
 				//	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
 				if(argsSuper.query == argsSub.query){
@@ -129,8 +129,8 @@ dojo.require("dojo.data.util.filter");
 				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 
+					}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]))){
 						return false;
@@ -216,7 +216,7 @@ dojo.require("dojo.data.util.filter");
 				//
 				//	request:
 				//		See dojo.data.api.Read.fetch request
-				//		
+				//
 				//	baseResults:
 				//		This provides the result set to start with for client side querying
 				if(request.queryOptions && request.queryOptions.results){
@@ -244,10 +244,10 @@ dojo.require("dojo.data.util.filter");
 				var start = request.start || 0;
 				var finalResults = (start || request.count) ? baseResults.slice(start,start + (request.count || baseResults.length)) : baseResults;
 				finalResults._fullLength = baseResults.length;
-				return finalResults; 
+				return finalResults;
 			},
 			matchesQuery: function(item,request){
-				var query = request.query; 
+				var query = request.query;
 				var ignoreCase = request.queryOptions && request.queryOptions.ignoreCase;
 				for(var i in query){
 					// if anything doesn't match, than this should be in the query
@@ -271,7 +271,7 @@ dojo.require("dojo.data.util.filter");
 					// sort order for ties and no sort orders
 					return function(){
 						return 0;// keep the order unchanged
-					}; 
+					};
 				}
 				var attribute = current.attribute;
 				var descending = !!current.descending;
@@ -283,10 +283,13 @@ dojo.require("dojo.data.util.filter");
 					if(av != bv){
 						return av < bv == descending ? 1 : -1;
 					}
-					return next(a,b); 
-				}; 
+					return next(a,b);
+				};
 			}
 		}
 	);
 	cf.onUpdate = function(){};
 })();
+
+return dojox.data.ClientFilter;
+});
diff --git a/dojox/data/CouchDBRestStore.js b/dojox/data/CouchDBRestStore.js
index bcff5dc..467f037 100644
--- a/dojox/data/CouchDBRestStore.js
+++ b/dojox/data/CouchDBRestStore.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.data.CouchDBRestStore");
-dojo.require("dojox.data.JsonRestStore");
+define("dojox/data/CouchDBRestStore", ["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.
@@ -77,3 +76,7 @@ dojox.data.CouchDBRestStore.getStores = function(couchServerUrl){
 	});
 	return stores;
 };
+
+return dojox.data.CouchDBRestStore;
+
+});
diff --git a/dojox/data/CssClassStore.js b/dojox/data/CssClassStore.js
index 52a0a94..cedbec4 100755
--- a/dojox/data/CssClassStore.js
+++ b/dojox/data/CssClassStore.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.data.CssClassStore");
-
-dojo.require("dojox.data.CssRuleStore");
+define("dojox/data/CssClassStore", ["dojo", "dojox", "dojox/data/CssRuleStore"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 	//	summary:
@@ -16,23 +14,23 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 	_cName: "dojox.data.CssClassStore",
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
-		return { 
+		return {
 			"dojo.data.api.Read" : true,
-			"dojo.data.api.Identity" : true 
+			"dojo.data.api.Identity" : true
 		};
 	},
 
 	getAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		return ['class', 'classSans'];
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
@@ -42,7 +40,7 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -84,7 +82,7 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 		//	summary:
 		//		Handles the return from a fetching action.  Delegates requests to act on the resulting
 		//		item set to eitehr the _handleFetchReturn or _handleFetchByIdentityReturn depending on
-		//		where the request originated.  
+		//		where the request originated.
 		var _inProgress = [];
 		
 		var items = {};
@@ -113,7 +111,7 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 		//	summary:
 		//		Handles a fetchByIdentity request by finding the correct item.
 		var items = request._items;
-		// Per https://bugs.webkit.org/show_bug.cgi?id=17935 , Safari 3.x always returns the selectorText 
+		// 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)];
 		if(!this.isItem(item)){
@@ -127,21 +125,21 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 
 	/* Identity API */
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		this._assertIsItem(item);
 		return this.getValue(item, this._idAttribute);
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Identity.getIdentityAttributes()
 		this._assertIsItem(item);
 		return [this._idAttribute];
 	},
 
 	fetchItemByIdentity: function(/* request */ request){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 		request = request || {};
 		if(!request.store){
@@ -156,3 +154,6 @@ dojo.declare("dojox.data.CssClassStore", dojox.data.CssRuleStore, {
 		return request;
 	}
 });
+
+return dojox.data.CssClassStore;
+});
diff --git a/dojox/data/CssRuleStore.js b/dojox/data/CssRuleStore.js
index 0239746..c1d740b 100755
--- a/dojox/data/CssRuleStore.js
+++ b/dojox/data/CssRuleStore.js
@@ -1,8 +1,4 @@
-dojo.provide("dojox.data.CssRuleStore");
-
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.sorter");
-dojo.require("dojox.data.css");
+define("dojox/data/CssRuleStore", ["dojo", "dojox", "dojo.data.util.sorter", "dojo/data/util/filter", "dojox/data/css"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.CssRuleStore", null, {
 	//	summary:
@@ -39,18 +35,18 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		this._waiting = [];
 		this.gatherHandle = null;
 		var self = this;
-		// CSS files may not be finished loading by the time the store is constructed.  We need to 
+		// CSS files may not be finished loading by the time the store is constructed.  We need to
 		// give them a little time, so setting the stylesheet loading to retry every 250ms.
 		function gatherRules(){
 			try{
-				// Funkiness here is due to css that may still be loading.  This throws an DOM Access 
+				// 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);
 				if(self.gatherHandle){
 					clearInterval(self.gatherHandle);
 					self.gatherHandle = null;
 				}
-				// Handle any fetches that have been queued while we've been waiting on the CSS files 
+				// Handle any fetches that have been queued while we've been waiting on the CSS files
 				// to finish
 				while(self._waiting.length){
 					var item = self._waiting.pop();
@@ -72,15 +68,15 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
-		return { 
+		return {
 			"dojo.data.api.Read" : true
 		};
 	},
 
 	isItem: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		if(item && item[this._storeRef] == this){
 			return true;
@@ -89,7 +85,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -101,7 +97,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attrs = ['selector', 'classes', 'rule', 'style', 'cssText', 'styleSheet', 'parentStyleSheet', 'parentStyleSheetHref'];
@@ -116,7 +112,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		var value = defaultValue;
@@ -127,7 +123,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -180,22 +176,22 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	getLabel: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		this._assertIsItem(item);
 		return this.getValue(item, this._labelAttribute);
 	},
 
 	getLabelAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		return [this._labelAttribute];
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -205,19 +201,19 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		return this.isItem(something); //boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
 
 	fetch: function(request){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.fetch()
 		request = request || {};
 		if(!request.store){
@@ -289,7 +285,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		//	summary:
 		//		Handles the return from a fetching action.  Delegates requests to act on the resulting
 		//		item set to eitehr the _handleFetchReturn or _handleFetchByIdentityReturn depending on
-		//		where the request originated.  
+		//		where the request originated.
 		var _inProgress = [];
 		
 		var items = [];
@@ -332,9 +328,9 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		}else if(request.query){
 			for(i in request._items){
 				var item = request._items[i];
-				// Per https://bugs.webkit.org/show_bug.cgi?id=17935 , Safari 3.x always returns the selectorText 
+				// 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 = dojo.isWebKit ? true : (request.queryOptions ? request.queryOptions.ignoreCase : false);
 				var regexpList = {};
 				var key;
 				var value;
@@ -352,7 +348,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 					}
 				}
 				if(match){
-					items.push(item); 
+					items.push(item);
 				}
 			}
 			this._cache[cacheKey] = items;
@@ -370,7 +366,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		var start = 0;
 		var count = items.length;
 		if(request.start > 0 && request.start < items.length){
-			start = request.start;	
+			start = request.start;
 		}
 		if(request.count && request.count){
 			count = request.count;
@@ -388,20 +384,20 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		if(request.onItem){
 			if(dojo.isArray(items)){
 				for(i = 0; i < items.length; i++){
-					request.onItem.call(scope, items[i], request); 
+					request.onItem.call(scope, items[i], request);
 				}
 				if(request.onComplete){
 					request.onComplete.call(scope, null, request);
 				}
 			}
 		}else if(request.onComplete){
-			request.onComplete.call(scope, items, request); 
+			request.onComplete.call(scope, items, request);
 		}
 		return request;
 	},
 
 	close: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.close()
 		//		Clears out the cache and allItems objects, meaning all future fetches will requery
 		//		the stylesheets.
@@ -412,9 +408,9 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error(this._cName + ": Invalid item argument.");
 		}
 	},
@@ -422,29 +418,29 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		//	summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error(this._cName + ": Invalid attribute argument.");
 		}
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -461,3 +457,7 @@ dojo.declare("dojox.data.CssRuleStore", null, {
 		});
 	}
 });
+
+return dojox.data.CssRuleStore;
+
+});
diff --git a/dojox/data/CsvStore.js b/dojox/data/CsvStore.js
index 09627f3..cc74d3c 100644
--- a/dojox/data/CsvStore.js
+++ b/dojox/data/CsvStore.js
@@ -1,7 +1,4 @@
-dojo.provide("dojox.data.CsvStore");
-
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.simpleFetch");
+define("dojox/data/CsvStore", ["dojo", "dojox", "dojo/data/util/filter", "dojo/data/util/simpleFetch"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.CsvStore", null, {
 	// summary:
@@ -24,7 +21,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	//		var csvStore = new dojox.data.CsvStore({url:"http://example.com/movies.csv");
 
 	constructor: function(/* Object */ keywordParameters){
-		// summary: 
+		// summary:
 		//		initializer
 		// keywordParameters: {url: String}
 		// keywordParameters: {data: String}
@@ -47,9 +44,9 @@ dojo.declare("dojox.data.CsvStore", null, {
 		}
 		this._storeProp = "_csvStore";	// Property name for the store reference on every item.
 		this._idProp = "_csvId"; 		// Property name for the Item Id on every item.
-		this._features = {	
+		this._features = {
 			'dojo.data.api.Read': true,
-			'dojo.data.api.Identity': true 
+			'dojo.data.api.Identity': true
 		};
 		this._loadInProgress = false;	//Got to track the initial load to prevent duelling loads of the dataset.
 		this._queuedFetches = [];
@@ -68,11 +65,11 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	// url: [public] string
-	//		Declarative hook for setting Csv source url.		
+	//		Declarative hook for setting Csv source url.
 	url: "",
 
 	// label: [public] string
-	//		Declarative hook for setting the label attribute. 
+	//		Declarative hook for setting the label attribute.
 	label: "",
 
 	// identifier: [public] string
@@ -80,23 +77,23 @@ dojo.declare("dojox.data.CsvStore", null, {
 	identifier: "",
 
 	// separator: [public] string
-	//		Declatative and programmatic hook for defining the separator 
-	//		character used in the Csv style file. 
+	//		Declatative and programmatic hook for defining the separator
+	//		character used in the Csv style file.
 	separator: ",",
 
 	// separator: [public] string
-	//		Parameter to allow specifying if preventCache should be passed to 
+	//		Parameter to allow specifying if preventCache should be passed to
 	//		the xhrGet call or not when loading data from a url.
-	//		Note this does not mean the store calls the server on each fetch, 
+	//		Note this does not mean the store calls the server on each fetch,
 	//		only that the data load has preventCache set as an option.
 	urlPreventCache: false,
 
 	_assertIsItem: function(/* item */ item){
 		// summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		// item: 
+		// item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error(this.declaredClass + ": a function was passed an item argument that was not an item");
 		}
 	},
@@ -116,12 +113,12 @@ dojo.declare("dojox.data.CsvStore", null, {
 /***************************************
      dojo.data.api.Read API
 ***************************************/
-	getValue: function(	/* item */ item, 
-						/* attribute || attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute || attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getValue()
-		//		Note that for the CsvStore, an empty string value is the same as no value, 
+		//		Note that for the CsvStore, an empty string value is the same as no value,
 		// 		so the defaultValue would be returned instead of an empty string.
 		this._assertIsItem(item);
 		var itemValue = defaultValue;
@@ -137,9 +134,9 @@ dojo.declare("dojox.data.CsvStore", null, {
 		return itemValue; //String
 	},
 
-	getValues: function(/* item */ item, 
+	getValues: function(/* item */ item,
 						/* attribute || attribute-name-string */ attribute){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getValues()
 		// 		CSV syntax does not support multi-valued attributes, so this is just a
 		// 		wrapper function for getValue().
@@ -148,7 +145,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	getAttributes: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -164,7 +161,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		// 		The hasAttribute test is true if attribute has an index number within the item's array length
 		// 		AND if the item has a value for that attribute. Note that for the CsvStore, an
@@ -179,10 +176,10 @@ dojo.declare("dojox.data.CsvStore", null, {
 		}
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute || attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute || attribute-name-string */ attribute,
 							/* anything */ value){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -191,22 +188,22 @@ dojo.declare("dojox.data.CsvStore", null, {
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute || attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute || attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		// summary: 
+		// summary:
 		//		Internal function for looking at the values contained by the item.
-		// description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		// description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		// item:
 		//		The data item to examine for attribute values.
 		// attribute:
 		//		The attribute to inspect.
-		// value:	
+		// value:
 		//		The value to match.
 		// regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -229,7 +226,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.isItem()
 		if(something && something[this._storeProp] === this){
 			var identity = something[this._idProp];
@@ -250,14 +247,14 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		//		The CsvStore always loads all items, so if it's an item, then it's loaded.
 		return this.isItem(something); //Boolean
 	},
 
 	loadItem: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.loadItem()
 		// description:
 		//		The CsvStore always loads all items, so if it's an item, then it's loaded.
@@ -268,13 +265,13 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	getFeatures: function(){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return this._features; //Object
 	},
 
 	getLabel: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this.label && this.isItem(item)){
 			return this.getValue(item,this.label); //String
@@ -283,7 +280,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		if(this.label){
 			return [this.label]; //array
@@ -295,10 +292,10 @@ dojo.declare("dojox.data.CsvStore", null, {
 	// The dojo.data.api.Read.fetch() function is implemented as
 	// a mixin from dojo.data.util.simpleFetch.
 	// That mixin requires us to define _fetchItems().
-	_fetchItems: function(	/* Object */ keywordArgs, 
-							/* Function */ findCallback, 
+	_fetchItems: function(	/* Object */ keywordArgs,
+							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		// summary: 
+		// summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		// tags:
 		//		protected
@@ -308,7 +305,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 			if(requestArgs.query){
 				var key, value;
 				items = [];
-				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; 
+				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
 
 				//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
 				//same value for each item examined.  Much more efficient.
@@ -334,9 +331,9 @@ dojo.declare("dojox.data.CsvStore", null, {
 					}
 				}
 			}else{
-				// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
+				// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
 				// of the internal list so that multiple callers can get lists and sort without affecting each other.
-				items = arrayOfAllItems.slice(0,arrayOfAllItems.length); 
+				items = arrayOfAllItems.slice(0,arrayOfAllItems.length);
 				
 			}
 			findCallback(items, requestArgs);
@@ -347,14 +344,14 @@ dojo.declare("dojox.data.CsvStore", null, {
 		}else{
 			if(this.url !== ""){
 				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be 
+				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
 					this._queuedFetches.push({args: keywordArgs, filter: filter});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self.url, 
+							url: self.url,
 							handleAs: "text",
 							preventCache: self.urlPreventCache
 						};
@@ -415,7 +412,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 	
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Read.close()
 	},
 	
@@ -429,9 +426,9 @@ dojo.declare("dojox.data.CsvStore", null, {
 		//		Given a string containing CSV records, this method parses
 		//		the string and returns a data structure containing the parsed
 		//		content.  The data structure we return is an array of length
-		//		R, where R is the number of rows (lines) in the CSV data.  The 
-		//		return array contains one sub-array for each CSV line, and each 
-		//		sub-array contains C string values, where C is the number of 
+		//		R, where R is the number of rows (lines) in the CSV data.  The
+		//		return array contains one sub-array for each CSV line, and each
+		//		sub-array contains C string values, where C is the number of
 		//		columns in the CSV data.
 		// example:
 		//		For example, given this CSV string as input:
@@ -468,8 +465,8 @@ dojo.declare("dojox.data.CsvStore", null, {
 						var thirdToLastChar = field.charAt(field.length - 3);
 						if(field.length === 2 && field == "\"\""){
 							listOfFields[j] = ""; //Special case empty string field.
-						}else if((firstChar == '"') && 
-								((lastChar != '"') || 
+						}else if((firstChar == '"') &&
+								((lastChar != '"') ||
 								 ((lastChar == '"') && (secondToLastChar == '"') && (thirdToLastChar != '"')))){
 							if(j+1 === listOfFields.length){
 								// alert("The last field in record " + i + " is corrupted:\n" + field);
@@ -494,7 +491,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 			// The first item of the array must be the header row with attribute names.
 			this._attributes = arrayOfOutputRecords.shift();
 			for(i = 0; i<this._attributes.length; i++){
-				// Store the index of each attribute 
+				// Store the index of each attribute
 				this._attributeIndexes[this._attributes[i]] = i;
 			}
 			this._dataArray = arrayOfOutputRecords; //Array
@@ -598,7 +595,7 @@ dojo.declare("dojox.data.CsvStore", null, {
      dojo.data.api.Identity API
 ***************************************/
 	getIdentity: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		// tags:
 		//		public
@@ -609,7 +606,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 		// tags:
 		//		public
@@ -620,14 +617,14 @@ dojo.declare("dojox.data.CsvStore", null, {
 			var self = this;
 			if(this.url !== ""){
 				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be 
+				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
 					this._queuedFetches.push({args: keywordArgs});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self.url, 
+							url: self.url,
 							handleAs: "text"
 						};
 					var getHandler = dojo.xhrGet(getArgs);
@@ -685,7 +682,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Identity.getIdentifierAttributes()
 		// tags:
 		//		public
@@ -700,7 +697,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 	},
 
 	_handleQueuedFetches: function(){
-		// summary: 
+		// summary:
 		//		Internal function to execute delayed request in the store.
 		// tags:
 		//		private
@@ -712,7 +709,7 @@ dojo.declare("dojox.data.CsvStore", null, {
 				var delayedFilter = fData.filter;
 				var delayedQuery = fData.args;
 				if(delayedFilter){
-					delayedFilter(delayedQuery, this._arrayOfAllItems); 
+					delayedFilter(delayedQuery, this._arrayOfAllItems);
 				}else{
 					this.fetchItemByIdentity(fData.args);
 				}
@@ -723,3 +720,6 @@ dojo.declare("dojox.data.CsvStore", null, {
 });
 //Mix in the simple fetch implementation to this class.
 dojo.extend(dojox.data.CsvStore,dojo.data.util.simpleFetch);
+
+return dojox.data.CsvStore;
+});
diff --git a/dojox/data/FileStore.js b/dojox/data/FileStore.js
index 6ff11bc..cd860f8 100755
--- a/dojox/data/FileStore.js
+++ b/dojox/data/FileStore.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.data.FileStore");
+define("dojox/data/FileStore", ["dojo", "dojox"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.FileStore", null, {
 	constructor: function(/*Object*/args){
@@ -57,14 +57,14 @@ dojo.declare("dojox.data.FileStore", null, {
 	_storeRef: "_S",
 
 	// label: [public] string
-	//		Default attribute to use to represent the item as a user-readable 
+	//		Default attribute to use to represent the item as a user-readable
 	//		string.  Public, so users can change it.
 	label: "name",
 
 	// _identifier: [private] string
-	//		Default attribute to use to represent the item's identifier.  
-	//		Path should always be unique in the store instance.		
-	_identifier: "path",	
+	//		Default attribute to use to represent the item's identifier.
+	//		Path should always be unique in the store instance.
+	_identifier: "path",
 
 	// _attributes: [private] string
 	//		Internal variable of attributes all file items should have.
@@ -76,7 +76,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	pathSeparator: "/",
 
 	// options: [public] array
-	//		Array of options to always send when doing requests.  
+	//		Array of options to always send when doing requests.
 	//		Back end service controls this, like 'dirsOnly', 'showHiddenFiles', 'expandChildren', etc.
 	options: [],
 
@@ -91,9 +91,9 @@ dojo.declare("dojox.data.FileStore", null, {
 	_assertIsItem: function(/* item */ item){
 		// summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		// item: 
+		// item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojox.data.FileStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -101,9 +101,9 @@ dojo.declare("dojox.data.FileStore", null, {
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		// summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		// attribute: 
+		// attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.FileStore: a function was passed an attribute argument that was not an attribute name string");
 		}
 	},
@@ -111,7 +111,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	pathAsQueryParam: false, //Function to switch between REST style URL lookups and passing the path to specific items as a query param: 'path'.
 
 	getFeatures: function(){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true, 'dojo.data.api.Identity':true
@@ -119,7 +119,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
@@ -129,13 +129,13 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 
 	getAttributes: function(item){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getAttributes()
-		return this._attributes; 
+		return this._attributes;
 	},
 
 	hasAttribute: function(item, attribute){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -143,30 +143,30 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 	
 	getIdentity: function(/* item */ item){
-		// summary: 
+		// summary:
 		//		See dojo.data.api.Identity.getIdentity()
-		return this.getValue(item, this._identifier); 
+		return this.getValue(item, this._identifier);
 	},
 	
 	getIdentityAttributes: function(item){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getLabelAttributes()
 		return [this._identifier];
 	},
 
 
 	isItemLoaded: function(item){
-		 //	summary: 
+		 //	summary:
 		 //      See dojo.data.api.Read.isItemLoaded()
 		 var loaded = this.isItem(item);
 		 if(loaded && typeof item._loaded == "boolean" && !item._loaded){
-		 	loaded = false; 
+		 	loaded = false;
 		 }
 		 return loaded;
 	},
 
 	loadItem: function(keywordArgs){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.loadItem()
 		var item = keywordArgs.item;
 		var self = this;
@@ -208,19 +208,19 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 
 	getLabel: function(item){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getLabel()
 		return this.getValue(item,this.label);
 	},
 	
 	getLabelAttributes: function(item){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getLabelAttributes()
 		return [this.label];
 	},
 	
 	containsValue: function(item, attribute, value){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
@@ -232,7 +232,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -240,14 +240,14 @@ dojo.declare("dojox.data.FileStore", null, {
 		var value = item[attribute];
 		if(typeof value !== "undefined" && !dojo.isArray(value)){
 			value = [value];
-		}else if(typeof value === "undefined"){	
+		}else if(typeof value === "undefined"){
 			value = [];
 		}
 		return value;
 	},
 
 	isItem: function(item){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
@@ -256,7 +256,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 	
 	close: function(request){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.close()
 	},
 
@@ -318,7 +318,7 @@ dojo.declare("dojox.data.FileStore", null, {
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
-		// summary: 
+		// summary:
 		//      See dojo.data.api.Read.loadItem()
 		var path = keywordArgs.identity;
 		var self = this;
@@ -427,3 +427,5 @@ dojo.declare("dojox.data.FileStore", null, {
 	}
 });
 
+return dojox.data.FileStore;
+});
diff --git a/dojox/data/FlickrRestStore.js b/dojox/data/FlickrRestStore.js
index c6d0cc2..b139d55 100644
--- a/dojox/data/FlickrRestStore.js
+++ b/dojox/data/FlickrRestStore.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.data.FlickrRestStore");
-
-dojo.require("dojox.data.FlickrStore");
+define("dojox/data/FlickrRestStore", ["dojo", "dojox", "dojox/data/FlickrStore"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.FlickrRestStore",
 	dojox.data.FlickrStore, {
@@ -480,3 +478,6 @@ dojo.declare("dojox.data.FlickrRestStore",
 	}
 });
 
+return dojox.data.FlickrRestStore;
+});
+
diff --git a/dojox/data/FlickrStore.js b/dojox/data/FlickrStore.js
index 2fabc22..7f804a1 100644
--- a/dojox/data/FlickrStore.js
+++ b/dojox/data/FlickrStore.js
@@ -1,289 +1,283 @@
-dojo.provide("dojox.data.FlickrStore");
-
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.io.script");
-dojo.require("dojo.date.stamp");
-dojo.require("dojo.AdapterRegistry");
-
-(function(){
-	var d = dojo;
-
-	dojo.declare("dojox.data.FlickrStore", null, {
-		constructor: function(/*Object*/args){
-			//	summary:
-			//		Initializer for the FlickrStore store.  
-			//	description:
-			//		The FlickrStore is a Datastore interface to one of the basic services
-			//		of the Flickr service, the public photo feed.  This does not provide
-			//		access to all the services of Flickr.
-			//		This store cannot do * and ? filtering as the flickr service 
-			//		provides no interface for wildcards.
-			if(args && args.label){
-				this.label = args.label;
-			}
-			if(args && "urlPreventCache" in args){
-				this.urlPreventCache = args.urlPreventCache?true:false;
-			}
-		},
-
-		_storeRef: "_S",
+define("dojox/data/FlickrStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/io/script", "dojo/date/stamp", "dojo/AdapterRegistry"], function(dojo, dojox) {
+
+dojo.declare("dojox.data.FlickrStore", null, {
+	constructor: function(/*Object*/args){
+		//	summary:
+		//		Initializer for the FlickrStore store.
+		//	description:
+		//		The FlickrStore is a Datastore interface to one of the basic services
+		//		of the Flickr service, the public photo feed.  This does not provide
+		//		access to all the services of Flickr.
+		//		This store cannot do * and ? filtering as the flickr service
+		//		provides no interface for wildcards.
+		if(args && args.label){
+			this.label = args.label;
+		}
+		if(args && "urlPreventCache" in args){
+			this.urlPreventCache = args.urlPreventCache?true:false;
+		}
+	},
 
-		label: "title",
+	_storeRef: "_S",
 
-		//Flag to allor control of if cache prevention is enabled or not.
-		urlPreventCache: true,
+	label: "title",
 
-		_assertIsItem: function(/* item */ item){
-			//	summary:
-			//      This function tests whether the item passed in is indeed an item in the store.
-			//	item: 
-			//		The item to test for being contained by the store.
-			if(!this.isItem(item)){ 
-				throw new Error("dojox.data.FlickrStore: a function was passed an item argument that was not an item");
-			}
-		},
-
-		_assertIsAttribute: function(/* attribute-name-string */ attribute){
-			//	summary:
-			//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-			//	attribute: 
-			//		The attribute to test for being contained by the store.
-			if(typeof attribute !== "string"){ 
-				throw new Error("dojox.data.FlickrStore: a function was passed an attribute argument that was not an attribute name string");
-			}
-		},
-
-		getFeatures: function(){
-			//	summary: 
-			//      See dojo.data.api.Read.getFeatures()
-			return {
-				'dojo.data.api.Read': true
-			};
-		},
-
-		getValue: function(item, attribute, defaultValue){
-			//	summary: 
-			//      See dojo.data.api.Read.getValue()
-			var values = this.getValues(item, attribute);
-			if(values && values.length > 0){
-				return values[0];
-			}
-			return defaultValue;
-		},
-
-		getAttributes: function(item){
-			//	summary: 
-			//      See dojo.data.api.Read.getAttributes()
-			return [
-				"title", "description", "author", "datePublished", "dateTaken", 
-				"imageUrl", "imageUrlSmall", "imageUrlMedium", "tags", "link"
-			]; 
-		},
-
-		hasAttribute: function(item, attribute){
-			//	summary: 
-			//      See dojo.data.api.Read.hasAttributes()
-			var v = this.getValue(item,attribute); 
-			if(v || v === "" || v === false){
-				return true;
-			}
-			return false;
-		},
-
-		isItemLoaded: function(item){
-			 //	summary: 
-			 //      See dojo.data.api.Read.isItemLoaded()
-			 return this.isItem(item);
-		},
-
-		loadItem: function(keywordArgs){
-			//	summary: 
-			//      See dojo.data.api.Read.loadItem()
-		},
-
-		getLabel: function(item){
-			//	summary: 
-			//      See dojo.data.api.Read.getLabel()
-			return this.getValue(item,this.label);
-		},
-		
-		getLabelAttributes: function(item){
-			//	summary: 
-			//      See dojo.data.api.Read.getLabelAttributes()
-			return [this.label];
-		},
-
-		containsValue: function(item, attribute, value){
-			//	summary: 
-			//      See dojo.data.api.Read.containsValue()
-			var values = this.getValues(item,attribute);
-			for(var i = 0; i < values.length; i++){
-				if(values[i] === value){
-					return true;
-				}
-			}
-			return false;
-		},
-
-		getValues: function(item, attribute){
-			//	summary: 
-			//      See dojo.data.api.Read.getValue()
-
-			this._assertIsItem(item);
-			this._assertIsAttribute(attribute);
-			var u = d.hitch(this, "_unescapeHtml");
-			var s = d.hitch(d.date.stamp, "fromISOString");
-			switch(attribute){
-				case "title":
-					return [ u(item.title) ];
-				case "author":
-					return [ u(item.author) ];
-				case "datePublished":
-					return [ s(item.published) ];
-				case "dateTaken":
-					return [ s(item.date_taken) ];
-				case "imageUrlSmall":
-					return [ item.media.m.replace(/_m\./, "_s.") ];
-				case "imageUrl":
-					return [ item.media.m.replace(/_m\./, ".") ];
-				case "imageUrlMedium":
-					return [ item.media.m ];
-				case "link":
-					return [ item.link ];
-				case "tags":
-					return item.tags.split(" ");
-				case "description":
-					return [ u(item.description) ];
-				default:
-					return [];
-			}
-		},
+	//Flag to allor control of if cache prevention is enabled or not.
+	urlPreventCache: true,
 
-		isItem: function(item){
-			//	summary: 
-			//      See dojo.data.api.Read.isItem()
-			if(item && item[this._storeRef] === this){
+	_assertIsItem: function(/* item */ item){
+		//	summary:
+		//      This function tests whether the item passed in is indeed an item in the store.
+		//	item:
+		//		The item to test for being contained by the store.
+		if(!this.isItem(item)){
+			throw new Error("dojox.data.FlickrStore: a function was passed an item argument that was not an item");
+		}
+	},
+
+	_assertIsAttribute: function(/* attribute-name-string */ attribute){
+		//	summary:
+		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
+		//	attribute:
+		//		The attribute to test for being contained by the store.
+		if(typeof attribute !== "string"){
+			throw new Error("dojox.data.FlickrStore: a function was passed an attribute argument that was not an attribute name string");
+		}
+	},
+
+	getFeatures: function(){
+		//	summary:
+		//      See dojo.data.api.Read.getFeatures()
+		return {
+			'dojo.data.api.Read': true
+		};
+	},
+
+	getValue: function(item, attribute, defaultValue){
+		//	summary:
+		//      See dojo.data.api.Read.getValue()
+		var values = this.getValues(item, attribute);
+		if(values && values.length > 0){
+			return values[0];
+		}
+		return defaultValue;
+	},
+
+	getAttributes: function(item){
+		//	summary:
+		//      See dojo.data.api.Read.getAttributes()
+		return [
+			"title", "description", "author", "datePublished", "dateTaken",
+			"imageUrl", "imageUrlSmall", "imageUrlMedium", "tags", "link"
+		];
+	},
+
+	hasAttribute: function(item, attribute){
+		//	summary:
+		//      See dojo.data.api.Read.hasAttributes()
+		var v = this.getValue(item,attribute);
+		if(v || v === "" || v === false){
+			return true;
+		}
+		return false;
+	},
+
+	isItemLoaded: function(item){
+		 //	summary:
+		 //      See dojo.data.api.Read.isItemLoaded()
+		 return this.isItem(item);
+	},
+
+	loadItem: function(keywordArgs){
+		//	summary:
+		//      See dojo.data.api.Read.loadItem()
+	},
+
+	getLabel: function(item){
+		//	summary:
+		//      See dojo.data.api.Read.getLabel()
+		return this.getValue(item,this.label);
+	},
+	
+	getLabelAttributes: function(item){
+		//	summary:
+		//      See dojo.data.api.Read.getLabelAttributes()
+		return [this.label];
+	},
+
+	containsValue: function(item, attribute, value){
+		//	summary:
+		//      See dojo.data.api.Read.containsValue()
+		var values = this.getValues(item,attribute);
+		for(var i = 0; i < values.length; i++){
+			if(values[i] === value){
 				return true;
 			}
-			return false;
-		},
-		
-		close: function(request){
-			//	summary: 
-			//      See dojo.data.api.Read.close()
-		},
-
-		_fetchItems: function(request, fetchHandler, errorHandler){
-			//	summary:
-			//		Fetch flickr items that match to a query
-			//	request:
-			//		A request object
-			//	fetchHandler:
-			//		A function to call for fetched items
-			//	errorHandler:
-			//		A function to call on error
-
-			var rq = request.query = request.query || {};
-
-			//Build up the content to send the request for.
-			var content = {
-				format: "json",
-				tagmode:"any"
-			};
-
-			d.forEach(
-				[ "tags", "tagmode", "lang", "id", "ids" ],
-				function(i){
-					if(rq[i]){ content[i] = rq[i]; }
-				}
-			);
-
-			content.id = rq.id || rq.userid || rq.groupid;
-
-			if(rq.userids){
-				content.ids = rq.userids;
-			}
-
-			//Linking this up to Flickr is a PAIN!
-			var handle = null;
-			var getArgs = {
-				url: dojox.data.FlickrStore.urlRegistry.match(request),
-				preventCache: this.urlPreventCache,
-				content: content
-			};
-			var myHandler = d.hitch(this, function(data){
-				if(!!handle){
-					d.disconnect(handle);
-				}
-
-				//Process the items...
-				fetchHandler(this._processFlickrData(data), request);
-			});
-			handle = d.connect("jsonFlickrFeed", myHandler);
-			var deferred = d.io.script.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){
-				d.disconnect(handle);
-				errorHandler(error, request);
-			});
-		},
-
-		_processFlickrData: function(data){
-			 var items = [];
-			 if(data.items){
-				 items = data.items;
-				 //Add on the store ref so that isItem can work.
-				 for(var i = 0; i < data.items.length; i++){
-					 var item = data.items[i];
-					 item[this._storeRef] = this;
-				 }
-			 }
-			 return items;
-		},
-
-		_unescapeHtml: function(/*String*/ str){
-			// summary: 
-			//		Utility function to un-escape XML special characters in an
-			//		HTML string.
-			//	str: String.
-			//		The string to un-escape
-			// returns: 
-			//		HTML String converted back to the normal text (unescaped)
-			//		characters (<,>,&, ", etc,).
-
-			//TODO: 
-			//		Check to see if theres already compatible escape() in
-			//		dojo.string or dojo.html
-			return 	str.replace(/&/gm, "&").
-						replace(/</gm, "<").
-						replace(/>/gm, ">").
-						replace(/"/gm, "\"").
-						replace(/'/gm, "'"); 
 		}
-	});
-
-	dojo.extend(dojox.data.FlickrStore, dojo.data.util.simpleFetch);
-
-	var feedsUrl = "http://api.flickr.com/services/feeds/";
+		return false;
+	},
+
+	getValues: function(item, attribute){
+		//	summary:
+		//      See dojo.data.api.Read.getValue()
+
+		this._assertIsItem(item);
+		this._assertIsAttribute(attribute);
+		var u = dojo.hitch(this, "_unescapeHtml");
+		var s = dojo.hitch(dojo.date.stamp, "fromISOString");
+		switch(attribute){
+			case "title":
+				return [ u(item.title) ];
+			case "author":
+				return [ u(item.author) ];
+			case "datePublished":
+				return [ s(item.published) ];
+			case "dateTaken":
+				return [ s(item.date_taken) ];
+			case "imageUrlSmall":
+				return [ item.media.m.replace(/_m\./, "_s.") ];
+			case "imageUrl":
+				return [ item.media.m.replace(/_m\./, ".") ];
+			case "imageUrlMedium":
+				return [ item.media.m ];
+			case "link":
+				return [ item.link ];
+			case "tags":
+				return item.tags.split(" ");
+			case "description":
+				return [ u(item.description) ];
+			default:
+				return [];
+		}
+	},
 
-	var reg = dojox.data.FlickrStore.urlRegistry = new d.AdapterRegistry(true);
+	isItem: function(item){
+		//	summary:
+		//      See dojo.data.api.Read.isItem()
+		if(item && item[this._storeRef] === this){
+			return true;
+		}
+		return false;
+	},
+	
+	close: function(request){
+		//	summary:
+		//      See dojo.data.api.Read.close()
+	},
+
+	_fetchItems: function(request, fetchHandler, errorHandler){
+		//	summary:
+		//		Fetch flickr items that match to a query
+		//	request:
+		//		A request object
+		//	fetchHandler:
+		//		A function to call for fetched items
+		//	errorHandler:
+		//		A function to call on error
+
+		var rq = request.query = request.query || {};
+
+		//Build up the content to send the request for.
+		var content = {
+			format: "json",
+			tagmode:"any"
+		};
+
+		dojo.forEach(
+			[ "tags", "tagmode", "lang", "id", "ids" ],
+			function(i){
+				if(rq[i]){ content[i] = rq[i]; }
+			}
+		);
 
-	reg.register("group pool",
-		function(request){ return !!request.query["groupid"]; },
-		feedsUrl+"groups_pool.gne"
-	);
+		content.id = rq.id || rq.userid || rq.groupid;
 
-	reg.register("default", 
-		function(request){ return true; },
-		feedsUrl+"photos_public.gne"
-	);
-})();
+		if(rq.userids){
+			content.ids = rq.userids;
+		}
 
+		//Linking this up to Flickr is a PAIN!
+		var handle = null;
+		var getArgs = {
+			url: dojox.data.FlickrStore.urlRegistry.match(request),
+			preventCache: this.urlPreventCache,
+			content: content
+		};
+		var myHandler = dojo.hitch(this, function(data){
+			if(!!handle){
+				dojo.disconnect(handle);
+			}
 
-//We have to define this because of how the Flickr API works.  
+			//Process the items...
+			fetchHandler(this._processFlickrData(data), request);
+		});
+		handle = dojo.connect("jsonFlickrFeed", myHandler);
+		var deferred = dojo.io.script.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);
+			errorHandler(error, request);
+		});
+	},
+
+	_processFlickrData: function(data){
+		 var items = [];
+		 if(data.items){
+			 items = data.items;
+			 //Add on the store ref so that isItem can work.
+			 for(var i = 0; i < data.items.length; i++){
+				 var item = data.items[i];
+				 item[this._storeRef] = this;
+			 }
+		 }
+		 return items;
+	},
+
+	_unescapeHtml: function(/*String*/ str){
+		// summary:
+		//		Utility function to un-escape XML special characters in an
+		//		HTML string.
+		//	str: String.
+		//		The string to un-escape
+		// returns:
+		//		HTML String converted back to the normal text (unescaped)
+		//		characters (<,>,&, ", etc,).
+
+		//TODO:
+		//		Check to see if theres already compatible escape() in
+		//		dojo.string or dojo.html
+		return 	str.replace(/&/gm, "&").
+					replace(/</gm, "<").
+					replace(/>/gm, ">").
+					replace(/"/gm, "\"").
+					replace(/'/gm, "'");
+	}
+});
+
+dojo.extend(dojox.data.FlickrStore, dojo.data.util.simpleFetch);
+
+var feedsUrl = "http://api.flickr.com/services/feeds/";
+
+var reg = dojox.data.FlickrStore.urlRegistry = new dojo.AdapterRegistry(true);
+
+reg.register("group pool",
+	function(request){ return !!request.query["groupid"]; },
+	feedsUrl+"groups_pool.gne"
+);
+
+reg.register("default",
+	function(request){ return true; },
+	feedsUrl+"photos_public.gne"
+);
+
+//We have to define this because of how the Flickr API works.
 //This somewhat stinks, but what can you do?
 if(!jsonFlickrFeed){
 	var jsonFlickrFeed = function(data){};
 }
+
+return dojox.data.FlickrStore;
+
+});
diff --git a/dojox/data/GoogleFeedStore.js b/dojox/data/GoogleFeedStore.js
index bb55773..077df99 100644
--- a/dojox/data/GoogleFeedStore.js
+++ b/dojox/data/GoogleFeedStore.js
@@ -1,11 +1,10 @@
-dojo.provide("dojox.data.GoogleFeedStore");
-dojo.experimental("dojox.data.GoogleFeedStore");
+define("dojox/data/GoogleFeedStore", ["dojo", "dojox", "dojox/data/GoogleSearchStore"], function(dojo, dojox) {
 
-dojo.require("dojox.data.GoogleSearchStore");
+dojo.experimental("dojox.data.GoogleFeedStore");
 
 dojo.declare("dojox.data.GoogleFeedStore", dojox.data.GoogleSearchStore,{
 	// summary:
-	//	A data store for retrieving RSS and Atom feeds from Google. The 
+	//	A data store for retrieving RSS and Atom feeds from Google. The
 	//  feeds can come from any source, which is specified in the "url"
 	//  parameter of the query passed to the "fetch" function.
 	//	The following attributes are supported on each item:
@@ -73,3 +72,6 @@ dojo.declare("dojox.data.GoogleFeedStore", dojox.data.GoogleSearchStore,{
 		return cb;
 	}
 });
+
+return dojox.data.GoogleFeedStore;
+});
diff --git a/dojox/data/GoogleSearchStore.js b/dojox/data/GoogleSearchStore.js
index 1912070..7e36896 100644
--- a/dojox/data/GoogleSearchStore.js
+++ b/dojox/data/GoogleSearchStore.js
@@ -1,4 +1,5 @@
-dojo.provide("dojox.data.GoogleSearchStore");
+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");
@@ -7,8 +8,6 @@ dojo.provide("dojox.data.GoogleNewsSearchStore");
 dojo.provide("dojox.data.GoogleBookSearchStore");
 dojo.provide("dojox.data.GoogleImageSearchStore");
 
-dojo.require("dojo.io.script");
-
 dojo.experimental("dojox.data.GoogleSearchStore");
 
 dojo.declare("dojox.data.GoogleSearchStore",null,{
@@ -77,7 +76,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 
 	// _attributes: Array
 	// The list of attributes that this store supports
-	_attributes: [	"unescapedUrl", "url", "visibleUrl", "cacheUrl", "title", 
+	_attributes: [	"unescapedUrl", "url", "visibleUrl", "cacheUrl", "title",
 			"titleNoFormatting", "content", "estimatedResultCount"],
 
 	// _aggregtedAttributes: Hash
@@ -101,7 +100,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 
 
 	// _queryAttrs: Hash
-	// Maps query hash keys to Google query parameters. 
+	// Maps query hash keys to Google query parameters.
 	_queryAttrs: {
 		text: 'q'
 	},
@@ -242,7 +241,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 
 		if(!request.query){
 			if(request.onError){
-				request.onError.call(scope, new Error(this.declaredClass + 
+				request.onError.call(scope, new Error(this.declaredClass +
 					": A query must be specified."));
 				return;
 			}
@@ -252,7 +251,7 @@ dojo.declare("dojox.data.GoogleSearchStore",null,{
 		var query = {};
 		for(var attr in this._queryAttrs) {
 			query[attr] = request.query[attr];
-		}		
+		}
 		request = {
 			query: query,
 			onComplete: request.onComplete,
@@ -499,7 +498,7 @@ dojo.declare("dojox.data.GoogleBlogSearchStore", dojox.data.GoogleSearchStore,{
 	//		</ul>
 	//		The query accepts one parameter: text - The string to search for
 	_type: "blogs",
-	_attributes: ["blogUrl", "postUrl", "title", "titleNoFormatting", "content", 
+	_attributes: ["blogUrl", "postUrl", "title", "titleNoFormatting", "content",
 			"author", "publishedDate"],
 	_aggregatedAttributes: { }
 });
@@ -644,8 +643,11 @@ dojo.declare("dojox.data.GoogleImageSearchStore", dojox.data.GoogleSearchStore,{
 	//		</ul>
 	//		The query accepts one parameter: text - The string to search for
 	_type: "images",
-	_attributes: ["title", "titleNoFormatting", "visibleUrl", "url", "unescapedUrl", 
-			"originalContextUrl", "width", "height", "tbWidth", "tbHeight", 
+	_attributes: ["title", "titleNoFormatting", "visibleUrl", "url", "unescapedUrl",
+			"originalContextUrl", "width", "height", "tbWidth", "tbHeight",
 			"tbUrl", "content", "contentNoFormatting"],
 	_aggregatedAttributes: { }
 });
+
+return dojox.data.GoogleSearchStore;
+});
diff --git a/dojox/data/HtmlStore.js b/dojox/data/HtmlStore.js
index c03e6e3..67010a2 100644
--- a/dojox/data/HtmlStore.js
+++ b/dojox/data/HtmlStore.js
@@ -1,13 +1,9 @@
-dojo.provide("dojox.data.HtmlStore");
-
-dojo.require("dojox.xml.parser");
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
+define("dojox/data/HtmlStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.HtmlStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
-		//		Initializer for the HTML table store.  
+		//		Initializer for the HTML table store.
 		//	description:
 		//		The HtmlStore can be created in one of two ways: a) by parsing an existing
 		//		table or list DOM node on the current page or b) by referencing an external url and giving
@@ -56,7 +52,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		//		dataId:	The id of the table element in the remote page
 		//		and the option:
 		//		trimWhitespace:  Trim off any surrounding whitespace from the headers (attribute
-		//			names) and text content of the items in question.  Default is false for 
+		//			names) and text content of the items in question.  Default is false for
 		//			backwards compatibility.
 		if(args && "urlPreventCache" in args){
 			this.urlPreventCache = args.urlPreventCache?true:false;
@@ -65,18 +61,21 @@ dojo.declare("dojox.data.HtmlStore", null, {
 			this.trimWhitespace = args.trimWhitespace?true:false;
 		}
 		if(args.url){
-			if(!args.dataId)
+			if(!args.dataId){
 				throw new Error("dojo.data.HtmlStore: Cannot instantiate using url without an id!");
+			}
 			this.url = args.url;
 			this.dataId = args.dataId;
 		}else{
 			if(args.dataId){
-				this._rootNode = dojo.byId(args.dataId);
-				this.dataId = this._rootNode.id;
-			}else{
-				this._rootNode = dojo.byId(this.dataId);
+				this.dataId = args.dataId;
 			}
-			this._indexItems();
+		}
+		if(args && "fetchOnCreate" in args){
+			this.fetchOnCreate = args.fetchOnCreate?true:false;
+		}
+		if(this.fetchOnCreate && this.dataId){
+			this.fetch();
 		}
 	},
 
@@ -89,16 +88,22 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	dataId: "",
 
 	// trimWhitepace: [public] boolean
-	//		Boolean flag to denote if the store should trim whitepace around 
+	//		Boolean flag to denote if the store should trim whitepace around
 	//		header and data content of a node.  This matters if reformatters
 	//		alter the white spacing around the tags.  The default is false for
 	//		backwards compat.
-	trimWhitespace: false, 
+	trimWhitespace: false,
 
 	// urlPreventCache: [public] boolean
 	//		Flag to denote if peventCache should be used on xhrGet calls.
 	urlPreventCache: false,
 	
+	// fetchOnCreate: [public] boolean
+	// 		Flag to denote if it should try to load from a data id (nested in the page)
+	//		The moment the store is created, instead of waiting for first
+	//		fetch call.
+	fetchOnCreate: false,
+	
 	_indexItems: function(){
 		// summary:
 		//		Function to index items found under the id.
@@ -111,14 +116,12 @@ dojo.declare("dojox.data.HtmlStore", null, {
 			}
 			var i;
 			for(i=0; i<this._rootNode.rows.length; i++){
-				this._rootNode.rows[i].store = this;
 				this._rootNode.rows[i]._ident = i+1;
 			}
 		}else{//lists
 			var c=1;
 			for(i=0; i<this._rootNode.childNodes.length; i++){
 				if(this._rootNode.childNodes[i].nodeType === 1){
-					this._rootNode.childNodes[i].store = this;
 					this._rootNode.childNodes[i]._ident = c;
 					c++;
 				}
@@ -128,13 +131,13 @@ dojo.declare("dojox.data.HtmlStore", null, {
 
 	_getHeadings: function(){
 		//	summary:
-		//		Function to load the attribute names from the table header so that the 
+		//		Function to load the attribute names from the table header so that the
 		//		attributes (cells in a row), can have a reasonable name.
 		//      For list items, returns single implicit heading, ["name"]
 		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); 
+				var text = dojox.xml.parser.textContent(th);
 				this._headings.push(this.trimWhitespace?dojo.trim(text):text);
 			}));
 		}else{
@@ -164,9 +167,9 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojo.data.HtmlStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -174,12 +177,12 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	_assertIsAttribute: function(/* String */ attribute){
 		//	summary:
 		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
 		//
 		//	returns:
 		//		Returns the index (column) that the attribute resides in the row.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojo.data.HtmlStore: a function was passed an attribute argument that was not an attribute name string");
 			return -1;
 		}
@@ -190,18 +193,18 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	 dojo.data.api.Read API
 ***************************************/
 	
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
 	},
 
-	getValues: function(/* item */ item, 
+	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 
 		this._assertIsItem(item);
@@ -219,7 +222,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -232,15 +235,15 @@ dojo.declare("dojox.data.HtmlStore", null, {
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		return this.getValues(item, attribute).length > 0;
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -249,22 +252,22 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -285,22 +288,19 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
-		if(something && something.store && something.store === this){
-			return true; //boolean
-		}
-		return false; //boolean
+		return something && dojo.isDescendant(something, this._rootNode);
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		return this.isItem(something);
 	},
 
 	loadItem: function(/* Object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
@@ -329,6 +329,8 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		}else{
 			if(!this.url){
 				this._rootNode = dojo.byId(this.dataId);
+				this._indexItems();
+				this._finishFetchItems(request, fetchHandler, errorHandler);
 			}else{
 				var getArgs = {
 						url: this.url,
@@ -372,7 +374,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 		var items = [];
 		var arrayOfAllItems = this._getAllItems();
 		if(request.query){
-			var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; 
+			var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;
 			items = [];
 
 			//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
@@ -402,17 +404,17 @@ dojo.declare("dojox.data.HtmlStore", null, {
 			}
 			fetchHandler(items, request);
 		}else{
-			// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
+			// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
 			// of the internal list so that multiple callers can get listsand sort without affecting each other.
 			if(arrayOfAllItems.length> 0){
-				items = arrayOfAllItems.slice(0,arrayOfAllItems.length); 
+				items = arrayOfAllItems.slice(0,arrayOfAllItems.length);
 			}
 			fetchHandler(items, request);
 		}
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
@@ -427,7 +429,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this.isItem(item)){
 			if(item.cells){
@@ -440,7 +442,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		if(item.cells){
 			return null;
@@ -454,7 +456,7 @@ dojo.declare("dojox.data.HtmlStore", null, {
 ***************************************/
 
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		this._assertIsItem(item);
 		if(this.hasAttribute(item, "name")){
@@ -465,14 +467,14 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Identity.getIdentityAttributes()
 		 //Identity isn't taken from a public attribute.
 		 return null;
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 		var identity = keywordArgs.identity;
 		var self = this;
@@ -556,3 +558,5 @@ dojo.declare("dojox.data.HtmlStore", null, {
 	}
 });
 dojo.extend(dojox.data.HtmlStore,dojo.data.util.simpleFetch);
+return dojox.data.HtmlStore;
+});
diff --git a/dojox/data/HtmlTableStore.js b/dojox/data/HtmlTableStore.js
index f46e33f..0f3a9af 100644
--- a/dojox/data/HtmlTableStore.js
+++ b/dojox/data/HtmlTableStore.js
@@ -1,14 +1,10 @@
-dojo.provide("dojox.data.HtmlTableStore");
-
-dojo.require("dojox.xml.parser");
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
+define("dojox/data/HtmlTableStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.HtmlTableStore", null, {
 	constructor: function(/*Object*/args){
 		dojo.deprecated("dojox.data.HtmlTableStore", "Please use dojox.data.HtmlStore");
 		//	summary:
-		//		Initializer for the HTML table store.  
+		//		Initializer for the HTML table store.
 		//	description:
 		//		The HtmlTableStore can be created in one of two ways: a) by parsing an existing
 		//		table DOM node on the current page or b) by referencing an external url and giving
@@ -70,7 +66,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 
 	_getHeadings: function(){
 		//	summary:
-		//		Function to load the attribute names from the table header so that the 
+		//		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){
@@ -91,9 +87,9 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojo.data.HtmlTableStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -101,12 +97,12 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	_assertIsAttribute: function(/* String */ attribute){
 		//	summary:
 		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
 		//
 		//	returns:
 		//		Returns the index (column) that the attribute resides in the row.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojo.data.HtmlTableStore: a function was passed an attribute argument that was not an attribute name string");
 			return -1;
 		}
@@ -117,18 +113,18 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
      dojo.data.api.Read API
 ***************************************/
 	
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		return (values.length > 0)?values[0]:defaultValue; //Object || int || Boolean
 	},
 
-	getValues: function(/* item */ item, 
+	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 
 		this._assertIsItem(item);
@@ -141,7 +137,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -154,15 +150,15 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		return this.getValues(item, attribute).length > 0;
 	},
 
-	containsValue: function(/* item */ item, 
-							/* attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -171,22 +167,22 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -207,7 +203,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		if(something && something.store && something.store === this){
 			return true; //boolean
@@ -216,13 +212,13 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		return this.isItem(something);
 	},
 
 	loadItem: function(/* Object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		this._assertIsItem(keywordArgs.item);
 	},
@@ -300,7 +296,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 		var items = null;
 		var arrayOfAllItems = this._getAllItems();
 		if(request.query){
-			var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; 
+			var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;
 			items = [];
 
 			//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
@@ -330,17 +326,17 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 			}
 			fetchHandler(items, request);
 		}else{
-			// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
+			// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
 			// of the internal list so that multiple callers can get listsand sort without affecting each other.
 			if(arrayOfAllItems.length> 0){
-				items = arrayOfAllItems.slice(0,arrayOfAllItems.length); 
+				items = arrayOfAllItems.slice(0,arrayOfAllItems.length);
 			}
 			fetchHandler(items, request);
 		}
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true,
@@ -355,7 +351,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this.isItem(item))
 			return "Table Row #" + this.getIdentity(item);
@@ -363,7 +359,7 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		return null;
 	},
@@ -373,28 +369,28 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 ***************************************/
 
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		this._assertIsItem(item);
-		//Opera doesn't support the sectionRowIndex, 
-		//So, have to call the indexOf to locate it. 
+		//Opera doesn't support the sectionRowIndex,
+		//So, have to call the indexOf to locate it.
 		//Blah.
 		if(!dojo.isOpera){
-			return item.sectionRowIndex; // int	
+			return item.sectionRowIndex; // int
 		}else{
 			return (dojo.indexOf(this._rootNode.rows, item) - 1) // int
 		}
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Identity.getIdentityAttributes()
 		 //Identity isn't taken from a public attribute.
 		 return null;
 	},
 
 	fetchItemByIdentity: function(keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 		var identity = keywordArgs.identity;
 		var self = this;
@@ -468,3 +464,6 @@ dojo.declare("dojox.data.HtmlTableStore", null, {
 	}
 });
 dojo.extend(dojox.data.HtmlTableStore,dojo.data.util.simpleFetch);
+
+return dojox.data.HtmlTableStore;
+});
diff --git a/dojox/data/JsonQueryRestStore.js b/dojox/data/JsonQueryRestStore.js
index 799767d..aedd94a 100644
--- a/dojox/data/JsonQueryRestStore.js
+++ b/dojox/data/JsonQueryRestStore.js
@@ -1,10 +1,8 @@
-dojo.provide("dojox.data.JsonQueryRestStore");
-dojo.require("dojox.data.JsonRestStore");
-dojo.require("dojox.data.util.JsonQuery");
+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 
+dojo.requireIf(!!dojox.data.ClientFilter,"dojox.json.query"); // this is so we can perform queries locally
 
-// this is an extension of JsonRestStore to convert object attribute queries to 
+// this is an extension of JsonRestStore to convert object attribute queries to
 // JSONQuery/JSONPath syntax to be sent to the server. This also enables
 //	JSONQuery/JSONPath queries to be performed locally if dojox.data.ClientFilter
 //	has been loaded
@@ -13,3 +11,6 @@ dojo.declare("dojox.data.JsonQueryRestStore",[dojox.data.JsonRestStore,dojox.dat
 		return item.__id && (item.__id.indexOf("#") == -1) && this.inherited(arguments);
 	}
 });
+
+return dojox.data.JsonQueryRestStore;
+});
diff --git a/dojox/data/JsonRestStore.js b/dojox/data/JsonRestStore.js
index 0f7f921..9e678eb 100644
--- a/dojox/data/JsonRestStore.js
+++ b/dojox/data/JsonRestStore.js
@@ -1,7 +1,4 @@
-dojo.provide("dojox.data.JsonRestStore");
-
-dojo.require("dojox.data.ServiceStore");
-dojo.require("dojox.rpc.JsonRest");
+define("dojox/data/JsonRestStore", ["dojo", "dojox", "dojox/rpc/JsonRest", "dojox/data/ServiceStore"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.JsonRestStore",
 	dojox.data.ServiceStore,
@@ -480,3 +477,6 @@ dojox.data._getStoreForItem = function(item){
 	return null;
 };
 dojox.json.ref._useRefs = true; // Use referencing when identifiable objects are referenced
+
+return dojox.data.JsonRestStore;
+});
diff --git a/dojox/data/KeyValueStore.js b/dojox/data/KeyValueStore.js
index 5484a1e..68c66ea 100644
--- a/dojox/data/KeyValueStore.js
+++ b/dojox/data/KeyValueStore.js
@@ -1,19 +1,16 @@
-dojo.provide("dojox.data.KeyValueStore");
-
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.simpleFetch");
+define("dojox/data/KeyValueStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter"], function(dojo, dojox) {
 
 dojo.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 
+	//		array, JSON string, or URL as the data source.  Data is expected to be in the
 	//		following format:
 	//			[
 	//				{ "key1": "value1" },
 	//				{ "key2": "value2" }
 	//			]
-	//		This is to mimic the Java Properties file format.  Each 'item' from this store 
-	//		is a JS object representing a key-value pair.  If an item in the above array has 
+	//		This is to mimic the Java Properties file format.  Each 'item' from this store
+	//		is a JS object representing a key-value pair.  If an item in the above array has
 	//		more than one key/value pair, only the first will be used/accessed.
 	constructor: function(/* Object */ keywordParameters){
 		//	summary: constructor
@@ -28,9 +25,9 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 		this._keyAttribute = "key";
 		this._valueAttribute = "value";
 		this._storeProp = "_keyValueStore";
-		this._features = {	
+		this._features = {
 			'dojo.data.api.Read': true,
-			'dojo.data.api.Identity': true 
+			'dojo.data.api.Identity': true
 		};
 		this._loadInProgress = false;	//Got to track the initial load to prevent duelling loads of the dataset.
 		this._queuedFetches = [];
@@ -44,14 +41,14 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 
 	//urlPreventCache: boolean
 	//Controls if urlPreventCache should be used with underlying xhrGet.
-	urlPreventCache: false, 
+	urlPreventCache: false,
 	
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojox.data.KeyValueStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -59,7 +56,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	_assertIsAttribute: function(/* item */ item, /* String */ attribute){
 		//	summary:
 		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
 		if(!dojo.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");
@@ -69,10 +66,10 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 /***************************************
      dojo.data.api.Read API
 ***************************************/
-	getValue: function(	/* item */ item, 
-						/* attribute-name-string */ attribute, 
+	getValue: function(	/* item */ item,
+						/* attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(item, attribute);
@@ -90,7 +87,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 
 	getValues: function(/* item */ item,
 						/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 		// 		Key/Value syntax does not support multi-valued attributes, so this is just a
 		// 		wrapper function for getValue().
@@ -99,14 +96,14 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	getAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		return [this._keyAttribute, this._valueAttribute, item[this._keyAttribute]];
 	},
 
 	hasAttribute: function(	/* item */ item,
 							/* attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		this._assertIsItem(item);
 		this._assertIsAttribute(item, attribute);
@@ -114,9 +111,9 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	containsValue: function(/* item */ item,
-							/* attribute-name-string */ attribute, 
+							/* attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -125,22 +122,22 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute || attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute || attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -161,7 +158,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	isItem: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		if(something && something[this._storeProp] === this){
 			return true; //Boolean
@@ -170,14 +167,14 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		//		The KeyValueStore always loads all items, so if it's an item, then it's loaded.
 		return this.isItem(something); //Boolean
 	},
 
 	loadItem: function(/* object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		//	description:
 		//		The KeyValueStore always loads all items, so if it's an item, then it's loaded.
@@ -188,24 +185,24 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return this._features; //Object
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.close()
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		return item[this._keyAttribute];
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		return [this._keyAttribute];
 	},
@@ -216,7 +213,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	_fetchItems: function(	/* Object */ keywordArgs,
 							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		
 		var self = this;
@@ -225,7 +222,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 			var items = null;
 			if(requestArgs.query){
 				items = [];
-				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; 
+				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
 
 				//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
 				//same value for each item examined.  Much more efficient.
@@ -261,10 +258,10 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 					}
 				}
 			}else{
-				// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
+				// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
 				// of the internal list so that multiple callers can get lists and sort without affecting each other.
 				if(arrayOfAllItems.length> 0){
-					items = arrayOfAllItems.slice(0,arrayOfAllItems.length); 
+					items = arrayOfAllItems.slice(0,arrayOfAllItems.length);
 				}
 			}
 			findCallback(items, requestArgs);
@@ -275,14 +272,14 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 		}else{
 			if(this.url !== ""){
 				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be 
+				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
 					this._queuedFetches.push({args: keywordArgs, filter: filter});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self.url, 
+							url: self.url,
 							handleAs: "json-comment-filtered",
 							preventCache: this.urlPreventCache
 						};
@@ -313,7 +310,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	_handleQueuedFetches: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function to execute delayed request in the store.
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
@@ -322,7 +319,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 				var delayedFilter = fData.filter;
 				var delayedQuery = fData.args;
 				if(delayedFilter){
-					delayedFilter(delayedQuery, this._arrayOfAllItems); 
+					delayedFilter(delayedQuery, this._arrayOfAllItems);
 				}else{
 					this.fetchItemByIdentity(fData.args);
 				}
@@ -355,7 +352,7 @@ dojo.declare("dojox.data.KeyValueStore", null, {
      dojo.data.api.Identity API
 ***************************************/
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		if(this.isItem(item)){
 			return item[this._keyAttribute]; //String
@@ -364,13 +361,13 @@ dojo.declare("dojox.data.KeyValueStore", null, {
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentifierAttributes()
 		return [this._keyAttribute];
 	},
 
 	fetchItemByIdentity: function(/* object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 		keywordArgs.oldOnItem = keywordArgs.onItem;
 		keywordArgs.onItem = null;
@@ -389,3 +386,5 @@ 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;
+});
diff --git a/dojox/data/OpenSearchStore.js b/dojox/data/OpenSearchStore.js
index 39e2a0b..2a429d5 100644
--- a/dojox/data/OpenSearchStore.js
+++ b/dojox/data/OpenSearchStore.js
@@ -9,7 +9,7 @@ dojo.experimental("dojox.data.OpenSearchStore");
 dojo.declare("dojox.data.OpenSearchStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
-		//		Initializer for the OpenSearchStore store.  
+		//		Initializer for the OpenSearchStore store.
 		//	description:
 		//		The OpenSearchStore is a Datastore interface to any search
 		//		engine that implements the open search specifications.
@@ -29,7 +29,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 		});
 		def.addCallback(this, "_processOsdd");
 		def.addErrback(function(){
-			throw new Error("Unable to load OpenSearch Description document from " . args.url);					
+			throw new Error("Unable to load OpenSearch Description document from " . args.url);
 		});
 	},
 	
@@ -54,9 +54,9 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojox.data.OpenSearchStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -64,15 +64,15 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		//	summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.OpenSearchStore: a function was passed an attribute argument that was not an attribute name string");
 		}
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
@@ -80,7 +80,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values){
@@ -90,13 +90,13 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getAttributes()
-		return ["content"]; 
+		return ["content"];
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.hasAttributes()
 		if(this.getValue(item,attribute)){
 			return true;
@@ -105,30 +105,30 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary: 
+		 //	summary:
 		 //      See dojo.data.api.Read.isItemLoaded()
 		 return this.isItem(item);
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getLabel()
 		return undefined;
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getLabelAttributes()
 		return null;
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
@@ -140,7 +140,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 
 		this._assertIsItem(item);
@@ -153,7 +153,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
@@ -162,19 +162,19 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 	},
 	
 	close: function(request){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.close()
 	},
 	
 	process: function(data){
-		// This should return an array of items.  This would be the function to override if the 
+		// This should return an array of items.  This would be the function to override if the
 		// developer wanted to customize the processing/parsing of the entire batch of search
 		// results.
 		return this["_processOSD"+this.contentType](data);
 	},
 	
 	processItem: function(item, attribute){
-		// This returns the text that represents the item.  If a developer wanted to customize 
+		// This returns the text that represents the item.  If a developer wanted to customize
 		// how an individual item is rendered/parsed, they'd override this function.
 		return this["_processItem"+this.contentType](item.node, attribute);
 	},
@@ -212,7 +212,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 			request.query={};
 		}
 
-		//Build up the content using information from the request 
+		//Build up the content using information from the request
 		var self = this;
 		var url = this._createSearchUrl(request);
 		var getArgs = {
@@ -361,7 +361,7 @@ dojo.declare("dojox.data.OpenSearchStore", null, {
 					this.contentType = this.XML_CONTENT_TYPE_STRING;
 					break;
 			}
-		} 
+		}
 	}
 });
 dojo.extend(dojox.data.OpenSearchStore,dojo.data.util.simpleFetch);
diff --git a/dojox/data/OpmlStore.js b/dojox/data/OpmlStore.js
index 280aa2c..f42fc64 100644
--- a/dojox/data/OpmlStore.js
+++ b/dojox/data/OpmlStore.js
@@ -1,11 +1,8 @@
-dojo.provide("dojox.data.OpmlStore");
-
-dojo.require("dojo.data.util.filter");
-dojo.require("dojo.data.util.simpleFetch");
+define("dojox/data/OpmlStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.OpmlStore", null, {
 	/* summary:
-	 *   The OpmlStore implements the dojo.data.api.Read API.  
+	 *   The OpmlStore implements the dojo.data.api.Read API.
 	 */
 	 
 	/* examples:
@@ -48,7 +45,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	urlPreventCache: false,
 
 	_assertIsItem: function(/* item */ item){
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojo.data.OpmlStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -56,7 +53,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	_assertIsAttribute: function(/* item || String */ attribute){
 		//	summary:
 		//      This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
 		if(!dojo.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");
@@ -72,8 +69,8 @@ dojo.declare("dojox.data.OpmlStore", null, {
 		var i, childNode;
 		for(i = 0; i < childNodes.length; ++i){
 			childNode = childNodes[i];
-			if(childNode.nodeType != 1){ 
-				nodesToRemove.push(childNode); 
+			if(childNode.nodeType != 1){
+				nodesToRemove.push(childNode);
 			}
 		}
 		for(i = 0; i < nodesToRemove.length; ++i){
@@ -140,11 +137,11 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	_getItemsArray: function(/*object?*/queryOptions){
-		//	summary: 
+		//	summary:
 		//		Internal function to determine which list of items to search over.
 		//	queryOptions: The query options parameter, if any.
 		if(queryOptions && queryOptions.deep){
-			return this._arrayOfAllItems; 
+			return this._arrayOfAllItems;
 		}
 		return this._arrayOfTopLevelItems;
 	},
@@ -155,7 +152,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	getValue: function( /* item */ item,
 						/* attribute || attribute-name-string */ attribute,
 						/* value? */ defaultValue){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -169,7 +166,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	
 	getValues: function(/* item */ item,
 						/* attribute || attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValues()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -185,7 +182,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 	
 	getAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		var attributes = [];
@@ -203,15 +200,15 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	
 	hasAttribute: function( /* item */ item,
 							/* attribute || attribute-name-string */ attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttribute()
 		return (this.getValues(item, attribute).length > 0); //Boolean
 	},
 	
-	containsValue: function(/* item */ item, 
-							/* attribute || attribute-name-string */ attribute, 
+	containsValue: function(/* item */ item,
+							/* attribute || attribute-name-string */ attribute,
 							/* anything */ value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		var regexp = undefined;
 		if(typeof value === "string"){
@@ -220,22 +217,22 @@ dojo.declare("dojox.data.OpmlStore", null, {
 		return this._containsValue(item, attribute, value, regexp); //boolean.
 	},
 
-	_containsValue: function(	/* item */ item, 
-								/* attribute || attribute-name-string */ attribute, 
+	_containsValue: function(	/* item */ item,
+								/* attribute || attribute-name-string */ attribute,
 								/* anything */ value,
 								/* RegExp?*/ regexp){
-		//	summary: 
+		//	summary:
 		//		Internal function for looking at the values contained by the item.
-		//	description: 
-		//		Internal function for looking at the values contained by the item.  This 
+		//	description:
+		//		Internal function for looking at the values contained by the item.  This
 		//		function allows for denoting if the comparison should be case sensitive for
 		//		strings or not (for handling filtering cases where string case should not matter)
-		//	
+		//
 		//	item:
 		//		The data item to examine for attribute values.
 		//	attribute:
 		//		The attribute to inspect.
-		//	value:	
+		//	value:
 		//		The value to match.
 		//	regexp:
 		//		Optional regular expression generated off value if value was of string type to handle wildcarding.
@@ -256,28 +253,28 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 			
 	isItem: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		//	description:
 		//		Four things are verified to ensure that "something" is an item:
 		//		something can not be null, the nodeType must be an XML Element,
 		//		the tagName must be "outline", and the node must be a member of
-		//		XML document for this datastore. 
-		return (something && 
-				something.nodeType == 1 && 
+		//		XML document for this datastore.
+		return (something &&
+				something.nodeType == 1 &&
 				something.tagName == 'outline' &&
 				something.ownerDocument === this._xmlData); //Boolean
 	},
 	
 	isItemLoaded: function(/* anything */ something){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItemLoaded()
 		// 		OpmlStore loads every item, so if it's an item, then it's loaded.
 		return this.isItem(something); //Boolean
 	},
 	
 	loadItem: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 		//	description:
 		//		The OpmlStore always loads all items, so if it's an item, then it's loaded.
@@ -287,7 +284,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		if(this.isItem(item)){
 			return this.getValue(item,this.label); //String
@@ -296,7 +293,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		return [this.label]; //array
 	},
@@ -304,10 +301,10 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	// The dojo.data.api.Read.fetch() function is implemented as
 	// a mixin from dojo.data.util.simpleFetch.
 	// That mixin requires us to define _fetchItems().
-	_fetchItems: function(	/* Object */ keywordArgs, 
-							/* Function */ findCallback, 
+	_fetchItems: function(	/* Object */ keywordArgs,
+							/* Function */ findCallback,
 							/* Function */ errorCallback){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.util.simpleFetch.fetch()
 		
 		var self = this;
@@ -315,7 +312,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 			var items = null;
 			if(requestArgs.query){
 				items = [];
-				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false; 
+				var ignoreCase = requestArgs.queryOptions ? requestArgs.queryOptions.ignoreCase : false;
 
 				//See if there are any string values that can be regexp parsed first to avoid multiple regexp gens on the
 				//same value for each item examined.  Much more efficient.
@@ -341,10 +338,10 @@ dojo.declare("dojox.data.OpmlStore", null, {
 					}
 				}
 			}else{
-				// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort 
+				// We want a copy to pass back in case the parent wishes to sort the array.  We shouldn't allow resort
 				// of the internal list so that multiple callers can get lists and sort without affecting each other.
 				if(arrayOfItems.length> 0){
-					items = arrayOfItems.slice(0,arrayOfItems.length); 
+					items = arrayOfItems.slice(0,arrayOfItems.length);
 				}
 			}
 			findCallback(items, requestArgs);
@@ -355,7 +352,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 		}else{
 
 			//If fetches come in before the loading has finished, but while
-			//a load is in progress, we have to defer the fetching to be 
+			//a load is in progress, we have to defer the fetching to be
 			//invoked in the callback.
 			if(this._loadInProgress){
 				this._queuedFetches.push({args: keywordArgs, filter: filter});
@@ -363,7 +360,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 				if(this.url !== ""){
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self.url, 
+							url: self.url,
 							handleAs: "xml",
 							preventCache: self.urlPreventCache
 						};
@@ -400,7 +397,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
      dojo.data.api.Identity API
 ***************************************/
 	getIdentity: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.getIdentity()
 		if(this.isItem(item)){
 			//No ther way to do this other than O(n) without
@@ -415,7 +412,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	fetchItemByIdentity: function(/* Object */ keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Identity.fetchItemByIdentity()
 
 		//Hasn't loaded yet, we have to trigger the load.
@@ -423,14 +420,14 @@ dojo.declare("dojox.data.OpmlStore", null, {
 			var self = this;
 			if(this.url !== ""){
 				//If fetches come in before the loading has finished, but while
-				//a load is in progress, we have to defer the fetching to be 
+				//a load is in progress, we have to defer the fetching to be
 				//invoked in the callback.
 				if(this._loadInProgress){
 					this._queuedFetches.push({args: keywordArgs});
 				}else{
 					this._loadInProgress = true;
 					var getArgs = {
-							url: self.url, 
+							url: self.url,
 							handleAs: "xml"
 						};
 					var getHandler = dojo.xhrGet(getArgs);
@@ -486,7 +483,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	getIdentityAttributes: function(/* item */ item){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Identity.getIdentifierAttributes()
 		 
 		 //Identity isn't a public attribute in the item, it's the node count.
@@ -495,7 +492,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	_handleQueuedFetches: function(){
-		//	summary: 
+		//	summary:
 		//		Internal function to execute delayed request in the store.
 		//Execute any deferred fetches now.
 		if(this._queuedFetches.length > 0){
@@ -504,7 +501,7 @@ dojo.declare("dojox.data.OpmlStore", null, {
 				var delayedQuery = fData.args;
 				var delayedFilter = fData.filter;
 				if(delayedFilter){
-					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions)); 
+					delayedFilter(delayedQuery, this._getItemsArray(delayedQuery.queryOptions));
 				}else{
 					this.fetchItemByIdentity(delayedQuery);
 				}
@@ -514,10 +511,13 @@ dojo.declare("dojox.data.OpmlStore", null, {
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Read.close()
 	}
 });
 //Mix in the simple fetch implementation to this class.
 dojo.extend(dojox.data.OpmlStore,dojo.data.util.simpleFetch);
+
+return dojox.data.OpmlStore;
+});
 	
diff --git a/dojox/data/PersevereStore.js b/dojox/data/PersevereStore.js
index fd4d243..e64f695 100644
--- a/dojox/data/PersevereStore.js
+++ b/dojox/data/PersevereStore.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.data.PersevereStore");
-dojo.require("dojox.data.JsonQueryRestStore");
-dojo.require("dojox.rpc.Client"); // Persevere supports this and it improves reliability
+define("dojox/data/PersevereStore", ["dojo", "dojox", "dojox/data/JsonQueryRestStore", "dojox/rpc/Client"], function(dojo, dojox) {
 
 // PersevereStore is an extension of JsonRestStore to handle Persevere's special features
 
@@ -8,7 +6,7 @@ dojox.json.ref.serializeFunctions = true; // Persevere supports persisted functi
 
 dojo.declare("dojox.data.PersevereStore",dojox.data.JsonQueryRestStore,{
 	useFullIdInQueries: true, // in JSONQuerys use the full id
-	jsonQueryPagination: false // use the Range headers instead	
+	jsonQueryPagination: false // use the Range headers instead
 });
 	
 dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync){
@@ -59,7 +57,7 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 			if(methodsDefinitions && methodsTarget){
 				for(var j in methodsDefinitions){
 					var methodDef = methodsDefinitions[j];
-					// if any method definitions indicate that the method should run on the server, than add 
+					// if any method definitions indicate that the method should run on the server, than add
 					// it to the prototype as a JSON-RPC method
 					if(methodDef.runAt != "client" && !methodsTarget[j]){
 						methodsTarget[j] = (function(methodName){
@@ -68,7 +66,7 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 								var deferred = dojo.rawXhrPost({
 									url: this.__id,
 									// the JSON-RPC call
-									postData: dojo.toJson({
+									postData: dojox.json.ref.toJson({
 										method: methodName,
 										id: callId++,
 										params: dojo._toArray(arguments)
@@ -83,7 +81,7 @@ dojox.data.PersevereStore.getStores = function(/*String?*/path,/*Boolean?*/sync)
 								});
 								return deferred;
 							}
-						})(j);	
+						})(j);
 					}
 				}
 			}
@@ -108,3 +106,7 @@ dojox.data.PersevereStore.addProxy = function(){
 	dojo.require("dojox.io.xhrPlugins"); // also not necessary, but we can register that Persevere supports proxying
 	dojox.io.xhrPlugins.addProxy("/proxy/");
 };
+
+return dojox.data.PersevereStore;
+
+});
diff --git a/dojox/data/PicasaStore.js b/dojox/data/PicasaStore.js
index 4b5bc1f..ea7902b 100644
--- a/dojox/data/PicasaStore.js
+++ b/dojox/data/PicasaStore.js
@@ -1,18 +1,14 @@
-dojo.provide("dojox.data.PicasaStore");
-
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.io.script");
-dojo.require("dojo.date.stamp");
+define("dojox/data/PicasaStore", ["dojo", "dojox", "dojo/io/script", "dojo/data/util/simpleFetch", "dojo/date/stamp"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.PicasaStore", null, {
 	constructor: function(/*Object*/args){
 		//	summary:
-		//		Initializer for the PicasaStore store.  
+		//		Initializer for the PicasaStore store.
 		//	description:
 		//		The PicasaStore is a Datastore interface to one of the basic services
 		//		of the Picasa service, the public photo feed.  This does not provide
 		//		access to all the services of Picasa.
-		//		This store cannot do * and ? filtering as the picasa service 
+		//		This store cannot do * and ? filtering as the picasa service
 		//		provides no interface for wildcards.
 		if(args && args.label){
 			this.label = args.label;
@@ -46,9 +42,9 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	_assertIsItem: function(/* item */ item){
 		//	summary:
 		//      This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojox.data.PicasaStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -56,15 +52,15 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		//	summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.PicasaStore: a function was passed an attribute argument that was not an attribute name string");
 		}
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
@@ -72,7 +68,7 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 		var values = this.getValues(item, attribute);
 		if(values && values.length > 0){
@@ -82,16 +78,16 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getAttributes()
-		 return ["id", "published", "updated", "category", "title$type", "title", 
-			 "summary$type", "summary", "rights$type", "rights", "link", "author", 
+		 return ["id", "published", "updated", "category", "title$type", "title",
+			 "summary$type", "summary", "rights$type", "rights", "link", "author",
 			 "gphoto$id", "gphoto$name", "location", "imageUrlSmall", "imageUrlMedium",
-			 "imageUrl", "datePublished", "dateTaken","description"]; 
+			 "imageUrl", "datePublished", "dateTaken","description"];
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.hasAttributes()
 		if(this.getValue(item,attribute)){
 			return true;
@@ -100,30 +96,30 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary: 
+		 //	summary:
 		 //      See dojo.data.api.Read.isItemLoaded()
 		 return this.isItem(item);
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getLabel()
 		return this.getValue(item,this.label);
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getLabelAttributes()
 		return [this.label];
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.containsValue()
 		var values = this.getValues(item,attribute);
 		for(var i = 0; i < values.length; i++){
@@ -135,7 +131,7 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	},
 
 	getValues: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.getValue()
 
 		this._assertIsItem(item);
@@ -167,7 +163,7 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.isItem()
 		if(item && item[this._storeRef] === this){
 			return true;
@@ -176,7 +172,7 @@ dojo.declare("dojox.data.PicasaStore", null, {
 	},
 	
 	close: function(request){
-		//	summary: 
+		//	summary:
 		//      See dojo.data.api.Read.close()
 	},
 
@@ -264,9 +260,13 @@ dojo.declare("dojox.data.PicasaStore", null, {
 		//TODO: Check to see if theres already compatible escape() in dojo.string or dojo.html
 		if(str){
 			str = str.replace(/&/gm, "&").replace(/</gm, "<").replace(/>/gm, ">").replace(/"/gm, "\"");
-			str = str.replace(/'/gm, "'"); 
+			str = str.replace(/'/gm, "'");
 		}
 		return str;
 	}
 });
-dojo.extend(dojox.data.PicasaStore,dojo.data.util.simpleFetch);										  
+dojo.extend(dojox.data.PicasaStore,dojo.data.util.simpleFetch);
+
+return dojox.data.PicasaStore;
+
+});
diff --git a/dojox/data/QueryReadStore.js b/dojox/data/QueryReadStore.js
index 137c7d7..1e5401f 100644
--- a/dojox/data/QueryReadStore.js
+++ b/dojox/data/QueryReadStore.js
@@ -1,7 +1,4 @@
-dojo.provide("dojox.data.QueryReadStore");
-
-dojo.require("dojo.string");
-dojo.require("dojo.data.util.sorter");
+define("dojox/data/QueryReadStore", ["dojo", "dojox", "dojo.data.util.sorter", "dojo/string"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.QueryReadStore",
 	null,
@@ -67,14 +64,14 @@ dojo.declare("dojox.data.QueryReadStore",
 		// This will contain the items we have loaded from the server.
 		// The contents of this array is optimized to satisfy all read-api requirements
 		// and for using lesser storage, so the keys and their content need some explaination:
-		// 		this._items[0].i - the item itself 
+		// 		this._items[0].i - the item itself
 		//		this._items[0].r - a reference to the store, so we can identify the item
 		//			securly. We set this reference right after receiving the item from the
 		//			server.
 		_items:[],
 		
 		// Store the last query that triggered xhr request to the server.
-		// So we can compare if the request changed and if we shall reload 
+		// So we can compare if the request changed and if we shall reload
 		// (this also depends on other factors, such as is caching used, etc).
 		_lastServerQuery:null,
 		
@@ -117,12 +114,11 @@ dojo.declare("dojox.data.QueryReadStore",
 				throw new Error(this._className+".getValue(): Invalid attribute, string expected!");
 			}
 			if(!this.hasAttribute(item, attribute)){
-				// read api says: return defaultValue "only if *item* does not have a value for *attribute*." 
+				// read api says: return defaultValue "only if *item* does not have a value for *attribute*."
 				// Is this the case here? The attribute doesn't exist, but a defaultValue, sounds reasonable.
 				if(defaultValue){
 					return defaultValue;
 				}
-				console.log(this._className+".getValue(): Item does not have the attribute '"+attribute+"'.");
 			}
 			return item.i[attribute];
 		},
@@ -146,7 +142,7 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		hasAttribute: function(/* item */ item,	/* attribute-name-string */ attribute){
-			//	summary: 
+			//	summary:
 			//		See dojo.data.api.Read.hasAttribute()
 			return this.isItem(item) && typeof item.i[attribute]!="undefined";
 		},
@@ -273,7 +269,7 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 	
 		close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-			// I have no idea if this is really needed ... 
+			// I have no idea if this is really needed ...
 		},
 	
 		getLabel: function(/* item */ item){
@@ -305,9 +301,9 @@ dojo.declare("dojox.data.QueryReadStore",
 			// Store a ref to "this" in each item, so we can simply check if an item
 			// really origins form here (idea is from ItemFileReadStore, I just don't know
 			// how efficient the real storage use, garbage collection effort, etc. is).
-			dojo.forEach(data.items,function(e){ 
-				this._items.push({i:e, r:this}); 
-			},this); 
+			dojo.forEach(data.items,function(e){
+				this._items.push({i:e, r:this});
+			},this);
 			
 			var identifier = data.identifier;
 			this._itemsByIdentity = {};
@@ -334,7 +330,7 @@ dojo.declare("dojox.data.QueryReadStore",
 			// (does it really sanititze them) and store the data optimal. should we? for security reasons???
 			numRows = this._numRows = (numRows === -1) ? this._items.length : numRows;
 			fetchHandler(this._items, request, numRows);
-			this._numRows = numRows;		
+			this._numRows = numRows;
 		},
 		
 		_fetchItems: function(request, fetchHandler, errorHandler){
@@ -393,7 +389,10 @@ dojo.declare("dojox.data.QueryReadStore",
 				fetchHandler(this._items, request, this._numRows);
 			}else{
 				var xhrFunc = this.requestMethod.toLowerCase() == "post" ? dojo.xhrPost : dojo.xhrGet;
-				var xhrHandler = xhrFunc({url:this.url, handleAs:"json-comment-optional", content:serverQuery});
+				var xhrHandler = xhrFunc({url:this.url, handleAs:"json-comment-optional", content:serverQuery, failOk: true});
+				request.abort = function(){
+					xhrHandler.cancel();
+				};
 				xhrHandler.addCallback(dojo.hitch(this, function(data){
 					this._xhrFetchHandler(data, request, fetchHandler, errorHandler);
 				}));
@@ -411,7 +410,7 @@ dojo.declare("dojox.data.QueryReadStore",
 		_filterResponse: function(data){
 			//	summary:
 			//		If the data from servers needs to be processed before it can be processed by this
-			//		store, then this function should be re-implemented in subclass. This default 
+			//		store, then this function should be re-implemented in subclass. This default
 			//		implementation just return the data unchanged.
 			//	data:
 			//		The data received from server
@@ -422,7 +421,7 @@ dojo.declare("dojox.data.QueryReadStore",
 			//	summary:
 			//		It throws an error if item is not valid, so you can call it in every method that needs to
 			//		throw an error when item is invalid.
-			//	item: 
+			//	item:
 			//		The item to test for being contained by the store.
 			if(!this.isItem(item)){
 				throw new Error(this._className+": Invalid item argument.");
@@ -432,15 +431,15 @@ dojo.declare("dojox.data.QueryReadStore",
 		_assertIsAttribute: function(/* attribute-name-string */ attribute){
 			//	summary:
 			//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-			//	attribute: 
+			//	attribute:
 			//		The attribute to test for being contained by the store.
-			if(typeof attribute !== "string"){ 
+			if(typeof attribute !== "string"){
 				throw new Error(this._className+": Invalid attribute argument ('"+attribute+"').");
 			}
 		},
 	
 		fetchItemByIdentity: function(/* Object */ keywordArgs){
-			//	summary: 
+			//	summary:
 			//		See dojo.data.api.Identity.fetchItemByIdentity()
 	
 			// See if we have already loaded the item with that id
@@ -496,7 +495,7 @@ dojo.declare("dojox.data.QueryReadStore",
 		},
 		
 		getIdentity: function(/* item */ item){
-			//	summary: 
+			//	summary:
 			//		See dojo.data.api.Identity.getIdentity()
 			var identifier = null;
 			if(this._identifier === Number){
@@ -514,3 +513,6 @@ dojo.declare("dojox.data.QueryReadStore",
 		}
 	}
 );
+
+return dojox.data.QueryReadStore;
+});
diff --git a/dojox/data/RailsStore.js b/dojox/data/RailsStore.js
index 68d00e1..9516e08 100644
--- a/dojox/data/RailsStore.js
+++ b/dojox/data/RailsStore.js
@@ -1,8 +1,6 @@
-dojo.provide("dojox.data.RailsStore");
-dojo.require("dojox.data.JsonRestStore");
-// Contains code donated by Travis Tilley under CLA
-
+define("dojox/data/RailsStore", ["dojo", "dojox", "dojox/data/JsonRestStore"], function(dojo, dojox) {
 
+// Contains code donated by Travis Tilley under CLA
 dojo.declare("dojox.data.RailsStore", dojox.data.JsonRestStore, {
 	constructor: function(){
 		//	summary:
@@ -165,3 +163,6 @@ dojo.declare("dojox.data.RailsStore", dojox.data.JsonRestStore, {
 		return {totalCount:deferred.fullLength || (deferred.request.count == count ? (deferred.request.start || 0) + count * 2 : count), items: items};
 	}
 });
+
+return dojox.data.RailsStore;
+});
diff --git a/dojox/data/S3Store.js b/dojox/data/S3Store.js
index 51923c9..1f8ecf1 100644
--- a/dojox/data/S3Store.js
+++ b/dojox/data/S3Store.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.data.S3Store");
-dojo.require("dojox.rpc.ProxiedPath");
-dojo.require("dojox.data.JsonRestStore");
+define("dojox/data/S3Store", ["dojo", "dojox", "dojox/data/JsonRestStore", "dojox/rpc/ProxiedPath"], function(dojo, dojox) {
 
 // S3JsonRestStore is an extension of JsonRestStore to handle
 // Amazon's S3 service using JSON data
@@ -32,3 +30,6 @@ dojo.declare("dojox.data.S3Store",
 		}
 	}
 );
+
+return dojox.data.S3Store;
+});
diff --git a/dojox/data/ServiceStore.js b/dojox/data/ServiceStore.js
index 0bfa09d..626880d 100644
--- a/dojox/data/ServiceStore.js
+++ b/dojox/data/ServiceStore.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.data.ServiceStore");
+define("dojox/data/ServiceStore", ["dojo", "dojox"], function(dojo, dojox) {
 
 // note that dojox.rpc.Service is not required, you can create your own services
 
@@ -397,3 +397,6 @@ dojo.declare("dojox.data.ServiceStore",
 
 	}
 );
+
+return dojox.data.ServiceStore;
+});
diff --git a/dojox/data/SnapLogicStore.js b/dojox/data/SnapLogicStore.js
index 300e21a..570675c 100644
--- a/dojox/data/SnapLogicStore.js
+++ b/dojox/data/SnapLogicStore.js
@@ -1,7 +1,4 @@
-dojo.provide("dojox.data.SnapLogicStore");
-
-dojo.require("dojo.io.script");
-dojo.require("dojo.data.util.sorter");
+define("dojox/data/SnapLogicStore", ["dojo", "dojox", "dojo/io/script", "dojo/data/util/sorter"], function(dojo, dojox) {
 
 dojo.declare("dojox.data.SnapLogicStore", null, {
 	Parts: {
@@ -33,9 +30,9 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	_assertIsItem: function(/* item */item){
 		//	summary:
 		//		This function tests whether the item passed in is indeed an item in the store.
-		//	item: 
+		//	item:
 		//		The item to test for being contained by the store.
-		if(!this.isItem(item)){ 
+		if(!this.isItem(item)){
 			throw new Error("dojox.data.SnapLogicStore: a function was passed an item argument that was not an item");
 		}
 	},
@@ -43,15 +40,15 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	_assertIsAttribute: function(/* attribute-name-string */ attribute){
 		//	summary:
 		//		This function tests whether the item passed in is indeed a valid 'attribute' like type for the store.
-		//	attribute: 
+		//	attribute:
 		//		The attribute to test for being contained by the store.
-		if(typeof attribute !== "string"){ 
+		if(typeof attribute !== "string"){
 			throw new Error("dojox.data.SnapLogicStore: a function was passed an attribute argument that was not an attribute name string");
 		}
 	},
 
 	getFeatures: function(){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getFeatures()
 		return {
 			'dojo.data.api.Read': true
@@ -59,7 +56,7 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	getValue: function(item, attribute, defaultValue){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -71,14 +68,14 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	getAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getAttributes()
 		this._assertIsItem(item);
 		return item.attributes;
 	},
 
 	hasAttribute: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.hasAttributes()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -91,36 +88,36 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	isItemLoaded: function(item){
-		 //	summary: 
+		 //	summary:
 		 //		 See dojo.data.api.Read.isItemLoaded()
 		 return this.isItem(item);		// Boolean
 	},
 
 	loadItem: function(keywordArgs){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.loadItem()
 	},
 
 	getLabel: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		return undefined;
 	},
 	
 	getLabelAttributes: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		return null;
 	},
 
 	containsValue: function(item, attribute, value){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.containsValue()
 		return this.getValue(item, attribute) === value;		// Boolean
 	},
 
 	getValues: function(item, attribute){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getValue()
 		this._assertIsItem(item);
 		this._assertIsAttribute(attribute);
@@ -132,7 +129,7 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	isItem: function(item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.isItem()
 		if(item && item._store === this){
 			return true;
@@ -141,12 +138,12 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 	
 	close: function(request){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.close()
 	},
 
 	_fetchHandler: function(/* Object */request){
-		//	summary: 
+		//	summary:
 		//		Process data retrieved via fetch and send it back to requester.
 		//	response:
 		//		The data returend from the I/O transport. In the normal case, it will be an array of result rows
@@ -165,7 +162,7 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 			var response = request._dataResponse;
 
 			if(!response.length){
-				request.onError.call(scope, 
+				request.onError.call(scope,
 									 new Error("dojox.data.SnapLogicStore: invalid response of length 0"),
 									 request);
 				return;
@@ -208,7 +205,7 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 		
 	_partHandler: function(/* Object */request, /* String */part, /* Object */response){
-		//	summary: 
+		//	summary:
 		//		Handle the individual replies for both data and length requests.
 		//	request:
 		//		The request/handle object used with the original fetch() call.
@@ -236,7 +233,7 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 			}else{
 				request._countResponse = response;
 			}
-			if((!request._dataHandle || request._dataResponse !== null) && 
+			if((!request._dataHandle || request._dataResponse !== null) &&
 				(!request._countHandle || request._countResponse !== null)){
 				this._fetchHandler(request);
 			}
@@ -244,7 +241,7 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	},
 
 	fetch: function(/* Object */request){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.close()
 		//	request:
 		//		See dojo.data.api.Read.close() for generic interface.
@@ -326,3 +323,6 @@ dojo.declare("dojox.data.SnapLogicStore", null, {
 	}
 });
 
+return dojox.data.SnapLogicStore;
+});
+
diff --git a/dojox/data/StoreExplorer.js b/dojox/data/StoreExplorer.js
index f0bbce7..e047acc 100644
--- a/dojox/data/StoreExplorer.js
+++ b/dojox/data/StoreExplorer.js
@@ -9,7 +9,9 @@ dojo.declare("dojox.data.StoreExplorer", dijit.layout.BorderContainer, {
 		dojo.mixin(this, options);
 	},
 	store: null,
+	columnWidth: '',
 	stringQueries: false,
+	showAllColumns: false,
 	postCreate: function(){
 		var self = this;
 		this.inherited(arguments);
@@ -43,7 +45,7 @@ dojo.declare("dojox.data.StoreExplorer", dijit.layout.BorderContainer, {
 		this.setItemName = function(name){
 			createNewButton.attr('label',"<img style='width:12px; height:12px' src='" + dojo.moduleUrl("dijit.themes.tundra.images","dndCopy.png") + "' /> Create New " + name);
 			deleteButton.attr('label',"Delete " + name);
-		}
+		};
 		addButton("Save",function(){
 			self.store.save({onError:function(error){
 				alert(error);
@@ -153,16 +155,18 @@ dojo.declare("dojox.data.StoreExplorer", dijit.layout.BorderContainer, {
 				}
 			}
 			layout = layout.sort(function(a, b){
-				return a._score > b._score ? -1 : 1;
+				return  b._score - a._score;
 			});
-			for(j=0; column = layout[j]; j++){
-				if(column._score < items.length/40 * j){
-					layout.splice(j,layout.length-j);
-					break;
+			if(!self.showAllColumns){
+				for(j=0; column=layout[j]; j++){
+					if(column._score < items.length/40 * j) {
+						layout.splice(j, layout.length-j);
+						break;
+					}
 				}
 			}
 			for(j=0; column = layout[j++];){
-				column.width=Math.round(100/layout.length) + '%';
+				column.width=self.columnWidth || Math.round(100/layout.length) + '%';
 			}
 			grid._onFetchComplete = defaultOnComplete;
 			grid.attr("structure",layout);
diff --git a/dojox/data/WikipediaStore.js b/dojox/data/WikipediaStore.js
index deb134a..7ccad28 100644
--- a/dojox/data/WikipediaStore.js
+++ b/dojox/data/WikipediaStore.js
@@ -1,8 +1,4 @@
-dojo.provide("dojox.data.WikipediaStore");
-
-dojo.require("dojo.io.script");
-dojo.require("dojox.rpc.Service");
-dojo.require("dojox.data.ServiceStore");
+define("dojox/data/WikipediaStore", ["dojo", "dojox", "dojo/io/script", "dojox/rpc/Service", "dojox/data/ServiceStore"], function(dojo, dojox) {
 
 dojo.experimental("dojox.data.WikipediaStore");
 
@@ -113,3 +109,7 @@ dojo.declare("dojox.data.WikipediaStore", dojox.data.ServiceStore,{
 	}
 });
 
+return dojox.data.WikipediaStore;
+
+});
+
diff --git a/dojox/data/XmlStore.js b/dojox/data/XmlStore.js
index a4a3962..8c32233 100644
--- a/dojox/data/XmlStore.js
+++ b/dojox/data/XmlStore.js
@@ -1,9 +1,6 @@
-dojo.provide("dojox.data.XmlStore");
-dojo.provide("dojox.data.XmlItem");
+define("dojox/data/XmlStore", ["dojo", "dojox", "dojo/data/util/simpleFetch", "dojo/data/util/filter", "dojox/xml/parser"], function(dojo, dojox) {
 
-dojo.require("dojo.data.util.simpleFetch");
-dojo.require("dojo.data.util.filter");
-dojo.require("dojox.xml.parser");
+dojo.provide("dojox.data.XmlItem");
 
 dojo.declare("dojox.data.XmlStore", null, {
 	//	summary:
@@ -13,21 +10,21 @@ dojo.declare("dojox.data.XmlStore", null, {
 	
 	constructor: function(/* object */ args){
 		//	summary:
-		//		Constructor for the XML store.  
+		//		Constructor for the XML store.
 		//	args:
 		//		An anonymous object to initialize properties.  It expects the following values:
 		//		url:		The url to a service or an XML document that represents the store
 		//		rootItem:	A tag name for root items
 		//		keyAttribute:	An attribute name for a key or an identity (unique identifier)
-		//						Required for serverside fetchByIdentity, etc.  Not required for 
+		//						Required for serverside fetchByIdentity, etc.  Not required for
 		//						client side fetchItemBIdentity, as it will use an XPath-like
 		//						structure if keyAttribute was not specified.  Recommended to always
 		//						set this, though, for consistent identity behavior.
 		// 		attributeMap:   An anonymous object contains properties for attribute mapping,
 		//						{"tag_name.item_attribute_name": "@xml_attribute_name", ...}
-		//		sendQuery:		A boolean indicate to add a query string to the service URL.  
+		//		sendQuery:		A boolean indicate to add a query string to the service URL.
 		//						Default is false.
-		//		urlPreventCache: Parameter to indicate whether or not URL calls should apply 
+		//		urlPreventCache: Parameter to indicate whether or not URL calls should apply
 		//		                 the preventCache option to the xhr request.
 		if(args){
 			this.url = args.url;
@@ -45,7 +42,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 		this._modifiedItems = [];
 	},
 
-	//Values that may be set by the parser.  
+	//Values that may be set by the parser.
 	//Ergo, have to be instantiated to something
 	//So the parser knows how to set them.
 	url: "",
@@ -67,9 +64,9 @@ dojo.declare("dojox.data.XmlStore", null, {
 	//	Default is false.
 	sendQuery: false,
 
-	//	An anonymous object that contains properties for attribute mapping, 
-	//	for example {"tag_name.item_attribute_name": "@xml_attribute_name", ...}. 
-	//	This is optional. This is done so that attributes which are actual 
+	//	An anonymous object that contains properties for attribute mapping,
+	//	for example {"tag_name.item_attribute_name": "@xml_attribute_name", ...}.
+	//	This is optional. This is done so that attributes which are actual
 	//	XML tag attributes (and not sub-tags of an XML tag), can be referenced.
 	attributeMap: null,
 
@@ -132,7 +129,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			if(attribute.charAt(0) === '@'){
 				var name = attribute.substring(1);
 				var value = element.getAttribute(name);
-				//Note that getAttribute will return null or empty string for undefined/unset 
+				//Note that getAttribute will return null or empty string for undefined/unset
 				//attributes, therefore, we should just check the return was valid
 				//non-empty string and not null.
 				return (value) ? value : defaultValue; //object
@@ -353,7 +350,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			"dojo.data.api.Write": true
 		};
 
-		//Local XML parsing can implement Identity fairly simple via 
+		//Local XML parsing can implement Identity fairly simple via
 		if(!this.sendQuery || this.keyAttribute !== ""){
 			features["dojo.data.api.Identity"] = true;
 		}
@@ -361,7 +358,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 	},
 
 	getLabel: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabel()
 		if((this.label !== "") && this.isItem(item)){
 			var label = this.getValue(item,this.label);
@@ -373,7 +370,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 	},
 
 	getLabelAttributes: function(/* item */ item){
-		//	summary: 
+		//	summary:
 		//		See dojo.data.api.Read.getLabelAttributes()
 		if(this.label !== ""){
 			return [this.label]; //array
@@ -504,7 +501,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			nodes = document.documentElement.childNodes;
 		}
 
-		var deep = request.queryOptions ? request.queryOptions.deep : false; 
+		var deep = request.queryOptions ? request.queryOptions.deep : false;
 		if(deep){
 			nodes = this._flattenNodes(nodes);
 		}
@@ -515,7 +512,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			}
 			var item = this._getItem(node);
 			if(query){
-				var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false; 
+				var ignoreCase = request.queryOptions ? request.queryOptions.ignoreCase : false;
 				var value;
 				var match = false;
 				var j;
@@ -537,7 +534,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 						value = values[j];
 						if(value){
 							var queryValue = query[attribute];
-							if((typeof value) === "string" && 
+							if((typeof value) === "string" &&
 								(regexpList[attribute])){
 								if((value.match(regexpList[attribute])) !== null){
 									match = true;
@@ -545,7 +542,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 									match = false;
 								}
 							}else if((typeof value) === "object"){
-								if(	value.toString && 
+								if(	value.toString &&
 									(regexpList[attribute])){
 									var stringValue = value.toString();
 									if((stringValue.match(regexpList[attribute])) !== null){
@@ -562,7 +559,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 								}
 							}
 						}
-						//One of the multiValue values matched, 
+						//One of the multiValue values matched,
 						//so quit looking.
 						if(match){
 							break;
@@ -572,7 +569,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 						break;
 					}
 				}
-				//Either the query was an empty object {}, which is match all, or 
+				//Either the query was an empty object {}, which is match all, or
 				//was an actual match.
 				if(emptyQuery || match){
 					items.push(item);
@@ -591,7 +588,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 	},
 
 	_flattenNodes: function(nodes){
-		//	Summary:	
+		//	Summary:
 		//		Function used to flatten a hierarchy of XML nodes into a single list for
 		//		querying over.  Used when deep = true;
 		var flattened = [];
@@ -609,7 +606,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 	},
 
 	close: function(/*dojo.data.api.Request || keywordArgs || null */ request){
-		 //	summary: 
+		 //	summary:
 		 //		See dojo.data.api.Read.close()
 	},
 
@@ -1152,7 +1149,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			var q = null;
 			//Avoid function call if possible.
 			if(this.keyAttribute === ""){
-				q = this._getXPath(element); 
+				q = this._getXPath(element);
 			}
 			return new dojox.data.XmlItem(element, this, q); //object
 		}catch (e){
@@ -1185,12 +1182,12 @@ dojo.declare("dojox.data.XmlStore", null, {
 
 	_restoreItems: function(items){
 
-		dojo.forEach(items,function(item){ 
+		dojo.forEach(items,function(item){
 			if(item._backup){
 				item.element = item._backup;
 				item._backup = null;
 			}
-		},this); 
+		},this);
 	},
 
 	_forgetItem: function(item){
@@ -1264,7 +1261,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 	 *************************************/
 	getIdentity: function(/* item */ item){
 		//	summary:
-		//		Returns a unique identifier for an item.  
+		//		Returns a unique identifier for an item.
 		//	item:
 		//		The XML Item from the store from which to obtain its identifier.
 		if(!this.isItem(item)){
@@ -1277,7 +1274,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 				if(this.keyAttribute !== ""){
 					id = this.getValue(item,this.keyAttribute).toString();
 				}else{
-					//No specified identity, so return the dojo.query/xpath 
+					//No specified identity, so return the dojo.query/xpath
 					//for the node as fallback.
 					id = item.q;
 				}
@@ -1290,14 +1287,14 @@ dojo.declare("dojox.data.XmlStore", null, {
 		//	summary:
 		//		Returns an array of attribute names that are used to generate the identity.
 		//	description:
-		//		For XmlStore, if sendQuery is false and no keyAttribute was set, then this function 
-		//		returns null, as xpath is used for the identity, which is not a public attribute of 
+		//		For XmlStore, if sendQuery is false and no keyAttribute was set, then this function
+		//		returns null, as xpath is used for the identity, which is not a public attribute of
 		//		the item.  If sendQuery is true and keyAttribute is set, then this function
-		//		returns an array of one attribute name: keyAttribute.   This means the server side 
-		//		implementation must apply a keyAttribute to a returned node that always allows 
+		//		returns an array of one attribute name: keyAttribute.   This means the server side
+		//		implementation must apply a keyAttribute to a returned node that always allows
 		//		it to be looked up again.
 		//	item:
-		//		The item from the store from which to obtain the array of public attributes that 
+		//		The item from the store from which to obtain the array of public attributes that
 		//		compose the identifier, if any.
 		if(!this.isItem(item)){
 			throw new Error("dojox.data.XmlStore: Object supplied to getIdentity is not an item");
@@ -1305,7 +1302,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			if(this.keyAttribute !== ""){
 				return [this.keyAttribute]; //array
 			}else{
-				//Otherwise it's either using xpath (not an attribute), or the remote store 
+				//Otherwise it's either using xpath (not an attribute), or the remote store
 				//doesn't support identity.
 				return null; //null
 			}
@@ -1350,8 +1347,8 @@ dojo.declare("dojox.data.XmlStore", null, {
 						}
 					}else{
 						//Since dojo.query doesn't really support the functions needed
-						//to do child node selection on IE well and since xpath support 
-						//is flakey across browsers, it's simpler to implement a 
+						//to do child node selection on IE well and since xpath support
+						//is flakey across browsers, it's simpler to implement a
 						//pseudo-xpath parser here.
 						var qArgs = keywordArgs.identity.split("/");
 						var i;
@@ -1426,7 +1423,7 @@ dojo.declare("dojox.data.XmlStore", null, {
 			}
 		}else{
 			//Server side querying, so need to pass the keyAttribute back to the server and let it return
-			//what it will.  It SHOULD be only one item.  
+			//what it will.  It SHOULD be only one item.
 			if(self.keyAttribute !== ""){
 				var request = {query:{}};
 				request.query[self.keyAttribute] = keywordArgs.identity;
@@ -1489,7 +1486,7 @@ dojo.declare("dojox.data.XmlItem", null, {
 		this.element = element;
 		this.store = store;
 		this.q = query;
-	}, 
+	},
 	//	summary:
 	//		A data item of 'XmlStore'
 	//	description:
@@ -1515,3 +1512,6 @@ dojo.declare("dojox.data.XmlItem", null, {
 	}
 });
 dojo.extend(dojox.data.XmlStore,dojo.data.util.simpleFetch);
+
+return dojox.data.XmlStore;
+});
diff --git a/dojox/data/css.js b/dojox/data/css.js
index d7185c7..9c1e248 100755
--- a/dojox/data/css.js
+++ b/dojox/data/css.js
@@ -1,6 +1,7 @@
-dojo.provide('dojox.data.css');
-dojo.provide('dojox.data.css.rules');
+define("dojox/data/css", ["dojo", "dojox"], function(dojo, dojox) {
 
+dojox.data.css.rules = {};
+		
 dojox.data.css.rules.forEach = function(fn,ctx,context){
 	if(context){
 		var _processSS = function(styleSheet){
@@ -49,7 +50,7 @@ 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 dojo.some(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules
 				//console.debug("Processing IE @import rule",importedSS);
 				return _processSS(importedSS);
 			});
@@ -67,7 +68,7 @@ dojox.data.css.findStyleSheet = function(sheet){
 	return sheetObjects;
 };
 dojox.data.css.determineContext = function(initialStylesheets){
-	// Takes an array of stylesheet paths and returns an array of all stylesheets that fall in the 
+	// 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){
@@ -78,7 +79,7 @@ dojox.data.css.determineContext = function(initialStylesheets){
 	var _processSS = function(styleSheet){
 		ret.push(styleSheet);
 		if(styleSheet.imports){
-			dojo.forEach(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules 
+			dojo.forEach(styleSheet.imports, function(importedSS){ //IE stylesheet has imports[] containing @import'ed rules
 				//console.debug("Processing IE @import rule",importedSS);
 				_processSS(importedSS);
 			});
@@ -93,3 +94,7 @@ dojox.data.css.determineContext = function(initialStylesheets){
 	dojo.forEach(initialStylesheets,_processSS);
 	return ret;
 };
+
+return dojox.data.css;
+
+});
diff --git a/dojox/data/demos/stores/LazyLoadJSIStore.js b/dojox/data/demos/stores/LazyLoadJSIStore.js
index 7a08840..e811e85 100644
--- a/dojox/data/demos/stores/LazyLoadJSIStore.js
+++ b/dojox/data/demos/stores/LazyLoadJSIStore.js
@@ -3,9 +3,9 @@ dojo.require("dojo.data.ItemFileReadStore");
 
 dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadStore, {
 	constructor: function(/* object */ keywordParameters){
-		// LazyLoadJSIStore extends ItemFileReadStore to implement an 
+		// LazyLoadJSIStore extends ItemFileReadStore to implement an
 		// example of lazy-loading/faulting in items on-demand.
-		// Note this is certianly not a perfect implementation, it is 
+		// Note this is certianly not a perfect implementation, it is
 		// an example.
 	},
 	
@@ -17,7 +17,7 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 		//	item:
 		//		The item to examine.
 		
-		//For this store, if it has the value of stub for its type attribute, 
+		//For this store, if it has the value of stub for its type attribute,
 		//then the item basn't been fully loaded yet.  It's just a placeholder.
 		if(this.getValue(item, "type") === "stub"){
 			return false;
@@ -39,7 +39,7 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 		this._assertIsItem(item);
 
 		//Build the path to the data.json for this item
-		//The path consists of where its parent was loaded from 
+		//The path consists of where its parent was loaded from
 		//plus the item name.
 		var itemName = this.getValue(item, "name");
 		var parent   = this.getValue(item, "parent");
@@ -79,7 +79,7 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 			//Reset the item in the reference.
 			self._arrayOfAllItems[item[self._itemNumPropName]] = item;
 
-			//Scan the new values in the item for extra stub items we need to 
+			//Scan the new values in the item for extra stub items we need to
 			//add to the items array of the store so they can be lazy-loaded later...
 			var attributes = self.getAttributes(item);
 			for(i in attributes){
@@ -97,7 +97,7 @@ dojo.declare("dojox.data.demos.stores.LazyLoadJSIStore", dojo.data.ItemFileReadS
 							};
 							if (parent) {
 								//Add in any parents to your parent so URL construstruction is accurate.
-								stub.parent[0] = parent + "/" + stub.parent[0]; 
+								stub.parent[0] = parent + "/" + stub.parent[0];
 							}
 							//Finalize the addition of the new stub item into the ItemFileReadStore list.
 							self._arrayOfAllItems.push(stub);
diff --git a/dojox/data/demos/widgets/FileView.js b/dojox/data/demos/widgets/FileView.js
index a73cb4c..c6776af 100755
--- a/dojox/data/demos/widgets/FileView.js
+++ b/dojox/data/demos/widgets/FileView.js
@@ -8,7 +8,7 @@ dojo.declare("dojox.data.demos.widgets.FileView", [dijit._Widget, dijit._Templat
 	templateString: dojo.cache("dojox", "data/demos/widgets/templates/FileView.html"),
 
 	//Attach points for reference.
-	titleNode: null, 
+	titleNode: null,
 	descriptionNode: null,
 	imageNode: null,
 	authorNode: null,
diff --git a/dojox/data/demos/widgets/FlickrViewList.js b/dojox/data/demos/widgets/FlickrViewList.js
index 0798235..5125c13 100644
--- a/dojox/data/demos/widgets/FlickrViewList.js
+++ b/dojox/data/demos/widgets/FlickrViewList.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.data.demos.widgets.FlickrViewList");
 dojo.require("dojox.dtl._Templated");
 dojo.require("dijit._Widget");
 
-dojo.declare("dojox.data.demos.widgets.FlickrViewList", 
+dojo.declare("dojox.data.demos.widgets.FlickrViewList",
 	[ dijit._Widget, dojox.dtl._Templated ],
 	{
 		store: null,
diff --git a/dojox/data/demos/widgets/PicasaView.js b/dojox/data/demos/widgets/PicasaView.js
index 039d7a1..015a5f2 100644
--- a/dojox/data/demos/widgets/PicasaView.js
+++ b/dojox/data/demos/widgets/PicasaView.js
@@ -8,7 +8,7 @@ dojo.declare("dojox.data.demos.widgets.PicasaView", [dijit._Widget, dijit._Templ
 	templateString: dojo.cache("dojox", "data/demos/widgets/templates/PicasaView.html"),
 
 	//Attach points for reference.
-	titleNode: null, 
+	titleNode: null,
 	descriptionNode: null,
 	imageNode: null,
 	authorNode: null,
diff --git a/dojox/data/dom.js b/dojox/data/dom.js
index b320245..35d1d40 100644
--- a/dojox/data/dom.js
+++ b/dojox/data/dom.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.data.dom");
-dojo.require("dojox.xml.parser");
+define("dojox/data/dom", ["dojo", "dojox", "dojox/xml/parser"], function(dojo, dojox) {
 
 //DOM type to int value for reference.
 //Ints make for more compact code than full constant names.
@@ -25,7 +24,7 @@ dojox.data.dom.createDocument = function(/*string?*/ str, /*string?*/ mimetype){
 	//		cross-browser implementation of creating an XML document object.
 	//
 	//	str:
-	//		Optional text to create the document from.  If not provided, an empty XML document will be created.  
+	//		Optional text to create the document from.  If not provided, an empty XML document will be created.
 	//		If str is empty string "", then a new empty document will be created.
 	//	mimetype:
 	//		Optional mimetype of the text.  Typically, this is text/xml.  Will be defaulted to text/xml if not provided.
@@ -43,7 +42,7 @@ dojox.data.dom.textContent = function(/*Node*/node, /*string?*/text){
 	//		Implementation of the DOM Level 3 attribute; scan node for text
 	//	description:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
-	//		This function can also update the text of a node by replacing all child 
+	//		This function can also update the text of a node by replacing all child
 	//		content of the node.
 	//	node:
 	//		The node to get the text off of or set the text on.
@@ -93,3 +92,7 @@ dojox.data.dom.innerXML = function(/*Node*/node){
 	return dojox.xml.parser.innerXML(node); //string||null
 };
 
+return dojox.data.dom;
+
+});
+
diff --git a/dojox/data/tests/ClientFilter.js b/dojox/data/tests/ClientFilter.js
index fa6261e..4ecbe3d 100644
--- a/dojox/data/tests/ClientFilter.js
+++ b/dojox/data/tests/ClientFilter.js
@@ -16,26 +16,26 @@ mockService = function(query){
 mockService.servicePath = "mock/";
 jsonStore = new dojox.data.JsonRestStore({service:mockService});
 
-doh.register("dojox.data.tests.ClientFilter", 
+doh.register("dojox.data.tests.ClientFilter",
 	[
 		function updateWhileLoading(t) {
 			var d = new doh.Deferred();
-			jsonStore.fetch({query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}], 
+			jsonStore.fetch({query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}],
 				onComplete: function(items, request){
 					t.is(5, items.length); // make sure it was added
 					t.is(newJack,items[4]); // make sure it is in the right location
 					console.log("updateWhileLoading",items[4],newJack);
-					d.callback(true);					
+					d.callback(true);
 				}
 			});
 			newJack = jsonStore.newItem({firstName:"Jack",lastName:"Smith"}); // this should fire while we are waiting for the fetch response
 			return d;
 		},
 		function makeChanges(t) {
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on JsonRestStore of a simple query.
 			var d = new doh.Deferred();
-			jsonStore.fetch({queryOptions:{cache:true},query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}], 
+			jsonStore.fetch({queryOptions:{cache:true},query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}],
 				onComplete: function(items, request){
 					t.is(5, items.length); // make sure it was added
 					t.is(newJack,items[4]); // make sure it is in the right location
@@ -66,7 +66,7 @@ doh.register("dojox.data.tests.ClientFilter",
 			});
 			console.log("sent first");
 			var finished;
-			jsonStore.fetch({query:{lastName:"Smith",firstName:"Jack"},sort:[{attribute:"firstName",descending:true}], 
+			jsonStore.fetch({query:{lastName:"Smith",firstName:"Jack"},sort:[{attribute:"firstName",descending:true}],
 				onComplete: function(items, request){
 					console.log("items first",items);
 					finished = true;
@@ -81,7 +81,7 @@ doh.register("dojox.data.tests.ClientFilter",
 		function cachedResults(t) {
 			var d = new doh.Deferred();
 			var finished;
-			jsonStore.fetch({query:{lastName:"Smith",firstName:"Jack"},sort:[{attribute:"firstName",descending:true}], 
+			jsonStore.fetch({query:{lastName:"Smith",firstName:"Jack"},sort:[{attribute:"firstName",descending:true}],
 				onComplete: function(items, request){
 					console.log("items",items);
 					finished = true;
@@ -95,19 +95,19 @@ doh.register("dojox.data.tests.ClientFilter",
 		function repeatedQueries(t) {
 			var d = new doh.Deferred();
 			var finished;
-			jsonStore.fetch({queryOptions:{cache:true},query:{}, 
+			jsonStore.fetch({queryOptions:{cache:true},query:{},
 				onComplete: function(items, request){
 					console.log("items",items);
 					t.is(6, items.length); // make sure we get the correct number of items
 					jsonStore.newItem({firstName:"Jack",lastName:"Jones"});
-					jsonStore.fetch({query:{}, 
+					jsonStore.fetch({query:{},
 						onComplete: function(items, request){
 							t.is(7, items.length); // make sure we get the correct number of items
 						}
 					});
 					jsonStore.serverVersion = jsonStore._updates.length;
 					jsonStore.newItem({firstName:"Jack",lastName:"Jones"});
-					jsonStore.fetch({query:{}, 
+					jsonStore.fetch({query:{},
 						onComplete: function(items, request){
 							finished = true;
 							t.is(8, items.length); // make sure we get the correct number of items
@@ -123,14 +123,14 @@ doh.register("dojox.data.tests.ClientFilter",
 			var d = new doh.Deferred();
 			var finished;
 			// test sorting. Descending order should be John,Jim,Jill,Jerry,Jack
-			jsonStore.fetch({query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}], 
+			jsonStore.fetch({query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName",descending:true}],
 				onComplete: function(items, request){
 					var last = jsonStore.getValue(items[0], "firstName");
 					console.log("last name: ",last, items[0]);
 
 					t.is("John", last); // make sure we get the correct number of items
 
-					jsonStore.fetch({query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName"}], 
+					jsonStore.fetch({query:{lastName:"Smith",firstName:"*"},sort:[{attribute:"firstName"}],
 						onComplete: function(items, request){
 							var first = jsonStore.getValue(items[0], "firstName");
 							console.log("first name",first, items[0]);
diff --git a/dojox/data/tests/dom.js b/dojox/data/tests/dom.js
index 3d8759c..5754232 100644
--- a/dojox/data/tests/dom.js
+++ b/dojox/data/tests/dom.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.data.tests.dom");
 dojo.require("dojox.data.dom");
 
-tests.register("dojox.data.tests.dom", 
+tests.register("dojox.data.tests.dom",
 	[
 		function testCreateDocument(t){
 			var document = dojox.data.dom.createDocument();
diff --git a/dojox/data/tests/module.js b/dojox/data/tests/module.js
index 323e7f6..e040788 100644
--- a/dojox/data/tests/module.js
+++ b/dojox/data/tests/module.js
@@ -4,8 +4,8 @@ try{
 	dojo.require("dojox.data.tests.ClientFilter");
 	dojo.require("dojox.data.tests.stores.CsvStore");
 	dojo.require("dojox.data.tests.stores.KeyValueStore");
-	dojo.require("dojox.data.tests.stores.AndOrReadStore"); 
-	dojo.require("dojox.data.tests.stores.AndOrWriteStore"); 
+	dojo.require("dojox.data.tests.stores.AndOrReadStore");
+	dojo.require("dojox.data.tests.stores.AndOrWriteStore");
 	dojo.requireIf(dojo.isBrowser, "dojox.data.tests.stores.HtmlTableStore");
 	dojo.requireIf(dojo.isBrowser, "dojox.data.tests.stores.HtmlStore");
 	dojo.requireIf(dojo.isBrowser, "dojox.data.tests.stores.OpmlStore");
diff --git a/dojox/data/tests/performance/CsvStore.js b/dojox/data/tests/performance/CsvStore.js
index 23059f3..7dba47a 100755
--- a/dojox/data/tests/performance/CsvStore.js
+++ b/dojox/data/tests/performance/CsvStore.js
@@ -5,8 +5,8 @@ dojo.require("dojo.data.util.sorter");
 
 dojox.data.tests.performance.CsvStore.getData = function(size){
 	//	summary:
-	//		This function generates a psuedorandom dataset collected 
-	//		from some templated entries.  
+	//		This function generates a psuedorandom dataset collected
+	//		from some templated entries.
 	//	returns:
 	//		A 2000 'row' CSV dataset.
 
@@ -93,7 +93,7 @@ doh.register("dojox.data.tests.performance.CsvStore",[
 			};
 			store.fetch({onComplete: complete, onError: err});
 			if(!dojo.isSafari){
-				//Well, realistically this is all sync so we don't *have* to 
+				//Well, realistically this is all sync so we don't *have* to
 				//pass back a deferred.  I think safari is blowing stack again.
 				//Need to look more at DOH once more.
 				return def;
@@ -124,7 +124,7 @@ doh.register("dojox.data.tests.performance.CsvStore",[
 			//about the fetch time, only the getValue processing.  So,
 			//I just gab the first item.
 			var value = dojox.data.tests.performance.CsvStore.store.getValue(
-				dojox.data.tests.performance.CsvStore.store._arrayOfAllItems[0], 
+				dojox.data.tests.performance.CsvStore.store._arrayOfAllItems[0],
 				"Title");
 		}
 	},
@@ -154,11 +154,11 @@ doh.register("dojox.data.tests.performance.CsvStore",[
 
 			//Create a clone array of all the data.  Yes, this accesses internals, but my goal here
 			//is to test the sorter code with respect to the store.
-			var data = dojox.data.tests.performance.CsvStore.store._arrayOfAllItems.slice(0, 
+			var data = dojox.data.tests.performance.CsvStore.store._arrayOfAllItems.slice(0,
 				dojox.data.tests.performance.CsvStore.store._arrayOfAllItems.length);
 
 			//Sort it using the generic sorter..
-			data.sort(dojo.data.util.sorter.createSortFunction(sort, 
+			data.sort(dojo.data.util.sorter.createSortFunction(sort,
 				dojox.data.tests.performance.CsvStore.store));
 		}
 	}
diff --git a/dojox/data/tests/stores/AndOrReadStore.js b/dojox/data/tests/stores/AndOrReadStore.js
index 98a6213..d4e3834 100755
--- a/dojox/data/tests/stores/AndOrReadStore.js
+++ b/dojox/data/tests/stores/AndOrReadStore.js
@@ -7,7 +7,7 @@ dojo.require("dojo.date.stamp");
 
 dojo.declare("dojox.data.tests.Wrapper", null, {
 	//	summary:
-	//		Simple class to use for typeMap in order to	test out 
+	//		Simple class to use for typeMap in order to	test out
 	//		'falsy' values for _value.
 	_wrapped: null,
 
@@ -29,14 +29,14 @@ dojo.declare("dojox.data.tests.Wrapper", null, {
 });
 
 
-//The test data-sets and tests are taken from ItemFileReadStore, to show 
+//The test data-sets and tests are taken from ItemFileReadStore, to show
 //  backwards compatibility.
 //Additionally, where appropriate (fetch/query), the AndOrReadStore test is immediately
-//  followed by the same query (with ", complex" in the description), but with the query 
-//  being a string rather than a json object. 
+//  followed by the same query (with ", complex" in the description), but with the query
+//  being a string rather than a json object.
 //Below all those tests are new ones that test the use of AND, OR, NOT, ||, &&, (, ), and ","
 //  in queries, as well as a mix of string and json object queries.
-//Since some widgets expect the query to be in json object form, in addition to the 
+//Since some widgets expect the query to be in json object form, in addition to the
 //  query="id:1234 || dept:'Sales Department' || (dept:Auto && id:2*)" programmatic syntax,
 //  query="{complexQuery:'id:1234 || dept:\"Sales Department\" || (dept:Auto && id:2*)" is
 //  tested/supported.
@@ -49,7 +49,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("dojox", "data/tests/stores/countries.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				identifier:'abbr',
 				label:'name',
 				items:[
@@ -64,7 +64,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 			} };
 		}
 	}else if(name === "countries_withNull"){
-		data = {data: { 
+		data = {data: {
 			identifier:"abbr",
 			items:[
 				{abbr:"ec", name:null, capital:"Quito"},
@@ -77,7 +77,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 			]
 		} };
 	}else if(name === "countries_withoutid"){
-		data = {data: { 
+		data = {data: {
 			label: "name",
 			items:[
 				{abbr:"ec", name:null, capital:"Quito"},
@@ -90,7 +90,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 			]
 		} };
 	}else if (name === "countries_withBoolean"){
-		data = {data: { 
+		data = {data: {
 			identifier:"abbr",
 			items:[
 				{abbr:"ec", name:"Ecuador", capital:"Quito", real:true},
@@ -104,7 +104,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 			]
 		} };
 	}else if (name === "countries_withDates"){
-		data = {data: { 
+		data = {data: {
 			identifier:"abbr",
 			items:[
 				{abbr:"ec", name:"Ecuador", capital:"Quito"},
@@ -117,7 +117,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 			]
 		} };
 	}else if (name === "geography_hierarchy_small"){
-		data = {data: { 
+		data = {data: {
 			items:[
 				{ name:'Africa', countries:[
 					{ name:'Egypt', capital:'Cairo' },
@@ -137,9 +137,9 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 			]
 		}};
 	}else if (name === "data_multitype"){
-		data = {data: { 
+		data = {data: {
 						"identifier": "count",
-						"label": "count", 
+						"label": "count",
 						items: [
 							{ count: 1,    value: "true" },
 							{ count: 2,    value: true   },
@@ -154,7 +154,7 @@ dojox.data.tests.stores.AndOrReadStore.getTestData = function(name){
 							{ count: 11,   value: [false, false]},
 							{ count: "12", value: [false, "true"]}
 					   ]
-					} 
+					}
 				};
 	}else if (name === "countries_references"){
 		data = {data: { identifier: 'name',
@@ -214,7 +214,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity()",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 	
@@ -238,7 +238,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() notFound",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store.
@@ -260,7 +260,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentityAttributes()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getIdentityAttributes function.
 				//	description:
 				//		Simple test of the getIdentityAttributes function.
@@ -286,7 +286,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() commentFilteredJson",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store.
@@ -316,7 +316,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() nullValue",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checling a null value.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a null value.
@@ -342,7 +342,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() booleanValue",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
@@ -368,7 +368,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() withoutSpecifiedIdInData",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
 				//	description:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
@@ -392,7 +392,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getIdentity function of the store.
 				//	description:
 				//		Simple test of the getIdentity function of the store.
@@ -415,7 +415,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the #4691 bug
 				//	description:
 				//		Simple test of the #4691 bug
@@ -438,7 +438,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the #4691 bug
 				//	description:
 				//		Simple test of the #4691 bug
@@ -461,7 +461,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() all",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore.
@@ -485,7 +485,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() abort",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch abort on AndOrReadStore.
 				//	description:
 				//		Simple test of a basic fetch abort on AndOrReadStore.
@@ -522,7 +522,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -537,8 +537,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -547,7 +547,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -562,8 +562,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "ec"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "ec"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -572,7 +572,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items.
@@ -588,8 +588,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -598,7 +598,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of only toplevel items.
@@ -614,8 +614,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "A*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "A*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -624,7 +624,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -651,14 +651,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onCompleteOne, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onCompleteOne,
 										onError: onError
 									});
 	
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "N*"}, 
-										onComplete: onCompleteTwo, 
+				store.fetch({ 	query: {name: "N*"},
+										onComplete: onCompleteTwo,
 										onError: onError
 									});
 	
@@ -668,7 +668,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -695,14 +695,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "A*"', 
-										onComplete: onCompleteOne, 
+				store.fetch({ 	query: 'name: "A*"',
+										onComplete: onCompleteOne,
 										onError: onError
 									});
 	
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "N*"', 
-										onComplete: onCompleteTwo, 
+				store.fetch({ 	query: 'name: "N*"',
+										onComplete: onCompleteTwo,
 										onError: onError
 									});
 	
@@ -712,7 +712,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -745,8 +745,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "El*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "El*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				
@@ -757,7 +757,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -790,8 +790,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "El*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "El*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				
@@ -802,7 +802,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
@@ -818,8 +818,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -829,7 +829,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of all items (including children (nested))
@@ -845,8 +845,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: 'name: "A*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "A*"',
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -856,7 +856,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -902,8 +902,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				}
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -913,7 +913,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off refs still parse",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -960,8 +960,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					d.errback(errData);
 				}
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -971,7 +971,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -990,8 +990,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 						t.assertTrue(false);
 						d.errback(errData);
 					};
-					store.fetch({ 	query: {abbr: "ec"}, 
-											onComplete: onComplete, 
+					store.fetch({ 	query: {abbr: "ec"},
+											onComplete: onComplete,
 											onError: onError
 										});
 					return d;
@@ -1001,7 +1001,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -1020,8 +1020,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 						t.assertTrue(false);
 						d.errback(errData);
 					};
-					store.fetch({ 	query: 'abbr: "ec"', 
-											onComplete: onComplete, 
+					store.fetch({ 	query: 'abbr: "ec"',
+											onComplete: onComplete,
 											onError: onError
 										});
 					return d;
@@ -1031,7 +1031,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
@@ -1047,8 +1047,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {name: "E*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "E*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1057,7 +1057,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item where some attributes are null.
@@ -1073,8 +1073,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'name: "E*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "E*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1083,7 +1083,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() all_streaming",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore.
@@ -1111,7 +1111,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 	
 				//Get everything...
 				store.fetch({	onBegin: onBegin,
-										onItem: onItem, 
+										onItem: onItem,
 										onComplete: onComplete,
 										onError: onError
 									});
@@ -1121,7 +1121,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() paging",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				//	description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -1193,7 +1193,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1209,8 +1209,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {count: "1*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {count: "1*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1219,7 +1219,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1235,8 +1235,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'count: "1*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'count: "1*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1245,7 +1245,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1261,8 +1261,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {value: "true"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {value: "true"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1271,7 +1271,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1287,8 +1287,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'value: "true"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'value: "true"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1297,7 +1297,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabel()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -1315,8 +1315,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1325,7 +1325,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabel(), complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -1343,8 +1343,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "ec"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "ec"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1353,7 +1353,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -1371,8 +1371,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1381,7 +1381,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes(), complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -1399,8 +1399,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "ec"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "ec"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1409,7 +1409,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getValue()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -1433,7 +1433,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getValues()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValues function of the store.
 				//	description:
 				//		Simple test of the getValues function of the store.
@@ -1459,7 +1459,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: isItem()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//	description:
 				//		Simple test of the isItem function of the store
@@ -1483,7 +1483,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: isItem() multistore",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//		to verify two different store instances do not accept
 				//		items from each other.
@@ -1492,7 +1492,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				//		to verify two different store instances do not accept
 				//		items from each other.
 	
-				// Two different instances, even  if they read from the same URL 
+				// Two different instances, even  if they read from the same URL
 				// should not accept items between each other!
 				var store1 = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
 				var store2 = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -1526,7 +1526,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: hasAttribute()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute function of the store
 				//	description:
 				//		Simple test of the hasAttribute function of the store
@@ -1559,7 +1559,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: containsValue()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue function of the store
 				//	description:
 				//		Simple test of the containsValue function of the store
@@ -1593,7 +1593,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getAttributes()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes function of the store
 				//	description:
 				//		Simple test of the getAttributes function of the store
@@ -1622,7 +1622,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: getFeatures()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getFeatures function of the store
 				//	description:
 				//		Simple test of the getFeatures function of the store
@@ -1636,7 +1636,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything starting with lowercase e
 				//	description:
 				//		Function to test pattern matching of everything starting with lowercase e
@@ -1671,7 +1671,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything starting with lowercase e
 				//	description:
 				//		Function to test pattern matching of everything starting with lowercase e
@@ -1706,14 +1706,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything with $ in it.
 				//	description:
 				//		Function to test pattern matching of everything with $ in it.
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1754,14 +1754,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything with $ in it.
 				//	description:
 				//		Function to test pattern matching of everything with $ in it.
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1802,14 +1802,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test exact pattern match
 				//	description:
 				//		Function to test exact pattern match
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1850,14 +1850,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test exact pattern match
 				//	description:
 				//		Function to test exact pattern match
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1898,14 +1898,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-sensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -1941,14 +1941,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-sensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -1984,14 +1984,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-insensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -2027,14 +2027,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-insensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -2070,14 +2070,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumeric",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting numerically.
 				//	description:
 				//		Function to test sorting numerically.
 				
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-													   {uniqueId: 1, value:"ba|r*foo"}, 
+													   {uniqueId: 1, value:"ba|r*foo"},
 													   {uniqueId: 2, value:"boomBam"},
 													   {uniqueId: 3, value:"bit$Bite"},
 													   {uniqueId: 4, value:"ouagadogou"},
@@ -2123,14 +2123,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericDescending",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting numerically.
 				//	description:
 				//		Function to test sorting numerically.
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-													   {uniqueId: 1, value:"ba|r*foo"}, 
+													   {uniqueId: 1, value:"ba|r*foo"},
 													   {uniqueId: 2, value:"boomBam"},
 													   {uniqueId: 3, value:"bit$Bite"},
 													   {uniqueId: 4, value:"ouagadogou"},
@@ -2175,14 +2175,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericWithCount",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
 				//	description:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-													  {uniqueId: 1, value:"ba|r*foo"}, 
+													  {uniqueId: 1, value:"ba|r*foo"},
 													  {uniqueId: 2, value:"boomBam"},
 													  {uniqueId: 3, value:"bit$Bite"},
 													  {uniqueId: 4, value:"ouagadogou"},
@@ -2230,14 +2230,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabetic",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting alphabetic ordering.
 				//	description:
 				//		Function to test sorting alphabetic ordering.
 			
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"abc"},
-													  {uniqueId: 1, value:"bca"}, 
+													  {uniqueId: 1, value:"bca"},
 													  {uniqueId: 2, value:"abcd"},
 													  {uniqueId: 3, value:"abcdefg"},
 													  {uniqueId: 4, value:"lmnop"},
@@ -2297,14 +2297,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticDescending",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting alphabetic ordering in descending mode.
 				//	description:
 				//		Function to test sorting alphabetic ordering in descending mode.
 			
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"abc"},
-													  {uniqueId: 1, value:"bca"}, 
+													  {uniqueId: 1, value:"bca"},
 													  {uniqueId: 2, value:"abcd"},
 													  {uniqueId: 3, value:"abcdefg"},
 													  {uniqueId: 4, value:"lmnop"},
@@ -2365,14 +2365,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDate",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting date.
 				//	description:
 				//		Function to test sorting date.
 			
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value: new Date(0)},
-													  {uniqueId: 1, value: new Date(100)}, 
+													  {uniqueId: 1, value: new Date(100)},
 													  {uniqueId: 2, value:new Date(1000)},
 													  {uniqueId: 3, value:new Date(2000)},
 													  {uniqueId: 4, value:new Date(3000)},
@@ -2420,14 +2420,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDateDescending",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting date in descending order.
 				//	description:
 				//		Function to test sorting date in descending order.
 			
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value: new Date(0)},
-													  {uniqueId: 1, value: new Date(100)}, 
+													  {uniqueId: 1, value: new Date(100)},
 													  {uniqueId: 2, value:new Date(1000)},
 													  {uniqueId: 3, value:new Date(2000)},
 													  {uniqueId: 4, value:new Date(3000)},
@@ -2476,14 +2476,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultiple",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting on multiple attributes.
 				//	description:
 				//		Function to test sorting on multiple attributes.
 				
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 1, value:"fo|o*b.ar"},
-													  {uniqueId: 2, value:"ba|r*foo"}, 
+													  {uniqueId: 2, value:"ba|r*foo"},
 													  {uniqueId: 3, value:"boomBam"},
 													  {uniqueId: 4, value:"bit$Bite"},
 													  {uniqueId: 5, value:"ouagadogou"},
@@ -2545,14 +2545,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultipleSpecialComparator",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting on multiple attributes with a custom comparator.
 				//	description:
 				//		Function to test sorting on multiple attributes with a custom comparator.
 	
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 1, status:"CLOSED"},
-													  {uniqueId: 2,  status:"OPEN"}, 
+													  {uniqueId: 2,  status:"OPEN"},
 													  {uniqueId: 3,  status:"PENDING"},
 													  {uniqueId: 4,  status:"BLOCKED"},
 													  {uniqueId: 5,  status:"CLOSED"},
@@ -2569,7 +2569,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 			
 			
 				store.comparatorMap = {};
-				store.comparatorMap["status"] = function(a,b) { 
+				store.comparatorMap["status"] = function(a,b) {
 					var ret = 0;
 					// We want to map these by what the priority of these items are, not by alphabetical.
 					// So, custom comparator.
@@ -2615,14 +2615,14 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticWithUndefined",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting alphabetic ordering.
 				//	description:
 				//		Function to test sorting alphabetic ordering.
 			
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"abc"},
-													  {uniqueId: 1, value:"bca"}, 
+													  {uniqueId: 1, value:"bca"},
 													  {uniqueId: 2, value:"abcd"},
 													  {uniqueId: 3, value:"abcdefg"},
 													  {uniqueId: 4, value:"lmnop"},
@@ -2670,16 +2670,16 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_inMemory",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 				//	description:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 	
-				var store = new dojox.data.AndOrReadStore({	data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({	data: { identifier: "uniqueId",
 																	items: [{uniqueId: 12345, value:"foo"},
-																			{uniqueId: 123456, value:"bar"}, 
+																			{uniqueId: 123456, value:"bar"},
 																			{uniqueId: 12345, value:"boom"},
 																			{uniqueId: 123457, value:"bit"}
 																		]
@@ -2704,7 +2704,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_xhr",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 				//	description:
@@ -2741,7 +2741,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(item !== null);
 					var independenceDate = store.getValue(item, "independence");
 					t.assertTrue(independenceDate instanceof Date);
-					//Check to see if the value was deserialized properly.  Since the store stores in UTC/GMT, it 
+					//Check to see if the value was deserialized properly.  Since the store stores in UTC/GMT, it
 					//should also be compared in the UTC/GMT mode
 					t.assertTrue(dojo.date.stamp.toISOString(independenceDate, {zulu:true}) === "1993-05-24T00:00:00Z");
 					d.callback(true);
@@ -2757,7 +2757,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_SimpleMapping",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2789,7 +2789,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_GeneralMapping",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2800,7 +2800,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrReadStore({
 						data:dataset,
-						typeMap:{'Color': 	{	
+						typeMap:{'Color': 	{
 												type: dojo.Color,
 												deserialize: function(value){
 													return new dojo.Color(value);
@@ -2827,7 +2827,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject 0 (False) value",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2838,7 +2838,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrReadStore({
 						data:dataset,
-						typeMap:{'dojox.data.tests.Wrapper': 	{	
+						typeMap:{'dojox.data.tests.Wrapper': 	{
 												type: dojox.data.tests.Wrapper,
 												deserialize: function(value){
 													return new dojox.data.tests.Wrapper(value);
@@ -2866,7 +2866,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject Boolean False values",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2877,7 +2877,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrReadStore({
 						data:dataset,
-						typeMap:{'dojox.data.tests.Wrapper': 	{	
+						typeMap:{'dojox.data.tests.Wrapper': 	{
 												type: dojox.data.tests.Wrapper,
 												deserialize: function(value){
 													return new dojox.data.tests.Wrapper(value);
@@ -2904,7 +2904,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject Empty String values",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2915,7 +2915,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrReadStore({
 						data:dataset,
-						typeMap:{'dojox.data.tests.Wrapper': 	{	
+						typeMap:{'dojox.data.tests.Wrapper': 	{
 												type: dojox.data.tests.Wrapper,
 												deserialize: function(value){
 													return new dojox.data.tests.Wrapper(value);
@@ -2942,7 +2942,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject explicit null values",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2953,7 +2953,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrReadStore({
 						data:dataset,
-						typeMap:{'dojox.data.tests.Wrapper': 	{	
+						typeMap:{'dojox.data.tests.Wrapper': 	{
 												type: dojox.data.tests.Wrapper,
 												deserialize: function(value){
 													return new dojox.data.tests.Wrapper(value);
@@ -2980,7 +2980,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_CustomObject explicit undefined value",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test type mapping and _values that are false-like
 				var dataset = {
 					identifier:'name',
@@ -2991,7 +2991,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrReadStore({
 						data:dataset,
-						typeMap:{'dojox.data.tests.Wrapper': 	{	
+						typeMap:{'dojox.data.tests.Wrapper': 	{
 												type: dojox.data.tests.Wrapper,
 												deserialize: function(value){
 													return new dojox.data.tests.Wrapper(value);
@@ -3071,7 +3071,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -3127,7 +3127,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch, close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -3185,7 +3185,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset _jsonFileUrl.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrReadStore(dojox.data.tests.stores.AndOrReadStore.getTestData("countries"));
@@ -3241,13 +3241,13 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset data.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test that clear on close and reset of data works.
 				//	description:
 				//		Function to test that clear on close and reset of data works.
-				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrReadStore({data: { identifier: "uniqueId",
 						items: [ {uniqueId: 1, value:"foo*bar"},
-							{uniqueId: 2, value:"bar*foo"}, 
+							{uniqueId: 2, value:"bar*foo"},
 							{uniqueId: 3, value:"boomBam"},
 							{uniqueId: 4, value:"bit$Bite"},
 							{uniqueId: 5, value:"ouagadogou"},
@@ -3266,9 +3266,9 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 	
 					//Set the store clearing options and the new data
 					store.clearOnClose = true;
-					store.data = { identifier: "uniqueId", 
+					store.data = { identifier: "uniqueId",
 						items: [ {uniqueId: 1, value:"foo*bar"},
-							{uniqueId: 2, value:"bar*foo"}, 
+							{uniqueId: 2, value:"bar*foo"},
 							{uniqueId: 3, value:"boomBam"},
 							{uniqueId: 4, value:"bit$Bite"},
 							{uniqueId: 5, value:"ouagadogou"},
@@ -3309,7 +3309,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 	 		runTest: function(t){
 				var arrayOfItems = [
 					{name:"Kermit", color:"green"},
-					{name:"Miss Piggy", likes:"Kermit"}, 
+					{name:"Miss Piggy", likes:"Kermit"},
 					{name:"Beaker", hairColor:"red"}
 				];
 				var store = new dojox.data.AndOrReadStore({data:{items:arrayOfItems}});
@@ -3362,7 +3362,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: functionConformance",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -3390,7 +3390,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Identity API: functionConformance",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -3421,7 +3421,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, OR, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -3436,8 +3436,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "s*" || capital:"A*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "s*" || capital:"A*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3446,7 +3446,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND(OR, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -3461,8 +3461,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "e*" AND (capital:"A*" or capital: "Q*")', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "e*" AND (capital:"A*" or capital: "Q*")',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3471,7 +3471,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND(OR, as json object, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -3486,8 +3486,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")'}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")'},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3496,7 +3496,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -3511,8 +3511,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")', name: "Ec*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")', name: "Ec*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3521,7 +3521,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs and spaces",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -3537,8 +3537,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {complexQuery:'abbr: "g*" AND (capital:"A*" or capital: "M*")', name: "Equatorial G*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {complexQuery:'abbr: "g*" AND (capital:"A*" or capital: "M*")', name: "Equatorial G*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3547,7 +3547,7 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as quoted json object, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrReadStore of a single item.
@@ -3562,8 +3562,8 @@ dojox.data.tests.stores.AndOrReadStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: "{complexQuery:'abbr: \"e*\" AND (capital:\"A*\" or capital: \"Q*\")'}", 
-										onComplete: onComplete, 
+				store.fetch({ 	query: "{complexQuery:'abbr: \"e*\" AND (capital:\"A*\" or capital: \"Q*\")'}",
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
diff --git a/dojox/data/tests/stores/AndOrWriteStore.js b/dojox/data/tests/stores/AndOrWriteStore.js
index 35495bb..a20c3f1 100755
--- a/dojox/data/tests/stores/AndOrWriteStore.js
+++ b/dojox/data/tests/stores/AndOrWriteStore.js
@@ -8,16 +8,16 @@ dojo.require("dojo.data.api.Write");
 dojo.require("dojo.data.api.Notification");
 
 
-//The test data-sets and tests are taken from ItemFileReadStore, to show 
-//  backwards compatibility, and from ItemFileWriteStore.  
+//The test data-sets and tests are taken from ItemFileReadStore, to show
+//  backwards compatibility, and from ItemFileWriteStore.
 //Since no new write capabilities are included in AndOrWriteStore (just those from
 //  ItemFileWriteStore), no new write tests were added.
 //Additionally, where appropriate (fetch/query), the ItemFileReadStore test is immediately
-//  followed by the same query (with ", complex" in the description), but with the query 
-//  being a string rather than a json object. 
+//  followed by the same query (with ", complex" in the description), but with the query
+//  being a string rather than a json object.
 //Below all those tests are new ones that test the use of AND, OR, NOT, ||, &&, (, ), and ","
 //  in queries, as well as a mix of string and json object queries.
-//Since some widgets expect the query to be in json object form, in addition to the 
+//Since some widgets expect the query to be in json object form, in addition to the
 //  query="id:1234 || dept:'Sales Department' || (dept:Auto && id:2*)" programmatic syntax,
 //  query="{complexQuery:'id:1234 || dept:\"Sales Department\" || (dept:Auto && id:2*)" is
 //  tested/supported.
@@ -30,7 +30,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 		if(dojo.isBrowser){
 			data = {url: dojo.moduleUrl("dojox", "data/tests/stores/countries.json").toString() };
 		}else{
-			data = {data: { 
+			data = {data: {
 				identifier:'abbr',
 				label:'name',
 				items:[
@@ -45,7 +45,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 			} };
 		}
 	}else if(name === "countries_withNull"){
-		data = {data: { 
+		data = {data: {
 			identifier:"abbr",
 			items:[
 				{abbr:"ec", name:null, capital:"Quito"},
@@ -58,7 +58,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 			]
 		} };
 	}else if(name === "countries_withoutid"){
-		data = {data: { 
+		data = {data: {
 			label: "name",
 			items:[
 				{abbr:"ec", name:null, capital:"Quito"},
@@ -71,7 +71,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 			]
 		} };
 	}else if (name === "countries_withBoolean"){
-		data = {data: { 
+		data = {data: {
 			identifier:"abbr",
 			items:[
 				{abbr:"ec", name:"Ecuador", capital:"Quito", real:true},
@@ -85,7 +85,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 			]
 		} };
 	}else if (name === "countries_withDates"){
-		data = {data: { 
+		data = {data: {
 			identifier:"abbr",
 			items:[
 				{abbr:"ec", name:"Ecuador", capital:"Quito"},
@@ -98,7 +98,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 			]
 		} };
 	}else if (name === "geography_hierarchy_small"){
-		data = {data: { 
+		data = {data: {
 			items:[
 				{ name:'Africa', countries:[
 					{ name:'Egypt', capital:'Cairo' },
@@ -118,9 +118,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 			]
 		}};
 	}else if (name === "data_multitype"){
-		data = {data: { 
+		data = {data: {
 						"identifier": "count",
-						"label": "count", 
+						"label": "count",
 						items: [
 							{ count: 1,    value: "true" },
 							{ count: 2,    value: true   },
@@ -135,7 +135,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 							{ count: 11,   value: [false, false]},
 							{ count: "12", value: [false, "true"]}
 					   ]
-					} 
+					}
 				};
 	}else if (name === "countries_references"){
 		data = {data: { identifier: 'name',
@@ -185,8 +185,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTestData = function(name){
 					}
 				};
 	}else if(name === "reference_integrity"){  //write test data.
-		data = 
-			{ data: { 
+		data =
+			{ data: {
 				"identifier": "id",
 				"label": "name",
 				"items": [
@@ -220,7 +220,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity()",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
@@ -244,7 +244,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() notFound",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store.
@@ -266,7 +266,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentityAttributes()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getIdentityAttributes function.
 				//	description:
 				//		Simple test of the getIdentityAttributes function.
@@ -292,7 +292,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() commentFilteredJson",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store.
@@ -322,7 +322,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() nullValue",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checling a null value.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a null value.
@@ -348,7 +348,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() booleanValue",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
 				//	description:
 				//		Simple test of the fetchItemByIdentity function of the store, checking a boolean value.
@@ -374,7 +374,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: fetchItemByIdentity() withoutSpecifiedIdInData",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
 				//	description:
 				//		Simple test of bug #4691, looking up something by assigned id, not one specified in the JSON data.
@@ -398,7 +398,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getIdentity function of the store.
 				//	description:
 				//		Simple test of the getIdentity function of the store.
@@ -421,7 +421,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the #4691 bug
 				//	description:
 				//		Simple test of the #4691 bug
@@ -444,7 +444,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: getIdentity() withoutSpecifiedId, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the #4691 bug
 				//	description:
 				//		Simple test of the #4691 bug
@@ -467,7 +467,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() all",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore.
@@ -491,7 +491,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() abort",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch abort on AndOrWriteStore.
 				//	description:
 				//		Simple test of a basic fetch abort on AndOrWriteStore.
@@ -528,7 +528,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -543,8 +543,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -553,7 +553,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -568,8 +568,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "ec"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "ec"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -578,7 +578,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items.
@@ -594,8 +594,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -604,7 +604,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() shallow, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of only toplevel items.
@@ -620,8 +620,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "A*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "A*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -630,7 +630,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -657,14 +657,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onCompleteOne, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onCompleteOne,
 										onError: onError
 									});
 	
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "N*"}, 
-										onComplete: onCompleteTwo, 
+				store.fetch({ 	query: {name: "N*"},
+										onComplete: onCompleteTwo,
 										onError: onError
 									});
 	
@@ -674,7 +674,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() Multiple, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -701,14 +701,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "A*"', 
-										onComplete: onCompleteOne, 
+				store.fetch({ 	query: 'name: "A*"',
+										onComplete: onCompleteOne,
 										onError: onError
 									});
 	
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "N*"', 
-										onComplete: onCompleteTwo, 
+				store.fetch({ 	query: 'name: "N*"',
+										onComplete: onCompleteTwo,
 										onError: onError
 									});
 	
@@ -718,7 +718,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -751,8 +751,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				};
 				
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: {name: "El*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "El*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				
@@ -763,7 +763,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() MultipleMixedFetch, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
 				//	description:
 				//		Tests that multiple fetches at the same time queue up properly and do not clobber each other on initial load.
@@ -796,8 +796,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				};
 				
 				//Find all items starting with A, only toplevel (root) items.
-				store.fetch({ 	query: 'name: "El*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "El*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				
@@ -808,7 +808,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
@@ -824,8 +824,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -835,7 +835,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() deep, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items (including children (nested))
@@ -851,8 +851,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				};
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: 'name: "A*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "A*"',
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -862,7 +862,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -908,8 +908,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				}
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -919,7 +919,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() hierarchy off refs still parse",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of all items with hierarchy disabled
 				//		This should turn off processing child objects as data store items.  It will still process
 				//		references and type maps.
@@ -966,8 +966,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					d.errback(errData);
 				}
 				//Find all items starting with A, including child (nested) items.
-				store.fetch({ 	query: {name: "A*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "A*"},
+										onComplete: onComplete,
 										onError: onError,
 										queryOptions: {deep:true}
 									});
@@ -977,7 +977,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -996,8 +996,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						t.assertTrue(false);
 						d.errback(errData);
 					};
-					store.fetch({ 	query: {abbr: "ec"}, 
-											onComplete: onComplete, 
+					store.fetch({ 	query: {abbr: "ec"},
+											onComplete: onComplete,
 											onError: onError
 										});
 					return d;
@@ -1007,7 +1007,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() one_commentFilteredJson, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -1026,8 +1026,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						t.assertTrue(false);
 						d.errback(errData);
 					};
-					store.fetch({ 	query: 'abbr: "ec"', 
-											onComplete: onComplete, 
+					store.fetch({ 	query: 'abbr: "ec"',
+											onComplete: onComplete,
 											onError: onError
 										});
 					return d;
@@ -1037,7 +1037,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
@@ -1053,8 +1053,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {name: "E*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {name: "E*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1063,7 +1063,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() withNull, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item where some attributes are null.
@@ -1079,8 +1079,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'name: "E*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'name: "E*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1089,7 +1089,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() all_streaming",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore.
@@ -1117,7 +1117,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 	
 				//Get everything...
 				store.fetch({	onBegin: onBegin,
-										onItem: onItem, 
+										onItem: onItem,
 										onComplete: onComplete,
 										onError: onError
 									});
@@ -1127,7 +1127,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() paging",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				//	description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -1199,7 +1199,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1215,8 +1215,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {count: "1*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {count: "1*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1225,7 +1225,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType Match, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1241,8 +1241,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'count: "1*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'count: "1*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1251,7 +1251,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1267,8 +1267,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {value: "true"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {value: "true"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1277,7 +1277,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() with MultiType, MultiValue Match, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
 				//	description:
 				//		Simple test of a basic fetch againct an attribute that has different types for the value across items
@@ -1293,8 +1293,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'value: "true"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'value: "true"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1303,7 +1303,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabel()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -1321,8 +1321,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1331,7 +1331,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabel(), complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -1349,8 +1349,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "ec"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "ec"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1359,7 +1359,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -1377,8 +1377,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {abbr: "ec"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {abbr: "ec"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1387,7 +1387,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getLabelAttributes(), complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -1405,8 +1405,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "ec"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "ec"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -1415,7 +1415,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getValue()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -1439,7 +1439,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getValues()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValues function of the store.
 				//	description:
 				//		Simple test of the getValues function of the store.
@@ -1465,7 +1465,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: isItem()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//	description:
 				//		Simple test of the isItem function of the store
@@ -1489,7 +1489,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: isItem() multistore",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//		to verify two different store instances do not accept
 				//		items from each other.
@@ -1498,7 +1498,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				//		to verify two different store instances do not accept
 				//		items from each other.
 	
-				// Two different instances, even  if they read from the same URL 
+				// Two different instances, even  if they read from the same URL
 				// should not accept items between each other!
 				var store1 = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 				var store2 = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -1532,7 +1532,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: hasAttribute()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute function of the store
 				//	description:
 				//		Simple test of the hasAttribute function of the store
@@ -1565,7 +1565,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: containsValue()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue function of the store
 				//	description:
 				//		Simple test of the containsValue function of the store
@@ -1599,7 +1599,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getAttributes()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes function of the store
 				//	description:
 				//		Simple test of the getAttributes function of the store
@@ -1628,7 +1628,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: getFeatures()",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getFeatures function of the store
 				//	description:
 				//		Simple test of the getFeatures function of the store
@@ -1642,7 +1642,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything starting with lowercase e
 				//	description:
 				//		Function to test pattern matching of everything starting with lowercase e
@@ -1677,7 +1677,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch0, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything starting with lowercase e
 				//	description:
 				//		Function to test pattern matching of everything starting with lowercase e
@@ -1712,14 +1712,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything with $ in it.
 				//	description:
 				//		Function to test pattern matching of everything with $ in it.
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1760,14 +1760,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch1, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of everything with $ in it.
 				//	description:
 				//		Function to test pattern matching of everything with $ in it.
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1808,14 +1808,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test exact pattern match
 				//	description:
 				//		Function to test exact pattern match
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1856,14 +1856,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch2, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test exact pattern match
 				//	description:
 				//		Function to test exact pattern match
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"boomBam"},
 													   {uniqueId: 4, value:"bit$Bite"},
 													   {uniqueId: 5, value:"ouagadogou"},
@@ -1904,14 +1904,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-sensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -1947,14 +1947,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseSensitive, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-sensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-sensitively
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -1990,14 +1990,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-insensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -2033,14 +2033,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() patternMatch_caseInsensitive, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test pattern matching of a pattern case-insensitively
 				//	description:
 				//		Function to test pattern matching of a pattern case-insensitively
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 1, value:"foo*bar"},
-													   {uniqueId: 2, value:"bar*foo"}, 
+													   {uniqueId: 2, value:"bar*foo"},
 													   {uniqueId: 3, value:"BAR*foo"},
 													   {uniqueId: 4, value:"BARBananafoo"}
 													 ]
@@ -2076,14 +2076,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumeric",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting numerically.
 				//	description:
 				//		Function to test sorting numerically.
 				
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-													   {uniqueId: 1, value:"ba|r*foo"}, 
+													   {uniqueId: 1, value:"ba|r*foo"},
 													   {uniqueId: 2, value:"boomBam"},
 													   {uniqueId: 3, value:"bit$Bite"},
 													   {uniqueId: 4, value:"ouagadogou"},
@@ -2129,14 +2129,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericDescending",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting numerically.
 				//	description:
 				//		Function to test sorting numerically.
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												  items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-													   {uniqueId: 1, value:"ba|r*foo"}, 
+													   {uniqueId: 1, value:"ba|r*foo"},
 													   {uniqueId: 2, value:"boomBam"},
 													   {uniqueId: 3, value:"bit$Bite"},
 													   {uniqueId: 4, value:"ouagadogou"},
@@ -2181,14 +2181,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortNumericWithCount",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
 				//	description:
 				//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"fo|o*b.ar"},
-													  {uniqueId: 1, value:"ba|r*foo"}, 
+													  {uniqueId: 1, value:"ba|r*foo"},
 													  {uniqueId: 2, value:"boomBam"},
 													  {uniqueId: 3, value:"bit$Bite"},
 													  {uniqueId: 4, value:"ouagadogou"},
@@ -2236,14 +2236,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabetic",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting alphabetic ordering.
 				//	description:
 				//		Function to test sorting alphabetic ordering.
 			
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"abc"},
-													  {uniqueId: 1, value:"bca"}, 
+													  {uniqueId: 1, value:"bca"},
 													  {uniqueId: 2, value:"abcd"},
 													  {uniqueId: 3, value:"abcdefg"},
 													  {uniqueId: 4, value:"lmnop"},
@@ -2303,14 +2303,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticDescending",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting alphabetic ordering in descending mode.
 				//	description:
 				//		Function to test sorting alphabetic ordering in descending mode.
 			
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"abc"},
-													  {uniqueId: 1, value:"bca"}, 
+													  {uniqueId: 1, value:"bca"},
 													  {uniqueId: 2, value:"abcd"},
 													  {uniqueId: 3, value:"abcdefg"},
 													  {uniqueId: 4, value:"lmnop"},
@@ -2371,14 +2371,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDate",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting date.
 				//	description:
 				//		Function to test sorting date.
 			
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value: new Date(0)},
-													  {uniqueId: 1, value: new Date(100)}, 
+													  {uniqueId: 1, value: new Date(100)},
 													  {uniqueId: 2, value:new Date(1000)},
 													  {uniqueId: 3, value:new Date(2000)},
 													  {uniqueId: 4, value:new Date(3000)},
@@ -2426,14 +2426,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortDateDescending",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting date in descending order.
 				//	description:
 				//		Function to test sorting date in descending order.
 			
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value: new Date(0)},
-													  {uniqueId: 1, value: new Date(100)}, 
+													  {uniqueId: 1, value: new Date(100)},
 													  {uniqueId: 2, value:new Date(1000)},
 													  {uniqueId: 3, value:new Date(2000)},
 													  {uniqueId: 4, value:new Date(3000)},
@@ -2482,14 +2482,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultiple",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting on multiple attributes.
 				//	description:
 				//		Function to test sorting on multiple attributes.
 				
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 1, value:"fo|o*b.ar"},
-													  {uniqueId: 2, value:"ba|r*foo"}, 
+													  {uniqueId: 2, value:"ba|r*foo"},
 													  {uniqueId: 3, value:"boomBam"},
 													  {uniqueId: 4, value:"bit$Bite"},
 													  {uniqueId: 5, value:"ouagadogou"},
@@ -2551,14 +2551,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortMultipleSpecialComparator",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting on multiple attributes with a custom comparator.
 				//	description:
 				//		Function to test sorting on multiple attributes with a custom comparator.
 	
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 1, status:"CLOSED"},
-													  {uniqueId: 2,  status:"OPEN"}, 
+													  {uniqueId: 2,  status:"OPEN"},
 													  {uniqueId: 3,  status:"PENDING"},
 													  {uniqueId: 4,  status:"BLOCKED"},
 													  {uniqueId: 5,  status:"CLOSED"},
@@ -2575,7 +2575,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 			
 			
 				store.comparatorMap = {};
-				store.comparatorMap["status"] = function(a,b) { 
+				store.comparatorMap["status"] = function(a,b) {
 					var ret = 0;
 					// We want to map these by what the priority of these items are, not by alphabetical.
 					// So, custom comparator.
@@ -2621,14 +2621,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() sortAlphabeticWithUndefined",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test sorting alphabetic ordering.
 				//	description:
 				//		Function to test sorting alphabetic ordering.
 			
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 												 items: [ {uniqueId: 0, value:"abc"},
-													  {uniqueId: 1, value:"bca"}, 
+													  {uniqueId: 1, value:"bca"},
 													  {uniqueId: 2, value:"abcd"},
 													  {uniqueId: 3, value:"abcdefg"},
 													  {uniqueId: 4, value:"lmnop"},
@@ -2676,16 +2676,16 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_inMemory",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 				//	description:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 	
-				var store = new dojox.data.AndOrWriteStore({	data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({	data: { identifier: "uniqueId",
 																	items: [{uniqueId: 12345, value:"foo"},
-																			{uniqueId: 123456, value:"bar"}, 
+																			{uniqueId: 123456, value:"bar"},
 																			{uniqueId: 12345, value:"boom"},
 																			{uniqueId: 123457, value:"bit"}
 																		]
@@ -2710,7 +2710,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: errorCondition_idCollision_xhr",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the errors thrown when there is an id collision in the data.
 				//		Added because of tracker: #2546
 				//	description:
@@ -2747,7 +2747,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(item !== null);
 					var independenceDate = store.getValue(item, "independence");
 					t.assertTrue(independenceDate instanceof Date);
-					//Check to see if the value was deserialized properly.  Since the store stores in UTC/GMT, it 
+					//Check to see if the value was deserialized properly.  Since the store stores in UTC/GMT, it
 					//should also be compared in the UTC/GMT mode
 					t.assertTrue(dojo.date.stamp.toISOString(independenceDate, {zulu:true}) === "1993-05-24T00:00:00Z");
 					d.callback(true);
@@ -2763,7 +2763,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_SimpleMapping",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2795,7 +2795,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: custom_datatype_Color_GeneralMapping",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test using literal values with custom datatypes
 				var dataset = {
 					identifier:'name',
@@ -2806,7 +2806,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				};
 				var store = new dojox.data.AndOrWriteStore({
 						data:dataset,
-						typeMap:{'Color': 	{	
+						typeMap:{'Color': 	{
 												type: dojo.Color,
 												deserialize: function(value){
 													return new dojo.Color(value);
@@ -2889,7 +2889,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 	 		runTest: function(t){
 				var arrayOfItems = [
 					{name:"Kermit", color:"green"},
-					{name:"Miss Piggy", likes:"Kermit"}, 
+					{name:"Miss Piggy", likes:"Kermit"},
 					{name:"Beaker", hairColor:"red"}
 				];
 				var store = new dojox.data.AndOrWriteStore({data:{items:arrayOfItems}});
@@ -2942,7 +2942,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: functionConformance",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -2970,7 +2970,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Identity API: functionConformance",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -3001,7 +3001,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, OR, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -3016,8 +3016,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "s*" || capital:"A*"', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "s*" || capital:"A*"',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3026,7 +3026,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND(OR, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -3041,8 +3041,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: 'abbr: "e*" AND (capital:"A*" or capital: "Q*")', 
-										onComplete: onComplete, 
+				store.fetch({ 	query: 'abbr: "e*" AND (capital:"A*" or capital: "Q*")',
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3051,7 +3051,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -3066,8 +3066,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")'}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")'},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3076,7 +3076,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -3091,8 +3091,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")', name: "Ec*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {complexQuery:'abbr: "e*" AND (capital:"A*" or capital: "Q*")', name: "Ec*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3101,7 +3101,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as json object, complex, with extra attrs and spaces",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -3120,8 +3120,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				var onError = function(errData, request){
 					d.errback(errData);
 				};
-				store.fetch({ 	query: {complexQuery:'abbr: "g*" AND (capital:"A*" or capital: "M*")', name: "Equatorial G*"}, 
-										onComplete: onComplete, 
+				store.fetch({ 	query: {complexQuery:'abbr: "g*" AND (capital:"A*" or capital: "M*")', name: "Equatorial G*"},
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3130,7 +3130,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch() multiple, AND/OR, as quoted json object, complex",
 	 		runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on AndOrWriteStore of a single item.
@@ -3145,8 +3145,8 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 					d.errback(errData);
 				};
-				store.fetch({ 	query: "{complexQuery:'abbr: \"e*\" AND (capital:\"A*\" or capital: \"Q*\")'}", 
-										onComplete: onComplete, 
+				store.fetch({ 	query: "{complexQuery:'abbr: \"e*\" AND (capital:\"A*\" or capital: \"Q*\")'}",
+										onComplete: onComplete,
 										onError: onError
 									});
 				return d;
@@ -3155,7 +3155,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -3211,7 +3211,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: fetch, close (clearOnClose: true, reset url.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -3269,7 +3269,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset _jsonFileUrl.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test the close api properly clears the store for reload when clearOnClose is set.
 				if (dojo.isBrowser) {
 					var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
@@ -3325,13 +3325,13 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Read API: close (clearOnClose: true, reset data.)",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Function to test that clear on close and reset of data works.
 				//	description:
 				//		Function to test that clear on close and reset of data works.
-				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId", 
+				var store = new dojox.data.AndOrWriteStore({data: { identifier: "uniqueId",
 						items: [ {uniqueId: 1, value:"foo*bar"},
-							{uniqueId: 2, value:"bar*foo"}, 
+							{uniqueId: 2, value:"bar*foo"},
 							{uniqueId: 3, value:"boomBam"},
 							{uniqueId: 4, value:"bit$Bite"},
 							{uniqueId: 5, value:"ouagadogou"},
@@ -3350,9 +3350,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 	
 					//Set the store clearing options and the new data
 					store.clearOnClose = true;
-					store.data = { identifier: "uniqueId", 
+					store.data = { identifier: "uniqueId",
 						items: [ {uniqueId: 1, value:"foo*bar"},
-							{uniqueId: 2, value:"bar*foo"}, 
+							{uniqueId: 2, value:"bar*foo"},
 							{uniqueId: 3, value:"boomBam"},
 							{uniqueId: 4, value:"bit$Bite"},
 							{uniqueId: 5, value:"ouagadogou"},
@@ -3393,13 +3393,13 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API:  getFeatures",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getFeatures function of the store
 				//	description:
 				//		Simple test of the getFeatures function of the store
 				var store = new dojox.data.AndOrWriteStore(dojox.data.tests.stores.AndOrWriteStore.getTestData("countries"));
 	
-				var features = store.getFeatures(); 
+				var features = store.getFeatures();
 	
 				// make sure we have the expected features:
 				t.assertTrue(features["dojo.data.api.Read"] !== null);
@@ -3411,9 +3411,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				// and only the expected features:
 				var count = 0;
 				for(var i in features){
-					t.assertTrue((i === "dojo.data.api.Read" || 
-						i === "dojo.data.api.Identity" || 
-						i === "dojo.data.api.Write" || 
+					t.assertTrue((i === "dojo.data.api.Read" ||
+						i === "dojo.data.api.Identity" ||
+						i === "dojo.data.api.Write" ||
 						i === "dojo.data.api.Notification"));
 					count++;
 				}
@@ -3423,7 +3423,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API:  setValue",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the setValue API
 				//	description:
 				//		Simple test of the setValue API
@@ -3435,7 +3435,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					var item = items[0];
 					t.assertTrue(store.containsValue(item, "capital", "Cairo"));
 					
-					// FIXME:  
+					// FIXME:
 					//    Okay, so this seems very odd.  Maybe I'm just being dense.
 					//    These tests works:
 					t.assertEqual(store.isDirty(item), false);
@@ -3443,7 +3443,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					//    But these seemingly equivalent tests will not work:
 					// t.assertFalse(store.isDirty(item));
 					// t.assertTrue(!(store.isDirty(item)));
-					//   
+					//
 					//    All of which seems especially weird, given that this *does* work:
 					t.assertFalse(store.isDirty());
 					
@@ -3466,7 +3466,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: setValues",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the setValues API
 				//	description:
 				//		Simple test of the setValues API
@@ -3497,7 +3497,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: unsetAttribute",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the unsetAttribute API
 				//	description:
 				//		Simple test of the unsetAttribute API
@@ -3526,7 +3526,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the newItem API
 				//	description:
 				//		Simple test of the newItem API
@@ -3565,7 +3565,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem with a parent assignment",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the newItem API with a parent assignment
 				//	description:
 				//		Simple test of the newItem API with a parent assignment
@@ -3624,7 +3624,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem with a parent assignment multiple times",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the newItem API with a parent assignment multiple times.
 				//	description:
 				//		Simple test of the newItem API with a parent assignment multiple times.
@@ -3691,7 +3691,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: deleteItem",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the deleteItem API
 				//	description:
 				//		Simple test of the deleteItem API
@@ -3725,7 +3725,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: isDirty",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isDirty API
 				//	description:
 				//		Simple test of the isDirty API
@@ -3751,7 +3751,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: revert",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the revert API
 				//	description:
 				//		Simple test of the revert API
@@ -3791,7 +3791,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: save",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the save API
 				//	description:
 				//		Simple test of the save API
@@ -3815,7 +3815,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: save, verify state",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the save API
 				//	description:
 				//		Simple test of the save API
@@ -3842,7 +3842,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the save API
 				//	description:
 				//		Simple test of the save API
@@ -3887,7 +3887,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything with Date type",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
 				//	description:
 				//		Simple test of the save API	with a non-atomic type (Date) that has a type mapping.
@@ -3902,7 +3902,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					var newStore = new dojox.data.AndOrWriteStore({data: dataset});
 	
 					var gotItem = function(item){
-						var independenceDate = newStore.getValue(item,"independence"); 
+						var independenceDate = newStore.getValue(item,"independence");
 						t.assertTrue(independenceDate instanceof Date);
 						t.assertTrue(dojo.date.compare(new Date(1993,4,24), independenceDate, "date") === 0);
 						saveCompleteCallback();
@@ -3931,7 +3931,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything, with custom color simple type",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 				//	description:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
@@ -3961,7 +3961,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					var newStore = new dojox.data.AndOrWriteStore({data: dataset, typeMap: customTypeMap});
 	
 					var gotItem = function(item){
-						var hairColor = newStore.getValue(item,"hairColor"); 
+						var hairColor = newStore.getValue(item,"hairColor");
 						t.assertTrue(hairColor instanceof dojo.Color);
 						t.assertEqual("rgba(255, 255, 0, 1)", hairColor.toString());
 						saveCompleteCallback();
@@ -3989,7 +3989,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: saveEverything, with custom color type general",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
 				//	description:
 				//		Simple test of the save API	with a non-atomic type (dojo.Color) that has a type mapping.
@@ -4005,7 +4005,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					]
 				};
 	
-				var customTypeMap = {'Color': 	{	
+				var customTypeMap = {'Color': 	{
 													type: dojo.Color,
 													deserialize: function(value){
 														return new dojo.Color(value);
@@ -4027,7 +4027,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					var newStore = new dojox.data.AndOrWriteStore({data: dataset, typeMap: customTypeMap});
 	
 					var gotItem = function(item){
-						var hairColor = newStore.getValue(item,"hairColor"); 
+						var hairColor = newStore.getValue(item,"hairColor");
 						t.assertTrue(hairColor instanceof dojo.Color);
 						t.assertEqual("rgba(255, 255, 0, 1)", hairColor.toString());
 						saveCompleteCallback();
@@ -4055,7 +4055,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem, revert",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Test for bug #5357.  Ensure that the revert properly nulls the identity position
 				//      for a new item after revert.
 				var args = {data: {
@@ -4069,7 +4069,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						{name:'Estonia', capital:'Tallinn'},
 						{name:'Ethiopia', capital:'Addis Ababa'}
 					]
-				} }; 
+				} };
 				var store = new dojox.data.AndOrWriteStore(args);
 	
 				var newCountry = store.newItem({name: "Utopia", capitol: "Perfect"});
@@ -4084,7 +4084,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem, modify revert",
 			runTest: function(){
-				//	summary: 
+				//	summary:
 				//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
 				//	description:
 				//		Test of a new item, modify it, then revert, to ensure the state remains consistent.  Added due to #9022.
@@ -4121,7 +4121,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: newItem, modify, delete, revert",
 			runTest: function(){
-				//	summary: 
+				//	summary:
 				//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
 				//	description:
 				//		Test of a new item, modify it, delete it, then revert, to ensure the state remains consistent.  Added due to #9022.
@@ -4147,7 +4147,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						doh.assertEqual(afterNewCount, (initialCount + 1));
 						store.deleteItem(canada);
 						
-						//Check that after delete, the total items count goes back to initial count.  
+						//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){
 							var afterDeleteCount = items.length;
@@ -4155,7 +4155,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 	
 							for(i=0; i < items.length; i++){
 								found = (store.getIdentity(items[i]) === "ca");
-								if(found){ 
+								if(found){
 									break;
 								}
 							}
@@ -4163,14 +4163,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 								deferred.errback(new Error("Error: Found the supposedly deleted item!"));
 							}else{
 								store.revert();
-								//Check that after revert, we still have the same item count as the 
+								//Check that after revert, we still have the same item count as the
 								//original fetch.  Also verify the item with abbr of ca is gone.
 								var afterRevertFetch = function(items, request){
 									var afterRevertCount = items.length;
 									doh.assertEqual(afterRevertCount, initialCount);
 									for(i=0; i < items.length; i++){
 										found = (store.getIdentity(items[i]) === "ca");
-										if(found){ 
+										if(found){
 											break;
 										}
 									}
@@ -4195,7 +4195,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: onSet notification",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the onSet API
 				//	description:
 				//		Simple test of the onSet API
@@ -4226,7 +4226,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: onNew notification",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the onNew API
 				//	description:
 				//		Simple test of the onNew API
@@ -4247,7 +4247,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: onDelete notification",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the onDelete API
 				//	description:
 				//		Simple test of the onDelete API
@@ -4275,7 +4275,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Read API conformance",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -4300,7 +4300,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Write API conformance",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -4325,7 +4325,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Notification API conformance",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test Notification API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -4350,9 +4350,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Identity, auto-creation when missing",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Test for bug #3873. Given a datafile that does not specify an
-				//		identifier, make sure AndOrWriteStore auto-creates identities 
+				//		identifier, make sure AndOrWriteStore auto-creates identities
 				//		that are unique even after calls to deleteItem() and newItem()
 				var args = {data: {
 					label:"name",
@@ -4365,7 +4365,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						{name:'Estonia', capital:'Tallinn'},
 						{name:'Ethiopia', capital:'Addis Ababa'}
 					]
-				} }; 
+				} };
 				var store = new dojox.data.AndOrWriteStore(args);
 				var d = new doh.Deferred();
 				
@@ -4406,9 +4406,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: Identity, auto-creation when missing, revert",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Test for bug #4691  Given a datafile that does not specify an
-				//		identifier, make sure AndOrWriteStore auto-creates identities 
+				//		identifier, make sure AndOrWriteStore auto-creates identities
 				//		that are unique even after calls to deleteItem() and newItem()
 				var args = {data: {
 					label:"name",
@@ -4421,7 +4421,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						{name:'Estonia', capital:'Tallinn'},
 						{name:'Ethiopia', capital:'Addis Ababa'}
 					]
-				} }; 
+				} };
 				var store = new dojox.data.AndOrWriteStore(args);
 				var d = new doh.Deferred();
 				
@@ -4469,7 +4469,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, check references",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify the references were properly resolved.
 				//	description:
 				//		Simple test to verify the references were properly resolved.
@@ -4541,7 +4541,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete referenced item",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify the references were properly deleted.
 				//	description:
 				//		Simple test to verify the references were properly deleted.
@@ -4599,7 +4599,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete referenced item, then revert",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify the references were properly deleted.
 				//	description:
 				//		Simple test to verify the references were properly deleted.
@@ -4613,7 +4613,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				};
 				var onItem = function(item, request){
 					try{
-						//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+						//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 						//THIS IS FOR TESTING INTERNAL STATE!
 						console.log("Map before delete:");
 						store._dumpReferenceMap();
@@ -4642,7 +4642,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete multiple items with references and revert",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify that a flow of deleting items with references and reverting does not damage the internal structure.
 				//		Created for tracker bug: #5743
 				//	description:
@@ -4688,7 +4688,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, remove reference from attribute",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify the reference removal updates the internal map.
 				//	description:
 				//		Simple test to verify the reference removal updates the internal map.
@@ -4706,7 +4706,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 						store.setValues(item, "friends", [null]);
 	
 						var onItem2 = function(item10, request){
-							//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+							//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 							//THIS IS FOR TESTING INTERNAL STATE!
 							var refMap = item10[store._reverseRefMap];
 							store._dumpReferenceMap();
@@ -4735,7 +4735,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, delete referenced item non-parent",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify the references to a non-parent item was properly deleted.
 				//	description:
 				//		Simple test to verify the references to a non-parent item was properly deleted.
@@ -4792,7 +4792,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, add reference to attribute",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify the reference additions can happen.
 				//	description:
 				//		Simple test to verify the reference additions can happen.
@@ -4812,7 +4812,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					var item1 = items[0];
 					var item2 = items[1];
 	
-					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 					//THIS IS FOR TESTING INTERNAL STATE!
 					console.log("Map state for Item 1 is: " + dojo.toJson(item1[store._reverseRefMap]));
 					console.log("Map state for Item 2 is: " + dojo.toJson(item2[store._reverseRefMap]));
@@ -4837,7 +4837,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, new item with parent reference",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
 				//	description:
 				//		Simple test to verify that newItems with a parent properly record the parent's reference in the map.
@@ -4853,9 +4853,9 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				var onItem = function(item, request){
 					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"}); 
+						var newItem = store.newItem({id: 17, name: "Item 17"}, {parent: item, attribute: "uncles"});
 						
-						//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+						//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'
 						var refs = newItem[store._reverseRefMap];
@@ -4881,7 +4881,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, new item with reference to existing item",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify that a new item with references to existing items properly record the references in the map.
 				//	description:
 				//		Simple test to verify that a new item with references to existing items properly record the references in the map.
@@ -4896,14 +4896,14 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 				};
 				var onItem = function(item, request){
 					try{
-						//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+						//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!  
+						//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];
@@ -4929,7 +4929,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 		{
 			name: "Write API: reference integrity, disable reference integrity",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test to verify reference integrity can be disabled.
 				//	description:
 				//		Simple test to verify reference integrity can be disabled.
@@ -4944,7 +4944,7 @@ dojox.data.tests.stores.AndOrWriteStore.getTests = function(){
 					t.assertTrue(false);
 				};
 				var onItem = function(item, request){
-					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!  
+					//DO NOT EVER ACCESS THESE VARIABLES LIKE THIS!
 					//THIS IS FOR TESTING INTERNAL STATE!
 					if(item[store._reverseRefMap] === undefined){
 						d.callback(true);
diff --git a/dojox/data/tests/stores/AppStore.js b/dojox/data/tests/stores/AppStore.js
index ca6d763..3270438 100644
--- a/dojox/data/tests/stores/AppStore.js
+++ b/dojox/data/tests/stores/AppStore.js
@@ -9,13 +9,13 @@ dojox.data.tests.stores.AppStore.getStore = function(preventCache){
 	return new dojox.data.AppStore({url: dojo.moduleUrl('dojox.atom.tests.widget', 'samplefeedEdit.xml').toString(), urlPreventCache: preventCache});
 };
 
-doh.register("dojox.data.tests.stores.AppStore", 
+doh.register("dojox.data.tests.stores.AppStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary: 
-			//		Simple test of fetching all items 
+			//	summary:
+			//		Simple test of fetching all items
 			//	description:
-			//		Simple test of fetching all items 
+			//		Simple test of fetching all items
 			var store = dojox.data.tests.stores.AppStore.getStore();
 
 			var d = new doh.Deferred();
@@ -30,10 +30,10 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_preventCache(t){
-			//	summary: 
-			//		Simple test of fetching all items 
+			//	summary:
+			//		Simple test of fetching all items
 			//	description:
-			//		Simple test of fetching all items 
+			//		Simple test of fetching all items
 			var store = dojox.data.tests.stores.AppStore.getStore(true);
 
 			var d = new doh.Deferred();
@@ -48,7 +48,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one item
 			//	description:
 			//		Simple test of fetching one item
@@ -66,7 +66,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of paging
 			//	description:
 			//		Simple test of paging
@@ -127,12 +127,12 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one item with ? pattern match
 			//	description:
 			//		Simple test of fetching one item with ? pattern match
 			var store = dojox.data.tests.stores.AppStore.getStore();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -144,7 +144,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one item with * pattern match
 			//	description:
 			//		Simple test of fetching one item with * pattern match
@@ -161,12 +161,12 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one item with * pattern match case insensitive
 			//	description:
 			//		Simple test of fetching one item with * pattern match case insensitive
 			var store = dojox.data.tests.stores.AppStore.getStore();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(8, items.length);
 				d.callback(true);
@@ -179,7 +179,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -201,7 +201,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -224,7 +224,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getValue(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValue API
 			 //	description:
 			 //		Simple test of the getValue API
@@ -245,7 +245,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			 return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValues API
 			 //	description:
 			 //		Simple test of the getValues API
@@ -268,7 +268,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the isItem API
 			 //	description:
 			 //		Simple test of the isItem API
@@ -291,7 +291,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem API across multiple store instances.
 			//	description:
 			//		Simple test of the isItem API across multiple store instances.
@@ -323,7 +323,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute API
 			//	description:
 			//		Simple test of the hasAttribute API
@@ -347,7 +347,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue API
 			//	description:
 			//		Simple test of the containsValue API
@@ -368,7 +368,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order.
 			//	description:
 			//		Simple test of the sorting API in descending order.
@@ -403,7 +403,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order.
 			//	description:
 			//		Simple test of the sorting API in ascending order.
@@ -438,7 +438,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItemLoaded API
 			//	description:
 			//		Simple test of the isItemLoaded API
@@ -458,13 +458,13 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.AppStore.getStore();
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 			var count = 0;
 			for(var i in features){
 				t.assertTrue(( i === "dojo.data.api.Read" || i === "dojo.data.api.Write" || i === "dojo.data.api.Identity"));
@@ -473,7 +473,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			t.assertEqual(3, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -494,7 +494,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_newItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the newItem API
 			//	description:
 			//		Simple test of the newItem API
@@ -502,7 +502,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 
 			store.newItem({title: "New entry", id: "12345", content: "This is test content", author: {name:"Bob"}});
 
-			var d = new doh.Deferred();        
+			var d = new doh.Deferred();
 			function onComplete(items, request){
 				t.assertEqual(1, items.length);
 				var item = items[0];
@@ -517,7 +517,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_newItemInCallback(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the newItem API
 			//	description:
 			//		Simple test of the newItem API
@@ -552,7 +552,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_deleteItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the deleteItem API
 			//	description:
 			//		Simple test of the deleteItem API
@@ -580,7 +580,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the setValue API
 			//	description:
 			//		Simple test of the setValue API
@@ -602,7 +602,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the setValues API
 			//	description:
 			//		Simple test of the setValues API
@@ -628,7 +628,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_unsetAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the unsetAttribute API
 			//	description:
 			//		Simple test of the unsetAttribute API
@@ -651,7 +651,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_isDirty(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isDirty API
 			//	description:
 			//		Simple test of the isDirty API
@@ -674,7 +674,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_revert(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isDirty API
 			//	description:
 			//		Simple test of the isDirty API
@@ -707,7 +707,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			return d; //Object
 		},
 		function testWriteAPI_revert2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the revert API
 			//	description:
 			//		Simple test of the revert API
@@ -746,7 +746,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching the identity of an item.
 			//	description:
 			//		Simple test of fetching the identity of an item.
@@ -767,7 +767,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_getIdentityAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching the identity attributes off an item,
 			//	description:
 			//		Simple test of fetching the identity attributes off an item,
@@ -789,7 +789,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_fetchItemByIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one atom item through its identity
 			//	description:
 			//		Simple test of fetching one atom item through its identity
@@ -809,7 +809,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_fetchItemByIdentity_fails(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one atom item through its identity fails correctly on no id match
 			//	description:
 			//		Simple test of fetching one atom item through its identity fails correctly on no id match
@@ -828,7 +828,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 		},
 
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -851,7 +851,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			t.assertTrue(passed);
 		},
 		function testWriteAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -873,7 +873,7 @@ doh.register("dojox.data.tests.stores.AppStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/CssClassStore.js b/dojox/data/tests/stores/CssClassStore.js
index 8d657b6..d41e2b0 100755
--- a/dojox/data/tests/stores/CssClassStore.js
+++ b/dojox/data/tests/stores/CssClassStore.js
@@ -69,16 +69,16 @@ dojox.data.tests.stores.CssClassStore.error = function(t, d, errData){
 	for (var i in errData) {
 		console.log(errData[i]);
 	}
-	d.errback(errData);	
+	d.errback(errData);
 };
 
-doh.register("dojox.data.tests.stores.CssClassStore", 
+doh.register("dojox.data.tests.stores.CssClassStore",
 	[
 		{
 			name: "testReadAPI_fetch",
-			timeout:	10000, //10 seconds.  
+			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on CssClassStore.
 				//	description:
 				//		Simple test of a basic fetch on CssClassStore.
@@ -100,7 +100,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			}
 		},
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssClassStore.
 			//	description:
 			//		Simple test of a basic fetch on CssClassStore.
@@ -120,7 +120,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinContext(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssClassStore.
 			//	description:
 			//		Simple test of a basic fetch on CssClassStore.
@@ -142,7 +142,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinMultipleSheetContext(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssClassStore.
 			//	description:
 			//		Simple test of a basic fetch on CssClassStore.
@@ -164,7 +164,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_switchContext(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssClassStore.
 			//	description:
 			//		Simple test of a basic fetch on CssClassStore.
@@ -197,7 +197,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -209,14 +209,14 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				d.callback(true);
 			}
 			cssClassStore.fetch({
-				query: {'class': '.linkTestClass'}, 
-				onComplete: onComplete, 
+				query: {'class': '.linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 			});
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_sans(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -228,14 +228,14 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				d.callback(true);
 			}
 			cssClassStore.fetch({
-				query: {'classSans': 'linkTestClass'}, 
-				onComplete: onComplete, 
+				query: {'classSans': 'linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 			});
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -261,14 +261,14 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			}
 			
 			try{
-				cssClassStore.fetch({ 
-					query: {'class': '.embeddedTestClass'}, 
-					onComplete: onCompleteOne, 
+				cssClassStore.fetch({
+					query: {'class': '.embeddedTestClass'},
+					onComplete: onCompleteOne,
 					onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 				});
-				cssClassStore.fetch({ 
-					query: {'class': '.linkTestClass'}, 
-					onComplete: onCompleteTwo, 
+				cssClassStore.fetch({
+					query: {'class': '.linkTestClass'},
+					onComplete: onCompleteTwo,
 					onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 				});
 			}catch(e){
@@ -280,7 +280,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -317,9 +317,9 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				}
 			}
 
-			cssClassStore.fetch({ 
-				query: {'class': '.linkTestClass'}, 
-				onComplete: onComplete, 
+			cssClassStore.fetch({
+				query: {'class': '.linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 			});
 			
@@ -331,7 +331,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore.
@@ -357,14 +357,14 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			cssClassStore.fetch({
 				query: {'class': '*TestClass'},
 				onBegin: onBegin,
-				onItem: onItem, 
+				onItem: onItem,
 				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 			});
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary: 
+			 //	summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			 //	description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
@@ -409,7 +409,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -429,14 +429,14 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				d.callback(true);
 			}
 			cssClassStore.fetch({
-				query: {'classSans': 'linkTestClass'}, 
-				onComplete: onComplete, 
+				query: {'classSans': 'linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 			});
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -450,15 +450,15 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				t.assertEqual("class", labelList[0]);
 				d.callback(true);
 			}
-			cssClassStore.fetch({ 
-				query: {'classSans': 'linkTestClass'}, 
-				onComplete: onComplete, 
+			cssClassStore.fetch({
+				query: {'classSans': 'linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssClassStore.error, t, d)
 			});
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -475,7 +475,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 					t.is('.linkTestClass', cssClassStore.getValue(item,'class'));
 					t.is('linkTestClass', cssClassStore.getValue(item,'classSans'));
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'linkTestClass'},
@@ -485,7 +485,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getValue_2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -502,7 +502,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 					t.is('.importTestClass', cssClassStore.getValue(item,'class'));
 					t.is('importTestClass', cssClassStore.getValue(item,'classSans'));
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'importTestClass'},
@@ -512,7 +512,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValues function of the store.
 			//	description:
 			//		Simple test of the getValues function of the store.
@@ -530,7 +530,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				}else{
 					t.is('.embeddedTestClass', values[0]);
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'embeddedTestClass'},
@@ -540,7 +540,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//	description:
 			//		Simple test of the isItem function of the store
@@ -553,7 +553,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				t.assertTrue(!cssClassStore.isItem({ item: "not an item" }));
 				t.assertTrue(!cssClassStore.isItem("not an item"));
 				t.assertTrue(!cssClassStore.isItem(["not an item"]));
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'embeddedTestClass'},
@@ -563,7 +563,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute function of the store
 			//	description:
 			//		Simple test of the hasAttribute function of the store
@@ -586,7 +586,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'embeddedTestClass'},
@@ -596,7 +596,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue function of the store
 			//	description:
 			//		Simple test of the containsValue function of the store
@@ -625,7 +625,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'embeddedTestClass'},
@@ -635,7 +635,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -651,7 +651,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				for(var i = 0; i < attributes.length; i++){
 					t.assertTrue((attributes[i] === 'class' || attributes[i] === 'classSans'));
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetch({
 				query: {'classSans': 'embeddedTestClass'},
@@ -661,13 +661,13 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 			var cssClassStore = dojox.data.tests.stores.CssClassStore.createStore();
 
-			var features = cssClassStore.getFeatures(); 
+			var features = cssClassStore.getFeatures();
 			var count = 0;
 			for(var i in features){
 				t.assertTrue(i === "dojo.data.api.Read" || i === "dojo.data.api.Identity");
@@ -676,7 +676,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything swith Cla in it
 			//	description:
 			//		Function to test pattern matching of everything with Cla in it
@@ -697,7 +697,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -723,7 +723,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -748,7 +748,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
@@ -775,7 +775,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
@@ -807,7 +807,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -834,7 +834,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -853,7 +853,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -862,7 +862,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetchItemByIdentity({
 				identity: ".bsClass",
@@ -872,7 +872,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -880,7 +880,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetchItemByIdentity({
 				identity: 'linkTestClass', // missing the '.'!
@@ -890,7 +890,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -898,7 +898,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssClassStore.fetchItemByIdentity({
 				identity: '9999999',
@@ -908,7 +908,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -938,7 +938,7 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getIdentityAttributes
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -949,8 +949,8 @@ doh.register("dojox.data.tests.stores.CssClassStore",
 				var attrs = cssClassStore.getIdentityAttributes(item);
 				t.assertTrue(dojo.isArray(attrs));
 				t.is(1, attrs.length);
-				t.assertEqual(attrs[0], 'class'); 
-				d.callback(true);	
+				t.assertEqual(attrs[0], 'class');
+				d.callback(true);
 			}
 			cssClassStore.fetchItemByIdentity({
 				identity: ".linkTestClass",
diff --git a/dojox/data/tests/stores/CssRuleStore.js b/dojox/data/tests/stores/CssRuleStore.js
index 86c333e..899f7f4 100755
--- a/dojox/data/tests/stores/CssRuleStore.js
+++ b/dojox/data/tests/stores/CssRuleStore.js
@@ -68,16 +68,16 @@ dojox.data.tests.stores.CssRuleStore.error = function(t, d, errData){
 	for (var i in errData) {
 		console.log(errData[i]);
 	}
-	d.errback(errData);	
+	d.errback(errData);
 };
 
-doh.register("dojox.data.tests.stores.CssRuleStore", 
+doh.register("dojox.data.tests.stores.CssRuleStore",
 	[
 		{
 			name: "testReadAPI_fetch",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on CssRuleStorem longer timeout because initial load can sometimes take a bit..
 				//	description:
 				//		Simple test of a basic fetch on CssRuleStorem longer timeout because initial load can sometimes take a bit.
@@ -99,7 +99,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			}
 		},
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssRuleStore.
 			//	description:
 			//		Simple test of a basic fetch on CssClassStore.
@@ -119,7 +119,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinContext(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssRuleStore.
 			//	description:
 			//		Simple test of a basic fetch on CssRuleStore.
@@ -141,7 +141,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withinMultipleSheetContext(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssRuleStore.
 			//	description:
 			//		Simple test of a basic fetch on CssRuleStore.
@@ -163,7 +163,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_switchContext(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CssRuleStore.
 			//	description:
 			//		Simple test of a basic fetch on CssRuleStore.
@@ -196,7 +196,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -208,14 +208,14 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				d.callback(true);
 			}
 			cssRuleStore.fetch({
-				query: {'selector': '.linkTestClass'}, 
-				onComplete: onComplete, 
+				query: {'selector': '.linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 			});
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_longer(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -227,14 +227,14 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				d.callback(true);
 			}
 			cssRuleStore.fetch({
-				query: {'selector': '.linkTestClass .test'}, 
-				onComplete: onComplete, 
+				query: {'selector': '.linkTestClass .test'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 			});
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -260,14 +260,14 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			}
 			
 			try{
-				cssRuleStore.fetch({ 
-					query: {'selector': '.embeddedTestClass'}, 
-					onComplete: onCompleteOne, 
+				cssRuleStore.fetch({
+					query: {'selector': '.embeddedTestClass'},
+					onComplete: onCompleteOne,
 					onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 				});
-				cssRuleStore.fetch({ 
-					query: {'selector': '.linkTestClass'}, 
-					onComplete: onCompleteTwo, 
+				cssRuleStore.fetch({
+					query: {'selector': '.linkTestClass'},
+					onComplete: onCompleteTwo,
 					onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 				});
 			}catch(e){
@@ -279,7 +279,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -316,9 +316,9 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				}
 			}
 
-			cssRuleStore.fetch({ 
-				query: {'selector': '.embeddedTestClass'}, 
-				onComplete: onComplete, 
+			cssRuleStore.fetch({
+				query: {'selector': '.embeddedTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 			});
 			
@@ -330,7 +330,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore.
@@ -356,14 +356,14 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			cssRuleStore.fetch({
 				query: {'selector': '*TestClass'},
 				onBegin: onBegin,
-				onItem: onItem, 
+				onItem: onItem,
 				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 			});
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary: 
+			 //	summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			 //	description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
@@ -409,7 +409,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -429,14 +429,14 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				d.callback(true);
 			}
 			cssRuleStore.fetch({
-				query: {'selector': '.linkTestClass'}, 
-				onComplete: onComplete, 
+				query: {'selector': '.linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 			});
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -450,15 +450,15 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				t.assertEqual('selector', labelList[0]);
 				d.callback(true);
 			}
-			cssRuleStore.fetch({ 
-				query: {'selector': '.linkTestClass'}, 
-				onComplete: onComplete, 
+			cssRuleStore.fetch({
+				query: {'selector': '.linkTestClass'},
+				onComplete: onComplete,
 				onError: dojo.partial(dojox.data.tests.stores.CssRuleStore.error, t, d)
 			});
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -474,7 +474,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 					t.is('.linkTestClass', cssRuleStore.getValue(item,'selector'));
 				}
 				t.assertTrue(cssRuleStore.getValue(item, 'parentStyleSheetHref').match('dojox/data/tests/stores/test1.css'));
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.linkTestClass'},
@@ -484,7 +484,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getValue_2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -500,7 +500,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 					t.is('.importTestClass', cssRuleStore.getValue(item,'selector'));
 				}
 				t.assertTrue(cssRuleStore.getValue(item, 'parentStyleSheetHref').match('dojox/data/tests/stores/test2.css'));
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.importTestClass'},
@@ -510,7 +510,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValues function of the store.
 			//	description:
 			//		Simple test of the getValues function of the store.
@@ -528,7 +528,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				}else{
 					t.is('.embeddedTestClass', values[0]);
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.embeddedTestClass'},
@@ -538,7 +538,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//	description:
 			//		Simple test of the isItem function of the store
@@ -551,7 +551,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 				t.assertTrue(!cssRuleStore.isItem({ item: "not an item" }));
 				t.assertTrue(!cssRuleStore.isItem("not an item"));
 				t.assertTrue(!cssRuleStore.isItem(["not an item"]));
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.embeddedTestClass'},
@@ -561,7 +561,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute function of the store
 			//	description:
 			//		Simple test of the hasAttribute function of the store
@@ -584,7 +584,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.embeddedTestClass'},
@@ -594,7 +594,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue function of the store
 			//	description:
 			//		Simple test of the containsValue function of the store
@@ -623,7 +623,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.embeddedTestClass'},
@@ -633,7 +633,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -653,7 +653,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 								||	a === 'cssText' 			|| a === 'styleSheet'
 								||	a === 'parentStyleSheet' 	|| a === 'parentStyleSheetHref'));
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			cssRuleStore.fetch({
 				query: {'selector': '.embeddedTestClass'},
@@ -663,13 +663,13 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d;
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 			var cssRuleStore = dojox.data.tests.stores.CssRuleStore.createStore();
 
-			var features = cssRuleStore.getFeatures(); 
+			var features = cssRuleStore.getFeatures();
 			var count = 0;
 			for(var i in features){
 				t.assertTrue(i === "dojo.data.api.Read");
@@ -678,7 +678,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_fetch_patternMatch(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything swith Cla in it
 			//	description:
 			//		Function to test pattern matching of everything with Cla in it
@@ -699,7 +699,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -725,7 +725,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -750,7 +750,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
@@ -777,7 +777,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
@@ -807,7 +807,7 @@ doh.register("dojox.data.tests.stores.CssRuleStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/CsvStore.js b/dojox/data/tests/stores/CsvStore.js
index 0afc0c5..d9a705d 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 = dojo.moduleUrl("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.
@@ -127,13 +127,13 @@ dojox.data.tests.stores.CsvStore.error = function(t, d, errData){
 	for (var i in errData) {
 		console.log(errData[i]);
 	}
-	d.errback(errData);	
+	d.errback(errData);
 };
 
-doh.register("dojox.data.tests.stores.CsvStore", 
+doh.register("dojox.data.tests.stores.CsvStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore.
@@ -152,7 +152,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_empty(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore that's empty.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore that's empty.
@@ -171,7 +171,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_semicolon(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
@@ -191,7 +191,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_pipe(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |
@@ -210,7 +210,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_pipe_indata(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore with separator defined as |
@@ -229,7 +229,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_withnewlinedCsv(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore loading a CSV file with quoted newlines.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore loading a CSV file with quoted newlines.
@@ -248,7 +248,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_withEmptyStringField(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore.
@@ -267,7 +267,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -280,14 +280,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.is(1, items.length);
 				d.callback(true);
 			}
-			csvStore.fetch({ 	query: {Title: "*Sequel*"}, 
-								onComplete: onComplete, 
+			csvStore.fetch({ 	query: {Title: "*Sequel*"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_preventcache(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -301,14 +301,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.is(1, items.length);
 				d.callback(true);
 			}
-			csvStore.fetch({ 	query: {Title: "*Sequel*"}, 
-								onComplete: onComplete, 
+			csvStore.fetch({ 	query: {Title: "*Sequel*"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -338,12 +338,12 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			
 			try
 			{
-				csvStore.fetch({ 	query: {Title: "*Sequel*"}, 
-									onComplete: onCompleteOne, 
+				csvStore.fetch({ 	query: {Title: "*Sequel*"},
+									onComplete: onCompleteOne,
 									onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 								});
-				csvStore.fetch({ 	query: {Title: "2001:*"}, 
-									onComplete: onCompleteTwo, 
+				csvStore.fetch({ 	query: {Title: "2001:*"},
+									onComplete: onCompleteTwo,
 									onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 								});
 			}
@@ -357,7 +357,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore of a single item.
@@ -386,8 +386,8 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				}
 			}
 
-			csvStore.fetch({ 	query: {Title: "*Sequel*"}, 
-								onComplete: onComplete, 
+			csvStore.fetch({ 	query: {Title: "*Sequel*"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 							});
 			
@@ -395,7 +395,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on CsvStore.
 			//	description:
 			//		Simple test of a basic fetch on CsvStore.
@@ -421,14 +421,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 
 			//Get everything...
 			csvStore.fetch({	onBegin: onBegin,
-								onItem: onItem, 
+								onItem: onItem,
 								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary: 
+			 //	summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			 //	description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
@@ -496,7 +496,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -513,14 +513,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertEqual("The Sequel to \"Dances With Wolves.\"", label);
 				d.callback(true);
 			}
-			csvStore.fetch({ 	query: {Title: "*Sequel*"}, 
-								onComplete: onComplete, 
+			csvStore.fetch({ 	query: {Title: "*Sequel*"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 							});
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -537,14 +537,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertEqual("Title", labelList[0]);
 				d.callback(true);
 			}
-			csvStore.fetch({ 	query: {Title: "*Sequel*"}, 
-								onComplete: onComplete, 
+			csvStore.fetch({ 	query: {Title: "*Sequel*"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)
 							});
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -557,13 +557,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(item !== null);
 				t.is('Dymtryk "the King", Edward', csvStore.getValue(item,"Producer"));
 				t.is('Caine Mutiny, The', csvStore.getValue(item,"Title"));
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "6", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
-		},	
+		},
 		function testReadAPI_getValue_2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -576,13 +576,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(item !== null);
 				t.is("City of God", csvStore.getValue(item,"Title"));
 				t.is("2002", csvStore.getValue(item,"Year"));
-				d.callback(true);	
+				d.callback(true);
 			}
             csvStore.fetchItemByIdentity({identity: "0", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
-		},	
+		},
 		function testReadAPI_getValue_3(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -595,13 +595,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(item !== null);
 				t.is("1979", csvStore.getValue(item,"Year"));
 				t.is("Alien", csvStore.getValue(item,"Title"));
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "4", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
-		},	
+		},
 		function testReadAPI_getValue_4(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -614,14 +614,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(item !== null);
 				t.is("2001: A Space Odyssey", csvStore.getValue(item,"Title"));
 				t.is("Stanley Kubrick", csvStore.getValue(item,"Producer"));
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "2", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
-		},	
+		},
 
 		function testReadAPI_getValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValues function of the store.
 			//	description:
 			//		Simple test of the getValues function of the store.
@@ -636,13 +636,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(dojo.isArray(names));
 				t.is(1, names.length);
 				t.is("Rain", names[0]);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -653,14 +653,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_withDefinedIdentifier(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -672,14 +672,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "City of God", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_withDefinedIdentifier_bad1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -691,14 +691,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "No Such Title", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -709,13 +709,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "7", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -725,13 +725,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "-1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -741,13 +741,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "999999", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -775,7 +775,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_getIdentity_withDefinedIdentifier(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -804,7 +804,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_getIdentity_withBadDefinedIdentifier(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -827,7 +827,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getIdentityAttributes
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -838,14 +838,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(csvStore.isItem(item));
-				t.assertEqual(null, csvStore.getIdentityAttributes(item)); 
-				d.callback(true);	
+				t.assertEqual(null, csvStore.getIdentityAttributes(item));
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//	description:
 			//		Simple test of the isItem function of the store
@@ -860,13 +860,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(!csvStore.isItem({ item: "not an item" }));
 				t.assertTrue(!csvStore.isItem("not an item"));
 				t.assertTrue(!csvStore.isItem(["not an item"]));
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute function of the store
 			//	description:
 			//		Simple test of the hasAttribute function of the store
@@ -891,13 +891,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue function of the store
 			//	description:
 			//		Simple test of the containsValue function of the store
@@ -923,13 +923,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "4", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -947,14 +947,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				for(var i = 0; i < attributes.length; i++){
 					t.assertTrue((attributes[i] === "Title" || attributes[i] === "Year" || attributes[i] === "Producer"));
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "4", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 		   	return d;
 		},
 
 		function testReadAPI_getAttributes_onlyTwo(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -972,14 +972,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 				t.assertTrue(attributes.length === 2);
 				t.assertTrue(attributes[0] === "Title");
 				t.assertTrue(attributes[1] === "Producer");
-				d.callback(true);	
+				d.callback(true);
 			}
 			csvStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 		   	return d;
 		},
 
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
@@ -987,7 +987,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
 			var csvStore = new dojox.data.CsvStore(args);
 
-			var features = csvStore.getFeatures(); 
+			var features = csvStore.getFeatures();
 			var count = 0;
 			for(var i in features){
 				t.assertTrue((i === "dojo.data.api.Read" || i === "dojo.data.api.Identity"));
@@ -996,7 +996,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything starting with lowercase e
 			//	description:
 			//		Function to test pattern matching of everything starting with lowercase e
@@ -1016,7 +1016,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch1(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything with $ in it.
 			//	description:
 			//		Function to test pattern matching of everything with $ in it.
@@ -1036,7 +1036,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch2(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match
 			//	description:
 			//		Function to test exact pattern match
@@ -1055,7 +1055,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -1074,7 +1074,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -1092,7 +1092,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically.
 			//	description:
 			//		Function to test sorting numerically.
@@ -1110,13 +1110,13 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			}
 
 			var sortAttributes = [{attribute: "uniqueId"}];
-			csvStore.fetch({onComplete: completed, 
+			csvStore.fetch({onComplete: completed,
 							onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d),
 							sort: sortAttributes});
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortNumericDescending(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically.
 			//	description:
 			//		Function to test sorting numerically.
@@ -1138,7 +1138,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortNumericWithCount(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			//	description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
@@ -1156,14 +1156,14 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			}
 			
 			var sortAttributes = [{attribute: "uniqueId", descending: true}];
-			csvStore.fetch({sort: sortAttributes, 
+			csvStore.fetch({sort: sortAttributes,
 							count: 5,
 							onComplete: completed,
 							onError: dojo.partial(dojox.data.tests.stores.CsvStore.error, t, d)});
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
@@ -1195,7 +1195,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
@@ -1227,7 +1227,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultiple(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting on multiple attributes.
 			//	description:
 			//		Function to test sorting on multiple attributes.
@@ -1260,7 +1260,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultipleSpecialComparator(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 			//	description:
 			//		Function to test sorting on multiple attributes with a custom comparator.
@@ -1269,7 +1269,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			var csvStore = new dojox.data.CsvStore(args);
 			
 			csvStore.comparatorMap = {};
-			csvStore.comparatorMap["Producer"] = function(a,b){ 
+			csvStore.comparatorMap["Producer"] = function(a,b){
 				var ret = 0;
 				// We want to sort authors alphabetical by their last name
 				function lastName(name){
@@ -1312,12 +1312,12 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		{
 			name: "testReadAPI_fetch_abort",
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch abort on CsvStore.
 				//	description:
 				//		Simple test of a basic fetch abort on CsvStore.
 				//Can only async abort in a browser, so disable this test from rhino
-				if(dojo.isBrowser){                                            
+				if(dojo.isBrowser){
 					var args = dojox.data.tests.stores.CsvStore.getDatasource("stores/movies.csv");
 					var store = new dojox.data.CsvStore(args);
 				
@@ -1352,7 +1352,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 		},
 
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -1380,7 +1380,7 @@ doh.register("dojox.data.tests.stores.CsvStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/FileStore.js b/dojox/data/tests/stores/FileStore.js
index 79dc59a..bf4f972 100755
--- a/dojox/data/tests/stores/FileStore.js
+++ b/dojox/data/tests/stores/FileStore.js
@@ -9,7 +9,7 @@ dojox.data.tests.stores.FileStore.getGeoStore = function(){
 };
 
 
-doh.register("dojox.data.tests.stores.FileStore", 
+doh.register("dojox.data.tests.stores.FileStore",
 	[
 /***************************************
 	 dojo.data.api.Read API
@@ -18,7 +18,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_all",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching all xml items through an XML element called isbn
 				//	description:
 				//		Simple test of fetching all xml items through an XML element called isbn
@@ -40,7 +40,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_one",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				//	description:
 				//		Simple test of fetching one xml items through an XML element called isbn
@@ -62,7 +62,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_paging",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching a series of pages
 				//	description:
 				//		Simple test of fetching a series of pages
@@ -135,12 +135,12 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern0",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching a few files based on wildcarded name
 				//	description:
 				//		Simple test of fetching a few files based on wildcarded name
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
-				var d = new doh.Deferred();                                                             
+				var d = new doh.Deferred();
 				function onComplete(items, request) {
 					t.assertEqual(3, items.length);
 					d.callback(true);
@@ -156,7 +156,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern1",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching a one files based on wildcarded name
 				//	description:
 				//		Simple test of fetching a one file based on wildcarded name
@@ -177,12 +177,12 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern_caseInsensitive",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one file item case insensitively
 				//	description:
 				//		Simple test of fetching one file item case insensitively
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
-				var d = new doh.Deferred();                                                             
+				var d = new doh.Deferred();
 				function onComplete(items, request) {
 					t.assertEqual(1, items.length);
 					d.callback(true);
@@ -198,12 +198,12 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_fetch_pattern_caseSensitive",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one file item case sensitively
 				//	description:
 				//		Simple test of fetching one file item case sensitively
 				var store = dojox.data.tests.stores.FileStore.getGeoStore();
-				var d = new doh.Deferred();                                                             
+				var d = new doh.Deferred();
 				function onComplete(items, request) {
 					t.assertEqual(1, items.length);
 					d.callback(true);
@@ -219,7 +219,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getLabel",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store
 				//	description:
 				//		Simple test of the getLabel function against a store
@@ -245,7 +245,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getLabelAttributes",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -271,7 +271,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getValue",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue API
 				//	description:
 				//		Simple test of the getValue API
@@ -296,7 +296,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getValues",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValues API
 				//	description:
 				//		Simple test of the getValues API
@@ -323,7 +323,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_isItem",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem API
 				//	description:
 				//		Simple test of the isItem API
@@ -350,7 +350,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_isItem_multistore",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem API across multiple store instances.
 				//	description:
 				//		Simple test of the isItem API across multiple store instances.
@@ -386,7 +386,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_hasAttribute",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute API
 				//	description:
 				//		Simple test of the hasAttribute API
@@ -411,7 +411,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_containsValue",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue API
 				//	description:
 				//		Simple test of the containsValue API
@@ -436,7 +436,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_sortDescending",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -467,7 +467,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_sortAscending",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in ascending order.
 				//	description:
 				//		Simple test of the sorting API in ascending order.
@@ -476,7 +476,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 				//Comparison is done as a string type (toString comparison), so the order won't be numeric
 				//So have to compare in 'alphabetic' order.
 
-				var order = ["root.json","United States of America","Sudan","Spain","Russia","Mongolia","Mexico","Kenya","Italy","India","Germany","France","Egypt","Commonwealth of Australia","China","Canada","Brazil","Argentina"].reverse();			
+				var order = ["root.json","United States of America","Sudan","Spain","Russia","Mongolia","Mexico","Kenya","Italy","India","Germany","France","Egypt","Commonwealth of Australia","China","Canada","Brazil","Argentina"].reverse();
 
 				var d = new doh.Deferred();
 				function onComplete(items, request) {
@@ -499,7 +499,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_isItemLoaded",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItemLoaded API
 				//	description:
 				//		Simple test of the isItemLoaded API
@@ -520,13 +520,13 @@ doh.register("dojox.data.tests.stores.FileStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.FileStore.getGeoStore();
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 			var count = 0;
 			var i;
 			for(i in features){
@@ -539,7 +539,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testReadAPI_getAttributes",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes API
 				//	description:
 				//		Simple test of the getAttributes API
@@ -564,7 +564,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			}
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -596,7 +596,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testIdentityAPI_getIdentity",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes API
 				//	description:
 				//		Simple test of the getAttributes API
@@ -620,7 +620,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testIdentityAPI_getIdentityAttributes",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes API
 				//	description:
 				//		Simple test of the getAttributes API
@@ -647,7 +647,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			name: "testIdentityAPI_fetchItemByIdentity",
 			timeout:	10000, //10 seconds.  Lots of server calls, expect network delay
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the fetchItemByIdentity API
 				//	description:
 				//		Simple test of the fetchItemByIdentity API
@@ -668,7 +668,7 @@ doh.register("dojox.data.tests.stores.FileStore",
 			}
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/FlickrRestStore.js b/dojox/data/tests/stores/FlickrRestStore.js
index 6cbb60b..ef9adac 100644
--- a/dojox/data/tests/stores/FlickrRestStore.js
+++ b/dojox/data/tests/stores/FlickrRestStore.js
@@ -6,16 +6,16 @@ dojo.require("dojo.data.api.Read");
 dojox.data.tests.stores.FlickrRestStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 
-doh.register("dojox.data.tests.stores.FlickrRestStore", 
+doh.register("dojox.data.tests.stores.FlickrRestStore",
 	[
 		{
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on FlickrRestStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on FlickrRestStore of a single item.
@@ -27,13 +27,13 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 					t.is(1, items.length);
 					d.callback(true);
 				}
-				flickrStore.fetch({ 	
+				flickrStore.fetch({
 					query: {
 						userid: "44153025 at N00",
 						apikey: "8c6803164dbc395fb7131c9d54843627"
 					},
 					count: 1,
-					onComplete: onComplete, 
+					onComplete: onComplete,
 					onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, doh, d)
 				});
 				return d; //Object
@@ -43,7 +43,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on FlickrRestStore.
 				//	description:
 				//		Simple test of a basic fetch on FlickrRestStore.
@@ -63,7 +63,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 					d.callback(true);
 				}
 				//Get everything...
-				flickrStore.fetch({	
+				flickrStore.fetch({
 					query: {
 						userid: "44153025 at N00",
 						apikey: "8c6803164dbc395fb7131c9d54843627"
@@ -81,7 +81,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, //30 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				//	description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -146,8 +146,8 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 						userid: "44153025 at N00",
 						apikey: "8c6803164dbc395fb7131c9d54843627"
 					},
-					count: 7, 
-					onComplete: completed, 
+					count: 7,
+					onComplete: completed,
 					onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 				});
 				return d; //Object
@@ -157,7 +157,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -171,13 +171,13 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 					t.assertTrue(label !== null);
 					d.callback(true);
 				}
-				flickrStore.fetch({ 	
+				flickrStore.fetch({
 					query: {
 						userid: "44153025 at N00",
 						apikey: "8c6803164dbc395fb7131c9d54843627"
-					}, 
+					},
 					count: 1,
-					onComplete: onComplete, 
+					onComplete: onComplete,
 					onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 				});
 				return d;
@@ -187,7 +187,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -202,13 +202,13 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 					t.assertEqual("title", labelList[0]);
 					d.callback(true);
 				}
-				flickrStore.fetch({ 	
+				flickrStore.fetch({
 									query: {
 										userid: "44153025 at N00",
 										apikey: "8c6803164dbc395fb7131c9d54843627"
 									},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 								});
 				return d;
@@ -218,7 +218,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -240,8 +240,8 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 									userid: "44153025 at N00",
 									apikey: "8c6803164dbc395fb7131c9d54843627"
 								},
-								count: 1, 
-								onComplete: completedAll, 
+								count: 1,
+								onComplete: completedAll,
 								onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)});
 				return d; //Object
 			}
@@ -250,7 +250,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -278,10 +278,10 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 								userid: "44153025 at N00",
 								apikey: "8c6803164dbc395fb7131c9d54843627"
 							},
-							count: 1, 
-							onComplete: completedAll, 
-							onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, 
-							t, 
+							count: 1,
+							onComplete: completedAll,
+							onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error,
+							t,
 							d)});
 				return d; //Object
 			}
@@ -290,7 +290,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//	description:
 				//		Simple test of the isItem function of the store
@@ -310,9 +310,9 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 						query: {
 							userid: "44153025 at N00",
 							apikey: "8c6803164dbc395fb7131c9d54843627"
-						},						
-						count: 5, 
-						onComplete: completedAll, 
+						},
+						count: 5,
+						onComplete: completedAll,
 						onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 					});
 				return d; //Object
@@ -322,7 +322,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute function of the store
 				//	description:
 				//		Simple test of the hasAttribute function of the store
@@ -350,13 +350,13 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 				}
 
 				//Get one item...
-				flickrStore.fetch({ 	
+				flickrStore.fetch({
 					query: {
 						userid: "44153025 at N00",
 						apikey: "8c6803164dbc395fb7131c9d54843627"
 					},
 					count: 1,
-						onComplete: onComplete, 
+						onComplete: onComplete,
 						onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 				});
 				return d; //Object
@@ -366,7 +366,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue function of the store
 				//	description:
 				//		Simple test of the containsValue function of the store
@@ -380,13 +380,13 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 				}
 
 				//Get one item...
-				flickrStore.fetch({ 	
+				flickrStore.fetch({
 									query: {
 										userid: "44153025 at N00",
 										apikey: "8c6803164dbc395fb7131c9d54843627"
 									},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 								});
 				return d; //Object
@@ -396,7 +396,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes function of the store
 				//	description:
 				//		Simple test of the getAttributes function of the store
@@ -414,27 +414,27 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 				}
 
 				//Get everything...
-				flickrStore.fetch({ 
+				flickrStore.fetch({
 						query: {
 							userid: "44153025 at N00",
 							apikey: "8c6803164dbc395fb7131c9d54843627"
-						},						
-						count: 1, 
-						onComplete: onComplete, 
+						},
+						count: 1,
+						onComplete: onComplete,
 						onError: dojo.partial(dojox.data.tests.stores.FlickrRestStore.error, t, d)
 					});
 				return d; //Object
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var flickrStore = new dojox.data.FlickrRestStore();
 
-			var features = flickrStore.getFeatures(); 
+			var features = flickrStore.getFeatures();
 			var count = 0;
 			for(i in features){
 				t.assertTrue((i === "dojo.data.api.Read"));
@@ -443,7 +443,7 @@ doh.register("dojox.data.tests.stores.FlickrRestStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/FlickrStore.js b/dojox/data/tests/stores/FlickrStore.js
index e81368f..c4e9d48 100644
--- a/dojox/data/tests/stores/FlickrStore.js
+++ b/dojox/data/tests/stores/FlickrStore.js
@@ -6,16 +6,16 @@ dojo.require("dojo.data.api.Read");
 dojox.data.tests.stores.FlickrStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 
-doh.register("dojox.data.tests.stores.FlickrStore", 
+doh.register("dojox.data.tests.stores.FlickrStore",
 	[
 		{
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on FlickrStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on FlickrStore of a single item.
@@ -29,7 +29,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 				}
 				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrStore.error, doh, d)
 								});
 				return d; //Object
@@ -39,7 +39,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on FlickrStore.
 				//	description:
 				//		Simple test of a basic fetch on FlickrStore.
@@ -75,7 +75,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, //30 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				//	description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -143,7 +143,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -157,9 +157,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 					t.assertTrue(label !== null);
 					d.callback(true);
 				}
-				flickrStore.fetch({ 	query: {tags: "animals"}, 
+				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrStore.error, t, d)
 								});
 				return d;
@@ -169,7 +169,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -186,7 +186,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 				}
 				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrStore.error, t, d)
 								});
 				return d;
@@ -196,7 +196,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -221,7 +221,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -246,7 +246,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//	description:
 				//		Simple test of the isItem function of the store
@@ -270,7 +270,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute function of the store
 				//	description:
 				//		Simple test of the hasAttribute function of the store
@@ -299,9 +299,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 				}
 
 				//Get one item...
-				flickrStore.fetch({ 	query: {tags: "animals"}, 
+				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrStore.error, t, d)
 								});
 				return d; //Object
@@ -311,7 +311,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue function of the store
 				//	description:
 				//		Simple test of the containsValue function of the store
@@ -325,9 +325,9 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 				}
 
 				//Get one item...
-				flickrStore.fetch({ 	query: {tags: "animals"}, 
+				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.FlickrStore.error, t, d)
 								});
 				return d; //Object
@@ -337,7 +337,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, //10 seconds.  Flickr can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes function of the store
 				//	description:
 				//		Simple test of the getAttributes function of the store
@@ -360,14 +360,14 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var flickrStore = new dojox.data.FlickrStore();
 
-			var features = flickrStore.getFeatures(); 
+			var features = flickrStore.getFeatures();
 			var count = 0;
 			for(i in features){
 				t.assertTrue((i === "dojo.data.api.Read"));
@@ -376,7 +376,7 @@ doh.register("dojox.data.tests.stores.FlickrStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/GoogleSearchStore.js b/dojox/data/tests/stores/GoogleSearchStore.js
index 8d1597f..5a3b231 100644
--- a/dojox/data/tests/stores/GoogleSearchStore.js
+++ b/dojox/data/tests/stores/GoogleSearchStore.js
@@ -538,7 +538,7 @@ doh.register("dojox.data.tests.stores.GoogleSearchStore",
 				var preScriptCount = dojo.query("head script").length;
 				
 				function onComplete(items){
-					var postScriptCount = dojo.query("head script").length;					
+					var postScriptCount = dojo.query("head script").length;
 					t.is(preScriptCount, postScriptCount);
 					d.callback(true);
 				}
diff --git a/dojox/data/tests/stores/HtmlStore.js b/dojox/data/tests/stores/HtmlStore.js
index 7684ad8..dacba8f 100644
--- a/dojox/data/tests/stores/HtmlStore.js
+++ b/dojox/data/tests/stores/HtmlStore.js
@@ -8,6 +8,10 @@ dojox.data.tests.stores.HtmlStore.getBooks3Store = function(){
 	return new dojox.data.HtmlStore({url: dojo.moduleUrl("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});
+};
+
 dojox.data.tests.stores.HtmlStore.getBooks2Store = function(){
 	return new dojox.data.HtmlStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books2.html").toString(), dataId: "books2"});
 };
@@ -24,13 +28,13 @@ 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});
 };
 
-doh.register("dojox.data.tests.stores.HtmlStore", 
+doh.register("dojox.data.tests.stores.HtmlStore",
 	[
 /***************************************
      dojo.data.api.Read API
 ***************************************/
 		function testReadAPI_fetch_all_table(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching all xml items through an XML element called isbn
@@ -48,7 +52,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_table_Whitespace(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all table row items through an header called isbn
 			//	description:
 			//		Simple test of fetching all table row items through an header called isbn
@@ -66,7 +70,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_list(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching all xml items through an XML element called isbn
@@ -84,7 +88,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_table(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn
@@ -102,7 +106,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_table_Whitespace(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one item through an element called isbn
 			//	description:
 			//		Simple test of fetching one item through an element called isbn
@@ -119,7 +123,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one_list(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn
@@ -136,8 +140,26 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			store.fetch({query:{name:"A9B57C - Title of 1 - Author of 1"}, onComplete: onComplete, onError: onError});
 			return d; //Object
 		},
+		function testReadAPI_fetch_one_list_oncreate(t){
+			//	summary:
+			//		Simple test of fetching one xml items through an XML element called isbn
+			//	description:
+			//		Simple test of fetching one xml items through an XML element called isbn
+			var store = dojox.data.tests.stores.HtmlStore.getBooks3StoreOnCreate();
+
+			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:{name:"A9B57C - Title of 1 - Author of 1"}, onComplete: onComplete, onError: onError});
+			return d; //Object
+		},
 		function testReadAPI_fetch_one_list_Whitespace(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one item through an attribute called name
 			//	description:
 			//		Simple test of fetching one item through an attribute called name
@@ -155,7 +177,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn
@@ -223,12 +245,12 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -240,7 +262,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
@@ -257,7 +279,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
@@ -274,12 +296,12 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -291,12 +313,12 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -308,7 +330,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getLabel_table(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -330,7 +352,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d;
 		},
 		function testReadAPI_getLabel_list(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -352,7 +374,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -374,7 +396,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 		},
 
 		function testReadAPI_getValue(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValue API
 			 //	description:
 			 //		Simple test of the getValue API
@@ -395,7 +417,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValues API
 			 //	description:
 			 //		Simple test of the getValues API
@@ -418,7 +440,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the isItem API
 			 //	description:
 			 //		Simple test of the isItem API
@@ -441,7 +463,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem API across multiple store instances.
 			//	description:
 			//		Simple test of the isItem API across multiple store instances.
@@ -471,7 +493,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute API
 			//	description:
 			//		Simple test of the hasAttribute API
@@ -492,7 +514,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue API
 			//	description:
 			//		Simple test of the containsValue API
@@ -513,7 +535,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order.
 			//	description:
 			//		Simple test of the sorting API in descending order.
@@ -541,7 +563,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order.
 			//	description:
 			//		Simple test of the sorting API in ascending order.
@@ -569,7 +591,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescendingNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
 			//	description:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
@@ -606,7 +628,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscendingNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
 			//	description:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
@@ -643,7 +665,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItemLoaded API
 			//	description:
 			//		Simple test of the isItemLoaded API
@@ -663,13 +685,13 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.HtmlStore.getBooks2Store();
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 			var count = 0;
 			for(i in features){
 				t.assertTrue((i === "dojo.data.api.Read" || i === "dojo.data.api.Identity"));
@@ -678,7 +700,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			t.assertEqual(2, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -702,7 +724,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -729,7 +751,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
      dojo.data.api.Identity API
 ***************************************/
 		function testIdentityAPI_getIdentity_table(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -749,7 +771,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentity_list(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -769,7 +791,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -791,7 +813,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_fetchItemByIdentity_table(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity API
 			//	description:
 			//		Simple test of the fetchItemByIdentity API
@@ -811,7 +833,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_fetchItemByIdentity_list(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity API
 			//	description:
 			//		Simple test of the fetchItemByIdentity API
@@ -831,7 +853,7 @@ doh.register("dojox.data.tests.stores.HtmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/HtmlTableStore.js b/dojox/data/tests/stores/HtmlTableStore.js
index b7daf1c..e8234a3 100644
--- a/dojox/data/tests/stores/HtmlTableStore.js
+++ b/dojox/data/tests/stores/HtmlTableStore.js
@@ -12,13 +12,13 @@ dojox.data.tests.stores.HtmlTableStore.getBooksStore = function(){
 	return new dojox.data.HtmlTableStore({url: dojo.moduleUrl("dojox.data.tests", "stores/books.html").toString(), tableId: "books"});
 };
 
-doh.register("dojox.data.tests.stores.HtmlTableStore", 
+doh.register("dojox.data.tests.stores.HtmlTableStore",
 	[
 /***************************************
      dojo.data.api.Read API
 ***************************************/
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching all xml items through an XML element called isbn
@@ -36,7 +36,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn
@@ -54,7 +54,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn
@@ -122,12 +122,12 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -139,7 +139,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
@@ -156,7 +156,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
@@ -173,12 +173,12 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -190,12 +190,12 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -207,7 +207,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -229,7 +229,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -251,7 +251,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 		},
 
 		function testReadAPI_getValue(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValue API
 			 //	description:
 			 //		Simple test of the getValue API
@@ -272,7 +272,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			 return d; //Object
 		},
 		function testReadAPI_getValues(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValues API
 			 //	description:
 			 //		Simple test of the getValues API
@@ -295,7 +295,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the isItem API
 			 //	description:
 			 //		Simple test of the isItem API
@@ -318,7 +318,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem API across multiple store instances.
 			//	description:
 			//		Simple test of the isItem API across multiple store instances.
@@ -348,7 +348,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute API
 			//	description:
 			//		Simple test of the hasAttribute API
@@ -369,7 +369,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue API
 			//	description:
 			//		Simple test of the containsValue API
@@ -390,7 +390,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order.
 			//	description:
 			//		Simple test of the sorting API in descending order.
@@ -418,7 +418,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order.
 			//	description:
 			//		Simple test of the sorting API in ascending order.
@@ -446,7 +446,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescendingNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
 			//	description:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
@@ -483,7 +483,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscendingNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
 			//	description:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
@@ -520,7 +520,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItemLoaded API
 			//	description:
 			//		Simple test of the isItemLoaded API
@@ -540,13 +540,13 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.HtmlTableStore.getBooks2Store();
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 			var count = 0;
 			for(i in features){
 				t.assertTrue((i === "dojo.data.api.Read" || i === "dojo.data.api.Identity"));
@@ -555,7 +555,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			t.assertEqual(2, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -579,7 +579,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -606,7 +606,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
      dojo.data.api.Identity API
 ***************************************/
 		function testIdentityAPI_getIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -626,7 +626,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -648,7 +648,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity API
 			//	description:
 			//		Simple test of the fetchItemByIdentity API
@@ -668,7 +668,7 @@ doh.register("dojox.data.tests.stores.HtmlTableStore",
 			return d; //Object
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/JsonQueryRestStore.js b/dojox/data/tests/stores/JsonQueryRestStore.js
index 11f0f99..a6b0572 100644
--- a/dojox/data/tests/stores/JsonQueryRestStore.js
+++ b/dojox/data/tests/stores/JsonQueryRestStore.js
@@ -5,11 +5,11 @@ dojo.require("dojox.data.JsonQueryRestStore");
 dojox.data.tests.stores.JsonQueryRestStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 testService = function(query){
 	lastQuery = query;
-	var deferred = new dojo.Deferred(); 
+	var deferred = new dojo.Deferred();
 	deferred.callback([
 		{id:1, name:"Ball", price: 5},
 		{id:2, name:"Car", price: 15},
@@ -22,16 +22,16 @@ testService = function(query){
 testService.servicePath = "/testing";
 jsonStore = new dojox.data.JsonQueryRestStore({service:testService});
 
-doh.register("dojox.data.tests.stores.JsonQueryRestStore", 
+doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 	[
 		{
 			name: "Fetch using a query object",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:{name:"Car"}, 
+				jsonStore.fetch({query:{name:"Car"},
 					onComplete: function(items, request){
 						t.is(lastQuery,"[?(@.name='Car')]");
 						d.callback(true);
@@ -45,11 +45,11 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch+Sorting using a query object",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				jsonStore.fetch({query:{name:"Car"},
-					sort:[{attribute:"price"}], 
+					sort:[{attribute:"price"}],
 					onComplete: function(items, request){
 						t.is(lastQuery,"[?(@.name='Car')][/@['price']]");
 						d.callback(true);
@@ -63,10 +63,10 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch all items (and cache for the next tests)",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"", 
+				jsonStore.fetch({query:"",
 					onComplete: function(items, request){
 						testItems = items;
 						console.log(items.length, items);
@@ -83,11 +83,11 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a query object",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
-				jsonStore.fetch({query:{name:"Car"}, 
+				jsonStore.fetch({query:{name:"Car"},
 					onComplete: function(items, request){
 						t.is(1, items.length);
 						t.is(lastQuery, null); // should not be sent to the service
@@ -102,11 +102,11 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a JSONQuery",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
-				jsonStore.fetch({query:"?name='Car'", 
+				jsonStore.fetch({query:"?name='Car'",
 					onComplete: function(items, request){
 						t.is(1, items.length);
 						t.is(lastQuery, null); // should not be sent to the service
@@ -121,11 +121,11 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a JSONQuery with operator",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
-				jsonStore.fetch({query:"[?price<20]", 
+				jsonStore.fetch({query:"[?price<20]",
 					onComplete: function(items, request){
 						t.is(2, items.length);
 						t.is(lastQuery, null); // should not be sent to the service
@@ -140,11 +140,11 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Fetch using a JSONQuery with operator and paging",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
-				jsonStore.fetch({query:"?price<20",start:1, count:1, 
+				jsonStore.fetch({query:"?price<20",start:1, count:1,
 					onComplete: function(items, request){
 						t.is(1, items.length);
 						t.is(lastQuery, null); // should not be sent to the service
@@ -160,11 +160,11 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Sorting",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				var d = new doh.Deferred();
 				lastQuery = null;
-				jsonStore.fetch({sort:[{attribute:"name", descending: true}], 
+				jsonStore.fetch({sort:[{attribute:"name", descending: true}],
 					onComplete: function(items, request){
 						t.is("Truck", items[0].name);
 						t.is("Ball", items[3].name);
@@ -180,7 +180,7 @@ doh.register("dojox.data.tests.stores.JsonQueryRestStore",
 			name: "Sorting + Paging",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonQueryRestStore of a simple query.
 				jsonStore.jsonQueryPagination = true;
 				var d = new doh.Deferred();
diff --git a/dojox/data/tests/stores/JsonRestStore.js b/dojox/data/tests/stores/JsonRestStore.js
index f6ead37..4af35aa 100644
--- a/dojox/data/tests/stores/JsonRestStore.js
+++ b/dojox/data/tests/stores/JsonRestStore.js
@@ -8,22 +8,22 @@ dojo.require("dojo.data.api.Read");
 dojox.data.tests.stores.JsonRestStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 testServices = new dojox.rpc.Service(dojo.moduleUrl("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});
 
-doh.register("dojox.data.tests.stores.JsonRestStore", 
+doh.register("dojox.data.tests.stores.JsonRestStore",
 	[
 		{
 			name: "Fetch some items",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonRestStore of a simple query.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						t.is(4, items.length);
 						d.callback(true);
@@ -37,10 +37,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "fetch by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonRestStore of a single item.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"obj1", 
+				jsonStore.fetch({query:"obj1",
 					onComplete: function(item, request){
 						t.is("Object 1", item.name);
 						t.t(jsonStore.hasAttribute(item,"name"));
@@ -57,10 +57,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Modify,save, check by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Fetch an item from a query, modify and save it, and check to see if it was modified correctly
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						var now = new Date().getTime();
 						jsonStore.setValue(items[0],"updated",now);
@@ -89,10 +89,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Revert",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"obj1", 
+				jsonStore.fetch({query:"obj1",
 					onComplete: function(item, request){
 						jsonStore.setValue(item,"name","new name");
 						jsonStore.setValue(item,"newProp","new value");
@@ -115,10 +115,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Delete",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
-				jsonStore.fetchItemByIdentity({identity:"obj1", 
+				jsonStore.fetchItemByIdentity({identity:"obj1",
 					onItem: function(item, request){
 						var newItem = jsonStore.newItem({directRef: item, name:"Foo"});
 						jsonStore.setValue(newItem, "arrayRef", [1,{subobject:item},item]);
@@ -138,10 +138,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Lazy loading",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		test lazy loading
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						var item = items[2];
 						t.f(jsonStore.isItemLoaded(item));
@@ -159,10 +159,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Lazy loading 2",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		test lazy loading
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						t.f(jsonStore.isItemLoaded(items[3]));
 						jsonStore.loadItem({item:items[3],onItem:function(item){
@@ -182,10 +182,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Load Lazy Value",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on ServiceStore of a single item.
 				var d = new doh.Deferred();
-				jsonStore.fetchItemByIdentity({identity:"obj1", 
+				jsonStore.fetchItemByIdentity({identity:"obj1",
 					onItem: function(item, request){
 						t.is("Object 1", item.name);
 						t.f(jsonStore.isItemLoaded(item.lazyValue));
@@ -208,7 +208,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 				//		Verify the fetchItemByIdentity method works
 				var d = new doh.Deferred();
 		
-				jsonStore.fetchItemByIdentity({identity:"obj3", 
+				jsonStore.fetchItemByIdentity({identity:"obj3",
 					onItem: function(item, request){
 						t.t(jsonStore.isItemLoaded(item));
 						t.is(jsonStore.getIdentity(item),"obj3");
@@ -222,7 +222,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Json can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		fetching with paging
 
 				var d = new doh.Deferred();
@@ -238,7 +238,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 					d.callback(true);
 				}
 				//Get everything...
-				jsonStore.fetch({	
+				jsonStore.fetch({
 					query: "bigQuery",
 					onBegin: null,
 					count: 20,
@@ -251,7 +251,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 		},
 		function testSchema(t){
 			var d = new doh.Deferred();
-			jsonStore.fetchItemByIdentity({identity:"obj3", 
+			jsonStore.fetchItemByIdentity({identity:"obj3",
 				onItem: function(item, request){
 					var set = false;
 					try{
@@ -273,7 +273,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -306,7 +306,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 );
 performanceTest = function (){
 	dojo.require("dojo.data.ItemFileReadStore");
-	jsonStore.fetch({query:"obj1", 
+	jsonStore.fetch({query:"obj1",
 		onComplete: function(item){
 			var now = new Date().getTime();
 			var result;
@@ -340,6 +340,6 @@ performanceTest = function (){
 			console.log("ifrs.getValue",new Date().getTime()-now,result);
 			
 		}
-	});	
+	});
 
 }
diff --git a/dojox/data/tests/stores/KeyValueStore.js b/dojox/data/tests/stores/KeyValueStore.js
index 76740ed..0365ba0 100644
--- a/dojox/data/tests/stores/KeyValueStore.js
+++ b/dojox/data/tests/stores/KeyValueStore.js
@@ -12,12 +12,12 @@ 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 = dojo.moduleUrl("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.
 		var keyData = "/*[";
-		// Properties of December 1, 2007 
+		// Properties of December 1, 2007
 		keyData += '{ "year": "2007" },';
 		keyData += '{ "nmonth": "12" },';
 		keyData += '{ "month": "December" },';
@@ -50,13 +50,13 @@ dojox.data.tests.stores.KeyValueStore.error = function(t, d, errData){
 	for (i in errData) {
 		console.log(errData[i]);
 	}
-	d.errback(errData);	
+	d.errback(errData);
 }
 
-doh.register("dojox.data.tests.stores.KeyValueStore", 
+doh.register("dojox.data.tests.stores.KeyValueStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on KeyValueStore.
 			//	description:
 			//		Simple test of a basic fetch on KeyValueStore.
@@ -75,7 +75,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_withEmptyStringField(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on KeyValueStore.
 			//	description:
 			//		Simple test of a basic fetch on KeyValueStore.
@@ -94,7 +94,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
@@ -107,14 +107,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.is(1, items.length);
 				d.callback(true);
 			}
-			keyStore.fetch({ 	query: {key: "year"}, 
-								onComplete: onComplete, 
+			keyStore.fetch({ 	query: {key: "year"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_fetch_Multiple(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
@@ -144,12 +144,12 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			
 			try
 			{
-				keyStore.fetch({ 	query: {key: "year"}, 
-									onComplete: onCompleteOne, 
+				keyStore.fetch({ 	query: {key: "year"},
+									onComplete: onCompleteOne,
 									onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 								});
-				keyStore.fetch({ 	query: {key: "month"}, 
-									onComplete: onCompleteTwo, 
+				keyStore.fetch({ 	query: {key: "month"},
+									onComplete: onCompleteTwo,
 									onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 								});
 			}
@@ -163,7 +163,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_MultipleMixed(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on KeyValueStore of a single item.
@@ -193,8 +193,8 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				}
 			}
 
-			keyStore.fetch({ 	query: {key: "day"}, 
-								onComplete: onComplete, 
+			keyStore.fetch({ 	query: {key: "day"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 							});
 			
@@ -202,7 +202,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on KeyValueStore.
 			//	description:
 			//		Simple test of a basic fetch on KeyValueStore.
@@ -228,14 +228,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 
 			//Get everything...
 			keyStore.fetch({	onBegin: onBegin,
-								onItem: onItem, 
+								onItem: onItem,
 								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary: 
+			 //	summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			 //	description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
@@ -302,7 +302,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 		},
 		
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -318,14 +318,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.assertEqual("year", label);
 				d.callback(true);
 			}
-			keyStore.fetch({ 	query: {key: "year"}, 
-								onComplete: onComplete, 
+			keyStore.fetch({ 	query: {key: "year"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 							});
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -341,14 +341,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.assertEqual("key", labelList[0]);
 				d.callback(true);
 			}
-			keyStore.fetch({ 	query: {key: "year"}, 
-								onComplete: onComplete, 
+			keyStore.fetch({ 	query: {key: "year"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)
 							});
 			return d;
 		},
 		function testReadAPI_getValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -362,13 +362,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.is("nday", keyStore.getValue(item,"key"));
 				t.is(1, keyStore.getValue(item,"value"));
 				t.is(1, keyStore.getValue(item,"nday"));
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "nday", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
-		},	
+		},
 		function testReadAPI_getValue_2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -382,13 +382,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.is("day", keyStore.getValue(item,"key"));
 				t.is("Saturday", keyStore.getValue(item,"value"));
 				t.is("Saturday", keyStore.getValue(item,"day"));
-				d.callback(true);	
+				d.callback(true);
 			}
             keyStore.fetchItemByIdentity({identity: "day", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
-		},	
+		},
 		function testReadAPI_getValue_3(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -402,13 +402,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.is("dayOfYear", keyStore.getValue(item,"key"));
 				t.is(335, keyStore.getValue(item,"value"));
 				t.is(335, keyStore.getValue(item,"dayOfYear"));
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "dayOfYear", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
-		},	
+		},
 		function testReadAPI_getValue_4(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -422,13 +422,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.is("weekOfYear", keyStore.getValue(item,"key"));
 				t.is(48, keyStore.getValue(item,"value"));
 				t.is(48, keyStore.getValue(item,"weekOfYear"));
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "weekOfYear", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
 		},
 		function testReadAPI_getValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValues function of the store.
 			//	description:
 			//		Simple test of the getValues function of the store.
@@ -443,13 +443,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.assertTrue(dojo.isArray(names));
 				t.is(1, names.length);
 				t.is(2007, names[0]);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -460,14 +460,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -478,13 +478,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "y3ar", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -494,13 +494,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "-1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -510,13 +510,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "999999", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -542,7 +542,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testIdentityAPI_getIdentityAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getIdentityAttributes
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -553,14 +553,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(keyStore.isItem(item));
-				t.assertEqual("key", keyStore.getIdentityAttributes(item)); 
-				d.callback(true);	
+				t.assertEqual("key", keyStore.getIdentityAttributes(item));
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_isItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//	description:
 			//		Simple test of the isItem function of the store
@@ -575,13 +575,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.assertTrue(!keyStore.isItem({ item: "not an item" }));
 				t.assertTrue(!keyStore.isItem("not an item"));
 				t.assertTrue(!keyStore.isItem(["not an item"]));
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute function of the store
 			//	description:
 			//		Simple test of the hasAttribute function of the store
@@ -607,13 +607,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_containsValue(t){
-			//	summary:  
+			//	summary:
 			//		Simple test of the containsValue function of the store
 			//	description:
 			//		Simple test of the containsValue function of the store
@@ -639,13 +639,13 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 					passed = true;
 				}
 				t.assertTrue(passed);
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 		   	return d;
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -663,14 +663,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				for(var i = 0; i < attributes.length; i++){
 					t.assertTrue((attributes[i] === "year" || attributes[i] === "value" || attributes[i] === "key"));
 				}
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "year", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 		   	return d;
 		},
 
 		function testReadAPI_getAttributes_onlyTwo(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -689,14 +689,14 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 				t.assertTrue(attributes[0] === "key");
 				t.assertTrue(attributes[1] === "value");
 				t.assertTrue(attributes[2] === "nmonth");
-				d.callback(true);	
+				d.callback(true);
 			}
 			keyStore.fetchItemByIdentity({identity: "nmonth", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.KeyValueStore.error, t, d)});
 		   	return d;
 		},
 
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
@@ -704,7 +704,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var args = dojox.data.tests.stores.KeyValueStore.getDatasource("stores/movies.csv");
 			var keyStore = new dojox.data.KeyValueStore(args);
 
-			var features = keyStore.getFeatures(); 
+			var features = keyStore.getFeatures();
 			var count = 0;
 			for(i in features){
 				t.assertTrue((i === "dojo.data.api.Read" || i === "dojo.data.api.Identity"));
@@ -713,7 +713,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything starting with lowercase e
 			//	description:
 			//		Function to test pattern matching of everything starting with lowercase e
@@ -733,7 +733,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch1(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything with $ in it.
 			//	description:
 			//		Function to test pattern matching of everything with $ in it.
@@ -753,7 +753,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch2(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match
 			//	description:
 			//		Function to test exact pattern match
@@ -775,7 +775,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -794,7 +794,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -812,7 +812,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
@@ -834,7 +834,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
@@ -856,7 +856,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultiple(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting on multiple attributes.
 			//	description:
 			//		Function to test sorting on multiple attributes.
@@ -890,7 +890,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortMultipleSpecialComparator(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting on multiple attributes with a custom comparator.
 			//	description:
 			//		Function to test sorting on multiple attributes with a custom comparator.
@@ -899,7 +899,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			var keyStore = new dojox.data.KeyValueStore(args);
 			
 			keyStore.comparatorMap = {};
-			keyStore.comparatorMap["key"] = function(a,b){ 
+			keyStore.comparatorMap["key"] = function(a,b){
 				var ret = 0;
 				// We want to sort keys alphabetical by the last character in the string
 				function lastChar(name){
@@ -939,7 +939,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -967,7 +967,7 @@ doh.register("dojox.data.tests.stores.KeyValueStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/OpenSearchStore.js b/dojox/data/tests/stores/OpenSearchStore.js
index 7282c97..67bb616 100644
--- a/dojox/data/tests/stores/OpenSearchStore.js
+++ b/dojox/data/tests/stores/OpenSearchStore.js
@@ -25,13 +25,13 @@ dojox.data.tests.stores.OpenSearchStore.getHTMLStore = function(){
 	return store;
 };
 
-doh.register("dojox.data.tests.stores.OpenSearchStore", 
+doh.register("dojox.data.tests.stores.OpenSearchStore",
 	[
 		{
 			name: 'testReadAPI_fetch_all_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching all atom entries
 				//	description:
 				//		Simple test of fetching all atom entries
@@ -53,7 +53,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_all_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching all atom entries
 				//	description:
 				//		Simple test of fetching all atom entries
@@ -75,7 +75,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_all_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching all atom entries
 				//	description:
 				//		Simple test of fetching all atom entries
@@ -97,7 +97,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_paging_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				//	description:
 				//		Simple test of fetching one xml items through an XML element called isbn
@@ -162,7 +162,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_paging_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				//	description:
 				//		Simple test of fetching one xml items through an XML element called isbn
@@ -227,7 +227,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_fetch_paging_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				//	description:
 				//		Simple test of fetching one xml items through an XML element called isbn
@@ -292,7 +292,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getLabel',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -317,7 +317,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getLabelAttributes',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -343,7 +343,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValue_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue API
 				//	description:
 				//		Simple test of the getValue API
@@ -372,7 +372,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValue_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue API
 				//	description:
 				//		Simple test of the getValue API
@@ -401,7 +401,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValue_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue API
 				//	description:
 				//		Simple test of the getValue API
@@ -432,7 +432,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValues_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValues API
 				//	description:
 				//		Simple test of the getValues API
@@ -460,7 +460,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValues_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValues API
 				//	description:
 				//		Simple test of the getValues API
@@ -488,7 +488,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getValues_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValues API
 				//	description:
 				//		Simple test of the getValues API
@@ -516,7 +516,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem API
 				//	description:
 				//		Simple test of the isItem API
@@ -543,7 +543,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem API
 				//	description:
 				//		Simple test of the isItem API
@@ -570,7 +570,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem API
 				//	description:
 				//		Simple test of the isItem API
@@ -597,7 +597,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItem_multistore',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem API across multiple store instances.
 				//	description:
 				//		Simple test of the isItem API across multiple store instances.
@@ -631,7 +631,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_hasAttribute_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute API
 				//	description:
 				//		Simple test of the hasAttribute API
@@ -657,7 +657,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_hasAttribute_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute API
 				//	description:
 				//		Simple test of the hasAttribute API
@@ -683,7 +683,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_hasAttribute_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute API
 				//	description:
 				//		Simple test of the hasAttribute API
@@ -709,7 +709,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_containsValue_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue API
 				//	description:
 				//		Simple test of the containsValue API
@@ -734,7 +734,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_containsValue_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue API
 				//	description:
 				//		Simple test of the containsValue API
@@ -759,7 +759,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_containsValue_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue API
 				//	description:
 				//		Simple test of the containsValue API
@@ -787,7 +787,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortDescending_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -841,7 +841,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortDescending_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -895,7 +895,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortDescending_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -948,7 +948,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortAscending_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -1001,7 +1001,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortAscending_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -1054,7 +1054,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_sortAscending_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the sorting API in descending order.
 				//	description:
 				//		Simple test of the sorting API in descending order.
@@ -1107,7 +1107,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItemLoaded_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItemLoaded API
 				//	description:
 				//		Simple test of the isItemLoaded API
@@ -1131,7 +1131,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItemLoaded_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItemLoaded API
 				//	description:
 				//		Simple test of the isItemLoaded API
@@ -1155,7 +1155,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_isItemLoaded_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItemLoaded API
 				//	description:
 				//		Simple test of the isItemLoaded API
@@ -1179,7 +1179,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getFeatures',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getFeatures function of the store
 				//	description:
 				//		Simple test of the getFeatures function of the store
@@ -1197,7 +1197,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getAttributes_atom',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes API
 				//	description:
 				//		Simple test of the getAttributes API
@@ -1224,7 +1224,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getAttributes_rss',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes API
 				//	description:
 				//		Simple test of the getAttributes API
@@ -1251,7 +1251,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_getAttributes_html',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes API
 				//	description:
 				//		Simple test of the getAttributes API
@@ -1278,7 +1278,7 @@ doh.register("dojox.data.tests.stores.OpenSearchStore",
 			name: 'testReadAPI_functionConformance',
 			timeout: 20000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 				//	description:
 				//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/OpmlStore.js b/dojox/data/tests/stores/OpmlStore.js
index 135d70f..8580b0b 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 = dojo.moduleUrl("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.
@@ -146,13 +146,13 @@ dojox.data.tests.stores.OpmlStore.verifyItems = function(opmlStore, items, attri
 dojox.data.tests.stores.OpmlStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 
-doh.register("dojox.data.tests.stores.OpmlStore", 
+doh.register("dojox.data.tests.stores.OpmlStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore.
 			//	description:
 			//		Simple test of a basic fetch on OpmlStore.
@@ -171,7 +171,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
@@ -184,15 +184,15 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.is(1, items.length);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-								onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d; //Object
 		},
 
 		function testReadAPI_fetch_one_Multiple(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
 			//	description:
 			//		Simple test of a basic fetch on OpmlStore of a single item.
@@ -217,13 +217,13 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				}
 			}
 
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-								onComplete: onCompleteOne, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+								onComplete: onCompleteOne,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 
-			opmlStore.fetch({ 	query: {text: "North America"}, 
-								onComplete: onCompleteTwo, 
+			opmlStore.fetch({ 	query: {text: "North America"},
+								onComplete: onCompleteTwo,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 
@@ -231,7 +231,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_one_MultipleMixed(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item mixing two fetch types.
 			//	description:
 			//		Simple test of a basic fetch on Cpmltore of a single item mixing two fetch types.
@@ -257,14 +257,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.assertTrue(item !== null);
 				console.log("Found item: " + opmlStore.getValue(item,"text"));
 				t.is('Egypt', opmlStore.getValue(item,"text")); //Should be the second node parsed, ergo id 1, first node is id 0.
-				t.is(1, opmlStore.getIdentity(item)); 
+				t.is(1, opmlStore.getIdentity(item));
 				if(done[0] && done[1]){
 					d.callback(true);
 				}
 			}
 
-			opmlStore.fetch({ 	query: {text: "Africa"}, 
-								onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Africa"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			
@@ -274,7 +274,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 		},
 
 		function testReadAPI_fetch_one_deep(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
 			//	description:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
@@ -287,16 +287,16 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.is(1, items.length);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Mexico City"}, 
+			opmlStore.fetch({ 	query: {text: "Mexico City"},
 								queryOptions: {deep:true},
-								onComplete: onComplete, 
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d; //Object
 		},
 
 		function testReadAPI_fetch_one_deep_off(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
 			//	description:
 			//		Simple test of a basic fetch on OpmlStore of a single item that's nested down as a child item.
@@ -310,15 +310,15 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.is(0, items.length);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Mexico City"}, 
-								onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Mexico City"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d; //Object
 		},
 
 		function testReadAPI_fetch_all_streaming(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of a basic fetch on OpmlStore.
 			//	description:
 			//		Simple test of a basic fetch on OpmlStore.
@@ -344,14 +344,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 
 			//Get everything...
 			opmlStore.fetch({	onBegin: onBegin,
-								onItem: onItem, 
+								onItem: onItem,
 								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_fetch_paging(t){
-			 //	summary: 
+			 //	summary:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
 			 //	description:
 			 //		Test of multiple fetches on a single result.  Paging, if you will.
@@ -418,7 +418,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 
 		},
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -434,14 +434,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.assertEqual("Asia", label);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-						   		onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+						   		onComplete: onComplete,
 						   		onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 						   	});
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -457,15 +457,15 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.assertEqual("text", labelList[0]);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-							   	onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+							   	onComplete: onComplete,
 							   	onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d;
 		},
 
 		function testReadAPI_getLabel_nondefault(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -482,14 +482,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.assertEqual("Continent/Asia", label);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-						   		onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+						   		onComplete: onComplete,
 						   		onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 						   	});
 			return d;
 		},
 		function testReadAPI_getLabelAttributes_nondefault(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -506,15 +506,15 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 				t.assertEqual("label", labelList[0]);
 				d.callback(true);
 			}
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-							   	onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+							   	onComplete: onComplete,
 							   	onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d;
 		},
 
 		function testReadAPI_getValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue function of the store.
 			//	description:
 			//		Simple test of the getValue function of the store.
@@ -556,9 +556,9 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			//Get everything...
 			opmlStore.fetch({ onComplete: completedAll, onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d; //Object
-		},	
+		},
 		function testReadAPI_getValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValues function of the store.
 			//	description:
 			//		Simple test of the getValues function of the store.
@@ -597,12 +597,12 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 
 			//Get one item...
 			opmlStore.fetch({	query: {text: "North America"},
-								onComplete: completed, 
+								onComplete: completed,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem function of the store
 			//	description:
 			//		Simple test of the isItem function of the store
@@ -629,7 +629,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute function of the store
 			//	description:
 			//		Simple test of the hasAttribute function of the store
@@ -660,14 +660,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			}
 
 			//Get one item...
-			opmlStore.fetch({ 	query: {text: "Asia"}, 
-								onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "Asia"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue function of the store
 			//	description:
 			//		Simple test of the containsValue function of the store
@@ -703,14 +703,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			}
 
 			//Get one item...
-			opmlStore.fetch({ 	query: {text: "North America"}, 
-								onComplete: onComplete, 
+			opmlStore.fetch({ 	query: {text: "North America"},
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)
 							});
 			return d; //Object
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes function of the store
 			//	description:
 			//		Simple test of the getAttributes function of the store
@@ -737,7 +737,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
@@ -745,7 +745,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			var args = dojox.data.tests.stores.OpmlStore.getDatasource("stores/geography.xml");
 			var opmlStore = new dojox.data.OpmlStore(args);
 
-			var features = opmlStore.getFeatures(); 
+			var features = opmlStore.getFeatures();
 			var count = 0;
 			for(i in features){
 				t.assertTrue((i === "dojo.data.api.Read") || (i === "dojo.data.api.Identity"));
@@ -754,7 +754,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			t.assertTrue(count === 2);
 		},
 		function testReadAPI_fetch_patternMatch0(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything starting with Capital A
 			//	description:
 			//		Function to test pattern matching of everything starting with Capital A
@@ -774,7 +774,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch1(t){
-			//	summary: 
+			//	summary:
 			//		Function to test pattern matching of everything with America in it.
 			//	description:
 			//		Function to test pattern matching of everything with America in it.
@@ -794,7 +794,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch2(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match
 			//	description:
 			//		Function to test exact pattern match
@@ -813,7 +813,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case insensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case insensitivity set.
@@ -832,7 +832,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_patternMatch_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Function to test exact pattern match with case sensitivity set.
 			//	description:
 			//		Function to test exact pattern match with case sensitivity set.
@@ -850,7 +850,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabetic(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering.
 			//	description:
 			//		Function to test sorting alphabetic ordering.
@@ -872,7 +872,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticDescending(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting alphabetic ordering in descending mode.
 			//	description:
 			//		Function to test sorting alphabetic ordering in descending mode.
@@ -895,7 +895,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_sortAlphabeticWithCount(t){
-			//	summary: 
+			//	summary:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
 			//	description:
 			//		Function to test sorting numerically in descending order, returning only a specified number of them.
@@ -914,14 +914,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			}
 			
 			var sortAttributes = [{attribute: "text", descending: true}];
-			opmlStore.fetch({sort: sortAttributes, 
+			opmlStore.fetch({sort: sortAttributes,
 							count: 4,
 							onComplete: completed,
 							onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d; //Object
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -947,7 +947,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_fetchItemByIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -958,14 +958,14 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item !== null);
-				d.callback(true);	
+				d.callback(true);
 			}
             opmlStore.fetchItemByIdentity({identity: "1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d;
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_bad1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -976,13 +976,13 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
             opmlStore.fetchItemByIdentity({identity: "200", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -992,13 +992,13 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
             opmlStore.fetchItemByIdentity({identity: "-1", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_fetchItemByIdentity_bad3(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -1008,13 +1008,13 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			var d = new doh.Deferred();
 			function onItem(item){
 				t.assertTrue(item === null);
-				d.callback(true);	
+				d.callback(true);
 			}
             opmlStore.fetchItemByIdentity({identity: "999999", onItem: onItem, onError: dojo.partial(dojox.data.tests.stores.OpmlStore.error, t, d)});
 			return d;
 		},
 		function testIdentityAPI_getIdentity(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the fetchItemByIdentity function of the store.
 			//	description:
 			//		Simple test of the fetchItemByIdentity function of the store.
@@ -1041,7 +1041,7 @@ doh.register("dojox.data.tests.stores.OpmlStore",
 			return d; //Object
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test identity API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/PicasaStore.js b/dojox/data/tests/stores/PicasaStore.js
index a899328..4144585 100755
--- a/dojox/data/tests/stores/PicasaStore.js
+++ b/dojox/data/tests/stores/PicasaStore.js
@@ -6,16 +6,16 @@ dojo.require("dojo.data.api.Read");
 dojox.data.tests.stores.PicasaStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 };
 
-doh.register("dojox.data.tests.stores.PicasaStore", 
+doh.register("dojox.data.tests.stores.PicasaStore",
 	[
 		{
 			name: "ReadAPI:  Fetch_One",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on PicasaStore of a single item.
 				//	description:
 				//		Simple test of a basic fetch on PicasaStore of a single item.
@@ -29,7 +29,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 				}
 				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.PicasaStore.error, doh, d)
 								});
 				return d; //Object
@@ -39,7 +39,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on PicasaStore.
 				//	description:
 				//		Simple test of a basic fetch on PicasaStore.
@@ -75,7 +75,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	30000, //30 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				//	description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -144,7 +144,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabel function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabel function against a store set that has a label defined.
@@ -158,9 +158,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 					t.assertTrue(label !== null);
 					d.callback(true);
 				}
-				flickrStore.fetch({ 	query: {tags: "animals"}, 
+				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.PicasaStore.error, t, d)
 								});
 				return d;
@@ -170,7 +170,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getLabelAttributes",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 				//	description:
 				//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -187,7 +187,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 				}
 				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.PicasaStore.error, t, d)
 								});
 				return d;
@@ -197,7 +197,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getValue",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -222,7 +222,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getValues",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -247,7 +247,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  isItem",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//	description:
 				//		Simple test of the isItem function of the store
@@ -271,7 +271,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute function of the store
 				//	description:
 				//		Simple test of the hasAttribute function of the store
@@ -299,9 +299,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 				}
 
 				//Get one item...
-				flickrStore.fetch({ 	query: {tags: "animals"}, 
+				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.PicasaStore.error, t, d)
 								});
 				return d; //Object
@@ -311,7 +311,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue function of the store
 				//	description:
 				//		Simple test of the containsValue function of the store
@@ -325,9 +325,9 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 				}
 
 				//Get one item...
-				flickrStore.fetch({ 	query: {tags: "animals"}, 
+				flickrStore.fetch({ 	query: {tags: "animals"},
 									count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.PicasaStore.error, t, d)
 								});
 				return d; //Object
@@ -337,7 +337,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			name: "ReadAPI:  getAttributes",
 			timeout:	10000, //10 seconds.  Picasa can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes function of the store
 				//	description:
 				//		Simple test of the getAttributes function of the store
@@ -360,14 +360,14 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var flickrStore = new dojox.data.PicasaStore();
 
-			var features = flickrStore.getFeatures(); 
+			var features = flickrStore.getFeatures();
 			var count = 0;
 			var i;
 			for(i in features){
@@ -377,7 +377,7 @@ doh.register("dojox.data.tests.stores.PicasaStore",
 			t.assertTrue(count === 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/QueryReadStore.js b/dojox/data/tests/stores/QueryReadStore.js
index cb82efd..9ba6064 100644
--- a/dojox/data/tests/stores/QueryReadStore.js
+++ b/dojox/data/tests/stores/QueryReadStore.js
@@ -11,7 +11,7 @@ dojox.data.tests.stores.QueryReadStore.getStore = function(){
 };
 
 
-tests.register("dojox.data.tests.stores.QueryReadStore", 
+tests.register("dojox.data.tests.stores.QueryReadStore",
 	[
 		/*
 		function testDocTests(t) {
@@ -24,7 +24,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		*/
 		
 		function testReadApi_getValue(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
@@ -52,7 +52,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_getValues(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
@@ -84,7 +84,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 		
 		function testReadApi_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
@@ -115,7 +115,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
@@ -142,7 +142,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_containsValue(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 
@@ -157,7 +157,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_isItem(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
@@ -176,7 +176,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_isItemLoaded(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
@@ -193,13 +193,13 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		//function testReadApi_loadItem(t){
-		//	//	summary: 
+		//	//	summary:
 		//	//	description:
 		//	t.assertTrue(false);
 		//},
 
 		function testReadApi_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all items.
 			//	description:
 			//		Simple test of fetching all items.
@@ -218,7 +218,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 		
 		function testReadApi_fetch_onBegin(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
 			//	description:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
@@ -246,7 +246,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_fetch_onBegin_ServersidePaging(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
 			//	description:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
@@ -274,7 +274,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_fetch_onBegin_ClientsidePaging(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
 			//	description:
 			//		Simple test of fetching items, checking that onBegin size is all items matched, and page is just the items asked for.
@@ -303,7 +303,7 @@ tests.register("dojox.data.tests.stores.QueryReadStore",
 		},
 
 		function testReadApi_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//	description:
 			var store = dojox.data.tests.stores.QueryReadStore.getStore();
 			
diff --git a/dojox/data/tests/stores/ServiceStore.js b/dojox/data/tests/stores/ServiceStore.js
index a99431b..98728bb 100644
--- a/dojox/data/tests/stores/ServiceStore.js
+++ b/dojox/data/tests/stores/ServiceStore.js
@@ -7,21 +7,21 @@ dojo.require("dojo.data.api.Read");
 dojox.data.tests.stores.ServiceStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 var testServices = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
 var jsonStore = new dojox.data.ServiceStore({service:testServices.jsonRestStore});
 
-doh.register("dojox.data.tests.stores.ServiceStore", 
+doh.register("dojox.data.tests.stores.ServiceStore",
 	[
 		{
 			name: "Fetch some items",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on ServiceStore of a simple query.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						t.is(4, items.length);
 						d.callback(true);
@@ -35,10 +35,10 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "fetchItemByIdentity, getValue, getValues, hasAttribute,containsValue, getAttributes, getIdentity",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on ServiceStore of a single item.
 				var d = new doh.Deferred();
-				jsonStore.fetchItemByIdentity({identity:1, 
+				jsonStore.fetchItemByIdentity({identity:1,
 					onItem: function(item, request){
 						t.is("Object 1", item.name);
 						t.is("Object 1",jsonStore.getValue(item,"name"));
@@ -62,7 +62,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "createLazyItem",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on ServiceStore of a single item.
 				var d = new doh.Deferred();
 				var lazyItem = {
@@ -88,9 +88,9 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 				var d = new doh.Deferred();
 				jsonStore.idAttribute = "id";
 				jsonStore.syncMode = true;
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
-						items[0]._loadObject = function(callback){							
+						items[0]._loadObject = function(callback){
 							jsonStore.fetch({query:this.id,onComplete:callback});
 						}
 						t.t(jsonStore.getValue(items[0],"testArray").length);
@@ -105,7 +105,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Json can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		fetching with paging
 
 				var d = new doh.Deferred();
@@ -121,7 +121,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 					d.callback(true);
 				}
 				//Get everything...
-				jsonStore.fetch({	
+				jsonStore.fetch({
 					query: "bigQuery",
 					onBegin: null,
 					count: 20,
@@ -133,7 +133,7 @@ doh.register("dojox.data.tests.stores.ServiceStore",
 			}
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/SnapLogicStore.js b/dojox/data/tests/stores/SnapLogicStore.js
index 557cef0..57759f8 100644
--- a/dojox/data/tests/stores/SnapLogicStore.js
+++ b/dojox/data/tests/stores/SnapLogicStore.js
@@ -9,16 +9,16 @@ dojox.data.tests.stores.SnapLogicStore.attributes = ["empno", "ename", "job", "h
 dojox.data.tests.stores.SnapLogicStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 
-doh.register("dojox.data.tests.stores.SnapLogicStore", 
+doh.register("dojox.data.tests.stores.SnapLogicStore",
 	[
 	    {
 			name: "ReadAPI:  Fetch One",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch from a SnapLogic pipeline
 				//	description:
 				//		Simple test of a basic fetch from a SnapLogic pipeline
@@ -31,7 +31,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 				store.fetch({	count: 1,
-								onComplete: onComplete, 
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, doh, d)
 								});
 				return d; //Object
@@ -41,7 +41,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch_10_Streaming",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on SnapLogic pipeline.
 				//	description:
 				//		Simple test of a basic fetch on SnapLogic pipeline.
@@ -78,7 +78,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch Zero",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Try fetching 0 records. A count of the items in the pipeline should be returned.
 				//	description:
 				//		Try fetching 0 records. A count of the items in the pipeline should be returned.
@@ -91,7 +91,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 				store.fetch({	count: 0,
-								onBegin: onBegin, 
+								onBegin: onBegin,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, doh, d)
 								});
 				return d; //Object
@@ -101,7 +101,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  Fetch_Paging",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
 				//	description:
 				//		Test of multiple fetches on a single result.  Paging, if you will.
@@ -153,8 +153,8 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 
-				store.fetch({	count: 5, 
-								onComplete: dumpFirstFetch, 
+				store.fetch({	count: 5,
+								onComplete: dumpFirstFetch,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)});
 				return d; //Object
 			}
@@ -163,7 +163,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getLabel",
 			timeout:	3000, //3 seconds
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Test that the label function returns undefined since it's not supported.
 				//	description:
 				//		Test that the label function returns undefined since it's not supported.
@@ -178,7 +178,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 				store.fetch({		count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)
 								});
 				return d;
@@ -186,9 +186,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 		},
 		{
 			name: "ReadAPI:  getLabelAttributes",
-			timeout:	3000, //3 seconds.  
+			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getLabelAttributes returns null since it's not supported.
 				//	description:
 				//		Simple test of the getLabelAttributes returns null since it's not supported.
@@ -203,7 +203,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 				store.fetch({		count: 1,
-									onComplete: onComplete, 
+									onComplete: onComplete,
 									onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)
 								});
 				return d;
@@ -213,7 +213,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getValue",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -232,8 +232,8 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 
-				store.fetch({	count: 1, 
-								onComplete: completedAll, 
+				store.fetch({	count: 1,
+								onComplete: completedAll,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)});
 				return d;
 			}
@@ -242,7 +242,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  getValues",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getValue function of the store.
 				//	description:
 				//		Simple test of the getValue function of the store.
@@ -259,17 +259,17 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 					d.callback(true);
 				}
 
-				store.fetch({	count: 1, 
-								onComplete: completedAll, 
+				store.fetch({	count: 1,
+								onComplete: completedAll,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)});
 				return d;
 			}
 		},
 		{
 			name: "ReadAPI:  isItem",
-			timeout:	3000, //3 seconds. 
+			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the isItem function of the store
 				//	description:
 				//		Simple test of the isItem function of the store
@@ -285,8 +285,8 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 				}
 
 				//Get everything...
-				store.fetch({	count: 5, 
-								onComplete: completedAll, 
+				store.fetch({	count: 5,
+								onComplete: completedAll,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)});
 				return d; //Object
 			}
@@ -295,7 +295,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  hasAttribute",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the hasAttribute function of the store
 				//	description:
 				//		Simple test of the hasAttribute function of the store
@@ -325,7 +325,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 
 				//Get one item...
 				store.fetch({	count: 1,
-								onComplete: onComplete, 
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)
 								});
 				return d; //Object
@@ -335,7 +335,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			name: "ReadAPI:  containsValue",
 			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the containsValue function of the store
 				//	description:
 				//		Simple test of the containsValue function of the store
@@ -352,7 +352,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 
 				//Get one item...
 				store.fetch({	count: 1,
-								onComplete: onComplete, 
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)
 								});
 				return d; //Object
@@ -360,9 +360,9 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 		},
 		{
 			name: "ReadAPI:  getAttributes",
-			timeout:	3000, //3 seconds. 
+			timeout:	3000, //3 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of the getAttributes function of the store
 				//	description:
 				//		Simple test of the getAttributes function of the store
@@ -382,21 +382,21 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 				}
 
 				//Get everything...
-				store.fetch({	count: 1, 
-								onComplete: onComplete, 
+				store.fetch({	count: 1,
+								onComplete: onComplete,
 								onError: dojo.partial(dojox.data.tests.stores.SnapLogicStore.error, t, d)});
 				return d; //Object
 			}
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = new dojox.data.SnapLogicStore({url: dojox.data.tests.stores.SnapLogicStore.pipelineUrl});
 
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 			var count = 0;
 			for(var i in features){
 				t.assertEqual(i, "dojo.data.api.Read");
@@ -406,7 +406,7 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			t.assertEqual(count, 1);
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -431,4 +431,4 @@ doh.register("dojox.data.tests.stores.SnapLogicStore",
 			t.assertTrue(passed);
 		}
 	]
-);		
+);
diff --git a/dojox/data/tests/stores/XmlStore.js b/dojox/data/tests/stores/XmlStore.js
index 3f68bca..e4121b4 100644
--- a/dojox/data/tests/stores/XmlStore.js
+++ b/dojox/data/tests/stores/XmlStore.js
@@ -29,10 +29,10 @@ 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"});
 };
 
-doh.register("dojox.data.tests.stores.XmlStore", 
+doh.register("dojox.data.tests.stores.XmlStore",
 	[
 		function testReadAPI_fetch_all(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching all xml items through an XML element called isbn
@@ -50,7 +50,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_one(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn
@@ -71,7 +71,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			name: "testReadAPI_fetch_paging",
 			timeout: 10000,
 			runTest: function(t){
-				//	summary: 
+				//	summary:
 				//		Simple test of fetching one xml items through an XML element called isbn
 				//	description:
 				//		Simple test of fetching one xml items through an XML element called isbn
@@ -141,12 +141,12 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			}
 		},
 		function testReadAPI_fetch_pattern0(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		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();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -158,7 +158,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
@@ -175,7 +175,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern1_preventCacheOff(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//		with preventCache off to test that it doesn't pass it when told not to.
 			//	description:
@@ -194,7 +194,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with * pattern match
@@ -211,7 +211,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_multi(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
 			//	description:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
@@ -228,7 +228,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_multiValuedValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
 			//	description:
 			//		Simple test of fetching one xml items with a pattern of multiple attrs.
@@ -245,12 +245,12 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseInsensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case insensitive mode.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -262,12 +262,12 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_pattern_caseSensitive(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			//	description:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match and in case sensitive mode.
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(1, items.length);
 				d.callback(true);
@@ -279,11 +279,11 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_all_rootItem(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching all xml items through an XML element called isbn
 			//	description:
 			//		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: dojo.moduleUrl("dojox.data.tests", "stores/books3.xml").toString(),
 				rootItem:"book"});
 
 			var d = new doh.Deferred();
@@ -330,13 +330,13 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_pattern0(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		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: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(3, items.length);
 				d.callback(true);
@@ -348,13 +348,13 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_pattern1(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		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(),
 				attributeMap: {"book.isbn": "@isbn"}});
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(5, items.length);
 				d.callback(true);
@@ -366,13 +366,13 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_fetch_withAttrMap_pattern2(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of fetching one xml items through an XML element called isbn with ? pattern match
 			//	description:
 			//		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: dojo.moduleUrl("dojox.data.tests", "stores/books_isbnAttr2.xml").toString(),
 				attributeMap: {"book.isbn": "@isbn"}});
-			var d = new doh.Deferred();                                                             
+			var d = new doh.Deferred();
 			function onComplete(items, request) {
 				t.assertEqual(2, items.length);
 				d.callback(true);
@@ -385,7 +385,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getLabel(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabel function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabel function against a store set that has a label defined.
@@ -407,7 +407,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d;
 		},
 		function testReadAPI_getLabelAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
 			//	description:
 			//		Simple test of the getLabelAttributes function against a store set that has a label defined.
@@ -430,7 +430,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getValue API
 			//	description:
 			//		Simple test of the getValue API
@@ -540,7 +540,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_getValues(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the getValues API
 			 //	description:
 			 //		Simple test of the getValues API
@@ -563,7 +563,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem(t){
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the isItem API
 			 //	description:
 			 //		Simple test of the isItem API
@@ -586,7 +586,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			 return d; //Object
 		},
 		function testReadAPI_isItem_multistore(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItem API across multiple store instances.
 			//	description:
 			//		Simple test of the isItem API across multiple store instances.
@@ -617,7 +617,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_hasAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the hasAttribute API
 			//	description:
 			//		Simple test of the hasAttribute API
@@ -641,7 +641,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_containsValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the containsValue API
 			//	description:
 			//		Simple test of the containsValue API
@@ -662,7 +662,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order.
 			//	description:
 			//		Simple test of the sorting API in descending order.
@@ -691,7 +691,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscending(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order.
 			//	description:
 			//		Simple test of the sorting API in ascending order.
@@ -719,7 +719,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortDescendingNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
 			//	description:
 			//		Simple test of the sorting API in descending order using a numeric comparator.
@@ -756,7 +756,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_sortAscendingNumeric(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
 			//	description:
 			//		Simple test of the sorting API in ascending order using a numeric comparator.
@@ -793,7 +793,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_isItemLoaded(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isItemLoaded API
 			//	description:
 			//		Simple test of the isItemLoaded API
@@ -813,13 +813,13 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testReadAPI_getFeatures(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getFeatures function of the store
 			//	description:
 			//		Simple test of the getFeatures function of the store
 
 			var store = dojox.data.tests.stores.XmlStore.getBooks2Store();
-			var features = store.getFeatures(); 
+			var features = store.getFeatures();
 			var count = 0;
 			var i;
 			for(i in features){
@@ -829,7 +829,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			t.assertEqual(3, count);
 		},
 		function testReadAPI_getAttributes(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the getAttributes API
 			//	description:
 			//		Simple test of the getAttributes API
@@ -841,7 +841,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 				var item = items[0];
 				var attributes = store.getAttributes(item);
 
-				//Should be six, as all items should have tagName, childNodes, and text() special attributes 
+				//Should be six, as all items should have tagName, childNodes, and text() special attributes
 				//in addition to any doc defined ones, which in this case are author, title, and isbn
 				//FIXME:  Figure out why IE returns 5!  Need to get firebug lite working in IE for that.
 				//Suspect it's childNodes, may not be defined if there are no child nodes.
@@ -862,7 +862,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValue(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the setValue API
 			//	description:
 			//		Simple test of the setValue API
@@ -884,7 +884,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_setValues(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the setValues API
 			//	description:
 			//		Simple test of the setValues API
@@ -910,7 +910,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_unsetAttribute(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the unsetAttribute API
 			//	description:
 			//		Simple test of the unsetAttribute API
@@ -933,7 +933,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_isDirty(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the isDirty API
 			//	description:
 			//		Simple test of the isDirty API
@@ -956,7 +956,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			return d; //Object
 		},
 		function testWriteAPI_revert(t){
-			//	summary: 
+			//	summary:
 			//		Simple test of the write revert API
 			//	description:
 			//		Simple test of the write revert API
@@ -990,7 +990,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_getIdentity(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API
 			 //	description:
 			 //		Simple test of the Identity getIdentity API
@@ -1016,7 +1016,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_getIdentityAttributes(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentityAttributes API where it defaults to internal xpath (no keyAttribute)
 			 //	description:
 			 //		Simple test of the Identity getIdentityAttributes API where it defaults to internal xpath (no keyAttribute)
@@ -1042,7 +1042,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_getIdentityAttributes_usingKeyAttributeIdentity(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentityAttributes API where identity is specified by the keyAttribute param
 			 //	description:
 			 //		Simple test of the Identity getIdentityAttributes API where identity is specified by the keyAttribute param
@@ -1069,7 +1069,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
@@ -1094,7 +1094,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity2(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
@@ -1119,7 +1119,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity3(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where the store defaults the identity to a xpathlike lookup.
@@ -1144,7 +1144,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
@@ -1168,7 +1168,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity2(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
@@ -1192,7 +1192,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity3(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
@@ -1216,7 +1216,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity4(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
@@ -1241,7 +1241,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 
 
 		function testIdentityAPI_fetchItemByIdentity_fails(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API
 			 //	description:
 			 //		Simple test of the Identity getIdentity API
@@ -1261,7 +1261,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_fails2(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API
 			 //	description:
 			 //		Simple test of the Identity getIdentity API
@@ -1281,7 +1281,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_fails3(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API
 			 //	description:
 			 //		Simple test of the Identity getIdentity API
@@ -1301,7 +1301,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testIdentityAPI_fetchItemByIdentity_usingKeyAttributeIdentity_fails(t) {
-			 //	summary: 
+			 //	summary:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
 			 //	description:
 			 //		Simple test of the Identity getIdentity API where identity is specified by the keyAttribute param
@@ -1324,7 +1324,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 		},
 
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -1348,7 +1348,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			t.assertTrue(passed);
 		},
 		function testWriteAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
@@ -1371,7 +1371,7 @@ doh.register("dojox.data.tests.stores.XmlStore",
 			t.assertTrue(passed);
 		},
 		function testIdentityAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test write API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/data/tests/stores/properties.js b/dojox/data/tests/stores/properties.js
index bbdd38d..486abbf 100644
--- a/dojox/data/tests/stores/properties.js
+++ b/dojox/data/tests/stores/properties.js
@@ -1,5 +1,5 @@
 /*[
-	// Properties of December 1, 2007 
+	// Properties of December 1, 2007
 	{ "year": "2007" },
 	{ "nmonth": "12" },
 	{ "month": "December" },
diff --git a/dojox/data/util/JsonQuery.js b/dojox/data/util/JsonQuery.js
index 34a17df..96a0f4c 100644
--- a/dojox/data/util/JsonQuery.js
+++ b/dojox/data/util/JsonQuery.js
@@ -1,5 +1,6 @@
-dojo.provide("dojox.data.util.JsonQuery");
-// this is a mixin to convert object attribute queries to 
+define("dojox/data/util/JsonQuery", ["dojo", "dojox"], function(dojo, dojox) {
+
+// this is a mixin to convert object attribute queries to
 // JSONQuery/JSONPath syntax to be sent to the server.
 dojo.declare("dojox.data.util.JsonQuery", null, {
 	useFullIdInQueries: false,
@@ -7,7 +8,7 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 		var first = true;
 		var self = this;
 		function buildQuery(path, query){
-			var isDataItem = query.__id; 
+			var isDataItem = query.__id;
 			if(isDataItem){
 				// it is a reference to a persisted object, need to make it a query by id
 				var newQuery = {};
@@ -26,7 +27,7 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 						 (self.simplifiedQuery ? encodeURIComponent(value) : dojo.toJson(value));
 					first = false;
 				}
-			}			
+			}
 		}
 		// performs conversion of Dojo Data query objects and sort arrays to JSONQuery strings
 		if(args.query && typeof args.query == "object"){
@@ -35,7 +36,7 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 			buildQuery("@", args.query);
 			if(!first){
 				// use ' instead of " for quoting in JSONQuery, and end with ]
-				jsonQuery += ")]"; 
+				jsonQuery += ")]";
 			}else{
 				jsonQuery = "";
 			}
@@ -47,18 +48,19 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 		var sort = args.sort;
 		if(sort){
 			// if we have a sort order, add that to the JSONQuery expression
-			args.queryStr = args.queryStr || (typeof args.query == 'string' ? args.query : ""); 
+			args.queryStr = args.queryStr || (typeof args.query == 'string' ? args.query : "");
 			first = true;
 			for(i = 0; i < sort.length; i++){
 				args.queryStr += (first ? '[' : ',') + (sort[i].descending ? '\\' : '/') + "@[" + dojo._escapeString(sort[i].attribute) + "]";
-				first = false; 
+				first = false;
 			}
+			args.queryStr += ']';
 		}
 		// this is optional because with client side paging JSONQuery doesn't yield the total count
 		if(jsonQueryPagination && (args.start || args.count)){
 			// pagination
 			args.queryStr = (args.queryStr || (typeof args.query == 'string' ? args.query : "")) +
-				'[' + (args.start || '') + ':' + (args.count ? (args.start || 0) + args.count : '') + ']'; 
+				'[' + (args.start || '') + ':' + (args.count ? (args.start || 0) + args.count : '') + ']';
 		}
 		if(typeof args.queryStr == 'string'){
 			args.queryStr = args.queryStr.replace(/\\"|"/g,function(t){return t == '"' ? "'" : t;});
@@ -75,7 +77,7 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 		return true;
 	},
 	matchesQuery: function(item,request){
-		request._jsonQuery = request._jsonQuery || dojox.json.query(this._toJsonQuery(request)); 
+		request._jsonQuery = request._jsonQuery || dojox.json.query(this._toJsonQuery(request));
 		return request._jsonQuery([item]).length;
 	},
 	clientSideFetch: function(/*Object*/ request,/*Array*/ baseResults){
@@ -91,3 +93,6 @@ dojo.declare("dojox.data.util.JsonQuery", null, {
 	}
 	
 });
+
+return dojox.data.util.JsonQuery;
+});
diff --git a/dojox/date/buddhist.js b/dojox/date/buddhist.js
index 376b919..8a3cc80 100644
--- a/dojox/date/buddhist.js
+++ b/dojox/date/buddhist.js
@@ -86,19 +86,19 @@ dojox.date.buddhist.add = function(/*dojox.date.buddhist.Date*/date, /*String*/i
 			break;
 		case "hour":
 			newBuddDate.setHours(date.getHours() + amount );
-			break;	
+			break;
 		case "minute":
 			newBuddDate.setMinutes(date.getMinutes() + amount );
-			break;	
+			break;
 		case "second":
 			newBuddDate.setSeconds(date.getSeconds() + amount );
-			break;	
+			break;
 		case "millisecond":
 			newBuddDate.setMilliseconds(date.getMilliseconds() + amount );
 			break;
 	}
 	return newBuddDate; // dojox.date.buddhist.Date
-}; 
+};
 
 dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*dojox.date.buddhist.Date?*/date2, /*String?*/interval){
 	//	based on and similar to dojo.date.difference
@@ -207,7 +207,7 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 				var i = enddate.getFullYear()+1;
 				var e = startdate.getFullYear();
 				for (i;   i < e;  i++){
-					delta += 12; 
+					delta += 12;
 				}
 			}
 			if (date1.toGregorian() < date2.toGregorian()){
@@ -236,5 +236,5 @@ dojox.date.buddhist.difference = function(/*dojox.date.buddhist.Date*/date1, /*d
 	}
 	
 	// Round for fractional values and DST leaps
-	return Math.round(delta); // Number (integer) 
+	return Math.round(delta); // Number (integer)
 };
\ No newline at end of file
diff --git a/dojox/date/buddhist/Date.js b/dojox/date/buddhist/Date.js
index 9511fb8..f23d838 100644
--- a/dojox/date/buddhist/Date.js
+++ b/dojox/date/buddhist/Date.js
@@ -19,7 +19,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 		//
 		// example:
 		// |		var date1 = new dojox.date.buddhist.Date();
-		// |		
+		// |
 		// |		var date2 = new dojox.date.buddhist.Date(date1);
 		// |
 		// |		var date3 = new dojox.date.buddhist.Date(2552,2,12);
@@ -38,13 +38,13 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 				this._date = new Date("");
 			}else{
 				this._year = arg0._year;
-				this._month =  arg0._month;  
+				this._month =  arg0._month;
 				this._date = arg0._date;
 				this._hours = arg0._hours;
 				this._minutes = arg0._minutes;
 				this._seconds = arg0._seconds;
-				this._milliseconds = arg0._milliseconds; 
-			}	
+				this._milliseconds = arg0._milliseconds;
+			}
 		}else if(len >=3){
 			this._year += arguments[0];
 			this._month += arguments[1];
@@ -52,7 +52,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 			
 			if(this._month >11){
 				console.warn("the month is incorrect , set 0");
-				this._month = 0;			
+				this._month = 0;
 			}
 			this._hours += arguments[3] || 0;
 			this._minutes += arguments[4] || 0;
@@ -83,7 +83,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 
 
 	getFullYear: function(){
-		// summary: This function return the Year value 
+		// summary: This function return the Year value
 		//
 		// example:
 		// |		var date1 = new dojox.date.buddhist.Date();
@@ -112,7 +112,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 		return this._milliseconds;
 	},
 
-	setDate: function(/*number*/date){	
+	setDate: function(/*number*/date){
 		// summary: This function sets the Date
 		// example:
 		// |		var date1 = new dojox.date.buddhist.Date();
@@ -124,8 +124,8 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 		}else{
 			var mdays;
 			if(date>0){
-				for(mdays = this._getDaysInMonth(this._month, this._year);	
-					date > mdays; 
+				for(mdays = this._getDaysInMonth(this._month, this._year);
+					date > mdays;
 						date -= mdays,mdays = this._getDaysInMonth(this._month, this._year)){
 					this._month++;
 					if(this._month >= 12){this._year++; this._month -= 12;}
@@ -133,8 +133,8 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 
 				this._date = date;
 			}else{
-				for(mdays = this._getDaysInMonth((this._month-1)>=0 ?(this._month-1) :11 ,((this._month-1)>=0)? this._year: this._year-1);	
-						date <= 0; 
+				for(mdays = this._getDaysInMonth((this._month-1)>=0 ?(this._month-1) :11 ,((this._month-1)>=0)? this._year: this._year-1);
+						date <= 0;
 							mdays = this._getDaysInMonth((this._month-1)>=0 ? (this._month-1) :11,((this._month-1)>=0)? this._year: this._year-1)){
 					this._month--;
 					if(this._month < 0){this._year--; this._month += 12;}
@@ -148,7 +148,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 	},
 	
 	setFullYear: function(/*number*/year, /*number?*/month, /*number?*/ date){
-		// summary: This function set Year 
+		// summary: This function set Year
 		//
 		// example:
 		// |		var date1 = new dojox.date.buddhist.Date();
@@ -205,7 +205,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 		//summary: set the Minutes  frm 0-59
 		while(minutes >= 60){
 			this._hours++;
-			if(this._hours >= 24){		 
+			if(this._hours >= 24){
 				this._date++;
 				this._hours -= 24;
 				var mdays = this._getDaysInMonth(this._month, this._year);
@@ -227,7 +227,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 			if(this._minutes >= 60){
 				this._hours++;
 				this._minutes -= 60;
-				if(this._hours >= 24){		 
+				if(this._hours >= 24){
 					this._date++;
 					this._hours -= 24;
 					var mdays = this._getDaysInMonth(this._month, this._year);
@@ -253,7 +253,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 				if(this._minutes >= 60){
 					this._hours++;
 					this._minutes -= 60;
-					if(this._hours >= 24){		 
+					if(this._hours >= 24){
 						this._date++;
 						this._hours -= 24;
 						var mdays = this._getDaysInMonth(this._month, this._year);
@@ -270,7 +270,7 @@ dojo.declare("dojox.date.buddhist.Date", null, {
 		this._milliseconds = milliseconds;
 	},
 
-	toString: function(){ 
+	toString: function(){
 		// summary: This returns a string representation of the date in "dd, MM, YYYY HH:MM:SS" format
 		return this._date + ", " + this._month + ", " + this._year + "  " + this._hours + ":" + this._minutes + ":" + this._seconds; // String
 	},
diff --git a/dojox/date/buddhist/locale.js b/dojox/date/buddhist/locale.js
index cc6dfab..cf000c9 100644
--- a/dojox/date/buddhist/locale.js
+++ b/dojox/date/buddhist/locale.js
@@ -80,13 +80,32 @@ dojo.requireLocalization("dojo.cldr", "buddhist");
 				case 'S':
 					s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l-3)); pad = true;
 					break;
+				case 'z':
+					// We only have one timezone to offer; the one from the browser
+					s = dojo.date.getTimezoneName(dateObject.toGregorian());
+					if(s){ break; }
+					l = 4;
+					// fallthrough... use GMT if tz not available
+				case 'Z':
+					var offset = dateObject.toGregorian().getTimezoneOffset();
+					var tz = [
+						(offset <= 0 ? "+" : "-"),
+						dojo.string.pad(Math.floor(Math.abs(offset) / 60), 2),
+						dojo.string.pad(Math.abs(offset) % 60, 2)
+					];
+					if(l == 4){
+						tz.splice(0, 0, "GMT");
+						tz.splice(3, 0, ":");
+					}
+					s = tz.join("");
+					break;
 				default:
 					throw new Error("dojox.date.buddhist.locale.formatPattern: invalid pattern char: "+pattern);
 			}
 			if(pad){ s = dojo.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
@@ -115,10 +134,10 @@ dojox.date.buddhist.locale.format = function(/*buddhist.Date*/dateObject, /*obje
 	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	
+	//	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
@@ -154,7 +173,7 @@ dojox.date.buddhist.locale._parseInfo = function(/*oblect?*/options){
 
 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	
+	// summary: This function parse string date value according to options
 	value =  value.replace(/[\u200E\u200F\u202A-\u202E]/g, ""); //remove special chars
 	
 	if(!options){options={};}
@@ -165,9 +184,9 @@ dojox.date.buddhist.locale.parse= function(/*String*/value, /*object?*/options){
 	
 	var match = re.exec(value);
 
-	var locale = dojo.i18n.normalizeLocale(options.locale); 
+	var locale = dojo.i18n.normalizeLocale(options.locale);
 
-	if(!match){ 
+	if(!match){
 		console.debug("dojox.date.buddhist.locale.parse: value  "+value+" doesn't match pattern   " + re);
 		return null;
 	} // null
@@ -201,7 +220,7 @@ dojox.date.buddhist.locale.parse= function(/*String*/value, /*object?*/options){
 					}
 					mLength = l;
 				}else{
-					v--;				
+					v--;
 				}
 				result[1] = Number(v);
 				break;
@@ -242,7 +261,7 @@ dojox.date.buddhist.locale.parse= function(/*String*/value, /*object?*/options){
 				break;
 			case 's': //seconds
 				result[5] = Number(v);
-				break; 
+				break;
 			case 'S': //milliseconds
 				result[6] = Number(v);
 		}
@@ -269,9 +288,9 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 	applyLiteral = applyLiteral || identity;
 	applyAll = applyAll || identity;
 
-	//split on single quotes (which escape literals in date format strings) 
+	//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 chunks = pattern.match(/(''|[^'])+/g);
 	var literal = pattern.charAt(0) == "'";
 
 	dojo.forEach(chunks, function(chunk, i){
@@ -286,10 +305,10 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 }
 
 function _buildDateTimeRE  (tokens, bundle, options, pattern){
-		// based on and similar to dojo.date.locale._buildDateTimeRE 
+		// based on and similar to dojo.date.locale._buildDateTimeRE
 		//
 	
-	pattern = dojo.regexp.escapeString(pattern); 
+	pattern = dojo.regexp.escapeString(pattern);
 	var locale = dojo.i18n.normalizeLocale(options.locale);
 	
 	return pattern.replace(/([a-z])\1*/ig, function(match){
@@ -350,7 +369,7 @@ function _buildDateTimeRE  (tokens, bundle, options, pattern){
 					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. */
@@ -384,16 +403,16 @@ dojox.date.buddhist.locale.getNames = function(/*String*/item, /*String*/type, /
 	// summary:
 	//		Used to get localized strings from dojo.cldr for day or month names.
 	var label;
-	var lookup = dojox.date.buddhist.locale._getBuddhistBundle;
+	var lookup = dojox.date.buddhist.locale._getBuddhistBundle(locale);
 	var props = [item, context, type];
 	if(context == 'standAlone'){
 		var key = props.join('-');
-		label = lookup(locale)[key];
+		label = lookup[key];
 		// Fall back to 'format' flavor of name
-		if(label === lookup("ROOT")[key]){ label = undefined; } // a bit of a kludge, in the absense of real aliasing support in dojo.cldr
+		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(locale)[props.join('-')]).concat(); /*Array*/
+	return (label || lookup[props.join('-')]).concat(); /*Array*/
 };
diff --git a/dojox/date/hebrew.js b/dojox/date/hebrew.js
index 3f555c4c..42dea14 100644
--- a/dojox/date/hebrew.js
+++ b/dojox/date/hebrew.js
@@ -81,30 +81,30 @@ 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 month = date.getMonth();
 			var add = month + amount;
 			if(!date.isLeapYear(date.getFullYear())){
 				if(month < 5 && add >= 5){ add++;}
-				else if (month > 5 && add <= 5){ add--;}	
+				else if (month > 5 && add <= 5){ add--;}
 			}
 			newHebrDate.setMonth(add);
 			break;
 		case "hour":
 			newHebrDate.setHours(date.getHours() + amount);
-			break;	
+			break;
 		case "minute":
 			newHebrDate.setMinutes(date.getMinutes() + amount);
-			break;	
+			break;
 		case "second":
 			newHebrDate.setSeconds(date.getSeconds() + amount);
-			break;	
+			break;
 		case "millisecond":
 			newHebrDate.setMilliseconds(date.getMilliseconds() + amount);
 			break;
 	}
 
 	return newHebrDate; // dojox.date.hebrew.Date
-}; 
+};
 
 dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox.date.hebrew.Date?*/date2, /*String?*/interval){
 	//	based on and similar to dojo.date.difference
@@ -214,7 +214,7 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 				var i = enddate.getFullYear()  + 1;
 				var e = startdate.getFullYear();
 				for (i;   i < e;  i++){
-					delta += enddate.isLeapYear(i) ? 13 : 12; 
+					delta += enddate.isLeapYear(i) ? 13 : 12;
 				}
 			}
 			if(date1.toGregorian() < date2.toGregorian()){
@@ -243,5 +243,5 @@ dojox.date.hebrew.difference = function(/*dojox.date.hebrew.Date*/date1, /*dojox
 	}
 
 	// Round for fractional values and DST leaps
-	return Math.round(delta); // Number (integer) 
+	return Math.round(delta); // Number (integer)
 };
diff --git a/dojox/date/hebrew/Date.js b/dojox/date/hebrew/Date.js
index 15356c2..81766f4 100644
--- a/dojox/date/hebrew/Date.js
+++ b/dojox/date/hebrew/Date.js
@@ -13,7 +13,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	//
 	// example:
 	// |	dojo.require("dojox.date.hebrew.Date");
-	// |		
+	// |
 	// |	var date = new dojox.date.hebrew.Date();
 	// |	console.log(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
 
@@ -142,7 +142,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		//
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date();
-		// |		
+		// |
 		// |		var date2 = new dojox.date.hebrew.Date(date1);
 		// |
 		// |		var date3 = new dojox.date.hebrew.Date(5768,2,12);
@@ -163,15 +163,15 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 				this._date = new Date(""); //TODO: should this be NaN?  _date is not a Date object
 			}else{  // this is hebrew.Date object
 				this._year = arg0._year;
-				this._month =  arg0._month;  
+				this._month =  arg0._month;
 				this._date = arg0._date;
 				this._hours = arg0._hours;
 				this._minutes = arg0._minutes;
 				this._seconds = arg0._seconds;
-				this._milliseconds = arg0._milliseconds; 
-			}	
+				this._milliseconds = arg0._milliseconds;
+			}
 		}else if(len >= 3){
-			// YYYY, MM, DD arguments passed, month is from 0-12,  "absolute" index of month 
+			// YYYY, MM, DD arguments passed, month is from 0-12,  "absolute" index of month
 			this._year += arguments[0];
 			this._month += arguments[1];
 			this._date += arguments[2];
@@ -186,7 +186,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 			this._milliseconds += arguments[6] || 0;
 		}
   
-		this._setDay();	
+		this._setDay();
 	},
 	
 	getDate: function(){
@@ -244,7 +244,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	getFullYear: function(){
-		// summary: returns the Year value 
+		// summary: returns the Year value
 		//
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
@@ -276,7 +276,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		return this._milliseconds;
 	},
 
-	setDate: function(/*number*/date){	
+	setDate: function(/*number*/date){
 		// summary: sets the date number for a given month
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date(5769, 6, 1);
@@ -299,13 +299,13 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 			}
 		}
 		this._date = date;
-		this._setDay();		
+		this._setDay();
 		return this;
 	},
 	
 
 	setFullYear: function(/*number*/year, /*number?*/month, /*number?*/ date){
-		// summary: set the year 
+		// summary: set the year
 		//
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date();
@@ -314,8 +314,8 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		
 		this._year = year = +year;
 		if(!this.isLeapYear(year) && this._month==5){  //incorrect month number for non leap year
-			this._month++; 
-		} 
+			this._month++;
+		}
 		
 		if(month !== undefined){this.setMonth(month);}
 		if(date !== undefined){this.setDate(date);}
@@ -346,26 +346,26 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		//	12. Elul - 12
 		//  For non leap years, for months after Shevat, the actual position of
 		//	the month in the year (used for short format) is less than
-		//	the "absolute" index by 1. 
+		//	the "absolute" index by 1.
 		//
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date();
 		// |		date1.setMonth(0); //first month
 
-		month = +month; // coerce to a Number					
+		month = +month; // coerce to a Number
 		if(!this.isLeapYear(this._year) && month == 5){month++;}
 	
 		if(month>=0){
 			while(month >12){
 				this._year++;
 				month -= 13;
-				if (!this.isLeapYear(this._year) && month >= 5){month++;}	
+				if (!this.isLeapYear(this._year) && month >= 5){month++;}
 			}
 		}else{
 			while(month<0){
 				this._year--;
-				month += (!this.isLeapYear(this._year)  &&  month < -7) ? 12 : 13; 
-			}		
+				month += (!this.isLeapYear(this._year)  &&  month < -7) ? 12 : 13;
+			}
 		}
 		
 		this._month = month;
@@ -383,10 +383,10 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		//	summary: sets the hour
 		//
 		//	description: Sets the hour and optionally minutes, seconds, milliseconds also.
-		//		
+		//
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date();
-		// |		date1.setHours(12, 30, 0, 0); 
+		// |		date1.setHours(12, 30, 0, 0);
 
 		var hours_arg_no = arguments.length;
 		var hours = 0;
@@ -427,7 +427,7 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		//summary: sets the minutes (0-59)
 		minutes = +minutes;
 		this._minutes = minutes % 60;
-		this.setHours(parseInt(minutes / 60));		
+		this.setHours(parseInt(minutes / 60));
 		this._setDay();
 		return this;
 	},
@@ -452,16 +452,16 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 		return this;
 	},
 
-	_setDay: function(){ 
+	_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._date - 1;
-		this._day = (day+1) % 7;	
+		this._day = (day+1) % 7;
 	},
 
-	toString: function(){ 
+	toString: function(){
 		// summary: returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format
 		//
 		// description: returns a string representation of the date in "dd, MM, yyyy HH:mm:ss" format (all numeric)
@@ -535,11 +535,11 @@ dojo.declare("dojox.date.hebrew.Date", null, {
 	},
 
 	// ported from the Java class com.ibm.icu.util.HebrewCalendar from ICU4J v3.6.1 at http://www.icu-project.org/
-	isLeapYear: function(/*Number*/year){	
+	isLeapYear: function(/*Number*/year){
 	//	summary:
 	//		Determines if the year (argument) is a leap year
 	//	description: The Leap year contains additional month adar sheni
-	//	
+	//
 		//return (year * 12 + 17) % 19 >= 12;
 		var x = (year*12 + 17) % 19;
 		return x >= ((x < 0) ? -7 : 12);
diff --git a/dojox/date/hebrew/locale.js b/dojox/date/hebrew/locale.js
index 938e125..808d80e 100644
--- a/dojox/date/hebrew/locale.js
+++ b/dojox/date/hebrew/locale.js
@@ -9,7 +9,7 @@ dojo.require("dojo.i18n");
 
 
 //Load the bundles containing localization information for
-// names and formats 
+// names and formats
 dojo.requireLocalization("dojo.cldr", "hebrew");
 
 (function(){
@@ -28,7 +28,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 						s = dojox.date.hebrew.numerals.getYearHebrewLetters(dateObject.getFullYear());
 					}else{
 						s = String(dateObject.getFullYear());
-					}	
+					}
 					break;
 				case 'M':
 					var m = dateObject.getMonth();
@@ -38,7 +38,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 							s = dojox.date.hebrew.numerals.getMonthHebrewLetters(m);
 						}else{
 							s = m+1; pad = true;
-						}	
+						}
 					}else{
 						var monthNames = dojox.date.hebrew.locale.getNames('months',widthList[l-3], 'format', locale, dateObject);
 						s = monthNames[m];
@@ -49,7 +49,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 						s =  dateObject.getDateLocalized(locale);
 					}else{
 						s = dateObject.getDate(); pad = true;
-					}	
+					}
 					break;
 				case 'E':
 					var d = dateObject.getDay();
@@ -95,7 +95,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 				case 'S':
 					s = Math.round(dateObject.getMilliseconds() * Math.pow(10, l-3)); pad = true;
 					break;
-				case 'z': 
+				case 'z':
 					s = "";
 					break;
 				default:
@@ -104,7 +104,7 @@ dojo.requireLocalization("dojo.cldr", "hebrew");
 			if(pad){ s = dojo.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
@@ -115,7 +115,7 @@ dojox.date.hebrew.locale.format = function(/*hebrew.Date*/dateObject, /*object?*
 	//		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
@@ -145,10 +145,10 @@ dojox.date.hebrew.locale.format = function(/*hebrew.Date*/dateObject, /*object?*
 	var result = str.join(" "); //TODO: use locale-specific pattern to assemble date + time
 
 	return result; // String
-};	
+};
 
 dojox.date.hebrew.locale.regexp = function(/*object?*/options){
-	//	based on and similar to dojo.date.locale.regexp	
+	//	based on and similar to dojo.date.locale.regexp
 	// summary:
 	//		Builds the regular needed to parse a hebrew.Date
 
@@ -189,18 +189,18 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 		// summary: This function parse string date value according to options
 		// example:
 		// |		var dateHebrew = dojox.date.hebrew.locale.parse('11/10/5740', {datePattern:'dd/MM/yy', selector:'date'});
-		// |		in Hebrew locale string for parsing contains Hebrew Numerals     
+		// |		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  
+		// |
+		// |   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
 
@@ -212,16 +212,16 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 	
 	var match = re.exec(value);
 
-	var locale = dojo.i18n.normalizeLocale(options.locale); 
+	var locale = dojo.i18n.normalizeLocale(options.locale);
 
-	if(!match){ 
+	if(!match){
 		console.debug("dojox.date.hebrew.locale.parse: value  "+value+" doesn't match pattern   " + re);
 		return null;
 	} // null
 	
 	var date, date1;
 	
-	//var result = [1970,0,1,0,0,0,0]; // 
+	//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;
@@ -236,7 +236,7 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 					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"
@@ -251,7 +251,7 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 						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; 
+					var monthName = v;
 					v = dojo.indexOf(months, monthName);
 					if(v == -1){
 						v = dojo.indexOf(leapmonths, monthName);
@@ -263,10 +263,10 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 					mLength = l;
 				}else{
 					if(locale.match(/^he(?:-.+)?$/)){
-						v = dojox.date.hebrew.numerals.parseMonthHebrewLetters(v); 
+						v = dojox.date.hebrew.numerals.parseMonthHebrewLetters(v);
 					}else{
 						v--;
-					}						
+					}
 				}
 				result[1] = Number(v);
 				break;
@@ -311,7 +311,7 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 				break;
 			case 's': //seconds
 				result[5] = Number(v);
-				break; 
+				break;
 			case 'S': //milliseconds
 				result[6] = Number(v);
 		}
@@ -329,7 +329,7 @@ dojox.date.hebrew.locale.parse= function(/*String*/value, /*object?*/options){
 	if(mLength < 3 && result[1] >= 5 && !dateObject.isLeapYear(dateObject.getFullYear())){
 		dateObject.setMonth(result[1]+1);
 	}
-	return dateObject; // hebrew.Date 
+	return dateObject; // hebrew.Date
 };
 
 
@@ -342,9 +342,9 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 	applyLiteral = applyLiteral || identity;
 	applyAll = applyAll || identity;
 
-	//split on single quotes (which escape literals in date format strings) 
+	//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 chunks = pattern.match(/(''|[^'])+/g);
 	var literal = pattern.charAt(0) == "'";
 
 	dojo.forEach(chunks, function(chunk, i){
@@ -359,10 +359,10 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 }
 
 function _buildDateTimeRE  (tokens, bundle, options, pattern){
-		// based on and similar to dojo.date.locale._buildDateTimeRE 
+		// based on and similar to dojo.date.locale._buildDateTimeRE
 		//
 	
-	pattern = dojo.regexp.escapeString(pattern); 
+	pattern = dojo.regexp.escapeString(pattern);
 	var locale = dojo.i18n.normalizeLocale(options.locale);
 	
 	return pattern.replace(/([a-z])\1*/ig, function(match){
@@ -387,7 +387,7 @@ function _buildDateTimeRE  (tokens, bundle, options, pattern){
 						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(?:-.+)?$')){
@@ -435,7 +435,7 @@ function _buildDateTimeRE  (tokens, bundle, options, pattern){
 					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. */
@@ -491,25 +491,25 @@ dojox.date.hebrew.locale.getNames = function(/*String*/item, /*String*/type, /*S
 	// 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,
+		lookup = dojox.date.hebrew.locale._getHebrewBundle(locale),
 		props = [item, context, type];
 	if(context == 'standAlone'){
 		var key = props.join('-');
-		label = lookup(locale)[key];
+		label = lookup[key];
 		// Fall back to 'format' flavor of name
-		if(label === lookup("ROOT")[key]){ label = undefined; } // a bit of a kludge, in the absence of real aliasing support in dojo.cldr
+		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(locale)[props.join('-')]).concat();
+	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(locale)[props.join('-')];
+			result[6] = lookup[props.join('-')];
 		}else{
 			// Remove Adar I but leave an empty position in the array
 			delete result[5];
diff --git a/dojox/date/hebrew/numerals.js b/dojox/date/hebrew/numerals.js
index c7d68be..15b406d 100644
--- a/dojox/date/hebrew/numerals.js
+++ b/dojox/date/hebrew/numerals.js
@@ -39,7 +39,7 @@ dojo.provide("dojox.date.hebrew.numerals");
 	 
 	var convertNumberToStr = function(num){
 		var str  = "", n = 4, j = 9;
-  		while(num){ 
+  		while(num){
 			if(num >= n*100){
 				str += HUN.charAt(n-1);
 				num -= n*100;
@@ -56,9 +56,9 @@ dojo.provide("dojox.date.hebrew.numerals");
 			}else if(num > 0){
 				str += DIG.charAt(num-1);
 				num = 0;
-			}		
+			}
 		}
-		return str; //String	
+		return str; //String
 	};
 
 	dojox.date.hebrew.numerals.getYearHebrewLetters = function(/*Number */ year){
@@ -67,7 +67,7 @@ dojo.provide("dojox.date.hebrew.numerals");
 		// example:
 		// |		var date1 = new dojox.date.hebrew.Date();
 		// |
-		// |		document.writeln(dojox.date.hebrew.numerals.getYearHebrewLetters(date1.getFullYear());	
+		// |		document.writeln(dojox.date.hebrew.numerals.getYearHebrewLetters(date1.getFullYear());
 		
 		var rem = year % 1000;
 		//FIXME: tests include dates outside this range and seem to pass.
@@ -77,7 +77,7 @@ dojo.provide("dojox.date.hebrew.numerals");
 	
 	dojox.date.hebrew.numerals.parseYearHebrewLetters  = function(/*String hebrew year*/ year){
 		// summary: converts the year written in Hebrew numerals to an integer
-		//                   
+		//
 		// example:
 		// |		var date = new dojox.date.hebrew.Date();
 		// |        	date.setFullYear(dojox.date.hebrew.numerals.parseYearHebrewLetters('\u05ea\u05e9\u05e1\u05f4\u05d7'));
@@ -115,7 +115,7 @@ dojo.provide("dojox.date.hebrew.numerals");
 		// |		document.writeln(dojox.date.hebrew.numerals.getMonthHebrewLetters(date1.getMonth());
 
 		return transformChars(convertNumberToStr(month+1)); // String
-	};	
+	};
 
 	dojox.date.hebrew.numerals.parseMonthHebrewLetters = function(/*String*/monthStr){
 		// summary: converts a Hebrew numeral string representing
@@ -132,7 +132,7 @@ dojo.provide("dojox.date.hebrew.numerals");
 		var monnum = dojox.date.hebrew.numerals.parseDayHebrewLetters(monthStr) - 1;
 
 		if(monnum == -1 || monnum > 12){
-			throw new Error("The month name is incorrect , month = " + monnum); 
+			throw new Error("The month name is incorrect , month = " + monnum);
 		}
 		return monnum;
 	};
diff --git a/dojox/date/islamic.js b/dojox/date/islamic.js
index 0bd51d9..3e4ff9a 100644
--- a/dojox/date/islamic.js
+++ b/dojox/date/islamic.js
@@ -67,9 +67,9 @@ dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/int
 					remdays = (amount > 0) ?  -1 : 1;
 				}else if(day == 6){ //shabat
 					day = 4;
-					remdays = (amount > 0) ? -2 : 2;		
+					remdays = (amount > 0) ? -2 : 2;
 				}
-				var add = (amount > 0) ? (5 - day - 1) : -day 
+				var add = (amount > 0) ? (5 - day - 1) : -day
 				var amountdif = amount - add;
 				var div = parseInt(amountdif / 5);
 				if(amountdif % 5 != 0){
@@ -87,25 +87,25 @@ dojox.date.islamic.add = function(/*dojox.date.islamic.Date*/date, /*String*/int
 			newIslamDate.setDate(date.getDate() + amount);
 			break;
 		case "month":
-			var month = date.getMonth(); 
+			var month = date.getMonth();
 			newIslamDate.setMonth(month + amount);
 			break;
 		case "hour":
 			newIslamDate.setHours(date.getHours() + amount);
-			break;	
+			break;
 		case "minute":
 			newIslamDate.setMinutes(date.getMinutes() + amount);
-			break;	
+			break;
 		case "second":
 			newIslamDate.setSeconds(date.getSeconds() + amount);
-			break;	
+			break;
 		case "millisecond":
 			newIslamDate.setMilliseconds(date.getMilliseconds() + amount);
 			break;
 	}
 
 	return newIslamDate; // dojox.date.islamic.Date
-}; 
+};
 
 dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*dojox.date.islamic.Date?*/date2, /*String?*/interval){
 	//	based on and similar to dojo.date.difference
@@ -214,7 +214,7 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 				var i = enddate.getFullYear()+1;
 				var e = startdate.getFullYear();
 				for (i;   i < e;  i++){
-					delta += 12; 
+					delta += 12;
 				}
 			}
 			if (date1.toGregorian() < date2.toGregorian()){
@@ -243,5 +243,5 @@ dojox.date.islamic.difference = function(/*dojox.date.islamic.Date*/date1, /*doj
 	}
 
 	// Round for fractional values and DST leaps
-	return Math.round(delta); // Number (integer) 
+	return Math.round(delta); // Number (integer)
 };
diff --git a/dojox/date/islamic/Date.js b/dojox/date/islamic/Date.js
index 58bdd5f..9395197 100644
--- a/dojox/date/islamic/Date.js
+++ b/dojox/date/islamic/Date.js
@@ -10,8 +10,8 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	//	This module is similar to the Date() object provided by JavaScript
 	//
 	// example:
-	// |	dojo.require("dojox.date.islamic.Date"); 
-	// |		
+	// |	dojo.require("dojox.date.islamic.Date");
+	// |
 	// |	var date = new dojox.date.islamic.Date();
 	// |	document.writeln(date.getFullYear()+'\'+date.getMonth()+'\'+date.getDate());
 
@@ -57,13 +57,13 @@ dojo.declare("dojox.date.islamic.Date", null, {
 				this._date = new Date(""); //TODO: should this be NaN?  _date is not a Date object
 			}else{  // this is Islamic.Date object
 				this._year = arg0._year;
-				this._month =  arg0._month;  
+				this._month =  arg0._month;
 				this._date = arg0._date;
 				this._hours = arg0._hours;
 				this._minutes = arg0._minutes;
 				this._seconds = arg0._seconds;
-				this._milliseconds = arg0._milliseconds; 
-			}	
+				this._milliseconds = arg0._milliseconds;
+			}
 		}else if(len >=3){
 			// YYYY MM DD arguments passed, month is from 0-12
 			this._year += arguments[0];
@@ -82,7 +82,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		// example:
 		// |		var date1 = new dojox.date.islamic.Date();
 		// |
-		// |		document.writeln(date1.getDate);		
+		// |		document.writeln(date1.getDate);
 		return this._date;
 	},
 	
@@ -98,7 +98,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 
 	getFullYear:function(){
-		// summary: This function return the Year value 
+		// summary: This function return the Year value
 		//
 		// example:
 		// |		var date1 = new dojox.date.islamic.Date();
@@ -139,7 +139,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		return this._milliseconds;
 	},
 
-	setDate: function(/*number*/date){	
+	setDate: function(/*number*/date){
 		// summary: This function sets the Date
 		// example:
 		// |		var date1 = new dojox.date.islamic.Date();
@@ -152,8 +152,8 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		}else{
 			var mdays;
 			if(date>0){
-				for(mdays = this.getDaysInIslamicMonth(this._month, this._year);	
-					date > mdays; 
+				for(mdays = this.getDaysInIslamicMonth(this._month, this._year);
+					date > mdays;
 						date -= mdays,mdays =this.getDaysInIslamicMonth(this._month, this._year)){
 					this._month++;
 					if(this._month >= 12){this._year++; this._month -= 12;}
@@ -161,8 +161,8 @@ dojo.declare("dojox.date.islamic.Date", null, {
 
 				this._date = date;
 			}else{
-				for(mdays = this.getDaysInIslamicMonth((this._month-1)>=0 ?(this._month-1) :11 ,((this._month-1)>=0)? this._year: this._year-1);	
-						date <= 0; 
+				for(mdays = this.getDaysInIslamicMonth((this._month-1)>=0 ?(this._month-1) :11 ,((this._month-1)>=0)? this._year: this._year-1);
+						date <= 0;
 							mdays = this.getDaysInIslamicMonth((this._month-1)>=0 ? (this._month-1) :11,((this._month-1)>=0)? this._year: this._year-1)){
 					this._month--;
 					if(this._month < 0){this._year--; this._month += 12;}
@@ -238,7 +238,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 
 		while(minutes >= 60){
 			this._hours++;
-			if(this._hours >= 24){		 
+			if(this._hours >= 24){
 				this._date++;
 				this._hours -= 24;
 				var mdays = this.getDaysInIslamicMonth(this._month, this._year);
@@ -261,7 +261,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 			if(this._minutes >= 60){
 				this._hours++;
 				this._minutes -= 60;
-				if(this._hours >= 24){		 
+				if(this._hours >= 24){
 					this._date++;
 					this._hours -= 24;
 					var mdays = this.getDaysInIslamicMonth(this._month, this._year);
@@ -287,7 +287,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 				if(this._minutes >= 60){
 					this._hours++;
 					this._minutes -= 60;
-					if(this._hours >= 24){		 
+					if(this._hours >= 24){
 						this._date++;
 						this._hours -= 24;
 						var mdays = this.getDaysInIslamicMonth(this._month, this._year);
@@ -305,7 +305,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 		
 		
-	toString:function(){ 
+	toString:function(){
 		// summary: This returns a string representation of the date in "DDDD MMMM DD YYYY HH:MM:SS" format
 		// example:
 		// |		var date1 = new dojox.date.islamic.Date();
@@ -330,7 +330,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 		var hYear = this._year;
 		var hMonth = this._month;
 		var hDate = this._date;
-		var julianDay = hDate + Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 
+		var julianDay = hDate + Math.ceil(29.5 * hMonth) + (hYear - 1) * 354
 						+ Math.floor((3 + (11 * hYear)) / 30) + this._ISLAMIC_EPOCH - 1;
 
 		var wjd = Math.floor(julianDay - 0.5) + 0.5,
@@ -347,21 +347,21 @@ dojo.declare("dojox.date.islamic.Date", null, {
 			year++;
 		}
 		
-		var gYearStart = this._GREGORIAN_EPOCH + (365 * (year - 1)) + Math.floor((year - 1) / 4) 
+		var gYearStart = this._GREGORIAN_EPOCH + (365 * (year - 1)) + Math.floor((year - 1) / 4)
 						- ( Math.floor((year - 1) / 100)) + Math.floor((year - 1) / 400);
 						
 		var yearday = wjd - gYearStart;
 		
-		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) 
+		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);
 			
 		var leapadj = ((wjd < tjd ) ? 0 : (dojo.date.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) 
+		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);
 					
 		var day = (wjd - tjd2) + 1;
@@ -388,8 +388,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) 
-					+(Math.floor(date.getSeconds() + 60 * (date.getMinutes() + 60 * date.getHours()) + 0.5) / 86400.0);
+					+ (((gMonth+1) <= 2) ? 0 : (dojo.date.isLeapYear(date) ? -1 : -2)) + gDay);
 		julianDay = Math.floor(julianDay) + 0.5;
 
 		var days = julianDay - this._ISLAMIC_EPOCH;
@@ -410,7 +409,7 @@ dojo.declare("dojox.date.islamic.Date", null, {
 	},
 	
 	valueOf:function(){
-		// summary: This function returns The stored time value in milliseconds 
+		// summary: This function returns The stored time value in milliseconds
 		// since midnight, January 1, 1970 UTC
 
 		return this.toGregorian().valueOf();
diff --git a/dojox/date/islamic/locale.js b/dojox/date/islamic/locale.js
index 7d2e578..a2ff470 100644
--- a/dojox/date/islamic/locale.js
+++ b/dojox/date/islamic/locale.js
@@ -105,7 +105,7 @@ dojo.requireLocalization("dojo.cldr", "islamic");
 			if(pad){ s = dojo.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){
@@ -134,10 +134,10 @@ dojox.date.islamic.locale.format = function(/*islamic.Date*/dateObject, /*Object
 	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	
+	//	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
@@ -173,7 +173,7 @@ dojox.date.islamic.locale._parseInfo = function(/*oblect?*/options){
 
 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	
+	// summary: This function parse string date value according to options
 	
 	value =  value.replace(/[\u200E\u200F\u202A\u202E]/g, ""); //remove bidi non-printing chars
 
@@ -186,9 +186,9 @@ dojox.date.islamic.locale.parse= function(/*String*/value, /*Object?*/options){
 
 	var match = re.exec(value);
 
-	var locale = dojo.i18n.normalizeLocale(options.locale); 
+	var locale = dojo.i18n.normalizeLocale(options.locale);
 
-	if(!match){ 
+	if(!match){
 		console.debug("dojox.date.islamic.locale.parse: value  "+value+" doesn't match pattern   " + re);
 		return null;
 	} // null
@@ -222,7 +222,7 @@ dojox.date.islamic.locale.parse= function(/*String*/value, /*Object?*/options){
 					}
 					mLength = l;
 				}else{
-					v--;				
+					v--;
 				}
 				result[1] = Number(v);
 				break;
@@ -263,7 +263,7 @@ dojox.date.islamic.locale.parse= function(/*String*/value, /*Object?*/options){
 				break;
 			case 's': //seconds
 				result[5] = Number(v);
-				break; 
+				break;
 			case 'S': //milliseconds
 				result[6] = Number(v);
 		}
@@ -290,9 +290,9 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 	applyLiteral = applyLiteral || identity;
 	applyAll = applyAll || identity;
 
-	//split on single quotes (which escape literals in date format strings) 
+	//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 chunks = pattern.match(/(''|[^'])+/g);
 	var literal = pattern.charAt(0) == "'";
 
 	dojo.forEach(chunks, function(chunk, i){
@@ -307,10 +307,10 @@ function _processPattern(pattern, applyPattern, applyLiteral, applyAll){
 }
 
 function _buildDateTimeRE  (tokens, bundle, options, pattern){
-		// based on and similar to dojo.date.locale._buildDateTimeRE 
+		// based on and similar to dojo.date.locale._buildDateTimeRE
 		//
 	
-	pattern = dojo.regexp.escapeString(pattern); 
+	pattern = dojo.regexp.escapeString(pattern);
 	var locale = dojo.i18n.normalizeLocale(options.locale);
 	
 	return pattern.replace(/([a-z])\1*/ig, function(match){
@@ -371,7 +371,7 @@ function _buildDateTimeRE  (tokens, bundle, options, pattern){
 					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. */
@@ -405,18 +405,18 @@ dojox.date.islamic.locale.getNames = function(/*String*/item, /*String*/type, /*
 	// summary:
 	//		Used to get localized strings from dojo.cldr for day or month names.
 	var label;
-	var lookup = dojox.date.islamic.locale._getIslamicBundle;
+	var lookup = dojox.date.islamic.locale._getIslamicBundle(locale);
 	var props = [item, context, type];
 	if(context == 'standAlone'){
 		var key = props.join('-');
-		label = lookup(locale)[key];
+		label = lookup[key];
 		// Fall back to 'format' flavor of name
-		if(label === lookup("ROOT")[key]){ label = undefined; } // a bit of a kludge, in the absense of real aliasing support in dojo.cldr
+		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(locale)[props.join('-')]).concat(); /*Array*/
+	return (label || lookup[props.join('-')]).concat(); /*Array*/
 };
 
 
diff --git a/dojox/date/php.js b/dojox/date/php.js
index 6f0090f..ac6511c 100644
--- a/dojox/date/php.js
+++ b/dojox/date/php.js
@@ -5,7 +5,7 @@ dojo.require("dojox.string.tokenize");
 dojox.date.php.format = function(/*Date*/ date, /*String*/ format){
 	// summary: Get a formatted string for a given date object
 	var df = new dojox.date.php.DateFormat(format);
-	return df.format(date);	
+	return df.format(date);
 }
 
 dojox.date.php.DateFormat = function(/*String*/ format){
diff --git a/dojox/date/posix.js b/dojox/date/posix.js
index 17c9dbf..892acb4 100644
--- a/dojox/date/posix.js
+++ b/dojox/date/posix.js
@@ -57,7 +57,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 			case "f": // month as a decimal number, a single digit is
 							// preceded by a space (range ' 1' to '12')
 				if(padChar == null){ padChar = " "; }
-				return _(dateObject.getMonth()+1);				
+				return _(dateObject.getMonth()+1);
 			
 			case "g": // like %G, but without the century.
 				break;
@@ -132,8 +132,8 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 
 			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
-				      // 1 January has four or more days in the new year, then it 
-				      // is considered week 1. Otherwise, it is the last week of 
+				      // 1 January has four or more days in the new year, then it
+				      // is considered week 1. Otherwise, it is the last week of
 				      // the previous year, and the next week is week 1.
 				return _(dojox.date.posix.getIsoWeekOfYear(dateObject));
 				
@@ -162,7 +162,7 @@ dojox.date.posix.strftime = function(/*Date*/dateObject, /*String*/format, /*Str
 			
 			case "z": // time zone or name or abbreviation
 				var timezoneOffset = dateObject.getTimezoneOffset();
-				return (timezoneOffset > 0 ? "-" : "+") + 
+				return (timezoneOffset > 0 ? "-" : "+") +
 					_(Math.floor(Math.abs(timezoneOffset)/60)) + ":" +
 					_(Math.abs(timezoneOffset)%60);
 
@@ -278,9 +278,9 @@ dojox.date.posix.getIsoWeekOfYear = function(/*Date*/dateObject){
 }
 
 dojox.date.posix.getIsoWeeksInYear = function(/*Date*/dateObject) {
-	// summary: Determine the number of ISO8601 weeks in the year of the given 
+	// summary: Determine the number of ISO8601 weeks in the year of the given
 	//   date. Most years have 52 but some have 53.
-	//   See http://www.phys.uu.nl/~vgent/calendar/isocalendar_text3.htm	
+	//   See http://www.phys.uu.nl/~vgent/calendar/isocalendar_text3.htm
 	function p(y) {
 		return y + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400);
 	}
diff --git a/dojox/date/relative.js b/dojox/date/relative.js
index 1e3942b..26cdbe9 100644
--- a/dojox/date/relative.js
+++ b/dojox/date/relative.js
@@ -75,7 +75,7 @@ dojox.date.relative.format = function(/*Date*/dateObject, /*dojox.date.relative.
 		return fmt(dateObject, del(fmtOpts, {selector: "time"}));
 	}else if(diff <= SIX_DAYS && diff > 0 && options.weekCheck !== false){
 		// within the last week: Mon 9:32 am
-		return fmt(dateObject, del(fmtOpts, {selector: "date", datePattern: "EEE"})) + 
+		return fmt(dateObject, del(fmtOpts, {selector: "date", datePattern: "EEE"})) +
 				" " +
 				fmt(dateObject, del(fmtOpts, {selector: "time", formatLength: "short"}));
 	}else if(dateObject.getFullYear() == today.getFullYear()){
diff --git a/dojox/date/tests/buddhist/Date.js b/dojox/date/tests/buddhist/Date.js
index ac5a50f..c23e349 100644
--- a/dojox/date/tests/buddhist/Date.js
+++ b/dojox/date/tests/buddhist/Date.js
@@ -3,10 +3,10 @@ dojo.require("dojox.date.buddhist");
 dojo.require("dojox.date.buddhist.Date");
 dojo.require("dojox.date.buddhist.locale");
 
-dojo.requireLocalization("dojo.cldr", "greg"); 
+dojo.requireLocalization("dojo.cldr", "greg");
 dojo.requireLocalization("dojo.cldr", "buddhist");
 
-tests.register("dojox.date.tests.buddhist.Date", 
+tests.register("dojox.date.tests.buddhist.Date",
 	[
 		{
 			// see tests for dojo.date.locale for setup info
@@ -28,7 +28,7 @@ tests.register("dojox.date.tests.buddhist.Date",
 				delete dojo.cldr.nls.greg;
 				delete dojo.cldr.nls.buddhist;
 			}
-		},	
+		},
 		{
 			name: "toGregorian",
 			runTest: function(t){
@@ -36,25 +36,25 @@ tests.register("dojox.date.tests.buddhist.Date",
 				var dateGregorian = dateBuddhist.toGregorian();
 				t.is(0, dojo.date.compare(new Date(2008, 11, 19), dateGregorian, "date"));//Date month 0-11
 				
-				dateBuddhist = new dojox.date.buddhist.Date(2548, 3, 18); 
+				dateBuddhist = new dojox.date.buddhist.Date(2548, 3, 18);
 				dateGregorian = dateBuddhist.toGregorian();
 				t.is(0, dojo.date.compare(new Date(2005, 3, 18), dateGregorian, "date"));
 				
-				dateBuddhist = new dojox.date.buddhist.Date(2550, 7, 10); 
+				dateBuddhist = new dojox.date.buddhist.Date(2550, 7, 10);
 				dateGregorian = dateBuddhist.toGregorian();
 				t.is(0, dojo.date.compare(new Date(2007, 7, 10), dateGregorian, "date"));
 				
-				dateBuddhist = new dojox.date.buddhist.Date(2552, 4, 20); 
+				dateBuddhist = new dojox.date.buddhist.Date(2552, 4, 20);
 				dateGregorian = dateBuddhist.toGregorian();
 				t.is(0, dojo.date.compare(new Date(2009, 4, 20), dateGregorian, "date"));
 				
-				dateBuddhist = new dojox.date.buddhist.Date(2553, 6, 31); 
+				dateBuddhist = new dojox.date.buddhist.Date(2553, 6, 31);
 				dateGregorian = dateBuddhist.toGregorian();
 				t.is(0, dojo.date.compare(new Date(2010, 6, 31), dateGregorian, "date"));
 				
-				dateBuddhist = new dojox.date.buddhist.Date(2554, 9, 1); 
+				dateBuddhist = new dojox.date.buddhist.Date(2554, 9, 1);
 				dateGregorian = dateBuddhist.toGregorian();
-				t.is(0, dojo.date.compare(new Date(2011, 9, 1), dateGregorian, "date"));				
+				t.is(0, dojo.date.compare(new Date(2011, 9, 1), dateGregorian, "date"));
 			}
 		},
 		{
@@ -75,19 +75,19 @@ tests.register("dojox.date.tests.buddhist.Date",
 				
 				dateGregorian = new Date(2007, 7, 10);
 				dateBuddhistFromGreg = new dojox.date.buddhist.Date(dateGregorian);
-				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2550, 7, 10), dateBuddhistFromGreg, "date"));					
+				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2550, 7, 10), dateBuddhistFromGreg, "date"));
 				
 				dateGregorian = new Date(2009, 4, 20);
 				dateBuddhistFromGreg = new dojox.date.buddhist.Date(dateGregorian);
-				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2552, 4, 20), dateBuddhistFromGreg, "date"));				
+				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2552, 4, 20), dateBuddhistFromGreg, "date"));
 				
 				dateGregorian = new Date(2010, 6, 31);
 				dateBuddhistFromGreg = new dojox.date.buddhist.Date(dateGregorian);
-				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2553, 6, 31), dateBuddhistFromGreg, "date"));	
+				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2553, 6, 31), dateBuddhistFromGreg, "date"));
 				
 				dateGregorian = new Date(2011, 9, 1);
 				dateBuddhistFromGreg = new dojox.date.buddhist.Date(dateGregorian);
-				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2554, 9, 1), dateBuddhistFromGreg, "date"));					
+				t.is(0, dojox.date.buddhist.compare(new dojox.date.buddhist.Date(2554, 9, 1), dateBuddhistFromGreg, "date"));
 			}
 		},
 		{
@@ -97,8 +97,8 @@ tests.register("dojox.date.tests.buddhist.Date",
 				var dateBuddhist1 = new dojox.date.buddhist.Date(2550,  10,  25);
 				t.is(1, dojo.date.compare(dateBuddhist.toGregorian(), dateBuddhist1.toGregorian()));
 				t.is(-1, dojo.date.compare(dateBuddhist1.toGregorian(), dateBuddhist.toGregorian()));
-			}	
-		},		
+			}
+		},
 		{
 			name: "add_and_difference",
 			runTest: function(t){
@@ -119,23 +119,23 @@ tests.register("dojox.date.tests.buddhist.Date",
 				t.is(0,  12 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "week", 12), dateBuddhistLeap,"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(dateBuddhistAdd3, dateBuddhist, "weekday"));
 				t.is(0,  20 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "weekday", 20), dateBuddhistLeap,"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(dateBuddhistAdd4, dateBuddhist, "day"));
 				t.is(0, -50 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "day", -50), dateBuddhistLeap,"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(dateBuddhistAdd5, dateBuddhist, "hour"));
 				t.is(0, 200 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "hour", 200), dateBuddhistLeap,"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(dateBuddhistAdd6, dateBuddhist, "minute"));
+				t.is(0, -200 - dojox.date.buddhist.difference(dojox.date.buddhist.add(dateBuddhistLeap, "minute", -200), dateBuddhistLeap,"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(dateBuddhistDiff, dateBuddhist));
 			}
 		},
 		{
@@ -166,9 +166,9 @@ tests.register("dojox.date.tests.buddhist.Date",
 				 str= dojox.date.buddhist.locale.format(dateBuddhist, options);
 				 dateBuddhist1 = dojox.date.buddhist.locale.parse(str, options);
 				gregDate = dojo.date.locale.parse(str, options);
-				t.is(0, dojo.date.compare(gregDate, dateBuddhist1.toGregorian(), 'time'));	
+				t.is(0, dojo.date.compare(gregDate, dateBuddhist1.toGregorian(), 'time'));
 								 	
-			}		
-		}	
+			}
+		}
 	]
 );
diff --git a/dojox/date/tests/hebrew/Date.js b/dojox/date/tests/hebrew/Date.js
index 8551e2e..798279c 100644
--- a/dojox/date/tests/hebrew/Date.js
+++ b/dojox/date/tests/hebrew/Date.js
@@ -3,10 +3,10 @@ dojo.require("dojox.date.hebrew");
 dojo.require("dojox.date.hebrew.Date");
 dojo.require("dojox.date.hebrew.locale");
 
-dojo.requireLocalization("dojo.cldr", "gregorian"); 
+dojo.requireLocalization("dojo.cldr", "gregorian");
 dojo.requireLocalization("dojo.cldr", "hebrew");
 
-tests.register("dojox.date.tests.hebrew.Date", 
+tests.register("dojox.date.tests.hebrew.Date",
 	[
 		{
 			// see tests for dojo.date.locale for setup info
@@ -36,14 +36,14 @@ tests.register("dojox.date.tests.hebrew.Date",
 				var dateHebrew1 = new dojox.date.hebrew.Date(5758,  10,  25);
 				t.is(1, dojo.date.compare(dateHebrew.toGregorian(), dateHebrew1.toGregorian()));
 				t.is(-1, dojo.date.compare(dateHebrew1.toGregorian(), dateHebrew.toGregorian()));
-			}	
-		},	
+			}
+		},
 		{
 			name: "toGregorian_fromGregorian",
 			runTest: function(t){
 			
 			//Hebrew month names
-			var TISHRI = 0 , HESHVAN = 1, KISLEV = 2, TEVET = 3, SHVAT = 4 , ADARI = 5, ADAR = 6, NISAN= 7 , IYAR= 8 , SIVAN= 9 , TAMMUZ = 10, AV = 11 , ELUL = 12;   	
+			var TISHRI = 0 , HESHVAN = 1, KISLEV = 2, TEVET = 3, SHVAT = 4 , ADARI = 5, ADAR = 6, NISAN= 7 , IYAR= 8 , SIVAN= 9 , TAMMUZ = 10, AV = 11 , ELUL = 12;
 				//hebrew.Date month names
 				//Gregorian Date month 1-12 -  for readability
 				var dateTable = [
@@ -60,14 +60,14 @@ tests.register("dojox.date.tests.hebrew.Date",
 					[1943, 5, 19, 5703, IYAR, 14],
 					[1943, 11, 6, 5704, HESHVAN, 8],
 					[1992, 4, 15, 5752, NISAN, 12],
-					[1996, 3, 25, 5756, NISAN, 5],					
+					[1996, 3, 25, 5756, NISAN, 5],
 					[2005, 4, 18, 5765, NISAN, 9],
-					[2007, 7, 12, 5767, TAMMUZ, 26],					
+					[2007, 7, 12, 5767, TAMMUZ, 26],
 					[2007, 10, 13, 5768, HESHVAN, 1],
 					[2007, 11, 11, 5768, KISLEV, 1],
 					[2007, 12, 10, 5768, TEVET, 1],
 					[2008, 1, 8, 5768, SHVAT, 1],
-					[2008, 2, 7, 5768, ADARI, 1], 
+					[2008, 2, 7, 5768, ADARI, 1],
 					[2008, 3, 8, 5768, ADAR, 1],
 					[2008, 4, 6, 5768, NISAN, 1],
 					[2008, 5, 6, 5768, IYAR, 1],
@@ -78,7 +78,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 					[2008, 9, 5, 5768, ELUL, 5],
 					[2008, 8, 5, 5768, AV, 4],
 					[2008, 9, 11, 5768, ELUL, 11],
-					[2008, 12, 19,  5769, KISLEV, 22],							
+					[2008, 12, 19,  5769, KISLEV, 22],
 					[2009, 1, 26, 5769, SHVAT, 1],
 					[2009, 2, 25, 5769, ADARI, 1], //incorrect, not leap year , the month is set to ADAR
 					[2009, 2, 25, 5769, ADAR, 1],
@@ -87,23 +87,23 @@ tests.register("dojox.date.tests.hebrew.Date",
 					[2009, 7, 22, 5769, AV, 1],
 					[2009, 8, 21, 5769, ELUL, 1],
 					[2010, 7, 2, 5770,  TAMMUZ, 20],
-					[2011, 10, 1, 5772, TISHRI, 3],	
+					[2011, 10, 1, 5772, TISHRI, 3],
 					[2038, 12, 9, 5799, KISLEV, 12],
-					[2094, 8, 17, 5854, ELUL, 5]													
+					[2094, 8, 17, 5854, ELUL, 5]
 				];
 
 					
 
-				var dateHebrew, dateGregorian; 
+				var dateHebrew, dateGregorian;
 				//toGregorian
-				dojo.forEach(dateTable, function(d, i){	
-					dateHebrew = new dojox.date.hebrew.Date(d[3], d[4], d[5]); 
+				dojo.forEach(dateTable, function(d, i){
+					dateHebrew = new dojox.date.hebrew.Date(d[3], d[4], d[5]);
 					dateGregorian = dateHebrew.toGregorian();
 					t.is(0, dojo.date.compare(new Date(d[0], d[1]-1, d[2]), dateGregorian, "date"));
 				});
 				
 				//fromGregorian
-				dojo.forEach(dateTable, function(d, i){	
+				dojo.forEach(dateTable, function(d, i){
 					dateGregorian = new  Date(d[0], d[1]-1, d[2]);
 					dateHebrew = new dojox.date.hebrew.Date(dateGregorian);
 					testHebrew = new dojox.date.hebrew.Date(d[3], d[4], d[5]);
@@ -115,15 +115,15 @@ tests.register("dojox.date.tests.hebrew.Date",
 			name: "getDay",
 			runTest: function(t){
 				 var dateTable = [
-					[5769, 0, 11, 5], 
+					[5769, 0, 11, 5],
 					[5769, 1, 3, 6],
 					[5769, 2, 10, 0],
-					[5769, 3, 23, 1], 
-					[5769, 6, 21, 2], 
+					[5769, 3, 23, 1],
+					[5769, 6, 21, 2],
 					[5769, 6, 22, 3],
 					[5769, 7, 15, 4]
 				];
-					dojo.forEach(dateTable, function(d, i){	
+					dojo.forEach(dateTable, function(d, i){
 					var date = new  dojox.date.hebrew.Date(d[0], d[1], d[2]);
 					t.is(d[3], 	date.getDay());
 				});
@@ -143,20 +143,20 @@ tests.register("dojox.date.tests.hebrew.Date",
 					[5769, 2, 30] //KISLEV,
 				];
 				
-				dojo.forEach(dateTable, function(d, i){	
+				dojo.forEach(dateTable, function(d, i){
 					var date = new  dojox.date.hebrew.Date(d[0], d[1], 1);
 					t.is(d[2], 	dojox.date.hebrew.getDaysInMonth(date));
 				});
-			}	
+			}
 		},
-		{	
+		{
 			name: "add_difference",
 			runTest: function(t){
 		//	5766, 5767, 5769, 5770, 5772, 5772, 5773, 5775 - non leap
 		//      5765, 5768, 5771, 5774 - leap
 		
 		//Hebrew month names
-				var TISHRI = 0 , HESHVAN = 1, KISLEV = 2, TEVET = 3, SHVAT = 4 , ADARI = 5, ADAR = 6, NISAN= 7 , IYAR= 8 , SIVAN= 9 , TAMMUZ = 10, AV = 11 , ELUL = 12;   	
+				var TISHRI = 0 , HESHVAN = 1, KISLEV = 2, TEVET = 3, SHVAT = 4 , ADARI = 5, ADAR = 6, NISAN= 7 , IYAR= 8 , SIVAN= 9 , TAMMUZ = 10, AV = 11 , ELUL = 12;
 				var start = [
 						[5767, TAMMUZ, 5769, SIVAN],
 						[5767, TAMMUZ, 5772, IYAR],
@@ -186,7 +186,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 						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"));
-					});	
+					});
 					
 					//different fields
 					var fields =  [
@@ -194,17 +194,17 @@ tests.register("dojox.date.tests.hebrew.Date",
 								[   5758, KISLEV,   30,      "year",   -1,     5757, KISLEV,   29 ],
 								[   5769, NISAN,   30,      "year",   -1,     5768, NISAN,  30 ],
 								[   5768, ADARI,  30,      "year",   1,     5769, ADAR,  29 ],
-								[   5757, TISHRI,   30,     "month",   1,     5757, HESHVAN,  29 ],								
-								[   5762, AV,       30,      "day",    1,     5762, ELUL,  1 ],   
-								[   5762, ELUL,      1,     "day",   -1,     5762, AV, 30 ],  
+								[   5757, TISHRI,   30,     "month",   1,     5757, HESHVAN,  29 ],
+								[   5762, AV,       30,      "day",    1,     5762, ELUL,  1 ],
+								[   5762, ELUL,      1,     "day",   -1,     5762, AV, 30 ],
 								[   5769,  TAMMUZ,  27,  "day",  10,  5769, AV, 8],
 								[   5757, KISLEV,    1,    "day",   30,     5757, TEVET,    2 ],   // 29-day month
-								[   5758, KISLEV,    1,     "day",   31,     5758, TEVET,    2 ],   // 30-day month								
+								[   5758, KISLEV,    1,     "day",   31,     5758, TEVET,    2 ],   // 30-day month
 								[   5769,  AV,   27,  "day",  10,  5769, ELUL, 7],
 								[   5769,  ELUL,   27,  "day",  10,  5770, TISHRI, 8],
 							        [   5769,  TAMMUZ,  27,  "day",  -30, 5769, SIVAN, 27],
-								[   5769,  AV,   1,  "day",  -60,  5769,	IYAR, 29],	
-								[   5769,  SHVAT, 	30, "day", 1, 	5769, ADAR, 1],															
+								[   5769,  AV,   1,  "day",  -60,  5769,	IYAR, 29],
+								[   5769,  SHVAT, 	30, "day", 1, 	5769, ADAR, 1],
 								[   5769,  TAMMUZ,  27,  "weekday", 10,  5769, AV, 12],
 								[   5769,  KISLEV,   1,  "weekday", 1, 5769, KISLEV, 3],
 								[   5769,  NISAN,  1,  "weekday",  -5,  5769, ADAR, 23],
@@ -215,15 +215,15 @@ tests.register("dojox.date.tests.hebrew.Date",
 								[   5769,  AV,   11,  "weekday", 6, 5769, AV, 19],
 								[   5769,  AV,   10,  "weekday", 6, 5769, AV, 19],
 								[   5769,  AV,   11,  "weekday", 12, 5769, AV, 27],
-								[   5769,  AV,   10,  "weekday", 12, 5769, AV, 27],	
-								[   5769,  AV,  9,  "weekday", 12, 5769, AV, 27],								
-								[   5769,  NISAN, 	29, "week", 1, 5769, IYAR, 6],	
-								[   5771,  NISAN, 	1, "week", -4, 5771, ADAR, 2],	
-								[   5771,  NISAN, 	1, "week", -8, 5771, ADARI, 4],	
-								[   5769,  AV, 	17, "week", 2, 5769, ELUL, 1],	
+								[   5769,  AV,   10,  "weekday", 12, 5769, AV, 27],
+								[   5769,  AV,  9,  "weekday", 12, 5769, AV, 27],
+								[   5769,  NISAN, 	29, "week", 1, 5769, IYAR, 6],
+								[   5771,  NISAN, 	1, "week", -4, 5771, ADAR, 2],
+								[   5771,  NISAN, 	1, "week", -8, 5771, ADARI, 4],
+								[   5769,  AV, 	17, "week", 2, 5769, ELUL, 1],
 								[   5769,  AV, 	18, "week", -1, 5769, AV, 11]						];
 						
-					//test add	
+					//test add
 					dojo.forEach( fields, function(f, i){
 						dateHebStart =  new dojox.date.hebrew.Date( f[0], f[1], f[2]);
 						dateHebEnd = dojox.date.hebrew.add(dateHebStart, f[3], f[4]);
@@ -249,14 +249,14 @@ tests.register("dojox.date.tests.hebrew.Date",
 					t.assertFalse(dateHebStart.getMonth() == dateHebAdd.getMonth());
 				
 				}
-		},	
+		},
 		{
 			name: "consistency_of_add_and_difference",
 			runTest: function(t){
 				var dateHebrew = new dojox.date.hebrew.Date(5769, 4, 16);
 				var dateHebrewLeap = new dojox.date.hebrew.Date(5768, 5, 16);
 				
-			//	var m =  ["TISHRI " , "HESHVAN", "KISLEV", "TEVET", "SHVAT" , "ADARI", "ADAR", "NISAN" , "IYAR" , "SIVAN" , "TAMMUZ", "AV" , "ELUL"];   	
+			//	var m =  ["TISHRI " , "HESHVAN", "KISLEV", "TEVET", "SHVAT" , "ADARI", "ADAR", "NISAN" , "IYAR" , "SIVAN" , "TAMMUZ", "AV" , "ELUL"];
 				
 				var amouts = [2, 5, 6, 7, 8,12, 18,20, 24, 50, -3, -4,  -5, -6, -7, -8, -9, -10, -50, 200, -200];
 				var dateHebrewAdd, dateHebrewAddLeap;
@@ -276,28 +276,28 @@ tests.register("dojox.date.tests.hebrew.Date",
 					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "week", amount), dateHebrewLeap,"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(dateHebrewAdd, dateHebrew, "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"));
 					
 					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(dateHebrewAdd, dateHebrew, "day"));
 					t.is(amount, dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "day", amount), dateHebrewLeap,"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(dateHebrewAdd, dateHebrew, "hour"));
 					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "hour", amount), dateHebrewLeap,"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(dateHebrewAdd, dateHebrew, "minute"));
 					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "minute", amount), dateHebrewLeap,"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(dateHebrewAdd, dateHebrew, "second"));
 					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "second", amount), dateHebrewLeap,"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(dateHebrewAdd, dateHebrew, "millisecond"));
 					t.is(amount,  dojox.date.hebrew.difference(dojox.date.hebrew.add(dateHebrewLeap, "millisecond", amount), dateHebrewLeap,"millisecond"));
 				 });
 				 
@@ -309,7 +309,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 			name: "getMonth_setMonth",
 			runTest: function(t){
 			var nonLeap = "5766, 5767, 5769, 5770, 5772, 5772, 5773, 5775";
-		        var leap = "5765, 5768, 5771, 5774";	
+		        var leap = "5765, 5768, 5771, 5774";
 		// ELUL - 12,  ADAR -6, ADARI -5
 				var dateHebrew = new dojox.date.hebrew.Date(5765, 1, 1);
 				for (var year = 5766; year < 5866; year++){
@@ -321,14 +321,14 @@ tests.register("dojox.date.tests.hebrew.Date",
 					t.is(6,dateHebrew.getMonth());
 					if (leap.match(year)){
 						dateHebrew.setMonth(5);
-						t.is(5,dateHebrew.getMonth());						
+						t.is(5,dateHebrew.getMonth());
 					}
 					if (nonLeap.match(year)){
 						dateHebrew.setMonth(5); // non leap year does not have  ADARI, set month to ADAR
-						t.is(6,dateHebrew.getMonth());						
+						t.is(6,dateHebrew.getMonth());
 					}
-				} 
-			}	
+				}
+			}
 		},
 		{
 			name: "hebrew_numerals",
@@ -351,14 +351,14 @@ tests.register("dojox.date.tests.hebrew.Date",
 				t.assertFalse (dojox.date.hebrew.numerals.parseYearHebrewLetters(dojox.date.hebrew.numerals.getYearHebrewLetters(2345)) == 2345);
 				t.assertFalse (dojox.date.hebrew.numerals.parseYearHebrewLetters(dojox.date.hebrew.numerals.getYearHebrewLetters(6789)) == 6789);
 			}
-		},		
+		},
 		{
 			name: "parse_and_format",
 			runTest: function(t){
 	
 				//test Hebrew and English locale
 												
-				var dates = [	
+				var dates = [
 							[5768, 5, 1],
 							[5768, 1, 29],
 							[5769, 6, 16], // "absolute" index of month, non-leap year
@@ -366,18 +366,18 @@ tests.register("dojox.date.tests.hebrew.Date",
 							[5770, 0, 2]
 						];
 						
-				var dateHebrew, dateHebrew1;		
+				var dateHebrew, dateHebrew1;
 				dojo.forEach(dates, function(date, i){
 					dateHebrew = new dojox.date.hebrew.Date(date[0], date[1], date[2]);
 					
 					var options = [{formatLength:'full', locale:'he'},{formatLength:'long', locale:'he'},{formatLength:'medium', locale:'he'},{formatLength:'short', locale:'he'},
-						{formatLength:'full', locale:'en'},{formatLength:'long', locale:'en'},{formatLength:'medium', locale:'en'},{formatLength:'short', locale:'en'}];					
+						{formatLength:'full', locale:'en'},{formatLength:'long', locale:'en'},{formatLength:'medium', locale:'en'},{formatLength:'short', locale:'en'}];
 					dojo.forEach(options, function(opt, i){
 						str= dojox.date.hebrew.locale.format(dateHebrew, opt);
 						var option = "{" +opt+", locale:'he'}";
 						dateHebrew1 = dojox.date.hebrew.locale.parse(str, opt);
 						t.is(0, dojo.date.compare(dateHebrew.toGregorian(), dateHebrew1.toGregorian(), 'date'));
-					}); 
+					});
 					
 					var pattern = ['d M yy', 'dd/MM/yy h:m:s',  'dd#MM#yy HH$mm$ss', 'dd MMMM yyyy'];
 					dojo.forEach( pattern, function(pat, i){
@@ -386,7 +386,7 @@ tests.register("dojox.date.tests.hebrew.Date",
 						dateHebrew1 = dojox.date.hebrew.locale.parse(str, options);
 						t.is(0, dojo.date.compare(dateHebrew.toGregorian(), dateHebrew1.toGregorian(), 'date'));
 					});
-				}); 
+				});
 						
 				dateHebrew = new dojox.date.hebrew.Date(5769, 6, 3, 15, 3, 59);
 				pattern = 'HH$mm$ss';
@@ -394,13 +394,13 @@ tests.register("dojox.date.tests.hebrew.Date",
 				str= dojox.date.hebrew.locale.format(dateHebrew, options);
 				dateHebrew1 = dojox.date.hebrew.locale.parse(str, options);
 				var gregDate = dojo.date.locale.parse(str, options);
-				t.is(0, dojo.date.compare(gregDate, dateHebrew1.toGregorian(), 'time'));	 
+				t.is(0, dojo.date.compare(gregDate, dateHebrew1.toGregorian(), 'time'));
 				
 				pattern = "h:m:s";
 				options = {timePattern:pattern, selector:'time'};
 				str= dojox.date.hebrew.locale.format(dateHebrew, options);
-				t.is(str, "3:3:59");	 				
-			}		
-		}	
+				t.is(str, "3:3:59");
+			}
+		}
 	]
 );
diff --git a/dojox/date/tests/islamic/Date.js b/dojox/date/tests/islamic/Date.js
index a3eab8b..3dbb80a 100644
--- a/dojox/date/tests/islamic/Date.js
+++ b/dojox/date/tests/islamic/Date.js
@@ -33,18 +33,18 @@ tests.register("dojox.date.tests.islamic.Date",
 		{
 			name: "toGregorian",
 			runTest: function(t) {
-				var dateIslamic = new dojox.date.islamic.Date(1431, 3, 6); // March 22 2010
+				var dateIslamic = new dojox.date.islamic.Date(1431, 3, 6, 15, 15, 10 ); // March 22 2010 3:15:10 PM
 				var dateGregorian = dateIslamic.toGregorian();
-				t.is(0, dojo.date.compare(new Date(2010, 2, 22), dateGregorian, "date"));
+				t.is(0, dojo.date.compare(new Date(2010, 2, 22, 15, 15, 10), dateGregorian, "date"));
 			}
 		},
 		{
 			name: "fromGregorian",
 			runTest: function(t) {
 				var dateIslamic = new dojox.date.islamic.Date();
-				var dateGregorian = new Date(2010, 2, 22);
+				var dateGregorian = new Date(2010, 2, 22, 15, 15, 10);
 				dateIslamic.fromGregorian(dateGregorian);
-				t.is(0, dojox.date.islamic.compare(new dojox.date.islamic.Date(1431, 3, 6), dateIslamic, "date"));
+				t.is(0, dojox.date.islamic.compare(new dojox.date.islamic.Date(1431, 3, 6, 15, 15, 10), dateIslamic, "date"));
 			}
 		},
 		{
@@ -71,10 +71,10 @@ tests.register("dojox.date.tests.islamic.Date",
 			runTest: function(t) {
 
 				var dateTable = [
-					[1430, 1, 29], 
-					[1420, 1, 29], 
-					[1422, 5, 29], 
-					[1431, 5, 29], 
+					[1430, 1, 29],
+					[1420, 1, 29],
+					[1422, 5, 29],
+					[1431, 5, 29],
 					[1430, 2, 30],
 					[1431, 2, 30]
 				];
@@ -226,6 +226,6 @@ tests.register("dojox.date.tests.islamic.Date",
 				str = dojox.date.islamic.locale.format(dateIslamic, options);
 				t.is(str, "3:3:59");
 			}
-		}	
+		}
 	]
 );
diff --git a/dojox/date/tests/posix.js b/dojox/date/tests/posix.js
index 754db36..e427447 100644
--- a/dojox/date/tests/posix.js
+++ b/dojox/date/tests/posix.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.date.tests.posix");
 dojo.require("dojox.date.posix");
 
-tests.register("dojox.date.tests.posix", 
+tests.register("dojox.date.tests.posix",
 	[
 		{
 			// see tests for dojo.date.locale for setup info
@@ -242,9 +242,9 @@ tests.register("dojox.date.tests.posix",
 			name: "getIsoWeeksInYear",
 			runTest: function(t){
 				// 44 long years in a 400 year cycle.
-				var longYears = [4, 9, 15, 20, 26, 32, 37, 43, 48, 54, 60, 65, 71, 76, 82, 
+				var longYears = [4, 9, 15, 20, 26, 32, 37, 43, 48, 54, 60, 65, 71, 76, 82,
 					88,	93, 99, 105, 111, 116, 122, 128, 133, 139, 144, 150, 156, 161, 167,
-					172, 178, 184, 189, 195, 201, 207, 212, 218, 224, 229, 235, 240, 246, 
+					172, 178, 184, 189, 195, 201, 207, 212, 218, 224, 229, 235, 240, 246,
 					252, 257, 263, 268, 274, 280, 285, 291, 296, 303, 308, 314, 320, 325,
 					331, 336, 342, 348, 353, 359, 364, 370, 376, 381, 387, 392, 398];
 			
diff --git a/dojox/date/tests/relative.js b/dojox/date/tests/relative.js
index 6096147..5c204a1 100644
--- a/dojox/date/tests/relative.js
+++ b/dojox/date/tests/relative.js
@@ -2,9 +2,9 @@ dojo.provide("dojox.date.tests.relative");
 dojo.require("dojox.date.relative");
 dojo.require("dojo.date");
 
-dojo.requireLocalization("dojo.cldr", "gregorian"); 
+dojo.requireLocalization("dojo.cldr", "gregorian");
 
-tests.register("dojox.date.tests.relative", 
+tests.register("dojox.date.tests.relative",
 	[
 		{
 			// Test formatting and parsing of dates in various locales pre-built in dojo.cldr
@@ -36,7 +36,7 @@ tests.register("dojox.date.tests.relative",
 				t.is("3:32 AM", dojox.date.relative.format(new Date(2009, 1, 1, 3, 32, 26), opts));
 				t.is("Sat 8:32 PM", dojox.date.relative.format(new Date(2009, 0, 31, 20, 32, 26), opts));
 				t.is("Jan 1", dojox.date.relative.format(new Date(2009, 0, 1, 20, 32, 26), opts));
-				t.is("Jan 1, 2008", dojox.date.relative.format(new Date(2008, 0, 1, 0), opts));				
+				t.is("Jan 1, 2008", dojox.date.relative.format(new Date(2008, 0, 1, 0), opts));
 				
 				//en-us: test various options as well as future dates and edge cases
 				t.is("8:32 PM", dojox.date.relative.format(new Date(2009, 1, 1, 20, 32, 26), opts));
@@ -51,7 +51,7 @@ tests.register("dojox.date.tests.relative",
 				t.is("\u4e0a\u53483:32", dojox.date.relative.format(new Date(2009, 1, 1, 3, 32, 26), opts));
 				t.is("\u5468\u516d \u4e0b\u53488:32", dojox.date.relative.format(new Date(2009, 0, 31, 20, 32, 26), opts));
 				t.is("1\u67081\u65e5", dojox.date.relative.format(new Date(2009, 0, 1, 20, 32, 26), opts));
-				t.is("2008-1-1", dojox.date.relative.format(new Date(2008, 0, 1, 0), opts));				
+				t.is("2008-1-1", dojox.date.relative.format(new Date(2008, 0, 1, 0), opts));
 			}
 		}
 	]
diff --git a/dojox/date/tests/timezoneFormatting.js b/dojox/date/tests/timezoneFormatting.js
index 2ce1037..a80fdbd 100644
--- a/dojox/date/tests/timezoneFormatting.js
+++ b/dojox/date/tests/timezoneFormatting.js
@@ -11,7 +11,7 @@ tests.register("dojox.date.tests.timezoneFormatting",
 
 				dojo.forEach(partLocaleList, function(locale){
 					dojo.requireLocalization("dojo.cldr", "gregorian", locale);
-				});			
+				});
 			},
 			runTest: function(t){
 				var date = new Date(1155257712345);
diff --git a/dojox/date/timezone.js b/dojox/date/timezone.js
index 452ec20..71769ef 100644
--- a/dojox/date/timezone.js
+++ b/dojox/date/timezone.js
@@ -16,8 +16,8 @@ dojo.require("dojo.date.locale");
 
 (function(_d){
 	var cfg = _d.config;
-	var _zoneFiles = [ "africa", "antarctica", "asia", "australasia", "backward", 
-					"etcetera", "europe", "northamerica", "pacificnew", 
+	var _zoneFiles = [ "africa", "antarctica", "asia", "australasia", "backward",
+					"etcetera", "europe", "northamerica", "pacificnew",
 					"southamerica" ];
 					
 	// Our mins an maxes for years that we care about
@@ -31,7 +31,7 @@ dojo.require("dojo.date.locale");
 	
 	// timezoneFileBasePath: String
 	//		A different location to pull zone files from
-	var timezoneFileBasePath = cfg.timezoneFileBasePath || 
+	var timezoneFileBasePath = cfg.timezoneFileBasePath ||
 								_d.moduleUrl("dojox.date", "zoneinfo");
 	
 	// loadingScheme: String
@@ -41,7 +41,7 @@ dojo.require("dojo.date.locale");
 	// defaultZoneFile: String or String[]
 	//		The default file (or files) to load on startup - other files will
 	//		be lazily-loaded on-demand
-	var defaultZoneFile = cfg.defaultZoneFile || 
+	var defaultZoneFile = cfg.defaultZoneFile ||
 					((loadingScheme == "preloadAll") ? _zoneFiles : "northamerica");
 
 	// Set our olson-zoneinfo content handler
@@ -96,7 +96,7 @@ dojo.require("dojo.date.locale");
 		return ret; // Object
 	};
 	
-	function loadZoneObj(/* Object */ data){
+	function loadZoneData(/* Object */ data){
 		// summary:
 		//		Loads the given data object into the zone database
 		//
@@ -127,14 +127,14 @@ dojo.require("dojo.date.locale");
 			url: timezoneFileBasePath + "/" + fileName,
 			sync: true, // Needs to be synchronous so we can return values
 			handleAs: "olson-zoneinfo",
-			load: loadZoneObj,
+			load: loadZoneData,
 			error: errorLoadingZoneFile
 		});
 	}
 	
 	var monthMap = { 'jan': 0, 'feb': 1, 'mar': 2, 'apr': 3,'may': 4, 'jun': 5,
 				'jul': 6, 'aug': 7, 'sep': 8, 'oct': 9, 'nov': 10, 'dec': 11 },
-		dayMap = {'sun': 0, 'mon': 1, 'tue': 2, 'wed': 3, 'thu': 4, 
+		dayMap = {'sun': 0, 'mon': 1, 'tue': 2, 'wed': 3, 'thu': 4,
 				'fri': 5, 'sat': 6 },
 		regionMap = {'EST': "northamerica", 'MST': "northamerica",
 					'HST': "northamerica", 'EST5EDT': "northamerica",
@@ -142,7 +142,7 @@ dojo.require("dojo.date.locale");
 					'PST8PDT': "northamerica", 'America': "northamerica",
 					'Pacific': "australasia", 'Atlantic': "europe",
 					'Africa': "africa", 'Indian': "africa",
-					'Antarctica': "antarctica", 'Asia': "asia", 
+					'Antarctica': "antarctica", 'Asia': "asia",
 					'Australia': "australasia", 'Europe': "europe",
 					'WET': "europe", 'CET': "europe", 'MET': "europe",
 					'EET': "europe"},
@@ -214,14 +214,14 @@ dojo.require("dojo.date.locale");
 							'America/Port_of_Spain':"southamerica",
 							'America/Montevideo':"southamerica",
 							'America/Caracas':"southamerica"},
-		abbrExceptions = { 'US': "S", 'Chatham': "S", 'NZ': "S", 'NT_YK': "S", 
+		abbrExceptions = { 'US': "S", 'Chatham': "S", 'NZ': "S", 'NT_YK': "S",
 							'Edm': "S", 'Salv': "S", 'Canada': "S", 'StJohns': "S",
 							'TC': "S", 'Guat': "S", 'Mexico': "S", 'Haiti': "S",
 							'Barb': "S", 'Belize': "S", 'CR': "S", 'Moncton': "S",
 							'Swift': "S", 'Hond': "S", 'Thule': "S", 'NZAQ': "S",
 							'Zion': "S", 'ROK': "S", 'PRC': "S", 'Taiwan': "S",
-							'Ghana': "GMT", 'SL': "WAT", 'Chicago': "S", 
-							'Detroit': "S", 'Vanc': "S", 'Denver': "S", 
+							'Ghana': "GMT", 'SL': "WAT", 'Chicago': "S",
+							'Detroit': "S", 'Vanc': "S", 'Denver': "S",
 							'Halifax': "S", 'Cuba': "S", 'Indianapolis': "S",
 							'Starke': "S", 'Marengo': "S", 'Pike': "S",
 							'Perry': "S", 'Vincennes': "S", 'Pulaski': "S",
@@ -231,7 +231,7 @@ dojo.require("dojo.date.locale");
 							'DR': "S", 'Toronto': "S", 'Winn': "S" };
 	
 	function invalidTZError(t) {
-		throw new Error('Timezone "' + t + 
+		throw new Error('Timezone "' + t +
 				'" is either incorrect, or not loaded in the timezone registry.');
 	}
 	
@@ -279,7 +279,7 @@ dojo.require("dojo.date.locale");
 		return hms; // int[]
 	}
 	
-	function getUTCStamp(/* int */ y, /* int */ m, /* int */ d, /* int */ h, 
+	function getUTCStamp(/* int */ y, /* int */ m, /* int */ d, /* int */ h,
 						/* int */ mn, /* int */ s, /* int? */ off){
 		// summary:
 		//		Returns the UTC timestamp, adjusted by the given (optional) offset
@@ -319,7 +319,7 @@ dojo.require("dojo.date.locale");
 				// Last day of the month at the desired time of day
 				day = dayMap[day.substr(4,3).toLowerCase()];
 				d = new Date(getUTCStamp(year, month + 1, 1,
-										time[1] - 24, time[2], time[3], 
+										time[1] - 24, time[2], time[3],
 										off));
 				dtDay = _d.date.add(d, "minute", -off).getUTCDay();
 				// Set it to the final day of the correct weekday that month
@@ -333,7 +333,7 @@ dojo.require("dojo.date.locale");
 				if(day != "undefined"){
 					if(rule[4].substr(3, 2) == '>='){
 						// The stated date of the month
-						d = new Date(getUTCStamp(year, month, parseInt(rule[4].substr(5), 10), 
+						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();
 						// Set to the first correct weekday after the stated date
@@ -344,7 +344,7 @@ dojo.require("dojo.date.locale");
 						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), 
+						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();
 						// Set to first correct weekday before the stated date
@@ -358,7 +358,7 @@ dojo.require("dojo.date.locale");
 			}
 		}else{
 			// Numeric date
-			d = new Date(getUTCStamp(year, month, parseInt(day, 10), 
+			d = new Date(getUTCStamp(year, month, parseInt(day, 10),
 						time[1], time[2], time[3], off));
 			return d;
 		}
@@ -420,7 +420,7 @@ dojo.require("dojo.date.locale");
 			}
 			
 			if(i === 0){
-				// The beginning of zoneinfo time - let's not worry about 
+				// The beginning of zoneinfo time - let's not worry about
 				// to-the-hour accuracy before Jan 1, 1835
 				r[0] = Date.UTC(_minYear,0,1,0,0,0,0);
 			}else{
@@ -468,15 +468,15 @@ dojo.require("dojo.date.locale");
 				// get close to Dec 31, 2038
 				r[1] = Date.UTC(_maxYear,11,31,23,59,59,999);
 			}else{
-				var year = parseInt(z[3], 10), 
-					month = getMonthNumber(z[4]||"Jan"), 
-					day = parseInt(z[5]||"1", 10), 
+				var year = parseInt(z[3], 10),
+					month = getMonthNumber(z[4]||"Jan"),
+					day = parseInt(z[5]||"1", 10),
 					time = parseTimeString(z[6]||"0");
-				var utcStmp = r[1] = getUTCStamp(year, month, day, 
+				var utcStmp = r[1] = getUTCStamp(year, month, day,
 									time[1], time[2], time[3],
 									((time[4] == "u") ? 0 : z[0]));
 				if(isNaN(utcStmp)){
-					utcStmp = r[1] = _getRuleStart([0,0,0,z[4],z[5],z[6]||"0"], 
+					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){
@@ -567,7 +567,7 @@ dojo.require("dojo.date.locale");
 				repl = abbrExceptions[zone[1]];
 			}else{
 				if(zoneInfo.idx > 0){
-					// Check if our previous zone's base is the same as our 
+					// Check if our previous zone's base is the same as our
 					// current in "S" (standard) mode.  If so, then use "S"
 					// for our replacement
 					var pz = _zones[tz][zoneInfo.idx - 1];
@@ -627,6 +627,14 @@ dojox.date.timezone.getTzInfo = function(dt, tz){
 	//	for date
 };
 
+dojox.date.timezone.loadZoneData = function(data){
+	// summary:
+	//		Loads the given data object into the zone database
+	//
+	// data: Object
+	//		The data to load - contains "zones" and "rules" parameters
+};
+
 dojox.date.timezone.getAllZones = function(){
 	// summary:
 	//	Returns an array of zones that have been loaded
@@ -664,6 +672,9 @@ dojox.date.timezone.getAllZones = function(){
 			var abbr = getAbbreviation(tz, zoneInfo, rule);
 			return { tzOffset: off, tzAbbr: abbr }; // Object
 		},
+		loadZoneData: function(data){
+			loadZoneData(data);
+		},
 		getAllZones: function(){
 			var arr = [];
 			for(var z in _zones){ arr.push(z); }
@@ -694,7 +705,7 @@ dojox.date.timezone.getAllZones = function(){
 			options._tzInfo = dojox.date.timezone.getTzInfo(dateObject, options.timezone);
 		}
 		if(options._tzInfo){
-			// Roll our date to display the correct time according to the 
+			// Roll our date to display the correct time according to the
 			// desired offset
 			var offset = dateObject.getTimezoneOffset() - options._tzInfo.tzOffset;
 			dateObject = new Date(dateObject.getTime() + (offset * 60 * 1000));
diff --git a/dojox/dnd/BoundingBoxController.js b/dojox/dnd/BoundingBoxController.js
index e51fc11..807e660 100644
--- a/dojox/dnd/BoundingBoxController.js
+++ b/dojox/dnd/BoundingBoxController.js
@@ -6,7 +6,7 @@ dojo.declare(
 	{
 		// 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 
+		// 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,
diff --git a/dojox/drawing/Drawing.js b/dojox/drawing/Drawing.js
index c97da63..20a18aa 100755
--- a/dojox/drawing/Drawing.js
+++ b/dojox/drawing/Drawing.js
@@ -28,7 +28,7 @@ dojo.provide("dojox.drawing.Drawing");
 		//			Like Drawing, Toolbar is a psudeo Dijit that does not need Dijit. It is
 		//			optional. It can be oriented horizontal or vertical by placing one of
 		//			those params in the class (at least one is required).  Plugins
-		//			can be added in markup. A drawingId is required to point toolbar to 
+		//			can be added in markup. A drawingId is required to point toolbar to
 		//			the drawing.
 		//		- defaults
 		//			Contains the default styles and dimensions for Stencils. An individual
@@ -67,7 +67,7 @@ dojo.provide("dojox.drawing.Drawing");
 		//
 		// example:
 		//		|	<div dojoType="dojox.drawing.Drawing" id="drawing" defaults="myCustom.defaults"
-		//		|		plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">   
+		//		|		plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
 		//		|   </div>
 		//
 		//	example:
@@ -198,7 +198,7 @@ dojo.provide("dojox.drawing.Drawing");
 				height:box.h+"px"
 			});
 			if(!this.canvas){
-				this._createCanvas();		
+				this._createCanvas();
 			}else if(box){
 				this.canvas.resize(box.w, box.h);
 			}
@@ -214,7 +214,7 @@ dojo.provide("dojox.drawing.Drawing");
 			//		a new Stencil. Mostly internal, but could be used.
 			//
 			var surface = data.stencilType;
-			var ui = this.mode=="ui" || mode=="ui"; 
+			var ui = this.mode=="ui" || mode=="ui";
 			return dojo.mixin({
 				container: ui && !surface ? this.canvas.overlay.createGroup() : this.canvas.surface.createGroup(),
 				util:this.util,
@@ -232,7 +232,7 @@ dojo.provide("dojox.drawing.Drawing");
 			//		to be parsed
 			this.plugins.push(plugin);
 			if(this.canvas.surfaceReady){
-				this.initPlugins();		
+				this.initPlugins();
 			}
 		},
 		
@@ -298,7 +298,7 @@ dojo.provide("dojox.drawing.Drawing");
 				}
 			}
 			dojo.forEach(this.plugins, function(p){
-				p.onSurfaceReady && p.onSurfaceReady();	
+				p.onSurfaceReady && p.onSurfaceReady();
 			});
 		
 		},
@@ -420,10 +420,10 @@ dojo.provide("dojox.drawing.Drawing");
 			//		to the drawing.
 			dojo.forEach(objects, function(m){
 				this.addStencil(m.type, m);
-			}, this);	
+			}, this);
 		},
 		
-		changeDefaults: function(/*Object*/newStyle){
+		changeDefaults: function(/*Object*/newStyle,/*boolean*/value){
 			// summary:
 			//		Change the defaults so that all Stencils from this
 			// 		point on will use the newly changed style.
@@ -432,8 +432,11 @@ dojo.provide("dojox.drawing.Drawing");
 			//			An object that represents one of the objects in
 			//			drawing.style that will be mixed in. Not all
 			//			properties are necessary. Only one object may
-			//			be changed at a time. Non-objects like angleSnap
-			//			cannot be changed in this manner.
+			//			be changed at a time. The object boolean parameter
+			//			is not required and if not set objects will automatically
+			//			be changed.
+			//			Changing non-objects like angleSnap requires value
+			//			to be true.
 			// example:
 			//		|	myDrawing.changeDefaults({
 			//		|		norm:{
@@ -443,14 +446,24 @@ dojo.provide("dojox.drawing.Drawing");
 			//		|		}
 			//		|	});
 			//
-			for(var nm in newStyle){
-				for(var n in newStyle[nm]){
-					console.log("  copy", nm, n, " to: ", newStyle[nm][n]);
-					this.defaults[nm][n] = newStyle[nm][n];
+			//console.log("----->>> changeDefault: ",newStyle, " value?: ",value);
+			if(value!=undefined && value){
+				for(var nm in newStyle){
+					this.defaults[nm] = newStyle[nm];
+				}
+			}else{
+				for(var nm in newStyle){
+					for(var n in newStyle[nm]){
+						//console.log("  copy", nm, n, " to: ", newStyle[nm][n]);
+						this.defaults[nm][n] = newStyle[nm][n];
+					}
 				}
 			}
-			this.unSetTool();
-			this.setTool(this.currentType);
+			
+			if(this.currentStencil!=undefined && (!this.currentStencil.created || this.defaults.clickMode)){
+				this.unSetTool();
+				this.setTool(this.currentType);
+			}
 		},
 		
 		onRenderStencil: function(/* Object */stencil){
@@ -462,10 +475,10 @@ dojo.provide("dojox.drawing.Drawing");
 			
 			this.stencils.register(stencil);
 			this.unSetTool();
-			if(!this.defaults.clickMode){ 
+			if(!this.defaults.clickMode){
 				this.setTool(this.currentType);
 			}else{
-				if(this.defaults.clickMode){ this.defaults.clickable = true; }
+				this.defaults.clickable = true;
 			}
 		},
 		
@@ -473,7 +486,7 @@ dojo.provide("dojox.drawing.Drawing");
 			// summary:
 			//		Event fired from a stencil that has destroyed itself
 			//	 	will also be called when it is removed by "removeStencil"
-			//	 	or stencils.onDelete. 
+			//	 	or stencils.onDelete.
 			//
 			this.stencils.unregister(stencil);
 		},
@@ -535,7 +548,7 @@ dojo.provide("dojox.drawing.Drawing");
 			// summary:
 			//		Destroys current tool
 			if(!this.currentStencil.created){
-				this.currentStencil.destroy();	
+				this.currentStencil.destroy();
 			}
 			
 		}
diff --git a/dojox/drawing/_base.js b/dojox/drawing/_base.js
index 10a1263..0056158 100644
--- a/dojox/drawing/_base.js
+++ b/dojox/drawing/_base.js
@@ -6,6 +6,7 @@ dojo.require("dojox.gfx");
 dojo.require("dojox.drawing.Drawing");
 dojo.require("dojox.drawing.util.oo");
 dojo.require("dojox.drawing.util.common");
+dojo.require("dojox.drawing.util.typeset");
 dojo.require("dojox.drawing.defaults");
 dojo.require("dojox.drawing.manager.Canvas");
 
diff --git a/dojox/drawing/annotations/Arrow.js b/dojox/drawing/annotations/Arrow.js
index 5350caf..877be7b 100755
--- a/dojox/drawing/annotations/Arrow.js
+++ b/dojox/drawing/annotations/Arrow.js
@@ -51,7 +51,7 @@ dojox.drawing.annotations.Arrow = dojox.drawing.util.oo.declare(
 			}
 			var angle = this.util.angle(obj);
 			
-			var lineLength = this.util.length(obj); 
+			var lineLength = this.util.length(obj);
 			var al = style.arrows.length;
 			var aw = style.arrows.width/2;
 			if(lineLength<al){
diff --git a/dojox/drawing/annotations/BoxShadow.js b/dojox/drawing/annotations/BoxShadow.js
index 2201cc1..5baf525 100644
--- a/dojox/drawing/annotations/BoxShadow.js
+++ b/dojox/drawing/annotations/BoxShadow.js
@@ -104,7 +104,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 				p = o.place,
 				c = o.color;
 				
-			this[this.method](o, size, mult, d, r, p, c);	
+			this[this.method](o, size, mult, d, r, p, c);
 		},
 		
 		hide: function(){
@@ -131,7 +131,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			for(var i=1;i<=size;i++){
 				var lineWidth = i * mult;
 				//var rect = this.container.createLine({x1:d.x1+shx, y1:d.y1+shy, x2:d.x2+shx, y2:d.y2+shy})
-				//	.setStroke({width:lineWidth, color:c, cap:"round"})		
+				//	.setStroke({width:lineWidth, color:c, cap:"round"})
 			
 				if(dojox.gfx.renderer=="svg"){
 					var strAr = [];
@@ -146,11 +146,11 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 					if(closePath){
 						strAr.push("Z");
 					}
-					this.container.createPath(strAr.join(", ")).setStroke({width:lineWidth, color:c, cap:"round"})	
+					this.container.createPath(strAr.join(", ")).setStroke({width:lineWidth, color:c, cap:"round"})
 					
 				}else{
 					// Leaving this code for VML. It seems slightly faster but times vary.
-					var pth = this.container.createPath({}).setStroke({width:lineWidth, color:c, cap:"round"})	
+					var pth = this.container.createPath({}).setStroke({width:lineWidth, color:c, cap:"round"})
 					
 					dojo.forEach(this.points, function(o, i){
 						if(i==0 || o.t=="M"){
@@ -177,7 +177,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			for(var i=1;i<=size;i++){
 				var lineWidth = i * mult;
 				this.container.createLine({x1:d.x1+shx, y1:d.y1+shy, x2:d.x2+shx, y2:d.y2+shy})
-					.setStroke({width:lineWidth, color:c, cap:"round"})		
+					.setStroke({width:lineWidth, color:c, cap:"round"})
 			}
 		},
 		createForEllipse: function(o, size, mult, d, r, p, c){
@@ -189,7 +189,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			for(var i=1;i<=size;i++){
 				var lineWidth = i * mult;
 				this.container.createEllipse({cx:d.cx+shx, cy:d.cy+shy, rx:d.rx-sh, ry:d.ry-sh, r:r})
-					.setStroke({width:lineWidth, color:c})		
+					.setStroke({width:lineWidth, color:c})
 			}
 		},
 		
@@ -202,7 +202,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 			for(var i=1;i<=size;i++){
 				var lineWidth = i * mult;
 				this.container.createRect({x:d.x+shx, y:d.y+shy, width:d.width-sh, height:d.height-sh, r:r})
-					.setStroke({width:lineWidth, color:c})		
+					.setStroke({width:lineWidth, color:c})
 			}
 		},
 		
@@ -225,7 +225,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 				y:pt.y
 			}
 			var angle = this.util.angle(obj);
-			var lineLength = this.util.length(obj); 
+			var lineLength = this.util.length(obj);
 			var al = this.style.arrows.length;
 			var aw = this.style.arrows.width/3;
 			if(lineLength<al){
@@ -270,7 +270,7 @@ dojox.drawing.annotations.BoxShadow = dojox.drawing.util.oo.declare(
 					
 				}else{
 					// Leaving this code for VML. It seems slightly faster but times vary.
-					var pth = this.container.createPath({}).setStroke({width:lineWidth, color:c, cap:"round"})	
+					var pth = this.container.createPath({}).setStroke({width:lineWidth, color:c, cap:"round"})
 					
 					dojo.forEach(pts, function(o, i){
 						if(i==0 || o.t=="M"){
diff --git a/dojox/drawing/annotations/Label.js b/dojox/drawing/annotations/Label.js
index 3fbe535..c9cb302 100755
--- a/dojox/drawing/annotations/Label.js
+++ b/dojox/drawing/annotations/Label.js
@@ -18,17 +18,18 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 		this.master = options.stencil;
 		this.labelPosition = options.labelPosition || "BR"; // TL, TR, BR, BL, or function
 		if(dojo.isFunction(this.labelPosition)){
-			this.setLabel = this.setLabelCustom;	
+			this.setLabel = this.setLabelCustom;
 		}
 		this.setLabel(options.text || "");
 		this.connect(this.master, "onTransform", this, "setLabel");
 		this.connect(this.master, "destroy", this, "destroy");
 		
 		if(this.style.labelSameColor){
-			this.connect(this.master, "attr", this, "beforeAttr");		
+			this.connect(this.master, "attr", this, "beforeAttr");
 		}
 	},{
 		_align:"start",
+		drawingType:"label",
 		
 		setLabelCustom: function(/* ? String */text){
 			// summary:
@@ -42,8 +43,8 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 				height:d.h || this._lineHeight
 			});
 			
-			// is an event, not text:
-			if(text && !text.split){ text = null; }
+			// is an event, not text, so keep the old label:
+			if(text && !text.split){ text = this.getText(); }
 			
 			this.render(this.typesetter(text));
 		},
@@ -69,7 +70,7 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 				this._align = "end";
 			}
 			
-			if(!this.labelWidth || (text && text.split && text != this.getText())){ //????????????????????????????????????
+			if(!this.labelWidth || (text && text.split && text != this.getText())){
 				this.setData({
 					x:x,
 					y:y,
@@ -96,7 +97,7 @@ dojox.drawing.annotations.Label = dojox.drawing.util.oo.declare(
 		beforeAttr: function(key, value){
 			if(value!==undefined){
 				// make it an object
-				var k = key; key = {}; key[k] = value;	
+				var k = key; key = {}; key[k] = value;
 			}
 			delete key.x;
 			delete key.y;
diff --git a/dojox/drawing/library/greek.js b/dojox/drawing/library/greek.js
new file mode 100644
index 0000000..a0e816f
--- /dev/null
+++ b/dojox/drawing/library/greek.js
@@ -0,0 +1,66 @@
+dojo.provide("dojox.drawing.library.greek");
+
+dojox.drawing.library.greek = {
+	// summary:
+	//		Greek characters used by typesetter and greekPalette.
+	// description:
+	//		These are used to convert between the character and
+	//		the written version of greek letters.  Any character
+	//		can be included here and it will automatically be added
+	//		to the palette and converted by typesetter
+        
+        "alpha": 945,   //alpha,     U+03B1 ISOgrk3 -->
+        "beta": 946,   //beta, U+03B2 ISOgrk3 -->
+        "gamma": 947,   //gamma,  U+03B3 ISOgrk3 -->
+        "delta": 948,   //delta,        U+03B4 ISOgrk3 -->
+        "epsilon": 949,   //epsilon,    U+03B5 ISOgrk3 -->
+        "zeta": 950,   //zeta, U+03B6 ISOgrk3 -->
+        "eta": 951,   //eta, U+03B7 ISOgrk3 -->
+        "theta": 952,   //theta,   U+03B8 ISOgrk3 -->
+        "iota": 953,   //iota, U+03B9 ISOgrk3 -->
+        "kappa": 954,   //kappa,   U+03BA ISOgrk3 -->
+        "lambda": 955,   //lambda,    U+03BB ISOgrk3 -->
+        "mu": 956,   //mu, U+03BC ISOgrk3 -->
+        "nu": 957,   //nu, U+03BD ISOgrk3 -->
+        "xi": 958,   //xi, U+03BE ISOgrk3 -->
+        "omicron": 959,   //omicron, U+03BF NEW -->
+        "pi": 960,   //pi, U+03C0 ISOgrk3 -->
+        "rho": 961,   //rho, U+03C1 ISOgrk3 -->
+        "sigmaf": 962,   //final sigma,  U+03C2 ISOgrk3 -->
+        "sigma": 963,   //sigma,  U+03C3 ISOgrk3 -->
+        "tau": 964,   //tau, U+03C4 ISOgrk3 -->
+        "upsilon": 965,   //upsilon,   U+03C5 ISOgrk3 -->
+        "phi": 966,   //phi, U+03C6 ISOgrk3 -->
+        "chi": 967,   //chi, U+03C7 ISOgrk3 -->
+        "psi": 968,   //psi, U+03C8 ISOgrk3 -->
+        "omega": 969,   //omega,      U+03C9 ISOgrk3 -->
+        "thetasym": 977,   //theta symbol,  U+03D1 NEW -->
+        "upsih": 978,     // upsilon with hook symbol,  U+03D2 NEW -->
+        "piv": 982,     // greek pi symbol, U+03D6 ISOgrk3 -->
+        "Alpha": 913,    // alpha, U+0391 -->
+        "Beta": 914,      // beta, U+0392 -->
+        "Gamma": 915,    //gamma, U+0393 ISOgrk3 -->
+        "Delta": 916,    //delta,           U+0394 ISOgrk3 -->
+        "Epsilon": 917,    //epsilon, U+0395 -->
+        "Zeta": 918,    //zeta, U+0396 -->
+        "Eta": 919,    //eta, U+0397 -->
+        "Theta": 920,    //theta,           U+0398 ISOgrk3 -->
+        "Iota": 921,    //iota, U+0399 -->
+        "Kappa": 922,    //kappa, U+039A -->
+        "Lambda": 923,    //lambda,      U+039B ISOgrk3 -->
+        "Mu": 924,    //mu, U+039C -->
+        "Nu": 925,    //nu, U+039D -->
+        "Xi": 926,    //xi, U+039E ISOgrk3 -->
+        "Omicron": 927,    //omicron, U+039F -->
+        "Pi": 928,    //pi, U+03A0 ISOgrk3 -->
+        "Rho": 929,    //rho, U+03A1 -->
+        "Sigma": 931,    //sigma,     U+03A3 ISOgrk3 -->
+        "Tau": 932,    //tau, U+03A4 -->
+        "Upsilon": 933,    //upsilon,   U+03A5 ISOgrk3 -->
+        "Phi": 934,    //phi, U+03A6 ISOgrk3 -->
+        "Chi": 935,    //chi, U+03A7 -->
+        "Psi": 936,    //psi,   U+03A8 ISOgrk3 -->
+        "Omega": 937    //omega,     U+03A9 ISOgrk3 -->
+};
+    
+    
\ No newline at end of file
diff --git a/dojox/drawing/manager/Anchors.js b/dojox/drawing/manager/Anchors.js
index 2719a3d..ef5ae39 100755
--- a/dojox/drawing/manager/Anchors.js
+++ b/dojox/drawing/manager/Anchors.js
@@ -60,7 +60,7 @@ dojox.drawing.manager.Anchors = dojox.drawing.util.oo.declare(
 				
 				
 				if(anchor.id == a.id || anchor.stencil.anchorType!="group"){
-					// nothing 
+					// nothing
 				}else{
 					if(anchor.org.y == a.org.y){
 						a.setPoint({
@@ -120,7 +120,7 @@ dojox.drawing.manager.Anchors = dojox.drawing.util.oo.declare(
 			// summary:
 			//		Creates anchor points on a Stencil, based on the
 			//		Stencil's points.
-			//	
+			//
 			this.items[item.id] = {
 				item:item,
 				anchors:[]
@@ -168,7 +168,7 @@ dojox.drawing.manager.Anchors = dojox.drawing.util.oo.declare(
 								anchor.y_anchor = a;
 							}
 						}
-					},this);	
+					},this);
 				},this);
 				
 			}
@@ -202,7 +202,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 		//		arguments:
 		//			dojox.__stencilArgs plus some additional
 		//			data, like which point this is (pointIdx)
-		//		
+		//
 		this.defaults = dojox.drawing.defaults.copy();
 		this.mouse = options.mouse;
 		this.point = options.point;
@@ -267,7 +267,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 		},
 		onAnchorDown: function(/*Mouse.EventObject*/obj){
 			// summary:
-			//		Event fires for mousedown on anchor 
+			//		Event fires for mousedown on anchor
 			this.selected = obj.id == this.id;
 		},
 		onAnchorUp: function(/*Mouse.EventObject*/obj){
@@ -336,7 +336,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 							y = conT;
 						}else if(y > conB){
 							// overlapping other anchor
-							y = conB; 
+							y = conB;
 						}
 					}
 				}else{
@@ -363,7 +363,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 						if(x < conL){
 							// overlapping other anchor
 							x = conL;
-						}							
+						}
 						
 					}else{
 						// left anchor
@@ -375,7 +375,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 							x = conL;
 						}else if(x > conR){
 							// overlapping other anchor
-							x = conR; 
+							x = conR;
 						}
 					}
 				}else{
@@ -387,9 +387,9 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 				}
 				//Constrains anchor point, returns null if not overwritten by stencil
 				var constrained = this.anchorConstrain(x, y);
-				if(constrained != null){ 
+				if(constrained != null){
 					x=constrained.x;
-					y=constrained.y; 
+					y=constrained.y;
 				}
 				
 				this.shape.setTransform({
@@ -423,7 +423,7 @@ dojox.drawing.manager.Anchor = dojox.drawing.util.oo.declare(
 			//		and it will automatically overwrite this stub.
 			//		Should return x and y coords. Success is both
 			//		being greater than zero, fail is if one or both
-			//		are less than zero. 
+			//		are less than zero.
 			return {x:1, y:1};
 		},
 		
diff --git a/dojox/drawing/manager/Canvas.js b/dojox/drawing/manager/Canvas.js
index 55a0658..47df302 100755
--- a/dojox/drawing/manager/Canvas.js
+++ b/dojox/drawing/manager/Canvas.js
@@ -9,7 +9,7 @@ dojo.provide("dojox.drawing.manager.Canvas");
 		//		This allows for more versatility.
 		//
 		//		Called internally from a dojox.Drawing.
-		//	
+		//
 		//		Note: Surface creation is asynchrous. Connect to
 		//  		onSurfaceReady in Drawing.
 		//
@@ -68,7 +68,7 @@ dojo.provide("dojox.drawing.manager.Canvas");
 				//		Method used to change size of canvas. Potentially
 				//		called from a container like ContentPane. May be
 				//		called directly.
-				//	
+				//
 				this.parentWidth = width;
 				this.parentHeight = height;
 				this.setDimensions(width, height);
@@ -133,7 +133,7 @@ dojo.provide("dojox.drawing.manager.Canvas");
 				//		Get the scroll position of the canvas
 				return {
 					top:this.domNode.parentNode.scrollTop,
-					left:this.domNode.parentNode.scrollLeft		
+					left:this.domNode.parentNode.scrollLeft
 				}; // Object
 			},
 			
diff --git a/dojox/drawing/manager/Mouse.js b/dojox/drawing/manager/Mouse.js
index 98a63fc..03857df 100755
--- a/dojox/drawing/manager/Mouse.js
+++ b/dojox/drawing/manager/Mouse.js
@@ -31,6 +31,13 @@ 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,
@@ -133,12 +140,17 @@ EventObject: function(){
 			
 			dojo.connect(this.container, "mousedown", this, function(evt){
 				this.down(evt);
-				_isDown = true;
-				c = dojo.connect(document, "mousemove", this, "drag");
+				// Right click shouldn't trigger drag
+				if(evt.button != dojo.mouseButtons.RIGHT){
+					_isDown = true;
+					c = dojo.connect(document, "mousemove", this, "drag");
+				}
 			});
 			dojo.connect(document, "mouseup", this, function(evt){
-				dojo.disconnect(c);
-				_isDown = false;
+				if(evt.button != dojo.mouseButtons.RIGHT){
+					dojo.disconnect(c);
+					_isDown = false;
+				}
 				this.up(evt);
 			});
 			dojo.connect(document, "mousemove", this, function(evt){
@@ -147,7 +159,7 @@ EventObject: function(){
 				}
 			});
 			dojo.connect(this.keys, "onEsc", this, function(evt){
-				this._dragged = false;	
+				this._dragged = false;
 			});
 		},
 		
@@ -163,7 +175,7 @@ EventObject: function(){
 			// 	Gets scroll offset of canvas
 			return {
 				top:this.container.parentNode.scrollTop,
-				left:this.container.parentNode.scrollLeft		
+				left:this.container.parentNode.scrollLeft
 			}; // Object
 		},
 
@@ -212,7 +224,7 @@ EventObject: function(){
 			// 		Create on[xx]Down event and send to broadcaster.
 			//		Could be connected to.
 			//console.info("onDown:", this.eventName("down"))
-			this._broadcastEvent(this.eventName("down"), obj);			
+			this._broadcastEvent(this.eventName("down"), obj);
 		},
 		
 		onDrag: function(obj){
@@ -241,9 +253,9 @@ EventObject: function(){
 			var nm = obj.id.split(".");
 			evt = evt.charAt(0).toUpperCase() + evt.substring(1);
 			if(nm[0] == "dojox" && (dojox.drawing.defaults.clickable || !dojox.drawing.defaults.clickMode)){
-				return "onStencil"+evt;	
+				return "onStencil"+evt;
 			}else{
-				return "on"+evt;	
+				return "on"+evt;
 			}
 			
 		},
@@ -351,9 +363,6 @@ EventObject: function(){
 			// summary:
 			//		Internal. Create onDown event
 			//
-			evt.preventDefault();
-			dojo.stopEvent(evt);
-			
 			this._downOnCanvas = true;
 			var sc = this.scrollOffset();
 			var dim = this._getXY(evt);
@@ -376,6 +385,13 @@ EventObject: function(){
 			var id = this._getId(evt);
 			//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
+			}else{
+				evt.preventDefault();
+				dojo.stopEvent(evt);
+			}
 			this.onDown({
 				mid:this.id,
 				x:x,
@@ -497,8 +513,8 @@ EventObject: function(){
 			// summary:
 			//		Sets the cursor for  a given node.  If no
 			//		node is specified the containing node is used.
-			if(!node){ 
-				dojo.style(this.container, "cursor", cursor); 
+			if(!node){
+				dojo.style(this.container, "cursor", cursor);
 			}else{
 				dojo.style(node, "cursor", cursor);
 			}
diff --git a/dojox/drawing/manager/Stencil.js b/dojox/drawing/manager/Stencil.js
index 76a9b5c..f8a59c3 100755
--- a/dojox/drawing/manager/Stencil.js
+++ b/dojox/drawing/manager/Stencil.js
@@ -38,6 +38,20 @@ dojo.provide("dojox.drawing.manager.Stencil");
 			_secondClick:false,
 			_isBusy:false,
 			
+			setRecentStencil: function(stencil){
+				// summary:
+				//		Keeps track of the most recent stencil interacted
+				//		with, whether created or selected.
+				this.recent = stencil;
+			},
+			
+			getRecentStencil: function(){
+				// summary:
+				//		Returns the stencil most recently interacted
+				//		with whether it's last created or last selected
+				return this.recent;
+			},
+			
 			register: function(/*Object*/stencil){
 				// summary:
 				//		Key method for adding Stencils. Stencils
@@ -55,6 +69,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				}
 				
 				this.stencils[stencil.id] = stencil;
+				this.setRecentStencil(stencil);
 				
 				if(stencil.execText){
 					if(stencil._text && !stencil.editMode){
@@ -148,7 +163,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				if(this._throttle){ return; }
 				this._throttle = true;
 				
-				this.saveMoveState();					
+				this.saveMoveState();
 				
 			},
 			unDelete: function(/*Array*/stencils){
@@ -165,7 +180,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				// summary:
 				//		Event fired on deletion of a stencil
 				//
-				console.log("onDelete", noundo);
+				console.log("Stencil onDelete", noundo);
 				if(noundo!==true){
 					this.undo.add({
 						before:dojo.hitch(this, "unDelete", this.selectedStencils),
@@ -343,6 +358,16 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				this.setConstraint();
 			},
 			
+			onLabelDoubleClick: function(/*EventObject*/obj){
+				// summary:
+				//		Event to connect a textbox to
+				//		for label edits
+				console.info("mgr.onLabelDoubleClick:", obj);
+				if(this.selectedStencils[obj.id]){
+					this.deselect();
+				}
+			},
+			
 			onStencilDoubleClick: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on the double-click of a stencil
@@ -374,6 +399,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				//
 				console.info(" >>> onStencilDown:", obj.id, this.keys.meta);
 				if(!this.stencils[obj.id]){ return; }
+				this.setRecentStencil(this.stencils[obj.id]);
 				this._isBusy = true;
 				
 				
@@ -398,7 +424,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 					// clicking on same selected item(s)
 					// RESET OFFSETS
 					var mx = this.group.getTransform();
-					this._offx = obj.x - mx.dx; 
+					this._offx = obj.x - mx.dx;
 					this._offy = obj.y - mx.dy;
 					return;
 				
@@ -416,7 +442,7 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				this.selectItem(obj.id);
 				
 				mx = this.group.getTransform();
-				this._offx = obj.x - mx.dx; 
+				this._offx = obj.x - mx.dx;
 				this._offy = obj.y - mx.dx;
 				
 				this.orgx = obj.x;
@@ -438,16 +464,29 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				});
 			},
 			
+			onLabelDown: function(/*EventObject*/obj, evt){
+				// summary:
+				//		Event fired on mousedown of a stencil's label
+				//		Because it's an annotation the id will be the
+				//		master stencil.
+				//console.info("===============>>>Label click: ",obj, " evt: ",evt);
+				this.onStencilDown(obj,evt);
+			},
+			
 			onStencilUp: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on mouseup off of a stencil
 				//
 			},
 			
+			onLabelUp: function(/*EventObject*/obj){
+				this.onStencilUp(obj);
+			},
+			
 			onStencilDrag: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired on every mousemove of a stencil drag
-				//	
+				//
 				if(!this._dragBegun){
 					// bug, in FF anyway - first mouse move shows x=0
 					// the 'else' fixes it
@@ -481,6 +520,10 @@ dojo.provide("dojox.drawing.manager.Stencil");
 				}
 			},
 			
+			onLabelDrag: function(/*EventObject*/obj){
+				this.onStencilDrag(obj);
+			},
+			
 			onDragEnd: function(/*EventObject*/obj){
 				// summary:
 				//		Event fired at the end of a stencil drag
diff --git a/dojox/drawing/manager/StencilUI.js b/dojox/drawing/manager/StencilUI.js
index b4af29d..70e6932 100644
--- a/dojox/drawing/manager/StencilUI.js
+++ b/dojox/drawing/manager/StencilUI.js
@@ -25,7 +25,7 @@ dojo.provide("dojox.drawing.manager.StencilUI");
 		},
 		{
 			register: function(/*Object*/stencil){
-				this.stencils[stencil.id] = stencil;	
+				this.stencils[stencil.id] = stencil;
 				return stencil;
 			},
 			onUiDown: function(/*EventObject*/obj){
diff --git a/dojox/drawing/manager/Undo.js b/dojox/drawing/manager/Undo.js
index e5feb16..917381a 100755
--- a/dojox/drawing/manager/Undo.js
+++ b/dojox/drawing/manager/Undo.js
@@ -26,7 +26,7 @@ dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
 		add: function(stack){
 			//console.log("undo add", stack)
 			stack.args = dojo.mixin({}, stack.args);
-			this.undostack.push(stack);	
+			this.undostack.push(stack);
 		},
 		apply: function(scope, method, args){
 			dojo.hitch(scope, method)(args);
@@ -34,7 +34,7 @@ dojox.drawing.manager.Undo = dojox.drawing.util.oo.declare(
 		undo: function(){
 			
 			var o = this.undostack.pop();
-			console.log("undo!", o);	
+			console.log("undo!", o);
 			if(!o){ return; }
 			
 			o.before();
diff --git a/dojox/drawing/manager/_registry.js b/dojox/drawing/manager/_registry.js
index bce0dbf..29fad89 100644
--- a/dojox/drawing/manager/_registry.js
+++ b/dojox/drawing/manager/_registry.js
@@ -14,11 +14,11 @@ dojo.provide("dojox.drawing.manager._registry");
 		if(type=="drawing"){
 			_registered.drawing[item.id] = item;
 		}else if(type=="tool"){
-			_registered.tool[item.name] = item;	
+			_registered.tool[item.name] = item;
 		}else if(type=="stencil"){
-			_registered.stencil[item.name] = item;	
+			_registered.stencil[item.name] = item;
 		}else if(type=="plugin"){
-			_registered.plugin[item.name] = item;	
+			_registered.plugin[item.name] = item;
 		}else if(type=="button"){
 			_registered.button[item.toolType] = item;
 		}
diff --git a/dojox/drawing/manager/keys.js b/dojox/drawing/manager/keys.js
index 7ce0179..ac796ad 100755
--- a/dojox/drawing/manager/keys.js
+++ b/dojox/drawing/manager/keys.js
@@ -89,12 +89,12 @@ dojo.provide("dojox.drawing.manager.keys");
 				scope: options.scope || window,
 				callback:options.callback,
 				keyCode:options.keyCode
-			});	
+			});
 		},
 		
 		_getLetter: function(evt){
 			if(!evt.meta && evt.keyCode>=65 && evt.keyCode<=90){
-				return alphabet.charAt(evt.keyCode-65);	
+				return alphabet.charAt(evt.keyCode-65);
 			}
 			return null;
 		},
@@ -140,10 +140,10 @@ dojo.provide("dojox.drawing.manager.keys");
 			this._fieldCons = [];
 			dojo.query("input").forEach(function(n){
 				var a = dojo.connect(n, "focus", this, function(evt){
-					this.enable(false);	
+					this.enable(false);
 				});
 				var b = dojo.connect(n, "blur", this, function(evt){
-					this.enable(true);	
+					this.enable(true);
 				});
 				this._fieldCons.push(a);
 				this._fieldCons.push(b);
@@ -224,7 +224,7 @@ dojo.provide("dojox.drawing.manager.keys");
 				}
 				
 				if(_stop && !isEdit){
-					dojo.stopEvent(evt);	
+					dojo.stopEvent(evt);
 				}
 			});
 			
@@ -252,9 +252,9 @@ dojo.provide("dojox.drawing.manager.keys");
 					evt.x = x;
 					evt.y = y;
 					evt.shift = this.shift;
-					this.onArrow(evt);
 					if(!isEdit){
-						dojo.stopEvent(evt);	
+						this.onArrow(evt);
+						dojo.stopEvent(evt);
 					}
 				}
 			});
diff --git a/dojox/drawing/plugins/_Plugin.js b/dojox/drawing/plugins/_Plugin.js
index f13ec8e..2fc6425 100755
--- a/dojox/drawing/plugins/_Plugin.js
+++ b/dojox/drawing/plugins/_Plugin.js
@@ -25,7 +25,7 @@ dojox.drawing.plugins._Plugin = dojox.drawing.util.oo.declare(
 		button:null,//gfx button
 		type:"dojox.drawing.plugins._Plugin",
 		connect: function(){
-			this._cons.push(dojo.connect.apply(dojo, arguments));	
+			this._cons.push(dojo.connect.apply(dojo, arguments));
 		},
 		disconnect: function(/*handle | Array*/handles){
 			// summary:
diff --git a/dojox/drawing/plugins/drawing/GreekPalette.js b/dojox/drawing/plugins/drawing/GreekPalette.js
new file mode 100644
index 0000000..b5b488c
--- /dev/null
+++ b/dojox/drawing/plugins/drawing/GreekPalette.js
@@ -0,0 +1,325 @@
+dojo.provide("dojox.drawing.plugins.drawing.GreekPalette");
+
+dojo.require("dojox.drawing.library.greek");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+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],
+	{
+	// summary:
+	//		This plugin uses the palette dijit in order to give
+	//		tips for non-english (mostly greek for now) letters.
+	// description:
+	//		Grid showing all available entity options which the
+	//		user can pick from.  The library loaded for use by the picker
+	//		is found in dojox.drawing.library.greek.  Adding characters
+	//		there will automatically add them to the palette.
+	//
+	//		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:
+	//
+	// example:
+	// |	<div dojoType="dojox.drawing.Drawing" id="drawing" jsId="myDrawing" class="drawing"
+	//			     plugins="[{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]" >
+
+	postMixInProperties: function(){
+		// Convert hash of entities into two-dimensional rows/columns table (array of arrays)
+		var choices = dojox.drawing.library.greek;
+		var numChoices = 0;
+		var entityKey;
+		for(entityKey in choices){numChoices++;}
+		var choicesPerRow = Math.floor(Math.sqrt(numChoices));
+		var numRows = choicesPerRow;
+		var currChoiceIdx = 0;
+		var rows = [];
+		var row = [];
+		for(entityKey in choices){
+			currChoiceIdx++;
+			row.push(entityKey);
+			if(currChoiceIdx % numRows === 0){
+				rows.push(row);
+				row = [];
+			}
+		}
+		if(row.length > 0){
+			rows.push(row);
+		}
+		this._palette = rows;
+	},
+	
+	onChange: function(val){
+		var textBlock = this._textBlock;
+		dijit.popup.close(this);
+		textBlock.insertText(this._pushChangeTo,val);
+		textBlock._dropMode = false;
+	},
+	
+	onCancel: function(/*Boolean*/ closeAll){
+		// summary:
+		//		attach point for notification about when the user cancels the current menu
+		dijit.popup.close(this);
+		this._textBlock._dropMode = false;
+	},
+	
+	id: "dropdown",
+
+	// templateString: String
+	//		The template of this widget.  Using dojoxEntityPalette classes
+	//		in order to allow easy transfer of css
+	templateString: '<div class="dojoxEntityPalette">\n' +
+			'	<table>\n' +
+			'		<tbody>\n' +
+			'			<tr>\n' +
+			'				<td>\n' +
+			'					<table class="dijitPaletteTable">\n' +
+			'						<tbody dojoAttachPoint="gridNode"></tbody>\n' +
+			'				   </table>\n' +
+			'				</td>\n' +
+			'			</tr>\n' +
+			'			<tr>\n' +
+			'				<td>\n'+
+			'					<table dojoAttachPoint="previewPane" class="dojoxEntityPalettePreviewTable">\n' +
+			'						<tbody>\n' +
+			'							<tr>\n' +
+			'								<td class="dojoxEntityPalettePreviewDetailEntity">Type: <span class="dojoxEntityPalettePreviewDetail" dojoAttachPoint="previewNode"></span></td>\n' +
+			'							</tr>\n' +
+			'						</tbody>\n' +
+			'					</table>\n' +
+			'				</td>\n' +
+			'			</tr>\n' +
+			'		</tbody>\n' +
+			'	</table>\n' +
+			'</div>',
+
+
+	baseClass: "dojoxEntityPalette",
+        
+        // showPreview: [public] Boolean
+	//	  Whether the preview pane will be displayed, to show details about the selected entity.
+	showPreview: true,
+
+	dyeClass: 'dojox.drawing.plugins.Greeks',
+
+	// domNodeClass [protected] String
+	paletteClass: 'editorLatinEntityPalette',
+
+	cellClass: "dojoxEntityPaletteCell",
+
+	buildRendering: function(){
+		this.inherited(arguments);
+
+		var i18n = dojo.i18n.getLocalization("dojox.editor.plugins", "latinEntities");
+
+		this._preparePalette(
+			this._palette,
+			i18n
+		);
+		
+		var cells = dojo.query(".dojoxEntityPaletteCell", this.gridNode);
+		dojo.forEach(cells, function(cellNode){
+			this.connect(cellNode, "onmouseenter", "_onCellMouseEnter");
+		}, this);
+	},
+        
+        _onCellMouseEnter: function(e){
+		// summary:
+		//		Simple function to handle updating the display at the bottom of
+		//		the palette.
+		// e:
+		//		The event.
+		// tags:
+		//		private
+		if(this.showPreview){
+			this._displayDetails(e.target);
+		}
+	},
+	
+	_onCellClick: function(/*Event*/ evt){
+		// summary:
+		//		Handler for click, enter key & space key. Selects the cell.
+		// evt:
+		//		The event.
+		// tags:
+		//		private
+		var target = evt.type == "click" ? evt.currentTarget : this._currentFocus,
+			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");
+
+		dojo.stopEvent(evt);
+	},
+
+	postCreate: function(){
+		this.inherited(arguments);
+
+		if(!this.showPreview){
+			dojo.style(this.previewNode,"display","none");
+		}
+	},
+
+	_setCurrent: function(/*DOMNode*/ node){
+		// summary:
+		//		Sets which node is the focused cell.
+		// description:
+   		//		At any point in time there's exactly one
+		//		cell with tabIndex != -1.   If focus is inside the palette then
+		// 		focus is on that cell.
+		//
+		//		After calling this method, arrow key handlers and mouse click handlers
+		//		should focus the cell in a setTimeout().
+		// tags:
+		//		protected
+		if("_currentFocus" in this){
+			// Remove tabIndex on old cell
+			dojo.attr(this._currentFocus, "tabIndex", "-1");
+			dojo.removeClass(this._currentFocus,"dojoxEntityPaletteCellHover");
+		}
+
+		// Set tabIndex of new cell
+		this._currentFocus = node;
+		if(node){
+			dojo.attr(node, "tabIndex", this.tabIndex);
+			dojo.addClass(this._currentFocus,"dojoxEntityPaletteCellHover");
+		}
+		if(this.showPreview){
+			this._displayDetails(node);
+		}
+	},
+
+	_displayDetails: function(/*DOMNode*/ cell){
+		// summary:
+		//	  Display the details of the currently focused entity in the preview pane
+		var dye = this._getDye(cell);
+		if(dye){
+			var ehtml = dye.getValue();
+			var ename = dye._alias;
+                        //console.warn("Greek help: ",dye._alias);
+			this.previewNode.innerHTML=ehtml;
+		}else{
+			this.previewNode.innerHTML="";
+			this.descNode.innerHTML="";
+		}
+	},
+	
+	_preparePalette: function(choices, titles) {
+		// summary:
+		//		Subclass must call _preparePalette() from postCreate(), passing in the tooltip
+		//		for each cell
+		// choices: String[][]
+		//		id's for each cell of the palette, used to create Dye JS object for each cell
+		// titles: String[]
+		//		Localized tooltip for each cell
+
+		this._cells = [];
+		var url = this._blankGif;
+		
+		var dyeClassObj = dojo.getObject(this.dyeClass);
+
+		for(var row=0; row < choices.length; row++){
+			var rowNode = dojo.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);
+					
+					var cellNode = dojo.create("td", {
+						"class": this.cellClass,
+						tabIndex: "-1",
+						title: titles[value]
+					});
+
+					// prepare cell inner structure
+					cellObject.fillCell(cellNode, url);
+
+					this.connect(cellNode, "ondijitclick", "_onCellClick");
+					this._trackMouseState(cellNode, this.cellClass);
+
+					dojo.place(cellNode, rowNode);
+
+					cellNode.index = this._cells.length;
+
+					// save cell info into _cells
+					this._cells.push({node:cellNode, dye:cellObject});
+				}
+			}
+		}
+		this._xDim = choices[0].length;
+		this._yDim = choices.length;
+		
+	},
+	
+	_navigateByArrow: function(evt){
+		// summary:
+		// 	  	This is a departure from the dijit, the textBlock needs
+		// 		navigation without losing focus, this allows that
+		// increment:
+		// 		How much the key is navigated.
+		// tags:
+		//		private
+		var keyIncrementMap = {
+			38: -this._xDim,
+			// The down key the index is increase by the x dimension.
+			40: this._xDim,
+			// Right and left move the index by 1.
+			39: this.isLeftToRight() ? 1 : -1,
+			37: this.isLeftToRight() ? -1 : 1
+		};
+		
+		var increment = keyIncrementMap[evt.keyCode];
+		var newFocusIndex = this._currentFocus.index + increment;
+		if(newFocusIndex < this._cells.length && newFocusIndex > -1){
+			var focusNode = this._cells[newFocusIndex].node;
+			this._setCurrent(focusNode);
+		}
+	}
+});
+
+dojo.declare("dojox.drawing.plugins.Greeks",
+        null,
+	{
+		// summary:
+		//		Represents a character.
+		//		Initialized using an alias for the character (like cent) rather
+		//		than with the character itself.
+
+ 		constructor: function(/*String*/ alias){
+			// summary:
+			//	 Construct JS object representing an entity (associated w/a cell
+			//		in the palette)
+			// value: String
+			//		alias name: 'cent', 'pound' ..
+			this._alias = alias;
+		},
+
+		getValue: function(){
+			// summary:
+			//   Returns HTML representing the character, like &
+			//
+			return this._alias;
+		},
+
+		fillCell: function(/*DOMNode*/ cell){
+			// Deal with entities that have keys which are reserved words.
+			cell.innerHTML = "&"+this._alias+";";
+                }
+});
\ No newline at end of file
diff --git a/dojox/drawing/plugins/drawing/Grid.js b/dojox/drawing/plugins/drawing/Grid.js
index a54aa35..24b730e 100755
--- a/dojox/drawing/plugins/drawing/Grid.js
+++ b/dojox/drawing/plugins/drawing/Grid.js
@@ -87,7 +87,7 @@ dojox.drawing.plugins.drawing.Grid = dojox.drawing.util.oo.declare(
 				x1 = mnr*i, x2 = x1;
 				clr = x1%mjr ? mn : mj;
 				createGridLine(x1,y1,x2,y2, clr);
-			}	
+			}
 		
 			s.moveToBack();
 			this.grid = s;
diff --git a/dojox/drawing/plugins/drawing/Silverlight.js b/dojox/drawing/plugins/drawing/Silverlight.js
index 596c9b7..a6baf4d 100755
--- a/dojox/drawing/plugins/drawing/Silverlight.js
+++ b/dojox/drawing/plugins/drawing/Silverlight.js
@@ -32,7 +32,7 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 			var conMouse = function(){
 				//console.info("------connect shape", item.id)
 				
-				// Connect to PARENT (SL Canvas) , not SHAPE 
+				// Connect to PARENT (SL Canvas) , not SHAPE
 				c1 = item.container.connect("onmousedown", function(evt){
 					//console.info("----------------------------------SHAPE DOWN", item.container)
 					evt.superTarget = item;
@@ -112,7 +112,7 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 			clearTimeout(this.__downInv);
 			if(this.util.attr(evt, "drawingType")=="surface"){
 				this.__downInv = setTimeout(dojo.hitch(this, function(){
-					this._down(evt);		
+					this._down(evt);
 				}),500);
 				return;
 			}
@@ -154,7 +154,7 @@ dojox.drawing.plugins.drawing.Silverlight = dojox.drawing.util.oo.declare(
 				if(elem.superTarget){
 					t = elem.superTarget;
 				}else if(elem.superClass){
-					t = elem.superClass; 
+					t = elem.superClass;
 				}else if(elem.target){
 					t = elem.target;
 				}else{
diff --git a/dojox/drawing/plugins/tools/Pan.js b/dojox/drawing/plugins/tools/Pan.js
index 465c9d2..5b9d78b 100755
--- a/dojox/drawing/plugins/tools/Pan.js
+++ b/dojox/drawing/plugins/tools/Pan.js
@@ -150,7 +150,7 @@ dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
 				mx = this.stencils.group ? this.stencils.group.getTransform() : {dx:0, dy:0},
 				sc = this.mouse.scrollOffset(),
 				// scY, scX: the scrollbar creates the need for extra dimension
-				scY = sc.left ? 10 : 0, 
+				scY = sc.left ? 10 : 0,
 				scX = sc.top ? 10 : 0,
 				// ch, cw: the current size of the canvas
 				ch = this.canvas.height,
@@ -184,7 +184,7 @@ dojox.drawing.plugins.tools.Pan = dojox.drawing.util.oo.declare(
 			b *= z;
 			var xscroll = 0, yscroll = 0;
 			log("Bottom test", "b:", b, "z:", z, "ch:", ch, "pch:", pch, "top:", sc.top, "sy:", sy, "mx.dy:", mx.dy);
-			if(b > pch || sc.top ){ 
+			if(b > pch || sc.top ){
 				log("*bottom scroll*");
 				// item off bottom
 				ch = Math.max(b, pch + sc.top);
diff --git a/dojox/drawing/resources/GreekPalette.css b/dojox/drawing/resources/GreekPalette.css
new file mode 100644
index 0000000..3b6015e
--- /dev/null
+++ b/dojox/drawing/resources/GreekPalette.css
@@ -0,0 +1,57 @@
+/*
+ This is directly from @import "../plugins/resources/css/InsertEntity.css";
+ It's here because certain details may change over time.  The classes
+ remain the same so applying the original will be easy in case of change.
+*/
+
+.dojoxEntityPalette {
+	/* outer node of the dropdown */
+	border: 1px solid #999;
+	background: #fff;
+	-moz-border-radius: 3pt;
+}
+
+.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 */
+	line-height: 18px;
+	overflow: hidden;
+	z-index: 10;
+	text-align: center;
+}
+
+.dojoxEntityPaletteCellHover, .dojoxEntityPaletteCellActive, .dojoxEntityPaletteCellFocused {
+	width: 18px;
+        line-height: 16px;
+	overflow: hidden;
+	cursor: default;
+	border:1px dashed #000;
+	outline:1px dashed #dedede;
+}
+
+
+.dojoxEntityPalettePreviewTable {
+	table-layout: auto;
+	font-size: 1em;
+	width: 100%;
+}
+
+.dojoxEntityPalettePreviewHeader {
+	font-size: .8em;
+	padding: 3px 3px 3px 3px;
+}
+
+.dojoxEntityPalettePreviewDetailEntity {
+	font-size: .8em;
+	font-weight: bold;
+}
+
+.dojoxEntityPalettePreviewDetail {
+	font-size: .8em;
+	padding: 3px 3px 3px 3px;
+}
+
+.dijit_a11y .dojoxEntityPaletteCell {
+	background-color:transparent !important;
+}
diff --git a/dojox/drawing/stencil/Ellipse.js b/dojox/drawing/stencil/Ellipse.js
index c84977e..f831b24 100755
--- a/dojox/drawing/stencil/Ellipse.js
+++ b/dojox/drawing/stencil/Ellipse.js
@@ -96,5 +96,5 @@ dojox.drawing.stencil.Ellipse = dojox.drawing.util.oo.declare(
 );
 
 dojox.drawing.register({
-	name:"dojox.drawing.stencil.Ellipse"	
+	name:"dojox.drawing.stencil.Ellipse"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/stencil/Image.js b/dojox/drawing/stencil/Image.js
index d81a39a..fdc13d2 100755
--- a/dojox/drawing/stencil/Image.js
+++ b/dojox/drawing/stencil/Image.js
@@ -151,5 +151,5 @@ StencilPoints: [
 
 
 dojox.drawing.register({
-	name:"dojox.drawing.stencil.Image"	
+	name:"dojox.drawing.stencil.Image"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/stencil/Line.js b/dojox/drawing/stencil/Line.js
index b24c3ab..32e5d1d 100755
--- a/dojox/drawing/stencil/Line.js
+++ b/dojox/drawing/stencil/Line.js
@@ -108,11 +108,11 @@ StencilPoints: [
 			this.renderHit && this._create("hit", this.data, this.style.currentHit);
 			this._create("shape", this.data, this.style.current);
 			
-		}		
+		}
 		
 	}
 );
 
 dojox.drawing.register({
-	name:"dojox.drawing.stencil.Line"	
+	name:"dojox.drawing.stencil.Line"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/stencil/Path.js b/dojox/drawing/stencil/Path.js
index 80e201d..3542c90 100755
--- a/dojox/drawing/stencil/Path.js
+++ b/dojox/drawing/stencil/Path.js
@@ -53,7 +53,7 @@ StencilPoints: [
 							if(o.x===undefined){// Z + undefined works here, but checking anyway
 								strAr.push(cmd);
 							}else{
-								strAr.push(cmd + o.x +" "+ o.y); 
+								strAr.push(cmd + o.x +" "+ o.y);
 							}
 						}
 					}
@@ -165,5 +165,5 @@ StencilPoints: [
 );
 
 dojox.drawing.register({
-	name:"dojox.drawing.stencil.Path"	
+	name:"dojox.drawing.stencil.Path"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/stencil/Rect.js b/dojox/drawing/stencil/Rect.js
index c369a16..79e29af 100755
--- a/dojox/drawing/stencil/Rect.js
+++ b/dojox/drawing/stencil/Rect.js
@@ -78,5 +78,5 @@ dojox.drawing.stencil.Rect = dojox.drawing.util.oo.declare(
 );
 
 dojox.drawing.register({
-	name:"dojox.drawing.stencil.Rect"	
+	name:"dojox.drawing.stencil.Rect"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/stencil/Text.js b/dojox/drawing/stencil/Text.js
index 841509e..cdbfbf9 100755
--- a/dojox/drawing/stencil/Text.js
+++ b/dojox/drawing/stencil/Text.js
@@ -72,9 +72,9 @@ StencilPoints: [
 			//		Uses function dojox.drawing.stencil.Text.typeset
 			//		for typesetting, if it exists.
 			//
-			if(dojox.drawing.stencil.Text.typeset){
+			if(dojox.drawing.util.typeset){
 				this._rawText = text;
-				return dojox.drawing.stencil.Text.typeset(text);
+				return dojox.drawing.util.typeset.convertLaTeX(text);
 			}
 			return text;
 		},
@@ -99,7 +99,7 @@ StencilPoints: [
 			// summary:
 			//		Getter for text.
 			//
-			return this._rawText || this._text;	
+			return this._rawText || this._text;
 		},
 		
 		dataToPoints: function(/*Object*/o){
@@ -146,9 +146,9 @@ StencilPoints: [
 			this.remove(this.shape, this.hit);
 			//console.log("text render, outline:", !this.annotation, this.renderHit, (!this.annotation && this.renderHit))
 			!this.annotation && this.renderHit && this._renderOutline();
-			if(text){
+			if(text!=undefined){
 				this._text = text;
-				this._textArray = this._text.split("\n");	
+				this._textArray = this._text.split("\n");
 			}
 			
 			var d = this.pointsToData();
@@ -224,5 +224,5 @@ StencilPoints: [
 	}
 );
 dojox.drawing.register({
-	name:"dojox.drawing.stencil.Text"	
+	name:"dojox.drawing.stencil.Text"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/stencil/_Base.js b/dojox/drawing/stencil/_Base.js
index 307d756..2b57eeb 100755
--- a/dojox/drawing/stencil/_Base.js
+++ b/dojox/drawing/stencil/_Base.js
@@ -364,9 +364,7 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		only fire once. But the mechanism for determining
 			//		this is more complicated than it sounds.
 			//
-			//if(!this._postRenderCon){
-				this._postRenderCon = dojo.connect(this, "render", this, "_onPostRender");
-			//}
+			this._postRenderCon = dojo.connect(this, "render", this, "_onPostRender");
 			this.created = true;
 			this.disconnectMouse();
 
@@ -860,11 +858,11 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 					container:this.container,
 					labelPosition:this.labelPosition
 				});
-			}else if(text){
+			}else if(text!=undefined){
 				this._label.setLabel(text);
 			}
 		},
-
+		
 		getLabel: function(){
 			// summary:
 			//		Get the text of the label.
@@ -1034,7 +1032,8 @@ dojox.drawing.stencil._Base = dojox.drawing.util.oo.declare(
 			//		"onStencilUp". To disable the selectability,
 			//		make the att "", which causes a standard
 			//		mouse event.
-			var att = this.enabled && !this.annotation ? this.drawingType : "";
+			//		Labels are special and used to select master stencils.
+			var att = this.enabled && (!this.annotation || this.drawingType=="label") ? this.drawingType : "";
 			this.util.attr(shape, "drawingType", att);
 		},
 
diff --git a/dojox/drawing/tests/drawing.html b/dojox/drawing/tests/drawing.html
index a59f76d..0af4766 100755
--- a/dojox/drawing/tests/drawing.html
+++ b/dojox/drawing/tests/drawing.html
@@ -1,10 +1,11 @@
 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
 <head>
     <title>Drawing Test</title>
-	<link href="../resources/drawing.css" rel="stylesheet" />
-	<link href="../resources/toolbar.css" rel="stylesheet" />
-
 	<style>
+		@import url("../../../dijit/themes/dijit.css");
+		@import url("../../../dojox/drawing/resources/drawing.css");
+		@import url("../../../dojox/drawing/resources/toolbar.css");
+		@import url("../../../dojox/drawing/resources/GreekPalette.css");
 		href, body{
 		}
 		.drawing{
@@ -57,6 +58,7 @@
 		dojo.require("dojox.drawing.ui.dom.Pan");
 		dojo.require("dojox.drawing.ui.dom.Zoom");
 		dojo.require("dojox.drawing.plugins.drawing.Grid");
+		dojo.require("dojox.drawing.plugins.drawing.GreekPalette");
 
 
 		var doExport = function(){
@@ -160,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}}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}},{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]">
 
 		</div>
 	</div>
diff --git a/dojox/drawing/tests/test_drawing.html b/dojox/drawing/tests/test_drawing.html
index 06d76f4..0948e14 100644
--- a/dojox/drawing/tests/test_drawing.html
+++ b/dojox/drawing/tests/test_drawing.html
@@ -1,10 +1,11 @@
 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
 <head>
     <title>Drawing GFX Toolbar Test</title>
-	<link href="../resources/drawing.css" rel="stylesheet" />
-	<link href="../resources/toolbar.css" rel="stylesheet" />
-
 	<style>
+		@import url("../../../dijit/themes/dijit.css");
+		@import url("../../../dojox/drawing/resources/drawing.css");
+		@import url("../../../dojox/drawing/resources/toolbar.css");
+		@import url("../../../dojox/drawing/resources/GreekPalette.css");
 		href, body{
 		}
 		.drawing{
@@ -61,8 +62,9 @@
 		dojo.require("dojox.drawing.plugins.tools.Zoom");
 		dojo.require("dojox.drawing.plugins.tools.Iconize");
 
+		dojo.require("dojox.drawing.plugins.drawing.GreekPalette");
 		dojo.require("dojox.drawing.plugins.drawing.Grid");
-
+		
 		dojo.require("dojox.drawing.ui.Toolbar");
 		dojo.require("dojox.drawing.ui.Button");
 		//dojo.require("dojox.drawing.ui.Tooltip");
@@ -89,7 +91,7 @@
 					drawing:myDrawing,
 					tools:"all",
 					plugs:"all",
-					selected:"ellipse",
+					selected:"",
 					size:30,
 					radius:2,
 					margin:5
@@ -136,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}}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}},{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]">
 		</div>
 	</div>
 
diff --git a/dojox/drawing/tests/test_drawing_toolbar.html b/dojox/drawing/tests/test_drawing_toolbar.html
index 70ed70b..08c51da 100644
--- a/dojox/drawing/tests/test_drawing_toolbar.html
+++ b/dojox/drawing/tests/test_drawing_toolbar.html
@@ -1,10 +1,11 @@
 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
 <head>
     <title>Drawing Test</title>
-	<link href="../resources/drawing.css" rel="stylesheet" />
-	<link href="../resources/toolbar.css" rel="stylesheet" />
-
 	<style>
+		@import url("../../../dijit/themes/dijit.css");
+		@import url("../../../dojox/drawing/resources/drawing.css");
+		@import url("../../../dojox/drawing/resources/toolbar.css");
+		@import url("../../../dojox/drawing/resources/GreekPalette.css");
 		href, body{
 			overflow:hidden;
 		}
@@ -76,6 +77,7 @@
 		dojo.require("dojox.drawing.plugins.tools.Pan");
 		dojo.require("dojox.drawing.plugins.tools.Zoom");
 		dojo.require("dojox.drawing.plugins.drawing.Grid");
+		dojo.require("dojox.drawing.plugins.drawing.GreekPalette");
 		
 		dojo.require("dojox.drawing.ui.Toolbar");
 		dojo.require("dojox.drawing.ui.Button");
@@ -93,7 +95,7 @@
 		<div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode" class="gfxToolbar" tools="all" plugs="all" selected="ellipse"></div>
 		
 		<div dojoType="dojox.drawing.Drawing" id="drawingNode" jsId="myDrawing" class="drawing"
-			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{gap:100}},{'name':'dojox.drawing.plugins.drawing.GreekPalette'}]">
 		</div>
 	</div>
 	
diff --git a/dojox/drawing/tests/test_paths.html b/dojox/drawing/tests/test_paths.html
index 49306cd..ffd4235 100644
--- a/dojox/drawing/tests/test_paths.html
+++ b/dojox/drawing/tests/test_paths.html
@@ -1,10 +1,11 @@
 <html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" >
 <head>
     <title>Drawing Paths Test</title>
-	<link href="../resources/drawing.css" rel="stylesheet" />
-	<link href="../resources/toolbar.css" rel="stylesheet" />
-
 	<style>
+		@import url("../../../dijit/themes/dijit.css");
+		@import url("../../../dojox/drawing/resources/drawing.css");
+		@import url("../../../dojox/drawing/resources/toolbar.css");
+		@import url("../../../dojox/drawing/resources/GreekPalette.css");
 		href, body{
 			overflow:hidden;
 		}
@@ -54,6 +55,7 @@
 		dojo.require("dojox.drawing.tools.Path");
 		dojo.require("dojox.drawing.tools.Pencil");
 		
+		dojo.require("dojox.drawing.plugins.drawing.GreekPalette");
 		dojo.require("dojox.drawing.plugins.drawing.Grid");
 		
 		dojo.require("dojox.drawing.ui.Toolbar");
@@ -99,16 +101,16 @@
 	</script>
 
 </head>
-<body>
+<body class="tundra">
     <h2>Drawing Paths Test</h2>
 	<div id="conEdit" contenteditable="true"></div>
 	<div id="wrapper">
 		
 		
-		<div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode" class="gfxToolbar" tools="all" plugs="all" selected="pencil"></div>
+		<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.Grid', 'options':{minor:20, major:100}}]">
+			 plugins="[{'name':'dojox.drawing.plugins.drawing.GreekPalette'},{'name':'dojox.drawing.plugins.drawing.Grid', 'options':{minor:20, major:100}}]">
 		</div>
 	</div>
 	
diff --git a/dojox/drawing/tools/Arrow.js b/dojox/drawing/tools/Arrow.js
index da84a1c..c874f75 100755
--- a/dojox/drawing/tools/Arrow.js
+++ b/dojox/drawing/tools/Arrow.js
@@ -15,7 +15,11 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 			this.endArrow = new dojox.drawing.annotations.Arrow({stencil:this, idx1:1, idx2:0});
 		}
 		if(this.points.length){
+			// This is protecting against cases when there are no points
+			// not sure how that would ever happen
+			// Render & label here instead of in base because of Arrow annotation
 			this.render();
+			options.label && this.setLabel(options.label);
 		}
 	},
 	{
@@ -31,6 +35,17 @@ dojox.drawing.tools.Arrow = dojox.drawing.util.oo.declare(
 		//		Whether or not to place an arrow on end.
 		arrowEnd:true,
 		
+		labelPosition: function(){
+			// summary:
+			//		The custom position used for the label
+			//
+			var d = this.data;
+			var pt = dojox.drawing.util.positioning.label({x:d.x1,y:d.y1},{x:d.x2,y:d.y2});
+			return {
+				x:pt.x,
+				y:pt.y
+			}
+		},
 		
 		onUp: function(/*EventObject*/obj){
 			// summary: See stencil._Base.onUp
diff --git a/dojox/drawing/tools/Ellipse.js b/dojox/drawing/tools/Ellipse.js
index e7cb627..93ee548 100755
--- a/dojox/drawing/tools/Ellipse.js
+++ b/dojox/drawing/tools/Ellipse.js
@@ -70,7 +70,7 @@ dojox.drawing.tools.Ellipse = dojox.drawing.util.oo.declare(
 
 dojox.drawing.tools.Ellipse.setup = {
 	// summary: See stencil._Base ToolsSetup
-	//	
+	//
 	name:"dojox.drawing.tools.Ellipse",
 	tooltip:"Ellipse Tool",
 	iconClass:"iconEllipse"
diff --git a/dojox/drawing/tools/Line.js b/dojox/drawing/tools/Line.js
index 45138f3..8db1f45 100755
--- a/dojox/drawing/tools/Line.js
+++ b/dojox/drawing/tools/Line.js
@@ -15,12 +15,12 @@ dojox.drawing.tools.Line = dojox.drawing.util.oo.declare(
 			//	Overwrites _Base.onTransformEnd
 			//
 			this._toggleSelected();
-			if(this.getRadius()<this.minimumSize){ 
-				var p = this.points; 
-				this.setPoints([ 
-					{x:p[0].x, y:p[0].y}, 
-					{x:p[0].x, y:p[0].y} 
-				]); 
+			if(this.getRadius()<this.minimumSize){
+				var p = this.points;
+				this.setPoints([
+					{x:p[0].x, y:p[0].y},
+					{x:p[0].x, y:p[0].y}
+				]);
 			}else{
 				var d = this.data;
 				var obj = {start:{x:d.x1,y:d.y1},x:d.x2,y:d.y2};
diff --git a/dojox/drawing/tools/Path.js b/dojox/drawing/tools/Path.js
index e3202e1..55f9584 100644
--- a/dojox/drawing/tools/Path.js
+++ b/dojox/drawing/tools/Path.js
@@ -17,7 +17,7 @@ dojox.drawing.tools.Path = dojox.drawing.util.oo.declare(
 	{
 		draws:true,
 		onDown: function(obj){
-			if(!this._started){ 
+			if(!this._started){
 				this.onStartPath(obj);
 			}
 			
@@ -57,15 +57,15 @@ dojox.drawing.tools.Path = dojox.drawing.util.oo.declare(
 				
 				switch(evt.letter){
 					case "c":
-						this.onCompletePath(true); break;		
+						this.onCompletePath(true); break;
 					case "l": this.pathMode = "L"; break;
-					case "m": this.makeSubPath(false); break;		
-					case "q": this.pathMode = "Q"; break;		
+					case "m": this.makeSubPath(false); break;
+					case "q": this.pathMode = "Q"; break;
 					case "s": this.pathMode = "S"; break;
 					case "z": this.makeSubPath(true); break;
 				}
 				 
-				//console.log("KEY:", evt.letter);	
+				//console.log("KEY:", evt.letter);
 			});
 		},
 		
diff --git a/dojox/drawing/tools/TextBlock.js b/dojox/drawing/tools/TextBlock.js
index af8b1e6..1d984b1 100755
--- a/dojox/drawing/tools/TextBlock.js
+++ b/dojox/drawing/tools/TextBlock.js
@@ -2,7 +2,6 @@ dojo.provide("dojox.drawing.tools.TextBlock");
 dojo.require("dojox.drawing.stencil.Text");
 
 (function(){
-	
 	var conEdit;
 	dojo.addOnLoad(function(){
 		//		In order to use VML in IE, it's necessary to remove the
@@ -12,6 +11,7 @@ dojo.require("dojox.drawing.stencil.Text");
 		//		that can be appended and removed as necessary:
 		//		<div id="conEdit" contenteditable="true"></div>
 		//
+		// console.log("Removing conedit");
 		conEdit = dojo.byId("conEdit");
 		if(!conEdit){
 			console.error("A contenteditable div is missing from the main document. See 'dojox.drawing.tools.TextBlock'")
@@ -44,13 +44,10 @@ dojo.require("dojox.drawing.stencil.Text");
 			//
 			if(options.data){
 				var d = options.data;
-				var text = d.text;
-				var w = !d.width ? this.style.text.minWidth : d.width=="auto" ? "auto" : Math.max(d.width, this.style.text.minWidth)
+				var text = d.text ? this.typesetter(d.text) : d.text;
+				var w = !d.width ? this.style.text.minWidth : d.width=="auto" ? "auto" : Math.max(d.width, this.style.text.minWidth);
 				var h = this._lineHeight;
 				
-				// need to typeset before measuring width
-				text = this.typesetter(text);
-				
 				if(text && w=="auto"){
 					var o = this.measureText(this.cleanText(text, false), w);
 					w = o.w;
@@ -85,9 +82,12 @@ dojo.require("dojox.drawing.stencil.Text");
 						this.render(text);
 					}
 					setTimeout(dojo.hitch(this, function(){
-						this.editMode = false;	
+						this.editMode = false;
 					}),100)
 					
+				}else{
+					// Why make it if it won't render...
+					this.render();
 				}
 				
 			}else{
@@ -100,6 +100,9 @@ dojo.require("dojox.drawing.stencil.Text");
 			draws:true,
 			baseRender:false,
 			type:"dojox.drawing.tools.TextBlock",
+			_caretStart: 0,
+			_caretEnd: 0,
+			_blockExec: false,
 			
 /*=====
 StencilData: {
@@ -121,7 +124,7 @@ StencilData: {
 			
 			// selectOnExec: Boolean
 			//		Whether the Stencil is selected when the text field
-			//		is executed or not	
+			//		is executed or not
 			selectOnExec:true,
 			//
 			// showEmpty: Boolean
@@ -152,7 +155,7 @@ StencilData: {
 				
 				var c = dojo.connect(this, "render", this, function(){
 					dojo.disconnect(c);
-					this.onRender(this);	
+					this.onRender(this);
 					
 				});
 				this.editMode = true;
@@ -216,7 +219,7 @@ StencilData: {
 				// In Safari, if the txt ends with '&' it gets stripped
 				conEdit.innerHTML = txt || "";
 				
-				return conEdit; //HTMLNade
+				return conEdit; //HTMLNode
 			},
 			connectTextField: function(){
 				// summary:
@@ -224,11 +227,17 @@ StencilData: {
 				//		contenteditable HTML node.
 				//
 				if(this._textConnected){ return; } // good ol' IE and its double events
+				// FIXME:
+				// Ouch-getting dropdown by id.  At the minimum this should
+				// be from the plugin manager
+				var dropdown = dijit.byId("dropdown");
 				this._textConnected = true;
+				this._dropMode = false;
 				this.mouse.setEventMode("TEXT");
 				this.keys.editMode(true);
 				var kc1, kc2, kc3, kc4, self = this, _autoSet = false,
 					exec = function(){
+						if(self._dropMode){ return; }
 						dojo.forEach([kc1,kc2,kc3,kc4], function(c){
 							dojo.disconnect(c)
 						});
@@ -247,26 +256,77 @@ StencilData: {
 						dojo.style(conEdit, "height", this._lineHeight+"px"); _autoSet = false;
 					}
 					
-					
-					if(evt.keyCode==13 || evt.keyCode==27){
-						dojo.stopEvent(evt);
-						exec();
+					if(!this._blockExec){
+						if(evt.keyCode==13 || evt.keyCode==27){
+							dojo.stopEvent(evt);
+							exec();
+						}
+					} else {
+						if(evt.keyCode==dojo.keys.SPACE){
+							dojo.stopEvent(evt);
+							dropdown.onCancel();
+						}
 					}
 				});
 				kc2 = dojo.connect(conEdit, "keydown", this, function(evt){
 					if(evt.keyCode==13 || evt.keyCode==27){ // TODO: make escape an option
 						dojo.stopEvent(evt);
 					}
+					//	if backslash, user is inputting a special character
+					//	This gives popup help.
+					if(evt.keyCode==220){
+						if(dropdown==undefined){
+							console.warn("Dropdown not found");
+							return;
+						}
+						dojo.stopEvent(evt);
+						this.getSelection(conEdit);
+						// Differences in how browsers handle events made it necessary
+						// to stop the evt and add the backslash here.
+						this.insertText(conEdit,"\\");
+						this._dropMode = true;
+						this._blockExec = true;
+						dropdown._pushChangeTo = conEdit;
+						dropdown._textBlock = this;
+						dijit.popup.open({
+							parent:this.parentNode,
+							popup:dropdown,
+							around:this.parentNode,
+							orient:{'BL':'TL'}
+						});
+					}
+					if(!this._dropMode){
+						this._blockExec = false;
+					} else {
+						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);
+								break;
+							case dojo.keys.ENTER:
+								dojo.stopEvent(evt);
+								dropdown._onCellClick(evt);
+								break;
+							case dojo.keys.BACKSPACE:
+							case dojo.keys.DELETE:
+								dojo.stopEvent(evt);
+								dropdown.onCancel();
+								break;
+						}
+					}
+					
 				});
 				
 				kc3 = dojo.connect(document, "mouseup", this, function(evt){
 					// note: _onAnchor means an anchor has been clicked upon
-					
 					if(!this._onAnchor && evt.target.id != "conEdit"){
 						dojo.stopEvent(evt);
 						exec();
-					}else{
-						// wonky stuff happens when you click on the 
+					}else if(evt.target.id == "conEdit" && conEdit.innerHTML == ""){
+						// wonky stuff happens when you click on the
 						// field when its empty.
 						conEdit.blur();
 						setTimeout(function(){
@@ -301,10 +361,11 @@ StencilData: {
 							exec();
 							self.onUp = function(){}
 						}
-					}	
+					}
 				}), 500);
 			},
 			
+			
 			execText: function(){
 				// summary:
 				//		Internal. Method fired when text is executed,
@@ -349,8 +410,8 @@ StencilData: {
 					this._text = "";
 					this._textArray = [];
 				}
-				this.render(o.text);
 				// Only for Combo objects (vectors, rectangle, or ellipse).
+				this.render(o.text);
 				this.onChangeText(this.getText());
 			},
 			
@@ -425,7 +486,7 @@ StencilData: {
 				// arguments:
 				//		str: String
 				//			The text to display and measure.
-				//		width: [optional] Number 
+				//		width: [optional] Number
 				//			If the width is not provided, it will be assumed
 				//			that the text is one line and the width will be
 				//			measured and the _lineHeight used for th height.
@@ -472,7 +533,7 @@ StencilData: {
 					
 					dojo.forEach(strAr, function(ar, i){
 						strAr[i] = ar.join(" ");
-					});	
+					});
 					txt = strAr.join("\n");
 					
 					// get the resultant height
@@ -584,19 +645,96 @@ StencilData: {
 				for(var n in this._anchors){
 					dojo.forEach(this._anchors[n].con, dojo.disconnect, dojo);
 					dojo.destroy(this._anchors[n].a);
+				};
+			},
+			
+			setSavedCaret: function(val){
+				// summary:
+				//		Internal, called when caret needs to
+				//		be moved into position after text is added
+				this._caretStart = this._caretEnd = val;
+			},
+			
+			getSavedCaret: function(){
+				return {start: this._caretStart, end: this._caretEnd}
+			},
+			
+			insertText: function(node,val){
+				// summary:
+				//		Uses saved caret position to insert text
+				//		into position and place caret at the end of
+				//		insertion
+				//
+				var t, text = node.innerHTML;
+				var caret = this.getSavedCaret();
+				
+				text = text.replace(/ /g, " ");
+				t = text.substr(0,caret.start) + val + text.substr(caret.end);
+				t = this.cleanText(t,true);
+				this.setSavedCaret(Math.min(t.length,(caret.end + val.length)));
+				node.innerHTML = t;
+				this.setSelection(node,"stored");
+			},
+			
+			getSelection: function(node){
+				// summary:
+				//		This gets and stores the caret position
+				//		in the contentEditable div (conEdit).
+				//		NOTE: Doesn't work with html nodes inside
+				//		the div.
+				//
+				var start, end;
+				if(dojo.doc.selection){
+					//debugger;
+					var r = dojo.doc.selection.createRange();
+					var rs = dojo.body().createTextRange();
+					rs.moveToElementText(node);
+					var re = rs.duplicate();
+					rs.moveToBookmark(r.getBookmark());
+					re.setEndPoint('EndToStart', rs);
+					start = this._caretStart = re.text.length;
+					end = this._caretEnd = re.text.length+r.text.length;
+					console.warn("Caret start: ",start," end: ",end," length: ",re.text.length," text: ",re.text);
+				} else {
+					this._caretStart = dojo.global.getSelection().getRangeAt(node).startOffset;
+					this._caretEnd = dojo.global.getSelection().getRangeAt(node).endOffset;
+					console.log("Caret start: ", this._caretStart," end: ", this._caretEnd);
 				}
 			},
+			
 			setSelection: function(node, what){
 				// summary:
-				//		Used for placing the cursor at the end of the
-				//		text on edit.
+				//		Used for placing the cursor during edits and character help.
+				//		Takes the values: end, beg, start, all or any numerical value
+				//		(in which case the number will constitute the caret position)
 				//
 				console.warn("setSelection:");
 				if(dojo.doc.selection){ // IE
-					var r = dojo.body().createTextRange();
-					r.moveToElementText(node);
-					r.collapse(false);
-					r.select();
+					//debugger;
+					var rs = dojo.body().createTextRange();
+					rs.moveToElementText(node);
+					
+					switch(what){
+						case "end":
+							rs.collapse(false);
+							break;
+						case "beg" || "start":
+							rs.collapse();
+							break;
+						case "all":
+							rs.collapse();
+							rs.moveStart("character", 0);
+							rs.moveEnd("character",node.text.length);
+							break;
+						case "stored":
+							rs.collapse();
+							var dif = this._caretStart-this._caretEnd;
+							//console.log("start: ",this._caretStart, " end: ",this._caretEnd," dif: ",dif);
+							rs.moveStart("character",this._caretStart);
+							rs.moveEnd("character",dif);
+							break;
+					};
+					rs.select();
 					
 				}else{
 					var getAllChildren = function(node, children){
@@ -607,11 +745,11 @@ StencilData: {
 								children.push(n);
 							}else if(n.tagName && n.tagName.toLowerCase()=="img"){
 								children.push(n);
-							}
-							
+							};
+								
 							if(n.childNodes && n.childNodes.length){
 								getAllChildren(n, children);
-							}
+							};
 						}
 						return children;
 					};
@@ -619,27 +757,29 @@ StencilData: {
 					node.focus();
 					var selection = dojo.global.getSelection();
 					selection.removeAllRanges();
-					console.log(1);
-					r = dojo.doc.createRange();
-					r.selectNodeContents(node);
-					console.log(2);
+					var r = dojo.doc.createRange();
 					var nodes = getAllChildren(node);
-					console.log(3);
-					if(what == "end"){
-						console.log("len:", nodes[nodes.length - 1].textContent.length);
-						r.setStart(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
-						r.setEnd(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
-					}else if(what=="beg" || what == "start"){
-						r.setStart(nodes[0], 0);
-						r.setEnd(nodes[0], 0);
-					}else if(what=="all"){
-						r.setStart(nodes[0], 0);
-						r.setEnd(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
+					switch(what){
+						case "end":
+							console.log("len:", nodes[nodes.length - 1].textContent.length);
+							r.setStart(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
+							r.setEnd(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
+							break;
+						case "beg" || "start":
+							r.setStart(nodes[0], 0);
+							r.setEnd(nodes[0], 0);
+							break;
+						case "all":
+							r.setStart(nodes[0], 0);
+							r.setEnd(nodes[nodes.length - 1], nodes[nodes.length - 1].textContent.length);
+							break;
+						case "stored":
+							console.log("Caret start: ",this._caretStart," caret end: ",this._caretEnd);
+							r.setStart(nodes[0], this._caretStart);
+							r.setEnd(nodes[0], this._caretEnd);
 					}
-					
 					selection.addRange(r);
-					
-					console.log("sel ", what, " on ", node)
+					console.log("sel ", what, " on ", node);
 				}
 			}
 		}
@@ -654,4 +794,4 @@ StencilData: {
 	};
 	dojox.drawing.register(dojox.drawing.tools.TextBlock.setup, "tool");
 	
-})();
\ No newline at end of file
+})();
diff --git a/dojox/drawing/tools/custom/Axes.js b/dojox/drawing/tools/custom/Axes.js
index 4e8875e..69b085e 100755
--- a/dojox/drawing/tools/custom/Axes.js
+++ b/dojox/drawing/tools/custom/Axes.js
@@ -91,8 +91,8 @@ dojox.drawing.tools.custom.Axes = dojox.drawing.util.oo.declare(
 				{x:z.x, y:z.y}
 			];
 			var len = this.util.length({start:{x:c.x, y:c.y}, x:z.x, y:z.y});
-			len > this.zAxis.minimumSize ? this.zAxis.setPoints(p) : false; 
-			this.zAxis.cosphi = 1; 
+			len > this.zAxis.minimumSize ? this.zAxis.setPoints(p) : false;
+			this.zAxis.cosphi = 1;
 		},
 		
 		createLabels: function(){
diff --git a/dojox/drawing/tools/custom/Vector.js b/dojox/drawing/tools/custom/Vector.js
index 4f2bd40..65ab116 100755
--- a/dojox/drawing/tools/custom/Vector.js
+++ b/dojox/drawing/tools/custom/Vector.js
@@ -10,8 +10,6 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 	//		head is only at the end. There is additionaly functionality
 	//		to allow for a 'zero vector' - one with no length.
 	//
-	// 	TODO: Zero Vectors are less than the minimumSize. But if
-	//	you get the radius, it will report a length.
 	//
 	dojox.drawing.tools.Arrow,
 	function(options){
@@ -24,17 +22,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 		minimumSize:30,
 		showAngle:true,
 		
-		labelPosition: function(){
-			// summary:
-			//		The custom position used for the label
-			//
-			var d = this.data;
-			var pt = dojox.drawing.util.positioning.label({x:d.x1,y:d.y1},{x:d.x2,y:d.y2});
-			return {
-				x:pt.x,
-				y:pt.y
-			}
-		},
+		
 		
 		changeAxis: function(cosphi){
 			//	summary:
@@ -143,7 +131,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			// is for stencil move:
 			
 			this.setPoints(this.points);
-			this.render();			
+			this.render();
 		},
 		
 		anchorConstrain: function(x, y){
@@ -153,7 +141,7 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 			var radians = this.style.zAngle*Math.PI/180;
 			//Constrain to angle
 			var test = x<0 ? x>-y : x<-y;
-			var dx = test ? x : -y/Math.tan(radians); 
+			var dx = test ? x : -y/Math.tan(radians);
 			var dy = !test ? y : -Math.tan(radians)*x;
 			return {x:dx, y:dy}
 		},
@@ -270,17 +258,15 @@ dojox.drawing.tools.custom.Vector = dojox.drawing.util.oo.declare(
 				this.render();
 			}
 			
-			// if too small, need to reset
-			// 		This sets the zero length vector to zero within the minimum size 
-			
+			// When within minimum size this sets zero vector length to zero
 			if(this.getRadius()<this.minimumSize){
-				var p = this.points; 
-				this.setPoints([ 
-					{x:p[0].x, y:p[0].y}, 
-					{x:p[0].x, y:p[0].y} 
-				]); 
-			}else{ 			
-				//needed as else to avoid zero length problem in snapAngle 
+				var p = this.points;
+				this.setPoints([
+					{x:p[0].x, y:p[0].y},
+					{x:p[0].x, y:p[0].y}
+				]);
+			}else{
+				//SnapAngle fails for the zero length vector
 				var p = this.points;
 				var pt = this.style.zAxis ? this.zPoint(obj) : this.util.snapAngle(obj, this.angleSnap/180);
 				this.setPoints([
@@ -308,7 +294,7 @@ if(dojox.drawing.defaults.zAxisEnabled){
 		// summary:
 		//		Creates a secondary tool for the Vector Stencil.
 		// description:
-		//		See Toolbar.js makeButtons function.  The toolbar 
+		//		See Toolbar.js makeButtons function.  The toolbar
 		//		checks Vector.setup for a secondary tool and requires
 		//		name, label, and funct.  Currently it doesn't accept icon
 		//		and only uses text from label for the button.  Funct is the
@@ -360,7 +346,7 @@ if(dojox.drawing.defaults.zAxisEnabled){
 				dojo.forEach(this.buttons, function(b){
 					if(b.toolType=="vector" && b.selected){
 						this.drawing.currentStencil.style.zAxis = zAxis;
-					} 
+					}
 				},this);
 			};
 			dojo.connect(this, "onRenderStencil", this, function(){ if(this.zSelected){ this.zDeselect(this.zSelected)}});
diff --git a/dojox/drawing/ui/Button.js b/dojox/drawing/ui/Button.js
index 7c34225..8b79e65 100644
--- a/dojox/drawing/ui/Button.js
+++ b/dojox/drawing/ui/Button.js
@@ -189,7 +189,7 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 		
 		_change: function(/*Object*/sty){
 			this.shape.attr(sty);
-			this.shape.shadow && this.shape.shadow.container.moveToBack();	
+			this.shape.shadow && this.shape.shadow.container.moveToBack();
 			if(this.icon){this.icon.shape.moveToFront();};
 		},
 		onOver: function(){
@@ -217,10 +217,10 @@ dojox.drawing.ui.Button =  dojox.drawing.util.oo.declare(
 		attr: function(options){
 			if(this.icon){this.icon.attr(options);}
 		}
-	}	
+	}
 	
 );
 
 dojox.drawing.register({
-	name:"dojox.drawing.ui.Button"	
+	name:"dojox.drawing.ui.Button"
 }, "stencil");
\ No newline at end of file
diff --git a/dojox/drawing/ui/Toolbar.js b/dojox/drawing/ui/Toolbar.js
index b2dc25e..b2ea79a 100644
--- a/dojox/drawing/ui/Toolbar.js
+++ b/dojox/drawing/ui/Toolbar.js
@@ -23,7 +23,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 	//		|	});
 	//
 	//		| <div dojoType="dojox.drawing.ui.Toolbar" id="gfxToolbarNode" drawingId="drawingNode"
-	//		|		class="gfxToolbar" tools="all" plugs="all" selected="ellipse"></div>
+	//		|		class="gfxToolbar" tools="all" plugs="all" selected="ellipse" orient="H"></div>
 	//
 	//
 	constructor: function(props, node){
@@ -41,7 +41,8 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 			this.strTools = props.tools;
 			this.strPlugs = props.plugs;
 			this._mixprops(["padding", "margin", "size", "radius"], props);
-			this.addBack()
+			this.addBack();
+			this.orient = props.orient ? props.orient : false;
 		}else{
 			// markup
 			var box = dojo.marginBox(node);
@@ -52,10 +53,11 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 			this.strPlugs = dojo.attr(node, "plugs");
 			this._mixprops(["padding", "margin", "size", "radius"], node);
 			this.toolDrawing = new dojox.drawing.Drawing({mode:"ui"}, node);
+			this.orient = dojo.attr(node, "orient");
 		}
 		
-		this.horizontal = this.width > this.height;
-		
+		this.horizontal = this.orient ? this.orient == "H" : this.width > this.height;
+		console.log("this.hor: ",this.horizontal," orient: ",this.orient);
 		if(this.toolDrawing.ready){
 			this.makeButtons();
 			if(!this.strSelected && this.drawing.defaults.clickMode){ this.drawing.mouse.setCursor('default'); };
@@ -63,12 +65,12 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 			var c = dojo.connect(this.toolDrawing, "onSurfaceReady", this, function(){
 				//console.log("TB built")
 				dojo.disconnect(c);
-				this.drawing = dojox.drawing.getRegistered("drawing", dojo.attr(node, "drawingId")); // 
+				this.drawing = dojox.drawing.getRegistered("drawing", dojo.attr(node, "drawingId")); //
 				this.makeButtons();
-				if(!this.strSelected && this.drawing.defaults.clickMode){ 
+				if(!this.strSelected && this.drawing.defaults.clickMode){
 					var c = dojo.connect(this.drawing, "onSurfaceReady", this, function(){
 					dojo.disconnect(c);
-					this.drawing.mouse.setCursor('default'); 
+					this.drawing.mouse.setCursor('default');
 					});
 				}
 			});
@@ -166,8 +168,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 					this.drawing.setTool(btn.toolType);
 				}
 				if(this.horizontal){
-					var space = secondary ? h/2 + g : h + g;
-					y += space;
+					x += h + g;
 				}else{
 					var space = secondary ? h/2 + g : h + g;
 					y += space;
@@ -176,7 +177,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 		}
 		
 		if(this.horizontal){
-			y += this.toolPlugGap;
+			x += this.toolPlugGap;
 		}else{
 			y += this.toolPlugGap;
 		}
@@ -198,13 +199,13 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 			dojo.forEach(plugAr, function(p){
 				var t = dojo.trim(p);
 				//console.log("   plugin:", p);
-				if(plugMap[p].button != false){  
+				if(plugMap[p].button != false){
 					var btn = this.toolDrawing.addUI("button", {data:{x:x, y:y, width:w, height:h, r:r}, toolType:t, icon:sym[t], shadow:s, scope:this, callback:"onPlugClick"});
 					dojox.drawing.register(btn, "button");
 					this.plugins.push(btn);
 					
 					if(this.horizontal){
-						y += h + g;
+						x += h + g;
 					}else{
 						y += h + g;
 					}
@@ -212,7 +213,7 @@ dojo.declare("dojox.drawing.ui.Toolbar", [], {
 				
 				var addPlug = {}
 				plugMap[p].button == false ? addPlug = {name:this.drawing.stencilTypeMap[p]} : addPlug = {name:this.drawing.stencilTypeMap[p], options:{button:btn}};
-				this.drawing.addPlugin(addPlug); 
+				this.drawing.addPlugin(addPlug);
 			}, this);
 		}
 		
diff --git a/dojox/drawing/ui/Tooltip.js b/dojox/drawing/ui/Tooltip.js
index 9336d48..a565945 100644
--- a/dojox/drawing/ui/Tooltip.js
+++ b/dojox/drawing/ui/Tooltip.js
@@ -20,7 +20,7 @@ dojo.require("dojox.drawing.plugins._Plugin");
 				this.domNode.innerHTML = text;
 				
 				var dx = 30;
-				var px = button.data.x + button.data.width; 
+				var px = button.data.x + button.data.width;
 				var py = button.data.y + button.data.height;
 				var x =  px + this.mouse.origin.x + dx;
 				var y = py + this.mouse.origin.y + dx;
@@ -110,6 +110,6 @@ dojo.require("dojox.drawing.plugins._Plugin");
 	);
 	
 	dojox.drawing.register({
-		name:"dojox.drawing.ui.Tooltip"	
+		name:"dojox.drawing.ui.Tooltip"
 	}, "stencil");
 })();
\ No newline at end of file
diff --git a/dojox/drawing/ui/dom/Pan.js b/dojox/drawing/ui/dom/Pan.js
index 810fde0..773e5a1 100644
--- a/dojox/drawing/ui/dom/Pan.js
+++ b/dojox/drawing/ui/dom/Pan.js
@@ -119,7 +119,7 @@ dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
 				mx = this.stencils.group ? this.stencils.group.getTransform() : {dx:0, dy:0},
 				sc = this.mouse.scrollOffset(),
 				// scY, scX: the scrollbar creates the need for extra dimension
-				scY = sc.left ? 10 : 0, 
+				scY = sc.left ? 10 : 0,
 				scX = sc.top ? 10 : 0,
 				// ch, cw: the current size of the canvas
 				ch = this.canvas.height,
@@ -152,7 +152,7 @@ dojox.drawing.ui.dom.Pan = dojox.drawing.util.oo.declare(
 			b *= z;
 			var xscroll = 0, yscroll = 0;
 			log("Bottom test", "b:", b, "z:", z, "ch:", ch, "pch:", pch, "top:", sc.top, "sy:", sy);
-			if(b > pch || sc.top ){ 
+			if(b > pch || sc.top ){
 				log("*bottom scroll*");
 				// item off bottom
 				ch = Math.max(b, pch + sc.top);
diff --git a/dojox/drawing/ui/dom/Toolbar.js b/dojox/drawing/ui/dom/Toolbar.js
index 7501c51..8331619 100644
--- a/dojox/drawing/ui/dom/Toolbar.js
+++ b/dojox/drawing/ui/dom/Toolbar.js
@@ -109,7 +109,7 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 			dojo.attr(node, "tabIndex", 1);
 			var constr = dojo.getObject(type);
 			
-			this.createIcon(node, constr);	
+			this.createIcon(node, constr);
 			
 			this.drawing.registerTool(type, constr);
 			dojo.connect(node, "mouseup", this, function(evt){
@@ -176,7 +176,7 @@ dojo.deprecated("dojox.drawing.ui.dom.Toolbar", "It may not even make it to the
 				
 			}, this);
 			this.drawing.initPlugins();
-			dojo.connect(this.drawing, "setTool", this, "onSetTool");	
+			dojo.connect(this.drawing, "setTool", this, "onSetTool");
 			this.drawing.setTool(_sel);
 		},
 		onClick: function(/*String*/type){
diff --git a/dojox/drawing/util/common.js b/dojox/drawing/util/common.js
index ff47ae5..30706c3 100755
--- a/dojox/drawing/util/common.js
+++ b/dojox/drawing/util/common.js
@@ -47,7 +47,7 @@ dojo.require("dojox.math.round");
 			// arguments:
 			//		obj: EventObject
 			//			Manager.Mouse event.
-			// 		snap: Float 
+			// 		snap: Float
 			//			Returns nearest angle within snap limits
 			//
 			//obj = this.argsToObj.apply(this, arguments);
@@ -214,7 +214,7 @@ dojo.require("dojox.math.round");
 		},
 		mixin: function(o1, o2){
 			// TODO: make faster
-			//return dojo.mixin(dojo.clone(o1), dojo.clone(o2));	
+			//return dojo.mixin(dojo.clone(o1), dojo.clone(o2));
 		},
 		
 		objects:{}, //private?
@@ -225,7 +225,7 @@ dojo.require("dojox.math.round");
 			//		the Toolbar. Since multiple drawings can be on one
 			//		page, this function serves a little more use than
 			//		on first apearance.
-			this.objects[obj.id] = obj;	
+			this.objects[obj.id] = obj;
 		},
 		byId: function(/*String*/id){
 			// summary:
@@ -259,8 +259,8 @@ dojo.require("dojox.math.round");
 				if(elem.rawNode || elem.target){
 					var args = Array.prototype.slice.call(arguments);
 					args[0] = elem.rawNode || elem.target;
-					return dojo.attr.apply(dojo, args);	
-				}		
+					return dojo.attr.apply(dojo, args);
+				}
 				return dojo.attr(elem, "id");
 				
 				
diff --git a/dojox/drawing/util/oo.js b/dojox/drawing/util/oo.js
index db416dc..e29d63f 100755
--- a/dojox/drawing/util/oo.js
+++ b/dojox/drawing/util/oo.js
@@ -49,9 +49,9 @@ dojox.drawing.util.oo = {
 		//		|		{
 		//		|			customType:"equation", // mixed in property
 		//		|			doThing: function(){   // mixed in method
-		//		|					
+		//		|
 		//		|			}
-		//		|		}	
+		//		|		}
 		//		|	);
 		//		|
 		//		|	var f = new MyFunction();
diff --git a/dojox/drawing/util/positioning.js b/dojox/drawing/util/positioning.js
index 677555a..72a8425 100755
--- a/dojox/drawing/util/positioning.js
+++ b/dojox/drawing/util/positioning.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.drawing.util.positioning");	
+dojo.provide("dojox.drawing.util.positioning");
 
 (function(){
 	
@@ -8,18 +8,22 @@ dojo.provide("dojox.drawing.util.positioning");
 	
 	dojox.drawing.util.positioning.label = function(/*Object*/start, /*Object*/end){
 		// summary:
-		//		Returns the optimal position for annotations.Label.
-		//
-		// 	text position
+		//		Returns the optimal text positions for annotations.Label.
+		
 		// label at middle of vector
 		var x = 0.5*(start.x+end.x);
 		var y = 0.5*(start.y+end.y);
 		
 		// move label a set distance from the line
 		var slope = dojox.drawing.util.common.slope(start, end);
-		
 		var deltay = textOffset/Math.sqrt(1.0+slope*slope);
-		if(end.y>start.y){deltay = -deltay;}
+		
+		if(end.y>start.y && end.x>start.x || end.y<start.y && end.x<start.x){
+			// Position depending on quadrant.  Y offset
+			// positions box aligned vertically from top
+			deltay = -deltay;
+			y -= textYOffset;
+		}
 		x += -deltay*slope;
 		y += deltay;
 		
@@ -27,11 +31,6 @@ dojo.provide("dojox.drawing.util.positioning");
 		// This will make force diagrams less crowded
 		var align = end.x<start.x ? "end" : "start";
 		
-	        // box vertical aligned from top
-		if(end.y>start.y){
-			y -= textYOffset;
-		}
-		
 		return { x:x, y:y, foo:"bar", align:align}; // Object
 	};
 	
diff --git a/dojox/drawing/util/typeset.js b/dojox/drawing/util/typeset.js
new file mode 100644
index 0000000..c1bd6e2
--- /dev/null
+++ b/dojox/drawing/util/typeset.js
@@ -0,0 +1,67 @@
+dojo.provide("dojox.drawing.util.typeset");
+dojo.require("dojox.drawing.library.greek");
+// Summary:
+//		Singleton used for converting characters and typsetting.  Required by _base.
+//
+// Description:
+//		Eventually, this is supposed to turn input strings of mathematical
+//		expressions into typeset expressions that can be displayed on the
+//		canvas.  For now, we just generate Greek letters based on LaTeX style
+//		entity codes.
+
+(function(){
+	
+	var greeks = dojox.drawing.library.greek;
+	
+	dojox.drawing.util.typeset = {
+
+		convertHTML: function(inText){
+			if(inText){
+				return inText.replace(/&([^;]+);/g,function(match,code){
+					if(code.charAt(0)=='#'){
+						//coerce remainder of string to int
+						var number=+code.substr(1);
+						if(!isNaN(number)){
+							return String.fromCharCode(number);
+						}
+					}else if(greeks[code]){
+						return String.fromCharCode(greeks[code]);
+					}
+					// This is generally for server code, so there
+					// is no point bothering the user in the case of an error.
+					console.warn("no HTML conversion for ",match);
+					return match;
+				});
+			}
+			return inText;
+		},
+
+		convertLaTeX: function(inText){
+			// console.log("***** convertLaTeX for ",inText);
+			if(inText){
+				return inText.replace(/\\([a-zA-Z]+)/g,function(match,word){
+					if(greeks[word]){
+						return String.fromCharCode(greeks[word]);
+					}else if(word.substr(0,2)=="mu"){
+						// special handling for \mu since it is
+						// a unit prefix for micro.
+						return String.fromCharCode(greeks["mu"])+word.substr(2);
+					}else if(word.substr(0,5)=="theta"){
+						// special handling for \theta since it is
+						// a standard prefix for angle associated with a vector.
+						return String.fromCharCode(greeks["theta"])+word.substr(5);
+					}else if(word.substr(0,3)=="phi"){
+						// special handling for \phi since it is
+						// a standard prefix for angle associated with a z-axis vector.
+						return String.fromCharCode(greeks["phi"])+word.substr(3);
+					}
+					console.log("no match for ",match," in ",inText);
+					console.log("Need user-friendly error handling here!");
+				}).replace(/\\\\/g,'\\');
+			}
+			return inText;
+		}
+
+	};
+
+})();
diff --git a/dojox/dtl/_Templated.js b/dojox/dtl/_Templated.js
index 983a3f5..56c2e7a 100644
--- a/dojox/dtl/_Templated.js
+++ b/dojox/dtl/_Templated.js
@@ -66,7 +66,7 @@ dojo.declare("dojox.dtl._Templated", dijit._Templated, {
 				inherited: {dir: this.dir, lang: this.lang}
 			}));
 
-			//Restore the query. 
+			//Restore the query.
 			if(qry){
 				parser._query = qry;
 				parser._attrName = attr;
@@ -100,7 +100,7 @@ dojo.declare("dojox.dtl._Templated", dijit._Templated, {
 
 		templateString = dojo.string.trim(templateString || dojo.cache(templatePath, {sanitize: true}));
 
-		if(	this._dijitTemplateCompat && 
+		if(	this._dijitTemplateCompat &&
 			(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g))
 		){
 			templateString = this._stringRepl(templateString);
diff --git a/dojox/dtl/_base.js b/dojox/dtl/_base.js
index 6838bda..b79915d 100644
--- a/dojox/dtl/_base.js
+++ b/dojox/dtl/_base.js
@@ -72,7 +72,7 @@ dojo.experimental("dojox.dtl");
 		}
 	});
 
-	var smart_split_re = /("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+)/g;           
+	var smart_split_re = /("(?:[^"\\]*(?:\\.[^"\\]*)*)"|'(?:[^'\\]*(?:\\.[^'\\]*)*)'|[^\s]+)/g;
 	var split_re = /\s+/g;
 	var split = function(/*String|RegExp?*/ splitter, /*Integer?*/ limit){
 		splitter = splitter || split_re;
diff --git a/dojox/dtl/tests/context.js b/dojox/dtl/tests/context.js
index 21ca0ac..bd72daa 100644
--- a/dojox/dtl/tests/context.js
+++ b/dojox/dtl/tests/context.js
@@ -3,7 +3,7 @@ dojo.provide("dojox.dtl.tests.context");
 dojo.require("dojox.dtl");
 dojo.require("dojox.dtl.Context");
 
-doh.register("dojox.dtl.context", 
+doh.register("dojox.dtl.context",
 	[
 		function test_context_creation(t){
 			var context = new dojox.dtl.Context({ foo: "foo", bar: "bar" });
diff --git a/dojox/dtl/tests/dom/buffer.js b/dojox/dtl/tests/dom/buffer.js
index 9c2a844..29c6809 100644
--- a/dojox/dtl/tests/dom/buffer.js
+++ b/dojox/dtl/tests/dom/buffer.js
@@ -4,7 +4,7 @@ dojo.require("dojox.dtl.dom");
 dojo.require("dojox.dtl.Context");
 dojo.require("dojox.dtl.tests.dom.util");
 
-doh.register("dojox.dtl.dom.buffer", 
+doh.register("dojox.dtl.dom.buffer",
 	[
 		function test_insertion_order_text(t){
 			var dd = dojox.dtl;
diff --git a/dojox/dtl/tests/dom/tag.js b/dojox/dtl/tests/dom/tag.js
index 112dc79..c3f0cc3 100644
--- a/dojox/dtl/tests/dom/tag.js
+++ b/dojox/dtl/tests/dom/tag.js
@@ -4,7 +4,7 @@ dojo.require("dojox.dtl.dom");
 dojo.require("dojox.dtl.Context");
 dojo.require("dojox.dtl.tests.dom.util");
 
-doh.register("dojox.dtl.dom.tag", 
+doh.register("dojox.dtl.dom.tag",
 	[
 		function test_errors(t){
 			var dd = dojox.dtl;
diff --git a/dojox/dtl/tests/text/filter.js b/dojox/dtl/tests/text/filter.js
index afb74a4..1887efe 100644
--- a/dojox/dtl/tests/text/filter.js
+++ b/dojox/dtl/tests/text/filter.js
@@ -7,7 +7,7 @@ dojo.require("dojox.date.php");
 dojo.require("dojox.string.sprintf");
 
 // If you update something here, update it in the HTML tests
-doh.register("dojox.dtl.text.filter", 
+doh.register("dojox.dtl.text.filter",
 	[
 		function test_filter_add(t){
 			var dd = dojox.dtl;
@@ -569,7 +569,7 @@ doh.register("dojox.dtl.text.filter",
 			context.then = new Date(2007, 0, 17);
 			t.is("2 weeks", tpl.render(context));
 			context.then = new Date(2008, 1, 1);
-			t.is("1 year", tpl.render(context));	
+			t.is("1 year", tpl.render(context));
 		},
 		function test_filter_title(t){
 			var dd = dojox.dtl;
diff --git a/dojox/dtl/tests/text/tag.js b/dojox/dtl/tests/text/tag.js
index c8e72c3..3ec4496 100644
--- a/dojox/dtl/tests/text/tag.js
+++ b/dojox/dtl/tests/text/tag.js
@@ -3,7 +3,7 @@ dojo.provide("dojox.dtl.tests.text.tag");
 dojo.require("dojox.dtl");
 dojo.require("dojox.dtl.Context");
 
-doh.register("dojox.dtl.text.tag", 
+doh.register("dojox.dtl.text.tag",
 	[
 		function test_tag_block_and_extends(t){
 			var dd = dojox.dtl;
diff --git a/dojox/dtl/utils/date.js b/dojox/dtl/utils/date.js
index a2b6f70..8cd04ed 100644
--- a/dojox/dtl/utils/date.js
+++ b/dojox/dtl/utils/date.js
@@ -9,7 +9,7 @@ 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: 
+		// description:
 		//		Examples: '1', '1:30', '2:05', '2'
 		//		Proprietary extension.
 		return (!this.date.getMinutes()) ? this.g() : this.g() + ":" + this.i();
diff --git a/dojox/editor/README b/dojox/editor/README
index 71619a9..ee7140c 100644
--- a/dojox/editor/README
+++ b/dojox/editor/README
@@ -18,6 +18,9 @@ Credits
 	David Schwartz and Gu Yi He (IBM) - Contributed enhancements to the
 		look and feel of FindReplace, as well as behavioral
 		improvements.
+	Eldon (IBM, CCLA) - LocalImage, AutoUrlLink, TablePluginsColorCell -
+		dojox.widget.ColorPicker, ResizeTableColumn, AutoSave, SpellCheck
+
 -------------------------------------------------------------------------------
 Project description
 
@@ -136,6 +139,26 @@ dojox.editor.plugins.StatusBar:
 	Status: Experimental (unsupported).
 	A plugin that adds a status bar and an optional resize handle to the footer of the editor.
 
+dojox.editor.plugins.LocalImage
+	Status: Beta
+	A plugin that adds local image upload and edit capability to the editor.
+
+dojox.editor.plugins.AutoUrlLink
+	Status: Experimental (Unsupported)
+	A plugin that adds auto url link creation capability as a headless plugin to the editor
+
+dojox.editor.plugins.ResizeColumnPlugin
+	Status: Experimental (Unsupported)
+	A plugin that adds column resize to the editor table plugins.
+
+dojox.editor.plugins.AutoSave
+	Status: Experimental (Unsupported)
+	A plugin that provides 'auto-save' capablity, eg, post back to some url at an interval.
+
+dojox.editor.plugins.SpellCheck
+	Status: Experimental (Unsupported)
+	A plugin that provides server-side spell-check support.
+
 -------------------------------------------------------------------------------
 Dependencies:
 
@@ -161,15 +184,21 @@ See also:
 	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/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
 
+	
 -------------------------------------------------------------------------------
 Plugin Installation instructions
 
@@ -254,9 +283,9 @@ For the PasteFromWord plugin:
 	<link href="[path]dojox/editor/plugins/resources/css/PasteFromWord.css" type="text/css" rel="stylesheet" />
 
 For the InsertAnchor plugin:
-        dojo.require("dojox.editor.plugins.InsertAnchor");
-        and CSS:
-        <link href="[path]dojox/editor/plugins/resources/css/InsertAnchor.css" type="text/css" rel="stylesheet" />
+	dojo.require("dojox.editor.plugins.InsertAnchor");
+	and CSS:
+	<link href="[path]dojox/editor/plugins/resources/css/InsertAnchor.css" type="text/css" rel="stylesheet" />
 
 For the TextColor plugin:
 	dojo.require("dojox.editor.plugins.TextColor");
@@ -269,10 +298,35 @@ For the NormalizeStyle plugin:
 	No CSS required.
 
 For the StatusBar plugin:
-        dojo.require("dojox.editor.plugins.StatusBar");
-        and CSS:
-        <link href="[path]dojox/editor/plugins/resources/css/StatusBar.css" type="text/css" rel="stylesheet" />
+	dojo.require("dojox.editor.plugins.StatusBar");
+	and CSS:
+	<link href="[path]dojox/editor/plugins/resources/css/StatusBar.css" type="text/css" rel="stylesheet" />
 
+For the LocalImage plugin:
+	dojo.require("dojox.editor.plugins.LocalImage");
+	and CSS:
+	<link href="[path]dojox/editor/plugins/resources/css/LocalImage.css" type="text/css" rel="stylesheet" />
+
+For the AutoUrlLink plugin:
+	dojo.require("dojox.editor.plugins.AutoUrlLink");
+	and CSS:
+	No CSS required.
+
+For the ResizeTableColumn plugin:
+	dojo.require("dojox.editor.plugins.ResizeTableColumn");
+	and CSS:
+	No CSS required in addition to the table plugins css.
+
+For the AutoSave plugin:
+	dojo.require("dojox.editor.plugins.AutoSave");
+	and CSS:
+	<link href="[path]dojox/editor/plugins/resources/css/AutoSave.css" type="text/css" rel="stylesheet" />
+        
+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" />
+                
 See tests for examples:
 	dojox/editor/tests/editorTablePlugs.html
 	dojox/editor/tests/editorUploadPlug.html
@@ -293,4 +347,9 @@ See tests for examples:
 	dojox/editor/tests/editorTextColor.html
 	dojox/editor/tests/editorNormalizeStyle.html
 	dojox/editor/tests/editorStatusBar.html
+	dojox/editor/tests/editorLocalImage.html
+	dojox/editor/tests/editorAutoUrlLink.html
+	dojox/editor/tests/editorResizeTableColumn.html
+	dojox/editor/tests/editorAutoSave.html
+	dojox/editor/tests/editorSpellCheck.html
 	dojox/editor/tests/testPluginsAll.html
diff --git a/dojox/editor/plugins/AutoSave.js b/dojox/editor/plugins/AutoSave.js
new file mode 100644
index 0000000..46a19b1
--- /dev/null
+++ b/dojox/editor/plugins/AutoSave.js
@@ -0,0 +1,409 @@
+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) {
+
+dojo.experimental("dojox.editor.plugins.AutoSave");
+
+dojo.declare("dojox.editor.plugins._AutoSaveSettingDialog", [dijit._Widget, dijit._Templated], {
+	
+	// dialogTitle [public] String
+	//		The tile of the Auto-Save setting dialog
+	dialogTitle: "",
+	
+	// dialogDescription [public] String
+	//		The description of the Auto-Save setting dialog
+	dialogDescription: "",
+	
+	// paramName [public] String
+	//		The name of the parameter (Auto-Save Interval)
+	paramName: "",
+	
+	// paramLabel [public] String
+	//		Minute
+	paramLabel: "",
+	
+	// btnOk [public] String
+	//		The label of the OK button
+	btnOk: "",
+	
+	// btnCancel [public] String
+	//		The label of the Cancel button
+	btnCancel: "",
+	
+	widgetsInTemplate: true,
+	
+	templateString:
+		"<span id='${dialogId}' class='dijit dijitReset dijitInline' tabindex='-1'>" +
+			"<div dojoType='dijit.Dialog' title='${dialogTitle}' dojoAttachPoint='dialog' " +
+				"class='dijitEditorAutoSaveSettingDialog'>" +
+				"<div tabindex='-1'>${dialogDescription}</div>" +
+				"<div tabindex='-1' class='dijitEditorAutoSaveSettingInputArea'>${paramName}</div>" +
+				"<div class='dijitEditorAutoSaveSettingInputArea' tabindex='-1'>" +
+					"<input class='textBox' dojoType='dijit.form.TextBox' id='${textBoxId}' required='false' intermediateChanges='true' " +
+						"selectOnClick='true' required='true' dojoAttachPoint='intBox' " +
+						"dojoAttachEvent='onKeyDown: _onKeyDown, onChange: _onChange'/>" +
+					"<label class='dijitLeft dijitInline boxLabel' " +
+						"for='${textBoxId}' tabindex='-1'>${paramLabel}</label>" +
+				"</div>" +
+				"<div class='dijitEditorAutoSaveSettingButtonArea' tabindex='-1'>" +
+					"<button dojoType='dijit.form.Button' dojoAttachEvent='onClick: onOk'>${btnOk}</button>" +
+					"<button dojoType='dijit.form.Button' dojoAttachEvent='onClick: onCancel'>${btnCancel}</button>" +
+				"</div>" +
+			"</div>" +
+		"</span>",
+	
+	postMixInProperties: function(){
+		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+		this.dialogId = this.id + "_dialog";
+		this.textBoxId = this.id + "_textBox";
+	},
+	
+	show: function(){
+		// summary:
+		//		Display the setting dialog. If the internal interval value is ""
+		//		set it to zero
+		// tags:
+		//		public
+		if(this._value == ""){
+			this._value = 0;
+			this.intBox.set("value", 0);
+		}else{
+			this.intBox.set("value", this._value);
+		}
+		this.dialog.show();
+		dijit.selectInputText(this.intBox.focusNode);
+	},
+	
+	hide: function(){
+		// summray:
+		//		Hide the setting dialog.
+		// tags:
+		//		public
+		this.dialog.hide();
+	},
+	
+	onOk: function(){
+		// summary:
+		//		Handle the OK event and close the dialog.
+		// tags:
+		//		public
+		this.dialog.hide();
+	},
+	
+	onCancel: function(){
+		// summary:
+		//		Handle the Cancel event and close the dialog.
+		// tags:
+		//		public
+		this.dialog.hide();
+	},
+	
+	_onKeyDown: function(evt){
+		// summary:
+		//		Handle the keydown event
+		//	tags:
+		//		private
+		if(evt.keyCode == dojo.keys.ENTER){
+			this.onOk();
+		}
+	},
+	
+	_onChange: function(/*String*/ val){
+		// summary:
+		//		Check if the value is between 1 - 999.
+		// tags:
+		//		public
+		if(this._isValidValue(val)){
+			this._value = val;
+		}else{
+			this.intBox.set("value", this._value);
+		}
+	},
+	
+	_setValueAttr: function(/*String*/ val){
+		//	summary:
+		//		Set the value attribute if it is acceptable
+		// val:
+		//		The invertal value
+		// tags:
+		//		private
+		if(this._isValidValue(val)){
+			this._value = val;
+		}
+	},
+	
+	_getValueAttr: function(){
+		// summary:
+		//		Get the interval value
+		// tags:
+		//		protected
+		return this._value;
+	},
+	
+	_isValidValue: function(/*String*/ val){
+		// summary:
+		//		Check if this value between 1- 999
+		// tags:
+		//		private
+		var regExp = /^\d{0,3}$/,
+			_v = String(val);
+		return Boolean(_v.match ? _v.match(regExp) : "");
+	}
+});
+
+dojo.declare("dojox.editor.plugins.AutoSave", dojox.editor.plugins.Save, {
+	// summary:
+	//		This plugin provides the auto save capability to the editor. The
+	//		plugin saves the content of the editor in interval. When
+	//		the save action is performed, the document in the editor frame
+	//		will be posted to the URL provided, or none, if none provided.
+	
+	// url [public]	String
+	//		The URL to POST the content back to.  Used by the save function.
+	url: "",
+
+	// logErrors [public] boolean
+	//		Boolean flag to indicate that the default action for save and
+	//		error handlers is to just log to console.  Default is true.
+	logResults: true,
+	
+	// interval [public] Number
+	//		The interval to perform the save action.
+	interval: 0,
+	
+	// _iconClassPrefix [private] String
+	//		This prefix of the CSS class
+	_iconClassPrefix: "dijitEditorIconAutoSave",
+	
+	// _MIN [private const] Number
+	//		Default 1 minute
+	_MIN: 60000,
+	
+	_setIntervalAttr: function(val){
+		// summary:
+		//		Set the interval value.
+		//		Delay the boundary check to _isValidValue of the dialog class
+		// val:
+		//		The interval value.
+		// tags:
+		//		private
+		this.interval = val;
+	},
+	
+	_getIntervalAttr: function(){
+		// summary:
+		//		Get the interval value
+		// tags:
+		//		private
+		return this._interval;
+	},
+	
+	setEditor: function(editor){
+		// summary:
+		//		Over-ride for the setting of the editor. No toggle button for
+		//		this plugin. And start to save the content of the editor in
+		//		interval
+		// editor: Object
+		//		The editor to configure for this plugin to use.
+		this.editor = editor;
+		this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "AutoSave");
+		this._initButton();
+		
+		this._saveSettingDialog = new dojox.editor.plugins._AutoSaveSettingDialog({
+			"dialogTitle": this._strings["saveSettingdialogTitle"],
+			"dialogDescription": this._strings["saveSettingdialogDescription"],
+			"paramName": this._strings["saveSettingdialogParamName"],
+			"paramLabel": this._strings["saveSettingdialogParamLabel"],
+			"btnOk": this._strings["saveSettingdialogButtonOk"],
+			"btnCancel": this._strings["saveSettingdialogButtonCancel"]
+		});
+		this.connect(this._saveSettingDialog, "onOk", "_onDialogOk");
+		
+		var pd = this._promDialog = new dijit.TooltipDialog();
+		pd.startup();
+		pd.set("content", "");
+	},
+	
+	_initButton: function(){
+		var menu = new dijit.Menu({
+				style: "display: none"
+			}),
+			menuItemSave = new dijit.MenuItem({
+				iconClass: this._iconClassPrefix + "Default " + this._iconClassPrefix,
+				label: this._strings["saveLabel"]
+			}),
+			menuItemAutoSave = this._menuItemAutoSave = new dijit.MenuItem({
+				iconClass: this._iconClassPrefix + "Setting " + this._iconClassPrefix,
+				label: this._strings["saveSettingLabelOn"]
+			});
+			
+		menu.addChild(menuItemSave);
+		menu.addChild(menuItemAutoSave);
+		this.button = new dijit.form.ComboButton({
+			label: this._strings["saveLabel"],
+			iconClass: this._iconClassPrefix + "Default " + this._iconClassPrefix,
+			showLabel: false,
+			dropDown: menu
+		});
+		
+		this.connect(this.button, "onClick", "_save");
+		this.connect(menuItemSave, "onClick", "_save");
+		this._menuItemAutoSaveClickHandler = dojo.connect(menuItemAutoSave, "onClick", this, "_showAutSaveSettingDialog");
+	},
+	
+	_showAutSaveSettingDialog: function(){
+		// summary:
+		//		Show the setting dialog
+		// tags:
+		//		private
+		var dialog = this._saveSettingDialog;
+		dialog.set("value", this.interval);
+		dialog.show();
+	},
+	
+	_onDialogOk: function(){
+		// summary:
+		//		If the interval is set (larger than 0), enable auto-save.
+		// tags:
+		//		private
+		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"
+			// Connect it to another handler that terminates the auto-save.
+			dojo.disconnect(this._menuItemAutoSaveClickHandler);
+			this._menuItemAutoSave.set("label", this._strings["saveSettingLabelOff"]);
+			this._menuItemAutoSaveClickHandler = dojo.connect(this._menuItemAutoSave, "onClick", this, "_onStopClick");
+			// Change the icon of the main button to auto-save style
+			this.button.set("iconClass", this._iconClassPrefix + "Setting " + this._iconClassPrefix);
+		}
+	},
+	
+	_onStopClick: function(){
+		// summary:
+		//		Stop auto-save
+		// tags:
+		//		private
+		this._clearSaveInterval();
+		// Change the menu "Turn off Auto-Save" to "Set Auto-Save Interval...".
+		// Connect it to another handler that show the setting dialog.
+		dojo.disconnect(this._menuItemAutoSaveClickHandler);
+		this._menuItemAutoSave.set("label", this._strings["saveSettingLabelOn"]);
+		this._menuItemAutoSaveClickHandler = dojo.connect(this._menuItemAutoSave, "onClick", this, "_showAutSaveSettingDialog");
+		// Change the icon of the main button
+		this.button.set("iconClass", this._iconClassPrefix + "Default " + this._iconClassPrefix);
+	},
+	
+	_setSaveInterval: function(/*Number*/ interval){
+		// summary:
+		//		Function to trigger saving of the editor document
+		// tags:
+		//		private
+		if(interval <= 0){
+			return;
+		}
+		this._clearSaveInterval();
+		this._intervalHandler = setInterval(dojo.hitch(this,  function(){
+									if(!this._isWorking && !this.get("disabled")){
+										// If the plugin is not disabled (ViewSource, etc.)
+										// and not working. Do saving!
+										this._isWorking = true;
+										this._save();
+									}
+								}), interval);
+	},
+	
+	_clearSaveInterval: function(){
+		if(this._intervalHandler){
+			clearInterval(this._intervalHandler);
+			this._intervalHandler = null;
+		}
+	},
+
+	onSuccess: function(resp, ioargs){
+		// summary:
+		//		User over-ridable save success function for editor content.
+		// resp:
+		//		The response from the server, if any, in text format.
+		// tags:
+		//		public
+		this.button.set("disabled", false);
+		// Show the successful message
+		this._promDialog.set("content", dojo.string.substitute(
+					this._strings["saveMessageSuccess"], {"0": dojo.date.locale.format(new Date(), {selector: "time"})}));
+				dijit.popup.open({popup: this._promDialog, around: this.button.domNode});
+				this._promDialogTimeout = setTimeout(dojo.hitch(this, function(){
+					clearTimeout(this._promDialogTimeout);
+					this._promDialogTimeout = null;
+					dijit.popup.close(this._promDialog);
+				}), 3000);
+		this._isWorking = false;
+		if(this.logResults){
+			console.log(resp);
+		}
+	},
+
+	onError: function(error, ioargs){
+		// summary:
+		//		User over-ridable save success function for editor content.
+		// resp:
+		//		The response from the server, if any, in text format.
+		// tags:
+		//		public
+		this.button.set("disabled", false);
+		// Show the failure message
+		this._promDialog.set("content", dojo.string.substitute(
+					this._strings["saveMessageFail"], {"0": dojo.date.locale.format(new Date(), {selector: "time"})}));
+				dijit.popup.open({popup: this._promDialog, around: this.button.domNode});
+				this._promDialogTimeout = setTimeout(dojo.hitch(this, function(){
+					clearTimeout(this._promDialogTimeout);
+					this._promDialogTimeout = null;
+					dijit.popup.close(this._promDialog);
+				}), 3000);
+		this._isWorking = false;
+		if(this.logResults){
+			console.log(error);
+		}
+	},
+	
+	destroy: function(){
+		// summary:
+		//		Cleanup of our plugin.
+		this.inherited(arguments);
+		
+		this._menuItemAutoSave = null;
+		
+		if(this._promDialogTimeout){
+			clearTimeout(this._promDialogTimeout);
+			this._promDialogTimeout = null;
+			dijit.popup.close(this._promDialog);
+		}
+		
+		this._clearSaveInterval();
+		
+		if(this._saveSettingDialog){
+			this._saveSettingDialog.destroyRecursive();
+			this._destroyRecursive = null;
+		}
+		
+		if(this._menuItemAutoSaveClickHandler){
+			dojo.disconnect(this._menuItemAutoSaveClickHandler);
+			this._menuItemAutoSaveClickHandler = null;
+		}
+	}
+});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+	if(o.plugin){ return; }
+	var name = o.args.name.toLowerCase();
+	if(name == "autosave"){
+		o.plugin = new dojox.editor.plugins.AutoSave({
+			url: ("url" in o.args) ? o.args.url : "",
+			logResults: ("logResults" in o.args) ? o.args.logResults : true,
+			interval: ("interval" in o.args) ? o.args.interval : 5
+		});
+	}
+});
+
+return dojox.editor.plugins.AutoSave;
+
+});
diff --git a/dojox/editor/plugins/AutoUrlLink.js b/dojox/editor/plugins/AutoUrlLink.js
new file mode 100644
index 0000000..a6916ce
--- /dev/null
+++ b/dojox/editor/plugins/AutoUrlLink.js
@@ -0,0 +1,223 @@
+define("dojox/editor/plugins/AutoUrlLink", ["dojo", "dijit", "dojox", "dojo/string", "dijit/_editor/_Plugin", "dijit/form/Button"], function(dojo, dijit, dojox) {
+
+dojo.declare("dojox.editor.plugins.AutoUrlLink", [dijit._editor._Plugin], {
+	//summary:
+	//		This plugin can recognize a URL like string
+	//		(such as http://www.website.com) and turn it into
+	//		a hyperlink that points to that URL.
+	
+	// _template [private] String
+	//		The link template
+	_template: "<a _djrealurl='${url}' href='${url}'>${url}</a>",
+	
+	setEditor: function(/*dijit.Editor*/ editor){
+		// summary:
+		//		Called by the editor it belongs to.
+		// editor:
+		//		The editor it belongs to.
+		this.editor = editor;
+		if(!dojo.isIE){
+			// IE will recognize URL as a link automatically
+			// No need to re-invent the wheel.
+			dojo.some(editor._plugins, function(plugin){
+				// Need to detect which enter key mode it is now
+				if(plugin.isInstanceOf(dijit._editor.plugins.EnterKeyHandling)){
+					this.blockNodeForEnter = plugin.blockNodeForEnter;
+					return true;
+				}
+				return false;
+			}, this);
+			this.connect(editor, "onKeyPress", "_keyPress");
+			this.connect(editor, "onClick", "_recognize");
+			this.connect(editor, "onBlur", "_recognize");
+		}
+	},
+	
+	_keyPress: function(evt){
+		// summary:
+		//		Handle the keypress event and dispatch it to the target handler
+		// evt:
+		//		The keypress event object.
+		// tags:
+		//		protected
+		var ks = dojo.keys, v = 118, V = 86,
+			kc = evt.keyCode, cc = evt.charCode;
+		if(cc == ks.SPACE || (evt.ctrlKey && (cc == v || cc == V))){
+			setTimeout(dojo.hitch(this, "_recognize"), 0);
+		}else if(kc == ks.ENTER){
+			// Handle the enter event after EnterKeyHandling finishes its job
+			setTimeout(dojo.hitch(this, function(){
+				this._recognize({enter: true});
+			}), 0);
+		}else{
+			// _saved: The previous dom node when the cursor is at a new dom node.
+			// When we click elsewhere, the previous dom node
+			// should be examed to see if there is any URL need to be activated
+			this._saved = this.editor.window.getSelection().anchorNode;
+		}
+	},
+	
+	_recognize: function(args){
+		// summary:
+		//		Recognize the URL like strings and turn them into a link
+		// tags:
+		//		private
+		var template = this._template,
+			isEnter = args ? args.enter : false,
+			ed = this.editor,
+			selection = ed.window.getSelection();
+			if(selection){
+				var node = isEnter ? this._findLastEditingNode(selection.anchorNode) :
+								(this._saved || selection.anchorNode),
+				bm = this._saved = selection.anchorNode,
+				bmOff = selection.anchorOffset;
+			
+			if(node.nodeType == 3 && !this._inLink(node)){
+				var linked = false, result = this._findUrls(node, bm, bmOff),
+					range = ed.document.createRange(),
+					item, cost = 0, isSameNode = (bm == node);
+						
+				item = result.shift();
+				while(item){
+					// Covert a URL to a link.
+					range.setStart(node, item.start);
+					range.setEnd(node, item.end);
+					selection.removeAllRanges();
+					selection.addRange(range);
+					ed.execCommand("insertHTML", dojo.string.substitute(template, {url: range.toString()}));
+					cost += item.end;
+					item = result.shift();
+					linked = true;
+				}
+				
+				// If bm and node are the some dom node, caculate the actual bookmark offset
+				// If the position of the cursor is modified (turned into a link, etc.), no
+				// need to recover the cursor position
+				if(isSameNode && (bmOff = bmOff - cost) <= 0){ return; }
+	
+				// We didn't update anything, so don't collapse selections.
+				if(!linked) { return ; }
+				try{
+					// Try to recover the cursor position
+					range.setStart(bm, 0);
+					range.setEnd(bm, bmOff);
+					selection.removeAllRanges();
+					selection.addRange(range);
+					dojo.withGlobal(ed.window, "collapse", dijit._editor.selection, []);
+				}catch(e){}
+			}
+		}
+	},
+	
+	_inLink: function(/*DomNode*/ node){
+		// summary:
+		//		Check if the node is already embraced within a <a>...</a> tag.
+		// node:
+		//		The node to be examed.
+		// tags:
+		//		private
+		var editNode = this.editor.editNode,
+			result = false, tagName;
+			
+		node = node.parentNode;
+		while(node && node !== editNode){
+			tagName = node.tagName ? node.tagName.toLowerCase() : "";
+			if(tagName == "a"){
+				result = true;
+				break;
+			}
+			node = node.parentNode;
+		}
+		return result;
+	},
+	
+	_findLastEditingNode: function(/*DomNode*/ node){
+		// summary:
+		//		Find the last node that was edited so that we can
+		//		get the last edited text.
+		// node:
+		//		The current node that the cursor is at.
+		// tags:
+		//		private
+		var blockTagNames = dijit.range.BlockTagNames,
+			editNode = this.editor.editNode, blockNode;
+
+		if(!node){ return node; }
+		if(this.blockNodeForEnter == "BR" &&
+				(!(blockNode = dijit.range.getBlockAncestor(node, null, editNode).blockNode) ||
+				blockNode.tagName.toUpperCase() != "LI")){
+			while((node = node.previousSibling) && node.nodeType != 3){}
+		}else{
+			// EnterKeyHandling is under "DIV" or "P" mode or
+			// it's in a LI element. Find the last editing block
+			if((blockNode || (blockNode = dijit.range.getBlockAncestor(node, null, editNode).blockNode)) &&
+					blockNode.tagName.toUpperCase() == "LI"){
+				node = blockNode;
+			}else{
+				node = dijit.range.getBlockAncestor(node, null, editNode).blockNode;
+			}
+			// Find the last editing text node
+			while((node = node.previousSibling) && !(node.tagName && node.tagName.match(blockTagNames))){}
+			if(node){
+				node = node.lastChild;
+				while(node){
+					if(node.nodeType == 3 && dojo.trim(node.nodeValue) != ""){
+						break;
+					}else if(node.nodeType == 1){
+						node = node.lastChild;
+					}else{
+						node = node.previousSibling;
+					}
+				}
+			}
+		}
+		return node;
+	},
+	
+	_findUrls: function(/*DomNode*/ node, /*DomNode*/ bm, /*Number*/ bmOff){
+		// summary:
+		//		Find the occurrace of the URL strings.
+		//		FF, Chrome && Safri have a behavior that when insertHTML is executed,
+		//		the orignal referrence to the text node will be the text node next to
+		//		the inserted anchor automatically. So we have to re-caculate the index of
+		//		the following URL occurrence.
+		// value:
+		//		A text to be scanned.
+		// tags:
+		//		private
+		var pattern = /(http|https|ftp):\/\/[^\s]+/ig,
+			list = [], baseIndex = 0,
+			value = node.nodeValue, result, ch;
+		
+		if(node === bm && bmOff < value.length){
+			// Break the text so that it may not grab extra words.
+			// Such as if you type:
+			// foo http://foo.com|bar (And | is where you press enter).
+			// It will grab the bar word as part of the link. That's annoying/bad.
+			// Also it prevents recognizing the text after the cursor.
+			value = value.substr(0, bmOff);
+		}
+		
+		while((result = pattern.exec(value)) != null){
+			if(result.index == 0 || (ch = value.charAt(result.index - 1)) == " " || ch == "\xA0"){
+				list.push({start: result.index - baseIndex, end: result.index + result[0].length - baseIndex});
+				baseIndex = result.index + result[0].length;
+			}
+		}
+
+		return list;
+	}
+});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+	if(o.plugin){ return; }
+	var name = o.args.name.toLowerCase();
+	if(name ===  "autourllink"){
+		o.plugin = new dojox.editor.plugins.AutoUrlLink();
+	}
+});
+
+return dojox.editor.plugins.AutoUrlLink;
+
+});
diff --git a/dojox/editor/plugins/Blockquote.js b/dojox/editor/plugins/Blockquote.js
index 69e55a1..d6f31f1 100755
--- a/dojox/editor/plugins/Blockquote.js
+++ b/dojox/editor/plugins/Blockquote.js
@@ -1,14 +1,8 @@
-dojo.provide("dojox.editor.plugins.Blockquote");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "Blockquote");
+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) {
 
 dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 	//	summary:
-	//		This plugin provides Blockquote cabability to the editor. 
+	//		This plugin provides Blockquote cabability to the editor.
 	//		window/tab
 
 	// iconClassPrefix: [const] String
@@ -37,12 +31,12 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 		this._initButton();
 		this.connect(this.editor, "onNormalizedDisplayChanged", "updateState");
 		// We need the custom undo code since we manipulate the dom
-		// outside of the browser natives and only customUndo really handles 
+		// outside of the browser natives and only customUndo really handles
 		// that.  It will incur a performance hit, but should hopefully be
-		// relatively small.  
+		// relatively small.
 		editor.customUndo = true;
 	},
-
+	
 	_toggleQuote: function(arg){
 		// summary:
 		//		Function to trigger previewing of the editor document
@@ -67,9 +61,9 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 						// No selection, just cursor point, we need to see if we're
 						// in an indentable block, or similar.
 						if(this._isRootInline(range.startContainer)){
-							// Text at the 'root' of the document, so we need to gather all of it., 
+							// Text at the 'root' of the document, so we need to gather all of it.,
 		
-							// First, we need to find the toplevel inline element that is rooted 
+							// First, we need to find the toplevel inline element that is rooted
 							// to the document 'editNode'
 							start = range.startContainer;
 							while(start && start.parentNode !== ed.editNode){
@@ -78,19 +72,19 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							// Now we need to walk up its siblings and look for the first one in the rooting
 							// that isn't inline or text, as we want to grab all of that for indent.
 							while(start && start.previousSibling && (
-									this._isTextElement(start) || 
-									(start.nodeType === 1 && 
+									this._isTextElement(start) ||
+									(start.nodeType === 1 &&
 									 this._isInlineFormat(this._getTagName(start))
 								))){
 								start = start.previousSibling;
 							}
-							if(start && start.nodeType === 1 && 
+							if(start && start.nodeType === 1 &&
 							   !this._isInlineFormat(this._getTagName(start))){
 								// Adjust slightly, we're one node too far back in this case.
 								start = start.nextSibling;
 							}
 		
-							// Okay, we have a configured start, lets grab everything following it that's 
+							// Okay, we have a configured start, lets grab everything following it that's
 							// inline and make it part of the blockquote!
 							if(start){
 								bq = ed.document.createElement("blockquote");
@@ -99,10 +93,10 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 								end = bq.nextSibling;
 								while(end && (
 									this._isTextElement(end) ||
-									(end.nodeType === 1 && 
+									(end.nodeType === 1 &&
 										this._isInlineFormat(this._getTagName(end)))
 									)){
-									// Add it. 
+									// Add it.
 									bq.appendChild(end);
 									end = bq.nextSibling;
 								}
@@ -110,9 +104,9 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 						}else{
 							// Figure out what to do when not root inline....
 							var node = range.startContainer;
-							while ((this._isTextElement(node) || 
+							while ((this._isTextElement(node) ||
 									this._isInlineFormat(this._getTagName(node))
-									|| this._getTagName(node) === "li") && 
+									|| this._getTagName(node) === "li") &&
 								node !== ed.editNode && node !== ed.document.body){
 								node = node.parentNode;
 							}
@@ -123,9 +117,9 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							}
 						}
 						if(bq){
-							dojo.withGlobal(ed.window, 
+							dojo.withGlobal(ed.window,
 								"selectElementChildren", dijit._editor.selection, [bq]);
-							dojo.withGlobal(ed.window, 
+							dojo.withGlobal(ed.window,
 								"collapse", dijit._editor.selection, [true]);
 						}
 					}else{
@@ -144,13 +138,13 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 
 						// Try to find the end node.  We have to check the selection junk
 						curNode = start;
-						while(curNode.nextSibling && dojo.withGlobal(ed.window, 
+						while(curNode.nextSibling && dojo.withGlobal(ed.window,
 							"inSelection", dijit._editor.selection, [curNode])){
 							curNode = curNode.nextSibling;
 						}
-						end = curNode; 
+						end = curNode;
 						if(end === ed.editNode || end === ed.document.body){
-							// Unable to determine real selection end, so just make it 
+							// Unable to determine real selection end, so just make it
 							// a single node indent of start + all following inline styles, if
 							// present, then just exit.
 							bq = ed.document.createElement("blockquote");
@@ -158,7 +152,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							tag = this._getTagName(start);
 							if(this._isTextElement(start) || this._isInlineFormat(tag)){
 								// inline element or textnode
-								// Find and move all inline tags following the one we inserted also into the 
+								// Find and move all inline tags following the one we inserted also into the
 								// blockquote so we don't split up content funny.
 								var next = start;
 								while(next && (
@@ -184,7 +178,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 								tag = this._getTagName(curNode);
 								if(tag !== "br"){
 									if(!window.getSelection){
-										// IE sometimes inserts blank P tags, which we want to skip 
+										// IE sometimes inserts blank P tags, which we want to skip
 										// as they end up blockquoted, which messes up layout.
 										if(tag === "p" && this._isEmpty(curNode)){
 											curNode = curNode.nextSibling;
@@ -230,9 +224,9 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							if(this._isEmpty(bq)){
 								bq.parentNode.removeChild(bq);
 							}else{
-								dojo.withGlobal(ed.window, 
+								dojo.withGlobal(ed.window,
 									"selectElementChildren", dijit._editor.selection, [bq]);
-								dojo.withGlobal(ed.window, 
+								dojo.withGlobal(ed.window,
 									"collapse", dijit._editor.selection, [true]);
 							}
 							bq = null;
@@ -259,9 +253,9 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 							}
 							elem.parentNode.removeChild(elem);
 							if(lastChild){
-								dojo.withGlobal(ed.window, 
+								dojo.withGlobal(ed.window,
 									"selectElementChildren", dijit._editor.selection, [lastChild]);
-								dojo.withGlobal(ed.window, 
+								dojo.withGlobal(ed.window,
 									"collapse", dijit._editor.selection, [true]);
 							}
 						}
@@ -274,7 +268,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 						}
 						var selectedNodes = [];
 						var cNode = start;
-						while(cNode && cNode.nextSibling && dojo.withGlobal(ed.window, 
+						while(cNode && cNode.nextSibling && dojo.withGlobal(ed.window,
 							"inSelection", dijit._editor.selection, [cNode])){
 							if(cNode.parentNode && this._getTagName(cNode.parentNode) === "blockquote"){
 								cNode = cNode.parentNode;
@@ -310,8 +304,15 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 		// tags:
 		//		protected
 		var ed = this.editor;
+		var disabled = this.get("disabled");
+		
 		if(!ed || !ed.isLoaded){ return; }
 		if(this.button){
+			this.button.set("disabled", disabled);
+			if(disabled){
+				return;
+			}
+
 			// Some browsers (WebKit) doesn't actually get the tag info right.
 			// So ... lets check it manually.
 			var elem;
@@ -354,7 +355,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 				var node = nodeList[i];
 				if(node.nodeType === 1){
 					if(this._getTagName(node) === "blockquote"){
-						bnList.push(node);   
+						bnList.push(node);
 					}
 					if(node.childNodes && node.childNodes.length > 0){
 						bnList = bnList.concat(this._findBlockQuotes(node.childNodes));
@@ -439,7 +440,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 				if(n.nodeType === 1){
 					if(this._getTagName(n) === "p"){
 						if(!dojo.trim(n.innerHTML)){
-							continue;	
+							continue;
 						}
 					}
 					empty = false;
@@ -465,7 +466,7 @@ dojo.declare("dojox.editor.plugins.Blockquote",dijit._editor._Plugin,{
 	_isInlineFormat: function(tag){
 		// summary:
 		//		Function to determine if the current tag is an inline
-		//		element that does formatting, as we don't want to 
+		//		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
@@ -504,3 +505,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.Blockquote({});
 	}
 });
+
+return dojox.editor.plugins.Blockquote;
+
+});
diff --git a/dojox/editor/plugins/Breadcrumb.js b/dojox/editor/plugins/Breadcrumb.js
index 6df3b71..355b918 100755
--- a/dojox/editor/plugins/Breadcrumb.js
+++ b/dojox/editor/plugins/Breadcrumb.js
@@ -1,20 +1,7 @@
-dojo.provide("dojox.editor.plugins.Breadcrumb");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit._editor.range");
-dojo.require("dojo.i18n");
-dojo.require("dojo.string");
-dojo.require("dijit.Toolbar");
-dojo.require("dijit.form.Button");
-dojo.require("dijit._editor.selection");
-dojo.require("dijit.Menu");
-dojo.require("dijit.MenuItem");
-dojo.require("dijit.MenuSeparator");
+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) {
 
 dojo.experimental("dojox.editor.plugins.Breadcrumb");
 
-dojo.requireLocalization("dojox.editor.plugins", "Breadcrumb");
-
 dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._Templated, dijit._Contained],{
 	// summary:
 	//		SImple internal, non-clickable, menu entry to act as a menu title bar.
@@ -39,8 +26,8 @@ dojo.declare("dojox.editor.plugins._BreadcrumbMenuTitle",[dijit._Widget, dijit._
 
 dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 	// summary:
-	//		This plugin provides Breadcrumb cabability to the editor.  When 
-	//		As you move around the editor, it updates with your current indention 
+	//		This plugin provides Breadcrumb cabability to the editor.  When
+	//		As you move around the editor, it updates with your current indention
 	//		depth.
 
 	//	_menu: [private]
@@ -88,14 +75,14 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 			this._moveSMenu = new dijit.MenuItem({label: strings.moveStart, onClick: dojo.hitch(this, this._moveCToStart)});
 			this._moveEMenu = new dijit.MenuItem({label: strings.moveEnd, onClick: dojo.hitch(this, this._moveCToEnd)});
 
-			this._menu.addChild(this._menuTitle); 
-			this._menu.addChild(this._selCMenu); 
-			this._menu.addChild(this._delCMenu); 
-			this._menu.addChild(new dijit.MenuSeparator({})); 
-			this._menu.addChild(this._selEMenu); 
-			this._menu.addChild(this._delEMenu); 
-			this._menu.addChild(new dijit.MenuSeparator({})); 
-			this._menu.addChild(this._moveSMenu); 
+			this._menu.addChild(this._menuTitle);
+			this._menu.addChild(this._selCMenu);
+			this._menu.addChild(this._delCMenu);
+			this._menu.addChild(new dijit.MenuSeparator({}));
+			this._menu.addChild(this._selEMenu);
+			this._menu.addChild(this._delEMenu);
+			this._menu.addChild(new dijit.MenuSeparator({}));
+			this._menu.addChild(this._moveSMenu);
 			this._menu.addChild(this._moveEMenu);
 
 			body._ddConnect = dojo.connect(body, "openDropDown", dojo.hitch(this, function(){
@@ -136,11 +123,11 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 				case 'area':
 				case 'basefont':
 						break;
-				default: 
+				default:
 					try{
-						dojo.withGlobal(this.editor.window, 
+						dojo.withGlobal(this.editor.window,
 							"collapse", dijit._editor.selection, [null]);
-						dojo.withGlobal(this.editor.window, 
+						dojo.withGlobal(this.editor.window,
 							"selectElementChildren", dijit._editor.selection, [this._menuTarget]);
 						this.editor.onDisplayChanged();
 					}catch(e){/*squelch*/}
@@ -154,7 +141,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		if(this._menuTarget){
 			this.editor.beginEditing();
 			this._selectContents();
-			dojo.withGlobal(this.editor.window, 
+			dojo.withGlobal(this.editor.window,
 				"remove", dijit._editor.selection, [this._menuTarget]);
 			this.editor.endEditing();
 			this._updateBreadcrumb();
@@ -167,9 +154,9 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		//		Internal function for selecting the contents of a node.
 		this.editor.focus();
 		if(this._menuTarget){
-			dojo.withGlobal(this.editor.window, 
+			dojo.withGlobal(this.editor.window,
 				"collapse", dijit._editor.selection, [null]);
-			dojo.withGlobal(this.editor.window, 
+			dojo.withGlobal(this.editor.window,
 				"selectElement", dijit._editor.selection, [this._menuTarget]);
 			this.editor.onDisplayChanged();
 			
@@ -182,7 +169,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		if(this._menuTarget){
 			this.editor.beginEditing();
 			this._selectElement();
-			dojo.withGlobal(this.editor.window, 
+			dojo.withGlobal(this.editor.window,
 				"remove", dijit._editor.selection, [this._menuTarget]);
 			this.editor.endEditing();
 			this._updateBreadcrumb();
@@ -196,7 +183,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		this.editor.focus();
 		if(this._menuTarget){
 			this._selectContents();
-			dojo.withGlobal(this.editor.window, 
+			dojo.withGlobal(this.editor.window,
 				"collapse", dijit._editor.selection, [true]);
 		}
 	},
@@ -207,7 +194,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		this.editor.focus();
 		if(this._menuTarget){
 			this._selectContents();
-			dojo.withGlobal(this.editor.window, 
+			dojo.withGlobal(this.editor.window,
 				"collapse", dijit._editor.selection, [false]);
 		}
 	},
@@ -224,7 +211,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 				var range = sel.getRangeAt(0);
                 
 				// Check the getSelectedElement call.  Needed when dealing with img tags.
-				var node = dojo.withGlobal(ed.window, 
+				var node = dojo.withGlobal(ed.window,
 					"getSelectedElement", dijit._editor.selection) || range.startContainer;
 				//var node = range.startContainer;
 				var bcList = [];
@@ -234,7 +221,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 				if(node && node.ownerDocument === ed.document){
 					while(node && node !== ed.editNode && node != ed.document.body && node != ed.document){
 						if(node.nodeType === 1){
-							bcList.push({type: node.tagName.toLowerCase(), node: node}); 
+							bcList.push({type: node.tagName.toLowerCase(), node: node});
 						}
 						node = node.parentNode;
 					}
@@ -310,7 +297,7 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		// summary:
 		//		Over-ride of updateState to hide the toolbar when the iframe is not visible.
 		//		Also triggers the breadcrumb update.
-		if(dojo.style(this.editor.iframe, "display") === "none"){
+		if(dojo.style(this.editor.iframe, "display") === "none" || this.get("disabled")){
 			dojo.style(this.breadcrumbBar.domNode, "display", "none");
 		}else{
 			if(dojo.style(this.breadcrumbBar.domNode, "display") === "none"){
@@ -328,9 +315,13 @@ dojo.declare("dojox.editor.plugins.Breadcrumb",dijit._editor._Plugin,{
 		// summary:
 		//		Over-ride to clean up the breadcrumb toolbar.
 		if(this.breadcrumbBar){
-			this.breadcrumbBar.destroy();
+			this.breadcrumbBar.destroyRecursive();
 			this.breadcrumbBar = null;
 		}
+		if(this._menu){
+			this._menu.destroyRecursive();
+			delete this._menu;
+		}
 		this._buttons = null;
 		delete this.editor.breadcrumbBar;
 		this.inherited(arguments);
@@ -345,3 +336,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.Breadcrumb({});
 	}
 });
+
+return dojox.editor.plugins.Breadcrumb;
+
+});
diff --git a/dojox/editor/plugins/CollapsibleToolbar.js b/dojox/editor/plugins/CollapsibleToolbar.js
index fd5df5c..35f421a 100644
--- a/dojox/editor/plugins/CollapsibleToolbar.js
+++ b/dojox/editor/plugins/CollapsibleToolbar.js
@@ -1,10 +1,4 @@
-dojo.provide("dojox.editor.plugins.CollapsibleToolbar");
-
-dojo.require("dijit._Widget")
-dojo.require("dijit._Templated");
-dojo.require("dijit._editor._Plugin");
-
-dojo.requireLocalization("dojox.editor.plugins", "CollapsibleToolbar");
+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], {
 	// summary:
@@ -61,7 +55,7 @@ dojo.declare("dojox.editor.plugins.CollapsibleToolbar",dijit._editor._Plugin,{
 	_constructContainer: function(){
 		// summary:
 		//		Internal function to construct a wrapper for the toolbar/header that allows
-		//		it to expand and collapse.  It effectively builds a containing table, 
+		//		it to expand and collapse.  It effectively builds a containing table,
 		//		which handles the layout nicely and gets BIDI support by default.
 		// tags:
 		//		private
@@ -172,3 +166,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.CollapsibleToolbar({});
 	}
 });
+
+return dojox.editor.plugins.CollapsibleToolbar;
+
+});
diff --git a/dojox/editor/plugins/EntityPalette.js b/dojox/editor/plugins/EntityPalette.js
index 86c1b24..e5f4a7a 100755
--- a/dojox/editor/plugins/EntityPalette.js
+++ b/dojox/editor/plugins/EntityPalette.js
@@ -1,11 +1,4 @@
-dojo.provide("dojox.editor.plugins.EntityPalette");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._PaletteMixin");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "latinEntities");
+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) {
 
 dojo.experimental("dojox.editor.plugins.EntityPalette");
 
@@ -221,3 +214,7 @@ dojo.declare("dojox.editor.plugins.LatinEntity",
 			cell.innerHTML = this.getValue();
 		}
 });
+
+return dojox.editor.plugins.EntityPalette;
+
+});
diff --git a/dojox/editor/plugins/FindReplace.js b/dojox/editor/plugins/FindReplace.js
index bfbc71e..43a0f3e 100755
--- a/dojox/editor/plugins/FindReplace.js
+++ b/dojox/editor/plugins/FindReplace.js
@@ -1,16 +1,4 @@
-dojo.provide("dojox.editor.plugins.FindReplace");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.Toolbar");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.CheckBox");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dojox.editor.plugins.ToolbarLineBreak");
-dojo.require("dojo.i18n");
-dojo.require("dojo.string");
-
-dojo.requireLocalization("dojox.editor.plugins", "FindReplace");
+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) {
 
 dojo.experimental("dojox.editor.plugins.FindReplace");
 
@@ -31,7 +19,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceCloseBox", [dijit._Widget, dijit.
 	
 	postMixInProperties: function(){
 		// Set some substitution variables used in the template
-		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));		
+		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
 		this.btnId = this.id + "_close";
 		this.inherited(arguments);
 	},
@@ -55,7 +43,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 	textId: "",
 	
 	// label: [public] String
-	//		The label of the enhanced textbox 
+	//		The label of the enhanced textbox
 	label: "",
 	
 	// tooltip: [public] String
@@ -74,7 +62,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 
 	postMixInProperties: function(){
 		// Set some substitution variables used in the template
-		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));		
+		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
 		this.textId = this.id + "_text";
 		
 		this.inherited(arguments);
@@ -98,12 +86,12 @@ dojo.declare("dojox.editor.plugins._FindReplaceTextBox",
 
 	_setDisabledAttr: function(/*Boolean*/ value){
 		// summary:
-		//		Over-ride for the textbox's 'disabled' attribute so that it can be 
+		//		Over-ride for the textbox's 'disabled' attribute so that it can be
 		//		disabled programmatically.
 		// value:
 		//		The boolean value to indicate if the textbox should be disabled or not
 		// tags:
-		//		private 
+		//		private
 		this.disabled = value;
 		this.textBox.set("disabled", value);
 	},
@@ -180,7 +168,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
 
 	postMixInProperties: function(){
 		// Set some substitution variables used in the template
-		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));		
+		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
 		this.checkId = this.id + "_check";
 		this.inherited(arguments);
 	},
@@ -217,7 +205,7 @@ dojo.declare("dojox.editor.plugins._FindReplaceCheckBox",
 
 	_setDisabledAttr: function(/*Boolean*/ value){
 		// summary:
-		//		Over-ride for the button's 'disabled' attribute so that it can be 
+		//		Over-ride for the button's 'disabled' attribute so that it can be
 		//		disabled programmatically.
 		// value:
 		//		The flag that indicates if the checkbox is disabled or not.
@@ -392,7 +380,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 				this._displayed = false;
 			}
 			
-			// If the toggle button is disabled, it is most likely that 
+			// If the toggle button is disabled, it is most likely that
 			// another plugin such as ViewSource disables it.
 			// So we do not need to focus the text area of the editor to
 			// prevent the editor from an invalid status.
@@ -409,7 +397,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 	_populateFindField: function(){
 		// summary:
 		//		Populate the Find field with selected text when dialog initially displayed.
-		//		Auto-select text in Find field after it’s populated.
+		//		Auto-select text in Find field after it is populated.
 		//		If nothing selected, restore previous entry from the same session.
 		// tags:
 		//		private
@@ -455,9 +443,9 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 			_tb.addChild(this._replaceField);
 
 			// Define the Find/Replace/ReplaceAll buttons.
-			_tb.addChild(new dojox.editor.plugins._ToolbarLineBreak());
+			_tb.addChild(new dojox.editor.plugins.ToolbarLineBreak());
 			
-			this._findButton = new dijit.form.Button({label: this._strings["findButton"], showLabel: true, 
+			this._findButton = new dijit.form.Button({label: this._strings["findButton"], showLabel: true,
 				iconClass: this.iconClassPrefix + " dijitEditorIconFind"});
 			this._findButton.titleNode.title = this._strings["findButtonTooltip"];
 			_tb.addChild(this._findButton);
@@ -481,7 +469,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 				{label: this._strings["backwards"], tooltip: this._strings["backwardsTooltip"]});
 			_tb.addChild(this._backwards);
 
-			// Set initial states, buttons should be disabled unless content is 
+			// Set initial states, buttons should be disabled unless content is
 			// present in the fields.
 			this._findButton.set("disabled", true);
 			this._replaceButton.set("disabled", true);
@@ -551,7 +539,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		//		private.
 		// returns:
 		//		Boolean indicating if the content was found or not.
-		var txt = this._findField.get("value") || ""; 
+		var txt = this._findField.get("value") || "";
 		if(txt){
 			var caseSensitive = this._caseSensitive.get("value");
 			var backwards = this._backwards.get("value");
@@ -616,7 +604,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 					// to avoid the infinite recursive replace
 					this._findText(repTxt, caseSensitive, backwards);
 					dojo.withGlobal(ed.window, "collapse", dijit._editor.selection, [true]);
-				}	
+				}
 			}
 			
 			if(!this._find(false) && showMessage){	// Find the next
@@ -634,6 +622,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 			}
 			return isReplaced;
 		 }
+		 return null;
 	},
 	
 	_replaceAll: function(/*Boolean?*/ showMessage){
@@ -654,7 +643,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		}
 		
 		// The _replace will return false if the current selection deos not match
-		// the searched text. So try the first attempt so that the selection 
+		// the searched text. So try the first attempt so that the selection
 		// is always the searched text if there is one that matches
 		if(this._replace(false)) { replaced++; }
 		// Do the replace via timeouts to avoid locking the browser up for a lot of replaces.
@@ -708,7 +697,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 				var doc = ed.document;
 				if(doc.selection){
 					/* IE */
-					// Focus to restore position/selection, 
+					// Focus to restore position/selection,
 					// then shift to search from current position.
 					this.editor.focus();
 					var txtRg = doc.body.createTextRange();
@@ -736,11 +725,11 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 	},
 
 	_filterRegexp: function(/*String*/ pattern, /*Boolean*/ ignoreCase){
-		// summary:  
+		// summary:
 		//		Helper function to convert a simple pattern to a regular expression for matching.
 		// description:
 		//		Returns a regular expression object that conforms to the defined conversion rules.
-		//		For example:  
+		//		For example:
 		//			ca*   -> /^ca.*$/
 		//			*ca*  -> /^.*ca.*$/
 		//			*c\*a*  -> /^.*c\*a.*$/
@@ -752,7 +741,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		//			* Means match anything, so ca* means match anything starting with ca
 		//			? Means match single character.  So, b?b will match to bob and bab, and so on.
 		//			\ is an escape character.  So for example, \* means do not treat * as a match, but literal character *.
-		//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be 
+		//				To use a \ as a character in the string, it must be escaped.  So in the pattern it should be
 		//				represented by \\ to be treated as an ordinary \ character instead of an escape.
 		//
 		//	ignoreCase:
@@ -795,6 +784,12 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		}
 		
 	},
+	
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
 
 	destroy: function(){
 		// summary:
@@ -803,7 +798,7 @@ dojo.declare("dojox.editor.plugins.FindReplace",[dijit._editor._Plugin],{
 		if(this._promDialogTimeout){
 			clearTimeout(this._promDialogTimeout);
 			this._promDialogTimeout = null;
-			dijit.popup.close(this._promDialog);	
+			dijit.popup.close(this._promDialog);
 		}
 		if(this._frToolbar){
 			this._frToolbar.destroyRecursive();
@@ -825,3 +820,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.FindReplace({});
 	}
 });
+
+return dojox.editor.plugins.FindReplace;
+
+});
diff --git a/dojox/editor/plugins/InsertAnchor.js b/dojox/editor/plugins/InsertAnchor.js
index cede291..5b3b094 100755
--- a/dojox/editor/plugins/InsertAnchor.js
+++ b/dojox/editor/plugins/InsertAnchor.js
@@ -1,17 +1,4 @@
-dojo.provide("dojox.editor.plugins.InsertAnchor");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.ValidationTextBox");
-dojo.require("dijit.form.Select");
-dojo.require("dijit._editor.range");
-dojo.require("dojo.i18n");
-dojo.require("dojo.string");
-dojo.requireLocalization("dijit", "common");
-dojo.requireLocalization("dojox.editor.plugins", "InsertAnchor");
+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) {
 
 dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 	// summary:
@@ -103,6 +90,12 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 		this.editor.contentDomPostFilters.push(dojo.hitch(this, this._postDomFilter));
 		this._setup();
 	},
+	
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
 
 	setEditor: function(editor){
 		// summary:
@@ -115,7 +108,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 
 	_checkInput: function(){
 		// summary:
-		//		Function to check the input to the dialog is valid 
+		//		Function to check the input to the dialog is valid
 		//		and enable/disable set button
 		// tags:
 		//		private
@@ -159,7 +152,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 		var modurl = dojo.moduleUrl(dojox._scopeName, "editor/plugins/resources").toString();
 		if(!(modurl.match(/^https?:\/\//i)) &&
 			!(modurl.match(/^file:\/\//i))){
-			// We have to root it to the page location on webkit for some nutball reason. 
+			// We have to root it to the page location on webkit for some nutball reason.
 			// Probably has to do with how iframe was loaded.
 			var bUrl;
 			if(modurl.charAt(0) === "/"){
@@ -216,7 +209,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 				fullUrl = fullUrl.substring(0,index);
 			}
 
-			// Now we need to trim if necessary.  If it ends in /, then we don't 
+			// Now we need to trim if necessary.  If it ends in /, then we don't
 			// have a filename to trim off so we can return.
 			index = fullUrl.lastIndexOf("/");
 			if (index > 0 && index < fullUrl.length) {
@@ -232,8 +225,8 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 		// summary:
 		//		Function to check the values in args and 'fix' them up as needed.
 		// args: Object
-		//		Content being set.		
-		// tags: 
+		//		Content being set.
+		// tags:
 		//		protected
 		if(args){
 			if(args.anchorInput){
@@ -287,7 +280,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 			}
 		}
 		// make sure values are properly escaped, etc.
-		args = this._checkValues(args); 
+		args = this._checkValues(args);
 		this.editor.execCommand('inserthtml',
 			dojo.string.substitute(this.htmlTemplate, args));
 	},
@@ -377,7 +370,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 
 	_preDomFilter: function(node){
 		// summary:
-		//		A filter to identify the 'a' tags and if they're anchors, 
+		//		A filter to identify the 'a' tags and if they're anchors,
 		//		apply the right style to them.
 		// node:
 		//		The node to search from.
@@ -397,7 +390,7 @@ dojo.declare("dojox.editor.plugins.InsertAnchor", dijit._editor._Plugin, {
 
 	_postDomFilter: function(node){
 		// summary:
-		//		A filter to identify the 'a' tags and if they're anchors, 
+		//		A filter to identify the 'a' tags and if they're anchors,
 		//		remove the class style that shows up in the editor from
 		//		them.
 		// node:
@@ -428,3 +421,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.InsertAnchor();
 	}
 });
+
+return dojox.editor.plugins.InsertAnchor;
+
+});
diff --git a/dojox/editor/plugins/InsertEntity.js b/dojox/editor/plugins/InsertEntity.js
index c094174..bc47480 100755
--- a/dojox/editor/plugins/InsertEntity.js
+++ b/dojox/editor/plugins/InsertEntity.js
@@ -1,18 +1,8 @@
-dojo.provide("dojox.editor.plugins.InsertEntity");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dojox.editor.plugins.EntityPalette");
-dojo.require("dojox.html.entities");
-
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "InsertEntity");
+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) {
 
 dojo.declare("dojox.editor.plugins.InsertEntity",dijit._editor._Plugin,{
 	// summary:
-	//		This plugin allows the user to select from standard Symbols (HTML Entities) 
+	//		This plugin allows the user to select from standard Symbols (HTML Entities)
 	//		to insert at the current cursor position.  It binds to the key pattern:
 	//		ctrl-shift-s for opening the insert symbol dropdown.
 	//
@@ -43,6 +33,12 @@ dojo.declare("dojox.editor.plugins.InsertEntity",dijit._editor._Plugin,{
 		});
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
+
 	setEditor: function(editor){
 		// summary:
 		//		Over-ride for the setting of the editor.
@@ -72,8 +68,8 @@ dojo.declare("dojox.editor.plugins.InsertEntity",dijit._editor._Plugin,{
 
 	_postFilterEntities: function(s/*String content passed in*/){
 		// summary:
-		//		A function to filter out entity characters into encoded form so they 
-		//		are properly displayed in the editor.  It gets registered with the 
+		//		A function to filter out entity characters into encoded form so they
+		//		are properly displayed in the editor.  It gets registered with the
 		//		postFilters of the editor.
 		// tags:
 		//		private.
@@ -92,3 +88,6 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+return dojox.editor.plugins.InsertEntity;
+});
diff --git a/dojox/editor/plugins/LocalImage.js b/dojox/editor/plugins/LocalImage.js
new file mode 100644
index 0000000..7092f32
--- /dev/null
+++ b/dojox/editor/plugins/LocalImage.js
@@ -0,0 +1,341 @@
+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) {
+
+dojo.declare("dojox.editor.plugins.LocalImage", dijit._editor.plugins.ImgLinkDialog, {
+	// summary:
+	//		This plugin provides an enhanced image link dialog that
+	//		not only insert the online images, but upload the local image files onto
+	//		to server then insert them as well.
+	// Dependencies:
+	//		This plugin depends on dojox.form.FileUploader to upload the images on the local driver.
+	//		Do the regression test whenever FileUploader is upgraded.
+	
+	// uploadable [public] Boolean
+	//		Indicate whether the user can upload a local image file onto the server.
+	//		If it is set to true, the Browse button will be available.
+	uploadable: false,
+	
+	// uploadUrl [public] String
+	//		The url targeted for uploading. Both absolute and relative URLs are OK.
+	uploadUrl: "",
+	
+	// baseImageUrl [public] String
+	//		The prefix of the image url on the server.
+	//		For example, an image is uploaded and stored at the following location
+	//			http://www.myhost.com/images/uploads/test.jpg.
+	//		When the image is uploaded, the server returns "uploads/test.jpg" as the
+	//		relative path. So the baseImageUrl should be set to "http://www.myhost.com/images/"
+	//		so that the client can retrieve the image from the server.
+	//		If the image file is located on the same domain as that of the current web page,
+	//		baseImageUrl can be a relative path. For example:
+	//			baseImageUrl = images/
+	//		and the server returns uploads/test.jpg
+	//		The complete URL of the image file is images/upload/test.jpg
+	baseImageUrl: "",
+	
+	// fileMask [public] String
+	//		Specify the types of images that are allowed to be uploaded.
+	//		Note that the type checking on server is also very important!
+	fileMask: "*.jpg;*.jpeg;*.gif;*.png;*.bmp",
+	
+	// urlRegExp [protected] String
+	//		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:"uploadedfile",
+	
+	// _isLocalFile [private] Boolean
+	//		Indicate if a local file is to be uploaded to the server
+	//		If false, the text of _urlInput field is regarded as the
+	//		URL of the online image
+	_isLocalFile: false,
+	
+	// _messages [private] Array<String>
+	//		Contains i18n strings.
+	_messages: "",
+	
+	// _cssPrefix [private] String
+	//		The prefix of the CSS style
+	_cssPrefix: "dijitEditorEilDialog",
+	
+	// _closable [private] Boolean
+	//		Indicate if the tooltip dialog can be closed. Used to workaround Safari 5 bug
+	//		where the file dialog doesn't pop up in modal until after the first click.
+	_closable: true,
+	
+	// linkDialogTemplate [protected] String
+	//		Over-ride for template since this is an enhanced image dialog.
+	linkDialogTemplate: [
+		"<div style='border-bottom: 1px solid black; padding-bottom: 2pt; margin-bottom: 4pt;'></div>", // <hr/> breaks the dialog in IE6
+		"<div class='dijitEditorEilDialogDescription'>${prePopuTextUrl}${prePopuTextBrowse}</div>",
+		"<table><tr><td colspan='2'>",
+		"<label for='${id}_urlInput' title='${prePopuTextUrl}${prePopuTextBrowse}'>${url}</label>",
+		"</td></tr><tr><td class='dijitEditorEilDialogField'>",
+		"<input dojoType='dijit.form.ValidationTextBox' class='dijitEditorEilDialogField'" +
+		"regExp='${urlRegExp}' title='${prePopuTextUrl}${prePopuTextBrowse}'  selectOnClick='true' required='true' " +
+		"id='${id}_urlInput' name='urlInput' intermediateChanges='true' invalidMessage='${invalidMessage}' " +
+		"prePopuText='<${prePopuTextUrl}${prePopuTextBrowse}&gt'>",
+		"</td><td>",
+		"<div id='${id}_browse' style='display:${uploadable}'>${browse}</div>",
+		"</td></tr><tr><td colspan='2'>",
+		"<label for='${id}_textInput'>${text}</label>",
+		"</td></tr><tr><td>",
+		"<input dojoType='dijit.form.TextBox' required='false' id='${id}_textInput' " +
+		"name='textInput' intermediateChanges='true' selectOnClick='true' class='dijitEditorEilDialogField'>",
+		"</td><td></td></tr><tr><td>",
+		"</td><td>",
+		"</td></tr><tr><td colspan='2'>",
+		"<button dojoType='dijit.form.Button' id='${id}_setButton'>${set}</button>",
+		"</td></tr></table>"
+	].join(""),
+
+	_initButton: function(){
+		// summary:
+		//		Override _Plugin._initButton() to initialize DropDownButton and TooltipDialog.
+		// tags:
+		//		protected
+		var _this = this,
+			messages = this._messages = dojo.i18n.getLocalization("dojox.editor.plugins", "LocalImage");
+		
+		this.tag = "img";
+		var dropDown = (this.dropDown = new dijit.TooltipDialog({
+			title: messages[this.command + "Title"],
+			onOpen: function(){
+				_this._initialFileUploader();
+				_this._onOpenDialog();
+				dijit.TooltipDialog.prototype.onOpen.apply(this, arguments);
+				setTimeout(function(){
+					// Auto-select the text if it is not empty
+					dijit.selectInputText(_this._urlInput.textbox);
+					_this._urlInput.isLoadComplete = true;
+				}, 0);
+			},
+			onClose: function(){
+				dojo.disconnect(_this.blurHandler);
+				_this.blurHandler = null;
+				this.onHide();
+			},
+			onCancel: function(){
+				setTimeout(dojo.hitch(_this, "_onCloseDialog"),0);
+			}
+		}));
+		
+		var label = this.getLabel(this.command),
+			className = this.iconClassPrefix + " " + this.iconClassPrefix + this.command.charAt(0).toUpperCase() + this.command.substr(1),
+			props = dojo.mixin({
+					label: label,
+					showLabel: false,
+					iconClass: className,
+					dropDown: this.dropDown,
+					tabIndex: "-1"
+				}, this.params || {});
+		
+		if(!dojo.isIE && (!dojo.isFF || dojo.isFF < 4)){
+			// 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
+			// FF & Chrome: the select-file dialog does not block the execution of JS
+			props.closeDropDown = function(/*Boolean*/ focus){
+				if(_this._closable){
+					if(this._opened){
+						dijit.popup.close(this.dropDown);
+						if(focus){ this.focus(); }
+						this._opened = false;
+						this.state = "";
+					}
+				}
+				setTimeout(function(){ _this._closable = true; }, 10);
+			};
+		}
+		
+		this.button = new dijit.form.DropDownButton(props);
+		
+		// Generate the RegExp of the ValidationTextBox from fileMask
+		// *.jpg;*.png => /.*\.jpg|.*\.JPG|.*\.png|.*\.PNG/
+		var masks = this.fileMask.split(";"),
+			temp = "";
+		dojo.forEach(masks, function(m){
+			m = m.replace(/\./, "\\.").replace(/\*/g, ".*");
+			temp += "|" + m + "|" + m.toUpperCase();
+		});
+		messages.urlRegExp = this.urlRegExp = temp.substring(1);
+		
+		if(!this.uploadable){
+			messages["prePopuTextBrowse"] = ".";
+		}
+		
+		messages.id = dijit.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");
+		
+		if(urlInput){
+			var pt = dijit.form.ValidationTextBox.prototype;
+			urlInput = dojo.mixin(urlInput, {
+				// Indicate if the widget is ready to validate the input text
+				isLoadComplete: false,
+				isValid: function(isFocused){
+					if(this.isLoadComplete){
+						return pt.isValid.apply(this, arguments);
+					}else{
+						return this.get("value").length > 0;
+					}
+				},
+				reset: function(){
+					this.isLoadComplete = false;
+					pt.reset.apply(this, arguments);
+				}
+			});
+			
+			this.connect(urlInput, "onKeyDown", "_cancelFileUpload");
+			this.connect(urlInput, "onChange", "_checkAndFixInput");
+		}
+		if(this._setButton){
+			this.connect(this._setButton, "onClick", "_checkAndSetValue");
+		}
+		this._connectTagEvents();
+	},
+	
+	_initialFileUploader: function(){
+		// summary:
+		//		Initialize the FileUploader and connect up its events
+		// tags:
+		//		private
+		var fup = null,
+			_this = this,
+			widgetId = _this._uniqueId,
+			fUpId = widgetId + "_browse",
+			urlInput = _this._urlInput;
+		
+		if(_this.uploadable && !_this._fileUploader){
+			fup = _this._fileUploader = new dojox.form.FileUploader({
+				force: "html", // Noticed that SWF may cause browsers to crash sometimes
+				uploadUrl: _this.uploadUrl,
+				htmlFieldName: _this.htmlFieldName,
+				uploadOnChange: false,
+				selectMultipleFiles: false,
+				showProgress: true
+			}, fUpId);
+			
+			// TooltipDialog will call reset on all the widgets contained within it.
+			// Have FileUploader be responsive to this call.
+			fup.reset = function(){
+				_this._isLocalFile = false;
+				fup._resetHTML();
+			};
+			
+			_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:
+					// 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.
+					_this._closable = false;
+				}
+			});
+
+			
+			_this.connect(fup, "onChange", function(data){
+				_this._isLocalFile = true;
+				urlInput.set("value", data[0].name); //Single selection
+				urlInput.focus();
+			});
+			
+			_this.connect(fup, "onComplete", function(data){
+				var urlPrefix = _this.baseImageUrl;
+				urlPrefix = urlPrefix && urlPrefix.charAt(urlPrefix.length - 1) == "/" ? urlPrefix : urlPrefix + "/";
+				urlInput.set("value", urlPrefix + data[0].file); //Single selection
+				_this._isLocalFile = false;
+				_this._setDialogStatus(true);
+				_this.setValue(_this.dropDown.get("value"));
+			});
+			
+			_this.connect(fup, "onError", function(evtObject){
+				// summary:
+				//		Fires on errors
+				console.log("Error occurred when uploading image file!");
+				_this._setDialogStatus(true);
+			});
+		}
+	},
+	
+	_checkAndFixInput: function(){
+		// summray:
+		//		Over-ride the original method
+		this._setButton.set("disabled", !this._isValid());
+	},
+	
+	_isValid: function(){
+		// summray:
+		//		Invalid cases: URL is not ended with the suffix listed
+		return this._urlInput.isValid();
+	},
+	
+	_cancelFileUpload: function(){
+		this._fileUploader.reset();
+		this._isLocalFile = false;
+	},
+	
+	_checkAndSetValue: function(){
+		// summray:
+		//		Determine if a local file is to be uploaded.
+		//		If a local file is to be uploaded, do not close the dialog
+		//		until the file uploading is finished. Else, insert the image directly into the editor.
+		// tags:
+		//		private
+		if(this._fileUploader && this._isLocalFile){
+			this._setDialogStatus(false);
+			this._fileUploader.upload();
+		}else{
+			this.setValue(this.dropDown.get("value"));
+		}
+	},
+	
+	_setDialogStatus: function(/*Boolean*/ value){
+		this._urlInput.set("disabled", !value);
+		this._textInput.set("disabled", !value);
+		this._setButton.set("disabled", !value);
+	},
+	
+	destroy: function(){
+		// summary:
+		//		Cleanup of the plugin.
+		this.inherited(arguments);
+		if(this._fileUploader){
+			this._fileUploader.destroy();
+			this._fileUploader = null;
+		}
+	}
+});
+
+// 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"
+		});
+	}
+});
+
+return dojox.editor.plugins.LocalImage;
+
+});
diff --git a/dojox/editor/plugins/NormalizeIndentOutdent.js b/dojox/editor/plugins/NormalizeIndentOutdent.js
index 19f7cd5..2998bc0 100755
--- a/dojox/editor/plugins/NormalizeIndentOutdent.js
+++ b/dojox/editor/plugins/NormalizeIndentOutdent.js
@@ -1,9 +1,4 @@
-dojo.provide("dojox.editor.plugins.NormalizeIndentOutdent");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit._editor.selection");
-
-dojo.experimental("dojox.editor.plugins.NormalizeIndentOutdent");
+define("dojox/editor/plugins/NormalizeIndentOutdent", ["dojo", "dijit", "dojox", "dijit/_editor/selection", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin,{
 	// summary:
@@ -19,7 +14,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 	
 	// indentUnits: [public] String
 	//		The units to apply to the indent amount.  Usually 'px', but can also
-	//		be em.  
+	//		be em.
 	indentUnits: "px",
 
 	setEditor: function(editor){
@@ -41,9 +36,9 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 		editor.queryCommandEnabled = dojo.hitch(this, this._queryCommandEnabled);
 
 		// We need the custom undo code since we manipulate the dom
-		// outside of the browser natives and only customUndo really handles 
+		// outside of the browser natives and only customUndo really handles
 		// that.  It will incur a performance hit, but should hopefully be
-		// relatively small.  
+		// relatively small.
 		editor.customUndo = true;
 	},
 
@@ -130,7 +125,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 
 	_indentImpl: function(/*String*/ html) {
 		// summary:
-		//		Improved implementation of indent, generates correct indent for 
+		//		Improved implementation of indent, generates correct indent for
 		//		ul/ol
 		var ed = this.editor;
 
@@ -145,11 +140,11 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 				// No selection, just cursor point, we need to see if we're
 				// in an indentable block, or similar.
 				if(this._isRootInline(range.startContainer)){
-					// Text at the 'root' of the document, 
-					// we'll try to indent it and all inline selements around it 
+					// Text at the 'root' of the document,
+					// we'll try to indent it and all inline selements around it
 					// as they are visually a single line.
 
-					// First, we need to find the toplevel inline element that is rooted 
+					// First, we need to find the toplevel inline element that is rooted
 					// to the document 'editNode'
 					start = range.startContainer;
 					while(start && start.parentNode !== ed.editNode){
@@ -159,7 +154,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 					// Now we need to walk up its siblings and look for the first one in the rooting
 					// that isn't inline or text, as we want to grab all of that for indent.
 					while(start && start.previousSibling && (
-							this._isTextElement(start) || 
+							this._isTextElement(start) ||
 							(start.nodeType === 1 && this._isInlineFormat(this._getTagName(start))
 						))){
 						start = start.previousSibling;
@@ -169,7 +164,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 						start = start.nextSibling;
 					}
 
-					// Okay, we have a configured start, lets grab everything following it that's 
+					// Okay, we have a configured start, lets grab everything following it that's
 					// inline and make it an indentable block!
 					if(start){
 						div = ed.document.createElement("div");
@@ -178,17 +173,17 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 						end = div.nextSibling;
 						while(end && (
 							this._isTextElement(end) ||
-							(end.nodeType === 1 && 
+							(end.nodeType === 1 &&
 								this._isInlineFormat(this._getTagName(end)))
 							)){
-							// Add it. 
+							// Add it.
 							div.appendChild(end);
 							end = div.nextSibling;
 						}
 						this._indentElement(div);
-						dojo.withGlobal(ed.window, 
+						dojo.withGlobal(ed.window,
 							"selectElementChildren", dijit._editor.selection, [div]);
-						dojo.withGlobal(ed.window, 
+						dojo.withGlobal(ed.window,
 							"collapse", dijit._editor.selection, [true]);
 					}
 				}else{
@@ -224,13 +219,13 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 					// Okay, selection end is somewhere after start, we need to find the last node
 					// that is safely in the range.
 					curNode = start;
-					while(curNode.nextSibling && 
+					while(curNode.nextSibling &&
 						dojo.withGlobal(ed.window, "inSelection", dijit._editor.selection, [curNode])){
 						curNode = curNode.nextSibling;
 					}
-					end = curNode; 
+					end = curNode;
 					if(end === ed.editNode || end === ed.document.body){
-						// Unable to determine real selection end, so just make it 
+						// Unable to determine real selection end, so just make it
 						// a single node indent of start + all following inline styles, if
 						// present, then just exit.
 						tag = this._getTagName(start);
@@ -244,7 +239,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 							div = ed.document.createElement("div");
 							dojo.place(div, start, "after");
 
-							// Find and move all inline tags following the one we inserted also into the 
+							// Find and move all inline tags following the one we inserted also into the
 							// div so we don't split up content funny.
 							var next = start;
 							while(next && (
@@ -269,7 +264,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 					if(curNode.nodeType === 1){
 						tag = this._getTagName(curNode);
 						if(dojo.isIE){
-							// IE sometimes inserts blank P tags, which we want to skip 
+							// IE sometimes inserts blank P tags, which we want to skip
 							// as they end up indented, which messes up layout.
 							if(tag === "p" && this._isEmpty(curNode)){
 								curNode = curNode.nextSibling;
@@ -390,7 +385,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 
 	_outdentImpl: function(/*String*/ html) {
 		// summary:
-		//		Improved implementation of outdent, generates correct indent for 
+		//		Improved implementation of outdent, generates correct indent for
 		//		ul/ol and other elements.
 		// tags:
 		//		private
@@ -440,7 +435,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 
 					}
 					curNode = curNode.nextSibling;
-				}	
+				}
 			}
 		}
 		return null;
@@ -479,8 +474,8 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 			// There is a previous node in the list, so we want to append a new list
 			// element after it that contains a new list of the content to indent it.
 			if(prevTag && prevTag.tagName.toLowerCase() == "li"){
-				// Lets see if we can merge this into another  (Eg, 
-				// does the sibling li contain an embedded list already of 
+				// Lets see if we can merge this into another  (Eg,
+				// does the sibling li contain an embedded list already of
 				// the same type?  if so, we move into that one.
 				var embList;
 				if(prevTag.childNodes){
@@ -526,9 +521,9 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 				}
 
 				// Move cursor.
-				dojo.withGlobal(ed.window, 
+				dojo.withGlobal(ed.window,
 					"selectElementChildren", dijit._editor.selection, [listItem]);
-				dojo.withGlobal(ed.window, 
+				dojo.withGlobal(ed.window,
 					"collapse", dijit._editor.selection, [true]);
 			}
 		}
@@ -563,7 +558,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 		if(lpTg === "li" || lpTg === "ol" || lpTg === "ul"){
 			if(lpTg === "ol" || lpTg === "ul"){
 				// Okay, we need to fix this up, this is invalid html,
-				// So try to combine this into a previous element before 
+				// So try to combine this into a previous element before
 				// de do a shuffle of the nodes, to build an HTML compliant
 				// list.
 				var prevListLi = list.previousSibling;
@@ -624,14 +619,14 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 				dojo.place(listItem, listParent, "after");
 				listItem.appendChild(list);
 			}else if(!nextLi){
-				// Last item in a nested list, shuffle it out after 
+				// Last item in a nested list, shuffle it out after
 				// the nsted list only.
 				dojo.place(listItem, listParent, "after");
 			}else{
-				// Item is in the middle of an embedded  list, so we 
+				// Item is in the middle of an embedded  list, so we
 				// have to split it.
 
-				// Move all the items following current list item into 
+				// Move all the items following current list item into
 				// a list after it.
 				var newList = ed.document.createElement(type);
 				dojo.style(newList, {
@@ -643,23 +638,23 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 					newList.appendChild(listItem.nextSibling);
 				}
 
-				// Okay, now place the list item after the 
+				// Okay, now place the list item after the
 				// current list parent (li).
 				dojo.place(listItem, listParent, "after");
 			}
 			
 			// Clean up any empty lists left behind.
 			if(list && this._isEmpty(list)){
-				list.parentNode.removeChild(list);	
+				list.parentNode.removeChild(list);
 			}
 			if(listParent && this._isEmpty(listParent)){
 				listParent.parentNode.removeChild(listParent);
 			}
 			
 			// Move our cursor to the list item we moved.
-			dojo.withGlobal(ed.window, 
+			dojo.withGlobal(ed.window,
 				"selectElementChildren", dijit._editor.selection, [listItem]);
-			dojo.withGlobal(ed.window, 
+			dojo.withGlobal(ed.window,
 				"collapse", dijit._editor.selection, [true]);
 		}else{
 			// Not in a nested list, so we can just defer to the
@@ -685,7 +680,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 				if(n.nodeType === 1){
 					if(this._getTagName(n) === "p"){
 						if(!dojo.trim(n.innerHTML)){
-							continue;	
+							continue;
 						}
 					}
 					empty = false;
@@ -734,7 +729,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 
 	_convertIndent: function(indent){
 		// summary:
-		//		Function to convert the current indent style to 
+		//		Function to convert the current indent style to
 		//		the units we're using by some heuristic.
 		// indent:
 		//		The indent amount to convert.
@@ -772,7 +767,7 @@ dojo.declare("dojox.editor.plugins.NormalizeIndentOutdent",dijit._editor._Plugin
 	_isInlineFormat: function(tag){
 		// summary:
 		//		Function to determine if the current tag is an inline
-		//		element that does formatting, as we don't want to 
+		//		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
@@ -862,12 +857,16 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	var name = o.args.name.toLowerCase();
 	if(name === "normalizeindentoutdent"){
 		o.plugin = new dojox.editor.plugins.NormalizeIndentOutdent({
-			indentBy: ("indentBy" in o.args) ? 
-				(o.args.indentBy > 0 ? o.args.indentBy : 40) : 
+			indentBy: ("indentBy" in o.args) ?
+				(o.args.indentBy > 0 ? o.args.indentBy : 40) :
 				40,
-			indentUnits: ("indentUnits" in o.args) ? 
-				(o.args.indentUnits.toLowerCase() == "em"? "em" : "px") : 
+			indentUnits: ("indentUnits" in o.args) ?
+				(o.args.indentUnits.toLowerCase() == "em"? "em" : "px") :
 				"px"
 		});
 	}
 });
+
+return dojox.editor.plugins.NormalizeIndentOutdent;
+
+});
diff --git a/dojox/editor/plugins/NormalizeStyle.js b/dojox/editor/plugins/NormalizeStyle.js
index 88f7020..4529457 100755
--- a/dojox/editor/plugins/NormalizeStyle.js
+++ b/dojox/editor/plugins/NormalizeStyle.js
@@ -1,26 +1,21 @@
-dojo.provide("dojox.editor.plugins.NormalizeStyle");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit._editor.html");
-
-dojo.experimental("dojox.editor.plugins.NormalizeStyle");
+define("dojox/editor/plugins/NormalizeStyle", ["dojo", "dijit", "dojox", "dijit/_editor/html", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
-	//	summary:
+	// summary:
 	//		This plugin provides NormalizeStyle cabability to the editor.  It is
 	//		a headless plugin that tries to normalize how content is styled when
 	//		it comes out of th editor ('b' or css).   It also auto-converts
-	//		incoming content to the proper one expected by the browser as well so 
+	//		incoming content to the proper one expected by the browser as well so
 	//		that the native styling buttons work.
 
 	// mode [public] String
-	//		A String variable indicating if it should use semantic tags 'b', 'i', etc, or 
+	//		A String variable indicating if it should use semantic tags 'b', 'i', etc, or
 	//		CSS styling.  The default is semantic.
 	mode: "semantic",
 
 	// condenseSpans [public] Boolean
-	//		A boolean variable indicating if it should try to condense 
-	//		'span''span''span' styles  when in css mode 
+	//		A boolean variable indicating if it should try to condense
+	//		'span''span''span' styles  when in css mode
 	//		The default is true, it will try to combine where it can.
 	condenseSpans: true,
 
@@ -41,7 +36,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 		// Pre DOM filters are usually based on what browser, as they all use different ways to
 		// apply styles with actions and modify them.
 		if(dojo.isIE){
-			// IE still uses sematic tags most of the time, so convert to that.
+			// IE still uses semantic tags most of the time, so convert to that.
 			this.editor.contentDomPreFilters.push(dojo.hitch(this, this._convertToSemantic));
 			this._browserFilter = this._convertToSemantic;
 		}else if(dojo.isWebKit){
@@ -49,7 +44,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 			this._browserFilter = this._convertToCss;
 		}else if(dojo.isMoz){
 			//Editor currently forces Moz into semantic mode, so we need to match.  Ideally
-			//editor could get rid of that and just use CSS mode, whitch would work cleaner
+			//editor could get rid of that and just use CSS mode, which would work cleaner
 			//That's why this is split out, to make it easy to change later.
 			this.editor.contentDomPreFilters.push(dojo.hitch(this, this._convertToSemantic));
 			this._browserFilter = this._convertToSemantic;
@@ -68,8 +63,8 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 
 	_convertToSemantic: function(node){
 		// summary:
-		//		A function to convert the HTML structure of 'node' into 
-		//		sematic tags where possible.
+		//		A function to convert the HTML structure of 'node' into
+		//		semantic tags where possible.
 		// node: DOMNode
 		//		The node to process.
 		// tags:
@@ -136,7 +131,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 										case "underline":
 											sTag = dojo.withGlobal(w, "create", dojo, ["u", {}] );
 											break;
-										case "line-through": 
+										case "line-through":
 											sTag = dojo.withGlobal(w, "create", dojo, ["strike", {}] );
 											break;
 									}
@@ -162,7 +157,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 									"-webkit-xxx-large": 7
 								};
 
-								// Convert point or px size to size 
+								// Convert point or px size to size
 								// to something roughly mappable.
 								if(s.indexOf("pt") > 0){
 									s = s.substring(0,s.indexOf("pt"));
@@ -212,7 +207,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 							sTag = null;
 							if(bc && tag !== "font" && self._isInline(tag)){
 								// IE doesn't like non-font background color crud.
-								// Also, don't move it in if the background color is set on a block style node, 
+								// Also, don't move it in if the background color is set on a block style node,
 								// as it won't color properly once put on inline font.
 								bc = new dojo.Color(bc).toHex();
 								sTag = dojo.withGlobal(w, "create", dojo, ["font", {style: {backgroundColor: bc}}] );
@@ -243,7 +238,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 	},
 	
 	_normalizeTags: function(node){
-		// summary: 
+		// summary:
 		//		A function to handle normalizing certain tag types contained under 'node'
 		// node:
 		//		The node to search from.
@@ -270,7 +265,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 								break;
 					}
 					if(tTag){
-						var nNode = dojo.withGlobal(w, "create", dojo, [tTag, null, n, "before"] );	 
+						var nNode = dojo.withGlobal(w, "create", dojo, [tTag, null, n, "before"] );
 						while(n.firstChild){
 							nNode.appendChild(n.firstChild);
 						}
@@ -284,9 +279,9 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 
 	_convertToCss: function(node){
 		// summary:
-		//		A function to convert the HTML structure of 'node' into 
-		//		css span styles around text instead of sematic tags.
-		//		Note:  It does not do compression of dpans together.
+		//		A function to convert the HTML structure of 'node' into
+		//		css span styles around text instead of semantic tags.
+		//		Note:  It does not do compression of spans together.
 		// node: DOMNode
 		//		The node to process
 		// tags:
@@ -382,7 +377,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 		var compressSpans = function(node){
 			// Okay, span with no class or id and it has styles.
 			// So, merge the styles, then collapse.  Merge requires determining
-			// all the common/different styles and anything that overlaps the style, 
+			// all the common/different styles and anything that overlaps the style,
 			// but a different value can't be merged.
 			var genStyleMap = function(styleText){
 				var m;
@@ -417,7 +412,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 			if(node && node.nodeType == 1){
 				var tag = node.tagName? node.tagName.toLowerCase() : "";
 				if(tag === "span" && node.childNodes && node.childNodes.length === 1){
-					// Okay, a possibly compressable span
+					// Okay, a possibly compressible span
 					var c = node.firstChild;
 					while(c && c.nodeType == 1 && c.tagName && c.tagName.toLowerCase() == "span"){
 						if(!dojo.attr(c, "class") && !dojo.attr(c, "id") && c.style){
@@ -433,13 +428,13 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 										delete s2[i];
 									}else if(s1[i] != s2[i]){
 										// Collision, cannot merge.
-										// IE does not handle combined uderline strikethrough text
-										// decoraations on a single span.
+										// IE does not handle combined underline strikethrough text
+										// decorations on a single span.
 										if(i == "textDecoration"){
 											combinedMap[i] = s1[i] + " " + s2[i];
 											delete s2[i];
 										}else{
-											combinedMap = null;	
+											combinedMap = null;
 										}
 										break;
 									}else{
@@ -480,7 +475,7 @@ dojo.declare("dojox.editor.plugins.NormalizeStyle",dijit._editor._Plugin,{
 	_isInline: function(tag){
 		// summary:
 		//		Function to determine if the current tag is an inline
-		//		element that does formatting, as we don't want to 
+		//		element that does formatting, as we don't want to
 		//		try to combine inlines with divs on styles.
 		// tag:
 		//		The tag to examine
@@ -549,3 +544,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+return dojox.editor.plugins.NormalizeStyle;
+
+});
diff --git a/dojox/editor/plugins/PageBreak.js b/dojox/editor/plugins/PageBreak.js
index ff73f97..6ba52e1 100755
--- a/dojox/editor/plugins/PageBreak.js
+++ b/dojox/editor/plugins/PageBreak.js
@@ -1,9 +1,4 @@
-dojo.provide("dojox.editor.plugins.PageBreak");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "PageBreak");
+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) {
 
 dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 	//	summary:
@@ -17,7 +12,7 @@ dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 	useDefaultCommand: false,
 
 	// iconClassPrefix: [const] String
-	//		The CSS class name for the button node is formed from 
+	//		The CSS class name for the button node is formed from
 	//		`iconClassPrefix` and `command`
 	iconClassPrefix: "dijitAdditionalEditorIcon",
 
@@ -46,7 +41,7 @@ dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 				//Register our hotkey to CTRL-SHIFT-ENTER.
 				ed.addKeyHandler(dojo.keys.ENTER, true, true, dojo.hitch(this, this._insertPageBreak));
 				if(dojo.isWebKit || dojo.isOpera){
-					// Webkit and Opera based browsers don't generate keypress events when ctrl and shift are 
+					// Webkit and Opera based browsers don't generate keypress events when ctrl and shift are
 					// held then enter is pressed.  Odd, that.
 					this.connect(this.editor, "onKeyDown", dojo.hitch(this, function(e){
 						if((e.keyCode === dojo.keys.ENTER) && e.ctrlKey && e.shiftKey){
@@ -57,6 +52,12 @@ dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 			})
 		);
 	},
+	
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
 
 	setEditor: function(editor){
 		// summary:
@@ -70,7 +71,7 @@ dojo.declare("dojox.editor.plugins.PageBreak",dijit._editor._Plugin,{
 	_style: function(){
 		// summary:
 		//		Internal function for inserting dynamic css.  This was originally
-		//		in an editor.onLoadDeferred, but I ran into issues in Chrome with 
+		//		in an editor.onLoadDeferred, but I ran into issues in Chrome with
 		//		the tag being ignored.  Having it done at insert worked better.
 		// tags:
 		//		private
@@ -157,3 +158,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.PageBreak({});
 	}
 });
+
+return dojox.editor.plugins.PageBreak;
+
+});
diff --git a/dojox/editor/plugins/PasteFromWord.js b/dojox/editor/plugins/PasteFromWord.js
index c42737f..320d203 100755
--- a/dojox/editor/plugins/PasteFromWord.js
+++ b/dojox/editor/plugins/PasteFromWord.js
@@ -1,24 +1,15 @@
-dojo.provide("dojox.editor.plugins.PasteFromWord");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.Dialog");
-dojo.require("dojo.i18n");
-dojo.require("dojo.string");
-dojo.require("dojox.html.format");
-
-dojo.requireLocalization("dojox.editor.plugins", "PasteFromWord");
+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) {
 
 dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 	// summary:
-	//		This plugin provides PasteFromWord cabability to the editor.  When 
+	//		This plugin provides PasteFromWord cabability to the editor.  When
 	//		clicked, a dialog opens with a spartan RichText instance to paste
-	//		word content into via the keyboard commands.  The contents are 
+	//		word content into via the keyboard commands.  The contents are
 	//		then filtered to remove word style classes and other meta-junk
 	//		that tends to cause issues.
 
 	// iconClassPrefix: [const] String
-	//		The CSS class name for the button node is formed from `iconClassPrefix` 
+	//		The CSS class name for the button node is formed from `iconClassPrefix`
 	//		and `command`
 	iconClassPrefix: "dijitAdditionalEditorIcon",
 
@@ -33,7 +24,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 	_template: ["<div class='dijitPasteFromWordEmbeddedRTE'>",
 				"<div style='width: ${width}; padding-top: 5px; padding-bottom: 5px;'>${instructions}</div>",
 				"<div id='${uId}_rte' style='width: ${width}; height: ${height}'></div>",
-				"<table style='width: ${width}' tabindex='-1'>", 
+				"<table style='width: ${width}' tabindex='-1'>",
 					"<tbody>",
 						"<tr>",
 							"<td align='center'>",
@@ -49,18 +40,18 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 	// _filters: [private] 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 
+	//		Prettymuch all of it is junk and not good html.  The hander is a place to put a function
 	//		for match handling.  In most cases, it just handles it as empty string.  But the option is
 	//		there for more complex handling.
 	_filters: [
 		// Meta tags, link tags, and prefixed tags
-		{regexp: /(<meta\s*[^>]*\s*>)|(<\s*link\s* href="file:[^>]*\s*>)|(<\/?\s*\w+:[^>]*\s*>)/gi, handler: ""},  
+		{regexp: /(<meta\s*[^>]*\s*>)|(<\s*link\s* href="file:[^>]*\s*>)|(<\/?\s*\w+:[^>]*\s*>)/gi, handler: ""},
 		// Style tags
-		{regexp: /(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi, handler: ""}, 
+		{regexp: /(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi, handler: ""},
 		// MS class tags and comment tags.
 		{regexp: /(class="Mso[^"]*")|(<!--(.|\s){1,}?-->)/gi, handler: ""},
 		// blank p tags
-		{regexp: /(<p[^>]*>\s*(\ |\u00A0)*\s*<\/p[^>]*>)|(<p[^>]*>\s*<font[^>]*>\s*(\ |\u00A0)*\s*<\/\s*font\s*>\s<\/p[^>]*>)/ig, handler: ""}, 
+		{regexp: /(<p[^>]*>\s*(\ |\u00A0)*\s*<\/p[^>]*>)|(<p[^>]*>\s*<font[^>]*>\s*(\ |\u00A0)*\s*<\/\s*font\s*>\s<\/p[^>]*>)/ig, handler: ""},
 		// Strip out styles containing mso defs and margins, as likely added in IE and are not good to have as it mangles presentation.
 		{regexp: /(style="[^"]*mso-[^;][^"]*")|(style="margin:\s*[^;"]*;")/gi, handler: ""},
 		// Scripts (if any)
@@ -99,6 +90,12 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 		this.connect(this._dialog, "onHide", "_clearDialog");
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
+	
 	setEditor: function(editor){
 		// summary:
 		//		Over-ride for the setting of the editor.
@@ -115,7 +112,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 		//		private
 		this._dialog.show();
 		if(!this._rte){
-			// RTE hasn't been created yet, so we need to create it now that the 
+			// RTE hasn't been created yet, so we need to create it now that the
 			// dialog is showing up.
 			setTimeout(dojo.hitch(this, function() {
 				this._rte = new dijit._editor.RichText({height: this.height || "300px"}, this._uId + "_rte");
@@ -130,7 +127,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 
 	_paste: function(){
 		// summary:
-		//		Function to handle setting the contents of the copy from dialog 
+		//		Function to handle setting the contents of the copy from dialog
 		//		into the editor.
 		// tags:
 		//		private
@@ -159,7 +156,7 @@ dojo.declare("dojox.editor.plugins.PasteFromWord",dijit._editor._Plugin,{
 
 	_cancel: function(){
 		// summary:
-		//		Function to handle cancelling setting the contents of the 
+		//		Function to handle cancelling setting the contents of the
 		//		copy from dialog into the editor.
 		// tags:
 		//		private
@@ -204,3 +201,5 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+});
diff --git a/dojox/editor/plugins/PrettyPrint.js b/dojox/editor/plugins/PrettyPrint.js
index bdc24aa..f9b7cbe 100755
--- a/dojox/editor/plugins/PrettyPrint.js
+++ b/dojox/editor/plugins/PrettyPrint.js
@@ -1,22 +1,19 @@
-dojo.provide("dojox.editor.plugins.PrettyPrint");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dojox.html.format");
+define("dojox/editor/plugins/PrettyPrint", ["dojo", "dijit", "dojox", "dijit/_editor/_Plugin", "dojox/html/format"], function(dojo, dijit, dojox) {
 
 dojo.declare("dojox.editor.plugins.PrettyPrint",dijit._editor._Plugin,{
 	// summary:
-	//		This plugin provides a mechanism by wich to 'beautify HTML'
+	//		This plugin provides a mechanism by which to 'beautify HTML'
 	//		generated by the editor.  It is by no means perfect.
 
 	// indentBy [public] Integer
-	//		The indentBy property configures if the plugin should use a 
+	//		The indentBy property configures if the plugin should use a
 	//		set number of spaces for indent (between 1-5), or just tab.
 	//		The default value is -1, which means tab.
 	indentBy: -1,
 
 	// lineLength [public] Integer
 	//		The lineLength property configures if the plugin should break up long
-	//		text lines into N lines of 'lineLength' length.  This parameter does not 
+	//		text lines into N lines of 'lineLength' length.  This parameter does not
 	//		take into account indention depth, only text line length.  The default is -1
 	//		which means unlimited line length.
 	lineLength: -1,
@@ -32,18 +29,18 @@ dojo.declare("dojox.editor.plugins.PrettyPrint",dijit._editor._Plugin,{
 	entityMap: null,
 
 	// xhtml: [public] boolean
-	//		Flag to denote that the PrettyPrint plugin try to generate XHTML compliant 
+	//		Flag to denote that the PrettyPrint plugin try to generate XHTML compliant
 	//		markup.
 
 	_initButton: function(){
 		// summary:
 		//		Over-ride for creation of the resize button.
-		delete this.command; 
+		delete this.command;
 	},
 
 	setToolbar: function(toolbar){
 		// summary:
-		//		Over-ride to do nothing.  
+		//		Over-ride to do nothing.
 		//		We don't want to append a button, we take over getValue.
 	},
 
@@ -98,3 +95,5 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+});
diff --git a/dojox/editor/plugins/Preview.js b/dojox/editor/plugins/Preview.js
index 28c1877..873a66b 100755
--- a/dojox/editor/plugins/Preview.js
+++ b/dojox/editor/plugins/Preview.js
@@ -1,14 +1,8 @@
-dojo.provide("dojox.editor.plugins.Preview");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "Preview");
+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) {
 
 dojo.declare("dojox.editor.plugins.Preview",dijit._editor._Plugin,{
 	//	summary:
-	//		This plugin provides Preview cabability to the editor.  When 
+	//		This plugin provides Preview cabability to the editor.  When
 	//		clicked, the document in the editor frame will displayed in a separate
 	//		window/tab
 
@@ -50,6 +44,12 @@ dojo.declare("dojox.editor.plugins.Preview",dijit._editor._Plugin,{
 		this._initButton();
 	},
 
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
+	
 	_preview: function(){
 		// summary:
 		//		Function to trigger previewing of the editor document
@@ -91,3 +91,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+return dojox.editor.plugins.Preview;
+
+});
diff --git a/dojox/editor/plugins/ResizeTableColumn.js b/dojox/editor/plugins/ResizeTableColumn.js
new file mode 100644
index 0000000..0079243
--- /dev/null
+++ b/dojox/editor/plugins/ResizeTableColumn.js
@@ -0,0 +1,290 @@
+dojo.provide("dojox.editor.plugins.ResizeTableColumn");
+
+dojo.require("dojox.editor.plugins.TablePlugins");
+
+dojo.declare("dojox.editor.plugins.ResizeTableColumn",	dojox.editor.plugins.TablePlugins, {
+		
+		constructor: function(){
+			// summary:
+			//		Because IE will ignore the cursor style when the editMode of the document is on,
+			//		we need to create a div within the outer document to mimic the behavior of drag&drop
+			this.isLtr = this.dir ? (this.dir == "ltr") : dojo._isBodyLtr();
+			this.ruleDiv = dojo.create("div",
+				{style: "top: -10000px; z-index: 10001"},
+				dojo.body(), "last");
+		},
+		
+		setEditor: function(editor){
+			// summary:
+			//		Handle the drag&drop events
+			// editor:
+			//		The editor which this plugin belongs to
+			// tags:
+			//		protected
+			var ruleDiv = this.ruleDiv;
+			
+			this.editor = editor;
+			this.editor.customUndo = true;
+			this.onEditorLoaded();
+			
+			// The content of the editor is loaded asynchronously, so the function
+			// should be called when it is loaded.
+			editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+				this.connect(this.editor.editNode, "onmousemove", function(evt){
+					var editorCoords = dojo.coords(editor.iframe, true),
+						ex = editorCoords.x, cx = evt.clientX;
+					
+					if(!this.isDragging){
+						// If it is just a movement, put the div at the edge of the
+						// target cell so that when the cursor hover on it, it will
+						// change to the col-resize style.
+						var obj = evt.target;
+						
+						if(obj.tagName && obj.tagName.toLowerCase() == "td"){
+							var objCoords = dojo.coords(obj), ox = objCoords.x, ow = objCoords.w,
+								pos = ex + objCoords.x - 2;
+							if(this.isLtr){
+								ruleDiv.headerColumn = true;
+								if(!isBoundary(obj, "first") || cx > ox + ow / 2){
+									pos += ow;
+									ruleDiv.headerColumn = false;
+								}
+							}else{
+								ruleDiv.headerColumn = false;
+								if(isBoundary(obj, "first") && cx > ox + ow / 2){
+									pos += ow;
+									ruleDiv.headerColumn = true;
+								}
+							}
+							dojo.style(ruleDiv, {
+								position: "absolute",
+								cursor: "col-resize",
+								display: "block",
+								width: "4px",
+								backgroundColor: "transparent",
+								top: editorCoords.y + objCoords.y + "px",
+								left: pos + "px",
+								height: objCoords.h + "px"
+							});
+							this.activeCell = obj;
+						}else{
+							dojo.style(ruleDiv, {display: "none", top: "-10000px"});
+						}
+					}else{
+						// Begin to drag&drop
+						var activeCell = this.activeCell,
+							activeCoords = dojo.coords(activeCell), ax = activeCoords.x, aw = activeCoords.w,
+							sibling = nextSibling(activeCell), siblingCoords, sx, sw,
+							containerCoords = dojo.coords(getTable(activeCell).parentNode),
+							ctx = containerCoords.x, ctw = containerCoords.w;
+						
+						if(sibling){
+							siblingCoords = dojo.coords(sibling);
+							sx = siblingCoords.x;
+							sw = siblingCoords.w;
+						}
+						
+						// The leading and trailing columns can only be sized to the extent of the containing div.
+						if(this.isLtr &&
+								((ruleDiv.headerColumn && sibling && ctx < cx && cx < ax + aw) ||
+									((!sibling && ax < cx && cx < ctx + ctw) || (sibling && ax < cx && cx < sx + sw))) ||
+							!this.isLtr &&
+								((ruleDiv.headerColumn && sibling && ctx > cx && cx > ax) ||
+									((!sibling && ax + aw > cx && cx > ctx) || (sibling && ax + aw > cx && cx > sx)))){
+							dojo.style(ruleDiv, {left: ex + cx + "px"});
+						}
+					}
+				});
+				
+				this.connect(ruleDiv, "onmousedown", function(evt){
+					var editorCoords = dojo.coords(editor.iframe, true),
+						tableCoords = dojo.coords(getTable(this.activeCell));
+					
+					this.isDragging = true;
+					dojo.style(editor.editNode, {cursor: "col-resize"});
+					dojo.style(ruleDiv, {
+						width: "1px",
+						left: evt.clientX + "px",
+						top: editorCoords.y + tableCoords.y + "px",
+						height: tableCoords.h + "px",
+						backgroundColor: "#777"
+					});
+				});
+				
+				this.connect(ruleDiv, "onmouseup", function(evt){
+					var activeCell = this.activeCell,
+						activeCoords = dojo.coords(activeCell), aw = activeCoords.w, ax = activeCoords.x,
+						sibling = nextSibling(activeCell), siblingCoords, sx, sw,
+						editorCoords = dojo.coords(editor.iframe), ex = editorCoords.x,
+						table = getTable(activeCell), tableCoords = dojo.coords(table),
+						cs = table.getAttribute("cellspacing"),
+						cx = evt.clientX,
+						headerCell = getHeaderCell(activeCell), headerSibling,
+						newWidth, newSiblingWidth;
+					
+					if(!cs || (cs = parseInt(cs, 10)) < 0){ cs = 2; }
+					
+					if(sibling){
+						siblingCoords = dojo.coords(sibling);
+						sx = siblingCoords.x;
+						sw = siblingCoords.w;
+						headerSibling = getHeaderCell(sibling);
+					}
+					
+					// The delta width is either taken from or added to the adjacent column on the trailing edge.
+					// Sizing the rightmost or leftmost columns affects only those columns.
+					if(this.isLtr){
+						if(ruleDiv.headerColumn){
+							newWidth = ex + ax + aw - cx;
+						}else{
+							newWidth = cx - ex - ax;
+							if(sibling) { newSiblingWidth = ex + sx + sw - cx - cs; }
+						}
+					}else{
+						if(ruleDiv.headerColumn){
+							newWidth = cx - ex - ax;
+						}else{
+							newWidth = ex + ax + aw - cx;
+							if(sibling) { newSiblingWidth = cx - ex - sx - cs; }
+						}
+					}
+					
+					this.isDragging = false;
+					marginBox(headerCell, newWidth);
+					if(sibling){
+						if(!ruleDiv.headerColumn){
+							marginBox(headerSibling, newSiblingWidth);
+						}
+					}
+					if(ruleDiv.headerColumn && isBoundary(activeCell, "first") || isBoundary(activeCell, "last")){
+						dojo.marginBox(table, {w: tableCoords.w + newWidth - aw});
+					}
+					// Do it again to consolidate the result,
+					// because maybe the cell cannot be so narrow as you specified.
+					marginBox(headerCell, dojo.coords(activeCell).w);
+					if(sibling){
+						marginBox(headerSibling, dojo.coords(sibling).w);
+					}
+					dojo.style(editor.editNode, {cursor: "auto"});
+					dojo.style(ruleDiv, {display: "none", top: "-10000px"});
+					this.activeCell = null;
+				});
+			}));
+			
+			function isBoundary(/*DomNode*/ n, /*String*/ b){
+				// summary:
+				//		Check if the current cell is in the first column or
+				//		in the last column.
+				// n:
+				//		The node of a table cell
+				// b:
+				//		Indicate if the cell node is compared with the first coluln
+				//		or the last column
+				var nodes = dojo.withGlobal(editor.window, "query", dojo, ["> td", n.parentNode]);
+				switch(b){
+					case "first":
+						return nodes[0] == n;
+					case "last":
+						return nodes[nodes.length - 1] == n;
+					default:
+						return false;
+				}
+			}
+			
+			function nextSibling(/*DomNode*/ node){
+				// summary:
+				//		Get the next cell in row
+				// node:
+				//		The table cell
+				node = node.nextSibling
+				while(node){
+					if(node.tagName && node.tagName.toLowerCase() == "td"){
+						break;
+					}
+					node = node.nextSibling
+				}
+				return node;
+			}
+			
+			function getTable(/*DomNode*/ t){
+				// summary:
+				//		Get the table that this cell belongs to.
+				// t:
+				//		The table cell
+				while((t = t.parentNode) && t.tagName.toLowerCase() != "table"){}
+				return t;
+			}
+			
+			function getHeaderCell(/*DomNode*/ t){
+				// summary:
+				//		Get the table cell in the first row that shares the same
+				//		column with the node t.
+				// t:
+				//		The node of the table cell
+				var tds = dojo.withGlobal(editor.window, "query", dojo, ["td", getTable(t)]),
+					len = tds.length;
+				for(var i = 0; i < len; i++){
+					if(dojo.coords(tds[i]).x == dojo.coords(t).x){
+						return tds[i];
+					}
+				}
+				return null;
+			}
+			
+			function marginBox(/*DomNode*/ node, /*Number*/ width){
+				// summary:
+				//		In IE, if the border width of the td is not specified in table, the default value is 1px,
+				//		though it is marked "medium".
+				// node:
+				//		The node to be set width
+				// width:
+				//		The new width of the node
+				if(dojo.isIE){
+					var s = node.currentStyle,
+						bl = px(node, s.borderLeftWidth), br = px(node, s.borderRightWidth),
+						pl = px(node, s.paddingLeft), pr = px(node, s.paddingRight);
+					
+					node.style.width = width - bl - br - pl - pr;
+				}else{
+					dojo.marginBox(node, {w: width});
+				}
+				
+				function px(element, avalue){
+					if(!avalue){ return 0; }
+					if(avalue == "medium"){ return 1; }
+					// 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;
+				}
+			}
+		}
+});
+
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+	if(o.plugin){ return; }
+	// make first character lower case
+	if(o.args && o.args.command){
+		var cmd = o.args.command.charAt(0).toLowerCase() + o.args.command.substring(1, o.args.command.length);
+		if(cmd == "resizeTableColumn"){
+			o.plugin = new dojox.editor.plugins.ResizeTableColumn({commandName: cmd});
+		}
+	}
+});
\ No newline at end of file
diff --git a/dojox/editor/plugins/Save.js b/dojox/editor/plugins/Save.js
index 5bc9255..dd24385 100755
--- a/dojox/editor/plugins/Save.js
+++ b/dojox/editor/plugins/Save.js
@@ -1,30 +1,24 @@
-dojo.provide("dojox.editor.plugins.Save");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "Save");
+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) {
 
 dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
 	// summary:
-	//		This plugin provides Save cabability to the editor.  When 
+	//		This plugin provides Save cabability to the editor.  When
 	//		clicked, the document in the editor frame will be osted to the URL
 	//		provided, or none, if none provided.  Users who desire a different save
-	//		function can extend this plugin (via dojo.extend) and over-ride the 
+	//		function can extend this plugin (via dojo.extend) and over-ride the
 	//		save method	while save is in process, the save button is disabled.
 
 	// iconClassPrefix: [const] String
-	//		The CSS class name for the button node is formed from `iconClassPrefix` 
+	//		The CSS class name for the button node is formed from `iconClassPrefix`
 	//		and `command`
 	iconClassPrefix: "dijitAdditionalEditorIcon",
 
 	// url [public]	String
-	//		The URL to POST the content back to.  Used by the save function. 
+	//		The URL to POST the content back to.  Used by the save function.
 	url: "",
 
 	// logErrors [public] boolean
-	//		Boolean flag to indicate that the default action for save and 
+	//		Boolean flag to indicate that the default action for save and
 	//		error handlers is to just log to console.  Default is true.
 	logResults: true,
 
@@ -40,6 +34,12 @@ dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
 			onClick: dojo.hitch(this, "_save")
 		});
 	},
+	
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
 
 	setEditor: function(editor){
 		// summary:
@@ -90,7 +90,7 @@ dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
 
 	onSuccess: function(resp, ioargs){
 		// summary:
-		//		User over-ridable save success function for editor content.  
+		//		User over-ridable save success function for editor content.
 		//		Be sure to call this.inherited(arguments) if over-riding this method.
 		// resp:
 		//		The response from the server, if any, in text format.
@@ -104,7 +104,7 @@ dojo.declare("dojox.editor.plugins.Save",dijit._editor._Plugin,{
 
 	onError: function(error, ioargs){
 		// summary:
-		//		User over-ridable save success function for editor content.  
+		//		User over-ridable save success function for editor content.
 		//		Be sure to call this.inherited(arguments) if over-riding this method.
 		// resp:
 		//		The response from the server, if any, in text format.
@@ -128,3 +128,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		});
 	}
 });
+
+return dojox.editor.plugins.Save;
+
+});
diff --git a/dojox/editor/plugins/ShowBlockNodes.js b/dojox/editor/plugins/ShowBlockNodes.js
index 8a3d225..c9b44f6 100755
--- a/dojox/editor/plugins/ShowBlockNodes.js
+++ b/dojox/editor/plugins/ShowBlockNodes.js
@@ -1,14 +1,8 @@
-dojo.provide("dojox.editor.plugins.ShowBlockNodes");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.i18n");
-
-dojo.requireLocalization("dojox.editor.plugins", "ShowBlockNodes");
+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) {
 
 dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
 	// summary:
-	//		This plugin provides ShowBlockNodes cabability to the editor.  When 
+	//		This plugin provides ShowBlockNodes cabability to the editor.  When
 	//		clicked, the document in the editor will apply a class to specific
 	//		block nodes to make them visible in the layout.  This info is not
 	//		exposed/extracted when the editor value is obtained, it is purely for help
@@ -39,6 +33,12 @@ dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
 		});
 		this.editor.addKeyHandler(dojo.keys.F9, true, true, dojo.hitch(this, this.toggle));
 	},
+	
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
 
 	setEditor: function(editor){
 		// summary:
@@ -67,10 +67,10 @@ dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
 				this._styled = true;
 
 				var style = "";
-				var blocks = ["div", "p", "ul", "ol", "table", "h1", 
-					"h2", "h3", "h4", "h5", "h6", "pre", "dir", "center", 
+				var blocks = ["div", "p", "ul", "ol", "table", "h1",
+					"h2", "h3", "h4", "h5", "h6", "pre", "dir", "center",
 					"blockquote", "form", "fieldset", "address", "object",
-					"pre", "hr", "ins", "noscript", "li", "map", "button", 
+					"pre", "hr", "ins", "noscript", "li", "map", "button",
 					"dd", "dt"];
 
 				var template = "@media screen {\n" +
@@ -87,14 +87,14 @@ dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
 				"}\n";
 
 				dojo.forEach(blocks, function(tag){
-					style += template.replace(/\{TAG\}/gi, tag); 
+					style += template.replace(/\{TAG\}/gi, tag);
 				});
 
 				//Finally associate in the image locations based off the module url.
 				var modurl = dojo.moduleUrl(dojox._scopeName, "editor/plugins/resources").toString();
 				if(!(modurl.match(/^https?:\/\//i)) &&
 					!(modurl.match(/^file:\/\//i))){
-					// We have to root it to the page location on webkit for some nutball reason. 
+					// We have to root it to the page location on webkit for some nutball reason.
 					// Probably has to do with how iframe was loaded.
 					var bUrl;
 					if(modurl.charAt(0) === "/"){
@@ -149,7 +149,7 @@ dojo.declare("dojox.editor.plugins.ShowBlockNodes",dijit._editor._Plugin,{
 				fullUrl = fullUrl.substring(0,index);
 			}
 
-			// Now we need to trim if necessary.  If it ends in /, then we don't 
+			// Now we need to trim if necessary.  If it ends in /, then we don't
 			// have a filename to trim off so we can return.
 			index = fullUrl.lastIndexOf("/");
 			if (index > 0 && index < fullUrl.length) {
@@ -170,3 +170,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.ShowBlockNodes();
 	}
 });
+
+return dojox.editor.plugins.ShowBlockNodes;
+
+});
diff --git a/dojox/editor/plugins/Smiley.js b/dojox/editor/plugins/Smiley.js
index 0ca3813..3218f47 100644
--- a/dojox/editor/plugins/Smiley.js
+++ b/dojox/editor/plugins/Smiley.js
@@ -1,13 +1,6 @@
-dojo.provide("dojox.editor.plugins.Smiley");
-dojo.experimental("dojox.editor.plugins.Smiley");
-
-dojo.require("dojo.i18n");
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.form.ToggleButton");
-dojo.require("dijit.form.DropDownButton");
-dojo.require("dojox.editor.plugins._SmileyPalette");
+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) {
 
-dojo.requireLocalization("dojox.editor.plugins", "Smiley");
+dojo.experimental("dojox.editor.plugins.Smiley");
 
 dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 	// summary:
@@ -51,6 +44,12 @@ dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 		});
 		this.emoticonImageRegexp = new RegExp("class=(\"|\')" + this.emoticonImageClass + "(\"|\')");
 	},
+	
+	updateState: function(){
+		// summary:
+		//		Over-ride for button state control for disabled to work.
+		this.button.set("disabled", this.get("disabled"));
+	},
 
 	setEditor: function(editor){
 		// summary:
@@ -89,7 +88,7 @@ dojo.declare("dojox.editor.plugins.Smiley", dijit._editor._Plugin, {
 		// summary:
 		//		Pre-filter for editor to convert strings like [:-)] into an <img> of the corresponding smiley
 		var emoticon = dojox.editor.plugins.Emoticon.fromAscii(ascii);
-		return emoticon ? emoticon.imgHtml(this.emoticonImageClass) : ascii;
+		return emoticon ? emoticon.imgHtml(this.emoticonImageClass) : str;
 	},
 
 	_encode: function(str){
@@ -114,3 +113,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.Smiley();
 	}
 });
+
+return dojox.editor.plugins.Smiley;
+
+});
diff --git a/dojox/editor/plugins/SpellCheck.js b/dojox/editor/plugins/SpellCheck.js
new file mode 100644
index 0000000..5a5bf5c
--- /dev/null
+++ b/dojox/editor/plugins/SpellCheck.js
@@ -0,0 +1,1405 @@
+dojo.provide("dojox.editor.plugins.SpellCheck");
+
+dojo.require("dijit.form.TextBox");
+dojo.require("dijit.form.DropDownButton");
+dojo.require("dijit.TooltipDialog");
+dojo.require("dijit.form.MultiSelect");
+dojo.require("dojo.io.script");
+dojo.require("dijit.Menu");
+
+dojo.requireLocalization("dojox.editor.plugins", "SpellCheck");
+
+dojo.experimental("dojox.editor.plugins.SpellCheck");
+
+dojo.declare("dojox.editor.plugins._spellCheckControl", [dijit._Widget, dijit._Templated], {
+	// summary:
+	//		The widget that is used for the UI of the batch spelling check
+	
+	widgetsInTemplate: true,
+	
+	templateString:
+		"<table class='dijitEditorSpellCheckTable'>" +
+			"<tr><td colspan='3' class='alignBottom'><label for='${textId}' id='${textId}_label'>${unfound}</label>" +
+				"<div class='dijitEditorSpellCheckBusyIcon' id='${id}_progressIcon'></div></td></tr>" +
+			"<tr>" +
+				"<td class='dijitEditorSpellCheckBox'><input dojoType='dijit.form.TextBox' required='false' intermediateChanges='true' " +
+					"class='dijitEditorSpellCheckBox' dojoAttachPoint='unfoundTextBox' id='${textId}'/></td>" +
+				"<td><button dojoType='dijit.form.Button' class='blockButton' dojoAttachPoint='skipButton'>${skip}</button></td>" +
+				"<td><button dojoType='dijit.form.Button' class='blockButton' dojoAttachPoint='skipAllButton'>${skipAll}</button></td>" +
+			"</tr>" +
+			"<tr>" +
+				"<td class='alignBottom'><label for='${selectId}'>${suggestions}</td></label>" +
+				"<td colspan='2'><button dojoType='dijit.form.Button' class='blockButton' dojoAttachPoint='toDicButton'>${toDic}</button></td>" +
+			"</tr>" +
+			"<tr>" +
+				"<td>" +
+					"<select dojoType='dijit.form.MultiSelect' id='${selectId}' " +
+						"class='dijitEditorSpellCheckBox listHeight' dojoAttachPoint='suggestionSelect'></select>" +
+				"</td>" +
+				"<td colspan='2'>" +
+					"<button dojoType='dijit.form.Button' class='blockButton' dojoAttachPoint='replaceButton'>${replace}</button>" +
+					"<div class='topMargin'><button dojoType='dijit.form.Button' class='blockButton' " +
+						"dojoAttachPoint='replaceAllButton'>${replaceAll}</button><div>" +
+				"</td>" +
+			"</tr>" +
+			"<tr>" +
+				"<td><div class='topMargin'><button dojoType='dijit.form.Button' dojoAttachPoint='cancelButton'>${cancel}</button></div></td>" +
+				"<td></td>" +
+				"<td></td>" +
+			"</tr>" +
+		"</table>",
+	
+	/*************************************************************************/
+	/**                      Framework Methods                              **/
+	/*************************************************************************/
+	constructor: function(){
+		// Indicate if the textbox ignores the text change event of the textbox
+		this.ignoreChange = false;
+		// Indicate if the text of the textbox is changed or not
+		this.isChanged = false;
+		// Indicate if the dialog is open or not
+		this.isOpen = false;
+		// Indicate if the dialog can be closed
+		this.closable = true;
+	},
+	
+	postMixInProperties: function(){
+		this.id = dijit.getUniqueId(this.declaredClass.replace(/\./g,"_"));
+		this.textId = this.id + "_textBox";
+		this.selectId = this.id + "_select";
+	},
+	
+	postCreate: function(){
+		var select = this.suggestionSelect;
+		
+		// Customize multi-select to single select
+		dojo.removeAttr(select.domNode, "multiple");
+		select.addItems = function(/*Array*/ items){
+			// summary:
+			//		Add items to the select widget
+			// items:
+			//		An array of items be added to the select
+			// tags:
+			//		public
+			var _this = this;
+			var o = null;
+			if(items && items.length > 0){
+				dojo.forEach(items, function(item, i){
+					o = dojo.create("option", {innerHTML: item, value: item}, _this.domNode);
+					if(i == 0){
+						o.selected = true;
+					}
+				});
+			}
+		};
+		select.removeItems = function(){
+			// summary:
+			//		Remove all the items within the select widget
+			// tags:
+			//		public
+			dojo.empty(this.domNode);
+		};
+	
+		select.deselectAll = function(){
+			// summary:
+			//		De-select all the selected items
+			// tags:
+			//		public
+			this.containerNode.selectedIndex = -1;
+		};
+		
+		// Connect up all the controls with their event handler
+		this.connect(this, "onKeyPress", "_cancel");
+		this.connect(this.unfoundTextBox, "onKeyPress", "_enter");
+		this.connect(this.unfoundTextBox, "onChange", "_unfoundTextBoxChange");
+		this.connect(this.suggestionSelect, "onKeyPress", "_enter");
+		this.connect(this.skipButton, "onClick", "onSkip");
+		this.connect(this.skipAllButton, "onClick", "onSkipAll");
+		this.connect(this.toDicButton, "onClick", "onAddToDic");
+		this.connect(this.replaceButton, "onClick", "onReplace");
+		this.connect(this.replaceAllButton, "onClick", "onReplaceAll");
+		this.connect(this.cancelButton, "onClick", "onCancel");
+	},
+	
+	/*************************************************************************/
+	/**                      Public Methods                                 **/
+	/*************************************************************************/
+	
+	onSkip: function(){
+		// Stub for the click event of the skip button.
+	},
+	
+	onSkipAll: function(){
+		// Stub for the click event of the skipAll button.
+	},
+	
+	onAddToDic: function(){
+		// Stub for the click event of the toDic button.
+	},
+	
+	onReplace: function(){
+		// Stub for the click event of the replace button.
+	},
+	
+	onReplaceAll: function(){
+		// Stub for the click event of the replaceAll button.
+	},
+	
+	onCancel: function(){
+		// Stub for the click event of the cancel button.
+	},
+	
+	onEnter: function(){
+		// Stub for the enter event of the unFound textbox.
+	},
+	
+	focus: function(){
+		// summary:
+		//		Set the focus of the control
+		// tags:
+		//		public
+		this.unfoundTextBox.focus();
+	},
+	
+	/*************************************************************************/
+	/**                      Private Methods                                **/
+	/*************************************************************************/
+	
+	_cancel: function(/*Event*/ evt){
+		// summary:
+		//		Handle the cancel event
+		// evt:
+		//		The event object
+		// tags:
+		//		private
+		if(evt.keyCode == dojo.keys.ESCAPE){
+			this.onCancel();
+			dojo.stopEvent(evt);
+		}
+	},
+	
+	_enter: function(/*Event*/ evt){
+		// summary:
+		//		Handle the enter event
+		// evt:
+		//		The event object
+		// tags:
+		//		private
+		if(evt.keyCode == dojo.keys.ENTER){
+			this.onEnter();
+			dojo.stopEvent(evt);
+		}
+	},
+	
+	_unfoundTextBoxChange: function(){
+		// summary:
+		//		Indicate that the Not Found textbox is changed or not
+		// tags:
+		//		private
+		var id = this.textId + "_label";
+		if(!this.ignoreChange){
+			dojo.byId(id).innerHTML = this["replaceWith"];
+			this.isChanged = true;
+			this.suggestionSelect.deselectAll();
+		}else{
+			dojo.byId(id).innerHTML = this["unfound"];
+		}
+	},
+	
+	_setUnfoundWordAttr: function(/*String*/ value){
+		// summary:
+		//		Set the value of the Not Found textbox
+		// value:
+		//		The value of the Not Found textbox
+		// tags:
+		//		private
+		value = value || "";
+		this.unfoundTextBox.set("value", value);
+	},
+	
+	_getUnfoundWordAttr: function(){
+		// summary:
+		//		Get the value of the Not Found textbox
+		// tags:
+		//		private
+		return this.unfoundTextBox.get("value");
+	},
+	
+	_setSuggestionListAttr: function(/*Array*/ values){
+		// summary:
+		//		Set the items of the suggestion list
+		// values:
+		//		The list of the suggestion items
+		// tags:
+		//		private
+		var select = this.suggestionSelect;
+		values = values || [];
+		select.removeItems();
+		select.addItems(values);
+	},
+	
+	_getSelectedWordAttr: function(){
+		// summary:
+		//		Get the suggested word.
+		//		If the select box is selected, the value is the selected item's value,
+		//		else the value the the textbox's value
+		// tags:
+		//		private
+		var selected = this.suggestionSelect.getSelected();
+		if(selected && selected.length > 0){
+			return selected[0].value;
+		}else{
+			return this.unfoundTextBox.get("value");
+		}
+	},
+	
+	_setDisabledAttr: function(/*Boolean*/ disabled){
+		// summary:
+		//		Enable/disable the control
+		// tags:
+		//		private
+		this.skipButton.set("disabled", disabled);
+		this.skipAllButton.set("disabled", disabled);
+		this.toDicButton.set("disabled", disabled);
+		this.replaceButton.set("disabled", disabled);
+		this.replaceAllButton.set("disabled", disabled);
+	},
+	
+	_setInProgressAttr: function(/*Boolean*/ show){
+		// summary:
+		//		Set the visibility of the progress icon
+		// tags:
+		//		private
+		var id = this.id + "_progressIcon",
+			cmd = show ? "removeClass" : "addClass";
+			dojo[cmd](id, "hidden");
+	}
+});
+
+dojo.declare("dojox.editor.plugins._SpellCheckScriptMultiPart", null, {
+	// summary:
+	//		It is a base network service component. It transfers text to a remote service port
+	//		with cross domain ability enabled. It can split text into specified pieces and send
+	//		them out one by one so that it can handle the case when the service has a limitation of
+	//		the capability.
+	//		The encoding is UTF-8.
+	
+	// ACTION [public const] String
+	//		Actions for the server-side piece to take
+	ACTION_QUERY: "query",
+	ACTION_UPDATE: "update",
+	
+	// callbackHandle [public] String
+	//		The callback name of JSONP
+	callbackHandle: "callback",
+	
+	// maxBufferLength [public] Number
+	//		The max number of charactors that send to the service at one time.
+	maxBufferLength: 100,
+	
+	// delimiter [public] String
+	//		A token that is used to identify the end of a word (a complete unit). It prevents the service from
+	//		cutting a single word into two parts. For example:
+	//			"Dojo toolkit is a ajax framework. It helps the developers buid their web applications."
+	//		Without the delimiter, the sentence might be split into the follow pieces which is absolutely
+	//		not the result we want.
+	//			"Dojo toolkit is a ajax fram", "ework It helps the developers bu", "id their web applications"
+	//		Having " " as the delimiter, we get the following correct pieces.
+	//			"Dojo toolkit is a ajax framework", " It helps the developers buid", " their web applications"
+	delimiter: " ",
+	
+	// label [public] String
+	//		The leading label of the JSON response. The service will return the result like this:
+	//		{response: [
+	//				{
+	//					text: "teest",
+	//					suggestion: ["test","treat"]
+	//				}
+	//			]}
+	label: "response",
+	
+	// _timeout [private] Number
+	//		Set JSONP timeout period
+	_timeout: 30000,
+	SEC: 1000,
+	
+	constructor: function(){
+		// The URL of the target service
+		this.serviceEndPoint = "";
+		// The queue that holds all the xhr request
+		this._queue = [];
+		// Indicate if the component is still working. For example, waiting for collecting all
+		// the responses from the service
+		this.isWorking = false;
+		// The extra command passed to the service
+		this.exArgs = null;
+		// The counter that indicate if all the responses are collected to
+		// assemble the final result.
+		this._counter = 0;
+	},
+	
+	send: function(/*String*/ content, /*String?*/ action){
+		// summary:
+		//		Send the content to the service port with the specified action
+		// content:
+		//		The text to be sent
+		// action:
+		//		The action the service should take. Current support actions are
+		//		ACTION_QUERY and ACTION_UPDATE
+		// tags:
+		//		public
+		var _this = this,
+			dt = this.delimiter,
+			mbl = this.maxBufferLength,
+			label = this.label,
+			serviceEndPoint = this.serviceEndPoint,
+			callbackParamName = this.callbackHandle,
+			comms = this.exArgs,
+			timeout = this._timeout,
+			l = 0, r = 0;
+		
+		// Temparary list that holds the result returns from the service, which will be
+		// assembled into a completed one.
+		if(!this._result) {
+			this._result = [];
+		}
+
+		action = action || this.ACTION_QUERY;
+
+		var batchSend = function(){
+			var plan = [];
+			var plannedSize = 0;
+			if(content && content.length > 0){
+				_this.isWorking = true;
+				var len = content.length;
+				do{
+					l = r + 1;
+					if((r += mbl) > len){
+						r = len;
+					}else{
+						// If there is no delimiter (emplty string), leave the right boundary where it is.
+						// Else extend the right boundary to the first occurance of the delimiter if
+						// it doesn't meet the end of the content.
+						while(dt && content.charAt(r) != dt && r <= len){
+							r++;
+						}
+					}
+					// Record the information of the text slices
+					plan.push({l: l, r: r});
+					plannedSize++;
+				}while(r < len);
+
+				dojo.forEach(plan, function(item, index){
+					var jsonpArgs = {
+						url: serviceEndPoint,
+						action: action,
+						timeout: timeout,
+						callbackParamName: callbackParamName,
+						handle: function(response, ioArgs){
+							if(++_this._counter <= this.size && !(response instanceof Error) &&
+								response[label] && dojo.isArray(response[label])){
+								// Collect the results
+								var offset = this.offset;
+								dojo.forEach(response[label], function(item){
+									item.offset += offset;
+								});
+								// Put the packages in order
+								_this._result[this.number]= response[label];
+							}
+							if(_this._counter == this.size){
+								_this._finalizeCollection(this.action);
+								_this.isWorking = false;
+								if(_this._queue.length > 0){
+									// Call the next request waiting in queue
+									(_this._queue.shift())();
+								}
+							}
+						}
+					};
+					jsonpArgs.content = comms ? dojo.mixin(comms, {action: action, content: content.substring(item.l - 1, item.r)}):
+													{action: action, content: content.substring(item.l - 1, item.r)};
+					jsonpArgs.size = plannedSize;
+					jsonpArgs.number = index; // The index of the current package
+					jsonpArgs.offset = item.l - 1;
+					dojo.io.script.get(jsonpArgs);
+				});
+			}
+		};
+	
+		if(!_this.isWorking){
+			batchSend();
+		}else{
+			_this._queue.push(batchSend);
+		}
+	},
+	
+	_finalizeCollection: function(action){
+		// summary:
+		//		Assemble the responses into one result.
+		// action:
+		//		The action token
+		// tags:
+		//		private
+		var result = this._result,
+			len = result.length;
+		// Turn the result into a one-dimensional array
+		for(var i = 0; i < len; i++){
+			var temp = result.shift();
+			result = result.concat(temp);
+		}
+		if(action == this.ACTION_QUERY){
+			this.onLoad(result);
+		}
+		this._counter = 0;
+		this._result = [];
+	},
+	
+	onLoad: function(/*String*/ data){
+		// Stub method for a sucessful call
+	},
+	
+	setWaitingTime: function(/*Number*/ seconds){
+		this._timeout = seconds * this.SEC;
+	}
+});
+
+dojo.declare("dojox.editor.plugins.SpellCheck", [dijit._editor._Plugin], {
+	//	summary:
+	//		This plugin provides a spelling check cabability for the editor.
+	
+	// url [public] String
+	//		The url of the spelling check service
+	url: "",
+	
+	// bufferLength [public] Number
+	//		The max length of each XHR request. It is used to divide the large
+	//		text into pieces so that the server-side piece can hold.
+	bufferLength: 100,
+	
+	// interactive [public] Boolean
+	//		Indicate if the interactive spelling check is enabled
+	interactive: false,
+	
+	// timeout [public] Number
+	//		The minutes to waiting for the response. The default value is 30 seconds.
+	timeout: 30,
+	
+	// button [protected] dijit.form.DropDownButton
+	//		The button displayed on the editor's toolbar
+	button: null,
+	
+	// _editor [private] dijit.Editor
+	//		The reference to the editor the plug-in belongs to.
+	_editor: null,
+	
+	// exArgs [private] Object
+	//		The object that holds all the parametes passed into the constructor
+	exArgs: null,
+	
+	// _cursorSpan [private] String
+	//		The span that holds the current position of the cursor
+	_cursorSpan:
+		"<span class=\"cursorPlaceHolder\"></span>",
+	
+	// _cursorSelector [private] String
+	//		The CSS selector of the cursor span
+	_cursorSelector:
+		"cursorPlaceHolder",
+	
+	// _incorrectWordsSpan [private] String
+	//		The wrapper that marks the incorrect words
+	_incorrectWordsSpan:
+		"<span class='incorrectWordPlaceHolder'>${text}</span>",
+		
+	// _ignoredIncorrectStyle [private] Object
+	//		The style of the ignored incorrect words
+	_ignoredIncorrectStyle:
+		{"cursor": "inherit", "borderBottom": "none", "backgroundColor": "transparent"},
+		
+	// _normalIncorrectStyle [private] Object
+	//		The style of the marked incorrect words.
+	_normalIncorrectStyle:
+		{"cursor": "pointer", "borderBottom": "1px dotted red", "backgroundColor": "yellow"},
+	
+	// _highlightedIncorrectStyle [private] Object
+	//		The style of the highlighted incorrect words
+	_highlightedIncorrectStyle:
+		{"borderBottom": "1px dotted red", "backgroundColor": "#b3b3ff"},
+	
+	// _selector [private] String
+	//		An empty CSS class that identifies the incorrect words
+	_selector: "incorrectWordPlaceHolder",
+	
+	// _maxItemNumber [private] Number
+	//		The max number of the suggestion list items
+	_maxItemNumber: 3,
+	
+	/*************************************************************************/
+	/**                      Framework Methods                              **/
+	/*************************************************************************/
+	
+	constructor: function(){
+		// A list that holds all the spans that contains the incorrect words
+		// It is used to select/replace the specified word.
+		this._spanList = [];
+		// The cache that stores all the words. It looks like the following
+		// {
+		//   "word": [],
+		//   "wrd": ["word", "world"]
+		// }
+		this._cache = {};
+		// Indicate if this plugin is enabled or not
+		this._enabled = true;
+		// The index of the _spanList
+		this._iterator = 0;
+	},
+	
+	setEditor: function(/*dijit.Editor*/ editor){
+		this._editor = editor;
+		this._initButton();
+		this._setNetwork();
+		this._connectUp();
+	},
+	
+	/*************************************************************************/
+	/**                      Private Methods                                **/
+	/*************************************************************************/
+	
+	_initButton: function(){
+		// summary:
+		//		Initialize the button displayed on the editor's toolbar
+		// tags:
+		//		private
+		var _this = this,
+			strings = this._strings = dojo.i18n.getLocalization("dojox.editor.plugins", "SpellCheck"),
+			dialogPane = this._dialog = new dijit.TooltipDialog();
+		
+		dialogPane.set("content", (this._dialogContent = new dojox.editor.plugins._spellCheckControl({
+			unfound: strings["unfound"],
+			skip: strings["skip"],
+			skipAll: strings["skipAll"],
+			toDic: strings["toDic"],
+			suggestions: strings["suggestions"],
+			replaceWith: strings["replaceWith"],
+			replace: strings["replace"],
+			replaceAll: strings["replaceAll"],
+			cancel: strings["cancel"]
+		})));
+		
+		this.button = new dijit.form.DropDownButton({
+			label: strings["widgetLabel"],
+			showLabel: false,
+			iconClass: "dijitEditorSpellCheckIcon",
+			dropDown: dialogPane,
+			id: dijit.getUniqueId(this.declaredClass.replace(/\./g,"_")) + "_dialogPane",
+			closeDropDown: function(focus){
+				// Determine if the dialog can be closed
+				if(_this._dialogContent.closable){
+					_this._dialogContent.isOpen = false;
+					if(dojo.isIE){
+						var pos = _this._iterator,
+							list = _this._spanList;
+						if(pos < list.length && pos >=0 ){
+							dojo.style(list[pos], _this._normalIncorrectStyle);
+						}
+					}
+					if(this._opened){
+						dijit.popup.close(this.dropDown);
+						if(focus){ this.focus(); }
+						this._opened = false;
+						this.state = "";
+					}
+				}
+			}
+		});
+		_this._dialogContent.isOpen = false;
+		
+		dijit.setWaiState(dialogPane.domNode, "label", this._strings["widgetLabel"]);
+	},
+	
+	_setNetwork: function(){
+		// summary:
+		//		Set up the underlying network service
+		// tags:
+		//		private
+		var comms = this.exArgs;
+		
+		if(!this._service){
+			var service = this._service = new dojox.editor.plugins._SpellCheckScriptMultiPart();
+			service.serviceEndPoint = this.url;
+			service.maxBufferLength = this.bufferLength;
+			service.setWaitingTime(this.timeout);
+			// Pass the other arguments directly to the service
+			if(comms){
+				delete comms.name;
+				delete comms.url;
+				delete comms.interactive;
+				delete comms.timeout;
+				service.exArgs = comms;
+			}
+		}
+	},
+	
+	_connectUp: function(){
+		// summary:
+		//		Connect up all the events with their event handlers
+		// tags:
+		//		private
+		var editor = this._editor,
+			cont = this._dialogContent;
+		
+		this.connect(this.button, "set", "_disabled");
+		this.connect(this._service, "onLoad", "_loadData");
+		this.connect(this._dialog, "onOpen", "_openDialog");
+		this.connect(editor, "onKeyPress", "_keyPress");
+		this.connect(editor, "onLoad", "_submitContent");
+		this.connect(cont, "onSkip", "_skip");
+		this.connect(cont, "onSkipAll", "_skipAll");
+		this.connect(cont, "onAddToDic", "_add");
+		this.connect(cont, "onReplace", "_replace");
+		this.connect(cont, "onReplaceAll", "_replaceAll");
+		this.connect(cont, "onCancel", "_cancel");
+		this.connect(cont, "onEnter", "_enter");
+		
+		editor.contentPostFilters.push(this._spellCheckFilter); // Register the filter
+		dojo.publish(dijit._scopeName + ".Editor.plugin.SpellCheck.getParser", [this]); // Get the language parser
+		if(!this.parser){
+			console.error("Can not get the word parser!");
+		}
+	},
+
+	/*************************************************************************/
+	/**                      Event Handlers                                 **/
+	/*************************************************************************/
+	
+	_disabled: function(name, disabled){
+		// summary:
+		//		When the plugin is disabled (the button is disabled), reset all to their initial status.
+		//		If the interactive mode is on, check the content once it is enabled.
+		// name:
+		//		Command name
+		// disabled:
+		//		Command argument
+		// tags:
+		//		private
+		if(name == "disabled"){
+			if(disabled){
+				this._iterator = 0;
+				this._spanList = [];
+			}else if(this.interactive && !disabled && this._service){
+				this._submitContent(true);
+			}
+			this._enabled = !disabled;
+		}
+	},
+	
+	_keyPress: function(evt){
+		// summary:
+		//		The handler of the onKeyPress event of the editor
+		// tags:
+		//		private
+		if(this.interactive){
+			var v = 118, V = 86,
+				cc = evt.charCode;
+			if(!evt.altKey && cc == dojo.keys.SPACE){
+				this._submitContent();
+			}else if((evt.ctrlKey && (cc == v || cc == V)) || (!evt.ctrlKey && evt.charCode)){
+				this._submitContent(true);
+			}
+		}
+	},
+	
+	_loadData: function(/*Array*/ data){
+		// summary:
+		//		Apply the query result to the content
+		// data:
+		//		The result of the query
+		// tags:
+		//		private
+		var cache = this._cache,
+			html = this._editor.get("value"),
+			cont = this._dialogContent;
+		
+		this._iterator = 0;
+		
+		// Update the local cache
+		dojo.forEach(data, function(d){
+			cache[d.text] = d.suggestion;
+			cache[d.text].correct = false;
+		});
+
+		if(this._enabled){
+			// Mark incorrect words
+			cont.closable = false;
+			this._markIncorrectWords(html, cache);
+			cont.closable = true;
+			
+			if(this._dialogContent.isOpen){
+				this._iterator = -1;
+				this._skip();
+			}
+		}
+	},
+	
+	_openDialog: function(){
+		// summary:
+		//		The handler of the onOpen event
+		var cont = this._dialogContent;
+		
+		// Clear dialog content and disable it first
+		cont.ignoreChange = true;
+		cont.set("unfoundWord", "");
+		cont.set("suggestionList", null);
+		cont.set("disabled", true);
+		cont.set("inProgress", true);
+		
+		cont.isOpen = true; // Indicate that the dialog is open
+		cont.closable = false;
+		
+		this._submitContent();
+		
+		cont.closable = true;
+	},
+	
+	_skip: function(/*Event?*/ evt, /*Boolean?*/ noUpdate){
+		// summary:
+		//		Ignore this word and move to the next unignored one.
+		// evt:
+		//		The event object
+		// noUpdate:
+		//		Indicate whether to update the status of the span list or not
+		// tags:
+		//		private
+		var cont = this._dialogContent,
+			list = this._spanList || [],
+			len = list.length,
+			iter = this._iterator;
+		
+		cont.closable = false;
+		cont.isChanged = false;
+		cont.ignoreChange = true;
+		
+		// Skip the current word
+		if(!noUpdate && iter >= 0 && iter < len){
+			this._skipWord(iter);
+		}
+		
+		// Move to the next
+		while(++iter < len && list[iter].edited == true){ /* do nothing */}
+		if(iter < len){
+			this._iterator = iter;
+			this._populateDialog(iter);
+			this._selectWord(iter);
+		}else{
+			// Reaches the end of the list
+			this._iterator = -1;
+			cont.set("unfoundWord", this._strings["msg"]);
+			cont.set("suggestionList", null);
+			cont.set("disabled", true);
+			cont.set("inProgress", false);
+		}
+		
+		setTimeout(function(){
+			// When moving the focus out of the iframe in WebKit browsers, we
+			// need to focus something else first. So the textbox
+			// can be focused correctly.
+			if(dojo.isWebKit) { cont.skipButton.focus(); }
+			cont.focus();
+			cont.ignoreChange = false;
+			cont.closable = true;
+		}, 0);
+	},
+	
+	_skipAll: function(){
+		// summary:
+		//		Ignore all the same words
+		// tags:
+		//		private
+		this._dialogContent.closable = false;
+		this._skipWordAll(this._iterator);
+		this._skip();
+	},
+	
+	_add: function(){
+		// summary:
+		//		Add the unrecognized word into the dictionary
+		// tags:
+		//		private
+		var cont = this._dialogContent;
+		
+		cont.closable = false;
+		cont.isOpen = true;
+		this._addWord(this._iterator, cont.get("unfoundWord"));
+		this._skip();
+	},
+	
+	_replace: function(){
+		// summary:
+		//		Replace the incorrect word with the selected one,
+		//		or the one the user types in the textbox
+		// tags:
+		//		private
+		var cont = this._dialogContent,
+			iter = this._iterator,
+			targetWord = cont.get("selectedWord");
+		
+		cont.closable = false;
+		this._replaceWord(iter, targetWord);
+		this._skip(null, true);
+	},
+	
+	_replaceAll: function(){
+		// summary:
+		//		Replace all the words with the same text
+		// tags:
+		//		private
+		var cont = this._dialogContent,
+			list = this._spanList,
+			len = list.length,
+			word = list[this._iterator].innerHTML.toLowerCase(),
+			targetWord = cont.get("selectedWord");
+		
+		cont.closable = false;
+		for(var iter = 0; iter < len; iter++){
+			// If this word is not ignored and is the same as the source word,
+			// replace it.
+			if(list[iter].innerHTML.toLowerCase() == word){
+				this._replaceWord(iter, targetWord);
+			}
+		}
+		
+		this._skip(null, true);
+	},
+	
+	_cancel: function(){
+		// summary:
+		//		Cancel this check action
+		// tags:
+		//		private
+		this._dialogContent.closable = true;
+		this._editor.focus();
+	},
+	
+	_enter: function(){
+		// summary:
+		//		Handle the ENTER event
+		// tags:
+		//		private
+		if(this._dialogContent.isChanged){
+			this._replace();
+		}else{
+			this._skip();
+		}
+	},
+	
+	/*************************************************************************/
+	/**                              Utils                                  **/
+	/*************************************************************************/
+	
+	_query: function(/*String*/ html){
+		// summary:
+		//		Send the query text to the service. The query text is a string of words
+		//		separated by space.
+		// html:
+		//		The html value of the editor
+		// tags:
+		//		private
+		var service = this._service,
+			cache = this._cache,
+			words = this.parser.parseIntoWords(this._html2Text(html)) || [];
+		var content = [];
+		dojo.forEach(words, function(word){
+			word = word.toLowerCase();
+			if(!cache[word]){
+				// New word that need to be send to the server side for check
+				cache[word] = [];
+				cache[word].correct = true;
+				content.push(word);
+			}
+		});
+		if(content.length > 0){
+			service.send(content.join(" "));
+		}else if(!service.isWorking){
+			this._loadData([]);
+		}
+	},
+	
+	_html2Text: function(html){
+		// summary:
+		//		Substitute the tag with white charactors so that the server
+		//		can easily process the text. For example:
+		//		"<a src="sample.html">Hello, world!</a>" ==>
+		//		"                     Hello, world!    "
+		// html:
+		//		The html code
+		// tags:
+		//		private
+		var text = [],
+			isTag = false,
+			len = html ? html.length : 0;
+		
+		for(var i = 0; i < len; i++){
+			if(html.charAt(i) == "<"){ isTag = true; }
+			if(isTag == true){
+				text.push(" ");
+			}else{
+				text.push(html.charAt(i));
+			}
+			if(html.charAt(i) == ">"){ isTag = false; }
+			
+		}
+		return text.join("");
+	},
+	
+	_getBookmark: function(/*String*/ eValue){
+		// summary:
+		//		Get the cursor position. It is the index of the characters
+		//		where the cursor is.
+		// eValue:
+		//		The html value of the editor
+		// tags:
+		//		private
+		var ed = this._editor,
+			cp = this._cursorSpan;
+		ed.execCommand("inserthtml", cp);
+		var nv = ed.get("value"),
+			index = nv.indexOf(cp),
+			i = -1;
+		while(++i < index && eValue.charAt(i) == nv.charAt(i)){ /* do nothing */}
+		return i;
+	},
+	
+	_moveToBookmark: function(){
+		// summary:
+		//		Move to the position when the cursor was.
+		// tags:
+		//		private
+		var ed = this._editor,
+			cps = dojo.withGlobal(ed.window, "query", dojo, ["." + this._cursorSelector]),
+			cursorSpan = cps && cps[0];
+		// Find the cursor place holder
+		if(cursorSpan){
+			ed._sCall("selectElement", [cursorSpan]);
+			ed._sCall("collapse", [true]);
+			var parent = cursorSpan.parentNode;
+			if(parent){ parent.removeChild(cursorSpan); }
+		}
+	},
+	
+	_submitContent: function(/*Boolean?*/ delay){
+		// summary:
+		//		Functions to submit the content of the editor
+		// delay:
+		//		Indicate if the action is taken immediately or not
+		// tags:
+		//		private
+		if(delay){
+			var _this = this,
+				interval = 3000;
+			if(this._delayHandler){
+				clearTimeout(this._delayHandler);
+				this._delayHandler = null;
+			}
+			setTimeout(function(){ _this._query(_this._editor.get("value")); }, interval);
+		}else{
+			this._query(this._editor.get("value"));
+		}
+	},
+	
+	_populateDialog: function(index){
+		// summary:
+		//		Populate the content of the dailog
+		// index:
+		//		The idex of the span list
+		// tags:
+		//		private
+		var list = this._spanList,
+			cache = this._cache,
+			cont = this._dialogContent;
+		
+		cont.set("disabled", false);
+		if(index < list.length && list.length > 0){
+			var word = list[index].innerHTML;
+			cont.set("unfoundWord", word);
+			cont.set("suggestionList", cache[word.toLowerCase()]);
+			cont.set("inProgress", false);
+		}
+	},
+	
+	_markIncorrectWords: function(/*String*/ html, /*Object*/ cache){
+		// summary:
+		//		Mark the incorrect words and set up menus if available
+		// html:
+		//		The html value of the editor
+		// cache:
+		//		The local word cache
+		// tags:
+		//		private
+		var _this = this,
+			parser = this.parser,
+			editor = this._editor,
+			spanString = this._incorrectWordsSpan,
+			nstyle = this._normalIncorrectStyle,
+			selector = this._selector,
+			words = parser.parseIntoWords(this._html2Text(html).toLowerCase()),
+			indices = parser.getIndices(),
+			bookmark = this._cursorSpan,
+			bmpos = this._getBookmark(html),
+			spanOffset = "<span class='incorrectWordPlaceHolder'>".length,
+			bmMarked = false,
+			cArray = html.split(""),
+			spanList = null;
+		
+		// Mark the incorrect words and cursor position
+		for(var i = words.length - 1; i >= 0; i--){
+			var word = words[i];
+			if(cache[word] && !cache[word].correct){
+				var offset = indices[i],
+					len = words[i].length,
+					end = offset + len;
+				if(end <= bmpos && !bmMarked){
+					cArray.splice(bmpos, 0, bookmark);
+					bmMarked = true;
+				}
+				cArray.splice(offset, len, dojo.string.substitute(spanString, {text: html.substring(offset, end)}));
+				if(offset < bmpos && bmpos < end && !bmMarked){
+					var tmp = cArray[offset].split("");
+					tmp.splice(spanOffset + bmpos - offset, 0, bookmark);
+					cArray[offset] = tmp.join("");
+					bmMarked = true;
+				}
+			}
+		}
+		if(!bmMarked){
+			cArray.splice(bmpos, 0, bookmark);
+			bmMarked = true;
+		}
+		
+		editor.set("value", cArray.join(""));
+		editor._cursorToStart = false; // HACK! But really necessary here.
+		
+		this._moveToBookmark();
+		
+		// Get the incorrect words <span>
+		spanList = this._spanList = dojo.withGlobal(editor.window, "query", dojo, ["." + this._selector]);
+		dojo.forEach(spanList, function(span, i){ span.id = selector + i; });
+		
+		// Set them to the incorrect word style
+		if(!this.interactive){ delete nstyle.cursor; }
+		spanList.style(nstyle);
+		
+		if(this.interactive){
+			// Build the context menu
+			if(_this._contextMenu){
+				_this._contextMenu.uninitialize();
+				_this._contextMenu = null;
+			}
+			_this._contextMenu = new dijit.Menu({
+				targetNodeIds: [editor.iframe],
+				
+				bindDomNode: function(/*String|DomNode*/ node){
+					// summary:
+					//		Attach menu to given node
+					node = dojo.byId(node);
+			
+					var cn;	// Connect node
+			
+					// Support context menus on iframes.   Rather than binding to the iframe itself we need
+					// to bind to the <body> node inside the iframe.
+					var iframe, win;
+					if(node.tagName.toLowerCase() == "iframe"){
+						iframe = node;
+						win = this._iframeContentWindow(iframe);
+						cn = dojo.withGlobal(win, dojo.body);
+					}else{
+						
+						// To capture these events at the top level, attach to <html>, not <body>.
+						// Otherwise right-click context menu just doesn't work.
+						cn = (node == dojo.body() ? dojo.doc.documentElement : node);
+					}
+			
+			
+					// "binding" is the object to track our connection to the node (ie, the parameter to bindDomNode())
+					var binding = {
+						node: node,
+						iframe: iframe
+					};
+			
+					// Save info about binding in _bindings[], and make node itself record index(+1) into
+					// _bindings[] array.   Prefix w/_dijitMenu to avoid setting an attribute that may
+					// start with a number, which fails on FF/safari.
+					dojo.attr(node, "_dijitMenu" + this.id, this._bindings.push(binding));
+			
+					// Setup the connections to monitor click etc., unless we are connecting to an iframe which hasn't finished
+					// loading yet, in which case we need to wait for the onload event first, and then connect
+					// On linux Shift-F10 produces the oncontextmenu event, but on Windows it doesn't, so
+					// we need to monitor keyboard events in addition to the oncontextmenu event.
+					var doConnects = dojo.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){
+								var target = evt.target,
+									strings = _this._strings;
+								// Schedule context menu to be opened unless it's already been scheduled from onkeydown handler
+								if(dojo.hasClass(target, selector) && !target.edited){ // Click on the incorrect word
+									dojo.stopEvent(evt);
+									
+									// Build the on-demand menu items
+									var maxNumber = _this._maxItemNumber,
+										id = target.id,
+										index = id.substring(selector.length),
+										suggestions = cache[target.innerHTML.toLowerCase()],
+										slen = suggestions.length;
+										
+									// Add the suggested words menu items
+									this.destroyDescendants();
+									if(slen == 0){
+										this.addChild(new dijit.MenuItem({
+											label: strings["iMsg"],
+											disabled: true
+										}));
+									}else{
+										for(var i = 0 ; i < maxNumber && i < slen; i++){
+											this.addChild(new dijit.MenuItem({
+												label: suggestions[i],
+												onClick: (function(){
+													var idx = index, txt = suggestions[i];
+													return function(){
+														_this._replaceWord(idx, txt);
+														editor.focus();
+													};
+												})()
+											}));
+										}
+									}
+									
+									//Add the other action menu items
+									this.addChild(new dijit.MenuSeparator());
+									this.addChild(new dijit.MenuItem({
+										label: strings["iSkip"],
+										onClick: function(){
+											_this._skipWord(index);
+											editor.focus();
+										}
+									}));
+									this.addChild(new dijit.MenuItem({
+										label: strings["iSkipAll"],
+										onClick: function(){
+											_this._skipWordAll(index);
+											editor.focus();
+										}
+									}));
+									this.addChild(new dijit.MenuSeparator());
+									this.addChild(new dijit.MenuItem({
+										label: strings["toDic"],
+										onClick: function(){
+											_this._addWord(index);
+											editor.focus();
+										}
+									}));
+									
+									this._scheduleOpen(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);
+									this._scheduleOpen(evt.target, iframe);	// no coords - open near target node
+								}
+							})
+						];
+					});
+					binding.connects = cn ? doConnects(cn) : [];
+			
+					if(iframe){
+						// Setup handler to [re]bind to the iframe when the contents are initially loaded,
+						// and every time the contents change.
+						// Need to do this b/c we are actually binding to the iframe's <body> node.
+						// Note: can't use dojo.connect(), see #9609.
+			
+						binding.onloadHandler = dojo.hitch(this, function(){
+							// want to remove old connections, but IE throws exceptions when trying to
+							// access the <body> node because it's already gone, or at least in a state of limbo
+			
+							var win = this._iframeContentWindow(iframe);
+								cn = dojo.withGlobal(win, dojo.body);
+							binding.connects = doConnects(cn);
+						});
+						if(iframe.addEventListener){
+							iframe.addEventListener("load", binding.onloadHandler, false);
+						}else{
+							iframe.attachEvent("onload", binding.onloadHandler);
+						}
+					}
+				}
+			});
+		}
+	},
+	
+	_selectWord: function(index){
+		// summary:
+		//		Select the incorrect word. Move to it and highlight it
+		// index:
+		//		The index of the span list
+		// tags:
+		//		private
+		var list = this._spanList,
+			win = this._editor.window;
+		
+		if(index < list.length && list.length > 0){
+			dojo.withGlobal(win, "selectElement", dijit._editor.selection, [list[index]]);
+			dojo.withGlobal(win, "collapse", dijit._editor.selection, [true]);
+			this._findText(list[index].innerHTML, false, false);
+			if(dojo.isIE){
+				// Because the selection in the iframe will be lost when the outer window get the
+				// focus, we need to mimic the highlight ourselves.
+				dojo.style(list[index], this._highlightedIncorrectStyle);
+			}
+		}
+	},
+	
+	_replaceWord: function(index, text){
+		// summary:
+		//		Replace the word at the given index with the text
+		// index:
+		//		The index of the span list
+		// text:
+		//		The text to be replaced with
+		// tags:
+		//		private
+		var list = this._spanList;
+		
+		list[index].innerHTML = text;
+		dojo.style(list[index], this._ignoredIncorrectStyle);
+		list[index].edited = true;
+	},
+	
+	_skipWord: function(index){
+		// summary:
+		//		Skip the word at the index
+		// index:
+		//		The index of the span list
+		// tags:
+		//		private
+		var list = this._spanList;
+		
+		dojo.style(list[index], this._ignoredIncorrectStyle);
+		this._cache[list[index].innerHTML.toLowerCase()].correct = true;
+		list[index].edited = true;
+	},
+	
+	_skipWordAll: function(index, /*String?*/word){
+		// summary:
+		//		Skip the all the word that have the same text as the word at the index
+		//		or the given word
+		// index:
+		//		The index of the span list
+		// word:
+		//		If this argument is given, skip all the words that have the same text
+		//		as the word
+		// tags:
+		//		private
+		var list = this._spanList,
+			len = list.length;
+		word = word || list[index].innerHTML.toLowerCase();
+			
+		for(var i = 0; i < len; i++){
+			if(!list[i].edited && list[i].innerHTML.toLowerCase() == word){
+				this._skipWord(i);
+			}
+		}
+	},
+	
+	_addWord: function(index, /*String?*/word){
+		// summary:
+		//		Add the word at the index to the dictionary
+		// index:
+		//		The index of the span list
+		// word:
+		//		If this argument is given, add the word to the dictionary and
+		//		skip all the words like it
+		// tags:
+		//		private
+		var service = this._service;
+		service.send(word || this._spanList[index].innerHTML.toLowerCase(), service.ACTION_UPDATE);
+		this._skipWordAll(index, word);
+	},
+	
+	_findText: function(/*String*/ txt, /*Boolean*/ caseSensitive, /*Boolean*/ backwards){
+		// summary:
+		//		This function invokes a find with specific options
+		// txt: String
+		//		The text to locate in the document.
+		// caseSensitive: Boolean
+		//		Whether or ot to search case-sensitively.
+		// backwards: Boolean
+		//		Whether or not to search backwards in the document.
+		// tags:
+		//		private.
+		// returns:
+		//		Boolean indicating if the content was found or not.
+		var ed = this._editor,
+			win = ed.window,
+			found = false;
+		if(txt){
+			if(win.find){
+				found = win.find(txt, caseSensitive, backwards, false, false, false, false);
+			}else{
+				var doc = ed.document;
+				if(doc.selection){
+					/* IE */
+					// Focus to restore position/selection,
+					// then shift to search from current position.
+					this._editor.focus();
+					var txtRg = doc.body.createTextRange();
+					var curPos = doc.selection?doc.selection.createRange():null;
+					if(curPos){
+						if(backwards){
+							txtRg.setEndPoint("EndToStart", curPos);
+						}else{
+							txtRg.setEndPoint("StartToEnd", curPos);
+						}
+					}
+					var flags = caseSensitive?4:0;
+					if(backwards){
+						flags = flags | 1;
+					}
+					//flags = flags |
+					found = txtRg.findText(txt,txtRg.text.length,flags);
+					if(found){
+						txtRg.select();
+					}
+				}
+			}
+		}
+		return found;
+	},
+	
+	_spellCheckFilter: function(/*String*/ value){
+		// summary:
+		//		Filter out the incorrect word style so that the value of the edtior
+		//		won't include the spans that wrap around the incorrect words
+		// value:
+		//		The html value of the editor
+		// tags:
+		//		private
+		var regText = /<span class=["']incorrectWordPlaceHolder["'].*?>(.*?)<\/span>/g;
+		return value.replace(regText, "$1");
+	}
+});
+
+// Register this plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
+	if(o.plugin){ return; }
+	var name = o.args.name.toLowerCase();
+	if(name ===  "spellcheck"){
+		o.plugin = new dojox.editor.plugins.SpellCheck({
+			url: ("url" in o.args) ? o.args.url : "",
+			interactive: ("interactive" in o.args) ? o.args.interactive : false,
+			bufferLength: ("bufferLength" in o.args) ? o.args.bufferLength: 100,
+			timeout: ("timeout" in o.args) ? o.args.timeout : 30,
+			exArgs: o.args
+		});
+	}
+});
diff --git a/dojox/editor/plugins/StatusBar.js b/dojox/editor/plugins/StatusBar.js
index 79f1e69..4a2b28c 100755
--- a/dojox/editor/plugins/StatusBar.js
+++ b/dojox/editor/plugins/StatusBar.js
@@ -1,19 +1,13 @@
-dojo.provide("dojox.editor.plugins.StatusBar");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.Toolbar");
-dojo.require("dojox.layout.ResizeHandle");
+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) {
 
 dojo.experimental("dojox.editor.plugins.StatusBar");
-
-
 dojo.declare("dojox.editor.plugins._StatusBar", [dijit._Widget, dijit._Templated],{
 	// 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.
 	templateString: '<div class="dojoxEditorStatusBar">' +
 		'<table><tbody><tr>'+
-		'<td class="dojoxEditorStatusBarText" tabindex="-1" aria-role="presentation" aria-live="aggressive"><span dojoAttachPoint="barContent"> </span></td>' + 
+		'<td class="dojoxEditorStatusBarText" tabindex="-1" aria-role="presentation" aria-live="aggressive"><span dojoAttachPoint="barContent"> </span></td>' +
 		'<td><span dojoAttachPoint="handle"></span></td>' +
 		'</tr></tbody><table>'+
 	'</div>',
@@ -170,3 +164,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.StatusBar({resizer: resizer});
 	}
 });
+
+return dojox.editor.plugins.StatusBar;
+
+});
diff --git a/dojox/editor/plugins/TablePlugins.js b/dojox/editor/plugins/TablePlugins.js
index 552f43d..f5b1d52 100644
--- a/dojox/editor/plugins/TablePlugins.js
+++ b/dojox/editor/plugins/TablePlugins.js
@@ -1,14 +1,9 @@
-dojo.provide("dojox.editor.plugins.TablePlugins");
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit._editor.selection");
-dojo.require("dijit.Menu");
-dojo.require("dojo.i18n");
-dojo.requireLocalization("dojox.editor.plugins", "TableDialog");
+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) {
 
 dojo.experimental("dojox.editor.plugins.TablePlugins");
 
 // summary:
-//		A series of plugins that give the Editor the ability to create and edit 
+//		A series of plugins that give the Editor the ability to create and edit
 //		HTML tables. See the end of this document for all avaiable plugins
 //		and dojox/editorPlugins/tests/editorTablePlugs.html for an example
 //
@@ -21,21 +16,21 @@ dojo.experimental("dojox.editor.plugins.TablePlugins");
 //		|		Editor text is here
 //		|	</div>
 //
-// TODO:	
+// TODO:
 //		Currently not supporting merging or splitting cells
 //
-// FIXME:	Undo is very buggy, and therefore unimeplented in all browsers 
+// FIXME:	Undo is very buggy, and therefore unimeplented in all browsers
 //			except IE - which itself has only been lightly tested.
 //
 // FIXME:	Selecting multiple table cells in Firefox looks to be impossible.
-//			This affect the 'colorTableCell' plugin. Cells can still be 
+//			This affect the 'colorTableCell' plugin. Cells can still be
 //			colored individually or in rows.
 
 dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	// summary:
-	//		A global object that handles common tasks for all the plugins. Since 
+	//		A global object that handles common tasks for all the plugins. Since
 	//		there are several plugins that are all calling common methods, it's preferable
-	//		that they call a centralized location that either has a set variable or a 
+	//		that they call a centralized location that either has a set variable or a
 	//		timeout to only repeat code-heavy calls when necessary.
 	//
 	tablesConnected:false,
@@ -47,7 +42,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	shiftKeyDown:false,
 	editorDomNode: null,
 	undoEnabled: true, //Using custom undo for all browsers.
-	refCount: 0, 
+	refCount: 0,
 	
 	doMixins: function(){
 		
@@ -100,7 +95,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 			// RichText should have a mouseup connection to recognize drag-selections
 			// Example would be selecting multiple table cells
 			this._myListeners = [];
-			this._myListeners.push(dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick")); 
+			this._myListeners.push(dojo.connect(this.editorDomNode , "mouseup", this.editor, "onClick"));
 			this._myListeners.push(dojo.connect(this.editor, "onDisplayChanged", this, "checkAvailable"));
 			this._myListeners.push(dojo.connect(this.editor, "onBlur", this, "checkAvailable"));
 			this.doMixins();
@@ -115,10 +110,10 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		//
 		if(forceNewData){ this._tempStoreTableData(false); }
 		if(this.tableData){
-			// tableData is set for a short amount of time, so that all 
+			// tableData is set for a short amount of time, so that all
 			// plugins get the same return without doing the method over
 			//console.log("returning current tableData:", this.tableData);
-			return this.tableData;	
+			return this.tableData;
 		}
 		var tr, trs, td, tds, tbl, cols, tdIndex, trIndex;
 
@@ -151,7 +146,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		};
 		//console.log("NEW tableData:",o);
 		this.tableData = o;
-		this._tempStoreTableData(500);	
+		this._tempStoreTableData(500);
 		return this.tableData;
 	},
 	
@@ -186,17 +181,17 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [tbl]);
 		
 		tbl.ondragstart = function(){
-			//console.log("ondragstart");									
+			//console.log("ondragstart");
 		};
 		tbl.ondrag = function(){
 			alert("drag")
-			//console.log("ondrag");											
-		*/		
+			//console.log("ondrag");
+		*/
 	},
 	onDragStart: function(){
 		var e = window.event;
 		if(!e.srcElement.id){
-			e.srcElement.id = "tbl_"+(new Date().getTime());	
+			e.srcElement.id = "tbl_"+(new Date().getTime());
 		}
 		//console.log("onDragStart", e.srcElement.id);
 	},
@@ -206,9 +201,9 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		//		Currently, this code is only used for when a table is dragged
 		//		and clears the "align" attribute, so that the table will look
 		//		to be more in the place that the user expected.
-		//		TODO: This code can be used for other things, most 
+		//		TODO: This code can be used for other things, most
 		//		notably UNDO, which currently is not quite usable.
-		//		This code could also find itself in the Editor code when it is 
+		//		This code could also find itself in the Editor code when it is
 		//		complete.
 		
 		//console.log("onDragEnd");
@@ -232,11 +227,11 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	checkAvailable: function(){
 		// summary:
 		//		For table plugs
-		//		Checking if a table or part of a table has focus so that 
+		//		Checking if a table or part of a table has focus so that
 		//		Plugs can change their status
 		//
 		if(this.availableCurrentlySet){
-			// availableCurrentlySet is set for a short amount of time, so that all 
+			// availableCurrentlySet is set for a short amount of time, so that all
 			// plugins get the same return without doing the method over
 			//console.log("availableCurrentlySet:", this.availableCurrentlySet, "currentlyAvailable:", this.currentlyAvailable)
 			return this.currentlyAvailable;
@@ -262,6 +257,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		}
 		
 		this._tempAvailability(500);
+		
 		dojo.publish(this.editor.id + "_tablePlugins", [ this.currentlyAvailable ]);
 		return this.currentlyAvailable;
 	},
@@ -269,7 +265,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	_prepareTable: function(tbl){
 		//	For IE's sake, we are adding IDs to the TDs if none is there
 		//	We go ahead and use it for other code for convenience
-		//	
+		//
 		var tds = this.editor.query("td", tbl);
 		console.log("prep:", tds, tbl);
 		if(!tds[0].id){
@@ -283,23 +279,24 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	},
 	
 	getTimeStamp: function(){
-		return Math.floor(new Date().getTime() * 0.00000001);
+		return new Date().getTime(); // Fixed the bug that this method always returns the same timestamp
+//		return Math.floor(new Date().getTime() * 0.00000001);
 	},
 	
 	_tempStoreTableData: function(type){
 		// caching or clearing table data, depending on the arg
 		//
 		if(type===true){
-			//store indefinitely	
+			//store indefinitely
 		}else if(type===false){
-			// clear object	
+			// clear object
 			this.tableData = null;
 		}else if(type===undefined){
-			console.warn("_tempStoreTableData must be passed an argument");	
-		}else{ 
+			console.warn("_tempStoreTableData must be passed an argument");
+		}else{
 			// type is a number/ms
 			setTimeout(dojo.hitch(this, function(){
-				this.tableData = null;											 
+				this.tableData = null;
 			}), type);
 		}
 	},
@@ -310,11 +307,11 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 			//store indefinitely
 			this.availableCurrentlySet = true;
 		}else if(type===false){
-			// clear object	
+			// clear object
 			this.availableCurrentlySet = false;
 		}else if(type===undefined){
-			console.warn("_tempAvailability must be passed an argument");	
-		}else{ 
+			console.warn("_tempAvailability must be passed an argument");
+		}else{
 			// type is a number/ms
 			this.availableCurrentlySet = true;
 			setTimeout(dojo.hitch(this, function(){
@@ -327,13 +324,13 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 	connectTableKeys: function(){
 		// summary:
 		//		When a table is in focus, start detecting keys
-		//		Mainly checking for the TAB key so user can tab 
+		//		Mainly checking for the TAB key so user can tab
 		//		through a table (blocking the browser's desire to
 		//		tab away from teh editor completely)
 		if(this.tablesConnected){ return; }
 		this.tablesConnected = true;
 		var node = (this.editor.iframe) ? this.editor.document : this.editor.editNode;
-		this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown"); 
+		this.cnKeyDn = dojo.connect(node, "onkeydown", this, "onKeyDown");
 		this.cnKeyUp = dojo.connect(node, "onkeyup", this, "onKeyUp");
 		this._myListeners.push(dojo.connect(node, "onkeypress", this, "onKeyUp"));
 	},
@@ -363,7 +360,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 				//	to run the method
 				this.currentlyAvailable = true;
 				this._tempAvailability(true);
-				// 
+				//
 				this._tempStoreTableData(true);
 				this.stopEvent = true;
 			}else{
@@ -401,7 +398,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 		//		Function to handle cleaning up of connects
 		//		and such.  It only finally destroys everything once
 		//		all 'references' to it have gone.  As in all plugins
-		//		that called init on it destroyed their refs in their 
+		//		that called init on it destroyed their refs in their
 		//		cleanup calls.
 		// editor:
 		//		The editor to detach from.
@@ -427,7 +424,7 @@ dojo.declare("dojox.editor.plugins._TableHandler", dijit._editor._Plugin,{
 dojo.declare("dojox.editor.plugins.TablePlugins",
 	dijit._editor._Plugin,
 	{
-		//summary: 
+		//summary:
 		//		A collection of Plugins for inserting and modifying tables in the Editor
 		//		See end of this document for all avaiable plugs
 		//		and dojox/editorPlugins/tests/editorTablePlugs.html for an example
@@ -465,7 +462,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 				// Create it and init it off the editor.  This
 				// will create the _tablePluginHandler reference on
 				// the dijit.Editor instance.  This avoids a global.
-				var tablePluginHandler = new dojox.editor.plugins._TableHandler(); 
+				var tablePluginHandler = new dojox.editor.plugins._TableHandler();
 				tablePluginHandler.initialize(this.editor);
 			}else{
 				this.editor._tablePluginHandler.initialize(this.editor);
@@ -473,7 +470,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 		},
 		
 		selectTable: function(){
-			// selects table that is in focus 
+			// selects table that is in focus
 			var o = this.getTableInfo();
 			if(o && o.tbl){
 				dojo.withGlobal(this.editor.window, "selectElement",dijit._editor.selection, [o.tbl]);
@@ -495,9 +492,9 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 		modTable: function(cmd, args){
 			// summary:
 			//		Where each plugin performs its action
-			//		Note: not using execCommand. In spite of their presence in the 
+			//		Note: not using execCommand. In spite of their presence in the
 			//		Editor as query-able plugins, I was not able to find any evidence
-			//		that they are supported (especially in NOT IE). If they are 
+			//		that they are supported (especially in NOT IE). If they are
 			//		supported in other browsers, it may help with the undo problem.
 			//
 			this.begEdit();
@@ -581,7 +578,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 				if(this.editor.customUndo){
 					this.editor.endEditing();
 				}else{
-					// This code ALMOST works for undo - 
+					// This code ALMOST works for undo -
 					//	It seems to only work for one step
 					//	back in history however
 					var afterUndo = this.editor.getValue();
@@ -627,7 +624,7 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 				if(i===0){ c = c.toUpperCase();}
 				ns.push(c);
 			});
-			return ns.join("");	
+			return ns.join("");
 		},
 		
 		
@@ -676,6 +673,18 @@ dojo.declare("dojox.editor.plugins.TablePlugins",
 			}
 			return cells;
 		},
+		
+		updateState: function(){
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			if(this.button){
+				if((this.available || this.alwaysAvailable) && !this.get("disabled")){
+					this.button.set("disabled",false);
+				}else{
+					this.button.set("disabled",true);
+				}
+			}
+		},
 
 		destroy: function(){
 			// summary:
@@ -705,7 +714,18 @@ dojo.declare("dojox.editor.plugins.TableContextMenu",
 				}));
 				this.button.domNode.style.display = "none";
 			});
-		},	
+		},
+
+		destroy: function(){
+			// summary:
+			//	Over-ride to do menu cleanup.
+			if(this.menu){
+				this.menu.destroyRecursive();
+				delete this.menu;
+			}
+			this.inherited(arguments);
+		},
+	
 		
 		_initButton: function(){
 			this.inherited(arguments);
@@ -731,7 +751,7 @@ dojo.declare("dojox.editor.plugins.TableContextMenu",
 			pMenu.addChild(new dijit.MenuItem({label: messages.deleteTableColumnLabel, onClick: dojo.hitch(this, "modTable", "deleteTableColumn" )}));
 
 			this.menu = pMenu;
-		}		
+		}
 });
 
 dojo.declare("dojox.editor.plugins.InsertTable",
@@ -753,14 +773,14 @@ dojo.declare("dojox.editor.plugins.InsertTable",
 				//HMMMM.... This throws a security error now. didn't used to.
 				//this.editor.selectElement(td);
 			});
-		}	
+		}
 });
 
 dojo.declare("dojox.editor.plugins.ModifyTable",
 	dojox.editor.plugins.TablePlugins,
 	{
 		modTable: function(){
-			if (!this.editor._tablePluginHandler.checkAvailable()) {return;} 
+			if (!this.editor._tablePluginHandler.checkAvailable()) {return;}
 			var o = this.getTableInfo();
 			//console.log("LAUNCH DIALOG");
 			var w = new dojox.editor.plugins.EditorModifyTableDialog({table:o.tbl});
@@ -771,21 +791,130 @@ dojo.declare("dojox.editor.plugins.ModifyTable",
 				//console.log("set color:", color);
 				dojo.attr(o.td, "bgcolor", color);
 			});
-		}	
+		}
 });
 
-dojo.declare("dojox.editor.plugins.ColorTableCell",
-	dojox.editor.plugins.TablePlugins,
-	{
-		
+dojo.declare("dojox.editor.plugins._CellColorDropDown", [dijit._Widget, dijit._Templated], {
+	// summary:
+	//		A smple widget that uses/creates a dropdown with a dojox.widget.ColorPicker.  Also provides
+	//		passthroughs to the value of the color picker and convenient hook points.
+	// tags:
+	//		private
+
+	// templateString: String
+	//		The template used to create the ColorPicker.
+	templateString:
+		"<div style='display: none; position: absolute; top: -10000; z-index: -10000'>" +
+			"<div dojoType='dijit.TooltipDialog' dojoAttachPoint='dialog' class='dojoxEditorColorPicker'>" +
+				"<div dojoType='dojox.widget.ColorPicker' dojoAttachPoint='_colorPicker'></div>" +
+				"<div style='margin: 0.5em 0em 0em 0em'>" +
+					"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_setButton'>${buttonSet}</button>" +
+					" " +
+					"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_cancelButton'>${buttonCancel}</button>" +
+				"</div>" +
+			"</div>" +
+		"</div>",
+
+	// widgetsInTemplate: Boolean
+	//		Flag denoting widgets are contained in the template.
+	widgetsInTemplate: true,
+
+	constructor: function(){
+		// summary:
+		//		Constructor over-ride so that the translated strings are mixsed in so
+		//		the template fills out.
+		var strings = dojo.i18n.getLocalization("dojox.editor.plugins", "TableDialog");
+		dojo.mixin(this, strings);
+	},
+
+	startup: function(){
+		// summary:
+		//		Over-ride of startup to do the basic connect setups and such.
+		if(!this._started){
+			this.inherited(arguments);
+			this.connect(this._setButton, "onClick", function(){
+				this.onChange(this.get("value"));
+			});
+			this.connect(this._cancelButton, "onClick", function(){
+				dijit.popup.close(this.dialog);
+				this.onCancel();
+			});
+			// Fully statred, so go ahead and remove the hide.
+			dojo.style(this.domNode, "display", "block");
+		}
+	},
+
+	_setValueAttr: function(value, priorityChange){
+		// summary:
+		//		Passthrough function for the color picker value.
+		// value: String
+		//		The value to set in the color picker
+		// priorityChange:
+		//		Value to indicate whether or not to trigger an onChange event.
+		this._colorPicker.set("value", value, priorityChange);
+	},
+
+	_getValueAttr: function(){
+		// summary:
+		//		Passthrough function for the color picker value.
+		return this._colorPicker.get("value");
+	},
+
+	setColor: function(/*String*/ color){
+		this._colorPicker.setColor(color, false);
+	},
+	
+	onChange: function(value){
+		// summary:
+		//		Hook point to get the value when the color picker value is selected.
+		// value: String
+		//		The value from the color picker.
+	},
+
+	onCancel: function(){
+		// summary:
+		//		Hook point to get when the dialog is canceled.
+	}
+});
+
+dojo.declare("dojox.editor.plugins.ColorTableCell", dojox.editor.plugins.TablePlugins, {
 		constructor: function(){
 			// summary:
-			//		Initialize certain plugins
-			//
+			//		Initialize ColorTableCell plugin
+			this.closable = true;
 			this.buttonClass = dijit.form.DropDownButton;
-			this.dropDown = new dijit.ColorPalette();
-			this.connect(this.dropDown, "onChange", function(color){
+			var picker = new dojox.editor.plugins._CellColorDropDown();
+			dojo.body().appendChild(picker.domNode);
+			picker.startup();
+			this.dropDown = picker.dialog;
+			this.connect(picker, "onChange", function(color){
 				this.modTable(null, color);
+				this.editor.focus();
+			});
+			this.connect(picker, "onCancel", function(color){
+				this.editor.focus();
+			});
+			this.connect(picker.dialog, "onOpen", function(){
+				var o = this.getTableInfo(),
+					tds = this.getSelectedCells(o.tbl);
+				if(tds && tds.length > 0){
+					var t = tds[0] == this.lastObject ? tds[0] : tds[tds.length - 1],
+						color;
+					while(t && ((color = dojo.style(t, "backgroundColor")) == "transparent" || color.indexOf("rgba") == 0)){
+						t = t.parentNode;
+					}
+					color = dojo.style(t, "backgroundColor");
+					if(color != "transparent" && color.indexOf("rgba") != 0){
+						picker.setColor(color);
+					}
+				}
+			});
+			this.connect(this, "setEditor", function(editor){
+				editor.onLoadDeferred.addCallback(dojo.hitch(this, function(){
+					this.connect(this.editor.editNode, "onmouseup", function(evt){
+						this.lastObject = evt.target;
+					});
+				}));
 			});
 		},
 		
@@ -795,37 +924,31 @@ dojo.declare("dojox.editor.plugins.ColorTableCell",
 			this.label = this.editor.commands[this.command] = this._makeTitle(this.command);
 			this.inherited(arguments);
 			delete this.command;
-			
+
 			this.onDisplayChanged(false);
 		},
         
 		modTable: function(cmd, args){
 			// summary
 			//	Where each plugin performs its action
-			//	Note: not using execCommand. In spite of their presence in the 
+			//	Note: not using execCommand. In spite of their presence in the
 			//	Editor as query-able plugins, I was not able to find any evidence
-			//	that they are supported (especially in NOT IE). If they are 
+			//	that they are supported (especially in NOT IE). If they are
 			//	supported in other browsers, it may help with the undo problem.
 			//
 			this.begEdit();
-			var o = this.getTableInfo();			
+			var o = this.getTableInfo();
 			// The one plugin that really needs use of the very verbose
 			//	getSelectedCells()
 			var tds = this.getSelectedCells(o.tbl);
 			//console.debug("SELECTED CELLS ", tds , " FOR ", o);
 			dojo.forEach(tds, function(td){
-				dojo.style(td, "backgroundColor", args);				   
+				dojo.style(td, "backgroundColor", args);
 			});
 			this.endEdit();
 		}
 });
 
-dojo.provide("dojox.editor.plugins.EditorTableDialog");
-dojo.require("dijit.Dialog");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dijit.form.Button");
-
 dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], {
 	// summary:
 	//		Dialog box with options for table creation
@@ -882,7 +1005,7 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], {
 
 	onCancel: function(){
 		// summary:
-		//		Function to clean up memory so that the dialog is destroyed 
+		//		Function to clean up memory so that the dialog is destroyed
 		//		when closed.
 		var c = dojo.connect(this, "onHide", function(){
 			dojo.disconnect(c);
@@ -898,10 +1021,6 @@ dojo.declare("dojox.editor.plugins.EditorTableDialog", [dijit.Dialog], {
 	}
 });
 
-
-dojo.provide("dojox.editor.plugins.EditorModifyTableDialog");
-dojo.require("dijit.ColorPalette");
-
 dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
 	
 	// summary:
@@ -931,7 +1050,7 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
 			this.setBrdColor(color);
 		});
 		this.connect(w1, "onBlur", function(){
-			dijit.popup.close(w1);	
+			dijit.popup.close(w1);
 		});
 		this.connect(this.borderCol, "click", function(){
 			dijit.popup.open({popup:w1, around:this.borderCol});
@@ -943,7 +1062,7 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
 			this.setBkColor(color);
 		});
 		this.connect(w2, "onBlur", function(){
-			dijit.popup.close(w2);	
+			dijit.popup.close(w2);
 		});
 		this.connect(this.backgroundCol, "click", function(){
             dijit.popup.open({popup:w2, around:this.backgroundCol});
@@ -1011,7 +1130,7 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
 
 	onCancel: function(){
 		// summary:
-		//		Function to clean up memory so that the dialog is destroyed 
+		//		Function to clean up memory so that the dialog is destroyed
 		//		when closed.
 		var c = dojo.connect(this, "onHide", function(){
 			dojo.disconnect(c);
@@ -1039,9 +1158,6 @@ dojo.declare("dojox.editor.plugins.EditorModifyTableDialog", [dijit.Dialog], {
 	}
 });
 
-
-
-
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	if(o.plugin){ return; }
 	// make first character lower case
@@ -1076,3 +1192,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		}
 	}
 });
+
+return dojox.editor.plugins.TablePlugins;
+
+});
diff --git a/dojox/editor/plugins/TextColor.js b/dojox/editor/plugins/TextColor.js
index 37d9cf9..6e8ef21 100755
--- a/dojox/editor/plugins/TextColor.js
+++ b/dojox/editor/plugins/TextColor.js
@@ -1,15 +1,6 @@
-dojo.provide("dojox.editor.plugins.TextColor");
-
-dojo.require("dijit._editor._Plugin");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dijit.form.Button");
-dojo.require("dojox.widget.ColorPicker");
-
-dojo.require("dojo.i18n");
-dojo.requireLocalization("dojox.editor.plugins", "TextColor");
+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) {
 
 dojo.experimental("dojox.editor.plugins.TextColor");
-
 dojo.declare("dojox.editor.plugins._TextColorDropDown", [dijit._Widget, dijit._Templated], {
 	// summary:
 	//		A smple widget that uses/creates a dropdown with a dojox.widget.ColorPicker.  Also provides
@@ -22,8 +13,8 @@ dojo.declare("dojox.editor.plugins._TextColorDropDown", [dijit._Widget, dijit._T
 	templateString: "<div style='display: none; position: absolute; top: -10000; z-index: -10000'>" +
 		"<div dojoType='dijit.TooltipDialog' dojoAttachPoint='dialog' class='dojoxEditorColorPicker'>" +
 			"<div dojoType='dojox.widget.ColorPicker' dojoAttachPoint='_colorPicker'></div>" +
-			"<br>" + 
-			"<center>" + 
+			"<br>" +
+			"<center>" +
 				"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_setButton'>${setButtonText}</button>" +
 				" " +
 				"<button dojoType='dijit.form.Button' type='button' dojoAttachPoint='_cancelButton'>${cancelButtonText}</button>" +
@@ -132,8 +123,14 @@ dojo.declare("dojox.editor.plugins.TextColor", dijit._editor._Plugin, {
 			return;
 		}
 		
+		var disabled = this.get("disabled");
+		
 		var value;
 		if(this.button){
+			this.button.set("disabled", disabled);
+			if(disabled){
+				return;
+			}
 			try{
 				value = _e.queryCommandValue(_c)|| "";
 			}catch(e){
@@ -150,7 +147,7 @@ dojo.declare("dojox.editor.plugins.TextColor", dijit._editor._Plugin, {
 		}
 
 		if(typeof value == "string"){
-			//if RGB value, convert to hex value	
+			//if RGB value, convert to hex value
 			if(value.indexOf("rgb")> -1){
 				value = dojo.colorFromRgb(value).toHex();
 			}
@@ -175,7 +172,7 @@ dojo.declare("dojox.editor.plugins.TextColor", dijit._editor._Plugin, {
 	}
 });
 
-// Register this plugin.  Uses the same name as the dijit one, so you 
+// Register this plugin.  Uses the same name as the dijit one, so you
 // use one or the other, not both.
 dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
 	if(o.plugin){
@@ -189,3 +186,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin", null, function(o){
 			});
 	}
 });
+
+return dojox.editor.plugins.TextColor;
+
+});
diff --git a/dojox/editor/plugins/ToolbarLineBreak.js b/dojox/editor/plugins/ToolbarLineBreak.js
index 695e72a..0802309 100755
--- a/dojox/editor/plugins/ToolbarLineBreak.js
+++ b/dojox/editor/plugins/ToolbarLineBreak.js
@@ -1,23 +1,23 @@
-dojo.provide("dojox.editor.plugins.ToolbarLineBreak");
+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");
 
-dojo.declare("dojox.editor.plugins._ToolbarLineBreak",
+dojo.declare("dojox.editor.plugins.ToolbarLineBreak",
 	[ dijit._Widget, dijit._Templated ],
 	{
 	// summary:
-	//		A 'line break' between two `dijit.Toolbar` items so that very 
+	//		A 'line break' between two `dijit.Toolbar` items so that very
 	//		long toolbars can be organized a bit.
 	templateString: "<span class='dijit dijitReset'><br></span>",
 	postCreate: function(){ dojo.setSelectable(this.domNode, false); },
-	isFocusable: function(){ 
+	isFocusable: function(){
 		// summary:
 		//		This widget isn't focusable, so pass along that fact.
 		// tags:
 		//		protected
-		return false; 
+		return false;
 	}
 });
 
@@ -28,10 +28,14 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 	var name = o.args.name.toLowerCase();
 	if(name ===  "||" || name === "toolbarlinebreak"){
 		o.plugin = new dijit._editor._Plugin({
-			button: new dojox.editor.plugins._ToolbarLineBreak(),
+			button: new dojox.editor.plugins.ToolbarLineBreak(),
 			setEditor: function(editor){
 				this.editor = editor;
 			}
 		});
 	}
 });
+
+return dojox.editor.plugins.ToolbarLineBreak;
+
+});
diff --git a/dojox/editor/plugins/UploadImage.js b/dojox/editor/plugins/UploadImage.js
index dece07c..aab5417 100644
--- a/dojox/editor/plugins/UploadImage.js
+++ b/dojox/editor/plugins/UploadImage.js
@@ -1,15 +1,13 @@
-dojo.provide("dojox.editor.plugins.UploadImage");
-dojo.require("dijit._editor._Plugin");
-dojo.require("dojox.form.FileUploader");
+define("dojox/editor/plugins/UploadImage", ["dojo", "dijit", "dojox", "dojox/form/FileUploader", "dijit/_editor/_Plugin"], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins.UploadImage");
 
 dojo.declare("dojox.editor.plugins.UploadImage",
 	dijit._editor._Plugin,
 	{
-		//summary: 
+		//summary:
 		// 	Adds an icon to the Editor toolbar that when clicked, opens a system dialog
-		//	Although the toolbar icon is a tiny "image" the uploader could be used for 
+		//	Although the toolbar icon is a tiny "image" the uploader could be used for
 		//	any file type
 		
 		tempImageUrl: "",
@@ -31,6 +29,12 @@ dojo.declare("dojox.editor.plugins.UploadImage",
 			delete this.command;
 		},
 		
+		updateState: function(){
+			// summary:
+			//		Over-ride for button state control for disabled to work.
+			this.button.set("disabled", this.get("disabled"));
+		},
+		
 		createFileInput: function(){
 			var node = dojo.create('span', {innerHTML:"."}, document.body)
 			dojo.style(node, {
@@ -79,7 +83,7 @@ dojo.declare("dojox.editor.plugins.UploadImage",
 		insertTempImage: function(){
 			// inserting a "busy" image to show something is hapening
 			//	during upload and download of the image.
-			this.currentImageId = "img_"+(new Date().getTime()); 
+			this.currentImageId = "img_"+(new Date().getTime());
 			var iTxt = '<img id="'+this.currentImageId+'" src="'+this.tempImageUrl+'" width="32" height="32"/>';
 			this.editor.execCommand('inserthtml', iTxt);
 		}
@@ -94,3 +98,7 @@ dojo.subscribe(dijit._scopeName + ".Editor.getPlugin",null,function(o){
 		o.plugin = new dojox.editor.plugins.UploadImage({url: o.args.url});
 	}
 });
+
+return dojox.editor.plugins.UploadImage;
+
+});
diff --git a/dojox/editor/plugins/_SmileyPalette.js b/dojox/editor/plugins/_SmileyPalette.js
index ecb0c7e..4909cd1 100644
--- a/dojox/editor/plugins/_SmileyPalette.js
+++ b/dojox/editor/plugins/_SmileyPalette.js
@@ -1,12 +1,4 @@
-dojo.provide("dojox.editor.plugins._SmileyPalette");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
-dojo.require("dojo.i18n");
-
-dojo.require("dijit._PaletteMixin");
-
-dojo.requireLocalization("dojox.editor.plugins", "Smiley");
+define("dojox/editor/plugins/_SmileyPalette", ["dojo", "dijit", "dojox", "dijit/_Widget", "dijit._PaletteMixin", "dojo/i18n", "i18n!dojox/editor/plugins/nls/Smiley"], function(dojo, dijit, dojox) {
 
 dojo.experimental("dojox.editor.plugins._SmileyPalette");
 
@@ -27,7 +19,7 @@ dojo.declare("dojox.editor.plugins._SmileyPalette",
 	// |	picker.startup();
 
 	//		The template of this widget.
-	templateString: 
+	templateString:
 		'<table class="dijitInline dijitEditorSmileyPalette dijitPaletteTable"' +
 		' cellSpacing=0 cellPadding=0><tbody dojoAttachPoint="gridNode"></tbody></table>',
 
@@ -54,7 +46,7 @@ dojo.declare("dojox.editor.plugins._SmileyPalette",
 		var emoticonI18n = {};
 		for(var name in i18n){
 			if(name.substr(0,8) == "emoticon"){
-				emoticonI18n[name.substr(8).toLowerCase()] = i18n[name]; 
+				emoticonI18n[name.substr(8).toLowerCase()] = i18n[name];
 			}
 		}
         this._preparePalette(
@@ -140,3 +132,7 @@ dojox.editor.plugins.Emoticon.fromAscii = function(/*String*/str){
 	}
 	return null;
 };
+
+return dojox.editor.plugins._SmileyPalette;
+
+});
diff --git a/dojox/editor/plugins/_SpellCheckParser.js b/dojox/editor/plugins/_SpellCheckParser.js
new file mode 100644
index 0000000..02516f6
--- /dev/null
+++ b/dojox/editor/plugins/_SpellCheckParser.js
@@ -0,0 +1,63 @@
+define("dojox/editor/plugins/_SpellCheckParser", ["dojo", "dojox"], function(dojo, dojox) {
+
+dojo.declare("dojox.editor.plugins._SpellCheckParser", null, {
+	lang: "english",
+	
+	parseIntoWords: function(/*String*/ text){
+		// summary:
+		//		Parse the text into words
+		// text:
+		//		Plain text without html tags
+		// tags:
+		//		public
+		// returns:
+		//		Array holding all the words
+		function isCharExt(c){
+			var ch = c.charCodeAt(0);
+			return 48 <= ch && ch <= 57 || 65 <= ch && ch <= 90 || 97 <= ch && ch <= 122;
+		}
+		var words = this.words = [],
+			indices = this.indices = [],
+			index = 0,
+			length = text && text.length,
+			start = 0;
+		
+		while(index < length){
+			var ch;
+			// Skip the white charactor and need to treat HTML entity respectively
+			while(index < length && !isCharExt(ch = text.charAt(index)) && ch != "&"){ index++; }
+			if(ch == "&"){ // An HTML entity, skip it
+				while(++index < length && (ch = text.charAt(index)) != ";" && isCharExt(ch)){}
+			}else{ // A word
+				start = index;
+				while(++index < length && isCharExt(text.charAt(index))){}
+				if(start < length){
+					words.push(text.substring(start, index));
+					indices.push(start);
+				}
+			}
+		}
+		
+		return words;
+	},
+	
+	getIndices: function(){
+		// summary:
+		//		Get the indices of the words. They are in one-to-one correspondence
+		// tags:
+		//		public
+		// returns:
+		//		Index array
+		return this.indices;
+	}
+});
+
+// Register this parser in the SpellCheck plugin.
+dojo.subscribe(dijit._scopeName + ".Editor.plugin.SpellCheck.getParser", null, function(sp){
+	if(sp.parser){ return; }
+	sp.parser = new dojox.editor.plugins._SpellCheckParser();
+});
+
+return dojox.editor.plugins._SpellCheckParser;
+
+});
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/AutoSave.js b/dojox/editor/plugins/nls/AutoSave.js
new file mode 100644
index 0000000..655451f
--- /dev/null
+++ b/dojox/editor/plugins/nls/AutoSave.js
@@ -0,0 +1,13 @@
+({
+	"saveLabel": "Save",
+	"saveSettingLabelOn": "Set Auto-Save Interval...",
+	"saveSettingLabelOff": "Turn off Auto-Save",
+	"saveSettingdialogTitle": "Auto-Save",
+	"saveSettingdialogDescription": "Specify Auto-Save interval",
+	"saveSettingdialogParamName": "Auto-Save Interval",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Set Interval",
+	"saveSettingdialogButtonCancel": "Cancel",
+	"saveMessageSuccess": "Saved at ${0}",
+	"saveMessageFail": "Failed to save at ${0}"
+})
diff --git a/dojox/editor/plugins/nls/LocalImage.js b/dojox/editor/plugins/nls/LocalImage.js
new file mode 100644
index 0000000..d8bfed3
--- /dev/null
+++ b/dojox/editor/plugins/nls/LocalImage.js
@@ -0,0 +1,10 @@
+({
+	insertImageTitle: "Insert Image",
+	url: "Image",
+	browse: "Browse...",
+	text: "Description",
+	set: "Insert",
+	invalidMessage: "Invalid image file type",
+	prePopuTextUrl: "Enter an image URL",
+	prePopuTextBrowse: " or browse to a local file."
+})
diff --git a/dojox/editor/plugins/nls/Smiley.js b/dojox/editor/plugins/nls/Smiley.js
index caf0623..522ce50 100644
--- a/dojox/editor/plugins/nls/Smiley.js
+++ b/dojox/editor/plugins/nls/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "wink",
 	emoticonGrin: "grin",
 	emoticonCool: "cool",
-	emoticonAngry: "angry",  
-	emoticonHalf: "half", 
+	emoticonAngry: "angry",
+	emoticonHalf: "half",
 	emoticonEyebrow: "eyebrow",
 	emoticonFrown: "frown",
 	emoticonShy: "shy",
@@ -15,7 +15,7 @@
 	emoticonTongue: "tongue",
 	emoticonIdea: "idea",
 	emoticonYes: "yes",
-	emoticonNo: "no",	
+	emoticonNo: "no",
 	emoticonAngel: "angel",
 	emoticonCrying: "crying"
 })
diff --git a/dojox/editor/plugins/nls/SpellCheck.js b/dojox/editor/plugins/nls/SpellCheck.js
new file mode 100644
index 0000000..07faeb9
--- /dev/null
+++ b/dojox/editor/plugins/nls/SpellCheck.js
@@ -0,0 +1,16 @@
+({
+	widgetLabel: "Batch Spell Check",
+	unfound: "Not found",
+	skip: "Skip",
+	skipAll: "Skip All",
+	toDic: "Add to dictionary",
+	suggestions: "Suggestions",
+	replace: "Replace",
+	replaceWith: "Replace with",
+	replaceAll: "Replace All",
+	cancel: "Cancel",
+	msg: "No misspellings found",
+	iSkip: "Skip this",
+	iSkipAll: "Skip all like this",
+	iMsg: "No spelling suggestions"
+})
diff --git a/dojox/editor/plugins/nls/TableDialog.js b/dojox/editor/plugins/nls/TableDialog.js
index ca9001b..6130f3b 100644
--- a/dojox/editor/plugins/nls/TableDialog.js
+++ b/dojox/editor/plugins/nls/TableDialog.js
@@ -9,7 +9,7 @@
 	tableWidth: "Table Width:",
 	backgroundColor: "Background Color:",
 	borderColor: "Border Color:",
-	borderThickness: "BorderThickness",
+	borderThickness: "Border Thickness:",
 	percent: "percent",
 	pixels: "pixels",
 	"default": "default",
@@ -18,6 +18,7 @@
 	right: "right",
 	buttonSet: "Set", // translated elsewhere?
 	buttonInsert: "Insert",
+	buttonCancel: "Cancel",
 
 	selectTableLabel: "Select Table",
 	insertTableRowBeforeLabel: "Add Row Before",
@@ -27,3 +28,4 @@
 	deleteTableRowLabel: "Delete Row",
 	deleteTableColumnLabel: "Delete Column"
 })
+	
\ No newline at end of file
diff --git a/dojox/editor/plugins/nls/ar/AutoSave.js b/dojox/editor/plugins/nls/ar/AutoSave.js
new file mode 100644
index 0000000..ba5c591
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "حفظ",
+	"saveSettingLabelOn": "تحديد الفترة الزمنية للحفظ الآلي...",
+	"saveSettingLabelOff": "ايقاف الحفظ الآلي",
+	"saveSettingdialogTitle": "حفظ آلي",
+	"saveSettingdialogDescription": "تحديد الفترة الزمنية للحفظ الآلي",
+	"saveSettingdialogParamName": "الفترة الزمنية للحفظ الآلي",
+	"saveSettingdialogParamLabel": "دقيقة",
+	"saveSettingdialogButtonOk": "تحديد الفترة الزمنية",
+	"saveSettingdialogButtonCancel": "الغاء",
+	"saveMessageSuccess": "تم الحفظ في ${0}",
+	"saveMessageFail": "فشل في الحفظ في ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/Blockquote.js b/dojox/editor/plugins/nls/ar/Blockquote.js
new file mode 100644
index 0000000..48194c3
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "علامة تنصيص الفقرة"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/Breadcrumb.js b/dojox/editor/plugins/nls/ar/Breadcrumb.js
new file mode 100644
index 0000000..7b0cccf
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} تصرفات",
+	"selectContents": "تحديد المحتويات",
+	"selectElement": "تحديد عنصر",
+	"deleteElement": "حذف عنصر",
+	"deleteContents": "حذف محتويات",
+	"moveStart": "نقل المؤشر للبداية",
+	"moveEnd": "نقل المؤشر للنهاية"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
new file mode 100644
index 0000000..6811d2c
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "طي خط أدوات المحرر",
+	"expand": "توسيع خط أدوات المحرر"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/FindReplace.js b/dojox/editor/plugins/nls/ar/FindReplace.js
new file mode 100644
index 0000000..0f45207
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "ايجاد:",
+	"findTooltip": "ادخال نص لايجاد",
+	"replaceLabel": "استبدال بالآتي:",
+	"replaceTooltip": "ادخال نص للاستبدال مع",
+	"findReplace": "ايجاد واستبدال",
+	"matchCase": "مطابقة حالة الحروف",
+	"matchCaseTooltip": "مطابقة حالة الحروف",
+	"backwards": "الى الوراء",
+	"backwardsTooltip": "البحث الى الوراء عن نص",
+	"replaceAll": "كل التكرارات",
+	"replaceAllButton": "استبدال كل",
+	"replaceAllButtonTooltip": "استبدال كل النص",
+	"findButton": "ايجاد",
+	"findButtonTooltip": "ايجاد النص",
+	"replaceButton": "استبدال",
+	"replaceButtonTooltip": "استبدال النص",
+	"replaceDialogText": "التكرارات ${0} المستبدلة.",
+	"eofDialogText": "آخر تكرار ${0}",
+	"eofDialogTextFind": "موجودة",
+	"eofDialogTextReplace": "مستبدل"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/InsertAnchor.js b/dojox/editor/plugins/nls/ar/InsertAnchor.js
new file mode 100644
index 0000000..351f9b8
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "ادراج نقطة التثبيت",
+	title: "خصائص نقطة التثبيت",
+	anchor: "الاسم:",
+	text: "الوصف:",
+	set: "تحديد",
+	cancel: "الغاء"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/InsertEntity.js b/dojox/editor/plugins/nls/ar/InsertEntity.js
new file mode 100644
index 0000000..6ac1b72
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "ادراج رمز"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/LocalImage.js b/dojox/editor/plugins/nls/ar/LocalImage.js
new file mode 100644
index 0000000..f61f2ad
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "ادراج صورة",
+	url: "صورة",
+	browse: "استعراض...",
+	text: "الوصف",
+	set: "‏ادراج‏",
+	invalidMessage: "نوع ملف صور غير صحيح",
+	prePopuTextUrl: "ادخل عنوان URL لصورة",
+	prePopuTextBrowse: " أو تصفح الى ملف محلي."
+})
+
diff --git a/dojox/editor/plugins/nls/ar/PageBreak.js b/dojox/editor/plugins/nls/ar/PageBreak.js
new file mode 100644
index 0000000..ea4675d
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "فاصل الصفحات"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/PasteFromWord.js b/dojox/editor/plugins/nls/ar/PasteFromWord.js
new file mode 100644
index 0000000..211ff4a
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "لصق من Word",
+	"paste": "لصق",
+	"cancel": "الغاء",
+	"instructions": "لصق المحتويات من Word الى مربع النص بأسفل. بمجرد أن تكون راضيا عن المحتوى المراد ادراجه، اضغط على اختيار لصق. للتوقف عن ادراج النص، اضغط  اختيار الغاء."
+})
+
diff --git a/dojox/editor/plugins/nls/ar/Preview.js b/dojox/editor/plugins/nls/ar/Preview.js
new file mode 100644
index 0000000..419fdb8
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "معاينة"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/Save.js b/dojox/editor/plugins/nls/ar/Save.js
new file mode 100644
index 0000000..6b589b2
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "حفظ"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/ShowBlockNodes.js b/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
new file mode 100644
index 0000000..d8fb3ca
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "عرض عناصر كتلة HTML"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/Smiley.js b/dojox/editor/plugins/nls/ar/Smiley.js
new file mode 100644
index 0000000..9031c30
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "ادراج شكل متحرك",
+	emoticonSmile: "ابتسامة",
+	emoticonLaughing: "ضاحك",
+	emoticonWink: "غمزة",
+	emoticonGrin: "تكشير",
+	emoticonCool: "حسنا",
+	emoticonAngry: "غضبان",
+	emoticonHalf: "نصف",
+	emoticonEyebrow: "حاجب",
+	emoticonFrown: "عبوس",
+	emoticonShy: "خجول",
+	emoticonGoofy: "أبله",
+	emoticonOops: "عفوا",
+	emoticonTongue: "لسان",
+	emoticonIdea: "فكرة",
+	emoticonYes: "نعم",
+	emoticonNo: "لا",
+	emoticonAngel: "ملاك",
+	emoticonCrying: "يبكي"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/SpellCheck.js b/dojox/editor/plugins/nls/ar/SpellCheck.js
new file mode 100644
index 0000000..d07e035
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "فحص هجاء دفعي",
+	unfound: "غير موجودة",
+	skip: "تخطي",
+	skipAll: "تخطي كل",
+	toDic: "اضافة الى القاموس",
+	suggestions: "اقتراحات",
+	replace: "استبدال",
+	replaceWith: "استبدال مع",
+	replaceAll: "استبدال كل",
+	cancel: "الغاء",
+	msg: "لا يوجد أخطاء في الهجاء",
+	iSkip: "تخطي هذا",
+	iSkipAll: "تخطي كل المماثل لهذا",
+	iMsg: "لا توجد اقتراحات للهجاء"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/TableDialog.js b/dojox/editor/plugins/nls/ar/TableDialog.js
index e44dbd1..a474e51 100644
--- a/dojox/editor/plugins/nls/ar/TableDialog.js
+++ b/dojox/editor/plugins/nls/ar/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "لليمين",
 	buttonSet: "تحديد", // translated elsewhere?
 	buttonInsert: "‏ادراج‏",
+	buttonCancel: "الغاء",
 
 	selectTableLabel: "تحديد جدول",
 	insertTableRowBeforeLabel: "اضافة صف قبل",
diff --git a/dojox/editor/plugins/nls/ar/TextColor.js b/dojox/editor/plugins/nls/ar/TextColor.js
new file mode 100644
index 0000000..90a9aa3
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "تحديد",
+	"cancelButtonText": "الغاء"
+})
+
diff --git a/dojox/editor/plugins/nls/ar/latinEntities.js b/dojox/editor/plugins/nls/ar/latinEntities.js
new file mode 100644
index 0000000..df844ac
--- /dev/null
+++ b/dojox/editor/plugins/nls/ar/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* These are already handled in the default RTE
+		amp:"ampersand",lt:"less-than sign",
+		gt:"greater-than sign",
+		nbsp:"no-break space\nnon-breaking space",
+		quot:"quote",
+	*/
+	iexcl:"علامة تعجب معكوسة",
+	cent:"علامة السنت",
+	pound:"علامة الجنيه",
+	curren:"علامة العملة",
+	yen:"علامة نعم\nعلامة nyuan",
+	brvbar:"خط مكسور\nخط أفقي مكسور",
+	sect:"علامة القسم",
+	uml:"تقسيم\nتباعد التقسيم",
+	copy:"علامة حقوق النشر",
+	ordf:"مؤشر ترتيبي أنثوي",
+	laquo:"علامة تنصيص بزاوية مزدوجة تشير الى اليسار\nعلامة تنصيص تشير الى اليسار ",
+	not:"ليست علامة",
+	shy:"وصلة قصيرة لينة\nوصلة قصيرة تقديرية",
+	reg:"علامة مسجلة\nعلامة تجارية مسجلة",
+	macr:"علامة المد\nتباعد علامة المد\nكتابة فوق السطر\nكتابة فوق سطر APL",
+	deg:"علامة الدرجة",
+	plusmn:"علامة زائد-ناقص\nعلامة زائد-أو-ناقص",
+	sup2:"رمز علوي اثنان\nعدد الرمز العلوي اثنان\nمربع",
+	sup3:"رمز علوي ثلاثة\nعدد الرمز العلوي ثلاثة\nمكعب",
+	acute:"علامة النطق الحادة\nتباعد الحادة",
+	micro:"علامة الصغر المتناهي",
+	para:"علامة الفقرة\nعلامة الفقرة",
+	middot:"النقطة الوسطى\nفاصلة جورجية\nنقطة وسطى يونانية",
+	cedil:"علامة السديلة\nتباعد علامة السديلة",
+	sup1:"رمز علوي واحد\nعدد رمز علوي واحد",
+	ordm:"مؤشر ترتيبي مذكر",
+	raquo:"علامة تنصيص بزاوية مزدوجة تشير الى اليمين\nعلامة تنصيص تشير الى اليمين ",
+	frac14:"جزء عام ربع واحد\nجزء ربع واحد",
+	frac12:"جزء عام نصف واحد\nجزء نصف واحد",
+	frac34:"جزء عام ثلاثة أرباع\nجزء ثلاثة أرباع",
+	iquest:"علامة استفهام معكوسة\nعلامة استفهام متحولة",
+	Agrave:"حرف لاتيني كبير A مع حفر\nحرف لاتيني كبير A حفر",
+	Aacute:"حرف لاتيني كبير A حاد",
+	Acirc:"حرف لاتيني كبير A مع علامة صوتية",
+	Atilde:"حرف لاتيني كبير A مع علامة التلدة",
+	Auml:"حرف لاتيني كبير A مع علامة حرف العلة",
+	Aring:"حرف لاتيني كبير A مع حلقة فوقه\nحرف لاتيني كبير A حلقة",
+	AElig:"حرف لاتيني كبير AE\nحرف لاتيني كبير مع الحرف المزدوج AE",
+	Ccedil:"حرف لاتيني كبير C مع علامة السديلة",
+	Egrave:"حرف لاتيني كبير  E مع حفر",
+	Eacute:"حرف لاتيني كبير E حاد",
+	Ecirc:"حرف لاتيني كبير E مع علامة صوتية",
+	Euml:"حرف لاتيني كبير E مع علامة حرف العلة",
+	Igrave:"حرف لاتيني كبير  I مع حفر",
+	Iacute:"حرف لاتيني كبير I حاد",
+	Icirc:"حرف لاتيني كبير I مع علامة صوتية",
+	Iuml:"حرف لاتيني كبير I مع علامة حرف العلة",
+	ETH:"حرف لاتيني كبير ETH",
+	Ntilde:"حرف لاتيني كبير N مع علامة التلدة",
+	Ograve:"حرف لاتيني كبير  O مع حفر",
+	Oacute:"حرف لاتيني كبير O حاد",
+	Ocirc:"حرف لاتيني كبير O مع علامة صوتية",
+	Otilde:"حرف لاتيني كبير O مع علامة التلدة",
+	Ouml:"حرف لاتيني كبير O مع علامة حرف العلة",
+	times:"علامة الضرب",
+	Oslash:"حرف لاتيني كبير O مع حركة منتظمة متكررة\nحرف لاتيني كبير O شرطة مائلة",
+	Ugrave:"حرف لاتيني كبير  U مع حفر",
+	Uacute:"حرف لاتيني كبير U حاد",
+	Ucirc:"حرف لاتيني كبير U مع علامة صوتية",
+	Uuml:"حرف لاتيني كبير U مع علامة حرف العلة",
+	Yacute:"حرف لاتيني كبير Y حاد",
+	THORN:"حرف لاتيني كبير THORN",
+	szlig:"حرف لاتيني صغير حاد s\ness-zed",
+	agrave:"حرف لاتيني صغير a مع حفر\nحرف لاتيني صغير a حفر",
+	aacute:"حرف لاتيني صغير a حاد",
+	acirc:"حرف لاتيني صغير a مع علامة صوتية",
+	atilde:"حرف لاتيني صغير a مع علامة التلدة",
+	auml:"حرف لاتيني صغير a مع علامة حرف العلة",
+	aring:"حرف لاتيني صغير a مع حلقة فوقه\nحرف لاتيني صغير a حلقة",
+	aelig:"حرف لاتيني صغير ae\nحرف لاتيني صغير مزدوج ae",
+	ccedil:"حرف لاتيني صغير c مع علامة السديلة",
+	egrave:"حرف لاتيني صغير e مع حفر",
+	eacute:"حرف لاتيني صغير e حاد",
+	ecirc:"حرف لاتيني صغير e مع علامة صوتية",
+	euml:"حرف لاتيني صغير e مع علامة حرف العلة",
+	igrave:"حرف لاتيني صغير i مع حفر",
+	iacute:"حرف لاتيني صغير i حاد",
+	icirc:"حرف لاتيني صغير i مع علامة صوتية",
+	iuml:"حرف لاتيني صغير i مع علامة حرف العلة",
+	eth:"حرف لاتيني صغير eth",
+	ntilde:"حرف لاتيني صغير n مع علامة التلدة",
+	ograve:"حرف لاتيني صغير o مع حفر",
+	oacute:"حرف لاتيني صغير o حاد",
+	ocirc:"حرف لاتيني صغير o مع علامة صوتية",
+	otilde:"حرف لاتيني صغير o مع علامة التلدة",
+	ouml:"حرف لاتيني صغير o مع علامة حرف العلة",
+	divide:"علامة القسمة",
+	oslash:"حرف لاتيني صغير o مع حركة منتظمة متكررة\nحرف لاتيني صغير o شرطة مائلة",
+	ugrave:"حرف لاتيني صغير u مع حفر",
+	uacute:"حرف لاتيني صغير u حاد",
+	ucirc:"حرف لاتيني صغير u مع علامة صوتية",
+	uuml:"حرف لاتيني صغير u مع علامة حرف العلة",
+	yacute:"حرف لاتيني صغير y حاد",
+	thorn:"حرف لاتيني صغير طنان",
+	yuml:"حرف لاتيني صغير y مع علامة حرف العلة",
+
+// Greek Characters and Symbols
+	fnof:"حرف لاتيني صغير f مع التواء\nوظيفة\nفلورين",
+	Alpha:"حرف يوناني كبير الفا",
+	Beta:"حرف يوناني كبير beta",
+	Gamma:"حرف يوناني كبير جاما",
+	Delta:"حرف يوناني كبير دلتا",
+	Epsilon:"حرف يوناني كبير epsilon",
+	Zeta:"حرف يوناني كبير zeta",
+	Eta:"حرف يوناني كبير eta",
+	Theta:"حرف يوناني كبير theta",
+	Iota:"حرف يوناني كبير iota",
+	Kappa:"حرف يوناني كبير kappa",
+	Lambda:"حرف يوناني كبير lambda",
+	Mu:"حرف يوناني كبير mu",
+	Nu:"حرف يوناني كبير nu",
+	Xi:"حرف يوناني كبير xi",
+	Omicron:"حرف يوناني كبير omicron",
+	Pi:"حرف يوناني كبير pi",
+	Rho:"حرف يوناني كبير rho",
+	Sigma:"حرف يوناني كبير sigma",
+	Tau:"حرف يوناني كبير tau",
+	Upsilon:"حرف يوناني كبير upsilon",
+	Phi:"حرف يوناني كبير phi",
+	Chi:"حرف يوناني كبير chi",
+	Psi:"حرف يوناني كبير psi",
+	Omega:"حرف يوناني كبير omega",
+	alpha:"حرف يوناني صغير الفا",
+	beta:"حرف يوناني صغير beta",
+	gamma:"حرف يوناني صغير gamma",
+	delta:"حرف يوناني صغير delta",
+	epsilon:"حرف يوناني صغير epsilon",
+	zeta:"حرف يوناني صغير zeta",
+	eta:"حرف يوناني صغير eta",
+	theta:"حرف يوناني صغير theta",
+	iota:"حرف يوناني صغير iota",
+	kappa:"حرف يوناني صغير kappa",
+	lambda:"حرف يوناني صغير lambda",
+	mu:"حرف يوناني صغير mu",
+	nu:"حرف يوناني صغير nu",
+	xi:"حرف يوناني صغير xi",
+	omicron:"حرف يوناني صغير omicron",
+	pi:"حرف يوناني صغير pi",
+	rho:"حرف يوناني صغير rho",
+	sigmaf:"حرف يوناني صغير final النهائي",
+	sigma:"حرف يوناني صغير sigma",
+	tau:"حرف يوناني صغير tau",
+	upsilon:"حرف يوناني صغير upsilon",
+	phi:"حرف يوناني صغير phi",
+	chi:"حرف يوناني صغير chi",
+	psi:"حرف يوناني صغير psi",
+	omega:"حرف يوناني صغير omega",
+	thetasym:"حرف يوناني صغير رمز theta",
+	upsih:"upsilon يوناني مع رمز الالتواء",
+	piv:"رمز pi اليوناني",
+	bull:"نقطة\nدائرة سوداء صغيرة",
+	hellip:"علامة حذف أفقية\nافتتاحية بثلاث نقاط",
+	prime:"أولي\nدقائق\nقدم",
+	Prime:"أولي مزدوج\nثواني\nبوصات",
+	oline:"كتابة فوق سطر\nتباعد شطب السطر",
+	frasl:"شرطة مائلة لجزء",
+	weierp:"حرف كبير P للنص\nتحديد الطاقة\nWeierstrass p",
+	image:"حرف كبير أسود I\nجزء تخيلي",
+	real:"حرف كبير أسود R\nرمز الجزء الحقيقي",
+	trade:"علامة تجارية",
+	alefsym:"رمز alef\nما وراء المحدود الأساسي الأول",
+	larr:"سهم متجه لليسار",
+	uarr:"سهم متجه لأعلى",
+	rarr:"سهم متجه لليمين",
+	darr:"سهم متجه لأسفل",
+	harr:"سهم يسار يمين",
+	crarr:"سهم متجه لأسفل مع الاتجاه لليسار بزاوية\nارجاع النقل",
+	lArr:"سهم مزدوج متجه لليسار",
+	uArr:"سهم مزدوج متجه لأعلى",
+	rArr:"سهم مزدوج متجه لليمين",
+	dArr:"سهم مزدوج متجه لأسفل",
+	hArr:"سهم مزدوج يسار يمين",
+	forall:"للكل",
+	part:"الفارق الجزئي",
+	exist:"يوجد هناك",
+	empty:"مجموعة خالية\nمجموعة صفرية\nالقطر",
+	nabla:"nabla\nاختلاف عكسي",
+	isin:"عنصر من",
+	notin:"ليس عنصر من",
+	ni:"يتضمن كعضو",
+	prod:"منتج n-ary\nعلامة المنتج",
+	sum:"جمع n-ary",
+	minus:"علامة الطرح",
+	lowast:"معامل علامة النجمة",
+	radic:"الجذر التربيعي\nعلامة الجذر",
+	prop:"تناسبي الى",
+	infin:"لا نهائي",
+	ang:"زاوية",
+	and:"منطقي و\nعلامة قبعة معكوسة",
+	or:"منطقي أو\nمخروطي",
+	cap:"نقطة تقاطع\ncap",
+	cup:"اتحاد\nكأس","int":"صحيح",
+	there4:"لذلك",
+	sim:"معامل علامة التلدة\nيتغير مع\nمماثل مع",
+	cong:"تقريبا مساو الى",
+	asymp:"تقريبا يساوي\nمقارب الى",
+	ne:"لا يساوي",
+	equiv:"مماثل الى",
+	le:"أقل من أو يساوي",
+	ge:"أكبر من أو يساوي",
+	sub:"فرعية من",
+	sup:"مجاميع من",
+	nsub:"ليس فرعية من",
+	sube:"فرعية من أو تساوي",
+	supe:"مجاميع من أو تساوي",
+	oplus:"علامة زائد في دائرة\nمجموع مباشر",
+	otimes:"أضعاف في دائرة\nمنتج nvector",
+	perp:"تثبيت لأعلى\nمتعامد على\nعمودي",
+	sdot:"معامل النقطة",
+	lceil:"حد أعلى يسار\nAPL upstile",
+	rceil:"حد أعلى يمين",
+	lfloor:"الطابق الأيسر\nAPL downstile",
+	rfloor:"الطابق الأيمن",
+	lang:"قوس مربع يشير الى اليسار",
+	rang:"قوس مربع يشير الى اليمين",
+	loz:"المعين",
+	spades:"بدلة بستوني أسود",
+	clubs:"بدلة نادي سوداء\nshamrock",
+	hearts:"بدلة قلب أسود\nvalentine",
+	diams:"بدلة شكل معين سوداء",
+	OElig:"حرف لاتيني كبير مزدوج OE",
+	oelig:"حرف لاتيني صغير مزدوج oe",
+	Scaron:"حرف لاتيني كبير S مع علامة قبعة معكوسة",
+	scaron:"حرف لاتيني صغير s مع علامة قبعة معكوسة",
+	Yuml:"حرف لاتيني كبير Y مع علامة حرف العلة",
+	circ:"نبرة علامة صوتية حرف تعديل",
+	tilde:"علامة التلدة صغيرة",
+	ensp:"مساحة en",
+	emsp:"مساحة em",
+	thinsp:"مساحة رفيعة",
+	zwnj:"عرض صفر غير مرتبط",
+	zwj:"عرض صفر مرتبط",
+	lrm:"علامة يسار الى يمين",
+	rlm:"علامة يمين الى يسار",
+	ndash:"شرطة en",
+	mdash:"شرطة em",
+	lsquo:"علامة تنصيص يسار منفردة",
+	rsquo:"علامة تنصيص يمين منفردة",
+	sbquo:"علامة تنصيص low-9 منفردة",
+	ldquo:"علامة تنصيص يسار مزدوجة",
+	rdquo:"علامة تنصيص يمين مزدوجة",
+	bdquo:"علامة تنصيص low-9 مزدوجة",
+	dagger:"خنجرية",
+	Dagger:"خنجرية مزدوجة",
+	permil:"علامة بالألف",
+	lsaquo:"علامة تنصيص زاوية منفردة تشير الى اليسار",
+	rsaquo:"علامة تنصيص زاوية منفردة تشير الى اليمين",
+	euro:"علامة اليورو"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/AutoSave.js b/dojox/editor/plugins/nls/ca/AutoSave.js
new file mode 100644
index 0000000..33b62c1
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Desa",
+	"saveSettingLabelOn": "Estableix l'interval per desar automàticament...",
+	"saveSettingLabelOff": "Deshabilita el desat automàtic",
+	"saveSettingdialogTitle": "Desat automàtic",
+	"saveSettingdialogDescription": "Especifiqueu l'interval de desat automàtic",
+	"saveSettingdialogParamName": "Interval de desat automàtic",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Estableix l'interval",
+	"saveSettingdialogButtonCancel": "Cancel·la",
+	"saveMessageSuccess": "Desat a les ${0}",
+	"saveMessageFail": "No s'ha pogut desar a les ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/Blockquote.js b/dojox/editor/plugins/nls/ca/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/Breadcrumb.js b/dojox/editor/plugins/nls/ca/Breadcrumb.js
new file mode 100644
index 0000000..41d0ed1
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} - Accions",
+	"selectContents": "Selecciona contingut",
+	"selectElement": "Selecciona element",
+	"deleteElement": "Suprimeix element",
+	"deleteContents": "Suprimeix contingut",
+	"moveStart": "Mou el cursor a l'inici",
+	"moveEnd": "Mou el cursor al final"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
new file mode 100644
index 0000000..94daaec
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Redueix la barra d'eines de l'editor",
+	"expand": "Expandeix la barra d'eines de l'editor"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/FindReplace.js b/dojox/editor/plugins/nls/ca/FindReplace.js
new file mode 100644
index 0000000..e0429d1
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Cerca:",
+	"findTooltip": "Especifiqueu el text que voleu trobar",
+	"replaceLabel": "Substitueix per:",
+	"replaceTooltip": "Especifiqueu el text amb què el voleu substituir",
+	"findReplace": "Cerca i substitueix",
+	"matchCase": "Coincidència de majúscules i minúscules",
+	"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",
+	"findButtonTooltip": "Troba el text",
+	"replaceButton": "Substitueix",
+	"replaceButtonTooltip": "Substitueix el text",
+	"replaceDialogText": "S'han substituït ${0} aparicions.",
+	"eofDialogText": "Darrera aparició ${0}",
+	"eofDialogTextFind": "trobat",
+	"eofDialogTextReplace": "substituït"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/InsertAnchor.js b/dojox/editor/plugins/nls/ca/InsertAnchor.js
new file mode 100644
index 0000000..2f40546
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Insereix una àncora",
+	title: "Propietats de l'àncora",
+	anchor: "Nom:",
+	text: "Descripció:",
+	set: "Defineix",
+	cancel: "Cancel·la"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/InsertEntity.js b/dojox/editor/plugins/nls/ca/InsertEntity.js
new file mode 100644
index 0000000..c2cff1b
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Insereix símbol"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/LocalImage.js b/dojox/editor/plugins/nls/ca/LocalImage.js
new file mode 100644
index 0000000..a27cced
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Insereix imatge",
+	url: "Imatge",
+	browse: "Navega...",
+	text: "Descripció",
+	set: "Insereix",
+	invalidMessage: "Tipus de fitxer d\'imatge no vàlid",
+	prePopuTextUrl: "Especifiqueu un URL d\'imatge",
+	prePopuTextBrowse: " o navegueu fins un fitxer local."
+})
+
diff --git a/dojox/editor/plugins/nls/ca/PageBreak.js b/dojox/editor/plugins/nls/ca/PageBreak.js
new file mode 100644
index 0000000..cd56c5c
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Salt de pàgina"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/PasteFromWord.js b/dojox/editor/plugins/nls/ca/PasteFromWord.js
new file mode 100644
index 0000000..f971b08
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Enganxa des de Word",
+	"paste": "Enganxa",
+	"cancel": "Cancel·la",
+	"instructions": "Enganxa el contingut de Word al quadre de text següent. Un cop esteu satisfets amb el contingut que voleu inserir, feu clic al botó Enganxa. Per cancel·lar la inserció de text, feu clic al botó Cancel·la."
+})
+
diff --git a/dojox/editor/plugins/nls/ca/Preview.js b/dojox/editor/plugins/nls/ca/Preview.js
new file mode 100644
index 0000000..40a446c
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Visualització prèvia"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/Save.js b/dojox/editor/plugins/nls/ca/Save.js
new file mode 100644
index 0000000..5ab9ef5
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Desa"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/ShowBlockNodes.js b/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
new file mode 100644
index 0000000..1fbccc9
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Mostra elements de bloc HTML"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/Smiley.js b/dojox/editor/plugins/nls/ca/Smiley.js
new file mode 100644
index 0000000..101a542
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Insereix emoticona",
+	emoticonSmile: "somriure",
+	emoticonLaughing: "rient",
+	emoticonWink: "ullet",
+	emoticonGrin: "gran somriure",
+	emoticonCool: "guai",
+	emoticonAngry: "enfadat",
+	emoticonHalf: "meitat",
+	emoticonEyebrow: "cella",
+	emoticonFrown: "espantat",
+	emoticonShy: "avergonyit",
+	emoticonGoofy: "babau",
+	emoticonOops: "ep",
+	emoticonTongue: "llengua",
+	emoticonIdea: "idea",
+	emoticonYes: "sí",
+	emoticonNo: "no",
+	emoticonAngel: "àngel",
+	emoticonCrying: "plorant"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/SpellCheck.js b/dojox/editor/plugins/nls/ca/SpellCheck.js
new file mode 100644
index 0000000..80dc34f
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Correcció ortogràfica per lots",
+	unfound: "No trobat",
+	skip: "Salta",
+	skipAll: "Salta tot",
+	toDic: "Afegeix al diccionari",
+	suggestions: "Suggeriments",
+	replace: "Substitueix",
+	replaceWith: "Substitueix per",
+	replaceAll: "Substitueix tot",
+	cancel: "Cancel·la",
+	msg: "No s'ha trobat cap error ortogràfic",
+	iSkip: "Saltar aquest",
+	iSkipAll: "Saltar tots els que són com aquest",
+	iMsg: "No hi ha suggeriments ortogràfics"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/TableDialog.js b/dojox/editor/plugins/nls/ca/TableDialog.js
index 0e748ab..1420bc1 100644
--- a/dojox/editor/plugins/nls/ca/TableDialog.js
+++ b/dojox/editor/plugins/nls/ca/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "dreta",
 	buttonSet: "Defineix", // translated elsewhere?
 	buttonInsert: "Insereix",
+	buttonCancel: "Cancel·la",
 
 	selectTableLabel: "Selecciona taula",
 	insertTableRowBeforeLabel: "Afegeix fila abans",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "Suprimeix fila",
 	deleteTableColumnLabel: "Suprimeix columna"
 })
-
diff --git a/dojox/editor/plugins/nls/ca/TextColor.js b/dojox/editor/plugins/nls/ca/TextColor.js
new file mode 100644
index 0000000..b550bea
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Defineix",
+	"cancelButtonText": "Cancel·la"
+})
+
diff --git a/dojox/editor/plugins/nls/ca/latinEntities.js b/dojox/editor/plugins/nls/ca/latinEntities.js
new file mode 100644
index 0000000..7e1c56d
--- /dev/null
+++ b/dojox/editor/plugins/nls/ca/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"signe d'exclamació obert",
+	cent:"signe de cèntims",
+	pound:"signe de lliura",
+	curren:"signe de moneda",
+	yen:"signe de ien\nsigne de iuan",
+	brvbar:"barra partida\nbarra vertical partida",
+	sect:"signe de secció",
+	uml:"dièresi\ndièresi d'espai",
+	copy:"signe de copyright",
+	ordf:"indicador ordinal femení",
+	laquo:"cometes llatines apuntant cap a l'esquerra\ncometes llatines cap a l'esquerra",
+	not:"signe de negació",
+	shy:"guió tou\nguió opcional",
+	reg:"signe de registrat\nsigne de marca comercial registrada",
+	macr:"macron\nmacron d'espaiat\nsobre-ratllat\nguió alt",
+	deg:"signe de graus",
+	plusmn:"signe de més-menys\nsigne de més-o-menys",
+	sup2:"dos en superíndex\nnúmero dos en superíndex\nal quadrat",
+	sup3:"tres en superíndex\nnúmero tres en superíndex\nal cub",
+	acute:"accent agut\nespaiat agut",
+	micro:"signe de micro",
+	para:"signe de paràgrafn\nsigne de canvi de paràgraf",
+	middot:"punt volat\ncoma georgiana\npunt volat grec",
+	cedil:"ce trencada\nespai de ce trencada",
+	sup1:"ú en superíndex\nnúmero ú en superíndex",
+	ordm:"indicador d'ordinal masculí",
+	raquo:"cometes llatines apuntant cap a la dreta\ncometes llatines cap a la dreta",
+	frac14:"fracció vulgar d'un quart\nfracció d'un quart",
+	frac12:"fracció vulgar de meitat\nfracció d'un mig",
+	frac34:"fracció vulgar de tres quarts\nfracció de tres quarts",
+	iquest:"signe d'interrogació obert\ninterrogació oberta",
+	Agrave:"lletra llatina A majúscula amb accent greu\nA majúscula amb accent greu",
+	Aacute:"lletra llatina A majúscula amb accent agut\nA majúscula amb accent agut",
+	Acirc:"lletra llatina A majúscula amb circumflex\nA majúscula amb circumflex",
+	Atilde:"lletra llatina A majúscula amb titlla",
+	Auml:"lletra llatina A majúscula amb dièresi",
+	Aring:"lletra llatina A majúscula amb anell al damunt\nA majúscula amb anell",
+	AElig:"lletra llatina AE majúscula\n Lligatura llatina AE majúscula",
+	Ccedil:"lletra llatina C trencada majúscula",
+	Egrave:"lletra llatina E majúscula amb accent greu",
+	Eacute:"lletra llatina E majúscula amb accent agut",
+	Ecirc:"lletra llatina E majúscula amb circumflex",
+	Euml:"lletra llatina E majúscula amb dièresi",
+	Igrave:"lletra llatina I majúscula amb accent greu",
+	Iacute:"lletra llatina I majúscula amb accent agut",
+	Icirc:"lletra llatina I majúscula amb circumflex",
+	Iuml:"lletra llatina I majúscula amb dièresi",
+	ETH:"lletra llatina ETH majúscula",
+	Ntilde:"lletra llatina N majúscula amb titlla\nlletra enye majúscula",
+	Ograve:"lletra llatina O majúscula amb accent greu",
+	Oacute:"lletra llatina O majúscula amb accent agut",
+	Ocirc:"lletra llatina O majúscula amb circumflex",
+	Otilde:"lletra llatina O majúscula amb titlla",
+	Ouml:"lletra llatina O majúscula amb dièresi",
+	times:"signe de multiplicació",
+	Oslash:"lletra llatina O majúscula amb traçat\nO majúscula amb barra inclinada",
+	Ugrave:"lletra llatina U majúscula amb accent greu",
+	Uacute:"lletra llatina U majúscula amb accent agut",
+	Ucirc:"lletra llatina U majúscula amb circumflex",
+	Uuml:"lletra llatina U majúscula amb dièresi",
+	Yacute:"lletra llatina Y majúscula amb accent agut",
+	THORN:"lletra llatina THORN majúscula",
+	szlig:"lletra llatina s fina\nesze alemanya",
+	agrave:"Lletra llatina a minúscula amb accent greu\na minúscula amb accent greu",
+	aacute:"lletra llatina a minúscula amb accent agut",
+	acirc:"lletra llatina a minúscula amb circumflex",
+	atilde:"lletra llatina a minúscula amb titlla",
+	auml:"lletra llatina a minúscula amb dièresi",
+	aring:"Lletra llatina a minúscula amb anell\na minúscula amb anell",
+	aelig:"lletra llatina AE minúscula\n Lligatura llatina AE minúscula",
+	ccedil:"lletra llatina c trencada minúscula",
+	egrave:"lletra llatina e minúscula amb accent greu",
+	eacute:"lletra llatina e minúscula amb accent agut",
+	ecirc:"lletra llatina e minúscula amb circumflex",
+	euml:"lletra llatina e minúscula amb dièresi",
+	igrave:"lletra llatina i minúscula amb accent greu",
+	iacute:"lletra llatina i minúscula amb accent agut",
+	icirc:"lletra llatina i minúscula amb circumflex",
+	iuml:"lletra llatina i minúscula amb dièresi",
+	eth:"lletra llatina eth minúscula",
+	ntilde:"lletra llatina n minúscula amb titlla\nlletra enye minúscula",
+	ograve:"lletra llatina o minúscula amb accent greu",
+	oacute:"lletra llatina o minúscula amb accent agut",
+	ocirc:"lletra llatina o minúscula amb circumflex",
+	otilde:"lletra llatina o minúscula amb titlla",
+	ouml:"lletra llatina o minúscula amb dièresi",
+	divide:"signe de divisió",
+	oslash:"lletra llatina o minúscula amb traçat\no minúscula amb barra inclinada",
+	ugrave:"lletra llatina u minúscula amb accent greu",
+	uacute:"lletra llatina u minúscula amb accent agut",
+	ucirc:"lletra llatina u minúscula amb circumflex",
+	uuml:"lletra llatina u minúscula amb dièresi",
+	yacute:"lletra llatina y minúscula amb accent agut",
+	thorn:"lletra llatina thorn minúscula",
+	yuml:"lletra llatina y minúscula amb dièresi",
+
+// Greek Characters and Symbols
+	fnof:"lletra llatina f minúscula amb ganxet\nfunció\nflorí",
+	Alpha:"lletra grega alfa majúscula",
+	Beta:"lletra grega beta majúscula",
+	Gamma:"lletra grega gamma majúscula",
+	Delta:"lletra grega delta majúscula",
+	Epsilon:"lletra grega epsilon majúscula",
+	Zeta:"lletra grega zeta majúscula",
+	Eta:"lletra grega eta majúscula",
+	Theta:"lletra grega theta majúscula",
+	Iota:"lletra grega iota majúscula",
+	Kappa:"lletra grega kappa majúscula",
+	Lambda:"lletra grega lambda majúscula",
+	Mu:"lletra grega mu majúscula",
+	Nu:"lletra grega nu majúscula",
+	Xi:"lletra grega xi majúscula",
+	Omicron:"lletra grega omicron majúscula",
+	Pi:"lletra grega pi majúscula",
+	Rho:"lletra grega rho majúscula",
+	Sigma:"lletra grega sigma majúscula",
+	Tau:"lletra grega tau majúscula",
+	Upsilon:"lletra grega upsilon majúscula",
+	Phi:"lletra grega phi majúscula",
+	Chi:"lletra grega chi majúscula",
+	Psi:"lletra grega psi majúscula",
+	Omega:"lletra grega omega majúscula",
+	alpha:"lletra grega alfa minúscula",
+	beta:"lletra grega beta minúscula",
+	gamma:"lletra grega gamma minúscula",
+	delta:"lletra grega delta minúscula",
+	epsilon:"lletra grega epsilon minúscula",
+	zeta:"lletra grega zeta minúscula",
+	eta:"lletra grega eta minúscula",
+	theta:"lletra grega theta minúscula",
+	iota:"lletra grega iota minúscula",
+	kappa:"lletra grega kappa minúscula",
+	lambda:"lletra grega lambda minúscula",
+	mu:"lletra grega mu minúscula",
+	nu:"lletra grega nu minúscula",
+	xi:"lletra grega xi minúscula",
+	omicron:"lletra grega omicron minúscula",
+	pi:"lletra grega pi minúscula",
+	rho:"lletra grega rho minúscula",
+	sigmaf:"lletra grega sigma final minúscula",
+	sigma:"lletra grega sigma minúscula",
+	tau:"lletra grega tau minúscula",
+	upsilon:"lletra grega upsilon minúscula",
+	phi:"lletra grega phi minúscula",
+	chi:"lletra grega chi minúscula",
+	psi:"lletra grega psi minúscula",
+	omega:"lletra grega omega minúscula",
+	thetasym:"símbol de lletra grega theta minúscula",
+	upsih:"símbol de lletra grega upsilon amb ganxet",
+	piv:"símbol grec de pi",
+	bull:"vinyeta\npetit cercle negre",
+	hellip:"el·lipsi horitzontal\nguia de tres punts",
+	prime:"prima\nminuts\npeus",
+	Prime:"doble prima\nsegons\npolzades",
+	oline:"sobre-ratllat\nespai de guió alt",
+	frasl:"barra de fracció",
+	weierp:"lletra P majúscula de script\nconjunt de potència\np de Weierstrass",
+	image:"I majúscula negra\npart imaginària",
+	real:"R majúscula negra\nsímbol de part real",
+	trade:"signe de marca registrada",
+	alefsym:"símbol d'alef\nprimer cardinal transfinit",
+	larr:"fletxa cap a l'esquerra",
+	uarr:"fletxa cap amunt",
+	rarr:"fletxa cap a la dreta",
+	darr:"fletxa cap avall",
+	harr:"fletxa a esquerra i dreta",
+	crarr:"fletxa cap avall amb cantonada a l'esquerra\nretorn de carro",
+	lArr:"doble fletxa cap a l'esquerra",
+	uArr:"doble fletxa cap amunt",
+	rArr:"doble fletxa cap a la dreta",
+	dArr:"doble fletxa cap avall",
+	hArr:"doble fletxa a esquerra i dreta",
+	forall:"per a tot",
+	part:"diferencial parcial",
+	exist:"existeix",
+	empty:"conjunt buit\nconjunt nul\ndiàmetre",
+	nabla:"nabla\ndiferència cap enrere",
+	isin:"és element de",
+	notin:"no és element de",
+	ni:"conté com a membre",
+	prod:"producte n-ari\nsigne de producte",
+	sum:"sumatori n-ari",
+	minus:"signe menys",
+	lowast:"operador asterisc",
+	radic:"arrel quadrada\nsigne de radical",
+	prop:"proporcional a",
+	infin:"infinit",
+	ang:"angle",
+	and:"i lògic\nfalca",
+	or:"o lògica\nvall",
+	cap:"intersecció\nbarret",
+	cup:"unió\ncopa","int":"integral",
+	there4:"per tant",
+	sim:"operador de titlla\nvaria amb\nsemblant a",
+	cong:"aproximadament igual que",
+	asymp:"gairebé igual que\nasintòtic amb",
+	ne:"no igual que",
+	equiv:"idèntic a",
+	le:"menor o igual que",
+	ge:"major o igual que",
+	sub:"sots-conjunt de",
+	sup:"super-conjunt de",
+	nsub:"no és un sots-conjunt de",
+	sube:"sots-conjunt de o igual que",
+	supe:"super-conjunt de o igual que",
+	oplus:"més encerclat\nsuma directa",
+	otimes:"multiplicació encerclada\nproducte de vectors",
+	perp:"clau aixecat\nortogonal a\nperpendicular",
+	sdot:"operador de punt",
+	lceil:"sostre esquerre\nAPL amunt",
+	rceil:"sostre dret",
+	lfloor:"terra esquerre\nAPL avall",
+	rfloor:"terra dret",
+	lang:"claudàtor angular apuntant a l'esquerra",
+	rang:"claudàtor angular apuntant a la dreta",
+	loz:"rombe",
+	spades:"pal de piques negre",
+	clubs:"pal de trèbols negre\ntrèbol",
+	hearts:"pal de cors negre\nsant valentí",
+	diams:"pal de diamants negre",
+	OElig:"lligatura llatina OE majúscula",
+	oelig:"lligatura llatina oe minúscula",
+	Scaron:"lletra llatina S majúscula amb circumflex invertit",
+	scaron:"lletra llatina s minúscula amb circumflex invertit",
+	Yuml:"lletra llatina Y majúscula amb dièresi",
+	circ:"modificador de lletra d'accent circumflex",
+	tilde:"titlla petita",
+	ensp:"espai en",
+	emsp:"espai em",
+	thinsp:"espai prim",
+	zwnj:"no-unió d'ample zero",
+	zwj:"unió d'ample zero",
+	lrm:"marca d'esquerra-a-dreta",
+	rlm:"marca de dreta-a-esquerra",
+	ndash:"guió en",
+	mdash:"guió em",
+	lsquo:"marca de citació senzilla esquerra",
+	rsquo:"marca de citació senzilla dreta",
+	sbquo:"marca de citació de 9-baix senzilla",
+	ldquo:"marca de citació doble esquerra",
+	rdquo:"marca de citació doble dreta",
+	bdquo:"marca de citació de 9-baix doble",
+	dagger:"daga",
+	Dagger:"doble daga",
+	permil:"signe de tant per mil",
+	lsaquo:"marca de citació en angle senzilla esquerra",
+	rsaquo:"marca de citació en angle senzilla dreta",
+	euro:"signe de l'euro"
+})
+
diff --git a/dojox/editor/plugins/nls/cs/AutoSave.js b/dojox/editor/plugins/nls/cs/AutoSave.js
new file mode 100644
index 0000000..711c7b1
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Uložit",
+	"saveSettingLabelOn": "Nastavit interval pro automatické uložení",
+	"saveSettingLabelOff": "Vypnout automatické uložení",
+	"saveSettingdialogTitle": "Automatické uložení",
+	"saveSettingdialogDescription": "Určit interval pro automatické uložení",
+	"saveSettingdialogParamName": "Interval pro automatické uložení",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Nastavit interval",
+	"saveSettingdialogButtonCancel": "Storno",
+	"saveMessageSuccess": "Uloženo v ${0}",
+	"saveMessageFail": "Selhalo uložení v ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/cs/Blockquote.js b/dojox/editor/plugins/nls/cs/Blockquote.js
new file mode 100644
index 0000000..3016648
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Citace v bloku"
+})
+
diff --git a/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js b/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
new file mode 100644
index 0000000..df9a95c
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Sbalit panel nástrojů editoru",
+	"expand": "Rozbalit panel nástrojů editoru"
+})
+
diff --git a/dojox/editor/plugins/nls/cs/FindReplace.js b/dojox/editor/plugins/nls/cs/FindReplace.js
index 1ce3dfd..19d7922 100644
--- a/dojox/editor/plugins/nls/cs/FindReplace.js
+++ b/dojox/editor/plugins/nls/cs/FindReplace.js
@@ -1,12 +1,22 @@
 ({
-	"findLabel": "Hledaný řetězec:",
+	"findLabel": "Najít:",
+	"findTooltip": "Zadejte hledaný text.",
 	"replaceLabel": "Nahrazující řetězec:",
-	"findReplace": "Přepnout hledání/nahrazování",
-	"matchCase": "S rozlišením velkých a malých písmen", 
+	"replaceTooltip": "Zadejte text pro nahrazení.",
+	"findReplace": "Najít a nahradit",
+	"matchCase": "S rozlišením velkých a malých písmen",
+	"matchCaseTooltip": "S rozlišením velkých a malých písmen",
 	"backwards": "V opačném směru",
-	"replaceAll": "Všechny výskyty", 
+	"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",
+	"findButtonTooltip": "Najít text",
 	"replaceButton": "Nahradit",
-	"replaceDialogText": "Počet nahrazených výskytů: ${0}. "
+	"replaceButtonTooltip": "Nahradit text",
+	"replaceDialogText": "Počet nahrazených výskytů: ${0}.",
+	"eofDialogText": "Poslední výskyt ${0}",
+	"eofDialogTextFind": "byl nalezen",
+	"eofDialogTextReplace": "byl nahrazen"
 })
-
diff --git a/dojox/editor/plugins/nls/cs/InsertAnchor.js b/dojox/editor/plugins/nls/cs/InsertAnchor.js
new file mode 100644
index 0000000..54bb097
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Vložit kotvu",
+	title: "Vlastnosti kotvy",
+	anchor: "Název:",
+	text: "Popis:",
+	set: "Nastavit",
+	cancel: "Storno"
+})
+
diff --git a/dojox/editor/plugins/nls/cs/LocalImage.js b/dojox/editor/plugins/nls/cs/LocalImage.js
new file mode 100644
index 0000000..5e2ab2a
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Vložit obrázek",
+	url: "Obrázek",
+	browse: "Procházet...",
+	text: "Popis",
+	set: "Vložit",
+	invalidMessage: "Neplatný typ souboru obrázku",
+	prePopuTextUrl: "Zadejte adresu URL obrázku",
+	prePopuTextBrowse: " nebo vyhledejte lokální soubor."
+})
+
diff --git a/dojox/editor/plugins/nls/cs/PasteFromWord.js b/dojox/editor/plugins/nls/cs/PasteFromWord.js
new file mode 100644
index 0000000..2a6329d
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Vložit z aplikace Word",
+	"paste": "Vložit",
+	"cancel": "Storno",
+	"instructions": "Vložte obsah z aplikace Word do zobrazeného textového pole. Jakmile jste s vkládaným obsahem spokojeni, stiskněte tlačítko Vložit. Pomocí tlačítka Storno vkládání zrušíte."
+})
+
diff --git a/dojox/editor/plugins/nls/cs/Smiley.js b/dojox/editor/plugins/nls/cs/Smiley.js
index 5787737..9dd6953 100644
--- a/dojox/editor/plugins/nls/cs/Smiley.js
+++ b/dojox/editor/plugins/nls/cs/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "mrknutí",
 	emoticonGrin: "úšklebek",
 	emoticonCool: "skvělé",
-	emoticonAngry: "hněv",  
-	emoticonHalf: "polovina", 
+	emoticonAngry: "hněv",
+	emoticonHalf: "polovina",
 	emoticonEyebrow: "obočí",
 	emoticonFrown: "zamračení",
 	emoticonShy: "stud",
@@ -15,7 +15,7 @@
 	emoticonTongue: "jazyk",
 	emoticonIdea: "nápad",
 	emoticonYes: "ano",
-	emoticonNo: "ne",	
+	emoticonNo: "ne",
 	emoticonAngel: "anděl",
 	emoticonCrying: "pláč"
 })
diff --git a/dojox/editor/plugins/nls/cs/SpellCheck.js b/dojox/editor/plugins/nls/cs/SpellCheck.js
new file mode 100644
index 0000000..48f65bf
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Dávková kontrola pravopisu",
+	unfound: "Nenalezeno",
+	skip: "Přeskočit",
+	skipAll: "Přeskočit vše",
+	toDic: "Přidat do slovníku",
+	suggestions: "Návrhy",
+	replace: "Nahradit",
+	replaceWith: "Text pro nahrazení",
+	replaceAll: "Nahradit vše",
+	cancel: "Storno",
+	msg: "Nebyly nalezeny žádné chyby pravopisu.",
+	iSkip: "Přeskočit tento výskyt",
+	iSkipAll: "Přeskočit všechny podobné výskyty",
+	iMsg: "Žádné návrhy pravopisu"
+})
+
diff --git a/dojox/editor/plugins/nls/cs/TableDialog.js b/dojox/editor/plugins/nls/cs/TableDialog.js
index 7f0e406..867b610 100644
--- a/dojox/editor/plugins/nls/cs/TableDialog.js
+++ b/dojox/editor/plugins/nls/cs/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "vpravo",
 	buttonSet: "Nastavit", // translated elsewhere?
 	buttonInsert: "Vložit",
+	buttonCancel: "Storno",
 
 	selectTableLabel: "Vybrat tabulku",
 	insertTableRowBeforeLabel: "Přidat řádek před",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "Odstranit řádek",
 	deleteTableColumnLabel: "Odstranit sloupec"
 })
-
diff --git a/dojox/editor/plugins/nls/cs/TextColor.js b/dojox/editor/plugins/nls/cs/TextColor.js
new file mode 100644
index 0000000..cc460e7
--- /dev/null
+++ b/dojox/editor/plugins/nls/cs/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Nastavit",
+	"cancelButtonText": "Storno"
+})
+
diff --git a/dojox/editor/plugins/nls/da/AutoSave.js b/dojox/editor/plugins/nls/da/AutoSave.js
new file mode 100644
index 0000000..4e45c98
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Gem",
+	"saveSettingLabelOn": "Angiv interval for automatisk lagring...",
+	"saveSettingLabelOff": "Deaktivér automatisk lagring",
+	"saveSettingdialogTitle": "Gem automatisk",
+	"saveSettingdialogDescription": "Angiv interval for automatisk lagring",
+	"saveSettingdialogParamName": "Interval for automatisk lagring",
+	"saveSettingdialogParamLabel": "min.",
+	"saveSettingdialogButtonOk": "Angiv interval",
+	"saveSettingdialogButtonCancel": "Annullér",
+	"saveMessageSuccess": "Gemt i ${0}",
+	"saveMessageFail": "Ikke gemt i ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/da/Blockquote.js b/dojox/editor/plugins/nls/da/Blockquote.js
new file mode 100644
index 0000000..cc44605
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Citat"
+})
+
diff --git a/dojox/editor/plugins/nls/da/Breadcrumb.js b/dojox/editor/plugins/nls/da/Breadcrumb.js
new file mode 100644
index 0000000..73e368a
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} - handlinger",
+	"selectContents": "Vælg indhold",
+	"selectElement": "Vælg element",
+	"deleteElement": "Slet element",
+	"deleteContents": "Slet indhold",
+	"moveStart": "Flyt markør til start",
+	"moveEnd": "Flyt markør til slut"
+})
+
diff --git a/dojox/editor/plugins/nls/da/CollapsibleToolbar.js b/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
new file mode 100644
index 0000000..d9cb207
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Skjul editorværktøjslinje",
+	"expand": "Udvid editorværktøjslinje"
+})
+
diff --git a/dojox/editor/plugins/nls/da/FindReplace.js b/dojox/editor/plugins/nls/da/FindReplace.js
new file mode 100644
index 0000000..aac4e7c
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Søg efter:",
+	"findTooltip": "Indtast tekst, der skal søges efter",
+	"replaceLabel": "Erstat med:",
+	"replaceTooltip": "Indtast tekst, der skal erstattes med",
+	"findReplace": "Søg og erstat",
+	"matchCase": "Store/små bogstaver",
+	"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",
+	"findButtonTooltip": "Find teksten",
+	"replaceButton": "Erstat",
+	"replaceButtonTooltip": "Erstat teksten",
+	"replaceDialogText": "Erstattet ${0} forekomster.",
+	"eofDialogText": "Sidste forekomst ${0}",
+	"eofDialogTextFind": "fundet",
+	"eofDialogTextReplace": "erstattet"
+})
+
diff --git a/dojox/editor/plugins/nls/da/InsertAnchor.js b/dojox/editor/plugins/nls/da/InsertAnchor.js
new file mode 100644
index 0000000..4937e12
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Indsæt anker",
+	title: "Ankeregenskaber",
+	anchor: "Navn:",
+	text: "Beskrivelse:",
+	set: "Definér",
+	cancel: "Annullér"
+})
+
diff --git a/dojox/editor/plugins/nls/da/InsertEntity.js b/dojox/editor/plugins/nls/da/InsertEntity.js
new file mode 100644
index 0000000..81e2c6d
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Indsæt symbol"
+})
+
diff --git a/dojox/editor/plugins/nls/da/LocalImage.js b/dojox/editor/plugins/nls/da/LocalImage.js
new file mode 100644
index 0000000..1e39501
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Indsæt billede",
+	url: "Billede",
+	browse: "Gennemse...",
+	text: "Beskrivelse",
+	set: "Indsæt",
+	invalidMessage: "Ugyldig billedfiltype",
+	prePopuTextUrl: "Angiv en billed-URL",
+	prePopuTextBrowse: " eller søg efter en lokal fil."
+})
+
diff --git a/dojox/editor/plugins/nls/da/PageBreak.js b/dojox/editor/plugins/nls/da/PageBreak.js
new file mode 100644
index 0000000..3fdbd10
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Sideskift"
+})
+
diff --git a/dojox/editor/plugins/nls/da/PasteFromWord.js b/dojox/editor/plugins/nls/da/PasteFromWord.js
new file mode 100644
index 0000000..4c0cab3
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Sæt ind fra Word",
+	"paste": "Sæt ind",
+	"cancel": "Annullér",
+	"instructions": "Indsæt indholdet fra Word i tekstfeltet nedenfor. Klik på knappen Sæt ind, når du er tilfreds med indholdet. Klik på knappen Annullér for at annullere indsættelse af tekst."
+})
+
diff --git a/dojox/editor/plugins/nls/da/Preview.js b/dojox/editor/plugins/nls/da/Preview.js
new file mode 100644
index 0000000..6c63e4c
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Eksempel"
+})
+
diff --git a/dojox/editor/plugins/nls/da/Save.js b/dojox/editor/plugins/nls/da/Save.js
new file mode 100644
index 0000000..a1f3aec
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Gem"
+})
+
diff --git a/dojox/editor/plugins/nls/da/ShowBlockNodes.js b/dojox/editor/plugins/nls/da/ShowBlockNodes.js
new file mode 100644
index 0000000..4fa9842
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Vis HTML-blokelementer"
+})
+
diff --git a/dojox/editor/plugins/nls/da/Smiley.js b/dojox/editor/plugins/nls/da/Smiley.js
new file mode 100644
index 0000000..565b13f
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Indsæt humørikon",
+	emoticonSmile: "smil",
+	emoticonLaughing: "ler",
+	emoticonWink: "blink",
+	emoticonGrin: "grin",
+	emoticonCool: "sej",
+	emoticonAngry: "vred",
+	emoticonHalf: "halv",
+	emoticonEyebrow: "øjenbryn",
+	emoticonFrown: "rynker panden",
+	emoticonShy: "genert",
+	emoticonGoofy: "skør",
+	emoticonOops: "ups",
+	emoticonTongue: "tungen ud",
+	emoticonIdea: "idé",
+	emoticonYes: "ja",
+	emoticonNo: "nej",
+	emoticonAngel: "engel",
+	emoticonCrying: "græder"
+})
+
diff --git a/dojox/editor/plugins/nls/da/SpellCheck.js b/dojox/editor/plugins/nls/da/SpellCheck.js
new file mode 100644
index 0000000..901f70f
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Bundtvis stavekontrol",
+	unfound: "Ikke fundet",
+	skip: "Spring over",
+	skipAll: "Spring alle over",
+	toDic: "Tilføj til ordbog",
+	suggestions: "Forslag",
+	replace: "Erstat",
+	replaceWith: "Erstat med",
+	replaceAll: "Erstat alle",
+	cancel: "Annullér",
+	msg: "Ingen stavefejl fundet",
+	iSkip: "Spring dette over",
+	iSkipAll: "Spring alle disse over",
+	iMsg: "Ingen forslag til stavning"
+})
+
diff --git a/dojox/editor/plugins/nls/da/TableDialog.js b/dojox/editor/plugins/nls/da/TableDialog.js
index 3b0ba7f..76029da 100644
--- a/dojox/editor/plugins/nls/da/TableDialog.js
+++ b/dojox/editor/plugins/nls/da/TableDialog.js
@@ -10,7 +10,7 @@
 	backgroundColor: "Baggrundsfarve:",
 	borderColor: "Kantfarve:",
 	borderThickness: "Kanttykkelse",
-	percent: "percent",
+	percent: "procent",
 	pixels: "pixel",
 	"default": "standard",
 	left: "venstre",
@@ -18,6 +18,7 @@
 	right: "højre",
 	buttonSet: "Definér", // translated elsewhere?
 	buttonInsert: "Indsæt",
+	buttonCancel: "Annullér",
 
 	selectTableLabel: "Markér tabel",
 	insertTableRowBeforeLabel: "Tilføj række før",
diff --git a/dojox/editor/plugins/nls/da/TextColor.js b/dojox/editor/plugins/nls/da/TextColor.js
new file mode 100644
index 0000000..dffe0b2
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Definér",
+	"cancelButtonText": "Annullér"
+})
+
diff --git a/dojox/editor/plugins/nls/da/latinEntities.js b/dojox/editor/plugins/nls/da/latinEntities.js
new file mode 100644
index 0000000..d45abcf
--- /dev/null
+++ b/dojox/editor/plugins/nls/da/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"inverted exclamation mark",
+	cent:"cent sign",
+	pound:"pound sign",
+	curren:"currency sign",
+	yen:"yen sign\nyuan sign",
+	brvbar:"broken bar\nbroken vertical bar",
+	sect:"section sign",
+	uml:"diaeresis\nspacing diaeresis",
+	copy:"copyright sign",
+	ordf:"feminine ordinal indicator",
+	laquo:"left-pointing double angle quotation mark\nleft pointing guillemet",
+	not:"not sign",
+	shy:"soft hyphen\ndiscretionary hyphen",
+	reg:"registered sign\nregistered trade mark sign",
+	macr:"macron\nspacing macron\noverline\nAPL overbar",
+	deg:"degree sign",
+	plusmn:"plus-minus sign\nplus-or-minus sign",
+	sup2:"superscript two\nsuperscript digit two\nsquared",
+	sup3:"superscript three\nsuperscript digit three\ncubed",
+	acute:"acute accent\nspacing acute",
+	micro:"micro sign",
+	para:"pilcrow sign\nparagraph sign",
+	middot:"middle dot\nGeorgian comma\nGreek middle dot",
+	cedil:"cedilla\nspacing cedilla",
+	sup1:"superscript one\nsuperscript digit one",
+	ordm:"masculine ordinal indicator",
+	raquo:"right-pointing double angle quotation mark\nright pointing guillemet",
+	frac14:"vulgar fraction one quarter\nfraction one quarter",
+	frac12:"vulgar fraction one half\nfraction one half",
+	frac34:"vulgar fraction three quarters\nfraction three quarters",
+	iquest:"inverted question mark\nturned question mark",
+	Agrave:"Latin capital letter A with grave\nLatin capital letter A grave",
+	Aacute:"Latin capital letter A with acute",
+	Acirc:"Latin capital letter A with circumflex",
+	Atilde:"Latin capital letter A with tilde",
+	Auml:"Latin capital letter A with diaeresis",
+	Aring:"Latin capital letter A with ring above\nLatin capital letter A ring",
+	AElig:"Latin capital letter AE\nLatin capital ligature AE",
+	Ccedil:"Latin capital letter C with cedilla",
+	Egrave:"Latin capital letter E with grave",
+	Eacute:"Latin capital letter E with acute",
+	Ecirc:"Latin capital letter E with circumflex",
+	Euml:"Latin capital letter E with diaeresis",
+	Igrave:"Latin capital letter I with grave",
+	Iacute:"Latin capital letter I with acute",
+	Icirc:"Latin capital letter I with circumflex",
+	Iuml:"Latin capital letter I with diaeresis",
+	ETH:"Latin capital letter ETH",
+	Ntilde:"Latin capital letter N with tilde",
+	Ograve:"Latin capital letter O with grave",
+	Oacute:"Latin capital letter O with acute",
+	Ocirc:"Latin capital letter O with circumflex",
+	Otilde:"Latin capital letter O with tilde",
+	Ouml:"Latin capital letter O with diaeresis",
+	times:"multiplication sign",
+	Oslash:"Latin capital letter O with stroke\nLatin capital letter O slash",
+	Ugrave:"Latin capital letter U with grave",
+	Uacute:"Latin capital letter U with acute",
+	Ucirc:"Latin capital letter U with circumflex",
+	Uuml:"Latin capital letter U with diaeresis",
+	Yacute:"Latin capital letter Y with acute",
+	THORN:"Latin capital letter THORN",
+	szlig:"Latin small letter sharp s\ness-zed",
+	agrave:"Latin small letter a with grave\nLatin small letter a grave",
+	aacute:"Latin small letter a with acute",
+	acirc:"Latin small letter a with circumflex",
+	atilde:"Latin small letter a with tilde",
+	auml:"Latin small letter a with diaeresis",
+	aring:"Latin small letter a with ring above\nLatin small letter a ring",
+	aelig:"Latin small letter ae\nLatin small ligature ae",
+	ccedil:"Latin small letter c with cedilla",
+	egrave:"Latin small letter e with grave",
+	eacute:"Latin small letter e with acute",
+	ecirc:"Latin small letter e with circumflex",
+	euml:"Latin small letter e with diaeresis",
+	igrave:"Latin small letter i with grave",
+	iacute:"Latin small letter i with acute",
+	icirc:"Latin small letter i with circumflex",
+	iuml:"Latin small letter i with diaeresis",
+	eth:"Latin small letter eth",
+	ntilde:"Latin small letter n with tilde",
+	ograve:"Latin small letter o with grave",
+	oacute:"Latin small letter o with acute",
+	ocirc:"Latin small letter o with circumflex",
+	otilde:"Latin small letter o with tilde",
+	ouml:"Latin small letter o with diaeresis",
+	divide:"division sign",
+	oslash:"Latin small letter o with stroke\nLatin small letter o slash",
+	ugrave:"Latin small letter u with grave",
+	uacute:"Latin small letter u with acute",
+	ucirc:"Latin small letter u with circumflex",
+	uuml:"Latin small letter u with diaeresis",
+	yacute:"Latin small letter y with acute",
+	thorn:"Latin small letter thorn",
+	yuml:"Latin small letter y with diaeresis",
+
+// Greek Characters and Symbols
+	fnof:"Latin small f with hook\nfunction\nflorin",
+	Alpha:"Greek capital letter alpha",
+	Beta:"Greek capital letter beta",
+	Gamma:"Greek capital letter gamma",
+	Delta:"Greek capital letter delta",
+	Epsilon:"Greek capital letter epsilon",
+	Zeta:"Greek capital letter zeta",
+	Eta:"Greek capital letter eta",
+	Theta:"Greek capital letter theta",
+	Iota:"Greek capital letter iota",
+	Kappa:"Greek capital letter kappa",
+	Lambda:"Greek capital letter lambda",
+	Mu:"Greek capital letter mu",
+	Nu:"Greek capital letter nu",
+	Xi:"Greek capital letter xi",
+	Omicron:"Greek capital letter omicron",
+	Pi:"Greek capital letter pi",
+	Rho:"Greek capital letter rho",
+	Sigma:"Greek capital letter sigma",
+	Tau:"Greek capital letter tau",
+	Upsilon:"Greek capital letter upsilon",
+	Phi:"Greek capital letter phi",
+	Chi:"Greek capital letter chi",
+	Psi:"Greek capital letter psi",
+	Omega:"Greek capital letter omega",
+	alpha:"Greek small letter alpha",
+	beta:"Greek small letter beta",
+	gamma:"Greek small letter gamma",
+	delta:"Greek small letter delta",
+	epsilon:"Greek small letter epsilon",
+	zeta:"Greek small letter zeta",
+	eta:"Greek small letter eta",
+	theta:"Greek small letter theta",
+	iota:"Greek small letter iota",
+	kappa:"Greek small letter kappa",
+	lambda:"Greek small letter lambda",
+	mu:"Greek small letter mu",
+	nu:"Greek small letter nu",
+	xi:"Greek small letter xi",
+	omicron:"Greek small letter omicron",
+	pi:"Greek small letter pi",
+	rho:"Greek small letter rho",
+	sigmaf:"Greek small letter final sigma",
+	sigma:"Greek small letter sigma",
+	tau:"Greek small letter tau",
+	upsilon:"Greek small letter upsilon",
+	phi:"Greek small letter phi",
+	chi:"Greek small letter chi",
+	psi:"Greek small letter psi",
+	omega:"Greek small letter omega",
+	thetasym:"Greek small letter theta symbol",
+	upsih:"Greek upsilon with hook symbol",
+	piv:"Greek pi symbol",
+	bull:"bullet\nblack small circle",
+	hellip:"horizontal ellipsis\nthree dot leader",
+	prime:"prime\nminutes\nfeet",
+	Prime:"double prime\nseconds\ninches",
+	oline:"overline\nspacing overscore",
+	frasl:"fraction slash",
+	weierp:"script capital P\npower set\nWeierstrass p",
+	image:"blackletter capital I\nimaginary part",
+	real:"blackletter capital R\nreal part symbol",
+	trade:"trade mark sign",
+	alefsym:"alef symbol\nfirst transfinite cardinal",
+	larr:"leftwards arrow",
+	uarr:"upwards arrow",
+	rarr:"rightwards arrow",
+	darr:"downwards arrow",
+	harr:"left right arrow",
+	crarr:"downwards arrow with corner leftwards\ncarriage return",
+	lArr:"leftwards double arrow",
+	uArr:"upwards double arrow",
+	rArr:"rightwards double arrow",
+	dArr:"downwards double arrow",
+	hArr:"left right double arrow",
+	forall:"for all",
+	part:"partial differential",
+	exist:"there exists",
+	empty:"empty set\nnull set\ndiameter",
+	nabla:"nabla\nbackward difference",
+	isin:"element of",
+	notin:"not an element of",
+	ni:"contains as member",
+	prod:"n-ary product\nproduct sign",
+	sum:"n-ary sumation",
+	minus:"minus sign",
+	lowast:"asterisk operator",
+	radic:"square root\nradical sign",
+	prop:"proportional to",
+	infin:"infinity",
+	ang:"angle",
+	and:"logical and\nwedge",
+	or:"logical or\nvee",
+	cap:"intersection\ncap",
+	cup:"union\ncup","int":"integral",
+	there4:"therefore",
+	sim:"tilde operator\nvaries with\nsimilar to",
+	cong:"approximately equal to",
+	asymp:"almost equal to\nasymptotic to",
+	ne:"not equal to",
+	equiv:"identical to",
+	le:"less-than or equal to",
+	ge:"greater-than or equal to",
+	sub:"subset of",
+	sup:"superset of",
+	nsub:"not a subset of",
+	sube:"subset of or equal to",
+	supe:"superset of or equal to",
+	oplus:"circled plus\ndirect sum",
+	otimes:"circled times\nvector product",
+	perp:"up tack\northogonal to\nperpendicular",
+	sdot:"dot operator",
+	lceil:"left ceiling\nAPL upstile",
+	rceil:"right ceiling",
+	lfloor:"left floor\nAPL downstile",
+	rfloor:"right floor",
+	lang:"left-pointing angle bracket",
+	rang:"right-pointing angle bracket",
+	loz:"lozenge",
+	spades:"black spade suit",
+	clubs:"black club suit\nshamrock",
+	hearts:"black heart suit\nvalentine",
+	diams:"black diamond suit",
+	OElig:"Latin capital ligature OE",
+	oelig:"Latin small ligature oe",
+	Scaron:"Latin capital letter S with caron",
+	scaron:"Latin small letter s with caron",
+	Yuml:"Latin capital letter Y with diaeresis",
+	circ:"modifier letter circumflex accent",
+	tilde:"small tilde",
+	ensp:"en space",
+	emsp:"em space",
+	thinsp:"thin space",
+	zwnj:"zero width non-joiner",
+	zwj:"zero width joiner",
+	lrm:"left-to-right mark",
+	rlm:"right-to-left mark",
+	ndash:"en dash",
+	mdash:"em dash",
+	lsquo:"left single quotation mark",
+	rsquo:"right single quotation mark",
+	sbquo:"single low-9 quotation mark",
+	ldquo:"left double quotation mark",
+	rdquo:"right double quotation mark",
+	bdquo:"double low-9 quotation mark",
+	dagger:"dagger",
+	Dagger:"double dagger",
+	permil:"per mille sign",
+	lsaquo:"single left-pointing angle quotation mark",
+	rsaquo:"single right-pointing angle quotation mark",
+	euro:"euro sign"
+})
+
diff --git a/dojox/editor/plugins/nls/de/AutoSave.js b/dojox/editor/plugins/nls/de/AutoSave.js
new file mode 100644
index 0000000..23a17b1
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Speichern",
+	"saveSettingLabelOn": "Intervall für automatisches Speichern festlegen",
+	"saveSettingLabelOff": "Automatisches Speichern inaktivieren",
+	"saveSettingdialogTitle": "Automatisch speichern",
+	"saveSettingdialogDescription": "Intervall für automatisches Speichern angeben",
+	"saveSettingdialogParamName": "Intervall für automatisches Speichern",
+	"saveSettingdialogParamLabel": "Min.",
+	"saveSettingdialogButtonOk": "Intervall festlegen",
+	"saveSettingdialogButtonCancel": "Abbrechen",
+	"saveMessageSuccess": "Gespeichert um ${0}",
+	"saveMessageFail": "Konnte nicht um ${0} gespeichert werden"
+})
+
diff --git a/dojox/editor/plugins/nls/de/Blockquote.js b/dojox/editor/plugins/nls/de/Blockquote.js
new file mode 100644
index 0000000..45e3ff8
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockzitat"
+})
+
diff --git a/dojox/editor/plugins/nls/de/CollapsibleToolbar.js b/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
new file mode 100644
index 0000000..a9fcbf4
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Editor-Symbolleiste ausblenden",
+	"expand": "Editor-Symbolleiste einblenden"
+})
+
diff --git a/dojox/editor/plugins/nls/de/FindReplace.js b/dojox/editor/plugins/nls/de/FindReplace.js
index a7e2d25..982b3cf 100644
--- a/dojox/editor/plugins/nls/de/FindReplace.js
+++ b/dojox/editor/plugins/nls/de/FindReplace.js
@@ -1,12 +1,23 @@
 ({
 	"findLabel": "Suchbegriff:",
+	"findTooltip": "Text zum Suchen eingeben",
 	"replaceLabel": "Ersetzen durch:",
+	"replaceTooltip": "Text zum Ersetzen eingeben",
 	"findReplace": "Suchen/Ersetzen",
-	"matchCase": "Groß- und Kleinschreibung abgleichen", 
+	"matchCase": "Groß- und Kleinschreibung abgleichen",
+	"matchCaseTooltip": "Groß- und Kleinschreibung abgleichen",
 	"backwards": "Zurück",
-	"replaceAll": "Alle Vorkommen", 
+	"backwardsTooltip": "Rückwärts nach Text suchen",
+	"replaceAll": "Alle Vorkommen",
+	"replaceAllButton": "Global ersetzen",
+	"replaceAllButtonTooltip": "Gesamten Text ersetzen",
 	"findButton": "Suchen",
+	"findButtonTooltip": "Text suchen",
 	"replaceButton": "Ersetzen",
-	"replaceDialogText": "Es wurden ${0} Vorkommen ersetzt."
+	"replaceButtonTooltip": "Text ersetzen",
+	"replaceDialogText": "Es wurden ${0} Vorkommen ersetzt.",
+	"eofDialogText": "Letztes Vorkommen ${0}",
+	"eofDialogTextFind": "gefunden",
+	"eofDialogTextReplace": "ersetzt"
 })
 
diff --git a/dojox/editor/plugins/nls/de/InsertAnchor.js b/dojox/editor/plugins/nls/de/InsertAnchor.js
new file mode 100644
index 0000000..748fd9c
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Anker einfügen",
+	title: "Eigenschaften des Ankers",
+	anchor: "Name:",
+	text: "Beschreibung:",
+	set: "Festlegen",
+	cancel: "Abbrechen"
+})
+
diff --git a/dojox/editor/plugins/nls/de/LocalImage.js b/dojox/editor/plugins/nls/de/LocalImage.js
new file mode 100644
index 0000000..faa1699
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Grafik einfügen",
+	url: "Grafik",
+	browse: "Durchsuchen...",
+	text: "Beschreibung",
+	set: "Einfügen",
+	invalidMessage: "Ungültiger Grafikdateityp",
+	prePopuTextUrl: "Geben Sie eine gültige Grafik-URL ein",
+	prePopuTextBrowse: "oder blättern Sie zu einer lokalen Datei."
+})
+
diff --git a/dojox/editor/plugins/nls/de/PasteFromWord.js b/dojox/editor/plugins/nls/de/PasteFromWord.js
new file mode 100644
index 0000000..3be00e6
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Aus Word einfügen",
+	"paste": "Einfügen",
+	"cancel": "Abbrechen",
+	"instructions": "Fügt den Inhalt aus Word in das Textfeld unten ein. Wenn Sie mit dem einzufügenden Inhalt zufrieden sind, klicken Sie auf die Schaltfläche zum Einfügen. Um das Einfügen von Text abzubrechen, klicken Sie auf die Schaltfläche zum Abbrechen. "
+})
+
diff --git a/dojox/editor/plugins/nls/de/Smiley.js b/dojox/editor/plugins/nls/de/Smiley.js
index 116f402..dbc5ca3 100644
--- a/dojox/editor/plugins/nls/de/Smiley.js
+++ b/dojox/editor/plugins/nls/de/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "Augenzwinkern",
 	emoticonGrin: "Grinsen",
 	emoticonCool: "Cool",
-	emoticonAngry: "Zornig",  
-	emoticonHalf: "Halb", 
+	emoticonAngry: "Zornig",
+	emoticonHalf: "Halb",
 	emoticonEyebrow: "Hochgezogene Augenbraue",
 	emoticonFrown: "Stirnrunzeln",
 	emoticonShy: "Schüchtern",
@@ -15,7 +15,7 @@
 	emoticonTongue: "Zunge",
 	emoticonIdea: "Idee",
 	emoticonYes: "Ja",
-	emoticonNo: "Nein",	
+	emoticonNo: "Nein",
 	emoticonAngel: "Engel",
 	emoticonCrying: "Weinen"
 })
diff --git a/dojox/editor/plugins/nls/de/SpellCheck.js b/dojox/editor/plugins/nls/de/SpellCheck.js
new file mode 100644
index 0000000..4861e14
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Batchrechtschreibprüfung",
+	unfound: "Nicht gefunden",
+	skip: "Überspringen",
+	skipAll: "Alle überspringen",
+	toDic: "Zum Wörterbuch hinzufügen",
+	suggestions: "Vorschläge",
+	replace: "Ersetzen",
+	replaceWith: "Ersetzen durch",
+	replaceAll: "Global ersetzen",
+	cancel: "Abbrechen",
+	msg: "Keine Rechtschreibfehler gefunden",
+	iSkip: "Diesen Fund überspringen",
+	iSkipAll: "Alle entsprechenden Funde überspringen",
+	iMsg: "Keine Rechtschreibvorschläge"
+})
+
diff --git a/dojox/editor/plugins/nls/de/TableDialog.js b/dojox/editor/plugins/nls/de/TableDialog.js
index a3cb555..d918793 100644
--- a/dojox/editor/plugins/nls/de/TableDialog.js
+++ b/dojox/editor/plugins/nls/de/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "Rechts",
 	buttonSet: "Festlegen", // translated elsewhere?
 	buttonInsert: "Einfügen",
+	buttonCancel: "Abbrechen",
 
 	selectTableLabel: "Tabelle auswählen",
 	insertTableRowBeforeLabel: "Zeile oberhalb einfügen",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "Zeile löschen",
 	deleteTableColumnLabel: "Spalte löschen"
 })
-
diff --git a/dojox/editor/plugins/nls/de/TextColor.js b/dojox/editor/plugins/nls/de/TextColor.js
new file mode 100644
index 0000000..b7d53cc
--- /dev/null
+++ b/dojox/editor/plugins/nls/de/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Festlegen",
+	"cancelButtonText": "Abbrechen"
+})
+
diff --git a/dojox/editor/plugins/nls/el/AutoSave.js b/dojox/editor/plugins/nls/el/AutoSave.js
new file mode 100644
index 0000000..0b4edd9
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Αποθήκευση",
+	"saveSettingLabelOn": "Ορισμός διαστήματος αυτόματης αποθήκευσης...",
+	"saveSettingLabelOff": "Απενεργοποίηση αυτόματης αποθήκευσης",
+	"saveSettingdialogTitle": "Αυτόματη αποθήκευση",
+	"saveSettingdialogDescription": "Ορισμός διαστήματος αυτόματης αποθήκευσης",
+	"saveSettingdialogParamName": "Διάστημα αυτόματης αποθήκευσης",
+	"saveSettingdialogParamLabel": "λεπτά",
+	"saveSettingdialogButtonOk": "Ορισμός διαστήματος",
+	"saveSettingdialogButtonCancel": "Ακύρωση",
+	"saveMessageSuccess": "Αποθηκεύτηκε στις ${0}",
+	"saveMessageFail": "Απέτυχε η αποθήκευση στις ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/el/Blockquote.js b/dojox/editor/plugins/nls/el/Blockquote.js
new file mode 100644
index 0000000..32046f0
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Ενότητα παράθεσης"
+})
+
diff --git a/dojox/editor/plugins/nls/el/Breadcrumb.js b/dojox/editor/plugins/nls/el/Breadcrumb.js
new file mode 100644
index 0000000..a3c915d
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} - Ενέργειες",
+	"selectContents": "Επιλογή περιεχομένων",
+	"selectElement": "Επιλογή στοιχείου",
+	"deleteElement": "Διαγραφή στοιχείου",
+	"deleteContents": "Διαγραφή περιεχομένων",
+	"moveStart": "Μετακίνηση δρομέα στην αρχή",
+	"moveEnd": "Μετακίνηση δρομέα στο τέλος"
+})
+
diff --git a/dojox/editor/plugins/nls/el/CollapsibleToolbar.js b/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
new file mode 100644
index 0000000..d7bc087
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Σύμπτυξη γραμμής εργαλείων λειτουργίας επεξεργασίας",
+	"expand": "Ανάπτυξη γραμμής εργαλείων λειτουργίας επεξεργασίας"
+})
+
diff --git a/dojox/editor/plugins/nls/el/FindReplace.js b/dojox/editor/plugins/nls/el/FindReplace.js
new file mode 100644
index 0000000..021a38a
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Εύρεση:",
+	"findTooltip": "Καταχωρήστε το κείμενο που θέλετε να εντοπίσετε",
+	"replaceLabel": "Αντικατάσταση με:",
+	"replaceTooltip": "Καταχωρήστε το κείμενο με το οποίο θέλετε να αντικαταστήσετε το αναζητούμενο κείμενο",
+	"findReplace": "Εύρεση και αντικατάσταση",
+	"matchCase": "Διάκριση πεζών/κεφαλαίων",
+	"matchCaseTooltip": "Διάκριση πεζών/κεφαλαίων",
+	"backwards": "Προς τα πίσω",
+	"backwardsTooltip": "Αναζήτηση κειμένου προς τα πίσω",
+	"replaceAll": "Όλες οι εμφανίσεις",
+	"replaceAllButton": "Αντικατάσταση όλων",
+	"replaceAllButtonTooltip": "Αντικατάσταση όλου του κειμένου",
+	"findButton": "Εύρεση",
+	"findButtonTooltip": "Εύρεση του κειμένου",
+	"replaceButton": "Αντικατάσταση",
+	"replaceButtonTooltip": "Αντικατάσταση του κειμένου",
+	"replaceDialogText": "Αντικαταστάθηκαν ${0} εμφανίσεις.",
+	"eofDialogText": "Τελευταία εμφάνιση: ${0}",
+	"eofDialogTextFind": "εντοπίστηκε",
+	"eofDialogTextReplace": "αντικαταστάθηκε"
+})
+
diff --git a/dojox/editor/plugins/nls/el/InsertAnchor.js b/dojox/editor/plugins/nls/el/InsertAnchor.js
new file mode 100644
index 0000000..eb188bb
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Εισαγωγή αγκίστρωσης",
+	title: "Ιδιότητες αγκίστρωσης",
+	anchor: "Όνομα:",
+	text: "Περιγραφή:",
+	set: "Ορισμός",
+	cancel: "Ακύρωση"
+})
+
diff --git a/dojox/editor/plugins/nls/el/InsertEntity.js b/dojox/editor/plugins/nls/el/InsertEntity.js
new file mode 100644
index 0000000..e01c1d1
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Εισαγωγή συμβόλου"
+})
+
diff --git a/dojox/editor/plugins/nls/el/LocalImage.js b/dojox/editor/plugins/nls/el/LocalImage.js
new file mode 100644
index 0000000..810eb11
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Εισαγωγή εικόνας",
+	url: "Εικόνα",
+	browse: "Αναζήτηση...",
+	text: "Περιγραφή",
+	set: "Εισαγωγή",
+	invalidMessage: "Μη έγκυρο είδος αρχείου εικόνας",
+	prePopuTextUrl: "Καταχωρήστε τη διεύθυνση URL μιας εικόνας",
+	prePopuTextBrowse: " ή επιλέξτε ένα τοπικό αρχείο."
+})
+
diff --git a/dojox/editor/plugins/nls/el/PageBreak.js b/dojox/editor/plugins/nls/el/PageBreak.js
new file mode 100644
index 0000000..9f012bc
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Αλλαγή σελίδας"
+})
+
diff --git a/dojox/editor/plugins/nls/el/PasteFromWord.js b/dojox/editor/plugins/nls/el/PasteFromWord.js
new file mode 100644
index 0000000..c784559
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Επικόλληση από το Word",
+	"paste": "Επικόλληση",
+	"cancel": "Ακύρωση",
+	"instructions": "Επικολλήστε το περιεχόμενο από το Word στο παρακάτω πλαίσιο. Όταν το κείμενο για εισαγωγή είναι σωστό, πατήστε το κουμπί Επικόλληση. Για να ακυρώσετε την εισαγωγή κειμένου, πατήστε το κουμπί Ακύρωση."
+})
+
diff --git a/dojox/editor/plugins/nls/el/Preview.js b/dojox/editor/plugins/nls/el/Preview.js
new file mode 100644
index 0000000..bcb0872
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Προεπισκόπηση"
+})
+
diff --git a/dojox/editor/plugins/nls/el/Save.js b/dojox/editor/plugins/nls/el/Save.js
new file mode 100644
index 0000000..e7f42b5
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Αποθήκευση"
+})
+
diff --git a/dojox/editor/plugins/nls/el/ShowBlockNodes.js b/dojox/editor/plugins/nls/el/ShowBlockNodes.js
new file mode 100644
index 0000000..115537a
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Εμφάνιση στοιχείων ενότητας HTML"
+})
+
diff --git a/dojox/editor/plugins/nls/el/Smiley.js b/dojox/editor/plugins/nls/el/Smiley.js
new file mode 100644
index 0000000..55547fb
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Εισαγωγή εικονιδίου συναισθήματος",
+	emoticonSmile: "Χαμόγελο",
+	emoticonLaughing: "Γέλιο",
+	emoticonWink: "Κλείσιμο ματιού",
+	emoticonGrin: "Πλατύ χαμόγελο",
+	emoticonCool: "Άνετος",
+	emoticonAngry: "Θυμωμένος",
+	emoticonHalf: "Μισό",
+	emoticonEyebrow: "Σηκωμένο φρύδι",
+	emoticonFrown: "Συνοφρυωμένος",
+	emoticonShy: "Ντροπαλός",
+	emoticonGoofy: "Χαζόφατσα",
+	emoticonOops: "Έκπληξη",
+	emoticonTongue: "Κοροϊδία",
+	emoticonIdea: "Ιδέα",
+	emoticonYes: "Ναι",
+	emoticonNo: "Όχι",
+	emoticonAngel: "Αγγελούδι",
+	emoticonCrying: "Κλάμα"
+})
+
diff --git a/dojox/editor/plugins/nls/el/SpellCheck.js b/dojox/editor/plugins/nls/el/SpellCheck.js
new file mode 100644
index 0000000..ea629a8
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Συνολικός ορθογραφικός έλεγχος",
+	unfound: "Δεν εντοπίστηκε",
+	skip: "Παράλειψη",
+	skipAll: "Παράλειψη όλων",
+	toDic: "Προσθήκη στο λεξικό",
+	suggestions: "Προτάσεις",
+	replace: "Αντικατάσταση",
+	replaceWith: "Αντικατάσταση με",
+	replaceAll: "Αντικατάσταση όλων",
+	cancel: "Ακύρωση",
+	msg: "Δεν βρέθηκαν ορθογραφικά λάθη",
+	iSkip: "Παράλειψη τρέχοντος",
+	iSkipAll: "Παράλειψη όλων των όμοιων",
+	iMsg: "Δεν υπάρχουν προτάσεις ορθογραφίας"
+})
+
diff --git a/dojox/editor/plugins/nls/el/TableDialog.js b/dojox/editor/plugins/nls/el/TableDialog.js
index 802ad47..c6a9a4c 100644
--- a/dojox/editor/plugins/nls/el/TableDialog.js
+++ b/dojox/editor/plugins/nls/el/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "δεξιά",
 	buttonSet: "Ορισμός", // translated elsewhere?
 	buttonInsert: "Εισαγωγή",
+	buttonCancel: "Ακύρωση",
 
 	selectTableLabel: "Επιλογή πίνακα",
 	insertTableRowBeforeLabel: "Προσθήκη γραμμής πριν",
diff --git a/dojox/editor/plugins/nls/el/TextColor.js b/dojox/editor/plugins/nls/el/TextColor.js
new file mode 100644
index 0000000..f6f3b17
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Ορισμός",
+	"cancelButtonText": "Ακύρωση"
+})
+
diff --git a/dojox/editor/plugins/nls/el/latinEntities.js b/dojox/editor/plugins/nls/el/latinEntities.js
new file mode 100644
index 0000000..ed8b58c
--- /dev/null
+++ b/dojox/editor/plugins/nls/el/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* These are already handled in the default RTE
+		amp:"ampersand",lt:"less-than sign",
+		gt:"greater-than sign",
+		nbsp:"no-break space\nnon-breaking space",
+		quot:"quote",
+	*/
+	iexcl:"Αντεστραμμένο θαυμαστικό",
+	cent:"Σύμβολο λεπτού δολαρίου (σεντ)",
+	pound:"Σύμβολο λίρας",
+	curren:"Σύμβολο νομίσματος",
+	yen:"Σύμβολο γιεν\Σύμβολο γιουάν",
+	brvbar:"Διακεκομμένη κάθετος",
+	sect:"Σύμβολο εδαφίου/παραγράφου",
+	uml:"Διαλυτικά",
+	copy:"Σύμβολο copyright",
+	ordf:"Δείκτης τακτικού αριθμητικού θηλυκού γένους",
+	laquo:"Αριστερά ελληνικά εισαγωγικά",
+	not:"Σύμβολο 'δεν είναι'",
+	shy:"Προαιρετικό ενωτικό",
+	reg:"Σύμβολο σήματος κατατεθέντος",
+	macr:"Σύμβολο μακρού",
+	deg:"Σύμβολο βαθμού/μοίρας",
+	plusmn:"Σύμβολο συν-πλην",
+	sup2:"Εκθέτης 2",
+	sup3:"Εκθέτης 3",
+	acute:"Οξεία",
+	micro:"Σύμβολο 'μίκρο'",
+	para:"Σύμβολο παραγράφου",
+	middot:"Τελεία διαχωρισμού\nΕλληνική άνω τελεία",
+	cedil:"Σημείο υπόστιξης",
+	sup1:"Εκθέτης 1",
+	ordm:"Δείκτης τακτικού αριθμητικού αρσενικού γένους",
+	raquo:"Δεξιά ελληνικά εισαγωγικά",
+	frac14:"Κλάσμα ενός τετάρτου",
+	frac12:"Κλάσμα ενός δευτέρου",
+	frac34:"Κλάσμα τριών τετάρτων",
+	iquest:"Αντεστραμμένο λατινικό ερωτηματικό",
+	Agrave:"Κεφαλαίο λατινικό γράμμα Α με βαρεία",
+	Aacute:"Κεφαλαίο λατινικό γράμμα Α με οξεία",
+	Acirc:"Κεφαλαίο λατινικό γράμμα Α με περισπωμένη circumflex",
+	Atilde:"Κεφαλαίο λατινικό γράμμα Α με περισπωμένη tilde",
+	Auml:"Κεφαλαίο λατινικό γράμμα Α με διαλυτικά",
+	Aring:"Κεφαλαίο λατινικό γράμμα Α με δακτύλιο",
+	AElig:"Κεφαλαίο λατινικό δίψηφο AE",
+	Ccedil:"Κεφαλαίο λατινικό γράμμα C με υπόστιξη",
+	Egrave:"Κεφαλαίο λατινικό γράμμα E με βαρεία",
+	Eacute:"Κεφαλαίο λατινικό γράμμα E με οξεία",
+	Ecirc:"Κεφαλαίο λατινικό γράμμα E με περισπωμένη circumflex",
+	Euml:"Κεφαλαίο λατινικό γράμμα E με διαλυτικά",
+	Igrave:"Κεφαλαίο λατινικό γράμμα I με βαρεία",
+	Iacute:"Κεφαλαίο λατινικό γράμμα I με οξεία",
+	Icirc:"Κεφαλαίο λατινικό γράμμα I με περισπωμένη circumflex",
+	Iuml:"Κεφαλαίο λατινικό γράμμα I με διαλυτικά",
+	ETH:"Κεφαλαίο λατινικό γράμμα ETH",
+	Ntilde:"Κεφαλαίο λατινικό γράμμα N με περισπωμένη tilde",
+	Ograve:"Κεφαλαίο λατινικό γράμμα O με βαρεία",
+	Oacute:"Κεφαλαίο λατινικό γράμμα O με οξεία",
+	Ocirc:"Κεφαλαίο λατινικό γράμμα O με περισπωμένη circumflex",
+	Otilde:"Κεφαλαίο λατινικό γράμμα O με περισπωμένη tilde",
+	Ouml:"Κεφαλαίο λατινικό γράμμα O με διαλυτικά",
+	times:"Σύμβολο πολλαπλασιασμού",
+	Oslash:"Κεφαλαίο λατινικό γράμμα O με κάθετο",
+	Ugrave:"Κεφαλαίο λατινικό γράμμα U με βαρεία",
+	Uacute:"Κεφαλαίο λατινικό γράμμα U με οξεία",
+	Ucirc:"Κεφαλαίο λατινικό γράμμα U με περισπωμένη circumflex",
+	Uuml:"Κεφαλαίο λατινικό γράμμα U με διαλυτικά",
+	Yacute:"Κεφαλαίο λατινικό γράμμα Y με οξεία",
+	THORN:"Κεφαλαίο λατινικό γράμμα THORN",
+	szlig:"Πεζό λατινικό γράμμα ες-τσετ",
+	agrave:"Πεζό λατινικό γράμμα a με βαρεία",
+	aacute:"Πεζό λατινικό γράμμα a με οξεία",
+	acirc:"Πεζό λατινικό γράμμα a με περισπωμένη circumflex",
+	atilde:"Πεζό λατινικό γράμμα a με περισπωμένη tilde",
+	auml:"Πεζό λατινικό γράμμα a με διαλυτικά",
+	aring:"Πεζό λατινικό γράμμα a με δακτύλιο",
+	aelig:"Πεζό λατινικό δίψηφο ae",
+	ccedil:"Πεζό λατινικό γράμμα c με υπόστιξη",
+	egrave:"Πεζό λατινικό γράμμα e με βαρεία",
+	eacute:"Πεζό λατινικό γράμμα e με οξεία",
+	ecirc:"Πεζό λατινικό γράμμα e με περισπωμένη circumflex",
+	euml:"Πεζό λατινικό γράμμα e με διαλυτικά",
+	igrave:"Πεζό λατινικό γράμμα i με βαρεία",
+	iacute:"Πεζό λατινικό γράμμα i με οξεία",
+	icirc:"Πεζό λατινικό γράμμα i με περισπωμένη circumflex",
+	iuml:"Πεζό λατινικό γράμμα i με διαλυτικά",
+	eth:"Πεζό λατινικό γράμμα eth",
+	ntilde:"Πεζό λατινικό γράμμα n με περισπωμένη tilde",
+	ograve:"Πεζό λατινικό γράμμα o με βαρεία",
+	oacute:"Πεζό λατινικό γράμμα o με οξεία",
+	ocirc:"Πεζό λατινικό γράμμα o με περισπωμένη circumflex",
+	otilde:"Πεζό λατινικό γράμμα o με περισπωμένη tilde",
+	ouml:"Πεζό λατινικό γράμμα o με διακριτικά",
+	divide:"Σύμβολο διαίρεσης",
+	oslash:"Πεζό λατινικό γράμμα o με κάθετο",
+	ugrave:"Πεζό λατινικό γράμμα u με βαρεία",
+	uacute:"Πεζό λατινικό γράμμα u με οξεία",
+	ucirc:"Πεζό λατινικό γράμμα u με περισπωμένη circumflex",
+	uuml:"Πεζό λατινικό γράμμα u με διαλυτικά",
+	yacute:"Πεζό λατινικό γράμμα y με οξεία",
+	thorn:"Πεζό λατινικό γράμμα thorn",
+	yuml:"Πεζό λατινικό γράμμα y με διαλυτικά",
+
+// Greek Characters and Symbols
+	fnof:"Πεζό λατινικό γράμμα f με άγκιστρο\nΣύμβολο συνάρτησης",
+	Alpha:"Κεφαλαίο ελληνικό γράμμα Α",
+	Beta:"Κεφαλαίο ελληνικό γράμμα Β",
+	Gamma:"Κεφαλαίο ελληνικό γράμμα Γ",
+	Delta:"Κεφαλαίο ελληνικό γράμμα Δ",
+	Epsilon:"Κεφαλαίο ελληνικό γράμμα Ε",
+	Zeta:"Κεφαλαίο ελληνικό γράμμα Ζ",
+	Eta:"Κεφαλαίο ελληνικό γράμμα Η",
+	Theta:"Κεφαλαίο ελληνικό γράμμα Θ",
+	Iota:"Κεφαλαίο ελληνικό γράμμα Ι",
+	Kappa:"Κεφαλαίο ελληνικό γράμμα Κ",
+	Lambda:"Κεφαλαίο ελληνικό γράμμα Λ",
+	Mu:"Κεφαλαίο ελληνικό γράμμα Μ",
+	Nu:"Κεφαλαίο ελληνικό γράμμα Ν",
+	Xi:"Κεφαλαίο ελληνικό γράμμα Ξ",
+	Omicron:"Κεφαλαίο ελληνικό γράμμα Ο",
+	Pi:"Κεφαλαίο ελληνικό γράμμα Π",
+	Rho:"Κεφαλαίο ελληνικό γράμμα Ρ",
+	Sigma:"Κεφαλαίο ελληνικό γράμμα Σ",
+	Tau:"Κεφαλαίο ελληνικό γράμμα Τ",
+	Upsilon:"Κεφαλαίο ελληνικό γράμμα Υ",
+	Phi:"Κεφαλαίο ελληνικό γράμμα Φ",
+	Chi:"Κεφαλαίο ελληνικό γράμμα Χ",
+	Psi:"Κεφαλαίο ελληνικό γράμμα Ψ",
+	Omega:"Κεφαλαίο ελληνικό γράμμα Ω",
+	alpha:"Πεζό ελληνικό γράμμα α",
+	beta:"Πεζό ελληνικό γράμμα β",
+	gamma:"Πεζό ελληνικό γράμμα γ",
+	delta:"Πεζό ελληνικό γράμμα δ",
+	epsilon:"Πεζό ελληνικό γράμμα ε",
+	zeta:"Πεζό ελληνικό γράμμα ζ",
+	eta:"Πεζό ελληνικό γράμμα η",
+	theta:"Πεζό ελληνικό γράμμα θ",
+	iota:"Πεζό ελληνικό γράμμα ι",
+	kappa:"Πεζό ελληνικό γράμμα κ",
+	lambda:"Πεζό ελληνικό γράμμα λ",
+	mu:"Πεζό ελληνικό γράμμα μ",
+	nu:"Πεζό ελληνικό γράμμα ν",
+	xi:"Πεζό ελληνικό γράμμα ξ",
+	omicron:"Πεζό ελληνικό γράμμα ο",
+	pi:"Πεζό ελληνικό γράμμα π",
+	rho:"Πεζό ελληνικό γράμμα ρ",
+	sigmaf:"Πεζό ελληνικό γράμμα ς",
+	sigma:"Πεζό ελληνικό γράμμα σ",
+	tau:"Πεζό ελληνικό γράμμα τ",
+	upsilon:"Πεζό ελληνικό γράμμα υ",
+	phi:"Πεζό ελληνικό γράμμα φ",
+	chi:"Πεζό ελληνικό γράμμα χ",
+	psi:"Πεζό ελληνικό γράμμα ψ",
+	omega:"Πεζό ελληνικό γράμμα ω",
+	thetasym:"Σύμβολο θ (Πεζό ελληνικό γράμμα θήτα)",
+	upsih:"Σύμβολο Υ (Ελληνικό γράμμα ύψιλον με άγκριστρο)",
+	piv:"Σύμβολο π (Ελληνικό γράμμα πι)",
+	bull:"Κουκίδα\nΜικρός μαύρος κύκλος",
+	hellip:"Αποσιωπητικά\nΟριζόντια έλλειψη",
+	prime:"Τόνος\nΛεπτά\nΠόδια",
+	Prime:"Διπλός τόνος\nΔευτερόλεπτα\nΊντσες",
+	oline:"Άνω γραμμή",
+	frasl:"Κάθετος κλάσματος",
+	weierp:"Καλλιγραφικό κεφαλαίο P\nΔυναμοσύνολο\np-συνάρτηση του Weierstrass",
+	image:"Κεφαλαίο I γοτθικού στυλ (black-letter)\nΣύμβολο φανταστικού μέρους",
+	real:"Κεφαλαίο R γοτθικού στυλ (black-letter)\nΣύμβολο πραγματικού μέρους",
+	trade:"Σύμβολο εμπορικού σήματος",
+	alefsym:"Σύμβολο αλέφ (alef)\nΠρώτος υπερπεπερασμένος αριθμός",
+	larr:"Βέλος προς τα αριστερά",
+	uarr:"Βέλος προς τα πάνω",
+	rarr:"Βέλος προς τα δεξιά",
+	darr:"Βέλος προς τα κάτω",
+	harr:"Βέλος δύο κατευθύνσεων (αριστερά και δεξιά)",
+	crarr:"Βέλος προς τα κάτω με γωνία προς τα αριστερά",
+	lArr:"Διπλό βέλος προς τα αριστερά",
+	uArr:"Διπλό βέλος προς τα πάνω",
+	rArr:"Διπλό βέλος προς τα δεξιά",
+	dArr:"Διπλό βέλος προς τα κάτω",
+	hArr:"Διπλό βέλος δύο κατευθύνσεων (αριστερά και δεξιά)",
+	forall:"Σύμβολο 'για κάθε'",
+	part:"Σύμβολο μερικού διαφορικού",
+	exist:"Σύμβολο 'υπάρχει'",
+	empty:"Κενό σύνολο\nΣύνολο null\nΔιάμετρος",
+	nabla:"Ανάδελτα\nΤελεστής nabla",
+	isin:"Σύμβολο 'ανήκει'",
+	notin:"Σύμβολο 'δεν ανήκει'",
+	ni:"Σύμβολο 'περιλαμβάνει ως μέλος'",
+	prod:"Γινόμενο",
+	sum:"Άθροισμα",
+	minus:"Σύμβολο πλην",
+	lowast:"Αστερίσκος",
+	radic:"Τετραγωνική ρίζα",
+	prop:"Σύμβολο αναλογίας",
+	infin:"Άπειρο",
+	ang:"Γωνία",
+	and:"Λογικό ΚΑΙ (AND)",
+	or:"Λογικό Ή (OR)",
+	cap:"Τομή",
+	cup:"Ένωση","int":"Ολοκλήρωμα",
+	there4:"Σύμβολο 'συνεπώς'",
+	sim:"Σύμβολο σχέσεως ισοδυναμίας",
+	cong:"Περίπου ίσο με",
+	asymp:"Σχεδόν ίσο με",
+	ne:"Όχι ίσο με",
+	equiv:"Ταυτόσημο με",
+	le:"Μικρότερο από ή ίσο με",
+	ge:"Μεγαλύτερο από ή ίσο με",
+	sub:"Υποσύνολο του",
+	sup:"Υπερσύνολο του",
+	nsub:"Σύμβολο 'δεν είναι υποσύνολο του'",
+	sube:"Υποσύνολο του ή ίσο με",
+	supe:"Υπερσύνολο του ή ίσο με",
+	oplus:"Κυκλωμένο συν\nΆμεσο άθροισμα",
+	otimes:"Κυκλωμένο επί\nΔιανυσματικό γινόμενο",
+	perp:"Ορθογώνιο προς\nΚάθετο",
+	sdot:"Τελεστής κουκίδας",
+	lceil:"Αριστερή οροφή",
+	rceil:"Δεξιά οροφή",
+	lfloor:"Αριστερό δάπεδο",
+	rfloor:"Δεξιό δάπεδο",
+	lang:"Αριστερή γωνιακή παρένθεση",
+	rang:"Δεξιά γωνιακή παρένθεση",
+	loz:"Ρόμβος",
+	spades:"Μπαστούνι μαύρο",
+	clubs:"Σπαθί μαύρο",
+	hearts:"Κούπα (μαύρο χρώμα)",
+	diams:"Καρό (μαύρο χρώμα)",
+	OElig:"Κεφαλαίο λατινικό δίψηφο OE",
+	oelig:"Πεζό λατινικό δίψηφο oe",
+	Scaron:"Κεφαλαίο λατινικό γράμμα S με caron",
+	scaron:"Πεζό λατινικό γράμμα s με caron",
+	Yuml:"Κεφαλαίο λατινικό γράμμα Y με διαλυτικά",
+	circ:"Περισπωμένη circumflex (τροποποιητικό γράμματος)",
+	tilde:"Μικρή περισπωμένη",
+	ensp:"Κενό διάστημα πλάτους παύλας",
+	emsp:"Κενό διάστημα πλάτους διπλής παύλας",
+	thinsp:"Λεπτό κενό διάστημα",
+	zwnj:"Διαχωριστικό μηδενικού πλάτους",
+	zwj:"Ενωτικό μηδενικού πλάτους",
+	lrm:"Σημείο ένδειξης κατεύθυνσης από τα αριστερά προς τα δεξιά",
+	rlm:"Σημείο ένδειξης κατεύθυνσης από τα δεξιά προς τα αριστερά",
+	ndash:"Παύλα",
+	mdash:"Μεγάλη παύλα",
+	lsquo:"Αριστερό μονό εισαγωγικό",
+	rsquo:"Δεξιό μονό εισαγωγικό",
+	sbquo:"Μονό κάτω εισαγωγικό (σχήματος 9)",
+	ldquo:"Αριστερό διπλό εισαγωγικό",
+	rdquo:"Δεξιό διπλό εισαγωγικό",
+	bdquo:"Διπλό κάτω εισαγωγικό (σχήματος 9)",
+	dagger:"Σταυρός",
+	Dagger:"Διπλός σταυρός",
+	permil:"Σύμβολο 'τοις χιλίοις'",
+	lsaquo:"Αριστερό μονό ελληνικό εισαγωγικό",
+	rsaquo:"Δεξιό μονό ελληνικό εισαγωγικό",
+	euro:"Σύμβολο ευρώ"
+})
+
diff --git a/dojox/editor/plugins/nls/es/AutoSave.js b/dojox/editor/plugins/nls/es/AutoSave.js
new file mode 100644
index 0000000..324a35a
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Guardar",
+	"saveSettingLabelOn": "Definir intervalo de guardado automático...",
+	"saveSettingLabelOff": "Desactivar guardado automático",
+	"saveSettingdialogTitle": "Guardado automático",
+	"saveSettingdialogDescription": "Especificar intervalo de guardado automático",
+	"saveSettingdialogParamName": "Intervalo de guardado automático",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Definir intervalo",
+	"saveSettingdialogButtonCancel": "Cancelar",
+	"saveMessageSuccess": "Guardado a las ${0}",
+	"saveMessageFail": "No se ha podido guardar a las ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/es/Blockquote.js b/dojox/editor/plugins/nls/es/Blockquote.js
new file mode 100644
index 0000000..9a4fb1a
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Cita en bloque"
+})
+
diff --git a/dojox/editor/plugins/nls/es/CollapsibleToolbar.js b/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
new file mode 100644
index 0000000..0581505
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Contraer barra de herramientas del editor",
+	"expand": "Expandir barra de herramientas del editor"
+})
+
diff --git a/dojox/editor/plugins/nls/es/FindReplace.js b/dojox/editor/plugins/nls/es/FindReplace.js
index 3362263..0bd0c39 100644
--- a/dojox/editor/plugins/nls/es/FindReplace.js
+++ b/dojox/editor/plugins/nls/es/FindReplace.js
@@ -1,12 +1,22 @@
 ({
 	"findLabel": "Buscar:",
+	"findTooltip": "Especifique el texto que desee buscar",
 	"replaceLabel": "Sustituir por:",
+	"replaceTooltip": "Especifique el texto por el que se debe sustituir",
 	"findReplace": "Conmutar Buscar/Sustituir",
-	"matchCase": "Coincidir mayúsculas y minúsculas", 
+	"matchCase": "Coincidir mayúsculas y minúsculas",
+	"matchCaseTooltip": "Coincidir mayúsculas y minúsculas",
 	"backwards": "Hacia atrás",
-	"replaceAll": "Todas las apariciones", 
+	"backwardsTooltip": "Buscar texto hacia atrás",
+	"replaceAll": "Todas las apariciones",
+	"replaceAllButton": "Sustituir todo",
+	"replaceAllButtonTooltip": "Sustituir todo el texto",
 	"findButton": "Buscar",
+	"findButtonTooltip": "Buscar el texto",
 	"replaceButton": "Sustituir",
-	"replaceDialogText": "Se han sustituido ${0} apariciones."
+	"replaceButtonTooltip": "Sustituir el texto",
+	"replaceDialogText": "Se han sustituido ${0} apariciones.",
+	"eofDialogText": "Última aparición ${0}",
+	"eofDialogTextFind": "encontrado",
+	"eofDialogTextReplace": "sustituido"
 })
-
diff --git a/dojox/editor/plugins/nls/es/InsertAnchor.js b/dojox/editor/plugins/nls/es/InsertAnchor.js
new file mode 100644
index 0000000..65841f4
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Insertar ancla",
+	title: "Propiedades del ancla",
+	anchor: "Nombre:",
+	text: "Descripción:",
+	set: "Establecer",
+	cancel: "Cancelar"
+})
+
diff --git a/dojox/editor/plugins/nls/es/LocalImage.js b/dojox/editor/plugins/nls/es/LocalImage.js
new file mode 100644
index 0000000..b38221c
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Insertar imagen",
+	url: "Imagen",
+	browse: "Examinar...",
+	text: "Descripción",
+	set: "Insertar",
+	invalidMessage: "Tipo de archivo de imagen no válido",
+	prePopuTextUrl: "Especifique un URL de imagen",
+	prePopuTextBrowse: " o seleccione un archivo local."
+})
+
diff --git a/dojox/editor/plugins/nls/es/PasteFromWord.js b/dojox/editor/plugins/nls/es/PasteFromWord.js
new file mode 100644
index 0000000..ce07ae6
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Pegar desde Word",
+	"paste": "Pegar",
+	"cancel": "Cancelar",
+	"instructions": "Pegue el contenido de Word en el siguiente recuadro de texto. Cuando esté satisfecho con el contenido que se debe insertar, pulse el botón pegar. Para abortar la inserción de texto, pulse el botón cancelar."
+})
+
diff --git a/dojox/editor/plugins/nls/es/Smiley.js b/dojox/editor/plugins/nls/es/Smiley.js
index a5b20ef..7fd1221 100644
--- a/dojox/editor/plugins/nls/es/Smiley.js
+++ b/dojox/editor/plugins/nls/es/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "guiño",
 	emoticonGrin: "carcajada",
 	emoticonCool: "guay",
-	emoticonAngry: "enfadado",  
-	emoticonHalf: "escéptico", 
+	emoticonAngry: "enfadado",
+	emoticonHalf: "escéptico",
 	emoticonEyebrow: "ceja levantada",
 	emoticonFrown: "ceño fruncido",
 	emoticonShy: "tímido",
@@ -15,7 +15,7 @@
 	emoticonTongue: "burlón",
 	emoticonIdea: "idea",
 	emoticonYes: "sí",
-	emoticonNo: "no",	
+	emoticonNo: "no",
 	emoticonAngel: "ángel",
 	emoticonCrying: "llorando"
 })
diff --git a/dojox/editor/plugins/nls/es/SpellCheck.js b/dojox/editor/plugins/nls/es/SpellCheck.js
new file mode 100644
index 0000000..d5395f7
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Corrector ortográfico por lotes",
+	unfound: "No encontrado",
+	skip: "Saltar",
+	skipAll: "Saltar todo",
+	toDic: "Añadir al diccionario",
+	suggestions: "Sugerencias",
+	replace: "Sustituir",
+	replaceWith: "Sustituir por",
+	replaceAll: "Sustituir todo",
+	cancel: "Cancelar",
+	msg: "No se han encontrado errores ortográficos",
+	iSkip: "Saltar esto",
+	iSkipAll: "Saltar todos los casos como este",
+	iMsg: "No hay sugerencias de ortografía"
+})
+
diff --git a/dojox/editor/plugins/nls/es/TableDialog.js b/dojox/editor/plugins/nls/es/TableDialog.js
index ff48725..c4593e1 100644
--- a/dojox/editor/plugins/nls/es/TableDialog.js
+++ b/dojox/editor/plugins/nls/es/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "derecha",
 	buttonSet: "Establecer", // translated elsewhere?
 	buttonInsert: "Insertar",
+	buttonCancel: "Cancelar",
 
 	selectTableLabel: "Seleccionar tabla",
 	insertTableRowBeforeLabel: "Añadir fila antes",
@@ -27,4 +28,5 @@
 	deleteTableRowLabel: "Suprimir fila",
 	deleteTableColumnLabel: "Suprimir columna"
 })
+	
 
diff --git a/dojox/editor/plugins/nls/es/TextColor.js b/dojox/editor/plugins/nls/es/TextColor.js
new file mode 100644
index 0000000..f684f6e
--- /dev/null
+++ b/dojox/editor/plugins/nls/es/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Establecer",
+	"cancelButtonText": "Cancelar"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/AutoSave.js b/dojox/editor/plugins/nls/fi/AutoSave.js
new file mode 100644
index 0000000..1b4ba49
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Tallenna",
+	"saveSettingLabelOn": "Aseta automaattisen tallennuksen väli...",
+	"saveSettingLabelOff": "Ota automaattinen tallennus pois käytöstä",
+	"saveSettingdialogTitle": "Automaattinen tallennus",
+	"saveSettingdialogDescription": "Määritä automaattisen tallennuksen väli",
+	"saveSettingdialogParamName": "Automaattisen tallennuksen väli",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Aseta väli",
+	"saveSettingdialogButtonCancel": "Peruuta",
+	"saveMessageSuccess": "Tallennusaika ${0}",
+	"saveMessageFail": "Tallennus epäonnistui ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/Blockquote.js b/dojox/editor/plugins/nls/fi/Blockquote.js
new file mode 100644
index 0000000..23c7690
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Sitaatti"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/Breadcrumb.js b/dojox/editor/plugins/nls/fi/Breadcrumb.js
new file mode 100644
index 0000000..dcdcc87
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} - Toiminnot",
+	"selectContents": "Valitse sisältö",
+	"selectElement": "Valitse elementti",
+	"deleteElement": "Poista elementti",
+	"deleteContents": "Poista sisältö",
+	"moveStart": "Siirrä kohdistin alkuun",
+	"moveEnd": "Siirrä kohdistin loppuun"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js b/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
new file mode 100644
index 0000000..f489ec1
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Pienennä muokkausohjelman työkalurivi",
+	"expand": "Laajenna muokkausohjelman työkalurivi"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/FindReplace.js b/dojox/editor/plugins/nls/fi/FindReplace.js
new file mode 100644
index 0000000..4a82134
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Etsi:",
+	"findTooltip": "Anna etsittävä teksti",
+	"replaceLabel": "Korvaava:",
+	"replaceTooltip": "Anna korvaava teksti",
+	"findReplace": "Etsi ja korvaa",
+	"matchCase": "Sama kirjainkoko",
+	"matchCaseTooltip": "Sama kirjainkoko",
+	"backwards": "Taaksepäin",
+	"backwardsTooltip": "Etsi tekstiä taaksepäin",
+	"replaceAll": "Kaikki esiintymät",
+	"replaceAllButton": "Korvaa kaikki",
+	"replaceAllButtonTooltip": "Korvaa kaikki teksti",
+	"findButton": "Etsi",
+	"findButtonTooltip": "Etsi teksti",
+	"replaceButton": "Korvaa",
+	"replaceButtonTooltip": "Korvaa teksti",
+	"replaceDialogText": "Korvattu ${0} esiintymää.",
+	"eofDialogText": "Viimeinen esiintymä ${0}",
+	"eofDialogTextFind": "löytynyt",
+	"eofDialogTextReplace": "korvattu"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/InsertAnchor.js b/dojox/editor/plugins/nls/fi/InsertAnchor.js
new file mode 100644
index 0000000..c9f25cf
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Lisää ankkuri",
+	title: "Ankkurin ominaisuudet",
+	anchor: "Nimi:",
+	text: "Kuvaus:",
+	set: "Aseta",
+	cancel: "Peruuta"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/InsertEntity.js b/dojox/editor/plugins/nls/fi/InsertEntity.js
new file mode 100644
index 0000000..78b0b2f
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Lisää symboli"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/LocalImage.js b/dojox/editor/plugins/nls/fi/LocalImage.js
new file mode 100644
index 0000000..277dc07
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Lisää kuva",
+	url: "Kuva",
+	browse: "Selaa...",
+	text: "Kuvaus",
+	set: "Lisää",
+	invalidMessage: "Virheellinen kuvatiedoston laji",
+	prePopuTextUrl: "Anna kuvan URL-osoite",
+	prePopuTextBrowse: " tai selaa paikalliseen tiedostoon."
+})
+
diff --git a/dojox/editor/plugins/nls/fi/PageBreak.js b/dojox/editor/plugins/nls/fi/PageBreak.js
new file mode 100644
index 0000000..efeabe6
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Sivunvaihto"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/PasteFromWord.js b/dojox/editor/plugins/nls/fi/PasteFromWord.js
new file mode 100644
index 0000000..bfdcf52
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Liitä Word-ohjelmasta",
+	"paste": "Liitä",
+	"cancel": "Peruuta",
+	"instructions": "Liitä sisältö Word-tiedostosta alla olevaan tekstikenttään. Kun lisättävä sisältö on mielestäsi valmis, napsauta Liitä-painiketta. Voit peruuttaa lisäyksen napsauttamalla Peruuta-painiketta."
+})
+
diff --git a/dojox/editor/plugins/nls/fi/Preview.js b/dojox/editor/plugins/nls/fi/Preview.js
new file mode 100644
index 0000000..5cd828f
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Esikatselu"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/Save.js b/dojox/editor/plugins/nls/fi/Save.js
new file mode 100644
index 0000000..74e605a
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Tallenna"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/ShowBlockNodes.js b/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
new file mode 100644
index 0000000..f37ca88
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Näytä HTML-lohkoelementit"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/Smiley.js b/dojox/editor/plugins/nls/fi/Smiley.js
new file mode 100644
index 0000000..856b7c6
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Lisää hymiö",
+	emoticonSmile: "hymyillä",
+	emoticonLaughing: "nauraa",
+	emoticonWink: "iskeä silmää",
+	emoticonGrin: "virnistää",
+	emoticonCool: "viileä hymy",
+	emoticonAngry: "vihainen",
+	emoticonHalf: "puolikas",
+	emoticonEyebrow: "ihmetellä",
+	emoticonFrown: "irvistää",
+	emoticonShy: "ujo",
+	emoticonGoofy: "hölmö",
+	emoticonOops: "hups",
+	emoticonTongue: "näyttää kieltä",
+	emoticonIdea: "idea",
+	emoticonYes: "kyllä",
+	emoticonNo: "ei",
+	emoticonAngel: "enkeli",
+	emoticonCrying: "itkeä"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/SpellCheck.js b/dojox/editor/plugins/nls/fi/SpellCheck.js
new file mode 100644
index 0000000..449ab2f
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Eräoikoluku",
+	unfound: "Ei löydy",
+	skip: "Ohita",
+	skipAll: "Ohita kaikki",
+	toDic: "Lisää sanastoon",
+	suggestions: "Ehdotukset",
+	replace: "Korvaa",
+	replaceWith: "Korvaava",
+	replaceAll: "Korvaa kaikki",
+	cancel: "Peruuta",
+	msg: "Kirjoitusvirheitä ei löytynyt",
+	iSkip: "Ohita tämä",
+	iSkipAll: "Ohita kaikki samanlaiset",
+	iMsg: "Ei oikeinkirjoitusehdotuksia"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/TableDialog.js b/dojox/editor/plugins/nls/fi/TableDialog.js
index 12ff00d..3f00b82 100644
--- a/dojox/editor/plugins/nls/fi/TableDialog.js
+++ b/dojox/editor/plugins/nls/fi/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "oikea",
 	buttonSet: "Aseta", // translated elsewhere?
 	buttonInsert: "Lisää",
+	buttonCancel: "Peruuta",
 
 	selectTableLabel: "Valitse taulukko",
 	insertTableRowBeforeLabel: "Lisää rivi ennen",
diff --git a/dojox/editor/plugins/nls/fi/TextColor.js b/dojox/editor/plugins/nls/fi/TextColor.js
new file mode 100644
index 0000000..1d759d7
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Aseta",
+	"cancelButtonText": "Peruuta"
+})
+
diff --git a/dojox/editor/plugins/nls/fi/latinEntities.js b/dojox/editor/plugins/nls/fi/latinEntities.js
new file mode 100644
index 0000000..be9ec5b
--- /dev/null
+++ b/dojox/editor/plugins/nls/fi/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"ylösalainen huutomerkki",
+	cent:"sentin merkki",
+	pound:"punnan merkki",
+	curren:"valuuttamerkki",
+	yen:"jenin merkki\nyuanin merkki",
+	brvbar:"katkopystyviiva",
+	sect:"pykälämerkki",
+	uml:"treema\ntilaa vievä treema",
+	copy:"tekijänoikeusmerkki",
+	ordf:"feminiinisen järjestysluvun merkki",
+	laquo:"vasemmalle osoittava kaksinkertainen kulmalainausmerkki\nvasemmalle osoittava kulmalainausmerkki",
+	not:"negaation merkki\nei-merkki",
+	shy:"ehdollinen tavuviiva\npehmeä tavuviiva\ntavutusvihje",
+	reg:"rekisteröidyn tavaramerkin merkki\nrekisteröity tavaramerkki -merkki",
+	macr:"macron\nviiva-aksentti\npituusmerkki\npäällekkäisviiva",
+	deg:"astemerkki",
+	plusmn:"plus-miinus-merkki\nplus- tai miinusmerkki",
+	sup2:"yläindeksi kaksi\nneliö\ntoinen potenssi",
+	sup3:"yläindeksi kolme\nkuutio\nkolmas potenssi",
+	acute:"akuutti\nakuuttiaksentti",
+	micro:"mikro-merkki",
+	para:"kappaleen merkki\nkappalemerkki",
+	middot:"keskipiste\nrivinkeskinen piste\ngeorgialainen pilkku\nkreikkalainen keskipiste",
+	cedil:"sedilji\ntilaa vievä sedilji\ncedilla",
+	sup1:"yläindeksi yksi",
+	ordm:"maskuliinisen järjestysluvun merkki",
+	raquo:"oikealle osoittava kaksinkertainen kulmalainausmerkki\noikealle osoittava kulmalainausmerkki",
+	frac14:"neljäsosan merkki\nneljäsosa",
+	frac12:"puolikkaan merkki\npuolikas",
+	frac34:"kolmen neljäsosan merkki\nkolme neljäsosaa",
+	iquest:"ylösalainen kysymysmerkki",
+	Agrave:"iso A ja gravis\nversaali A ja gravis",
+	Aacute:"iso A ja akuutti\niso A ja akuuttiaksentti\nversaali A ja akuutti",
+	Acirc:"iso A ja sirkumfleksi\nversaali A ja sirkumfleksi",
+	Atilde:"iso A ja tilde\nversaali A ja tilde\niso A ja aaltoviiva\nversaali A ja aaltoviiva",
+	Auml:"iso Ä\nversaali Ä",
+	Aring:"iso Å\nversaali Å\niso ruotsalainen o\nversaali ruotsalainen o",
+	AElig:"iso AE\nversaali AE\niso ligatuuri AE\nversaaliligatuuri AE\niso tanskalainen ä\nversaali tanskalainen ä",
+	Ccedil:"iso C ja sedilji\nversaali C ja sedilji",
+	Egrave:"iso E ja gravis\nversaali E ja gravis",
+	Eacute:"iso E ja akuutti\niso E ja akuuttiaksentti\nversaali E ja akuutti",
+	Ecirc:"iso E ja sirkumfleksi\nversaali E ja sirkumfleksi",
+	Euml:"iso E ja treema\nversaali E ja treema",
+	Igrave:"iso I ja gravis\nversaali I ja gravis",
+	Iacute:"iso I ja akuutti\niso I ja akuuttiaksentti\nversaali I ja akuutti",
+	Icirc:"iso I ja sirkumfleksi\nversaali I ja sirkumfleksi",
+	Iuml:"iso I ja treema\nversaali I ja treema",
+	ETH:"iso eth\nversaali eth",
+	Ntilde:"iso N ja tilde\nversaali N ja tilde\niso N ja aaltoviiva\nversaali N ja aaltoviiva",
+	Ograve:"iso O ja gravis\nversaali O ja gravis",
+	Oacute:"iso O ja akuutti\niso O ja akuuttiaksentti\nversaali O ja akuutti",
+	Ocirc:"iso O ja sirkumfleksi\nversaali O ja sirkumfleksi",
+	Otilde:"iso O ja tilde\nversaali O ja tilde\niso O ja aaltoviiva\nversaali O ja aaltoviiva",
+	Ouml:"iso O ja treema\nversaali O ja treema",
+	times:"kertomerkki",
+	Oslash:"iso tanskalainen ö\nversaali tanskalainen ö\niso O ja vinoviiva\nversaali O ja vinoviiva\niso O, jossa on poikkiviiva\nversaali O, jossa on poikkiviiva",
+	Ugrave:"iso U ja gravis\nversaali U ja gravis",
+	Uacute:"iso U ja akuutti\niso U ja akuuttiaksentti\nversaali U ja akuutti",
+	Ucirc:"iso U ja sirkumfleksi\nversaali U ja sirkumfleksi",
+	Uuml:"iso U ja treema\nversaali U ja treema\niso saksalainen y\nversaali saksalainen y",
+	Yacute:"iso Y ja akuutti\niso Y ja akuuttiaksentti\nversaali Y ja akuutti",
+	THORN:"iso thorn\nversaali thorn",
+	szlig:"pieni kaksois-s\ngemena kaksois-s\npieni saksalainen kaksois-s\ngemena saksalainen kaksois-s",
+	agrave:"pieni a ja gravis\ngemena a ja gravis",
+	aacute:"pieni a ja akuutti\ngemena a ja akuutti\npieni a ja akuuttiaksentti",
+	acirc:"pieni a ja sirkumfleksi\ngemena a ja sirkumfleksi",
+	atilde:"pieni a ja tilde\ngemena a ja tilde\npieni a ja aaltoviiva\ngemena a ja aaltoviiva",
+	auml:"pieni ä\ngemena ä",
+	aring:"pieni å\ngemena å\npieni ruotsalainen o\ngemena ruotsalainen o",
+	aelig:"pieni ae\ngemena ae\npieni ligatuuri ae\ngemenaligatuuri ae\npieni tanskalainen ä\ngemena tanskalainen ä",
+	ccedil:"pieni c ja sedilji\ngemena c ja sedilji",
+	egrave:"pieni e ja gravis\ngemena e ja gravis",
+	eacute:"pieni e ja akuutti\ngemena e ja akuutti\npieni e ja akuuttiaksentti",
+	ecirc:"pieni e ja sirkumfleksi\ngemena e ja sirkumfleksi",
+	euml:"pieni e ja treema\ngemena e ja treema",
+	igrave:"pieni i ja gravis\ngemena e ja gravis",
+	iacute:"pieni i ja akuutti\ngemena i ja akuutti\npieni i ja akuuttiaksentti",
+	icirc:"pieni i ja sirkumfleksi\ngemena i ja sirkumfleksi",
+	iuml:"pieni i ja treema\ngemena i ja treema",
+	eth:"pieni eth\ngemena eth",
+	ntilde:"pieni n ja tilde\ngemena n ja tilde\npieni n ja aaltoviiva\ngemena n ja aaltoviiva",
+	ograve:"pieni o ja gravis\ngemena o ja gravis",
+	oacute:"pieni o ja akuutti\ngemena o ja akuutti\npieni o ja akuuttiaksentti",
+	ocirc:"pieni o ja sirkumfleksi\ngemena o ja sirkumfleksi",
+	otilde:"pieni o ja tilde\ngemena o ja tilde\npieni o ja aaltoviiva\ngemena o ja aaltoviiva",
+	ouml:"pieni ö\ngemena ö",
+	divide:"jakomerkki",
+	oslash:"pieni tanskalainen ö\ngemena tanskalainen ö\npieni o ja vinoviiva\ngemena o ja vinoviiva\npieni o, jossa on poikkiviiva\ngemena o, jossa on poikkiviiva",
+	ugrave:"pieni u ja gravis\ngemena u ja gravis",
+	uacute:"pieni u ja akuutti\ngemena u ja akuutti\npieni u ja akuuttiaksentti",
+	ucirc:"pieni u ja sirkumfleksi\ngemena u ja sirkumfleksi",
+	uuml:"pieni u ja treema\ngemena u ja treema\npieni saksalainen y\ngemena saksalainen y",
+	yacute:"pieni y ja akuutti\ngemena y ja akuutti\npieni y ja akuuttiaksentti",
+	thorn:"pieni thorn\ngemena thorn",
+	yuml:"pieni y ja treema\ngemena y ja treema",
+
+// Greek Characters and Symbols
+	fnof:"pieni f, jossa koukku\ngemena f, jossa koukku\nfunktio\nguldeni",
+	Alpha:"iso alfa\nversaali alfa",
+	Beta:"iso beeta\nversaali beeta",
+	Gamma:"iso gamma\nversaali gamma",
+	Delta:"iso delta\nversaali delta",
+	Epsilon:"iso epsilon\nversaali epsilon",
+	Zeta:"iso zeeta\nversaali zeeta",
+	Eta:"iso eeta\nversaali eeta",
+	Theta:"iso theeta\nversaali theeta",
+	Iota:"iso ioota\nversaali ioota",
+	Kappa:"iso kappa\nversaali kappa",
+	Lambda:"iso lambda\nversaali lambda",
+	Mu:"iso myy\nversaali myy",
+	Nu:"iso nyy\nversaali nyy",
+	Xi:"iso ksii\nversaali ksii",
+	Omicron:"iso omikron\nversaali omikron",
+	Pi:"iso pii\nversaali pii",
+	Rho:"iso rhoo\nversaali rhoo",
+	Sigma:"iso sigma\nversaali sigma",
+	Tau:"iso tau\nversaali tau",
+	Upsilon:"iso ypsilon\nversaali ypsilon",
+	Phi:"iso fii\nversaali fii",
+	Chi:"iso khii\nversaali khii",
+	Psi:"iso psii\nversaali psii",
+	Omega:"iso oomega\nversaali oomega",
+	alpha:"pieni alfa\ngemena alfa",
+	beta:"pieni beeta\ngemena beeta",
+	gamma:"pieni gamma\ngemena gamma",
+	delta:"pieni delta\ngemena delta",
+	epsilon:"pieni epsilon\ngemena epsilon",
+	zeta:"pieni zeeta\ngemena zeeta",
+	eta:"pieni eeta\ngemena eeta",
+	theta:"pieni theeta\ngemena theeta",
+	iota:"pieni ioota\ngemena ioota",
+	kappa:"pieni kappa\ngemena kappa",
+	lambda:"pieni lambda\ngemena lambda",
+	mu:"pieni myy\ngemena myy",
+	nu:"pieni nyy\ngemena nyy",
+	xi:"pieni ksii\ngemena ksii",
+	omicron:"pieni omikron\ngemena omikron",
+	pi:"pieni pii\ngemena pii",
+	rho:"pieni rhoo\ngemena rhoo",
+	sigmaf:"pieni sananloppuinen sigma\ngemena sananloppuinen sigma",
+	sigma:"pieni sigma\ngemena sigma",
+	tau:"pieni tau\ngemena tau",
+	upsilon:"pieni ypsilon\ngemena ypsilon",
+	phi:"pieni fii\ngemena fii",
+	chi:"pieni khii\ngemena khii",
+	psi:"pieni psii\ngemena psii",
+	omega:"pieni oomega\ngemena oomega",
+	thetasym:"pieni theeta\ngemena theeta",
+	upsih:"ypsilon, jossa koukku",
+	piv:"pii-merkki",
+	bull:"luetelmamerkki\nluetelmapallo\npieni musta ympyrä",
+	hellip:"kolme pistettä\nkolme pistettä vaakasuunnassa\nellipsi",
+	prime:"yläpuolinen indeksointipilkku\nindeksointipilkku\nminuutit\njalat",
+	Prime:"kaksinkertainen yläpuolinen indeksointipilkku\nsekunnit\ntuumat",
+	oline:"yläviiva",
+	frasl:"murtoluvun vinoviiva\nmurtolukuviiva",
+	weierp:"iso kaunokirjoitus-P\npotenssijoukko\nWeierstrassin p",
+	image:"goottilainen iso I\ngoottilainen versaali I\nimaginaarinen osa",
+	real:"goottilainen iso R\ngoottilainen versaali R\nreaaliosa",
+	trade:"tavaramerkki\ntavaramerkin merkki",
+	alefsym:"alef-merkki\nalef\nensimmäinen transfiniittinen kardinaali",
+	larr:"vasen nuoli\nnuoli vasemmalle",
+	uarr:"ylänuoli\nnuoli ylös\nylöspäin osoittava nuoli",
+	rarr:"oikea nuoli\nnuoli oikealle",
+	darr:"alanuoli\nnuoli alas\nalaspäin osoittava nuoli",
+	harr:"nuoli vasemmalle ja oikealle",
+	crarr:"rivinvaihtomerkki",
+	lArr:"kaksoisnuoli vasemmalle",
+	uArr:"kaksoisnuoli ylös",
+	rArr:"kaksoisnuoli oikealle",
+	dArr:"kaksoisnuoli alas",
+	hArr:"kaksoisnuoli vasemmalle ja oikealle",
+	forall:"kaikkikvanttori\nuniversaalikvanttori",
+	part:"osittaisderivaatta",
+	exist:"olemassaolokvanttori",
+	empty:"tyhjä joukko\nhalkaisija",
+	nabla:"nabla\ngradientti",
+	isin:"joukkoon kuulumisen merkki",
+	notin:"joukkoon kuulumattomuuden merkki",
+	ni:"käänteinen joukkoon kuulumisen merkki",
+	prod:"tulo\ntulon merkki",
+	sum:"summa",
+	minus:"miinusmerkki",
+	lowast:"tähti\nasteriski",
+	radic:"neliöjuuri\njuurimerkki",
+	prop:"verrannollinen",
+	infin:"ääretön\näärettömän merkki",
+	ang:"kulma",
+	and:"looginen ja-merkki",
+	or:"looginen tai-merkki",
+	cap:"leikkauksen merkki\nleikkaus",
+	cup:"yhdisteen merkki\nyhdiste\nunioni","int":"integraalimerkki\nintegraali",
+	there4:"loogisen seuraamuksen merkki\njoten\nsiis",
+	sim:"tildeoperaattori\nlikiarvo",
+	cong:"suunnilleen yhtä suuri kuin -merkki",
+	asymp:"likimain yhtä suuri kuin -merkki\nasymptoottinen",
+	ne:"eri suuri kuin -merkki\nerisuuruusmerkki",
+	equiv:"identtisesti yhtä suuri kuin -merkki",
+	le:"pienempi tai yhtä suuri kuin -merkki",
+	ge:"suurempi tai yhtä suuri kuin -merkki",
+	sub:"osajoukon merkki",
+	sup:"ylijoukon merkki",
+	nsub:"osajoukkosuhteen negaation merkki",
+	sube:"osajoukkosuhteen tai yhtäläisyyden merkki",
+	supe:"ylijoukkosuhteen tai yhtäläisyyden merkki",
+	oplus:"ympyrässä oleva plusmerkki\nsuora summa",
+	otimes:"ympyrässä oleva kertomerkki\nvektoritulo\nristitulo",
+	perp:"kohtisuoruusmerkki",
+	sdot:"pisteoperaattori",
+	lceil:"vasen kattosymboli",
+	rceil:"oikea kattosymboli",
+	lfloor:"vasen lattiasymboli",
+	rfloor:"oikea lattiasymboli",
+	lang:"vasemmalle osoittava kulmasulje",
+	rang:"oikealle osoittava kulmasulje",
+	loz:"vinoneliö\nnelikovero",
+	spades:"musta korttipakan pata",
+	clubs:"musta korttipakan risti\napila",
+	hearts:"musta korttipakan hertta\nsydän",
+	diams:"musta korttipakan ruutu",
+	OElig:"iso ligatuuri OE\nversaaliligatuuri OE",
+	oelig:"pieni ligatuuri oe\ngemenaligatuuri oe",
+	Scaron:"iso hattu-S\nversaali hattu-S",
+	scaron:"pieni hattu-s\ngemena hattu-s",
+	Yuml:"iso Y ja treema\nversaali Y ja treema",
+	circ:"tarkkeenomainen sirkumfleksi",
+	tilde:"pieni tilde",
+	ensp:"n-väli\nn-kirjaimen levyinen väli",
+	emsp:"m-väli\nm-kirjaimen levyinen väli",
+	thinsp:"kapea väli",
+	zwnj:"leveydetön erottava merkki",
+	zwj:"leveydetön yhdistävä merkki",
+	lrm:"vasemmalta oikealle -merkki",
+	rlm:"oikealta vasemmalle -merkki",
+	ndash:"n-viiva\nlyhyt ajatusviiva",
+	mdash:"m-viiva\npitkä ajatusviiva",
+	lsquo:"ylösalainen puolilainausmerkki",
+	rsquo:"puolilainausmerkki",
+	sbquo:"rivinalinen puolilainausmerkki",
+	ldquo:"ylösalainen kokolainausmerkki",
+	rdquo:"kokolainausmerkki",
+	bdquo:"rivinalinen kokolainausmerkki",
+	dagger:"risti",
+	Dagger:"kaksoisristi",
+	permil:"promillemerkki",
+	lsaquo:"vasemmalle osoittava kulmapuolilainausmerkki",
+	rsaquo:"oikealle osoittava kulmapuolilainausmerkki",
+	euro:"euron merkki"
+})
+
diff --git a/dojox/editor/plugins/nls/fr/AutoSave.js b/dojox/editor/plugins/nls/fr/AutoSave.js
new file mode 100644
index 0000000..0c9cfc7
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Enregistrer",
+	"saveSettingLabelOn": "Définir l'intervalle d'enregistrement automatique...",
+	"saveSettingLabelOff": "Désactiver l'enregistrement automatique",
+	"saveSettingdialogTitle": "Enregistrement automatique",
+	"saveSettingdialogDescription": "Spécifiez l'intervalle d'enregistrement automatique",
+	"saveSettingdialogParamName": "Intervalle d'enregistrement automatique",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Définir l'intervalle",
+	"saveSettingdialogButtonCancel": "Annuler",
+	"saveMessageSuccess": "Enregistré à ${0}",
+	"saveMessageFail": "Echec de l'enregistrement à ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/fr/Blockquote.js b/dojox/editor/plugins/nls/fr/Blockquote.js
new file mode 100644
index 0000000..d73127b
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Bloc de citation"
+})
+
diff --git a/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js b/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
new file mode 100644
index 0000000..e06f27a
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Réduire la barre d'outils de l'éditeur",
+	"expand": "Développer la barre d'outils de l'éditeur"
+})
+
diff --git a/dojox/editor/plugins/nls/fr/FindReplace.js b/dojox/editor/plugins/nls/fr/FindReplace.js
index 23e12cc..1c81610 100644
--- a/dojox/editor/plugins/nls/fr/FindReplace.js
+++ b/dojox/editor/plugins/nls/fr/FindReplace.js
@@ -1,12 +1,22 @@
 ({
-	"findLabel": "Que rechercher :",
+	"findLabel": "Rechercher :",
+	"findTooltip": "Entrez le texte à rechercher",
 	"replaceLabel": "Remplacer par :",
-	"findReplace": "Rechercher/Remplacer",
-	"matchCase": "Respecter la casse", 
+	"replaceTooltip": "Entrez le texte de remplacement",
+	"findReplace": "Rechercher et remplacer",
+	"matchCase": "Respecter la casse",
+	"matchCaseTooltip": "Respecter la casse",
 	"backwards": "Vers l'arrière",
-	"replaceAll": "Toutes les occurrences", 
+	"backwardsTooltip": "Recherchez le texte vers l'arrière",
+	"replaceAll": "Toutes les occurrences",
+	"replaceAllButton": "Remplacer tout",
+	"replaceAllButtonTooltip": "Remplacez tout le texte",
 	"findButton": "Rechercher",
+	"findButtonTooltip": "Recherchez le texte",
 	"replaceButton": "Remplacer",
-	"replaceDialogText": "${0} occurrence(s) remplacée(s)."
+	"replaceButtonTooltip": "Remplacez le texte",
+	"replaceDialogText": "${0} occurrence(s) remplacée(s)",
+	"eofDialogText": "Dernière occurrence ${0}",
+	"eofDialogTextFind": "trouvé",
+	"eofDialogTextReplace": "remplacé"
 })
-
diff --git a/dojox/editor/plugins/nls/fr/InsertAnchor.js b/dojox/editor/plugins/nls/fr/InsertAnchor.js
new file mode 100644
index 0000000..805e592
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Insérer un point d'ancrage",
+	title: "Propriétés du point d'ancrage",
+	anchor: "Nom :",
+	text: "Description :",
+	set: "Définir",
+	cancel: "Annuler"
+})
+
diff --git a/dojox/editor/plugins/nls/fr/LocalImage.js b/dojox/editor/plugins/nls/fr/LocalImage.js
new file mode 100644
index 0000000..2e4399d
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Insérer une image",
+	url: "Image",
+	browse: "Parcourir...",
+	text: "Description",
+	set: "Insérer",
+	invalidMessage: "Type de fichier image non valide",
+	prePopuTextUrl: "Entrez une URL d'image",
+	prePopuTextBrowse: " ou sélectionnez un fichier local."
+})
+
diff --git a/dojox/editor/plugins/nls/fr/PasteFromWord.js b/dojox/editor/plugins/nls/fr/PasteFromWord.js
new file mode 100644
index 0000000..016359c
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Coller depuis Word",
+	"paste": "Coller",
+	"cancel": "Annuler",
+	"instructions": "Collez le contenu Word dans la zone de texte ci-dessous. Quand le contenu à insérer vous convient, appuyez sur le bouton Coller. Pour annuler l'insertion du texte, utilisez le bouton Annuler."
+})
+
diff --git a/dojox/editor/plugins/nls/fr/Smiley.js b/dojox/editor/plugins/nls/fr/Smiley.js
index 0e6f8c5..5d9e3ba 100644
--- a/dojox/editor/plugins/nls/fr/Smiley.js
+++ b/dojox/editor/plugins/nls/fr/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "clin d'oeil",
 	emoticonGrin: "sourire large",
 	emoticonCool: "calme",
-	emoticonAngry: "colère",  
-	emoticonHalf: "demi", 
+	emoticonAngry: "colère",
+	emoticonHalf: "demi",
 	emoticonEyebrow: "sourcils",
 	emoticonFrown: "froncement de sourcils",
 	emoticonShy: "timide",
@@ -15,7 +15,7 @@
 	emoticonTongue: "langue",
 	emoticonIdea: "idée",
 	emoticonYes: "oui",
-	emoticonNo: "non",	
+	emoticonNo: "non",
 	emoticonAngel: "ange",
 	emoticonCrying: "pleurs"
 })
diff --git a/dojox/editor/plugins/nls/fr/SpellCheck.js b/dojox/editor/plugins/nls/fr/SpellCheck.js
new file mode 100644
index 0000000..12ec416
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Vérification orthographique par lots",
+	unfound: "Introuvable",
+	skip: "Ignorer",
+	skipAll: "Ignorer tout",
+	toDic: "Ajouter au dictionnaire",
+	suggestions: "Suggestions",
+	replace: "Remplacer",
+	replaceWith: "Remplacer par",
+	replaceAll: "Remplacer tout",
+	cancel: "Annuler",
+	msg: "Aucune faute d'orthographe trouvée",
+	iSkip: "Ignorer une fois",
+	iSkipAll: "Ignorer chaque fois",
+	iMsg: "Aucune suggestion orthographique"
+})
+
diff --git a/dojox/editor/plugins/nls/fr/TableDialog.js b/dojox/editor/plugins/nls/fr/TableDialog.js
index 20edf5e..37b42fa 100644
--- a/dojox/editor/plugins/nls/fr/TableDialog.js
+++ b/dojox/editor/plugins/nls/fr/TableDialog.js
@@ -1,30 +1,31 @@
 ({
-	insertTableTitle: "Insertion d'une table",
-	modifyTableTitle: "Modification d'une table",
+	insertTableTitle: "Insérer une table",
+	modifyTableTitle: "Modifier une table",
 	rows: "Lignes :",
 	columns: "Colonnes :",
 	align: "Aligner :",
-	cellPadding: "Remplissage des cellules",
+	cellPadding: "Remplissage des cellules :",
 	cellSpacing: "Espacement des cellules :",
-	tableWidth: "Largeur de la table :",
+	tableWidth: "Largeur de table :",
 	backgroundColor: "Couleur d'arrière-plan :",
-	borderColor: "Couleur de la bordure :",
-	borderThickness: "Epaisseur de la bordure",
+	borderColor: "Couleur des bordures :",
+	borderThickness: "Epaisseur des bordures",
 	percent: "pourcentage",
 	pixels: "pixels",
-	"default": "valeur par défaut",
-	left: "à gauche",
-	center: "au centre",
-	right: "à droite",
+	"default": "par défaut",
+	left: "aligné à gauche",
+	center: "centré",
+	right: "aligné à droite",
 	buttonSet: "Définir", // translated elsewhere?
 	buttonInsert: "Insérer",
+	buttonCancel: "Annuler",
 
-	selectTableLabel: "Sélection d'une table",
+	selectTableLabel: "Sélectionner une table",
 	insertTableRowBeforeLabel: "Ajouter une ligne avant",
 	insertTableRowAfterLabel: "Ajouter une ligne après",
 	insertTableColumnBeforeLabel: "Ajouter une colonne avant",
 	insertTableColumnAfterLabel: "Ajouter une colonne après",
-	deleteTableRowLabel: "Supprimer une ligne",
-	deleteTableColumnLabel: "Supprimer une colonne"
+	deleteTableRowLabel: "Supprimer la ligne",
+	deleteTableColumnLabel: "Supprimer la colonne"
 })
-
+	
diff --git a/dojox/editor/plugins/nls/fr/TextColor.js b/dojox/editor/plugins/nls/fr/TextColor.js
new file mode 100644
index 0000000..ad0fe03
--- /dev/null
+++ b/dojox/editor/plugins/nls/fr/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Définir",
+	"cancelButtonText": "Annuler"
+})
+
diff --git a/dojox/editor/plugins/nls/he/AutoSave.js b/dojox/editor/plugins/nls/he/AutoSave.js
new file mode 100644
index 0000000..64b12c2
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "שמירה",
+	"saveSettingLabelOn": "הגדרת מרווח שמירה אוטומטית...‏",
+	"saveSettingLabelOff": "השבתת שמירה אוטומטית",
+	"saveSettingdialogTitle": "שמירה אוטומטית",
+	"saveSettingdialogDescription": "ציינו מרווח שמירה אוטומטית ",
+	"saveSettingdialogParamName": "מרווח שמירה אוטומטית ",
+	"saveSettingdialogParamLabel": "דות",
+	"saveSettingdialogButtonOk": "הגדרת מרווח  ",
+	"saveSettingdialogButtonCancel": "ביטול",
+	"saveMessageSuccess": "נשמר ${0}",
+	"saveMessageFail": "כשל בשמירה ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/he/Blockquote.js b/dojox/editor/plugins/nls/he/Blockquote.js
new file mode 100644
index 0000000..b995106
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "ציטוט"
+})
+
diff --git a/dojox/editor/plugins/nls/he/Breadcrumb.js b/dojox/editor/plugins/nls/he/Breadcrumb.js
new file mode 100644
index 0000000..9d6526c
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "פעולות ${nodeName} ",
+	"selectContents": "בחירת תוכן ",
+	"selectElement": "בחירת מרכיב ",
+	"deleteElement": "מחיקת מרכיב ",
+	"deleteContents": "מחיקת תוכן ",
+	"moveStart": "העברת הסמן להתחלה ",
+	"moveEnd": "העברת הסמן לסוף "
+})
+
diff --git a/dojox/editor/plugins/nls/he/CollapsibleToolbar.js b/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
new file mode 100644
index 0000000..a74a6e2
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "כיווץ סרגל הכלים של העורך ",
+	"expand": "הרחבת סרגל הכלים של העורך"
+})
+
diff --git a/dojox/editor/plugins/nls/he/FindReplace.js b/dojox/editor/plugins/nls/he/FindReplace.js
new file mode 100644
index 0000000..a8fde39
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "חיפוש: ",
+	"findTooltip": "ציינו תמליל לחיפוש",
+	"replaceLabel": "החלפה עם: ",
+	"replaceTooltip": "ציינו תמליל להחלפה",
+	"findReplace": "חיפוש והחלפה ",
+	"matchCase": "התאמת רישיות ",
+	"matchCaseTooltip": "התאמת רישיות",
+	"backwards": "אחורה ",
+	"backwardsTooltip": "חיפוש תמליל אחורה ",
+	"replaceAll": "כל המופעים ",
+	"replaceAllButton": "החלפת הכל ",
+	"replaceAllButtonTooltip": "החלפת כל התמליל ",
+	"findButton": "חיפוש",
+	"findButtonTooltip": "חיפוש התמליל",
+	"replaceButton": "החלפה ",
+	"replaceButtonTooltip": "החלפת התמליל",
+	"replaceDialogText": "הוחלפו ${0} מופעים ",
+	"eofDialogText": "המופע האחרון ${0}",
+	"eofDialogTextFind": "נמצאו",
+	"eofDialogTextReplace": "הוחלפו "
+})
+
diff --git a/dojox/editor/plugins/nls/he/InsertAnchor.js b/dojox/editor/plugins/nls/he/InsertAnchor.js
new file mode 100644
index 0000000..9638b00
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "הוספת עוגן ",
+	title: "תכונות עוגן ",
+	anchor: "שם:",
+	text: "תיאור:",
+	set: "הגדרה",
+	cancel: "ביטול"
+})
+
diff --git a/dojox/editor/plugins/nls/he/InsertEntity.js b/dojox/editor/plugins/nls/he/InsertEntity.js
new file mode 100644
index 0000000..3e1c46b
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "הוספת סמל "
+})
+
diff --git a/dojox/editor/plugins/nls/he/LocalImage.js b/dojox/editor/plugins/nls/he/LocalImage.js
new file mode 100644
index 0000000..50c4f11
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "הוספת תמונה",
+	url: "תמונה",
+	browse: "עיון...‏ ",
+	text: "תיאור ",
+	set: "הוספה",
+	invalidMessage: "סוג קובץ תמונה לא חוקי",
+	prePopuTextUrl: "ציינו URL של תמונה",
+	prePopuTextBrowse: " או נווטו לקובץ מקומי. "
+})
+
diff --git a/dojox/editor/plugins/nls/he/PageBreak.js b/dojox/editor/plugins/nls/he/PageBreak.js
new file mode 100644
index 0000000..008130d
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "מעבר עמוד"
+})
+
diff --git a/dojox/editor/plugins/nls/he/PasteFromWord.js b/dojox/editor/plugins/nls/he/PasteFromWord.js
new file mode 100644
index 0000000..cd35c7d
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "הדבקה מתוך Word",
+	"paste": "הדבקה",
+	"cancel": "ביטול",
+	"instructions": "הדביקו את התוכן מתוך Word לתוך תיבת התמליל למטה. לאחר שתהיו מרוצים מהתוכן להוספה, לחצו על לחצן ההדבקה. כדי לבטל את הוספת התמליל, לחצו על לחצן הביטול. "
+})
+
diff --git a/dojox/editor/plugins/nls/he/Preview.js b/dojox/editor/plugins/nls/he/Preview.js
new file mode 100644
index 0000000..dbbed34
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "תצוגה מקדימה"
+})
+
diff --git a/dojox/editor/plugins/nls/he/Save.js b/dojox/editor/plugins/nls/he/Save.js
new file mode 100644
index 0000000..1683e27
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "שמירה"
+})
+
diff --git a/dojox/editor/plugins/nls/he/ShowBlockNodes.js b/dojox/editor/plugins/nls/he/ShowBlockNodes.js
new file mode 100644
index 0000000..0547f02
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "הצגת מרכיבי Block של HTML "
+})
+
diff --git a/dojox/editor/plugins/nls/he/Smiley.js b/dojox/editor/plugins/nls/he/Smiley.js
new file mode 100644
index 0000000..d2fc8f8
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "הוספת רגשון",
+	emoticonSmile: "חיוך",
+	emoticonLaughing: "צחוק ",
+	emoticonWink: "קריצה",
+	emoticonGrin: "גיחוך",
+	emoticonCool: "מגניב",
+	emoticonAngry: "כועס ",
+	emoticonHalf: "חצי ",
+	emoticonEyebrow: "גבה",
+	emoticonFrown: "קימוט מצח",
+	emoticonShy: "ביישן",
+	emoticonGoofy: "דבילי",
+	emoticonOops: "אופס ",
+	emoticonTongue: "לשון ",
+	emoticonIdea: "רעיון",
+	emoticonYes: "כן",
+	emoticonNo: "לא",
+	emoticonAngel: "מלאך ",
+	emoticonCrying: "בוכה"
+})
+
diff --git a/dojox/editor/plugins/nls/he/SpellCheck.js b/dojox/editor/plugins/nls/he/SpellCheck.js
new file mode 100644
index 0000000..ec996bd
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "בדיקת איות באצווה ",
+	unfound: "לא נמצא ",
+	skip: "דילוג",
+	skipAll: "דילוג על הכל",
+	toDic: "הוספה למילון",
+	suggestions: "הצעות ",
+	replace: "החלפה ",
+	replaceWith: "החלפה בערך ",
+	replaceAll: "החלפת הכל",
+	cancel: "ביטול",
+	msg: "לא נמצאו שגיאות איות ",
+	iSkip: "דילוג על ערך זה ",
+	iSkipAll: "דילוג על כל הערכים הדומים לערך זה ",
+	iMsg: "אין הצעות איות "
+})
+
diff --git a/dojox/editor/plugins/nls/he/TableDialog.js b/dojox/editor/plugins/nls/he/TableDialog.js
index 3a488c0..c2e1089 100644
--- a/dojox/editor/plugins/nls/he/TableDialog.js
+++ b/dojox/editor/plugins/nls/he/TableDialog.js
@@ -6,11 +6,11 @@
 	align: "יישור:",
 	cellPadding: "ריפוד תאים:",
 	cellSpacing: "ריווח תאים:",
-	tableWidth: "רוחב טבלה:",
+	tableWidth: "רוחב טבלה:‏",
 	backgroundColor: "צבע רקע:",
 	borderColor: "צבע גבול:",
 	borderThickness: "עובי גבול",
-	percent: "אחוז",
+	percent: "אחוזים",
 	pixels: "פיקסלים",
 	"default": "ברירת מחדל",
 	left: "ימין",
@@ -18,6 +18,7 @@
 	right: "שמאל",
 	buttonSet: "הגדרה", // translated elsewhere?
 	buttonInsert: "הוספה",
+	buttonCancel: "ביטול",
 
 	selectTableLabel: "בחירת טבלה",
 	insertTableRowBeforeLabel: "הוספת שורה לפני",
diff --git a/dojox/editor/plugins/nls/he/TextColor.js b/dojox/editor/plugins/nls/he/TextColor.js
new file mode 100644
index 0000000..f52f472
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "הגדרה",
+	"cancelButtonText": "ביטול"
+})
+
diff --git a/dojox/editor/plugins/nls/he/latinEntities.js b/dojox/editor/plugins/nls/he/latinEntities.js
new file mode 100644
index 0000000..ca7f715
--- /dev/null
+++ b/dojox/editor/plugins/nls/he/latinEntities.js
@@ -0,0 +1,256 @@
+({
+	/* 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:"inverted exclamation mark",
+	cent:"cent sign",
+	pound:"pound sign",
+	curren:"currency sign",
+	yen:"yen sign\nyuan sign",
+	brvbar:"broken bar\nbroken vertical bar",
+	sect:"section sign",
+	uml:"diaeresis\nspacing diaeresis",
+	copy:"copyright sign",
+	ordf:"feminine ordinal indicator",
+	laquo:"left-pointing double angle quotation mark\nleft pointing guillemet",
+	not:"not sign",
+	shy:"soft hyphen\ndiscretionary hyphen",
+	reg:"registered sign\nregistered trade mark sign",
+	macr:"macron\nspacing macron\noverline\nAPL overbar",
+	deg:"degree sign",
+	plusmn:"plus-minus sign\nplus-or-minus sign",
+	sup2:"superscript two\nsuperscript digit two\nsquared",
+	sup3:"superscript three\nsuperscript digit three\ncubed",
+	acute:"acute accent\nspacing acute",
+	micro:"micro sign",
+	para:"pilcrow sign\nparagraph sign",
+	middot:"middle dot\nGeorgian comma\nGreek middle dot",
+	cedil:"cedilla\nspacing cedilla",
+	sup1:"superscript one\nsuperscript digit one",
+	ordm:"masculine ordinal indicator",
+	raquo:"right-pointing double angle quotation mark\nright pointing guillemet",
+	frac14:"vulgar fraction one quarter\nfraction one quarter",
+	frac12:"vulgar fraction one half\nfraction one half",
+	frac34:"vulgar fraction three quarters\nfraction three quarters",
+	iquest:"inverted question mark\nturned question mark",
+	Agrave:"Latin capital letter A with grave\nLatin capital letter A grave",
+	Aacute:"Latin capital letter A with acute",
+	Acirc:"Latin capital letter A with circumflex",
+	Atilde:"Latin capital letter A with tilde",
+	Auml:"Latin capital letter A with diaeresis",
+	Aring:"Latin capital letter A with ring above\nLatin capital letter A ring",
+	AElig:"Latin capital letter AE\nLatin capital ligature AE",
+	Ccedil:"Latin capital letter C with cedilla",
+	Egrave:"Latin capital letter E with grave",
+	Eacute:"Latin capital letter E with acute",
+	Ecirc:"Latin capital letter E with circumflex",
+	Euml:"Latin capital letter E with diaeresis",
+	Igrave:"Latin capital letter I with grave",
+	Iacute:"Latin capital letter I with acute",
+	Icirc:"Latin capital letter I with circumflex",
+	Iuml:"Latin capital letter I with diaeresis",
+	ETH:"Latin capital letter ETH",
+	Ntilde:"Latin capital letter N with tilde",
+	Ograve:"Latin capital letter O with grave",
+	Oacute:"Latin capital letter O with acute",
+	Ocirc:"Latin capital letter O with circumflex",
+	Otilde:"Latin capital letter O with tilde",
+	Ouml:"Latin capital letter O with diaeresis",
+	times:"multiplication sign",
+	Oslash:"Latin capital letter O with stroke\nLatin capital letter O slash",
+	Ugrave:"Latin capital letter U with grave",
+	Uacute:"Latin capital letter U with acute",
+	Ucirc:"Latin capital letter U with circumflex",
+	Uuml:"Latin capital letter U with diaeresis",
+	Yacute:"Latin capital letter Y with acute",
+	THORN:"Latin capital letter THORN",
+	szlig:"Latin small letter sharp s\ness-zed",
+	agrave:"Latin small letter a with grave\nLatin small letter a grave",
+	aacute:"Latin small letter a with acute",
+	acirc:"Latin small letter a with circumflex",
+	atilde:"Latin small letter a with tilde",
+	auml:"Latin small letter a with diaeresis",
+	aring:"Latin small letter a with ring above\nLatin small letter a ring",
+	aelig:"Latin small letter ae\nLatin small ligature ae",
+	ccedil:"Latin small letter c with cedilla",
+	egrave:"Latin small letter e with grave",
+	eacute:"Latin small letter e with acute",
+	ecirc:"Latin small letter e with circumflex",
+	euml:"Latin small letter e with diaeresis",
+	igrave:"Latin small letter i with grave",
+	iacute:"Latin small letter i with acute",
+	icirc:"Latin small letter i with circumflex",
+	iuml:"Latin small letter i with diaeresis",
+	eth:"Latin small letter eth",
+	ntilde:"Latin small letter n with tilde",
+	ograve:"Latin small letter o with grave",
+	oacute:"Latin small letter o with acute",
+	ocirc:"Latin small letter o with circumflex",
+	otilde:"Latin small letter o with tilde",
+	ouml:"Latin small letter o with diaeresis",
+	divide:"division sign",
+	oslash:"Latin small letter o with stroke\nLatin small letter o slash",
+	ugrave:"Latin small letter u with grave",
+	uacute:"Latin small letter u with acute",
+	ucirc:"Latin small letter u with circumflex",
+	uuml:"Latin small letter u with diaeresis",
+	yacute:"Latin small letter y with acute",
+	thorn:"Latin small letter thorn",
+	yuml:"Latin small letter y with diaeresis",
+
+// Greek Characters and Symbols
+	fnof:"Latin small f with hook\nfunction\nflorin",
+	Alpha:"Greek capital letter alpha",
+	Beta:"Greek capital letter beta",
+	Gamma:"Greek capital letter gamma",
+	Delta:"Greek capital letter delta",
+	Epsilon:"Greek capital letter epsilon",
+	Zeta:"Greek capital letter zeta",
+	Eta:"Greek capital letter eta",
+	Theta:"Greek capital letter theta",
+	Iota:"Greek capital letter iota",
+	Kappa:"Greek capital letter kappa",
+	Lambda:"Greek capital letter lambda",
+	Mu:"Greek capital letter mu",
+	Nu:"Greek capital letter nu",
+	Xi:"Greek capital letter xi",
+	Omicron:"Greek capital letter omicron",
+	Pi:"Greek capital letter pi",
+	Rho:"Greek capital letter rho",
+	Sigma:"Greek capital letter sigma",
+	Tau:"Greek capital letter tau",
+	Upsilon:"Greek capital letter upsilon",
+	Phi:"Greek capital letter phi",
+	Chi:"Greek capital letter chi",
+	Psi:"Greek capital letter psi",
+	Omega:"Greek capital letter omega",
+	alpha:"Greek small letter alpha",
+	beta:"Greek small letter beta",
+	gamma:"Greek small letter gamma",
+	delta:"Greek small letter delta",
+	epsilon:"Greek small letter epsilon",
+	zeta:"Greek small letter zeta",
+	eta:"Greek small letter eta",
+	theta:"Greek small letter theta",
+	iota:"Greek small letter iota",
+	kappa:"Greek small letter kappa",
+	lambda:"Greek small letter lambda",
+	mu:"Greek small letter mu",
+	nu:"Greek small letter nu",
+	xi:"Greek small letter xi",
+	omicron:"Greek small letter omicron",
+	pi:"Greek small letter pi",
+	rho:"Greek small letter rho",
+	sigmaf:"Greek small letter final sigma",
+	sigma:"Greek small letter sigma",
+	tau:"Greek small letter tau",
+	upsilon:"Greek small letter upsilon",
+	phi:"Greek small letter phi",
+	chi:"Greek small letter chi",
+	psi:"Greek small letter psi",
+	omega:"Greek small letter omega",
+	thetasym:"Greek small letter theta symbol",
+	upsih:"Greek upsilon with hook symbol",
+	piv:"Greek pi symbol",
+	bull:"bullet\nblack small circle",
+	hellip:"horizontal ellipsis\nthree dot leader",
+	prime:"prime\nminutes\nfeet",
+	Prime:"double prime\nseconds\ninches",
+	oline:"overline\nspacing overscore",
+	frasl:"fraction slash",
+	weierp:"script capital P\npower set\nWeierstrass p",
+	image:"blackletter capital I\nimaginary part",
+	real:"blackletter capital R\nreal part symbol",
+	trade:"trade mark sign",
+	alefsym:"alef symbol\nfirst transfinite cardinal",
+	larr:"leftwards arrow",
+	uarr:"upwards arrow",
+	rarr:"rightwards arrow",
+	darr:"downwards arrow",
+	harr:"left right arrow",
+	crarr:"downwards arrow with corner leftwards\ncarriage return",
+	lArr:"leftwards double arrow",
+	uArr:"upwards double arrow",
+	rArr:"rightwards double arrow",
+	dArr:"downwards double arrow",
+	hArr:"left right double arrow",
+	forall:"for all",
+	part:"partial differential",
+	exist:"there exists",
+	empty:"empty set\nnull set\ndiameter",
+	nabla:"nabla\nbackward difference",
+	isin:"element of",
+	notin:"not an element of",
+	ni:"contains as member",
+	prod:"n-ary product\nproduct sign",
+	sum:"n-ary sumation",
+	minus:"minus sign",
+	lowast:"asterisk operator",
+	radic:"square root\nradical sign",
+	prop:"proportional to",
+	infin:"infinity",
+	ang:"angle",
+	and:"logical and\nwedge",
+	or:"logical or\nvee",
+	cap:"intersection\ncap",
+	cup:"union\ncup","int":"integral",
+	there4:"therefore",
+	sim:"tilde operator\nvaries with\nsimilar to",
+	cong:"approximately equal to",
+	asymp:"almost equal to\nasymptotic to",
+	ne:"not equal to",
+	equiv:"identical to",
+	le:"less-than or equal to",
+	ge:"greater-than or equal to",
+	sub:"subset of",
+	sup:"superset of",
+	nsub:"not a subset of",
+	sube:"subset of or equal to",
+	supe:"superset of or equal to",
+	oplus:"circled plus\ndirect sum",
+	otimes:"circled times\nvector product",
+	perp:"up tack\northogonal to\nperpendicular",
+	sdot:"dot operator",
+	lceil:"left ceiling\nAPL upstile",
+	rceil:"right ceiling",
+	lfloor:"left floor\nAPL downstile",
+	rfloor:"right floor",
+	lang:"left-pointing angle bracket",
+	rang:"right-pointing angle bracket",
+	loz:"lozenge",
+	spades:"black spade suit",
+	clubs:"black club suit\nshamrock",
+	hearts:"black heart suit\nvalentine",
+	diams:"black diamond suit",
+	OElig:"Latin capital ligature OE",
+	oelig:"Latin small ligature oe",
+	Scaron:"Latin capital letter S with caron",
+	scaron:"Latin small letter s with caron",
+	Yuml:"Latin capital letter Y with diaeresis",
+	circ:"modifier letter circumflex accent",
+	tilde:"small tilde",
+	ensp:"en space",
+	emsp:"em space",
+	thinsp:"thin space",
+	zwnj:"zero width non-joiner",
+	zwj:"zero width joiner",
+	lrm:"left-to-right mark",
+	rlm:"right-to-left mark",
+	ndash:"en dash",
+	mdash:"em dash",
+	lsquo:"left single quotation mark",
+	rsquo:"right single quotation mark",
+	sbquo:"single low-9 quotation mark",
+	ldquo:"left double quotation mark",
+	rdquo:"right double quotation mark",
+	bdquo:"double low-9 quotation mark",
+	dagger:"dagger",
+	Dagger:"double dagger",
+	permil:"per mille sign",
+	lsaquo:"single left-pointing angle quotation mark",
+	rsaquo:"single right-pointing angle quotation mark",
+	euro:"euro sign"
+})
diff --git a/dojox/editor/plugins/nls/hu/AutoSave.js b/dojox/editor/plugins/nls/hu/AutoSave.js
new file mode 100644
index 0000000..41d06c9
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Mentés",
+	"saveSettingLabelOn": "Automatikus mentés időközének beállítása...",
+	"saveSettingLabelOff": "Automatikus mentés kikapcsolása",
+	"saveSettingdialogTitle": "Automatikus mentés",
+	"saveSettingdialogDescription": "Automatikus mentés időközének megadása",
+	"saveSettingdialogParamName": "Automatikus mentés időköze",
+	"saveSettingdialogParamLabel": "perc",
+	"saveSettingdialogButtonOk": "Időköz beállítása",
+	"saveSettingdialogButtonCancel": "Mégse",
+	"saveMessageSuccess": "Mentés: ${0}",
+	"saveMessageFail": "Sikertelen mentés: ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/hu/Blockquote.js b/dojox/editor/plugins/nls/hu/Blockquote.js
new file mode 100644
index 0000000..e1271e1
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Idézet"
+})
+
diff --git a/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js b/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
new file mode 100644
index 0000000..6dd535e
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Szerkesztő eszköztár összezárása",
+	"expand": "Szerkesztő eszköztár kibontása"
+})
+
diff --git a/dojox/editor/plugins/nls/hu/FindReplace.js b/dojox/editor/plugins/nls/hu/FindReplace.js
index c5b879f..71e8644 100644
--- a/dojox/editor/plugins/nls/hu/FindReplace.js
+++ b/dojox/editor/plugins/nls/hu/FindReplace.js
@@ -1,12 +1,23 @@
 ({
-	"findLabel": "Keresés: ",
-	"replaceLabel": "Csere: ",
-	"findReplace": "Keresés/Csere váltása",
-	"matchCase": "Kis- és nagybetűk egyeztetése", 
+	"findLabel": "Keresés:",
+	"findTooltip": "Adja meg a keresett szöveget",
+	"replaceLabel": "Csere:",
+	"replaceTooltip": "Adja meg a cseréhez az új szöveget",
+	"findReplace": "Keresés és csere",
+	"matchCase": "Kis-nagybetűk egyeznek",
+	"matchCaseTooltip": "Kis-nagybetűk egyeznek",
 	"backwards": "Visszafelé",
-	"replaceAll": "Minden előfordulás", 
+	"backwardsTooltip": "Szöveg keresése visszafelé",
+	"replaceAll": "Minden előfordulás",
+	"replaceAllButton": "Mindent lecserél",
+	"replaceAllButtonTooltip": "Minden szöveg cseréje",
 	"findButton": "Keresés",
+	"findButtonTooltip": "Szöveg keresése",
 	"replaceButton": "Csere",
-	"replaceDialogText": "${0} előfordulás cseréje megtörtént. "
+	"replaceButtonTooltip": "Szöveg cseréje",
+	"replaceDialogText": "${0} előfordulás cseréje megtörtént.",
+	"eofDialogText": "Legutóbbi előfordulás: ${0}",
+	"eofDialogTextFind": "találat",
+	"eofDialogTextReplace": "cserélve"
 })
 
diff --git a/dojox/editor/plugins/nls/hu/InsertAnchor.js b/dojox/editor/plugins/nls/hu/InsertAnchor.js
new file mode 100644
index 0000000..1998bca
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Horgony beszúrása",
+	title: "Horgony tulajdonságai",
+	anchor: "Név:",
+	text: "Leírás:",
+	set: "Beállítás",
+	cancel: "Mégse"
+})
+
diff --git a/dojox/editor/plugins/nls/hu/LocalImage.js b/dojox/editor/plugins/nls/hu/LocalImage.js
new file mode 100644
index 0000000..c9c99b1
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Kép beszúrása",
+	url: "Kép",
+	browse: "Tallózás...",
+	text: "Leírás",
+	set: "Beszúrás",
+	invalidMessage: "Érvénytelen képfájltípus",
+	prePopuTextUrl: "Adja meg a kép URL címét",
+	prePopuTextBrowse: " vagy tallózással válasszon ki egy helyi fájlt."
+})
+
diff --git a/dojox/editor/plugins/nls/hu/PasteFromWord.js b/dojox/editor/plugins/nls/hu/PasteFromWord.js
new file mode 100644
index 0000000..f0ce2b5
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Beillesztés Word alkalmazásból",
+	"paste": "Beillesztés",
+	"cancel": "Mégse",
+	"instructions": "Illessze be a Word alkalmazás tartalmát az alábbi szövegmezőbe. Ha elégedett a beszúrandó tartalommal, akkor nyomja meg a beillesztés gombot. Szöveg beszúrásának megszakításához nyomja meg a mégse gombot."
+})
+
diff --git a/dojox/editor/plugins/nls/hu/Smiley.js b/dojox/editor/plugins/nls/hu/Smiley.js
index ff80909..dd55a73 100644
--- a/dojox/editor/plugins/nls/hu/Smiley.js
+++ b/dojox/editor/plugins/nls/hu/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "kacsintás",
 	emoticonGrin: "vigyor",
 	emoticonCool: "laza",
-	emoticonAngry: "mérges",  
-	emoticonHalf: "fél", 
+	emoticonAngry: "mérges",
+	emoticonHalf: "fél",
 	emoticonEyebrow: "szemöldök",
 	emoticonFrown: "rosszallás",
 	emoticonShy: "szégyenlős",
@@ -15,7 +15,7 @@
 	emoticonTongue: "nyelv",
 	emoticonIdea: "ötlet",
 	emoticonYes: "igen",
-	emoticonNo: "nem",	
+	emoticonNo: "nem",
 	emoticonAngel: "angyal",
 	emoticonCrying: "sírás"
 })
diff --git a/dojox/editor/plugins/nls/hu/SpellCheck.js b/dojox/editor/plugins/nls/hu/SpellCheck.js
new file mode 100644
index 0000000..9b29fc5
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Kötegelt helyesírás-ellenőrzés",
+	unfound: "Nem található",
+	skip: "Kihagyja",
+	skipAll: "Mindet kihagyja",
+	toDic: "Hozzáadás a szótárhoz",
+	suggestions: "Javaslatok",
+	replace: "Csere",
+	replaceWith: "Csere erre",
+	replaceAll: "Mindent lecserél",
+	cancel: "Mégse",
+	msg: "Nem található helyesírási hiba",
+	iSkip: "Ezt kihagyja",
+	iSkipAll: "Összes hasonlót kihagyja",
+	iMsg: "Nincsenek helyesírási javaslatok"
+})
+
diff --git a/dojox/editor/plugins/nls/hu/TableDialog.js b/dojox/editor/plugins/nls/hu/TableDialog.js
index 61078c1..3a134e4 100644
--- a/dojox/editor/plugins/nls/hu/TableDialog.js
+++ b/dojox/editor/plugins/nls/hu/TableDialog.js
@@ -1,15 +1,15 @@
 ({
 	insertTableTitle: "Táblázat beszúrása",
 	modifyTableTitle: "Táblázat módosítása",
-	rows: "Sorok: ",
-	columns: "Oszlopok: ",
-	align: "Igazítás: ",
-	cellPadding: "Cellakitöltés: ",
-	cellSpacing: "Cella térköz: ",
-	tableWidth: "Táblázat szélessége: ",
-	backgroundColor: "Háttérszín: ",
-	borderColor: "Szegélyszín: ",
-	borderThickness: "Szegély vastagsága ",
+	rows: "Sorok:",
+	columns: "Oszlopok:",
+	align: "Igazítás:",
+	cellPadding: "Cellakitöltés:",
+	cellSpacing: "Cella térköz:",
+	tableWidth: "Táblázat szélessége:",
+	backgroundColor: "Háttérszín:",
+	borderColor: "Szegélyszín:",
+	borderThickness: "Szegély vastagsága",
 	percent: "százalék",
 	pixels: "képpont",
 	"default": "alapértelmezett",
@@ -18,13 +18,13 @@
 	right: "jobbra",
 	buttonSet: "Beállítás", // translated elsewhere?
 	buttonInsert: "Beszúrás",
+	buttonCancel: "Mégse",
 
 	selectTableLabel: "Táblázat kijelölése",
 	insertTableRowBeforeLabel: "Sor hozzáadása előtte",
 	insertTableRowAfterLabel: "Sor hozzáadása utána",
 	insertTableColumnBeforeLabel: "Oszlop hozzáadása előtte",
 	insertTableColumnAfterLabel: "Oszlop hozzáadása utána",
-	deleteTableRowLabel: "Sor törlése ",
+	deleteTableRowLabel: "Sor törlése",
 	deleteTableColumnLabel: "Oszlop törlése"
 })
-
diff --git a/dojox/editor/plugins/nls/hu/TextColor.js b/dojox/editor/plugins/nls/hu/TextColor.js
new file mode 100644
index 0000000..890e9a0
--- /dev/null
+++ b/dojox/editor/plugins/nls/hu/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Beállítás",
+	"cancelButtonText": "Mégse"
+})
+
diff --git a/dojox/editor/plugins/nls/hu/latinEntities.js b/dojox/editor/plugins/nls/hu/latinEntities.js
index 5e40ef7..224bdf7 100644
--- a/dojox/editor/plugins/nls/hu/latinEntities.js
+++ b/dojox/editor/plugins/nls/hu/latinEntities.js
@@ -15,7 +15,7 @@
 	uml:"dupla ékezet\numlaut",
 	copy:"copyright jel",
 	ordf:"nőnemű sorszámnév jelzése a felső indexben",
-	laquo:"balra mutató dupla hegyes idézőjel\nbalra mutató belső idézőjel ",
+	laquo:"balra mutató dupla hegyes idézőjel\nbalra mutató belső idézőjel",
 	not:"nem jel",
 	shy:"lágy kötőjel\nfeltételes kötőjel",
 	reg:"védjegy jel\nbejegyzett védjegy jel",
@@ -38,123 +38,123 @@
 	iquest:"fordított kérdőjel\nmegfordított kérdőjel",
 	Agrave:"Latin nagy A betű tompa ékezettel\nTompa ékezetes latin nagy A betű",
 	Aacute:"Latin nagy A betű éles ékezettel",
-	Acirc:"Latin kalapos nagy A betű ",
+	Acirc:"Latin kalapos nagy A betű",
 	Atilde:"Latin hullámvonalas nagy A betű",
 	Auml:"Latin kétpontos nagy A betű",
 	Aring:"Latin nagy A betű felül körrel\nLatin nagy A betű felső körrel",
-	AElig:"Latin nagy AE\nLatin nagy AE ikerbetű  ",
-	Ccedil:"Latin nagy C betű cedillel ",
+	AElig:"Latin nagy AE\nLatin nagy AE ikerbetű",
+	Ccedil:"Latin nagy C betű cedillel",
 	Egrave:"Latin nagy E betű tompa ékezettel",
 	Eacute:"Latin nagy E betű éles ékezettel",
-	Ecirc:"Latin kalapos nagy E betű ",
+	Ecirc:"Latin kalapos nagy E betű",
 	Euml:"Latin kétpontos nagy E betű",
 	Igrave:"Latin nagy I betű tompa ékezettel",
 	Iacute:"Latin nagy I betű éles ékezettel",
-	Icirc:"Latin kalapos nagy I betű ",
+	Icirc:"Latin kalapos nagy I betű",
 	Iuml:"Latin kétpontos nagy I betű",
-	ETH:"Latin nagy ETH betű ",
+	ETH:"Latin nagy ETH betű",
 	Ntilde:"Latin hullámvonalas nagy N betű",
 	Ograve:"Latin nagy O betű tompa ékezettel",
 	Oacute:"Latin nagy O betű éles ékezettel",
-	Ocirc:"Latin kalapos nagy O betű ",
+	Ocirc:"Latin kalapos nagy O betű",
 	Otilde:"Latin hullámvonalas nagy O betű",
 	Ouml:"Latin kétpontos nagy O betű",
 	times:"szorzásjel",
 	Oslash:"Latin áthúzott nagy O betű\nLatin nagy O betű osztásjellel",
 	Ugrave:"Latin nagy U betű tompa ékezettel",
 	Uacute:"Latin nagy U betű éles ékezettel",
-	Ucirc:"Latin kalapos nagy U betű ",
+	Ucirc:"Latin kalapos nagy U betű",
 	Uuml:"Latin kétpontos nagy U betű",
 	Yacute:"Latin nagy Y betű éles ékezettel",
-	THORN:"Latin nagy THORN betű  ",
+	THORN:"Latin nagy THORN betű",
 	szlig:"Latin kis sharfes s\neszett",
 	agrave:"Latin kis a betű tompa ékezettel\nTompa ékezetes latin kis a betű",
 	aacute:"Latin kis a betű éles ékezettel",
-	acirc:"Latin kalapos kis a betű ",
+	acirc:"Latin kalapos kis a betű",
 	atilde:"Latin hullámvonalas kis a betű",
 	auml:"Latin kétpontos kis a betű",
 	aring:"Latin kis a betű felül körrel\nLatin kis a betű felső körrel",
-	aelig:"Latin kis ae betű\nLatin kis ae ikerbetű  ",
-	ccedil:"Latin kis c betű cedillel ",
+	aelig:"Latin kis ae betű\nLatin kis ae ikerbetű",
+	ccedil:"Latin kis c betű cedillel",
 	egrave:"Latin kis e betű tompa ékezettel",
 	eacute:"Latin kis e betű éles ékezettel",
-	ecirc:"Latin kalapos kis e betű ",
+	ecirc:"Latin kalapos kis e betű",
 	euml:"Latin kétpontos kis e betű",
 	igrave:"Latin kis i betű tompa ékezettel",
 	iacute:"Latin kis i betű éles ékezettel",
-	icirc:"Latin kalapos kis i betű ",
+	icirc:"Latin kalapos kis i betű",
 	iuml:"Latin kétpontos kis i betű",
-	eth:"Latin kis eth betű ",
+	eth:"Latin kis eth betű",
 	ntilde:"Latin hullámvonalas kis n betű",
 	ograve:"Latin kis o betű tompa ékezettel",
 	oacute:"Latin kis o betű éles ékezettel",
-	ocirc:"Latin kalapos kis o betű ",
+	ocirc:"Latin kalapos kis o betű",
 	otilde:"Latin hullámvonalas kis o betű",
 	ouml:"Latin kétpontos kis o betű",
-	divide:"osztásjel ",
+	divide:"osztásjel",
 	oslash:"Latin áthúzott kis o betű\nLatin kis o betű osztásjellel",
 	ugrave:"Latin kis u betű tompa ékezettel",
 	uacute:"Latin kis u betű éles ékezettel",
-	ucirc:"Latin kalapos kis u betű ",
+	ucirc:"Latin kalapos kis u betű",
 	uuml:"Latin kétpontos kis u betű",
 	yacute:"Latin kis y éles ékezettel",
-	thorn:"Latin kis thorn betű ",
-	yuml:"Latin kétpontos kis y ",
+	thorn:"Latin kis thorn betű",
+	yuml:"Latin kétpontos kis y",
 
 // Greek Characters and Symbols
 	fnof:"Latin kis f horoggal\nfüggvény\nforint",
 	Alpha:"Görög nagy alfa betű",
-	Beta:"Görög nagy béta betű ",
+	Beta:"Görög nagy béta betű",
 	Gamma:"Görög nagy gamma betű",
-	Delta:"Görög nagy delta betű ",
+	Delta:"Görög nagy delta betű",
 	Epsilon:"Görög nagy epszilon betű",
-	Zeta:"Görög nagy dzéta betű ",
-	Eta:"Görög nagy éta betű ",
-	Theta:"Görög nagy théta betű ",
-	Iota:"Görög nagy iota betű ",
-	Kappa:"Görög nagy kappa betű ",
-	Lambda:"Görög nagy lambda betű ",
-	Mu:"Görög nagy mű betű ",
-	Nu:"Görög nagy nű betű ",
-	Xi:"Görög nagy kszí betű ",
-	Omicron:"Görög nagy omikron betű ",
-	Pi:"Görög nagy pi betű ",
-	Rho:"Görög nagy ró betű ",
-	Sigma:"Görög nagy szigma betű ",
-	Tau:"Görög nagy tau betű ",
-	Upsilon:"Görög nagy üpszilon betű ",
-	Phi:"Görög nagy fí betű ",
-	Chi:"Görög nagy khí betű ",
-	Psi:"Görög nagy pszí betű ",
-	Omega:"Görög nagy ómega betű ",
+	Zeta:"Görög nagy dzéta betű",
+	Eta:"Görög nagy éta betű",
+	Theta:"Görög nagy théta betű",
+	Iota:"Görög nagy iota betű",
+	Kappa:"Görög nagy kappa betű",
+	Lambda:"Görög nagy lambda betű",
+	Mu:"Görög nagy mű betű",
+	Nu:"Görög nagy nű betű",
+	Xi:"Görög nagy kszí betű",
+	Omicron:"Görög nagy omikron betű",
+	Pi:"Görög nagy pi betű",
+	Rho:"Görög nagy ró betű",
+	Sigma:"Görög nagy szigma betű",
+	Tau:"Görög nagy tau betű",
+	Upsilon:"Görög nagy üpszilon betű",
+	Phi:"Görög nagy fí betű",
+	Chi:"Görög nagy khí betű",
+	Psi:"Görög nagy pszí betű",
+	Omega:"Görög nagy ómega betű",
 	alpha:"Görög kis alfa betű",
-	beta:"Görög kis béta betű ",
+	beta:"Görög kis béta betű",
 	gamma:"Görög kis gamma betű",
-	delta:"Görög kis delta betű ",
+	delta:"Görög kis delta betű",
 	epsilon:"Görög kis epszilon betű",
-	zeta:"Görög kis dzéta betű ",
+	zeta:"Görög kis dzéta betű",
 	eta:"Görög kis éta betű",
-	theta:"Görög kis théta betű ",
-	iota:"Görög kis ióta betű ",
-	kappa:"Görög kis kappa betű ",
-	lambda:"Görög kis lambda betű ",
-	mu:"Görög kis mű betű ",
-	nu:"Görög kis nű betű ",
-	xi:"Görög kis kszí betű ",
-	omicron:"Görög kis omikron betű ",
-	pi:"Görög kis pí betű ",
-	rho:"Görög kis ró betű ",
+	theta:"Görög kis théta betű",
+	iota:"Görög kis ióta betű",
+	kappa:"Görög kis kappa betű",
+	lambda:"Görög kis lambda betű",
+	mu:"Görög kis mű betű",
+	nu:"Görög kis nű betű",
+	xi:"Görög kis kszí betű",
+	omicron:"Görög kis omikron betű",
+	pi:"Görög kis pí betű",
+	rho:"Görög kis ró betű",
 	sigmaf:"Görög kis szigma betű utolsó helyen",
-	sigma:"Görög kis szigma betű  ",
-	tau:"Görög kis taú betű ",
-	upsilon:"Görög kis üpszilon betű ",
-	phi:"Görög kis fí betű ",
-	chi:"Görög kis khí betű ",
-	psi:"Görög kis pszí betű ",
-	omega:"Görög kis ómega betű ",
-	thetasym:"Görög kis théta betű szimbólum ",
-	upsih:"Görög üpszilon horog szimbólummal ",
-	piv:"Görög pí szimbólum ",
+	sigma:"Görög kis szigma betű",
+	tau:"Görög kis taú betű",
+	upsilon:"Görög kis üpszilon betű",
+	phi:"Görög kis fí betű",
+	chi:"Görög kis khí betű",
+	psi:"Görög kis pszí betű",
+	omega:"Görög kis ómega betű",
+	thetasym:"Görög kis théta betű szimbólum",
+	upsih:"Görög üpszilon horog szimbólummal",
+	piv:"Görög pí szimbólum",
 	bull:"pont felsorolásjel\nkis fekete kör",
 	hellip:"vízszintes hármaspont\nbevezető hármas pont",
 	prime:"szimpla egyenes idézőjel\nperc\nláb",
@@ -174,7 +174,7 @@
 	crarr:"lefelé mutató nyíl bal oldalon sarokkal\nsoremelés",
 	lArr:"balra mutató dupla nyíl",
 	uArr:"felfelé mutató dupla nyíl",
-	rArr:"jobbra mutató dupla nyíl ",
+	rArr:"jobbra mutató dupla nyíl",
 	dArr:"lefelé mutató dupla nyíl",
 	hArr:"balra-jobbra mutató dupla nyíl",
 	forall:"minden\nfordított nagy A betű",
@@ -182,15 +182,15 @@
 	exist:"létezik",
 	empty:"üres halmaz\nnull halmaz\nátmérő",
 	nabla:"nabla\nfordított különbség",
-	isin:"eleme ",
-	notin:"nem eleme ",
-	ni:"tagként tartalmazza ",
+	isin:"eleme",
+	notin:"nem eleme",
+	ni:"tagként tartalmazza",
 	prod:"n-tagú Descartes szorzat\nszorzatjel",
 	sum:"n-tagú összegzés",
 	minus:"mínusz jel",
 	lowast:"csillag operátor",
 	radic:"négyzetgyök\nnégyzetgyök jel",
-	prop:"arányos ",
+	prop:"arányos",
 	infin:"végtelen",
 	ang:"szög",
 	and:"logikai és\nék",
@@ -206,7 +206,7 @@
 	le:"kisebb vagy egyenlő",
 	ge:"nagyobb vagy egyenlő",
 	sub:"részhalmaza",
-	sup:"bővített halmaza ",
+	sup:"bővített halmaza",
 	nsub:"nem részhalmaza",
 	sube:"részhalmaza vagy egyenlő",
 	supe:"bővített halmaza vagy egyenlő",
@@ -221,15 +221,15 @@
 	lang:"balra mutató hegyes zárójel",
 	rang:"jobbra mutató hegyes zárójel",
 	loz:"rombusz",
-	spades:"fekete pikk kártyajel ",
+	spades:"fekete pikk kártyajel",
 	clubs:"fekete treff kártyjel\nlóhere",
 	hearts:"fekete kör kártyajel\nszívalak",
 	diams:"fekete káró káryajel",
-	OElig:"Latin nagy OE ikerbetű ",
-	oelig:"Latin kis oe ikerbetű ",
+	OElig:"Latin nagy OE ikerbetű",
+	oelig:"Latin kis oe ikerbetű",
 	Scaron:"Latin nagy S betű csónakkal",
 	scaron:"Latin kis s betű csónakkal",
-	Yuml:"Latin kétpontos nagy Y betű ",
+	Yuml:"Latin kétpontos nagy Y betű",
 	circ:"betűt módosító kalap ékezet",
 	tilde:"kis hullám",
 	ensp:"n szóköz",
@@ -248,7 +248,7 @@
 	rdquo:"jobb dupla idézőjel",
 	bdquo:"alsó 9-es dupla idézőjel",
 	dagger:"kereszt",
-	Dagger:"dupla kereszt ",
+	Dagger:"dupla kereszt",
 	permil:"ezrelékjel",
 	lsaquo:"szimpla balra mutató hegyes idézőjel",
 	rsaquo:"szimpla jobbra mutató hegyes idézőjel",
diff --git a/dojox/editor/plugins/nls/it/AutoSave.js b/dojox/editor/plugins/nls/it/AutoSave.js
new file mode 100644
index 0000000..10697ae
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Salva",
+	"saveSettingLabelOn": "Imposta intervallo di salvataggio automatico...",
+	"saveSettingLabelOff": "Disattiva salvataggio automatico",
+	"saveSettingdialogTitle": "Salvataggio automatico",
+	"saveSettingdialogDescription": "Specifica intervallo di salvataggio automatico",
+	"saveSettingdialogParamName": "Intervallo di salvataggio automatico",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Imposta intervallo",
+	"saveSettingdialogButtonCancel": "Annulla",
+	"saveMessageSuccess": "Salvato alle ${0}",
+	"saveMessageFail": "Salvataggio alle ${0} non riuscito"
+})
+
diff --git a/dojox/editor/plugins/nls/it/Blockquote.js b/dojox/editor/plugins/nls/it/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/it/CollapsibleToolbar.js b/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
new file mode 100644
index 0000000..0c91077
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Comprimi la barra degli strumenti dell'editor",
+	"expand": "Espandi la barra degli strumenti dell'editor"
+})
+
diff --git a/dojox/editor/plugins/nls/it/FindReplace.js b/dojox/editor/plugins/nls/it/FindReplace.js
index 29f5a5e..7a60ef5 100644
--- a/dojox/editor/plugins/nls/it/FindReplace.js
+++ b/dojox/editor/plugins/nls/it/FindReplace.js
@@ -1,12 +1,23 @@
 ({
 	"findLabel": "Trova:",
+	"findTooltip": "Immettere il testo da trovare",
 	"replaceLabel": "Sostituisci con:",
-	"findReplace": "Mostra/Nascondi Trova/Sostituisci",
-	"matchCase": "Maiuscole/minuscole", 
+	"replaceTooltip": "Immettere il testo sostitutivo",
+	"findReplace": "Trova e sostituisci",
+	"matchCase": "Maiuscole/minuscole",
+	"matchCaseTooltip": "Maiuscole/minuscole",
 	"backwards": "Indietro",
-	"replaceAll": "Tutte le occorrenze", 
+	"backwardsTooltip": "Cerca testo indietro",
+	"replaceAll": "Tutte le ricorrenze",
+	"replaceAllButton": "Sostituisci tutto",
+	"replaceAllButtonTooltip": "Sostituisci tutto il testo",
 	"findButton": "Trova",
+	"findButtonTooltip": "Trova il testo",
 	"replaceButton": "Sostituisci",
-	"replaceDialogText": "Occorrenze sostituite: ${0}."
+	"replaceButtonTooltip": "Sostituisci il testo",
+	"replaceDialogText": "${0} ricorrenze sostituite.",
+	"eofDialogText": "Ultima ricorrenza ${0}",
+	"eofDialogTextFind": "trovato",
+	"eofDialogTextReplace": "sostituito"
 })
 
diff --git a/dojox/editor/plugins/nls/it/InsertAnchor.js b/dojox/editor/plugins/nls/it/InsertAnchor.js
new file mode 100644
index 0000000..2b1f40d
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Inserisci ancoraggio",
+	title: "Proprietà ancoraggio",
+	anchor: "Nome:",
+	text: "Descrizione:",
+	set: "Imposta",
+	cancel: "Annulla"
+})
+
diff --git a/dojox/editor/plugins/nls/it/LocalImage.js b/dojox/editor/plugins/nls/it/LocalImage.js
new file mode 100644
index 0000000..ba09478
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Inserisci immagine",
+	url: "Immagine",
+	browse: "Sfoglia...",
+	text: "Descrizione",
+	set: "Inserisci",
+	invalidMessage: "Tipo di file immagine non valido",
+	prePopuTextUrl: "Immettere un URL immagine",
+	prePopuTextBrowse: " o individuare un file locale."
+})
+
diff --git a/dojox/editor/plugins/nls/it/PasteFromWord.js b/dojox/editor/plugins/nls/it/PasteFromWord.js
new file mode 100644
index 0000000..0c856ff
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Incolla da Word",
+	"paste": "Incolla",
+	"cancel": "Annulla",
+	"instructions": "Incolla il contenuto da Word nella casella di testo sottostante. Al termine dell'inserimento del contenuto, premere il pulsante Incolla. Per annullare l'inserimento del testo, premere il pulsante Annulla."
+})
+
diff --git a/dojox/editor/plugins/nls/it/Smiley.js b/dojox/editor/plugins/nls/it/Smiley.js
index 0e9b446..c01a814 100644
--- a/dojox/editor/plugins/nls/it/Smiley.js
+++ b/dojox/editor/plugins/nls/it/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "occhiolino",
 	emoticonGrin: "ghigno",
 	emoticonCool: "figo",
-	emoticonAngry: "arrabbiato",  
-	emoticonHalf: "metà", 
+	emoticonAngry: "arrabbiato",
+	emoticonHalf: "metà",
 	emoticonEyebrow: "sopracciglia",
 	emoticonFrown: "triste",
 	emoticonShy: "timido",
@@ -15,7 +15,7 @@
 	emoticonTongue: "linguaccia",
 	emoticonIdea: "idea",
 	emoticonYes: "yes",
-	emoticonNo: "no",	
+	emoticonNo: "no",
 	emoticonAngel: "angelo",
 	emoticonCrying: "in lacrime"
 })
diff --git a/dojox/editor/plugins/nls/it/SpellCheck.js b/dojox/editor/plugins/nls/it/SpellCheck.js
new file mode 100644
index 0000000..4546c0b
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Controllo ortografico batch",
+	unfound: "Non trovato",
+	skip: "Ignora",
+	skipAll: "Ignora tutto",
+	toDic: "Aggiungi al dizionario",
+	suggestions: "Suggerimenti",
+	replace: "Sostituisci",
+	replaceWith: "Sostituisci con",
+	replaceAll: "Sostituisci tutto",
+	cancel: "Annulla",
+	msg: "Nessun errore di ortografia trovato",
+	iSkip: "Ignora",
+	iSkipAll: "Ignora tutto",
+	iMsg: "Nessun suggerimento ortografico"
+})
+
diff --git a/dojox/editor/plugins/nls/it/TableDialog.js b/dojox/editor/plugins/nls/it/TableDialog.js
index 8fafa9e..293c6d8 100644
--- a/dojox/editor/plugins/nls/it/TableDialog.js
+++ b/dojox/editor/plugins/nls/it/TableDialog.js
@@ -4,13 +4,13 @@
 	rows: "Righe:",
 	columns: "Colonne:",
 	align: "Allinea:",
-	cellPadding: "Riempimento cella:",
+	cellPadding: "Padding celle:",
 	cellSpacing: "Spaziatura celle:",
-	tableWidth: "Larghezza tabella:",
-	backgroundColor: "Colore sfondo:",
-	borderColor: "Colore bordo:",
-	borderThickness: "Spessore bordo",
-	percent: "percento",
+	tableWidth: "Larghezza tabelle:",
+	backgroundColor: "Colore di sfondo:",
+	borderColor: "Colore bordi:",
+	borderThickness: "Spessore bordi",
+	percent: "percentuale",
 	pixels: "pixel",
 	"default": "predefinito",
 	left: "sinistra",
@@ -18,13 +18,15 @@
 	right: "destra",
 	buttonSet: "Imposta", // translated elsewhere?
 	buttonInsert: "Inserisci",
+	buttonCancel: "Annulla",
 
 	selectTableLabel: "Seleziona tabella",
-	insertTableRowBeforeLabel: "Inserisci riga prima",
-	insertTableRowAfterLabel: "Inserisci riga dopo",
+	insertTableRowBeforeLabel: "Aggiungi riga prima",
+	insertTableRowAfterLabel: "Aggiungi riga dopo",
 	insertTableColumnBeforeLabel: "Aggiungi colonna prima",
 	insertTableColumnAfterLabel: "Aggiungi colonna dopo",
 	deleteTableRowLabel: "Elimina riga",
 	deleteTableColumnLabel: "Elimina colonna"
 })
+	
 
diff --git a/dojox/editor/plugins/nls/it/TextColor.js b/dojox/editor/plugins/nls/it/TextColor.js
new file mode 100644
index 0000000..af28fa6
--- /dev/null
+++ b/dojox/editor/plugins/nls/it/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Imposta",
+	"cancelButtonText": "Annulla"
+})
+
diff --git a/dojox/editor/plugins/nls/ja/AutoSave.js b/dojox/editor/plugins/nls/ja/AutoSave.js
new file mode 100644
index 0000000..5c0cc4b
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/AutoSave.js
@@ -0,0 +1,13 @@
+({
+	"saveLabel": "保存",
+	"saveSettingLabelOn": "自動保存間隔の設定...",
+	"saveSettingLabelOff": "自動保存をオフにする",
+	"saveSettingdialogTitle": "自動保存",
+	"saveSettingdialogDescription": "自動保存間隔の指定",
+	"saveSettingdialogParamName": "自動保存間隔",
+	"saveSettingdialogParamLabel": "分",
+	"saveSettingdialogButtonOk": "間隔の設定",
+	"saveSettingdialogButtonCancel": "キャンセル",
+	"saveMessageSuccess": "${0} に保存されました",
+	"saveMessageFail": "${0} に保存に失敗しました"
+})
diff --git a/dojox/editor/plugins/nls/ja/Blockquote.js b/dojox/editor/plugins/nls/ja/Blockquote.js
new file mode 100644
index 0000000..deaf4d9
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/Blockquote.js
@@ -0,0 +1,3 @@
+({
+	"blockquote": "引用"
+})
diff --git a/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
new file mode 100644
index 0000000..ba03720
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/CollapsibleToolbar.js
@@ -0,0 +1,4 @@
+({
+	"collapse": "エディターのツールバーを省略",
+	"expand": "エディターのツールバーを展開"
+})
diff --git a/dojox/editor/plugins/nls/ja/FindReplace.js b/dojox/editor/plugins/nls/ja/FindReplace.js
index e5bd6fc..21b7bf9 100644
--- a/dojox/editor/plugins/nls/ja/FindReplace.js
+++ b/dojox/editor/plugins/nls/ja/FindReplace.js
@@ -1,12 +1,22 @@
 ({
 	"findLabel": "検索内容:",
+	"findTooltip": "検索するテキストを入力",
 	"replaceLabel": "次で置換:",
+	"replaceTooltip": "置換するテキストを入力",
 	"findReplace": "検索/置換の切り替え",
-	"matchCase": "大/小文字を区別", 
+	"matchCase": "大/小文字の区別",
+	"matchCaseTooltip": "大/小文字を区別",
 	"backwards": "後方",
-	"replaceAll": "すべてのオカレンス", 
+	"backwardsTooltip": "テキストを後方検索",
+	"replaceAll": "すべてのオカレンス",
+	"replaceAllButton": "すべてを置換",
+	"replaceAllButtonTooltip": "テキストすべてを置換",
 	"findButton": "検索",
+	"findButtonTooltip": "テキストを検索",
 	"replaceButton": "置換",
-	"replaceDialogText": "${0} 個のオカレンスを置換しました。"
+	"replaceButtonTooltip": "テキストを置換",
+	"replaceDialogText": "${0} 個のオカレンスを置換しました。",
+	"eofDialogText": "最後のオカレンス ${0}",
+	"eofDialogTextFind": "見つかりました",
+	"eofDialogTextReplace": "置換されました"
 })
-
diff --git a/dojox/editor/plugins/nls/ja/InsertAnchor.js b/dojox/editor/plugins/nls/ja/InsertAnchor.js
new file mode 100644
index 0000000..fdb8455
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/InsertAnchor.js
@@ -0,0 +1,8 @@
+({
+	insertAnchor: "アンカーの挿入",
+	title: "アンカー・プロパティー",
+	anchor: "名前:",
+	text: "説明:",
+	set: "設定",
+	cancel: "キャンセル"
+})
diff --git a/dojox/editor/plugins/nls/ja/LocalImage.js b/dojox/editor/plugins/nls/ja/LocalImage.js
new file mode 100644
index 0000000..aec866f
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/LocalImage.js
@@ -0,0 +1,10 @@
+({
+	insertImageTitle: "イメージの挿入",
+	url: "イメージ",
+	browse: "参照...",
+	text: "説明",
+	set: "挿入",
+	invalidMessage: "無効なイメージ・ファイル・タイプです",
+	prePopuTextUrl: "イメージ URL を入力するか、",
+	prePopuTextBrowse: "ローカル・ファイルを参照してください。"
+})
diff --git a/dojox/editor/plugins/nls/ja/PasteFromWord.js b/dojox/editor/plugins/nls/ja/PasteFromWord.js
new file mode 100644
index 0000000..bc277c7
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/PasteFromWord.js
@@ -0,0 +1,6 @@
+({
+	"pasteFromWord": "Word からの貼り付け",
+	"paste": "貼り付け",
+	"cancel": "キャンセル",
+	"instructions": "Word のコンテンツを以下のテキスト・ボックスに貼り付けてください。挿入するコンテンツを確認したら、貼り付けボタンを押します。テキストの挿入を中止するには、キャンセル・ボタンを押します。"
+})
diff --git a/dojox/editor/plugins/nls/ja/Smiley.js b/dojox/editor/plugins/nls/ja/Smiley.js
index e39cbf1..411d64e 100644
--- a/dojox/editor/plugins/nls/ja/Smiley.js
+++ b/dojox/editor/plugins/nls/ja/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "ウィンク",
 	emoticonGrin: "笑顔",
 	emoticonCool: "無愛想",
-	emoticonAngry: "怒り",  
-	emoticonHalf: "半分", 
+	emoticonAngry: "怒り",
+	emoticonHalf: "半分",
 	emoticonEyebrow: "眉毛",
 	emoticonFrown: "眉をひそめる",
 	emoticonShy: "はにかんだ",
@@ -15,7 +15,7 @@
 	emoticonTongue: "舌を出す",
 	emoticonIdea: "アイデア",
 	emoticonYes: "はい",
-	emoticonNo: "いいえ",	
+	emoticonNo: "いいえ",
 	emoticonAngel: "エンジェル",
 	emoticonCrying: "泣く"
 })
diff --git a/dojox/editor/plugins/nls/ja/SpellCheck.js b/dojox/editor/plugins/nls/ja/SpellCheck.js
new file mode 100644
index 0000000..d1a2768
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/SpellCheck.js
@@ -0,0 +1,16 @@
+({
+	widgetLabel: "一括スペル・チェック",
+	unfound: "見つかりません",
+	skip: "スキップ",
+	skipAll: "すべてをスキップ",
+	toDic: "辞書に追加",
+	suggestions: "修正候補",
+	replace: "置換",
+	replaceWith: "置き換え",
+	replaceAll: "すべてを置換",
+	cancel: "キャンセル",
+	msg: "ミススペルはありません",
+	iSkip: "これをスキップ",
+	iSkipAll: "これと類似のものをスキップ",
+	iMsg: "スペルの修正候補はありません"
+})
diff --git a/dojox/editor/plugins/nls/ja/TableDialog.js b/dojox/editor/plugins/nls/ja/TableDialog.js
index 8e193fc..644850e 100644
--- a/dojox/editor/plugins/nls/ja/TableDialog.js
+++ b/dojox/editor/plugins/nls/ja/TableDialog.js
@@ -1,30 +1,31 @@
 ({
 	insertTableTitle: "テーブルの挿入",
 	modifyTableTitle: "テーブルの変更",
-	rows: "行",
-	columns: "列",
-	align: "位置合わせ",
+	rows: "行:",
+	columns: "列:",
+	align: "位置合わせ:",
 	cellPadding: "セル余白:",
 	cellSpacing: "セル間隔:",
-	tableWidth: "テーブルの幅:",
+	tableWidth: "テーブル幅:",
 	backgroundColor: "背景色:",
-	borderColor: "ボーダー色:",
-	borderThickness: "ボーダー線幅",
+	borderColor: "ボーダーの色:",
+	borderThickness: "ボーダーの太さ",
 	percent: "パーセント",
 	pixels: "ピクセル",
-	"default": "default",
+	"default": "デフォルト",
 	left: "左",
 	center: "中央",
 	right: "右",
 	buttonSet: "設定", // translated elsewhere?
 	buttonInsert: "挿入",
+	buttonCancel: "キャンセル",
 
 	selectTableLabel: "テーブルの選択",
-	insertTableRowBeforeLabel: "行を前に追加",
-	insertTableRowAfterLabel: "行を後に追加",
-	insertTableColumnBeforeLabel: "列を前に追加",
-	insertTableColumnAfterLabel: "列を後に追加",
+	insertTableRowBeforeLabel: "前に行を追加",
+	insertTableRowAfterLabel: "後ろに行を追加",
+	insertTableColumnBeforeLabel: "前に列を追加",
+	insertTableColumnAfterLabel: "後ろに列を追加",
 	deleteTableRowLabel: "行の削除",
 	deleteTableColumnLabel: "列の削除"
 })
-
+	
diff --git a/dojox/editor/plugins/nls/ja/TextColor.js b/dojox/editor/plugins/nls/ja/TextColor.js
new file mode 100644
index 0000000..a59d4e7
--- /dev/null
+++ b/dojox/editor/plugins/nls/ja/TextColor.js
@@ -0,0 +1,4 @@
+({
+	"setButtonText": "設定",
+	"cancelButtonText": "キャンセル"
+})
diff --git a/dojox/editor/plugins/nls/kk/AutoSave.js b/dojox/editor/plugins/nls/kk/AutoSave.js
new file mode 100644
index 0000000..19c3fc0
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Сақтау",
+	"saveSettingLabelOn": "Автосақтау аралығын орнату...",
+	"saveSettingLabelOff": "Автосақтауды өшіру",
+	"saveSettingdialogTitle": "Автосақтау",
+	"saveSettingdialogDescription": "Автосақтау аралығын көрсету",
+	"saveSettingdialogParamName": "Автосақтау аралығы",
+	"saveSettingdialogParamLabel": "мин",
+	"saveSettingdialogButtonOk": "Аралықты орнату",
+	"saveSettingdialogButtonCancel": "Болдырмау",
+	"saveMessageSuccess": "${0} сақталды",
+	"saveMessageFail": "${0} сақталмады"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/Blockquote.js b/dojox/editor/plugins/nls/kk/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/Breadcrumb.js b/dojox/editor/plugins/nls/kk/Breadcrumb.js
new file mode 100644
index 0000000..c567e05
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} Әрекеттер",
+	"selectContents": "Мазмұнын таңдау",
+	"selectElement": "Элементті таңдау",
+	"deleteElement": "Элементті жою",
+	"deleteContents": "Мазмұнын жою",
+	"moveStart": "Жүгіргіні басына жылжыту",
+	"moveEnd": "Жүгіргіні аяғына жылжыту"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js b/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
new file mode 100644
index 0000000..9bc93bb
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Өңдегіш құралдар тақтасын тасалау",
+	"expand": "Өңдегіш құралдар тақтасын шығарып алу"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/FindReplace.js b/dojox/editor/plugins/nls/kk/FindReplace.js
new file mode 100644
index 0000000..33f64c2
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Табу:",
+	"findTooltip": "Табылатын мәтінді енгізу",
+	"replaceLabel": "Келесімен ауыстыру:",
+	"replaceTooltip": "Ауыстырылатын мәтінді енгізу",
+	"findReplace": "Табу және ауыстыру",
+	"matchCase": "Үлкен-кішілігін ескеріп",
+	"matchCaseTooltip": "Үлкен-кішілігін ескеріп",
+	"backwards": "Артқа қарай",
+	"backwardsTooltip": "Мәтінді табу үшін артқа қарай іздеу",
+	"replaceAll": "Барлық оқиғалар",
+	"replaceAllButton": "Барлығын ауыстыру",
+	"replaceAllButtonTooltip": "Барлық мәтінді ауыстыру",
+	"findButton": "Табу",
+	"findButtonTooltip": "Мәтінді табу",
+	"replaceButton": "Ауыстыру",
+	"replaceButtonTooltip": "Мәтінді ауыстыру",
+	"replaceDialogText": "${0} дана ауыстырылды.",
+	"eofDialogText": "Соңғы дана: ${0}",
+	"eofDialogTextFind": "табылды",
+	"eofDialogTextReplace": "ауыстырылды"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/InsertAnchor.js b/dojox/editor/plugins/nls/kk/InsertAnchor.js
new file mode 100644
index 0000000..be15181
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Бетбелгі кірістіру",
+	title: "Бетбелгі сипаттары",
+	anchor: "Аты:",
+	text: "Сипаттама:",
+	set: "Орнату",
+	cancel: "Болдырмау"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/InsertEntity.js b/dojox/editor/plugins/nls/kk/InsertEntity.js
new file mode 100644
index 0000000..588f2c7
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Нышанды кірістіру"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/LocalImage.js b/dojox/editor/plugins/nls/kk/LocalImage.js
new file mode 100644
index 0000000..9a9fa10
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Сурет кірістіру",
+	url: "Кескін",
+	browse: "Шолу...",
+	text: "Сипаттама",
+	set: "Кірістіру",
+	invalidMessage: "Кескін файлының түрі дұрыс емес",
+	prePopuTextUrl: "Кескіннің URL мекен-жайын енгізіңіз",
+	prePopuTextBrowse: " немесе жергілікті файлға өтіңіз."
+})
+
diff --git a/dojox/editor/plugins/nls/kk/PageBreak.js b/dojox/editor/plugins/nls/kk/PageBreak.js
new file mode 100644
index 0000000..68d46b0
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Бет үзілімі"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/PasteFromWord.js b/dojox/editor/plugins/nls/kk/PasteFromWord.js
new file mode 100644
index 0000000..de8c8c2
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Word бағдарламасынан қою",
+	"paste": "Қою",
+	"cancel": "Болдырмау",
+	"instructions": "Мазмұнды Word бағдарламасынан төмендегі мәтін ұясына қойыңыз.  Кірістірілетін мазмұн дұрыс болса, қою түймешігін басыңыз.  Мәтінді кірістіруді доғару үшін болдырмау түймешігін басыңыз."
+})
+
diff --git a/dojox/editor/plugins/nls/kk/Preview.js b/dojox/editor/plugins/nls/kk/Preview.js
new file mode 100644
index 0000000..1cb20dd
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Алдын ала қарау"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/Save.js b/dojox/editor/plugins/nls/kk/Save.js
new file mode 100644
index 0000000..1d871dc
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Сақтау"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/ShowBlockNodes.js b/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
new file mode 100644
index 0000000..3f6913c
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "HTML блогы элементтерін көрсету"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/Smiley.js b/dojox/editor/plugins/nls/kk/Smiley.js
new file mode 100644
index 0000000..6552abd
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Эмограмма енгізу",
+	emoticonSmile: "күлімсіреу",
+	emoticonLaughing: "күлу",
+	emoticonWink: "көз қысу",
+	emoticonGrin: "ақситу",
+	emoticonCool: "салқын",
+	emoticonAngry: "ашулы",
+	emoticonHalf: "жарты",
+	emoticonEyebrow: "қас",
+	emoticonFrown: "қабағы түйілу",
+	emoticonShy: "ұялшақ",
+	emoticonGoofy: "ақымақ",
+	emoticonOops: "ой",
+	emoticonTongue: "тіл",
+	emoticonIdea: "ой",
+	emoticonYes: "иә",
+	emoticonNo: "ешбір",
+	emoticonAngel: "періште",
+	emoticonCrying: "жылау"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/SpellCheck.js b/dojox/editor/plugins/nls/kk/SpellCheck.js
new file mode 100644
index 0000000..f275c14
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Бума емлесін тексеру",
+	unfound: "Табылмады",
+	skip: "Өткізіп жіберу",
+	skipAll: "Барлығын өткізіп жіберу",
+	toDic: "Сөздікке қосу",
+	suggestions: "Ұсыныстар",
+	replace: "Ауыстыру",
+	replaceWith: "Келесімен ауыстыру",
+	replaceAll: "Барлығын ауыстыру",
+	cancel: "Болдырмау",
+	msg: "Қате жазылған сөздер табылмады",
+	iSkip: "Бұны өткізіп жіберу",
+	iSkipAll: "Осы сияқты барлығын өткізіп жіберу",
+	iMsg: "Емле ұсыныстары жоқ"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/TableDialog.js b/dojox/editor/plugins/nls/kk/TableDialog.js
new file mode 100644
index 0000000..410658a
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/TableDialog.js
@@ -0,0 +1,32 @@
+({
+	insertTableTitle: "Кесте кірістіру",
+	modifyTableTitle: "Кестені өзгерту",
+	rows: "Жолдар:",
+	columns: "Бағандар:",
+	align: "Туралау:",
+	cellPadding: "Ұяшық өрісі:",
+	cellSpacing: "Ұяшық аралығы:",
+	tableWidth: "Кесте ені:",
+	backgroundColor: "Өң түсі:",
+	borderColor: "Жиек түсі:",
+	borderThickness: "Жиек қалыңдығы",
+	percent: "пайыз",
+	pixels: "нүктелер",
+	"default": "әдепкі",
+	left: "сол жақ",
+	center: "ортасы",
+	right: "оң жақ",
+	buttonSet: "Орнату", // translated elsewhere?
+	buttonInsert: "Кірістіру",
+	buttonCancel: "Болдырмау",
+
+	selectTableLabel: "Кестені таңдау",
+	insertTableRowBeforeLabel: "Жолды алдына қосу",
+	insertTableRowAfterLabel: "Жолды артына қосу",
+	insertTableColumnBeforeLabel: "Бағанды алдына қосу",
+	insertTableColumnAfterLabel: "Бағанды артына қосу",
+	deleteTableRowLabel: "Жолды жою",
+	deleteTableColumnLabel: "Бағанды жою"
+})
+	
+
diff --git a/dojox/editor/plugins/nls/kk/TextColor.js b/dojox/editor/plugins/nls/kk/TextColor.js
new file mode 100644
index 0000000..679b1ab
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Орнату",
+	"cancelButtonText": "Болдырмау"
+})
+
diff --git a/dojox/editor/plugins/nls/kk/latinEntities.js b/dojox/editor/plugins/nls/kk/latinEntities.js
new file mode 100644
index 0000000..3dbd692
--- /dev/null
+++ b/dojox/editor/plugins/nls/kk/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* These are already handled in the default RTE
+		amp:"ampersand",lt:"less-than sign",
+		gt:"greater-than sign",
+		nbsp:"no-break space\nnon-breaking space",
+		quot:"quote",
+	*/
+	iexcl:"аударылған леп белгісі",
+	cent:"цент белгісі",
+	pound:"фунт белгісі",
+	curren:"ақша белгісі",
+	yen:"йен белгісі\nюань белгісі",
+	brvbar:"үзілген сызық\nүзілген тік сызық",
+	sect:"бөлім белгісі",
+	uml:"диэреза\nаралық диэрезасы",
+	copy:"авторлық құқық белгісі",
+	ordf:"реттік көрсеткіш",
+	laquo:"сол жақты көрсететін қос бұрышты тырнақша\nсол жақты көрсететін кайра",
+	not:"not белгісі",
+	shy:"тасымалдау белгісі\nеркін тасымалдау",
+	reg:"тіркелген белгісі\nтіркелген сауда белгісінің белгісі",
+	macr:"созылыңқы белгісі\nаралық созылыңқы белгісі\noсызылған\nүстін сызу",
+	deg:"градус белгісі",
+	plusmn:"қосу-алу белгісі\nқосу-немесе-алу белгісі",
+	sup2:"жол үсті екі\nжол үсті сан екі\nшаршы",
+	sup3:"жол үсті үш\nжол үсті сан үш\nтекше",
+	acute:"диакритика белгісі\nаралық диакритика белгісі",
+	micro:"шағын белгісі",
+	para:"pilcrow белгісі\nеже белгісі",
+	middot:"ортаңғы нүкте\nГрузиялық нүктесі\nГрек ортаңғы нүктесі",
+	cedil:"седиль\nаралық седиль",
+	sup1:"жол үсті бір\nжол үсті сан бір",
+	ordm:"реттік көрсеткіш",
+	raquo:"оң жақты көрсететін қос бұрышты тырнақша\nоң жақты көрсететін кайра",
+	frac14:"жай бөлшек бір ширек\nбөлшек бір ширек",
+	frac12:"жай бөлшек бір жарым\nбөлшек бір жарым",
+	frac34:"жай бөлшек үш ширек\nбөлшек үш ширек",
+	iquest:"аударылған сұрақ белгісі\nбұрылған сұрақ белгісі",
+	Agrave:"Екпін түсетін латын A бас әрпі\nЕкпін түсетін латын A бас әрпі",
+	Aacute:"Диакритика белгісі бар латын A бас әрпі",
+	Acirc:"Циркумфлекс белгісі бар латын A бас әрпі",
+	Atilde:"Тильда белгісі бар латын A бас әрпі",
+	Auml:"Диэреза белгісі бар латын A бас әрпі",
+	Aring:"Үстінде сақина бар латын A бас әрпі\nСақина бар латын A бас әрпі",
+	AElig:"Латын AE бас әрпі\nЛатын AE бас әріп лигатурасы",
+	Ccedil:"Седиль белгісі бар латын С бас әрпі",
+	Egrave:"Екпін түсетін латын E бас әрпі",
+	Eacute:"Диакритика белгісі бар латын E бас әрпі",
+	Ecirc:"Циркумфлекс белгісі бар латын E бас әрпі",
+	Euml:"Диэреза белгісі бар латын E бас әрпі",
+	Igrave:"Екпін түсетін латын I бас әрпі",
+	Iacute:"Диакритика белгісі бар латын I бас әрпі",
+	Icirc:"Циркумфлекс белгісі бар латын I бас әрпі",
+	Iuml:"Диэреза белгісі бар латын I бас әрпі",
+	ETH:"Латын ETH бас әрпі",
+	Ntilde:"Тильда белгісі бар латын N бас әрпі",
+	Ograve:"Екпін түсетін латын O бас әрпі",
+	Oacute:"Диакритика белгісі бар латын O бас әрпі",
+	Ocirc:"Циркумфлекс белгісі бар латын O бас әрпі",
+	Otilde:"Тильда белгісі бар латын O бас әрпі",
+	Ouml:"Диэреза белгісі бар латын O бас әрпі",
+	times:"көбейту белгісі",
+	Oslash:"Қиғаш сызықпен латын O бас әрпі\nҚиғаш сызықпен латын O бас әрпі",
+	Ugrave:"Екпін түсетін латын U бас әрпі",
+	Uacute:"Диакритика белгісі бар латын U бас әрпі",
+	Ucirc:"Циркумфлекс белгісі бар латын U бас әрпі",
+	Uuml:"Диэреза белгісі бар латын U бас әрпі",
+	Yacute:"Диакритика белгісі бар латын Y бас әрпі",
+	THORN:"Латын THORN бас әрпі",
+	szlig:"Латын sharp s\ness-zed кіші әрпі",
+	agrave:"Екпін түсетін латын кіші әрпі\nЕкпін түсетін латын кіші әрпі",
+	aacute:"Диакритика белгісі бар латын кіші әрпі",
+	acirc:"Циркумфлекс белгісі бар латын кіші әрпі",
+	atilde:"Тильда белгісі бар латын кіші әрпі",
+	auml:"Диэреза белгісі бар латын кіші әрпі",
+	aring:"Үстінде сақина бар латын кіші әрпі\nСақина бар латын кіші әрпі",
+	aelig:"Латын ae кіші әрпі\nЛатын ae кіші лигатурасы",
+	ccedil:"Седиль белгісі бар латын c кіші әрпі",
+	egrave:"Екпін түсетін латын e кіші әрпі",
+	eacute:"Диакритика белгісі бар латын e кіші әрпі",
+	ecirc:"Циркумфлекс белгісі бар латын e кіші әрпі",
+	euml:"Диэреза белгісі бар латын e кіші әрпі",
+	igrave:"Екпін түсетін латын i кіші әрпі",
+	iacute:"Диакритика белгісі бар латын i кіші әрпі",
+	icirc:"Циркумфлекс белгісі бар латын i кіші әрпі",
+	iuml:"Диэреза белгісі бар латын i кіші әрпі",
+	eth:"Латын eth кіші әрпі",
+	ntilde:"Тильда белгісі бар латын n кіші әрпі",
+	ograve:"Екпін түсетін латын o кіші әрпі",
+	oacute:"Диакритика белгісі бар латын o кіші әрпі",
+	ocirc:"Циркумфлекс белгісі бар латын o кіші әрпі",
+	otilde:"Тильда белгісі бар латын o кіші әрпі",
+	ouml:"Диэреза белгісі бар латын o кіші әрпі",
+	divide:"бөлу белгісі",
+	oslash:"Қиғаш сызықпен латын o кіші әрпі\nҚиғаш сызықпен латын o кіші әрпі",
+	ugrave:"Екпін түсетін латын u кіші әрпі",
+	uacute:"Диакритика белгісі бар латын u кіші әрпі",
+	ucirc:"Циркумфлекс белгісі бар латын u кіші әрпі",
+	uuml:"Диэреза белгісі бар латын u кіші әрпі",
+	yacute:"Диакритика белгісі бар латын y кіші әрпі",
+	thorn:"Латын thorn кіші әрпі",
+	yuml:"Диэреза белгісі бар латын y кіші әрпі",
+
+// Greek Characters and Symbols
+	fnof:"Тырнақшаға алынған латын f кіші әрпі\nфункция\nфлорин",
+	Alpha:"Грек альфа бас әрпі",
+	Beta:"Грек бета бас әрпі",
+	Gamma:"Грек гамма бас әрпі",
+	Delta:"Грек дельта бас әрпі",
+	Epsilon:"Грек эпсилон бас әрпі",
+	Zeta:"Грек зета бас әрпі",
+	Eta:"Грек эта бас әрпі",
+	Theta:"Грек тэта бас әрпі",
+	Iota:"Грек йота бас әрпі",
+	Kappa:"Грек каппа бас әрпі",
+	Lambda:"Грек ламбда бас әрпі",
+	Mu:"Грек му бас әрпі",
+	Nu:"Грек ну бас әрпі",
+	Xi:"Грек кси бас әрпі",
+	Omicron:"Грек омикрон бас әрпі",
+	Pi:"Грек пи бас әрпі",
+	Rho:"Грек ро бас әрпі",
+	Sigma:"Грек сигма бас әрпі",
+	Tau:"Грек тау бас әрпі",
+	Upsilon:"Грек ипсилон бас әрпі",
+	Phi:"Грек фи бас әрпі",
+	Chi:"Грек хи бас әрпі",
+	Psi:"Грек пси бас әрпі",
+	Omega:"Грек омега бас әрпі",
+	alpha:"Грек альфа кіші әрпі",
+	beta:"Грек бета кіші әрпі",
+	gamma:"Грек гамма кіші әрпі",
+	delta:"Грек дельта кіші әрпі",
+	epsilon:"Грек эпсилон кіші әрпі",
+	zeta:"Грек зета кіші әрпі",
+	eta:"Грек эта кіші әрпі",
+	theta:"Грек тэта кіші әрпі",
+	iota:"Грек йота кіші әрпі",
+	kappa:"Грек каппа кіші әрпі",
+	lambda:"Грек ламбда кіші әрпі",
+	mu:"Грек му кіші әрпі",
+	nu:"Грек ну кіші әрпі",
+	xi:"Грек кси кіші әрпі",
+	omicron:"Грек омикрон кіші әрпі",
+	pi:"Грек пи кіші әрпі",
+	rho:"Грек ро кіші әрпі",
+	sigmaf:"Грек соңғы сигма кіші әрпі",
+	sigma:"Грек сигма кіші әрпі",
+	tau:"Грек тау кіші әрпі",
+	upsilon:"Грек упсилон кіші әрпі",
+	phi:"Грек фи кіші әрпі",
+	chi:"Грек хи кіші әрпі",
+	psi:"Грек пси кіші әрпі",
+	omega:"Грек омега кіші әрпі",
+	thetasym:"Грек кіші әрпі тэта нышаны",
+	upsih:"Ілмек нышанымен грек упсилоны",
+	piv:"Грек пи нышаны",
+	bull:"байрақша\nқара кіші дөңгелек",
+	hellip:"көлденең эллипсис\nүш нүкте толтырғышы",
+	prime:"прим\nминут\nфут",
+	Prime:"қос прим\nсекунд\nдюйм",
+	oline:"үстінен сызу\nаралық сызу",
+	frasl:"бөлшек қиғаш сызығы",
+	weierp:"сценарийдің P бас әрпі\nдәреже көптігі\nВейерштрасс p",
+	image:"ескі I бас әрпі\nжорымал бөлік",
+	real:"ескі R бас әрпі\nнақты бөлік нышаны",
+	trade:"сауда белгісінің белгісі",
+	alefsym:"alef нышаны\nбірінші шексіз кардинал саны",
+	larr:"солға қарай көрсеткі",
+	uarr:"жоғары қарай көрсеткі",
+	rarr:"оңға қарай көрсеткі",
+	darr:"төменге қарай көрсеткі",
+	harr:"солдан оңға қарай көрсеткі",
+	crarr:"бұрышы солға қарайтын төменге қарай көрсеткі\nкаретканы қайтару",
+	lArr:"солға қарай қос көрсеткі",
+	uArr:"жоғары қарай қос көрсеткі",
+	rArr:"оңға қарай қос көрсеткі",
+	dArr:"төменге қарай қос көрсеткі",
+	hArr:"солдан оңға қарай қос көрсеткі",
+	forall:"барлығына",
+	part:"жартылай дифференциал",
+	exist:"бар",
+	empty:"бос жиын\nбос жиын\nдиаметр",
+	nabla:"набла\nсолға қарай айырмашылық",
+	isin:"элементі",
+	notin:"элементі емес",
+	ni:"құрамында мүше ретінде",
+	prod:"n-ary өнімі\nөнім белгісі",
+	sum:"n-ary қосу",
+	minus:"алу белгісі",
+	lowast:"жұлдызша амалдағышы",
+	radic:"квадрат түбір\nтүбір белгісі",
+	prop:"пропорционалды",
+	infin:"шексіздік",
+	ang:"бұрыш",
+	and:"логикалық және\nүшбұрыш призма",
+	or:"логикалық немесе\nүшбұрыш",
+	cap:"қиылысу\nконус",
+	cup:"байланыс\nбіріктіру белгісі","int":"интеграл",
+	there4:"сондықтан",
+	sim:"тильда амалдағышы\nөзгеріп отырады\nұқсас",
+	cong:"шамамен тең",
+	asymp:"тең дерлік\nасимптотикалық",
+	ne:"тең емес",
+	equiv:"бірдей",
+	le:"аздау немесе тең",
+	ge:"үлкендеу немесе тең",
+	sub:"ішкі жиыны",
+	sup:"көптігі",
+	nsub:"ішкі жиыны емес",
+	sube:"ішкі жиыны немесе тең",
+	supe:"көптігі немесе тең",
+	oplus:"дөңгелектелген плюс\nтікелей сома",
+	otimes:"дөңгелектелген уақыттар\nвектор көбейтіндісі",
+	perp:"жоғары түймесі\nтік бұрышты\nперпендикулярлық",
+	sdot:"нүкте амалдағышы",
+	lceil:"сол жақ шегі\nAPL жоғарғы деңгейі",
+	rceil:"оң жақ шегі",
+	lfloor:"сол жақ төменгі деңгейі\nAPL төменгі деңгейі",
+	rfloor:"оң жақ төменгі деңгейі",
+	lang:"сол жақты көрсететін бұрыштық жақша",
+	rang:"оң жақты көрсететін бұрыштық жақша",
+	loz:"ромб",
+	spades:"қара қалақ дестесі",
+	clubs:"қара клуб дестесі\nүшқұлақ",
+	hearts:"қара жүрек дестесі\nвалентин",
+	diams:"қара алмас дестесі",
+	OElig:"Латын OE бас әріп лигатурасы",
+	oelig:"Латын oe кіші әріп лигатурасы",
+	Scaron:"Кароны бар латын S бас әрпі",
+	scaron:"Кароны бар латын s кіші әрпі",
+	Yuml:"Диэреза белгісі бар латын Y бас әрпі",
+	circ:"түрлендіргіш әрпі циркумфлекс екпіні",
+	tilde:"кіші тильда",
+	ensp:"эн аралығы",
+	emsp:"ең үлкен аралық",
+	thinsp:"тар аралық",
+	zwnj:"ені нөл біріктіргіш емес",
+	zwj:"ені нөл біріктіргіш",
+	lrm:"солдан оңға қарай белгісі",
+	rlm:"оңнан солға қарай белгісі",
+	ndash:"қысқа тире",
+	mdash:"ұзын тире",
+	lsquo:"сол жақ бір тырнақша",
+	rsquo:"оң жақ бір тырнақша",
+	sbquo:"бір төмен-9 тырнақша",
+	ldquo:"сол жақ қос тырнақша",
+	rdquo:"оң жақ қос тырнақша",
+	bdquo:"қос төмен-9 тырнақша",
+	dagger:"сілтеме белгісі",
+	Dagger:"қос сілтеме белгісі",
+	permil:"промилле белгісі",
+	lsaquo:"бір сол жақты көрсететін бұрыштық тырнақша",
+	rsaquo:"бір оң жақты көрсететін бұрыштық тырнақша",
+	euro:"еуро белгісі"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/AutoSave.js b/dojox/editor/plugins/nls/ko/AutoSave.js
new file mode 100644
index 0000000..a691dff
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "저장",
+	"saveSettingLabelOn": "자동 저장 간격 설정...",
+	"saveSettingLabelOff": "자동 저장 끄기",
+	"saveSettingdialogTitle": "자동 저장",
+	"saveSettingdialogDescription": "자동 저장 간격 지정",
+	"saveSettingdialogParamName": "자동 저장 간격",
+	"saveSettingdialogParamLabel": "최소",
+	"saveSettingdialogButtonOk": "간격 설정",
+	"saveSettingdialogButtonCancel": "취소",
+	"saveMessageSuccess": "${0}에 저장됨",
+	"saveMessageFail": "${0}에 저장 실패"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/Blockquote.js b/dojox/editor/plugins/nls/ko/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
new file mode 100644
index 0000000..6b8a2f1
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "편집기 도구 모음 접기",
+	"expand": "편집기 도구 모음 펼치기"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/FindReplace.js b/dojox/editor/plugins/nls/ko/FindReplace.js
index 61c34dc..da6df43 100755
--- a/dojox/editor/plugins/nls/ko/FindReplace.js
+++ b/dojox/editor/plugins/nls/ko/FindReplace.js
@@ -1,12 +1,22 @@
 ({
-	"findLabel": "찾을 문자열:",
+	"findLabel": "찾기:",
+	"findTooltip": "찾을 텍스트 입력",
 	"replaceLabel": "바꿀 대상:",
-	"findReplace": "토글 찾기/바꾸기",
-	"matchCase": "대소문자 일치", 
+	"replaceTooltip": "대체할 텍스트 입력",
+	"findReplace": "찾기 및 바꾸기",
+	"matchCase": "대소문자 구분",
+	"matchCaseTooltip": "대소문자 구분",
 	"backwards": "뒤로",
-	"replaceAll": "모두 바꾸기", 
+	"backwardsTooltip": "텍스트 역방향 검색",
+	"replaceAll": "모든 발생",
+	"replaceAllButton": "모두 바꾸기",
+	"replaceAllButtonTooltip": "텍스트 모두 바꾸기",
 	"findButton": "찾기",
+	"findButtonTooltip": "텍스트 찾기",
 	"replaceButton": "바꾸기",
-	"replaceDialogText": "${0}개를 바꿨습니다."
+	"replaceButtonTooltip": "텍스트 바꾸기",
+	"replaceDialogText": "${0}개를 대체했습니다.",
+	"eofDialogText": "마지막 발생 ${0}",
+	"eofDialogTextFind": "찾음",
+	"eofDialogTextReplace": "대체됨"
 })
-
diff --git a/dojox/editor/plugins/nls/ko/InsertAnchor.js b/dojox/editor/plugins/nls/ko/InsertAnchor.js
new file mode 100644
index 0000000..c29b77b
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "기준 위치 삽입",
+	title: "기준 위치 특성",
+	anchor: "이름:",
+	text: "설명:",
+	set: "설정",
+	cancel: "취소"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/LocalImage.js b/dojox/editor/plugins/nls/ko/LocalImage.js
new file mode 100644
index 0000000..2492bbc
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "이미지 삽입",
+	url: "이미지",
+	browse: "찾아보기...",
+	text: "설명",
+	set: "삽입",
+	invalidMessage: "올바르지 않은 이미지 파일 유형",
+	prePopuTextUrl: "이미지 URL 입력",
+	prePopuTextBrowse: "또는 로컬 파일 찾아보기"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/PasteFromWord.js b/dojox/editor/plugins/nls/ko/PasteFromWord.js
new file mode 100644
index 0000000..86c979a
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "단어에서 붙여넣기",
+	"paste": "붙여넣기",
+	"cancel": "취소",
+	"instructions": "단어에서 아래 텍스트 상자로 컨텐츠를 붙여 넣으십시오. 삽입할 컨텐츠가 준비되면 붙여넣기 단추를 누르십시오. 텍스트 삽입을 중단하려면 취소 단추를 누르십시오. "
+})
+
diff --git a/dojox/editor/plugins/nls/ko/Smiley.js b/dojox/editor/plugins/nls/ko/Smiley.js
index 67872d3..fc34dec 100644
--- a/dojox/editor/plugins/nls/ko/Smiley.js
+++ b/dojox/editor/plugins/nls/ko/Smiley.js
@@ -4,9 +4,9 @@
 	emoticonLaughing: "하하",
 	emoticonWink: "윙크",
 	emoticonGrin: "씨익",
-	emoticonCool: "멋진데",
-	emoticonAngry: "화남",  
-	emoticonHalf: "고민 중", 
+	emoticonCool: "멋진",
+	emoticonAngry: "화남",
+	emoticonHalf: "고민 중",
 	emoticonEyebrow: "글쎄",
 	emoticonFrown: "불만",
 	emoticonShy: "부끄러움",
@@ -15,8 +15,7 @@
 	emoticonTongue: "메롱",
 	emoticonIdea: "아이디어",
 	emoticonYes: "예",
-	emoticonNo: "아니오",	
+	emoticonNo: "아니오",
 	emoticonAngel: "천사",
 	emoticonCrying: "울음"
 })
-
diff --git a/dojox/editor/plugins/nls/ko/SpellCheck.js b/dojox/editor/plugins/nls/ko/SpellCheck.js
new file mode 100644
index 0000000..5cc229a
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "맞춤법 검사 일괄처리",
+	unfound: "찾을 수 없음",
+	skip: "건너뛰기",
+	skipAll: "모두 건너뛰기",
+	toDic: "사전에 추가",
+	suggestions: "제안",
+	replace: "바꾸기",
+	replaceWith: "다음으로 바꾸기",
+	replaceAll: "모두 바꾸기",
+	cancel: "취소",
+	msg: "맞춤법 오류 없음",
+	iSkip: "이 항목 건너뛰기",
+	iSkipAll: "다음과 같이 모두 건너뛰기",
+	iMsg: "맞춤법 제안 없음"
+})
+
diff --git a/dojox/editor/plugins/nls/ko/TableDialog.js b/dojox/editor/plugins/nls/ko/TableDialog.js
index 788d588..852c8b8 100644
--- a/dojox/editor/plugins/nls/ko/TableDialog.js
+++ b/dojox/editor/plugins/nls/ko/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "오른쪽",
 	buttonSet: "설정", // translated elsewhere?
 	buttonInsert: "삽입",
+	buttonCancel: "취소",
 
 	selectTableLabel: "테이블 선택",
 	insertTableRowBeforeLabel: "사전 행 추가",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "행 삭제",
 	deleteTableColumnLabel: "열 삭제"
 })
-
diff --git a/dojox/editor/plugins/nls/ko/TextColor.js b/dojox/editor/plugins/nls/ko/TextColor.js
new file mode 100644
index 0000000..cf91979
--- /dev/null
+++ b/dojox/editor/plugins/nls/ko/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "설정",
+	"cancelButtonText": "취소"
+})
+
diff --git a/dojox/editor/plugins/nls/nb/AutoSave.js b/dojox/editor/plugins/nls/nb/AutoSave.js
new file mode 100644
index 0000000..24be57b
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/AutoSave.js
@@ -0,0 +1,13 @@
+({
+	"saveLabel": "Lagre",
+	"saveSettingLabelOn": "Angi intervall for automatisk lagring...",
+	"saveSettingLabelOff": "Slå av automatisk lagring",
+	"saveSettingdialogTitle": "Automatisk lagring",
+	"saveSettingdialogDescription": "Definer intervall for automatisk lagring",
+	"saveSettingdialogParamName": "Intervall for automatisk lagring",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Angi intervall",
+	"saveSettingdialogButtonCancel": "Avbryt",
+	"saveMessageSuccess": "Lagret klokken ${0}",
+	"saveMessageFail": "Mislykket lagring klokken ${0}"
+})
diff --git a/dojox/editor/plugins/nls/nb/Blockquote.js b/dojox/editor/plugins/nls/nb/Blockquote.js
new file mode 100644
index 0000000..40fa6eb
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/Blockquote.js
@@ -0,0 +1,3 @@
+({
+	"blockquote": "Blokksitat"
+})
diff --git a/dojox/editor/plugins/nls/nb/Breadcrumb.js b/dojox/editor/plugins/nls/nb/Breadcrumb.js
new file mode 100644
index 0000000..223b72d
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/Breadcrumb.js
@@ -0,0 +1,9 @@
+({
+	"nodeActions": "${nodeName} Handlinger",
+	"selectContents": "Velg innhold",
+	"selectElement": "Velg element",
+	"deleteElement": "Slett element",
+	"deleteContents": "Slett innhold",
+	"moveStart": "Flytt markør til start",
+	"moveEnd": "Flytt markør til slutt"
+})
diff --git a/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js b/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
new file mode 100644
index 0000000..8e0e85e
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/CollapsibleToolbar.js
@@ -0,0 +1,4 @@
+({
+	"collapse": "Komprimer verktøylinje for redigeringsprogram",
+	"expand": "Utvid verktøylinje for redigeringsprogram"
+})
diff --git a/dojox/editor/plugins/nls/nb/FindReplace.js b/dojox/editor/plugins/nls/nb/FindReplace.js
new file mode 100644
index 0000000..16ecca2
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/FindReplace.js
@@ -0,0 +1,22 @@
+({
+	"findLabel": "Søk:",
+	"findTooltip": "Skriv inn teksten du vil søke etter",
+	"replaceLabel": "Erstatt med:",
+	"replaceTooltip": "Skriv inn teksten du vil erstatte med",
+	"findReplace": "Søk og erstatt",
+	"matchCase": "Skill mellom store og små bokstaver",
+	"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",
+	"findButtonTooltip": "Søk etter teksten",
+	"replaceButton": "Erstatt",
+	"replaceButtonTooltip": "Erstatt teksten",
+	"replaceDialogText": "Erstattet ${0} forekomster.",
+	"eofDialogText": "Siste forekomst ${0}",
+	"eofDialogTextFind": "funnet",
+	"eofDialogTextReplace": "erstattet"
+})
diff --git a/dojox/editor/plugins/nls/nb/InsertAnchor.js b/dojox/editor/plugins/nls/nb/InsertAnchor.js
new file mode 100644
index 0000000..e53bc13
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/InsertAnchor.js
@@ -0,0 +1,8 @@
+({
+	insertAnchor: "Sett inn anker",
+	title: "Ankeregenskaper",
+	anchor: "Navn:",
+	text: "Beskrivelse:",
+	set: "Definer",
+	cancel: "Avbryt"
+})
diff --git a/dojox/editor/plugins/nls/nb/InsertEntity.js b/dojox/editor/plugins/nls/nb/InsertEntity.js
new file mode 100644
index 0000000..0bce161
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/InsertEntity.js
@@ -0,0 +1,3 @@
+({
+	insertEntity: "Sett inn symbol"
+})
diff --git a/dojox/editor/plugins/nls/nb/LocalImage.js b/dojox/editor/plugins/nls/nb/LocalImage.js
new file mode 100644
index 0000000..5f07d91
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/LocalImage.js
@@ -0,0 +1,10 @@
+({
+	insertImageTitle: "Sett inn bilde",
+	url: "Bilde",
+	browse: "Bla gjennom...",
+	text: "Beskrivelse",
+	set: "Sett inn",
+	invalidMessage: "Ugyldig bildefiltype",
+	prePopuTextUrl: "Angi en bilde-URL",
+	prePopuTextBrowse: " eller bla gjennom til en lokal fil."
+})
diff --git a/dojox/editor/plugins/nls/nb/PageBreak.js b/dojox/editor/plugins/nls/nb/PageBreak.js
new file mode 100644
index 0000000..aad5cd4
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/PageBreak.js
@@ -0,0 +1,3 @@
+({
+	"pageBreak": "Sideskift"
+})
diff --git a/dojox/editor/plugins/nls/nb/PasteFromWord.js b/dojox/editor/plugins/nls/nb/PasteFromWord.js
new file mode 100644
index 0000000..0892207
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/PasteFromWord.js
@@ -0,0 +1,6 @@
+({
+	"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."
+})
diff --git a/dojox/editor/plugins/nls/nb/Preview.js b/dojox/editor/plugins/nls/nb/Preview.js
new file mode 100644
index 0000000..b821bea
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/Preview.js
@@ -0,0 +1,3 @@
+({
+	"preview": "Forhåndsvis"
+})
diff --git a/dojox/editor/plugins/nls/nb/Save.js b/dojox/editor/plugins/nls/nb/Save.js
new file mode 100644
index 0000000..0608da8
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/Save.js
@@ -0,0 +1,3 @@
+({
+	"save": "Lagre"
+})
diff --git a/dojox/editor/plugins/nls/nb/ShowBlockNodes.js b/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
new file mode 100644
index 0000000..e5964c0
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/ShowBlockNodes.js
@@ -0,0 +1,3 @@
+({
+	"showBlockNodes": "Vis HTML-blokkelementer"
+})
diff --git a/dojox/editor/plugins/nls/nb/Smiley.js b/dojox/editor/plugins/nls/nb/Smiley.js
new file mode 100644
index 0000000..f4f8730
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/Smiley.js
@@ -0,0 +1,21 @@
+({
+	smiley: "Sett inn uttrykksikon",
+	emoticonSmile: "smil",
+	emoticonLaughing: "latter",
+	emoticonWink: "blunk",
+	emoticonGrin: "glis",
+	emoticonCool: "kul",
+	emoticonAngry: "sint",
+	emoticonHalf: "halv",
+	emoticonEyebrow: "øyebryn",
+	emoticonFrown: "streng",
+	emoticonShy: "sjenert",
+	emoticonGoofy: "tåpelig",
+	emoticonOops: "ops",
+	emoticonTongue: "tunge",
+	emoticonIdea: "ide",
+	emoticonYes: "ja",
+	emoticonNo: "nei",
+	emoticonAngel: "engel",
+	emoticonCrying: "gråt"
+})
diff --git a/dojox/editor/plugins/nls/nb/SpellCheck.js b/dojox/editor/plugins/nls/nb/SpellCheck.js
new file mode 100644
index 0000000..2e8d58c
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/SpellCheck.js
@@ -0,0 +1,16 @@
+({
+	widgetLabel: "Satsvis stavekontroll",
+	unfound: "Ikke funnet",
+	skip: "Hopp over",
+	skipAll: "Hopp over alle",
+	toDic: "Legg til i ordliste",
+	suggestions: "Forslag",
+	replace: "Erstatt",
+	replaceWith: "Erstatt med",
+	replaceAll: "Erstatt alle",
+	cancel: "Avbryt",
+	msg: "Ingen stavefeil funnet",
+	iSkip: "Hopp over dette",
+	iSkipAll: "Hopp over alle slike",
+	iMsg: "Ingen staveforslag"
+})
diff --git a/dojox/editor/plugins/nls/nb/TableDialog.js b/dojox/editor/plugins/nls/nb/TableDialog.js
index 0d04820..ce412e1 100644
--- a/dojox/editor/plugins/nls/nb/TableDialog.js
+++ b/dojox/editor/plugins/nls/nb/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "høyre",
 	buttonSet: "Definer", // translated elsewhere?
 	buttonInsert: "Sett inn",
+	buttonCancel: "Avbryt",
 
 	selectTableLabel: "Velg tabell",
 	insertTableRowBeforeLabel: "Legg til rad foran",
diff --git a/dojox/editor/plugins/nls/nb/TextColor.js b/dojox/editor/plugins/nls/nb/TextColor.js
new file mode 100644
index 0000000..e53687b
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/TextColor.js
@@ -0,0 +1,4 @@
+({
+	"setButtonText": "Definer",
+	"cancelButtonText": "Avbryt"
+})
diff --git a/dojox/editor/plugins/nls/nb/latinEntities.js b/dojox/editor/plugins/nls/nb/latinEntities.js
new file mode 100644
index 0000000..ae206b5
--- /dev/null
+++ b/dojox/editor/plugins/nls/nb/latinEntities.js
@@ -0,0 +1,256 @@
+({
+	/* 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:"invertert utropstegn",
+	cent:"cent-tegn",
+	pound:"pund-tegn",
+	curren:"valutategn",
+	yen:"yen-tegn\nyuan-tegn",
+	brvbar:"brutt strek\nbrutt loddrett strek",
+	sect:"seksjonstegn",
+	uml:"dieresis",
+	copy:"opphavsrettstegn",
+	ordf:"feminin ordenstallsindikator",
+	laquo:"venstre doble anførselstegn",
+	not:"ikke-tegn",
+	shy:"myk bindestrek",
+	reg:"registrert-tegn\nregistrert varemerke-tegn",
+	macr:"makron\nmellomromsmakron\noverstrek\nAPL-overstrek",
+	deg:"gradtegn",
+	plusmn:"pluss-minus-tegn\npluss-eller-minus-tegn",
+	sup2:"hevet skrift to\nhevet skrift tall to\nkvadrat",
+	sup3:"hevet skrift tre\nhevet skrift tall tre\nkubikk",
+	acute:"akuttegn\nmellomromsakuttegn",
+	micro:"mikro-tegn",
+	para:"avsnittstegn",
+	middot:"midtprikk\nGeorgisk komma\ngresk midtprikk",
+	cedil:"cedille\nmellomromscedille",
+	sup1:"hevet skrift en\nhevet skrift tall en",
+	ordm:"maskulin ordenstallsindikator",
+	raquo:"høyre doble anførselstegn",
+	frac14:"brøk en kvart",
+	frac12:"brøk en halv",
+	frac34:"brøk tre kvart",
+	iquest:"invertert spørsmålstegn\nsnudd spørsmålstegn",
+	Agrave:"Stor bokstav A med aksent grave\nStor bokstav A grave",
+	Aacute:"Stor bokstav A med aigu",
+	Acirc:"Stor bokstav A med circumfleks",
+	Atilde:"Stor bokstav A med tilde",
+	Auml:"Stor bokstav A med dieresis",
+	Aring:"Stor bokstav A med ring\nStor bokstav A ring",
+	AElig:"Stor bokstav AE\nStor bokstav sammenbundet AE",
+	Ccedil:"Stor bokstav C med cedille",
+	Egrave:"Stor bokstav E med grave",
+	Eacute:"Stor bokstav E med aigu",
+	Ecirc:"Stor bokstav E med circumfleks",
+	Euml:"Stor bokstav E med diaeresis",
+	Igrave:"Stor bokstav I med grave",
+	Iacute:"Stor bokstav I med aigu",
+	Icirc:"Stor bokstav I med circumflex",
+	Iuml:"Stor bokstav I med dieresis",
+	ETH:"Stor bokstav ETH",
+	Ntilde:"Stor bokstav N med tilde",
+	Ograve:"Stor bokstav O med grave",
+	Oacute:"Stor bokstav O med aigu",
+	Ocirc:"Stor bokstav O med circumfleks",
+	Otilde:"Stor bokstav O med tilde",
+	Ouml:"Stor bokstav O med dieresis",
+	times:"multiplikasjonstegn",
+	Oslash:"Stor bokstav O med strek\nStor bokstav O skråstrek",
+	Ugrave:"Stor bokstav U med grave",
+	Uacute:"Stor bokstav U med aigu",
+	Ucirc:"Stor bokstav U med circumflex",
+	Uuml:"Stor bokstav U med dieresis",
+	Yacute:"Stor bokstav Y med aigu",
+	THORN:"Stor bokstav THORN",
+	szlig:"liten bokstav dobbelt-s\neszett",
+	agrave:"Liten bokstav a med aksent grave\nLiten bokstav a grave",
+	aacute:"Liten bokstav a med aigu",
+	acirc:"Liten bokstav a med circumfleks",
+	atilde:"Liten bokstav a med tilde",
+	auml:"Liten bokstav a med dieresis",
+	aring:"Liten bokstav a med aksent grave\nLiten bokstav a ring",
+	aelig:"Liten bokstav ae\nLiten bokstav sammenbundet AE",
+	ccedil:"Liten bokstav c med cedille",
+	egrave:"Liten bokstav e med grave",
+	eacute:"Liten bokstav e med aigu",
+	ecirc:"Liten bokstav e med circumflex",
+	euml:"Liten bokstav e med dieresis",
+	igrave:"Liten bokstav i med grave",
+	iacute:"Liten bokstav i med aigu",
+	icirc:"Liten bokstav i med circumflex",
+	iuml:"Liten bokstav i med dieresis",
+	eth:"Liten bokstav eth",
+	ntilde:"Liten bokstav n med tilde",
+	ograve:"Liten bokstav o med grave",
+	oacute:"Liten bokstav o med aigu",
+	ocirc:"Liten bokstav o med circumflex",
+	otilde:"Liten bokstav o med tilde",
+	ouml:"Liten bokstav o med dieresis",
+	divide:"divisjonstegn",
+	oslash:"Liten bokstav o med strek\nLiten bokstav o skråstrek",
+	ugrave:"Liten bokstav u med grave",
+	uacute:"Liten bokstav u med aigu",
+	ucirc:"Liten bokstav u med circumfleks",
+	uuml:"Liten bokstav u med dieresis",
+	yacute:"Liten bokstav y med aigu",
+	thorn:"Liten bokstav thorn",
+	yuml:"Liten bokstav y med dieresis",
+
+// Greek Characters and Symbols
+	fnof:"Liten bokstav f med krok\nfunksjon\nflorin",
+	Alpha:"Gresk stor bokstav alfa",
+	Beta:"Gresk stor bokstav beta",
+	Gamma:"Gresk stor bokstav gamma",
+	Delta:"Gresk stor bokstav delta",
+	Epsilon:"Gresk stor bokstav epsilon",
+	Zeta:"Gresk stor bokstav zeta",
+	Eta:"Gresk stor bokstav eta",
+	Theta:"Gresk stor bokstav theta",
+	Iota:"Gresk stor bokstav iota",
+	Kappa:"Gresk stor bokstav kappa",
+	Lambda:"Gresk stor bokstav lambda",
+	Mu:"Gresk stor bokstav my",
+	Nu:"Gresk stor bokstav ny",
+	Xi:"Gresk stor bokstav ksi",
+	Omicron:"Gresk stor bokstav omikron",
+	Pi:"Gresk stor bokstav pi",
+	Rho:"Gresk stor bokstav rho",
+	Sigma:"Gresk stor bokstav sigma",
+	Tau:"Gresk stor bokstav tau",
+	Upsilon:"Gresk stor bokstav ypsilon",
+	Phi:"Gresk stor bokstav phi",
+	Chi:"Gresk stor bokstav khi",
+	Psi:"Gresk stor bokstav psi",
+	Omega:"Gresk stor bokstav omega",
+	alpha:"Gresk liten bokstav alfa",
+	beta:"Gresk liten bokstav beta",
+	gamma:"Gresk liten bokstav gamma",
+	delta:"Gresk liten bokstav delta",
+	epsilon:"Gresk liten bokstav epsilon",
+	zeta:"Gresk liten bokstav zeta",
+	eta:"Gresk liten bokstav eta",
+	theta:"Gresk liten bokstav theta",
+	iota:"Gresk liten bokstav iota",
+	kappa:"Gresk liten bokstav kappa",
+	lambda:"Gresk liten bokstav lambda",
+	mu:"Gresk liten bokstav my",
+	nu:"Gresk liten bokstav ny",
+	xi:"Gresk liten bokstav ksi",
+	omicron:"Gresk liten bokstav omikron",
+	pi:"Gresk liten bokstav pi",
+	rho:"Gresk liten bokstav rho",
+	sigmaf:"Gresk liten bokstav sluttform sigma",
+	sigma:"Gresk liten bokstav sigma",
+	tau:"Gresk liten bokstav tau",
+	upsilon:"Gresk liten bokstav ypsilon",
+	phi:"Gresk liten bokstav phi",
+	chi:"Gresk liten bokstav khi",
+	psi:"Gresk liten bokstav psi",
+	omega:"Gresk liten bokstav omega",
+	thetasym:"Gresk liten bokstav theta-symbol",
+	upsih:"Gresk ypsilon med krok-symbol",
+	piv:"Gresk pi-symbol",
+	bull:"punkt\nliten svart sirkel",
+	hellip:"vannrett ellipse\ntre prikker",
+	prime:"prim\nminutter\nfot",
+	Prime:"dobbelt prim\nsekunder\ntommer",
+	oline:"overstrek\nmellomromsoverstrek",
+	frasl:"brøkskråstrek",
+	weierp:"script capital P\npower set\nWeierstrass p",
+	image:"blackletter capital I\nimaginary part",
+	real:"blackletter capital R\nreal part symbol",
+	trade:"varemerketegn",
+	alefsym:"alef symbol\nfirst transfinite cardinal",
+	larr:"venstrepil",
+	uarr:"opp-pil",
+	rarr:"høyrepil",
+	darr:"nedpil",
+	harr:"venstre-høyre-pil",
+	crarr:"nedpil med hjørne mot venstre\nretur",
+	lArr:"dobbeltpil mot venstre",
+	uArr:"dobbeltpil oppover",
+	rArr:"dobbeltpil mot høyre",
+	dArr:"dobbeltpil nedover",
+	hArr:"dobbeltpil venstre-høyre",
+	forall:"for alle",
+	part:"partiell differensial",
+	exist:"det finnes",
+	empty:"tomt sett\nnullsett\ndiameter",
+	nabla:"nabla\nbakoverdifferanse",
+	isin:"element av",
+	notin:"ikke et element av",
+	ni:"contains as member",
+	prod:"n-ært produkt\nprodukttegn",
+	sum:"n-ær summering",
+	minus:"minustegn",
+	lowast:"stjerneoperator",
+	radic:"kvadratrot\nradikaltegn",
+	prop:"proporsjonalt med",
+	infin:"uendelighet",
+	ang:"vinkel",
+	and:"logisk og\nkile",
+	or:"logisk eller\nv",
+	cap:"snitt\nbue",
+	cup:"union\nkopp","int":"integral",
+	there4:"derfor",
+	sim:"tilde-operator\nvarierer med\nlikner på",
+	cong:"omtrent lik",
+	asymp:"nesten lik\nasymptotisk med",
+	ne:"ikke lik",
+	equiv:"identisk med",
+	le:"mindre enn eller lik",
+	ge:"større enn eller lik",
+	sub:"delsett av",
+	sup:"overordnet sett av",
+	nsub:"ikke delsett av",
+	sube:"delsett av eller lik",
+	supe:"overordnet sett av eller lik",
+	oplus:"pluss med sirkel\ndirekte sum",
+	otimes:"circled times\nvector product",
+	perp:"up tack\northogonal to\nperpendicular",
+	sdot:"dot operator",
+	lceil:"left ceiling\nAPL upstile",
+	rceil:"right ceiling",
+	lfloor:"left floor\nAPL downstile",
+	rfloor:"right floor",
+	lang:"left-pointing angle bracket",
+	rang:"right-pointing angle bracket",
+	loz:"lozenge",
+	spades:"black spade suit",
+	clubs:"black club suit\nshamrock",
+	hearts:"black heart suit\nvalentine",
+	diams:"black diamond suit",
+	OElig:"Stor bokstav ligatur OE",
+	oelig:"Liten bokstav ligatur oe",
+	Scaron:"Latin capital letter S with caron",
+	scaron:"Latin small letter s with caron",
+	Yuml:"Latin capital letter Y with diaeresis",
+	circ:"modifier letter circumflex accent",
+	tilde:"liten tilde",
+	ensp:"en-mellomrom",
+	emsp:"em-mellomrom",
+	thinsp:"tynt mellomrom",
+	zwnj:"zero width non-joiner",
+	zwj:"zero width joiner",
+	lrm:"left-to-right mark",
+	rlm:"right-to-left mark",
+	ndash:"en-strek",
+	mdash:"em-strek",
+	lsquo:"venstre enkelt anførselstegn",
+	rsquo:"høyre enkelt anførselstegn",
+	sbquo:"single low-9 quotation mark",
+	ldquo:"venstre dobbelt anførselstegn",
+	rdquo:"høyre dobbelt anførselstegn",
+	bdquo:"double low-9 quotation mark",
+	dagger:"dolk",
+	Dagger:"dobbelt dolk",
+	permil:"per mille sign",
+	lsaquo:"single left-pointing angle quotation mark",
+	rsaquo:"single right-pointing angle quotation mark",
+	euro:"euro-tegn"
+})
diff --git a/dojox/editor/plugins/nls/nl/AutoSave.js b/dojox/editor/plugins/nls/nl/AutoSave.js
new file mode 100644
index 0000000..9699de1
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Opslaan",
+	"saveSettingLabelOn": "Interval voor automatisch opslaan instellen...",
+	"saveSettingLabelOff": "Automatisch opslaan uitschakelen",
+	"saveSettingdialogTitle": "Automatisch opslaan",
+	"saveSettingdialogDescription": "Geef het interval voor Automatisch opslaan op.",
+	"saveSettingdialogParamName": "Interval voor Automatisch opslaan",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Interval instellen",
+	"saveSettingdialogButtonCancel": "Annuleren",
+	"saveMessageSuccess": "Opgeslagen op ${0}",
+	"saveMessageFail": "Opslaan mislukt op ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/Blockquote.js b/dojox/editor/plugins/nls/nl/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/Breadcrumb.js b/dojox/editor/plugins/nls/nl/Breadcrumb.js
new file mode 100644
index 0000000..8ceefd0
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} Acties",
+	"selectContents": "Inhoud selecteren",
+	"selectElement": "Element selecteren",
+	"deleteElement": "Element wissen",
+	"deleteContents": "Inhoud wissen",
+	"moveStart": "Cursor verplaatsen naar start",
+	"moveEnd": "Cursor verplaatsen naar eind"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js b/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
new file mode 100644
index 0000000..adb6cae
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Editor-werkbalk samenvouwen",
+	"expand": "Editor-werkbalk uitvouwen"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/FindReplace.js b/dojox/editor/plugins/nls/nl/FindReplace.js
new file mode 100644
index 0000000..798af2a
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Zoeken:",
+	"findTooltip": "Geef de zoektekst op",
+	"replaceLabel": "Vervangen door:",
+	"replaceTooltip": "Geef de vervangende tekst op",
+	"findReplace": "Zoeken en vervangen",
+	"matchCase": "Hoofdlettergevoelig",
+	"matchCaseTooltip": "Hoofdlettergevoelig",
+	"backwards": "Terug",
+	"backwardsTooltip": "Terugwaarts naar tekst zoeken",
+	"replaceAll": "Alle posities",
+	"replaceAllButton": "Alle vervangen",
+	"replaceAllButtonTooltip": "Gehele tekst vervangen",
+	"findButton": "Zoeken:",
+	"findButtonTooltip": "Tekst zoeken",
+	"replaceButton": "Vervangen",
+	"replaceButtonTooltip": "Tekst vervangen",
+	"replaceDialogText": "${0} vervangingen.",
+	"eofDialogText": "Laatste positie ${0}",
+	"eofDialogTextFind": "gevonden",
+	"eofDialogTextReplace": "vervangen"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/InsertAnchor.js b/dojox/editor/plugins/nls/nl/InsertAnchor.js
new file mode 100644
index 0000000..958aee6
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Anker invoegen",
+	title: "Ankereigenschappen",
+	anchor: "Naam:",
+	text: "Beschrijving:",
+	set: "Instellen",
+	cancel: "Annuleren"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/InsertEntity.js b/dojox/editor/plugins/nls/nl/InsertEntity.js
new file mode 100644
index 0000000..145b9b8
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Symbool invoegen"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/LocalImage.js b/dojox/editor/plugins/nls/nl/LocalImage.js
new file mode 100644
index 0000000..401d1d9
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Afbeelding invoegen",
+	url: "Afbeelding",
+	browse: "Bladeren...",
+	text: "Beschrijving",
+	set: "Invoegen",
+	invalidMessage: "Ongeldig bestandstype voor afbeelding",
+	prePopuTextUrl: "Geef een afbeeldings-URL op",
+	prePopuTextBrowse: " of navigeer naar een lokaal bestand."
+})
+
diff --git a/dojox/editor/plugins/nls/nl/PageBreak.js b/dojox/editor/plugins/nls/nl/PageBreak.js
new file mode 100644
index 0000000..c7ec1fa
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Paginaeinde"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/PasteFromWord.js b/dojox/editor/plugins/nls/nl/PasteFromWord.js
new file mode 100644
index 0000000..3087ce8
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Plakken vanuit Word",
+	"paste": "Plakken",
+	"cancel": "Annuleren",
+	"instructions": "Plak de content vanuit Word in het tekstvak hieronder. Klik als u klaar bent op de knop Plakken. Kies Annuleren als u de invoeging van tekst wilt afbreken."
+})
+
diff --git a/dojox/editor/plugins/nls/nl/Preview.js b/dojox/editor/plugins/nls/nl/Preview.js
new file mode 100644
index 0000000..54c0dd2
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Preview"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/Save.js b/dojox/editor/plugins/nls/nl/Save.js
new file mode 100644
index 0000000..ea761a1
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Opslaan"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/ShowBlockNodes.js b/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
new file mode 100644
index 0000000..d2d13b8
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "HTML-blokelementen afbeelden"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/Smiley.js b/dojox/editor/plugins/nls/nl/Smiley.js
new file mode 100644
index 0000000..26d115c
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Emoticon invoegen",
+	emoticonSmile: "glimlach",
+	emoticonLaughing: "lach",
+	emoticonWink: "knipoog",
+	emoticonGrin: "grijns",
+	emoticonCool: "cool",
+	emoticonAngry: "kwaad",
+	emoticonHalf: "half",
+	emoticonEyebrow: "verbaasd",
+	emoticonFrown: "frons",
+	emoticonShy: "verlegen",
+	emoticonGoofy: "goofy",
+	emoticonOops: "oeps",
+	emoticonTongue: "tong",
+	emoticonIdea: "idee",
+	emoticonYes: "ja",
+	emoticonNo: "nee",
+	emoticonAngel: "engel",
+	emoticonCrying: "bedroefd"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/SpellCheck.js b/dojox/editor/plugins/nls/nl/SpellCheck.js
new file mode 100644
index 0000000..69d4a8a
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Groepsgewijze spellingcontrole",
+	unfound: "Niet gevonden",
+	skip: "Overslaan",
+	skipAll: "Alle overslaan",
+	toDic: "Toevoegen aan woordenboek",
+	suggestions: "Suggesties",
+	replace: "Vervangen",
+	replaceWith: "Vervangen door",
+	replaceAll: "Alle vervangen",
+	cancel: "Annuleren",
+	msg: "Geen spelfouten gevonden",
+	iSkip: "Deze overslaan",
+	iSkipAll: "Al deze overslaan",
+	iMsg: "Geen spellingsuggesties"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/TableDialog.js b/dojox/editor/plugins/nls/nl/TableDialog.js
index 16f23ea..16df279 100644
--- a/dojox/editor/plugins/nls/nl/TableDialog.js
+++ b/dojox/editor/plugins/nls/nl/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "rechts",
 	buttonSet: "Instellen", // translated elsewhere?
 	buttonInsert: "invoegen",
+	buttonCancel: "Annuleren",
 
 	selectTableLabel: "Tabel selecteren",
 	insertTableRowBeforeLabel: "Rij boven toevoegen",
diff --git a/dojox/editor/plugins/nls/nl/TextColor.js b/dojox/editor/plugins/nls/nl/TextColor.js
new file mode 100644
index 0000000..e43b60c
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Instellen",
+	"cancelButtonText": "Annuleren"
+})
+
diff --git a/dojox/editor/plugins/nls/nl/latinEntities.js b/dojox/editor/plugins/nls/nl/latinEntities.js
new file mode 100644
index 0000000..6367f61
--- /dev/null
+++ b/dojox/editor/plugins/nls/nl/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"omgekeerd uitroepteken",
+	cent:"dollarcent",
+	pound:"pond",
+	curren:"algemeen muntsymbool",
+	yen:"yen\nyuan",
+	brvbar:"sluisteken\ngebroken streepje",
+	sect:"paragraaf",
+	uml:"umlaut/trema",
+	copy:"copyright (auteursrecht)",
+	ordf:"aanduiding vrouwelijk rangtelwoord (Spaans)",
+	laquo:"linker guillemet\ndubbele punthaak openen",
+	not:"niet-teken",
+	shy:"zacht afbreekstreepje",
+	reg:"gedeponeerd handelsmerk",
+	macr:"macron\nbovenlijn",
+	deg:"graad",
+	plusmn:"plusminus\nplus-of-min",
+	sup2:"superscript 2\nkwadraat",
+	sup3:"superscript 3\ntot de derde",
+	acute:"accent aigu",
+	micro:"micro (mu)",
+	para:"paragraaf (pilcrow)",
+	middot:"vermenigvuldigingspunt\nmiddle dot",
+	cedil:"cedille",
+	sup1:"superscript 1",
+	ordm:"aanduiding mannelijk rangtelwoord (Spaans)",
+	raquo:"rechter guillemet\ndubbele punthaak sluiten",
+	frac14:"1/4 (kwart)",
+	frac12:"1/2 (half)",
+	frac34:"3/4 (driekwart)",
+	iquest:"omgekeerd vraagteken",
+	Agrave:"hoofdletter A met accent grave",
+	Aacute:"hoofdletter A met accent aigu",
+	Acirc:"hoofdletter A met accent circonflexe",
+	Atilde:"hoofdletter A met tilde",
+	Auml:"hoofdletter A met trema",
+	Aring:"hoofdletter A met corona",
+	AElig:"hoofletter AE-ligatuur",
+	Ccedil:"hoofdletter C met cedille",
+	Egrave:"hoofdletter E met accent grave",
+	Eacute:"hoofdletter E met accent aigu",
+	Ecirc:"hoofdletter E met accent circonflexe",
+	Euml:"hoofdletter E met trema",
+	Igrave:"hoofdletter I met accent grave",
+	Iacute:"hoofdletter I met accent aigu",
+	Icirc:"hoofdletter I met accent circonflexe",
+	Iuml:"hoofdletter I met trema",
+	ETH:"hoofdletter ETH-ligatuur",
+	Ntilde:"hoofdletter N met tilde",
+	Ograve:"hoofdletter O met accent grave",
+	Oacute:"hoofdletter O met accent aigu",
+	Ocirc:"hoofdletter O met accent circonflexe",
+	Otilde:"hoofdletter O met tilde",
+	Ouml:"hoofdletter O met trema",
+	times:"maal",
+	Oslash:"hoofdletter O doorgestreept",
+	Ugrave:"hoofdletter U met accent grave",
+	Uacute:"hoofdletter U met accent aigu",
+	Ucirc:"hoofdletter U met accent circonflexe",
+	Uuml:"hoofdletter U met trema",
+	Yacute:"hoofdletter Y met accent aigu",
+	THORN:"hoofdletter THORN",
+	szlig:"sz-ligatuur\nringel S",
+	agrave:"kleine letter a met accent grave",
+	aacute:"kleine letter a met accent aigu",
+	acirc:"kleine letter a met accent circonflexe",
+	atilde:"kleine letter a met tilde",
+	auml:"kleine letter a met trema",
+	aring:"kleine letter a met corona",
+	aelig:"kleine letter ae-ligatuur",
+	ccedil:"kleine letter c met cedille",
+	egrave:"kleine letter e met accent grave",
+	eacute:"kleine letter e met accent aigu",
+	ecirc:"kleine letter e met accent circonflexe",
+	euml:"kleine letter e met trema",
+	igrave:"kleine letter i met accent grave",
+	iacute:"kleine letter i met accent aigu",
+	icirc:"kleine letter i met accent circonflexe",
+	iuml:"kleine letter i met trema",
+	eth:"kleine letter eth",
+	ntilde:"kleine letter n met tilde",
+	ograve:"kleine letter o met accent grave",
+	oacute:"kleine letter o met accent aigu",
+	ocirc:"kleine letter o met accent circonflexe",
+	otilde:"kleine letter o met tilde",
+	ouml:"kleine letter o met trema",
+	divide:"deelteken",
+	oslash:"kleine letter o doorgestreept",
+	ugrave:"kleine letter u met accent grave",
+	uacute:"kleine letter u met accent aigu",
+	ucirc:"kleine letter u met accent circonflexe",
+	uuml:"kleine letter u met trema",
+	yacute:"kleine letter y met accent aigu",
+	thorn:"kleine letter thorn",
+	yuml:"kleine letter y met trema",
+
+// Greek Characters and Symbols
+	fnof:"cursieve f\nfunctie\ngulden",
+	Alpha:"Griekse hoofdletter alpha",
+	Beta:"Griekse hoofdletter bèta",
+	Gamma:"Griekse hoofdletter gamma",
+	Delta:"Griekse hoofdletter delta",
+	Epsilon:"Griekse hoofdletter epsilon",
+	Zeta:"Griekse hoofdletter zèta",
+	Eta:"Griekse hoofdletter èta",
+	Theta:"Griekse hoofdletter thèta",
+	Iota:"Griekse hoofdletter iota",
+	Kappa:"Griekse hoofdletter kappa",
+	Lambda:"Griekse hoofdletter lambda",
+	Mu:"Griekse hoofdletter mu",
+	Nu:"Griekse hoofdletter nu",
+	Xi:"Griekse hoofdletter xi",
+	Omicron:"Griekse hoofdletter omicron",
+	Pi:"Griekse hoofdletter pi",
+	Rho:"Griekse hoofdletter rho",
+	Sigma:"Griekse hoofdletter sigma",
+	Tau:"Griekse hoofdletter tau",
+	Upsilon:"Griekse hoofdletter ypsilon",
+	Phi:"Griekse hoofdletter phi",
+	Chi:"Griekse hoofdletter chi",
+	Psi:"Griekse hoofdletter psi",
+	Omega:"Griekse hoofdletter omega",
+	alpha:"Griekse kleine letter alpha",
+	beta:"Griekse kleine letter bèta",
+	gamma:"Griekse kleine letter gamma",
+	delta:"Griekse kleine letter delta",
+	epsilon:"Griekse kleine letter epsilon",
+	zeta:"Griekse kleine letter zèta",
+	eta:"Griekse kleine letter èta",
+	theta:"Griekse kleine letter thèta",
+	iota:"Griekse kleine letter iota",
+	kappa:"Griekse kleine letter kappa",
+	lambda:"Griekse kleine letter lambda",
+	mu:"Griekse kleine letter mu",
+	nu:"Griekse kleine letter nu",
+	xi:"Griekse kleine letter xi",
+	omicron:"Griekse kleine letter omicron",
+	pi:"Griekse kleine letter pi",
+	rho:"Griekse kleine letter rho",
+	sigmaf:"Griekse kleine letter sigma (einde woord)",
+	sigma:"Griekse kleine letter sigma",
+	tau:"Griekse kleine letter tau",
+	upsilon:"Griekse kleine letter ypsilon",
+	phi:"Griekse kleine letter phi",
+	chi:"Griekse kleine letter chi",
+	psi:"Griekse kleine letter psi",
+	omega:"Griekse kleine letter omega",
+	thetasym:"Griekse kleine letter thèta (2e vorm)",
+	upsih:"Griekse letter ypsilon met haakje",
+	piv:"Griekse letter pi (2e vorm)",
+	bull:"opsommingsteken\naandachtspunt",
+	hellip:"beletselteken\weglatingsteken",
+	prime:"accent\nminuut\nvoet",
+	Prime:"dubbel accent\nseconde\ninch",
+	oline:"hoge lijn\nbovenstreepje",
+	frasl:"deelteken/schuine streep",
+	weierp:"Gotische P",
+	image:"Gotische I\nimaginair deel",
+	real:"Gotische R\nreëel deel",
+	trade:"handelsmerk",
+	alefsym:"alef",
+	larr:"pijl naar links",
+	uarr:"pijl omhoog",
+	rarr:"pijl naar rechts",
+	darr:"pijl omlaag",
+	harr:"pijl links/rechts",
+	crarr:"pijl omlaag en naar links\nterugloopteken",
+	lArr:"dubbele pijl naar links",
+	uArr:"dubbele pijl omhoog",
+	rArr:"dubbele pijl naar rechts",
+	dArr:"dubbele pijl omlaag",
+	hArr:"dubbele pijl links/rechts",
+	forall:"voor alle geldt",
+	part:"partiële differentiaal",
+	exist:"er bestaat",
+	empty:"lege verzameling\nnulverzameling\ndiameter",
+	nabla:"nabla\ngradiënt",
+	isin:"is element van",
+	notin:"is geen element van",
+	ni:"heeft als element",
+	prod:"product\nherhaald vermenigvuldigen",
+	sum:"som\nherhaald optellen",
+	minus:"min",
+	lowast:"asterisk operator",
+	radic:"wortel\nvierkantswortel",
+	prop:"evenredig met",
+	infin:"oneindig",
+	ang:"hoek",
+	and:"logische en",
+	or:"logische of",
+	cap:"snijpunt",
+	cup:"vereniging","int":"integraal",
+	there4:"hieruit volgt",
+	sim:"tilde operator\nvarieert met\nvergelijkbaar met",
+	cong:"congruent aan",
+	asymp:"ongeveer gelijk aan",
+	ne:"niet gelijk aan",
+	equiv:"identiek met",
+	le:"kleiner dan of gelijk aan",
+	ge:"groter dan of gelijk aan",
+	sub:"is deelverzameling van",
+	sup:"bevat deelverzameling",
+	nsub:"is geen deelverzameling van",
+	sube:"is deelverzameling van of is gelijk aan",
+	supe:"bevat deelverzameling of is gelijk aan",
+	oplus:"plus in cirkel\ndirecte som",
+	otimes:"maal in cirkel\nvectorproduct",
+	perp:"loodrecht\northogonaal met",
+	sdot:"punt operator",
+	lceil:"linker afrondingshaakje (naar boven)",
+	rceil:"rechter afrondingshaakje (naar boven)",
+	lfloor:"linker afrondingshaakje (naar beneden)",
+	rfloor:"linker afrondingshaakje (naar beneden)",
+	lang:"punthaak openen",
+	rang:"punthaak sluiten",
+	loz:"ruit",
+	spades:"schoppen",
+	clubs:"klaveren",
+	hearts:"harten",
+	diams:"ruiten",
+	OElig:"hoofdletter OE-ligatuur",
+	oelig:"kleine letter oe-ligatuur",
+	Scaron:"hoofdletter S met caron",
+	scaron:"kleine letter s met caron",
+	Yuml:"hoofdletter Y met trema",
+	circ:"accent circonflexe",
+	tilde:"kleine tilde",
+	ensp:"smalle spatie",
+	emsp:"brede spatie",
+	thinsp:"extra smalle spatie",
+	zwnj:"verdelingsteken met breedte nul",
+	zwj:"verbindingsteken met breedte nul",
+	lrm:"van links naar rechts-markering",
+	rlm:"van rechts naar links-markering",
+	ndash:"divisie (kort steepje)",
+	mdash:"divisie (lang steepje)",
+	lsquo:"linker enkel aanhalingsteken",
+	rsquo:"rechter enkel aanhalingsteken",
+	sbquo:"apostrof (vorm = 9)",
+	ldquo:"linker dubbele aanhalingsteken",
+	rdquo:"rechter dubbele aanhalingsteken",
+	bdquo:"dubbele apostrof (vorm = 9)",
+	dagger:"obelisk",
+	Dagger:"dubbele obelisk",
+	permil:"promille",
+	lsaquo:"enkele linkswijzend aanhalingsteken",
+	rsaquo:"enkele rechtswijzend aanhalingsteken",
+	euro:"euro"
+})
+
diff --git a/dojox/editor/plugins/nls/pl/AutoSave.js b/dojox/editor/plugins/nls/pl/AutoSave.js
new file mode 100644
index 0000000..8b89855
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Zapisz",
+	"saveSettingLabelOn": "Ustaw odstęp czasu automatycznego zapisywania...",
+	"saveSettingLabelOff": "Wyłącz automatyczne zapisywanie",
+	"saveSettingdialogTitle": "Automatyczne zapisywanie",
+	"saveSettingdialogDescription": "Określ odstęp czasu automatycznego zapisywania",
+	"saveSettingdialogParamName": "Odstęp czasu automatycznego zapisywania",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Ustaw odstęp czasu",
+	"saveSettingdialogButtonCancel": "Anuluj",
+	"saveMessageSuccess": "Zapisano: ${0}",
+	"saveMessageFail": "Zapisanie nie powiodło się: ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/pl/Blockquote.js b/dojox/editor/plugins/nls/pl/Blockquote.js
new file mode 100644
index 0000000..a948b82
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Cytat blokowy"
+})
+
diff --git a/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js b/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
new file mode 100644
index 0000000..b034f4e
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Zwiń pasek narzędzi edytora",
+	"expand": "Rozwiń pasek narzędzi edytora"
+})
+
diff --git a/dojox/editor/plugins/nls/pl/FindReplace.js b/dojox/editor/plugins/nls/pl/FindReplace.js
index eabf728..0833763 100644
--- a/dojox/editor/plugins/nls/pl/FindReplace.js
+++ b/dojox/editor/plugins/nls/pl/FindReplace.js
@@ -1,12 +1,23 @@
 ({
 	"findLabel": "Znajdź:",
+	"findTooltip": "Wprowadź szukany tekst",
 	"replaceLabel": "Zastąp przez:",
-	"findReplace": "Przełącz znajdowanie/zastępowanie",
-	"matchCase": "Uwzględniaj wielkość liter", 
+	"replaceTooltip": "Wprowadź tekst zastępujący",
+	"findReplace": "Znajdź i zastąp",
+	"matchCase": "Uwzględnij wielkość liter",
+	"matchCaseTooltip": "Uwzględnij wielkość liter",
 	"backwards": "Do tyłu",
-	"replaceAll": "Wszystkie wystąpienia", 
+	"backwardsTooltip": "Wyszukaj tekst wstecz",
+	"replaceAll": "Wszystkie wystąpienia",
+	"replaceAllButton": "Zastąp wszystkie",
+	"replaceAllButtonTooltip": "Zastąp cały tekst",
 	"findButton": "Znajdź",
+	"findButtonTooltip": "Znajdź tekst",
 	"replaceButton": "Zastąp",
-	"replaceDialogText": "Zastąpione wystąpienia: ${0}."
+	"replaceButtonTooltip": "Zastąp tekst",
+	"replaceDialogText": "Zastąpione wystąpienia: ${0}.",
+	"eofDialogText": "Ostatnie wystąpienie: ${0}",
+	"eofDialogTextFind": "znaleziono",
+	"eofDialogTextReplace": "zastąpiono"
 })
 
diff --git a/dojox/editor/plugins/nls/pl/InsertAnchor.js b/dojox/editor/plugins/nls/pl/InsertAnchor.js
new file mode 100644
index 0000000..912f9b2
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Wstaw zakotwiczenie",
+	title: "Właściwości zakotwiczenia",
+	anchor: "Nazwa:",
+	text: "Opis:",
+	set: "Ustaw",
+	cancel: "Anuluj"
+})
+
diff --git a/dojox/editor/plugins/nls/pl/LocalImage.js b/dojox/editor/plugins/nls/pl/LocalImage.js
new file mode 100644
index 0000000..ee85290
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Wstaw obraz",
+	url: "Obraz",
+	browse: "Przeglądaj...",
+	text: "Opis",
+	set: "Wstaw",
+	invalidMessage: "Niepoprawny typ pliku graficznego",
+	prePopuTextUrl: "Wprowadź adres URL obrazu",
+	prePopuTextBrowse: " lub wskaż plik lokalny. "
+})
+
diff --git a/dojox/editor/plugins/nls/pl/PasteFromWord.js b/dojox/editor/plugins/nls/pl/PasteFromWord.js
new file mode 100644
index 0000000..47384b4
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Wklej z programu Word",
+	"paste": "Wklej",
+	"cancel": "Anuluj",
+	"instructions": "Wklej tekst z programu Word do poniższego pola tekstowego. Po uzyskaniu odpowiedniej treści do wstawienia kliknij przycisk Wklej. Aby przerwać wstawianie tekstu, kliknij przycisk Anuluj. "
+})
+
diff --git a/dojox/editor/plugins/nls/pl/Smiley.js b/dojox/editor/plugins/nls/pl/Smiley.js
index db95edf..a12a9f3 100644
--- a/dojox/editor/plugins/nls/pl/Smiley.js
+++ b/dojox/editor/plugins/nls/pl/Smiley.js
@@ -4,18 +4,18 @@
 	emoticonLaughing: "śmiech",
 	emoticonWink: "mrugnięcie",
 	emoticonGrin: "szeroki uśmiech",
-	emoticonCool: "na luzie",
-	emoticonAngry: "złość",  
-	emoticonHalf: "niesmak", 
-	emoticonEyebrow: "brew",
+	emoticonCool: "cwaniak",
+	emoticonAngry: "złość",
+	emoticonHalf: "niesmak",
+	emoticonEyebrow: "uniesienie brwi",
 	emoticonFrown: "niezadowolenie",
 	emoticonShy: "nieśmiałość",
 	emoticonGoofy: "niezdarność",
-	emoticonOops: "oj",
-	emoticonTongue: "język",
+	emoticonOops: "ups",
+	emoticonTongue: "pokazywanie języka",
 	emoticonIdea: "pomysł",
 	emoticonYes: "Tak",
-	emoticonNo: "Nie",	
+	emoticonNo: "Nie",
 	emoticonAngel: "anioł",
 	emoticonCrying: "płacz"
 })
diff --git a/dojox/editor/plugins/nls/pl/SpellCheck.js b/dojox/editor/plugins/nls/pl/SpellCheck.js
new file mode 100644
index 0000000..3642cf6
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Wsadowe sprawdzanie pisowni",
+	unfound: "Nie znaleziono",
+	skip: "Pomiń",
+	skipAll: "Pomiń wszystko",
+	toDic: "Dodaj do słownika",
+	suggestions: "Propozycje",
+	replace: "Zastąp",
+	replaceWith: "Zastąp przez",
+	replaceAll: "Zastąp wszystko",
+	cancel: "Anuluj",
+	msg: "Nie znaleziono błędów pisowni",
+	iSkip: "Pomiń tę pozycję",
+	iSkipAll: "Pomiń wszystkie pozycje podobne do tej",
+	iMsg: "Brak propozycji pisowni"
+})
+
diff --git a/dojox/editor/plugins/nls/pl/TableDialog.js b/dojox/editor/plugins/nls/pl/TableDialog.js
index 710ad5e..087d4f0 100644
--- a/dojox/editor/plugins/nls/pl/TableDialog.js
+++ b/dojox/editor/plugins/nls/pl/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "prawa strona",
 	buttonSet: "Ustaw", // translated elsewhere?
 	buttonInsert: "Wstaw",
+	buttonCancel: "Anuluj",
 
 	selectTableLabel: "Wybierz tabelę",
 	insertTableRowBeforeLabel: "Dodaj wiersz przed",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "Usuń wiersz",
 	deleteTableColumnLabel: "Usuń kolumnę"
 })
-
diff --git a/dojox/editor/plugins/nls/pl/TextColor.js b/dojox/editor/plugins/nls/pl/TextColor.js
new file mode 100644
index 0000000..7e954b4
--- /dev/null
+++ b/dojox/editor/plugins/nls/pl/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Ustaw",
+	"cancelButtonText": "Anuluj"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/AutoSave.js b/dojox/editor/plugins/nls/pt-pt/AutoSave.js
new file mode 100644
index 0000000..9f23d63
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Guardar",
+	"saveSettingLabelOn": "Definir intervalo de gravação automática...",
+	"saveSettingLabelOff": "Desactivar gravação automática",
+	"saveSettingdialogTitle": "Gravação automática",
+	"saveSettingdialogDescription": "Especificar intervalo de gravação automática",
+	"saveSettingdialogParamName": "Intervalo de gravação automática",
+	"saveSettingdialogParamLabel": "mín.",
+	"saveSettingdialogButtonOk": "Definir intervalo",
+	"saveSettingdialogButtonCancel": "Cancelar",
+	"saveMessageSuccess": "Guardado às ${0}",
+	"saveMessageFail": "Falha ao guardar às ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/Blockquote.js b/dojox/editor/plugins/nls/pt-pt/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js b/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
new file mode 100644
index 0000000..aee6191
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "Acções de ${nodeName}",
+	"selectContents": "Seleccionar conteúdo",
+	"selectElement": "Seleccionar elemento",
+	"deleteElement": "Eliminar elemento",
+	"deleteContents": "Eliminar conteúdo",
+	"moveStart": "Mover cursor para o início",
+	"moveEnd": "Mover cursor para o fim"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js b/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
new file mode 100644
index 0000000..fa26a52
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Contrair barra de ferramentas do editor",
+	"expand": "Expandir barra de ferramentas do editor"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/FindReplace.js b/dojox/editor/plugins/nls/pt-pt/FindReplace.js
new file mode 100644
index 0000000..df7176b
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Localizar:",
+	"findTooltip": "Introduzir texto a localizar",
+	"replaceLabel": "Substituir por:",
+	"replaceTooltip": "Introduzir texto de substituição",
+	"findReplace": "Localizar e substituir",
+	"matchCase": "Correspondência de maiúsculas/minúsculas",
+	"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",
+	"findButtonTooltip": "Localizar o texto",
+	"replaceButton": "Substituir",
+	"replaceButtonTooltip": "Substituir o texto",
+	"replaceDialogText": "Foram substituídas ${0} ocorrências.",
+	"eofDialogText": "Última ocorrência ${0}",
+	"eofDialogTextFind": "localizado",
+	"eofDialogTextReplace": "substituído"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js b/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
new file mode 100644
index 0000000..140265a
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Inserir âncora",
+	title: "Propriedades da âncora",
+	anchor: "Nome:",
+	text: "Descrição:",
+	set: "Definir",
+	cancel: "Cancelar"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/InsertEntity.js b/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
new file mode 100644
index 0000000..e2288f9
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Inserir símbolo"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/LocalImage.js b/dojox/editor/plugins/nls/pt-pt/LocalImage.js
new file mode 100644
index 0000000..ea4aae6
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Inserir imagem",
+	url: "Imagem",
+	browse: "Pesquisar...",
+	text: "Descrição",
+	set: "Inserir",
+	invalidMessage: "Tipo de ficheiro de imagem não válido",
+	prePopuTextUrl: "Introduzir um URL de imagem",
+	prePopuTextBrowse: " ou navegar até um ficheiro local."
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/PageBreak.js b/dojox/editor/plugins/nls/pt-pt/PageBreak.js
new file mode 100644
index 0000000..76f29ef
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Quebra de página"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js b/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
new file mode 100644
index 0000000..52c10f1
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Colar do Word",
+	"paste": "Colar",
+	"cancel": "Cancelar",
+	"instructions": "Cole o conteúdo do Word na caixa de texto abaixo. Após estar satisfeito com o conteúdo a inserir, prima o botão de colagem. Para cancelar a inserção de texto, prima o botão de cancelamento."
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/Preview.js b/dojox/editor/plugins/nls/pt-pt/Preview.js
new file mode 100644
index 0000000..aaf4d32
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Pré-visualizar"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/Save.js b/dojox/editor/plugins/nls/pt-pt/Save.js
new file mode 100644
index 0000000..11af7ed
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Guardar"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js b/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
new file mode 100644
index 0000000..9a7e5e5
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Mostrar elementos do bloco HTML"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/Smiley.js b/dojox/editor/plugins/nls/pt-pt/Smiley.js
new file mode 100644
index 0000000..8159299
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Inserir ícone emotivo",
+	emoticonSmile: "sorriso",
+	emoticonLaughing: "riso",
+	emoticonWink: "piscadela",
+	emoticonGrin: "gargalhada",
+	emoticonCool: "com estilo",
+	emoticonAngry: "zangado",
+	emoticonHalf: "céptico",
+	emoticonEyebrow: "desconfiado",
+	emoticonFrown: "triste",
+	emoticonShy: "tímido",
+	emoticonGoofy: "engraçado",
+	emoticonOops: "ups",
+	emoticonTongue: "língua de fora",
+	emoticonIdea: "ideia",
+	emoticonYes: "sim",
+	emoticonNo: "não",
+	emoticonAngel: "anjo",
+	emoticonCrying: "a chorar"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/SpellCheck.js b/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
new file mode 100644
index 0000000..bb4c272
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Verificação ortográfica por grupo",
+	unfound: "Não localizado",
+	skip: "Ignorar",
+	skipAll: "Ignorar tudo",
+	toDic: "Adicionar ao dicionário",
+	suggestions: "Sugestões",
+	replace: "Substituir",
+	replaceWith: "Substituir por",
+	replaceAll: "Substituir tudo",
+	cancel: "Cancelar",
+	msg: "Não forem encontrados erros ortográficos",
+	iSkip: "Ignorar isto",
+	iSkipAll: "Ignorar semelhantes",
+	iMsg: "Sem sugestões de ortografia"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/TableDialog.js b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
index 2b81fe1..fa72f93 100644
--- a/dojox/editor/plugins/nls/pt-pt/TableDialog.js
+++ b/dojox/editor/plugins/nls/pt-pt/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "direita",
 	buttonSet: "Definir", // translated elsewhere?
 	buttonInsert: "Inserir",
+	buttonCancel: "Cancelar",
 
 	selectTableLabel: "Seleccionar tabela",
 	insertTableRowBeforeLabel: "Adicionar linha antes",
diff --git a/dojox/editor/plugins/nls/pt-pt/TextColor.js b/dojox/editor/plugins/nls/pt-pt/TextColor.js
new file mode 100644
index 0000000..aa9092c
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Definir",
+	"cancelButtonText": "Cancelar"
+})
+
diff --git a/dojox/editor/plugins/nls/pt-pt/latinEntities.js b/dojox/editor/plugins/nls/pt-pt/latinEntities.js
new file mode 100644
index 0000000..65e05da
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt-pt/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"ponto de exclamação invertido",
+	cent:"símbolo de cêntimo",
+	pound:"símbolo de libra",
+	curren:"símbolo monetário",
+	yen:"símbolo do iene\nsímbolo do yuan",
+	brvbar:"barra quebrada\nbarra vertical quebrada",
+	sect:"símbolo de secção",
+	uml:"trema\ntrema de espaço",
+	copy:"símbolo de direitos de autor",
+	ordf:"indicador ordinal feminino",
+	laquo:"aspas esquerdas em ângulo\naspas esquerdas",
+	not:"sinal de negação",
+	shy:"hífen virtual\nhífen discricionário",
+	reg:"símbolo de marca registada\nsímbolo de marca comercial registada",
+	macr:"mácron\nmácron de espaço\nlinha sobreposta\nbarra superior de APL",
+	deg:"sinal de graus",
+	plusmn:"sinal de adição-subtracção\nsinal de adição ou subtracção",
+	sup2:"expoente dois\nexpoente algarismo dois\nao quadrado",
+	sup3:"expoente três\nexpoente algarismo três\nao cubo",
+	acute:"acento agudo\nacento agudo de espaço",
+	micro:"sinal de micro",
+	para:"sinal de parágrafo\nsímbolo de parágrafo",
+	middot:"ponto central\nvírgula georgina\nGrego - Ponto central",
+	cedil:"cedilha\ncedilha de espaço",
+	sup1:"expoente um\nexpoente algarismo um",
+	ordm:"indicador ordinal masculino",
+	raquo:"aspas direitas em ângulo\naspas direitas",
+	frac14:"fracção comum - um quarto\nfracção - um quarto",
+	frac12:"fracção comum - um meio\nfracção - um meio",
+	frac34:"fracção comum - três quartos\nfracção - três quartos",
+	iquest:"ponto de interrogação invertido",
+	Agrave:"Latim - Letra maiúscula A com acento grave\nLatim - Letra maiúscula A grave",
+	Aacute:"Latim - Letra maiúscula A com acento agudo",
+	Acirc:"Latim - Letra maiúscula A com acento circumflexo",
+	Atilde:"Latim - Letra maiúscula A com til",
+	Auml:"Latim - Letra maiúscula A com trema",
+	Aring:"Latim - Letra maiúscula A com círculo por cima\nLatim - Letra maiúscula A com círculo",
+	AElig:"Latim - Letras maiúsculas AE\nLatim - Letras maiúsculas ligadas AE",
+	Ccedil:"Latim - Letra maiúscula C com cedilha",
+	Egrave:"Latim - Letra maiúscula E com acento grave",
+	Eacute:"Latim - Letra maiúscula E com acento agudo",
+	Ecirc:"Latim - Letra maiúscula E com acento circunflexo",
+	Euml:"Latim - Letra maiúscula E com trema",
+	Igrave:"Latim - Letra maiúscula I com acento grave",
+	Iacute:"Latim - Letra maiúscula I com acento agudo",
+	Icirc:"Latim - Letra maiúscula I com acento circunflexo",
+	Iuml:"Latim - Letra maiúscula I com trema",
+	ETH:"Latim - Letra maiúscula islandesa ETH",
+	Ntilde:"Latim - Letra maiúscula N com til",
+	Ograve:"Latim - Letra maiúscula O com acento grave",
+	Oacute:"Latim - Letra maiúscula O com acento agudo",
+	Ocirc:"Latim - Letra maiúscula O com acento circunflexo",
+	Otilde:"Latim - Letra maiúscula O com til",
+	Ouml:"Latim - Letra maiúscula O com trema",
+	times:"sinal de multiplicação",
+	Oslash:"Latim - Letra maiúscula O cortada por um traço\nLatim - Letra maiúscula O cortada",
+	Ugrave:"Latim - Letra maiúscula U com acento grave",
+	Uacute:"Latim - Letra maiúscula U com acento agudo",
+	Ucirc:"Latim - Letra maiúscula U com acento circunflexo",
+	Uuml:"Latim - Letra maiúscula U com trema",
+	Yacute:"Latim - Letra maiúscula Y com acento agudo",
+	THORN:"Latim - Letra maiúscula islandesa THORN",
+	szlig:"Latim - Letra minúscula beta\ness-zett alemão",
+	agrave:"Latim - Letra minúscula a com acento grave\nLatim - Letra minúscula a grave",
+	aacute:"Latim - Letra minúscula a com acento agudo",
+	acirc:"Latim - Letra minúscula a com acento circunflexo",
+	atilde:"Latim - Letra minúscula a com til",
+	auml:"Latim - Letra minúscula a com trema",
+	aring:"Latim - Letra minúscula a com círculo por cima\nLatim - Letra minúscula a com círculo",
+	aelig:"Latim - Letras minúsculas ae\nLatim - Letras minúsculas ligadas ae",
+	ccedil:"Latim - Letra minúscula c com cedilha",
+	egrave:"Latim - Letra minúscula e com acento grave",
+	eacute:"Latim - Letra minúscula e com acento agudo",
+	ecirc:"Latim - Letra minúscula e com acento circunflexo",
+	euml:"Latim - Letra minúscula e com trema",
+	igrave:"Latim - Letra minúscula i com acento grave",
+	iacute:"Latim - Letra minúscula i com acento agudo",
+	icirc:"Latim - Letra minúscula i com acento circunflexo",
+	iuml:"Latim - Letra minúscula i com trema",
+	eth:"Latim - Letra minúscula islandesa eth",
+	ntilde:"Latim - Letra minúscula n com til",
+	ograve:"Latim - Letra minúscula o com acento grave",
+	oacute:"Latim - Letra minúscula o com acento agudo",
+	ocirc:"Latim - Letra minúscula o com acento circunflexo",
+	otilde:"Latim - Letra minúscula o com til",
+	ouml:"Latim - Letra minúscula o com trema",
+	divide:"sinal de divisão",
+	oslash:"Latim - Letra minúscula o cortada por um traço\nLatim - Letra minúscula o cortada",
+	ugrave:"Latim - Letra minúscula u com acento grave",
+	uacute:"Latim - Letra minúscula u com acento agudo",
+	ucirc:"Latim - Letra minúscula u com acento circunflexo",
+	uuml:"Latim - Letra minúscula u com trema",
+	yacute:"Latim - Letra minúscula y com acento agudo",
+	thorn:"Latim - Letra minúscula islandesa thorn",
+	yuml:"Latim - Letra minúscula y com trema",
+
+// Greek Characters and Symbols
+	fnof:"Latim - Letra minúscula f com gancho\nfunção\nflorim",
+	Alpha:"Grego - Letra maiúscula alfa",
+	Beta:"Grego - Letra maiúscula beta",
+	Gamma:"Grego - Letra maiúscula gama",
+	Delta:"Grego - Letra maiúscula delta",
+	Epsilon:"Grego - Letra maiúscula épsilon",
+	Zeta:"Grego - Letra maiúscula zeta",
+	Eta:"Grego - Letra maiúscula eta",
+	Theta:"Grego - Letra maiúscula teta",
+	Iota:"Grego - Letra maiúscula iota",
+	Kappa:"Grego - Letra maiúscula capa",
+	Lambda:"Grego - Letra maiúscula lambda",
+	Mu:"Grego - Letra maiúscula mi",
+	Nu:"Grego - Letra maiúscula ni",
+	Xi:"Grego - Letra maiúscula csi",
+	Omicron:"Grego - Letra maiúscula ómicron",
+	Pi:"Grego - Letra maiúscula pi",
+	Rho:"Grego - Letra maiúscula ró",
+	Sigma:"Grego - Letra maiúscula sigma",
+	Tau:"Grego - Letra maiúscula tau",
+	Upsilon:"Grego - Letra maiúscula ípsilon",
+	Phi:"Grego - Letra maiúscula fi",
+	Chi:"Grego - Letra maiúscula qui",
+	Psi:"Grego - Letra maiúscula psi",
+	Omega:"Grego - Letra maiúscula ómega",
+	alpha:"Grego - Letra minúscula alfa",
+	beta:"Grego - Letra minúscula beta",
+	gamma:"Grego - Letra minúscula gama",
+	delta:"Grego - Letra minúscula delta",
+	epsilon:"Grego - Letra minúscula épsilon",
+	zeta:"Grego - Letra minúscula zeta",
+	eta:"Grego - Letra minúscula eta",
+	theta:"Grego - Letra minúscula teta",
+	iota:"Grego - Letra minúscula iota",
+	kappa:"Grego - Letra minúscula capa",
+	lambda:"Grego - Letra minúscula lambda",
+	mu:"Grego - Letra minúscula mi",
+	nu:"Grego - Letra minúscula ni",
+	xi:"Grego - Letra minúscula csi",
+	omicron:"	Grego - Letra minúscula ómicron",
+	pi:"Grego - Letra minúscula pi",
+	rho:"Grego - Letra minúscula ró",
+	sigmaf:"	Grego - Letra minúscula sigma final",
+	sigma:"Grego - Letra minúscula sigma",
+	tau:"Grego - Letra minúscula tau",
+	upsilon:"Grego - Letra minúscula ípsilon",
+	phi:"Grego - Letra minúscula fi",
+	chi:"Grego - Letra minúscula qui",
+	psi:"	Grego - Letra minúscula psi",
+	omega:"Grego - Letra minúscula ómega",
+	thetasym:"Grego - Símbolo da letra minúscula teta",
+	upsih:"Grego - Ípsilon com símbolo do gancho",
+	piv:"Grego - Símbolo pi",
+	bull:"marca\ncírculo pequeno preto",
+	hellip:"reticências horizontais\ntrês pontos de seguimento",
+	prime:"apóstrofo\nminutos\npés",
+	Prime:"apóstrofo duplo\nsegundos\npolegadas",
+	oline:"linha sobreposta\nlinha sobreposta de espaço",
+	frasl:"barra de fracção",
+	weierp:"letra maiúscula P cursiva\nconjunto potência\np de Weierstrass",
+	image:"letra maiúscula I carregada\nparte imaginária",
+	real:"letra maiúscula R carregada\nsímbolo da parte real",
+	trade:"símbolo de marca comercial",
+	alefsym:"símbolo de elif\nprimeiro cardinal transfinito",
+	larr:"seta para a esquerda",
+	uarr:"seta para cima",
+	rarr:"seta para a direita",
+	darr:"seta para baixo",
+	harr:"seta para a esquerda e para a direita",
+	crarr:"seta para baixo em ângulo recto para a esquerda\nsímbolo de retorno",
+	lArr:"seta dupla para a esquerda",
+	uArr:"seta dupla para cima",
+	rArr:"seta dupla para a direita",
+	dArr:"seta dupla para baixo",
+	hArr:"Seta dupla para a esquerda e para a direita",
+	forall:"para todos",
+	part:"diferencial parcial",
+	exist:"existe",
+	empty:"conjunto vazio\nconjunto nulo\ndiâmetro",
+	nabla:"nabla\ngradiente",
+	isin:"pertence a",
+	notin:"não pertence a",
+	ni:"contém como membro",
+	prod:"produto n-ário\nsinal de produto",
+	sum:"somatório n-ário",
+	minus:"sinal de subtracção",
+	lowast:"operador asterisco",
+	radic:"raiz quadrada\nsinal de radical",
+	prop:"proporcional a",
+	infin:"infinito",
+	ang:"ângulo",
+	and:"E lógico\ncunha",
+	or:"OU lógico\nv",
+	cap:"intersecção\n cap",
+	cup:"união\n cup","int":"integral",
+	there4:"para isso",
+	sim:"operador til\nvaria\nsemelhante a",
+	cong:"aproximadamente igual a",
+	asymp:"quase igual a\nassimptótico a",
+	ne:"não igual a",
+	equiv:"idêntico a",
+	le:"menor ou igual a",
+	ge:"maior ou igual a",
+	sub:"está contido",
+	sup:"contém",
+	nsub:"não está contido em",
+	sube:"está contido ou igual a",
+	supe:"contém ou igual a",
+	oplus:"adição dentro de um círculo\nsoma directa",
+	otimes:"multiplicação dentro de um círculo\nproduto vectorial",
+	perp:"tacha em cima\nortogonal a\nperpendicular",
+	sdot:"operador de ponto",
+	lceil:"limite superior à esquerda\nAPL upstile",
+	rceil:"limite superior à direita",
+	lfloor:"limite inferior à esquerda\nAPL downstile",
+	rfloor:"limite inferior à direita",
+	lang:"parêntese esquerdo em ângulo",
+	rang:"parêntese direito em ângulo",
+	loz:"losango",
+	spades:"naipe preto de espadas",
+	clubs:"naipe preto de paus\ntrevo",
+	hearts:"naipe preto de copas\ncoração",
+	diams:"naipe preto de ouros",
+	OElig:"Latim - Letras maiúsculas ligadas OE",
+	oelig:"Latim - Letras minúsculas ligadas oe",
+	Scaron:"Latim - Letra maiúscula S com cáron",
+	scaron:"Latim - Letra minúscula s com cáron",
+	Yuml:"Latim - Letra maiúscula Y com trema",
+	circ:"modificadores - acento circunflexo",
+	tilde:"til pequeno",
+	ensp:"espaço simples",
+	emsp:"espaço duplo",
+	thinsp:"espaço fino",
+	zwnj:"não separador de largura nula",
+	zwj:"separador de largura nula",
+	lrm:"marca da esquerda para a direita",
+	rlm:"marca da direita para a esquerda",
+	ndash:"traço",
+	mdash:"travessão",
+	lsquo:"plica esquerda",
+	rsquo:"plica direita",
+	sbquo:"plica curva inferior",
+	ldquo:"aspas esquerdas",
+	rdquo:"aspas direitas",
+	bdquo:"aspas curvas inferiores",
+	dagger:"óbelo",
+	Dagger:"óbelo duplo",
+	permil:"sinal de por mil",
+	lsaquo:"plica esquerda em ângulo",
+	rsaquo:"plica direita em ângulo",
+	euro:"símbolo do euro"
+})
+
diff --git a/dojox/editor/plugins/nls/pt/AutoSave.js b/dojox/editor/plugins/nls/pt/AutoSave.js
new file mode 100644
index 0000000..510cf35
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/AutoSave.js
@@ -0,0 +1,13 @@
+({
+	"saveLabel": "Salvar",
+	"saveSettingLabelOn": "Configurar Intervalo de Salvamento Automático...",
+	"saveSettingLabelOff": "Desativar Salvamento Automático",
+	"saveSettingdialogTitle": "Salvamento Automático",
+	"saveSettingdialogDescription": "Especificar Intervalo de Salvamento Automático",
+	"saveSettingdialogParamName": "Intervalo de Salvamento Automático",
+	"saveSettingdialogParamLabel": "mín.",
+	"saveSettingdialogButtonOk": "Configurar Intervalo",
+	"saveSettingdialogButtonCancel": "Cancelar",
+	"saveMessageSuccess": "Salvo em ${0}",
+	"saveMessageFail": "Falha ao salvar em ${0}"
+})
diff --git a/dojox/editor/plugins/nls/pt/Blockquote.js b/dojox/editor/plugins/nls/pt/Blockquote.js
new file mode 100644
index 0000000..3da0bd2
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/Blockquote.js
@@ -0,0 +1,3 @@
+({
+	"blockquote": "Citação de Bloco"
+})
diff --git a/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js b/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
new file mode 100644
index 0000000..da50a0b
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/CollapsibleToolbar.js
@@ -0,0 +1,4 @@
+({
+	"collapse": "Reduzir Barra de Ferramentas do Editor",
+	"expand": "Expandir Barra de Ferramentas do Editor"
+})
diff --git a/dojox/editor/plugins/nls/pt/FindReplace.js b/dojox/editor/plugins/nls/pt/FindReplace.js
index 7b9a364..5041fdc 100644
--- a/dojox/editor/plugins/nls/pt/FindReplace.js
+++ b/dojox/editor/plugins/nls/pt/FindReplace.js
@@ -1,12 +1,22 @@
 ({
 	"findLabel": "Localizar:",
+	"findTooltip": "Inserir texto a ser localizado",
 	"replaceLabel": "Substituir por:",
-	"findReplace": "Comutar Localizar/Substituir",
-	"matchCase": "Caso de Correspondência", 
+	"replaceTooltip": "Inserir texto a ser substituído por",
+	"findReplace": "Localizar e Substituir",
+	"matchCase": "Coincidir maiúscula/minúscula",
+	"matchCaseTooltip": "Coincidir maiúscula/minúscula",
 	"backwards": "Retroceder",
-	"replaceAll": "Todas as Ocorrências", 
+	"backwardsTooltip": "Procurar texto para trás",
+	"replaceAll": "Todas as Ocorrências",
+	"replaceAllButton": "Substituir Todos",
+	"replaceAllButtonTooltip": "Substituir todo o texto",
 	"findButton": "Localizar",
+	"findButtonTooltip": "Localizar o texto",
 	"replaceButton": "Substituir",
-	"replaceDialogText": "${0} ocorrências substituídas."
+	"replaceButtonTooltip": "Substituir o texto",
+	"replaceDialogText": "${0} ocorrências substituídas.",
+	"eofDialogText": "Última ocorrência ${0}",
+	"eofDialogTextFind": "localizado",
+	"eofDialogTextReplace": "substituído"
 })
-
diff --git a/dojox/editor/plugins/nls/pt/InsertAnchor.js b/dojox/editor/plugins/nls/pt/InsertAnchor.js
new file mode 100644
index 0000000..8817cc9
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/InsertAnchor.js
@@ -0,0 +1,8 @@
+({
+	insertAnchor: "Inserir Âncora",
+	title: "Propriedades de Âncora",
+	anchor: "Nome:",
+	text: "Descrição:",
+	set: "Definir",
+	cancel: "Cancelar"
+})
diff --git a/dojox/editor/plugins/nls/pt/LocalImage.js b/dojox/editor/plugins/nls/pt/LocalImage.js
new file mode 100644
index 0000000..20fca98
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/LocalImage.js
@@ -0,0 +1,10 @@
+({
+	insertImageTitle: "Inserir imagem",
+	url: "Imagem",
+	browse: "Procurar...",
+	text: "Descrição",
+	set: "Inserir",
+	invalidMessage: "Tipo de arquivo de imagem inválido",
+	prePopuTextUrl: "Insira uma URL de imagem",
+	prePopuTextBrowse: " ou navegue até um arquivo local."
+})
diff --git a/dojox/editor/plugins/nls/pt/PasteFromWord.js b/dojox/editor/plugins/nls/pt/PasteFromWord.js
new file mode 100644
index 0000000..3b6ea84
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/PasteFromWord.js
@@ -0,0 +1,6 @@
+({
+	"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."
+})
diff --git a/dojox/editor/plugins/nls/pt/Smiley.js b/dojox/editor/plugins/nls/pt/Smiley.js
index 22d76a5..13371bb 100644
--- a/dojox/editor/plugins/nls/pt/Smiley.js
+++ b/dojox/editor/plugins/nls/pt/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "piscando",
 	emoticonGrin: "sorriso largo",
 	emoticonCool: "legal",
-	emoticonAngry: "bravo",  
-	emoticonHalf: "confuso", 
+	emoticonAngry: "bravo",
+	emoticonHalf: "confuso",
 	emoticonEyebrow: "sarcástico",
 	emoticonFrown: "sobrancelhas franzidas",
 	emoticonShy: "envergonhado",
@@ -15,8 +15,7 @@
 	emoticonTongue: "mostrando a língua",
 	emoticonIdea: "ideia",
 	emoticonYes: "sim",
-	emoticonNo: "não",	
+	emoticonNo: "não",
 	emoticonAngel: "angelical",
 	emoticonCrying: "chorando"
 })
-
diff --git a/dojox/editor/plugins/nls/pt/SpellCheck.js b/dojox/editor/plugins/nls/pt/SpellCheck.js
new file mode 100644
index 0000000..8399132
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/SpellCheck.js
@@ -0,0 +1,16 @@
+({
+	widgetLabel: "Verificação Ortográfica em Lote",
+	unfound: "Não localizado",
+	skip: "Ignorar",
+	skipAll: "Ignorar Todos",
+	toDic: "Incluir no dicionário",
+	suggestions: "Sugestões",
+	replace: "Substituir",
+	replaceWith: "Substituir por",
+	replaceAll: "Substituir Todos",
+	cancel: "Cancelar",
+	msg: "Nenhum erro de ortografia encontrado",
+	iSkip: "Ignorar isto",
+	iSkipAll: "Ignorar todos iguais a este",
+	iMsg: "Nenhuma sugestão de ortografia"
+})
diff --git a/dojox/editor/plugins/nls/pt/TableDialog.js b/dojox/editor/plugins/nls/pt/TableDialog.js
index 5258c26..f2a828f 100644
--- a/dojox/editor/plugins/nls/pt/TableDialog.js
+++ b/dojox/editor/plugins/nls/pt/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "direita",
 	buttonSet: "Configurar", // translated elsewhere?
 	buttonInsert: "Inserir",
+	buttonCancel: "Cancelar",
 
 	selectTableLabel: "Selecionar Tabela",
 	insertTableRowBeforeLabel: "Incluir Linha Antes",
@@ -27,4 +28,4 @@
 	deleteTableRowLabel: "Excluir Linha",
 	deleteTableColumnLabel: "Excluir Coluna"
 })
-
+	
diff --git a/dojox/editor/plugins/nls/pt/TextColor.js b/dojox/editor/plugins/nls/pt/TextColor.js
new file mode 100644
index 0000000..2d065fd
--- /dev/null
+++ b/dojox/editor/plugins/nls/pt/TextColor.js
@@ -0,0 +1,4 @@
+({
+	"setButtonText": "Definir",
+	"cancelButtonText": "Cancelar"
+})
diff --git a/dojox/editor/plugins/nls/pt/latinEntities.js b/dojox/editor/plugins/nls/pt/latinEntities.js
index 1c240b5..e8a26ec 100644
--- a/dojox/editor/plugins/nls/pt/latinEntities.js
+++ b/dojox/editor/plugins/nls/pt/latinEntities.js
@@ -254,4 +254,3 @@
 	rsaquo:"aspa latina de abertura",
 	euro:"símbolo de euro"
 })
-
diff --git a/dojox/editor/plugins/nls/ro/AutoSave.js b/dojox/editor/plugins/nls/ro/AutoSave.js
new file mode 100644
index 0000000..3391244
--- /dev/null
+++ b/dojox/editor/plugins/nls/ro/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Salvare",
+	"saveSettingLabelOn": "Setare interval auto-salvare...",
+	"saveSettingLabelOff": "Oprire auto-salvare",
+	"saveSettingdialogTitle": "Auto-salvare",
+	"saveSettingdialogDescription": "Specificare interval auto-salvare",
+	"saveSettingdialogParamName": "Interval auto-salvare",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Setare interval",
+	"saveSettingdialogButtonCancel": "Anulare",
+	"saveMessageSuccess": "Salvat la ${0}",
+	"saveMessageFail": "A eşuat să salveze la${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/ro/FindReplace.js b/dojox/editor/plugins/nls/ro/FindReplace.js
index f029cdb..1442259 100644
--- a/dojox/editor/plugins/nls/ro/FindReplace.js
+++ b/dojox/editor/plugins/nls/ro/FindReplace.js
@@ -1,18 +1,18 @@
 ({
 	"findLabel": "Găsire:",
-	"findTooltip": "Introduceţi textul de găsit ",
-	"replaceLabel": "Înlocuire cu: ",
+	"findTooltip": "Introduceţi textul de găsit",
+	"replaceLabel": "Înlocuire cu:",
 	"replaceTooltip": "Introduceţi textul cu care se înlocuieşte",
 	"findReplace": "Găsire şi înlocuire",
-	"matchCase": "Potrivire majuscule ",
-	"matchCaseTooltip": "Potrivire majuscule ",
+	"matchCase": "Potrivire majuscule",
+	"matchCaseTooltip": "Potrivire majuscule",
 	"backwards": "Înapoi",
 	"backwardsTooltip": "Căutaţi înapoi pentru text",
-	"replaceAllButton": "Înlocuire toate ",
+	"replaceAllButton": "Înlocuire toate",
 	"replaceAllButtonTooltip": "Înlocuiţi tot textul",
 	"findButton": "Găsire",
 	"findButtonTooltip": "Găsiţi textul",
-	"replaceButton": "Înlocuire ",
+	"replaceButton": "Înlocuire",
 	"replaceButtonTooltip": "Înlocuiţi textul",
 	"replaceDialogText": "Au fost înlocuite ${0} apariţii.",
 	"eofDialogText": "Ultima apariţie ${0}",
diff --git a/dojox/editor/plugins/nls/ro/LocalImage.js b/dojox/editor/plugins/nls/ro/LocalImage.js
new file mode 100644
index 0000000..a8dcb07
--- /dev/null
+++ b/dojox/editor/plugins/nls/ro/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Inserare imagine",
+	url: "Imagine",
+	browse: "Răsfoire...",
+	text: "Descriere",
+	set: "Inserare",
+	invalidMessage: "Tip de fişier imagine nevalid",
+	prePopuTextUrl: "Introduceţi un URL de imagine",
+	prePopuTextBrowse: "sau răsfoiţi la un fişier local."
+})
+
diff --git a/dojox/editor/plugins/nls/ro/Preview.js b/dojox/editor/plugins/nls/ro/Preview.js
index 95a6462..5d6629d 100644
--- a/dojox/editor/plugins/nls/ro/Preview.js
+++ b/dojox/editor/plugins/nls/ro/Preview.js
@@ -1,4 +1,4 @@
 ({
-	"preview": "Previzualizare "
+	"preview": "Previzualizare"
 })
 
diff --git a/dojox/editor/plugins/nls/ro/Smiley.js b/dojox/editor/plugins/nls/ro/Smiley.js
index 382910d..1ac00db 100644
--- a/dojox/editor/plugins/nls/ro/Smiley.js
+++ b/dojox/editor/plugins/nls/ro/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "face cu ochiul",
 	emoticonGrin: "rânjet",
 	emoticonCool: "calm",
-	emoticonAngry: "furios",  
-	emoticonHalf: "jumătate", 
+	emoticonAngry: "furios",
+	emoticonHalf: "jumătate",
 	emoticonEyebrow: "sprânceană",
 	emoticonFrown: "posac",
 	emoticonShy: "timid",
@@ -15,7 +15,7 @@
 	emoticonTongue: "limbă",
 	emoticonIdea: "idee",
 	emoticonYes: "da",
-	emoticonNo: "nu",	
+	emoticonNo: "nu",
 	emoticonAngel: "înger",
 	emoticonCrying: "plâns"
 })
diff --git a/dojox/editor/plugins/nls/ro/SpellCheck.js b/dojox/editor/plugins/nls/ro/SpellCheck.js
new file mode 100644
index 0000000..e35c0b1
--- /dev/null
+++ b/dojox/editor/plugins/nls/ro/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Verificare ortografică lot",
+	unfound: "Nu a fost găsit",
+	skip: "Salt",
+	skipAll: "Salt toate",
+	toDic: "Adăugare la dicţionar",
+	suggestions: "Sugestii",
+	replace: "Înlocuire",
+	replaceWith: "Înlocuire cu",
+	replaceAll: "Înlocuire toate",
+	cancel: "Anulare",
+	msg: "Nicio greşeală de verificare ortografică nu a fost găsită.",
+	iSkip: "Salt peste acesta",
+	iSkipAll: "Salt peste toate acestea",
+	iMsg: "Nicio sugestie de verificare ortografică"
+})
+
diff --git a/dojox/editor/plugins/nls/ro/TableDialog.js b/dojox/editor/plugins/nls/ro/TableDialog.js
index 2af7f18..b66cf79 100644
--- a/dojox/editor/plugins/nls/ro/TableDialog.js
+++ b/dojox/editor/plugins/nls/ro/TableDialog.js
@@ -1,15 +1,15 @@
 ({
-	insertTableTitle: "Inserare tabelă",
-	modifyTableTitle: "Modificare tabelă",
+	insertTableTitle: "Inserare tabel",
+	modifyTableTitle: "Modificare tabel",
 	rows: "Rânduri:",
 	columns: "Coloane:",
 	align: "Aliniere:",
-	cellPadding: "Completare celulă:",
+	cellPadding: "Padding celulă:",
 	cellSpacing: "Spaţiere celulă:",
 	tableWidth: "Lăţime tabelă:",
-	backgroundColor: "Culoare fundal:",
-	borderColor: "Culoare bordură:",
-	borderThickness: "Grosime bordură",
+	backgroundColor: "Culoare de fundal:",
+	borderColor: "Coloare de bordură:",
+	borderThickness: "Grosime de bordură:",
 	percent: "procent",
 	pixels: "pixeli",
 	"default": "implicit",
@@ -18,13 +18,15 @@
 	right: "dreapta",
 	buttonSet: "Setare", // translated elsewhere?
 	buttonInsert: "Inserare",
+	buttonCancel: "Anulare",
 
-	selectTableLabel: "Selectare tabelă ",
+	selectTableLabel: "Selectare tabelă",
 	insertTableRowBeforeLabel: "Adăugare rând înainte",
 	insertTableRowAfterLabel: "Adăugare rând după",
 	insertTableColumnBeforeLabel: "Adăugare coloană înainte",
 	insertTableColumnAfterLabel: "Adăugare coloană după",
-	deleteTableRowLabel: "Ştergere rând ",
+	deleteTableRowLabel: "Ştergere rând",
 	deleteTableColumnLabel: "Ştergere coloană"
 })
+	
 
diff --git a/dojox/editor/plugins/nls/ro/latinEntities.js b/dojox/editor/plugins/nls/ro/latinEntities.js
index a21a2b1..70496a4 100644
--- a/dojox/editor/plugins/nls/ro/latinEntities.js
+++ b/dojox/editor/plugins/nls/ro/latinEntities.js
@@ -180,7 +180,7 @@
 	forall:"pentru toate",
 	part:"diferenţiale parţiale",
 	exist:"Există",
-	empty:"set gol\nset zero\ndiametru",
+	empty:"set gol\nset null\ndiametru",
 	nabla:"nabla\ndiferenţa înapoi",
 	isin:"element al",
 	notin:"nu este un element al",
@@ -212,7 +212,7 @@
 	supe:"superset al sau egal cu",
 	oplus:"plus încercuit\nsumă directă",
 	otimes:"multiplicator încercuit\nprodus vectorial",
-	perp:"t întors\nortogonal la\nerpendicular",
+	perp:"up tack\northogonal to\nperpendicular",
 	sdot:"operator punct",
 	lceil:"plafon stânga\nAPL upstile",
 	rceil:"plafon dreapta",
@@ -243,7 +243,7 @@
 	mdash:"linie em",
 	lsquo:"ghilimele simple stânga",
 	rsquo:"ghilimele simple dreapta",
-	sbquo:"single low-9 semn de citare ",
+	sbquo:"single low-9 semn de citare",
 	ldquo:"ghilimele duble stânga",
 	rdquo:"ghilimele duble dreapta",
 	bdquo:"double low-9 semn de citare",
diff --git a/dojox/editor/plugins/nls/ru/AutoSave.js b/dojox/editor/plugins/nls/ru/AutoSave.js
new file mode 100644
index 0000000..8e4c786
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Сохранить",
+	"saveSettingLabelOn": "Задать интервал автосохранения...",
+	"saveSettingLabelOff": "Выключить автосохранение",
+	"saveSettingdialogTitle": "Автосохранение",
+	"saveSettingdialogDescription": "Укажите интервал автосохранения",
+	"saveSettingdialogParamName": "Интервал автосохранения",
+	"saveSettingdialogParamLabel": "мин",
+	"saveSettingdialogButtonOk": "Задать интервал",
+	"saveSettingdialogButtonCancel": "Отменить",
+	"saveMessageSuccess": "Сохранено ${0}",
+	"saveMessageFail": "Не удалось сохранить ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/ru/Blockquote.js b/dojox/editor/plugins/nls/ru/Blockquote.js
new file mode 100644
index 0000000..6218872
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Блок цитат"
+})
+
diff --git a/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js b/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
new file mode 100644
index 0000000..0ae0da8
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Свернуть панель редактирования",
+	"expand": "Развернуть панель редактирования"
+})
+
diff --git a/dojox/editor/plugins/nls/ru/FindReplace.js b/dojox/editor/plugins/nls/ru/FindReplace.js
index cd4ae13..0292156 100644
--- a/dojox/editor/plugins/nls/ru/FindReplace.js
+++ b/dojox/editor/plugins/nls/ru/FindReplace.js
@@ -1,12 +1,23 @@
 ({
 	"findLabel": "Найти:",
+	"findTooltip": "Введите текст для поиска",
 	"replaceLabel": "Заменить на:",
-	"findReplace": "Переключатель Поиск/Замена",
-	"matchCase": "С учетом регистра", 
+	"replaceTooltip": "Введите текст для замены",
+	"findReplace": "Найти и заменить",
+	"matchCase": "С учетом регистра",
+	"matchCaseTooltip": "С учетом регистра",
 	"backwards": "Назад",
-	"replaceAll": "Все вхождения", 
+	"backwardsTooltip": "Поиск текста в обратном направлении",
+	"replaceAll": "Все вхождения",
+	"replaceAllButton": "Заменить все",
+	"replaceAllButtonTooltip": "Заменить весь текст",
 	"findButton": "Найти",
+	"findButtonTooltip": "Найти текст",
 	"replaceButton": "Заменить",
-	"replaceDialogText": "Заменено ${0} вхождений."
+	"replaceButtonTooltip": "Заменить текст",
+	"replaceDialogText": "Заменено ${0} вхождений.",
+	"eofDialogText": "Последнее вхождение ${0}",
+	"eofDialogTextFind": "найдено",
+	"eofDialogTextReplace": "заменено"
 })
 
diff --git a/dojox/editor/plugins/nls/ru/InsertAnchor.js b/dojox/editor/plugins/nls/ru/InsertAnchor.js
new file mode 100644
index 0000000..6909d0a
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Вставить метку",
+	title: "Свойства метки",
+	anchor: "Имя:",
+	text: "Описание:",
+	set: "Задать",
+	cancel: "Отменить"
+})
+
diff --git a/dojox/editor/plugins/nls/ru/LocalImage.js b/dojox/editor/plugins/nls/ru/LocalImage.js
new file mode 100644
index 0000000..315df73
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Вставить изображение",
+	url: "Изображение",
+	browse: "Обзор...",
+	text: "Описание",
+	set: "Вставить",
+	invalidMessage: "Недопустимый тип файла изображения",
+	prePopuTextUrl: "Введите URL изображения",
+	prePopuTextBrowse: " или выберите локальный файл."
+})
+
diff --git a/dojox/editor/plugins/nls/ru/PasteFromWord.js b/dojox/editor/plugins/nls/ru/PasteFromWord.js
new file mode 100644
index 0000000..4d0d575
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Вставить из Word",
+	"paste": "Вставить",
+	"cancel": "Отменить",
+	"instructions": "Вставить содержимое из Word в текстовое поле ниже.  Когда выберите содержимое для вставки, нажмите кнопку Вставить.  Для отмены вставки текста нажмите кнопку Отмена."
+})
+
diff --git a/dojox/editor/plugins/nls/ru/Smiley.js b/dojox/editor/plugins/nls/ru/Smiley.js
index 463e805..70db6bf 100644
--- a/dojox/editor/plugins/nls/ru/Smiley.js
+++ b/dojox/editor/plugins/nls/ru/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "подмигивание",
 	emoticonGrin: "усмешка",
 	emoticonCool: "здорово",
-	emoticonAngry: "злость",  
-	emoticonHalf: "половина", 
+	emoticonAngry: "злость",
+	emoticonHalf: "половина",
 	emoticonEyebrow: "удивление",
 	emoticonFrown: "хмурый вид",
 	emoticonShy: "застенчивость",
@@ -15,7 +15,7 @@
 	emoticonTongue: "насмешка",
 	emoticonIdea: "есть идея",
 	emoticonYes: "да",
-	emoticonNo: "нет",	
+	emoticonNo: "нет",
 	emoticonAngel: "ангел",
 	emoticonCrying: "плачь"
 })
diff --git a/dojox/editor/plugins/nls/ru/SpellCheck.js b/dojox/editor/plugins/nls/ru/SpellCheck.js
new file mode 100644
index 0000000..2cd93c5
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Проверка орфографии",
+	unfound: "Не найдено",
+	skip: "Пропустить",
+	skipAll: "Пропустить все",
+	toDic: "Добавить в словарь",
+	suggestions: "Варианты",
+	replace: "Заменить",
+	replaceWith: "Заменить на",
+	replaceAll: "Заменить все",
+	cancel: "Отменить",
+	msg: "Ошибок не найдено",
+	iSkip: "Пропустить это",
+	iSkipAll: "Пропусть все схожие",
+	iMsg: "Нет вариантов написания"
+})
+
diff --git a/dojox/editor/plugins/nls/ru/TableDialog.js b/dojox/editor/plugins/nls/ru/TableDialog.js
index 5e79a01..638e051 100644
--- a/dojox/editor/plugins/nls/ru/TableDialog.js
+++ b/dojox/editor/plugins/nls/ru/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "по правому краю",
 	buttonSet: "Задать", // translated elsewhere?
 	buttonInsert: "Вставить",
+	buttonCancel: "Отмена",
 
 	selectTableLabel: "Выбрать таблицу",
 	insertTableRowBeforeLabel: "Добавить строку перед",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "Удалить строку",
 	deleteTableColumnLabel: "Удалить столбец"
 })
-
diff --git a/dojox/editor/plugins/nls/ru/TextColor.js b/dojox/editor/plugins/nls/ru/TextColor.js
new file mode 100644
index 0000000..51919e3
--- /dev/null
+++ b/dojox/editor/plugins/nls/ru/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Задать",
+	"cancelButtonText": "Отменить"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/AutoSave.js b/dojox/editor/plugins/nls/sk/AutoSave.js
new file mode 100644
index 0000000..47e14d5
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Uložiť",
+	"saveSettingLabelOn": "Nastaviť interval automatického ukladania...",
+	"saveSettingLabelOff": "Vypnúť automatické ukladanie",
+	"saveSettingdialogTitle": "Automatické ukladanie",
+	"saveSettingdialogDescription": "Zadajte interval automatického ukladania",
+	"saveSettingdialogParamName": "Interval automatického ukladania",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Nastaviť interval",
+	"saveSettingdialogButtonCancel": "Zrušiť",
+	"saveMessageSuccess": "Uložené o ${0}",
+	"saveMessageFail": "Zlyhalo ukladanie o ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/Blockquote.js b/dojox/editor/plugins/nls/sk/Blockquote.js
new file mode 100644
index 0000000..859084b
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockquote"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/Breadcrumb.js b/dojox/editor/plugins/nls/sk/Breadcrumb.js
new file mode 100644
index 0000000..6fae818
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "Akcie pre ${nodeName}",
+	"selectContents": "Vybrať obsah",
+	"selectElement": "Vybrať element",
+	"deleteElement": "Vymazať element",
+	"deleteContents": "Vymazať obsah",
+	"moveStart": "Presunúť kurzor na začiatok",
+	"moveEnd": "Presunúť kurzor na koniec"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js b/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
new file mode 100644
index 0000000..fd57120
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Zvinúť lištu nástrojov editora",
+	"expand": "Rozvinúť lištu nástrojov editora"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/FindReplace.js b/dojox/editor/plugins/nls/sk/FindReplace.js
new file mode 100644
index 0000000..804e9e4
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/FindReplace.js
@@ -0,0 +1,22 @@
+({
+	"findLabel": "Hľadať:",
+	"findTooltip": "Zadajte text na nájdenie",
+	"replaceLabel": "Nahradiť s:",
+	"replaceTooltip": "Zadajte text na nahradenie",
+	"findReplace": "Hľadať a nahradiť",
+	"matchCase": "Rozlišovať veľkosť písmen",
+	"matchCaseTooltip": "Rozlišovať veľkosť písmen",
+	"backwards": "Dozadu",
+	"backwardsTooltip": "Hľadať text dozadu",
+	"replaceAllButton": "Nahradiť všetko",
+	"replaceAllButtonTooltip": "Nahradiť všetok text",
+	"findButton": "Hľadať",
+	"findButtonTooltip": "Hľadať text",
+	"replaceButton": "Nahradiť",
+	"replaceButtonTooltip": "Nahradiť text",
+	"replaceDialogText": "Nahradilo sa ${0} výskytov.",
+	"eofDialogText": "Posledný výskyt ${0}",
+	"eofDialogTextFind": "nájdený",
+	"eofDialogTextReplace": "nahradený"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/InsertAnchor.js b/dojox/editor/plugins/nls/sk/InsertAnchor.js
new file mode 100644
index 0000000..c978c7c
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Vložiť kotvu",
+	title: "Vlastnosti kotvy",
+	anchor: "Názov:",
+	text: "Opis:",
+	set: "Nastaviť",
+	cancel: "Zrušiť"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/InsertEntity.js b/dojox/editor/plugins/nls/sk/InsertEntity.js
new file mode 100644
index 0000000..f325903
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Vložiť symbol"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/LocalImage.js b/dojox/editor/plugins/nls/sk/LocalImage.js
new file mode 100644
index 0000000..0895ced
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Vložiť obrázok",
+	url: "Obrázok",
+	browse: "Prehľadať...",
+	text: "Opis",
+	set: "Vložiť",
+	invalidMessage: "Neplatný typ súboru obrázka",
+	prePopuTextUrl: "Zadajte adresu URL",
+	prePopuTextBrowse: "alebo nájdite lokálny súbor."
+})
+
diff --git a/dojox/editor/plugins/nls/sk/PageBreak.js b/dojox/editor/plugins/nls/sk/PageBreak.js
new file mode 100644
index 0000000..ee4d65e
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Zlom strany"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/PasteFromWord.js b/dojox/editor/plugins/nls/sk/PasteFromWord.js
new file mode 100644
index 0000000..5090a9c
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Prilepiť z aplikácie Word",
+	"paste": "Prilepiť",
+	"cancel": "Zrušiť",
+	"instructions": "Prilepte obsah z aplikácie Word do textového okienka dole. Keď ste spokojný s obsahom na vloženie, stlačte tlačidlo prilepenia. Ak chcete zrušiť vkladanie textu, stlačte tlačidlo zrušenia."
+})
+
diff --git a/dojox/editor/plugins/nls/sk/Preview.js b/dojox/editor/plugins/nls/sk/Preview.js
new file mode 100644
index 0000000..835b4bd
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Náhľad"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/Save.js b/dojox/editor/plugins/nls/sk/Save.js
new file mode 100644
index 0000000..0f8a1f1
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Uložiť"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/ShowBlockNodes.js b/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
new file mode 100644
index 0000000..a458f00
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Zobraziť elementy blokov HTML"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/Smiley.js b/dojox/editor/plugins/nls/sk/Smiley.js
new file mode 100644
index 0000000..0c11431
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Vložiť emotikon",
+	emoticonSmile: "úsmev",
+	emoticonLaughing: "smiech",
+	emoticonWink: "žmurknutie",
+	emoticonGrin: "úškľabok",
+	emoticonCool: "super",
+	emoticonAngry: "nahnevaný",
+	emoticonHalf: "polovica",
+	emoticonEyebrow: "zdvihnuté obočie",
+	emoticonFrown: "zamračený",
+	emoticonShy: "hanblivý",
+	emoticonGoofy: "pojašený",
+	emoticonOops: "ups",
+	emoticonTongue: "jazyk",
+	emoticonIdea: "nápad",
+	emoticonYes: "áno",
+	emoticonNo: "nie",
+	emoticonAngel: "anjel",
+	emoticonCrying: "plač"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/SpellCheck.js b/dojox/editor/plugins/nls/sk/SpellCheck.js
new file mode 100644
index 0000000..04b0ad9
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Dávková kontrola pravopisu",
+	unfound: "Nenašlo sa",
+	skip: "Preskočiť",
+	skipAll: "Preskočiť všetko",
+	toDic: "Pridať do slovníka",
+	suggestions: "Návrhy",
+	replace: "Nahradiť",
+	replaceWith: "Nahradiť s",
+	replaceAll: "Nahradiť všetko",
+	cancel: "Zrušiť",
+	msg: "Nenašli sa žiadne chyby",
+	iSkip: "Preskočiť toto",
+	iSkipAll: "Preskočiť všetky podobné",
+	iMsg: "Žiadne návrhy na hláskovanie"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/TableDialog.js b/dojox/editor/plugins/nls/sk/TableDialog.js
index 4999d00..70d3f30 100644
--- a/dojox/editor/plugins/nls/sk/TableDialog.js
+++ b/dojox/editor/plugins/nls/sk/TableDialog.js
@@ -3,21 +3,22 @@
 	modifyTableTitle: "Upraviť tabuľku",
 	rows: "Riadky:",
 	columns: "Stĺpce:",
-	align: "Zarovnať:",
-	cellPadding: "Odsadenie obsahu buniek:",
-	cellSpacing: "Rozstupy buniek:",
+	align: "Zarovnanie:",
+	cellPadding: "Výplň buniek:",
+	cellSpacing: "Rozstup buniek:",
 	tableWidth: "Šírka tabuľky:",
 	backgroundColor: "Farba pozadia:",
-	borderColor: "Farba rámčeka:",
-	borderThickness: "Hrúbka rámčeka",
-	percent: "percentá",
-	pixels: "pixely",
-	"default": "štandardne",
+	borderColor: "Farba rámika:",
+	borderThickness: "Hrúbka rámika:",
+	percent: "percent",
+	pixels: "pixlov",
+	"default": "predvolené",
 	left: "vľavo",
-	center: "na stred",
+	center: "stred",
 	right: "vpravo",
 	buttonSet: "Nastaviť", // translated elsewhere?
 	buttonInsert: "Vložiť",
+	buttonCancel: "Zrušiť",
 
 	selectTableLabel: "Vybrať tabuľku",
 	insertTableRowBeforeLabel: "Pridať riadok pred",
@@ -27,4 +28,5 @@
 	deleteTableRowLabel: "Vymazať riadok",
 	deleteTableColumnLabel: "Vymazať stĺpec"
 })
+	
 
diff --git a/dojox/editor/plugins/nls/sk/TextColor.js b/dojox/editor/plugins/nls/sk/TextColor.js
new file mode 100644
index 0000000..58b7cf7
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Nastaviť",
+	"cancelButtonText": "Zrušiť"
+})
+
diff --git a/dojox/editor/plugins/nls/sk/latinEntities.js b/dojox/editor/plugins/nls/sk/latinEntities.js
new file mode 100644
index 0000000..f4b2187
--- /dev/null
+++ b/dojox/editor/plugins/nls/sk/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"invertovaný výkričník",
+	cent:"znak centu",
+	pound:"znak libry",
+	curren:"znak meny",
+	yen:"znak yen\nznak yuan",
+	brvbar:"prerušovaná čiara\nprerušovaná zvislá čiara",
+	sect:"znak paragraf",
+	uml:"znak prehláskovania",
+	copy:"znak copyright",
+	ordf:"ordinálny indikátor, ženský",
+	laquo:"znak dvojitej šípky vľavo\nukazovateľ vľavo",
+	not:"znak nie",
+	shy:"voľná pomlčka",
+	reg:"znak registrácie\nznačka registrovanej ochrannej známky",
+	macr:"vodorovná čiarka",
+	deg:"znak stupeň",
+	plusmn:"znak plus-mínus\nznak plus alebo mínus",
+	sup2:"horný index dva\nna druhú",
+	sup3:"horný index tri\nna tretiu",
+	acute:"dĺžeň",
+	micro:"znak mikro",
+	para:"znak odseku",
+	middot:"stredová bodka\ngregoriánska čiarka\ngrécka stredová bodka",
+	cedil:"cedilla\nspodný háčik",
+	sup1:"horný index jedna",
+	ordm:"ordinálny indikátor, mužský",
+	raquo:"znak dvojitej šípky vpravo\nukazovateľ vpravo",
+	frac14:"jedna štvrtina",
+	frac12:"jedna polovica",
+	frac34:"tri štvrtiny",
+	iquest:"invertovaný otáznik\notočený otáznik",
+	Agrave:"veľké latinské písmeno A s opačným dĺžňom",
+	Aacute:"veľké latinské písmeno A s dĺžňom",
+	Acirc:"veľké latinské písmeno A so strieškou",
+	Atilde:"veľké latinské písmeno A s tildou",
+	Auml:"veľké latinské písmeno A prehlasované",
+	Aring:"veľké latinské písmeno A s krúžkom",
+	AElig:"veľké latinské písmeno AE",
+	Ccedil:"veľké latinské písmeno C so spodným háčikom",
+	Egrave:"veľké latinské písmeno E s opačným dĺžňom",
+	Eacute:"veľké latinské písmeno E s dĺžňom",
+	Ecirc:"veľké latinské písmeno E so strieškou",
+	Euml:"veľké latinské písmeno E prehlasované",
+	Igrave:"veľké latinské písmeno I s opačným dĺžňom",
+	Iacute:"veľké latinské písmeno I s dĺžňom",
+	Icirc:"veľké latinské písmeno I so strieškou",
+	Iuml:"veľké latinské písmeno I prehlasované",
+	ETH:"veľké latinské písmeno ETH",
+	Ntilde:"veľké latinské písmeno N s tildou",
+	Ograve:"veľké latinské písmeno O s opačným dĺžňom",
+	Oacute:"veľké latinské písmeno O s dĺžňom",
+	Ocirc:"veľké latinské písmeno O so strieškou",
+	Otilde:"veľké latinské písmeno O s tildou",
+	Ouml:"veľké latinské písmeno O prehlasované",
+	times:"znak násobenia",
+	Oslash:"veľké latinské písmeno O s prečiarknutím",
+	Ugrave:"veľké latinské písmeno U s opačným dĺžňom",
+	Uacute:"veľké latinské písmeno U s dĺžňom",
+	Ucirc:"veľké latinské písmeno U so strieškou",
+	Uuml:"veľké latinské písmeno U prehlasované",
+	Yacute:"veľké latinské písmeno Y s dĺžňom",
+	THORN:"veľké latinské písmeno THORN",
+	szlig:"malé latinské písmeno ostré s",
+	agrave:"malé latinské písmeno a s opačným dĺžňom",
+	aacute:"malé latinské písmeno a s dĺžňom",
+	acirc:"malé latinské písmeno a so strieškou",
+	atilde:"malé latinské písmeno a s tildou",
+	auml:"malé latinské písmeno a prehlasované",
+	aring:"malé latinské písmeno a s krúžkom",
+	aelig:"malé latinské písmeno ae",
+	ccedil:"malé latinské písmeno c so spodným háčikom",
+	egrave:"malé latinské písmeno e s opačným dĺžňom",
+	eacute:"malé latinské písmeno e s dĺžňom",
+	ecirc:"malé latinské písmeno e so strieškou",
+	euml:"malé latinské písmeno e prehlasované",
+	igrave:"malé latinské písmeno i s opačným dĺžňom",
+	iacute:"malé latinské písmeno i s dĺžňom",
+	icirc:"malé latinské písmeno i so strieškou",
+	iuml:"malé latinské písmeno i prehlasované",
+	eth:"malé latinské písmeno eth",
+	ntilde:"malé latinské písmeno n s tildou",
+	ograve:"malé latinské písmeno o s opačným dĺžňom",
+	oacute:"malé latinské písmeno o s dĺžňom",
+	ocirc:"malé latinské písmeno o so strieškou",
+	otilde:"malé latinské písmeno o s tildou",
+	ouml:"malé latinské písmeno o prehlasované",
+	divide:"znak delenia",
+	oslash:"malé latinské písmeno o s prečiarknutím",
+	ugrave:"malé latinské písmeno u s opačným dĺžňom",
+	uacute:"malé latinské písmeno u s dĺžňom",
+	ucirc:"malé latinské písmeno u so strieškou",
+	uuml:"malé latinské písmeno u prehlasované",
+	yacute:"malé latinské písmeno y s dĺžňom",
+	thorn:"malé latinské písmeno thorn",
+	yuml:"malé latinské písmeno y prehlasované",
+
+// Greek Characters and Symbols
+	fnof:"malé latinské písmeno f s háčikom",
+	Alpha:"veľké grécke písmeno alfa",
+	Beta:"veľké grécke písmeno beta",
+	Gamma:"veľké grécke písmeno gama",
+	Delta:"veľké grécke písmeno delta",
+	Epsilon:"veľké grécke písmeno epsilon",
+	Zeta:"veľké grécke písmeno zéta",
+	Eta:"veľké grécke písmeno éta",
+	Theta:"veľké grécke písmeno téta",
+	Iota:"veľké grécke písmeno jota",
+	Kappa:"veľké grécke písmeno kapa",
+	Lambda:"veľké grécke písmeno lambda",
+	Mu:"veľké grécke písmeno mí",
+	Nu:"veľké grécke písmeno ní",
+	Xi:"veľké grécke písmeno ksí",
+	Omicron:"veľké grécke písmeno omikron",
+	Pi:"veľké grécke písmeno pí",
+	Rho:"veľké grécke písmeno ró",
+	Sigma:"veľké grécke písmeno sigma",
+	Tau:"veľké grécke písmeno tau",
+	Upsilon:"veľké grécke písmeno ypsilon",
+	Phi:"veľké grécke písmeno fí",
+	Chi:"veľké grécke písmeno chí",
+	Psi:"veľké grécke písmeno psí",
+	Omega:"veľké grécke písmeno omega",
+	alpha:"malé grécke písmeno alfa",
+	beta:"malé grécke písmeno beta",
+	gamma:"malé grécke písmeno gama",
+	delta:"malé grécke písmeno delta",
+	epsilon:"malé grécke písmeno epsilon",
+	zeta:"malé grécke písmeno zéta",
+	eta:"malé grécke písmeno éta",
+	theta:"malé grécke písmeno téta",
+	iota:"malé grécke písmeno jota",
+	kappa:"malé grécke písmeno kapa",
+	lambda:"malé grécke písmeno lambda",
+	mu:"malé grécke písmeno mí",
+	nu:"malé grécke písmeno ní",
+	xi:"malé grécke písmeno ksí",
+	omicron:"malé grécke písmeno omikron",
+	pi:"malé grécke písmeno pí",
+	rho:"malé grécke písmeno ró",
+	sigmaf:"malé grécke písmeno sigma (koncové)",
+	sigma:"malé grécke písmeno sigma",
+	tau:"malé grécke písmeno tau",
+	upsilon:"malé grécke písmeno ypsilon",
+	phi:"malé grécke písmeno fí",
+	chi:"malé grécke písmeno chí",
+	psi:"malé grécke písmeno psí",
+	omega:"malé grécke písmeno omega",
+	thetasym:"malé grécke písmeno téta",
+	upsih:"grécky znak ypsilon s háčikom",
+	piv:"grécky symbol pí",
+	bull:"odrážka\nmalý čierny krúžok",
+	hellip:"tri body vodorovne",
+	prime:"minúty\nstopa",
+	Prime:"sekundy\npalce",
+	oline:"čiara nad riadkom",
+	frasl:"lomka",
+	weierp:"veľké písané písmeno P\nmocninný rad",
+	image:"gotické veľké písmeno I\nimaginárna časť",
+	real:"gotické veľké písmeno R\nreálna časť",
+	trade:"znak ochrannej známky",
+	alefsym:"symbol alef",
+	larr:"šípka doľava",
+	uarr:"šípka nahor",
+	rarr:"šípka doprava",
+	darr:"šípka nadol",
+	harr:"šípka vľavo-vpravo",
+	crarr:"lomená šípka nadol doľava\nnávrat vozíka",
+	lArr:"dvojitá šípka doľava",
+	uArr:"dvojitá šípka nahor",
+	rArr:"dvojitá šípka doprava",
+	dArr:"dvojitá šípka nadol",
+	hArr:"dvojitá šípka vľavo-vpravo",
+	forall:"pre všetky",
+	part:"čiastočný rozdiel",
+	exist:"existuje",
+	empty:"prázdna množina\npriemer",
+	nabla:"nabla\nopačný rozdiel",
+	isin:"prvok z",
+	notin:"nie je prvok z",
+	ni:"obsahuje ako člen",
+	prod:"n-árny súčin\nznak súčinu",
+	sum:"n-árny súčet",
+	minus:"znak mínus",
+	lowast:"operátor hviezdička",
+	radic:"druhá odmocnina",
+	prop:"proporcionálne k",
+	infin:"nekonečno",
+	ang:"uhol",
+	and:"logické a",
+	or:"logické alebo",
+	cap:"prienik",
+	cup:"zjednotenie","int":"integrál",
+	there4:"preto",
+	sim:"operátor tilda\nmení sa\npodobné",
+	cong:"približne rovné",
+	asymp:"takmer rovné\nasymptotický k",
+	ne:"nerovný",
+	equiv:"identický",
+	le:"menší ako alebo rovný",
+	ge:"väčší ako alebo rovný",
+	sub:"podmnožina",
+	sup:"nadmnožina",
+	nsub:"nie podmnožina",
+	sube:"podmnožina alebo rovné",
+	supe:"nadmnožina alebo rovné",
+	oplus:"plus v krúžku\npriamy súčet",
+	otimes:"krát v krúžku\nvektorový súčin",
+	perp:"otočený klinček\nortogonálny\nkolmý",
+	sdot:"operátor bodka",
+	lceil:"ľavý strop",
+	rceil:"pravý strop",
+	lfloor:"ľavá podlaha",
+	rfloor:"pravá podlaha",
+	lang:"hranatá zátvorka smerujúca doľava",
+	rang:"hranatá zátvorka smerujúca doprava",
+	loz:"kosoštvorec",
+	spades:"čierny znak pikovej karty",
+	clubs:"čierny znak krížovej karty",
+	hearts:"čierny znak guľovej karty",
+	diams:"čierny znak károvej karty",
+	OElig:"veľká latinská ligatúra OE",
+	oelig:"malá latinská ligatúra oe",
+	Scaron:"veľké latinské písmeno S s mäkčeňom",
+	scaron:"malé latinské písmeno s s mäkčeňom",
+	Yuml:"veľké latinské písmeno Y prehlasované",
+	circ:"znak striešky",
+	tilde:"malá tilda",
+	ensp:"krátka medzera",
+	emsp:"dlhá medzera",
+	thinsp:"tenká medzera",
+	zwnj:"nespojovač nulovej dĺžky",
+	zwj:"spojovač nulovej dĺžky",
+	lrm:"značka zľava-doprava",
+	rlm:"značka sprava-doľava",
+	ndash:"pomlčka",
+	mdash:"dlhá pomlčka",
+	lsquo:"jednoduchá ľavá úvodzovka",
+	rsquo:"jednoduchá pravá úvodzovka",
+	sbquo:"jednoduchá dolná ľavá úvodzovka",
+	ldquo:"dvojitá ľavá úvodzovka",
+	rdquo:"dvojitá pravá úvodzovka",
+	bdquo:"dvojitá dolná ľavá úvodzovka",
+	dagger:"krížik",
+	Dagger:"dvojitý krížik",
+	permil:"znak promile",
+	lsaquo:"jednoduchý ľavý ukazovateľ",
+	rsaquo:"jednoduchý pravý ukazovateľ",
+	euro:"znak euro"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/AutoSave.js b/dojox/editor/plugins/nls/sl/AutoSave.js
new file mode 100644
index 0000000..d14ab32
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Shrani",
+	"saveSettingLabelOn": "Nastavi interval za samodejno shranjevanje ... ",
+	"saveSettingLabelOff": "Izključi samodejno shranjevanje ",
+	"saveSettingdialogTitle": "Samodejno shranjevanje ",
+	"saveSettingdialogDescription": "Podaj interval za samodejno shranjevanje ",
+	"saveSettingdialogParamName": "Interval za samodejno shranjevanje ",
+	"saveSettingdialogParamLabel": "min",
+	"saveSettingdialogButtonOk": "Nastavi interval",
+	"saveSettingdialogButtonCancel": "Prekliči",
+	"saveMessageSuccess": "Shranjeno ob ${0}",
+	"saveMessageFail": "Shranjevanje ob ${0} ni uspelo "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/Blockquote.js b/dojox/editor/plugins/nls/sl/Blockquote.js
new file mode 100644
index 0000000..d572a2e
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blokovno besedilo"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/Breadcrumb.js b/dojox/editor/plugins/nls/sl/Breadcrumb.js
new file mode 100644
index 0000000..8f6fa98
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "Dejanja ${nodeName} ",
+	"selectContents": "Izberi vsebine ",
+	"selectElement": "Izberi element ",
+	"deleteElement": "Izbriši element ",
+	"deleteContents": "Izbriši vsebine ",
+	"moveStart": "Pomakni kazalko na začetek ",
+	"moveEnd": "Pomakni kazalko na konec "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js b/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
new file mode 100644
index 0000000..026cd07
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Strni orodno vrstico urejevalnika ",
+	"expand": "Razširi orodno vrstico urejevalnika "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/FindReplace.js b/dojox/editor/plugins/nls/sl/FindReplace.js
new file mode 100644
index 0000000..85f6614
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Najdi:",
+	"findTooltip": "Vnesite besedilo za iskanje",
+	"replaceLabel": "Zamenjaj z: ",
+	"replaceTooltip": "Vnesite besedilo za zamenjavo ",
+	"findReplace": "Najdi in zamenjaj",
+	"matchCase": "Razlikuj velike in male črke",
+	"matchCaseTooltip": "Razlikuj velike in male črke",
+	"backwards": "Nazaj",
+	"backwardsTooltip": "Vzvratno iskanje besedila ",
+	"replaceAll": "Vse pojavitve ",
+	"replaceAllButton": "Zamenjaj vse",
+	"replaceAllButtonTooltip": "Zamenjaj celotno besedilo ",
+	"findButton": "Najdi",
+	"findButtonTooltip": "Najdi besedilo ",
+	"replaceButton": "Zamenjaj ",
+	"replaceButtonTooltip": "Zamenjaj besedilo ",
+	"replaceDialogText": "Zamenjanih ${0} pojavitev. ",
+	"eofDialogText": "Zadnja pojavitev ${0}",
+	"eofDialogTextFind": "najdeno ",
+	"eofDialogTextReplace": "zamenjano "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/InsertAnchor.js b/dojox/editor/plugins/nls/sl/InsertAnchor.js
new file mode 100644
index 0000000..dae88e9
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Vstavi sidro",
+	title: "Lastnosti sidra",
+	anchor: "Ime:",
+	text: "Opis:",
+	set: "Nastavi",
+	cancel: "Prekliči"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/InsertEntity.js b/dojox/editor/plugins/nls/sl/InsertEntity.js
new file mode 100644
index 0000000..21d3473
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Vstavi simbol "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/LocalImage.js b/dojox/editor/plugins/nls/sl/LocalImage.js
new file mode 100644
index 0000000..8d2e6e2
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Vstavi sliko",
+	url: "Slika ",
+	browse: "Prebrskaj ... ",
+	text: "Opis ",
+	set: "Vstavi ",
+	invalidMessage: "Neveljavna vrsta slikovne datoteke ",
+	prePopuTextUrl: "Vnesite URL slike",
+	prePopuTextBrowse: " ali prebrskajte in izberite lokalno datoteko. "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/PageBreak.js b/dojox/editor/plugins/nls/sl/PageBreak.js
new file mode 100644
index 0000000..8747566
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Prelom strani"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/PasteFromWord.js b/dojox/editor/plugins/nls/sl/PasteFromWord.js
new file mode 100644
index 0000000..3eb0906
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Prilepi iz programa Word",
+	"paste": "Prilepi",
+	"cancel": "Prekliči",
+	"instructions": "Vsebino iz programa Word prilepite v spodnje besedilno polje.  Ko ste zadovoljni z vstavljeno vsebino, pritisnite gumb Vstavi. Če želite prenehati z vstavljanjem vsebine, pritisnite gumb Prekliči. "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/Preview.js b/dojox/editor/plugins/nls/sl/Preview.js
new file mode 100644
index 0000000..a6aae73
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Predogled "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/Save.js b/dojox/editor/plugins/nls/sl/Save.js
new file mode 100644
index 0000000..dfc67e8
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Shrani"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/ShowBlockNodes.js b/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
new file mode 100644
index 0000000..bcd98ebb
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Pokaži elemente blokade HTML-ja "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/Smiley.js b/dojox/editor/plugins/nls/sl/Smiley.js
new file mode 100644
index 0000000..5e9183e
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Vstavi čustveni simbol",
+	emoticonSmile: "smeško",
+	emoticonLaughing: "smeško z odprtimi usti",
+	emoticonWink: "smeško pomežikne",
+	emoticonGrin: "smeško se nasmehne do ušes",
+	emoticonCool: "smeško je frajer",
+	emoticonAngry: "smeško je jezen",
+	emoticonHalf: "smeško se mršči",
+	emoticonEyebrow: "smeško dviga obrv",
+	emoticonFrown: "smeško ni zadovoljen",
+	emoticonShy: "smeško je v zadregi",
+	emoticonGoofy: "smeško se pači",
+	emoticonOops: "smeško ga je polomil",
+	emoticonTongue: "smeško kaže jezik",
+	emoticonIdea: "ideja",
+	emoticonYes: "smeško prikimava",
+	emoticonNo: "smeško odkimava",
+	emoticonAngel: "smeško je angelček",
+	emoticonCrying: "smeško joka"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/SpellCheck.js b/dojox/editor/plugins/nls/sl/SpellCheck.js
new file mode 100644
index 0000000..c434d14
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Paketno preverjanje črkovanja ",
+	unfound: "Ni najdeno ",
+	skip: "Preskoči",
+	skipAll: "Preskoči vse",
+	toDic: "Dodaj v slovar ",
+	suggestions: "Predlogi ",
+	replace: "Zamenjaj ",
+	replaceWith: "Zamenjaj z",
+	replaceAll: "Zamenjaj vse",
+	cancel: "Prekliči",
+	msg: "Najdenih ni bilo nobenih napačnih črkovanj ",
+	iSkip: "Preskoči to ",
+	iSkipAll: "Preskoči vse vnose, kot je ta ",
+	iMsg: "Ni predlogov za črkovanje "
+})
+
diff --git a/dojox/editor/plugins/nls/sl/TableDialog.js b/dojox/editor/plugins/nls/sl/TableDialog.js
index d8c8e1f..502a298 100644
--- a/dojox/editor/plugins/nls/sl/TableDialog.js
+++ b/dojox/editor/plugins/nls/sl/TableDialog.js
@@ -4,7 +4,7 @@
 	rows: "Vrstice:",
 	columns: "Stolpci:",
 	align: "Poravnaj:",
-	cellPadding: "Odmik celic:",
+	cellPadding: "Polnjenje celic:",
 	cellSpacing: "Razmik med celicami:",
 	tableWidth: "Širina tabele:",
 	backgroundColor: "Barva ozadja:",
@@ -18,6 +18,7 @@
 	right: "desno",
 	buttonSet: "Nastavi", // translated elsewhere?
 	buttonInsert: "Vstavi",
+	buttonCancel: "Prekliči",
 
 	selectTableLabel: "Izberi tabelo",
 	insertTableRowBeforeLabel: "Dodaj vrstico pred",
@@ -27,4 +28,5 @@
 	deleteTableRowLabel: "Izbriši vrstico",
 	deleteTableColumnLabel: "Izbriši stolpec"
 })
+	
 
diff --git a/dojox/editor/plugins/nls/sl/TextColor.js b/dojox/editor/plugins/nls/sl/TextColor.js
new file mode 100644
index 0000000..c3cd623
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Nastavi",
+	"cancelButtonText": "Prekliči"
+})
+
diff --git a/dojox/editor/plugins/nls/sl/latinEntities.js b/dojox/editor/plugins/nls/sl/latinEntities.js
new file mode 100644
index 0000000..764c6d5
--- /dev/null
+++ b/dojox/editor/plugins/nls/sl/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"obrnjen klicaj ",
+	cent:"znak za cent ",
+	pound:"znak za funt ",
+	curren:"znak za valuto ",
+	yen:"znak za jen\njuan ",
+	brvbar:"prekinjena črta\nprekinjena navpična črta ",
+	sect:"znak za odsek ",
+	uml:"diareza\ndiareza z razmikom ",
+	copy:"znak za avtorske pravice ",
+	ordf:"ženski ordinalni indikator ",
+	laquo:"dvojni narekovaj, ki kaže v levo smer ",
+	not:"znak za ne ",
+	shy:"pogojni deljaj ",
+	reg:"znak za registrirano\nznak za registrirano blagovno znamko ",
+	macr:"ravni preglas ",
+	deg:"znak za stopinje ",
+	plusmn:"znak plus-minus\nznak plus ali minus ",
+	sup2:"nadpisana dve\nnadpisana števka dve\nna kvadrat ",
+	sup3:"nadpisana tri\nnadpisana števka tri\nna kub ",
+	acute:"ostrivec ",
+	micro:"znak za mikro",
+	para:"znak za paragraf",
+	middot:"pika na sredini\nGeorgian comma\nGrška pika na sredini ",
+	cedil:"cedila ",
+	sup1:"nadpisana ena\nnadpisana števka ena ",
+	ordm:"moški ordinalni indikator ",
+	raquo:"dvojni narekovaj, ki kaže v desno smer ",
+	frac14:"pravi ulomek ena četrtina ",
+	frac12:"pravi ulomek ena polovica ",
+	frac34:"pravi ulomek tri četrtine ",
+	iquest:"obrnjen vprašaj ",
+	Agrave:"Latinska velika črka A s krativcem ",
+	Aacute:"Latinska velika črka A z ostrivcem ",
+	Acirc:"Latinska velika črka A s cirkumfleksom ",
+	Atilde:"Latinska velika črka A s tildo ",
+	Auml:"Latinska velika črka A z diarezo ",
+	Aring:"Latinska velika črka A s krogcem na vrhu ",
+	AElig:"Latinska velika črka AE ",
+	Ccedil:"Latinska velika črka C s cedilo ",
+	Egrave:"Latinska velika črka E s krativcem ",
+	Eacute:"Latinska velika črka E z ostrivcem ",
+	Ecirc:"Latinska velika črka E s cirkumfleksom ",
+	Euml:"Latinska velika črka E z diarezo ",
+	Igrave:"Latinska velika črka I s krativcem ",
+	Iacute:"Latinska velika črka I z ostrivcem ",
+	Icirc:"Latinska velika črka I s cirkumfleksom ",
+	Iuml:"Latinska velika črka I z diarezo ",
+	ETH:"Latinska velika črka ETH ",
+	Ntilde:"Latinska velika črka N s tildo ",
+	Ograve:"Latinska velika črka O s krativcem ",
+	Oacute:"Latinska velika črka O z ostrivcem ",
+	Ocirc:"Latinska velika črka O s cirkumfleksom ",
+	Otilde:"Latinska velika črka O s tildo ",
+	Ouml:"Latinska velika črka O z diarezo ",
+	times:"znak za množenje ",
+	Oslash:"Poševno prečrtana latinska velika črka O ",
+	Ugrave:"Latinska velika črka U s krativcem ",
+	Uacute:"Latinska velika črka U z ostrivcem ",
+	Ucirc:"Latinska velika črka U s cirkumfleksom ",
+	Uuml:"Latinska velika črka U z diarezo ",
+	Yacute:"Latinska velika črka Y z ostrivcem ",
+	THORN:"Latinska velika črka THORN ",
+	szlig:"Latinska majhna črka ostri s ",
+	agrave:"Latinska majhna črka a s krativcem ",
+	aacute:"Latinska majhna črka a z ostrivcem ",
+	acirc:"Latinska majhna črka a s cirkumfleksom ",
+	atilde:"Latinska majhna črka a s tildo ",
+	auml:"Latinska majhna črka a z diarezo ",
+	aring:"Latinska majhna črka a s krogcem na vrhu ",
+	aelig:"Latinska majhna črka ae ",
+	ccedil:"Latinska majhna črka c s cedilo ",
+	egrave:"Latinska majhna črka e s krativcem ",
+	eacute:"Latinska majhna črka e z ostrivcem ",
+	ecirc:"Latinska majhna črka e s cirkumfleksom ",
+	euml:"Latinska majhna črka e z diarezo ",
+	igrave:"Latinska majhna črka i s krativcem ",
+	iacute:"Latinska majhna črka i z ostrivcem ",
+	icirc:"Latinska majhna črka i s cirkumfleksom ",
+	iuml:"Latinska majhna črka i z diarezo ",
+	eth:"Latinska majhna črka eth ",
+	ntilde:"Latinska majhna črka n s tildo ",
+	ograve:"Latinska majhna črka o s krativcem ",
+	oacute:"Latinska majhna črka o z ostrivcem ",
+	ocirc:"Latinska majhna črka o s cirkumfleksom ",
+	otilde:"Latinska majhna črka o s tildo ",
+	ouml:"Latinska majhna črka o z diarezo ",
+	divide:"znak za deljenje ",
+	oslash:"Poševno prečrtana latinska majhna črka o ",
+	ugrave:"Latinska majhna črka u s krativcem ",
+	uacute:"Latinska majhna črka u z ostrivcem ",
+	ucirc:"Latinska majhna črka u s cirkumfleksom ",
+	uuml:"Latinska majhna črka u z diarezo ",
+	yacute:"Latinska majhna črka y z ostrivcem ",
+	thorn:"Latinska majhna črka thorn ",
+	yuml:"Latinska majhna črka y z diarezo ",
+
+// Greek Characters and Symbols
+	fnof:"Zavita latinska majhna črka f\nfunkcija ",
+	Alpha:"Grška velika črka alfa ",
+	Beta:"Grška velika črka beta ",
+	Gamma:"Grška velika črka gama ",
+	Delta:"Grška velika črka delta ",
+	Epsilon:"Grška velika črka epsilon ",
+	Zeta:"Grška velika črka zeta ",
+	Eta:"Grška velika črka eta ",
+	Theta:"Grška velika črka theta ",
+	Iota:"Grška velika črka jota ",
+	Kappa:"Grška velika črka kapa ",
+	Lambda:"Grška velika črka lambda ",
+	Mu:"Grška velika črka mu ",
+	Nu:"Grška velika črka nu ",
+	Xi:"Grška velika črka ksi ",
+	Omicron:"Grška velika črka omikron ",
+	Pi:"Grška velika črka pi ",
+	Rho:"Grška velika črka ro ",
+	Sigma:"Grška velika črka sigma ",
+	Tau:"Grška velika črka tau ",
+	Upsilon:"Grška velika črka ipsilon ",
+	Phi:"Grška velika črka fi ",
+	Chi:"Grška velika črka hi ",
+	Psi:"Grška velika črka psi ",
+	Omega:"Grška velika črka omega ",
+	alpha:"Grška majhna črka alfa ",
+	beta:"Grška majhna črka beta ",
+	gamma:"Grška majhna črka gama ",
+	delta:"Grška majhna črka delta ",
+	epsilon:"Grška majhna črka epsilon ",
+	zeta:"Grška majhna črka zeta ",
+	eta:"Grška majhna črka eta ",
+	theta:"Grška majhna črka theta ",
+	iota:"Grška majhna črka iota ",
+	kappa:"Grška majhna črka kapa ",
+	lambda:"Grška majhna črka lambda ",
+	mu:"Grška majhna črka mu ",
+	nu:"Grška majhna črka nu ",
+	xi:"Grška majhna črka ksi ",
+	omicron:"Grška majhna črka omikron ",
+	pi:"Grška majhna črka pi ",
+	rho:"Grška majhna črka ro ",
+	sigmaf:"Grška majhna črka končna sigma ",
+	sigma:"Grška majhna črka sigma ",
+	tau:"Grška majhna črka tau ",
+	upsilon:"Grška majhna črka ipsilon ",
+	phi:"Grška majhna črka fi ",
+	chi:"Grška majhna črka hi ",
+	psi:"Grška majhna črka psi ",
+	omega:"Grška majhna črka omega ",
+	thetasym:"Simbol majhne grške črke theta ",
+	upsih:"Grški zaviti simbol ipsilon ",
+	piv:"Grški simbol pi ",
+	bull:"oznaka\nmajhen črn krog ",
+	hellip:"tripičje ",
+	prime:"apostrof\nminute\nčevlji ",
+	Prime:"dvojni apostrof\nsekunde\npalci",
+	oline:"nadčrtaj ",
+	frasl:"poševnica ulomka ",
+	weierp:"potenčna množica\nWierstrassov p ",
+	image:"Gotska velika črka I\nimaginarni del ",
+	real:"Gotska velika črka R\nrealni del ",
+	trade:"znak za blagovno znamko ",
+	alefsym:"simbol alef\nprvo transfinitno kardinalno število ",
+	larr:"puščica levo ",
+	uarr:"puščica navzgor ",
+	rarr:"puščica desno ",
+	darr:"puščica navzdol ",
+	harr:"puščica levo navzgor ",
+	crarr:"puščica navzdol s kotom na levi strani\nzačetek vrstice ",
+	lArr:"dvojna puščica levo ",
+	uArr:"dvojna puščica navzgor ",
+	rArr:"dvojna puščica desno ",
+	dArr:"dvojna puščica navzdol ",
+	hArr:"dvojna puščica levo-desno ",
+	forall:"za vse ",
+	part:"delni diferencial ",
+	exist:"obstaja ",
+	empty:"prazna množica ",
+	nabla:"nabla ",
+	isin:"je element ",
+	notin:"ni element ",
+	ni:"vsebuje kot člana ",
+	prod:"n-kratni produkt ",
+	sum:"n-kratna vsota ",
+	minus:"znak za minus ",
+	lowast:"operator zvezdice ",
+	radic:"kvadratni koren ",
+	prop:"proporcialno z ",
+	infin:"neskončnost ",
+	ang:"kot ",
+	and:"logični in ",
+	or:"logični ali ",
+	cap:"presek ",
+	cup:"unija ","int":"integral ",
+	there4:"zato ",
+	sim:"operator tilda\nje podobno\nvarira z ",
+	cong:"je približno enako kot ",
+	asymp:"je skoraj enako kot\nasimptotsko glede na ",
+	ne:"ni enako ",
+	equiv:"je identično ",
+	le:"je manjše ali enako kot ",
+	ge:"je večje ali enako kot ",
+	sub:"je podmnožica ",
+	sup:"je nadmnožica ",
+	nsub:"ni podmnožnica ",
+	sube:"podmnožica ali enako ",
+	supe:"nadmnožica ali enako ",
+	oplus:"obkrožen plus\nneposredna svota ",
+	otimes:"obrkrožen krat\nvektorski produkt ",
+	perp:"žebljiček, obrnjen navzgor\npravokoten glede na ",
+	sdot:"operator pika ",
+	lceil:"levi zgornji kot ",
+	rceil:"desni zgornji kot ",
+	lfloor:"levi spodnji kot ",
+	rfloor:"desni spodnji kot ",
+	lang:"lomljeni oklepaj, ki kaže v levo ",
+	rang:"lomljeni oklepaj, ki kaže v desno ",
+	loz:"romb ",
+	spades:"črni pik ",
+	clubs:"črni križ\ndetelja ",
+	hearts:"črno srce\nvalentinovo ",
+	diams:"črni karo ",
+	OElig:"Latinska velika ligatura OE ",
+	oelig:"Latinska majhna ligatura oe ",
+	Scaron:"Latinska velika črka S s strešico ",
+	scaron:"Latinska majhna črka s s strešico ",
+	Yuml:"Latinska velika črka Y z diarezo ",
+	circ:"znak za cirkumfleks ",
+	tilde:"mala tilda ",
+	ensp:"presledek ",
+	emsp:"dolgi presledek ",
+	thinsp:"kratki presledek ",
+	zwnj:"razdruževalnik z nično širino ",
+	zwj:"združevalnik z nično širino ",
+	lrm:"oznaka od leve proti desni ",
+	rlm:"oznaka od desne proti levi ",
+	ndash:"pomišljaj",
+	mdash:"dolgi pomišljaj ",
+	lsquo:"levi opuščaj ",
+	rsquo:"desni opuščaj ",
+	sbquo:"enojni spodnji narekovaj ",
+	ldquo:"levi dvojni narekovaj ",
+	rdquo:"desni dvojni narekovaj ",
+	bdquo:"dvojni spodnji narekovaj ",
+	dagger:"križec ",
+	Dagger:"dvojni križec ",
+	permil:"znak 'na miljo' ",
+	lsaquo:"enojni kotni narekovaj, ki kaže v levo ",
+	rsaquo:"enojni kotni narekovaj, ki kaže v desno ",
+	euro:"znak za evro "
+})
+
diff --git a/dojox/editor/plugins/nls/sv/AutoSave.js b/dojox/editor/plugins/nls/sv/AutoSave.js
new file mode 100644
index 0000000..de9b56c
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Spara",
+	"saveSettingLabelOn": "Ange intervall för automatiskt sparande...",
+	"saveSettingLabelOff": "Avaktivera automatiskt sparande",
+	"saveSettingdialogTitle": "Spara automatiskt",
+	"saveSettingdialogDescription": "Ange intervall för automatiskt sparande",
+	"saveSettingdialogParamName": "Intervall för automatiskt sparande",
+	"saveSettingdialogParamLabel": "min.",
+	"saveSettingdialogButtonOk": "Ange intervall",
+	"saveSettingdialogButtonCancel": "Avbryt",
+	"saveMessageSuccess": "Sparades ${0}",
+	"saveMessageFail": "Kunde inte sparas ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/Blockquote.js b/dojox/editor/plugins/nls/sv/Blockquote.js
new file mode 100644
index 0000000..f654c02
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Blockcitat"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/Breadcrumb.js b/dojox/editor/plugins/nls/sv/Breadcrumb.js
new file mode 100644
index 0000000..6a39235
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName}-åtgärder",
+	"selectContents": "Välj innehåll",
+	"selectElement": "Välj element",
+	"deleteElement": "Ta bort element",
+	"deleteContents": "Ta bort innehåll",
+	"moveStart": "Flytta markören till början",
+	"moveEnd": "Flytta markören till slutet"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js b/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
new file mode 100644
index 0000000..35c57cd
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Komprimera redigerarverktygsfältet",
+	"expand": "Expandera redigerarverktygsfältet"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/FindReplace.js b/dojox/editor/plugins/nls/sv/FindReplace.js
new file mode 100644
index 0000000..0a21346
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Sök:",
+	"findTooltip": "Ange den text du vill söka efter",
+	"replaceLabel": "Ersätt med:",
+	"replaceTooltip": "Ange den text du vill ersätta med",
+	"findReplace": "Sök och ersätt",
+	"matchCase": "Matcha skiftläge",
+	"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",
+	"findButtonTooltip": "Sök efter texten",
+	"replaceButton": "Ersätt",
+	"replaceButtonTooltip": "Ersätt texten",
+	"replaceDialogText": "${0} förekomster ersattes.",
+	"eofDialogText": "Senaste förekomst${0}",
+	"eofDialogTextFind": "hittades",
+	"eofDialogTextReplace": "ersattes"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/InsertAnchor.js b/dojox/editor/plugins/nls/sv/InsertAnchor.js
new file mode 100644
index 0000000..5bd899e
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Infoga ankare",
+	title: "Egenskaper för ankare",
+	anchor: "Namn:",
+	text: "Beskrivning:",
+	set: "Ange",
+	cancel: "Avbryt"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/InsertEntity.js b/dojox/editor/plugins/nls/sv/InsertEntity.js
new file mode 100644
index 0000000..e9e76c2
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Infoga symbol"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/LocalImage.js b/dojox/editor/plugins/nls/sv/LocalImage.js
new file mode 100644
index 0000000..2b00b3d
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Infoga bild",
+	url: "Bild",
+	browse: "Bläddra...",
+	text: "Beskrivning",
+	set: "Infoga",
+	invalidMessage: "Ogiltigt bildfilformat",
+	prePopuTextUrl: "Ange en bild-URL-adress",
+	prePopuTextBrowse: " eller bläddra efter en lokal fil."
+})
+
diff --git a/dojox/editor/plugins/nls/sv/PageBreak.js b/dojox/editor/plugins/nls/sv/PageBreak.js
new file mode 100644
index 0000000..f79d133
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Sidbrytning"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/PasteFromWord.js b/dojox/editor/plugins/nls/sv/PasteFromWord.js
new file mode 100644
index 0000000..003ff9a
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Klistra in från Word",
+	"paste": "Klistra in",
+	"cancel": "Avbryt",
+	"instructions": "Klistra in innehållet från Word i textfältet nedan. När du är klar klickar du på Klistra in. Om du vill avbryta klickar du på Avbryt."
+})
+
diff --git a/dojox/editor/plugins/nls/sv/Preview.js b/dojox/editor/plugins/nls/sv/Preview.js
new file mode 100644
index 0000000..75af1ba
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Förhandsgranska"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/Save.js b/dojox/editor/plugins/nls/sv/Save.js
new file mode 100644
index 0000000..94dd0cf
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Spara"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/ShowBlockNodes.js b/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
new file mode 100644
index 0000000..787c683
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "Visa HTML-blockelement"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/Smiley.js b/dojox/editor/plugins/nls/sv/Smiley.js
new file mode 100644
index 0000000..dadaaf9
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "Infoga känslolägesikon",
+	emoticonSmile: "ler",
+	emoticonLaughing: "skrattar",
+	emoticonWink: "blinkar med ena ögat",
+	emoticonGrin: "ler stort",
+	emoticonCool: "cool",
+	emoticonAngry: "arg",
+	emoticonHalf: "halvt leende",
+	emoticonEyebrow: "lyfter på ena ögonbrynet",
+	emoticonFrown: "rynkar pannan",
+	emoticonShy: "blyg",
+	emoticonGoofy: "knasig",
+	emoticonOops: "hoppsan",
+	emoticonTongue: "räcker ut tungan",
+	emoticonIdea: "idé",
+	emoticonYes: "ja",
+	emoticonNo: "nej",
+	emoticonAngel: "ängel",
+	emoticonCrying: "gråter"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/SpellCheck.js b/dojox/editor/plugins/nls/sv/SpellCheck.js
new file mode 100644
index 0000000..f2cbefa
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Kontrollera stavning",
+	unfound: "Hittades inte",
+	skip: "Hoppa över",
+	skipAll: "Hoppa över alla",
+	toDic: "Lägg till i ordlistan",
+	suggestions: "Förslag",
+	replace: "Ersätt",
+	replaceWith: "Ersätt med",
+	replaceAll: "Ersätt alla",
+	cancel: "Avbryt",
+	msg: "Inga stavfel hittades",
+	iSkip: "Hoppa över",
+	iSkipAll: "Hoppa över alla liknande",
+	iMsg: "Inga stavningsförslag"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/TableDialog.js b/dojox/editor/plugins/nls/sv/TableDialog.js
index c1212da..5874cc2 100644
--- a/dojox/editor/plugins/nls/sv/TableDialog.js
+++ b/dojox/editor/plugins/nls/sv/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "högerjustera",
 	buttonSet: "Ange", // translated elsewhere?
 	buttonInsert: "Infoga",
+	buttonCancel: "Avbryt",
 
 	selectTableLabel: "Välj tabell",
 	insertTableRowBeforeLabel: "Lägg till rad före",
diff --git a/dojox/editor/plugins/nls/sv/TextColor.js b/dojox/editor/plugins/nls/sv/TextColor.js
new file mode 100644
index 0000000..591c3c0
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Ange",
+	"cancelButtonText": "Avbryt"
+})
+
diff --git a/dojox/editor/plugins/nls/sv/latinEntities.js b/dojox/editor/plugins/nls/sv/latinEntities.js
new file mode 100644
index 0000000..ab998a7
--- /dev/null
+++ b/dojox/editor/plugins/nls/sv/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"omvänt utropstecken",
+	cent:"centtecken",
+	pound:"pundtecken",
+	curren:"valutatecken",
+	yen:"yentecken\nyuantecken",
+	brvbar:"brutet lodrätt streck",
+	sect:"avsnittstecken",
+	uml:"trema",
+	copy:"copyrighttecken",
+	ordf:"indikator för feminint ordningstal",
+	laquo:"dubbelt vänstercitattecken",
+	not:"inte-tecken",
+	shy:"mjukt blanksteg",
+	reg:"registrerat varumärke-tecken",
+	macr:"makron",
+	deg:"gradtecken",
+	plusmn:"plus/minus-tecken\nplus/minus-tecken",
+	sup2:"upphöjd tvåa\nkvadrat",
+	sup3:"upphöjd trea\nkubik",
+	acute:"akut accent",
+	micro:"mikrotecken",
+	para:"alinea\nstycketecken",
+	middot:"halvhög punkt",
+	cedil:"cedilj",
+	sup1:"upphöjd etta",
+	ordm:"indikator för maskulint ordningstal",
+	raquo:"dubbelt högercitattecken",
+	frac14:"en fjärdedel",
+	frac12:"en halv",
+	frac34:"tre fjärdedelar",
+	iquest:"omvänt frågetecken",
+	Agrave:"versalt latinskt a med grav accent",
+	Aacute:"versalt latinskt a med akut accent",
+	Acirc:"versalt latinskt a med cirkumflex",
+	Atilde:"versalt latinskt a med tilde",
+	Auml:"versalt latinskt a med trema",
+	Aring:"versalt latinskt a med ring",
+	AElig:"versal latinsk ae-ligatur",
+	Ccedil:"versalt latinskt c med cedilj",
+	Egrave:"versalt latinskt e med grav accent",
+	Eacute:"versalt latinskt e med akut accent",
+	Ecirc:"versalt latinskt e med cirkumflex",
+	Euml:"versalt latinskt e med trema",
+	Igrave:"versalt latinskt i med grav accent",
+	Iacute:"versalt latinskt i med akut accent",
+	Icirc:"versalt latinskt i med cirkumflex",
+	Iuml:"versalt latinskt i med trema",
+	ETH:"versalt latinskt eth",
+	Ntilde:"versalt latinskt n med tilde",
+	Ograve:"versalt latinskt o med grav accent",
+	Oacute:"versalt latinskt o med akut accent",
+	Ocirc:"versalt latinskt o med cirkumflex",
+	Otilde:"versalt latinskt o med tilde",
+	Ouml:"versalt latinskt o med trema",
+	times:"multiplikationstecken",
+	Oslash:"versalt latinskt o med streck",
+	Ugrave:"versalt latinskt u med grav accent",
+	Uacute:"versalt latinskt u med akut accent",
+	Ucirc:"versalt latinskt u med cirkumflex",
+	Uuml:"versalt latinskt u med trema",
+	Yacute:"versalt latinskt y med akut accent",
+	THORN:"versalt latinskt thorn",
+	szlig:"gement latinskt dubbel-s\nß",
+	agrave:"gement latinskt a med grav accent",
+	aacute:"gement latinskt a med akut accent",
+	acirc:"gement latinskt a med cirkumflex",
+	atilde:"gement latinskt a med tilde",
+	auml:"gement latinskt a med trema",
+	aring:"gement latinskt a med ring",
+	aelig:"gemen latinsk ae-ligatur",
+	ccedil:"gement latinskt c med cedilj",
+	egrave:"gement latinskt e med grav accent",
+	eacute:"gement latinskt e med akut accent",
+	ecirc:"gement latinskt e med cirkumflex",
+	euml:"gement latinskt e med trema",
+	igrave:"gement latinskt i med grav accent",
+	iacute:"gement latinskt i med akut accent",
+	icirc:"gement latinskt i med cirkumflex",
+	iuml:"gement latinskt i med trema",
+	eth:"gement latinskt eth",
+	ntilde:"gement latinskt n med tilde",
+	ograve:"gement latinskt o med grav accent",
+	oacute:"gement latinskt o med akut accent",
+	ocirc:"gement latinskt o med cirkumflex",
+	otilde:"gement latinskt o med tilde",
+	ouml:"gement latinskt o med trema",
+	divide:"divisionstecken",
+	oslash:"gement latinskt o med streck",
+	ugrave:"gement latinskt u med grav accent",
+	uacute:"gement latinskt u med akut accent",
+	ucirc:"gement latinskt u med cirkumflex",
+	uuml:"gement latinskt u med trema",
+	yacute:"gement latinskt y med akut accent",
+	thorn:"gement latinskt thorn",
+	yuml:"gement latinskt y med trema",
+
+// Greek Characters and Symbols
+	fnof:"gement latinskt f med krok\nfunktion\nflorin",
+	Alpha:"versalt grekiskt alfa",
+	Beta:"versalt grekiskt beta",
+	Gamma:"versalt grekiskt gamma",
+	Delta:"versalt grekiskt delta",
+	Epsilon:"versalt grekiskt epsilon",
+	Zeta:"versalt grekiskt zeta",
+	Eta:"versalt grekiskt eta",
+	Theta:"versalt grekiskt theta",
+	Iota:"versalt grekiskt iota",
+	Kappa:"versalt grekiskt kappa",
+	Lambda:"versalt grekiskt lambda",
+	Mu:"versalt grekiskt my",
+	Nu:"versalt grekiskt ny",
+	Xi:"versalt grekiskt xi",
+	Omicron:"versalt grekiskt omikron",
+	Pi:"versalt grekiskt pi",
+	Rho:"versalt grekiskt rho",
+	Sigma:"versalt grekiskt sigma",
+	Tau:"versalt grekiskt tau",
+	Upsilon:"versalt grekiskt ypsilon",
+	Phi:"versalt grekiskt fi",
+	Chi:"versalt grekiskt chi",
+	Psi:"versalt grekiskt psi",
+	Omega:"versalt grekiskt omega",
+	alpha:"gement grekiskt alfa",
+	beta:"gement grekiskt beta",
+	gamma:"gement grekiskt gamma",
+	delta:"gement grekiskt delta",
+	epsilon:"gement grekiskt epsilon",
+	zeta:"gement grekiskt zeta",
+	eta:"gement grekiskt eta",
+	theta:"gement grekiskt theta",
+	iota:"gement grekiskt iota",
+	kappa:"gement grekiskt kappa",
+	lambda:"gement grekiskt lambda",
+	mu:"gement grekiskt my",
+	nu:"gement grekiskt ny",
+	xi:"gement grekiskt xi",
+	omicron:"gement grekiskt omikron",
+	pi:"gement grekiskt pi",
+	rho:"gement grekiskt rho",
+	sigmaf:"gement grekiskt slutligt sigma",
+	sigma:"gement grekiskt sigma",
+	tau:"gement grekiskt tau",
+	upsilon:"gement grekiskt ypsilon",
+	phi:"gement grekiskt fi",
+	chi:"gement grekiskt chi",
+	psi:"gement grekiskt psi",
+	omega:"gement grekiskt omega",
+	thetasym:"gement grekiskt theta",
+	upsih:"grekiskt ypsilon med krok",
+	piv:"grekisk pi-symbol",
+	bull:"punkt\nliten smart cirkel",
+	hellip:"ellips\ntre punkter",
+	prime:"primtecken\nminuter\nfot",
+	Prime:"dubbelt primtecken\nsekunder\ntum",
+	oline:"överstrykning\navståndsöverstrykning",
+	frasl:"bråkstreck",
+	weierp:"versalt skript-P\nexponentuppsättning\nweierstrass-p",
+	image:"versalt I\nimaginärdelssymbol",
+	real:"versalt R\nrealdelssymbol",
+	trade:"varumärkessymbol",
+	alefsym:"alefsymbol",
+	larr:"vänsterpil",
+	uarr:"uppåtpil",
+	rarr:"högerpil",
+	darr:"nedåtpil",
+	harr:"vänster/höger-pil",
+	crarr:"nedåtpil ned vänstergående hörn\nradbrytning",
+	lArr:"vänsterdubbelpil",
+	uArr:"uppåtdubbelpil",
+	rArr:"högerdubbelpil",
+	dArr:"nedåtdubbelpil",
+	hArr:"vänster/höger-dubbelpil",
+	forall:"för alla",
+	part:"partiell differential",
+	exist:"det finns",
+	empty:"tom uppsättning\nnull-uppsättning\ndiameter",
+	nabla:"nabla\nbakåtdifferens",
+	isin:"element av",
+	notin:"inte element av",
+	ni:"innehåller som medlem",
+	prod:"n-unär produkt\nprodukttecken",
+	sum:"n-unär summering",
+	minus:"minustecken",
+	lowast:"asteriskoperator",
+	radic:"kvadratrot",
+	prop:"proportionellt mot",
+	infin:"oändligheten",
+	ang:"vinkel",
+	and:"logiskt och",
+	or:"logiskt eller",
+	cap:"skärning",
+	cup:"union","int":"integral",
+	there4:"därför",
+	sim:"tildeoperator\nvarierar med\nliknar",
+	cong:"ungefär lika med",
+	asymp:"nästan lika med\nasymptotiskt med",
+	ne:"inte lika med",
+	equiv:"identiskt med",
+	le:"mindre än eller lika med",
+	ge:"större än eller lika med",
+	sub:"delmängd av",
+	sup:"överordnad mängd till",
+	nsub:"inte delmängd av",
+	sube:"delmängd av eller lika med",
+	supe:"överordnad mängd till eller lika med",
+	oplus:"plustecken i cirkel\ndirektsumma",
+	otimes:"multiplikationstecken i cirkel\nvektorprodukt",
+	perp:"uppåt\nortogonal mot\nvinkelrät",
+	sdot:"punktoperator",
+	lceil:"vänstertak",
+	rceil:"högertak",
+	lfloor:"vänstergolv",
+	rfloor:"högergolv",
+	lang:"vänstervinkelhakparentes",
+	rang:"högervinkelhakparentes",
+	loz:"romb",
+	spades:"svart spader",
+	clubs:"svart klöver\ntreklöver",
+	hearts:"svart hjärter",
+	diams:"svart ruter",
+	OElig:"versal latinsk oe-ligatur",
+	oelig:"gemen latinsk oe-ligatur",
+	Scaron:"versalt latinskt s med karon",
+	scaron:"gement latinskt s med karon",
+	Yuml:"versalt latinskt y med trema",
+	circ:"modifieringscirkumflex",
+	tilde:"litet tilde",
+	ensp:"halvfyrkantsblanksteg",
+	emsp:"fyrkantsblanksteg",
+	thinsp:"tunt blanksteg",
+	zwnj:"mjukt hårfint blanksteg",
+	zwj:"hårt hårfint blanksteg",
+	lrm:"vänster-till-höger-märke",
+	rlm:"höger-till-vänster-märke",
+	ndash:"tankstreck",
+	mdash:"långt tankstreck",
+	lsquo:"enkelt vänstercitattecken",
+	rsquo:"enkelt högercitattecken",
+	sbquo:"enkelt underkantscitattecken",
+	ldquo:"dubbelt vänstercitattecken",
+	rdquo:"dubbelt högercitattecken",
+	bdquo:"dubbelt underkantscitattecken",
+	dagger:"kors",
+	Dagger:"dubbelkors",
+	permil:"promille",
+	lsaquo:"enkel vänstervinkelparentes",
+	rsaquo:"enkel högervinkelparentes",
+	euro:"eurotecken"
+})
+
diff --git a/dojox/editor/plugins/nls/th/AutoSave.js b/dojox/editor/plugins/nls/th/AutoSave.js
new file mode 100644
index 0000000..9b12b9d
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "บันทึก",
+	"saveSettingLabelOn": "ตั้งช่วงเวลาบันทึกอัตโนมัติ...",
+	"saveSettingLabelOff": "ปิดบันทึกอัตโนมัติ",
+	"saveSettingdialogTitle": "บันทึกอัตโนมัติ",
+	"saveSettingdialogDescription": "ระบุช่วงเวลาบันทึกอัตโนมัติ",
+	"saveSettingdialogParamName": "ช่วงเวลาบันทึกอัตโนมัติ",
+	"saveSettingdialogParamLabel": "นาที",
+	"saveSettingdialogButtonOk": "ตั้งช่วงเวลา",
+	"saveSettingdialogButtonCancel": "ยกเลิก",
+	"saveMessageSuccess": "ถูกบันทึกเมื่อ ${0}",
+	"saveMessageFail": "ล้มเหลวในการบันทึกเมื่อ ${0}"
+})
+
diff --git a/dojox/editor/plugins/nls/th/Blockquote.js b/dojox/editor/plugins/nls/th/Blockquote.js
new file mode 100644
index 0000000..643efbf
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "บล็อกคำพูด"
+})
+
diff --git a/dojox/editor/plugins/nls/th/Breadcrumb.js b/dojox/editor/plugins/nls/th/Breadcrumb.js
new file mode 100644
index 0000000..08a9d53
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} แอ็คชัน",
+	"selectContents": "เลือกเนื้อหา",
+	"selectElement": "เลือกอิลิเมนต์",
+	"deleteElement": "ลบอิลิเมนต์",
+	"deleteContents": "ลบเนื้อหา",
+	"moveStart": "ย้ายเคอร์เซอร์ไปยังจุดเริ่มต้น",
+	"moveEnd": "ย้ายเคอร์เซอร์ไปยังจุดสิ้นสุด"
+})
+
diff --git a/dojox/editor/plugins/nls/th/CollapsibleToolbar.js b/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
new file mode 100644
index 0000000..270b0ab
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "ยุบรวมแถบเครื่องมือตัวแก้ไข",
+	"expand": "ขยายแถบเครื่องมือตัวแก้ไข"
+})
+
diff --git a/dojox/editor/plugins/nls/th/FindReplace.js b/dojox/editor/plugins/nls/th/FindReplace.js
new file mode 100644
index 0000000..4abd152
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "ค้นหา:",
+	"findTooltip": "ป้อนข้อความเพื่อหา",
+	"replaceLabel": "แทนที่ด้วย:",
+	"replaceTooltip": "ป้อนข้อความเพื่อแทนที่ด้วย",
+	"findReplace": "ค้นหาและแทนที่",
+	"matchCase": "ตรงตามตัวพิมพ์ใหญ่เล็ก",
+	"matchCaseTooltip": "ตรงตามตัวพิมพ์ใหญ่เล็ก",
+	"backwards": "ย้อนกลับ",
+	"backwardsTooltip": "ค้นหาย้อนกับเพื่อหาข้อความ",
+	"replaceAll": "ที่เกิดขึ้นทั้งหมด",
+	"replaceAllButton": "แทนที่ทั้งหมด",
+	"replaceAllButtonTooltip": "แทนที่ข้อความทั้งหมด",
+	"findButton": "ค้นหา",
+	"findButtonTooltip": "หาข้อความ",
+	"replaceButton": "แทนที่",
+	"replaceButtonTooltip": "แทนที่ข้อความ",
+	"replaceDialogText": "แทนที่ ${0} ที่เกิดขึ้น",
+	"eofDialogText": "การเกิดขึ้นล่าสุด ${0}",
+	"eofDialogTextFind": "หาพบ",
+	"eofDialogTextReplace": "ถูกแทนที่"
+})
+
diff --git a/dojox/editor/plugins/nls/th/InsertAnchor.js b/dojox/editor/plugins/nls/th/InsertAnchor.js
new file mode 100644
index 0000000..b8f941e
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "แทรกจุดยึด",
+	title: "คุณสมบัติจุดยึด",
+	anchor: "ชื่อ:",
+	text: "รายละเอียด",
+	set: "ตั้งค่า",
+	cancel: "ยกเลิก"
+})
+
diff --git a/dojox/editor/plugins/nls/th/InsertEntity.js b/dojox/editor/plugins/nls/th/InsertEntity.js
new file mode 100644
index 0000000..7c05c08
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "แทรกสัญลักษณ์"
+})
+
diff --git a/dojox/editor/plugins/nls/th/LocalImage.js b/dojox/editor/plugins/nls/th/LocalImage.js
new file mode 100644
index 0000000..d7a6f93
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "แทรกรูปภาพ",
+	url: "รูปภาพ",
+	browse: "เรียกดู...",
+	text: "รายละเอียด",
+	set: "แทรก",
+	invalidMessage: "ชนิดของไฟล์รูปภาพไม่ถูกต้อง",
+	prePopuTextUrl: "ป้อน URL ของรูปภาพ",
+	prePopuTextBrowse: " หรือเรียกดูโลคัลไฟล์"
+})
+
diff --git a/dojox/editor/plugins/nls/th/PageBreak.js b/dojox/editor/plugins/nls/th/PageBreak.js
new file mode 100644
index 0000000..62a2841
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "เส้นกั้นหน้า"
+})
+
diff --git a/dojox/editor/plugins/nls/th/PasteFromWord.js b/dojox/editor/plugins/nls/th/PasteFromWord.js
new file mode 100644
index 0000000..cfafda8
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "วางจาก Word",
+	"paste": "วาง",
+	"cancel": "ยกเลิก",
+	"instructions": "วางเนื้อหาจาก Word ลงในกล่องข้อความข้างล่าง เมื่อคุณพอใจกับเนื้อหาที่แทรกแล้วให้กดปุ่ม วาง เมื่อต้องการยกเลิกการเรียงลำดับข้อความให้กดปุ่ม ยกเลิก"
+})
+
diff --git a/dojox/editor/plugins/nls/th/Preview.js b/dojox/editor/plugins/nls/th/Preview.js
new file mode 100644
index 0000000..d91eb68
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "แสดงตัวอย่าง"
+})
+
diff --git a/dojox/editor/plugins/nls/th/Save.js b/dojox/editor/plugins/nls/th/Save.js
new file mode 100644
index 0000000..ed35c1b
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "บันทึก"
+})
+
diff --git a/dojox/editor/plugins/nls/th/ShowBlockNodes.js b/dojox/editor/plugins/nls/th/ShowBlockNodes.js
new file mode 100644
index 0000000..90546ee
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "แสดงอิลิเมนต์บล็อก HTML"
+})
+
diff --git a/dojox/editor/plugins/nls/th/Smiley.js b/dojox/editor/plugins/nls/th/Smiley.js
new file mode 100644
index 0000000..ced4f0a
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "แทรกไอคอนแสดงอารมณ์",
+	emoticonSmile: "ยิ้ม",
+	emoticonLaughing: "หัวเราะ",
+	emoticonWink: "ขยิบตา",
+	emoticonGrin: "ยิ้มกว้าง",
+	emoticonCool: "เจ๋ง",
+	emoticonAngry: "โกรธ",
+	emoticonHalf: "ครึ่งซีก",
+	emoticonEyebrow: "คิ้ว",
+	emoticonFrown: "หน้าบึ้ง",
+	emoticonShy: "อาย",
+	emoticonGoofy: "โง่",
+	emoticonOops: "oops",
+	emoticonTongue: "แลบลิ้น",
+	emoticonIdea: "ความคิด",
+	emoticonYes: "ใช่",
+	emoticonNo: "ไม่ใช่",
+	emoticonAngel: "โมโห",
+	emoticonCrying: "ร้องไห้"
+})
+
diff --git a/dojox/editor/plugins/nls/th/SpellCheck.js b/dojox/editor/plugins/nls/th/SpellCheck.js
new file mode 100644
index 0000000..f64da88
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "ตรวจสอบการสะกดคำแบบแบตช์",
+	unfound: "ไม่พบ",
+	skip: "ข้าม",
+	skipAll: "ข้ามทั้งหมด",
+	toDic: "เพิ่งลงในพจนานุกรม",
+	suggestions: "การแนะนำ",
+	replace: "แทนที่",
+	replaceWith: "แทนที่ด้วย",
+	replaceAll: "แทนที่ทั้งหมด",
+	cancel: "Cancel",
+	msg: "ไม่พบคำที่สะกดผิด",
+	iSkip: "ข้ามนี้",
+	iSkipAll: "ข้ามที่เหมือนนี้",
+	iMsg: "ไม่มีการแนะนำการสะกด"
+})
+
diff --git a/dojox/editor/plugins/nls/th/TableDialog.js b/dojox/editor/plugins/nls/th/TableDialog.js
index e0ba34d..b00e247 100644
--- a/dojox/editor/plugins/nls/th/TableDialog.js
+++ b/dojox/editor/plugins/nls/th/TableDialog.js
@@ -1,6 +1,6 @@
 ({
 	insertTableTitle: "แทรกตาราง",
-	modifyTableTitle: "ปรับเปลี่ยนตาราง",
+	modifyTableTitle: "ปรับเปลี่ยนไขตาราง",
 	rows: "แถว:",
 	columns: "คอลัมน์:",
 	align: "จัดตำแหน่ง:",
@@ -18,6 +18,7 @@
 	right: "ขวา",
 	buttonSet: "ตั้งค่า", // translated elsewhere?
 	buttonInsert: "แทรก",
+	buttonCancel: "ยกเลิก",
 
 	selectTableLabel: "เลือกตาราง",
 	insertTableRowBeforeLabel: "เพิ่มแถวก่อน",
@@ -27,4 +28,3 @@
 	deleteTableRowLabel: "ลบแถว",
 	deleteTableColumnLabel: "ลบคอลัมน์"
 })
-
diff --git a/dojox/editor/plugins/nls/th/TextColor.js b/dojox/editor/plugins/nls/th/TextColor.js
new file mode 100644
index 0000000..442ea59
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "เซ็ต",
+	"cancelButtonText": "ยกเลิก"
+})
+
diff --git a/dojox/editor/plugins/nls/th/latinEntities.js b/dojox/editor/plugins/nls/th/latinEntities.js
new file mode 100644
index 0000000..2834064
--- /dev/null
+++ b/dojox/editor/plugins/nls/th/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* These are already handled in the default RTE
+		amp:"ampersand",lt:"less-than sign",
+		gt:"greater-than sign",
+		nbsp:"no-break space\nnon-breaking space",
+		quot:"quote",
+	*/
+	iexcl:"เครื่องหมายอัศเจรีย์กลับหัว",
+	cent:"เครื่องหมาย เซ็นต์",
+	pound:"เครื่องหมายปอนด์",
+	curren:"เครื่องหมายสกุลเงิน",
+	yen:"เครื่องหมาย เยน\เครื่องหมาย หยวน",
+	brvbar:"แถบแยก\nแถบแยกแนวตั้ง",
+	sect:"เครื่องหมายแบ่งส่วน",
+	uml:"ไดเอเรซิส\nช่องว่างของไดเอเรซิส",
+	copy:"เครื่องหมายลิขสิทธิ์",
+	ordf:"ตังบ่งชี้ลำดับของผู้หญิง",
+	laquo:"เครื่องหมายคำพูดที่ชี้ไปทางซ้าย\nguillemet ที่ชี้ไปทางซ้าย",
+	not:"ลัญญลักษณ์ น็อท",
+	shy:"ซิร์ฟไฮเฟน\nไฮเฟนการตัดสินใจ",
+	reg:"ลัญญลักษณ์การจดทะเบียน\nลัญญลักษณ์เครื่องหมายการค้าจดทะเบียน",
+	macr:"ไมครอน\nช่องว่างของไมครอน\noverline\nAPL overbar",
+	deg:"สัญญลักษณ์องศา",
+	plusmn:"เครื่องหมายบวก-ลบ\nเครื่องหมายบวก-หรือ-ลบ",
+	sup2:"ตัวยกสอง\nตัวยกหลักสอง\nยกกำลังสอง",
+	sup3:"ตัวยกสาม\nตัวยกหลักสาม\ncubed",
+	acute:"acute accent\nช่องว่างของอคิวท์",
+	micro:"เครื่องหมายไมโคร",
+	para:"เครื่องหมาย pilcrow\nเครื่องหมายย่อหน้า",
+	middot:"จุดกึ่งกลาง\nคอมม่า Georgian\nจุดกึ่งกลางภาษากรีซ",
+	cedil:"ซีดิลลา\nช่องว่างของซีดิลลา",
+	sup1:"ตัวยกหนึ่ง\nตัวยกหลักหนึ่ง",
+	ordm:"ตังบ่งชี้ลำดับของผู้ชาย",
+	raquo:"เครื่องหมายคำพูดที่ชี้ไปทางขวา\nguillemet ที่ชี้ไปทางขวา",
+	frac14:"เศษหนึ่งส่วนสี่แบบหยาบๆ\nเศษหนึ่งส่วนสี่",
+	frac12:"เศษหนึ่งส่วนสองแบบหยาบๆ\nเศษหนึ่งส่วนสอง",
+	frac34:"เศษสามส่วนสี่แบบหยาบๆ\nเศษสามส่วนสี่",
+	iquest:"เครื่องหมายคำถามกลับหัว\nเครื่อหมายคำถามกลับหัว",
+	Agrave:"อักษร A ตัวใหญ่ภาษาละติน A ที่มีเครื่องหมายกราฟ\nอักษร A ตัวใหญ่ภาษาละตินที่มีเครื่องหมายกราฟ",
+	Aacute:"อักษรละติน A ตัวใหญ่ พร้อมเครื่องหมายอคิวท์",
+	Acirc:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์ ",
+	Atilde:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายทิลเดอ",
+	Auml:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
+	Aring:"อักษรละติน A ตัวใหญ่ที่มีเครื่องหมายวงแหวนด้านบน\nอักษรละติน A ตัวใหญ่ที่มีเครื่องหมายวงแหวน",
+	AElig:"อักษรละติน AE ตัวใหญ่\nอักษรละติน AE ตัวใหญ่ที่ติดกัน",
+	Ccedil:"อักษรละติน C ตัวใหญ่ที่มีเครื่องหมายซีดิลลา",
+	Egrave:"อักษรละติน E ตัวใหญ่ที่มีเครื่องหมายกราฟ",
+	Eacute:"อักษรละติน E ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
+	Ecirc:"อักษรละติน E ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	Euml:"อักษรละติน E ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
+	Igrave:"อักษรละติน I ตัวใหญ่ที่มีเครื่องหมายกราฟ",
+	Iacute:"อักษรละติน I ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
+	Icirc:"อักษรละติน I ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	Iuml:"อักษรละติน I ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
+	ETH:"อักษรละติน ETH ตัวใหญ่",
+	Ntilde:"อักษรละติน N ตัวใหญ่ที่มีเครื่องหมายทิลเดอ",
+	Ograve:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายกราฟ",
+	Oacute:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
+	Ocirc:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลก",
+	Otilde:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายทิลเดอ",
+	Ouml:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
+	times:"เครื่องหมายคูณ",
+	Oslash:"อักษรละติน O ตัวใหญ่ที่มีเครื่องหมายแลช\nกษรละติน O ตัวใหญ่ที่มีเครื่องหมายสแลช",
+	Ugrave:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายกราฟ",
+	Uacute:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
+	Ucirc:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	Uuml:"อักษรละติน U ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
+	Yacute:"อักษรละติน Y ตัวใหญ่ที่มีเครื่องหมายอคิวท์",
+	THORN:"อักษรละติน THORN ตัวใหญ่",
+	szlig:"อักษร sharp s ตัวเล็กภาษาละติน\ness-zed",
+	agrave:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ\nอักษร a ตัวล็กภาษาละตินที่มีเครื่องหมายกราฟ",
+	aacute:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
+	acirc:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	atilde:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายทิลเดอ",
+	auml:"อักษร a ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
+	aring:"อักษร a ตัวเล็กภาษาละตินที่มีวงแหวนข้างบน\nอักษร a ตัวล็กภาษาละตินที่มีวงแหวน",
+	aelig:"อักษร ae ตัวเล็กภาษาละติน\nอักษร ae ตัวเล็กภาษาละตินที่ติดกัน",
+	ccedil:"อักษร c ตัวเล็กภาษาละตินที่มีเครื่องหมายซีดิลลา",
+	egrave:"อักษร c ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
+	eacute:"อักษร c ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
+	ecirc:"อักษร e ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลก",
+	euml:"อักษร e ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
+	igrave:"อักษร i ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
+	iacute:"อักษร i ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
+	icirc:"อักษร i ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	iuml:"อักษร i ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
+	eth:"อักษร eth ตัวเล็กภาษาละติน",
+	ntilde:"อักษร n ตัวเล็กภาษาละตินที่มีเครื่องหมายทิลเดอ",
+	ograve:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
+	oacute:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
+	ocirc:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	otilde:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายทิลเดอ",
+	ouml:"อักษร o ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
+	divide:"เครื่องหมายหาร",
+	oslash:"อักษรละติน o ตัวเล็กที่มีเครื่องหมายแลช\nอักษรละติน o ตัวเล็กที่มีเครื่องหมายสแลช",
+	ugrave:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายกราฟ",
+	uacute:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
+	ucirc:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายเซอร์คัมเฟลกซ์",
+	uuml:"อักษร u ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
+	yacute:"อักษร y ตัวเล็กภาษาละตินที่มีเครื่องหมายอคิวท์",
+	thorn:"อักษร thorn ตัวเล็กภาษาละติน",
+	yuml:"อักษร y ตัวเล็กภาษาละตินที่มีเครื่องหมายไดเอเรซิส",
+
+// Greek Characters and Symbols
+	fnof:"อักษร f ตัวเล็กภาษาละตินที่มีห่วง\nฟังก์ชัน\nflorin",
+	Alpha:"อักษรอัลฟาตัวใหญ่ภาษากรีซ",
+	Beta:"อักษรเบตาตัวใหญ่ภาษากรีซ",
+	Gamma:"อักษรแกมม่าตัวใหญ่ภาษากรีซ",
+	Delta:"อักษรเดลตาตัวใหญ่ภาษากรีซ",
+	Epsilon:"อักษรเอปซีลอนตัวใหญ่ภาษากรีซ",
+	Zeta:"อักษรซีตาตัวใหญ่ภาษากรีซ",
+	Eta:"อักษรอีตาตัวใหญ่ภาษากรีซ",
+	Theta:"อักษรทีตาตัวใหญ่ภาษากรีซ",
+	Iota:"อักษรไอโอตาตัวใหญ่ภาษากรีซ",
+	Kappa:"อักษรแคปปาตัวใหญ่ภาษากรีซ",
+	Lambda:"อักษรแลมดาตัวใหญ่ภาษากรีซ",
+	Mu:"อักษร mu ตัวใหญ่ภาษากรีซ",
+	Nu:"อักษร nu ตัวใหญ่ภาษากรีซ",
+	Xi:"อักษร xi ตัวใหญ่ภาษากรีซ",
+	Omicron:"อักษรโอไมครอนตัวใหญ่ภาษากรีซ",
+	Pi:"อักษร pi ตัวใหญ่ภาษากรีซ",
+	Rho:"อักษร rho ตัวใหญ่ภาษากรีซ",
+	Sigma:"อักษรซิกมาตัวใหญ่ภาษากรีซ",
+	Tau:"อักษร tau ตัวใหญ่ภาษากรีซ",
+	Upsilon:"อักษรอิปไซลอนตัวใหญ่ภาษากรีซ",
+	Phi:"อักษร phi ตัวใหญ่ภาษากรีซ",
+	Chi:"อักษร chi ตัวใหญ่ภาษากรีซ",
+	Psi:"อักษร psi ตัวใหญ่ภาษากรีซ",
+	Omega:"อักษรโอเมกาตัวใหญ่ภาษากรีซ",
+	alpha:"อักษรอัลฟาตัวเล็กภาษากรีซ",
+	beta:"อักษรเบตาตัวเล็กภาษากรีซ",
+	gamma:"อักษรแกมม่าตัวเล็กภาษากรีซ",
+	delta:"อักษรเดลตาตัวเล็กภาษากรีซ",
+	epsilon:"อักษรเอปซิลอนตัวเล็กภาษากรีซ",
+	zeta:"อักษรซีตาตัวเล็กภาษากรีซ",
+	eta:"อักษรอีตาตัวเล็กภาษากรีซ",
+	theta:"อักษรทีตาตัวเล็กภาษากรีซ",
+	iota:"อักษรไอโอตาตัวเล็กภาษากรีซ",
+	kappa:"อักษรแคปปาตัวเล็กภาษากรีซ",
+	lambda:"อักษรแลมดาตัวเล็กภาษากรีซ",
+	mu:"อักษร mu ตัวเล็กภาษากรีซ",
+	nu:"อักษร nu ตัวเล็กภาษากรีซ",
+	xi:"อักษร xi ตัวเล็กภาษากรีซ",
+	omicron:"อักษรโอไมครอนตัวเล็กภาษากรีซ",
+	pi:"อักษร pi ตัวเล็กภาษากรีซ",
+	rho:"อักษร rho ตัวเล็กภาษากรีซ",
+	sigmaf:"อักษรซิกมาสุดท้ายตัวเล็กภาษากรีซ",
+	sigma:"อักษรซิกมาตัวเล็กภาษากรีซ",
+	tau:"อักษร tau ตัวเล็กภาษากรีซ",
+	upsilon:"อักษรอิปไซลอนตัวเล็กภาษากรีซ",
+	phi:"อักษร phi ตัวเล็กภาษากรีซ",
+	chi:"อักษร chi ตัวเล็กภาษากรีซ",
+	psi:"อักษร psi ตัวเล็กภาษากรีซ",
+	omega:"อักษรโอเมกาตัวเล็กภาษากรีซ",
+	thetasym:"อักษรสัญญลักษณ์ทีตาตัวเล็กภาษากรีซ",
+	upsih:"อักษรอิปไซลอนภาษากริซที่มีสัญญลักษณ์ห่วง",
+	piv:"สัญญลักษณ์ pi ภาษากรีซ",
+	bull:"จุดนำ\nวงกลมสีดำเล็กๆ",
+	hellip:"จุดแนวนอน\nจุดนำสามจุด",
+	prime:"เครื่องหมายไพร์ม\nนาที\nฟุต",
+	Prime:"เครื่องหมายดับเบิลไพร์ม\nวินาที\nนิ้ว",
+	oline:"overline\nช่องว่าง overscore",
+	frasl:"สแลชเศษส่วน",
+	weierp:"สคริปต์ P ตัวใหญ่\npower set\nWeierstrass p",
+	image:"ตัวอักษร I สีดำตัวใหญ่\nส่วนสมมุติ",
+	real:"ตัวอักษร R สีดำตัวใหญ่\nสัญญลักษณ์ส่วนที่แท้จริง",
+	trade:"สัญญลักษณ์เครื่องหมายการค้า",
+	alefsym:"สัญญลักษณ์ alef\nfirst transfinite cardinal",
+	larr:"ลูกศรชี้ไปทางซ้าย",
+	uarr:"ลูกศรชี้ขึ้นบน",
+	rarr:"ลูกศรชี้ไปทางขวา",
+	darr:"ลูกศรชี้ลง",
+	harr:"ลูกศรซ้ายขวา",
+	crarr:"ลูกศรชี้ลงที่มีมุมไปทางซ้าย\ncarriage return",
+	lArr:"ลูกศรสองตัวชี้ไปทางซ้าย",
+	uArr:"ลูกศรสองตัวที่ชี้ไปข้างบน",
+	rArr:"ลูกศรสองตัวชี้ไปทางขวา",
+	dArr:"ลูกศรสองตัวที่ชี้ไปด้านล่าง",
+	hArr:"ลูกศรสองตัวที่ชี้ไปซ้ายขวา",
+	forall:"สำหรับทั้งหมด",
+	part:"แตกต่างบางส่วน",
+	exist:"ที่มีอยู่",
+	empty:"เซ็ตว่าง\nเซ็ต null\nเส้นผ่าศูนย์กลาง",
+	nabla:"nabla\nความแตกต่างไปข้างหลัง",
+	isin:"อิลิเมนต์ของ",
+	notin:"ไม่ใช่อิลิเมนต์ของ",
+	ni:"รวมเป็นสมาชิก",
+	prod:"ผลิตภัณฑ์ n-ary\เครื่องหมายผลิตภัณฑ์",
+	sum:"n-ary sumation",
+	minus:"เครื่องหมายลบ",
+	lowast:"โอเปอเรเตอร์เครื่องหมายดอกจัน",
+	radic:"สแควร์รูท\nเครื่องหมายราก",
+	prop:"เป็นสัดส่วนกับ",
+	infin:"อนันต์",
+	ang:"มุม",
+	and:"โลจิคัลและ\nwedge",
+	or:"โลจิคัล หรือ\nvee",
+	cap:"อินเตอร์เซกชัน\ncap",
+	cup:"ยูเนียน\ncup","int":"อินทีกรัล",
+	there4:"ดังนั้น",
+	sim:"โอเปอเรเตอร์ดิลเดอ\nแตกต่างกับ\nเหมือนกับ",
+	cong:"ประมาณเท่ากับ",
+	asymp:"เกือบเท่ากับ\nasymptotic to",
+	ne:"ไม่เท่ากับ",
+	equiv:"เหมือนกับ",
+	le:"น้อยกว่าหรือเท่ากับ",
+	ge:"มากกว่าหรือเท่ากับ",
+	sub:"เซ็ตย่อยของ",
+	sup:"ซุปเปอร์เซ็ตของ",
+	nsub:"ไม่ใช่เซ็ตย่อยของ",
+	sube:"เซ็ตย่อยของหรือเท่ากับ",
+	supe:"ซุปเปอร์เซ็ตของหรือเท่ากับ",
+	oplus:"เครื่องหมายวงกลม\nผลรวมโดยตรง",
+	otimes:"วงกลมครั้ง\nผลิตภัณฑ์เวคเตอร์",
+	perp:"up tack\northogonal to\nperpendicular",
+	sdot:"โอเปอเรเตอร์จุด",
+	lceil:"เพดานด้านซ้าย\nAPL upstile",
+	rceil:"เพดานด้านขวา",
+	lfloor:"พื้นด้านซ้าย\nAPL downstile",
+	rfloor:"พื้นด้านซ้าย",
+	lang:"วงเล็บซ้าย",
+	rang:"วงเล็บขวา",
+	loz:"lozenge",
+	spades:"black spade suit",
+	clubs:"black club suit\nshamrock",
+	hearts:"black heart suit\nvalentine",
+	diams:"black diamond suit",
+	OElig:"อักษรละติน OE ตัวใหญ่",
+	oelig:"อักษร oe ตัวเล็กติดกันภาษาละติน",
+	Scaron:"อักษรละติน S ตัวใหญ่ที่มีเครื่องหมายคารอน",
+	scaron:"อักษรละติน s ตัวเล็กที่มีเครื่องหมายคารอน",
+	Yuml:"อักษรละติน Y ตัวใหญ่ที่มีเครื่องหมายไดเอเรซิส",
+	circ:"ตัวแก้ไขตัวอักษรเซอร์คัมเฟลกซ์",
+	tilde:"ทิลเดอตัวเล็ก",
+	ensp:"ช่องว่าง en",
+	emsp:"ช่องว่าง em",
+	thinsp:"ช่องว่างแบบบาง",
+	zwnj:"ไม่ใช่ตัวรวมที่ความกว้างเป็นศูนย์",
+	zwj:"ตัวรวมที่ความกว้างเป็นศูนย์",
+	lrm:"มาร์กซ้ายไปขวา",
+	rlm:"มาร์กขวาไปซ้าย",
+	ndash:"แดช en",
+	mdash:"แดช em",
+	lsquo:"เครื่องหมายคำพูดเดี่ยวด้านซ้าย",
+	rsquo:"เครื่องหมายคำพูดเดี่ยวด้านขวา",
+	sbquo:"เครื่องหมายคำพูด low-9 เดี่ยว",
+	ldquo:"เครื่องหมายคำพูดคู่ด้านซ้าย",
+	rdquo:"เครื่องหมายคำพูดคู่ด้านขวา",
+	bdquo:"เครื่องหมายคำพูด low-9 คู่",
+	dagger:"dagger",
+	Dagger:"dagger คู่",
+	permil:"เครื่องหมาย per mille",
+	lsaquo:"เครื่องหมายคำพูดเดี่ยวที่ชี้ไปด้านซ้าย",
+	rsaquo:"เครื่องหมายคำพูดเดี่ยวที่ชี้ไปด้านขวา",
+	euro:"เครื่องหมายยูโร"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/AutoSave.js b/dojox/editor/plugins/nls/tr/AutoSave.js
new file mode 100644
index 0000000..1aed6f3
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/AutoSave.js
@@ -0,0 +1,14 @@
+({
+	"saveLabel": "Kaydet",
+	"saveSettingLabelOn": "Otomatik Kaydetme Aralığını Ayarla...",
+	"saveSettingLabelOff": "Otomatik Kaydetmeyi Kapat",
+	"saveSettingdialogTitle": "Otomatik Kaydet",
+	"saveSettingdialogDescription": "Otomatik Kaydetme Aralığını Belirt",
+	"saveSettingdialogParamName": "Otomatik Kaydetme Aralığı",
+	"saveSettingdialogParamLabel": "dak",
+	"saveSettingdialogButtonOk": "Aralığı Ayarla",
+	"saveSettingdialogButtonCancel": "İptal",
+	"saveMessageSuccess": "${0} konumuna kaydedildi",
+	"saveMessageFail": "${0} konumuna kaydedilemedi"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/Blockquote.js b/dojox/editor/plugins/nls/tr/Blockquote.js
new file mode 100644
index 0000000..1bcb572
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/Blockquote.js
@@ -0,0 +1,4 @@
+({
+	"blockquote": "Öbek"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/Breadcrumb.js b/dojox/editor/plugins/nls/tr/Breadcrumb.js
new file mode 100644
index 0000000..e97ac04
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/Breadcrumb.js
@@ -0,0 +1,10 @@
+({
+	"nodeActions": "${nodeName} Eylemleri",
+	"selectContents": "İçindekileri seç",
+	"selectElement": "Öğeyi seç",
+	"deleteElement": "Öğeyi sil",
+	"deleteContents": "İçindekileri sil",
+	"moveStart": "İmleci başa taşı",
+	"moveEnd": "İmleci sona taşı"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js b/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
new file mode 100644
index 0000000..93a281f
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/CollapsibleToolbar.js
@@ -0,0 +1,5 @@
+({
+	"collapse": "Düzenleyici Araç Çubuğunu Daralt",
+	"expand": "Düzenleyici Araç Çubuğunu Genişlet"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/FindReplace.js b/dojox/editor/plugins/nls/tr/FindReplace.js
new file mode 100644
index 0000000..0798eee
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/FindReplace.js
@@ -0,0 +1,23 @@
+({
+	"findLabel": "Bul:",
+	"findTooltip": "Bulunacak metni girin",
+	"replaceLabel": "Değiştir:",
+	"replaceTooltip": "Değiştirilecek metni girin",
+	"findReplace": "Bul ve Değiştir",
+	"matchCase": "Büyük/küçük harf eşleştir",
+	"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",
+	"findButtonTooltip": "Metni bul",
+	"replaceButton": "Değiştir",
+	"replaceButtonTooltip": "Metni değiştir",
+	"replaceDialogText": "${0} tekrar değiştirildi.",
+	"eofDialogText": "Son tekrar ${0}",
+	"eofDialogTextFind": "bulundu",
+	"eofDialogTextReplace": "değiştirildi"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/InsertAnchor.js b/dojox/editor/plugins/nls/tr/InsertAnchor.js
new file mode 100644
index 0000000..b366868
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/InsertAnchor.js
@@ -0,0 +1,9 @@
+({
+	insertAnchor: "Tutturucu Ekle",
+	title: "Tutturucu Özellikleri",
+	anchor: "Ad:",
+	text: "Açıklama:",
+	set: "Ayarla",
+	cancel: "İptal"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/InsertEntity.js b/dojox/editor/plugins/nls/tr/InsertEntity.js
new file mode 100644
index 0000000..5f84a4e
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/InsertEntity.js
@@ -0,0 +1,4 @@
+({
+	insertEntity: "Simge Ekle"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/LocalImage.js b/dojox/editor/plugins/nls/tr/LocalImage.js
new file mode 100644
index 0000000..a9c3259
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/LocalImage.js
@@ -0,0 +1,11 @@
+({
+	insertImageTitle: "Resim Ekle",
+	url: "Resim",
+	browse: "Göz at...",
+	text: "Açıklama",
+	set: "Ekle",
+	invalidMessage: "Geçersiz resim dosyası tipi",
+	prePopuTextUrl: "Bir resim URL'si girin",
+	prePopuTextBrowse: " ya da yerel bir dosyaya göz atın."
+})
+
diff --git a/dojox/editor/plugins/nls/tr/PageBreak.js b/dojox/editor/plugins/nls/tr/PageBreak.js
new file mode 100644
index 0000000..a12bd1d
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/PageBreak.js
@@ -0,0 +1,4 @@
+({
+	"pageBreak": "Sayfa Sonu"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/PasteFromWord.js b/dojox/editor/plugins/nls/tr/PasteFromWord.js
new file mode 100644
index 0000000..8d0fccd
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/PasteFromWord.js
@@ -0,0 +1,7 @@
+({
+	"pasteFromWord": "Word'den Kopyala",
+	"paste": "Yapıştır",
+	"cancel": "İptal",
+	"instructions": "İçeriği Word'den aşağıdaki metin kutusuna yapıştırın. Eklediğiniz içerikten memnunsanız, Yapıştır düğmesini tıklatın. Metin eklemeyi durdurmak için İptal düğmesini tıklatın."
+})
+
diff --git a/dojox/editor/plugins/nls/tr/Preview.js b/dojox/editor/plugins/nls/tr/Preview.js
new file mode 100644
index 0000000..fca84e7
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/Preview.js
@@ -0,0 +1,4 @@
+({
+	"preview": "Önizleme"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/Save.js b/dojox/editor/plugins/nls/tr/Save.js
new file mode 100644
index 0000000..87cd5bd
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/Save.js
@@ -0,0 +1,4 @@
+({
+	"save": "Kaydet"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/ShowBlockNodes.js b/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
new file mode 100644
index 0000000..6ea4456
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/ShowBlockNodes.js
@@ -0,0 +1,4 @@
+({
+	"showBlockNodes": "HTML Bloğu Öğelerini Göster"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/Smiley.js b/dojox/editor/plugins/nls/tr/Smiley.js
new file mode 100644
index 0000000..a44be6f
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/Smiley.js
@@ -0,0 +1,22 @@
+({
+	smiley: "İfade Ekle",
+	emoticonSmile: "gülümseme",
+	emoticonLaughing: "kahkaha",
+	emoticonWink: "göz kırpma",
+	emoticonGrin: "sırıtma",
+	emoticonCool: "havalı",
+	emoticonAngry: "kızgın",
+	emoticonHalf: "kafası karışık ifade",
+	emoticonEyebrow: "kaşı kalkık ifade",
+	emoticonFrown: "kaşı çatık ifade",
+	emoticonShy: "utangaç",
+	emoticonGoofy: "ağzı açık ifade",
+	emoticonOops: "şaşıran ifade",
+	emoticonTongue: "dil çıkaran ifade",
+	emoticonIdea: "aklına bir fikir gelmiş",
+	emoticonYes: "evet",
+	emoticonNo: "hayır",
+	emoticonAngel: "melek",
+	emoticonCrying: "ağlayan ifade"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/SpellCheck.js b/dojox/editor/plugins/nls/tr/SpellCheck.js
new file mode 100644
index 0000000..3f8a548
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/SpellCheck.js
@@ -0,0 +1,17 @@
+({
+	widgetLabel: "Toplu Yazım Denetimi",
+	unfound: "Bulunamadı",
+	skip: "Atla",
+	skipAll: "Tümünü Atla",
+	toDic: "Sözlüğe ekle",
+	suggestions: "Öneriler",
+	replace: "Değiştir",
+	replaceWith: "Şununla Değiştir",
+	replaceAll: "Tümünü Değiştir",
+	cancel: "İptal",
+	msg: "Yazım hatası bulunamadı",
+	iSkip: "Bunu atla",
+	iSkipAll: "Buna benzeyenlerin tümünü atla",
+	iMsg: "Yazım önerisi yok"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/TableDialog.js b/dojox/editor/plugins/nls/tr/TableDialog.js
index 9df7cce..d79d3de 100644
--- a/dojox/editor/plugins/nls/tr/TableDialog.js
+++ b/dojox/editor/plugins/nls/tr/TableDialog.js
@@ -8,7 +8,7 @@
 	cellSpacing: "Hücre Aralığı:",
 	tableWidth: "Tablo Genişliği",
 	backgroundColor: "Arka Plan Rengi:",
-	borderColor: "Kenarlık Rengi: ",
+	borderColor: "Kenarlık Rengi:",
 	borderThickness: "Kenarlık Kalınlığı",
 	percent: "yüzde",
 	pixels: "piksel",
@@ -18,6 +18,7 @@
 	right: "sağ",
 	buttonSet: "Ayarla", // translated elsewhere?
 	buttonInsert: "Ekle",
+	buttonCancel: "İptal",
 
 	selectTableLabel: "Tablo Seç",
 	insertTableRowBeforeLabel: "Satırı Önüne Ekle",
diff --git a/dojox/editor/plugins/nls/tr/TextColor.js b/dojox/editor/plugins/nls/tr/TextColor.js
new file mode 100644
index 0000000..6e866b7
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/TextColor.js
@@ -0,0 +1,5 @@
+({
+	"setButtonText": "Ayarla",
+	"cancelButtonText": "İptal"
+})
+
diff --git a/dojox/editor/plugins/nls/tr/latinEntities.js b/dojox/editor/plugins/nls/tr/latinEntities.js
new file mode 100644
index 0000000..cec77b2
--- /dev/null
+++ b/dojox/editor/plugins/nls/tr/latinEntities.js
@@ -0,0 +1,257 @@
+({
+	/* 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:"ters ünlem işareti",
+	cent:"sent işareti",
+	pound:"sterlin işareti",
+	curren:"döviz işareti",
+	yen:"yen işareti\nyuan işareti",
+	brvbar:"kesik çubuk\nkesik çubuk",
+	sect:"bölüm işareti",
+	uml:"umlaut işareti\naralıklı umlaut işareti",
+	copy:"telif hakkı işareti",
+	ordf:"dişi sıra göstergesi",
+	laquo:"sol açılı çift tırnak işareti\nleft pointing guillemet",
+	not:"değil işareti",
+	shy:"koşullu kesme işareti\nisteğe bağlı kesme işareti",
+	reg:"tescil işareti\ntescilli ticari marka işareti",
+	macr:"uzatma işareti\naralıklı uzatma işareti\nüst çizgi\nAPL üstçizgisi",
+	deg:"derece işareti",
+	plusmn:"artı-eksi işareti\nartı-veya-eksi işareti",
+	sup2:"üst simge iki\nüst simge iki rakamı\nkare işareti",
+	sup3:"üst simge üç\nüst simge üç rakamı\nküp işareti",
+	acute:"tiz aksan işareti\naralıklı aksan",
+	micro:"mikro işareti",
+	para:"pilcrow işareti\nparagraf işareti",
+	middot:"orta nokta\nGeorgian comma\nGreek middle dot",
+	cedil:"çengel\naralıklı çengel",
+	sup1:"üst simge bir\nüst simge bir rakamı",
+	ordm:"erkek sıra göstergesi",
+	raquo:"sağ açılı çift tırnak işareti\nright pointing guillemet",
+	frac14:"dörtte birlik bayağı kesir\ndörtte birlik kesir",
+	frac12:"bir bölü ikilik bayağı kesir\nbir bölü ikilik kesir",
+	frac34:"dörtte üçlük bayağı kesir\ndörtte üçlük kesir",
+	iquest:"ters soru işareti\ndönmüş soru işareti",
+	Agrave:"Aksan imiyle Latince büyük harf A\nLatince büyük harf A aksanlı",
+	Aacute:"Vurgu imiyle Latince büyük harf A",
+	Acirc:"İnceltme imiyle Latince büyük harf A",
+	Atilde:"Tilde imiyle Latince büyük harf A",
+	Auml:"Umlaut imiyle Latince büyük harf A",
+	Aring:"Üstte halka imiyle Latince büyük harf A\nLatince büyük harf A halkalı",
+	AElig:"Latince büyük harf AE\nLatin büyük birleştirmeli yazım AE",
+	Ccedil:"Çengel imiyle Latince büyük harf C",
+	Egrave:"Aksan imiyle Latince büyük harf E",
+	Eacute:"Vurgu imiyle Latince büyük harf E",
+	Ecirc:"İnceltme imiyle Latince büyük harf E",
+	Euml:"Umlaut imiyle Latince büyük harf E",
+	Igrave:"Aksan imiyle Latince büyük harf I",
+	Iacute:"Vurgu imiyle Latince büyük harf I",
+	Icirc:"İnceltme imiyle Latince büyük harf I",
+	Iuml:"Umlaut imiyle Latince büyük harf I",
+	ETH:"Latince büyük harf ETH",
+	Ntilde:"Tilde imiyle Latince büyük harf N",
+	Ograve:"Aksan imiyle Latince büyük harf O",
+	Oacute:"Vurgu imiyle Latince büyük harf O",
+	Ocirc:"İnceltme imiyle Latince büyük harf O",
+	Otilde:"Tilde imiyle Latince büyük harf O",
+	Ouml:"Umlaut imiyle Latince büyük harf O",
+	times:"çarpma işareti",
+	Oslash:"Bölü işaretiyle Latince büyük harf O\ntaksim işaretiyle Latince büyük harf O",
+	Ugrave:"Aksan imiyle Latince büyük harf U",
+	Uacute:"Vurgu imiyle Latince büyük harf U",
+	Ucirc:"İnceltme imiyle Latince büyük harf U",
+	Uuml:"Umlaut işaretiyle Latince büyük harf U",
+	Yacute:"Vurgu imiyle Latince büyük harf Y",
+	THORN:"Latince büyük harf THORN",
+	szlig:"Latince küçük harf sert s\ness-zed",
+	agrave:"Aksan imiyle Latince küçük harf a\nLatince küçük harf a aksanlı",
+	aacute:"Vurgu imiyle Latince küçük harf a",
+	acirc:"İnceltme imiyle Latince küçük harf a",
+	atilde:"Tilde imiyle Latince küçük harf a",
+	auml:"Umlaut imiyle Latince küçük harf a",
+	aring:"Üstte halka imiyle Latince küçük harf a\nLatince küçük harf a halkalı",
+	aelig:"Latince küçük harf ae\nLatince küçük birleştirmeli yazım ae",
+	ccedil:"Çengel imiyle Latince küçük harf c",
+	egrave:"Aksan imiyle Latince küçük harf e",
+	eacute:"Vurgu imiyle Latince küçük harf e",
+	ecirc:"İnceltme imiyle Latince küçük harf e",
+	euml:"Umlaut imiyle Latince küçük harf e",
+	igrave:"Aksan imiyle Latince küçük harf i",
+	iacute:"Vurgu imiyle Latince küçük harf i",
+	icirc:"İnceltme imiyle Latince küçük harf i",
+	iuml:"Umlaut imiyle Latince küçük harf i",
+	eth:"Latince küçük harf eth",
+	ntilde:"Tilde imiyle Latince küçük harf n",
+	ograve:"Aksan imiyle Latince küçük harf o",
+	oacute:"Vurgu imiyle Latince küçük harf o",
+	ocirc:"İnceltme imiyle Latince küçük harf o",
+	otilde:"Tilde imiyle Latince küçük harf o",
+	ouml:"Umlaut imiyle Latince küçük harf o",
+	divide:"bölü işareti",
+	oslash:"Bölü işaretiyle Latince küçük harf o\ntaksim işaretiyle Latince küçük harf o",
+	ugrave:"Aksan imiyle Latice küçük harf u",
+	uacute:"Vurgu imiyle Latince küçük harf u",
+	ucirc:"İnceltme imiyle Latince küçük harf u",
+	uuml:"Umlaut imiyle Latince küçük harf u",
+	yacute:"Vurgu imiyle Latince küçük harf y",
+	thorn:"Latince küçük harf thorn",
+	yuml:"Umlaut imiyle Latince küçük harf y",
+
+// Greek Characters and Symbols
+	fnof:"Kanca imiyle Latince küçük f\nfonksiyon\nflorin",
+	Alpha:"Yunanca büyük harf alpha",
+	Beta:"Yunanca büyük harf beta",
+	Gamma:"Yunanca büyük harf gamma",
+	Delta:"Yunanca büyük harf delta",
+	Epsilon:"Yunanca büyük harf epsilon",
+	Zeta:"Yunanca büyük harf zeta",
+	Eta:"Yunanca büyük harf eta",
+	Theta:"Yunanca büyük harf theta",
+	Iota:"Yunanca büyük harf iota",
+	Kappa:"Yunanca büyük harf kappa",
+	Lambda:"Yunanca büyük harf lambda",
+	Mu:"Yunanca büyük harf mu",
+	Nu:"Yunanca büyük harf nu",
+	Xi:"Yunanca büyük harf xi",
+	Omicron:"Yunanca büyük harf omicron",
+	Pi:"Yunanca büyük harf pi",
+	Rho:"Yunanca büyük harf rho",
+	Sigma:"Yunanca büyük harf sigma",
+	Tau:"Yunanca büyük harf tau",
+	Upsilon:"Yunanca büyük harf upsilon",
+	Phi:"Yunanca büyük harf phi",
+	Chi:"Yunanca büyük harf chi",
+	Psi:"Yunanca büyük harf psi",
+	Omega:"Yunanca büyük harf omega",
+	alpha:"Yunanca küçük harf alpha",
+	beta:"Yunanca küçük harf beta",
+	gamma:"Yunanca küçük harf gamma",
+	delta:"Yunanca küçük harf delta",
+	epsilon:"Yunanca küçük harf epsilon",
+	zeta:"Yunanca küçük harf zeta",
+	eta:"Yunanca küçük harf eta",
+	theta:"Yunanca küçük harf theta",
+	iota:"Yunanca küçük harf iota",
+	kappa:"Yunanca küçük harf kappa",
+	lambda:"Yunanca küçük harf lambda",
+	mu:"Yunanca küçük harf mu",
+	nu:"Yunanca küçük harf nu",
+	xi:"Yunanca küçük harf xi",
+	omicron:"Yunanca küçük harf omicron",
+	pi:"Yunanca küçük harf pi",
+	rho:"Yunanca küçük harf rho",
+	sigmaf:"Yunanca küçük harf final",
+	sigma:"Yunanca küçük harf final",
+	tau:"Yunanca küçük harf tau",
+	upsilon:"Yunanca küçük harf final",
+	phi:"Yunanca küçük harf phi",
+	chi:"Yunanca küçük harf final",
+	psi:"Yunanca küçük harf psi",
+	omega:"Yunanca küçük harf final",
+	thetasym:"Yunanca küçük harf theta",
+	upsih:"Kanca işaretiyle Yunanca upsilon",
+	piv:"Yunanca pi işareti",
+	bull:"madde imi\nsiyah küçük daire",
+	hellip:"yanyana üç nokta\nüç nokta",
+	prime:"üssü\ndakika\nfit",
+	Prime:"üssü iki\nsaniye\ninç",
+	oline:"üstçizgi\naralıklı üstçizgi",
+	frasl:"bölme işaretli kesir",
+	weierp:"el yazısı büyük harf P\nkuvvet kümesi\nWeierstrass p",
+	image:"Gotik büyük harf I\nsanal kısım",
+	real:"Gotik büyük harf R\ngerçek kısım işareti",
+	trade:"ticari marka işareti",
+	alefsym:"alef işareti\nbirinci sonsuz sayma sayısı",
+	larr:"sol ok işareti",
+	uarr:"yukarı ok işareti",
+	rarr:"sağ ol işareti",
+	darr:"aşağı ok işareti",
+	harr:"sol sağ ok",
+	crarr:"sola dönen aşağı ok\nsatır başı karakteri",
+	lArr:"sola çift ok",
+	uArr:"yukarı çift ok",
+	rArr:"sağa çift ok",
+	dArr:"aşağı çift ok",
+	hArr:"sola sağa çift ok",
+	forall:"for all",
+	part:"kısmi türev",
+	exist:"vardır",
+	empty:"boş küme\nboş küme\nçap",
+	nabla:"nabla\ngeriye doğru fark",
+	isin:"elemanıdır",
+	notin:"elemanı değildir",
+	ni:"kapsar",
+	prod:"n-ary çarpım\çarpım işareti",
+	sum:"n-ary toplamı",
+	minus:"eksi işareti",
+	lowast:"asterisk işleci",
+	radic:"kare kök\nkök işareti",
+	prop:"orantılı",
+	infin:"sonsuzluk",
+	ang:"açı",
+	and:"mantıklı ve\nwedge",
+	or:"mantıklı veya\nvee",
+	cap:"arakesit\ncap",
+	cup:"birleşim\ncup","int":"integral",
+	there4:"bu nedenle",
+	sim:"tilde işleci\ndeğişir\nbenzer",
+	cong:"yaklaşık olarak eşit",
+	asymp:"neredeyse eşit\nkavuşmaz",
+	ne:"eşit değil",
+	equiv:"aynı",
+	le:"daha küçük ya da eşit",
+	ge:"daha büyük ya da eşit",
+	sub:"alt kümesi",
+	sup:"üst kümesi",
+	nsub:"alt kümesi değil",
+	sube:"alt kümesi ya da eşit",
+	supe:"üst kümesi ya da eşit",
+	oplus:"daire içinde artı\ndolaysız toplam",
+	otimes:"daire içinde çarpı\nvektörel çarpım",
+	perp:"up tack\ndik\ndikey",
+	sdot:"nokta işleci",
+	lceil:"left ceiling\nAPL upstile",
+	rceil:"right ceiling",
+	lfloor:"left floor\nAPL downstile",
+	rfloor:"right floor",
+	lang:"sol açılı ayraç",
+	rang:"sağ açılı ayraç",
+	loz:"baklava biçimi",
+	spades:"siyah maça işareti",
+	clubs:"siyah sinek işareti\nyonca",
+	hearts:"siyah kupa işareti\nkalp",
+	diams:"siyah karo işareti",
+	OElig:"Latince büyük birleşik harf OE",
+	oelig:"Latince küçük birleşik harf oe",
+	Scaron:"Karon imiyle Latince büyük harf S",
+	scaron:"Karon imiyle Latince küçük harf s",
+	Yuml:"Umlaut imiyle Latince büyük harf Y",
+	circ:"niteleyici harf inceltme vurgusu",
+	tilde:"küçük tilde",
+	ensp:"kısa boşluk",
+	emsp:"uzun boşluk",
+	thinsp:"ince boşluk",
+	zwnj:"sıfır genişlik ayırıcı",
+	zwj:"sıfır genişlik birleştirici",
+	lrm:"soldan sağa işareti",
+	rlm:"sağdan sola işareti",
+	ndash:"tire",
+	mdash:"uzun tire",
+	lsquo:"sol tek tırnak işareti",
+	rsquo:"sağ tek tırnak işareti",
+	sbquo:"9 biçimli alçak tek tırnak işareti",
+	ldquo:"sol çift tırnak işareti",
+	rdquo:"sağ çift tırnak işareti",
+	bdquo:"9 biçimli alçak çift tırnak işareti",
+	dagger:"kama",
+	Dagger:"çift kama",
+	permil:"binde işareti",
+	lsaquo:"sol açılı tek tırnak işareti",
+	rsaquo:"sağ açılı tek tırnak işareti",
+	euro:"euro işareti"
+})
+
diff --git a/dojox/editor/plugins/nls/zh-tw/AutoSave.js b/dojox/editor/plugins/nls/zh-tw/AutoSave.js
new file mode 100644
index 0000000..9490fd5
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/AutoSave.js
@@ -0,0 +1,13 @@
+({
+	"saveLabel": "儲存",
+	"saveSettingLabelOn": "設定自動儲存間隔...",
+	"saveSettingLabelOff": "關閉自動儲存",
+	"saveSettingdialogTitle": "自動儲存",
+	"saveSettingdialogDescription": "指定自動儲存間隔",
+	"saveSettingdialogParamName": "自動儲存間隔",
+	"saveSettingdialogParamLabel": "分鐘",
+	"saveSettingdialogButtonOk": "設定間隔",
+	"saveSettingdialogButtonCancel": "取消",
+	"saveMessageSuccess": "已儲存於 ${0}",
+	"saveMessageFail": "無法儲存於 ${0}"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/Blockquote.js b/dojox/editor/plugins/nls/zh-tw/Blockquote.js
new file mode 100644
index 0000000..d83daa5
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/Blockquote.js
@@ -0,0 +1,3 @@
+({
+	"blockquote": "區塊引文"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js b/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
new file mode 100644
index 0000000..affd4bd
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/CollapsibleToolbar.js
@@ -0,0 +1,4 @@
+({
+	"collapse": "收合編輯器工具列",
+	"expand": "展開編輯器工具列"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/FindReplace.js b/dojox/editor/plugins/nls/zh-tw/FindReplace.js
index a47f3bd..c78b0de 100644
--- a/dojox/editor/plugins/nls/zh-tw/FindReplace.js
+++ b/dojox/editor/plugins/nls/zh-tw/FindReplace.js
@@ -1,12 +1,22 @@
 ({
-	"findLabel": "尋找目標:",
+	"findLabel": "尋找:",
+	"findTooltip": "輸入要尋找的文字",
 	"replaceLabel": "取代為:",
-	"findReplace": "切換尋找/取代",
-	"matchCase": "大小寫相符", 
+	"replaceTooltip": "輸入要取代的文字",
+	"findReplace": "尋找/取代",
+	"matchCase": "大小寫相符",
+	"matchCaseTooltip": "大小寫相符",
 	"backwards": "向後",
-	"replaceAll": "所有出現位置", 
+	"backwardsTooltip": "往回搜尋文字",
+	"replaceAll": "所有出現項目",
+	"replaceAllButton": "全部取代",
+	"replaceAllButtonTooltip": "取代所有文字",
 	"findButton": "尋找",
+	"findButtonTooltip": "尋找文字",
 	"replaceButton": "取代",
-	"replaceDialogText": "取代了 ${0} 項。"
+	"replaceButtonTooltip": "取代文字",
+	"replaceDialogText": "取代了 ${0} 項。",
+	"eofDialogText": "前次出現 ${0}",
+	"eofDialogTextFind": "找到",
+	"eofDialogTextReplace": "已取代"
 })
-
diff --git a/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js b/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
new file mode 100644
index 0000000..f104625
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/InsertAnchor.js
@@ -0,0 +1,8 @@
+({
+	insertAnchor: "插入錨點",
+	title: "錨點內容",
+	anchor: "名稱:",
+	text: "說明:",
+	set: "設定",
+	cancel: "取消"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/LocalImage.js b/dojox/editor/plugins/nls/zh-tw/LocalImage.js
new file mode 100644
index 0000000..85fa74f
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/LocalImage.js
@@ -0,0 +1,10 @@
+({
+	insertImageTitle: "插入影像",
+	url: "影像",
+	browse: "瀏覽...",
+	text: "說明",
+	set: "插入",
+	invalidMessage: "影像檔類型無效",
+	prePopuTextUrl: "輸入影像 URL",
+	prePopuTextBrowse: " 或瀏覽本端檔案。"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js b/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
new file mode 100644
index 0000000..ac4c70d
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/PasteFromWord.js
@@ -0,0 +1,6 @@
+({
+	"pasteFromWord": "從 Word 貼上",
+	"paste": "貼上",
+	"cancel": "取消",
+	"instructions": "將 Word 中的內容貼入下方的文字框。在滿意要插入的內容之後,請按貼上按鈕。若要中斷插入文字,請按取消按鈕。"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/Smiley.js b/dojox/editor/plugins/nls/zh-tw/Smiley.js
index 07d3f50..dabf814 100644
--- a/dojox/editor/plugins/nls/zh-tw/Smiley.js
+++ b/dojox/editor/plugins/nls/zh-tw/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "眨眼",
 	emoticonGrin: "露齒而笑",
 	emoticonCool: "酷",
-	emoticonAngry: "生氣",  
-	emoticonHalf: "左右為難", 
+	emoticonAngry: "生氣",
+	emoticonHalf: "左右為難",
 	emoticonEyebrow: "揚眉",
 	emoticonFrown: "皺眉",
 	emoticonShy: "羞怯",
@@ -15,7 +15,7 @@
 	emoticonTongue: "吐舌頭",
 	emoticonIdea: "思考",
 	emoticonYes: "對",
-	emoticonNo: "不對",	
+	emoticonNo: "不對",
 	emoticonAngel: "守護神",
 	emoticonCrying: "哭泣"
 })
diff --git a/dojox/editor/plugins/nls/zh-tw/SpellCheck.js b/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
new file mode 100644
index 0000000..6376a00
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/SpellCheck.js
@@ -0,0 +1,16 @@
+({
+	widgetLabel: "批次拼字檢查",
+	unfound: "找不到",
+	skip: "跳過",
+	skipAll: "全部跳過",
+	toDic: "新增至字典",
+	suggestions: "建議",
+	replace: "取代",
+	replaceWith: "取代為",
+	replaceAll: "全部取代",
+	cancel: "取消",
+	msg: "找不到拼錯",
+	iSkip: "跳過此項",
+	iSkipAll: "跳過所有如此項的項目",
+	iMsg: "沒有拼字建議"
+})
diff --git a/dojox/editor/plugins/nls/zh-tw/TableDialog.js b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
index 561d6df..fd07f14 100644
--- a/dojox/editor/plugins/nls/zh-tw/TableDialog.js
+++ b/dojox/editor/plugins/nls/zh-tw/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "靠右",
 	buttonSet: "設定", // translated elsewhere?
 	buttonInsert: "插入",
+	buttonCancel: "取消",
 
 	selectTableLabel: "選取表格",
 	insertTableRowBeforeLabel: "在前面新增一個列",
diff --git a/dojox/editor/plugins/nls/zh-tw/TextColor.js b/dojox/editor/plugins/nls/zh-tw/TextColor.js
new file mode 100644
index 0000000..56c66f4
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh-tw/TextColor.js
@@ -0,0 +1,4 @@
+({
+	"setButtonText": "設定",
+	"cancelButtonText": "取消"
+})
diff --git a/dojox/editor/plugins/nls/zh/AutoSave.js b/dojox/editor/plugins/nls/zh/AutoSave.js
new file mode 100644
index 0000000..70cfc0d
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/AutoSave.js
@@ -0,0 +1,13 @@
+({
+	"saveLabel": "保存",
+	"saveSettingLabelOn": "设置自动保存时间间隔...",
+	"saveSettingLabelOff": "关闭自动保存",
+	"saveSettingdialogTitle": "自动保存",
+	"saveSettingdialogDescription": "指定自动保存时间间隔",
+	"saveSettingdialogParamName": "自动保存时间间隔",
+	"saveSettingdialogParamLabel": "分钟",
+	"saveSettingdialogButtonOk": "设置时间间隔",
+	"saveSettingdialogButtonCancel": "取消",
+	"saveMessageSuccess": "已保存到 ${0}",
+	"saveMessageFail": "未能保存到 ${0}"
+})
diff --git a/dojox/editor/plugins/nls/zh/Blockquote.js b/dojox/editor/plugins/nls/zh/Blockquote.js
new file mode 100644
index 0000000..0439fbc
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/Blockquote.js
@@ -0,0 +1,3 @@
+({
+	"blockquote": "块引用"
+})
diff --git a/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js b/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
new file mode 100644
index 0000000..6515c53
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/CollapsibleToolbar.js
@@ -0,0 +1,4 @@
+({
+	"collapse": "折叠编辑器工具栏",
+	"expand": "展开编辑器工具栏"
+})
diff --git a/dojox/editor/plugins/nls/zh/FindReplace.js b/dojox/editor/plugins/nls/zh/FindReplace.js
index 21bdd40..fc7418d 100644
--- a/dojox/editor/plugins/nls/zh/FindReplace.js
+++ b/dojox/editor/plugins/nls/zh/FindReplace.js
@@ -1,22 +1,22 @@
 ({
-	"findLabel": "查找对象:",
-	"findTooltip": "输入查找文本",
+	"findLabel": "查找:",
+	"findTooltip": "输入要查找的文本",
 	"replaceLabel": "替换为:",
-	"replaceTooltip": "输入替换文本",
-	"findReplace": "切换“查找/替换”",
-	"matchCase": "大小写匹配",
+	"replaceTooltip": "输入要替换成的文本",
+	"findReplace": "查找和替换",
+	"matchCase": "匹配大小写",
 	"matchCaseTooltip": "匹配大小写",
-	"backwards": "向后查找",
-	"backwardsTooltip": "向后查找文本",
+	"backwards": "向后",
+	"backwardsTooltip": "向后搜索文本",
+	"replaceAll": "所有匹配项",
 	"replaceAllButton": "全部替换",
-	"replaceAllButtonTooltip": "替换所有出现位置",
+	"replaceAllButtonTooltip": "替换所有文本",
 	"findButton": "查找",
-	"findButtonTooltip": "查找该文本",
+	"findButtonTooltip": "查找文本",
 	"replaceButton": "替换",
-	"replaceButtonTooltip": "替换该文本",
-	"replaceDialogText": "已替换 ${0} 个出现位置",
-	"eofDialogText": "已完成最后一次${0}",
-	"eofDialogTextFind": "查找",
-	"eofDialogTextReplace": "替换"
+	"replaceButtonTooltip": "替换文本",
+	"replaceDialogText": "已替换 ${0} 个匹配项",
+	"eofDialogText": "最后一个匹配项 ${0}",
+	"eofDialogTextFind": "已找到",
+	"eofDialogTextReplace": "已替换"
 })
-
diff --git a/dojox/editor/plugins/nls/zh/InsertAnchor.js b/dojox/editor/plugins/nls/zh/InsertAnchor.js
new file mode 100644
index 0000000..269b334
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/InsertAnchor.js
@@ -0,0 +1,8 @@
+({
+	insertAnchor: "插入锚点",
+	title: "锚点属性",
+	anchor: "名称:",
+	text: "描述:",
+	set: "设置",
+	cancel: "取消"
+})
diff --git a/dojox/editor/plugins/nls/zh/LocalImage.js b/dojox/editor/plugins/nls/zh/LocalImage.js
new file mode 100644
index 0000000..c06e1ab
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/LocalImage.js
@@ -0,0 +1,10 @@
+({
+	insertImageTitle: "插入图像",
+	url: "图像",
+	browse: "浏览...",
+	text: "描述",
+	set: "插入",
+	invalidMessage: "无效的图像文件类型",
+	prePopuTextUrl: "输入图像 URL",
+	prePopuTextBrowse: "或浏览本地文件。"
+})
diff --git a/dojox/editor/plugins/nls/zh/PasteFromWord.js b/dojox/editor/plugins/nls/zh/PasteFromWord.js
new file mode 100644
index 0000000..8d0b634
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/PasteFromWord.js
@@ -0,0 +1,6 @@
+({
+	"pasteFromWord": "从 Word 中粘贴",
+	"paste": "粘贴",
+	"cancel": "取消",
+	"instructions": "将内容从 Word 粘贴到以下文本框。如果对插入的内容满意,请按“粘贴”按钮。要停止插入文本,请按“取消”按钮。"
+})
diff --git a/dojox/editor/plugins/nls/zh/Smiley.js b/dojox/editor/plugins/nls/zh/Smiley.js
index 1c68e64..3bf6ab7 100644
--- a/dojox/editor/plugins/nls/zh/Smiley.js
+++ b/dojox/editor/plugins/nls/zh/Smiley.js
@@ -5,8 +5,8 @@
 	emoticonWink: "眨眼",
 	emoticonGrin: "咧着嘴笑",
 	emoticonCool: "酷",
-	emoticonAngry: "愤怒",  
-	emoticonHalf: "左右为难", 
+	emoticonAngry: "愤怒",
+	emoticonHalf: "左右为难",
 	emoticonEyebrow: "挑眉",
 	emoticonFrown: "皱眉",
 	emoticonShy: "害羞",
@@ -15,7 +15,7 @@
 	emoticonTongue: "吐舌",
 	emoticonIdea: "思考",
 	emoticonYes: "点头",
-	emoticonNo: "摇头",	
+	emoticonNo: "摇头",
 	emoticonAngel: "天使",
 	emoticonCrying: "哭泣"
 })
diff --git a/dojox/editor/plugins/nls/zh/SpellCheck.js b/dojox/editor/plugins/nls/zh/SpellCheck.js
new file mode 100644
index 0000000..6700857
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/SpellCheck.js
@@ -0,0 +1,16 @@
+({
+	widgetLabel: "批处理拼写检查",
+	unfound: "未找到",
+	skip: "跳过",
+	skipAll: "全部跳过",
+	toDic: "添加到字典",
+	suggestions: "建议",
+	replace: "替换",
+	replaceWith: "替换为",
+	replaceAll: "全部替换",
+	cancel: "取消",
+	msg: "未找到拼写错误",
+	iSkip: "跳过此处",
+	iSkipAll: "跳过所有与此处相同的地方",
+	iMsg: "没有拼写建议"
+})
diff --git a/dojox/editor/plugins/nls/zh/TableDialog.js b/dojox/editor/plugins/nls/zh/TableDialog.js
index 0debf15..9ed06d4 100644
--- a/dojox/editor/plugins/nls/zh/TableDialog.js
+++ b/dojox/editor/plugins/nls/zh/TableDialog.js
@@ -18,6 +18,7 @@
 	right: "右边对齐",
 	buttonSet: "设置", // translated elsewhere?
 	buttonInsert: "插入",
+	buttonCancel: "取消",
 
 	selectTableLabel: "选择表",
 	insertTableRowBeforeLabel: "在之前添加行",
diff --git a/dojox/editor/plugins/nls/zh/TextColor.js b/dojox/editor/plugins/nls/zh/TextColor.js
new file mode 100644
index 0000000..1b3f283
--- /dev/null
+++ b/dojox/editor/plugins/nls/zh/TextColor.js
@@ -0,0 +1,4 @@
+({
+	"setButtonText": "设置",
+	"cancelButtonText": "取消"
+})
diff --git a/dojox/editor/plugins/nls/zh/latinEntities.js b/dojox/editor/plugins/nls/zh/latinEntities.js
index c1ad103..e2382e9 100644
--- a/dojox/editor/plugins/nls/zh/latinEntities.js
+++ b/dojox/editor/plugins/nls/zh/latinEntities.js
@@ -103,55 +103,55 @@
 
 // Greek Characters and Symbols
 	fnof:"带挂钩符号的拉丁小写 f\n分数\nflorin",
-	Alpha:"希腊大写字母 Α",
-	Beta:"希腊大写字母 Β",
-	Gamma:"希腊大写字母 Γ",
-	Delta:"希腊大写字母 Δ",
-	Epsilon:"希腊大写字母 Ε",
-	Zeta:"希腊大写字母 Ζ",
-	Eta:"希腊大写字母 Η",
-	Theta:"希腊大写字母 Θ",
-	Iota:"希腊大写字母 Ι",
-	Kappa:"希腊大写字母 Κ",
-	Lambda:"希腊大写字母 Λ",
-	Mu:"希腊大写字母 Μ",
-	Nu:"希腊大写字母 Ν",
-	Xi:"希腊大写字母 Ξ",
-	Omicron:"希腊大写字母 Ο",
-	Pi:"希腊大写字母 Π",
-	Rho:"希腊大写字母 Ρ",
-	Sigma:"希腊大写字母 Σ",
-	Tau:"希腊大写字母 Τ",
-	Upsilon:"希腊大写字母 Υ",
-	Phi:"希腊大写字母 Φ",
-	Chi:"希腊大写字母 Χ",
-	Psi:"希腊大写字母 Ψ",
-	Omega:"希腊大写字母 Ω",
-	alpha:"希腊小写字母 α",
-	beta:"希腊小写字母 β",
-	gamma:"希腊小写字母 γ",
-	delta:"希腊小写字母 δ",
-	epsilon:"希腊小写字母 ε",
-	zeta:"希腊小写字母 ζ",
-	eta:"希腊小写字母 η",
-	theta:"希腊小写字母 θ",
-	iota:"希腊小写字母 ι",
-	kappa:"希腊小写字母 κ",
-	lambda:"希腊小写字母 λ",
-	mu:"希腊小写字母 μ",
-	nu:"希腊小写字母 ν",
-	xi:"希腊小写字母 ξ",
-	omicron:"希腊小写字母 ο",
-	pi:"希腊小写字母 π",
-	rho:"希腊小写字母 ρ",
+	Alpha:"希腊大写字母 alpha",
+	Beta:"希腊大写字母 beta",
+	Gamma:"希腊大写字母 gamma",
+	Delta:"希腊大写字母 delta",
+	Epsilon:"希腊大写字母 epsilon",
+	Zeta:"希腊大写字母 zeta",
+	Eta:"希腊大写字母 eta",
+	Theta:"希腊大写字母 theta",
+	Iota:"希腊大写字母 iota",
+	Kappa:"希腊大写字母 kappa",
+	Lambda:"希腊大写字母 lambda",
+	Mu:"希腊大写字母 mu",
+	Nu:"希腊大写字母 nu",
+	Xi:"希腊大写字母 xi",
+	Omicron:"希腊大写字母 omicron",
+	Pi:"希腊大写字母 pi",
+	Rho:"希腊大写字母 rho",
+	Sigma:"希腊大写字母 sigma",
+	Tau:"希腊大写字母 tau",
+	Upsilon:"希腊大写字母 upsilon",
+	Phi:"希腊大写字母 phi",
+	Chi:"希腊大写字母 chi",
+	Psi:"希腊大写字母 psi",
+	Omega:"希腊大写字母 omega",
+	alpha:"希腊小写字母 alpha",
+	beta:"希腊小写字母 beta",
+	gamma:"希腊小写字母 gamma",
+	delta:"希腊小写字母 delta",
+	epsilon:"希腊小写字母 epsilon",
+	zeta:"希腊小写字母 zeta",
+	eta:"希腊小写字母 eta",
+	theta:"希腊小写字母 theta",
+	iota:"希腊小写字母 iota",
+	kappa:"希腊小写字母 kappa",
+	lambda:"希腊小写字母 lambda",
+	mu:"希腊小写字母 mu",
+	nu:"希腊小写字母 nu",
+	xi:"希腊小写字母 xi",
+	omicron:"希腊小写字母 omicron",
+	pi:"希腊小写字母 pi",
+	rho:"希腊小写字母 rho",
 	sigmaf:"希腊小写字母 final sigma",
-	sigma:"希腊小写字母 σ",
-	tau:"希腊小写字母 τ",
-	upsilon:"希腊小写字母 υ",
-	phi:"希腊小写字母 φ",
-	chi:"希腊小写字母 χ",
-	psi:"希腊小写字母 ψ",
-	omega:"希腊小写字母 ω",
+	sigma:"希腊小写字母 sigma",
+	tau:"希腊小写字母 tau",
+	upsilon:"希腊小写字母 upsilon",
+	phi:"希腊小写字母 phi",
+	chi:"希腊小写字母 chi",
+	psi:"希腊小写字母 psi",
+	omega:"希腊小写字母 omega",
 	thetasym:"希腊小写字母 theta 符号",
 	upsih:"带挂钩符号的希腊字母 upsilon",
 	piv:"希腊 pi 符号",
@@ -214,10 +214,10 @@
 	otimes:"带圆圈的乘号\n向量积",
 	perp:"倒 T\n正交于\n垂直",
 	sdot:"点运算符",
-	lceil:"左上限\nAPL 顶",
-	rceil:"右上限",
-	lfloor:"左下限\nAPL 底",
-	rfloor:"右下限",
+	lceil:"left ceiling\nAPL upstile",
+	rceil:"right ceiling",
+	lfloor:"left floor\nAPL downstile",
+	rfloor:"right floor",
 	lang:"左尖括号",
 	rang:"右尖括号",
 	loz:"菱形",
@@ -254,4 +254,3 @@
 	rsaquo:"右尖括号",
 	euro:"欧元符号"
 })
-
diff --git a/dojox/editor/plugins/resources/css/AutoSave.css b/dojox/editor/plugins/resources/css/AutoSave.css
new file mode 100644
index 0000000..8bfada2
--- /dev/null
+++ b/dojox/editor/plugins/resources/css/AutoSave.css
@@ -0,0 +1,48 @@
+.dijitEditorIconAutoSave {
+	background-image: url(../icons/autoSave.png);
+	background-repeat: no-repeat;
+	width: 18px;
+	height: 18px;
+}
+
+.dijitEditorIconAutoSaveDefault {
+	background-position: -18px 0px;
+}
+
+.dijitDisabled .dijitEditorIconAutoSaveDefault {
+	background-position: -54px 0px;
+}
+
+.dijitEditorIconAutoSaveSetting {
+	background-position: 0px 0px;
+}
+
+.dijitEditorAutoSaveSettingDialog {
+	width: 21em;
+}
+
+.dijitEditorAutoSaveSettingInputArea {
+	margin-top: 0.3em;
+	margin-left: 2em;
+}
+
+.dijitEditorAutoSaveSettingInputArea .textBox {
+	width: 2em;
+}
+
+.dijitEditorAutoSaveSettingInputArea .boxLabel {
+	margin: 0em 0em 0em 0.3em;
+}
+
+.dijitEditorAutoSaveSettingButtonArea {
+	text-align: right;
+	margin: 0.3em 0em 0em 0em;
+}
+
+.lucid .dijitEditorAutoSaveSettingDialog {
+	width: 22em;
+}
+
+.lucid .dijitEditorAutoSaveSettingInputArea .textBox {
+	width: 2.5em;
+}
diff --git a/dojox/editor/plugins/resources/css/LocalImage.css b/dojox/editor/plugins/resources/css/LocalImage.css
new file mode 100644
index 0000000..3b308af
--- /dev/null
+++ b/dojox/editor/plugins/resources/css/LocalImage.css
@@ -0,0 +1,13 @@
+.dijitEditorEilDialogTitle {
+	font-weight: bold;
+	margin-bottom: 0.6em;
+}
+
+.dijitEditorEilDialogDescription {
+	white-space: normal;
+	margin: 0em 0em 0.3em 0em;
+}
+
+.dijitEditorEilDialogField{
+	width: 20em;
+}
diff --git a/dojox/editor/plugins/resources/css/SpellCheck.css b/dojox/editor/plugins/resources/css/SpellCheck.css
new file mode 100644
index 0000000..434b579
--- /dev/null
+++ b/dojox/editor/plugins/resources/css/SpellCheck.css
@@ -0,0 +1,51 @@
+.dijitEditorSpellCheckIcon {
+	background-image: url(../icons/spellcheck.gif);
+	background-repeat: no-repeat;
+	background-position: center center;
+	width: 18px;
+	height: 18px;
+}
+
+.dijitEditorSpellCheckBusyIcon {
+	background-image: url(../images/checking.gif);
+	background-repeat: no-repeat;
+	background-position: center center;
+	display: inline-block;
+	zoom: 1;
+	*display: inline;
+	width: 16px;
+	height: 16px;
+	margin: 0em 0.5em 0em 0.5em;
+}
+
+.dijitEditorSpellCheckTable .dijitEditorSpellCheckBox {
+	width: 15em;
+}
+
+.dijitEditorSpellCheckTable .listHeight {
+	height: 5em;
+}
+
+.dijitEditorSpellCheckTable,
+.dijitEditorSpellCheckTable td {
+	border: none;
+	border-width: 0px;
+	vertical-align: top;
+}
+
+.dijitEditorSpellCheckTable .alignBottom {
+	vertical-align: bottom;
+}
+
+.dijitEditorSpellCheckTable .blockButton,
+.dijitEditorSpellCheckTable .dijitButtonNode {
+	display: block;
+}
+
+.dijitEditorSpellCheckTable .topMargin {
+	margin-top: 0.56em;
+}
+
+.dijitEditorSpellCheckTable .hidden {
+	display: none;
+}
diff --git a/dojox/editor/plugins/resources/editorPlugins.css b/dojox/editor/plugins/resources/editorPlugins.css
index d8c4661..db2c08a 100644
--- a/dojox/editor/plugins/resources/editorPlugins.css
+++ b/dojox/editor/plugins/resources/editorPlugins.css
@@ -3,34 +3,25 @@
 
 }
 .EditorTableDialog .etdTable{
-	width:350px;
 	border:none;
 	table-layout:fixed;
 	border-collapse:collapse;
 }
 .EditorTableDialog .etdTable td{
-	width:200px;
 	border:#CCCCCC 0px solid;
 	padding:5px;
 }
-.EditorTableDialog .etdTable td.left{
-	width:200px;
-}
-.EditorTableDialog .etdTable td.right{
-	width:150px;
+.EditorTableDialog .etdTable td.inner{
+	padding:0px;
 }
 .EditorTableDialog .dijitTextBox{
 	width:50px;
-	float:right;
 	padding-left:3px;
 }
 .EditorTableDialog .dijitComboBox{
 	width:85px;
 	padding-left:5px;
 }
-.EditorTableDialog .etdTable .floatDijit{
-	float:right;
-}
 .EditorTableDialog label{
 	float:right;
 	margin:0;
@@ -55,7 +46,6 @@
 	width:16px;
 	height:16px;
 	cursor:pointer;
-	float:right;
 }
 .colorSwatchBtn:hover{
 	border:#0099FF 2px solid;
@@ -71,8 +61,8 @@
 .editorIcon{
 	background-image:url(images/tableIcons.png);
 	background-repeat: no-repeat;
-	width: 16px;
-	height: 16px;
+	width: 18px;
+	height: 18px;
 	text-align: center;
 }
 .editorIconUploadImage{
@@ -81,46 +71,47 @@
 
 .editorIconInsertTable{				
 	background-position:0px 0px;	}
-
+.dijitDisabled .editorIconInsertTable{				
+	background-position:-162px 0px;	}
 .editorIconInsertTableRowBefore{ 	
-	background-position:-19px 0px;	}
+	background-position:-36px 0px;	}
 .dijitDisabled .editorIconInsertTableRowBefore{ 	
-	background-position:-120px 0px;	}
+	background-position:-198px 0px;	}
 	
 .editorIconInsertTableRowAfter{ 	
-	background-position:-35px 0px;	}
+	background-position:-54px 0px;	}
 .dijitDisabled .editorIconInsertTableRowAfter{ 	
-	background-position:-136px 0px;	}
+	background-position:-216px 0px;	}
 
 .editorIconInsertTableColumnBefore{ 	
-	background-position:-52px 0px;	}
+	background-position:-72px 0px;	}
 .dijitDisabled .editorIconInsertTableColumnBefore{ 	
-	background-position:-154px 0px;	}
+	background-position:-234px 0px;	}
 	
 .editorIconInsertTableColumnAfter{ 	
-	background-position:-69px 0px;	}
+	background-position:-90px 0px;	}
 .dijitDisabled .editorIconInsertTableColumnAfter{ 	
-	background-position:-171px 0px;	}
+	background-position:-252px 0px;	}
 	
 .editorIconDeleteTableRow{ 	
-	background-position:-86px 0px;	}
+	background-position:-108px 0px;	}
 .dijitDisabled .editorIconDeleteTableRow{ 	
-	background-position:-205px 0px;	}
+	background-position:-270px 0px;	}
 	
 .editorIconDeleteTableColumn{ 	
-	background-position:-103px 0px;	}
+	background-position:-126px 0px;	}
 .dijitDisabled .editorIconDeleteTableColumn{ 	
-	background-position:-188px 0px;	}
+	background-position:-288px 0px;	}
 	
 .editorIconColorTableCell{ 	
-	background-position:-222px 0px;	}
+	background-position:-144px 0px;	}
 .dijitDisabled .editorIconColorTableCell{ 	
-	background-position:-239px 0px;	}
+	background-position:-306px 0px;	}
 
 .editorIconModifyTable{ 	
-	background-position:-256px 0px;	}
+	background-position:-18px 0px;	}
 .dijitDisabled .editorIconModifyTable{ 	
-	background-position:-273px 0px;	}
+	background-position:-180px 0px;	}
 
 
 
diff --git a/dojox/editor/plugins/resources/icons/autoSave.png b/dojox/editor/plugins/resources/icons/autoSave.png
new file mode 100644
index 0000000..c23796f
Binary files /dev/null and b/dojox/editor/plugins/resources/icons/autoSave.png differ
diff --git a/dojox/editor/plugins/resources/icons/spellcheck.gif b/dojox/editor/plugins/resources/icons/spellcheck.gif
new file mode 100755
index 0000000..b0bba18
Binary files /dev/null and b/dojox/editor/plugins/resources/icons/spellcheck.gif differ
diff --git a/dojox/editor/plugins/resources/images/tableIcons.png b/dojox/editor/plugins/resources/images/tableIcons.png
index 898ecd8..fb00763 100644
Binary files a/dojox/editor/plugins/resources/images/tableIcons.png and b/dojox/editor/plugins/resources/images/tableIcons.png differ
diff --git a/dojox/editor/plugins/resources/images/tableIcons_rtl.png b/dojox/editor/plugins/resources/images/tableIcons_rtl.png
new file mode 100644
index 0000000..d78152f
Binary files /dev/null and b/dojox/editor/plugins/resources/images/tableIcons_rtl.png differ
diff --git a/dojox/editor/plugins/resources/insertTable.html b/dojox/editor/plugins/resources/insertTable.html
index 5d4b6b9..da5e9a8 100644
--- a/dojox/editor/plugins/resources/insertTable.html
+++ b/dojox/editor/plugins/resources/insertTable.html
@@ -1,4 +1,4 @@
-<div class="dijitDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+<div class="dijitDialog" tabindex="-1" role="dialog" aria-labelledby="${id}_title">
 	<div dojoAttachPoint="titleBar" class="dijitDialogTitleBar">
 	<span dojoAttachPoint="titleNode" class="dijitDialogTitle" id="${id}_title">${insertTableTitle}</span>
 	<span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="onclick: onCancel" title="${buttonCancel}">
@@ -7,31 +7,38 @@
 	</div>
     <div dojoAttachPoint="containerNode" class="dijitDialogPaneContent">
         <table class="etdTable"><tr>
-            <td class="left">
-                <span dojoAttachPoint="selectRow" dojoType="dijit.form.TextBox" value="2"></span>
+            <td>
                 <label>${rows}</label>
-            </td><td class="right">
-                <span dojoAttachPoint="selectCol" dojoType="dijit.form.TextBox" value="2"></span>
+			</td><td>
+                <span dojoAttachPoint="selectRow" dojoType="dijit.form.TextBox" value="2"></span>
+            </td><td><table><tr><td class="inner">
                 <label>${columns}</label>
-            </td></tr><tr><td>
-                <span dojoAttachPoint="selectWidth" dojoType="dijit.form.TextBox" value="100"></span>
+			</td><td class="inner">
+                <span dojoAttachPoint="selectCol" dojoType="dijit.form.TextBox" value="2"></span>
+            </td></tr></table></td></tr>		
+			<tr><td>
                 <label>${tableWidth}</label>
             </td><td>
+                <span dojoAttachPoint="selectWidth" dojoType="dijit.form.TextBox" value="100"></span>
+			</td><td>
                 <select dojoAttachPoint="selectWidthType" hasDownArrow="true" dojoType="dijit.form.FilteringSelect">
                   <option value="percent">${percent}</option>
                   <option value="pixels">${pixels}</option>
-                </select></td></tr>
-          <tr><td>
-                <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
+                </select></td></tr>	
+            <tr><td>
                 <label>${borderThickness}</label></td>
-            <td>
+            </td><td>
+                <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
+            </td><td>
                 ${pixels}
             </td></tr><tr><td>
-                <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
                 <label>${cellPadding}</label></td>
-            <td class="cellpad"></td></tr><tr><td>
-                <span dojoAttachPoint="selectSpace" dojoType="dijit.form.TextBox" value="0"></span>
+            </td><td>
+                <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
+            </td><td class="cellpad"></td></tr><tr><td>
                 <label>${cellSpacing}</label>
+            </td><td>
+                <span dojoAttachPoint="selectSpace" dojoType="dijit.form.TextBox" value="0"></span>
             </td><td class="cellspace"></td></tr></table>
         <div class="dialogButtonContainer">
             <div dojoType="dijit.form.Button" dojoAttachEvent="onClick: onInsert">${buttonInsert}</div>
diff --git a/dojox/editor/plugins/resources/modifyTable.html b/dojox/editor/plugins/resources/modifyTable.html
index c1b00c6..35232a7 100644
--- a/dojox/editor/plugins/resources/modifyTable.html
+++ b/dojox/editor/plugins/resources/modifyTable.html
@@ -1,4 +1,4 @@
-<div class="dijitDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+<div class="dijitDialog" tabindex="-1" role="dialog" aria-labelledby="${id}_title">
 	<div dojoAttachPoint="titleBar" class="dijitDialogTitleBar">
 	<span dojoAttachPoint="titleNode" class="dijitDialogTitle" id="${id}_title">${modifyTableTitle}</span>
 	<span dojoAttachPoint="closeButtonNode" class="dijitDialogCloseIcon" dojoAttachEvent="onclick: onCancel" title="${buttonCancel}">
@@ -7,39 +7,47 @@
 	</div>
     <div dojoAttachPoint="containerNode" class="dijitDialogPaneContent">
         <table class="etdTable">
-          <tr><td class="left">
-                <span class="colorSwatchBtn" dojoAttachPoint="backgroundCol"></span>
+          <tr><td>
                 <label>${backgroundColor}</label>
-            </td><td class="right">
-                <span class="colorSwatchBtn" dojoAttachPoint="borderCol"></span>
-                <label>${borderColor}</label>
+            </td><td colspan="2">
+                <span class="colorSwatchBtn" dojoAttachPoint="backgroundCol"></span>
             </td></tr><tr><td>
-                <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
-                <label>${borderThickness}</label>
-            </td><td>
-            ${pixels}
+                <label>${borderColor}</label>
+            </td><td colspan="2">
+                <span class="colorSwatchBtn" dojoAttachPoint="borderCol"></span>
             </td></tr><tr><td>
-                <select class="floatDijit" dojoAttachPoint="selectAlign" dojoType="dijit.form.FilteringSelect">
+                <label>${align}</label>
+            </td><td colspan="2">	
+                <select dojoAttachPoint="selectAlign" dojoType="dijit.form.FilteringSelect">
                   <option value="default">${default}</option>
                   <option value="left">${left}</option>
                   <option value="center">${center}</option>
                   <option value="right">${right}</option>
                 </select>
-                <label>${align}</label>
-            </td><td></td></tr><tr><td>
-                <span dojoAttachPoint="selectWidth" dojoType="dijit.form.TextBox" value="100"></span>
+            </td></tr>
+            <tr><td>
                 <label>${tableWidth}</label>
             </td><td>
+                <span dojoAttachPoint="selectWidth" dojoType="dijit.form.TextBox" value="100"></span>
+            </td><td>
                 <select dojoAttachPoint="selectWidthType" hasDownArrow="true" dojoType="dijit.form.FilteringSelect">
                   <option value="percent">${percent}</option>
                   <option value="pixels">${pixels}</option>
-                </select>
-                </td></tr><tr><td>
-                <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
+                </select></td></tr>	
+            <tr><td>
+                <label>${borderThickness}</label></td>
+            </td><td>
+                <span dojoAttachPoint="selectBorder" dojoType="dijit.form.TextBox" value="1"></span>
+            </td><td>
+                ${pixels}
+            </td></tr><tr><td>
                 <label>${cellPadding}</label></td>
-            <td class="cellpad"></td></tr><tr><td>
-                <span dojoAttachPoint="selectSpace" dojoType="dijit.form.TextBox" value="0"></span>
+            </td><td>
+                <span dojoAttachPoint="selectPad" dojoType="dijit.form.TextBox" value="0"></span>
+            </td><td class="cellpad"></td></tr><tr><td>
                 <label>${cellSpacing}</label>
+            </td><td>
+                <span dojoAttachPoint="selectSpace" dojoType="dijit.form.TextBox" value="0"></span>
             </td><td class="cellspace"></td></tr>
         </table>
         <div class="dialogButtonContainer">
diff --git a/dojox/editor/tests/PorterStemmer.php.disabled b/dojox/editor/tests/PorterStemmer.php.disabled
new file mode 100644
index 0000000..86a820d
--- /dev/null
+++ b/dojox/editor/tests/PorterStemmer.php.disabled
@@ -0,0 +1,474 @@
+<?php
+
+   /**
+   *
+   *  Present by Xinhao Chen in Dojo Team, IBM Shanghai
+   *
+   *  Usage: $stem = PorterStemmer::getStem($word);
+   *
+   *  Refrence: "An algorithm for suffix stripping", M.F.Porter, http://tartarus.org/martin/PorterStemmer/def.txt
+   *
+   */
+   
+   class PorterStemmer{
+   
+      /**
+      *  String to store the original word
+      *  @var string
+      */
+      private static $word = "";
+      
+      /**
+      *  Regex for matching a consonant
+      *  @var string
+      */
+      private static $regexConsonant = "#([bcdfghjklmnpqrstvwxz])|([aeiou]y)|^y#";
+      
+      /**
+      *  Regex for matching a vowel
+      *  @var string
+      */
+      private static $regexVowel = "#([aeiou])|([bcdfghjklmnpqrstvwxz]y)#";
+      
+      /**
+      *  Regex for matching a VC set, in order to calculate m
+      *  @var string
+      */
+      private static $regexVC = "#((([aeiou])|([bcdfghjklmnpqrstvwxz]y))[bcdfghjklmnpqrstvwxyz])#";
+      
+      /**
+      *  Regex for matching a CVC set, in order to represent condition  *o;
+      *  @var string
+      */
+      private static $regexCVC = "#((([bcdfghjklmnpqrstvwxz][aeiouy])|(y[aeiou]))[bcdfghjklmnpqrstvz])#";
+      
+      /**
+      *  Stems a word.
+      *  @param  string $word Word to stem
+      *  @return string       Stemmed word
+      */     
+      public static function getStem($word){
+         if (strlen($word) <= 2){
+         	return $word;
+         } 
+         
+         self::$word = strtolower($word);
+         self::step1a();
+         self::step1b();
+         self::step1c();
+         self::step2();
+         self::step3();
+         self::step4();
+         self::step5();
+         
+         return self::$word;
+      }
+      
+      /**
+      *  step 1a
+      */
+      private static function step1a(){
+         if (substr(self::$word, -1, 1)!= "s"){
+         	return;
+         } 
+         
+         switch (substr(self::$word, -2, 1)){
+         	case 'e': 
+         	  (self::matchLetter("sses")) && self::replaceLetter(4, "ss");
+         	  (self::matchLetter("ies")) && self::replaceLetter(3, "i");
+         	  (self::matchLetter("es")) && self::replaceLetter(2, "e");
+         	  break;
+         	case 's': 
+         	  //(self::matchLetter("ss")) && self::replaceLetter(2, "ss");
+         	  break;
+         	default :
+         	  (self::matchLetter("s")) && self::replaceLetter(1, "");
+         }             
+      }
+      
+      /**
+      *  step 1b
+      */
+      private static function step1b(){
+      	if (self::matchLetter("eed")){
+      		(self::getStemM(3) > 0) && self::replaceLetter(3,"ee");
+      		return;
+      	}
+      	if ((self::matchLetter("ed"))&&(self::stemContainVowel(2))){
+            self::replaceLetter(2,"");
+            self::step1b2();
+            return;             
+      	}
+      	if ((self::matchLetter("ing"))&&(self::stemContainVowel(3))){
+            self::replaceLetter(3,"");
+      		self::step1b2();	
+      	}
+      }
+      
+      /**
+      *  step 1b2
+      */
+      private static function step1b2(){
+      	(self::matchLetter("at")) && self::replaceLetter(2, "ate");
+         (self::matchLetter("bl")) && self::replaceLetter(2, "ble");
+         (self::matchLetter("iz")) && self::replaceLetter(2, "ize");
+         
+         if (self::stemEndWithCC(0) && !(self::stemEndWithLetter(0,'l') || self::stemEndWithLetter(0,'s') || self::stemEndWithLetter(0,'z'))){
+            self::$word = substr(self::$word, 0 ,-1);  
+         } else if ((self::getStemM(0) == 1) && self::stemEndWithCVC(0)){
+         	self::$word = self::$word."e";
+         }
+      }
+      
+      /**
+      *  step 1c
+      */
+      private static function step1c(){
+      	(self::matchLetter("y")) && (self::stemContainVowel(1)) && self::replaceLetter(1,"i");
+      }
+      
+      /**
+      *  step 2
+      */
+      private static function step2(){
+      	switch (substr(self::$word, -2, 1)){
+            case 'a' :
+               if(self::matchLetter("ational")){
+                  (self::getStemM(7)>0) && self::replaceLetter(7,"tion");
+                  break;
+               } else if (self::matchLetter("tional")){
+               	(self::getStemM(6)>0) && self::replaceLetter(6,"tion");
+               	break;
+               }
+               break;
+            case 'c' :
+               if(self::matchLetter("enci")){
+                  (self::getStemM(4)>0)&& self::replaceLetter(4,"ence");
+                  break;
+               } else if (self::matchLetter("anci")){
+               	(self::getStemM(4)>0) && self::replaceLetter(4,"ance");
+               	break;
+               }
+               break;
+            case 'e' :
+               if(self::matchLetter("izer")){
+                  (self::getStemM(4)>0) && self::replaceLetter(4,"ize");
+                  break;
+               } 
+               break;
+            case 'g' :
+               if(self::matchLetter("logi")){
+                  (self::getStemM(4)>0) && self::replaceLetter(4,"log");
+                  break;
+               }
+               break;
+            case 'l' :
+               if(self::matchLetter("bli")){
+                  (self::getStemM(3)>0) && self::replaceLetter(3,"ble");
+                  break;
+               } else if (self::matchLetter("alli")){
+               	(self::getStemM(4)>0) && self::replaceLetter(4,"al");
+               	break;
+               } else if (self::matchLetter("entli")){
+                  (self::getStemM(5)>0) && self::replaceLetter(5,"ent");
+                  break;
+               } else if (self::matchLetter("eli")){
+               	(self::getStemM(3)>0) && self::replaceLetter(3,"e");
+               	break;
+               } else if (self::matchLetter("ousli")){
+               	(self::getStemM(5)>0) && self::replaceLetter(5,"ous");
+               	break;
+               }
+               break;
+            case 'o':
+               if(self::matchLetter("ization")){
+                  (self::getStemM(7)>0) && self::replaceLetter(7,"ize");
+                  break;
+               } else if (self::matchLetter("ation")){
+               	(self::getStemM(5)>0) && self::replaceLetter(5,"ate");
+               	break;
+               } else if (self::matchLetter("ator")){
+                  (self::getStemM(4)>0) && self::replaceLetter(4,"ate");
+                  break;
+               }
+               break;
+            case 's':
+               if(self::matchLetter("alism")){
+                  (self::getStemM(5)>0) && self::replaceLetter(5,"al");
+                  break;
+               } else if (self::matchLetter("iveness")){
+               	(self::getStemM(7)>0) && self::replaceLetter(7,"ive");
+               	break;
+               } else if (self::matchLetter("fulness")){
+                  (self::getStemM(7)>0) && self::replaceLetter(7,"ful");
+                  break;
+               } else if (self::matchLetter("ousness")){
+               	(self::getStemM(7)>0) && self::replaceLetter(7,"ous");
+               	break;
+               } 
+               break;
+            case 't':
+               if(self::matchLetter("aliti")){
+                  (self::getStemM(5)>0) && self::replaceLetter(5,"al");
+                  break;
+               } else if (self::matchLetter("iviti")){
+               	(self::getStemM(5)>0) && self::replaceLetter(5,"ive");
+               	break;
+               } else if (self::matchLetter("biliti")){
+                  (self::getStemM(6)>0) && self::replaceLetter(6,"ble");
+                  break;
+               } 
+               break;
+      	}
+      }
+      
+      /**
+      *  step 3
+      */
+      private static function step3(){
+         switch (substr(self::$word, -1, 1)){
+            case 'e' :
+               if(self::matchLetter("icate")){
+                  (self::getStemM(5)>0) && self::replaceLetter(5,"ic");
+                  break;
+               } else if (self::matchLetter("ative")){
+               	(self::getStemM(5)>0) && self::replaceLetter(5,"");
+               	break;
+               } else if (self::matchLetter("alize")){
+                  (self::getStemM(5)>0) && self::replaceLetter(5,"al");
+                  break;
+               } 
+               break;
+            case 'i' :
+               if(self::matchLetter("iciti")){
+                  (self::getStemM(5)>0) && self::replaceLetter(5,"ic");
+                  break;
+               }
+               break;
+            case 'l' :
+               if(self::matchLetter("ical")){
+                  (self::getStemM(4)>0) && self::replaceLetter(4,"ic");
+                  break;
+               } else if (self::matchLetter("ful")){
+               	(self::getStemM(3)>0) && self::replaceLetter(3,"");
+               	break;
+               } 
+               break;
+            case 's' :
+               if(self::matchLetter("ness")){
+                  (self::getStemM(4)>0) && self::replaceLetter(4,"");
+                  break;
+               }
+               break;
+         }
+               
+      }
+      
+      /**
+      *  step 4
+      */
+      private static function step4(){
+      	switch (substr(self::$word, -2, 1)){
+      		case 'a' :
+               if(self::matchLetter("al")){
+                  (self::getStemM(2)>1) && self::replaceLetter(2,"");
+                  break;
+               }
+               break;
+            case 'c' :
+               if(self::matchLetter("ance")){
+                  (self::getStemM(4)>1) && self::replaceLetter(4,"");
+                  break;
+               } else if (self::matchLetter("ence")){
+                  (self::getStemM(4)>1) && self::replaceLetter(4,"");
+                  break;
+               }
+               break;
+            case 'e' :
+               if(self::matchLetter("er")){
+                  (self::getStemM(2)>1) && self::replaceLetter(2,"");
+                  break;
+               }
+               break;
+            case 'i' :
+               if(self::matchLetter("ic")){
+                  (self::getStemM(2)>1) && self::replaceLetter(2,"");
+                  break;
+               }
+            case 'l' :
+               if(self::matchLetter("able")){
+                  (self::getStemM(4)>1) && self::replaceLetter(4,"");
+                  break;
+               } else if (self::matchLetter("ible")){
+               	(self::getStemM(4)>1) && self::replaceLetter(4,"");
+               	break;
+               } 
+               break;
+            case 'n' :
+               if(self::matchLetter("ant")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               } else if (self::matchLetter("ement")){
+               	(self::getStemM(5)>1) && self::replaceLetter(5,"");
+               	break;
+               } else if (self::matchLetter("ment")){
+                  (self::getStemM(4)>1) && self::replaceLetter(4,"");
+                  break;
+               } else if (self::matchLetter("ent")){
+               	(self::getStemM(3)>1) && self::replaceLetter(3,"");
+               	break;
+               } 
+               break;
+            case 'o' :
+               if(self::matchLetter("sion")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               } else if (self::matchLetter("tion")){
+               	(self::getStemM(3)>1) && self::replaceLetter(3,"");
+               	break;
+               } else if (self::matchLetter("ou")){
+                  (self::getStemM(2)>1) && self::replaceLetter(2,"");
+                  break;
+               } 
+               break;
+            case 's' :
+               if(self::matchLetter("ism")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               }
+               break;
+            case 't' :
+               if(self::matchLetter("ate")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               } else if (self::matchLetter("iti")){
+               	(self::getStemM(3)>1) && self::replaceLetter(3,"");
+               	break;
+               } 
+               break;
+            case 'u' :
+               if(self::matchLetter("ous")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               }
+               break;
+            case 'v' :
+               if(self::matchLetter("ive")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               }
+               break;
+            case 'z' :
+               if(self::matchLetter("ize")){
+                  (self::getStemM(3)>1) && self::replaceLetter(3,"");
+                  break;
+               }
+               break;
+      	}
+      }
+      
+      /**
+      *  step 5
+      */
+      private static function step5(){
+      	if (self::matchLetter("e")){
+            if (self::getStemM(1)>1){
+               self::replaceLetter(1,"");
+            }else if ((self::getStemM(1)==1) && !self::stemEndWithCVC(1)){
+               self::replaceLetter(1,"");
+            } 
+         } 
+      	if (((self::matchLetter("dd"))||(self::matchLetter("ll")))&&(self::getStemM(0)>1)){
+      		self::$word = substr(self::$word, 0 ,-1); 
+      	}
+      }
+      
+      /**
+      *  check whether the suffix of the word matches $strOld
+      *  @param   (string) $strOld    String to check
+      *  @return  (bool)              Result
+      */
+      private static function matchLetter($strOld){
+         return (substr(self::$word, -strlen($strOld)) == $strOld);
+      }
+      
+      /**
+      *  replace the last ($offset) letters with $strNew
+      *  @param   (int)    $offset    offset intiger
+      *  @param   (string) $strNew    String to replace with
+      */
+      private static function replaceLetter($offset, $strNew){
+         self::$word = self::getSubString($offset).$strNew;
+      }
+      
+      /**
+      *  get the substring without the last ($offset) letters
+      *  @param   (int)    $offset    offset intiger
+      *  @return  (bool)              Result
+      */
+      private static function getSubString($offset){
+         return ($offset) ? substr(self::$word, 0, -$offset) : (self::$word);
+      }
+      
+      /**
+      *  get M of the substring without the last ($offset) letters
+      *  @param   (int)    $offset    offset intiger
+      *  @return  (bool)              Result
+      */
+      private static function getStemM($offset){
+         $stem = self::getSubString($offset);
+         preg_match_all(PorterStemmer::$regexVC, $stem, $matched);
+      	return sizeOf($matched[1]);
+      }
+      
+      /**
+      *  check whether the last letters of the substring
+      *  without the last ($offset) letters matches $chLetter
+      *  @param   (int)    $offset     offset intiger
+      *  @param   (string) $Letter     String to check
+      *  @return  (bool)               Result
+      */
+      private static function stemEndWithLetter($offset, $Letter){
+         $stem = self::getSubString($offset);
+         return (substr($stem, -1 ,1) == $Letter);
+      }
+      
+      /**
+      *  check whether the substring without the last ($offset) letters
+      *  contains a vowel
+      *  @param   (int)    $offset     offset intiger
+      *  @return  (bool)               Result
+      */
+      private static function stemContainVowel($offset){
+         $stem = self::getSubString($offset);
+      	return preg_match(self::$regexVowel, $stem);
+      }
+      
+      /**
+      *  check whether the last letters of the substring
+      *  without the last ($offset) letters matches double Consonant
+      *  @param   (int)    $offset     offset intiger
+      *  @return  (bool)               Result
+      */
+      private static function stemEndWithCC($offset){
+         $stem = self::getSubString($offset);
+         $temp1 = substr($stem, -1, 1);
+         $temp2 = substr($stem, -2, 1);
+      	return (($temp1==$temp2) && (preg_match(self::$regexConsonant, $temp1)));
+      }
+      
+      /**
+      *  check whether the last letters of the substring
+      *  without the last ($offset) letters matches CVC
+      *  @param   (int)    $offset     offset intiger
+      *  @return  (bool)               Result
+      */
+      private static function stemEndWithCVC($offset){
+         $stem = self::getSubString($offset);
+      	$temp = substr($stem, -3, 3);
+      	return (preg_match(self::$regexCVC, $temp));
+      }
+           
+   }
+
+?>
\ No newline at end of file
diff --git a/dojox/editor/tests/editorAutoSave.html b/dojox/editor/tests/editorAutoSave.html
new file mode 100644
index 0000000..507fd3e
--- /dev/null
+++ b/dojox/editor/tests/editorAutoSave.html
@@ -0,0 +1,172 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Editor Auto Save 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/AutoSave.css";
+		@import "../plugins/resources/css/ShowBlockNodes.css";
+	</style>
+	
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, isDebug: true"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+	
+	<script type="text/javascript">
+		dojo.require("dijit.Editor");
+		dojo.require("dojo.parser");
+		dojo.require("dojox.editor.plugins.AutoSave");
+		dojo.require("dijit._editor.plugins.FullScreen");
+		dojo.require("dijit._editor.plugins.ViewSource");
+		dojo.require("dojox.editor.plugins.ShowBlockNodes");
+	</script>
+</head>
+<body class="claro">
+	<br>
+	<h1 class="testTitle">Editor + Save Plugin</h1>
+
+	<h2>This is an example editor with Save enabled.</h2>  
+	The AutoSave plugin is a non-visual 'helper' plugin.  When enabled, it allows a quick way to POST back content to a
+	server.  The target URL for the default implementation uses xhrPost, and as such, it must POST back to the same
+	domain that served the page that instantiated the editor.  Users can extend this plugin to alter its save behavior, such
+	as use a different posting mechanism, or provide custom onSuccess and onError handlers.
+	<br>
+	<br>
+	<b>Note:</b> For nicely formatted HTML, consider also including the dojox.editor.plugins.PrettyPrint plugin to 
+	'clean up' the content the editor returns.
+	<br>
+	<br>
+	<b>Note:</b> This test makes use of PHP to simulate a back end service, so run it from a PHP enabled server!
+	Otherwise it may report errors.
+	<br>
+	<br>
+	<div dojoType="dijit.Editor" id="editor1" extraPlugins="[{name:'autosave', url:'dummySave.php', interval:5}, 'fullscreen', 'viewsource', 'showblocknodes']">
+		This instance is created from a div with an extra plugin, 'AutoSave' loaded.
+		<div>
+			<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</li>
+			</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>
+	</div>
+	<h2>Auto-Save with interval 10 minutes</h2>
+	<div dojoType="dijit.Editor" id="editor2" extraPlugins="[{name:'autosave', url:'dummySave.php', interval:10}]">
+		This instance is created from a div with an extra plugin, 'AutoSave' loaded.
+		<div>
+			<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</li>
+			</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>
+	</div>
+</body>
+</html>
diff --git a/dojox/editor/tests/editorAutoUrlLink.html b/dojox/editor/tests/editorAutoUrlLink.html
new file mode 100644
index 0000000..cdbe2c2
--- /dev/null
+++ b/dojox/editor/tests/editorAutoUrlLink.html
@@ -0,0 +1,208 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<title>Editor AutoUrlLink Test</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="parseOnLoad: true, isDebug: true"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+	
+	<script type="text/javascript">
+		dojo.require("dijit.Editor");
+		dojo.require("dojo.parser");
+		dojo.require("dojox.editor.plugins.AutoUrlLink");
+		dojo.require("dijit._editor.plugins.ViewSource");
+		
+		var e2Plugins = ["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
+			"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
+			{name: "dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter: "P"}];
+
+		var e3Plugins = ["undo","redo","|","cut","copy","paste","|","bold","italic","underline","strikethrough","|",
+			"insertOrderedList","insertUnorderedList","indent","outdent","|","justifyLeft","justifyRight","justifyCenter","justifyFull",
+			{name: "dijit._editor.plugins.EnterKeyHandling", blockNodeForEnter: "DIV"}];
+	</script>
+</head>
+<body class="claro">
+	<br>
+	<h1 class="testTitle">Editor + AutoUrlLink Plugin</h1>
+
+	<h2>This is an example editor with AutoUrlLink enabled.</h2>  
+	The AutoUrlLink plugin allows you recognize a URL as a link when you are typing.
+	<br>
+
+	<div dojoType="dijit.Editor" id="editor1" extraPlugins="['autourllink', 'viewsource']">
+		This instance is created from a div with an <b>extra</b> plugin, 'AutoUrlLink' loaded.
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<li>List Item Three</li>
+			<li>List Item Four</li>
+		</ul>
+		<br>
+		<blockquote><a href="http://www.dojotoolkit.org">The Dojo Toolkit</a></blockquote>
+		<br>
+		<table border="1">
+			<tr>
+				<td>Test Cell 1</td>
+				<td>Test Cell 2</td>
+			</tr>
+			<tr>
+				<td>Test Cell 3</td>
+				<td>Test Cell 4</td>
+			</tr>
+		</table>
+		<br>
+		<ol>
+			<li>One</li>
+			<li>Two
+			<ol>
+				<li>
+					Three
+				</li>
+			</ol>
+		</ol>
+		<br>
+		<h3>Malformed list #1</h3>
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<ul>
+				<li>List Item Three</li>
+				<li>List Item Four</li>
+				<li>List Item Five</li>
+			</ul>
+		</ul>
+		<h3>Malformed list #2</h3>
+		<ul>
+			<ul>
+				<li>List Item one</li>
+				<li>List Item two</li>
+				<li>List Item three</li>
+			</ul>
+			<li>List Item four</li>
+			<li>List Item five</li>
+		</ul>
+	</div>
+	<br>
+	<br>
+	<h1>Editor with BlockNodeForEnter = P</h1>
+	<div dojoType="dijit.Editor" id="editor2" plugins="e2Plugins" extraPlugins="['autourllink', 'viewsource']">
+		This instance is created from a div with an <b>extra</b> plugin, 'AutoUrlLink' loaded.
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<li>List Item Three</li>
+			<li>List Item Four</li>
+		</ul>
+		<br>
+		<blockquote><a href="http://www.dojotoolkit.org">The Dojo Toolkit</a></blockquote>
+		<br>
+		<table border="1">
+			<tr>
+				<td>Test Cell 1</td>
+				<td>Test Cell 2</td>
+			</tr>
+			<tr>
+				<td>Test Cell 3</td>
+				<td>Test Cell 4</td>
+			</tr>
+		</table>
+		<br>
+		<ol>
+			<li>One</li>
+			<li>Two
+			<ol>
+				<li>
+					Three
+				</li>
+			</ol>
+		</ol>
+		<br>
+		<h3>Malformed list #1</h3>
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<ul>
+				<li>List Item Three</li>
+				<li>List Item Four</li>
+				<li>List Item Five</li>
+			</ul>
+		</ul>
+		<h3>Malformed list #2</h3>
+		<ul>
+			<ul>
+				<li>List Item one</li>
+				<li>List Item two</li>
+				<li>List Item three</li>
+			</ul>
+			<li>List Item four</li>
+			<li>List Item five</li>
+		</ul>
+	</div>
+	<br>
+	<br>
+	<h1>Editor with BlockNodeForEnter = DIV</h1>
+	<div dojoType="dijit.Editor" id="editor3" plugins="e3Plugins" extraPlugins="['autourllink', 'viewsource']">
+		This instance is created from a div with an <b>extra</b> plugin, 'AutoUrlLink' loaded.
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<li>List Item Three</li>
+			<li>List Item Four</li>
+		</ul>
+		<br>
+		<blockquote><a href="http://www.dojotoolkit.org">The Dojo Toolkit</a></blockquote>
+		<br>
+		<table border="1">
+			<tr>
+				<td>Test Cell 1</td>
+				<td>Test Cell 2</td>
+			</tr>
+			<tr>
+				<td>Test Cell 3</td>
+				<td>Test Cell 4</td>
+			</tr>
+		</table>
+		<br>
+		<ol>
+			<li>One</li>
+			<li>Two
+			<ol>
+				<li>
+					Three
+				</li>
+			</ol>
+		</ol>
+		<br>
+		<h3>Malformed list #1</h3>
+		<ul>
+			<li>List Item One</li>
+			<li>List Item Two</li>
+			<ul>
+				<li>List Item Three</li>
+				<li>List Item Four</li>
+				<li>List Item Five</li>
+			</ul>
+		</ul>
+		<h3>Malformed list #2</h3>
+		<ul>
+			<ul>
+				<li>List Item one</li>
+				<li>List Item two</li>
+				<li>List Item three</li>
+			</ul>
+			<li>List Item four</li>
+			<li>List Item five</li>
+		</ul>
+	</div>
+	
+</body>
+</html>
diff --git a/dojox/editor/tests/editorLocalImage.html b/dojox/editor/tests/editorLocalImage.html
new file mode 100644
index 0000000..2fa384c
--- /dev/null
+++ b/dojox/editor/tests/editorLocalImage.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>Editor Test: Local Image Insert Dialog Plugin</title>
+	
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
+		@import "../../../dijit/themes/claro/claro.css";
+		@import "../../form/resources/FileUploader.css"; 
+		@import "../plugins/resources/css/LocalImage.css";
+	</style>
+	
+	<script type="text/javascript" src="../../../dojo/dojo.js"	djConfig="parseOnLoad: true, isDebug: true"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.Editor");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("dojox.editor.plugins.LocalImage");
+		dojo.require("dijit._editor.plugins.ViewSource");
+	</script>
+</head>
+<body class="claro">
+	<h1>Editor + Insert Image with file uploading</h1>
+	<br/>
+	<div dojoType="dijit.Editor" id="editor1" 
+		extraPlugins="[{name: 'LocalImage', uploadable: true, uploadUrl: '../../form/tests/UploadFile.php', baseImageUrl: '../../form/tests/'}, 'viewSource']">
+		<ol>
+			<li>The LocalImagePluginplugin is an 'example' style plugin that shows how to insert 
+			image tags.</li>
+			<li>You need a php server to test this plugin. Please enable <b>dojox\form\tests\cLOG.php</b> and 
+			<b>dojox\form\tests\UploadFile.php</b> first.</li>
+		</ol>
+		<br>
+		<div><a href="http://www.example.com/example.html" target="_top" id="exampleLink">This is an example link in the page.</a></div>
+		<br>
+		<br>
+		<div><img src="./sample.jpg" alt="Sample Image" id="exampleImage" /></div>
+		<br>
+		<br>
+	</div>
+	<br/>
+	<h1>Editor + Insert Image without file uploading</h1>
+	<br/>
+	<div dojoType="dijit.Editor" id="editor2" 
+		extraPlugins="[{name: 'LocalImage'}, 'viewSource']">
+		<ol>
+			<li>The LocalImagePlugin is an 'example' style plugin that shows how to insert 
+			image tags.</li>
+		</ol>
+		<br>
+		<div><a href="http://www.example.com/example.html" target="_top" id="exampleLink">This is an example link in the page.</a></div>
+		<br>
+		<br>
+		<div><img src="./sample.jpg" alt="Sample Image" id="exampleImage" /></div>
+		<br>
+		<br>
+	</div>
+</body>
+</html>
diff --git a/dojox/editor/tests/editorPrettyPrint.html b/dojox/editor/tests/editorPrettyPrint.html
index e6900f9..33dce66 100755
--- a/dojox/editor/tests/editorPrettyPrint.html
+++ b/dojox/editor/tests/editorPrettyPrint.html
@@ -56,7 +56,7 @@
 <body class="tundra">
 	<br>
 	<h1 class="testTitle">Editor + PrettyPrint Plugin</h1>
-   	<div dojoType="dijit.layout.AccordionContainer" style="width: 100%x; height: 550px; overflow: hidden">
+   	<div dojoType="dijit.layout.AccordionContainer" style="width: 100%; height: 550px; overflow: hidden">
 		<div dojoType="dijit.layout.ContentPane" title="PrettyPrint (with defaults)">
 			<h2>This is an example editor with PrettyPrint enabled and the default settings for indent, entity character mapping, and line length</h2>
 			<div dojoType="dijit.Editor" id="editor1" extraPlugins="['prettyprint', 'viewsource']">
diff --git a/dojox/editor/tests/editorResizeTableColumn.html b/dojox/editor/tests/editorResizeTableColumn.html
new file mode 100644
index 0000000..128f230
--- /dev/null
+++ b/dojox/editor/tests/editorResizeTableColumn.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+	<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+		<title>Editor Resize Table Column</title>
+		<style type="text/css">
+			@import "../../../dojo/resources/dojo.css";
+			@import "../../../dijit/themes/claro/claro.css";
+			@import "../../../dijit/themes/dijit.css";
+		</style>
+
+		<link href="../plugins/resources/editorPlugins.css" type="text/css" rel="stylesheet" />
+
+		<script type="text/javascript">
+			var djConfig = {
+				isDebug: true,
+				parseOnLoad: true,
+				popup:true
+				//forceFirebugLite:true
+			};
+		</script>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+		
+		<script>
+			dojo.require("dojo.parser");
+			dojo.require("dijit.Editor");
+			dojo.require("dijit.form.Button");
+			dojo.require("dojox.editor.plugins.ResizeTableColumn");
+			dojo.require("dijit._editor.plugins.ViewSource");
+			dojo.addOnLoad(function(){
+				console.log(dojo.version.toString());
+			});
+
+			dojo.addOnLoad(function(){
+				var editor = dijit.byId("editor");
+				var button = dijit.byId("removeButton");
+				var c = dojo.connect(button, "onClick", function(){
+					dojo.disconnect(c);
+					editor.close();
+					editor.destroy();
+				});
+			});
+		</script>
+		<style>
+			#main{
+				width:auto;
+				margin:20px 100px;
+			}
+		</style>
+	</head>
+	<body class="claro">
+		<div id="main">
+			<div id="editor" dojoType="dijit.Editor" height="200px" plugins="[
+				'undo', 'redo', 'bold','italic','|',
+				{name: 'dojox.editor.plugins.TablePlugins', command: 'resizeTableColumn'}, 'viewsource'
+			]">
+				Dojo Rocks with a fox in socks. Red socks. In a box.
+				<br/><br/>
+			        <table width="500" border="2" cellpadding="2" cellspacing="2" bordercolor="#00FFFF" bgcolor="#FF0000" id="myTable">
+					<tr>
+						<td> </td>
+						<td> </td>
+						<td> </td>
+					</tr>
+					<tr>
+						<td> </td>
+						<td id="myCell"> </td>
+						<td> </td>
+					</tr>
+					<tr>
+						<td> </td>
+						<td> </td>
+						<td bgcolor="#00FFFF">Text</td>
+					</tr>
+				</table> 
+			</div>
+		</div>
+		<button id="removeButton" dojoType="dijit.form.Button">Remove Editor</button>
+	</body>
+</html>
diff --git a/dojox/editor/tests/editorSpellCheck.html b/dojox/editor/tests/editorSpellCheck.html
new file mode 100644
index 0000000..3edb42e
--- /dev/null
+++ b/dojox/editor/tests/editorSpellCheck.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 http-equiv= "Content-Type" content= "text/html;charset=utf-8">
+	<title>Editor Test: Spell Check Plugin</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/ShowBlockNodes.css";
+		@import "../plugins/resources/css/SpellCheck.css";
+	</style>
+	
+	<script type="text/javascript" src="../../../dojo/dojo.js"	djConfig="parseOnLoad: true, isDebug: true"></script>
+
+	<!-- only needed for alternate theme testing: -->
+	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+
+	<script type="text/javascript">
+		dojo.require("dijit.Editor");
+		dojo.require("dojo.parser");	// scan page for widgets and instantiate them
+		dojo.require("dojox.editor.plugins.SpellCheck");
+		dojo.require("dojox.editor.plugins._SpellCheckParser");
+		dojo.require("dijit._editor.plugins.NewPage");
+		dojo.require("dojox.editor.plugins.ShowBlockNodes");
+		dojo.require("dijit._editor.plugins.ViewSource");
+	</script>
+</head>
+<body class="claro">
+	<h1>Editor + Batch/Interactive SpellCheck</h1>
+	<br/>
+	<div dojoType="dijit.Editor" id="editor1" 
+		extraPlugins="[{name: 'SpellCheck', url: 'spellCheck.php', lang: 'EN', interactive: true, timeout: 20}, 'newpage', 'showblocknodes', 'viewSource']">
+		<ol>
+			<li>The is a demo to show how to use the Spell Check plugin.</li>
+			<li>You need a php server to test this plugin. Please enable <b>dojox\editor\plugins\tests\spellcheck.php</b> and  <b>dojox\editor\plugins\tests\PorterStemmer.php</b> first.</li>
+		</ol>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+I am errir. Thi is wrng.
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+		<br/>
+Thi is the end of the txt.
+		<br/>
+		<br/>
+		<div><a href="http://www.example.com/example.html" target="_top" id="exampleLink">This is an example link in the page.</a></div>
+		<br/>
+		<br/>
+		<div><img src="./sample.jpg" alt="Sample Image" id="exampleImage" /></div>
+		<br/>
+		<br/>
+	</div>
+	<h1>Another Instance</h1>
+	<br/>
+	<div dojoType="dijit.Editor" id="editor2" 
+		extraPlugins="[{name: 'SpellCheck', url: 'spellCheck.php', lang: 'EN', interactive: true, timeout: 20}]">
+Don’t spend hours reinventing the wheel, use Dojo’s widget system Dijit for commonly used form widgets like calendars, input validation and more.
+		<br/>
+		<br/>
+	</div>
+</body>
+</html>
diff --git a/dojox/editor/tests/editorTablePlugs.html b/dojox/editor/tests/editorTablePlugs.html
index c900f6e..130b56d 100644
--- a/dojox/editor/tests/editorTablePlugs.html
+++ b/dojox/editor/tests/editorTablePlugs.html
@@ -5,8 +5,9 @@
 		<title>Editor Table Plugins</title>
 		<style type="text/css">
 			@import "../../../dojo/resources/dojo.css";
-			@import "../../../dijit/themes/tundra/tundra.css";
+			@import "../../../dijit/themes/claro/claro.css";
 			@import "../../../dijit/themes/dijit.css";
+			@import "../../widget/ColorPicker/ColorPicker.css";
 		</style>
 
 		<link href="../plugins/resources/editorPlugins.css" type="text/css" rel="stylesheet" />
@@ -21,11 +22,16 @@
 		</script>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		
+		<!-- only needed for alternate theme testing: -->
+		<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
+		
 		<script>
 			dojo.require("dojo.parser");
 			dojo.require("dijit.Editor");
 			dojo.require("dijit.form.Button");
 			dojo.require("dojox.editor.plugins.TablePlugins");
+			dojo.require("dijit._editor.plugins.ViewSource");
 			dojo.addOnLoad(function(){
 				console.log(dojo.version.toString());
 			});
@@ -47,7 +53,7 @@
 			}
 		</style>
 	</head>
-	<body class="tundra">
+	<body class="claro">
 		<div id="main">
 			<div id="editor" dojoType="dijit.Editor" height="200px" plugins="[
 				'undo', 'redo', 'bold','italic','|',
@@ -63,7 +69,8 @@
 				{name: 'dojox.editor.plugins.TablePlugins', command: 'tableContextMenu'}
 			]">
 				Dojo Rocks with a fox in socks. Red socks. In a box.
-			        <table width="200" border="2" align="center" cellpadding="2" cellspacing="2" bordercolor="#00FFFF" bgcolor="#FF0000" id="myTable">
+				<br/><br/>
+			        <table width="200" border="2" cellpadding="2" cellspacing="2" bordercolor="#00FFFF" bgcolor="#FF0000" id="myTable">
 					<tr>
 						<td> </td>
 						<td> </td>
diff --git a/dojox/editor/tests/editorTextColor.html b/dojox/editor/tests/editorTextColor.html
index b7a22d7..9b3f215 100755
--- a/dojox/editor/tests/editorTextColor.html
+++ b/dojox/editor/tests/editorTextColor.html
@@ -7,7 +7,7 @@
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
-		@import "../../../dijit/themes/tundra/tundra.css";
+		@import "../../../dijit/themes/claro/claro.css";
 		@import "../plugins/resources/css/TextColor.css";
 	</style>
 
@@ -19,7 +19,7 @@
 		dojo.require("dojox.editor.plugins.TextColor");
 	</script>
 </head>
-<body class="tundra">
+<body class="claro">
 	<br>
 	<h1 class="testTitle">Editor + TextColor Plugin</h1>
 
diff --git a/dojox/editor/tests/sample.jpg b/dojox/editor/tests/sample.jpg
new file mode 100644
index 0000000..53422b3
Binary files /dev/null and b/dojox/editor/tests/sample.jpg differ
diff --git a/dojox/editor/tests/spellCheck.php.disabled b/dojox/editor/tests/spellCheck.php.disabled
new file mode 100644
index 0000000..24cbebe
--- /dev/null
+++ b/dojox/editor/tests/spellCheck.php.disabled
@@ -0,0 +1,152 @@
+<?php
+	require("PorterStemmer.php");
+	
+	class Word{
+		public $text;
+		public $suggestion;
+	}
+	
+	class SpellDic{
+		// $fileName [String]
+		//		The dictionary file name
+		private $fileName = "wordlist.txt";
+		
+		// $_lang [String]
+		//		The target language
+		private $_lang;
+		
+		// $_encoding [String]
+		//		The encoding
+		private $_encoding;
+		
+		// $_words [Array<Word>]
+		//		The word list to be checked
+		private $_words;
+		
+		// $_dic [Array]
+		//		The array that mimic the dictionary. It can be more
+		//		sophisticated. However, this is only a demo.
+		private $_dic;
+		
+		// SIMI [Number]
+		//		The threshold of  the similarity
+		const SIMI = 0.6;
+		
+		public function __construct(){
+			$this->_dic = explode("\n", file_get_contents($this->fileName));
+		}
+		
+		public function setLanguage($lang){
+			$this->_lang = $lang;
+		}
+		
+		public function setEncoding($encoding){
+			$this->_encoding = $encoding;
+		}
+		
+		public function setWords($words){
+			$this->_words = $words;
+		}
+		
+		public function add($word){
+			$handle = fopen($this->fileName, 'a');
+			fwrite($handle, "$word\n");
+			fclose($handle);
+			return "{response:[]}";
+		}
+		
+		public function check(){
+			// summary:
+			//		Check the spelling and return a HTML page with a JSON string like
+			//			{response: [
+			//				{ 
+			//					text :"teest", 
+			//					suggestion:["test","treat"]
+			//				}
+			//			]}
+			if($this->_lang == "EN"){
+				$len = count($this->_words);
+				for($i = 0; $i < $len; $i++){
+					$this->_words[$i]->suggestion = $this->lookup($this->_words[$i]->text);
+				}
+				$temp = array();
+				for($i = 0; $i < $len; $i++){
+					if($this->_words[$i]->suggestion !== NULL){
+						array_push($temp, $this->_words[$i]);
+					}
+				}
+				return "{response:" . json_encode($temp). "}";
+			}else{
+				// This is only a demo, so keep the text as-is
+				// if the encoding is not UTF-8 or the language is
+				// not English
+				return "{response:[]}"; // No spelling error found
+			}
+		}
+		
+		private function lookup($word){
+			// summary:
+			//		Look for the given word. If it is not found, a suggestion list
+			//		will be returned, else an empty list will be returned.
+			$len = count($this->_dic);
+			$lst = array();
+			for($i = 0; $i < $len; $i++){
+				if($word == $this->_dic[$i] || PorterStemmer::getStem($word) == $this->_dic[$i]){
+					return NULL;
+				}else{
+					// Compare the two words to get the similarity.
+					$num = $this->_lcs($word, $this->_dic[$i]);
+					if($num / strlen($word) > self::SIMI && $num / strlen($this->_dic[$i]) > self::SIMI){
+						array_push($lst, $this->_dic[$i]);
+					}
+				}
+			}
+			return $lst;
+		}
+		
+		private function _lcs($word1, $word2){
+			// summary:
+			//		Longest Common Subsequence
+			/* $f[$i][$j] = max(f[$i-1][$j-1] + same($i, $j), f[$i-1][$j], f[$i][$j-1];*/
+			$len1 = strlen($word1);
+			$len2 = strlen($word2);
+			for($i = 0; $i <= $len1; $i++){ $f[$i][0] = 0; }
+			for($j = 0; $j <= $len2; $j++){ $f[0][$j] = 0; }
+			for($i = 1; $i <= $len1; $i++){
+				for($j = 1; $j <= $len2; $j++){
+					$f[$i][$j] = max($f[$i - 1][$j - 1] + ($word1[$i - 1] == $word2[$j - 1] ? 1 : 0),
+										max($f[$i - 1][$j], $f[$i][$j - 1]));
+				}
+			}
+			return $f[$i - 1][$j - 1];
+		}
+	}
+	
+	function text2Words($text){
+		$result = array();
+		$words = explode (" ", $text);
+		$len = count($words);
+		for($i = 0; $i < $len; $i++){
+			$word = new Word();
+			$word->text = $words[$i];
+			array_push($result, $word);
+		}
+		return $result;
+	}
+	
+	header('Content-Type: text/html; charset=UTF-8');
+	
+	$sourceText = array_key_exists("content", $_REQUEST) ? $_REQUEST["content"] : "";
+	$lang = array_key_exists("lang", $_REQUEST) ? $_REQUEST["lang"] : "EN";
+	$action = array_key_exists("action", $_REQUEST) ? $_REQUEST["action"] : "query";
+	$callback = array_key_exists("callback", $_REQUEST) ? $_REQUEST["callback"] : "callback";
+	
+	$dic = new SpellDic();
+	$dic->setLanguage($lang);
+	if($action == "query"){
+		$dic->setWords(text2Words(trim($sourceText)));
+		echo "$callback(" . $dic->check() . ");"; // JSONP Specification
+	}else if ($action == "update"){
+		echo "$callback(" . $dic->add($sourceText) . ");";
+	}
+?>
diff --git a/dojox/editor/tests/testPluginsAll.html b/dojox/editor/tests/testPluginsAll.html
index 9c22f74..0c27828 100644
--- a/dojox/editor/tests/testPluginsAll.html
+++ b/dojox/editor/tests/testPluginsAll.html
@@ -20,6 +20,8 @@
 		@import "../../../dojox/editor/plugins/resources/css/InsertAnchor.css";
 		@import "../../../dojox/editor/plugins/resources/editorPlugins.css";
 		@import "../../../dojox/editor/plugins/resources/css/StatusBar.css"; 
+		@import "../../../dojox/editor/plugins/resources/css/LocalImage.css";
+		@import "../../../dojox/editor/plugins/resources/css/AutoSave.css";
 
 		body, html { width:100%; height:100%; margin:0; padding:0; overflow:hidden;}
 		#borderContainer { width:100%; height:100%; overflow:hidden;}
@@ -60,15 +62,20 @@
 		dojo.require("dojox.editor.plugins.TextColor");
 		dojo.require("dojox.editor.plugins.InsertAnchor");
 		dojo.require("dojox.editor.plugins.StatusBar");
-		
-		var plugins = ['collapsibletoolbar', 'newPage', 'save', {name: 'viewSource', stripScripts: true, stripComments: true}, 'showBlockNodes', '|',
+		dojo.require("dojox.editor.plugins.LocalImage");
+		dojo.require("dojox.editor.plugins.AutoUrlLink");
+		dojo.require("dojox.editor.plugins.ResizeTableColumn");
+		dojo.require("dojox.editor.plugins.AutoSave");
+			
+		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', '|',
 			'pageBreak', 'insertHorizontalRule', 'insertOrderedList', 'insertUnorderedList', 'indent', 'outdent', 'blockquote', '|',
 			'justifyLeft', 'justifyRight', 'justifyCenter', 'justifyFull', 'toggleDir', '|',
 			'bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript',  'foreColor', 'hiliteColor', 'removeFormat', '||',
 			'fontName', 'fontSize', 'formatBlock', '||',
-			'insertEntity', 'createLink', 'unlink', 'insertanchor', 'insertImage',
+			'insertEntity', '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'},
 			{name: 'dojox.editor.plugins.TablePlugins', command: 'InsertTableRowBefore'},
@@ -79,8 +86,10 @@
 			{name: 'dojox.editor.plugins.TablePlugins', command: 'deleteTableColumn'},
 			{name: 'dojox.editor.plugins.TablePlugins', command: 'colorTableCell'},
 			{name: 'dojox.editor.plugins.TablePlugins', command: 'tableContextMenu'},
+			{name: 'dojox.editor.plugins.TablePlugins', command: 'resizeTableColumn'},
 			{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}
 		];
 	</script>
diff --git a/dojox/editor/tests/wordlist.txt b/dojox/editor/tests/wordlist.txt
new file mode 100644
index 0000000..131800a
--- /dev/null
+++ b/dojox/editor/tests/wordlist.txt
@@ -0,0 +1,1619 @@
+a
+able
+about
+above
+accept
+accident
+accuse
+acid
+across
+act
+activist
+activity
+actor
+ad.
+add
+administration
+admit
+adult
+advise
+affect
+afraid
+after
+again
+against
+age
+agency
+aggression
+ago
+agree
+agreement
+agriculture
+aid
+aim
+air
+airplane
+airport
+album
+alcohol
+alive
+all
+ally
+almost
+alone
+along
+already
+also
+although
+always
+ambassador
+amend
+ammunition
+among
+amount
+an
+anarchy
+ancestor
+ancient
+and
+anger
+animal
+anniversary
+announce
+another
+another
+answer
+any
+apologize
+appeal
+appear
+appoint
+approve
+archeology
+are
+area
+argue
+arms
+army
+around
+arrest
+arrive
+art
+artillery
+as
+ash
+ask
+asked
+asking
+assist
+astronaut
+astronomy
+asylum
+at
+atmosphere
+atom
+attach
+attack
+attempt
+attend
+automobile
+autumn
+average
+avoid
+awake
+award
+away
+B
+baby
+back
+bacteria
+bad
+balance
+ball
+balloon
+ballot
+ban
+bank
+bar
+barrier
+base
+battle
+be
+beat
+beauty
+because
+become
+bed
+before
+begin
+behind
+being
+believe
+bell
+belong
+below
+best
+betray
+better
+between
+big
+bill
+biology
+bird
+birth
+bite
+black
+blame
+blanket
+bleed
+blind
+block
+blood
+blow
+blue
+boat
+body
+boil
+bomb
+bombs
+bone
+book
+book,
+border
+borders
+born
+borrow
+both
+bottle
+bottom
+bottom
+bought
+box
+boy
+boycott
+brain
+brave
+bread
+break
+breathe
+bridge
+brief
+bright
+bring
+broadcast
+brother
+brown
+budget
+build
+building
+bullet
+burn
+burst
+bury
+bus
+business
+busy
+but
+buy
+by
+C
+cabinet
+call
+calm
+camera
+camp
+campaign
+can
+cancel
+cancer
+candidate
+cannot
+capital
+capitalism
+capture
+car
+care
+careful
+carefully
+carry
+case
+cat
+catch
+cause
+caused
+ceasefire
+celebrate
+cell
+center
+century
+ceremony
+chairman
+champion
+chance
+change
+charge
+charge
+chase
+cheat
+cheer
+chemicals
+chemistry
+chief
+child
+children
+choose
+chromosome
+circle
+citizen
+city
+civil
+civilian
+claim
+clash
+clean
+clear
+clergy
+climate
+climb
+clock
+close
+cloth
+clothes
+cloud
+coal
+coalition
+coast
+coffee
+cold
+collect
+college
+colony
+color
+colored
+combine
+come
+command
+comment
+committee
+committee
+common
+communicate
+communicating
+community
+company
+compare
+compete
+complete
+complex
+compound
+compromise
+computer
+concern
+condemn
+condition
+conference
+confirm
+conflict
+congratulate
+Congress
+conj.
+connect
+conservative
+consider
+constitution
+contain
+container
+continent
+continue
+continuing
+control
+convention
+cook
+cool
+cooperate
+copy
+corn
+correct
+cost
+cotton
+count
+country
+country,
+court
+cover
+cow
+crash
+create
+creature
+credit
+crew
+crime
+criminal
+crisis
+criticize
+crops
+cross
+crowd
+crush
+cry
+culture
+cure
+curfew
+current
+custom
+customs
+cut
+D
+dam
+damage
+dance
+danger
+dark
+date
+daughter
+day
+dead
+deaf
+deal
+debate
+debt
+decide
+declare
+decrease
+deep
+defeat
+defend
+deficit
+define
+degree
+delay
+delegate
+demand
+democracy
+demonstrate
+demonstrated
+denounce
+dense
+deny
+depend
+deplore
+deploy
+depression
+describe
+desert
+design
+desire
+destroy
+detail
+develop
+develops
+device
+dictator
+die
+diet
+different
+difficult
+dig
+dinner
+diplomat
+diplomatic
+direct
+direction
+dirt
+dis
+disappear
+disarm
+discover
+discuss
+disease
+dishonored
+dismiss
+dispute
+dissident
+distance
+dive
+divide
+do
+doctor
+document
+dog
+dollar
+door
+down
+dream
+drink
+drive
+drop
+drown
+drug
+dry
+during
+dust
+duty
+E
+each
+early
+earn
+earth
+earthquake
+earth's
+ease
+east
+easy
+eat
+ecology
+economy
+edge
+education
+effect
+effort
+efforts
+egg
+either
+elect
+electricity
+electron
+electronic
+element
+embassy
+emergency
+emotion
+emotions
+employ
+empty
+end
+enemy
+energy
+enforce
+engine
+engineer
+enjoy
+enough
+enter
+environment
+enzyme
+equal
+equipment
+escape
+especially
+establish
+estimate
+ethnic
+evaporate
+even
+event
+events
+ever
+every
+evidence
+evil
+exact
+examine
+example
+excellent
+except
+exchange
+excuse
+execute
+exercise
+exile
+exist
+expand
+expect
+expel
+experience
+experiment
+expert
+explain
+explode
+explore
+export
+express
+extend
+extra
+extreme
+extremist
+F
+face
+fact
+factory
+facts
+fail
+fair
+fall
+false,
+family
+famous
+far
+farm
+fast
+fat
+father
+fear
+feared
+federal
+feed
+feel
+feet
+female
+fence
+fertile
+fetus
+few
+field
+fierce
+fight
+fill
+film
+final
+financial
+find
+fine
+finish
+fire
+fireworks
+firm
+first
+fish
+fission
+fit
+fix
+flag
+flat
+flee
+float
+flood
+floor
+flow
+flower
+fluid
+fly
+fog
+follow
+food
+fool
+foot
+for
+force
+force
+force
+forced
+foreign
+foreign
+forest
+forget
+forgive
+form
+formed
+former
+forms
+forward
+free
+freedom
+freeze
+fresh
+friend
+frighten
+from
+front
+fruit
+fuel
+fuel
+full
+fun
+funeral
+fusion
+future
+G
+gain
+game
+gas
+gases
+gather
+general
+genes
+genetic
+gentle
+get
+gets
+gift
+girl
+give
+glass
+go
+goal
+god
+gold
+good
+goods
+govern
+government
+grain
+granddaughter
+grandfather
+grandmother
+grandson
+grass
+gravity
+gray
+great
+green
+grind
+ground
+group
+grow
+grown
+guarantee
+guard
+guerrilla
+guide
+guilty
+gun
+H
+had
+hair
+half
+halt
+hang
+happen
+happens
+happy
+hard
+harm
+harmless
+harvest
+hat
+hate
+have
+having
+he
+head
+headquarters
+heal
+health
+hear
+heart
+heat
+heat,
+heavy
+helicopter
+help
+here
+hero
+hide
+high
+highest
+hijack
+hill
+history
+hit
+hold
+hole
+holiday
+holy
+home
+honest
+honor
+hope
+horrible
+horse
+hospital
+hostage
+hostile
+hot
+hotel
+hour
+house
+how
+however
+huge
+human
+humor
+hunger
+hunt
+hurry
+hurt
+husband
+I
+ice
+idea
+identify
+if
+illegal
+image
+imagine
+immediate
+import
+important
+imports
+improve
+in
+in
+incident
+incite
+include
+increase
+independent
+independent
+individual
+industrial
+industry
+infect
+inflation
+influence
+inform
+information
+inject
+injure
+injury
+innocent
+insane
+insect
+inspect
+instead
+instrument
+instrument
+insult
+intelligence
+intelligent
+intense
+interest
+interfere
+international
+intervene
+intestines
+invade
+invent
+invest
+investigate
+investments
+invite
+involve
+iron
+is
+island
+issue
+it
+J
+jail
+jewel
+job
+join
+joint
+joke
+judge
+jump
+jury
+just
+K
+keep
+kick
+kidnap
+kidney
+kill
+kilometers
+kind
+kiss
+knife
+know
+knowledge
+known
+knows
+L
+labor
+laboratory
+lack
+lake
+land
+language
+large
+laser
+last
+late
+laugh
+launch
+law
+lead
+leak
+learn
+leave
+left
+legal
+legislature
+lend
+less
+let
+letter
+level
+liberal
+lie
+life
+lift
+light
+lightning
+like
+limit
+line
+link
+links
+liquid
+list
+listen
+literature
+little
+live
+liver
+load
+loan
+local
+lonely
+long
+look
+lose
+lost
+loud
+love
+low
+loyal
+luck
+lung
+M
+machine
+magazine
+magnet
+mail
+main
+major
+majority
+make
+male
+man
+manufacture
+many
+map
+march
+mark
+market
+marry
+mass
+mate
+material
+mathematics
+matter
+may
+mayor
+meal
+mean
+measure
+meat
+media
+medicine
+medicine
+meet
+melt
+member
+member
+memorial
+memory
+mental
+mercy
+message
+message
+metal
+meters
+method
+microscope
+middle
+militant
+military
+milk
+mind
+mine
+mineral
+minister
+minor
+minority
+minute
+miss
+missile
+missing
+mistake
+mistakes
+mix
+mob
+model
+moderate
+modern
+molecule
+money
+money,
+month
+moon
+moral
+more
+morning
+most
+mother
+motion
+mountain
+mourn
+move
+movement
+moves
+movie
+movie
+much
+murder
+music
+must
+mystery
+N
+n.
+name
+narrow
+nation
+native
+natural
+nature
+navy
+near
+necessary
+need
+negotiate
+neither
+nerve
+neutral
+never
+new
+news
+next
+nice
+night
+no
+noise
+nominate
+noon
+normal
+north
+not
+not
+note
+nothing
+now
+nowhere
+nuclear
+nucleic
+nucleus
+number
+nutrient
+O
+obey
+object
+observe
+occupy
+ocean
+oceans
+of
+of
+off
+offensive
+offer
+office
+officer
+official
+often
+oil
+old
+on
+once
+one
+only
+onto
+open
+operate
+opinion
+oppose
+opposite
+oppress
+or
+or
+orbit
+order
+organ
+organism
+organization
+organize
+ORGANS
+other
+others
+others,
+our
+oust
+out
+over
+overthrow
+owe
+own
+P
+pain
+paint
+pan
+paper
+parachute
+parade
+pardon
+parent
+parliament
+part
+particle
+party
+pass
+passenger
+passengers
+passport
+past
+path
+patient
+pay
+peace
+people
+percent
+perfect
+perform
+period
+permanent
+permit
+permitted
+person
+physical
+physics
+picture
+pictures
+piece
+pig
+pilot
+pipe
+place
+plan
+planet
+plant
+plants
+plastic
+play
+please
+plenty
+plot
+poem
+point
+poison
+police
+policy
+politics
+pollute
+poor
+popular
+population
+port
+position
+possess
+possible
+post
+postpone
+pour
+power
+power
+praise
+pray
+pregnant
+prep.
+preparation
+present
+presented
+president
+president
+press
+pressure
+prevent
+price
+prison
+private
+prize
+pro
+pro.
+probably
+problem
+process
+produce
+profession
+professor
+profit
+program
+progress
+project
+proof
+propaganda
+property
+propose
+prostate
+protect
+proteins
+protest
+prove
+provide
+public
+publication
+publish
+pull
+pump
+punish
+purchase
+pure
+purpose
+push
+put
+Q
+quality
+question
+quick
+quiet
+R
+race
+radar
+radiation
+radio
+radio
+raid
+railroad
+rain
+raise
+rare
+rate
+re
+reach
+reached
+react
+read
+ready
+ready
+real
+realistic
+reason
+reasonable
+rebel
+receive
+recent
+recession
+recognize
+record
+recover
+recovered
+red
+reduce
+reform
+refugee
+refuse
+regret
+reject
+related
+relations
+release
+religion
+religion,
+remain
+remains
+remember
+remembered
+remove
+repair
+repeat
+report
+report
+represent
+representation
+representative
+repress
+request
+require
+rescue
+research
+resign
+resist
+resolution
+resource
+responsibility
+responsible
+rest
+restrain
+restrict
+result
+retire
+return
+revolt
+rice
+rich
+ride
+right
+riot
+rise
+risk
+river
+road
+rob
+robot
+rock
+rocket
+roll
+room
+root
+rope
+rough
+round
+rub
+rubber
+ruin
+rule
+run
+S
+same
+saw
+science
+self
+selling
+sending
+separate
+separated
+services
+should
+side
+signal
+similar
+so
+soil
+soldier
+some
+somebody
+someone
+something
+space
+speak
+special
+speech
+speed
+spend
+spill
+spirit
+split
+sport
+sports
+spread
+spring
+spy
+square
+stab
+stand
+star
+stars
+start
+starve
+state
+States
+station
+statue
+statues
+stay
+steal
+steam
+steel
+step
+stepping
+stick
+still
+stomach
+stone
+stop
+store
+storm
+story
+stove
+straight
+strange
+street
+stretch
+strike
+strong
+structure
+struggle
+studied
+study
+studying
+stupid
+subject
+submarine
+substance
+substitute
+subversion
+succeed
+such
+sudden
+suffer
+sugar
+suggest
+summer
+sun
+supervise
+supply
+support
+suppose
+suppress
+sure
+surface
+surplus
+surplus.
+surprise
+surrender
+surround
+survive
+suspect
+suspend
+swallow
+swear
+sweet
+swim
+sympathy
+system
+T
+table
+take
+talk
+tall
+tank
+target
+taste
+tax
+tea
+teach
+teacher
+team
+tear
+tears
+technical
+technology
+telephone
+telescope
+television
+tell
+temperature
+temporary
+tense
+term
+terrible
+territory
+terror
+terrorist
+test
+than
+thank
+that
+the
+theater
+them
+then
+theory
+there
+these
+they
+thick
+thin
+thing
+think
+third
+this
+threaten
+through
+throw
+tie
+time
+tired
+tissue
+to
+to
+today
+together
+together
+together,
+tomorrow
+tonight
+too
+tool
+top
+torture
+total
+touch
+toward
+town
+trade
+tradition
+traffic
+tragic
+train
+transport
+transportation
+trap
+travel
+treason
+treasure
+treat
+treatment
+treaty
+tree
+trial
+tribe
+trick
+trip
+troops
+trouble
+truce
+truck
+trust
+try
+tube
+turn
+two
+U
+un
+under
+understand
+understanding
+unite
+universe
+university
+unless
+until
+up
+urge
+urgent
+us
+use
+used
+usual
+usually
+uterus
+V
+v.
+valley
+value
+vegetable
+vegetables
+vehicle
+version
+very
+veto
+vicious
+victim
+victory
+village
+violate
+violence
+virus
+visit
+voice
+volcano
+vote
+voters
+W
+wages
+wait
+walk
+wall
+want
+wanted
+war
+warm
+warm
+warn
+was
+wash
+waste
+watch
+water
+waterway
+wave
+way
+we
+weak
+wealth
+weapon
+wear
+weather
+week
+weigh
+welcome
+well
+west
+wet
+what
+wheat
+wheel
+when
+where
+where
+which
+while
+White
+who
+whole
+why
+wide
+wife
+wild
+will
+willing
+willingness
+win
+wind
+window
+winter
+wire
+wise
+wish
+with
+withdraw
+without
+woman
+wonder
+wonderful
+wood
+word
+WORDS
+work
+world
+worry
+worse
+worse
+worth
+wound
+wreck
+wreckage
+write
+wrong
+x-rays
+Y
+year
+yellow
+yes
+yesterday
+yet
+you
+young
+Z
+zero
+zoo
+weest
+tee st
+spell
+page
+demo
+show
+check
+plugin
+php
+server
+enable
+editor
+feature
+asynchronous
+communication
+browser
+done
+javascript
+provide
+changed
+i'm
+Terry
+student
+ibm
+am
+google
+microsoft
+soon
+hp
diff --git a/dojox/embed/Flash.js b/dojox/embed/Flash.js
index 8912081..091b33d 100644
--- a/dojox/embed/Flash.js
+++ b/dojox/embed/Flash.js
@@ -138,9 +138,6 @@ dojo.provide("dojox.embed.Flash");
 				+ 'width="' + kwArgs.width + '" '
 				+ 'height="' + kwArgs.height + '"'
 				+ ((kwArgs.style)?' style="' + kwArgs.style + '" ':'')
-				+ 'swLiveConnect="'+kwArgs.swLiveConnect+'" '
-				+ 'allowScriptAccess="' +kwArgs.allowScriptAccess+  '" '
-				+ 'allowNetworking="' +kwArgs.allowNetworking+  '" '
 
 				+ 'pluginspage="' + window.location.protocol + '//www.adobe.com/go/getflashplayer" ';
 			if(kwArgs.params){
diff --git a/dojox/embed/Quicktime.js b/dojox/embed/Quicktime.js
index 8f2521d..aac38a0 100644
--- a/dojox/embed/Quicktime.js
+++ b/dojox/embed/Quicktime.js
@@ -128,7 +128,7 @@ dojo.provide("dojox.embed.Quicktime");
 
 	dojox.embed.Quicktime=function(/* dojox.embed.__QTArgs */kwArgs, /* DOMNode */node){
 		//	summary:
-		//		Returns a reference to the HTMLObject/HTMLEmbed that is created to 
+		//		Returns a reference to the HTMLObject/HTMLEmbed that is created to
 		//		place the movie in the document.  You can use this either with or
 		//		without the new operator.  Note that with any other DOM manipulation,
 		//		you must wait until the document is finished loading before trying
@@ -175,7 +175,7 @@ dojo.provide("dojox.embed.Quicktime");
 		//	initialized: Boolean
 		//		Whether or not the QuickTime engine is available for use.
 		//	onInitialize: Function
-		//		A stub you can connect to if you are looking to fire code when the 
+		//		A stub you can connect to if you are looking to fire code when the
 		//		engine becomes available.  A note: do NOT use this stub to embed
 		//		a movie in your document; this WILL be fired before DOMContentLoaded
 		//		is fired, and you will get an error.  You should use dojo.addOnLoad
@@ -186,8 +186,8 @@ dojo.provide("dojox.embed.Quicktime");
 		supported: installed,
 		version: qtVersion,
 		initialized: false,
-		onInitialize: function(){ 
-			dojox.embed.Quicktime.initialized = true; 
+		onInitialize: function(){
+			dojox.embed.Quicktime.initialized = true;
 		},	//	stub function to let you know when this is ready
 
 		place: function(kwArgs, node){
@@ -255,7 +255,9 @@ dojo.provide("dojox.embed.Quicktime");
 		}
 		getVer();
 	}else if(d.isIE && installed){
-		// we already know if IE has QuickTime installed
-		dojox.embed.Quicktime.onInitialize();
+		// we already know if IE has QuickTime installed, but we need this to seem like a callback.
+		setTimeout(function(){
+			dojox.embed.Quicktime.onInitialize();
+		}, 10);
 	}
-})(dojo);
\ No newline at end of file
+})(dojo);
diff --git a/dojox/encoding/ascii85.js b/dojox/encoding/ascii85.js
index 79c6991..3ae7a49 100644
--- a/dojox/encoding/ascii85.js
+++ b/dojox/encoding/ascii85.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.encoding.ascii85");
+// AMD-ID "dojox/encoding/ascii85"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("encoding.ascii85", true, dojox);
 
 (function(){
 	var c = function(input, length, result){
@@ -13,7 +15,7 @@ dojo.provide("dojox.encoding.ascii85");
 			result.push(String.fromCharCode(b[4], b[3], b[2], b[1], b[0]));
 		}
 	};
-	
+
 	dojox.encoding.ascii85.encode = function(input){
 		// summary: encodes input data in ascii85 string
 		// input: Array: an array of numbers (0-255) to encode
@@ -57,3 +59,7 @@ dojo.provide("dojox.encoding.ascii85");
 		return r;
 	};
 })();
+
+
+return dojox.encoding.ascii85;
+});
diff --git a/dojox/encoding/base64.js b/dojox/encoding/base64.js
index 1b77bca..2233536 100644
--- a/dojox/encoding/base64.js
+++ b/dojox/encoding/base64.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.encoding.base64");
+// AMD-ID "dojox/encoding/base64"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("encoding.base64", true, dojox);
 
 (function(){
 	var p="=";
@@ -13,7 +15,7 @@ dojo.provide("dojox.encoding.base64");
 		var x=l-rm;
 		for (var i=0; i<x;){
 			var t=ba[i++]<<16|ba[i++]<<8|ba[i++];
-			s.push(tab.charAt((t>>>18)&0x3f)); 
+			s.push(tab.charAt((t>>>18)&0x3f));
 			s.push(tab.charAt((t>>>12)&0x3f));
 			s.push(tab.charAt((t>>>6)&0x3f));
 			s.push(tab.charAt(t&0x3f));
@@ -60,3 +62,7 @@ dojo.provide("dojox.encoding.base64");
 		return out;	//	byte[]
 	};
 })();
+
+
+return dojox.encoding.base64;
+});
diff --git a/dojox/encoding/bits.js b/dojox/encoding/bits.js
index 348fd22..f2d8637 100644
--- a/dojox/encoding/bits.js
+++ b/dojox/encoding/bits.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.encoding.bits");
+// AMD-ID "dojox/encoding/bits"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("encoding.bits", true, dojox);
 
 dojox.encoding.bits.OutputStream = function(){
 	this.reset();
@@ -62,3 +64,7 @@ dojo.extend(dojox.encoding.bits.InputStream, {
 		return this.width - this.bbyte * 8 - this.bit;
 	}
 });
+
+
+return dojox.encoding.bits;
+});
diff --git a/dojox/encoding/compression/lzw.js b/dojox/encoding/compression/lzw.js
index 272061e..4f8327e 100644
--- a/dojox/encoding/compression/lzw.js
+++ b/dojox/encoding/compression/lzw.js
@@ -1,8 +1,9 @@
-dojo.provide("dojox.encoding.compression.lzw");
-dojo.require("dojox.encoding.bits");
+// AMD-ID "dojox/encoding/compression/lzw"
+define(["dojo", "dojox", "dojox/encoding/bits"], function(dojo, dojox) {
+dojo.getObject("encoding.compression.lzw", true, dojox);
 
 (function(){
-	var _bits = function(x){
+		var _bits = function(x){
 		var w = 1;
 		for(var v = 2; x >= v; v <<= 1, ++w);
 		return w;
@@ -85,3 +86,7 @@ dojo.require("dojox.encoding.bits");
 		}
 	});
 })();
+
+
+return dojox.encoding.compression.lzw;
+});
diff --git a/dojox/encoding/compression/splay.js b/dojox/encoding/compression/splay.js
index 7582f8f..29c9d29 100644
--- a/dojox/encoding/compression/splay.js
+++ b/dojox/encoding/compression/splay.js
@@ -1,5 +1,6 @@
-dojo.provide("dojox.encoding.compression.splay");
-dojo.require("dojox.encoding.bits");
+// AMD-ID "dojox/encoding/compression/splay"
+define(["dojo", "dojox", "dojox/encoding/bits"], function(dojo, dojox) {
+dojo.getObject("encoding.compression.splay", true, dojox);
 
 dojox.encoding.compression.Splay = function(n){
 	this.up = new Array(2 * n + 1);
@@ -58,3 +59,7 @@ dojo.extend(dojox.encoding.compression.Splay, {
 		return	a;
 	}
 });
+
+
+return dojox.encoding.compression.splay;
+});
diff --git a/dojox/encoding/crypto/Blowfish.js b/dojox/encoding/crypto/Blowfish.js
index 69b21fd..3b381b7 100644
--- a/dojox/encoding/crypto/Blowfish.js
+++ b/dojox/encoding/crypto/Blowfish.js
@@ -1,7 +1,6 @@
-dojo.provide("dojox.encoding.crypto.Blowfish");
-
-dojo.require("dojox.encoding.base64");
-dojo.require("dojox.encoding.crypto._base");
+// 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);
 
 /*	Blowfish
  *	Created based on the C# implementation by Marcus Hahn (http://www.hotpixel.net/)
@@ -20,8 +19,8 @@ dojox.encoding.crypto.Blowfish = new function(){
 	var iv=null;	//	CBC mode initialization vector
 	var boxes={
 		p:[
-			0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89, 
-			0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 
+			0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+			0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c, 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
 			0x9216d5d9, 0x8979fb1b
 		],
 		s0:[
@@ -35,20 +34,20 @@ dojox.encoding.crypto.Blowfish = new function(){
 			0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193, 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
 			0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
 			0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
-			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 
-			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe, 
-			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d, 
+			0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3, 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+			0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+			0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
 			0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b, 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
 			0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
 			0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
-			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 
-			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8, 
-			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82, 
-			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 
+			0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3, 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+			0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+			0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+			0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db, 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
 			0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
-			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8, 
+			0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
 			0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4, 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
-			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c, 
+			0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
 			0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
 			0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299, 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
 			0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
@@ -66,24 +65,24 @@ dojox.encoding.crypto.Blowfish = new function(){
 			0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
 			0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
 			0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
-			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 
-			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 
+			0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+			0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
 			0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
-			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 
+			0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
 			0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
-			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509, 
-			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 
+			0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+			0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
 			0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
-			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960, 
+			0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
 			0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
-			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 
+			0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
 			0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
-			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 
-			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 
-			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281, 
+			0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+			0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+			0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
 			0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
 			0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
-			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0, 
+			0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
 			0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
 			0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
 			0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
@@ -113,49 +112,49 @@ dojox.encoding.crypto.Blowfish = new function(){
 			0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
 			0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
 			0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
-			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc, 
+			0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
 			0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
 			0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
-			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c, 
-			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 
-			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 
-			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027, 
+			0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+			0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+			0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+			0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
 			0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
 			0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
-			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc, 
+			0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
 			0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
 			0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
 		],
 		s3:[
 			0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
 			0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b, 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
-			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6, 
+			0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
 			0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
-			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 
-			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59, 
+			0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4, 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+			0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
 			0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
-			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 
-			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28, 
-			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd, 
+			0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28, 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+			0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+			0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
 			0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a, 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
-			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f, 
-			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32, 
-			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 
+			0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+			0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+			0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680, 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
 			0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
 			0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
-			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 
+			0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370, 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
 			0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
-			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd, 
-			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 
-			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f, 
-			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525, 
+			0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+			0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9, 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+			0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+			0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
 			0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1, 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
-			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e, 
+			0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
 			0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
-			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 
-			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc, 
-			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a, 
-			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 
+			0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f, 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+			0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+			0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+			0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6, 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
 			0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
 			0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
 			0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f, 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
@@ -242,16 +241,16 @@ dojox.encoding.crypto.Blowfish = new function(){
 
 		//	init the boxes
 		var pos=0, data=0, res={ left:0, right:0 }, i, j, l;
-		var box = { 
+		var box = {
 			p: dojo.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);
 			}),
-			s0:boxes.s0.slice(0), 
-			s1:boxes.s1.slice(0), 
-			s2:boxes.s2.slice(0), 
-			s3:boxes.s3.slice(0) 
+			s0:boxes.s0.slice(0),
+			s1:boxes.s1.slice(0),
+			s2:boxes.s2.slice(0),
+			s3:boxes.s3.slice(0)
 		};
 
 		//	encrypt p and the s boxes
@@ -364,12 +363,12 @@ dojox.encoding.crypto.Blowfish = new function(){
 				vector.right=o.right;
 			}
 
-			cipher.push((o.left>>24)&0xff); 
-			cipher.push((o.left>>16)&0xff); 
+			cipher.push((o.left>>24)&0xff);
+			cipher.push((o.left>>16)&0xff);
 			cipher.push((o.left>>8)&0xff);
 			cipher.push(o.left&0xff);
-			cipher.push((o.right>>24)&0xff); 
-			cipher.push((o.right>>16)&0xff); 
+			cipher.push((o.right>>24)&0xff);
+			cipher.push((o.right>>16)&0xff);
 			cipher.push((o.right>>8)&0xff);
 			cipher.push(o.right&0xff);
 			pos+=8;
@@ -404,7 +403,7 @@ dojox.encoding.crypto.Blowfish = new function(){
 		}
 		var bx = init(key);
 		var pt=[];
-	
+
 		var c=null;
 		switch(ip){
 			case dojox.encoding.crypto.outputTypes.Hex:{
@@ -475,3 +474,7 @@ dojox.encoding.crypto.Blowfish = new function(){
 
 	this.setIV("0000000000000000", dojox.encoding.crypto.outputTypes.Hex);
 }();
+
+
+return dojox.encoding.crypto.Blowfish;
+});
diff --git a/dojox/encoding/crypto/RSAKey-ext.js b/dojox/encoding/crypto/RSAKey-ext.js
index f7b85b5..607eef5 100644
--- a/dojox/encoding/crypto/RSAKey-ext.js
+++ b/dojox/encoding/crypto/RSAKey-ext.js
@@ -1,8 +1,8 @@
-dojo.provide("dojox.encoding.crypto.RSAKey-ext");
+// AMD-ID "dojox/encoding/crypto/RSAKey-ext"
+define(["dojo", "dojox", "dojox/encoding/crypto/RSAKey", "dojox/math/BigInteger-ext"], function(dojo, dojox) {
+
 dojo.experimental("dojox.encoding.crypto.RSAKey-ext");
 
-dojo.require("dojox.encoding.crypto.RSAKey");
-dojo.require("dojox.math.BigInteger-ext");
 
 (function(){
 	var BigInteger = dojox.math.BigInteger;
@@ -118,3 +118,7 @@ dojo.require("dojox.math.BigInteger-ext");
 		}
 	});
 })();
+
+
+return dojox.encoding.crypto.RSAKey;
+});
diff --git a/dojox/encoding/crypto/RSAKey.js b/dojox/encoding/crypto/RSAKey.js
index 04d7042..626cb31 100644
--- a/dojox/encoding/crypto/RSAKey.js
+++ b/dojox/encoding/crypto/RSAKey.js
@@ -1,8 +1,8 @@
-dojo.provide("dojox.encoding.crypto.RSAKey");
+// 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");
 
-dojo.require("dojox.math.BigInteger");
-dojo.require("dojox.math.random.Simple");
 
 // Copyright (c) 2005  Tom Wu
 // All Rights Reserved.
@@ -71,3 +71,7 @@ dojo.require("dojox.math.random.Simple");
 		}
 	});
 })();
+
+
+return dojox.encoding.crypto.RSAKey;
+});
diff --git a/dojox/encoding/crypto/SimpleAES.js b/dojox/encoding/crypto/SimpleAES.js
index adb8bbe..03e1fac 100644
--- a/dojox/encoding/crypto/SimpleAES.js
+++ b/dojox/encoding/crypto/SimpleAES.js
@@ -1,10 +1,9 @@
-dojo.provide("dojox.encoding.crypto.SimpleAES");
-
-dojo.require("dojox.encoding.base64");
-dojo.require("dojox.encoding.crypto._base");
+// 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]
+		// 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,
@@ -22,7 +21,7 @@ dojo.require("dojox.encoding.crypto._base");
 					 0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,
 					 0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16];
 
-		// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [§5.2]
+		// Rcon is Round Constant used for the Key Expansion [1st col is 2^(r-1) in GF(2^8)] [��5.2]
 		var Rcon = [ [0x00, 0x00, 0x00, 0x00],
 					 [0x01, 0x00, 0x00, 0x00],
 					 [0x02, 0x00, 0x00, 0x00],
@@ -33,7 +32,7 @@ dojo.require("dojox.encoding.crypto._base");
 					 [0x40, 0x00, 0x00, 0x00],
 					 [0x80, 0x00, 0x00, 0x00],
 					 [0x1b, 0x00, 0x00, 0x00],
-					 [0x36, 0x00, 0x00, 0x00] ]; 
+					 [0x36, 0x00, 0x00, 0x00] ];
 
 		/*
 		 * AES Cipher function: encrypt 'input' with Rijndael algorithm
@@ -45,11 +44,11 @@ dojo.require("dojox.encoding.crypto._base");
 		 *
 		 *	 returns byte-array encrypted value (16 bytes)
 		 */
-		function Cipher(input, w) {	   // main Cipher function [§5.1]
+		function Cipher(input, w) {	   // main Cipher function [��5.1]
 		  var Nb = 4;				// block size (in words): no of columns in state (fixed at 4 for AES)
 		  var Nr = w.length/Nb - 1; // no of rounds: 10/12/14 for 128/192/256-bit keys
 
-		  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [§3.4]
+		  var state = [[],[],[],[]];  // initialise 4xNb byte-array 'state' with input [��3.4]
 		  for (var i=0; i<4*Nb; i++) state[i%4][Math.floor(i/4)] = input[i];
 
 		  state = AddRoundKey(state, w, 0, Nb);
@@ -65,13 +64,13 @@ dojo.require("dojox.encoding.crypto._base");
 		  state = ShiftRows(state, Nb);
 		  state = AddRoundKey(state, w, Nr, Nb);
 
-		  var output = new Array(4*Nb);	 // convert state to 1-d array before returning [§3.4]
+		  var output = new Array(4*Nb);	 // convert state to 1-d array before returning [��3.4]
 		  for (var i=0; i<4*Nb; i++) output[i] = state[i%4][Math.floor(i/4)];
 		  return output;
 		}
 
 
-		function SubBytes(s, Nb) {	  // apply SBox to state S [§5.1.1]
+		function SubBytes(s, Nb) {	  // apply SBox to state S [��5.1.1]
 		  for (var r=0; r<4; r++) {
 			for (var c=0; c<Nb; c++) s[r][c] = Sbox[s[r][c]];
 		  }
@@ -79,25 +78,25 @@ dojo.require("dojox.encoding.crypto._base");
 		}
 
 
-		function ShiftRows(s, Nb) {	   // shift row r of state S left by r bytes [§5.1.2]
+		function ShiftRows(s, Nb) {	   // shift row r of state S left by r bytes [��5.1.2]
 		  var t = new Array(4);
 		  for (var r=1; r<4; r++) {
 			for (var c=0; c<4; c++) t[c] = s[r][(c+r)%Nb];	// shift into temp copy
 			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 
+		  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]
+		function MixColumns(s, Nb) {   // combine bytes of each col of state S [��5.1.3]
 		  for (var c=0; c<4; c++) {
 			var a = new Array(4);  // 'a' is a copy of the current column from 's'
-			var b = new Array(4);  // 'b' is a•{02} in GF(2^8)
+			var b = new Array(4);  // 'b' is a�ށ{02} in GF(2^8)
 			for (var i=0; i<4; i++) {
 			  a[i] = s[i][c];
 			  b[i] = s[i][c]&0x80 ? s[i][c]<<1 ^ 0x011b : s[i][c]<<1;
 			}
-			// a[n] ^ b[n] is a•{03} in GF(2^8)
+			// a[n] ^ b[n] is a�ށ{03} in GF(2^8)
 			s[0][c] = b[0] ^ a[1] ^ b[1] ^ a[2] ^ a[3]; // 2*a0 + 3*a1 + a2 + a3
 			s[1][c] = a[0] ^ b[1] ^ a[2] ^ b[2] ^ a[3]; // a0 * 2*a1 + 3*a2 + a3
 			s[2][c] = a[0] ^ a[1] ^ b[2] ^ a[3] ^ b[3]; // a0 + a1 + 2*a2 + 3*a3
@@ -107,7 +106,7 @@ dojo.require("dojox.encoding.crypto._base");
 		}
 
 
-		function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [§5.1.4]
+		function AddRoundKey(state, w, rnd, Nb) {  // xor Round Key into state S [��5.1.4]
 		  for (var r=0; r<4; r++) {
 			for (var c=0; c<Nb; c++) state[r][c] ^= w[rnd*4+c][r];
 		  }
@@ -115,7 +114,7 @@ dojo.require("dojox.encoding.crypto._base");
 		}
 
 
-		function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [§5.2]
+		function KeyExpansion(key) {  // generate Key Schedule (byte-array Nr+1 x Nb) from Key [��5.2]
 		  var Nb = 4;			 // block size (in words): no of columns in state (fixed at 4 for AES)
 		  var Nk = key.length/4	 // key length (in words): 4/6/8 for 128/192/256-bit keys
 		  var Nr = Nk + 6;		 // no of rounds: 10/12/14 for 128/192/256-bit keys
@@ -156,7 +155,7 @@ dojo.require("dojox.encoding.crypto._base");
 
 		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
 
-		/* 
+		/*
 		 * 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
@@ -166,7 +165,7 @@ dojo.require("dojox.encoding.crypto._base");
 		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 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);
@@ -176,7 +175,7 @@ dojo.require("dojox.encoding.crypto._base");
 
 		  key = key.concat(key.slice(0, nBytes-16));  // key is now 16/24/32 bytes long
 
-		  // initialise counter block (NIST SP800-38A §B.2): millisecond time-stamp for nonce in 1st 8 bytes,
+		  // initialise counter block (NIST SP800-38A ��B.2): millisecond time-stamp for nonce in 1st 8 bytes,
 		  // block counter in 2nd 8 bytes
 		  var blockSize = 16;  // block size fixed at 16 bytes / 128 bits (Nb=4) for AES
 		  var counterBlock = new Array(blockSize);	// block size fixed at 16 bytes / 128 bits (Nb=4) for AES
@@ -184,14 +183,14 @@ dojo.require("dojox.encoding.crypto._base");
 
 		  // 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; 
+		  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
@@ -232,7 +231,7 @@ dojo.require("dojox.encoding.crypto._base");
 			return ret;
 		}
 
-		/* 
+		/*
 		 * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation
 		 *
 		 *	 for each block
@@ -251,7 +250,7 @@ dojo.require("dojox.encoding.crypto._base");
 
 		  var keySchedule = KeyExpansion(key);
 
-		  ciphertext = ciphertext.split(' ');  // split ciphertext into array of block-length strings 
+		  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
@@ -302,7 +301,7 @@ dojo.require("dojox.encoding.crypto._base");
 		// summary:
 		// 		SimpleAES, ported from dojox.sql, and done without the need for
 		// 		a Google Gears worker pool.
-		// description: 
+		// description:
 		//		Taken from http://www.movable-type.co.uk/scripts/aes.html by
 		// 		Chris Veness (CLA signed); adapted for Dojo by Brad Neuberg
 		// 		(bkn3 AT columbia.edu) and moved to DojoX crypto by Tom Trenka
@@ -310,7 +309,7 @@ dojo.require("dojox.encoding.crypto._base");
 		//
 		// 		A few notes:
 		// 		1) This algorithm uses a customized version of CBC mode by creating
-		// 		a nonce, using it as an initialization vector, and storing the 
+		// 		a nonce, using it as an initialization vector, and storing the
 		// 		IV as the first portion of the encrypted text.  Because of this, it
 		// 		is HIGHLY PROBABLE that it will NOT be usable by other AES implementations.
 		// 		2) All encoding is done in hex format; other encoding formats (such
@@ -321,7 +320,7 @@ dojo.require("dojox.encoding.crypto._base");
 		// 		length) with null bytes.
 		this.encrypt = function(/* String */plaintext, /* String */key){
 			//	summary:
-			//		Encrypt the passed plaintext using the key, with a 
+			//		Encrypt the passed plaintext using the key, with a
 			//		hardcoded bit depth of 256.
 			return AESEncryptCtr(plaintext, key, 256);	//	String
 		};
@@ -331,5 +330,9 @@ dojo.require("dojox.encoding.crypto._base");
 			//		bit depth of 256.
 			return AESDecryptCtr(ciphertext, key, 256);	//	String
 		};
-	})();	
+	})();
 })();
+
+
+return dojox.encoding.crypto.SimpleAES;
+});
diff --git a/dojox/encoding/crypto/_base.js b/dojox/encoding/crypto/_base.js
index c599b01..3b8f133 100644
--- a/dojox/encoding/crypto/_base.js
+++ b/dojox/encoding/crypto/_base.js
@@ -1,15 +1,21 @@
-dojo.provide("dojox.encoding.crypto._base");
+// AMD-ID "dojox/encoding/crypto/_base"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("encoding.crypto", true, dojox);
 
 (function(){
 	var c=dojox.encoding.crypto;
 	c.cipherModes={
 		//	summary
 		//	Enumeration for various cipher modes.
-		ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5 
+		ECB:0, CBC:1, PCBC:2, CFB:3, OFB:4, CTR:5
 	};
-	c.outputTypes={ 
+	c.outputTypes={
 		//	summary
 		//	Enumeration for input and output encodings.
-		Base64:0, Hex:1, String:2, Raw:3 
+		Base64:0, Hex:1, String:2, Raw:3
 	};
 })();
+
+
+return dojox.encoding.crypto;
+});
diff --git a/dojox/encoding/digests/MD5.js b/dojox/encoding/digests/MD5.js
index f061e91..b13c7aa 100644
--- a/dojox/encoding/digests/MD5.js
+++ b/dojox/encoding/digests/MD5.js
@@ -1,6 +1,5 @@
-dojo.provide("dojox.encoding.digests.MD5");
-
-dojo.require("dojox.encoding.digests._base");
+// AMD-ID "dojox/encoding/digests/MD5"
+define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox) {
 
 /*	A port of Paul Johnstone's MD5 implementation
  *	http://pajhome.org.uk/crypt/md5/index.html
@@ -115,7 +114,7 @@ dojo.require("dojox.encoding.digests._base");
 
 	function hmac(data, key){
 		var wa=dxd.stringToWord(key);
-		if(wa.length>16){ 
+		if(wa.length>16){
 			wa=core(wa, key.length*chrsz);
 		}
 		var l=[], r=[];
@@ -171,3 +170,7 @@ dojo.require("dojox.encoding.digests._base");
 		}
 	};
 })();
+
+
+return dojox.encoding.digests.MD5;
+});
diff --git a/dojox/encoding/digests/SHA1.js b/dojox/encoding/digests/SHA1.js
index 6909218..7409322 100644
--- a/dojox/encoding/digests/SHA1.js
+++ b/dojox/encoding/digests/SHA1.js
@@ -1,5 +1,5 @@
-dojo.provide("dojox.encoding.digests.SHA1");
-dojo.require("dojox.encoding.digests._base");
+// AMD-ID "dojox/encoding/digests/SHA1"
+define(["dojo", "dojox", "dojox/encoding/digests/_base"], function(dojo, dojox) {
 
 /*
  * A port of Paul Johnstone's SHA1 implementation
@@ -15,7 +15,7 @@ dojo.require("dojox.encoding.digests._base");
 	var dxd=dojox.encoding.digests;
 	var chrsz=8,	//	change to 16 for unicode.
 		mask=(1<<chrsz)-1;
-	
+
 	function R(n,c){ return (n<<c)|(n>>>(32-c)); }
 	function FT(t,b,c,d){
 		if(t<20){ return (b&c)|((~b)&d); }
@@ -148,3 +148,7 @@ dojo.require("dojox.encoding.digests._base");
 		}
 	};
 })();
+
+
+return dojox.encoding.digests.SHA1;
+});
diff --git a/dojox/encoding/digests/_base.js b/dojox/encoding/digests/_base.js
index 7bc7c75..dc14807 100644
--- a/dojox/encoding/digests/_base.js
+++ b/dojox/encoding/digests/_base.js
@@ -1,13 +1,15 @@
-dojo.provide("dojox.encoding.digests._base");
+// AMD-ID "dojox/encoding/digests/_base"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("encoding.digests", true, dojox);
 
 (function(){
 	//TODO: see if it makes sense to meld this into one with the
 	//	crypto base enums
 	var d=dojox.encoding.digests;
-	d.outputTypes={ 
+	d.outputTypes={
 		//	summary:
 		//		Enumeration for input and output encodings.
-		Base64:0, Hex:1, String:2, Raw:3 
+		Base64:0, Hex:1, String:2, Raw:3
 	};
 
 	//	word-based addition
@@ -24,7 +26,7 @@ dojo.provide("dojox.encoding.digests._base");
 	//	than the encoding version (which works on bytes).
 	var chrsz=8;	//	16 for Unicode
 	var mask=(1<<chrsz)-1;
-	
+
 	d.stringToWord=function(/* string */s){
 		//	summary:
 		//		convert a string to a word array
@@ -34,7 +36,7 @@ dojo.provide("dojox.encoding.digests._base");
 		}
 		return wa;	//	word[]
 	};
-	
+
 	d.wordToString=function(/* word[] */wa){
 		//	summary:
 		//		convert an array of words to a string
@@ -44,7 +46,7 @@ dojo.provide("dojox.encoding.digests._base");
 		}
 		return s.join("");	//	string
 	}
-	
+
 	d.wordToHex=function(/* word[] */wa){
 		//	summary:
 		//		convert an array of words to a hex tab
@@ -72,3 +74,7 @@ dojo.provide("dojox.encoding.digests._base");
 		return s.join("");	//	string
 	};
 })();
+
+
+return dojox.encoding.digests;
+});
diff --git a/dojox/encoding/easy64.js b/dojox/encoding/easy64.js
index 8f8fd50..1f6ddc2 100644
--- a/dojox/encoding/easy64.js
+++ b/dojox/encoding/easy64.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.encoding.easy64");
+// AMD-ID "dojox/encoding/easy64"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("encoding.easy64", true, dojox);
 
 (function(){
 	var c = function(input, length, result){
@@ -11,7 +13,7 @@ dojo.provide("dojox.encoding.easy64");
 			);
 		}
 	};
-	
+
 	dojox.encoding.easy64.encode = function(input){
 		// summary: encodes input data in easy64 string
 		// input: Array: an array of numbers (0-255) to encode
@@ -44,3 +46,7 @@ dojo.provide("dojox.encoding.easy64");
 		return r;
 	};
 })();
+
+
+return dojox.encoding.easy64;
+});
diff --git a/dojox/encoding/tests/digests/MD5.js b/dojox/encoding/tests/digests/MD5.js
index 085abb5..0422be4 100644
--- a/dojox/encoding/tests/digests/MD5.js
+++ b/dojox/encoding/tests/digests/MD5.js
@@ -13,10 +13,10 @@ dojo.require("dojox.encoding.digests.MD5");
 			t.assertEqual(base64, ded.MD5(message));
 		},
 		function testHexCompute(t){
-			t.assertEqual(hex, ded.MD5(message, ded.outputTypes.Hex)); 
+			t.assertEqual(hex, ded.MD5(message, ded.outputTypes.Hex));
 		},
 		function testStringCompute(t){
-			t.assertEqual(s, ded.MD5(message, ded.outputTypes.String)); 
+			t.assertEqual(s, ded.MD5(message, ded.outputTypes.String));
 		}
 	]);
 })();
diff --git a/dojox/encoding/tests/digests/SHA1.js b/dojox/encoding/tests/digests/SHA1.js
index 45bd42a..bda28ef 100644
--- a/dojox/encoding/tests/digests/SHA1.js
+++ b/dojox/encoding/tests/digests/SHA1.js
@@ -13,10 +13,10 @@ dojo.require("dojox.encoding.digests.SHA1");
 			t.assertEqual(base64, ded.SHA1(message));
 		},
 		function testHexCompute(t){
-			t.assertEqual(hex, ded.SHA1(message, ded.outputTypes.Hex)); 
+			t.assertEqual(hex, ded.SHA1(message, ded.outputTypes.Hex));
 		},
 		function testStringCompute(t){
-			t.assertEqual(s, ded.SHA1(message, ded.outputTypes.String)); 
+			t.assertEqual(s, ded.SHA1(message, ded.outputTypes.String));
 		}
 	]);
 })();
diff --git a/dojox/flash/_base.js b/dojox/flash/_base.js
index 8d9cd0f..ec65c3a 100644
--- a/dojox/flash/_base.js
+++ b/dojox/flash/_base.js
@@ -11,72 +11,72 @@ dojox.flash = function(){
 	// description:
 	//	The goal of dojox.flash is to make it easy to extend Flash's capabilities
 	//	into an Ajax/DHTML environment.
-	//  
-	//	dojox.flash provides an easy object for interacting with the Flash plugin. 
+	//
+	//	dojox.flash provides an easy object for interacting with the Flash plugin.
 	//	This object provides methods to determine the current version of the Flash
-	//	plugin (dojox.flash.info); write out the necessary markup to 
-	//	dynamically insert a Flash object into the page (dojox.flash.Embed; and 
-	//	do dynamic installation and upgrading of the current Flash plugin in 
+	//	plugin (dojox.flash.info); write out the necessary markup to
+	//	dynamically insert a Flash object into the page (dojox.flash.Embed; and
+	//	do dynamic installation and upgrading of the current Flash plugin in
 	//	use (dojox.flash.Install). If you want to call methods on the Flash object
 	//	embedded into the page it is your responsibility to use Flash's ExternalInterface
 	//	API and get a reference to the Flash object yourself.
-	//		
-	//	To use dojox.flash, you must first wait until Flash is finished loading 
-	//	and initializing before you attempt communication or interaction. 
+	//
+	//	To use dojox.flash, you must first wait until Flash is finished loading
+	//	and initializing before you attempt communication or interaction.
 	//	To know when Flash is finished use dojo.connect:
-	//		
+	//
 	//|	dojo.connect(dojox.flash, "loaded", myInstance, "myCallback");
-	//		
+	//
 	//	Then, while the page is still loading provide the file name:
-	//		
+	//
 	//|	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"));
-	//			
+	//
 	//	If no SWF files are specified, then Flash is not initialized.
-	//		
+	//
 	//	Your Flash must use Flash's ExternalInterface to expose Flash methods and
 	//	to call JavaScript.
-	//		
+	//
 	//	setSwf can take an optional 'visible' attribute to control whether
 	//	the Flash object is visible or not on the page; the default is visible:
-	//		
+	//
 	//|	dojox.flash.setSwf(dojo.moduleUrl("dojox", "_storage/storage.swf"),
 	//						false);
-	//		
+	//
 	//	Once finished, you can query Flash version information:
-	//		
+	//
 	//|	dojox.flash.info.version
-	//		
-	//	Or can communicate with Flash methods that were exposed:	
+	//
+	//	Or can communicate with Flash methods that were exposed:
 	//
 	//|	var f = dojox.flash.get();
-	//|	var results = f.sayHello("Some Message");	
-	// 
+	//|	var results = f.sayHello("Some Message");
+	//
 	//	Your Flash files should use DojoExternalInterface.as to register methods;
 	//	this file wraps Flash's normal ExternalInterface but correct various
 	//	serialization bugs that ExternalInterface has.
 	//
 	//	Note that dojox.flash is not meant to be a generic Flash embedding
 	//	mechanism; it is as generic as necessary to make Dojo Storage's
-	//	Flash Storage Provider as clean and modular as possible. If you want 
+	//	Flash Storage Provider as clean and modular as possible. If you want
 	//	a generic Flash embed mechanism see [SWFObject](http://blog.deconcept.com/swfobject/).
 	//
 	// 	Notes:
 	//	Note that dojox.flash can currently only work with one Flash object
 	//	on the page; it does not yet support multiple Flash objects on
-	//	the same page. 
-	//		
+	//	the same page.
+	//
 	//	Your code can detect whether the Flash player is installing or having
 	//	its version revved in two ways. First, if dojox.flash detects that
 	//	Flash installation needs to occur, it sets dojox.flash.info.installing
 	//	to true. Second, you can detect if installation is necessary with the
 	//	following callback:
-	//		
+	//
 	//|	dojo.connect(dojox.flash, "installing", myInstance, "myCallback");
-	//		
+	//
 	//	You can use this callback to delay further actions that might need Flash;
 	//	when installation is finished the full page will be refreshed and the
 	//	user will be placed back on your page with Flash installed.
-	//		
+	//
 	//	-------------------
 	//	Todo/Known Issues
 	//	-------------------
@@ -89,7 +89,7 @@ dojox.flash = function(){
 	//	to initialize the dojox.flash subsystem.
 	//	* Things aren't super tested for sending complex objects to Flash
 	//	methods, since Dojo Storage only needs strings
-	//		
+	//
 	//	Author- Brad Neuberg, http://codinginparadise.org
 }
 
@@ -106,7 +106,7 @@ dojox.flash = {
 		// url: String
 		//	The URL to this Flash file.
 		// visible: boolean?
-		//	Whether the Flash file is visible or not. If it is not visible we hide 
+		//	Whether the Flash file is visible or not. If it is not visible we hide
 		//	it off the screen. This defaults to true (i.e. the Flash file is
 		//	visible).
 		this.url = url;
@@ -116,13 +116,13 @@ dojox.flash = {
 			this._visible = visible;
 		}
 		
-		// initialize ourselves		
+		// initialize ourselves
 		this._initialize();
 	},
 	
 	addLoadedListener: function(/* Function */ listener){
 		// summary:
-		//	Adds a listener to know when Flash is finished loading. 
+		//	Adds a listener to know when Flash is finished loading.
 		//	Useful if you don't want a dependency on dojo.event.
 		// listener: Function
 		//	A function that will be called when Flash is done loading.
@@ -132,21 +132,21 @@ dojox.flash = {
 
 	addInstallingListener: function(/* Function */ listener){
 		// summary:
-		//	Adds a listener to know if Flash is being installed. 
+		//	Adds a listener to know if Flash is being installed.
 		//	Useful if you don't want a dependency on dojo.event.
 		// listener: Function
 		//	A function that will be called if Flash is being
 		//	installed
 		
 		this._installingListeners.push(listener);
-	},	
+	},
 	
 	loaded: function(){
 		// summary: Called back when the Flash subsystem is finished loading.
 		// description:
 		//	A callback when the Flash subsystem is finished loading and can be
 		//	worked with. To be notified when Flash is finished loading, add a
-		//  loaded listener: 
+		//  loaded listener:
 		//
 		//  dojox.flash.addLoadedListener(loadedListener);
 	
@@ -164,7 +164,7 @@ dojox.flash = {
 		//	A callback to know if Flash is currently being installed or
 		//	having its version revved. To be notified if Flash is installing, connect
 		//	your callback to this method using the following:
-		//	
+		//
 		//	dojo.event.connect(dojox.flash, "installing", myInstance, "myCallback");
 		
 		if(dojox.flash._installingListeners.length){ // FIXME: redundant if? use forEach?
@@ -181,7 +181,7 @@ dojox.flash = {
 		var installer = new dojox.flash.Install();
 		dojox.flash.installer = installer;
 
-		if(installer.needed()){		
+		if(installer.needed()){
 			installer.install();
 		}else{
 			// write the flash object into the page
@@ -201,9 +201,9 @@ dojox.flash.Info = function(){
 	//	A class that helps us determine whether Flash is available,
 	//	it's major and minor versions, and what Flash version features should
 	//	be used for Flash/JavaScript communication. Parts of this code
-	//	are adapted from the automatic Flash plugin detection code autogenerated 
-	//	by the Macromedia Flash 8 authoring environment. 
-	//	
+	//	are adapted from the automatic Flash plugin detection code autogenerated
+	//	by the Macromedia Flash 8 authoring environment.
+	//
 	//	An instance of this class can be accessed on dojox.flash.info after
 	//	the page is finished loading.
 
@@ -218,7 +218,7 @@ dojox.flash.Info.prototype = {
 	// versionMajor, versionMinor, versionRevision: String
 	//		The major, minor, and revisions of the plugin. For example, if the
 	//		plugin is 8r22, then the major version is 8, the minor version is 0,
-	//		and the revision is 22. 
+	//		and the revision is 22.
 	versionMajor: -1,
 	versionMinor: -1,
 	versionRevision: -1,
@@ -232,18 +232,18 @@ dojox.flash.Info.prototype = {
 	installing: false,
 	
 	isVersionOrAbove: function(
-							/* int */ reqMajorVer, 
-							/* int */ reqMinorVer, 
+							/* int */ reqMajorVer,
+							/* int */ reqMinorVer,
 							/* int */ reqVer){ /* Boolean */
-		// summary: 
+		// summary:
 		//	Asserts that this environment has the given major, minor, and revision
 		//	numbers for the Flash player.
 		// description:
 		//	Asserts that this environment has the given major, minor, and revision
-		//	numbers for the Flash player. 
-		//	
+		//	numbers for the Flash player.
+		//
 		//	Example- To test for Flash Player 7r14:
-		//	
+		//
 		//	dojox.flash.info.isVersionOrAbove(7, 0, 14)
 		// returns:
 		//	Returns true if the player is equal
@@ -264,13 +264,13 @@ dojox.flash.Info.prototype = {
 	_detectVersion: function(){
 		var versionStr;
 		
-		// loop backwards through the versions until we find the newest version	
+		// loop backwards through the versions until we find the newest version
 		for(var testVersion = 25; testVersion > 0; testVersion--){
 			if(dojo.isIE){
 				var axo;
 				try{
 					if(testVersion > 6){
-						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." 
+						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash."
 																		+ testVersion);
 					}else{
 						axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
@@ -285,11 +285,11 @@ dojox.flash.Info.prototype = {
 					continue;
 				}
 			}else{
-				versionStr = this._JSFlashInfo(testVersion);		
+				versionStr = this._JSFlashInfo(testVersion);
 			}
 				
 			if(versionStr == -1 ){
-				this.capable = false; 
+				this.capable = false;
 				return;
 			}else if(versionStr != 0){
 				var versionArray;
@@ -316,13 +316,13 @@ dojox.flash.Info.prototype = {
 		}
 	},
 	 
-	// JavaScript helper required to detect Flash Player PlugIn version 
+	// JavaScript helper required to detect Flash Player PlugIn version
 	// information. Internet Explorer uses a corresponding Visual Basic
-	// version to interact with the Flash ActiveX control. 
+	// version to interact with the Flash ActiveX control.
 	_JSFlashInfo: function(testVersion){
 		// NS/Opera version >= 3 check for Flash plugin in plugin array
 		if(navigator.plugins != null && navigator.plugins.length > 0){
-			if(navigator.plugins["Shockwave Flash 2.0"] || 
+			if(navigator.plugins["Shockwave Flash 2.0"] ||
 				 navigator.plugins["Shockwave Flash"]){
 				var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
 				var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
@@ -355,11 +355,11 @@ dojox.flash.Embed = function(visible){
 dojox.flash.Embed.prototype = {
 	// width: int
 	//	The width of this Flash applet. The default is the minimal width
-	//	necessary to show the Flash settings dialog. Current value is 
+	//	necessary to show the Flash settings dialog. Current value is
 	//  215 pixels.
 	width: 215,
 	
-	// height: int 
+	// height: int
 	//	The height of this Flash applet. The default is the minimal height
 	//	necessary to show the Flash settings dialog. Current value is
 	// 138 pixels.
@@ -387,7 +387,7 @@ dojox.flash.Embed.prototype = {
 		// summary: Writes the Flash into the page.
 		// description:
 		//	This must be called before the page
-		//	is finished loading. 
+		//	is finished loading.
 		// doExpressInstall: Boolean
 		//	Whether to write out Express Install
 		//	information. Optional value; defaults to false.
@@ -410,7 +410,7 @@ dojox.flash.Embed.prototype = {
 			                + "&MMdoctitle=" + docTitle
 			                + "&baseUrl=" + escape(dojoUrl)
 			                + "&xdomain=" + escape(xdomainBase);
-			swflocEmbed += "?MMredirectURL=" + redirectURL 
+			swflocEmbed += "?MMredirectURL=" + redirectURL
 			                + "&MMplayerType=PlugIn"
 			                + "&baseUrl=" + escape(dojoUrl)
 			                + "&xdomain=" + escape(xdomainBase);
@@ -418,7 +418,7 @@ dojox.flash.Embed.prototype = {
 			// IE/Flash has an evil bug that shows up some time: if we load the
 			// Flash and it isn't in the cache, ExternalInterface works fine --
 			// however, the second time when its loaded from the cache a timing
-			// bug can keep ExternalInterface from working. The trick below 
+			// bug can keep ExternalInterface from working. The trick below
 			// simply invalidates the Flash object in the cache all the time to
 			// keep it loading fresh. -- Brad Neuberg
 			swflocObject += "?cachebust=" + new Date().getTime();
@@ -497,7 +497,7 @@ dojox.flash.Embed.prototype = {
 			body = body[0];
 			body.appendChild(div);
 		}));
-	},  
+	},
 	
 	get: function(){ /* Object */
 		// summary: Gets the Flash object DOM node.
@@ -508,7 +508,7 @@ dojox.flash.Embed.prototype = {
 		}else{
 			// different IDs on OBJECT and EMBED tags or
 			// else Firefox will return wrong one and
-			// communication won't work; 
+			// communication won't work;
 			// also, document.getElementById() returns a
 			// plugin but ExternalInterface calls don't
 			// work on it so we have to use
@@ -520,7 +520,7 @@ dojox.flash.Embed.prototype = {
 	setVisible: function(/* Boolean */ visible){
 		//console.debug("setVisible, visible="+visible);
 		
-		// summary: Sets the visibility of this Flash object.		
+		// summary: Sets the visibility of this Flash object.
 		var container = dojo.byId(this.id + "Container");
 		if(visible){
 			container.style.position = "absolute"; // IE -- Brad Neuberg
@@ -540,9 +540,9 @@ dojox.flash.Embed.prototype = {
 
 		var viewport = dojo.window.getBox();
 
-		// compute the centered position    
+		// compute the centered position
 		var x = viewport.l + (viewport.w - elementWidth) / 2;
-		var y = viewport.t + (viewport.h - elementHeight) / 2; 
+		var y = viewport.t + (viewport.h - elementHeight) / 2;
 		
 		// set the centered position
 		var container = dojo.byId(this.id + "Container");
@@ -557,13 +557,13 @@ dojox.flash.Communicator = function(){
 	//	A class that is used to communicate between Flash and JavaScript.
 	// description:
 	//	This class helps mediate Flash and JavaScript communication. Internally
-	//	it uses Flash 8's ExternalInterface API, but adds functionality to fix 
+	//	it uses Flash 8's ExternalInterface API, but adds functionality to fix
 	//	various encoding bugs that ExternalInterface has.
 }
 
 dojox.flash.Communicator.prototype = {
 	// Registers the existence of a Flash method that we can call with
-	// JavaScript, using Flash 8's ExternalInterface. 
+	// JavaScript, using Flash 8's ExternalInterface.
 	_addExternalInterfaceCallback: function(methodName){
 		//console.debug("addExternalInterfaceCallback, methodName="+methodName);
 		var wrapperCall = dojo.hitch(this, function(){
@@ -594,7 +594,7 @@ dojox.flash.Communicator.prototype = {
 		// transforming \ into \\ doesn't work; just use a custom encoding
 		data = data.replace("\\", "&custom_backslash;");
 
-		// also use custom encoding for the null character to avoid problems 
+		// also use custom encoding for the null character to avoid problems
 		data = data.replace(/\0/g, "&custom_null;");
 
 		return data;
@@ -617,11 +617,11 @@ dojox.flash.Communicator.prototype = {
 			return data;
 		}
 		
-		// needed for IE; \0 is the NULL character 
+		// needed for IE; \0 is the NULL character
 		data = data.replace(/\&custom_null\;/g, "\0");
 	
 		// certain XMLish characters break Flash's wire serialization for
-		// ExternalInterface; these are encoded on the 
+		// ExternalInterface; these are encoded on the
 		// DojoExternalInterface side into a custom encoding, rather than
 		// the standard entity encoding, because otherwise we won't be able to
 		// differentiate between our own encoding and any entity characters
@@ -647,22 +647,22 @@ dojox.flash.Communicator.prototype = {
 			}
 		}
 
-		// we use this gnarly hack below instead of 
+		// we use this gnarly hack below instead of
 		// plugin[methodName] for two reasons:
 		// 1) plugin[methodName] has no call() method, which
 		// means we can't pass in multiple arguments dynamically
 		// to a Flash method -- we can only have one
-		// 2) On IE plugin[methodName] returns undefined -- 
+		// 2) On IE plugin[methodName] returns undefined --
 		// plugin[methodName] used to work on IE when we
 		// used document.write but doesn't now that
 		// we use dynamic DOM insertion of the Flash object
 		// -- Brad Neuberg
-		var flashExec = function(){ 
+		var flashExec = function(){
 			return eval(plugin.CallFunction(
 						 "<invoke name=\"" + methodName
-						+ "\" returntype=\"javascript\">" 
-						+ __flash__argumentsToXML(methodArgs, 0) 
-						+ "</invoke>")); 
+						+ "\" returntype=\"javascript\">"
+						+ __flash__argumentsToXML(methodArgs, 0)
+						+ "</invoke>"));
 		};
 		var results = flashExec.call(methodArgs);
 		
@@ -676,10 +676,10 @@ dojox.flash.Communicator.prototype = {
 
 // FIXME: dojo.declare()-ify this
 
-// TODO: I did not test the Install code when I refactored Dojo Flash from 0.4 to 
-// 1.0, so am not sure if it works. If Flash is not present I now prefer 
+// TODO: I did not test the Install code when I refactored Dojo Flash from 0.4 to
+// 1.0, so am not sure if it works. If Flash is not present I now prefer
 // that Gears is installed instead of Flash because GearsStorageProvider is
-// much easier to work with than Flash's hacky ExternalInteface. 
+// much easier to work with than Flash's hacky ExternalInteface.
 // -- Brad Neuberg
 dojox.flash.Install = function(){
 	// summary: Helps install Flash plugin if needed.
@@ -693,7 +693,7 @@ dojox.flash.Install.prototype = {
 	needed: function(){ /* Boolean */
 		// summary:
 		//		Determines if installation or revving of the current plugin is
-		//		needed. 
+		//		needed.
 	
 		// do we even have flash?
 		if(!dojox.flash.info.capable){
@@ -751,7 +751,7 @@ dojox.flash.Install.prototype = {
 			alert("There was an error downloading the Flash Player update. "
 						+ "Please try again later, or visit macromedia.com to download "
 						+ "the latest version of the Flash plugin.");
-		}	
+		}
 	}
 }
 
diff --git a/dojox/flash/tests/test_flash.js b/dojox/flash/tests/test_flash.js
index a514dca..299fb51 100644
--- a/dojox/flash/tests/test_flash.js
+++ b/dojox/flash/tests/test_flash.js
@@ -21,7 +21,7 @@ function flashReady(){
 
 function pageReady(){
 	console.debug("pageReady");
-	if (pageLoaded) { 
+	if (pageLoaded) {
 	  return; // prevent double loads
 	}
 	
@@ -54,7 +54,7 @@ function loadResources(){
 		}
 	});
 
-	d.addErrback(function(error){ 
+	d.addErrback(function(error){
 		console.debug("Unable to load testXML.xml: " + error);
 	});
 	
@@ -71,7 +71,7 @@ function loadResources(){
 		}
 	});
 
-	d.addErrback(function(error){ 
+	d.addErrback(function(error){
 		console.debug("Unable to load testXML.xml: " + error);
 	});
 }
@@ -93,10 +93,10 @@ function run(){
 		// slashes; do a trick so that they can be compared easier
 		var doubleSlash = "\\";
 		doubleSlash = doubleSlash.charAt(0);
-		correct = "hello world\n\n\nasdfasdf!@#$@#%^[]{}&<xml>" + doubleSlash 
-						+ "<div>$%^&%^&*^&()<><><>,./;\0\r\f\'][`~=\"+-]\\0MORE!\n\rLESS"; 
-		var putSize = dojox.flash.comm.setMessage(correct); 
-		assert(putSize, correct.length, "Failed putting. Correct length = " 
+		correct = "hello world\n\n\nasdfasdf!@#$@#%^[]{}&<xml>" + doubleSlash
+						+ "<div>$%^&%^&*^&()<><><>,./;\0\r\f\'][`~=\"+-]\\0MORE!\n\rLESS";
+		var putSize = dojox.flash.comm.setMessage(correct);
+		assert(putSize, correct.length, "Failed putting. Correct length = "
 						+ correct.length + ", Flash length = " + putSize);
 		dojox.flash.comm.setMessage(correct);
 		actual = dojox.flash.comm.getMessage();
@@ -147,26 +147,26 @@ function run(){
 	}
 }
 
-function chop(testString){ 
-	console.debug("chopping '" + testString + "'"); 
-	for(var i = 0; i < Math.min(testString.length, 100); i++){ 
-		//console.debug("index = " + i); 
-		testSlice(testString, 0, i+1); 
-	} 
-} 
+function chop(testString){
+	console.debug("chopping '" + testString + "'");
+	for(var i = 0; i < Math.min(testString.length, 100); i++){
+		//console.debug("index = " + i);
+		testSlice(testString, 0, i+1);
+	}
+}
  
-function testSlice( testString, from, to){ 
-	var putSize = dojox.flash.comm.setMessageSlice( testString, from, to); 
-	var actual = dojox.flash.comm.getMessage(); 
+function testSlice( testString, from, to){
+	var putSize = dojox.flash.comm.setMessageSlice( testString, from, to);
+	var actual = dojox.flash.comm.getMessage();
 	var correct = testString.slice(from, to);
 	
-	var msg = "Put a string with " + testString.length 
+	var msg = "Put a string with " + testString.length
 					+ " chars, but it got with " + putSize + " chars in the Flash layer";
 	assert(putSize, testString.length, msg);
 	
 	msg = "I got '" + actual + "' instead of '" + correct +"'";
-	assert(correct, actual, msg); 
-} 
+	assert(correct, actual, msg);
+}
 
 function assert(correct, actual, msg){
 	//alert("correct="+correct+",\n\nactual="+actual);
diff --git a/dojox/form/BusyButton.js b/dojox/form/BusyButton.js
index 5ff18d7..ffe852a 100644
--- a/dojox/form/BusyButton.js
+++ b/dojox/form/BusyButton.js
@@ -5,10 +5,10 @@ dojo.require("dijit.form.Button");
 dojo.requireLocalization("dijit", "loading");
 
 dojo.declare("dojox.form._BusyButtonMixin",
-	null, 
+	null,
 	{
 		
-	isBusy: false,	
+	isBusy: false,
 	busyLabel: "", // text while button is busy
 	timeout: null, // timeout, should be controlled by xhr call
 	useIcon: true, // use a busy icon
@@ -56,15 +56,15 @@ dojo.declare("dojox.form._BusyButtonMixin",
 	resetTimeout: function(/*Int*/ timeout){
 		// summary:
 		//	to reset existing timeout and setting a new timeout
-		if(this._timeout){	
-			clearTimeout(this._timeout); 
+		if(this._timeout){
+			clearTimeout(this._timeout);
 		}
 		
 		// new timeout
 		if(timeout){
 			this._timeout = setTimeout(dojo.hitch(this, function(){
 				this.cancel();
-			}), timeout);			
+			}), timeout);
 		}else if(timeout == undefined || timeout === 0){
 			this.cancel();
 		}
@@ -109,10 +109,10 @@ dojo.declare("dojox.form._BusyButtonMixin",
 	
 	_clicked: 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){ 
+		if(!this.isBusy){
 			this.makeBusy();
 		}
 	}
diff --git a/dojox/form/CheckedMultiSelect.js b/dojox/form/CheckedMultiSelect.js
index db8e0bf..93199b5 100644
--- a/dojox/form/CheckedMultiSelect.js
+++ b/dojox/form/CheckedMultiSelect.js
@@ -1,9 +1,10 @@
 dojo.provide("dojox.form.CheckedMultiSelect");
 
 dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.Tooltip");
 dojo.require("dijit.form._FormSelectWidget");
 
-dojo.declare("dojox.form._CheckedMultiSelectItem", 
+dojo.declare("dojox.form._CheckedMultiSelectItem",
 	[dijit._Widget, dijit._Templated],
 	{
 	// summary:
@@ -51,13 +52,13 @@ dojo.declare("dojox.form._CheckedMultiSelectItem",
 	_changeBox: function(){
 		// summary:
 		//		Called to force the select to match the state of the check box
-		//		(only on click of the checkbox)  Radio-based calls _setValueAttr
+		//		(only on click of the checkbox)	 Radio-based calls _setValueAttr
 		//		instead.
 		if(this.get("disabled") || this.get("readOnly")){ return; }
 		if(this.parent.multiple){
-			this.option.selected = this.checkBox.attr('value') && true;
+			this.option.selected = this.checkBox.get('value') && true;
 		}else{
-			this.parent.attr('value', this.option.value);
+			this.parent.set('value', this.option.value);
 		}
 		// fire the parent's change
 		this.parent._updateSelection();
@@ -79,21 +80,21 @@ dojo.declare("dojox.form._CheckedMultiSelectItem",
 	_updateBox: function(){
 		// summary:
 		//		Called to force the box to match the state of the select
-		this.checkBox.attr('value', this.option.selected);
+		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.attr("disabled", this.disabled);
+		this.checkBox.set("disabled", this.disabled);
 		dojo.toggleClass(this.domNode, "dojoxMultiSelectDisabled", this.disabled);
 	},
 	
 	_setReadOnlyAttr: function(value){
 		// summary:
 		//		Sets read only (or unsets) all the children as well
-		this.checkBox.attr("readOnly", value);
+		this.checkBox.set("readOnly", value);
 		this.readOnly = value;
 	}
 });
@@ -105,6 +106,22 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 	templateString: dojo.cache("dojox.form", "resources/CheckedMultiSelect.html"),
 
 	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.",
+	
+	// _message: String
+	//		Currently displayed message
+	_message: "",
+	
+	// tooltipPosition: String[]
+	//		See description of `dijit.Tooltip.defaultPosition` for details on this parameter.
+	tooltipPosition: [],
 
 	_onMouseDown: function(e){
 		// summary:
@@ -113,15 +130,90 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 		dojo.stopEvent(e);
 	},
 	
+	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){
+			return opt.selected && opt.value != null && opt.value.toString().length != 0;
+		});
+	},
+	
+	validate: function(isFocused) {
+		dijit.hideTooltip(this.domNode);
+		var isValid = this.isValid(isFocused);
+		if(!isValid){ this.displayMessage(this.invalidMessage); }
+		return isValid;
+	},
+	
+	isValid: function(/*Boolean*/ isFocused) {
+		// summary:
+		//		Tests if the required items are selected.
+		//		Can override with your own routine in a subclass.
+		// tags:
+		//		protected
+		return this.validator();
+	},
+
+	getErrorMessage: function(/*Boolean*/ isFocused) {
+		// summary:
+		//		Return an error message to show if appropriate
+		// tags:
+		//		protected
+		return this.invalidMessage;
+	},
+	
+	displayMessage: function(/*String*/ message) {
+		// summary:
+		//		Overridable method to display validation errors/hints.
+		//		By default uses a tooltip.
+		// tags:
+		//		extension
+		dijit.hideTooltip(this.domNode);
+		if(message){
+			dijit.showTooltip(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){
-		this.wrapperDiv.appendChild(new dojox.form._CheckedMultiSelectItem({
+		var item = new dojox.form._CheckedMultiSelectItem({
 			option: option,
 			parent: this
-		}).domNode);
+		});
+		this.wrapperDiv.appendChild(item.domNode);
+		this.onAfterAddOptionItem(item, option);
+	},
+	
+	_refreshState: function(){
+		// summary:
+		//		Validate if selection changes.
+		this.validate(this._focused);
+	},
+
+	onChange: function(newValue){
+		// summary:
+		//		Validate if selection changes.
+		this._refreshState();
+	},
+	
+	reset: function(){
+		// summary: Overridden so that the state will be cleared.
+		this.inherited(arguments);
+		dijit.hideTooltip(this.domNode);
 	},
 	
 	_updateSelection: function(){
 		this.inherited(arguments);
+		this._handleOnChange(this.value);
 		dojo.forEach(this._getChildren(), function(c){ c._updateBox(); });
 	},
 	
@@ -146,8 +238,8 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 		//		Disable (or enable) all the children as well
 		this.inherited(arguments);
 		dojo.forEach(this._getChildren(), function(node){
-			if(node && node.attr){
-				node.attr("disabled", value);
+			if(node && node.set){
+				node.set("disabled", value);
 			}
 		});
 	},
@@ -160,13 +252,14 @@ dojo.declare("dojox.form.CheckedMultiSelect", dijit.form._FormSelectWidget, {
 		}
 		this.readOnly = value;
 		dojo.forEach(this._getChildren(), function(node){
-			if(node && node.attr){
-				node.attr("readOnly", value);
+			if(node && node.set){
+				node.set("readOnly", value);
 			}
 		});
 	},
 
 	uninitialize: function(){
+		dijit.hideTooltip(this.domNode);
 		// Make sure these children are destroyed
 		dojo.forEach(this._getChildren(), function(child){
 			child.destroyRecursive();
diff --git a/dojox/form/DateTextBox.js b/dojox/form/DateTextBox.js
index a7d7126..30e2c55 100644
--- a/dojox/form/DateTextBox.js
+++ b/dojox/form/DateTextBox.js
@@ -16,10 +16,10 @@ dojo.declare(
 		//  The popup widget to use. In this case, a calendar with Day, Month and Year views.
 		popupClass: "dojox.widget.Calendar",
 		_selector: "date",
-		
-		_open: function(){
+
+		openDropDown: function(){
 			this.inherited(arguments);
-			dojo.style(this._picker.domNode.parentNode, "position", "absolute");
+			dojo.style(this.dropDown.domNode.parentNode, "position", "absolute");
 		}
 	}
 );
@@ -31,15 +31,15 @@ dojo.declare(
 	{
 		// summary:
 		//		A validating, serializable, range-bound date text box with a popup calendar that contains just months.
-		
+
 		// popupClass: String
 		//  The popup widget to use. In this case, a calendar with just a Month view.
 		popupClass: "dojox.widget.DailyCalendar",
-		
+
 		parse: function(displayVal){
 			return displayVal;
 		},
-		
+
 		format: function(value){
 			return value.getDate ? value.getDate() : value;
 		},
@@ -47,46 +47,62 @@ dojo.declare(
 			var num = Number(value);
 			var isInt = /(^-?\d\d*$)/.test(String(value));
 			return value == "" || value == null || (isInt && num >= 1 && num <= 31);
-		},		
-		_open: function(){
+		},
+
+		_setValueAttr: function(value, priorityChange, formattedValue){
+			if(value){
+				if(value.getDate){
+					value = value.getDate();
+				}
+			}
+			dijit.form.TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+		},
+
+		openDropDown: function(){
 			this.inherited(arguments);
-			
-			this._picker.onValueSelected = dojo.hitch(this, function(value){
+
+			this.dropDown.onValueSelected = dojo.hitch(this, function(value){
 				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(dojo.hitch(this, "_close"), 1); // allow focus time to take
+				setTimeout(dojo.hitch(this, "closeDropDown"), 1); // allow focus time to take
 
 				dijit.form.TextBox.prototype._setValueAttr.call(this, String(value.getDate()), true, String(value.getDate()));
-			});			
+			});
 		}
 	}
 );
 
 dojo.declare(
 	"dojox.form.MonthTextBox",
-	dojox.form.DateTextBox, 
+	dojox.form.DateTextBox,
 	{
 		// summary:
 		//		A validating, serializable, range-bound date text box with a popup calendar that contains only years
-		
+
 		// popupClass: String
 		//  The popup widget to use. In this case, a calendar with just a Year view.
 		popupClass: "dojox.widget.MonthlyCalendar",
 
 		selector: "date",
-		
+
 		postMixInProperties: function(){
 			this.inherited(arguments);
 			this.constraints.datePattern = "MM";
 		},
-		
+
 		format: function(value) {
+			if(!value && value !== 0){
+				return 1;
+			}
+			if(value.getMonth){
+				return value.getMonth() + 1;
+			}
 			return Number(value) + 1;
 		},
-		
+
 		parse: function(value, constraints){
 			return Number(value) - 1;
 		},
-		
+
 		serialize: function(value, constraints) {
 			return String(value);
 		},
@@ -96,15 +112,24 @@ dojo.declare(
 			var isInt = /(^-?\d\d*$)/.test(String(value));
 			return value == "" || value == null || (isInt && num >= 1 && num <= 12);
 		},
-		
-		_open: function(){
+
+		_setValueAttr: function(value, priorityChange, formattedValue){
+			if(value){
+				if(value.getMonth){
+					value = value.getMonth();
+				}
+			}
+			dijit.form.TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+		},
+
+		openDropDown: function(){
 			this.inherited(arguments);
 
-			this._picker.onValueSelected = dojo.hitch(this, function(value){
+			this.dropDown.onValueSelected = dojo.hitch(this, function(value){
 				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(dojo.hitch(this, "_close"), 1); // allow focus time to take
-				dijit.form.TextBox.prototype._setValueAttr.call(this,value, true, value);
-			});						
+				setTimeout(dojo.hitch(this, "closeDropDown"), 1); // allow focus time to take
+				dijit.form.TextBox.prototype._setValueAttr.call(this, value, true, value);
+			});
 		}
 	}
 );
@@ -112,14 +137,15 @@ dojo.declare(
 
 dojo.declare(
 	"dojox.form.YearTextBox",
-	dojox.form.DateTextBox, 
+	dojox.form.DateTextBox,
 	{
 		// summary:
 		//		A validating, serializable, range-bound date text box with a popup calendar that contains only years
-		
+
 		popupClass: "dojox.widget.YearlyCalendar",
 
 		format: function(value) {
+			console.log('Year format ' + value);
 			if (typeof value == "string"){
 				return value;
 			}
@@ -128,21 +154,31 @@ dojo.declare(
 			}
 			return value;
 		},
-		
+
 		validator: function(value) {
 			return value == "" || value == null || /(^-?\d\d*$)/.test(String(value));
 		},
-		
-		_open: function(){
+
+		_setValueAttr: function(value, priorityChange, formattedValue){
+			if(value){
+				if(value.getFullYear){
+					value = value.getFullYear();
+				}
+			}
+			dijit.form.TextBox.prototype._setValueAttr.call(this, value, priorityChange, formattedValue);
+		},
+
+		openDropDown: function(){
 			this.inherited(arguments);
-			
-			this._picker.onValueSelected = dojo.hitch(this, function(value){
+			console.log('yearly openDropDown and value = ' + this.get('value'));
+
+			this.dropDown.onValueSelected = dojo.hitch(this, function(value){
 				this.focus(); // focus the textbox before the popup closes to avoid reopening the popup
-				setTimeout(dojo.hitch(this, "_close"), 1); // allow focus time to take
+				setTimeout(dojo.hitch(this, "closeDropDown"), 1); // allow focus time to take
 				dijit.form.TextBox.prototype._setValueAttr.call(this,value, true, value);
-			});						
+			});
 		},
-		
+
 		parse: function(/*String*/value, /*dojo.date.locale.__FormatOptions*/constraints) {
 			return value || (this._isEmpty(value) ? null : undefined); // Date
 		},
diff --git a/dojox/form/FileInput.js b/dojox/form/FileInput.js
index e21b48b..367f5c6 100644
--- a/dojox/form/FileInput.js
+++ b/dojox/form/FileInput.js
@@ -1,8 +1,8 @@
 dojo.provide("dojox.form.FileInput");
-dojo.experimental("dojox.form.FileInput"); 
+dojo.experimental("dojox.form.FileInput");
 
 dojo.require("dijit.form._FormWidget");
-dojo.require("dijit._Templated"); 
+dojo.require("dijit._Templated");
 
 dojo.declare("dojox.form.FileInput",
 	dijit.form._FormWidget,
@@ -11,7 +11,7 @@ dojo.declare("dojox.form.FileInput",
 	//
 	// description: A input type="file" form widget, with a button for uploading to be styled via css,
 	//	a cancel button to clear selection, and FormWidget mixin to provide standard dijit.form.Form
-	//	support (FIXME: maybe not fully implemented) 
+	//	support (FIXME: maybe not fully implemented)
 
 	// label: String
 	//	the title text of the "Browse" button
@@ -59,12 +59,12 @@ dojo.declare("dojox.form.FileInput",
 		if(this.fileInput){
 			this.domNode.removeChild(this.fileInput);
 		}
-		dojo.fadeOut({ node: this.cancelNode, duration:275 }).play(); 
+		dojo.fadeOut({ node: this.cancelNode, duration:275 }).play();
 
 		// should we use cloneNode()? can we?
 		this.fileInput = document.createElement('input');
 		// dojo.attr(this.fileInput,{
-		//	"type":"file", "id":this.id, "name": this.name	
+		//	"type":"file", "id":this.id, "name": this.name
 		//});
 		this.fileInput.setAttribute("type","file");
 		this.fileInput.setAttribute("id", this.id);
@@ -73,8 +73,8 @@ dojo.declare("dojox.form.FileInput",
 		this.domNode.appendChild(this.fileInput);
 
 		this._keyListener = this.connect(this.fileInput, "onkeyup", "_matchValue");
-		this._listener = this.connect(this.fileInput, "onchange", "_matchValue"); 
-		this.inputNode.value = ""; 
+		this._listener = this.connect(this.fileInput, "onchange", "_matchValue");
+		this.inputNode.value = "";
 	}
 
 });
\ No newline at end of file
diff --git a/dojox/form/FileInputAuto.js b/dojox/form/FileInputAuto.js
index 860701b..2544372 100644
--- a/dojox/form/FileInputAuto.js
+++ b/dojox/form/FileInputAuto.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.form.FileInputAuto");
 
 dojo.require("dojox.form.FileInput");
-dojo.require("dojo.io.iframe"); 
+dojo.require("dojo.io.iframe");
 
 dojo.declare("dojox.form.FileInputAuto",
 	dojox.form.FileInput,
@@ -11,12 +11,12 @@ dojo.declare("dojox.form.FileInputAuto",
 	// 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
 	//	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 
+	//
+	// notes: the return data from the io.iframe is used to populate the input element with
 	//	data regarding the results. it will be a JSON object, like:
-	//	
+	//
 	//	results = { size: "1024", filename: "file.txt" }
-	//	
+	//
 	//	all the parameters allowed to dojox.form.FileInput apply
 
 	// url: String
@@ -34,9 +34,9 @@ dojo.declare("dojox.form.FileInputAuto",
 	duration: 500,
 
 	// uploadMessage: String
-	//	
+	//
 	//	FIXME: i18n somehow?
-	uploadMessage: "Uploading ...", 
+	uploadMessage: "Uploading ...",
 	
 	// triggerEvent: String
 	//		Event which triggers the upload. Defaults to onblur, sending the file selected
@@ -50,7 +50,7 @@ dojo.declare("dojox.form.FileInputAuto",
 	templateString: dojo.cache("dojox.form","resources/FileInputAuto.html"),
 	
 	onBeforeSend: function(){
-		// summary: Called immediately before a FileInput sends it's file via io.iframe.send. 
+		// summary: Called immediately before a FileInput sends it's file via io.iframe.send.
 		//		The return of this function is passed as the `content` member in the io.iframe IOArgs
 		//		object.
 		return {};
@@ -59,7 +59,7 @@ dojo.declare("dojox.form.FileInputAuto",
 	startup: function(){
 		// summary: add our extra blur listeners
 		this._blurListener = this.connect(this.fileInput, this.triggerEvent, "_onBlur");
-		this._focusListener = this.connect(this.fileInput, "onfocus", "_onFocus"); 
+		this._focusListener = this.connect(this.fileInput, "onfocus", "_onFocus");
 		this.inherited(arguments);
 	},
 
@@ -72,7 +72,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(dojo.hitch(this,"_sendFile"),this.blurDelay);
 		}
 	},
 
@@ -101,9 +101,9 @@ dojo.declare("dojox.form.FileInputAuto",
 
 		dojo.fadeIn({ node: this.overlay, duration:this.duration }).play();
 
-		var _newForm; 
-		if(dojo.isIE){
-			// just to reiterate, IE is a steaming pile of code. 
+		var _newForm;
+		if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
+			// 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";
 			
@@ -136,7 +136,7 @@ dojo.declare("dojox.form.FileInputAuto",
 			opacity:0,
 			border:"none",
 			background:"none"
-		}); 
+		});
 
 		this.overlay.style.backgroundImage = "none";
 		this.fileInput.style.display = "none";
@@ -166,11 +166,11 @@ dojo.declare("dojox.form.FileInputAuto",
 		this._sent = false;
 		this._sending = false;
 		this._blurListener = this.connect(this.fileInput, this.triggerEvent,"_onBlur");
-		this._focusListener = this.connect(this.fileInput,"onfocus","_onFocus"); 
+		this._focusListener = this.connect(this.fileInput,"onfocus","_onFocus");
 	},
 
 	onComplete: function(data,ioArgs,widgetRef){
-		// summary: stub function fired when an upload has finished. 
+		// 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
 		// widgetRef: this widget pointer, so you can set this.overlay to a completed/error message easily
@@ -192,8 +192,8 @@ dojo.declare("dojox.form.FileInputBlind",
 		this._fixPosition();
 	},
 	
-	_fixPosition: function(){		
-		// summary: in this case, set the button under where the visible button is 
+	_fixPosition: function(){
+		// summary: in this case, set the button under where the visible button is
 		if(dojo.isIE){
 			dojo.style(this.fileInput,"width","1px");
 		}else{
@@ -204,6 +204,6 @@ dojo.declare("dojox.form.FileInputBlind",
 	reset: function(e){
 		// summary: onclick, we need to reposition our newly created input type="file"
 		this.inherited(arguments);
-		this._fixPosition(); 
+		this._fixPosition();
 	}
 });
diff --git a/dojox/form/FilePickerTextBox.js b/dojox/form/FilePickerTextBox.js
index 2ed1bfe..2f90b79 100644
--- a/dojox/form/FilePickerTextBox.js
+++ b/dojox/form/FilePickerTextBox.js
@@ -50,12 +50,12 @@ dojo.declare(
 			// summary: sets the value of this widget
 			if(!this._searchInProgress){
 				this.inherited(arguments);
-				value = value||"";
-				var tVal = this.dropDown.attr("pathValue")||"";
+				value = value || "";
+				var tVal = this.dropDown.get("pathValue") || "";
 				if(value !== tVal){
 					this._skip = true;
 					var fx = dojo.hitch(this, "_setBlurValue");
-					this.dropDown._setPathValueAttr(value, !fromWidget, 
+					this.dropDown._setPathValueAttr(value, !fromWidget,
 											this._settingBlurValue ? fx : null);
 				}
 			}
@@ -91,7 +91,7 @@ dojo.declare(
 			// set width to 0 so that it will resize automatically
 			this.dropDown.domNode.style.width="0px";
 			if(!("minPaneWidth" in (this.constraints||{}))){
-				this.dropDown.attr("minPaneWidth", (this.domNode.offsetWidth / this.numPanes));
+				this.dropDown.set("minPaneWidth", (this.domNode.offsetWidth / this.numPanes));
 			}
 			this.inherited(arguments);
 		},
@@ -99,8 +99,8 @@ dojo.declare(
 		toggleDropDown: function(){
 			this.inherited(arguments);
 			// Make sure our display is up-to-date with our value
-			if(this._opened){ 
-				this.dropDown.attr("pathValue", this.get("value"));
+			if(this._opened){
+				this.dropDown.set("pathValue", this.get("value"));
 			}
 		},
 		
@@ -163,7 +163,7 @@ dojo.declare(
 				return value;
 			}
 			var dd = this.dropDown, topDir = dd.topDir, sep = dd.pathSeparator;
-			var ddVal = dd.attr("pathValue");
+			var ddVal = dd.get("pathValue");
 			var norm = function(v){
 				if(topDir.length && v.indexOf(topDir) === 0){
 					v = v.substring(topDir.length);
@@ -217,8 +217,8 @@ dojo.declare(
 						var first = dojo.filter(children, function(i){
 							return (i.label.indexOf(dir) === 0);
 						})[0];
-						if(exact && 
-							((dirs.length > idx + 1 && exact.children) || 
+						if(exact &&
+							((dirs.length > idx + 1 && exact.children) ||
 							(!exact.children))){
 							idx++;
 							child._menu.onItemClick(exact, {type: "internal",
@@ -251,7 +251,7 @@ dojo.declare(
 								if(this._menuFocus){
 									this.dropDown._updateClass(this._menuFocus, "Item", {"Hover": false, "Focus": false});
 								}
-								delete this._menuFocus;							
+								delete this._menuFocus;
 							}
 							_cleanup();
 						}
diff --git a/dojox/form/FileUploader.js b/dojox/form/FileUploader.js
index 08c0b18..9cf138f 100644
--- a/dojox/form/FileUploader.js
+++ b/dojox/form/FileUploader.js
@@ -7,8 +7,7 @@ dojo.require("dijit._Templated");
 dojo.require("dojox.embed.flashVars");
 dojo.require("dijit._Contained");
 
-dojo.experimental("dojox.form.FileUploader");
-
+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.");
 
 	//	Usage Notes:
 	//		To center text vertically, use vertical-align:middle;
@@ -18,11 +17,11 @@ dojo.experimental("dojox.form.FileUploader");
 
 dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit._Contained], {
 	// version:
-	//		1.4
+	//		1.5 (deprecated)
 	// summary:
 	// 		Handles File Uploading to a server (PHP script included for testing)
 	//
-	//		***NEW: FileUploader is now a WIDGET. You do not have to pass a button
+	//		FileUploader is now a WIDGET. You do not have to pass a button
 	//		in. Passing a button is still supported until version 1.5 to maintain
 	//		backwards compatibility, but it is not reccomended. Just create your
 	//		uploader like any other widget.
@@ -35,13 +34,13 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	//
 	//		FileUploader works with Flash 10.
 	//
-	//		***NEW: The button styles are now recreated in Flash, so there is no longer
+	//		The button styles are now recreated in Flash, so there is no longer
 	//		using an invisible Flash movie with wmode=transparent. This way the Flash button
 	//		is actually placed inline with the DOM, not floating above it and constantly
 	//		resetting its position. The "Windows Firefox clickable bug" should be fixed (and
 	//		hopefully some Linux problems).
 	//
-	//		***NEW: The HTML button is created in a new way and it is now inline as is the
+	//		The HTML button is created in a new way and it is now inline as is the
 	//		FLash button. Styling is much easier and more versatile.
 	//
 	//	Dependencies:
@@ -93,7 +92,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/uploader.swf"),
+	swfPath: dojo.config.uploaderPath || dojo.moduleUrl("dojox.form", "resources/fileuploader.swf"),
 
 
 	templateString:'<div><div dojoAttachPoint="progNode"><div dojoAttachPoint="progTextNode"></div></div><div dojoAttachPoint="insideNode" class="uploaderInsideNode"></div></div>',
@@ -103,10 +102,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	//		changed to absolute.
 	uploadUrl: "",
 	//
-	//	button: dijit.form.Button or a domNode
-	// 		DEPRECATED: The "fake" button that when clicked, launches the upload dialog
-	// button:"",
-	//
 	//	isDebug: Boolean
 	//		If true, outputs traces from the SWF to console. What exactly gets passed
 	//		is very relative, and depends upon what traces have been left in the DEFT SWF.
@@ -163,11 +158,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	//		The SWF. Mostly Internal.
 	flashMovie: null,
 	//
-	//	flashDiv: [readonly] HTMLNode
-	//		DEPRECATED for insideNode
-	//		The div that holds the SWF and form/fileInput
-	flashDiv: null,
-	//
 	//	insideNode: [readonly] HTMLNode
 	//		The div that holds the SWF and form/fileInput
 	insideNode: null,
@@ -322,15 +312,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 
 		}
 
-		var w = this.getHiddenWidget();
-		if(w){
-			var __c = dojo.connect(w, "onShow", this, function(){
-				dojo.disconnect(__c);
-				this[createMethod]();
-			});
-		}else{
-			this[createMethod]();
-		}
+		this[createMethod]();
 
 		if(this.fileListId){
 			this.connect(dojo.byId(this.fileListId), "click", function(evt){
@@ -377,13 +359,13 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		if(!node){ return null; }
 		var hidden = null;
 		var p = node.parentNode;
-		while(p.tagName.toLowerCase() != "body"){
+		while(p && p.tagName.toLowerCase() != "body"){
 			var d = dojo.style(p, "display");
 			if(d == "none"){
 				hidden = p;
 				break;
 			}
-			p = p.parentNode
+			p = p.parentNode;
 		}
 		return hidden;
 	},
@@ -405,14 +387,9 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		var refNode = this.srcNodeRef;
 		this._hiddenNode = this.getHiddenNode(refNode);
 		if(this._hiddenNode){
-			console.info("Turning on hidden node")
 			dojo.style(this._hiddenNode, "display", "block");
 		}
 
-
-		if(this.button){
-			console.warn("DEPRECATED: FileUploader.button - will be removed in 1.5. FileUploader should be created as widget.");
-		}
 		if(!refNode && this.button && this.button.domNode){
 			// backwards compat for a Dijit button
 			var isDijitButton = true;
@@ -548,7 +525,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 				this.insideNode.appendChild(document.createTextNode(this.fhtml.cn));
 			}
 		}
-		this.flashDiv = this.insideNode; //backwards compat - rem in 1.5
 		if(this._hiddenNode){
 			dojo.style(this._hiddenNode, "display", "none");
 		}
@@ -709,12 +685,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			dojo.destroy("file_"+name);
 		}
 	},
-	destroyAll: function(){
-		//	summary:
-		// 		Destroys button
-		console.warn("DEPRECATED for 1.5 - use destroy() instead");
-		this.destroy();
-	},
 
 	destroy: function(){
 		//	summary:
@@ -730,32 +700,14 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		}
 		if(this.uploaderType == "flash"){
 			this.flashObject.destroy();
-			dojo.destroy(this.flashDiv);
+			delete this.flashObject;
 		}else{
-			dojo.destroy("dojoIoIframe");
 			dojo.destroy(this._fileInput);
 			dojo.destroy(this._formNode);
 		}
 		this.inherited(arguments);
 	},
-	hide: function(){
-		//	summary:
-		//		Hides the upload button.
-		console.warn("DEPRECATED for 1.5 - use dojo.style(domNode, 'display', 'none' instead");
-		dojo.style(this.domNode, 'display', 'none');
-	},
 
-	show: function(){
-		//	summary:
-		//		Shows the upload button. This is called
-		//		when within a dialog.
-		console.warn("DEPRECATED for 1.5 - use dojo.style(domNode, 'display', '') instead");
-		dojo.style(this.domNode, 'display', '');
-	},
-	disable: function(/*Boolean*/disabled){
-		console.warn("DEPRECATED: FileUploader.disable() - will be removed in 1.5. Use set('disable', true) instead.")
-		this.set("disable", disabled);
-	},
 	/*************************
 	 *	   Private Events	 *
 	 *************************/
@@ -765,7 +717,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		//
 		if(display === true){
 			if(this.uploaderType == "flash"){
-				dojo.style(this.insideNode,"left", "-2500px");
+				dojo.style(this.insideNode,"top", "-2500px");
 			}else{
 				dojo.style(this.insideNode,"display", "none");
 			}
@@ -938,13 +890,13 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 	},
 	_getDisabledAttr: function(){
 		// summary:
-		//		Internal. To get disabled use: widget.attr("disabled");
+		//		Internal. To get disabled use: widget.get("disabled");
 		return this._disabled;
 	},
 
 	_setDisabledAttr: function(disabled){
 		// summary:
-		//		Internal. To set disabled use: widget.attr("disabled", true | false);
+		//		Internal. To set disabled use: widget.set("disabled", true | false);
 		if(this._disabled == disabled){ return; }
 
 		if(this.uploaderType == "flash"){
@@ -1010,7 +962,7 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			this._animateProgress();
 		}
 		var dfd = dojo.io.iframe.send({
-			url: this.uploadUrl,
+			url: this.uploadUrl.toString(),
 			form: this._formNode,
 			handleAs: "json",
 			error: dojo.hitch(this, function(err){
@@ -1044,10 +996,12 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			this.onMouseOver(evt);
 		}));
 		this._cons.push(dojo.connect(this._fileInput, "mouseout", this, function(evt){
-			dojo.removeClass(this.domNode, this.activeClass);
-			dojo.removeClass(this.domNode, this.hoverClass);
-			this.onMouseOut(evt);
-			this._checkHtmlCancel("off");
+			setTimeout(dojo.hitch(this, function(){
+				dojo.removeClass(this.domNode, this.activeClass);
+				dojo.removeClass(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);
@@ -1132,17 +1086,21 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		// summary:
 		//		Build the form that holds the fileInput
 		//
+
 		if(this._formNode){ return; }
 
-		if(dojo.isIE){
+		if(dojo.isIE < 9 || (dojo.isIE && dojo.isQuirks)){
 			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.domNode.appendChild(this._formNode);
 		}else{
-			this._formNode = document.createElement('form');
-			this._formNode.setAttribute("enctype", "multipart/form-data");
+			this._formNode = dojo.create('form', {
+				enctype:"multipart/form-data",
+				method:"post",
+				id:dijit.getUniqueId("FileUploaderForm")
+			}, this.domNode);
 		}
-		this._formNode.id = dijit.getUniqueId("FileUploaderForm"); // needed for dynamic style
-		this.domNode.appendChild(this._formNode);
 	},
 
 	_buildFileInput: function(){
@@ -1176,7 +1134,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 		});
 
 		dojo.addClass(this._fileInput, "dijitFileInputReal");
-		console.warn("BUILD FI")
 		this._formNode.appendChild(this._fileInput);
 		var real = dojo.marginBox(this._fileInput);
 		dojo.style(this._fileInput, {
@@ -1243,7 +1200,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			for(var nm in this.postData){
 				o[nm] = this.postData[nm];
 			}
-			console.warn("this.postData:", o)
 			this.flashMovie.doUpload(o);
 
 		}catch(err){
@@ -1299,7 +1255,9 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 			},
 			params: {
 				scale:"noscale",
-				wmode:"opaque"
+				wmode:"opaque",
+				allowScriptAccess:"always",
+				allowNetworking:"all"
 			}
 
 		};
@@ -1393,7 +1351,6 @@ dojo.declare("dojox.form.FileUploader", [dijit._Widget, dijit._Templated, dijit.
 				// IE doesn't convert % to px. For god sakes.
 				var n = node;
 				while(n.tagName){
-					console.log(" P FONT:", dojo.style(node, "fontSize"))
 					if(dojo.style(n, "fontSize").indexOf("%") == -1){
 						o.fs = parseInt(dojo.style(n, "fontSize"), 10);
 						break;
diff --git a/dojox/form/ListInput.js b/dojox/form/ListInput.js
index 94f7e0f..f2e31b6 100755
--- a/dojox/form/ListInput.js
+++ b/dojox/form/ListInput.js
@@ -7,10 +7,10 @@ dojo.require("dijit.form.ValidationTextBox");
 dojo.require("dijit.InlineEditBox");
 dojo.requireLocalization("dijit", "common");
 
-dojo.declare("dojox.form.ListInput", 
+dojo.declare("dojox.form.ListInput",
 	[dijit.form._FormValueWidget],
 	{
-	// summary: 
+	// summary:
 	//		An automatic list maker
 	// description:
 	//		you can add value to list with add method.
@@ -95,7 +95,7 @@ dojo.declare("dojox.form.ListInput",
 	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 
+	//		If true, then item will use an anime to show hide itself
 	useAnim: true,
 	
 	// duration: Integer
@@ -153,20 +153,19 @@ dojo.declare("dojox.form.ListInput",
 		//		Change status and if needed, create the inputbox
 		// tags:
 		//		private
-		console.warn("_setReadOnlyInputAttr",this.id,value);
 		if(!this._started){ return this._createInputBox(); }
-		this.readOnlyInput=value;
+		this.readOnlyInput = value;
 		this._createInputBox();
 	},
 	
 	_setReadOnlyItemAttr: function(/*Boolean*/value){
-		// summary: 
+		// summary:
 		//		set read only items
 		// tags:
 		//		private
 		if(!this._started){ return; }
 		for(var i in this._items){
-			this._items[i].attr("readOnlyItem",value);
+			this._items[i].set("readOnlyItem", value);
 		}
 	},
 	
@@ -175,13 +174,13 @@ dojo.declare("dojox.form.ListInput",
 		//		Create the input box
 		// tags:
 		//		private
-		console.warn("_createInputBox",this.id,this.readOnlyInput);
-		dojo[(this.readOnlyInput?"add":"remove")+"Class"](this._inputNode,"dijitHidden");
+		dojo.toggleClass(this._inputNode, "dijitHidden", this.readOnlyInput);
 		if(this.readOnlyInput){ return; }
 		if(this._input){ return; }
 				
 		if(this.inputHandler === null){
-			return !console.warn("you must add some handler to connect to input field");
+			console.warn("you must add some handler to connect to input field");
+			return false;
 		}
 		if(dojo.isString(this.inputHandler)){
 			this.inputHandler = this.inputHandler.split(",");
@@ -211,8 +210,8 @@ dojo.declare("dojox.form.ListInput",
 		//		Compare 2 values (as returned by attr('value') for this widget).
 		// tags:
 		//		protected
-		val1=val1.join(",");
-		val2=val2.join(",");
+		val1 = val1.join(",");
+		val2 = val2.join(",");
 		if(val1 > val2){
 			return 1;
 		}else if(val1 < val2){
@@ -223,7 +222,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	add: function(/*String || Array*/values){
-		// summary: 
+		// summary:
 		//		Create new list element
 		if(this._count>=this.maxItems && this.maxItems !== null){return;}
 		this._lastValueReported = this._getValues();
@@ -284,7 +283,7 @@ dojo.declare("dojox.form.ListInput",
 		}
 		
 		if(!this.readOnlyInput){
-			this._input.attr("value","");
+			this._input.set("value", "");
 		}
 		
 		if(this._onChangeActive){ this.onChange(this.value); }
@@ -293,7 +292,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_setReadOnlyWhenMaxItemsReached: function(){
-		// summary: 
+		// summary:
 		//		set input to readonly when max is reached
 		// tags:
 		//		private
@@ -301,7 +300,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_setSelectNode: function(){
-		// summary: 
+		// summary:
 		//		put all item in the select (for a submit)
 		// tags:
 		//		private
@@ -318,7 +317,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_placeItem: function(/*domNode*/node){
-		// summary: 
+		// summary:
 		//		Place item in the list
 		// tags:
 		//		private
@@ -326,7 +325,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_getCursorPos: function(/*domNode*/node){
-		// summary: 
+		// summary:
 		//		get current cursor pos
 		// tags:
 		//		private
@@ -345,7 +344,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_onItemClose: function(/*dijit._Widget*/ item){
-		// summary: 
+		// summary:
 		//		Destroy a list element when close button is clicked
 		// tags:
 		//		private
@@ -364,7 +363,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_onItemKeyDown:  function(/*dijit._Widget*/ item, /*Event*/ e){
-		// summary: 
+		// summary:
 		//		Call when item get a keypress
 		// tags:
 		//		private
@@ -378,7 +377,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_editBefore: function(/*widget*/item) {
-		// summary: 
+		// summary:
 		//		move trough items
 		// tags:
 		//		private
@@ -388,7 +387,7 @@ dojo.declare("dojox.form.ListInput",
 		}
 	},
 	_editAfter: function(/*widget*/item) {
-		// summary: 
+		// summary:
 		//		move trough items
 		// tags:
 		//		private
@@ -407,13 +406,12 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_onItemChange: function(/*dijit._Widget*/ item, /*String*/ value){
-		// summary: 
+		// summary:
 		//		Call when item value change
 		// tags:
 		//		private
-		if(!value){
-			value=item.attr("value");
-		}
+
+		value = value || item.get("value");
 		
 		//revalidate content
 		this._testItem(item,value);
@@ -423,26 +421,24 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_onItemEdit: function(/*dijit._Widget*/ item){
-		// summary: 
+		// summary:
 		//		Call when item is edited
 		// tags:
 		//		private
-		dojo.removeClass(item.domNode,"dijitError");
-		dojo.removeClass(item.domNode,this.baseClass+"Match");
-		dojo.removeClass(item.domNode,this.baseClass+"Mismatch");
+		dojo.removeClass(item.domNode,["dijitError", this.baseClass + "Match", this.baseClass + "Mismatch"]);
 	},
 	
 	_testItem: function(/*Object*/item,/*String*/value){
-		// summary: 
+		// 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[(!match?"add":"remove")+"Class"](item.domNode, "dijitError");
+		dojo.removeClass(item.domNode, this.baseClass + (!match ? "Match" : "Mismatch"));
+		dojo.addClass(item.domNode, this.baseClass + (match ? "Match" : "Mismatch"));
+		dojo.toggleClass(item.domNode, "dijitError", !match);
 		
 		if((this.showCloseButtonWhenValid && match) ||
 			(this.showCloseButtonWhenInvalid && !match)){
@@ -453,7 +449,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_getValueAttr: function(){
-		// summary: 
+		// summary:
 		//		get all value in then list and return an array
 		// tags:
 		//		private
@@ -473,7 +469,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_parseValue: function(/*String*/newValue){
-		// summary: 
+		// summary:
 		//		search for delemiters and split if needed
 		// tags:
 		//		private
@@ -500,24 +496,24 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_setDisabledAttr: function(/*Boolean*/ value){
-		// summary: 
+		// summary:
 		//		also enable/disable editable items
 		// tags:
 		//		private
 		if(!this.readOnlyItem){
 			for(var i in this._items){
-				this._items[i].attr("disabled",value);
+				this._items[i].set("disabled", value);
 			}
 		}
 		
 		if(!this.readOnlyInput){
-			this._input.attr("disabled",value);
+			this._input.set("disabled", value);
 		}
 		this.inherited(arguments);
 	},
 	
 	_onHandler: function(/*String*/value){
-		// summary: 
+		// summary:
 		//		When handlers of input are fired, this method check input value and (if needed) modify it
 		// tags:
 		//		private
@@ -528,7 +524,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_onClick:  function(/*event*/e){
-		// summary: 
+		// summary:
 		//		give focus to inputbox
 		// tags:
 		//		private
@@ -536,7 +532,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_focusInput: function(){
-		// summary: 
+		// summary:
 		//		give focus to input
 		// tags:
 		//		private
@@ -546,34 +542,36 @@ dojo.declare("dojox.form.ListInput",
 	},
 
 	_inputOnKeyDown: function(/*event*/e){
-		// summary: 
+		// summary:
 		//		Used to add keybord interactivity
 		// tags:
 		//		private
-		this._currentItem=null;
+		this._currentItem = null;
+		var val = this._input.get("value");
 		
-		if(e.keyCode == dojo.keys.BACKSPACE && this._input.attr("value") == "" && this.get("lastItem")){
+		if(e.keyCode == dojo.keys.BACKSPACE && val == "" && this.get("lastItem")){
 			this._destroyItem(this.get("lastItem"));
-		}else if(e.keyCode == dojo.keys.ENTER && this._input.attr("value") != ""){
-			this.add(this._input.attr("value"));
-		}else if(e.keyCode == dojo.keys.LEFT_ARROW && this._getCursorPos(this._input.focusNode)==0 &&
+		}else if(e.keyCode == dojo.keys.ENTER && val != ""){
+			this.add(val);
+		}else if(e.keyCode == dojo.keys.LEFT_ARROW && this._getCursorPos(this._input.focusNode) == 0 &&
 			!this.readOnlyItem && this.useArrowForEdit){
 				this._editBefore();
 		}
 	},
 	
 	_inputOnBlur: function(){
-		// summary: 
+		// summary:
 		//		Remove focus class and act like pressing ENTER key
 		// tags:
 		//		private
-		if(this.useOnBlur && this._input.attr("value") != ""){
-			this.add(this._input.attr("value"));
+		var val = this._input.get('value');
+		if(this.useOnBlur && val != ""){
+			this.add(val);
 		}
 	},
 	
 	_getMatchedValueAttr: function(){
-		// summary: 
+		// summary:
 		//		get value that match regexp in then list and return an array
 		// tags:
 		//		private
@@ -581,7 +579,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_getMismatchedValueAttr: function(){
-		// summary: 
+		// summary:
 		//		get value that mismatch regexp in then list and return an array
 		// tags:
 		//		private
@@ -589,7 +587,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_getValues: function(/*function*/validator){
-		// summary: 
+		// summary:
 		//		return values with comparator constraint
 		// tags:
 		//		private
@@ -600,8 +598,8 @@ dojo.declare("dojox.form.ListInput",
 			if(item === null){
 				continue;
 			}
-			var itemValue=item.attr("value");
-			if (validator(itemValue)){
+			var itemValue = item.get("value");
+			if(validator(itemValue)){
 				value.push(itemValue);
 			}
 		}
@@ -609,14 +607,14 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_nullValidator: function(/*String*/itemValue){
-		// summary: 
+		// summary:
 		//		return true or false
 		// tags:
 		//		private
 		return true;
 	},
 	_matchValidator: function(/*String*/itemValue){
-		// summary: 
+		// summary:
 		//		return true or false
 		// tags:
 		//		private
@@ -624,7 +622,7 @@ dojo.declare("dojox.form.ListInput",
 		return itemValue.match(re);
 	},
 	_mismatchValidator: function(/*String*/itemValue){
-		// summary: 
+		// summary:
 		//		return true or false
 		// tags:
 		//		private
@@ -633,14 +631,14 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_getLastItemAttr: function(){
-		// summary: 
+		// summary:
 		//		return the last item in list
 		// tags:
 		//		private
 		return this._getSomeItem();
 	},
 	_getSomeItem: function(/*dijit._Widget*/ item,/*String*/ position){
-		// summary: 
+		// summary:
 		//		return the item before the one in params
 		// tags:
 		//		private
@@ -672,14 +670,14 @@ dojo.declare("dojox.form.ListInput",
 		return lastItem;
 	},
 	_getPreviousItem: function(/*dijit._Widget*/ item){
-		// summary: 
+		// summary:
 		//		return the item before the one in params
 		// tags:
 		//		private
 		return this._getSomeItem(item,"before");
 	},
 	_getNextItem: function(/*dijit._Widget*/ item){
-		// summary: 
+		// summary:
 		//		return the item before the one in params
 		// tags:
 		//		private
@@ -687,7 +685,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_destroyItem: function(/*dijit._Widget*/ item, /*Boolean?*/ updateValue){
-		// summary: 
+		// summary:
 		//		destroy an item
 		// tags:
 		//		private
@@ -701,7 +699,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_updateValues: function(){
-		// summary: 
+		// summary:
 		//		update this.value and the select node
 		// tags:
 		//		private
@@ -710,7 +708,7 @@ dojo.declare("dojox.form.ListInput",
 	},
 	
 	_destroyAllItems: function(){
-		// summary: 
+		// summary:
 		//		destroy all items
 		// tags:
 		//		private
@@ -739,10 +737,10 @@ dojo.declare("dojox.form.ListInput",
 	}
 });
 
-dojo.declare("dojox.form._ListInputInputItem", 
+dojo.declare("dojox.form._ListInputInputItem",
 	[dijit._Widget, dijit._Templated],
 	{
-	// summary: 
+	// summary:
 	//	Item created by ListInputInput when delimiter is found
 	// description:
 	//		Simple <li> with close button added to ListInputInput when delimiter is found
@@ -822,7 +820,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 		if(!value){
 			this._createInlineEditBox();
 		}else if(this._editBox){
-			this._editBox.attr("disabled",true);
+			this._editBox.set("disabled", true);
 		}
 	},
 	
@@ -833,11 +831,11 @@ dojo.declare("dojox.form._ListInputInputItem",
 		//		private
 		if(this.readOnlyItem){ return; }
 		if(!this._started){ return; }
-		if(this._editBox){ 
-			this._editBox.attr("disabled",false);
-			return; 
+		if(this._editBox){
+			this._editBox.set("disabled",false);
+			return;
 		}
-		this._editBox=new dijit.InlineEditBox({
+		this._editBox = new dijit.InlineEditBox({
 			value:this.value,
 			editor: "dijit.form.ValidationTextBox",
 			editorParams:{
@@ -883,7 +881,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 		// tags:
 		//		private
 		if(!this.readOnlyItem){
-			this._editBox.attr("disabled",value);
+			this._editBox.set("disabled", value);
 		}
 	},
 	
@@ -892,7 +890,7 @@ dojo.declare("dojox.form._ListInputInputItem",
 		//		return value
 		// tags:
 		//		private
-		return (!this.readOnlyItem && this._started ? this._editBox.attr("value") : this.value);
+		return (!this.readOnlyItem && this._started ? this._editBox.get("value") : this.value);
 	},
 	
 	destroy: function(){
@@ -921,22 +919,22 @@ dojo.declare("dojox.form._ListInputInputItem",
 	},
 	
 	onClose: function(){
-		// summary: 
+		// summary:
 		//		callback when close button is clicked
 	},
 	
 	onEdit: function(){
-		// summary: 
+		// summary:
 		//		callback when widget come in edition
 	},
 	
 	onClick: function(){
-		// summary: 
+		// summary:
 		//		callback when widget is click
 	},
 	
 	onChange: function(/*String*/value){
-		// summary: 
+		// summary:
 		//		callback when widget change its content
 	},
 	
@@ -946,10 +944,10 @@ dojo.declare("dojox.form._ListInputInputItem",
 		//		callback when widget get a KeyDown
 	}
 });
-dojo.declare("dojox.form._ListInputInputBox", 
+dojo.declare("dojox.form._ListInputInputBox",
 	[dijit.form.ValidationTextBox],
 	{
-	// summary: 
+	// summary:
 	//	auto-sized text box
 	// description:
 	//		Auto sized textbox based on dijit.form.TextBox
@@ -973,7 +971,7 @@ dojo.declare("dojox.form._ListInputInputBox",
 	_sizer:null,
 	
 	onChange: function(/*string*/value){
-		// summary: 
+		// summary:
 		//		compute content width
 		this.inherited(arguments);
 		if(this._sizer === null){
@@ -988,7 +986,7 @@ dojo.declare("dojox.form._ListInputInputBox",
 		this._sizer.innerHTML = value;
 		var w = dojo.contentBox(this._sizer).w + this.minWidth;
 		dojo.contentBox(this.domNode,{ w : w });
-	}, 
+	},
 	
 	destroy: function(){
 		// summary:
diff --git a/dojox/form/MultiComboBox.js b/dojox/form/MultiComboBox.js
index 4bb9a78..8291d0a 100644
--- a/dojox/form/MultiComboBox.js
+++ b/dojox/form/MultiComboBox.js
@@ -1,5 +1,5 @@
 dojo.provide("dojox.form.MultiComboBox");
-dojo.experimental("dojox.form.MultiComboBox"); 
+dojo.experimental("dojox.form.MultiComboBox");
 dojo.require("dijit.form.ComboBox");
 dojo.require("dijit.form.ValidationTextBox");
 
@@ -53,5 +53,5 @@ dojo.declare("dojox.form.MultiComboBox",
 			arguments[0] = text.replace(re, "");
 		}
 		this.inherited(arguments);
-	}		
+	}
 });
diff --git a/dojox/form/PasswordValidator.js b/dojox/form/PasswordValidator.js
index 49235c2..5570d1c 100644
--- a/dojox/form/PasswordValidator.js
+++ b/dojox/form/PasswordValidator.js
@@ -7,7 +7,7 @@ dojo.requireLocalization("dojox.form", "PasswordValidator");
 
 dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
 	// summary:
-	//		A class that is shared between all our children - extends 
+	//		A class that is shared between all our children - extends
 	//		ValidationTextBox and provides some shared functionality
 	//
 	// containerWidget: widget
@@ -20,8 +20,8 @@ dojo.declare("dojox.form._ChildTextBox", dijit.form.ValidationTextBox, {
 	
 	reset: function(){
 		// summary:
-		//		Force-set to empty string (we don't save passwords EVER)...and 
-		//		since _OldPWBox overrides _setValueAttr to check for empty string, 
+		//		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);
 		this._hasBeenBlurred = false;
@@ -66,13 +66,13 @@ dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, {
 			newVal = dojox.form._OldPWBox.superclass.attr.call(this, "value");
 		}
 		if(priority !== null){
-			//  Priority is passed in as null, explicitly when this is an 
+			//  Priority is passed in as null, explicitly when this is an
 			//	update (not initially set).  We want to check our password now.
 			this._isPWValid = this.containerWidget.pwCheck(newVal);
 		}
 		this.inherited(arguments);
 		// Trigger the containerWidget to recheck its value, if needed
-		this.containerWidget._childValueAttr(this.containerWidget._inputWidgets[1].attr("value"));
+		this.containerWidget._childValueAttr(this.containerWidget._inputWidgets[1].get("value"));
 	},
 
 	isValid: function(/* boolean */ isFocused){
@@ -81,7 +81,7 @@ dojo.declare("dojox.form._OldPWBox", dojox.form._ChildTextBox, {
 	},
 
 	_update: function(/* event */ e){
-		// Only call validate() if we've been blurred or else we get popups 
+		// Only call validate() if we've been blurred or else we get popups
 		// too early.
 		if(this._hasBeenBlurred){ this.validate(true); }
 		this._onMouse(e);
@@ -131,13 +131,13 @@ dojo.declare("dojox.form._VerifyPWBox", dojox.form._ChildTextBox, {
 		// summary:
 		//		Validates that we match the "real" password
 		return this.inherited("isValid", arguments) &&
-			(this.get("value") == this.containerWidget._inputWidgets[1].attr("value"));
+			(this.get("value") == this.containerWidget._inputWidgets[1].get("value"));
 	}
 });
 
 dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 	// summary:
-	//		A password validation widget that simplifies the "old/new/verify" 
+	//		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.
 	//
@@ -189,8 +189,7 @@ 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);
+			msg = dojo.i18n.getLocalization("dojox.form", "PasswordValidator", this.lang);
 		dojo.forEach(widgets, function(i, idx){
 			if(i){
 				var p = {containerWidget: this}, c;
@@ -207,42 +206,42 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 				}
 				widgets[idx] = new c(p, i);
 			}
-		}, this);	
+		}, this);
 	},
 
-	pwCheck: function(/* string */ password){ 
+	pwCheck: function(/* string */ password){
 		// summary:
 		//		Overridable function for validation of the old password box.
 		//
 		//		This function is called and passed the old password.  Return
 		//		true if it's OK to continue, and false if it is not.
-		//		
+		//
 		//		IMPORTANT SECURITY NOTE:  Do NOT EVER EVER EVER check this in
 		//									HTML or JavaScript!!!
 		//
-		//		You will probably want to override this function to callback 
-		//		to a server to verify the password (the callback will need to 
+		//		You will probably want to override this function to callback
+		//		to a server to verify the password (the callback will need to
 		//		be syncronous) - and it's probably a good idea to validate
 		//		it again on form submission before actually doing
-		//		anything destructive - that's why the "oldName" value 
+		//		anything destructive - that's why the "oldName" value
 		//		is available.
 		//
-		//		And don't just fetch the password from the server 
+		//		And don't just fetch the password from the server
 		//		either :)  Send the test password (probably hashed, for
 		//		security) and return from the server a status instead.
-		//				
-		//		Again - DON'T BE INSECURE!!!  Security is left as an exercise 
+		//
+		//		Again - DON'T BE INSECURE!!!  Security is left as an exercise
 		//		for the reader :)
-		return false; 
+		return false;
 	},
 
 	postCreate: function(){
 		//	summary:
 		//		Sets up the correct widgets.  You *MUST* specify one child
-		//		text box (a simple HTML <input> element) with pwType="new" 
-		//		*and* one child text box with pwType="verify".  You *MAY* 
-		//		specify a third child text box with pwType="old" in order to 
-		//		prompt the user to enter in their old password before the 
+		//		text box (a simple HTML <input> element) with pwType="new"
+		//		*and* one child text box with pwType="verify".  You *MAY*
+		//		specify a third child text box with pwType="old" in order to
+		//		prompt the user to enter in their old password before the
 		//		widget returns that it is valid.
 		
 		this.inherited(arguments);
@@ -250,8 +249,7 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		// 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]);
+			widgets.push(dojo.query("input[pwType=" + i + "]", this.containerNode)[0]);
 		}, this);
 		if (!widgets[1] || !widgets[2]){
 			throw new Error("Need at least pwType=\"new\" and pwType=\"verify\"");
@@ -262,7 +260,7 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		this.containerNode = this.domNode;
 		this._createSubWidgets();
 		this.connect(this._inputWidgets[1], "_setValueAttr", "_childValueAttr");
-		this.connect(this._inputWidgets[2], "_setValueAttr", "_childValueAttr");		
+		this.connect(this._inputWidgets[2], "_setValueAttr", "_childValueAttr");
 	},
 	
 	_childValueAttr: function(v){
@@ -272,7 +270,7 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 	_setDisabledAttr: function(value){
 		this.inherited(arguments);
 		dojo.forEach(this._inputWidgets, function(i){
-			if(i && i.attr){ i.attr("disabled", value);}
+			if(i && i.set){ i.set("disabled", value);}
 		});
 	},
 	
@@ -282,7 +280,7 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 		dijit.setWaiState(this.focusNode, "required", value);
 		this._refreshState();
 		dojo.forEach(this._inputWidgets, function(i){
-			if(i && i.attr){ i.attr("required", value);}
+			if(i && i.set){ i.set("required", value);}
 		});
 	},
 
@@ -297,7 +295,7 @@ dojo.declare("dojox.form.PasswordValidator", dijit.form._FormValueWidget, {
 	},
 	
 	focus: function(){
-		// summary: 
+		// summary:
 		//		places focus on the first invalid input widget - if all
 		//		input widgets are valid, the first widget is focused.
 		var f = false;
diff --git a/dojox/form/RangeSlider.js b/dojox/form/RangeSlider.js
index 60dd19f..9da0afc 100644
--- a/dojox/form/RangeSlider.js
+++ b/dojox/form/RangeSlider.js
@@ -26,29 +26,29 @@ dojo.require("dojox.fx");
 
 			// define a custom constructor for a SliderMoverMax that points back to me
 			var _self = this;
-			var mover = function(){
-				dijit.form._SliderMoverMax.apply(this, arguments);
-				this.widget = _self;
-			};
-			dojo.extend(mover, dijit.form._SliderMoverMax.prototype);
+            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);
 		
 			// a dnd for the bar!
-			var barMover = function(){
-				dijit.form._SliderBarMover.apply(this, arguments);
-				this.widget = _self;
-			};
-			dojo.extend(barMover, dijit.form._SliderBarMover.prototype);
+            var barMover = dojo.declare(dijit.form._SliderBarMover, {
+                constructor: function(){
+                    this.widget = _self;
+                }
+            });
 			this._movableBar = new dojo.dnd.Moveable(this.progressBar,{ mover: barMover });
 		},
 	
 		destroy: function(){
 			this.inherited(arguments);
 			this._movableMax.destroy();
-			this._movableBar.destroy(); 
+			this._movableBar.destroy();
 		},
 	
 		_onKeyPress: function(/*Event*/ e){
@@ -133,12 +133,12 @@ dojo.require("dojox.fx");
 			var value = dojo.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, 
+			this._setValueAttr(value, true,
 				// conditional passed the valueAttr
-				!dojo.isArray(signedChange) && 
+				!dojo.isArray(signedChange) &&
 				((signedChange > 0 && !useMaxValue) || (useMaxValue && signedChange < 0))
 			);
 		},
@@ -171,7 +171,7 @@ dojo.require("dojox.fx");
 				// (but don't do on IE because it causes a flicker on mouse up (due to blur then focus)
 				dijit.focus(this.progressBar);
 			}
-			dojo.stopEvent(e);	
+			dojo.stopEvent(e);
 		},
 	
 		_onRemainingBarClick: function(e){
@@ -273,8 +273,8 @@ 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 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]);
 				animCombine.play();
@@ -287,7 +287,7 @@ dojo.require("dojox.fx");
 		}
 	});
 
-	dojo.declare("dijit.form._SliderMoverMax", dijit.form._SliderMover, {	
+	dojo.declare("dijit.form._SliderMoverMax", dijit.form._SliderMover, {
 
 		onMouseMove: function(e){
 			var widget = this.widget;
@@ -297,7 +297,9 @@ dojo.require("dojox.fx");
 				widget._setPixelValue_ = dojo.hitch(widget, "_setPixelValue");
 				widget._isReversed_ = widget._isReversed();
 			}
-			var pixelValue = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord];
+			
+			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);
 		},
 	
@@ -327,12 +329,14 @@ dojo.require("dojox.fx");
 			if(!bar){
 				bar = widget._bar = dojo.coords(widget.progressBar, true);
 			}
+			var coordEvent = e.touches ? e.touches[0] : e; // if multitouch take first touch for coords
 			
 			if(!mouseOffset){
-				mouseOffset = widget._mouseOffset = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - bar[widget._startingPixelCount];
+				mouseOffset = widget._mouseOffset = coordEvent[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - bar[widget._startingPixelCount];
 			}
 			
-			var pixelValueMin = e[widget._mousePixelCoord] - abspos[widget._startingPixelCoord] - mouseOffset,
+				
+			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!
 				// maybe there is a simpler way
@@ -351,7 +355,7 @@ dojo.require("dojox.fx");
 			}
 			// getting the real values by pixel
 			var myValues = [
-				widget._getValueByPixelValue(widget._isReversed_ ? (abspos[widget._pixelCount] - pixelValues[0]) : pixelValues[0], abspos[widget._pixelCount]), 
+				widget._getValueByPixelValue(widget._isReversed_ ? (abspos[widget._pixelCount] - pixelValues[0]) : pixelValues[0], abspos[widget._pixelCount]),
 				widget._getValueByPixelValue(widget._isReversed_ ? (abspos[widget._pixelCount] - pixelValues[1]) : pixelValues[1], abspos[widget._pixelCount])
 			];
 			// and setting the value of the widget
diff --git a/dojox/form/Rating.js b/dojox/form/Rating.js
index 01ab1e8..449cd3d 100644
--- a/dojox/form/Rating.js
+++ b/dojox/form/Rating.js
@@ -49,7 +49,7 @@ dojo.declare("dojox.form.Rating",
 	},
 
 	_onMouse: function(evt){
-		if(this._hovering){
+		if(this.hovering){
 			var hoverValue = +dojo.attr(evt.target, "value");
 			this.onMouseOver(evt, hoverValue);
 			this._renderStars(hoverValue, true);
diff --git a/dojox/form/TimeSpinner.js b/dojox/form/TimeSpinner.js
index 829e975..2be058e 100644
--- a/dojox/form/TimeSpinner.js
+++ b/dojox/form/TimeSpinner.js
@@ -25,7 +25,7 @@ dojo.declare(
 
 	largeDelta: 30,
 
-	timeoutChangeRate: 0.50,	
+	timeoutChangeRate: 0.50,
 
 	parse: function(time, locale){
 		return dojo.date.locale.parse(time, {selector:"time", formatLength:"short"});
diff --git a/dojox/form/Uploader.js b/dojox/form/Uploader.js
new file mode 100644
index 0000000..170bd48
--- /dev/null
+++ b/dojox/form/Uploader.js
@@ -0,0 +1,391 @@
+dojo.provide("dojox.form.Uploader");
+dojo.experimental("dojox.form.Uploader");
+dojo.require("dojox.form.uploader.Base");
+dojo.require("dijit.form.Button");
+
+	//
+	// TODO:
+	//		i18n
+	//		label via innerHTML
+	//		Doc and or test what can be extended.
+	//		Doc custom file events
+	//		Use new FileReader() for thumbnails
+	//		flashFieldName should default to Flash
+	//		get('value'); and set warning
+	//
+
+dojo.declare("dojox.form.Uploader", [dojox.form.uploader.Base], {
+	//
+	// Version: 1.6
+	//
+	// summary:
+	//		A widget that creates a stylable file-input button, with optional multi-file selection,
+	//		using only HTML elements. Non-HTML5 browsers have fallback options of Flash or an iframe.
+	//
+	//	description:
+	//		A bare-bones, stylable file-input button, with optional multi-file selection. The list
+	//		of files is not displayed, that is for you to handle by connecting to the onChange
+	//		event, or use the dojox.form.uploader.FileList.
+	//
+	//		Uploader without plugins does not have any ability to upload - it is for use in forms
+	//		where you handle the upload either by a standard POST or with Ajax using an iFrame. This
+	//		class is for convenience of multiple files only. No progress events are available.
+	//
+	//		If the browser supports a file-input with the "multiple" attribute, that will be used.
+	//		If the browser does not support "multiple" (ergo, IE) multiple inputs are used,
+	//		one for each selection.
+	//
+	//
+	//	uploadOnSelect: Boolean
+	//		If true, uploads imediately after a file has been selected. If false,
+	//		waits for upload() to be called.
+	uploadOnSelect:false,
+	//	tabIndex: Number|String
+	//		The tab order in the DOM.
+	tabIndex:0,
+	//	multiple: Boolean
+	//		If true and flash mode, multiple files may be selected from the dialog.
+	multiple:false,
+	//
+	//	label: String
+	//		The text used in the button that when clicked, opens a system Browse Dialog.
+	label:"Upload...",
+	//
+	// url: String
+	//		The url targeted for upload. An absolute URL is preferred. Relative URLs are
+	//		changed to absolute.
+	url:"",
+	//
+	//	name: String
+	//		The name attribute needs to end with square brackets: [] as this is the standard way
+	//		of handling an attribute "array". This requires a slightly different technique on the
+	//		server.
+	name:"uploadedfile",
+	//
+	//	flashFieldName: String
+	//		If set, this will be the name of the field of the flash uploaded files that the server
+	//		is expecting. If not set, "Flash" is appended to the "name" property.
+	flashFieldName:"",
+	//
+	//	uploadType: String [readonly]
+	//		The type of uploader being used. As an alternative to determining the upload type on the
+	//		server based on the fieldName, this property could be sent to the server to help
+	//		determine what type of parsing should be used.
+	uploadType:"form",
+	//
+	_nameIndex:0,
+	widgetsInTemplate:true,
+	templateString:'<div class="dojoxFileInput"><div dojoType="dijit.form.Button" dojoAttachPoint="button">${label}</div></div>',
+
+	postMixInProperties: function(){
+		this._inputs = [];
+		this._getButtonStyle(this.srcNodeRef);
+		this.inherited(arguments);
+	},
+	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;
+		}
+		this._setButtonStyle();
+		if(restore){
+			dojo.place(this.domNode, position.node, position.pos)
+		}
+		this.inherited(arguments);
+	},
+
+	/*************************
+	 *	   Public Events	 *
+	 *************************/
+
+	onChange: function(/* Array */fileArray){
+		//	summary:
+		// 		stub to connect
+		// 		Fires when files are selected
+		// 		Event is an array of last files selected
+	},
+
+	onBegin: function(/* Array */dataArray){
+		// summary:
+		// 		Fires when upload begins
+	},
+
+	onProgress: function(/* Object */customEvent){
+		// summary:
+		// 		Stub to connect
+		// 		Fires on upload progress. Event is a normalized object of common properties
+		// 		from HTML5 uploaders and the Flash uploader. Will not fire for IFrame.
+		// customEvent:
+		// 		bytesLoaded: Number
+		// 			Amount of bytes uploaded so far of entire payload (all files)
+		//		bytesTotal: Number
+		//			Amount of bytes of entire payload (all files)
+		//		type: String
+		//			Type of event (progress or load)
+		//		timeStamp: Number
+		//			Timestamp of when event occurred
+	},
+
+	onComplete: function(/* Object */customEvent){
+		// summary:
+		// 		stub to connect
+		// 		Fires when all files have uploaded
+		// 		Event is an array of all files
+		this.reset();
+	},
+
+	onCancel: function(){
+		// summary:
+		// 		Stub to connect
+		// 		Fires when dialog box has been closed
+		//		without a file selection
+	},
+
+	onAbort: function(){
+		// summary:
+		// 		Stub to connect
+		// 		Fires when upload in progress was canceled
+	},
+
+	onError: function(/* Object or String */evtObject){
+		// summary:
+		//		Fires on errors
+		//
+		//FIXME: Unsure of a standard form of error events
+	},
+
+	/*************************
+	 *	   Public Methods	 *
+	 *************************/
+
+	upload: function(/*Object ? */formData){
+		// summary:
+		// 		When called, begins file upload. Only supported with plugins.
+	},
+
+	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.
+	},
+
+	reset: function(){
+		// summary
+		// 		Resets entire input, clearing all files.
+		// 		NOTE:
+		// 		Removing individual files is not yet supported, because the HTML5 uploaders can't
+		// 		be edited.
+		// 		TODO:
+		// 		Add this ability by effectively, not uploading them
+		//
+		this._disconnectButton();
+		dojo.forEach(this._inputs, dojo.destroy, dojo);
+		this._inputs = [];
+		this._nameIndex = 0;
+		this._createInput();
+	},
+
+	getFileList: function(){
+		// summary:
+		// 		Returns a list of selected files.
+		//
+		var fileArray = [];
+		if(this.supports("multiple")){
+			dojo.forEach(this.inputNode.files, function(f, i){
+				fileArray.push({
+					index:i,
+					name:f.name,
+					size:f.size,
+					type:f.type
+				});
+			}, 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)
+
+		}
+		return fileArray; // Array
+	},
+
+	/*********************************************
+	 *	   Private Property. Get off my lawn.	 *
+	 *********************************************/
+
+	_getValueAttr: function(){
+		// summary:
+		//		Internal. To get disabled use: uploader.get("disabled");
+		return this.getFileList();
+	},
+
+	_setValueAttr: function(disabled){
+		console.error("Uploader value is read only");
+	},
+
+	_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"
+		}
+	},
+
+	_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);
+		}
+	},
+
+	_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, {
+				top:"500px"
+			});
+			this._disconnectButton();
+			this._nameIndex++;
+		}
+
+		var name;
+		if(this.supports("multiple")){
+			// FF3.5+, WebKit
+			name = this.name+"s[]";
+		}else{
+			// <=IE8
+			name = this.name + (this.multiple ? this._nameIndex : "");
+		}
+		this.inputNode = dojo.create("input", {type:"file", name:name, className:"dojoxInputNode"}, this.domNode, "first");
+		if(this.supports("multiple") && this.multiple){
+			dojo.attr(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, {
+			position:"absolute",
+			top:"-2px",
+			left:"-"+(size.w-this.btnSize.w-2)+"px",
+			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.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(dojo.connect(this.inputNode, "blur", this, function(){
+				dojo.style(this.button.domNode.firstChild, "border", restoreBorderStyle);
+			}));
+		}
+	},
+
+	_disconnectButton: function(){
+		dojo.forEach(this._cons, dojo.disconnect, dojo);
+	}
+});
+
+(function(){
+	dojox.form.UploaderOrg = dojox.form.Uploader;
+	var extensions = [dojox.form.UploaderOrg];
+	dojox.form.addUploaderPlugin = function(plug){
+		// summary:
+		// 		Handle Uploader plugins. When the dojox.form.addUploaderPlugin() function is called,
+		// 		the dojox.form.Uploader is recreated using the new plugin (mixin).
+		//
+		extensions.push(plug);
+		dojo.declare("dojox.form.Uploader", extensions, {});
+	}
+})();
diff --git a/dojox/form/_SelectStackMixin.js b/dojox/form/_SelectStackMixin.js
index 04f5191..ae543b8 100644
--- a/dojox/form/_SelectStackMixin.js
+++ b/dojox/form/_SelectStackMixin.js
@@ -2,15 +2,15 @@ dojo.provide("dojox.form._SelectStackMixin");
 
 dojo.declare("dojox.form._SelectStackMixin", null, {
 	// summary:
-	//		Mix this class in to a dijit.form._FormSelectWidget in order to 
+	//		Mix this class in to a dijit.form._FormSelectWidget in order to
 	//		provide support for "selectable" multiforms.  The widget is pointed
-	//		to a dijit.layout.StackContainer and will handle displaying and 
+	//		to a dijit.layout.StackContainer and will handle displaying and
 	//		submitting the values of only the appropriate pane.
 	//
-	//		The options for this widget will be automatically set - based on 
+	//		The options for this widget will be automatically set - based on
 	//		the panes that are in the stack container.  The "title" attribute of
 	//		the pane will be used for the display of the option.  The "id" attribute
-	//		of the pane will be used as the value of the option.  In order to 
+	//		of the pane will be used as the value of the option.  In order to
 	//		avoid running into unique ID constraint issues, a stackPrefix mechanism
 	//		is provided.
 
@@ -20,7 +20,7 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 	
 	// 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 
+	//		This exists so that we won't run into unique ID constraints.  For
 	//		example, if stackPrefix is set to "foo_", and there are three panes
 	//		in our stack with ids of "foo_a", "foo_b", and "foo_c", then the values
 	//		of the options created for the stack controller widget will be "a",
@@ -54,7 +54,7 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 			savedStates = {};
 			dojo.forEach(widgets, function(w){
 				savedStates[w.id] = w.disabled;
-				w.attr("disabled", true);
+				w.set("disabled", true);
 			});
 			pane._savedStates = savedStates;
 		}else{
@@ -65,7 +65,7 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 				if(state == undefined){
 					state = false;
 				}
-				w.attr("disabled", state);
+				w.set("disabled", state);
 			});
 			delete pane._savedStates;
 		}
@@ -152,13 +152,13 @@ dojo.declare("dojox.form._SelectStackMixin", null, {
 		var _this = this;
 		var fx = function(){
 			// This stuff needs to be run after we show our child, if
-			// the stack is going to show a different child than is 
+			// the stack is going to show a different child than is
 			// selected - see trac #9396
 			delete _this._savedValue;
 			_this.onSelectChild(selPane);
 			if(!selPane._shown){
 				_this._togglePane(selPane, true);
-			}			
+			}
 		};
 		if(selPane !== info.selected){
 			var stack = dijit.byId(this.stackId);
diff --git a/dojox/form/manager/_EnableMixin.js b/dojox/form/manager/_EnableMixin.js
index 6182f5b..1a9aec3 100644
--- a/dojox/form/manager/_EnableMixin.js
+++ b/dojox/form/manager/_EnableMixin.js
@@ -25,7 +25,7 @@ dojo.require("dojox.form.manager._Mixin");
 			//		If it is omitted, all known form elements are to be processed.
 
 			var result = this.inspectFormWidgets(ia(function(name, widget){
-				return !widget.attr("disabled");
+				return !widget.get("disabled");
 			}), names);
 
 			if(this.inspectFormNodes){
@@ -53,7 +53,7 @@ dojo.require("dojox.form.manager._Mixin");
 			}
 
 			this.inspectFormWidgets(aa(function(name, widget, value){
-				widget.attr("disabled", !value);
+				widget.set("disabled", !value);
 			}), state, defaultState);
 
 			if(this.inspectFormNodes){
diff --git a/dojox/form/manager/_FormMixin.js b/dojox/form/manager/_FormMixin.js
index 3dd7e6a..e3d9218 100644
--- a/dojox/form/manager/_FormMixin.js
+++ b/dojox/form/manager/_FormMixin.js
@@ -115,7 +115,7 @@ dojo.require("dojox.form.manager._Mixin");
 			for(var name in this.formWidgets){
 				var stop = false;
 				aa(function(_, widget){
-					if(!widget.attr("disabled") && widget.isValid && !widget.isValid()){
+					if(!widget.get("disabled") && widget.isValid && !widget.isValid()){
 						stop = true;
 					}
 				}).call(this, null, this.formWidgets[name].widget);
@@ -124,6 +124,29 @@ dojo.require("dojox.form.manager._Mixin");
 				}
 			}
 			return true;
+		},
+		validate: function () {
+			var isValid = true,
+				formWidgets = this.formWidgets,
+				didFocus = false, name;
+
+			for(name in formWidgets){
+				aa(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);
+						widget.focus();
+						didFocus = true;
+					}
+					isValid = isValid && valid;
+				}).call(this, null, formWidgets[name].widget);
+			}
+
+			return isValid;
 		}
 	});
 })();
diff --git a/dojox/form/manager/_Mixin.js b/dojox/form/manager/_Mixin.js
index a91633c..98bd1a9 100644
--- a/dojox/form/manager/_Mixin.js
+++ b/dojox/form/manager/_Mixin.js
@@ -96,7 +96,7 @@ dojo.require("dijit._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(this.watch && dojo.attr(w.focusNode, "checked")){
+							if(this.watching && dojo.attr(w.focusNode, "checked")){
 								this[o](w.get("value"), name, w, evt);
 							}
 						}));
@@ -109,7 +109,7 @@ dojo.require("dijit._Widget");
 						"onClick" : "onChange";
 				dojo.forEach(observers, function(o){
 					c.push(dojo.connect(w, eventName, this, function(evt){
-						if(this.watch){
+						if(this.watching){
 							this[o](w.get("value"), name, w, evt);
 						}
 					}));
@@ -128,7 +128,7 @@ dojo.require("dijit._Widget");
 		//		functionality. See additional mixins in dojox.form.manager
 		//		namespace.
 
-		watch: true,
+		watching: true,
 
 		startup: function(){
 			// summary:
@@ -288,10 +288,10 @@ dojo.require("dijit._Widget");
 				// input/radio array of widgets
 				if(isSetter){
 					dojo.forEach(elem, function(widget){
-						widget.set("checked", false, !this.watch);
+						widget.set("checked", false, !this.watching);
 					});
 					dojo.forEach(elem, function(widget){
-						widget.set("checked", widget.value === value, !this.watch);
+						widget.set("checked", widget.value === value, !this.watching);
 					});
 					return this;	// self
 				}
@@ -313,7 +313,7 @@ dojo.require("dijit._Widget");
 			// checkbox widget is a special case :-(
 			if(elem.declaredClass == "dijit.form.CheckBox"){
 				if(isSetter){
-					elem.set("value", Boolean(value), !this.watch);
+					elem.set("value", Boolean(value), !this.watching);
 					return this;	// self
 				}
 				return Boolean(elem.get("value"));	// Object
@@ -321,7 +321,7 @@ dojo.require("dijit._Widget");
 
 			// all other elements
 			if(isSetter){
-				elem.set("value", value, !this.watch);
+				elem.set("value", value, !this.watching);
 				return this;	// self
 			}
 			return elem.get("value");	// Object
diff --git a/dojox/form/manager/_NodeMixin.js b/dojox/form/manager/_NodeMixin.js
index c691494..20dcf4c 100644
--- a/dojox/form/manager/_NodeMixin.js
+++ b/dojox/form/manager/_NodeMixin.js
@@ -92,7 +92,7 @@ dojo.require("dojox.form.manager._Mixin");
 				var eventName = ce(n);
 				dojo.forEach(observers, function(o){
 					c.push(dojo.connect(n, eventName, this, function(evt){
-						if(this.watch){
+						if(this.watching){
 							this[o](this.formNodeValue(name), name, n, evt);
 						}
 					}));
diff --git a/dojox/form/nls/ar/PasswordValidator.js b/dojox/form/nls/ar/PasswordValidator.js
index 7760eba..7ced464 100644
--- a/dojox/form/nls/ar/PasswordValidator.js
+++ b/dojox/form/nls/ar/PasswordValidator.js
@@ -1,5 +1,5 @@
 ({
-        nomatchMessage: "كلمة السرية غير مطابقة.",
+        nomatchMessage: "كلمات السرية غير مطابقة.",
 		badPasswordMessage: "كلمة سرية غير صحيحة."
 })
 
diff --git a/dojox/form/nls/kk/PasswordValidator.js b/dojox/form/nls/kk/PasswordValidator.js
new file mode 100644
index 0000000..88eecd5
--- /dev/null
+++ b/dojox/form/nls/kk/PasswordValidator.js
@@ -0,0 +1,5 @@
+({
+        nomatchMessage: "Құпия сөздер сәйкес емес.",
+		badPasswordMessage: "Құпия сөз дұрыс емес."
+})
+
diff --git a/dojox/form/nls/ko/PasswordValidator.js b/dojox/form/nls/ko/PasswordValidator.js
index fdc771d..a5150c9 100644
--- a/dojox/form/nls/ko/PasswordValidator.js
+++ b/dojox/form/nls/ko/PasswordValidator.js
@@ -1,5 +1,5 @@
 ({
         nomatchMessage: "비밀번호가 일치하지 않습니다.",
-		badPasswordMessage: "비밀번호가 올바르지 않습니다."
+		badPasswordMessage: "올바르지 않은 비밀번호"
 })
 
diff --git a/dojox/form/nls/nl/PasswordValidator.js b/dojox/form/nls/nl/PasswordValidator.js
index 075aca7..5b46472 100644
--- a/dojox/form/nls/nl/PasswordValidator.js
+++ b/dojox/form/nls/nl/PasswordValidator.js
@@ -1,5 +1,5 @@
 ({
         nomatchMessage: "Wachtwoorden komen niet overeen.",
-		badPasswordMessage: "Ongeldig wachtwoord. "
+		badPasswordMessage: "Ongeldig wachtwoord."
 })
 
diff --git a/dojox/form/resources/FileInput.css b/dojox/form/resources/FileInput.css
index f9865f8..a807bc0 100644
--- a/dojox/form/resources/FileInput.css
+++ b/dojox/form/resources/FileInput.css
@@ -107,7 +107,7 @@
 	background-color: #fff;
 	background-repeat: repeat-x;
 	background-position: top left;
-	background-image:url("../../../dijit/themes/claro/images/textBox_back.png");
+	background-image:url("../../../dijit/themes/claro/form/images/textBox_back.png");
 	line-height:normal;
 	padding:0.2em 0.3em;
 }
diff --git a/dojox/form/resources/FilePickerTextBox.html b/dojox/form/resources/FilePickerTextBox.html
index e2a0f00..207dbd4 100644
--- a/dojox/form/resources/FilePickerTextBox.html
+++ b/dojox/form/resources/FilePickerTextBox.html
@@ -1,9 +1,9 @@
 <div class="dijit dijitReset dijitInlineTable dijitLeft"
 	id="widget_${id}"
-	waiRole="combobox" tabIndex="-1"
+	role="combobox" tabIndex="-1"
 	><div style="overflow:hidden;"
 		><div class='dijitReset dijitRight dijitButtonNode dijitArrowButton dijitDownArrowButton'
-			dojoAttachPoint="downArrowNode,_buttonNode,_popupStateNode" waiRole="presentation"
+			dojoAttachPoint="downArrowNode,_buttonNode,_popupStateNode" role="presentation"
 			><div class="dijitArrowButtonInner"> </div
 			><div class="dijitArrowButtonChar">▼</div
 		></div
@@ -12,7 +12,7 @@
 		><div class="dijitReset dijitInputField"
 			><input type="text" autocomplete="off" ${!nameAttrSetting} class='dijitReset'
 				dojoAttachEvent='onkeypress:_onKey' 
-				dojoAttachPoint='textbox,focusNode' waiRole="textbox" waiState="haspopup-true,autocomplete-list"
+				dojoAttachPoint='textbox,focusNode' role="textbox" aria-haspopup="true" aria-autocomplete="list"
 		/></div
 	></div
 ></div>
diff --git a/dojox/form/resources/HorizontalRangeSlider.html b/dojox/form/resources/HorizontalRangeSlider.html
index 6d66db6..6aafba0 100644
--- a/dojox/form/resources/HorizontalRangeSlider.html
+++ b/dojox/form/resources/HorizontalRangeSlider.html
@@ -13,15 +13,15 @@
 		></td
 		><td class="dijitReset"
 			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
-			/><div waiRole="presentation" class="dojoxRangeSliderBarContainer" dojoAttachPoint="sliderBarContainer"
-				><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClick" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
+			/><div role="presentation" class="dojoxRangeSliderBarContainer" dojoAttachPoint="sliderBarContainer"
+				><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClick" role="slider" valuemin="${minimum}" valuemax="${maximum}"
 					><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div
 				></div
-				><div waiRole="presentation" dojoAttachPoint="progressBar,focusNode" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onmousedown:_onBarClick"></div
-				><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClickMax" waiRole="sliderMax" valuemin="${minimum}" valuemax="${maximum}"
+				><div role="presentation" dojoAttachPoint="progressBar,focusNode" class="dijitSliderBar dijitSliderBarH dijitSliderProgressBar dijitSliderProgressBarH" dojoAttachEvent="onmousedown:_onBarClick"></div
+				><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableH" dojoAttachEvent="onmousedown:_onHandleClickMax" role="sliderMax" valuemin="${minimum}" valuemax="${maximum}"
 					><div class="dijitSliderImageHandle dijitSliderImageHandleH"></div
 				></div
-				><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onRemainingBarClick"></div
+				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarH dijitSliderRemainingBar dijitSliderRemainingBarH" dojoAttachEvent="onmousedown:_onRemainingBarClick"></div
 			></div
 		></td
 		><td class="dijitReset"
diff --git a/dojox/form/resources/UploaderFileList.css b/dojox/form/resources/UploaderFileList.css
new file mode 100644
index 0000000..b2a9c98
--- /dev/null
+++ b/dojox/form/resources/UploaderFileList.css
@@ -0,0 +1,53 @@
+.dojoxUploaderFileList{
+	border:1px solid #ccc;
+	min-height:50px;
+}
+.dojoxUploaderFileListTable{
+	width:100%;
+	border-collapse:collapse;
+	margin-top:5px;
+}
+.dojoxUploaderFileListHeader th{
+	background-color:#eee;
+	padding:3px;
+}
+.dojoxUploaderFileListRow{
+
+}
+.dojoxUploaderIndex{
+	width:20px;
+}
+.dojoxUploaderIcon{
+	width:50px;
+}
+.dojoxUploaderFileName{
+
+}
+.dojoxUploaderSize{
+	width:70px;
+}
+.dojoxUploaderFileListContent{
+	width:100%;
+}
+.dojoxUploaderFileListProgress{
+	border:1px solid #666;
+	height:15px;
+	position:relative;
+	background:#fff;
+	overflow:hidden;
+}
+.dojoxUploaderFileListPercentText{
+	position:absolute;
+	right:3px;
+	top:3px;
+	font-size:10px;
+	text-align:right;
+}
+.dojoxUploaderFileListProgressBar{
+	position:absolute;
+	top:0px;
+	left:0px;
+	height:15px;
+	width:0%;
+	background:#bfe1fd;
+}
diff --git a/dojox/form/resources/VerticalRangeSlider.html b/dojox/form/resources/VerticalRangeSlider.html
index 24791bb..55b0d22 100644
--- a/dojox/form/resources/VerticalRangeSlider.html
+++ b/dojox/form/resources/VerticalRangeSlider.html
@@ -17,14 +17,14 @@
 		><td dojoAttachPoint="leftDecoration" class="dijitReset dijitSliderDecoration dijitSliderDecorationL dijitSliderDecorationV" style="text-align:center;height:100%;"></td
 		><td class="dijitReset" style="height:100%;"
 			><input dojoAttachPoint="valueNode" type="hidden" ${!nameAttrSetting}
-			/><center waiRole="presentation" style="position:relative;height:100%;" dojoAttachPoint="sliderBarContainer"
-				><div waiRole="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onmousedown:_onRemainingBarClick"
-					><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" style="vertical-align:top;" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
+			/><center role="presentation" style="position:relative;height:100%;" dojoAttachPoint="sliderBarContainer"
+				><div role="presentation" dojoAttachPoint="remainingBar" class="dijitSliderBar dijitSliderBarV dijitSliderRemainingBar dijitSliderRemainingBarV" dojoAttachEvent="onmousedown:_onRemainingBarClick"
+					><div dojoAttachPoint="sliderHandle" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClick" style="vertical-align:top;" role="slider" valuemin="${minimum}" valuemax="${maximum}"
 						><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div
 					></div
-					><div waiRole="presentation" dojoAttachPoint="progressBar,focusNode" tabIndex="${tabIndex}" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onBarClick"
+					><div role="presentation" dojoAttachPoint="progressBar,focusNode" tabIndex="${tabIndex}" class="dijitSliderBar dijitSliderBarV dijitSliderProgressBar dijitSliderProgressBarV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onBarClick"
 					></div
-					><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClickMax" style="vertical-align:top;" waiRole="slider" valuemin="${minimum}" valuemax="${maximum}"
+					><div dojoAttachPoint="sliderHandleMax,focusNodeMax" tabIndex="${tabIndex}" class="dijitSliderMoveable dijitSliderMoveableV" dojoAttachEvent="onkeypress:_onKeyPress,onmousedown:_onHandleClickMax" style="vertical-align:top;" role="slider" valuemin="${minimum}" valuemax="${maximum}"
 						><div class="dijitSliderImageHandle dijitSliderImageHandleV"></div
 					></div
 				></div
diff --git a/dojox/form/tests/UploadFile.php.disabled b/dojox/form/tests/UploadFile.php.disabled
index be491e2..6f981f4 100644
--- a/dojox/form/tests/UploadFile.php.disabled
+++ b/dojox/form/tests/UploadFile.php.disabled
@@ -6,10 +6,11 @@
 //
 //		NOTE: This is obviously a PHP file, and thus you need PHP running for this to work
 //		NOTE: Directories must have write permissions
-//		NOTE: This code uses the GD library (to get image sizes), that sometimes is not pre-installed in a 
-//				standard PHP build. 
+//		NOTE: This code uses the GD library (to get image sizes), that sometimes is not pre-installed in a
+//				standard PHP build.
 //
 require("cLOG.php");
+
 function findTempDirectory()
   {
     if(isset($_ENV["TMP"]) && is_writable($_ENV["TMP"])) return $_ENV["TMP"];
@@ -32,6 +33,8 @@ function trace($txt, $isArray=false){
 	}else{
 		$log->write($txt);
 	}
+
+	//echo "$txt<br>";
 }
 function getImageType($filename){
 	return strtolower(substr(strrchr($filename,"."),1));
@@ -54,54 +57,66 @@ $json = new Services_JSON();
 
 //
 // 	Determine if this is a Flash upload, or an HTML upload
-//	
+//
 //
 
 //		First combine relavant postVars
 $postdata = array();
 $htmldata = array();
 $data = "";
+trace("POSTDATA: " . count($_FILES) . " FILES");
 foreach ($_POST as $nm => $val) {
 	$data .= $nm ."=" . $val . ",";	// string for flash
 	$postdata[$nm] = $val;			// array for html
 }
-trace("POSTDATA:");
+
 trace($postdata, true);
 
+foreach ($_FILES as $nm => $val) {
+	trace("   file: ".$nm ."=" . $val);
+}
+
+foreach ($_GET as $nm => $val) {
+	trace($nm ."=" . $val);
+}
+
 $fieldName = "flashUploadFiles";//Filedata";
 
-if( isset($_FILES[$fieldName])){
+if( isset($_FILES[$fieldName]) || isset($_FILES['uploadedfileFlash'])){
 	//
 	// If the data passed has $fieldName, then it's Flash.
 	// NOTE: "Filedata" is the default fieldname, but we're using a custom fieldname.
+	// The SWF passes one file at a time to the server, so the files come across looking
+	// very much like a single HTML file. The SWF remembers the data and returns it to
+	// Dojo as an array when all are complete.
 	//
-	trace("returnFlashdata.... ");
-	
+	trace("returnFlashdata....");
+
 	trace("");
 	trace("ID:");
-	trace($_POST['testId']);
-	
+
 	trace("Flash POST:");
 	trace($_POST, true);
-	
-	
-	
-	trace("GET:");
-	trace($_GET, true);
-	
-	trace("FILES:");
-	trace($_FILES[$fieldName], true);
-	
-	trace("REQUEST:");
-	trace($_REQUEST, true);
-	
-	
-	
-	
-	
+
+
 	$returnFlashdata = true; //for dev
-	$m = move_uploaded_file($_FILES[$fieldName]['tmp_name'],  $upload_path . $_FILES[$fieldName]['name']);
-	$name = $_FILES[$fieldName]['name'];
+
+	if( isset($_FILES[$fieldName])){
+	  // backwards compat - FileUploader
+	  trace("FILES:");
+	  trace($_FILES[$fieldName], true);
+	  $m = move_uploaded_file($_FILES[$fieldName]['tmp_name'],  $upload_path . $_FILES[$fieldName]['name']);
+	  $name = $_FILES[$fieldName]['name'];
+
+	}else{
+	  // New fieldname - Uploader
+	  trace("FILES:");
+	  trace($_FILES['uploadedfileFlash'], true);
+	  $m = move_uploaded_file($_FILES['uploadedfileFlash']['tmp_name'],  $upload_path . $_FILES['uploadedfileFlash']['name']);
+	  $name = $_FILES['uploadedfileFlash']['name'];
+
+	}
+
 	$file = $upload_path . $name;
 	try{
 	  list($width, $height) = getimagesize($file);
@@ -112,9 +127,9 @@ if( isset($_FILES[$fieldName])){
 	$type = getImageType($file);
 	trace("file: " . $file ."  ".$type." ".$width);
 	// 		Flash gets a string back:
-	
+
 	//exit;
-	
+
 	$data .='file='.$file.',name='.$name.',width='.$width.',height='.$height.',type='.$type;
 	if($returnFlashdata){
 		trace("returnFlashdata:\n=======================");
@@ -126,42 +141,6 @@ if( isset($_FILES[$fieldName])){
 		return;
 	}
 
-
-
-
-}elseif( isset($_FILES['uploadedfile']) ){
-	//
-	// 	If the data passed has 'uploadedfile', then it's HTML. 
-	//	There may be better ways to check this, but this *is* just a test file.
-	//
-	$m = move_uploaded_file($_FILES['uploadedfile']['tmp_name'],  $upload_path . $_FILES['uploadedfile']['name']);
-	
-	trace("HTML single POST:");
-	trace($postdata, true);
-	
-	$name = $_FILES['uploadedfile']['name'];
-	$file = $upload_path . $name;
-	$type = getImageType($file);
-	try{
-	  list($width, $height) = getimagesize($file);
-	} catch(Exception $e){
-	  $width=0;
-	  $height=0;
-	}
-	trace("file: " . $file );
-	
-	foreach($postdata as $m){
-		
-	}
-	
-	$htmldata['file'] = $file;
-	$htmldata['name'] = $name;
-	$htmldata['width'] = $width;
-	$htmldata['height'] = $height;
-	$htmldata['type'] = $type;
-	$htmldata['size'] = filesize($file);
-	$htmldata['additionalParams'] = $postdata;
-	
 }elseif( isset($_FILES['uploadedfile0']) ){
 	//
 	//	Multiple files have been passed from HTML
@@ -169,10 +148,10 @@ if( isset($_FILES[$fieldName])){
 	$cnt = 0;
 	trace("HTML multiple POST:");
 	trace($postdata, true);
-	
+
 	$_post = $htmldata;
 	$htmldata = array();
-	
+
 	while(isset($_FILES['uploadedfile'.$cnt])){
 	  trace("HTML multiple POST");
 		$moved = move_uploaded_file($_FILES['uploadedfile'.$cnt]['tmp_name'],  $upload_path . $_FILES['uploadedfile'.$cnt]['name']);
@@ -188,7 +167,7 @@ if( isset($_FILES[$fieldName])){
 			  $height=0;
 			}
 			trace("file: " . $file );
-			
+
 			$_post['file'] = $file;
 			$_post['name'] = $name;
 			$_post['width'] = $width;
@@ -197,9 +176,9 @@ if( isset($_FILES[$fieldName])){
 			$_post['size'] = filesize($file);
 			$_post['additionalParams'] = $postdata;
 			trace($_post, true);
-			
+
 			$htmldata[$cnt] = $_post;
-			
+
 		}elseif(strlen($_FILES['uploadedfile'.$cnt]['name'])){
 		  $htmldata[$cnt] = array("ERROR" => "File could not be moved: ".$_FILES['uploadedfile'.$cnt]['name']);
 		}
@@ -209,6 +188,108 @@ if( isset($_FILES[$fieldName])){
 	foreach($htmldata as $key => $value){
 		trace($value, true);
 	}
+
+}elseif( isset($_POST['uploadedfiles']) ){
+  trace("HTML5 multi file input... CAN'T ACCESS THIS OBJECT! (POST[uploadedfiles])");
+  trace(count($_POST['uploadedfiles'])." ");
+
+
+}elseif( isset($_FILES['uploadedfiles']) ){
+	//
+	// 	If the data passed has 'uploadedfiles' (plural), then it's an HTML5 multi file input.
+	//
+	$cnt = 0;
+	trace("HTML5 multi file input");
+	//trace($_FILES, true);
+	//print_r($_FILES);
+	$_post = $postdata;
+	trace("POST DATA:::");
+	trace($_post, true);
+	$htmldata = array();
+	$len = count($_FILES['uploadedfiles']['name']);
+	//
+	// Ugh. The array passed from HTML to PHP is fugly.
+	//
+
+	//print_r($_FILES['uploadedfiles']);
+
+	for($i=0;$i<$len;$i++){
+		$moved = move_uploaded_file($_FILES['uploadedfiles']['tmp_name'][$i],  $upload_path . $_FILES['uploadedfiles']['name'][$i]);
+		trace("moved:" . $moved ."  ". $_FILES['uploadedfiles']['name'][$i]);
+		if($moved){
+			$name = $_FILES['uploadedfiles']['name'][$i];
+			$file = $upload_path . $name;
+			$type = getImageType($file);
+			try{
+			  list($width, $height) = getimagesize($file);
+			} catch(Exception $e){
+			  error_log("NO EL MOVEO: " . $name);
+			  $width=0;
+			  $height=0;
+			  $_post['filesInError'] = $name;
+			}
+
+			if(!$width){
+			  $_post['filesInError'] = $name;
+			  $width=0;
+			  $height=0;
+			}
+			trace("file: " . $file ." size: " . $width." ".$height);
+
+			$_post['file'] = $file;
+			$_post['name'] = $name;
+			$_post['width'] = $width;
+			$_post['height'] = $height;
+			$_post['type'] = $type;
+			$_post['size'] = filesize($file);
+			//$_post['additionalParams'] = $postdata;
+			//trace($_post, true);
+
+			$htmldata[$cnt] = $_post;
+
+		}elseif(strlen($_FILES['uploadedfiles']['name'][$i])){
+		  $htmldata[$cnt] = array("ERROR" => "File could not be moved: ".$_FILES['uploadedfiles']['name'][$i]);
+		}
+		$cnt++;
+	}
+
+	$data = $json->encode($htmldata);
+	trace($data);
+	print $data;
+	return $data;
+
+}elseif( isset($_FILES['uploadedfile']) ){
+	//
+	// 	If the data passed has 'uploadedfile', then it's HTML.
+	//	There may be better ways to check this, but this *is* just a test file.
+	//
+	$m = move_uploaded_file($_FILES['uploadedfile']['tmp_name'],  $upload_path . $_FILES['uploadedfile']['name']);
+
+
+
+	trace("HTML single POST:");
+	trace($postdata, true);
+
+	$name = $_FILES['uploadedfile']['name'];
+	$file = $upload_path . $name;
+	$type = getImageType($file);
+	try{
+	  list($width, $height) = getimagesize($file);
+	} catch(Exception $e){
+	  $width=0;
+	  $height=0;
+	}
+	trace("file: " . $file );
+
+	$htmldata['file'] = $file;
+	$htmldata['name'] = $name;
+	$htmldata['width'] = $width;
+	$htmldata['height'] = $height;
+	$htmldata['type'] = $type;
+	$htmldata['size'] = filesize($file);
+	$htmldata['additionalParams'] = $postdata;
+
+
 }elseif(isset($_GET['rmFiles'])){
 	trace("DELETING FILES" . $_GET['rmFiles']);
 	$rmFiles = explode(";", $_GET['rmFiles']);
@@ -219,7 +300,7 @@ if( isset($_FILES[$fieldName])){
 	}
 
 }else{
-	trace("IMROPER DATA SENT... $FILES:");
+	trace("IMROPER DATA SENT... $_FILES:");
 	trace($_FILES);
 	$htmldata = array("ERROR" => "Improper data sent - no files found");
 }
@@ -231,5 +312,4 @@ trace($data);
 // in a text field:
 ?>
 
-<textarea><?php print $data; ?></textarea>
-
+<textarea style="width:600px; height:150px;"><?php print $data; ?></textarea>
diff --git a/dojox/form/tests/images/attach.png b/dojox/form/tests/images/attach.png
new file mode 100644
index 0000000..7fc4811
Binary files /dev/null and b/dojox/form/tests/images/attach.png differ
diff --git a/dojox/form/tests/test_BusyButton.html b/dojox/form/tests/test_BusyButton.html
index 53769e0..12df2d1 100644
--- a/dojox/form/tests/test_BusyButton.html
+++ b/dojox/form/tests/test_BusyButton.html
@@ -27,10 +27,10 @@
 					dijit.byId("button_noTimeout").cancel();
 				});
 				dojo.connect(dijit.byId("buttonCancel2"), "onClick", function(){
-					dijit.byId("button_noTimeout2").attr("label", "Chargeback failed...", 1000);
+					dijit.byId("button_noTimeout2").set("label", "Chargeback failed...", 1000);
 				});
 				dojo.connect(dijit.byId("button_noTimeout3"), "_onClick", function(){
-					dijit.byId("button_noTimeout3").attr("label", "Creating account...");
+					dijit.byId("button_noTimeout3").set("label", "Creating account...");
 					dijit.byId("button_noTimeout3").resetTimeout();
 				});
 			});
diff --git a/dojox/form/tests/test_CheckedMultiSelect.html b/dojox/form/tests/test_CheckedMultiSelect.html
index cd1c45d..f6a3ae7 100644
--- a/dojox/form/tests/test_CheckedMultiSelect.html
+++ b/dojox/form/tests/test_CheckedMultiSelect.html
@@ -1,9 +1,22 @@
+<!DOCTYPE html>
 <html>
 	<head>
-	    <script type="text/javascript" 
-	        src="../../../dojo/dojo.js"
-	        djConfig="isDebug: true, parseOnLoad: true">
-	    </script>
+
+		<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("doh.runner");
 	        dojo.require("dojo.parser");
@@ -39,21 +52,21 @@
 				doh.register("tests",
 					[
 						function test_setValue(t){
-							t.is(["VA","WA"], form.attr("value").ms1);
-							t.is(["TX","GA"], form.attr("value").ms2);
-							ms1.attr("value", ["TN","CA"]);
-							t.is(["TN","CA"], form.attr("value").ms1);
+							t.is(["VA","WA"], form.get("value").ms1);
+							t.is(["TX","GA"], form.get("value").ms2);
+							ms1.set("value", ["TN","CA"]);
+							t.is(["TN","CA"], form.get("value").ms1);
 							ms1.invertSelection();
-							t.is(["VA","WA","FL"], form.attr("value").ms1);							
+							t.is(["VA","WA","FL"], form.get("value").ms1);
 						},
 						function test_addSelected(t){
 							dojo.forEach(ms2.getOptions(ms2.getValue()), function(i){
 								ms2.removeOption(i);
 								ms1.addOption(i);
 							});
-							t.is([], form.attr("value").ms2);
+							t.is([], form.get("value").ms2);
 							ms1.invertSelection();
-							t.is(["TN","CA"], form.attr("value").ms1);
+							t.is(["TN","CA"], form.get("value").ms1);
 						},
 						function delete_selected(t){
 							t.is(["TN","CA"], ms1.getValue());
@@ -68,19 +81,19 @@
 							return d;
 						},
 						function test_storeBased(t){
-							t.is([], ms4.attr("value"));
-							ms4.attr("value", ["CA","AL"]);
-							t.is(["AL","CA"], ms4.attr("value"));
+							t.is([], ms4.get("value"));
+							ms4.set("value", ["CA","AL"]);
+							t.is(["AL","CA"], ms4.get("value"));
 						},
 						function test_changeSelected(t){
-							t.is([], ms5.attr("value"));
-							ms5.attr("value", ["AL", "AK"]);
+							t.is([], ms5.get("value"));
+							ms5.set("value", ["AL", "AK"]);
 							var d = new doh.Deferred();
 							var cb = function(item){
 								try{
 									writeStore.setValue(item, "label", "North Pole");
 									try{
-										t.is(["AL","AK"], ms5.attr("value"));
+										t.is(["AL","AK"], ms5.get("value"));
 										t.is(writeStore.getValue(item, "label"), 
 												dojo.filter(ms5._getChildren(), function(n){return n.option.value==="AK";})[0].labelNode.innerHTML);
 										d.callback(true);
@@ -94,14 +107,14 @@
 							return d;
 						},
 						function test_deleteNonSelected(t){
-							t.is(["AL","AK"], ms5.attr("value"));
+							t.is(["AL","AK"], ms5.get("value"));
 							var d = new doh.Deferred();
 							var cb = function(item){
 								try{
 									t.is(7, ms5._getChildren().length);
 									writeStore.deleteItem(item);
 									try{
-										t.is(["AL","AK"], ms5.attr("value"));
+										t.is(["AL","AK"], ms5.get("value"));
 										t.is(6, ms5._getChildren().length);
 										d.callback(true);
 									}catch(e){ d.errback(e);}
@@ -113,14 +126,14 @@
 							return d;
 						},
 						function test_deleteSelected(t){
-							t.is(["AL","AK"], ms5.attr("value"));
+							t.is(["AL","AK"], ms5.get("value"));
 							var d = new doh.Deferred();
 							var cb = function(item){
 								try{
 									t.is(6, ms5._getChildren().length);
 									writeStore.deleteItem(item);
 									try{
-										t.is(["AL"], ms5.attr("value"));
+										t.is(["AL"], ms5.get("value"));
 										t.is(5, ms5._getChildren().length);
 										d.callback(true);
 									}catch(e){ d.errback(e);}
@@ -132,16 +145,16 @@
 							return d;
 						},
 						function test_newItem(t){
-							t.is(["AL"], ms5.attr("value"));
+							t.is(["AL"], ms5.get("value"));
 							t.is(5, ms5._getChildren().length);
-							ms5.attr("value", ["AL","NY"]);
-							t.is(["AL"], ms5.attr("value"));
+							ms5.set("value", ["AL","NY"]);
+							t.is(["AL"], ms5.get("value"));
 							var d = new doh.Deferred();
 							writeStore.newItem({value: "NY", label: "New York"});
 							try{
 								t.is(6, ms5._getChildren().length);
-								ms5.attr("value", ["AL","NY"]);
-								t.is(["AL","NY"], ms5.attr("value"));
+								ms5.set("value", ["AL","NY"]);
+								t.is(["AL","NY"], ms5.get("value"));
 								d.callback(true);
 							}catch(e){d.errback(e);}
 							return d;
@@ -213,17 +226,8 @@
 				});
 			});
 		</script>
-		<style>
-			@import url(../../../dojo/resources/dojo.css);
-			@import url(../../../dijit/themes/tundra/tundra.css);
-			@import url(../resources/CheckedMultiSelect.css);
-			@import url(../../../dijit/tests/css/dijitTests.css);
-		</style>
-		<style>
-		.ark { text-decoration: underline; }
-		</style>
 	</head>	
-	<body class="tundra">
+	<body class="claro">
 		<h1 class="testTitle">Test: dojox.form.CheckedMultiSelect</h1>
 		<form dojoType="dijit.form.Form" jsId="form">
 			<h2>Check Boxes</h2>
@@ -272,9 +276,28 @@
 			<select jsId="ms5" multiple="true" size="5" name="ms5" store="writeStore" dojoType="dojox.form.CheckedMultiSelect">
 			</select>
 		<hr>
+			<h4 class="testSubtitle">Validation</h4>
+			<select jsId="rq1" multiple="true" required="true" name="rq1" store="readStore" dojoType="dojox.form.CheckedMultiSelect"
+				invalidMessage="You need to select at least one"
+			></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>
 			<button dojoType="dijit.form.Button">
 				<script type="dojo/method" event="onClick">
-					console.dir(form.attr("value"));
+					console.dir(form.get("value"));
 				</script>
 				Get Values
 			</button>
@@ -294,15 +317,15 @@
 			</button>
 			<button dojoType="dijit.form.Button">
 				<script type="dojo/method" event="onClick">
-					ms3.attr("disabled", !ms3.disabled);
-					ss3.attr("disabled", !ss3.disabled);
+					ms3.set("disabled", !ms3.disabled);
+					ss3.set("disabled", !ss3.disabled);
 				</script>
 				Toggle Disabled
 			</button>
 			<button dojoType="dijit.form.Button">
 				<script type="dojo/method" event="onClick">
-					ms2.attr("readOnly", !ms2.readOnly);
-					ss2.attr("readOnly", !ss2.readOnly);
+					ms2.set("readOnly", !ms2.readOnly);
+					ss2.set("readOnly", !ss2.readOnly);
 				</script>
 				Toggle Read Only
 			</button>
@@ -314,7 +337,7 @@
 			</button>
 			<button dojoType="dijit.form.Button">
 				<script type="dojo/method" event="onClick">
-					console.log(ms1.attr("displayedValue"));
+					console.log(ms1.get("displayedValue"));
 				</script>
 				Get Displayed Value
 			</button>
diff --git a/dojox/form/tests/test_FileInput.html b/dojox/form/tests/test_FileInput.html
index e570d9a..6f09f79 100644
--- a/dojox/form/tests/test_FileInput.html
+++ b/dojox/form/tests/test_FileInput.html
@@ -91,6 +91,11 @@
 	<input dojoType="dojox.form.FileInputAuto" id="defaultAuto" name="inputFileAuto" url="../resources/RecieveFile.php" />
 	</p>
 
+	<h3>dojox.form.FileInputAuto, claro theme:</h3>
+	<p class="claro">
+	<input dojoType="dojox.form.FileInputAuto" id="claroAuto" name="inputFileAuto" url="../resources/RecieveFile.php" />
+	</p>
+
 	<h3>another one, tundra theme (with callback)</h3>
 	<p class="tundra">
 	<input dojoType="dojox.form.FileInputAuto" id="defaultAuto2" name="inputFileAuto2" url="../resources/RecieveFile.php" onComplete="sampleCallback"/>
diff --git a/dojox/form/tests/test_FileUploader.html b/dojox/form/tests/test_FileUploader.html
index 80bbec3..341a842 100644
--- a/dojox/form/tests/test_FileUploader.html
+++ b/dojox/form/tests/test_FileUploader.html
@@ -147,6 +147,9 @@
 					rmFiles+=d.file+";";
 				});
 			});
+			dojo.connect(f0, "onCancel", function(data){
+				dojo.byId("fileToUpload").value = "file selection cancelled by user.";
+			});
 
 			Destroy = function(){
 				f0.destroyAll();
diff --git a/dojox/form/tests/test_FileUploaderDialog.html b/dojox/form/tests/test_FileUploaderDialog.html
index 48653f9..f5999a6 100644
--- a/dojox/form/tests/test_FileUploaderDialog.html
+++ b/dojox/form/tests/test_FileUploaderDialog.html
@@ -23,7 +23,7 @@
 		dojo.require("dijit.form.Form");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.layout.TabContainer");
-		
+
         dojo.addOnLoad(function(){
 			console.warn("show")
 			console.log("CP:", dijit.byId("dialogContentPane"))
@@ -32,8 +32,8 @@
 				w.show();
 			}
 		});
-        
-        
+
+
     </script>
     <style>
 		html{
@@ -80,15 +80,20 @@
 			width:300px;
 			height:150px;
 		}
-		
+
 		#myDialog #dialogContentPane{
 			width:400px;
 			height:200px;
-			
+
 		}
     </style>
-	
-	
+	<script>
+		dojo.ready(function(){
+			var fu = dijit.byId("fu")
+			console.log(fu.domNode)
+		});
+	</script>
+
 </head>
 <body class="tundra">
 	<h1>FileUploader Dialog Test</h1>
@@ -99,17 +104,18 @@
 		<strong>NOTE: This test opens a Browse Dialog, but does not upload.</strong>
 	</p>
 		<div id="myDialog" class="dialog" dojoType="dijit.Dialog" title="Edit Account">
+
 		<div id="dialogContentPane" dojoType="dijit.layout.ContentPane">
 			<label>Dummy Upload:</label>
 			<span id="editUsername"></span>
 			<label>Password:</label>
 			<div id="editerror"></div>
 			<div id="editSubmitBtn" class="authButton" dojoType="dijit.form.Button">Submit</div>
-			
-			<button isDebug="false" devMode="false" dojoType="dojox.form.FileUploader">Default Markup Flash</button>
-			<button isDebug="true" devMode="true" force="html" dojoType="dojox.form.FileUploader">Default Markup HTML</button>
+
+			<button id="fu" isDebug="true" devMode="false" dojoType="dojox.form.FileUploader">Default Markup Flash</button>
+			<!--<button isDebug="false" devMode="true" force="html" dojoType="dojox.form.FileUploader">Default Markup HTML</button>-->
 		</div>
 	</div>
-	
+
 </body>
 </html>
diff --git a/dojox/form/tests/test_FileUploaderForm.html b/dojox/form/tests/test_FileUploaderForm.html
index 0ca0ce2..eb0967f 100644
--- a/dojox/form/tests/test_FileUploaderForm.html
+++ b/dojox/form/tests/test_FileUploaderForm.html
@@ -7,8 +7,8 @@
 		@import "../../../dijit/themes/dijit.css";
 		@import "../../../dijit/themes/tundra/form/Button.css";
 		@import "../../../dijit/themes/tundra/ProgressBar.css";
-		@import "../../../dijit/tests/css/dijitTests.css"; 
-		@import "../resources/FileUploader.css"; 
+		@import "../../../dijit/tests/css/dijitTests.css";
+		@import "../resources/FileUploader.css";
 	</style>
 	<script>
         djConfig = {
@@ -22,7 +22,7 @@
         dojo.require("dojox.form.FileUploader");
         dojo.require("dijit.form.Button");
 		dojo.require("dijit.ProgressBar");
-		
+
 		addThumb = function(d, id){
 			console.log("THUMB:", d);
 			var fileRoot = dojo.moduleUrl("dojox.form", "tests").toString();
@@ -47,7 +47,7 @@
 			dojo.byId(id).innerHTML += str;
 		}
         dojo.addOnLoad(function(){
-		
+
 			var props = {
 				isDebug:true,
 				devmode:true,
@@ -62,9 +62,9 @@
 					["All Images", 	"*.jpg;*.jpeg;*.gif;*.png"]
 				]
 			}
-			
+
 			if(dojo.byId("btnF")){
-				dojo.byId("fFiles").value = ""; 
+				dojo.byId("fFiles").value = "";
 				var f = new dojox.form.FileUploader(dojo.mixin({
 					progressWidgetId:"progressBar",
 					showProgress:true,
@@ -74,9 +74,9 @@
 					//uploadOnChange:true,
 					deferredUploading:false
 				},props), "btnF");
-				f.attr("disabled", dojo.byId("fGroup").value=="");
+				f.set("disabled", dojo.byId("fGroup").value=="");
 				dojo.connect(dojo.byId("fGroup"), "keyup", function(){
-					f.attr("disabled", dojo.byId("fGroup").value=="");
+					f.set("disabled", dojo.byId("fGroup").value=="");
 				});
 				dojo.connect(dijit.byId("fSubmit"), "onClick", function(){
 					f.submit(dojo.byId("formF"));
@@ -105,10 +105,10 @@
 					tabIndex:11,
 					devMode:true
 				}, props), "btnH");
-				
-				h.attr("disabled", dojo.byId("hGroup").value=="");
+
+				h.set("disabled", dojo.byId("hGroup").value=="");
 				dojo.connect(dojo.byId("hGroup"), "keyup", function(){
-					h.attr("disabled", dojo.byId("hGroup").value=="");
+					h.set("disabled", dojo.byId("hGroup").value=="");
 				});
 				dojo.connect(dijit.byId("hSubmit"), "onClick", function(evt){
 					h.submit(dojo.byId("formH"));
@@ -126,20 +126,20 @@
 			}
 			if(dijit.byId("btnD")){
 				var d = new FlashHTML.widget(dojo.mixin({button:dijit.byId("btnD")}, props));
-				d.attr("disabled", dojo.byId("dTitle").value=="");
+				d.set("disabled", dojo.byId("dTitle").value=="");
 				dojo.connect(dojo.byId("dTitle"), "keyup", function(){
-					d.attr("disabled", dojo.byId("dTitle").value=="");
+					d.set("disabled", dojo.byId("dTitle").value=="");
 				});
 				dojo.connect(dijit.byId("fSubmit"), "onClick", function(evt){
 					f.submit(dojo.byId("formF"));
 					dojo.stopEvent(evt);
 				});
 			}
-			
-			
+
+
 		});
-        
-        
+
+
     </script>
     <style>
        html, body{
@@ -240,7 +240,7 @@
 		<strong>NOTE:</strong> This test does upload,
 		but the server scripts are renamed to <em>tests/UploadFile.php.<strong>disabled</strong></em> and
 		<em>tests/cLOG.php.<strong>disabled</strong></em> to prevent security attacks on hosted servers.
-		You should rename these files (removing <em>.disabled</em>) in your local copy to conduct tests. 
+		You should rename these files (removing <em>.disabled</em>) in your local copy to conduct tests.
 	</p>
 	<h3>Both forms on this page are the same except one is for testing the Flash Uploader and one
 	is for the HTML Uploader. The following features are being tested:</h3>
@@ -277,7 +277,7 @@
 			<div id="fThumbs" class="thumbList"></div>
 		</td>
 		<td>
-			<form id="formH" class="form">	
+			<form id="formH" class="form">
 				<label>Group Name:</label>
 				<input class="field" tabIndex="7" type="text" value="" id="hGroup" name='hGroup' /><br/>
 				<label>Date:</label>
diff --git a/dojox/form/tests/test_ListInput.html b/dojox/form/tests/test_ListInput.html
index 083911e..a64bc6e 100755
--- a/dojox/form/tests/test_ListInput.html
+++ b/dojox/form/tests/test_ListInput.html
@@ -37,17 +37,17 @@
 		
 		
 		getValues=function() {
-			console.warn(window[current].attr("value"));
+			console.warn(window[current].get("value"));
 		};
 		getValuesMatch=function() {
-			console.warn(window[current].attr("MatchedValue"));
+			console.warn(window[current].get("MatchedValue"));
 		};
 		getValuesMisMatch=function() {
-			console.warn(window[current].attr("MismatchedValue"));
+			console.warn(window[current].get("MismatchedValue"));
 		};
 		
 		disable=function(disable) {
-			window[current].attr("disabled",disable);
+			window[current].set("disabled",disable);
 		};
 		reset=function() {
 			window[current].reset();
diff --git a/dojox/form/tests/test_MultiComboBox.html b/dojox/form/tests/test_MultiComboBox.html
index ce2689f..e017f02 100644
--- a/dojox/form/tests/test_MultiComboBox.html
+++ b/dojox/form/tests/test_MultiComboBox.html
@@ -4,7 +4,7 @@
 	<head>
 	<title>Multi-input ComboBox widget</title>
 		<style type="text/css">
-			@import "../../../dijit/themes/tundra/tundra.css";
+			@import "../../../dijit/themes/claro/claro.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 			@import "../../../dojo/resources/dojo.css";
 
@@ -22,7 +22,7 @@
 			dojo.require("dijit.form.Button"); 
 		</script>
 	</head>
-	<body class="tundra">
+	<body class="claro">
 		
 		<h1 class="testTitle">dojox.form.MultiComboBox</h1>
 		<p>
diff --git a/dojox/form/tests/test_PasswordValidator.html b/dojox/form/tests/test_PasswordValidator.html
index 5d1a4ef..ef6f9e9 100644
--- a/dojox/form/tests/test_PasswordValidator.html
+++ b/dojox/form/tests/test_PasswordValidator.html
@@ -16,12 +16,12 @@
 				doh.register("tests",
 					[
 						function test_setDisabled(t){
-							valid1.attr("disabled", true);
+							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;}));
-							valid1.attr("disabled", false);
+							valid1.set("disabled", false);
 							t.t(dojo.every(dojo.query("[widgetId]", 
 													valid1.domNode).map(function(i){
 														return dijit.byNode(i);
@@ -29,58 +29,58 @@
 						},
 						function test_isValid(t){
 							t.f(form1.isValid());
-							dijit.byId("nv1").attr("value", "test");
-							dijit.byId("vv1").attr("value", "Test");
+							dijit.byId("nv1").set("value", "test");
+							dijit.byId("vv1").set("value", "Test");
 							t.f(form1.isValid());
-							dijit.byId("vv1").attr("value", "test");
+							dijit.byId("vv1").set("value", "test");
 							t.t(form1.isValid());
 							t.t(form6.isValid());
-							t.is({password: ""}, form6.attr("value"));
-							dijit.byId("nv6").attr("value", "test");
+							t.is({password: ""}, form6.get("value"));
+							dijit.byId("nv6").set("value", "test");
 							t.f(form6.isValid());
-							t.is({password: ""}, form6.attr("value"));
-							dijit.byId("vv6").attr("value", "test");
+							t.is({password: ""}, form6.get("value"));
+							dijit.byId("vv6").set("value", "test");
 							t.t(form6.isValid());
-							t.is({password: "test"}, form6.attr("value"));
+							t.is({password: "test"}, form6.get("value"));
 						},
 						function test_getValue(t){
-							dijit.byId("nv1").attr("value", "test");
-							dijit.byId("vv1").attr("value", "Test");
-							t.is({password: ""}, form1.attr("value"));
-							dijit.byId("vv1").attr("value", "test123");
-							dijit.byId("nv1").attr("value", "test123");
-							t.is({password: "test123"}, form1.attr("value"));
+							dijit.byId("nv1").set("value", "test");
+							dijit.byId("vv1").set("value", "Test");
+							t.is({password: ""}, form1.get("value"));
+							dijit.byId("vv1").set("value", "test123");
+							dijit.byId("nv1").set("value", "test123");
+							t.is({password: "test123"}, form1.get("value"));
 						},
 						function test_oldPW(t){
-							dijit.byId("nv2").attr("value", "test");
-							dijit.byId("vv2").attr("value", "test");
+							dijit.byId("nv2").set("value", "test");
+							dijit.byId("vv2").set("value", "test");
 							t.f(form2.isValid());
-							dijit.byId("ov2").attr("value", "oldpw4");
+							dijit.byId("ov2").set("value", "oldpw4");
 							t.f(form2.isValid());
-							dijit.byId("ov2").attr("value", "oldpw2");
+							dijit.byId("ov2").set("value", "oldpw2");
 							t.t(form2.isValid());
 						},
 						function test_getOldValue(t){
-							t.is({password: "test"}, form2.attr("value"));
-							dijit.byId("nv3").attr("value", "test");
-							dijit.byId("vv3").attr("value", "test");
-							dijit.byId("ov3").attr("value", "oldpw4");
-							t.is({password: "", oldPassword: ""}, form3.attr("value"));
-							dijit.byId("ov3").attr("value", "oldpw3");
-							dijit.byId("vv3").attr("value", "Test");
-							t.is({password: "", oldPassword: ""}, form3.attr("value"));
-							dijit.byId("vv3").attr("value", "test");
-							t.is({password: "test", oldPassword: "oldpw3"}, form3.attr("value"));							
+							t.is({password: "test"}, form2.get("value"));
+							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"));
+							dijit.byId("ov3").set("value", "oldpw3");
+							dijit.byId("vv3").set("value", "Test");
+							t.is({password: "", oldPassword: ""}, form3.get("value"));
+							dijit.byId("vv3").set("value", "test");
+							t.is({password: "test", oldPassword: "oldpw3"}, form3.get("value"));
 						},
 						function test_getValuesInTable(t){ 
-							dijit.byId("nv4").attr("value", "test"); 
-							dijit.byId("vv4").attr("value", "test"); 
-							dijit.byId("ov4").attr("value", "oldpw4"); 
-							t.is({password: "test"}, form4.attr("value")); 
-							dijit.byId("nv5").attr("value", "test"); 
-							dijit.byId("vv5").attr("value", "test"); 
-							dijit.byId("ov5").attr("value", "oldpw5"); 
-							t.is({password: "test", oldPassword: "oldpw5"}, form5.attr("value")); 
+							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")); 
+							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")); 
 						} 
 					]
 				);
@@ -202,14 +202,14 @@
 		<button dojoType="dijit.form.Button">
 			<script type="dojo/method" event="onClick">
 				dojo.forEach([form1, form2, form3, form4, form5, form6], function(i){
-					console.dir(i.attr("value"));
+					console.dir(i.get("value"));
 				});
 			</script>
 			Get Values
 		</button>
 		<button dojoType="dijit.form.Button">
 			<script type="dojo/method" event="onClick">
-				valid5.attr("disabled", !valid5.disabled);
+				valid5.set("disabled", !valid5.disabled);
 			</script>
 			Toggle Disabled
 		</button>
diff --git a/dojox/form/tests/test_RangeSlider.html b/dojox/form/tests/test_RangeSlider.html
index 341d5b0..e8873cf 100644
--- a/dojox/form/tests/test_RangeSlider.html
+++ b/dojox/form/tests/test_RangeSlider.html
@@ -64,8 +64,8 @@
 	</div>
 	Horizontal Slider Min Value:<input readonly id="minValue" size="10" value="20.0%"/><br/>
 	Horizontal Slider Max Value:<input readonly id="maxValue" size="10" value="80.0%"/><br/>
-	<button id="disableButton" dojoType="dijit.form.Button" onClick="dijit.byId('hrSlider').attr('disabled', true);dijit.byId('disableButton').attr('disabled',true);dijit.byId('enableButton').attr('disabled',false);">Disable previous slider</button>
-	<button id="enableButton"  dojoType="dijit.form.Button" onClick="dijit.byId('hrSlider').attr('disabled', false);dijit.byId('disableButton').attr('disabled',false);dijit.byId('enableButton').attr('disabled', true);" disabled>Enable previous slider</button>
+	<button id="disableButton" dojoType="dijit.form.Button" onClick="dijit.byId('hrSlider').set('disabled', true);dijit.byId('disableButton').set('disabled',true);dijit.byId('enableButton').set('disabled',false);">Disable previous slider</button>
+	<button id="enableButton"  dojoType="dijit.form.Button" onClick="dijit.byId('hrSlider').set('disabled', false);dijit.byId('disableButton').set('disabled',false);dijit.byId('enableButton').set('disabled', true);" disabled>Enable previous slider</button>
 	
 	<h2>A customized horizontal slider</h2>
 	<div 
@@ -74,7 +74,7 @@
 		dojoType="dojox.form.HorizontalRangeSlider"
 		showButtons="false"
 	></div>
-	<button id="getValues" dojoType="dijit.form.Button" onClick="console.dir(dijit.byId('hrCustomSlider').attr('value'));">Get Value</button>
+	<button id="getValues" dojoType="dijit.form.Button" onClick="console.dir(dijit.byId('hrCustomSlider').get('value'));">Get Value</button>
 
 	<h2>Vertical slider</h2>
 	<div id="vrSlider"
diff --git a/dojox/form/tests/test_SelectStack.html b/dojox/form/tests/test_SelectStack.html
index 1978752..211ab5d 100644
--- a/dojox/form/tests/test_SelectStack.html
+++ b/dojox/form/tests/test_SelectStack.html
@@ -27,10 +27,10 @@
 								dual: "second",
 								dualSecondBox: "Dual First Value on Second (RO)",
 								dualSecondBox2: "Dual Another Value"
-								}, form.attr("value"));
+								}, form.get("value"));
 						},
 						function test_setValues(t){
-							form.attr("value", {
+							form.set("value", {
 								dropDown: "first",
 								dropDownSecondBox: "Changed First Value",
 								radio: "first",
@@ -47,8 +47,8 @@
 								radio: "first",
 								radioFirstBox: "Changed Radio Value",
 								dual: "first"
-							}, form.attr("value"));
-							form.attr("value", {
+							}, form.get("value"));
+							form.set("value", {
 								dropDown: "second",
 								radio: "second",
 								dual: "second"});
@@ -61,7 +61,7 @@
 								dual: "second",
 								dualSecondBox: "Changed me too",
 								dualSecondBox2: "Dual Another Value"
-								}, form.attr("value"));
+								}, form.get("value"));
 						}
 					]
 				);
@@ -120,7 +120,7 @@
 		<hr>
 			<button dojoType="dijit.form.Button">
 				<script type="dojo/method" event="onClick">
-					console.dir(form.attr("value"));
+					console.dir(form.get("value"));
 				</script>
 				Get Values
 			</button>
diff --git a/dojox/form/tests/test_Uploader.html b/dojox/form/tests/test_Uploader.html
new file mode 100644
index 0000000..e788757
--- /dev/null
+++ b/dojox/form/tests/test_Uploader.html
@@ -0,0 +1,173 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+    <title>Test dojox.form.Uploader</title>
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Common.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/form/Common.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Dialog.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/form/Button.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/layout/TabContainer.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Dialog.css" rel="stylesheet" />
+
+	<link href="../resources/UploaderFileList.css" rel="stylesheet" />
+	<style>
+		@import "../../../dijit/tests/css/dijitTests.css";
+		html, body{
+			font-family:sans-serif;
+		}
+		.browseButton{
+			width:300px;
+			height:20px;
+			font-weight:bold;
+			margin:10px 0 2px 0;
+		}
+		.dijitTabPane{
+			padding:20px;
+		}
+		form{
+			width:315px;
+			margin-right:10px;
+		}
+		fieldset{
+			text-align:right;
+		}
+		input[type=text]{
+			width:140px;
+		}
+		.dijitButton{
+			margin-top:15px;
+		}
+		.dojoxUploaderFileList{
+			text-align:left;
+			margin-top:10px;
+		}
+		.pageTable{
+			width:100%;
+		}
+		.pageTable td{
+			vertical-align:top;
+		}
+		#colForm{
+			width:330px;
+		}
+		#colImages{
+			padding-top:7px;
+		}
+		.thumb{
+			border:1px solid #ccc;
+			padding:5px;
+			width:123px;
+			background:#eee;
+			float:left;
+			margin:0 5px 5px 0;
+		}
+		.thumbbk{
+			background:#fff;
+			display:block;
+		}
+		.thumb img{
+			border:1px solid #ccc;
+			width:120px;
+		}
+		.form, .html5, .iframe, .flash{
+			display:none;
+		}
+		.Form .form, .HTML5 .html5, .IFrame .iframe, .Flash .flash{
+			display:block;
+		}
+		#dialog p{
+			width:310px;
+		}
+		.claro .attachButton{
+			width:350px;
+			height:60px;
+			border:0;
+		}
+		.claro .attachButton .dijitButton .dijitButtonNode{
+			background-color:#ffffff;
+			background-image:url(images/attach.png);
+			background-position:left top;
+			background-repeat:no-repeat;
+			height:56px;
+			border:0;
+			-moz-box-shadow:0 0 0;
+			-webkit-box-shadow:0 0 0;
+		}
+		.claro .attachButton .dijitButtonHover .dijitButtonNode{
+			background-position:0px -60px;
+		}
+		code{
+			font-family:monospace;
+			white-space:nowrap;
+		}
+	</style>
+	<script>
+		djConfig = {
+			parseOnLoad:true,
+			isDebug:true
+		}
+	</script>
+	<script src="../../../dojo/dojo.js"></script>
+	<script>
+		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){
+					console.log("display:", file)
+
+					var div = dojo.create('div', {className:'thumb'});
+					var span = dojo.create('span', {className:'thumbbk'}, div);
+					var img = dojo.create('img', {src:file.file}, span);
+					node.appendChild(div);
+				});
+			});
+		}
+		dojo.addOnLoad(function(){
+			dojo.connect(dijit.byId("remBtn"), "onClick", dijit.byId("uploader"), "reset");
+			handleUpload(dijit.byId("uploader"), dojo.byId('colImages'));
+		});
+	</script>
+</head>
+<body class="claro">
+    <h1>Test dojox.form.Uploader</h1>
+	<p style="font-size:14px; border:2px solid #ff0000; padding:3px;">
+		<strong>NOTE:</strong> This test does upload,
+		but the server scripts are renamed to <code>tests/UploadFile.php.<strong>disabled</strong></code> and
+		<code>tests/cLOG.php.<strong>disabled</strong></code> to prevent security attacks on hosted servers.
+		You should rename these files (removing <code>.disabled</code>) in your local copy to conduct tests.
+	</p>
+	<p class="flash">
+		The Flash plugin will use a SWF to upload in non-HTML5 browsers. All other browsers will use the HTML5 plugin,
+		unless <code>force="flash"</code> is used, then Flash will be used in all browsers. <code>force="flash"</code>
+		is provided because Flash has some features that HTML5 does not yet have. But it is still not
+		recommended because of the many problems that Firefox and Webkit have with the Flash plugin.
+	</p>
+
+	<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">
+						<input type="text" name="album" value="Summer Vacation" />
+						<input type="text" name="year" value="2011" />
+						<input type="button" id="remBtn" label="Clear" dojoType="dijit.form.Button" />
+						<input type="submit" label="Submit" dojoType="dijit.form.Button" />
+						<div id="files" dojoType="dojox.form.uploader.FileList" uploaderId="uploader"></div>
+					</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
new file mode 100644
index 0000000..d02a196
--- /dev/null
+++ b/dojox/form/tests/test_UploaderAll.html
@@ -0,0 +1,216 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 5//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+    <title>Test dojox.form.UploaderHTML5</title>
+	<link href="../../../dijit/themes/dijit.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Common.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/form/Common.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Dialog.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/form/Button.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/layout/TabContainer.css" rel="stylesheet" />
+	<link href="../../../dijit/themes/claro/Dialog.css" rel="stylesheet" />
+
+	<link href="../resources/UploaderFileList.css" rel="stylesheet" />
+	<style>
+		@import "../../../dijit/tests/css/dijitTests.css";
+		html, body{
+			font-family:sans-serif;
+		}
+		.browseButton{
+			width:300px;
+			height:20px;
+			font-weight:bold;
+			margin:10px 0 2px 0;
+		}
+		.dijitTabPane{
+			padding:20px;
+		}
+		form{
+			width:315px;
+			margin-right:10px;
+		}
+		fieldset{
+			text-align:right;
+		}
+		input[type=text]{
+			width:140px;
+		}
+		.dijitButton{
+			margin-top:15px;
+		}
+		.dojoxUploaderFileList{
+			text-align:left;
+			margin-top:10px;
+		}
+		.pageTable{
+			width:100%;
+		}
+		.pageTable td{
+			vertical-align:top;
+		}
+		#colForm{
+			width:330px;
+		}
+		#colImages{
+			padding-top:7px;
+		}
+		.thumb{
+			border:1px solid #ccc;
+			padding:5px;
+			width:123px;
+			background:#eee;
+			float:left;
+			margin:0 5px 5px 0;
+		}
+		.thumbbk{
+			background:#fff;
+			display:block;
+		}
+		.thumb img{
+			border:1px solid #ccc;
+			width:120px;
+		}
+		.form, .html5, .iframe, .flash{
+			display:none;
+		}
+		.Form .form, .HTML5 .html5, .IFrame .iframe, .Flash .flash{
+			display:block;
+		}
+		#dialog p{
+			width:310px;
+		}
+		.claro .attachButton{
+			width:350px;
+			height:60px;
+			border:0;
+		}
+		.claro .attachButton .dijitButton .dijitButtonNode{
+			background-color:#ffffff;
+			background-image:url(images/attach.png);
+			background-position:left top;
+			background-repeat:no-repeat;
+			height:56px;
+			border:0;
+			-moz-box-shadow:0 0 0;
+			-webkit-box-shadow:0 0 0;
+		}
+		.claro .attachButton .dijitButtonHover .dijitButtonNode{
+			background-position:0px -60px;
+		}
+		code{
+			font-family:monospace;
+			white-space:nowrap;
+		}
+	</style>
+	<script>
+		djConfig = {
+			parseOnLoad:true,
+			isDebug:true
+		}
+	</script>
+	<script src="../../../dojo/dojo.js"></script>
+	<script>
+		dojo.require("dojox.form.Uploader");
+		dojo.require("dojox.form.uploader.FileList");
+		dojo.require("dijit.form.Button");
+
+		// Dynamically determining which plugin to use, based off of the location search.
+		var plug = "Form"; // Default
+		switch(document.location.search){
+			case "?html5":
+				dojo.require("dojox.form.uploader.plugins.HTML5");
+				plug = "HTML5";
+				break;
+			case "?iframe":
+				dojo.require("dojox.form.uploader.plugins.IFrame");
+				plug = "IFrame";
+				break;
+			case "?flash":
+				dojo.require("dojox.form.uploader.plugins.Flash");
+				plug = "Flash";
+				break;
+		}
+
+		var title = "Test dojox.form.Uploader + " + plug;
+		document.title = title;
+		var handleUpload = function(upl, node){
+			if(plug == "Form"){
+				dojo.connect(upl, "onChange", function(){
+					node.appendChild(dojo.create('div', {innerHTML:"This Uploader does not work in Form mode."}));
+					//alert("This Uploader does not work in Form mode.")
+				});
+			}
+			dojo.connect(upl, "onComplete", function(dataArray){
+				dojo.forEach(dataArray, function(file){
+					console.log("display:", file)
+
+					var div = dojo.create('div', {className:'thumb'});
+					var span = dojo.create('span', {className:'thumbbk'}, div);
+					var img = dojo.create('img', {src:file.file}, span);
+					node.appendChild(div);
+				});
+			});
+		}
+		dojo.addOnLoad(function(){
+			dojo.addClass(dojo.body(), plug);
+			dojo.query('h1')[0].innerHTML = title;
+			dojo.connect(dijit.byId("remBtn"), "onClick", dijit.byId("uploader"), "reset");
+			handleUpload(dijit.byId("uploader"), dojo.byId('colImages'));
+		});
+	</script>
+</head>
+<body class="claro">
+    <h1>Test dojox.form.Uploader Flash</h1>
+	<p style="font-size:14px; border:2px solid #ff0000; padding:3px;">
+		<strong>NOTE:</strong> This test does upload,
+		but the server scripts are renamed to <code>tests/UploadFile.php.<strong>disabled</strong></code> and
+		<code>tests/cLOG.php.<strong>disabled</strong></code> to prevent security attacks on hosted servers.
+		You should rename these files (removing <code>.disabled</code>) in your local copy to conduct tests.
+	</p>
+	<p class="form">
+		The Uploader with no plugins is in "Form" mode. This mode <strong>will not do an Ajax upload</strong>.
+		Only form POSTs will work and they will navigate to the UploadFile.php page.
+	</p>
+	<p class="html5">
+		The HTML5 Uploder plugin does not support IE. HTML5 is more of a base class for IFrame or
+		Flash, or used in cases where IE is not a requirement. This test case is for development purposes.
+	</p>
+	<p class="iframe">
+		The IFrame plugin will use the IFrame to upload in IE. All other browsers will use the HTML5 plugin
+		unless force="iframe" is used.
+		When using this plugin, be sure your form use the attribute: <code>enctype="multipart/form-data"</code>
+	</p>
+	<p class="flash">
+		The Flash plugin will use a SWF to upload in non-HTML5 browsers. All other browsers will use the HTML5 plugin,
+		unless <code>force="flash"</code> is used, then Flash will be used in all browsers. <code>force="flash"</code>
+		is provided because Flash has some features that HTML5 does not yet have. But it is still not
+		recommended because of the many problems that Firefox and Webkit have with the Flash plugin.
+	</p>
+	<p>
+		<a href="test_UploaderAll.html">Form</a>
+		<a href="test_UploaderAll.html?html5">HTML5</a>
+		<a href="test_UploaderAll.html?iframe">IFrame</a>
+		<a href="test_UploaderAll.html?flash">Flash</a>
+	</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">
+						<input type="text" name="album" value="Summer Vacation" />
+						<input type="text" name="year" value="2011" />
+						<input type="button" id="remBtn" label="Clear" dojoType="dijit.form.Button" />
+						<input type="submit" label="Submit" dojoType="dijit.form.Button" />
+						<div id="files" dojoType="dojox.form.uploader.FileList" uploaderId="uploader"></div>
+					</fieldset>
+				</form>
+			</td>
+			<td id="colImages">
+			</td>
+		</tr>
+	</table>
+
+</body>
+</html>
diff --git a/dojox/form/uploader/Base.js b/dojox/form/uploader/Base.js
new file mode 100644
index 0000000..0c8dc2c
--- /dev/null
+++ b/dojox/form/uploader/Base.js
@@ -0,0 +1,120 @@
+dojo.provide("dojox.form.uploader.Base");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+
+dojo.declare("dojox.form.uploader.Base", [dijit._Widget, dijit._Templated], {
+	//
+	// Version: 1.6
+	//
+	// summary:
+	// 		The Base class used for dojox.form.Uploader and dojox.form.uploader.FileList.
+	//
+	// 	description:
+	// 		Should not be used as a standalone. To be mixed in with other classes.
+	//
+
+	getForm: function(){
+		// summary:
+		// 		Finds the parent form of the Uploader, if it exists.
+		//
+		if(!this.form){
+			var n = this.domNode;
+			while(n && n.tagName && n !== document.body){
+				if(n.tagName.toLowerCase() == "form"){
+					this.form = n;
+					break;
+				}
+				n = n.parentNode;
+			}
+		}
+		return this.form // Node;
+	},
+
+	getUrl: function(){
+		// summary:
+		// 		Finds the URL to upload to, whether it be the action in the parent form, this.url or
+		// 		this.uploadUrl
+		//
+		if(this.uploadUrl) this.url = this.uploadUrl;
+		if(this.url) return this.url;
+		if(this.getForm()) this.url = this.form.action;
+		return this.url; // String
+	},
+
+
+	connectForm: function(){
+		//console.log("connectForm...", this.url, !!this.uploadUrl, !!this.getForm())
+
+		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));
+			});
+			//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 false; // Boolean
+	},
+	getMimeType: function(){
+		//	summary:
+		//		Returns the mime type that should be used in an HTML5 upload form. Return result
+		//		may change as the current use is very generic.
+		//
+		return "application/octet-stream"; //image/gif
+	},
+	getFileType: function(/* String */name){
+		// summary:
+		// 		Gets the extension of a file
+		return name.substring(name.lastIndexOf(".")+1).toUpperCase(); // String
+	},
+	convertBytes: function(bytes){
+		// summary:
+		// 		Converts bytes. Returns an object with all conversions. The "value" property is
+		// 		considered the most likely desired result.
+		//
+		var kb = Math.round(bytes/1024*100000)/100000;
+		var mb = Math.round(bytes/1048576*100000)/100000;
+		var gb = Math.round(bytes/1073741824*100000)/100000;
+		var value = bytes;
+		if(kb>1) value = kb.toFixed(1)+" kb";
+		if(mb>1) value = mb.toFixed(1)+" mb";
+		if(gb>1) value = gb.toFixed(1)+" gb";
+		return {
+			kb:kb,
+			mb:mb,
+			gb:gb,
+			bytes:bytes,
+			value: value
+		}; // Object
+	}
+});
diff --git a/dojox/form/uploader/FileList.js b/dojox/form/uploader/FileList.js
new file mode 100644
index 0000000..2f30a1b
--- /dev/null
+++ b/dojox/form/uploader/FileList.js
@@ -0,0 +1,184 @@
+dojo.provide("dojox.form.uploader.FileList");
+
+dojo.require("dojox.form.uploader.Base");
+
+dojo.declare("dojox.form.uploader.FileList", [dojox.form.uploader.Base], {
+	//
+	// Version: 1.6
+	//
+	// summary:
+	//		A simple widget that provides a list of the files currently selected by
+	//		dojox.form.Uploader
+	//
+	//	description:
+	//		There is a required CSS file: resources/UploaderFileList.css.
+	//		This is a very simple widget, and not beautifully styled. It is here mainly for test
+	//		cases, but could very easily be used, extended, modified, or copied.
+	//
+	//	uploaderId: String
+	//		The id of the dojox.form.Uploader to connect to.
+	uploaderId:"",
+	//	uploader: dojox.form.Uploader
+	//		The dojox.form.Uploader to connect to. Use either this property of unploaderId. This
+	//		property is populated if uploaderId is used.
+	//
+	uploader:null,
+	//	headerIndex: String
+	// 		The label for the index column.
+	//
+	headerIndex:"#",
+	//	headerType: String
+	// 		The label for the file type column.
+	//
+	headerType:"Type",
+	//	headerFilename: String
+	// 		The label for the file name column.
+	//
+	headerFilename:"File Name",
+	//	headerFilesize: String
+	// 		The label for the file size column.
+	//
+	headerFilesize:"Size",
+
+	_upCheckCnt:0,
+	rowAmt:0,
+
+	templateString:	'<div class="dojoxUploaderFileList">' +
+						'<div dojoAttachPoint="progressNode" class="dojoxUploaderFileListProgress"><div dojoAttachPoint="percentBarNode" class="dojoxUploaderFileListProgressBar"></div><div dojoAttachPoint="percentTextNode" class="dojoxUploaderFileListPercentText">0%</div></div>' +
+						'<table class="dojoxUploaderFileListTable">'+
+							'<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>'+
+						'</table>'+
+						'<div>'
+						,
+
+	postCreate: function(){
+		this.setUploader();
+		this.hideProgress();
+	},
+
+	reset: function(){
+		// summary:
+		//		Clears all rows of items. Happens automatically if Uploader is reset, but you
+		//		could call this directly.
+		//
+		for(var i=0;i<this.rowAmt;i++){
+			this.listNode.deleteRow(0);
+		}
+		this.rowAmt = 0;
+	},
+
+	setUploader: function(){
+		// summary:
+		//		Connects to the Uploader based on the uploader or the uploaderId properties.
+		//
+		if(!this.uploaderId && !this.uploader){
+			console.warn("uploaderId not passed to UploaderFileList");
+		}else if(this.uploaderId && !this.uploader){
+			this.uploader = dijit.byId(this.uploaderId);
+		}else if(this._upCheckCnt>4){
+			console.warn("uploader not found for ID ", this.uploaderId);
+			return;
+		}
+		if(this.uploader){
+			this.connect(this.uploader, "onChange", "_onUploaderChange");
+			this.connect(this.uploader, "reset", "reset");
+			this.connect(this.uploader, "onBegin", function(){
+				this.showProgress(true);
+			});
+			this.connect(this.uploader, "onProgress", "_progress");
+			this.connect(this.uploader, "onComplete", function(){
+				setTimeout(dojo.hitch(this, function(){
+					this.hideProgress(true);
+				}), 1250);
+			});
+		}else{
+			this._upCheckCnt++;
+			setTimeout(dojo.hitch(this, "setUploader"), 250);
+		}
+	},
+
+	hideProgress: function(/* Boolean */animate){
+		var o = animate ? {
+			ani:true,
+			endDisp:"none",
+			beg:15,
+			end:0
+		} : {
+			endDisp:"none",
+			ani:false
+		};
+		this._hideShowProgress(o);
+	},
+
+	showProgress: function(/* Boolean */animate){
+		var o = animate ? {
+			ani:true,
+			endDisp:"block",
+			beg:0,
+			end:15
+		} : {
+			endDisp:"block",
+			ani:false
+		};
+		this._hideShowProgress(o);
+	},
+
+	_progress: function(/* Object */ customEvent){
+		this.percentTextNode.innerHTML = customEvent.percent;
+		dojo.style(this.percentBarNode, "width", customEvent.percent);
+	},
+
+	_hideShowProgress: function(o){
+		var node = this.progressNode;
+		var onEnd = function(){
+			dojo.style(node, "display", o.endDisp);
+		}
+		if(o.ani){
+			dojo.style(node, "display", "block");
+			dojo.animateProperty({
+				node: node,
+				properties:{
+					height:{
+						start:o.beg,
+						end:o.end,
+						units:"px"
+					}
+				},
+				onEnd:onEnd
+			}).play();
+		}else{
+			onEnd();
+		}
+	},
+
+	_onUploaderChange: function(fileArray){
+		this.reset();
+		dojo.forEach(fileArray, function(f, i){
+			this._addRow(i+1, this.getFileType(f.name), f.name, f.size);
+		}, this)
+	},
+
+	_addRow: function(index, type, name, size){
+
+		var c, r = this.listNode.insertRow(-1);
+		c = r.insertCell(-1);
+		dojo.addClass(c, "dojoxUploaderIndex");
+		c.innerHTML = index;
+
+		c = r.insertCell(-1);
+		dojo.addClass(c, "dojoxUploaderIcon");
+		c.innerHTML = type;
+
+		c = r.insertCell(-1);
+		dojo.addClass(c, "dojoxUploaderFileName");
+		c.innerHTML = name;
+		c = r.insertCell(-1);
+		dojo.addClass(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
new file mode 100644
index 0000000..42ebc0f
--- /dev/null
+++ b/dojox/form/uploader/plugins/Flash.js
@@ -0,0 +1,314 @@
+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", [], {
+	//
+	// Version: 1.6
+	//
+	// summary:
+	//		A plugin for dojox.form.Uploader that utilizes a Flash SWF for handling to upload in IE.
+	//		All other browsers will use the HTML5 plugin, unless force="flash" is used, then Flash
+	//		will be used in all browsers. force="flash"	is provided because Flash has some features
+	//		that HTML5 does not yet have. But it is still not recommended because of the many problems
+	//		that Firefox and Webkit have with the Flash plugin.
+	//
+	//	description:
+	//		Inherits all properties from dojox.form.Uploader and dojox.form.uploader.plugins.HTML5.
+	//		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"),
+	//
+	// skipServerCheck: Boolean
+	// 		If true, will not verify that the server was sent the correct format.
+	//		This can be safely set to true. The purpose of the server side check
+	//		is mainly to show the dev if they've implemented the different returns
+	//		correctly.
+	skipServerCheck:true,
+	//
+	// serverTimeout:Number (milliseconds)
+	//		The amount of time given to the uploaded file
+	//		to wait for a server response. After this amount
+	//		of time, the onComplete is fired but with a 'server timeout'
+	//		error in the returned item.
+	serverTimeout: 2000,
+	//
+	//	isDebug: Boolean
+	//		If true, outputs traces from the SWF to console. What exactly gets passed
+	//		is very relative, and depends upon what traces have been left in the DEFT SWF.
+	isDebug:false,
+	//
+	//	devMode: Boolean.
+	//		Re-implemented. devMode increases the logging, adding style tracing from the SWF.
+	devMode:false,
+	//
+	//	deferredUploading: Number (1 - X)
+	//		(Flash only) throttles the upload to a certain amount of files at a time.
+	//		By default, Flash uploads file one at a time to the server, but in parallel.
+	//		Firefox will try to queue all files at once, leading to problems. Set this
+	//		to the amount to upload in parallel at a time.
+	//		Generally, 1 should work fine, but you can experiment with queuing more than
+	//		one at a time.
+	//		This is of course ignored if selectMultipleFiles equals false.
+	deferredUploading:0,
+	//
+	//	force: String
+	//		Use "flash" to always use Flash (and hopefully force the user to download the plugin
+	//		if they don't have it).
+	force:"",
+
+	postMixInProperties: function(){
+		if(!this.supports("multiple")){
+			// Flash will only be used in IE6-8 unless force="flash"
+			this.uploadType = "flash";
+			this._files = [];
+			this._fileMap = {};
+			this._createInput = this._createFlashUploader;
+			this.getFileList = this.getFlashFileList;
+			this.reset = this.flashReset;
+			this.upload = this.uploadFlash;
+			this.submit = this.submitFlash;
+			this.fieldname = "flashUploadFiles"; ///////////////////// this.name
+		}
+		this.inherited(arguments);
+	},
+
+	/*************************
+	 *	   Public Events	 *
+	 *************************/
+
+	onReady: function(/* dojox.form.FileUploader */ uploader){
+		// summary:
+		//		Stub - Fired when dojox.embed.Flash has created the
+		//		Flash object, but it has not necessarilly finished
+		//		downloading, and is ready to be communicated with.
+	},
+
+	onLoad: function(/* dojox.form.FileUploader */ uploader){
+		// summary:
+		//		Stub - SWF has been downloaded 100%.
+	},
+
+	onFileChange: function(fileArray){
+		// summary:
+		// 		Stub - Flash-specific event. Fires on each selection of files
+		// 		and only provides the files selected on that event - not all files
+		// 		selected, as with HTML5
+	},
+
+	onFileProgress: function(fileArray){
+		// summary:
+		// 		Stub - Flash-specific event. Fires on progress of upload
+		// 		and only provides a file-specific event
+	},
+
+
+	/*************************
+	 *	   Public Methods	 *
+	 *************************/
+
+	getFlashFileList: function(){
+		// summary:
+		//		Returns list of currently selected files
+		return this._files; // Array
+	},
+
+	flashReset: function(){
+		this.flashMovie.reset();
+		this._files = [];
+	},
+
+	/*************************
+	 *	   Private Methods	 *
+	 *************************/
+
+	uploadFlash: function(){
+		// 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);
+	},
+
+
+	_change: function(fileArray){
+		this._files = this._files.concat(fileArray);
+		dojo.forEach(fileArray, function(f){
+			f.bytesLoaded = 0;
+			f.bytesTotal = f.size;
+			this._fileMap[f.name+"_"+f.size] = f;
+		}, this);
+		this.onChange(this._files);
+		this.onFileChange(fileArray);
+	},
+	_complete: function(fileArray){
+		var o = this._getCustomEvent();
+		o.type = "load";
+		this.onComplete(fileArray);
+	},
+	_progress: function(f){
+		this._fileMap[f.name+"_"+f.bytesTotal].bytesLoaded = f.bytesLoaded;
+		var o = this._getCustomEvent();
+		this.onFileProgress(f);
+		this.onProgress(o);
+	},
+	_error: function(err){
+		this.onError(err);
+	},
+	_onFlashBlur: function(fileArray){
+		//console.log("UploaderFlash._onFlashBlur");
+	},
+
+	_getCustomEvent: function(){
+		var o = {
+			bytesLoaded:0,
+			bytesTotal:0,
+			type:"progress",
+			timeStamp:new Date().getTime()
+		};
+
+
+		for(var nm in this._fileMap){
+			o.bytesTotal += this._fileMap[nm].bytesTotal;
+			o.bytesLoaded += this._fileMap[nm].bytesLoaded;
+		}
+		o.decimal = o.bytesLoaded / o.bytesTotal;
+		o.percent = Math.ceil((o.bytesLoaded / o.bytesTotal)*100)+"%";
+		return o; // Object
+	},
+
+	_connectFlash: function(){
+		// 	summary:
+		//		Subscribing to published topics coming from the
+		//		Flash uploader.
+		// 	description:
+		//		Sacrificing some readbilty for compactness. this.id
+		//		will be on the beginning of the topic, so more than
+		//		one uploader can be on a page and can have unique calls.
+		//
+
+		this._subs = [];
+		this._cons = [];
+
+		var doSub = dojo.hitch(this, function(s, funcStr){
+			this._subs.push(dojo.subscribe(this.id + s, this, funcStr));
+		});
+
+		doSub("/filesSelected", "_change");
+		doSub("/filesUploaded", "_complete");
+		doSub("/filesProgress", "_progress");
+		doSub("/filesError", "_error");
+		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
+			this.flashMovie.focus();
+			this.flashMovie.doFocus();
+		});
+		if(this.tabIndex>=0){
+			dojo.attr(this.domNode, "tabIndex", this.tabIndex);
+		}
+	},
+	_createFlashUploader: function(){
+		// summary:
+		//		Internal. Creates Flash Uploader
+		//
+		var url = this.getUrl();
+		if(url){
+			if(url.toLowerCase().indexOf("http")<0 && url.indexOf("/")!=0){
+				// Appears to be a relative path. Attempt to
+				//	convert it to absolute, so it will better
+				//target the SWF.
+				//
+				var loc = window.location.href.split("/");
+				loc.pop();
+				loc = loc.join("/")+"/";
+				url = loc+url;
+			}
+		}else{
+			console.warn("Warning: no uploadUrl provided.");
+		}
+
+		this.inputNode = dojo.create("div", {className:"dojoxFlashNode"}, this.domNode, "first");
+		dojo.style(this.inputNode, {
+			position:"absolute",
+			top:"-2px",
+			width:this.btnSize.w+"px",
+			height:this.btnSize.h+"px",
+			opacity:0
+		});
+
+		var w = this.btnSize.w;
+		var h = this.btnSize.h;
+
+		var args = {
+			expressInstall:true,
+			path: (this.swfPath.uri || this.swfPath) + "?cb_" + (new Date().getTime()),
+			width: w,
+			height: h,
+			allowScriptAccess:"always",
+			allowNetworking:"all",
+			vars: {
+				uploadDataFieldName: this.flashFieldName || this.name+"Flash",
+				uploadUrl: url,
+				uploadOnSelect: this.uploadOnSelect,
+				deferredUploading:this.deferredUploading || 0,
+				selectMultipleFiles: this.multiple,
+				id: this.id,
+				isDebug: this.isDebug,
+				noReturnCheck: this.skipServerCheck,
+				serverTimeout:this.serverTimeout
+			},
+			params: {
+				scale:"noscale",
+				wmode:"transparent",
+				wmode:"opaque",
+				allowScriptAccess:"always",
+				allowNetworking:"all"
+			}
+
+		};
+
+		this.flashObject = new dojox.embed.Flash(args, this.inputNode);
+		this.flashObject.onError = dojo.hitch(function(msg){
+			console.error("Flash Error: " + msg);
+		});
+		this.flashObject.onReady = dojo.hitch(this, function(){
+			this.onReady(this);
+		});
+		this.flashObject.onLoad = dojo.hitch(this, function(mov){
+			this.flashMovie = mov;
+			this.flashReady = true;
+
+			this.onLoad(this);
+		});
+		this._connectFlash();
+	}
+});
+dojox.form.addUploaderPlugin(dojox.form.uploader.plugins.Flash);
diff --git a/dojox/form/uploader/plugins/HTML5.js b/dojox/form/uploader/plugins/HTML5.js
new file mode 100644
index 0000000..a1681d8
--- /dev/null
+++ b/dojox/form/uploader/plugins/HTML5.js
@@ -0,0 +1,214 @@
+dojo.provide("dojox.form.uploader.plugins.HTML5");
+
+dojo.declare("dojox.form.uploader.plugins.HTML5", [], {
+	//
+	// Version: 1.6
+	//
+	// summary:
+	//		A plugin for dojox.form.Uploader that adds HTML5 multiple-file upload capabilities and
+	//		progress events.
+	//
+	//	description:
+	//		Add this plugin to have HTML5 capabilities in the Uploader. Note that it does not add
+	//		these capabilities to browsers that don't support them. For IE or older browsers, add
+	//		additional plugins: IFrame or Flash.
+	//
+	errMsg:"Error uploading files. Try checking permissions",
+
+	// Overwrites "form" and could possibly be overwritten again by iframe or flash plugin.
+	uploadType:"html5",
+
+	postCreate: function(){
+		this.connectForm();
+		this.inherited(arguments);
+		if(this.uploadOnSelect){
+			this.connect(this, "onChange", "upload");
+		}
+	},
+
+	/*************************
+	 *	   Public Methods	 *
+	 *************************/
+
+	upload: function(/*Object ? */formData){
+		// summary:
+		// 		See: dojox.form.Uploader.upload
+		//
+		this.onBegin(this.getFileList());
+		if(this.supports("FormData")){
+			this.uploadWithFormData(formData);
+		}else if(this.supports("sendAsBinary")){
+			this.sendAsBinary(formData);
+		}
+	},
+
+	submit: function(/* form Node ? */form){
+		// 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);
+	},
+
+	sendAsBinary: function(/* Object */data){
+		// summary:
+		// 		Used primarily in FF < 4.0. Sends files and form object as binary data, written to
+		// 		still enable use of $_FILES in PHP (or equivalent).
+		// tags:
+		// 		private
+		//
+		if(!this.getUrl()){
+			console.error("No upload url found.", this); return;
+		}
+
+		// The date/number doesn't matter but amount of dashes do. The actual boundary
+		// will have two more dashes than this one which is used in the header.
+		var boundary = "---------------------------" + (new Date).getTime();
+		var xhr = this.createXhr();
+
+		xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
+
+		// finally send the request as binary data
+		// still accessed as $_FILES
+		var msg = this._buildRequestBody(data, boundary);
+		if(!msg){
+			this.onError(this.errMsg);
+		}else{
+			xhr.sendAsBinary(msg);
+		}
+	},
+	uploadWithFormData: function(/* Object */data){
+		// summary
+		// 		Used with WebKit and Firefox 4+
+		// 		Upload files using the much friendlier FormData browser object.
+		// tags:
+		// 		private
+		//
+		if(!this.getUrl()){
+			console.error("No upload url found.", this); return;
+		}
+
+		var fd = new FormData();
+		dojo.forEach(this.inputNode.files, function(f, i){
+			fd.append(this.name+"s[]", f);
+		}, this);
+
+		if(data){
+			for(var nm in data){
+				fd.append(nm, data[nm]);
+			}
+		}
+
+		var xhr = this.createXhr();
+		xhr.send(fd);
+	},
+
+	_xhrProgress: function(evt){
+		if(evt.lengthComputable){
+			var o = {
+				bytesLoaded:evt.loaded,
+				bytesTotal:evt.total,
+				type:evt.type,
+				timeStamp:evt.timeStamp
+			};
+			if(evt.type == "load"){
+				// 100%
+				o.percent = "100%",
+				o.decimal = 1;
+			}else{
+				o.decimal = evt.loaded / evt.total;
+				o.percent = Math.ceil((evt.loaded / evt.total)*100)+"%";
+			}
+			this.onProgress(o);
+		}
+	},
+
+	createXhr: function(){
+		var xhr = new XMLHttpRequest();
+		var timer;
+        xhr.upload.addEventListener("progress", dojo.hitch(this, "_xhrProgress"), false);
+        xhr.addEventListener("load", dojo.hitch(this, "_xhrProgress"), false);
+        xhr.addEventListener("error", dojo.hitch(this, function(evt){
+			this.onError(evt);
+			clearInterval(timer);
+		}), false);
+        xhr.addEventListener("abort", dojo.hitch(this, function(evt){
+			this.onAbort(evt);
+			clearInterval(timer);
+		}), false);
+        xhr.onreadystatechange = dojo.hitch(this, function() {
+			if (xhr.readyState === 4) {
+				console.info("COMPLETE")
+				clearInterval(timer);
+				this.onComplete(dojo.eval(xhr.responseText));
+			}
+		});
+        xhr.open("POST", this.getUrl());
+
+		timer = setInterval(dojo.hitch(this, function(){
+			try{
+				if(typeof(xhr.statusText)){} // accessing this error throws an error. Awesomeness.
+			}catch(e){
+				//this.onError("Error uploading file."); // not always an error.
+				clearInterval(timer);
+			}
+		}),250);
+
+		return xhr;
+	},
+
+	_buildRequestBody : function(data, boundary) {
+		var EOL  = "\r\n";
+		var part = "";
+		boundary = "--" + boundary;
+
+		var filesInError = [];
+		dojo.forEach(this.inputNode.files, function(f, i){
+			var fieldName = this.name+"s[]";//+i;
+			var fileName  = this.inputNode.files[i].fileName;
+			var binary;
+
+			try{
+				binary = this.inputNode.files[i].getAsBinary() + EOL;
+				part += boundary + EOL;
+				part += 'Content-Disposition: form-data; ';
+				part += 'name="' + fieldName + '"; ';
+				part += 'filename="'+ fileName + '"' + EOL;
+				part += "Content-Type: " + this.getMimeType() + EOL + EOL;
+				part += binary;
+			}catch(e){
+				filesInError.push({index:i, name:fileName});
+			}
+		}, this);
+
+		if(filesInError.length){
+			if(filesInError.length >= this.inputNode.files.length){
+				// all files were bad. Nothing to upload.
+				this.onError({
+					message:this.errMsg,
+					filesInError:filesInError
+				});
+				part = false;
+			}
+		}
+
+		if(!part) return false;
+
+		if(data){
+			for(var nm in data){
+				part += boundary + EOL;
+				part += 'Content-Disposition: form-data; ';
+				part += 'name="' + nm + '"' + EOL + EOL;
+				part += data[nm] + EOL;
+			}
+		}
+
+
+		part += boundary + "--" + EOL;
+		return part;
+	}
+
+});
+dojox.form.addUploaderPlugin(dojox.form.uploader.plugins.HTML5);
diff --git a/dojox/form/uploader/plugins/IFrame.js b/dojox/form/uploader/plugins/IFrame.js
new file mode 100644
index 0000000..e26e32e
--- /dev/null
+++ b/dojox/form/uploader/plugins/IFrame.js
@@ -0,0 +1,60 @@
+dojo.provide("dojox.form.uploader.plugins.IFrame");
+
+dojo.require("dojox.form.uploader.plugins.HTML5");
+dojo.require("dojo.io.iframe");
+
+dojo.declare("dojox.form.uploader.plugins.IFrame", [], {
+	//
+	// Version: 1.6
+	//
+	// summary:
+	//		A plugin for dojox.form.Uploader that adds Ajax upload capabilities.
+	//
+	//	description:
+	//		Only supported by IE, due to the specifc iFrame hack used. The
+	//		dojox.form.uploader.plugins.HTML5 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.
+	//
+
+	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;
+		}
+	},
+
+	uploadIFrame: function(){
+		// summary:
+		//		Internal. You could use this, but you should use upload() or submit();
+		//		which can also handle the post data.
+		//
+		var url = this.getUrl();
+		var dfd = dojo.io.iframe.send({
+			url: this.getUrl(),
+			form: this.form,
+			handleAs: "json",
+			error: dojo.hitch(this, function(err){
+				console.error("HTML Upload Error:" + err.message);
+			}),
+			load: dojo.hitch(this, function(data, ioArgs, widgetRef){
+				this.onComplete(data);
+			})
+		});
+	}
+});
+
+dojox.form.addUploaderPlugin(dojox.form.uploader.plugins.IFrame);
diff --git a/dojox/fx.js b/dojox/fx.js
index 662581b..b21b9d8 100644
--- a/dojox/fx.js
+++ b/dojox/fx.js
@@ -1,3 +1,3 @@
 dojo.provide("dojox.fx");
 
-dojo.require("dojox.fx._base"); 
+dojo.require("dojox.fx._base");
diff --git a/dojox/fx/Shadow.js b/dojox/fx/Shadow.js
index 5d75eda..0d69f76 100644
--- a/dojox/fx/Shadow.js
+++ b/dojox/fx/Shadow.js
@@ -1,13 +1,13 @@
 dojo.provide("dojox.fx.Shadow");
-dojo.experimental("dojox.fx.Shadow"); 
+dojo.experimental("dojox.fx.Shadow");
 
-dojo.require("dijit._Widget"); 
-dojo.require("dojo.NodeList-fx"); 
+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){
@@ -31,7 +31,7 @@ dojo.declare("dojox.fx.Shadow",
 	//	Overall opacity of the shadow
 	opacity: 0.75,
 
-	// animate: Boolean	
+	// animate: Boolean
 	// 	A toggle to disable animated transitions
 	animate: false,
 
@@ -76,12 +76,12 @@ dojo.declare("dojox.fx.Shadow",
 			img = dojo.create("img", { src:url });
 		}
 
-		img.style.position="absolute"; 
+		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"); 
+		dojo.addClass(img,"shadowPiece");
 		this.pieces[name]=img;
 		this.node.appendChild(img);
 
@@ -90,8 +90,8 @@ dojo.declare("dojox.fx.Shadow",
 	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(dojo.isIE){ return; }
+		if(!animArgs){ animArgs = {}; }
 		if(this.animate){
 			var _anims = [];
 			this.nodeList.forEach(function(node){
@@ -100,7 +100,7 @@ dojo.declare("dojox.fx.Shadow",
 			dojo.fx.combine(_anims).play();
 		}else{
 			this.nodeList.style("opacity",n);
-		}	
+		}
 
 	},
 
@@ -108,12 +108,12 @@ dojo.declare("dojox.fx.Shadow",
 		// summary: enable / disable the shadow
 		if(disabled){
 			if(this.disabled){ return; }
-			if(this.animate){ this.nodeList.fadeOut().play(); 
+			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(); 
+			if(this.animate){ this.nodeList.fadeIn().play();
 			}else{ this.nodeList.style("visibility","visible"); }
 			this.disabled = false;
 		}
@@ -124,8 +124,8 @@ dojo.declare("dojox.fx.Shadow",
 		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 co = dojo._getBorderBox(this.node);
+			x = co.w; y = co.h;
 		}
 		var sideHeight = y - (this.shadowOffset+this.shadowThickness);
 		if (sideHeight < 0) { sideHeight = 0; }
diff --git a/dojox/fx/Timeline.js b/dojox/fx/Timeline.js
index 62ad309..a06dbe3 100644
--- a/dojox/fx/Timeline.js
+++ b/dojox/fx/Timeline.js
@@ -11,7 +11,7 @@ dojox.fx.animateTimeline = function(/* Object */options, /* DomNode|String */nod
 	// 				Defaults to 1000.
 	// node: DomNode
 	// 		The DomNode or id to be animated.
-	// 			
+	//
 	// summary:
 	//		An add-on to dojo.fx that provides the ability to create
 	//		a complex property animation based on an array of "keyframes".
@@ -34,7 +34,7 @@ dojox.fx.animateTimeline = function(/* Object */options, /* DomNode|String */nod
 	//	ease: String
 	//		The string name of a dojo.fx.easing ease. Defaults to "linear". Use
 	//		the suffix name of the ease, like: "quadIn", not: "dojo.fx.quadIn".
-	//		
+	//
 	// example:
 	// 		|	var keys = [
 	// 		|	{
@@ -60,7 +60,7 @@ dojox.fx.animateTimeline = function(/* Object */options, /* DomNode|String */nod
 		properties:_curve._properties,
 		// don't change! This easing is for the timeline,
 		// not individual properties
-		easing:dojo.fx.easing.linear, 
+		easing:dojo.fx.easing.linear,
 		onAnimate: function(v){
 			//console.log("   ani:", v);
 		}
@@ -119,7 +119,7 @@ dojox.fx._Timeline.prototype.flatten = function(keys){
 				};
 				p[nm] = {};
 				if(!/#/.test(k[nm])){
-					p[nm].units = o[nm].units = /\D{1,}/.exec(k[nm]).join("");	
+					p[nm].units = o[nm].units = /\D{1,}/.exec(k[nm]).join("");
 				}else{
 					p[nm].units = o[nm].units = "isColor";
 				}
@@ -178,7 +178,7 @@ dojox.fx._Timeline.prototype.getValue = function(/*float*/ p){
 			
 			}else if(p > step){
 				
-				if(next && p < k.steps[i+1]){ 
+				if(next && p < k.steps[i+1]){
 					// inbetween steps
 					var end = k.values[i+1];
 					var beg = k.values[i];
@@ -187,7 +187,7 @@ dojox.fx._Timeline.prototype.getValue = function(/*float*/ p){
 					seg = ease(seg);
 					
 					if(beg instanceof dojo.Color){
-						o[nm] = dojo.blendColors(beg, end, seg).toCss(false);	
+						o[nm] = dojo.blendColors(beg, end, seg).toCss(false);
 					}else{
 						var df = end - beg;
 						o[nm] = beg + seg * df + this._properties[nm].units;
diff --git a/dojox/fx/_arg.js b/dojox/fx/_arg.js
index bcfc401..4fab786 100644
--- a/dojox/fx/_arg.js
+++ b/dojox/fx/_arg.js
@@ -12,12 +12,12 @@ dojox.fx._arg.StyleArgs = function(/*Object*/ args){
 }
 
 dojox.fx._arg.ShadowResizeArgs = function(/*Object*/ args){
-	// summary: 
+	// summary:
 	//	The odd way to document object parameters.
 	// x: Integer
 	//	the width to set
 	// y: Integer
-	//	the height to set	
+	//	the height to set
 	this.x = args.x;
 	this.y = args.y;
 }
\ No newline at end of file
diff --git a/dojox/fx/_base.js b/dojox/fx/_base.js
index 9f72bbf..d28ee6d 100644
--- a/dojox/fx/_base.js
+++ b/dojox/fx/_base.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.fx._base");
-// summary: Experimental and extended Animations beyond Dojo Core / Base functionality. 
+// summary: Experimental and extended Animations beyond Dojo Core / Base functionality.
 //	Provides advanced Lines, Animations, and convenience aliases.
-dojo.require("dojo.fx"); 
+dojo.require("dojo.fx");
 
 dojo.mixin(dojox.fx, {
 
@@ -13,7 +13,7 @@ dojo.mixin(dojox.fx, {
 	//	Alias of `dojo.animateProperty` - animate any CSS property
 	animateProperty: dojo.animateProperty,
 
-	// fadeTo: Function 
+	// fadeTo: Function
 	//		Fade an element from an opacity to an opacity.
 	//		Omit `start:` property to detect. `end:` property is required.
 	//		Ultimately an alias to `dojo._fade`
@@ -50,18 +50,18 @@ dojo.mixin(dojox.fx, {
 });
 
 dojox.fx.sizeTo = function(/* Object */args){
-	// summary: 
+	// summary:
 	//		Creates an animation that will size a node
 	//
 	// description:
 	//		Returns an animation that will size the target node
 	//		defined in args Object about it's center to
-	//		a width and height defined by (args.width, args.height), 
+	//		a width and height defined by (args.width, args.height),
 	//		supporting an optional method: chain||combine mixin
-	//		(defaults to chain).	
+	//		(defaults to chain).
 	//
 	//	- works best on absolutely or relatively positioned elements
-	//	
+	//
 	// example:
 	//	|	// size #myNode to 400px x 200px over 1 second
 	//	|	dojo.fx.sizeTo({
@@ -76,9 +76,9 @@ dojox.fx.sizeTo = function(/* Object */args){
 	var node = args.node = dojo.byId(args.node),
 		abs = "absolute";
 
-	var method = args.method || "chain"; 
+	var method = args.method || "chain";
 	if(!args.duration){ args.duration = 500; } // default duration needed
-	if(method == "chain"){ args.duration = Math.floor(args.duration / 2); } 
+	if(method == "chain"){ args.duration = Math.floor(args.duration / 2); }
 	
 	var top, newTop, left, newLeft, width, height = null;
 
@@ -95,8 +95,8 @@ dojox.fx.sizeTo = function(/* Object */args){
 			width = (w == "auto" ? 0 : parseInt(w));
 			height = (h == "auto" ? 0 : parseInt(h));
 			
-			newLeft = left - Math.floor((args.width - width) / 2); 
-			newTop = top - Math.floor((args.height - height) / 2); 
+			newLeft = left - Math.floor((args.width - width) / 2);
+			newTop = top - Math.floor((args.height - height) / 2);
 
 			if(pos != abs && pos != 'relative'){
 				var ret = dojo.coords(n, true);
@@ -137,19 +137,19 @@ dojox.fx.sizeTo = function(/* Object */args){
 };
 
 dojox.fx.slideBy = function(/* Object */args){
-	// summary: 
+	// summary:
 	//		Returns an animation to slide a node by a defined offset.
 	//
 	// description:
 	//		Returns an animation that will slide a node (args.node) from it's
 	//		current position to it's current posision plus the numbers defined
-	//		in args.top and args.left. standard dojo.fx mixin's apply. 
-	//	
+	//		in args.top and args.left. standard dojo.fx mixin's apply.
+	//
 	// example:
 	//	|	// slide domNode 50px down, and 22px left
-	//	|	dojox.fx.slideBy({ 
-	//	|		node: domNode, duration:400, 
-	//	|		top: 50, left: -22 
+	//	|	dojox.fx.slideBy({
+	//	|		node: domNode, duration:400,
+	//	|		top: 50, left: -22
 	//	|	}).play();
 
 	var node = args.node = dojo.byId(args.node),
@@ -179,7 +179,7 @@ dojox.fx.slideBy = function(/* Object */args){
 			// null start values allow chaining to work, animateProperty will
 			// determine them for us (except in ie6? -- ugh)
 			top: top + (args.top || 0),
-			left: left + (args.left || 0) 
+			left: left + (args.left || 0)
 		}
 	}, args));
 	dojo.connect(_anim, "beforeBegin", _anim, init);
@@ -187,9 +187,9 @@ dojox.fx.slideBy = function(/* Object */args){
 };
 
 dojox.fx.crossFade = function(/* Object */args){
-	// summary: 
+	// summary:
 	//		Returns an animation cross fading two element simultaneously
-	// 
+	//
 	// args:
 	//	args.nodes: Array - two element array of domNodes, or id's
 	//
@@ -215,15 +215,15 @@ dojox.fx.crossFade = function(/* Object */args){
 };
 
 dojox.fx.highlight = function(/*Object*/ args){
-	// summary: 
+	// summary:
 	//		Highlight a node
 	//
 	// description:
 	//		Returns an animation that sets the node background to args.color
 	//		then gradually fades back the original node background color
-	//	
+	//
 	// example:
-	//	|	dojox.fx.highlight({ node:"foo" }).play(); 
+	//	|	dojox.fx.highlight({ node:"foo" }).play();
 
 	var node = args.node = dojo.byId(args.node);
 
@@ -263,14 +263,14 @@ dojox.fx.highlight = function(/*Object*/ args){
 dojox.fx.wipeTo = function(/*Object*/ args){
 	// summary:
 	//		Animate a node wiping to a specific width or height
-	//	
+	//
 	// description:
 	//		Returns an animation that will expand the
 	//		node defined in 'args' object from it's current to
 	//		the height or width value given by the args object.
 	//
 	//		default to height:, so leave height null and specify width:
-	//		to wipeTo a width. note: this may be deprecated by a 
+	//		to wipeTo a width. note: this may be deprecated by a
 	//
 	//		Note that the final value should not include
 	//		units and should be an integer.  Thus a valid args object
diff --git a/dojox/fx/_core.js b/dojox/fx/_core.js
index 5cca70b..96dc201 100644
--- a/dojox/fx/_core.js
+++ b/dojox/fx/_core.js
@@ -2,11 +2,11 @@ dojo.provide("dojox.fx._core");
 
 dojox.fx._Line = function(start, end){
 	// summary: a custom _Line to accomodate multi-dimensional values
-	//	
-	// description: 
+	//
+	// 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 
+	//	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
@@ -18,19 +18,19 @@ dojox.fx._Line = function(start, end){
 	// end: Integer|Array
 	//	An Integer (or an Array of integers) to use as an ending point
 	//
-	// example: see dojox.fx.smoothScroll 
+	// example: see dojox.fx.smoothScroll
 	//
-	// example: 
+	// 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. 
+	// | 	// at each step. arguments[0] and [1] in this example.
 	//
 	this.start = start;
 	this.end = end;
 	
-	var isArray = dojo.isArray(start), 
+	var isArray = dojo.isArray(start),
 		d = (isArray ? [] : end - start);
 	
 	if(isArray){
@@ -51,7 +51,7 @@ dojox.fx._Line = function(start, end){
 		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 
+			// returns: Mixed
 			return (d * n) + this.start; // Decimal
 		}
 	}
diff --git a/dojox/fx/ext-dojo/NodeList-style.js b/dojox/fx/ext-dojo/NodeList-style.js
index 17d85f7..d5ebb6c 100644
--- a/dojox/fx/ext-dojo/NodeList-style.js
+++ b/dojox/fx/ext-dojo/NodeList-style.js
@@ -1,12 +1,12 @@
 dojo.provide("dojox.fx.ext-dojo.NodeList-style");
 dojo.experimental("dojox.fx.ext-dojo.NodeList-style");
-// summary: 
+// summary:
 //		Core extensions to `dojo.NodeList` providing addtional 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 
+//		These are experimental animations, in an experimental
 
 dojo.require("dojo.NodeList-fx");
 dojo.require("dojox.fx.style");
diff --git a/dojox/fx/ext-dojo/NodeList.js b/dojox/fx/ext-dojo/NodeList.js
index ffb5bdf..13864c6 100644
--- a/dojox/fx/ext-dojo/NodeList.js
+++ b/dojox/fx/ext-dojo/NodeList.js
@@ -3,7 +3,7 @@ dojo.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 
+//	These are experimental animations, in an experimental
 
 dojo.require("dojo.NodeList-fx");
 dojo.require("dojox.fx");
@@ -25,9 +25,9 @@ dojo.extend(dojo.NodeList, {
 	slideBy: function(args){
 		//	summary:
 		//		slide all elements of this NodeList. Returns an instance of dojo.Animation
-		//		
+		//
 		//	example:
-		//	|	// slide all tables with class "blah" 10 px 
+		//	|	// 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
 	},
@@ -37,7 +37,7 @@ dojo.extend(dojo.NodeList, {
 		//		highlight all elements of the node list.
 		//		Returns an instance of dojo.Animation
 		//	example:
-		//	|	// highlight all links with class "foo" 
+		//	|	// highlight all links with class "foo"
 		//	|	dojo.query("a.foo").hightlight().play();
 		return this._anim(dojox.fx, "highlight", args); // dojo.Animation
 	},
diff --git a/dojox/fx/ext-dojo/complex.js b/dojox/fx/ext-dojo/complex.js
index 7673b6f..f804dad 100644
--- a/dojox/fx/ext-dojo/complex.js
+++ b/dojox/fx/ext-dojo/complex.js
@@ -10,14 +10,14 @@ dojo.provide("dojox.fx.ext-dojo.complex");
 		//		Note this can also be used with (and is actually intended for)
 		//		CSS3 properties, such as transform:
 		//		transform: rotate(10deg) translateX(0px)
-		//		
+		//
 		//	description:
 		//		The standard animation doesn't know what to do with something like
 		//		rect(...). This class identifies complex properties by they being a
 		//		string and having parenthesis. If so, that property is made into a
 		//		dojox.fx._Complex object and the getValue() is obtained from
 		//		there.
-		//		
+		//
 		//	example:
 		//		|	var ani = dojo.animateProperty({
 		//		|		node:dojo.byId("myDiv"),
@@ -26,7 +26,7 @@ dojo.provide("dojox.fx.ext-dojo.complex");
 		//		|			clip:{start:'rect(0px 50px 50px 0px)', end:'rect(10px 30px 30px 10px)'}
 		//		|		}
 		//		|	}).play();
-		//		
+		//
 		var d = dojo;
 		var ani = da(options);
 		
@@ -118,7 +118,7 @@ dojo.declare("dojox.fx._Complex", null, {
 		// 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 {
@@ -132,7 +132,7 @@ dojo.declare("dojox.fx._Complex", null, {
 		// 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)){
@@ -149,7 +149,7 @@ dojo.declare("dojox.fx._Complex", null, {
 		//		Helper function that returns the numeric verion of the string
 		//		property (or dojo.Color object) and the unit in which it was
 		//		defined.
-		//		
+		//
 		if(!prop){ return {}; }
 		if(/#/.test(prop)){
 			return {
diff --git a/dojox/fx/ext-dojo/reverse.js b/dojox/fx/ext-dojo/reverse.js
index d442356..5a856c7 100644
--- a/dojox/fx/ext-dojo/reverse.js
+++ b/dojox/fx/ext-dojo/reverse.js
@@ -26,7 +26,7 @@ dojo.extend(dojo.Animation, {
 		// 		A function to use for the reverse easing. This allows for
 		// 		the possibility of custom eases that are not in the dojo.fx
 		// 		library.
-		// 		
+		//
 		var playing = this.status() == "playing";
 		this.pause();
 		this._reversed = !this._reversed;
diff --git a/dojox/fx/flip.js b/dojox/fx/flip.js
index ddbeb4a..ba3abc4 100644
--- a/dojox/fx/flip.js
+++ b/dojox/fx/flip.js
@@ -1,9 +1,7 @@
-dojo.provide("dojox.fx.flip");
-dojo.experimental("dojox.fx.flip");
-dojo.require("dojo.fx");
-(function(){
-	
-	// because ShrinkSafe will eat this up: 
+define("dojox/fx/flip", ["dojo", "dojo/fx"], function(dojo) {
+
+	dojo.experimental("dojox.fx.flip");
+	// because ShrinkSafe will eat this up:
 	var borderConst = "border",
 		widthConst = "Width",
 		heightConst = "Height",
@@ -15,7 +13,7 @@ dojo.require("dojo.fx");
 
 	dojox.fx.flip = function(/*Object*/ args){
 		// summary: Animate a node flipping following a specific direction
-		//	
+		//
 		// description:
 		//		Returns an animation that will flip the
 		//		node around a central axis:
@@ -25,7 +23,7 @@ dojo.require("dojo.fx");
 		//		This effect is obtained using a border distorsion applied to a helper node.
 		//
 		//		The user can specify three background colors for the helper node:
-		//		darkColor: the darkest color reached during the animation 
+		//		darkColor: the darkest color reached during the animation
 		//		lightColor: the brightest color
 		//		endColor: the final backgroundColor for the node
         //
@@ -48,7 +46,7 @@ dojo.require("dojo.fx");
         //          node translation, perpendicular to the rotation axis
 		//
 		//	example:
-		//	|	var anim = dojox.fx.flip({ 
+		//	|	var anim = dojox.fx.flip({
 		//	|		node: dojo.byId("nodeId"),
 		//	|		dir: "top",
 		//	|		darkColor: "#555555",
@@ -60,19 +58,19 @@ dojo.require("dojo.fx");
 		//	|	  });
 
 		var helperNode = dojo.create("div"),
-			node = args.node = dojo.byId(args.node), 
+			node = args.node = dojo.byId(args.node),
 			s = node.style,
-			dims = null, 
-			hs = null, 
+			dims = null,
+			hs = null,
 			pn = null,
-			lightColor = args.lightColor || "#dddddd", 
+			lightColor = args.lightColor || "#dddddd",
 			darkColor = args.darkColor || "#555555",
-			bgColor = dojo.style(node, "backgroundColor"), 
+			bgColor = dojo.style(node, "backgroundColor"),
 			endColor = args.endColor || bgColor,
-			staticProps = {}, 
+			staticProps = {},
 			anims = [],
 			duration = args.duration ? args.duration / 2 : 250,
-			dir = args.dir || "left", 
+			dir = args.dir || "left",
 			pConst = .9,
 			transparentColor = "transparent",
 			whichAnim = args.whichAnim,
@@ -117,7 +115,7 @@ dojo.require("dojo.fx");
 			fontSize: "0",
 			visibility: "hidden"
 		};
-		var props = [ {}, 
+		var props = [ {},
 			{
 				top: dims["top"],
 				left: dims["left"]
@@ -127,7 +125,7 @@ dojo.require("dojo.fx");
 			left: [leftConst, rightConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst + "Min", leftConst, "end" + heightConst + "Max"],
 			right: [rightConst, leftConst, topConst, bottomConst, widthConst, heightConst, "end" + heightConst + "Min", leftConst, "end" + heightConst + "Max"],
 			top: [topConst, bottomConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"],
-			bottom: [bottomConst, topConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"] 
+			bottom: [bottomConst, topConst, leftConst, rightConst, heightConst, widthConst, "end" + widthConst + "Min", topConst, "end" + widthConst + "Max"]
 		};
 		// property names
 		pn = dynProperties[dir];
@@ -141,15 +139,15 @@ dojo.require("dojo.fx");
 		}
 		var p0 = props[0];
 		for(var i = 4; i < 6; i++){
-			if(axis == "center" || axis == "cube"){ // find a better name for "cube" 
-				dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst; 
-				dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst; 
+			if(axis == "center" || axis == "cube"){ // find a better name for "cube"
+				dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst;
+				dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst;
 			}else if(axis == "shortside"){
 				dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()];
-				dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst; 
+				dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()] / pConst;
 			}else if(axis == "longside"){
 				dims["end" + pn[i] + "Min"] = dims[pn[i].toLowerCase()] * pConst;
-				dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()];  
+				dims["end" + pn[i] + "Max"] = dims[pn[i].toLowerCase()];
 			}
 		}
 		if(axis == "center"){
@@ -163,9 +161,9 @@ dojo.require("dojo.fx");
 		staticProps[borderConst + pn[1] + widthConst] = dims[pn[4].toLowerCase()] + "px";
 		staticProps[borderConst + pn[1] + "Color"] = bgColor;
 
-		p0[borderConst + pn[1] + widthConst] = 0; 
-		p0[borderConst + pn[1] + "Color"] = darkColor; 
-		p0[borderConst + pn[2] + widthConst] = p0[borderConst + pn[3] + widthConst] = axis != "cube" 
+		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[pn[6]] / 2
 		;
@@ -194,19 +192,19 @@ dojo.require("dojo.fx");
 			for(i in p0){
 				p0[i] = { start: p0[i] };
 			}
-			p0[borderConst + pn[1] + "Color"] = { start: darkColor, end: endColor }; 
+			p0[borderConst + pn[1] + "Color"] = { start: darkColor, end: endColor };
 			p1 = p0;
 		}
 		if(!whichAnim || whichAnim == "first"){
 			anims.push(dojo.animateProperty({
-				node: helperNode, 
+				node: helperNode,
 				duration: duration,
 				properties: p0
 			}));
 		}
 		if(!whichAnim || whichAnim == "last"){
 			anims.push(dojo.animateProperty({
-				node: helperNode, 
+				node: helperNode,
 				duration: duration,
 				properties: p1,
 				onEnd: finalize
@@ -216,7 +214,7 @@ dojo.require("dojo.fx");
 		// hide the original node
 		dojo.connect(anims[0], "play", function(){
 			helperNode.style.visibility = "visible";
-			s.visibility = "hidden"; 
+			s.visibility = "hidden";
 		});
 
 		return dojo.fx.chain(anims); // dojo.Animation
@@ -227,8 +225,8 @@ dojo.require("dojo.fx");
 		// summary: An extension to `dojox.fx.flip` providing a more 3d-like rotation
 		//
 		// description:
-		//		An extension to `dojox.fx.flip` providing a more 3d-like rotation. 
-		//		Behaves the same as `dojox.fx.flip`, using the same attributes and 
+		//		An extension to `dojox.fx.flip` providing a more 3d-like rotation.
+		//		Behaves the same as `dojox.fx.flip`, using the same attributes and
 		//		other standard `dojo.Animation` properties.
 		//
 		//	example:
@@ -303,7 +301,7 @@ dojo.require("dojo.fx");
 		var d = dims[args.dir || "left"],
 			p = d.args
 		;
-		args.duration = args.duration ? args.duration * 2 : 500; 
+		args.duration = args.duration ? args.duration * 2 : 500;
 		args.depth = .8;
 		args.axis = "cube";
 		for(var i = p.length - 1; i >= 0; i--){
@@ -329,9 +327,9 @@ dojo.require("dojo.fx");
 			y = coords.y,
 			w = coords.w,
 			h = coords.h,
-			bgColor = dojo.style(n, "backgroundColor"), 
+			bgColor = dojo.style(n, "backgroundColor"),
 			lightColor = args.lightColor || "#dddddd",
-			darkColor = args.darkColor, 
+			darkColor = args.darkColor,
 			helperNode = dojo.create("div"),
 			anims = [],
 			hn = [],
@@ -445,14 +443,14 @@ dojo.require("dojo.fx");
 				height: nh + "px",
 				top: y + "px",
 				left: x + "px",
-				clip: "rect(" + i * h + "px," + nw + "px," + nh + "px,0)"	
+				clip: "rect(" + i * h + "px," + nw + "px," + nh + "px,0)"
 			});
 	     	dojo.body().appendChild(cn);
 			anims[i] = [];
 			for(var j = 0; j < cols; j++){
 				var hn = dojo.clone(helperNode),
 					l = r ? j : cols - (j + 1)
-				; 
+				;
 				var adjustClip = function(xn, yCounter, xCounter){
 					return function(){
 						if(!(yCounter % 2)){
@@ -500,4 +498,5 @@ dojo.require("dojo.fx");
 		});
 		return dojo.fx.combine(cAnims);
 	};
-})();
+	return dojox.fx.flip;
+});
diff --git a/dojox/fx/scroll.js b/dojox/fx/scroll.js
index 6f610a6..9fefa8e 100644
--- a/dojox/fx/scroll.js
+++ b/dojox/fx/scroll.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.fx.scroll");
-dojo.experimental("dojox.fx.scroll"); 
+dojo.experimental("dojox.fx.scroll");
 
-dojo.require("dojox.fx._core"); 
+dojo.require("dojox.fx._core");
 
 dojox.fx.smoothScroll = function(/* Object */args){
 	// summary: Returns an animation that will smooth-scroll to a node
@@ -10,8 +10,8 @@ dojox.fx.smoothScroll = function(/* Object */args){
 	// offset: {x: int, y: int} this will be added to the target position
 	// duration: Duration of the animation in milliseconds.
 	// win: a node or window object to scroll
-	
-	if(!args.target){ args.target = dojo.position(args.node,true); }
+
+	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 }
@@ -21,7 +21,6 @@ dojox.fx.smoothScroll = function(/* Object */args){
 		delta.x -= winPos.x;
 		delta.y -= winPos.y;
 	}
-
 	var _anim = (isWindow) ?
 		(function(val){
 			args.win.scrollTo(val[0],val[1]);
@@ -30,12 +29,11 @@ dojox.fx.smoothScroll = function(/* Object */args){
 			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],[delta.x,delta.y]);
+			anim.curve = new dojox.fx._Line([current.x,current.y],[current.x + delta.x, current.y + delta.y]);
 		},
 		onAnimate: _anim
 	},args));
diff --git a/dojox/fx/style.js b/dojox/fx/style.js
index 0f6ca3d..c956bab 100644
--- a/dojox/fx/style.js
+++ b/dojox/fx/style.js
@@ -1,30 +1,30 @@
 dojo.provide("dojox.fx.style");
-dojo.experimental("dojox.fx.style"); 
+dojo.experimental("dojox.fx.style");
 //
-// summary: 
-//		dojox.fx CSS Class Animations: 
+// summary:
+//		dojox.fx CSS Class Animations:
 //
-// description: 
+// description:
 //		a set of functions to animate properties based on
 //		normalized CSS class definitions.
 //
 //	provides: addClass, removeClass, and toggleClass
-//	
-dojo.require("dojo.fx"); 
+//
+dojo.require("dojo.fx");
 
 (function(){
 		
 	var d = dojo;
 
 	var _getStyleSnapshot = function(/* Object */cache){
-		// summary: 
+		// summary:
 		//		uses a dojo.getComputedStyle(node) cache reference and
 		// 		iterates through the 'documented/supported animate-able'
-		// 		properties. 
+		// 		properties.
 		//
 		// returns:  Array
 		//		an array of raw, calculcated values (no keys), to be normalized/compared
-		//		elsewhere	
+		//		elsewhere
 		return d.map(dojox.fx._allowedProperties, function(style){
 			return cache[style]; // String
 		}); // Array
@@ -37,8 +37,8 @@ dojo.require("dojo.fx");
 		//	of a node (args.node) by quickly adding or removing a class, and
 		//	iterateing over the results of dojox.fx._getStyleSnapshot()
 		//
-		// addClass: 
-		// 	true to calculate what adding a class would do, 
+		// addClass:
+		// 	true to calculate what adding a class would do,
 		// 	false to calculate what removing the class would do
 
 		node = d.byId(node);
@@ -46,25 +46,25 @@ dojo.require("dojo.fx");
 
 		// take our snapShots
 		var _before = _getStyleSnapshot(cs);
-		d[(addClass ? "addClass" : "removeClass")](node, cssClass); 
+		d[(addClass ? "addClass" : "removeClass")](node, cssClass);
 		var _after = _getStyleSnapshot(cs);
-		d[(addClass ? "removeClass" : "addClass")](node, cssClass); 
+		d[(addClass ? "removeClass" : "addClass")](node, cssClass);
 
 		var calculated = {}, i = 0;
 		d.forEach(dojox.fx._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' */ ; 
-			} 
+				calculated[prop] = parseInt(_after[i]) /* start: parseInt(_before[i]), units: 'px' */ ;
+			}
 			i++;
 		});
-		return calculated; 
+		return calculated;
 	};
 
 	d.mixin(dojox.fx,{
 
 		addClass: function(node, cssClass, args){
-			// summary: 
+			// summary:
 			//		Animate the effects of adding a class to a node
 			//
 			// description:
@@ -80,84 +80,84 @@ dojo.require("dojo.fx");
 			//		The CSS class name to add to the node
 			//
 			// args: Object?
-			//		Additional optional `dojo.animateProperty` arguments, such as 
+			//		Additional optional `dojo.animateProperty` arguments, such as
 			//		duration, easing and so on.
-			//	
+			//
 			// example:
-			//	| 
+			//	|
 			//	|	.bar { line-height: 12px; }
 			//	|	.foo { line-height: 40px; }
 			//	|	<div class="bar" id="test">
 			//	|	Multi<br>line<br>text
-			//	|	</div> 
+			//	|	</div>
 			//	|
 			//	|	// animate to line-height:40px
 			//	|	dojo.fx.addClass("test", "foo").play();
-			// 
-			node = d.byId(node); 
+			//
+			node = d.byId(node);
 
 			var pushClass = (function(n){
-				// summary: onEnd we want to add the class to the node 
-				//	(as dojo.addClass naturally would) in case our 
-				//	class parsing misses anything the browser would 
+				// summary: onEnd we want to add the class to the node
+				//	(as dojo.addClass naturally would) in case our
+				//	class parsing misses anything the browser would
 				// 	otherwise interpret. this may cause some flicker,
-				//	and will only apply the class so children can inherit 
+				//	and will only apply the class so children can inherit
 				//	after the animation is done (potentially more flicker)
 				return function(){
-					d.addClass(n, cssClass); 
-					n.style.cssText = _beforeStyle; 
+					d.addClass(n, cssClass);
+					n.style.cssText = _beforeStyle;
 				}
 			})(node);
 
 			// _getCalculatedStleChanges is the core of our style/class animations
 			var mixedProperties = _getCalculatedStyleChanges(node, cssClass, true);
-			var _beforeStyle = node.style.cssText; 
+			var _beforeStyle = node.style.cssText;
 			var _anim = d.animateProperty(d.mixin({
 				node: node,
 				properties: mixedProperties
 			}, args));
-			d.connect(_anim, "onEnd", _anim, pushClass); 
+			d.connect(_anim, "onEnd", _anim, pushClass);
 			return _anim; // dojo.Animation
 		},
 	
 		removeClass: function(node, cssClass, args){
 			// summary: Animate the effects of removing a class from a node
 			// description:
-			//	Creates an animation that will animate the properties of a 
-			// 	node (args.node) to the properties calculated after removing 
+			//	Creates an animation that will animate the properties of a
+			// 	node (args.node) to the properties calculated after removing
 			//	a standard CSS className from a that node.
-			//	
-			//	calls dojo.removeClass(args.cssClass) onEnd of animation		
 			//
-			//	standard dojo.Animation object rules apply. 
+			//	calls dojo.removeClass(args.cssClass) onEnd of animation
+			//
+			//	standard dojo.Animation object rules apply.
 			//
 			// example:
 			// |	// animate the removal of "foo" from a node with id="bar"
 			// |	dojox.fx.removeClass("bar", "foo").play()
 
-			node = d.byId(node); 
+			node = d.byId(node);
 
 			var pullClass = (function(n){
-				// summary: onEnd we want to remove the class from the node 
+				// summary: onEnd we want to remove the class from the node
 				//	(as dojo.removeClass naturally would) in case our class
-				//	parsing misses anything the browser would otherwise 
-				//	interpret. this may cause some flicker, and will only 
+				//	parsing misses anything the browser would otherwise
+				//	interpret. this may cause some flicker, and will only
 				//	apply the class so children can inherit after the
 				//	animation is done (potentially more flicker)
 				//
 				return function(){
-					d.removeClass(n, cssClass); 
-					n.style.cssText = _beforeStyle; 
+					d.removeClass(n, cssClass);
+					n.style.cssText = _beforeStyle;
 				}
 			})(node);
 
 			var mixedProperties = _getCalculatedStyleChanges(node, cssClass);
-			var _beforeStyle = node.style.cssText; 
+			var _beforeStyle = node.style.cssText;
 			var _anim = d.animateProperty(d.mixin({
 				node: node,
 				properties: mixedProperties
 			}, args));
-			d.connect(_anim, "onEnd", _anim, pullClass); 
+			d.connect(_anim, "onEnd", _anim, pullClass);
 			return _anim; // dojo.Animation
 		},
 
@@ -166,7 +166,7 @@ dojo.require("dojo.fx");
 			//		Animate the effects of Toggling a class on a Node
 			//
 			// description:
-			//		creates an animation that will animate the effect of 
+			//		creates an animation that will animate the effect of
 			//		toggling a class on or off of a node.
 			//		Adds a class to node if not present, or removes if present.
 			//		Pass a boolean condition if you want to explicitly add or remove.
@@ -174,7 +174,7 @@ dojo.require("dojo.fx");
 			// node: String|DomNode
 			//		The domNode (or string of the id) to toggle
 			// cssClass: String
-			//		String of the classname to add to the node	
+			//		String of the classname to add to the node
 			// condition: Boolean?
 			//		If passed, true means to add the class, false means to remove.
 			// args: Object?
@@ -197,14 +197,14 @@ dojo.require("dojo.fx");
 			// summary: Our pseudo map of properties we will check for.
 			// description:
 			//	it should be much more intuitive. a way to normalize and
-			//	"predict" intent, or even something more clever ... 
+			//	"predict" intent, or even something more clever ...
 			//	open to suggestions.
 
 			// no-brainers:
 			"width",
 			"height",
 			// only if position = absolute || relative?
-			"left", "top", // "right", "bottom", 
+			"left", "top", // "right", "bottom",
 			// these need to be filtered through dojo.colors?
 			// "background", // normalize to:
 			/* "backgroundImage", */
@@ -213,7 +213,7 @@ dojo.require("dojo.fx");
 
 			"color",
 
-			// "border", 
+			// "border",
 			//"borderBottomColor",
 			"borderBottomWidth",
 			//"borderTopColor",
@@ -223,7 +223,7 @@ dojo.require("dojo.fx");
 			//"borderRightColor",
 			"borderRightWidth",
 
-			// "padding", // normalize to: 
+			// "padding", // normalize to:
 			"paddingLeft", "paddingRight", "paddingTop", "paddingBottom",
 			// "margin", // normalize to:
 			"marginLeft", "marginTop", "marginRight", "marginBottom",
diff --git a/dojox/gantt/GanttChart.js b/dojox/gantt/GanttChart.js
new file mode 100644
index 0000000..cff3fd6
--- /dev/null
+++ b/dojox/gantt/GanttChart.js
@@ -0,0 +1,1265 @@
+dojo.provide("dojox.gantt.GanttChart");
+
+dojo.require("dijit.Tooltip");
+dojo.require("dojox.gantt.GanttProjectItem");
+dojo.require("dojox.gantt.GanttResourceItem");
+dojo.require("dojox.gantt.TabMenu");
+dojo.require("dojo.date.locale");
+
+(function(){
+	dojo.declare("dojox.gantt.GanttChart", null, {
+		constructor: function(configuration, node){
+			this.resourceChartHeight = configuration.resourceChartHeight !== undefined ? configuration.resourceChartHeight : false;
+			this.withResource = configuration.withResource !== undefined ? configuration.withResource : true;
+			this.correctError = configuration.autoCorrectError !== undefined ? configuration.autoCorrectError : false;
+			this.isShowConMenu = this.isContentEditable = !configuration.readOnly;
+			this.withTaskId = configuration.withTaskId !== undefined ? configuration.withTaskId : !configuration.readOnly;
+			this.animation = configuration.animation !== undefined ? configuration.animation : true;
+			this.saveProgramPath = configuration.saveProgramPath  || "saveGanttData.php";
+			this.dataFilePath = configuration.dataFilePath  || "gantt_default.json";
+			this.contentHeight = configuration.height || 400;
+			this.contentWidth = configuration.width || 600;
+			this.content = dojo.byId(node);
+			this.scrollBarWidth = 18;
+			this.panelTimeHeight = 102;
+			this.maxWidthPanelNames = 150;
+			this.maxWidthTaskNames = 150;
+			this.minWorkLength = 8;
+			this.heightTaskItem = 12;
+			this.heightTaskItemExtra = 11;
+			this.pixelsPerDay = 24;//px
+			this.hsPerDay = 8;
+			this.pixelsPerWorkHour = this.pixelsPerDay / this.hsPerDay;//px
+			this.pixelsPerHour = this.pixelsPerDay / 24;//px
+			this.countDays = 0;
+			this.totalDays = 0;
+			this.startDate = null;
+			this.initialPos = 0;
+			
+			this.contentDataHeight = 0;
+			this.panelTimeExpandDelta = 20;
+			
+			this.divTimeInfo = null;
+			this.panelNames = null;
+			this.panelTime = null;
+			this.contentData = null;
+			this.tabMenu = null;
+			
+			this.project = [];
+			this.arrProjects = [];
+			
+			this.xmlLoader = null;
+			this.isMoving = false;
+			this.isResizing = false;
+			this.animationNodes = [];
+			this.scale = 1;
+			this.tempDayInPixels = 0;
+			this.resource = null;
+			this.months = dojo.date.locale.getNames("months", "wide");
+			this._events = [];
+		},
+		getProject: function(id){
+			return dojo.filter(this.arrProjects, function(proj){
+				return proj.project.id == id;
+			}, this)[0];
+		},
+		checkPosPreviousTask: function(predTask, task){
+			var widthPred = this.getWidthOnDuration(predTask.duration);
+			var posPred = this.getPosOnDate(predTask.startTime);
+			var posChild = this.getPosOnDate(task.startTime);
+			if((widthPred + posPred) > posChild){
+				return false;
+			}
+			return true;
+		},
+		correctPosPreviousTask: function(predTask, ctask, ctaskObj){
+			var newDate = new Date(predTask.startTime);
+			newDate.setHours(newDate.getHours() + (predTask.duration / this.hsPerDay * 24))
+			if(newDate.getHours() > 0){
+				newDate.setHours(0);
+				newDate.setDate(newDate.getDate() + 1);
+			}
+			ctaskObj ? (ctaskObj.setStartTime(newDate, true)) : (ctask.startTime = newDate);
+			if(ctask.parentTask){
+				if(!this.checkPosParentTask(ctask.parentTask, ctask)){
+					var newDate2 = new Date(ctask.parentTask.startTime);
+					newDate2.setHours(newDate2.getHours() + (ctask.parentTask.duration / this.hsPerDay * 24))
+					ctask.duration = parseInt((parseInt((newDate2 - ctask.startTime) / (1000 * 60 * 60))) * this.hsPerDay / 24);
+				}
+			}
+		},
+		correctPosParentTask: function(parentTask, ctask){
+			if(!ctask.previousTask){
+				if(parentTask.startTime > ctask.startTime){
+					ctask.startTime = new Date(parentTask.startTime);
+				}
+				if(!this.checkPosParentTask(parentTask, ctask)){
+					ctask.duration = parentTask.duration;
+				}
+			}else{
+				this.correctPosPreviousTask(ctask.previousTask, ctask);
+			}
+		},
+		checkPosParentTaskInTree: function(parentTask){
+			var exception = false;
+			for(var i = 0; i < parentTask.cldTasks.length; i++){
+				var pcTask = parentTask.cldTasks[i];
+				if(!this.checkPosParentTask(parentTask, pcTask)){
+					if(!this.correctError){
+						return true;
+					}else{
+						this.correctPosParentTask(parentTask, pcTask);
+					}
+				}
+				if(parentTask.startTime > pcTask.startTime){
+					if(!this.correctError){
+						return true;
+					}else{
+						this.correctPosParentTask(parentTask, pcTask);
+					}
+				}
+				if(pcTask.cldTasks.length > 0){
+					exception = this.checkPosParentTaskInTree(pcTask);
+				}
+			}
+			return exception;
+		},
+		setPreviousTask: function(project){
+			var exception = false;
+			for(var i = 0; i < project.parentTasks.length; i++){
+				var ppTask = project.parentTasks[i];
+				if(ppTask.previousTaskId){
+					ppTask.previousTask = project.getTaskById(ppTask.previousTaskId);
+					if(!ppTask.previousTask){
+						if(!this.correctError){
+							return true;
+						}
+					}
+					ppTask.previousTask.cldPreTasks.push(ppTask);
+				}
+				if(ppTask.previousTask){
+					if(!this.checkPosPreviousTask(ppTask.previousTask, ppTask)){
+						if(!this.correctError){
+							return true;
+						}else{
+							this.correctPosPreviousTask(ppTask.previousTask, ppTask);
+						}
+					}
+				}
+				exception = this.setPreviousTaskInTree(ppTask);
+			}
+			return exception;
+		},
+		setPreviousTaskInTree: function(parentTask){
+			var exception = false;
+			for(var i = 0; i < parentTask.cldTasks.length; i++){
+				var pcTask = parentTask.cldTasks[i];
+				if(pcTask.previousTaskId){
+					pcTask.previousTask = parentTask.project.getTaskById(pcTask.previousTaskId);
+					if(!pcTask.previousTask){
+						if(!this.correctError){
+							return true;
+						}
+					}
+					if(!this.checkPosPreviousTask(pcTask.previousTask, pcTask)){
+						if(!this.correctError){
+							return true;
+						}else{
+							this.correctPosPreviousTask(pcTask.previousTask, pcTask);
+						}
+					}
+					pcTask.previousTask.cldPreTasks.push(pcTask);
+				}
+				
+				if(pcTask.cldTasks.length > 0){
+					exception = this.setPreviousTaskInTree(pcTask);
+				}
+			}
+			return exception;
+		},
+		checkPosParentTask: function(parentTask, task){
+			var widthParent = this.getWidthOnDuration(parentTask.duration);
+			var posParent = this.getPosOnDate(parentTask.startTime);
+			var posChild = this.getPosOnDate(task.startTime);
+			var widthChild = this.getWidthOnDuration(task.duration);
+			return (widthParent + posParent) >= (posChild + widthChild);
+		},
+		addProject: function(projectItem){
+			this.project.push(projectItem);
+		},
+		deleteProject: function(id){
+			var project = this.getProject(id);
+			if(project){
+				if(project.arrTasks.length > 0){
+					while(project.arrTasks.length > 0){
+						project.deleteChildTask(project.arrTasks[0]);
+					}
+				}
+				var rowHeight = this.heightTaskItemExtra + this.heightTaskItem;
+				project.nextProject && project.shiftNextProject(project, -rowHeight); //rowHeight: 23
+				this.project = dojo.filter(this.project, function(proj){
+					return proj.id != project.project.id;
+				}, this);
+				if((project.previousProject) && (project.nextProject)){
+					var previousProject = project.previousProject;
+					previousProject.nextProject = project.nextProject;
+				}
+				if((project.previousProject) && !(project.nextProject)){
+					var previousProject = project.previousProject;
+					previousProject.nextProject = null;
+				}
+				if(!(project.previousProject) && (project.nextProject)){
+					var nextProject = project.nextProject;
+					nextProject.previousProject = null;
+				}
+				for(var i = 0; i < this.arrProjects.length; i++){
+					if(this.arrProjects[i].project.id == id){
+						this.arrProjects.splice(i, 1);
+					}
+				}
+				project.projectItem[0].parentNode.removeChild(project.projectItem[0]);
+				project.descrProject.parentNode.removeChild(project.descrProject);
+				project.projectNameItem.parentNode.removeChild(project.projectNameItem);
+				this.contentDataHeight -= this.heightTaskItemExtra + this.heightTaskItem;
+				if(this.project.length == 0){
+					var d = new Date(this.startDate);
+					var t = new Date(d.setDate(d.getDate() + 1));
+					var pi = new dojox.gantt.GanttProjectItem({
+						id: 1,
+						name: "New Project",
+						startDate: t
+					});
+					this.project.push(pi);
+					var project = new dojox.gantt.GanttProjectControl(this, pi);
+					project.create();
+					this.arrProjects.push(project);
+					this.contentDataHeight += this.heightTaskItemExtra + this.heightTaskItem;
+				}
+				this.checkPosition();
+			}
+		},
+		insertProject: function(id, name, startDate){
+			if(this.startDate >= startDate){
+				return false;
+			}
+			if(this.getProject(id)){
+				return false;
+			}
+			this.checkHeighPanelTasks();
+			var project = new dojox.gantt.GanttProjectItem({
+				id: id,
+				name: name,
+				startDate: startDate
+			});
+			this.project.push(project);
+			var _project = new dojox.gantt.GanttProjectControl(this, project);
+			for(var i = 0; i < this.arrProjects.length; i++){
+				var curProject = this.arrProjects[i],
+					preProject = this.arrProjects[i-1],
+					nextProject = this.arrProjects[i+1];
+				if(startDate < curProject.project.startDate){
+					this.arrProjects.splice(i, 0, _project);
+					if(i > 0){
+						_project.previousProject = preProject;
+						preProject.nextProject = _project;
+					}
+					if(i + 1 <= this.arrProjects.length){
+						_project.nextProject = nextProject;
+						nextProject.previousProject = _project;
+						var rowHeight = this.heightTaskItem + this.heightTaskItemExtra;
+						_project.shiftNextProject(_project, rowHeight);
+					}
+					_project.create();
+					_project.hideDescrProject();
+					this.checkPosition();
+					return _project;
+				}
+			}
+			if(this.arrProjects.length > 0){
+				this.arrProjects[this.arrProjects.length - 1].nextProject = _project;
+				_project.previousProject = this.arrProjects[this.arrProjects.length - 1];
+			}
+			this.arrProjects.push(_project);
+			_project.create();
+			_project.hideDescrProject();
+			this.checkPosition();
+			return _project;
+		},
+		openTree: function(parentTask){
+			var lastParentTask = this.getLastCloseParent(parentTask);
+			this.openNode(lastParentTask);
+			parentTask.taskItem.id != lastParentTask.taskItem.id && this.openTree(parentTask);
+		},
+		openNode: function(parentTask){
+			if(!parentTask.isExpanded){
+				dojo.removeClass(parentTask.cTaskNameItem[2], "ganttImageTreeExpand");
+				dojo.addClass(parentTask.cTaskNameItem[2], "ganttImageTreeCollapse");
+				parentTask.isExpanded = true;
+				parentTask.shiftCurrentTasks(parentTask, parentTask.hideTasksHeight);
+				parentTask.showChildTasks(parentTask, parentTask.isExpanded);
+				parentTask.hideTasksHeight = 0;
+			}
+		},
+		getLastCloseParent: function(task){
+			if(task.parentTask){
+				if((!task.parentTask.isExpanded) ||
+				(task.parentTask.cTaskNameItem[2].style.display == "none")){
+					return this.getLastCloseParent(task.parentTask);
+				}else{
+					return task;
+				}
+			}else{
+				return task;
+			}
+		},
+		getProjectItemById: function(id){
+			return dojo.filter(this.project, function(proj){
+				return proj.id == id;
+			}, this)[0];
+		},
+		clearAll: function(){
+			this.contentDataHeight = 0;
+			this.startDate = null;
+			this.clearData();
+			this.clearItems();
+			this.clearEvents();
+		},
+		clearEvents: function(){
+			dojo.forEach(this._events, dojo.disconnect);
+			this._events = [];
+		},
+		clearData: function(){
+			this.project = [];
+			this.arrProjects = [];
+		},
+		clearItems: function(){
+			this.contentData.removeChild(this.contentData.firstChild);
+			this.contentData.appendChild(this.createPanelTasks());
+			this.panelNames.removeChild(this.panelNames.firstChild);
+			this.panelNames.appendChild(this.createPanelNamesTasks());
+			this.panelTime.removeChild(this.panelTime.firstChild);
+		},
+		buildUIContent: function(){
+			this.project.sort(this.sortProjStartDate);
+			this.startDate = this.getStartDate();
+			this.panelTime.appendChild(this.createPanelTime());
+			for(var i = 0; i < this.project.length; i++){
+				var proj = this.project[i];
+				for(var k = 0; k < proj.parentTasks.length; k++){
+					var ppTask = proj.parentTasks[k];
+					if(ppTask.startTime){
+						this.setStartTimeChild(ppTask);
+					}else{
+						return;
+					}
+					if(this.setPreviousTask(proj)){
+						return;
+					}
+				}
+				for(var k = 0; k < proj.parentTasks.length; k++){
+					var ppTask = proj.parentTasks[k];
+					if(ppTask.startTime < proj.startDate){
+						return;
+					}
+					if(this.checkPosParentTaskInTree(ppTask)) return;
+				}
+				this.sortTasksByStartTime(proj);
+			}
+			
+			for(var i = 0; i < this.project.length; i++){
+				var proj = this.project[i];
+				var project = new dojox.gantt.GanttProjectControl(this, proj);
+				if(this.arrProjects.length > 0){
+					var previousProject = this.arrProjects[this.arrProjects.length - 1];
+					project.previousProject = previousProject;
+					previousProject.nextProject = project;
+				}
+				project.create();
+				this.checkHeighPanelTasks();
+				this.arrProjects.push(project);
+				this.createTasks(project);
+			}
+			this.resource && this.resource.reConstruct();
+			this.postLoadData();
+			this.postBindEvents();
+		},
+		loadJSONData: function(filename){
+			var _this = this;
+			_this.dataFilePath = filename || _this.dataFilePath;
+			dojo.xhrGet({
+				url: _this.dataFilePath,
+				sync: true,
+				load: function(text, ioArgs){
+					_this.loadJSONString(text);
+					_this.buildUIContent();
+					alert("Successfully! Loaded data from: " + _this.dataFilePath);
+				},
+				error: function(err, ioArgs){
+					alert("Failed! Load error: " + _this.dataFilePath);
+				}
+			});
+		},
+		loadJSONString: function(content){
+			//load data
+			if(!content){ return; }
+			this.clearAll();
+			var jsonObj = dojo.fromJson(content);
+			
+			var items = jsonObj.items;
+			dojo.forEach(items, function(pItem){
+				var startDate = pItem.startdate.split("-");
+				var project = new dojox.gantt.GanttProjectItem({
+					id: pItem.id,
+					name: pItem.name,
+					startDate: new Date(startDate[0], (parseInt(startDate[1]) - 1), startDate[2])
+				});
+				var tItems = pItem.tasks;
+				dojo.forEach(tItems, function(tItem){
+					var id = tItem.id,
+						name = tItem.name,
+						starttime = tItem.starttime.split("-");
+						duration = tItem.duration,
+						percentage = tItem.percentage,
+						previousTaskId = tItem.previousTaskId,
+						taskOwner = tItem.taskOwner;
+					
+					var task = new dojox.gantt.GanttTaskItem({
+						id: id,
+						name: name,
+						startTime: new Date(starttime[0], (parseInt(starttime[1]) - 1), starttime[2]),
+						duration: duration,
+						percentage: percentage,
+						previousTaskId: previousTaskId,
+						taskOwner: taskOwner
+					});
+					var ctItems = tItem.children;
+					if(ctItems.length != 0){
+						this.buildChildTasksData(task, ctItems);
+					}
+					project.addTask(task);
+				}, this);
+				this.addProject(project);
+			 }, this);
+		},
+		buildChildTasksData: function(parentTask, childTaskItems){
+			childTaskItems && dojo.forEach(childTaskItems, function(ctItem){
+				var id = ctItem.id,
+					name = ctItem.name,
+					starttime = ctItem.starttime.split("-"),
+					duration = ctItem.duration,
+					percentage = ctItem.percentage,
+					previousTaskId = ctItem.previousTaskId,
+					taskOwner = ctItem.taskOwner;
+				
+				var task = new dojox.gantt.GanttTaskItem({
+					id: id,
+					name: name,
+					startTime: new Date(starttime[0], (parseInt(starttime[1]) - 1), starttime[2]),
+					duration: duration,
+					percentage: percentage,
+					previousTaskId: previousTaskId,
+					taskOwner: taskOwner
+				});
+				task.parentTask = parentTask;
+				parentTask.addChildTask(task);
+				
+				var ctItems = ctItem.children;
+				if(ctItems.length != 0){
+					this.buildChildTasksData(task, ctItems);
+				}
+			}, this);
+		},
+		getJSONData: function(){
+			var jsonObj = {identifier: 'id', items: []};
+			dojo.forEach(this.project, function(proj){
+				var project = {
+					id: proj.id,
+					name: proj.name,
+					startdate: proj.startDate.getFullYear() + '-' + (proj.startDate.getMonth() + 1) + '-' + proj.startDate.getDate(),
+					tasks: []
+				};
+				jsonObj.items.push(project);
+				dojo.forEach(proj.parentTasks, function(pTask){
+					var task = {
+						id: pTask.id,
+						name: pTask.name,
+						starttime: pTask.startTime.getFullYear() + '-' + (pTask.startTime.getMonth() + 1) + '-' + pTask.startTime.getDate(),
+						duration: pTask.duration,
+						percentage: pTask.percentage,
+						previousTaskId: (pTask.previousTaskId || ''),
+						taskOwner: (pTask.taskOwner || ''),
+						children: this.getChildTasksData(pTask.cldTasks)
+					};
+					project.tasks.push(task);
+				}, this);
+			}, this);
+			return jsonObj;
+		},
+		getChildTasksData: function(childTasks){
+			var cTaskObj = [];
+			childTasks && childTasks.length > 0 && dojo.forEach(childTasks, function(childTask){
+				var ctask = {
+					id: childTask.id,
+					name: childTask.name,
+					starttime: childTask.startTime.getFullYear() + '-' + (childTask.startTime.getMonth() + 1) + '-' + childTask.startTime.getDate(),
+					duration: childTask.duration,
+					percentage: childTask.percentage,
+					previousTaskId: (childTask.previousTaskId || ''),
+					taskOwner: (childTask.taskOwner || ''),
+					children: this.getChildTasksData(childTask.cldTasks)
+				};
+				cTaskObj.push(ctask);
+			}, this);
+			return cTaskObj;
+		},
+		saveJSONData: function(fileName){
+			var _this = this;
+			_this.dataFilePath = (fileName && dojo.trim(fileName).length > 0) ? fileName : this.dataFilePath;
+			try {
+				var td = dojo.xhrPost({
+					url: _this.saveProgramPath,
+					content: {filename: _this.dataFilePath, data: dojo.toJson(_this.getJSONData())},
+					handle: function(res, ioArgs){
+						if((dojo._isDocumentOk(ioArgs.xhr))||
+							(ioArgs.xhr.status == 405)
+						){
+							alert("Successfully! Saved data to " + _this.dataFilePath);
+						}else{
+							alert("Failed! Saved error");
+						}
+					}
+				});
+			} catch (e){
+				alert("exception: " + e.message);
+			}
+		},
+		sortTaskStartTime: function(a, b){
+			return a.startTime < b.startTime ? -1 : (a.startTime > b.startTime ? 1 : 0);
+		},
+		sortProjStartDate: function(a, b){
+			return a.startDate < b.startDate ? -1 : (a.startDate > b.startDate ? 1 : 0);
+		},
+		setStartTimeChild: function(parentTask){
+			dojo.forEach(parentTask.cldTasks, function(pcTask){
+				if(!pcTask.startTime){
+					pcTask.startTime = parentTask.startTime;
+				}
+				if(pcTask.cldTasks.length != 0){
+					this.setStartTimeChild(pcTask);
+				}
+			}, this);
+		},
+		createPanelTasks: function(){
+			var panelTask = dojo.create("div", {
+				className: "ganttTaskPanel"
+			});
+			dojo.style(panelTask, {
+				height: (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px"
+			});
+			return panelTask;
+		},
+		refreshParams: function(pixelsPerDay){
+			this.pixelsPerDay = pixelsPerDay;
+			this.pixelsPerWorkHour = this.pixelsPerDay / this.hsPerDay;
+			this.pixelsPerHour = this.pixelsPerDay / 24;
+		},
+		createPanelNamesTasksHeader: function(){
+			var _this = this;
+			var panelHeader = dojo.create("div", {className: "ganttPanelHeader"});
+			var tblHeader = dojo.create("table", {
+				cellPadding: "0px",
+				border: "0px",
+				cellSpacing: "0px",
+				bgColor: "#FFFFFF",
+				className: "ganttToolbar"
+			}, panelHeader);
+			var firstRow = tblHeader.insertRow(tblHeader.rows.length);
+			var secondRow = tblHeader.insertRow(tblHeader.rows.length);
+			var thirdRow = tblHeader.insertRow(tblHeader.rows.length);
+			var forthRow = tblHeader.insertRow(tblHeader.rows.length);
+			var zoomIn = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttToolbarZoomIn"
+			}, firstRow);
+			var zoomInFn = dojo.hitch(this, function(){
+				if(this.scale * 2 > 5){return;}
+				this.scale = this.scale * 2;
+				this.switchTeleMicroView(this.pixelsPerDay * this.scale);
+			});
+			dojo.disconnect(this.zoomInClickEvent);
+			this.zoomInClickEvent = dojo.connect(zoomIn, "onclick", this, zoomInFn);
+			//a11y support
+			dojo.disconnect(this.zoomInKeyEvent);
+			this.zoomInKeyEvent = dojo.connect(zoomIn, "onkeydown", this, function(e){
+				if(e.keyCode != dojo.keys.ENTER){return;}
+				zoomInFn();
+			});
+			dojo.attr(zoomIn, "tabIndex", 0);
+			var zoomOut = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttToolbarZoomOut"
+			}, firstRow);
+			var zoomOutFn = dojo.hitch(this, function(){
+				if(this.scale * 0.5 < 0.2){return;}
+				this.scale = this.scale * 0.5;
+				this.switchTeleMicroView(this.pixelsPerDay * this.scale);
+			});
+			dojo.disconnect(this.zoomOutClickEvent);
+			this.zoomOutClickEvent = dojo.connect(zoomOut, "onclick", this, zoomOutFn);
+			//a11y support
+			dojo.disconnect(this.zoomOutKeyEvent);
+			this.zoomOutKeyEvent = dojo.connect(zoomOut, "onkeydown", this, function(e){
+				if(e.keyCode != dojo.keys.ENTER){return;}
+				zoomOutFn();
+			});
+			dojo.attr(zoomOut, "tabIndex", 0);
+			var micro = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttToolbarMicro"
+			}, secondRow);
+			dojo.disconnect(this.microClickEvent);
+			this.microClickEvent = dojo.connect(micro, "onclick", this, dojo.hitch(this, this.refresh, this.animation?15:1, 0, 2));
+			//a11y support
+			dojo.disconnect(this.microKeyEvent);
+			this.microKeyEvent = dojo.connect(micro, "onkeydown", this, function(e){
+				if(e.keyCode != dojo.keys.ENTER){return;}
+				micro.blur();
+				this.refresh(this.animation?15:1, 0, 2);
+			});
+			dojo.attr(micro, "tabIndex", 0);
+			var tele = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttToolbarTele"
+			}, secondRow);
+			dojo.disconnect(this.teleClickEvent);
+			this.teleClickEvent = dojo.connect(tele, "onclick", this, dojo.hitch(this, this.refresh, this.animation?15:1, 0, 0.5));
+			//a11y support
+			dojo.disconnect(this.teleKeyEvent);
+			this.teleKeyEvent = dojo.connect(tele, "onkeydown", this, function(e){
+				if(e.keyCode != dojo.keys.ENTER){return;}
+				tele.blur();
+				this.refresh(this.animation?15:1, 0, 0.5);
+			});
+			dojo.attr(tele, "tabIndex", 0);
+			var save = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttToolbarSave"
+			}, thirdRow);
+			dojo.disconnect(this.saveClickEvent);
+			this.saveClickEvent = dojo.connect(save, "onclick", this, dojo.hitch(this, this.saveJSONData, ""));
+			//a11y support
+			dojo.disconnect(this.saveKeyEvent);
+			this.saveKeyEvent = dojo.connect(save, "onkeydown", this, function(e){
+				if(e.keyCode != dojo.keys.ENTER){return;}
+				this.saveJSONData("");
+			});
+			dojo.attr(save, "tabIndex", 0);
+			var load = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttToolbarLoad"
+			}, thirdRow);
+			dojo.disconnect(this.loadClickEvent);
+			this.loadClickEvent = dojo.connect(load, "onclick", this, dojo.hitch(this, this.loadJSONData, ""));
+			//a11y support
+			dojo.disconnect(this.loadKeyEvent);
+			this.loadKeyEvent = dojo.connect(load, "onkeydown", this, function(e){
+				if(e.keyCode != dojo.keys.ENTER){return;}
+				this.loadJSONData("");
+			});
+			dojo.attr(load, "tabIndex", 0);
+			//action popup description
+			var actions = [zoomIn, zoomOut, micro, tele, save, load],
+				titles = ["Enlarge timeline", "Shrink timeline", "Zoom in time zone(microscope view)", "Zoom out time zone(telescope view)",
+							"Save gantt data to json file", "Load gantt data from json file"];
+			dojo.forEach(actions, function(action, i){
+				var title = titles[i];
+				var tooltipShow = function(){
+					dojo.addClass(action, "ganttToolbarActionHover");
+					dijit.showTooltip(title, action, ["above", "below"]);
+				};
+				action.onmouseover = tooltipShow;
+				//a11y support
+				action.onfocus = tooltipShow;
+				var tooltipHide = function(){
+					dojo.removeClass(action, "ganttToolbarActionHover");
+					action && dijit.hideTooltip(action);
+				};
+				action.onmouseout = tooltipHide;
+				action.onblur = tooltipHide;
+			}, this);
+			return panelHeader;
+		},
+		createPanelNamesTasks: function(){
+			var panelNameTask = dojo.create("div", {
+				innerHTML: " ",
+				className: "ganttPanelNames"
+			});
+			dojo.style(panelNameTask, {
+				height: (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px",
+				width: this.maxWidthPanelNames + "px"
+			});
+			return panelNameTask;
+		},
+		createPanelTime: function(){
+			var panelTime = dojo.create("div", {className: "ganttPanelTime"});
+			var tblTime = dojo.create("table", {
+				cellPadding: "0px",
+				border: "0px",
+				cellSpacing: "0px",
+				bgColor: "#FFFFFF",
+				className: "ganttTblTime"
+			}, panelTime);
+			this.totalDays = this.countDays;
+			//year
+			var newYearRow = tblTime.insertRow(tblTime.rows.length), newYear = oldYear = new Date(this.startDate).getFullYear(), ycount = 0;
+			for(var i = 0; i < this.countDays; i++, ycount++){
+				var date = new Date(this.startDate);
+				date.setDate(date.getDate() + i);
+				newYear = date.getFullYear();
+				if(newYear != oldYear){
+					this.addYearInPanelTime(newYearRow, ycount, oldYear);
+					ycount = 0;
+					oldYear = newYear;
+				}
+			}
+			this.addYearInPanelTime(newYearRow, ycount, newYear);
+			dojo.style(newYearRow, "display", "none");
+			//month
+			var newMonthRow = tblTime.insertRow(tblTime.rows.length), newMonth = oldMonth = new Date(this.startDate).getMonth(), mcount = 0, lastYear = 1970;
+			for(var i = 0; i < this.countDays; i++, mcount++){
+				var date = new Date(this.startDate);
+				date.setDate(date.getDate() + i);
+				newMonth = date.getMonth();
+				lastYear = date.getFullYear();
+				if(newMonth != oldMonth){
+					this.addMonthInPanelTime(newMonthRow, mcount, oldMonth, lastYear);
+					mcount = 0;
+					oldMonth = newMonth;
+				}
+			}
+			this.addMonthInPanelTime(newMonthRow, mcount, newMonth, lastYear);
+			//week
+			var newWeekRow = tblTime.insertRow(tblTime.rows.length), newWeek = oldWeek = dojo.date.locale._getWeekOfYear(new Date(this.startDate)), mcount = 0;
+			for(var i = 0; i < this.countDays; i++, mcount++){
+				var date = new Date(this.startDate);
+				date.setDate(date.getDate() + i);
+				newWeek = dojo.date.locale._getWeekOfYear(date);
+				if(newWeek != oldWeek){
+					this.addWeekInPanelTime(newWeekRow, mcount, oldWeek);
+					mcount = 0;
+					oldWeek = newWeek;
+				}
+			}
+			this.addWeekInPanelTime(newWeekRow, mcount, newWeek);
+			//day
+			var newDayRow = tblTime.insertRow(tblTime.rows.length);
+			for(var i = 0; i < this.countDays; i++){
+				this.addDayInPanelTime(newDayRow);
+			}
+			//hour
+			var newHourRow = tblTime.insertRow(tblTime.rows.length);
+			for(var i = 0; i < this.countDays; i++){
+				this.addHourInPanelTime(newHourRow);
+			}
+			dojo.style(newHourRow, "display", "none");
+			return panelTime;
+		},
+		adjustPanelTime: function(width){
+			var maxEndPos = dojo.map(this.arrProjects, function(project){
+				return (parseInt(project.projectItem[0].style.left) + parseInt(project.projectItem[0].firstChild.style.width)
+					+ project.descrProject.offsetWidth + this.panelTimeExpandDelta);
+			}, this).sort(function(a,b){return b-a})[0];
+			if(this.maxTaskEndPos != maxEndPos){
+				//reset panel time
+				var prows = this.panelTime.firstChild.firstChild.rows;
+				for(var i = 0; i <= 4; i++){//prows.length
+					this.removeCell(prows[i]);
+				};
+				var countDays = Math.round((maxEndPos+this.panelTimeExpandDelta) / this.pixelsPerDay);
+				this.totalDays = countDays;
+				//year
+				var newYear = oldYear = new Date(this.startDate).getFullYear(), ycount = 0;
+				for(var i = 0; i < countDays; i++, ycount++){
+					var date = new Date(this.startDate);
+					date.setDate(date.getDate() + i);
+					newYear = date.getFullYear();
+					if(newYear != oldYear){
+						this.addYearInPanelTime(prows[0], ycount, oldYear);
+						ycount = 0;
+						oldYear = newYear;
+					}
+				}
+				this.addYearInPanelTime(prows[0], ycount, newYear);
+				//month
+				var newMonth = oldMonth = new Date(this.startDate).getMonth(), mcount = 0, lastYear = 1970;
+				for(var i = 0; i < countDays; i++, mcount++){
+					var date = new Date(this.startDate);
+					date.setDate(date.getDate() + i);
+					newMonth = date.getMonth();
+					lastYear = date.getFullYear();
+					if(newMonth != oldMonth){
+						this.addMonthInPanelTime(prows[1], mcount, oldMonth, lastYear);
+						mcount = 0;
+						oldMonth = newMonth;
+					}
+				}
+				this.addMonthInPanelTime(prows[1], mcount, newMonth, lastYear);
+				//week
+				var newWeek = oldWeek = dojo.date.locale._getWeekOfYear(new Date(this.startDate)), mcount = 0;
+				for(var i = 0; i < countDays; i++, mcount++){
+					var date = new Date(this.startDate);
+					date.setDate(date.getDate() + i);
+					newWeek = dojo.date.locale._getWeekOfYear(date);
+					if(newWeek != oldWeek){
+						this.addWeekInPanelTime(prows[2], mcount, oldWeek);
+						mcount = 0;
+						oldWeek = newWeek;
+					}
+				}
+				this.addWeekInPanelTime(prows[2], mcount, newWeek);
+				//day
+				for(var i = 0; i < countDays; i++){
+					this.addDayInPanelTime(prows[3]);
+				}
+				//hour
+				for(var i = 0; i < countDays; i++){
+					this.addHourInPanelTime(prows[4]);
+				}
+				this.panelTime.firstChild.firstChild.style.width = this.pixelsPerDay * (prows[3].cells.length) + "px";
+				this.contentData.firstChild.style.width = this.pixelsPerDay * (prows[3].cells.length) + "px";
+				this.maxTaskEndPos = maxEndPos;
+			}
+		},
+		addYearInPanelTime: function(row, count, year){
+			var data = "Year   " + year;
+			var newCell = dojo.create("td", {
+				colSpan: count,
+				align: "center",
+				vAlign: "middle",
+				className: "ganttYearNumber",
+				innerHTML: this.pixelsPerDay * count > 20 ? data : "",
+				innerHTMLData: data
+			}, row);
+			dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
+		},
+		addMonthInPanelTime: function(row, count, month, year){
+			var data = this.months[month] + (year ? " of " + year : "");
+			var newCell = dojo.create("td", {
+				colSpan: count,
+				align: "center",
+				vAlign: "middle",
+				className: "ganttMonthNumber",
+				innerHTML: this.pixelsPerDay * count > 30 ? data : "",
+				innerHTMLData: data
+			}, row);
+			dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
+		},
+		addWeekInPanelTime: function(row, count, week){
+			var data = "Week   " + week;
+			var newCell = dojo.create("td", {
+				colSpan: count,
+				align: "center",
+				vAlign: "middle",
+				className: "ganttWeekNumber",
+				innerHTML: this.pixelsPerDay * count > 20 ? data : "",
+				innerHTMLData: data
+			}, row);
+			dojo.style(newCell, "width", (this.pixelsPerDay * count) + "px");
+		},
+		addDayInPanelTime: function(row){
+			var date = new Date(this.startDate);
+			date.setDate(date.getDate() + parseInt(row.cells.length));
+			var newCell = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttDayNumber",
+				innerHTML: this.pixelsPerDay > 20 ? date.getDate() : "",
+				innerHTMLData: String(date.getDate()),
+				data: row.cells.length
+			}, row);
+			dojo.style(newCell, "width", this.pixelsPerDay + "px");
+			(date.getDay() >= 5) && dojo.addClass(newCell, "ganttDayNumberWeekend");
+			this._events.push(
+				dojo.connect(newCell, "onmouseover", this, function(event){
+					var dayTime = event.target || event.srcElement;
+					var date = new Date(this.startDate.getTime());
+					date.setDate(date.getDate() + parseInt(dojo.attr(dayTime, "data")));
+					dijit.showTooltip(date.getFullYear() + "." + (date.getMonth() + 1) + "." + date.getDate(), newCell, ["above", "below"]);
+				})
+			);
+			this._events.push(
+				dojo.connect(newCell, "onmouseout", this, function(event){
+					var dayTime = event.target || event.srcElement;
+					dayTime && dijit.hideTooltip(dayTime);
+				})
+			);
+		},
+		addHourInPanelTime: function(row){
+			var newCell = dojo.create("td", {
+				align: "center",
+				vAlign: "middle",
+				className: "ganttHourNumber",
+				data: row.cells.length
+			}, row);
+			dojo.style(newCell, "width", this.pixelsPerDay + "px");
+			
+			var hourTable = dojo.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0"
+			}, newCell);
+			var newRow = hourTable.insertRow(hourTable.rows.length);
+			for(var i = 0; i < this.hsPerDay; i++){
+				var hourTD = dojo.create("td", {
+					className: "ganttHourClass"
+				}, newRow);
+				dojo.style(hourTD, "width", (this.pixelsPerDay / this.hsPerDay) + "px");
+				dojo.attr(hourTD, "innerHTMLData", String(9 + i));
+				if(this.pixelsPerDay / this.hsPerDay > 5){
+					dojo.attr(hourTD, "innerHTML", String(9 + i));
+				}
+				dojo.addClass(hourTD, i <= 3?"ganttHourNumberAM":"ganttHourNumberPM");
+			}
+		},
+		incHeightPanelTasks: function(height){
+			var containerTasks = this.contentData.firstChild;
+			containerTasks.style.height = parseInt(containerTasks.style.height) + height + "px";
+		},
+		incHeightPanelNames: function(height){
+			var containerNames = this.panelNames.firstChild;
+			containerNames.style.height = parseInt(containerNames.style.height) + height + "px";
+		},
+		checkPosition: function(){
+			dojo.forEach(this.arrProjects, function(project){
+				dojo.forEach(project.arrTasks, function(task){
+					task.checkPosition();
+				}, this);
+			}, this);
+		},
+		checkHeighPanelTasks: function(){
+			this.contentDataHeight += this.heightTaskItemExtra + this.heightTaskItem;
+			if((parseInt(this.contentData.firstChild.style.height) <= this.contentDataHeight)){
+				this.incHeightPanelTasks(this.heightTaskItem + this.heightTaskItemExtra);
+				this.incHeightPanelNames(this.heightTaskItem + this.heightTaskItemExtra);
+			}
+		},
+		sortTasksByStartTime: function(project){
+			project.parentTasks.sort(this.sortTaskStartTime);
+			for(var i = 0; i < project.parentTasks.length; i++){
+				project.parentTasks[i] = this.sortChildTasks(project.parentTasks[i]);
+			}
+		},
+		sortChildTasks: function(parenttask){
+			parenttask.cldTasks.sort(this.sortTaskStartTime);
+			for(var i = 0; i < parenttask.cldTasks.length; i++){
+				if(parenttask.cldTasks[i].cldTasks.length > 0) this.sortChildTasks(parenttask.cldTasks[i]);
+			}
+			return parenttask;
+		},
+		refresh: function(count, current, multi){
+			//return if no task items
+			if(this.arrProjects.length <= 0){return;}
+			if(this.arrProjects[0].arrTasks.length <= 0){return;}
+			//Show panel of names
+			if(!count || current > count){
+				this.refreshController();
+				if(this.resource){
+					this.resource.refresh();
+				}
+				this.tempDayInPixels = 0;
+				this.panelNameHeadersCover && dojo.style(this.panelNameHeadersCover, "display", "none");
+				return;
+			}
+			if(this.tempDayInPixels == 0){
+				this.tempDayInPixels = this.pixelsPerDay;
+			}
+			this.panelNameHeadersCover && dojo.style(this.panelNameHeadersCover, "display", "");
+			var dip = this.tempDayInPixels + this.tempDayInPixels * (multi - 1) * Math.pow((current / count), 2);
+			this.refreshParams(dip);
+			dojo.forEach(this.arrProjects, function(project){
+				dojo.forEach(project.arrTasks, function(task){
+					task.refresh();
+				}, this);
+				project.refresh();
+			}, this);
+			setTimeout(dojo.hitch(this, function(){
+				this.refresh(count, ++current, multi);
+			}), 15);
+		},
+		switchTeleMicroView: function(dip){
+			var plChild = this.panelTime.firstChild.firstChild;
+			for(var i = 0; i < 5; i++){//0:Y 1:M 2:W 3:D 4:H
+				if(dip > 40){
+					dojo.style(plChild.rows[i], "display", (i==0||i==1)?"none":"");
+				}else if(dip < 20){
+					dojo.style(plChild.rows[i], "display", (i==2||i==4)?"none":"");
+				}else{
+					dojo.style(plChild.rows[i], "display", (i==0||i==4)?"none":"");
+				}
+			}
+		},
+		refreshController: function(){
+			this.contentData.firstChild.style.width = Math.max(1200, this.pixelsPerDay * this.totalDays) + "px";
+			this.panelTime.firstChild.style.width = this.pixelsPerDay * this.totalDays + "px";
+			this.panelTime.firstChild.firstChild.style.width = this.pixelsPerDay * this.totalDays + "px";
+			this.switchTeleMicroView(this.pixelsPerDay);
+			dojo.forEach(this.panelTime.firstChild.firstChild.rows, function(row){
+				dojo.forEach(row.childNodes, function(td){
+					var cs = parseInt(dojo.attr(td, "colSpan") || 1);
+					var idata = dojo.trim(dojo.attr(td, "innerHTMLData")||"");
+					if(idata.length > 0){
+						dojo.attr(td, "innerHTML", this.pixelsPerDay * cs < 20 ? "" : idata);
+					}else{
+						dojo.forEach(td.firstChild.rows[0].childNodes, function(td){
+							var sdata = dojo.trim(dojo.attr(td, "innerHTMLData")||"");
+							dojo.attr(td, "innerHTML", this.pixelsPerDay / this.hsPerDay > 10 ? sdata : "");
+						}, this);
+					}
+					if(cs == 1){
+						dojo.style(td, "width", (this.pixelsPerDay*cs) + "px");
+						if(idata.length <= 0){
+							dojo.forEach(td.firstChild.rows[0].childNodes, function(td){
+								dojo.style(td, "width", (this.pixelsPerDay*cs / this.hsPerDay) + "px");
+							}, this);
+						}
+					}
+				}, this);
+			}, this);
+		},
+		init: function(){
+			this.startDate = this.getStartDate();
+			dojo.style(this.content, {
+				width: this.contentWidth + "px",
+				height: this.contentHeight + "px"
+			});
+			//create Table
+			this.tableControl = dojo.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0",
+				className: "ganttTabelControl"
+			});
+			var newRowTblControl = this.tableControl.insertRow(this.tableControl.rows.length);
+			//Add to content Table
+			this.content.appendChild(this.tableControl);
+			this.countDays = this.getCountDays();
+			//Creation panel of time
+			this.panelTime = dojo.create("div", {className: "ganttPanelTimeContainer"});
+			dojo.style(this.panelTime, "height", this.panelTimeHeight + "px");
+			this.panelTime.appendChild(this.createPanelTime());
+			//Creation panel contentData
+			this.contentData = dojo.create("div", {className: "ganttContentDataContainer"});
+			dojo.style(this.contentData, "height", (this.contentHeight - this.panelTimeHeight) + "px");
+			this.contentData.appendChild(this.createPanelTasks());
+			//Creation panel of names
+			var newCellTblControl = dojo.create("td", {
+				vAlign: "top"
+			});
+			//Creation panel of task header
+			this.panelNameHeaders = dojo.create("div", {className: "ganttPanelNameHeaders"}, newCellTblControl);
+			dojo.style(this.panelNameHeaders, {
+				height: this.panelTimeHeight + "px",
+				width: this.maxWidthPanelNames + "px"
+			});
+			this.panelNameHeaders.appendChild(this.createPanelNamesTasksHeader());
+			this.panelNames = dojo.create("div", {className: "ganttPanelNamesContainer"}, newCellTblControl);
+			this.panelNames.appendChild(this.createPanelNamesTasks());
+			newRowTblControl.appendChild(newCellTblControl);
+			//add to control contentData and dataTime
+			newCellTblControl = dojo.create("td", {
+				vAlign: "top"
+			});
+			var divCell = dojo.create("div", {className: "ganttDivCell"});
+			divCell.appendChild(this.panelTime);
+			divCell.appendChild(this.contentData);
+			newCellTblControl.appendChild(divCell);
+			newRowTblControl.appendChild(newCellTblControl);
+			//Show panel of names
+			dojo.style(this.panelNames, "height", (this.contentHeight - this.panelTimeHeight - this.scrollBarWidth) + "px");
+			dojo.style(this.panelNames, "width", this.maxWidthPanelNames + "px");
+			dojo.style(this.contentData, "width", (this.contentWidth - this.maxWidthPanelNames) + "px");
+			dojo.style(this.contentData.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
+			dojo.style(this.panelTime, "width", (this.contentWidth - this.maxWidthPanelNames - this.scrollBarWidth) + "px");
+			dojo.style(this.panelTime.firstChild, "width", this.pixelsPerDay * this.countDays + "px");
+			if(this.isShowConMenu){
+				this.tabMenu = new dojox.gantt.TabMenu(this);
+			}
+			var _this = this;
+			this.contentData.onscroll = function(){
+				_this.panelTime.scrollLeft = this.scrollLeft;
+				if(_this.panelNames){
+					_this.panelNames.scrollTop = this.scrollTop;
+					if(_this.isShowConMenu){
+						_this.tabMenu.hide();
+					}
+				}
+				if(_this.resource){
+					_this.resource.contentData.scrollLeft = this.scrollLeft;
+				}
+			}
+			this.project.sort(this.sortProjStartDate);
+			for(var i = 0; i < this.project.length; i++){
+				var proj = this.project[i];
+				for(var k = 0; k < proj.parentTasks.length; k++){
+					var ppTask = proj.parentTasks[k];
+					if(!ppTask.startTime){
+						ppTask.startTime = proj.startDate;
+					}
+					this.setStartTimeChild(ppTask);
+					if(this.setPreviousTask(proj)){
+						return;
+					}
+				}
+				for(var k = 0; k < proj.parentTasks.length; k++){
+					var ppTask = proj.parentTasks[k];
+					if(ppTask.startTime < proj.startDate){
+						if(!this.correctError){
+							return;
+						}else{
+							ppTask.startTime = proj.startDate;
+						}
+					}
+					if(this.checkPosParentTaskInTree(ppTask)){
+						return;
+					}
+				}
+				this.sortTasksByStartTime(proj);
+			}
+			for(var i = 0; i < this.project.length; i++){
+				//creation project
+				var proj = this.project[i];
+				var project = new dojox.gantt.GanttProjectControl(this, proj);
+				if(this.arrProjects.length > 0){
+					var previousProject = this.arrProjects[this.arrProjects.length - 1];
+					project.previousProject = previousProject;
+					previousProject.nextProject = project;
+				}
+				project.create();
+				this.checkHeighPanelTasks();
+				this.arrProjects.push(project);
+				this.createTasks(project);
+			}
+			if(this.withResource){
+				this.resource = new dojox.gantt.GanttResourceItem(this);
+				this.resource.create();
+			}
+			this.postLoadData();
+			this.postBindEvents();
+			return this;
+		},
+		postLoadData: function(){
+			dojo.forEach(this.arrProjects, function(project){
+				dojo.forEach(project.arrTasks, function(task){
+					task.postLoadData();
+				}, this);
+				project.postLoadData();
+			}, this);
+			//toolbar cover div
+			var cpos = dojo.coords(this.panelNameHeaders);
+			if(!this.panelNameHeadersCover){
+				this.panelNameHeadersCover = dojo.create("div", {className: "ganttHeaderCover"}, this.panelNameHeaders.parentNode);
+				dojo.style(this.panelNameHeadersCover, {
+					left: cpos.l+"px",
+					top: cpos.t+"px",
+					height: cpos.h+"px",
+					width: cpos.w+"px",
+					display: "none"
+				});
+			}
+		},
+		postBindEvents: function(){
+			//highlight row
+			var pos = dojo.position(this.tableControl, true);
+			!dojo.isIE && this._events.push(
+				dojo.connect(this.tableControl, "onmousemove", this, function(event){
+					var elem = event.srcElement || event.target;
+					if(elem == this.panelNames.firstChild || elem == this.contentData.firstChild){
+						//23: this.heightTaskItem + this.heightTaskItemExtra
+						var rowHeight = this.heightTaskItem + this.heightTaskItemExtra;
+						var hlTop = parseInt(event.layerY / rowHeight) * rowHeight + this.panelTimeHeight - this.contentData.scrollTop;
+						if(hlTop != this.oldHLTop && hlTop < (pos.h - 50)){
+							if(this.highLightDiv){
+								dojo.style(this.highLightDiv, "top", (pos.y + hlTop) + "px");
+							}else{
+								this.highLightDiv = dojo.create("div", {
+									className: "ganttRowHighlight"
+								}, dojo.body());
+								dojo.style(this.highLightDiv, {
+									top: (pos.y + hlTop) + "px",
+									left: pos.x + "px",
+									width: (pos.w - 20) + "px",
+									height: rowHeight + "px"
+								});
+							}
+						}
+						this.oldHLTop = hlTop;
+					}
+				})
+			);
+			//TODO: other event bindings
+		},
+		getStartDate: function(){
+			dojo.forEach(this.project, function(proj){
+				if(this.startDate){
+					if(proj.startDate < this.startDate){
+						this.startDate = new Date(proj.startDate);
+					}
+				}else{
+					this.startDate = new Date(proj.startDate);
+				}
+			}, this);
+			this.initialPos = 24 * this.pixelsPerHour;
+			return this.startDate ? new Date(this.startDate.setHours(this.startDate.getHours() - 24)) : new Date();
+		},
+		getCountDays: function(){
+			return parseInt((this.contentWidth - this.maxWidthPanelNames) / (this.pixelsPerHour * 24));
+		},
+		createTasks: function(project){
+			dojo.forEach(project.project.parentTasks, function(pppTask, i){
+				if(i > 0){
+					project.project.parentTasks[i - 1].nextParentTask = pppTask;
+					pppTask.previousParentTask = project.project.parentTasks[i - 1];
+				}
+				var task = new dojox.gantt.GanttTaskControl(pppTask, project, this);
+				project.arrTasks.push(task);
+				task.create();
+				this.checkHeighPanelTasks();
+				if(pppTask.cldTasks.length > 0){
+					this.createChildItemControls(pppTask.cldTasks, project);
+				}
+			}, this);
+		},
+		createChildItemControls: function(arrChildTasks, project){
+			arrChildTasks && dojo.forEach(arrChildTasks, function(cTask, i){
+				if(i > 0){
+					cTask.previousChildTask = arrChildTasks[i - 1];
+					arrChildTasks[i - 1].nextChildTask = cTask;
+				}
+				var task = new dojox.gantt.GanttTaskControl(cTask, project, this);
+				task.create();
+				this.checkHeighPanelTasks();
+				if(cTask.cldTasks.length > 0){
+					this.createChildItemControls(cTask.cldTasks, project);
+				}
+			}, this);
+		},
+		getPosOnDate: function(startTime){
+			return (startTime - this.startDate) / (60 * 60 * 1000) * this.pixelsPerHour;
+		},
+		getWidthOnDuration: function(duration){
+			return Math.round(this.pixelsPerWorkHour * duration);
+		},
+		getLastChildTask: function(task){
+			return task.childTask.length > 0 ? this.getLastChildTask(task.childTask[task.childTask.length - 1]) : task;
+		},
+		removeCell: function(row){
+			while(row.cells[0]){
+				row.deleteCell(row.cells[0]);
+			}
+		}
+	});
+})();
\ No newline at end of file
diff --git a/dojox/gantt/GanttProjectItem.js b/dojox/gantt/GanttProjectItem.js
new file mode 100644
index 0000000..dcdbbd7
--- /dev/null
+++ b/dojox/gantt/GanttProjectItem.js
@@ -0,0 +1,967 @@
+dojo.provide("dojox.gantt.GanttProjectItem");
+
+dojo.require("dojox.gantt.GanttTaskItem");
+dojo.require("dojo.date.locale");
+
+dojo.declare("dojox.gantt.GanttProjectControl", null, {
+	constructor: function(ganttChart, projectItem){
+		this.project = projectItem;
+		this.ganttChart = ganttChart;
+		this.descrProject = null;
+		this.projectItem = null;
+		this.projectNameItem = null;
+		this.posY = 0;
+		this.posX = 0;
+		this.nextProject = null;
+		this.previousProject = null;
+		this.arrTasks = [];
+		this.percentage = 0;
+		this.duration = 0;
+	},
+	checkWidthProjectNameItem: function(){
+		if(this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft > this.ganttChart.maxWidthTaskNames){
+			var width = this.projectNameItem.offsetWidth + this.projectNameItem.offsetLeft - this.ganttChart.maxWidthTaskNames;
+			var countChar = Math.round(width / (this.projectNameItem.offsetWidth / this.projectNameItem.firstChild.length));
+			var pName = this.project.name.substring(0, this.projectNameItem.firstChild.length - countChar - 3);
+			pName += "...";
+			this.projectNameItem.innerHTML = pName;
+		}
+	},
+	refreshProjectItem: function(projectItem){
+		this.percentage = this.getPercentCompleted();
+		dojo.style(projectItem, {
+			"left": this.posX + "px",
+			"width": this.duration * this.ganttChart.pixelsPerWorkHour + "px"
+		});
+		var tblProjectItem = projectItem.firstChild;
+		var width = this.duration * this.ganttChart.pixelsPerWorkHour;
+		tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
+		tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
+		var rowprojectItem = tblProjectItem.rows[0];
+		if(this.percentage != -1){
+			if(this.percentage != 0){
+				var cellprojectItem = rowprojectItem.firstChild;
+				cellprojectItem.width = this.percentage + "%";
+				var imageProgress = cellprojectItem.firstChild;
+				dojo.style(imageProgress, {
+					width: (!this.duration ? 1 : (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				})
+			}
+			if(this.percentage != 100){
+				var cellprojectItem = rowprojectItem.lastChild;
+				cellprojectItem.width = (100 - this.percentage) + "%";
+				var imageProgress = cellprojectItem.firstChild;
+				dojo.style(imageProgress, {
+					width: (!this.duration ? 1 : ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				})
+			}
+		}else{
+			var cellprojectItem = rowprojectItem.firstChild;
+			cellprojectItem.width = "1px";
+			var imageProgress = cellprojectItem.firstChild;
+			dojo.style(imageProgress, {
+				width: "1px",
+				height: this.ganttChart.heightTaskItem + "px"
+			})
+		}
+		var divTaskInfo = projectItem.lastChild;
+		var tblTaskInfo = divTaskInfo.firstChild;
+		dojo.style(tblTaskInfo, {
+			height: this.ganttChart.heightTaskItem + "px",
+			width: (!this.duration ? 1 : (this.duration * this.ganttChart.pixelsPerWorkHour)) + "px"
+		});
+		var rowTaskInfo = tblTaskInfo.rows[0];
+		var cellTaskInfo = rowTaskInfo.firstChild;
+		cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
+		if(this.project.parentTasks.length == 0){
+			projectItem.style.display = "none";
+		}
+		return projectItem;
+	},
+	refreshDescrProject: function(divDesc){
+		var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		dojo.style(divDesc, {
+			"left": posX + "px"
+		});
+		if(this.project.parentTasks.length == 0){
+			this.descrProject.style.visibility = 'hidden';
+		}
+		return divDesc;
+	},
+	postLoadData: function(){
+		//TODO e.g. project relative info...
+	},
+	refresh: function(){
+		var containerTasks = this.ganttChart.contentData.firstChild;
+		this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
+		this.refreshProjectItem(this.projectItem[0]);
+		this.refreshDescrProject(this.projectItem[0].nextSibling);
+		return this;
+	},
+	create: function(){
+		var containerTasks = this.ganttChart.contentData.firstChild;
+		this.posX = (this.project.startDate - this.ganttChart.startDate) / (60 * 60 * 1000) * this.ganttChart.pixelsPerHour;
+		if(this.previousProject){
+			if(this.previousProject.arrTasks.length > 0){
+				var lastChildTask = this.ganttChart.getLastChildTask(this.previousProject.arrTasks[this.previousProject.arrTasks.length - 1]);
+				this.posY = parseInt(lastChildTask.cTaskItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			}else{
+				this.posY = parseInt(this.previousProject.projectItem[0].style.top) + this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			}
+		}else{
+			this.posY = 6;
+		}
+		var containerNames = this.ganttChart.panelNames.firstChild;
+		this.projectNameItem = this.createProjectNameItem();
+		containerNames.appendChild(this.projectNameItem);
+		this.checkWidthProjectNameItem();
+		this.projectItem = [this.createProjectItem(), []];
+		containerTasks.appendChild(this.projectItem[0]);
+		containerTasks.appendChild(this.createDescrProject());
+		this.adjustPanelTime();
+	},
+	getTaskById: function(id){
+		for(var i = 0; i < this.arrTasks.length; i++){
+			var aTask = this.arrTasks[i];
+			var task = this.searchTaskInTree(aTask, id);
+			if(task){
+				return task;
+			}
+		}
+		return null;
+	},
+	searchTaskInTree: function(task, id){
+		if(task.taskItem.id == id){
+			return task;
+		}else{
+			for(var i = 0; i < task.childTask.length; i++){
+				var cTask = task.childTask[i];
+				if(cTask.taskItem.id == id){
+					return cTask;
+				}else{
+					if(cTask.childTask.length > 0){
+						var cTask = this.searchTaskInTree(cTask, id);
+						if(cTask){
+							return cTask;
+						}
+					}
+				}
+			}
+		}
+		return null;
+	},
+	shiftProjectItem: function(){
+		var posItemL = null;
+		var posItemR = null;
+		var posProjectItemL = parseInt(this.projectItem[0].style.left);
+		var posProjectItemR = parseInt(this.projectItem[0].firstChild.style.width) + parseInt(this.projectItem[0].style.left);
+		var widthProjectItem = parseInt(this.projectItem[0].firstChild.style.width);
+		for(var i = 0; i < this.arrTasks.length; i++){
+			var aTask = this.arrTasks[i];
+			var tmpPosItemL = parseInt(aTask.cTaskItem[0].style.left);
+			var tmpPosItemR = parseInt(aTask.cTaskItem[0].style.left) + parseInt(aTask.cTaskItem[0].firstChild.firstChild.width);
+			if(!posItemL){
+				posItemL = tmpPosItemL;
+			}
+			if(!posItemR){
+				posItemR = tmpPosItemR;
+			}
+			if(posItemL > tmpPosItemL){
+				posItemL = tmpPosItemL;
+			}
+			if(posItemR < tmpPosItemR){
+				posItemR = tmpPosItemR;
+			}
+		}
+		if(posItemL != posProjectItemL){
+			this.project.startDate = new Date(this.ganttChart.startDate);
+			this.project.startDate.setHours(this.project.startDate.getHours() + (posItemL / this.ganttChart.pixelsPerHour));
+		}
+		this.projectItem[0].style.left = posItemL + "px";
+		this.resizeProjectItem(posItemR - posItemL);
+		this.duration = Math.round(parseInt(this.projectItem[0].firstChild.width) / (this.ganttChart.pixelsPerWorkHour));
+		this.shiftDescrProject();
+		this.adjustPanelTime();
+	},
+	adjustPanelTime: function(){
+		var projectItem = this.projectItem[0];
+		var width = parseInt(projectItem.style.left) + parseInt(projectItem.firstChild.style.width) + this.ganttChart.panelTimeExpandDelta;
+		width += this.descrProject.offsetWidth;
+		this.ganttChart.adjustPanelTime(width);
+	},
+	resizeProjectItem: function(width){
+		var percentage = this.percentage,
+			pItem = this.projectItem[0];
+		if(percentage > 0 && percentage < 100){
+			pItem.firstChild.style.width = width + "px";
+			pItem.firstChild.width = width + "px";
+			pItem.style.width = width + "px";
+			var firstRow = pItem.firstChild.rows[0];
+			firstRow.cells[0].firstChild.style.width = Math.round(width * percentage / 100) + "px";
+			firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
+			firstRow.cells[1].firstChild.style.width = Math.round(width * (100 - percentage) / 100) + "px";
+			firstRow.cells[1].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
+			pItem.lastChild.firstChild.width = width + "px";
+		}else if(percentage == 0 || percentage == 100){
+			pItem.firstChild.style.width = width + "px";
+			pItem.firstChild.width = width + "px";
+			pItem.style.width = width + "px";
+			var firstRow = pItem.firstChild.rows[0];
+			firstRow.cells[0].firstChild.style.width = width + "px";
+			firstRow.cells[0].firstChild.style.height = this.ganttChart.heightTaskItem + "px";
+			pItem.lastChild.firstChild.width = width + "px";
+		}
+	},
+	shiftDescrProject: function(){
+		var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		this.descrProject.style.left = posX + "px";
+		this.descrProject.innerHTML = this.getDescStr();
+	},
+	showDescrProject: function(){
+		var posX = (parseInt(this.projectItem[0].style.left) + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		this.descrProject.style.left = posX + "px";
+		this.descrProject.style.visibility = 'visible';
+		this.descrProject.innerHTML = this.getDescStr();
+	},
+	hideDescrProject: function(){
+		this.descrProject.style.visibility = 'hidden';
+	},
+	getDescStr: function(){
+		return this.duration/this.ganttChart.hsPerDay + " days,  " + this.duration + " hours";
+	},
+	createDescrProject: function(){
+		var posX = (this.posX + this.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		var divDesc = dojo.create("div", {
+			innerHTML: this.getDescStr(),
+			className: "ganttDescProject"
+		});
+		dojo.style(divDesc, {
+			left: posX + "px",
+			top: this.posY + "px"
+		});
+		this.descrProject = divDesc;
+		if(this.project.parentTasks.length == 0){
+			this.descrProject.style.visibility = 'hidden';
+		}
+		return divDesc;
+	},
+	createProjectItem: function(){
+		this.percentage = this.getPercentCompleted();
+		this.duration = this.getDuration();
+		var projectItem = dojo.create("div", {
+			id: this.project.id,
+			className: "ganttProjectItem"
+		});
+		dojo.style(projectItem, {
+			left: this.posX + "px",
+			top: this.posY + "px",
+			width: this.duration * this.ganttChart.pixelsPerWorkHour + "px"
+		});
+		var tblProjectItem = dojo.create("table", {
+			cellPadding: "0",
+			cellSpacing: "0",
+			className: "ganttTblProjectItem"
+		}, projectItem);
+		var width = this.duration * this.ganttChart.pixelsPerWorkHour;
+		tblProjectItem.width = ((width == 0) ? 1 : width) + "px";
+		tblProjectItem.style.width = ((width == 0) ? 1 : width) + "px";
+		
+		var rowprojectItem = tblProjectItem.insertRow(tblProjectItem.rows.length);
+		if(this.percentage != -1){
+			if(this.percentage != 0){
+				var cellprojectItem = dojo.create("td", {
+					width: this.percentage + "%"
+				}, rowprojectItem);
+				cellprojectItem.style.lineHeight = "1px";
+				var imageProgress = dojo.create("div", {
+					className: "ganttImageProgressFilled"
+				}, cellprojectItem);
+				dojo.style(imageProgress, {
+					width: (this.percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+			if(this.percentage != 100){
+				var cellprojectItem = dojo.create("td", {
+					width: (100 - this.percentage) + "%"
+				}, rowprojectItem);
+				cellprojectItem.style.lineHeight = "1px";
+				var imageProgress = dojo.create("div", {
+					className: "ganttImageProgressBg"
+				}, cellprojectItem);
+				dojo.style(imageProgress, {
+					width: ((100 - this.percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+		}else{
+			var cellprojectItem = dojo.create("td", {
+				width: "1px"
+			}, rowprojectItem);
+			cellprojectItem.style.lineHeight = "1px";
+			var imageProgress = dojo.create("div", {
+				className: "ganttImageProgressBg"
+			}, cellprojectItem);
+			dojo.style(imageProgress, {
+				width: "1px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}
+		var divTaskInfo = dojo.create("div", {className: "ganttDivTaskInfo"});
+		var tblTaskInfo = dojo.create("table", {
+			cellPadding: "0",
+			cellSpacing: "0",
+			height: this.ganttChart.heightTaskItem + "px",
+			width: ((this.duration * this.ganttChart.pixelsPerWorkHour == 0) ? 1 : this.duration * this.ganttChart.pixelsPerWorkHour) + "px"
+		}, divTaskInfo);
+		var rowTaskInfo = tblTaskInfo.insertRow(0);
+		var cellTaskInfo = dojo.create("td", {
+			align: "center",
+			vAlign: "top",
+			height: this.ganttChart.heightTaskItem + "px",
+			className: "ganttMoveInfo"
+		}, rowTaskInfo);
+		projectItem.appendChild(divTaskInfo);
+		if(this.project.parentTasks.length == 0){
+			projectItem.style.display = "none";
+		}
+		return projectItem;
+	},
+	createProjectNameItem: function(){
+		var divName = dojo.create("div", {
+			className: "ganttProjectNameItem",
+			innerHTML: this.project.name,
+			title: this.project.name
+		});
+		dojo.style(divName, {
+			left: "5px",
+			top: this.posY + "px"
+		});
+		dojo.attr(divName, "tabIndex", 0);
+		if(this.ganttChart.isShowConMenu){
+			this.ganttChart._events.push(
+				dojo.connect(divName, "onmouseover", this, function(event){
+					dojo.addClass(divName, "ganttProjectNameItemHover");
+					clearTimeout(this.ganttChart.menuTimer);
+					this.ganttChart.tabMenu.clear();
+					this.ganttChart.tabMenu.show(event.target, this);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divName, "onkeydown", this, function(event){
+					if(event.keyCode == dojo.keys.ENTER){
+						this.ganttChart.tabMenu.clear();
+						this.ganttChart.tabMenu.show(event.target, this);
+					}
+					if(this.ganttChart.tabMenu.isShow && (event.keyCode == dojo.keys.LEFT_ARROW || event.keyCode == dojo.keys.RIGHT_ARROW)){
+						dijit.focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
+					}
+					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
+						this.ganttChart.tabMenu.hide();
+					}
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divName, "onmouseout", this, function(){
+					dojo.removeClass(divName, "ganttProjectNameItemHover");
+					clearTimeout(this.ganttChart.menuTimer);
+					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
+						this.ganttChart.tabMenu.hide();
+					}), 200);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseover", this, function(){
+					clearTimeout(this.ganttChart.menuTimer);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onkeydown", this, function(event){
+					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
+						this.ganttChart.tabMenu.hide();
+					}
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseout", this, function(){
+					clearTimeout(this.ganttChart.menuTimer);
+					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
+						this.ganttChart.tabMenu.hide();
+					}), 200);
+				})
+			);
+		}
+		return divName;
+	},
+	getPercentCompleted: function(){
+		var sum = 0, percentage = 0;
+		dojo.forEach(this.project.parentTasks, function(ppTask){
+			sum += parseInt(ppTask.percentage);
+		}, this);
+		if(this.project.parentTasks.length != 0){
+			return percentage = Math.round(sum / this.project.parentTasks.length);
+		}else{
+			return percentage = -1;
+		}
+	},
+	getDuration: function(){
+		var duration = 0, tmpDuration = 0;
+		if(this.project.parentTasks.length > 0){
+			dojo.forEach(this.project.parentTasks, function(ppTask){
+				tmpDuration = ppTask.duration * 24 / this.ganttChart.hsPerDay + (ppTask.startTime - this.ganttChart.startDate) / (60 * 60 * 1000);
+				if(tmpDuration > duration){
+					duration = tmpDuration;
+				}
+			}, this);
+			return ((duration - this.posX) / 24) * this.ganttChart.hsPerDay;
+		}else{
+			return 0;
+		}
+	},
+	deleteTask: function(id){
+		var task = this.getTaskById(id);
+		if(task){
+			this.deleteChildTask(task);
+			this.ganttChart.checkPosition();
+		}
+	},
+	setName: function(name){
+		if(name){
+			this.project.name = name;
+			this.projectNameItem.innerHTML = name;
+			this.projectNameItem.title = name;
+			this.checkWidthProjectNameItem();
+			
+			this.descrProject.innerHTML = this.getDescStr();
+			this.adjustPanelTime();
+		}
+	},
+	setPercentCompleted: function(percentage){
+		percentage = parseInt(percentage);
+		if(isNaN(percentage) || percentage > 100 || percentage < 0){
+			return false;
+		}
+		var prow = this.projectItem[0].firstChild.rows[0],
+			rc0 = prow.cells[0], rc1 = prow.cells[1];
+		if((percentage > 0) && (percentage < 100) && (this.percentage > 0) && (this.percentage < 100)){
+			rc0.width = parseInt(percentage) + "%";
+			rc0.firstChild.style.width = (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
+			rc1.width = (100 - parseInt(percentage)) + "%";
+			rc1.firstChild.style.width = ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px";
+		}else if(((percentage == 0) || (percentage == 100)) && (this.percentage > 0) && (this.percentage < 100)){
+			if(percentage == 0){
+				rc0.parentNode.removeChild(rc0);
+				rc1.width = 100 + "%";
+				rc1.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
+			}else if(percentage == 100){
+				rc1.parentNode.removeChild(rc1);
+				rc0.width = 100 + "%";
+				rc0.firstChild.style.width = this.duration * this.ganttChart.pixelsPerWorkHour + "px";
+			}
+		}else if(((percentage == 0) || (percentage == 100)) && ((this.percentage == 0) || (this.percentage == 100))){
+			if((percentage == 0) && (this.percentage == 100)){
+				dojo.removeClass(rc0.firstChild, "ganttImageProgressFilled");
+				dojo.addClass(rc0.firstChild, "ganttImageProgressBg");
+			}else if((percentage == 100) && (this.percentage == 0)){
+				dojo.removeClass(rc0.firstChild, "ganttImageProgressBg");
+				dojo.addClass(rc0.firstChild, "ganttImageProgressFilled");
+			}
+		}else if(((percentage > 0) || (percentage < 100)) && ((this.percentage == 0) || (this.percentage == 100))){
+			rc0.parentNode.removeChild(rc0);
+			var cellprojectItem = dojo.create("td", {
+				width: percentage + "%"
+			}, prow);
+			cellprojectItem.style.lineHeight = "1px";
+			var imageProgress = dojo.create("div", {
+				className: "ganttImageProgressFilled"
+			}, cellprojectItem);
+			dojo.style(imageProgress, {
+				width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+			cellprojectItem = dojo.create("td", {
+				width: (100 - percentage) + "%"
+			}, prow);
+			cellprojectItem.style.lineHeight = "1px";
+			imageProgress = dojo.create("div", {
+				className: "ganttImageProgressBg"
+			}, cellprojectItem);
+			dojo.style(imageProgress, {
+				width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}else if(this.percentage == -1){
+			if(percentage == 100){
+				dojo.removeClass(rc0.firstChild, "ganttImageProgressBg");
+				dojo.addClass(rc0.firstChild, "ganttImageProgressFilled");
+			}else if(percentage < 100 && percentage > 0){
+				rc0.parentNode.removeChild(rc0);
+				var cellprojectItem = dojo.create("td", {
+					width: percentage + "%"
+				}, prow);
+				cellprojectItem.style.lineHeight = "1px";
+				imageProgress = dojo.create("div", {
+					className: "ganttImageProgressFilled"
+				}, cellprojectItem);
+				dojo.style(imageProgress, {
+					width: (percentage * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+				cellprojectItem = dojo.create("td", {
+					width: (100 - percentage) + "%"
+				}, prow);
+				cellprojectItem.style.lineHeight = "1px";
+				imageProgress = dojo.create("div", {
+					className: "ganttImageProgressBg"
+				}, cellprojectItem);
+				dojo.style(imageProgress, {
+					width: ((100 - percentage) * this.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+		}
+		this.percentage = percentage;
+		this.descrProject.innerHTML = this.getDescStr();
+		return true;
+	},
+	deleteChildTask: function(task){
+		if(task){
+			var tItem0 = task.cTaskItem[0], tNameItem0 = task.cTaskNameItem[0],
+				tItem1 = task.cTaskItem[1], tNameItem1 = task.cTaskNameItem[1],
+				tItem2 = task.cTaskItem[2], tNameItem2 = task.cTaskNameItem[2];
+			if(tItem0.style.display == "none"){
+				this.ganttChart.openTree(task.parentTask);
+			}
+			//delete of connecting lines
+			if(task.childPredTask.length > 0){
+				for(var i = 0; i < task.childPredTask.length; i++){
+					var cpTask = task.childPredTask[i];
+					for(var t = 0; t < cpTask.cTaskItem[1].length; t++){
+						cpTask.cTaskItem[1][t].parentNode.removeChild(cpTask.cTaskItem[1][t]);
+					}
+					cpTask.cTaskItem[1] = [];
+					cpTask.predTask = null;
+				}
+			}
+			//delete child task
+			if(task.childTask.length > 0){
+				while(task.childTask.length > 0){
+					this.deleteChildTask(task.childTask[0]);
+				}
+			}
+			//shift tasks
+			var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			if(tItem0.style.display != "none"){
+				task.shiftCurrentTasks(task, -rowHeight);
+			}
+			//delete object task
+			this.project.deleteTask(task.taskItem.id);
+			//delete div and connecting lines from contentData
+			if(tItem0){
+				tItem0.parentNode.removeChild(tItem0);
+			}
+			task.descrTask.parentNode.removeChild(task.descrTask);
+			if(tItem1.length > 0){
+				for(var j = 0; j < tItem1.length; j++){
+					tItem1[j].parentNode.removeChild(tItem1[j]);
+				}
+			}
+			//delete div and connecting lines from panelName
+			if(tNameItem0){
+				tNameItem0.parentNode.removeChild(tNameItem0);
+			}
+			if(task.cTaskNameItem[1]){
+				for(var j = 0; j < tNameItem1.length; j++){
+					tNameItem1[j].parentNode.removeChild(tNameItem1[j]);
+				}
+			}
+			if(tNameItem2 && tNameItem2.parentNode){
+				tNameItem2.parentNode.removeChild(tNameItem2);
+			}
+			if(task.taskIdentifier){
+				task.taskIdentifier.parentNode.removeChild(task.taskIdentifier);
+				task.taskIdentifier = null;
+			}
+			//delete object task
+			if(task.parentTask){
+				if(task.previousChildTask){
+					if(task.nextChildTask){
+						task.previousChildTask.nextChildTask = task.nextChildTask;
+					}else{
+						task.previousChildTask.nextChildTask = null;
+					}
+				}
+				var parentTask = task.parentTask;
+				for(var i = 0; i < parentTask.childTask.length; i++){
+					if(parentTask.childTask[i].taskItem.id == task.taskItem.id){
+						parentTask.childTask[i] = null;
+						parentTask.childTask.splice(i, 1);
+						break;
+					}
+				}
+				if(parentTask.childTask.length == 0){
+					if(parentTask.cTaskNameItem[2]){
+						parentTask.cTaskNameItem[2].parentNode.removeChild(parentTask.cTaskNameItem[2]);
+						parentTask.cTaskNameItem[2] = null;
+					}
+				}
+			}else{
+				if(task.previousParentTask){
+					if(task.nextParentTask){
+						task.previousParentTask.nextParentTask = task.nextParentTask;
+					}else{
+						task.previousParentTask.nextParentTask = null;
+					}
+				}
+				var project = task.project;
+				for(var i = 0; i < project.arrTasks.length; i++){
+					if(project.arrTasks[i].taskItem.id == task.taskItem.id){
+						project.arrTasks.splice(i, 1);
+					}
+				}
+			}
+			if(task.predTask){
+				var predTask = task.predTask;
+				for(var i = 0; i < predTask.childPredTask.length; i++){
+					if(predTask.childPredTask[i].taskItem.id == task.taskItem.id){
+						predTask.childPredTask[i] = null;
+						predTask.childPredTask.splice(i, 1);
+					}
+				}
+			}
+			if(task.project.arrTasks.length != 0){
+				task.project.shiftProjectItem();
+			}else{
+				task.project.projectItem[0].style.display = "none";
+				this.hideDescrProject();
+			}
+			this.ganttChart.contentDataHeight -= this.ganttChart.heightTaskItemExtra + this.ganttChart.heightTaskItem;
+		}
+	},
+	
+	insertTask: function(id, name, startTime, duration, percentage, previousTaskId, taskOwner, parentTaskId){
+		var task = null;
+		var _task = null;
+		if(this.project.getTaskById(id)){
+			return false;
+		}
+		if((!duration) || (duration < this.ganttChart.minWorkLength)){
+			duration = this.ganttChart.minWorkLength;
+		}
+		if((!name) || (name == "")){
+			name = id;
+		}
+		if((!percentage) || (percentage == "")){
+			percentage = 0;
+			
+		}else{
+			percentage = parseInt(percentage);
+			if(percentage < 0 || percentage > 100){
+				return false;
+			}
+		}
+		var sortRequired = false;
+		if((parentTaskId) && (parentTaskId != "")){
+			var parentTask = this.project.getTaskById(parentTaskId);
+			if(!parentTask){
+				return false;
+			}
+			startTime = startTime || parentTask.startTime;
+			if(startTime < parentTask.startTime){
+				return false;
+			}
+			task = new dojox.gantt.GanttTaskItem({
+				id: id,
+				name: name,
+				startTime: startTime,
+				duration: duration,
+				percentage: percentage,
+				previousTaskId: previousTaskId,
+				taskOwner: taskOwner
+			});
+			if(!this.ganttChart.checkPosParentTask(parentTask, task)){
+				return false;
+			}
+			task.parentTask = parentTask;
+			var _parentTask = this.getTaskById(parentTask.id);
+			var isHide = false;
+			if(_parentTask.cTaskItem[0].style.display == "none"){
+				isHide = true;
+			}else if(_parentTask.cTaskNameItem[2]){
+				if(!_parentTask.isExpanded){
+					isHide = true;
+				}
+			}
+			if(isHide){
+				if(_parentTask.childTask.length == 0){
+					this.ganttChart.openTree(_parentTask.parentTask);
+				}else{
+					this.ganttChart.openTree(_parentTask);
+				}
+			}
+			if(previousTaskId != ""){
+				var predTask = this.project.getTaskById(previousTaskId);
+				if(!predTask){
+					return false;
+				}
+				if(predTask.parentTask){
+					if(predTask.parentTask.id != task.parentTask.id){
+						return false;
+					}
+				}else{
+					return false;
+				}
+				if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
+					this.ganttChart.correctPosPreviousTask(predTask, task);
+				}
+				task.previousTask = predTask;
+			}
+			var isAdd = false;
+			if(sortRequired) for(var i = 0; i < parentTask.cldTasks.length; i++){
+				if(task.startTime < parentTask.cldTasks[i].startTime){
+					parentTask.cldTasks.splice(i, 0, task);
+					if(i > 0){
+						parentTask.cldTasks[i - 1].nextChildTask = parentTask.cldTasks[i];
+						parentTask.cldTasks[i].previousChildTask = parentTask.cldTasks[i - 1];
+					}
+					if(parentTask.cldTasks[i + 1]){
+						parentTask.cldTasks[i + 1].previousChildTask = parentTask.cldTasks[i];
+						parentTask.cldTasks[i].nextChildTask = parentTask.cldTasks[i + 1];
+					}
+					isAdd = true;
+					break;
+				}
+			}
+			if(!isAdd){
+				if(parentTask.cldTasks.length > 0){
+					parentTask.cldTasks[parentTask.cldTasks.length - 1].nextChildTask = task;
+					task.previousChildTask = parentTask.cldTasks[parentTask.cldTasks.length - 1];
+				}
+				parentTask.cldTasks.push(task);
+			}
+			if(parentTask.cldTasks.length == 1){
+				var treeImg = _parentTask.createTreeImg();
+				_parentTask.cTaskNameItem[2] = treeImg;
+			}
+			_task = new dojox.gantt.GanttTaskControl(task, this, this.ganttChart);
+			_task.create();
+			if(task.nextChildTask) _task.nextChildTask = _task.project.getTaskById(task.nextChildTask.id);
+			_task.adjustPanelTime();
+			var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			_task.shiftCurrentTasks(_task, rowHeight);//23
+		}else{
+			startTime = startTime || this.project.startDate;
+			task = new dojox.gantt.GanttTaskItem({
+				id: id,
+				name: name,
+				startTime: startTime,
+				duration: duration,
+				percentage: percentage,
+				previousTaskId: previousTaskId,
+				taskOwner: taskOwner
+			});
+			if(task.startTime <= this.ganttChart.startDate){
+				return false;
+			}
+			if(previousTaskId != ""){
+				var predTask = this.project.getTaskById(previousTaskId);
+				if(!predTask){
+					return false;
+				}
+				if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
+					this.ganttChart.correctPosPreviousTask(predTask, task);
+				}
+				if(predTask.parentTask){
+					return false;
+				}
+				task.previousTask = predTask;
+			}
+			var isAdd = false;
+			if(sortRequired){
+				for(var i = 0; i < this.project.parentTasks.length; i++){
+					var ppTask = this.project.parentTasks[i];
+					if(startTime < ppTask.startTime){
+						this.project.parentTasks.splice(i, 0, task);
+						if(i > 0){
+							this.project.parentTasks[i - 1].nextParentTask = task;
+							task.previousParentTask = this.project.parentTasks[i - 1];
+						}
+						if(this.project.parentTasks[i + 1]){
+							this.project.parentTasks[i + 1].previousParentTask = task;
+							task.nextParentTask = this.project.parentTasks[i + 1];
+						}
+						isAdd = true;
+						break;
+					}
+				}
+			}
+			if(!isAdd){
+				if(this.project.parentTasks.length > 0){
+					this.project.parentTasks[this.project.parentTasks.length - 1].nextParentTask = task;
+					task.previousParentTask = this.project.parentTasks[this.project.parentTasks.length - 1];
+				}
+				this.project.parentTasks.push(task);
+			}
+			_task = new dojox.gantt.GanttTaskControl(task, this, this.ganttChart);
+			_task.create();
+			if(task.nextParentTask) _task.nextParentTask = _task.project.getTaskById(task.nextParentTask.id);
+			_task.adjustPanelTime();
+			this.arrTasks.push(_task);
+			var rowHeight = this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			_task.shiftCurrentTasks(_task, rowHeight);
+			this.projectItem[0].style.display = "inline";
+			this.setPercentCompleted(this.getPercentCompleted());
+			this.shiftProjectItem();
+			this.showDescrProject();
+		}
+		this.ganttChart.checkHeighPanelTasks();
+		this.ganttChart.checkPosition();
+		return _task;
+	},
+	shiftNextProject: function(project, height){
+		if(project.nextProject){
+			project.nextProject.shiftProject(height);
+			this.shiftNextProject(project.nextProject, height);
+		}
+	},
+	shiftProject: function(height){
+		this.posY = this.posY + height;
+		this.projectItem[0].style.top = parseInt(this.projectItem[0].style.top) + height + "px";
+		this.descrProject.style.top = parseInt(this.descrProject.style.top) + height + "px";
+		this.projectNameItem.style.top = parseInt(this.projectNameItem.style.top) + height + "px";
+		if(this.arrTasks.length > 0){
+			this.shiftNextParentTask(this.arrTasks[0], height);
+		}
+	},
+	shiftTask: function(task, height){
+		task.posY = task.posY + height;
+		var tNameItem0 = task.cTaskNameItem[0], tNameItem1 = task.cTaskNameItem[1], tNameItem2 = task.cTaskNameItem[2],
+			tItem0 = task.cTaskItem[0], tItem1 = task.cTaskItem[1], tItem2 = task.cTaskItem[2];
+		tNameItem0.style.top = parseInt(tNameItem0.style.top) + height + "px";
+		if(tNameItem2){
+			tNameItem2.style.top = parseInt(tNameItem2.style.top) + height + "px";
+		}
+		if(task.parentTask){
+			tNameItem1[0].style.top = parseInt(tNameItem1[0].style.top) + height + "px";
+			tNameItem1[1].style.top = parseInt(tNameItem1[1].style.top) + height + "px";
+		}
+		task.cTaskItem[0].style.top = parseInt(task.cTaskItem[0].style.top) + height + "px";
+		task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
+		if(tItem1[0]){
+			tItem1[0].style.top = parseInt(tItem1[0].style.top) + height + "px";
+			tItem1[1].style.top = parseInt(tItem1[1].style.top) + height + "px";
+			tItem1[2].style.top = parseInt(tItem1[2].style.top) + height + "px";
+		}
+	},
+	shiftNextParentTask: function(task, height){
+		this.shiftTask(task, height);
+		this.shiftChildTasks(task, height);
+		if(task.nextParentTask){
+			this.shiftNextParentTask(task.nextParentTask, height);
+		}
+	},
+	shiftChildTasks: function(task, height){
+		dojo.forEach(task.childTask, function(cTask){
+			this.shiftTask(cTask, height);
+			if(cTask.childTask.length > 0){
+				this.shiftChildTasks(cTask, height);
+			}
+		}, this);
+	}
+});
+
+
+dojo.declare("dojox.gantt.GanttProjectItem", null, {
+	constructor: function(configuration){
+		//id is required
+		this.id = configuration.id;
+		this.name = configuration.name || this.id;
+		this.startDate = configuration.startDate || new Date();
+		this.parentTasks = [];
+	},
+	getTaskById: function(id){
+		for(var i = 0; i < this.parentTasks.length; i++){
+			var pTask = this.parentTasks[i];
+			var task = this.getTaskByIdInTree(pTask, id);
+			if(task){
+				return task;
+			}
+		}
+		return null;
+	},
+	getTaskByIdInTree: function(parentTask, id){
+		if(parentTask.id == id){
+			return parentTask;
+		}else{
+			for(var i = 0; i < parentTask.cldTasks.length; i++){
+				var pcTask = parentTask.cldTasks[i];
+				if(pcTask.id == id){
+					return pcTask;
+				}
+				if(pcTask.cldTasks.length > 0){
+					if(pcTask.cldTasks.length > 0){
+						var cTask = this.getTaskByIdInTree(pcTask, id);
+						if(cTask){
+							return cTask;
+						}
+					}
+				}
+			}
+		}
+		return null;
+	},
+	addTask: function(task){
+		this.parentTasks.push(task);
+		task.setProject(this);
+	},
+	deleteTask: function(id){
+		var task = this.getTaskById(id);
+		if(!task){return;}
+		if(!task.parentTask){
+			for(var i = 0; i < this.parentTasks.length; i++){
+				var pTask = this.parentTasks[i];
+				if(pTask.id == id){
+					if(pTask.nextParentTask){
+						if(pTask.previousParentTask){
+							pTask.previousParentTask.nextParentTask = pTask.nextParentTask;
+							pTask.nextParentTask.previousParentTask = pTask.previousParentTask;
+						}else{
+							pTask.nextParentTask.previousParentTask = null;
+						}
+					}else{
+						if(pTask.previousParentTask){
+							pTask.previousParentTask.nextParentTask = null;
+						}
+					}
+					pTask = null;
+					this.parentTasks.splice(i, 1);
+					break;
+				}
+			}
+		}else{
+			var parentTask = task.parentTask;
+			for(var i = 0; i < parentTask.cldTasks.length; i++){
+				var pcTask = parentTask.cldTasks[i];
+				if(pcTask.id == id){
+					if(pcTask.nextChildTask){
+						if(pcTask.previousChildTask){
+							pcTask.previousChildTask.nextChildTask = pcTask.nextChildTask;
+							pcTask.nextChildTask.previousChildTask = pcTask.previousChildTask;
+						}else{
+							pcTask.nextChildTask.previousChildTask = null;
+						}
+					}else{
+						if(pcTask.previousChildTask){
+							pcTask.previousChildTask.nextChildTask = null;
+						}
+					}
+					pcTask = null;
+					parentTask.cldTasks.splice(i, 1);
+					break;
+				}
+			}
+		}
+	}
+});
diff --git a/dojox/gantt/GanttResourceItem.js b/dojox/gantt/GanttResourceItem.js
new file mode 100644
index 0000000..937f33b
--- /dev/null
+++ b/dojox/gantt/GanttResourceItem.js
@@ -0,0 +1,456 @@
+dojo.provide("dojox.gantt.GanttResourceItem");
+
+dojo.require("dojo.date.locale");
+
+dojo.declare("dojox.gantt.GanttResourceItem", null, {
+	constructor: function(ganttchart){
+		this.ganttChart = ganttchart;
+		this.ownerItem = [];
+		this.ownerNameItem = [];
+		this.ownerTaskNodeMapping = {};
+		this.ownerTaskNodeMapping_time = {};
+		this.resourceInfo = {};
+		this.ownerTimeConsume = {};
+	},
+	clearAll: function(){
+		this.clearData();
+		this.clearItems();
+	},
+	clearData: function(){
+		this.ownerItem = [];
+		this.ownerNameItem = [];
+		this.ownerTaskNodeMapping = {};
+		this.ownerTaskNodeMapping_time = {};
+		this.resourceInfo = {};
+		this.ownerTimeConsume = {};
+	},
+	clearItems: function(){
+		dojo.destroy(this.content.firstChild);
+	},
+	buildResource: function(){
+		var resourceInfo = {};
+		dojo.forEach(this.ganttChart.arrProjects, function(project){
+			dojo.forEach(project.arrTasks, function(task){
+				task.buildResourceInfo(resourceInfo);
+			}, this);
+		}, this);
+		return resourceInfo;
+	},
+	buildOwnerTimeConsume: function(){
+		var ownerTimeConsume = {};
+		for(var owner in this.resourceInfo){
+			var tasks = this.resourceInfo[owner];
+			//combine time zone  (startTime - this.startDate) / (60 * 60 * 1000) * this.pixelsPerHour;
+			var timeZoom = {};
+			for(var i = 0; i < tasks.length; i++){
+				var task = tasks[i];
+				var startTime = task.taskItem.startTime.getTime(), dur = task.taskItem.duration * 24 * 60 * 60 * 1000 / this.ganttChart.hsPerDay;
+				timeZoom.min = timeZoom.min ? Math.min(timeZoom.min, startTime) : startTime;
+				timeZoom.max = timeZoom.max ? Math.max(timeZoom.max, (startTime + dur)) : (startTime + dur);
+			}
+			timeZoom.dur = (timeZoom.max - timeZoom.min) * this.ganttChart.hsPerDay / (24 * 60 * 60 * 1000);
+			timeZoom.min = new Date(timeZoom.min);
+			timeZoom.max = new Date(timeZoom.max);
+			ownerTimeConsume[owner] = timeZoom;
+		}
+		return ownerTimeConsume;
+	},
+	refresh: function(){
+		this.ownerTimeConsume = this.buildOwnerTimeConsume();
+		//resize outer div
+		this.contentData.firstChild.style.width = Math.max(1200, this.ganttChart.pixelsPerDay * this.ganttChart.totalDays) + "px";
+		for(var owner in this.resourceInfo){
+			this.refreshOwnerEntry(owner);
+		}
+	},
+	reConstruct: function(){
+		this.clearAll();
+		this.resourceInfo = this.buildResource();
+		this.ownerTimeConsume = this.buildOwnerTimeConsume();
+		this.tableControl = dojo.create("table", {
+			cellPadding: "0",
+			cellSpacing: "0",
+			className: "ganttResourceTableControl"
+		});
+		var newRowTblControl = this.tableControl.insertRow(this.tableControl.rows.length);
+		//Add to content Table
+		this.contentHeight = this.content.offsetHeight;
+		this.contentWidth = this.content.offsetWidth;
+		this.content.appendChild(this.tableControl);
+		//Creation panel contentData
+		this.contentData = dojo.create("div", {className: "ganttResourceContentDataContainer"});
+		this.contentData.appendChild(this.createPanelOwners());
+		dojo.style(this.contentData, "height", (this.contentHeight - this.ganttChart.panelTimeHeight) + "px");
+		//Creation panel of names
+		var newCellTblControl = dojo.create("td", {
+			vAlign: "top"
+		});
+		this.panelNames = dojo.create("div", {className: "ganttResourcePanelNames"});
+		this.panelNames.appendChild(this.createPanelNamesOwners());
+		newCellTblControl.appendChild(this.panelNames);
+		newRowTblControl.appendChild(newCellTblControl);
+		//add to control contentData and contentDataTime
+		newCellTblControl = dojo.create("td", {
+			vAlign: "top"
+		});
+		var divCell = dojo.create("div", {className: "ganttResourceDivCell"});
+		divCell.appendChild(this.contentData);
+		newCellTblControl.appendChild(divCell);
+		newRowTblControl.appendChild(newCellTblControl);
+		//Show panel of names
+		dojo.style(this.panelNames, {
+			height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
+			width: this.ganttChart.maxWidthPanelNames + "px"
+		});
+		this.contentData.style.width = (this.contentWidth - this.ganttChart.maxWidthPanelNames) + "px";
+		this.contentData.firstChild.style.width = this.ganttChart.pixelsPerDay * (this.ganttChart.panelTime.firstChild.firstChild.rows[3].cells.length) + "px";
+		var _this = this;
+		this.contentData.onscroll = function(){
+			if(_this.panelNames){
+				_this.panelNames.scrollTop = this.scrollTop;
+			}
+		}
+		this.contentData.scrollLeft = this.ganttChart.contentData.scrollLeft;
+		for(var owner in this.resourceInfo){
+			this.createOwnerEntry(owner);
+		}
+		this.postAdjustment();
+	},
+	create: function(){
+		var resourceHeader = dojo.create("div", {
+			innerHTML: "Resource Chart:",
+			className: "ganttResourceHeader"
+		}, this.ganttChart.content, "after");
+		dojo.style(resourceHeader, "width", this.ganttChart.contentWidth + "px");
+		var content = dojo.create("div", {className: "ganttResourceContent"}, resourceHeader, "after");
+		dojo.style(content, {
+			width: this.ganttChart.contentWidth + "px",
+			height: (this.ganttChart.resourceChartHeight || (this.ganttChart.contentHeight * 0.8)) + "px"
+		});
+		this.content = content || this.content;
+		//create Table
+		this.reConstruct();
+	},
+	postAdjustment: function(){
+		//contentData height
+		this.contentData.firstChild.style.height = (this.ownerItem.length * 23) + "px";
+		this.panelNames.firstChild.style.height = (this.ownerItem.length * 23) + "px";
+	},
+	
+	refreshOwnerEntry: function(owner){
+		this.refreshOwnerItem(owner);
+		dojo.forEach(this.resourceInfo[owner], function(task, i){
+			var item = this.ownerTaskNodeMapping[owner].tasks[i][0];
+			this.refreshDetailedTaskEntry(owner, item, task);
+		}, this);
+	},
+	createOwnerEntry: function(owner){
+		var containerOwner = this.contentData.firstChild;
+		var previousOwner = this.ownerItem[this.ownerItem.length - 1];
+		this.ownerTaskNodeMapping[owner] = {};
+		this.ownerTaskNodeMapping[owner][owner] = [];
+		//create nodes
+		var pos = dojo.position(containerOwner);
+		//creation arrTasks
+		var posY = (previousOwner ? parseInt(previousOwner.style.top) : (6 - 23)) + this.ganttChart.heightTaskItem + 11;
+		//creation task item
+		var oItem = this.createOwnerItem(owner, posY);
+		containerOwner.appendChild(oItem);
+		this.ownerItem.push(oItem);
+		this.ownerTaskNodeMapping[owner][owner].push(oItem);
+		if(this.panelNames){
+			var oNameItem = this.createOwnerNameItem(owner, posY);
+			this.panelNames.firstChild.appendChild(oNameItem);
+			this.ownerNameItem.push(oNameItem);
+			this.ownerTaskNodeMapping[owner][owner].push(oNameItem);
+		}
+		var currentOwnerNode = this.ownerItem[this.ownerNameItem.length - 1];
+		var currentOwnerNameNode = this.ownerNameItem[this.ownerNameItem.length - 1];
+		//adjust nodes
+		if(this.panelNames){
+			this.checkWidthTaskNameItem(currentOwnerNameNode);
+			var treeImg = this.createTreeImg(currentOwnerNameNode);
+			this.panelNames.firstChild.appendChild(treeImg);
+			this.ownerTaskNodeMapping[owner][owner].push(treeImg);
+		}
+		this.ownerTaskNodeMapping[owner]["taskCount"] = this.resourceInfo[owner].length;
+		this.ownerTaskNodeMapping[owner]["isOpen"] = false;
+		this.ownerTaskNodeMapping[owner]["tasks"] = [];
+		dojo.forEach(this.resourceInfo[owner], function(task){
+			this.ownerTaskNodeMapping[owner]["tasks"].push(this.createDetailedTaskEntry(owner, currentOwnerNameNode, task));
+		}, this);
+		return this;
+	},
+	createOwnerNameItem: function(owner, posY){
+		var ownerName = dojo.create("div", {
+			id: owner,
+			title: owner,
+			innerHTML: owner,
+			className: "ganttOwnerNameItem"
+		});
+		dojo.style(ownerName, "top", posY + "px");
+		return ownerName;
+	},
+	refreshOwnerItem: function(owner){
+		var item = this.ownerTaskNodeMapping[owner][owner][0];
+		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
+		item.style.left = posX + "px";
+		item.style.width = dur * this.ganttChart.pixelsPerWorkHour + "px";
+		dojo.forEach(this.resourceInfo[owner], function(task, i){
+			var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+			dojo.style(item.childNodes[i], {
+				left: (tposX - posX) + "px",
+				width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+			});
+		}, this);
+	},
+	createOwnerItem: function(owner, posY){
+		var start = this.ownerTimeConsume[owner].min, end = this.ownerTimeConsume[owner].max, dur = this.ownerTimeConsume[owner].dur;
+		var posX = this.ganttChart.getPosOnDate(start); // should be task start date
+		var ownerControl = dojo.create("div", {
+			id: owner,
+			owner: true,
+			className: "ganttOwnerBar"
+		});
+		dojo.style(ownerControl, {
+			left: posX + "px",
+			top: posY + "px",
+			width: dur * this.ganttChart.pixelsPerWorkHour + "px",
+			height: this.ganttChart.heightTaskItem + "px"
+		});
+		dojo.forEach(this.resourceInfo[owner], function(task){
+			var ownerTaskItem = dojo.create("div", {
+				id: owner,
+				className: "ganttOwnerTaskBar"
+			}, ownerControl);
+			var tposX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+			dojo.style(ownerTaskItem, {
+				left: (tposX - posX) + "px",
+				width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px", // should be task duration
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}, this);
+		return ownerControl;
+	},
+	refreshDetailedTaskEntry: function(owner, item, task){
+		this.refreshTaskItem(item, task);
+	},
+	createDetailedTaskEntry: function(owner, parentNode, task){
+		var taskItems = [];
+		var containerTasks = this.contentData.firstChild;
+		var posY = parseInt(parentNode.style.top);
+		
+		//creation task item
+		var taskItem = this.createTaskItem(task, posY);
+		taskItem.style.display = "none";
+		containerTasks.appendChild(taskItem);
+		this.ownerItem.push(taskItem);
+		taskItems.push(taskItem);
+		if(this.panelNames){
+			var taskNameItem = this.createTaskNameItem(task.taskItem.name, posY);
+			this.panelNames.firstChild.appendChild(taskNameItem);
+			taskNameItem.style.display = "none";
+			this.ownerNameItem.push(taskNameItem);
+			taskItems.push(taskNameItem);
+		}
+		if(this.panelNames){
+			this.ownerNameItem[this.ownerNameItem.length - 1].style.left = dojo.style(parentNode, "left") + 15 + "px";
+			var arrConnectingLinesNames = this.createConnectingLinesPN(parentNode, this.ownerNameItem[this.ownerNameItem.length - 1]);
+			dojo.forEach(arrConnectingLinesNames, function(lineName){
+				lineName.style.display = "none";
+			}, this);
+			taskItems.push({
+				"v": arrConnectingLinesNames[0],
+				"h": arrConnectingLinesNames[1]
+			});
+			this.checkWidthTaskNameItem(this.ownerNameItem[this.ownerNameItem.length - 1]);
+		}
+		return taskItems;
+	},
+	createTaskNameItem: function(owner, posY){
+		var taskNameItem = dojo.create("div", {
+			id: owner,
+			className: "ganttTaskNameItem",
+			title: owner,
+			innerHTML: owner
+		});
+		dojo.style(taskNameItem, "top", posY + "px");
+		return taskNameItem;
+	},
+	refreshTaskItem: function(item, task){
+		var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+		dojo.style(item, {
+			left: posX + "px",
+			width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+		});
+	},
+	createTaskItem: function(task, posY){
+		var posX = this.ganttChart.getPosOnDate(task.taskItem.startTime); // should be task start date
+		var itemControl = dojo.create("div", {
+			id: task.taskItem.name,
+			className: "ganttTaskBar"
+		});
+		dojo.style(itemControl, {
+			left: posX + "px",
+			top: posY + "px",
+			width: task.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
+			height: this.ganttChart.heightTaskItem + "px"
+		});
+		return itemControl;
+	},
+	createConnectingLinesPN: function(parentNode, currentNode){
+		var arrConnectingLinesNames = [];
+		var lineVerticalLeft = dojo.create("div", {
+			innerHTML: " ",
+			className: "ganttResourceLineVerticalLeft"
+		}, this.panelNames.firstChild);
+		lineVerticalLeft.cNode = currentNode;
+		lineVerticalLeft.pNode = parentNode;
+		var LineHorizontalLeft = dojo.create("div", {
+			noShade: true,
+			color: "#000000",
+			className: "ganttResourceLineHorizontalLeft"
+		}, this.panelNames.firstChild);
+		LineHorizontalLeft.cNode = currentNode;
+		LineHorizontalLeft.pNode = parentNode;
+		this.panelNames.firstChild.appendChild(LineHorizontalLeft);
+		arrConnectingLinesNames.push(lineVerticalLeft);
+		arrConnectingLinesNames.push(LineHorizontalLeft);
+		return arrConnectingLinesNames;
+	},
+	createTreeImg: function(ownerNameItem){
+		var treeImg = dojo.create("div", {
+			id: ownerNameItem.id,
+			className: "ganttImageTreeExpand"
+		});
+		dojo.attr(treeImg, "tabIndex", 0);
+		var currentItem = this.ownerTaskNodeMapping[ownerNameItem.id];
+		dojo.forEach(["onclick", "onkeydown"], function(e){
+			this.ganttChart._events.push(
+				dojo.connect(treeImg, e, this, function(evt){
+					if(e == "onkeydown" && evt.keyCode != dojo.keys.ENTER){ return; }
+					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];
+							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;
+									dojo.forEach(ownerItem.tasks, function(tItems, i){
+										dojo.forEach(tItems, function(tItem){
+											this.styleOwnerItem(tItem, ownerItem[owner][0], "none", 0);
+										}, this);
+									}, this);
+								}
+							}
+						}
+					}else{
+						dojo.removeClass(treeImg, "ganttImageTreeExpand");
+						dojo.addClass(treeImg, "ganttImageTreeCollapse");
+						currentItem.isOpen = true;
+						//expand
+						var reachTarget = false;
+						for(var owner in this.ownerTaskNodeMapping){
+							var 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;
+									dojo.forEach(ownerItem.tasks, function(tItems, i){
+										dojo.forEach(tItems, function(tItem){
+											this.styleOwnerItem(tItem, ownerItem[owner][0], "inline", (i + 1) * 23);
+										}, this);
+									}, this);
+								}
+							}
+						}
+					}
+				})
+			);
+		}, this);
+		dojo.addClass(treeImg, "ganttResourceTreeImage");
+		dojo.style(treeImg, {
+			left: (dojo.style(ownerNameItem, "left") - 12) + "px",
+			top: (dojo.style(ownerNameItem, "top") + 3) + "px"
+		});
+		return treeImg;
+	},
+	styleOwnerItem: function(tItem, owner, displayType, topOffset){
+		if(tItem.v || tItem.h){
+			dojo.style(tItem.v, {
+				height: Math.max(1, (tItem.v.cNode.offsetTop - tItem.v.pNode.offsetTop)) + "px",
+				top: (tItem.v.pNode.offsetTop + 5) + "px",
+				left: (tItem.v.pNode.offsetLeft - 9) + "px",
+				display: displayType
+			});
+			dojo.style(tItem.h, {
+				width: Math.max(1, (tItem.h.cNode.offsetLeft - tItem.h.pNode.offsetLeft + 4)) + "px",
+				top: (tItem.h.cNode.offsetTop + 5) + "px",
+				left: (tItem.h.pNode.offsetLeft - 9) + "px",
+				display: displayType
+			});
+		}else{
+			dojo.style(tItem, {
+				display: displayType,
+				top: parseInt(owner.style.top) + topOffset + "px"
+			});
+		}
+	},
+	checkWidthTaskNameItem: function(taskNameItem){
+		if(taskNameItem && taskNameItem.offsetWidth + taskNameItem.offsetLeft > this.ganttChart.maxWidthPanelNames){
+			var width = taskNameItem.offsetWidth + taskNameItem.offsetLeft - this.ganttChart.maxWidthPanelNames;
+			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;
+		}
+	},
+	createPanelOwners: function(){
+		var panelOwner = dojo.create("div", {
+			className: "ganttOwnerPanel"
+		});
+		dojo.style(panelOwner, {
+			height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px"
+		});
+		return panelOwner;
+	},
+	createPanelNamesOwners: function(){
+		var panelNameOwner = dojo.create("div", {
+			innerHTML: " ",
+			className: "ganttResourcePanelNamesOwners"
+		});
+		dojo.style(panelNameOwner, {
+			height: (this.contentHeight - this.ganttChart.panelTimeHeight - this.ganttChart.scrollBarWidth) + "px",
+			width: this.ganttChart.maxWidthPanelNames + "px"
+		});
+		return panelNameOwner;
+	}
+});
diff --git a/dojox/gantt/GanttTaskItem.js b/dojox/gantt/GanttTaskItem.js
new file mode 100644
index 0000000..c792e01
--- /dev/null
+++ b/dojox/gantt/GanttTaskItem.js
@@ -0,0 +1,1357 @@
+dojo.provide("dojox.gantt.GanttTaskItem");
+
+dojo.require("dojo.date.locale");
+
+dojo.declare("dojox.gantt.GanttTaskControl", null, {
+	constructor: function(taskInfo, project, chart){
+		this.ganttChart = chart;
+		this.project = project;
+		this.taskItem = taskInfo;
+		//control variables
+		this.checkMove = false;
+		this.checkResize = false;
+		this.moveChild = false;
+		this.maxPosXMove = -1;
+		this.minPosXMove = -1;
+		this.maxWidthResize = -1;
+		this.minWidthResize = -1;
+		this.posX = 0;
+		this.posY = 0;
+		this.mouseX = 0;
+		this.taskItemWidth = 0;
+		this.isHide = false;
+		this.hideTasksHeight = 0;
+		this.isExpanded = true;
+		this.descrTask = null;
+		this.cTaskItem = null;
+		this.cTaskNameItem = null;
+		this.parentTask = null;
+		this.predTask = null;
+		this.childTask = [];
+		this.childPredTask = [];
+		this.nextChildTask = null;
+		this.previousChildTask = null;
+		this.nextParentTask = null;
+		this.previousParentTask = null;
+	},
+	createConnectingLinesPN: function(){
+		var arrConnectingLinesNames = [];
+		var lineVerticalLeft = dojo.create("div", {
+			innerHTML: " ",
+			className: "ganttTaskLineVerticalLeft"
+		}, this.ganttChart.panelNames.firstChild);
+		var cTaskName = this.cTaskNameItem[0], pcTaskName = this.parentTask.cTaskNameItem[0];
+		dojo.style(lineVerticalLeft, {
+			height: (cTaskName.offsetTop - pcTaskName.offsetTop) + "px",
+			top: (pcTaskName.offsetTop + 5) + "px",
+			left: (pcTaskName.offsetLeft - 9) + "px"
+		});
+		var LineHorizontalLeft = dojo.create("div", {
+			noShade: true,
+			color: "#000000",
+			className: "ganttTaskLineHorizontalLeft"
+		}, this.ganttChart.panelNames.firstChild);
+		dojo.style(LineHorizontalLeft, {
+			left: (pcTaskName.offsetLeft - 9) + "px",
+			top: (cTaskName.offsetTop + 5) + "px",
+			height: "1px",
+			width: (cTaskName.offsetLeft - pcTaskName.offsetLeft + 4) + "px"
+		});
+		arrConnectingLinesNames.push(lineVerticalLeft);
+		arrConnectingLinesNames.push(LineHorizontalLeft);
+		return arrConnectingLinesNames;
+	},
+	createConnectingLinesDS: function(){
+		var contentData = this.ganttChart.contentData.firstChild;
+		var arrLines = [];
+		var arrowImg = new Image();
+		var arrowImg = dojo.create("div", {
+			className: "ganttImageArrow"
+		});
+		//vertical line
+		var lineVerticalRight = document.createElement("div");
+		//horizontal line
+		var lineHorizontal = document.createElement("div");
+		var posXPreviousTask = dojo.style(this.predTask.cTaskItem[0], "left");
+		var posYPreviousTask = dojo.style(this.predTask.cTaskItem[0], "top");
+		var posXChildTask = dojo.style(this.cTaskItem[0], "left");
+		var posYChildTask = this.posY + 2;
+		//width task item
+		var widthChildTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
+		var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
+		if(posYPreviousTask < posYChildTask){
+			dojo.addClass(lineVerticalRight, "ganttTaskLineVerticalRight");
+			dojo.style(lineVerticalRight, {
+				height: (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
+				width: "1px",
+				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+				top: (posYPreviousTask + this.ganttChart.heightTaskItem) + "px"
+			});
+			dojo.addClass(lineHorizontal, "ganttTaskLineHorizontal");
+			dojo.style(lineHorizontal, {
+				width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+				top: (posYChildTask + 2) + "px"
+			});
+			dojo.addClass(arrowImg, "ganttTaskArrowImg");
+			dojo.style(arrowImg, {
+				left: (posXChildTask - 7) + "px",
+				top: (posYChildTask - 1) + "px"
+			});
+		}else{
+			dojo.addClass(lineVerticalRight, "ganttTaskLineVerticalRightPlus");
+			dojo.style(lineVerticalRight, {
+				height: (posYPreviousTask + 2 - posYChildTask) + "px",
+				width: "1px",
+				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+				top: (posYChildTask + 2) + "px"
+			});
+			dojo.addClass(lineHorizontal, "ganttTaskLineHorizontalPlus");
+			dojo.style(lineHorizontal, {
+				width: (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+				left: (posXPreviousTask + widthPreviousTask - 20) + "px",
+				top: (posYChildTask + 2) + "px"
+			});
+			dojo.addClass(arrowImg, "ganttTaskArrowImgPlus");
+			dojo.style(arrowImg, {
+				left: (posXChildTask - 7) + "px",
+				top: (posYChildTask - 1) + "px"
+			});
+		}
+		contentData.appendChild(lineVerticalRight);
+		contentData.appendChild(lineHorizontal);
+		contentData.appendChild(arrowImg);
+		arrLines.push(lineVerticalRight);
+		arrLines.push(arrowImg);
+		arrLines.push(lineHorizontal);
+		return arrLines;
+	},
+	showChildTasks: function(task, isOpen){
+		if(isOpen){
+			for(var i = 0; i < task.childTask.length; i++){
+				var cTask = task.childTask[i],
+					cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
+					cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
+					cTaskItem2 = cTask.cTaskItem[2], cTaskName2 = cTask.cTaskNameItem[2];
+				if(cTaskItem0.style.display == "none"){
+					cTaskItem0.style.display = "inline";
+					cTaskName0.style.display = "inline";
+					cTask.showDescTask();
+					task.isHide = false;
+					if(cTaskName2){
+						cTaskName2.style.display = "inline";
+						isOpen = cTask.isExpanded;
+					}
+					for(var k = 0; k < cTaskItem1.length; k++){
+						cTaskItem1[k].style.display = "inline";
+					}
+					for(var k = 0; k < cTaskName1.length; k++){
+						cTaskName1[k].style.display = "inline";
+					}
+					(cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "inline");
+					this.hideTasksHeight += this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+					if(cTask.childTask.length > 0){
+						this.showChildTasks(cTask, isOpen);
+					}
+				}
+			}
+		}
+	},
+	hideChildTasks: function(task){
+		for(var i = 0; i < task.childTask.length; i++){
+			var cTask = task.childTask[i],
+				cTaskItem0 = cTask.cTaskItem[0], cTaskName0 = cTask.cTaskNameItem[0],
+				cTaskItem1 = cTask.cTaskItem[1], cTaskName1 = cTask.cTaskNameItem[1],
+				cTaskItem2 = cTask.cTaskItem[2], cTaskName2 = cTask.cTaskNameItem[2];
+			if(cTaskItem0.style.display != "none"){
+				cTaskItem0.style.display = "none";
+				cTaskName0.style.display = "none";
+				cTask.hideDescTask();
+				task.isHide = true;
+				if(cTaskName2){
+					cTaskName2.style.display = "none";
+				}
+				for(var k = 0; k < cTaskItem1.length; k++){
+					cTaskItem1[k].style.display = "none";
+				}
+				for(var k = 0; k < cTaskName1.length; k++){
+					cTaskName1[k].style.display = "none";
+				}
+				(cTask.taskIdentifier) && (cTask.taskIdentifier.style.display = "none");
+				this.hideTasksHeight += (this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra);
+				if(cTask.childTask.length > 0){
+					this.hideChildTasks(cTask);
+				}
+			}
+		}
+	},
+	shiftCurrentTasks: function(task, height){
+		this.shiftNextTask(this, height);
+		task.project.shiftNextProject(task.project, height);
+	},
+	shiftTask: function(task, height){
+		task.posY = task.posY + height;
+		var taskItem0 = task.cTaskItem[0], taskName0 = task.cTaskNameItem[0],
+			taskItem1 = task.cTaskItem[1], taskName1 = task.cTaskNameItem[1],
+			taskItem2 = task.cTaskItem[2], taskName2 = task.cTaskNameItem[2];
+		taskName0.style.top = parseInt(taskName0.style.top) + height + "px";
+		if(taskName2){
+			taskName2.style.top = parseInt(taskName2.style.top) + height + "px";
+		}
+		if(task.parentTask){
+			if(parseInt(this.cTaskNameItem[0].style.top) > parseInt(task.parentTask.cTaskNameItem[0].style.top) &&
+			(taskName1[0].style.display != "none")){
+				taskName1[0].style.height = parseInt(taskName1[0].style.height) + height + "px";
+			}else{
+				taskName1[0].style.top = parseInt(taskName1[0].style.top) + height + "px";
+			}
+			taskName1[1].style.top = parseInt(taskName1[1].style.top) + height + "px";
+		}
+		taskItem0.style.top = parseInt(taskItem0.style.top) + height + "px";
+		task.descrTask.style.top = parseInt(task.descrTask.style.top) + height + "px";
+		if(task.predTask){
+			if(((parseInt(this.cTaskItem[0].style.top) > parseInt(task.predTask.cTaskItem[0].style.top)) ||
+			(this.cTaskItem[0].id == task.predTask.taskItem.id)) &&
+			taskItem1[0].style.display != "none"){
+				taskItem1[0].style.height = parseInt(taskItem1[0].style.height) + height + "px";
+			}else{
+				taskItem1[0].style.top = parseInt(taskItem1[0].style.top) + height + "px";
+			}
+			taskItem1[1].style.top = parseInt(taskItem1[1].style.top) + height + "px";
+			taskItem1[2].style.top = parseInt(taskItem1[2].style.top) + height + "px";
+		}
+	},
+	shiftNextTask: function(task, height){
+		if(task.nextChildTask){
+			this.shiftTask(task.nextChildTask, height);
+			this.shiftChildTask(task.nextChildTask, height);
+			this.shiftNextTask(task.nextChildTask, height);
+		}else if(task.parentTask){
+			this.shiftNextTask(task.parentTask, height);
+		}else if(task.nextParentTask){
+			this.shiftTask(task.nextParentTask, height);
+			this.shiftChildTask(task.nextParentTask, height);
+			this.shiftNextTask(task.nextParentTask, height);
+		}
+	},
+	shiftChildTask: function(task, height){
+		dojo.forEach(task.childTask, function(cTask){
+			this.shiftTask(cTask, height);
+			if(cTask.childTask.length > 0){
+				this.shiftChildTask(cTask, height);
+			}
+		}, this);
+	},
+	endMove: function(){
+		var cTask0 = this.cTaskItem[0];
+		var width = dojo.style(cTask0, "left") - this.posX;
+		var startTime = this.getDateOnPosition(dojo.style(cTask0, "left"));
+		startTime = this.checkPos(startTime);
+		if(this.checkMove){
+			width = this.ganttChart.getPosOnDate(startTime) - this.posX;
+			this.moveCurrentTaskItem(width, this.moveChild);
+			this.project.shiftProjectItem();
+		}
+		this.checkMove = false;
+		this.posX = 0;
+		this.maxPosXMove = -1;
+		this.minPosXMove = -1;
+		cTask0.childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
+		this.adjustPanelTime();
+		if(this.ganttChart.resource){
+			this.ganttChart.resource.refresh();
+		}
+	},
+	checkPos: function(startTime){
+		var cTask0 = this.cTaskItem[0];
+		var h = startTime.getHours();
+		if(h >= 12){
+			startTime.setDate(startTime.getDate() + 1);
+			startTime.setHours(0);
+			if((parseInt(cTask0.firstChild.firstChild.width) + this.ganttChart.getPosOnDate(startTime) > this.maxPosXMove) && (this.maxPosXMove != -1)){
+				startTime.setDate(startTime.getDate() - 1);
+				startTime.setHours(0);
+			}
+		}else if((h < 12) && (h != 0)){
+			startTime.setHours(0);
+			if((this.ganttChart.getPosOnDate(startTime) < this.minPosXMove)){
+				startTime.setDate(startTime.getDate() + 1);
+			}
+		}
+		cTask0.style.left = this.ganttChart.getPosOnDate(startTime) + "px";
+		return startTime;
+	},
+	getMaxPosPredChildTaskItem: function(){
+		var posPredChildTaskItem = 0;
+		var nextPosPredChildTaskItem = 0;
+		for(var i = 0; i < this.childPredTask.length; i++){
+			nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(this.childPredTask[i]);
+			if(nextPosPredChildTaskItem > posPredChildTaskItem){
+				posPredChildTaskItem = nextPosPredChildTaskItem;
+			}
+		}
+		return posPredChildTaskItem;
+	},
+	getMaxPosPredChildTaskItemInTree: function(task){
+		var cTask0 = task.cTaskItem[0];
+		var currentPos = parseInt(cTask0.firstChild.firstChild.width) + dojo.style(cTask0, "left");
+		var posPredChildTaskItem = 0;
+		var nextPosPredChildTaskItem = 0;
+		dojo.forEach(task.childPredTask, function(cpTask){
+			nextPosPredChildTaskItem = this.getMaxPosPredChildTaskItemInTree(cpTask);
+			if(nextPosPredChildTaskItem > posPredChildTaskItem){
+				posPredChildTaskItem = nextPosPredChildTaskItem;
+			}
+		}, this);
+		return posPredChildTaskItem > currentPos ? posPredChildTaskItem : currentPos;
+	},
+	moveCurrentTaskItem: function(width, moveChild){
+		var taskItem = this.cTaskItem[0];
+		this.taskItem.startTime = new Date(this.ganttChart.startDate);
+		this.taskItem.startTime.setHours(this.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
+		this.showDescTask();
+		var cTask1 = this.cTaskItem[1];
+		if(cTask1.length > 0){
+			cTask1[2].style.width = parseInt(cTask1[2].style.width) + width + "px";
+			cTask1[1].style.left = parseInt(cTask1[1].style.left) + width + "px";
+		}
+		dojo.forEach(this.childTask, function(cTask){
+			if(!cTask.predTask){
+				this.moveChildTaskItems(cTask, width, moveChild);
+			}
+		}, this);
+		dojo.forEach(this.childPredTask, function(cpTask){
+			this.moveChildTaskItems(cpTask, width, moveChild);
+		}, this);
+	},
+	moveChildTaskItems: function(task, width, moveChild){
+		var taskItem = task.cTaskItem[0];
+		if(moveChild){
+			taskItem.style.left = parseInt(taskItem.style.left) + width + "px";
+			task.adjustPanelTime();
+			task.taskItem.startTime = new Date(this.ganttChart.startDate);
+			task.taskItem.startTime.setHours(task.taskItem.startTime.getHours() + (parseInt(taskItem.style.left) / this.ganttChart.pixelsPerHour));
+			var ctItem = task.cTaskItem[1];
+			dojo.forEach(ctItem, function(item){
+				item.style.left = parseInt(item.style.left) + width + "px";
+			}, this);
+			dojo.forEach(task.childTask, function(cTask){
+				if(!cTask.predTask){
+					this.moveChildTaskItems(cTask, width, moveChild);
+				}
+			}, this);
+			dojo.forEach(task.childPredTask, function(cpTask){
+				this.moveChildTaskItems(cpTask, width, moveChild);
+			}, this);
+		}else{
+			var ctItem = task.cTaskItem[1];
+			if(ctItem.length > 0){
+				var item0 = ctItem[0], item2 = ctItem[2];
+				item2.style.left = parseInt(item2.style.left) + width + "px";
+				item2.style.width = parseInt(item2.style.width) - width + "px";
+				item0.style.left = parseInt(item0.style.left) + width + "px";
+			}
+		}
+		task.moveDescTask();
+	},
+	adjustPanelTime: function(){
+		var taskItem = this.cTaskItem[0];
+		var width = parseInt(taskItem.style.left) + parseInt(taskItem.firstChild.firstChild.width) + this.ganttChart.panelTimeExpandDelta;
+		width += this.descrTask.offsetWidth;
+		this.ganttChart.adjustPanelTime(width);
+	},
+	getDateOnPosition: function(position){
+		var date = new Date(this.ganttChart.startDate);
+		date.setHours(date.getHours() + (position / this.ganttChart.pixelsPerHour));
+		return date;
+	},
+	moveItem: function(event){
+		var pageX = event.screenX;
+		var posTaskItem = (this.posX + (pageX - this.mouseX));
+		var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
+		var posTaskItemR = posTaskItem + widthTaskItem;
+		if(this.checkMove){
+			if(((this.minPosXMove <= posTaskItem)) &&
+			((posTaskItemR <= this.maxPosXMove) || (this.maxPosXMove == -1))){
+				this.moveTaskItem(posTaskItem);
+			}
+		}
+	},
+	moveTaskItem: function(posX){
+		var cTask = this.cTaskItem[0];
+		cTask.style.left = posX + "px";
+		cTask.childNodes[1].firstChild.rows[0].cells[0].innerHTML = this.getDateOnPosition(posX).getDate() + '.' + (this.getDateOnPosition(posX).getMonth() + 1) + '.' + this.getDateOnPosition(posX).getUTCFullYear();
+	},
+	resizeItem: function(event){
+		if(this.checkResize){
+			var taskItem = this.cTaskItem[0];
+			var mouseX = event.screenX;
+			var width = (mouseX - this.mouseX);
+			var widthTaskItem = this.taskItemWidth + (mouseX - this.mouseX);
+			if(widthTaskItem >= this.taskItemWidth){
+				if((widthTaskItem <= this.maxWidthResize) || (this.maxWidthResize == -1)){
+					this.resizeTaskItem(widthTaskItem);
+				}else if((this.maxWidthResize != -1) && (widthTaskItem > this.maxWidthResize)){
+					this.resizeTaskItem(this.maxWidthResize);
+				}
+			}else if(widthTaskItem <= this.taskItemWidth){
+				if(widthTaskItem >= this.minWidthResize){
+					this.resizeTaskItem(widthTaskItem);
+				}else if(widthTaskItem < this.minWidthResize){
+					this.resizeTaskItem(this.minWidthResize);
+				}
+			}
+		}
+	},
+	resizeTaskItem: function(width){
+		var taskItem = this.cTaskItem[0];
+		var countHours = Math.round(width / this.ganttChart.pixelsPerWorkHour);
+		var trow = taskItem.childNodes[0].firstChild.rows[0],
+			rc0 = trow.cells[0], rc1 = trow.cells[1];
+		rc0 && (rc0.firstChild.style.width = parseInt(rc0.width) * width / 100 + "px");
+		rc1 && (rc1.firstChild.style.width = parseInt(rc1.width) * width / 100 + "px");
+		taskItem.childNodes[0].firstChild.width = width + "px";
+		taskItem.childNodes[1].firstChild.width = width + "px";
+		//resize info
+		this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = countHours;
+		var tcNode2 = taskItem.childNodes[2];
+		tcNode2.childNodes[0].style.width = width + "px";
+		tcNode2.childNodes[1].style.left = width - 10 + "px";
+	},
+	endResizeItem: function(){
+		var taskItem = this.cTaskItem[0];
+		if((this.taskItemWidth != parseInt(taskItem.childNodes[0].firstChild.width))){
+			var posXL = taskItem.offsetLeft;
+			var posXR = taskItem.offsetLeft + parseInt(taskItem.childNodes[0].firstChild.width);
+			var countHours = Math.round((posXR - posXL) / this.ganttChart.pixelsPerWorkHour);
+			this.taskItem.duration = countHours;
+			if(this.childPredTask.length > 0){
+				for(var j = 0; j < this.childPredTask.length; j++){
+					var cpctItem = this.childPredTask[j].cTaskItem[1],
+						item0 = cpctItem[0], item2 = cpctItem[2], tcNode0 = taskItem.childNodes[0];
+					item2.style.width = parseInt(item2.style.width) - (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
+					item2.style.left = parseInt(item2.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
+					item0.style.left = parseInt(item0.style.left) + (parseInt(tcNode0.firstChild.width) - this.taskItemWidth) + "px";
+				}
+			}
+		}
+		this.cTaskItem[0].childNodes[1].firstChild.rows[0].cells[0].innerHTML = "";
+		this.checkResize = false;
+		this.taskItemWidth = 0;
+		this.mouseX = 0;
+		this.showDescTask();
+		this.project.shiftProjectItem();
+		this.adjustPanelTime();
+		if(this.ganttChart.resource){
+			this.ganttChart.resource.refresh();
+		}
+	},
+	startMove: function(event){
+		this.moveChild = event.ctrlKey;
+		this.mouseX = event.screenX;
+		this.getMoveInfo();
+		this.checkMove = true;
+		this.hideDescTask();
+	},
+	showDescTask: function(){
+		var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		this.descrTask.style.left = posX + "px";
+		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+		this.descrTask.style.visibility = 'visible';
+	},
+	hideDescTask: function(){
+		dojo.style(this.descrTask, "visibility", "hidden");
+	},
+	buildResourceInfo: function(resourceInfo){
+		if(this.childTask && this.childTask.length > 0){
+			for(var i = 0; i < this.childTask.length; i++){
+				var cTask = this.childTask[i];
+				cTask.buildResourceInfo(resourceInfo);
+			}
+		}
+		if(dojo.trim(this.taskItem.taskOwner).length > 0){
+			var owners = this.taskItem.taskOwner.split(";");
+			for(var i = 0; i < owners.length; i++){
+				var o = owners[i];
+				if(dojo.trim(o).length <= 0){
+					continue;
+				}
+				resourceInfo[o] ? (resourceInfo[o].push(this)) : (resourceInfo[o] = [this]);
+			}
+		}
+	},
+	objKeyToStr: function(obj, delm){
+		var returnStr = "";
+		delm = delm || " ";
+		if(obj){
+			for(var key in obj){
+				returnStr += delm + key;
+			}
+		}
+		return returnStr;
+	},
+	getTaskOwner: function(){
+		var tOwner = {};
+		if(dojo.trim(this.taskItem.taskOwner).length > 0){
+			var owners = this.taskItem.taskOwner.split(";");
+			for(var i = 0; i < owners.length; i++){
+				var o = owners[i];
+				tOwner[o] = 1;
+			}
+		}
+		dojo.forEach(this.childTask, function(ctask){
+			dojo.mixin(tOwner, ctask.getTaskOwner());
+		}, this);
+		return tOwner;
+	},
+	moveDescTask: function(){
+		var posX = (parseInt(this.cTaskItem[0].style.left) + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		this.descrTask.style.left = posX + "px";
+	},
+	getMoveInfo: function(){
+		this.posX = parseInt(this.cTaskItem[0].style.left);
+		var widthTaskItem = parseInt(this.cTaskItem[0].childNodes[0].firstChild.width);
+		var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
+		var posPredTaskItem = !this.predTask ? 0 : parseInt(this.predTask.cTaskItem[0].style.left) + parseInt(this.predTask.cTaskItem[0].childNodes[0].firstChild.width);
+		var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
+		
+		var childPredPosX = 0;
+		var childParentPosX = 0;
+		var childParentPosXR = 0;
+		if(this.childPredTask.length > 0){
+			var posChildTaskItem = null;
+			dojo.forEach(this.childPredTask, function(cpTask){
+				if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
+					posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
+				}
+			}, this);
+			childPredPosX = posChildTaskItem;
+		}
+		if(this.childTask.length > 0){
+			var posChildTaskItemR = null;
+			dojo.forEach(this.childTask, function(cTask){
+				if((!posChildTaskItemR) || ((posChildTaskItemR) && (posChildTaskItemR > (parseInt(cTask.cTaskItem[0].style.left))))){
+					posChildTaskItemR = parseInt(cTask.cTaskItem[0].style.left);
+				}
+			}, this);
+			childParentPosXR = posChildTaskItemR;
+			var posChildTaskItem = null;
+			dojo.forEach(this.childTask, function(cTask){
+				if((!posChildTaskItem) || ((posChildTaskItem)
+				&& (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
+					posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
+				}
+			}, this);
+			childParentPosX = posChildTaskItem;
+		}
+		if(!this.moveChild){
+			if(this.childPredTask.length > 0){
+				if(this.maxPosXMove < childPredPosX) this.maxPosXMove = childPredPosX;
+			}
+			if(this.childTask.length > 0){
+				if((this.childPredTask.length > 0) && (this.maxPosXMove - widthTaskItem) > childParentPosXR){
+					this.maxPosXMove = this.maxPosXMove - ((this.maxPosXMove - widthTaskItem) - childParentPosXR);
+				}
+				if(!(this.childPredTask.length > 0)){
+					this.maxPosXMove = childParentPosXR + widthTaskItem;
+				}
+				this.minPosXMove = (childParentPosX - widthTaskItem);
+			}
+			if(posParentTaskItem > 0){
+				if((!(this.childPredTask.length > 0)) && (this.childTask.length > 0)){
+					if(this.maxPosXMove > posParentTaskItem + widthParentTaskItem){
+						this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+					}
+				}
+				if(this.minPosXMove <= posParentTaskItem){
+					this.minPosXMove = posParentTaskItem;
+				}
+				if((!(this.childTask.length > 0)) && (!(this.childPredTask.length > 0))){
+					this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+				}else if((!(this.childTask.length > 0)) && (this.childPredTask.length > 0)){
+					if((posParentTaskItem + widthParentTaskItem) > posPredTaskItem){
+						this.maxPosXMove = childPredPosX;
+					}
+				}
+			}
+			if(posPredTaskItem > 0){
+				if(this.minPosXMove <= posPredTaskItem){
+					this.minPosXMove = posPredTaskItem;
+				}
+			}
+			if((posPredTaskItem == 0) && (posParentTaskItem == 0)){
+				if(this.minPosXMove <= this.ganttChart.initialPos){
+					this.minPosXMove = this.ganttChart.initialPos;
+				}
+			}
+		}else{
+			if((posParentTaskItem > 0) && (posPredTaskItem == 0)){
+				this.minPosXMove = posParentTaskItem;
+				this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+			}else if((posParentTaskItem == 0) && (posPredTaskItem == 0)){
+				this.minPosXMove = this.ganttChart.initialPos;
+				this.maxPosXMove = -1;
+			}else if((posParentTaskItem > 0) && (posPredTaskItem > 0)){
+				this.minPosXMove = posPredTaskItem;
+				this.maxPosXMove = posParentTaskItem + widthParentTaskItem;
+			}else if((posParentTaskItem == 0) && (posPredTaskItem > 0)){
+				this.minPosXMove = posPredTaskItem;
+				this.maxPosXMove = -1;
+			}
+			if((this.parentTask) && (this.childPredTask.length > 0)){
+				var posChildTaskItem = this.getMaxPosPredChildTaskItem(this);
+				var posParentTaskItem = parseInt(this.parentTask.cTaskItem[0].style.left) + parseInt(this.parentTask.cTaskItem[0].firstChild.firstChild.width);
+				this.maxPosXMove = this.posX + widthTaskItem + posParentTaskItem - posChildTaskItem;
+			}
+		}
+	},
+	startResize: function(event){
+		this.mouseX = event.screenX;
+		this.getResizeInfo();
+		this.hideDescTask();
+		this.checkResize = true;
+		this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
+	},
+	getResizeInfo: function(){
+		var cTask = this.cTaskItem[0];
+		var posParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].style.left);
+		var widthParentTaskItem = !this.parentTask ? 0 : parseInt(this.parentTask.cTaskItem[0].childNodes[0].firstChild.width);
+		var posTaskItem = parseInt(cTask.style.left);
+		var childPredPosX = 0;
+		var childParentPosX = 0;
+		if(this.childPredTask.length > 0){
+			var posChildTaskItem = null;
+			dojo.forEach(this.childPredTask, function(cpTask){
+				if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem > parseInt(cpTask.cTaskItem[0].style.left)))){
+					posChildTaskItem = parseInt(cpTask.cTaskItem[0].style.left);
+				}
+			}, this);
+			childPredPosX = posChildTaskItem;
+		}
+		if(this.childTask.length > 0){
+			var posChildTaskItem = null;
+			dojo.forEach(this.childTask, function(cTask){
+				if((!posChildTaskItem) || ((posChildTaskItem) && (posChildTaskItem < (parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width))))){
+					posChildTaskItem = parseInt(cTask.cTaskItem[0].style.left) + parseInt(cTask.cTaskItem[0].firstChild.firstChild.width);
+				}
+			}, this);
+			childParentPosX = posChildTaskItem;
+		}
+		this.minWidthResize = this.ganttChart.pixelsPerDay;
+		if(this.childTask.length > 0){
+			this.minWidthResize = childParentPosX - posTaskItem;
+		}
+		if((this.childPredTask.length > 0) && (!this.parentTask)){
+			this.maxWidthResize = childPredPosX - posTaskItem;
+		}else if((this.childPredTask.length > 0) && (this.parentTask)){
+			var w1 = posParentTaskItem + widthParentTaskItem - posTaskItem;
+			var w2 = childPredPosX - posTaskItem;
+			this.maxWidthResize = Math.min(w1, w2);
+		}else if((this.childPredTask.length == 0) && (this.parentTask)){
+			this.maxWidthResize = posParentTaskItem + widthParentTaskItem - posTaskItem;
+		}
+	},
+	createTaskItem: function(){
+		this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
+		var itemControl = dojo.create("div", {
+			id: this.taskItem.id,
+			className: "ganttTaskItemControl"
+		});
+		dojo.style(itemControl, {
+			left: this.posX + "px",
+			top: this.posY + "px"
+		});
+		var divTaskItem = dojo.create("div", {className: "ganttTaskDivTaskItem"}, itemControl);
+		var tblTaskItem = dojo.create("table", {
+			cellPadding: "0",
+			cellSpacing: "0",
+			width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px",
+			className: "ganttTaskTblTaskItem"
+		}, divTaskItem);
+		var rowTblTask = tblTaskItem.insertRow(tblTaskItem.rows.length);
+		if(this.taskItem.percentage != 0){
+			var cellTblTask = dojo.create("td", {
+				height: this.ganttChart.heightTaskItem + "px",
+				width: this.taskItem.percentage + "%"
+			}, rowTblTask);
+			cellTblTask.style.lineHeight = "1px";
+			var imageProgress = dojo.create("div", {
+				className: "ganttImageTaskProgressFilled"
+			}, cellTblTask);
+			dojo.style(imageProgress, {
+				width: (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}
+		if(this.taskItem.percentage != 100){
+			var cellTblTask = dojo.create("td", {
+				height: this.ganttChart.heightTaskItem + "px",
+				width: (100 - this.taskItem.percentage) + "%"
+			}, rowTblTask);
+			cellTblTask.style.lineHeight = "1px";
+			var imageProgressFill = dojo.create("div", {
+				className: "ganttImageTaskProgressBg"
+			}, cellTblTask);
+			dojo.style(imageProgressFill, {
+				width: ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}
+		if(this.ganttChart.isContentEditable){
+			var divTaskInfo = dojo.create("div", {className: "ganttTaskDivTaskInfo"}, itemControl);
+			var tblTaskInfo = dojo.create("table", {
+				cellPadding: "0",
+				cellSpacing: "0",
+				height: this.ganttChart.heightTaskItem + "px",
+				width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+			}, divTaskInfo);
+			var rowTaskInfo = tblTaskInfo.insertRow(0);
+			var cellTaskInfo = dojo.create("td", {
+				align: "center",
+				vAlign: "top",
+				height: this.ganttChart.heightTaskItem + "px",
+				className: "ganttMoveInfo"
+			}, rowTaskInfo);
+			var divTaskName = dojo.create("div", {className: "ganttTaskDivTaskName"}, itemControl);
+			var divMove = dojo.create("div", {}, divTaskName);
+			dojo.create("input", {
+				className: "ganttTaskDivMoveInput",
+				type: "text"
+			}, divMove);
+			dojo.isIE && dojo.style(divMove, {
+				background: "#000000",
+				filter: "alpha(opacity=0)"
+			});
+			dojo.style(divMove, {
+				height: this.ganttChart.heightTaskItem + "px",
+				width: this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + "px"
+			});
+			//Creation resize area
+			var divResize = dojo.create("div", {className: "ganttTaskDivResize"}, divTaskName);
+			dojo.create("input", {
+				className: "ganttTaskDivResizeInput",
+				type: "text"
+			}, divResize);
+			dojo.style(divResize, {
+				left: (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px",
+				height: this.ganttChart.heightTaskItem + "px",
+				width: "10px"
+			});
+			this.ganttChart._events.push(
+				dojo.connect(divMove, "onmousedown", this, function(event){
+					//start move
+					this.moveMoveConn = dojo.connect(document, "onmousemove", this, function(e){
+						this.checkMove && this.moveItem(e);
+					});
+					this.moveUpConn = dojo.connect(document, "onmouseup", this, function(e){
+						if(this.checkMove){
+							this.endMove();
+							this.ganttChart.isMoving = false;
+							document.body.releaseCapture && document.body.releaseCapture();
+							dojo.disconnect(this.moveMoveConn);
+							dojo.disconnect(this.moveUpConn);
+						}
+					});
+					this.startMove(event);
+					this.ganttChart.isMoving = true;
+					document.body.setCapture && document.body.setCapture(false);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divMove, "onmouseover", this, function(event){
+					event.target && (event.target.style.cursor = "move");
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divMove, "onmouseout", this, function(event){
+					event.target.style.cursor = "";
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divResize, "onmousedown", this, function(event){
+					//start resize
+					this.resizeMoveConn = dojo.connect(document, "onmousemove", this, function(e){
+						this.checkResize && this.resizeItem(e);
+					});
+					this.resizeUpConn = dojo.connect(document, "onmouseup", this, function(e){
+						if(this.checkResize){
+							this.endResizeItem();
+							this.ganttChart.isResizing = false;
+							document.body.releaseCapture && document.body.releaseCapture();
+							dojo.disconnect(this.resizeMoveConn);
+							dojo.disconnect(this.resizeUpConn);
+						}
+					});
+					this.startResize(event);
+					this.ganttChart.isResizing = true;
+					document.body.setCapture && document.body.setCapture(false);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divResize, "onmouseover", this, function(event){
+					(!this.ganttChart.isMoving) && (!this.ganttChart.isResizing) && event.target && (event.target.style.cursor = "e-resize");
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divResize, "onmouseout", this, function(event){
+					!this.checkResize && event.target && (event.target.style.cursor = "");
+				})
+			);
+		}
+		return itemControl;
+	},
+	createTaskNameItem: function(){
+		var divName = dojo.create("div", {
+			id: this.taskItem.id,
+			className: "ganttTaskTaskNameItem",
+			title: this.taskItem.name + ", id: " + this.taskItem.id + " ",
+			innerHTML: this.taskItem.name
+		});
+		dojo.style(divName, "top", this.posY + "px");
+		dojo.attr(divName, "tabIndex", 0);
+		if(this.ganttChart.isShowConMenu){
+			this.ganttChart._events.push(
+				dojo.connect(divName, "onmouseover", this, function(event){
+					dojo.addClass(divName, "ganttTaskTaskNameItemHover");
+					clearTimeout(this.ganttChart.menuTimer);
+					this.ganttChart.tabMenu.clear();
+					this.ganttChart.tabMenu.show(event.target, this);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divName, "onkeydown", this, function(event){
+					if(event.keyCode == dojo.keys.ENTER){
+						this.ganttChart.tabMenu.clear();
+						this.ganttChart.tabMenu.show(event.target, this);
+					}
+					if(this.ganttChart.tabMenu.isShow && (event.keyCode == dojo.keys.LEFT_ARROW || event.keyCode == dojo.keys.RIGHT_ARROW)){
+						dijit.focus(this.ganttChart.tabMenu.menuPanel.firstChild.rows[0].cells[0]);
+					}
+					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
+						this.ganttChart.tabMenu.hide();
+					}
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(divName, "onmouseout", this, function(){
+					dojo.removeClass(divName, "ganttTaskTaskNameItemHover");
+					clearTimeout(this.ganttChart.menuTimer);
+					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
+						this.ganttChart.tabMenu.hide();
+					}), 200);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseover", this, function(){
+					clearTimeout(this.ganttChart.menuTimer);
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onkeydown", this, function(event){
+					if(this.ganttChart.tabMenu.isShow && event.keyCode == dojo.keys.ESCAPE){
+						this.ganttChart.tabMenu.hide();
+					}
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(this.ganttChart.tabMenu.menuPanel, "onmouseout", this, function(){
+					clearTimeout(this.ganttChart.menuTimer);
+					this.ganttChart.menuTimer = setTimeout(dojo.hitch(this, function(){
+						this.ganttChart.tabMenu.hide();
+					}), 200);
+				})
+			);
+		}
+		return divName;
+	},
+	createTaskDescItem: function(){
+		var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		var divDesc = dojo.create("div", {
+			innerHTML: this.objKeyToStr(this.getTaskOwner()),
+			className: "ganttTaskDescTask"
+		});
+		dojo.style(divDesc, {
+			left: posX + "px",
+			top: this.posY + "px"
+		});
+		return this.descrTask = divDesc;
+	},
+	checkWidthTaskNameItem: function(){
+		if(this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft > this.ganttChart.maxWidthTaskNames){
+			var width = this.cTaskNameItem[0].offsetWidth + this.cTaskNameItem[0].offsetLeft - this.ganttChart.maxWidthTaskNames;
+			var countChar = Math.round(width / (this.cTaskNameItem[0].offsetWidth / this.cTaskNameItem[0].firstChild.length));
+			var tName = this.taskItem.name.substring(0, this.cTaskNameItem[0].firstChild.length - countChar - 3);
+			tName += "...";
+			this.cTaskNameItem[0].innerHTML = tName;
+		}
+	},
+	refreshTaskItem: function(itemControl){
+		this.posX = this.ganttChart.getPosOnDate(this.taskItem.startTime);
+		dojo.style(itemControl, {
+			"left": this.posX + "px"
+		});
+		var divTaskItem = itemControl.childNodes[0];
+		var tblTaskItem = divTaskItem.firstChild;
+		tblTaskItem.width = (!this.taskItem.duration ? 1 : this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) + "px";
+		var rowTblTask = tblTaskItem.rows[0];
+		if(this.taskItem.percentage != 0){
+			var cellTblTask = rowTblTask.firstChild;
+			cellTblTask.height = this.ganttChart.heightTaskItem + "px";
+			cellTblTask.width = this.taskItem.percentage + "%";
+			cellTblTask.style.lineHeight = "1px";
+			var imageProgress = cellTblTask.firstChild;
+			dojo.style(imageProgress, {
+				width: (!this.taskItem.duration ? 1 : (this.taskItem.percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}
+		if(this.taskItem.percentage != 100){
+			var cellTblTask = rowTblTask.lastChild;
+			cellTblTask.height = this.ganttChart.heightTaskItem + "px";
+			cellTblTask.width = (100 - this.taskItem.percentage) + "%";
+			cellTblTask.style.lineHeight = "1px";
+			var imageProgressFill = cellTblTask.firstChild;
+			dojo.style(imageProgressFill, {
+				width: (!this.taskItem.duration ? 1 : ((100 - this.taskItem.percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour / 100)) + "px",
+				height: this.ganttChart.heightTaskItem + "px"
+			});
+		}
+		if(this.ganttChart.isContentEditable){
+			var divTaskInfo = itemControl.childNodes[1];
+			var tblTaskInfo = divTaskInfo.firstChild;
+			tblTaskInfo.height = this.ganttChart.heightTaskItem + "px";
+			tblTaskInfo.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
+			var rowTaskInfo = tblTaskInfo.rows[0];
+			var cellTaskInfo = rowTaskInfo.firstChild;
+			cellTaskInfo.height = this.ganttChart.heightTaskItem + "px";
+			var divTaskName = itemControl.childNodes[2];
+			var divMove = divTaskName.firstChild;
+			divMove.style.height = this.ganttChart.heightTaskItem + "px";
+			divMove.style.width = (!this.taskItem.duration ? 1 : (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour)) + "px";
+			//Creation resize area
+			var divResize = divTaskName.lastChild;
+			dojo.style(divResize, {
+				"left": (this.taskItem.duration * this.ganttChart.pixelsPerWorkHour - 10) + "px"
+			});
+			divResize.style.height = this.ganttChart.heightTaskItem + "px";
+			divResize.style.width = "10px";
+		}
+		return itemControl;
+	},
+	refreshTaskDesc: function(divDesc){
+		var posX = (this.posX + this.taskItem.duration * this.ganttChart.pixelsPerWorkHour + 10);
+		dojo.style(divDesc, {
+			"left": posX + "px"
+		});
+		return divDesc;
+	},
+	refreshConnectingLinesDS: function(arrLines){
+		var arrowImg = arrLines[1];
+		var lineVerticalRight = arrLines[0];
+		//horizontal line
+		var lineHorizontal = arrLines[2];
+		var posXPreviousTask = dojo.style(this.predTask.cTaskItem[0], "left");
+		var posYPreviousTask = dojo.style(this.predTask.cTaskItem[0], "top");
+		var posXChildTask = dojo.style(this.cTaskItem[0], "left");
+		var posYChildTask = this.posY + 2;
+		//width task item
+		var widthChildTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
+		var widthPreviousTask = parseInt(this.predTask.cTaskItem[0].firstChild.firstChild.width);
+		if(posYPreviousTask < posYChildTask){
+			dojo.style(lineVerticalRight, {
+				"height": (posYChildTask - this.ganttChart.heightTaskItem / 2 - posYPreviousTask - 3) + "px",
+				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+			});
+			dojo.style(lineHorizontal, {
+				"width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+			});
+			
+			dojo.style(arrowImg, {
+				"left": (posXChildTask - 7) + "px"
+			});
+		}else{
+			dojo.style(lineVerticalRight, {
+				"height": (posYPreviousTask + 2 - posYChildTask) + "px",
+				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+			});
+			dojo.style(lineHorizontal, {
+				"width": (15 + (posXChildTask - (widthPreviousTask + posXPreviousTask))) + "px",
+				"left": (posXPreviousTask + widthPreviousTask - 20) + "px"
+			});
+			dojo.style(arrowImg, {
+				"left": (posXChildTask - 7) + "px"
+			});
+		}
+		return arrLines;
+	},
+	postLoadData: function(){
+		//TODO e.g. task relative info...
+	},
+	refresh: function(){
+		if(this.childTask && this.childTask.length > 0){
+			dojo.forEach(this.childTask, function(cTask){
+				cTask.refresh();
+			}, this);
+		}
+		//creation task item
+		this.refreshTaskItem(this.cTaskItem[0]);
+		this.refreshTaskDesc(this.cTaskItem[0].nextSibling);
+		//Create Connecting Lines
+		var arrConnectingLines = [];
+		if(this.taskItem.previousTask && this.predTask){
+			this.refreshConnectingLinesDS(this.cTaskItem[1]);
+		}
+		return this;
+	},
+	create: function(){
+		var containerTasks = this.ganttChart.contentData.firstChild;
+		var containerNames = this.ganttChart.panelNames.firstChild;
+		var previousTask = this.taskItem.previousTask;
+		var parentTask = this.taskItem.parentTask;
+		var isCParentTask = (this.taskItem.cldTasks.length > 0) ? true : false;
+		this.cTaskItem = [];
+		this.cTaskNameItem = [];
+		//creation arrTasks
+		if(!parentTask){
+			if(this.taskItem.previousParentTask){
+				this.previousParentTask = this.project.getTaskById(this.taskItem.previousParentTask.id);
+				var lastChildTask = this.ganttChart.getLastChildTask(this.previousParentTask);
+				this.posY = parseInt(lastChildTask.cTaskItem[0].style.top)
+					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				this.previousParentTask.nextParentTask = this;
+			}else{
+				this.posY = parseInt(this.project.projectItem[0].style.top)
+					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			}
+		}
+		if(parentTask){
+			var task = this.project.getTaskById(this.taskItem.parentTask.id);
+			this.parentTask = task;
+			
+			if(this.taskItem.previousChildTask){
+				this.previousChildTask = this.project.getTaskById(this.taskItem.previousChildTask.id);
+				var lastChildTask = this.ganttChart.getLastChildTask(this.previousChildTask);
+				this.posY = dojo.style(lastChildTask.cTaskItem[0], "top")
+					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+				this.previousChildTask.nextChildTask = this;
+			}else{
+				this.posY = dojo.style(task.cTaskItem[0], "top")
+					+ this.ganttChart.heightTaskItem + this.ganttChart.heightTaskItemExtra;
+			}
+			task.childTask.push(this);
+		}
+		if(previousTask){
+			var task = this.project.getTaskById(previousTask.id);
+			this.predTask = task;
+			task.childPredTask.push(this);
+		}
+		//creation task item
+		this.cTaskItem.push(this.createTaskItem());
+		containerTasks.appendChild(this.cTaskItem[0]);
+		if(this.ganttChart.panelNames){
+			this.cTaskNameItem.push(this.createTaskNameItem());
+			this.ganttChart.panelNames.firstChild.appendChild(this.cTaskNameItem[0]);
+		}
+		containerTasks.appendChild(this.createTaskDescItem());
+		//Create Connecting Lines
+		var arrConnectingLines = [];
+		if(previousTask){
+			arrConnectingLines = this.createConnectingLinesDS();
+		}
+		this.cTaskItem.push(arrConnectingLines);
+		if(this.ganttChart.panelNames){
+			//Create Connecting Lines
+			var arrConnectingLinesNames = [];
+			if(parentTask){
+				this.cTaskNameItem[0].style.left = dojo.style(this.parentTask.cTaskNameItem[0], "left") + 15 + "px";
+				arrConnectingLinesNames = this.createConnectingLinesPN();
+			}
+			this.checkWidthTaskNameItem();
+			//Identifier
+			this.checkPosition();
+			var treeImg = null;
+			if(isCParentTask){
+				treeImg = this.createTreeImg();
+			}
+			this.cTaskNameItem.push(arrConnectingLinesNames);
+			this.cTaskNameItem.push(treeImg);
+		}
+		this.adjustPanelTime();
+		return this;
+	},
+	checkPosition: function(){
+		//task name position: check Task Identifier
+		if(!this.ganttChart.withTaskId){
+			return;
+		}
+		var pos = dojo.coords(this.cTaskNameItem[0], true);
+		if(this.taskIdentifier){
+			if(this.childTask && this.childTask.length > 0){
+				dojo.forEach(this.childTask, function(cTask){
+					cTask.checkPosition();
+				}, this);
+			}
+			dojo.style(this.taskIdentifier, {
+				"left": (pos.l + pos.w + 4) + "px",
+				"top": (pos.t - 1) + "px"
+			});
+		}else{
+			this.taskIdentifier = dojo.create("div", {
+				id: "TaskId_" + this.taskItem.id,
+				className: "ganttTaskIdentifier",
+				title: this.taskItem.id,
+				innerHTML: this.taskItem.id
+			}, this.cTaskNameItem[0].parentNode);
+			dojo.style(this.taskIdentifier, {
+				left: (pos.l + pos.w + 4) + "px",
+				top: (pos.t - 1) + "px"
+			});
+		}
+	},
+	createTreeImg: function(){
+		var treeImg = dojo.create("div", {
+			id: this.taskItem.id,
+			className: "ganttImageTreeCollapse"
+		});
+		dojo.attr(treeImg, "tabIndex", 0);
+		dojo.forEach(["onclick", "onkeydown"], function(e){
+			this.ganttChart._events.push(
+				dojo.connect(treeImg, e, this, function(evt){
+					if(e == "onkeydown" && evt.keyCode != dojo.keys.ENTER){ return; }
+					if(this.isExpanded){
+						dojo.removeClass(treeImg, "ganttImageTreeCollapse");
+						dojo.addClass(treeImg, "ganttImageTreeExpand");
+						this.isExpanded = false;
+						this.hideChildTasks(this);
+						this.shiftCurrentTasks(this, -this.hideTasksHeight);
+						this.ganttChart.checkPosition();
+					}else{
+						dojo.removeClass(treeImg, "ganttImageTreeExpand");
+						dojo.addClass(treeImg, "ganttImageTreeCollapse");
+						this.isExpanded = true;
+						this.shiftCurrentTasks(this, this.hideTasksHeight);
+						this.showChildTasks(this, true);
+						this.hideTasksHeight = 0;
+						this.ganttChart.checkPosition();
+					}
+				})
+			);
+		}, this);
+		this.ganttChart.panelNames.firstChild.appendChild(treeImg);
+		dojo.addClass(treeImg, "ganttTaskTreeImage");
+		dojo.style(treeImg, {
+			left: (dojo.style(this.cTaskNameItem[0], "left") - 12) + "px",
+			top: (dojo.style(this.cTaskNameItem[0], "top") + 3) + "px"
+		});
+		return treeImg;
+	},
+	setPreviousTask: function(previousTaskId){
+		if(previousTaskId == ""){
+			this.clearPredTask();
+		}else{
+			var task = this.taskItem;
+			if(task.id == previousTaskId){
+				return false;
+			}
+			var predTaskObj = this.project.getTaskById(previousTaskId);
+			if(!predTaskObj){
+				return false;
+			}
+			var predTask = predTaskObj.taskItem;
+			var a1 = predTask.parentTask == null, a2 = task.parentTask == null;
+			if(a1 && !a2 || !a1 && a2 || !a1 && !a2 && (predTask.parentTask.id != task.parentTask.id)){
+				return false;
+			}
+			//check time
+			var startTime = task.startTime.getTime(),
+				pest = predTask.startTime.getTime(),
+				pdur = predTask.duration * 24 * 60 * 60 * 1000 / predTaskObj.ganttChart.hsPerDay;
+			if((pest+pdur) > startTime){
+				return false;
+			}
+			// remove current connection
+			this.clearPredTask();
+			if(!this.ganttChart.checkPosPreviousTask(predTask, task)){
+				this.ganttChart.correctPosPreviousTask(predTask, task, this);
+			}
+			task.previousTaskId = previousTaskId;
+			task.previousTask = predTask;
+			this.predTask = predTaskObj;
+			predTaskObj.childPredTask.push(this);
+			this.cTaskItem[1] = this.createConnectingLinesDS();
+		}
+		return true;
+	},
+	clearPredTask: function(){
+		if(this.predTask){
+			var ch = this.predTask.childPredTask;
+			for(var i = 0; i < ch.length; i++){
+				if(ch[i] == this){
+					ch.splice(i, 1);
+					break;
+				}
+			}
+			for(var i = 0; i < this.cTaskItem[1].length; i++){
+				this.cTaskItem[1][i].parentNode.removeChild(this.cTaskItem[1][i]);
+			}
+			this.cTaskItem[1] = [];
+			this.taskItem.previousTaskId = null;
+			this.taskItem.previousTask = null;
+			this.predTask = null;
+		}
+	},
+	setStartTime: function(startTime, shiftChild){
+		this.moveChild = shiftChild;
+		this.getMoveInfo();
+		var pos = this.ganttChart.getPosOnDate(startTime);
+		if((parseInt(this.cTaskItem[0].firstChild.firstChild.width) + pos > this.maxPosXMove) && (this.maxPosXMove != -1)){
+			this.maxPosXMove = -1;
+			this.minPosXMove = -1;
+			return false;
+		}
+		if(pos < this.minPosXMove){
+			this.maxPosXMove = -1;
+			this.minPosXMove = -1;
+			return false;
+		}
+		this.cTaskItem[0].style.left = pos;
+		var width = pos - this.posX;
+		this.moveCurrentTaskItem(width, shiftChild);
+		this.project.shiftProjectItem();
+		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+		this.adjustPanelTime();
+		this.posX = 0;
+		this.maxPosXMove = -1;
+		this.minPosXMove = -1;
+		return true;
+	},
+	setDuration: function(duration){
+		this.getResizeInfo();
+		var width = this.ganttChart.getWidthOnDuration(duration);
+		if((width > this.maxWidthResize) && (this.maxWidthResize != -1)){
+			return false;
+		}else if(width < this.minWidthResize){
+			return false;
+		}else{
+			this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
+			this.resizeTaskItem(width);
+			this.endResizeItem();
+			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+			return true;
+		}
+	},
+	setTaskOwner: function(owner){
+		owner = (owner == null || owner == undefined) ? "" : owner;
+		this.taskItem.taskOwner = owner;
+		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+		return true;
+	},
+	setPercentCompleted: function(percentage){
+		percentage = parseInt(percentage);
+		if(isNaN(percentage) || percentage > 100 || percentage < 0){
+			return false;
+		}
+		var trow = this.cTaskItem[0].childNodes[0].firstChild.rows[0],
+			rc0 = trow.cells[0], rc1 = trow.cells[1];
+		if((percentage != 0) && (percentage != 100)){
+			if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
+				rc0.width = percentage + "%";
+				rc1.width = 100 - percentage + "%";
+			}else if((this.taskItem.percentage == 0) || (this.taskItem.percentage == 100)){
+				rc0.parentNode.removeChild(rc0);
+				var cellTblTask = dojo.create("td", {
+					height: this.ganttChart.heightTaskItem + "px",
+					width: percentage + "%"
+				}, trow);
+				cellTblTask.style.lineHeight = "1px";
+				var imageProgressFill = dojo.create("div", {
+					className: "ganttImageTaskProgressFilled"
+				}, cellTblTask);
+				dojo.style(imageProgressFill, {
+					width: (percentage * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+				
+				cellTblTask = dojo.create("td", {
+					height: this.ganttChart.heightTaskItem + "px",
+					width: (100 - percentage) + "%"
+				}, trow);
+				cellTblTask.style.lineHeight = "1px";
+				imageProgressFill = dojo.create("div", {
+					className: "ganttImageTaskProgressBg"
+				}, cellTblTask);
+				dojo.style(imageProgressFill, {
+					width: ((100 - percentage) * this.taskItem.duration * this.ganttChart.pixelsPerWorkHour) / 100 + "px",
+					height: this.ganttChart.heightTaskItem + "px"
+				});
+			}
+		}else if(percentage == 0){
+			if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
+				rc0.parentNode.removeChild(rc0);
+				rc1.width = 100 + "%";
+			}else{
+				dojo.removeClass(rc0.firstChild, "ganttImageTaskProgressFilled");
+				dojo.addClass(rc0.firstChild, "ganttImageTaskProgressBg");
+			}
+		}else if(percentage == 100){
+			if((this.taskItem.percentage != 0) && (this.taskItem.percentage != 100)){
+				rc1.parentNode.removeChild(rc1);
+				rc0.width = 100 + "%";
+			}else{
+				dojo.removeClass(rc0.firstChild, "ganttImageTaskProgressBg");
+				dojo.addClass(rc0.firstChild, "ganttImageTaskProgressFilled");
+			}
+		}
+		this.taskItem.percentage = percentage;
+		this.taskItemWidth = parseInt(this.cTaskItem[0].firstChild.firstChild.width);
+		this.resizeTaskItem(this.taskItemWidth);
+		this.endResizeItem();
+		this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+		return true;
+	},
+	setName: function(name){
+		if(name){
+			this.taskItem.name = name;
+			this.cTaskNameItem[0].innerHTML = name;
+			this.cTaskNameItem[0].title = name;
+			this.checkWidthTaskNameItem();
+			this.checkPosition();
+			this.descrTask.innerHTML = this.objKeyToStr(this.getTaskOwner());
+			this.adjustPanelTime();
+		}
+	}
+});
+
+dojo.declare("dojox.gantt.GanttTaskItem", null, {
+	constructor: function(configuration){
+		//id is required
+		this.id = configuration.id;
+		this.name = configuration.name || this.id;
+		this.startTime = configuration.startTime || new Date();
+		this.duration = configuration.duration || 8;
+		this.percentage = configuration.percentage || 0;
+		this.previousTaskId = configuration.previousTaskId || "";
+		this.taskOwner = configuration.taskOwner || "";
+		this.cldTasks = [];
+		this.cldPreTasks = [];
+		this.parentTask = null;
+		this.previousTask = null;
+		this.project = null;
+		this.nextChildTask = null;
+		this.previousChildTask = null;
+		this.nextParentTask = null;
+		this.previousParentTask = null;
+	},
+	addChildTask: function(task){
+		this.cldTasks.push(task);
+		task.parentTask = this;
+	},
+	setProject: function(project){
+		this.project = project;
+		for(var j = 0; j < this.cldTasks.length; j++){
+			this.cldTasks[j].setProject(project);
+		}
+	}
+});
+
diff --git a/dojox/gantt/TabMenu.js b/dojox/gantt/TabMenu.js
new file mode 100644
index 0000000..ad91843
--- /dev/null
+++ b/dojox/gantt/TabMenu.js
@@ -0,0 +1,573 @@
+dojo.provide("dojox.gantt.TabMenu");
+
+dojo.require("dijit.dijit");
+dojo.require("dijit.Menu");
+dojo.require("dijit.Dialog");
+dojo.require("dijit.form.NumberSpinner");
+dojo.require("dijit.form.Button");
+dojo.require("dijit.form.CheckBox");
+dojo.require("dijit.form.DateTextBox");
+dojo.require("dijit.form.TimeTextBox");
+dojo.require("dojo.date.locale");
+
+dojo.require("dijit.form.Form");
+dojo.require("dojo.parser");
+
+(function(){
+	dojo.declare("dojox.gantt.TabMenu", null, {
+		constructor: function(chart){
+			this.ganttChart = chart;
+			this.menuPanel = null;
+			this.paneContentArea = null;
+			this.paneActionBar = null;
+			this.tabPanelDlg = null;
+			this.tabPanelDlgId = null;
+			this.arrTabs = [];
+			this.isShow = false;
+			this.buildContent();
+		},
+		buildContent: function(){
+			this.createMenuPanel();
+			this.createTabPanel();
+			
+			//tasks customization
+			var taskSucAdd = this.createTab(11, "Add Successor Task", "t", true, this);
+			taskSucAdd.addItem(1, "Id", "id", true);
+			taskSucAdd.addItem(2, "Name", "name");
+			taskSucAdd.addItem(3, "Start Time", "startTime");
+			taskSucAdd.addItem(4, "Duration (hours)", "duration");
+			taskSucAdd.addItem(5, "Percent Complete (%)", "percentage");
+			taskSucAdd.addItem(6, "Task Assignee", "taskOwner");
+			taskSucAdd.addAction("addSuccessorTaskAction");
+			
+			var taskChildAdd = this.createTab(10, "Add Child Task", "t", true, this);
+			taskChildAdd.addItem(1, "Id", "id", true);
+			taskChildAdd.addItem(2, "Name", "name");
+			taskChildAdd.addItem(3, "Start Time", "startTime");
+			taskChildAdd.addItem(4, "Duration (hours)", "duration");
+			taskChildAdd.addItem(5, "Percent Complete (%)", "percentage");
+			taskChildAdd.addItem(6, "Task Assignee", "taskOwner");
+			taskChildAdd.addAction("addChildTaskAction");
+			
+			var taskDuration = this.createTab(4, "Set Duration(hours)", "t", true, this, true);
+			taskDuration.addItem(1, "Duration (hours)", "duration", true);
+			taskDuration.addAction("durationUpdateAction");
+			
+			var taskCP = this.createTab(5, "Set Complete Percentage (%)", "t", true, this, true);
+			taskCP.addItem(1, "Percent Complete (%)", "percentage", true);
+			taskCP.addAction("cpUpdateAction");
+			
+			var taskOwner = this.createTab(20, "Set Owner", "t", true, this, true);
+			taskOwner.addItem(1, "Task Assignee", "taskOwner", true);
+			taskOwner.addAction("ownerUpdateAction");
+			
+			var taskPrevious = this.createTab(13, "Set Previous Task", "t", true, this);
+			taskPrevious.addItem(1, "Previous Task Id", "previousTaskId", true);
+			taskPrevious.addAction("ptUpdateAction");
+			
+			var taskRename = this.createTab(1, "Rename Task", "t", true, this, true);
+			taskRename.addItem(1, "New Name", "name", true);
+			taskRename.addAction("renameTaskAction");
+			
+			var taskDelete = this.createTab(2, "Delete Task", "t", true, this);
+			taskDelete.addAction("deleteAction");
+			
+			//projects customization
+			var projectAdd = this.createTab(12, "Add New Project", "p", false, this);
+			projectAdd.addItem(1, "Id", "id", true);
+			projectAdd.addItem(2, "Name", "name", true);
+			projectAdd.addItem(3, "Start Date", "startDate", true);
+			projectAdd.addAction("addProjectAction");
+			
+			var projectCP = this.createTab(8, "Set Complete Percentage (%)", "p", true, this, true);
+			projectCP.addItem(1, "Percent Complete (%)", "percentage", true);
+			projectCP.addAction("cpProjectAction");
+			
+			var projectRename = this.createTab(6, "Rename Project", "p", true, this, true);
+			projectRename.addItem(1, "New Name", "name", true);
+			projectRename.addAction("renameProjectAction");
+			
+			var projectDelete = this.createTab(7, "Delete Project", "p", true, this);
+			projectDelete.addAction("deleteProjectAction");
+			
+			//task relative
+			var projectTaskAdd = this.createTab(9, "Add New Task", "p", true, this);
+			projectTaskAdd.addItem(1, "Id", "id", true);
+			projectTaskAdd.addItem(2, "Name", "name");
+			projectTaskAdd.addItem(3, "Start Time", "startTime");
+			projectTaskAdd.addItem(4, "Duration (hours)", "duration");
+			projectTaskAdd.addItem(5, "Percent Complete (%)", "percentage");
+			projectTaskAdd.addItem(6, "Task Assignee", "taskOwner");
+			projectTaskAdd.addItem(7, "Parent Task Id", "parentTaskId");
+			projectTaskAdd.addItem(8, "Previous Task Id", "previousTaskId");
+			projectTaskAdd.addAction("addTaskAction");
+		},
+		createMenuPanel: function(){
+			this.menuPanel = dojo.create("div", {
+				innerHTML: "<table></table>",
+				className: "ganttMenuPanel"
+			}, this.ganttChart.content);
+			dojo.addClass(this.menuPanel.firstChild, "ganttContextMenu");
+			this.menuPanel.firstChild.cellPadding = 0;
+			this.menuPanel.firstChild.cellSpacing = 0;
+		},
+		createTabPanel: function(){
+			this.tabPanelDlg = dijit.byId(this.tabPanelDlgId) ||
+				new dijit.Dialog({
+					title: "Settings"
+				});
+			this.tabPanelDlgId = this.tabPanelDlg.id;
+			this.tabPanelDlg.closeButtonNode.style.display = "none";
+			var tabPanel = this.tabPanelDlg.containerNode;
+			this.paneContentArea = dojo.create("div", {className: "dijitDialogPaneContentArea"}, tabPanel);
+			this.paneActionBar = dojo.create("div", {className: "dijitDialogPaneActionBar"}, tabPanel);
+			this.paneContentArea.innerHTML = "<table cellpadding=0 cellspacing=0><tr><th></th></tr><tr><td></td></tr></table>";
+			var headerCell = this.paneContentArea.firstChild.rows[0].cells[0];
+			headerCell.colSpan = 2;
+			headerCell.innerHTML = "Description: ";
+			dojo.addClass(headerCell, "ganttDialogContentHeader");
+			var contentCell = this.paneContentArea.firstChild.rows[1].cells[0];
+			contentCell.innerHTML = "<table></table>";
+			dojo.addClass(contentCell.firstChild, "ganttDialogContentCell");
+			contentCell.align = "center";
+			this.ok = new dijit.form.Button({label: "OK"});
+			this.cancel = new dijit.form.Button({label: "Cancel"});
+			this.paneActionBar.appendChild(this.ok.domNode);
+			this.paneActionBar.appendChild(this.cancel.domNode);
+		},
+		addItemMenuPanel: function(tab){
+			var row = this.menuPanel.firstChild.insertRow(this.menuPanel.firstChild.rows.length);
+			var cell = dojo.create("td", {
+				className: "ganttContextMenuItem",
+				innerHTML: tab.Description
+			});
+			dojo.attr(cell, "tabIndex", 0);
+			this.ganttChart._events.push(
+				dojo.connect(cell, "onclick", this, function(){
+					try{
+						this.hide();
+						tab.show();
+					}catch(e){
+						console.log("dialog open exception: " + e.message);
+					}
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(cell, "onkeydown", this, function(e){
+					if(e.keyCode != dojo.keys.ENTER){return;}
+					try{
+						this.hide();
+						tab.show();
+					}catch(e){
+						console.log("dialog open exception: " + e.message);
+					}
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(cell, "onmouseover", this, function(){
+					dojo.addClass(cell, "ganttContextMenuItemHover");
+				})
+			);
+			this.ganttChart._events.push(
+				dojo.connect(cell, "onmouseout", this, function(){
+					dojo.removeClass(cell, "ganttContextMenuItemHover");
+				})
+			);
+			row.appendChild(cell);
+		},
+		show: function(elem, object){
+			if(object.constructor == dojox.gantt.GanttTaskControl){
+				dojo.forEach(this.arrTabs, function(tab){
+					if(tab.type == "t"){
+						tab.object = object;
+						this.addItemMenuPanel(tab);
+					}
+				}, this);
+			}else if(object.constructor == dojox.gantt.GanttProjectControl){
+				dojo.forEach(this.arrTabs, function(tab){
+					if(tab.type == "p"){
+						tab.object = object;
+						this.addItemMenuPanel(tab);
+					}
+				}, this);
+			}
+			this.isShow = true;
+			dojo.style(this.menuPanel, {
+				zIndex: 15,
+				visibility: "visible"
+			});
+			//make sure menu box inside gantt's bounding box
+			var menuBox = dojo.position(this.menuPanel, true),
+				bBox = dojo.position(this.ganttChart.content, true),
+				pos = dojo.coords(elem, true);
+			if((pos.y + menuBox.h) > (bBox.y + bBox.h + 50)){
+				this.menuPanel.style.top = pos.y - menuBox.h + pos.h + "px";
+			}else{
+				this.menuPanel.style.top = pos.y + "px";
+			}
+			if(dojo._isBodyLtr()){
+				this.menuPanel.style.left = pos.x + pos.w + 5 + "px";
+			}else{
+				this.menuPanel.style.left = pos.x - menuBox.w - 5 + "px";
+			}
+		},
+		hide: function(){
+			this.isShow = false;
+			this.menuPanel.style.visibility = "hidden";
+		},
+		clear: function(){
+			this.menuPanel.removeChild(this.menuPanel.firstChild);
+			this.menuPanel.innerHTML = "<table></table>";
+			dojo.addClass(this.menuPanel.firstChild, "ganttContextMenu");
+			this.menuPanel.firstChild.cellPadding = 0;
+			this.menuPanel.firstChild.cellSpacing = 0;
+		},
+		createTab: function(id, desc, type, showOInfo, menu, withDefaultValue){
+			var tab = new dojox.gantt.contextMenuTab(id, desc, type, showOInfo, menu, withDefaultValue);
+			this.arrTabs.push(tab);
+			return tab;
+		}
+	});
+	
+	dojo.declare("dojox.gantt.contextMenuTab", null, {
+		constructor: function(id, description, type, showOInfo, tabMenu, withDefaultValue){
+			this.id = id;
+			this.arrItems = [];
+			this.TabItemContainer = null;
+			this.Description = description;
+			this.tabMenu = tabMenu;
+			this.type = type;
+			this.object = null;
+			this.showObjectInfo = showOInfo;
+			this.withDefaultValue = withDefaultValue;
+		},
+		preValueValidation: function(items){
+			for(var i = 0; i < items.length; i++){
+				var item = items[i];
+				//TODO add more validation for Id, Name, .....
+				if(item.required && !item.control.textbox.value){
+					return false;
+				}
+			}
+			return true;
+		},
+		encodeDate: function(date){
+			return date.getFullYear() + "." + (date.getMonth() + 1) + "." + date.getDate();
+		},
+		decodeDate: function(dateStr){
+			var arr = dateStr.split(".");
+			return (arr.length < 3) ? "" : (new Date(arr[0], parseInt(arr[1]) - 1, arr[2]));
+		},
+		renameTaskAction: function(){
+			var name = this.arrItems[0].control.textbox.value;
+			if(dojo.trim(name).length <= 0){
+				return;
+			}
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.setName(name);
+			this.hide();
+		},
+		deleteAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.project.deleteTask(this.object.taskItem.id);
+			this.hide();
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		durationUpdateAction: function(){
+			var d = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setDuration(d)){
+				this.hide();
+			}else{
+				alert("Duration out of Range");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.refresh();
+		},
+		cpUpdateAction: function(){
+			var p = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setPercentCompleted(p)){
+				this.hide();
+			}else{
+				alert("Complete Percentage out of Range");
+				return;
+			}
+		},
+		ownerUpdateAction: function(){
+			var to = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setTaskOwner(to)){
+				this.hide();
+			}else{
+				alert("Task owner not Valid");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		ptUpdateAction: function(){
+			var p = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setPreviousTask(p)){
+				this.hide();
+			}else{
+				alert("Please verify the Previous Task (" + p + ")  and adjust its Time Range");
+				return;
+			}
+		},
+		renameProjectAction: function(){
+			var name = this.arrItems[0].control.textbox.value;
+			if(dojo.trim(name).length <= 0){
+				return;
+			}
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.setName(name);
+			this.hide();
+		},
+		deleteProjectAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			this.object.ganttChart.deleteProject(this.object.project.id);
+			this.hide();
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		cpProjectAction: function(){
+			var p = this.arrItems[0].control.textbox.value;
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			if(this.object.setPercentCompleted(p)){
+				this.hide();
+			}else{
+				alert("Percentage not Acceptable");
+				return;
+			}
+		},
+		addTaskAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var id = this.arrItems[0].control.textbox.value,
+				name = this.arrItems[1].control.textbox.value,
+				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
+				duration = this.arrItems[3].control.textbox.value,
+				pc = this.arrItems[4].control.textbox.value,
+				owner = this.arrItems[5].control.textbox.value,
+				parentTaskId = this.arrItems[6].control.textbox.value,
+				predTaskId = this.arrItems[7].control.textbox.value;
+			if(dojo.trim(id).length <= 0){
+				return;
+			}
+			if(this.object.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		addSuccessorTaskAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var pr = this.object.project,
+				id = this.arrItems[0].control.textbox.value,
+				name = this.arrItems[1].control.textbox.value,
+				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
+				duration = this.arrItems[3].control.textbox.value,
+				pc = this.arrItems[4].control.textbox.value,
+				owner = this.arrItems[5].control.textbox.value;
+			if(dojo.trim(id).length <= 0){
+				return;
+			}
+			var parentTaskId = !this.object.parentTask ? "" : this.object.parentTask.taskItem.id;
+			var predTaskId = this.object.taskItem.id;
+			if(pr.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		addChildTaskAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var pr = this.object.project,
+				id = this.arrItems[0].control.textbox.value,
+				name = this.arrItems[1].control.textbox.value,
+				startTime = this.decodeDate(this.arrItems[2].control.textbox.value),
+				duration = this.arrItems[3].control.textbox.value,
+				pc = this.arrItems[4].control.textbox.value,
+				owner = this.arrItems[5].control.textbox.value,
+				parentTaskId = this.object.taskItem.id,
+				predTaskId = "";
+			if(dojo.trim(id).length <= 0){
+				return;
+			}
+			if(pr.insertTask(id, name, startTime, duration, pc, predTaskId, owner, parentTaskId)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		addProjectAction: function(){
+			if(!this.preValueValidation(this.arrItems)){
+				return;
+			}
+			var id = this.arrItems[0].control.textbox.value,
+			namePr = this.arrItems[1].control.textbox.value,
+			startDatePr = this.decodeDate(this.arrItems[2].control.textbox.value);
+			if(dojo.trim(id).length <= 0 || dojo.trim(namePr).length <= 0){
+				return;
+			}
+			if(this.tabMenu.ganttChart.insertProject(id, namePr, startDatePr)){
+				this.hide();
+			}else{
+				alert("Please adjust your Customization");
+				return;
+			}
+			this.tabMenu.ganttChart.resource && this.tabMenu.ganttChart.resource.reConstruct();
+		},
+		
+		addAction: function(handler){
+			this.actionFunc = this[handler];
+		},
+		addItem: function(id, name, key, required){
+			var inputControl;
+			if(key == "startTime" || key == "startDate"){
+				inputControl = new dijit.form.DateTextBox({type:"text", constraints:{datePattern:"yyyy.M.d", strict:true}});
+			}else if(key == "percentage"){
+				inputControl = new dijit.form.NumberSpinner({ constraints:{ max:100, min:0 }});
+			}else if(key == "duration"){
+				inputControl = new dijit.form.NumberSpinner({ constraints:{ min:0 }});
+			}else{
+				inputControl = new dijit.form.TextBox();
+			}
+			this.arrItems.push({
+				id: id,
+				name: name,
+				control: inputControl,
+				tab: this,
+				key: key,
+				required: required
+			});
+		},
+		show: function(){
+			this.tabMenu.tabPanelDlg = this.tabMenu.tabPanelDlg || dijit.byId(this.tabMenu.tabPanelDlgId) ||
+				new dijit.Dialog({
+					title: "Settings"
+				});
+			try{
+				this.tabMenu.tabPanelDlg.show();
+			}catch(e){
+				console.log("dialog show exception: " + e.message);
+				return;
+			}
+			this.tabMenu.tabPanelDlg.titleNode.innerHTML = this.Description;
+			var content = this.tabMenu.paneContentArea.firstChild.rows[1].cells[0].firstChild,
+				action = this.tabMenu.paneActionBar;
+			var cell, cellValue, row = null;
+			
+			if(this.showObjectInfo){
+				if(this.object){
+					if(this.object.constructor == dojox.gantt.GanttTaskControl){
+						this.insertData(content, "Id", this.object.taskItem.id);
+						this.insertData(content, "Name", this.object.taskItem.name);
+						this.insertData(content, "Start Time", this.encodeDate(this.object.taskItem.startTime));
+						this.insertData(content, "Duration (hours)", this.object.taskItem.duration + " hours");
+						this.insertData(content, "Percent Complete (%)", this.object.taskItem.percentage + "%");
+						this.insertData(content, "Task Assignee", this.object.taskItem.taskOwner);
+						this.insertData(content, "Previous Task Id", this.object.taskItem.previousTaskId);
+					}else{
+						this.insertData(content, "Id", this.object.project.id);
+						this.insertData(content, "Name", this.object.project.name);
+						this.insertData(content, "Start date", this.encodeDate(this.object.project.startDate));
+					}
+				}
+			}
+			//separator
+			row = content.insertRow(content.rows.length);
+			cell = row.insertCell(row.cells.length);
+			cell.colSpan = 2;
+			cell.innerHTML = "<hr/>";
+			//input section header
+			row = content.insertRow(content.rows.length);
+			cell = row.insertCell(row.cells.length);
+			cell.colSpan = 2;
+			dojo.addClass(cell, "ganttMenuDialogInputCellHeader");
+			cell.innerHTML = "Customization: " + this.Description;
+			//input details
+			dojo.forEach(this.arrItems, function(item){
+				row = content.insertRow(content.rows.length);
+				cell = row.insertCell(row.cells.length);
+				dojo.addClass(cell, "ganttMenuDialogInputCell");
+				cellValue = row.insertCell(row.cells.length);
+				dojo.addClass(cellValue, "ganttMenuDialogInputCellValue");
+				cell.innerHTML = item.name;
+				cellValue.appendChild(item.control.domNode);
+				//initialize default value
+				if(this.withDefaultValue && this.object){
+					if(this.object.constructor == dojox.gantt.GanttTaskControl){
+						if(item.key == "startTime"){
+							item.control.textbox.value = this.encodeDate(this.object.taskItem.startTime);
+						}else{
+							item.control.textbox.value = item.key ? this.object.taskItem[item.key] : "";
+						}
+					}else{
+						if(item.key == "startDate"){
+							item.control.textbox.value = this.encodeDate(this.object.project.startDate);
+						}else{
+							item.control.textbox.value = item.key ? (this.object.project[item.key] || this.object[item.key] || "") : "";
+						}
+					}
+				}else{
+					//HTML5 placeholder property
+					item.control.textbox.placeholder = item.required ? "---required---" : "---optional---";
+				}
+			}, this);
+			this.tabMenu.ok.onClick = dojo.hitch(this, this.actionFunc);
+			this.tabMenu.cancel.onClick = dojo.hitch(this, this.hide);
+		},
+		hide: function(){
+			try{
+				this.tabMenu.tabPanelDlg.hide();
+			}catch(e){
+				console.log("dialog show exception: " + e.message);
+				this.tabMenu.tabPanelDlg.destroy();
+			}
+			var cell = this.tabMenu.paneContentArea.firstChild.rows[1].cells[0];
+			cell.firstChild.parentNode.removeChild(cell.firstChild);
+			cell.innerHTML = "<table></table>";
+			dojo.addClass(cell.firstChild, "ganttDialogContentCell");
+		},
+		insertData: function(content, name, value){
+			var cell, cellValue, row = null;
+			row = content.insertRow(content.rows.length);
+			cell = row.insertCell(row.cells.length);
+			dojo.addClass(cell, "ganttMenuDialogDescCell");
+			cell.innerHTML = name;
+			cellValue = row.insertCell(row.cells.length);
+			dojo.addClass(cellValue, "ganttMenuDialogDescCellValue");
+			cellValue.innerHTML = value;
+		}
+	});
+})();
diff --git a/dojox/gantt/resources/gantt.css b/dojox/gantt/resources/gantt.css
new file mode 100644
index 0000000..0f17a2a
--- /dev/null
+++ b/dojox/gantt/resources/gantt.css
@@ -0,0 +1,575 @@
+.ganttToolbarZoomIn {
+	background-image: url("images/zoomIn.png");
+	background-repeat: no-repeat;
+	height: 30px;
+	width: 30px;
+	padding: 2px;
+}
+.ganttToolbarZoomOut {
+	background-image: url("images/zoomOut.png");
+	background-repeat: no-repeat;
+	height: 30px;
+	width: 30px;
+	padding: 2px;
+}
+.ganttToolbarMicro {
+	background-image: url("images/zoomInTime.png");
+	background-repeat: no-repeat;
+	height: 30px;
+	width: 30px;
+	padding: 2px;
+}
+.ganttToolbarTele {
+	background-image: url("images/zoomOutTime.png");
+	background-repeat: no-repeat;
+	height: 30px;
+	width: 30px;
+	padding: 2px;
+}
+.ganttToolbarSave {
+	background-image: url("images/save.png");
+	background-repeat: no-repeat;
+	height: 30px;
+	width: 30px;
+	padding: 2px;
+}
+.ganttToolbarLoad {
+	background-image: url("images/load.png");
+	background-repeat: no-repeat;
+	height: 30px;
+	width: 30px;
+	padding: 2px;
+}
+.ganttToolbarActionHover{
+	border: 2px solid blue;
+	padding: 0px;
+}
+.ganttToolbar {
+	cursor: pointer;
+}
+.ganttPanelHeader{
+	position: relative;
+}
+.ganttPanelNameHeaders{
+	position: relative;
+	overflow: hidden;
+}
+.ganttPanelNamesContainer{
+	position: relative;
+	overflow: hidden;
+	border-left: #f1f3f1 1px solid;
+	border-bottom: #f1f3f1 1px solid;
+}
+.ganttPanelNames{
+	position: relative;
+	overflow: hidden;
+	border-left: #f1f3f1 1px solid;
+	border-bottom: #f1f3f1 1px solid;
+	background: url("images/bg.png") repeat scroll 0 0 transparent;
+}
+.ganttPanelTime{
+	position: relative;
+}
+.ganttPanelTimeContainer{
+	position: relative;
+	overflow: hidden;
+	direction: ltr;
+}
+.ganttContentDataContainer{
+	position: relative;
+	overflow: scroll;
+	border-left: #f1f3f1 1px solid;
+	direction: ltr;
+}
+.ganttDivCell{
+	position: relative;
+}
+.ganttMoveInfo {
+	font-family: Tahoma, Arial;
+	font-size: 10px;
+	color: #006600;
+	white-space: nowrap;
+}
+.ganttDescProject {
+	font-family: Tahoma, Arial;
+	font-size: 10px;
+	color: #3B3B3B;
+	cursor: default;
+	white-space: nowrap;
+	z-index: 6;
+	position: absolute;
+}
+.ganttProjectNameItem{
+	cursor:pointer;
+	color: #003366;
+	font-weight: bold;
+	font-size: 12px;
+	font-family: Tahoma, Arial;
+	white-space:nowrap;
+	height:15px;
+	z-index:6;
+	position: absolute;
+}
+.ganttProjectNameItemHover{
+	border-top: 1px solid black;
+	border-bottom: 1px solid black;
+}
+.ganttProjectItem{
+	z-index: 6;
+	position: absolute;
+}
+.ganttTblProjectItem{
+	border: solid 1px #555555;
+}
+.ganttDivTaskInfo{
+	text-align: center;
+	z-index: 7;
+	position: absolute;
+	left: 0px;
+	top: 0px;
+}
+.ganttTblTime {
+	background-color: transparent;
+	cursor: pointer;
+	margin-top: 0px;
+}
+.ganttHourNumber {
+	font-size: 7px;
+	color: #858585;
+	border: 1px solid transparent;
+	border-top: 1px solid #DBECFF;
+	height: 30px;
+}
+.ganttHourClass {
+	text-align: center;
+	padding: 5px 2px;
+	height: 20px;
+}
+.ganttHourNumberAM {
+	background: url("images/am.png") repeat scroll 0 0 transparent;
+}
+.ganttHourNumberPM {
+	background: url("images/pm.png") repeat scroll 0 0 transparent;
+}
+.ganttDayNumber {
+	font-family: Tahoma, Arial;
+	font-weight: bold;
+	font-size: 9px;
+	color: #858585;
+	border: 1px solid transparent;
+	border-top: 1px solid #DBECFF;
+	height: 30px;
+}
+.ganttDayNumberWeekend {
+	background: url("images/bg.png") repeat scroll 0 0 transparent;
+}
+.ganttWeekNumber {
+	font-family: Tahoma, Arial;
+	font-weight: bold;
+	font-size: 9px;
+	color: #858585;
+	border: 1px solid transparent;
+	border-top: 1px solid #DBECFF;
+	border-right: 1px solid #DBECFF;
+	height:30px;
+}
+.ganttMonthNumber {
+	font-family: Tahoma, Arial;
+	font-weight: bold;
+	font-size: 9px;
+	color: #858585;
+	border: 1px solid transparent;
+	border-top: 1px solid #DBECFF;
+	border-right: 1px solid #DBECFF;
+	height: 30px;
+}
+.ganttYearNumber {
+	font-family: Tahoma, Arial;
+	font-weight: bold;
+	font-size: 9px;
+	color: #858585;
+	border: 1px solid transparent;
+	border-top: 1px solid #DBECFF;
+	border-right: 1px solid #DBECFF;
+	height: 30px;
+}
+.ganttTabelControl{
+	width: 100%; 
+	position: relative;
+}
+.ganttContextMenu {
+	z-index: 10;
+	width: 200px;
+	cursor: pointer;
+	font-family: Tahoma, Arial;
+	font-size: 12px;
+	border: 1px solid #b5bcc7;
+	margin: 0px;
+	padding: 0px;
+	background-color: #fff;
+	background-repeat: repeat-x;
+	border-collapse: separate;
+	border-spacing: 0 0;
+}
+.ganttContextMenuItem {
+	background-image: url("images/menuHighlight.png");
+	background-position:0px -40px;
+	background-repeat:repeat-x;
+	padding: 3px 10px 4px;
+	height:18px;
+}
+.ganttContextMenuItemHover {
+	border:solid 1px #769dc0;
+	padding: 2px 9px 3px;
+	background-color: #9dcfff;
+	background-position:0px 0px;
+	color:#000;
+}
+.ganttMenuDialogDescCell{
+	width:150px;
+	padding: 3px;
+	border-bottom: 1px solid gray;
+	text-align: center;
+}
+.ganttMenuDialogDescCellValue{
+	width:150px;
+	padding: 3px;
+	border-bottom: 1px solid gray;
+	text-align: center;
+}
+.ganttMenuDialogInputCellHeader{
+	font-size:12px;
+	font-family:Tahoma,Arial;
+	font-weight: bold;
+	padding: 10px 3px 5px;
+}
+.ganttMenuDialogInputCell{
+	padding: 3px;
+}
+.ganttMenuDialogInputCellValue{
+	padding: 3px;
+}
+.ganttHeaderCover {
+	z-index: 999;
+	position: absolute;
+}
+.ganttResourceHeader {
+	font-family: Tahoma, Arial;
+	background: url("images/resourceHeader.png") repeat scroll 0 0 transparent;
+	color: black;
+	padding: 3px 0px 0px 6px;
+	height: 25px;
+	font-weight: bold;
+	position:relative;
+}
+.ganttResourceContent{
+	position:relative;
+}
+.ganttTaskNameItem {
+	font-family: Tahoma, Arial;
+	font-size: 11px;
+	font-weight: bold;
+	color: #7D7D7D;
+	white-space:nowrap;
+	height:15px;
+	z-index:1;
+	position: absolute;
+	left:20px;
+}
+.ganttMenuPanel{
+	visibility:hidden;
+	z-index:10;
+	position:absolute;
+}
+.ganttDialogContentCell{
+	width:300px;
+	font-size:11px;
+	font-family:Tahoma,Arial;
+}
+.ganttDialogContentHeader{
+	font-size:12px;
+	font-family:Tahoma,Arial;
+	font-weight: bold;
+}
+.ganttOwnerNameItem {
+	font-family: Tahoma, Arial;
+	font-size: 11px;
+	font-weight: bold;
+	color: black;
+	cursor:pointer;
+	white-space:nowrap;
+	height:15px;
+	z-index:1;
+	position: absolute;
+	left:20px;
+}
+.ganttTaskBar {
+	background: url("images/taskBar.png") repeat scroll 0 0 transparent;
+	-moz-border-radius: 10px;
+	z-index:1;
+	position:absolute;
+}
+.ganttOwnerBar {
+	z-index:1;
+	position:absolute;
+}
+.ganttOwnerTaskBar {
+	background: url("images/ownerBar.png") repeat scroll 0 0 transparent;
+	border-top: solid 1px black;
+	border-bottom: solid 1px black;
+	position:absolute;
+	top:0px;
+}
+.ganttRowHighlight {
+	background: url("images/rowHighlight.png") repeat scroll 0 0 transparent;
+	position: absolute;
+	z-index: 1;
+}
+.ganttTaskPanel {
+	background: url("images/bg.png") repeat scroll 0 0 transparent;
+	overflow: hidden;
+	position:relative;
+}
+.ganttOwnerPanel {
+	overflow: hidden;
+	position:relative;
+	background: url("images/resourceBg.png") repeat scroll 0 0 transparent;
+}
+.ganttContent {
+	margin: 15px 63px 0;
+}
+.ganttTaskLineVerticalLeft{
+	border-width: 0px 0px 0px 1px; 
+	border-style: dotted; 
+	border-color: #86A3BE; 
+	margin: 0px; 
+	padding: 0px;
+	z-index:10;
+	position: absolute;
+}
+.ganttTaskLineHorizontalLeft{
+	position: absolute;
+	border-width: 1px 0px 0px 0px;
+	font-size: 1px;
+	border-style: dotted; 
+	border-color: #86A3BE;
+	margin: 0px; 
+	padding: 0px;
+	z-index:10;
+}
+.ganttTaskLineVerticalRight{
+	border-width: 0px 0px 0px 1px; 
+	border-style: solid; 
+	border-color: #4A8F43;
+	margin: 0px; 
+	padding: 0px;
+	z-index:6;
+	font-size: 1px;
+	position: absolute;
+}
+.ganttTaskLineHorizontal{
+	height:1px;
+	border-color: #4A8F43;
+	border-style: solid;
+	border-width: 1px 0px 0px 0px;
+	margin: 0px; 
+	padding: 0px;
+	z-index:6;
+	position: absolute;
+}
+.ganttTaskArrowImg{
+	z-index:6;
+	margin: 0px; 
+	padding: 0px;
+	width:7px;
+	height:14px;
+	position: absolute;
+}
+.ganttTaskLineVerticalRightPlus{
+	border-width: 0px 0px 0px 1px; 
+	border-style: solid; 
+	border-color: #519145;
+	margin: 0px; 
+	padding: 0px;
+	z-index:6;
+	font-size: 1px;
+	position: absolute;
+}
+.ganttTaskLineHorizontalPlus{
+	height:1px;
+	border-color: #519145;
+	border-style: solid;
+	border-width: 1px 0px 0px 0px;
+	margin: 0px; 
+	padding: 0px;
+	z-index:6;
+	position: absolute;
+}
+.ganttTaskArrowImgPlus{
+	z-index:6;
+	margin: 0px; 
+	padding: 0px;
+	width:7px;
+	height:14px;
+	position: absolute;
+}
+.ganttTaskItemControl{
+	z-index:6;
+	position:absolute;
+}
+.ganttTaskDivTaskItem{
+	z-index:6;
+	position: absolute;
+	left:0px;
+	top:0px;
+}
+.ganttTaskTblTaskItem{
+	border: solid 1px #5FF55F;
+}
+.ganttTaskDivTaskInfo{
+	text-align:center;
+	font-size:9px;
+	z-index:7;
+	position: absolute;
+	left:0px;
+	top:0px;
+}
+.ganttTaskDivTaskName{
+	z-index:7;
+	position: absolute;
+	left:0px;
+	top:0px;
+}
+.ganttTaskDivMoveInput{
+	visibility:hidden;
+	width:1px;
+	height:1px;
+}
+.ganttTaskDivResizeInput{
+	visibility:hidden;
+	width:1px;
+	height:1px;
+}
+.ganttTaskDivResize{
+	z-index:10;
+	position: absolute;
+	top:0px;
+}
+.ganttTaskTaskNameItem{
+	font-family: Tahoma, Arial;
+	cursor:pointer;
+	white-space:nowrap;
+	height:15px;
+	z-index:6;
+	position: absolute;
+	left:20px;
+}
+.ganttTaskTaskNameItemHover{
+	border-top: 1px solid black;
+	border-bottom: 1px solid black;
+}
+.ganttTaskDescTask {
+	font-family: Tahoma, Arial;
+	font-size: 10px;
+	color: #008000;
+	cursor: default;
+	white-space: nowrap;
+	z-index:6;
+	position:absolute;
+}
+.ganttTaskIdentifier{
+	color:#7D7D7D;
+	font-family:Tahoma,Arial;
+	font-size:11px;
+	font-weight:bold;
+	border: solid 1px #7D7D7D;
+	-moz-border-radius: 20px;
+	-khtml-border-radius: 20px;
+	-webkit-border-radius: 20px;
+	border-radius: 20px;
+	padding: 0px 3px;
+	cursor:pointer;
+	white-space:nowrap;
+	height:14px;
+	z-index:6;
+	position:absolute;
+}
+.ganttTaskTreeImage{
+	cursor: pointer;
+	z-index:12;
+	position: absolute;
+}
+
+.ganttResourceTableControl{
+	width: 100%; 
+	position: relative;
+}
+.ganttResourceContentDataContainer{
+	position:relative;
+	overflow:scroll;
+	border-left:#f1f3f1 1px solid;
+	direction: ltr;
+}
+.ganttResourcePanelNames{
+	position:relative;
+	overflow:hidden;
+	border-left:#f1f3f1 1px solid;
+	border-bottom:#f1f3f1 1px solid;
+}
+.ganttResourceDivCell{
+	position: relative;
+}
+.ganttResourceLineVerticalLeft{
+	border-width: 0px 0px 0px 1px; 
+	border-style: dotted; 
+	border-color: #86A3BE; 
+	margin: 0px; 
+	padding: 0px;
+	z-index:10;
+	position: absolute;
+}
+.ganttResourceLineHorizontalLeft{
+	z-index:10;
+	height:1px;
+	position: absolute;
+	border-width: 1px 0px 0px 0px;
+	font-size: 1px;
+	border-style: dotted; 
+	border-color: #86A3BE;
+	margin: 0px; 
+	padding: 0px;
+}
+.ganttResourceTreeImage{
+	cursor: pointer;
+	z-index:12;
+	position: absolute;
+}
+.ganttResourcePanelNamesOwners{
+	position:relative;
+	background: url("images/resourceBg.png") repeat scroll 0 0 transparent;
+}
+.ganttImageProgressFilled{
+	background: url("images/projProgressFilled.png") repeat scroll 0 0 transparent;
+}
+.ganttImageProgressBg{
+	background: url("images/projProgressBg.png") repeat scroll 0 0 transparent;
+}
+.ganttImageTaskProgressFilled{
+	background: url("images/taskProgressFilled.png") repeat scroll 0 0 transparent;
+}
+.ganttImageTaskProgressBg{
+	background: url("images/taskProgressBg.png") repeat scroll 0 0 transparent;
+}
+.ganttImageTreeCollapse{
+	background: url("images/collapse.png") no-repeat scroll 0 0 transparent;
+	height: 9px;
+	width: 9px;
+}
+.ganttImageTreeExpand{
+	background: url("images/expand.png") no-repeat scroll 0 0 transparent;
+	height: 9px;
+	width: 9px;
+}
+.ganttImageArrow{
+	background: url("images/taskArrow.gif") no-repeat scroll 0 0 transparent;
+}
diff --git a/dojox/gantt/resources/images/am.png b/dojox/gantt/resources/images/am.png
new file mode 100644
index 0000000..94b127e
Binary files /dev/null and b/dojox/gantt/resources/images/am.png differ
diff --git a/dojox/gantt/resources/images/arrow.gif b/dojox/gantt/resources/images/arrow.gif
new file mode 100644
index 0000000..3bd0863
Binary files /dev/null and b/dojox/gantt/resources/images/arrow.gif differ
diff --git a/dojox/gantt/resources/images/bg.png b/dojox/gantt/resources/images/bg.png
new file mode 100644
index 0000000..a6cd044
Binary files /dev/null and b/dojox/gantt/resources/images/bg.png differ
diff --git a/dojox/gantt/resources/images/collapse.png b/dojox/gantt/resources/images/collapse.png
new file mode 100644
index 0000000..1ae0697
Binary files /dev/null and b/dojox/gantt/resources/images/collapse.png differ
diff --git a/dojox/gantt/resources/images/expand.png b/dojox/gantt/resources/images/expand.png
new file mode 100644
index 0000000..14a4f6d
Binary files /dev/null and b/dojox/gantt/resources/images/expand.png differ
diff --git a/dojox/gantt/resources/images/load.png b/dojox/gantt/resources/images/load.png
new file mode 100644
index 0000000..df33667
Binary files /dev/null and b/dojox/gantt/resources/images/load.png differ
diff --git a/dojox/gantt/resources/images/menuHighlight.png b/dojox/gantt/resources/images/menuHighlight.png
new file mode 100644
index 0000000..22328a7
Binary files /dev/null and b/dojox/gantt/resources/images/menuHighlight.png differ
diff --git a/dojox/gantt/resources/images/minus.gif b/dojox/gantt/resources/images/minus.gif
new file mode 100644
index 0000000..470c673
Binary files /dev/null and b/dojox/gantt/resources/images/minus.gif differ
diff --git a/dojox/gantt/resources/images/ownerBar.png b/dojox/gantt/resources/images/ownerBar.png
new file mode 100644
index 0000000..da9aa60
Binary files /dev/null and b/dojox/gantt/resources/images/ownerBar.png differ
diff --git a/dojox/gantt/resources/images/parentnode_bg.png b/dojox/gantt/resources/images/parentnode_bg.png
new file mode 100644
index 0000000..e58367b
Binary files /dev/null and b/dojox/gantt/resources/images/parentnode_bg.png differ
diff --git a/dojox/gantt/resources/images/parentnode_filled.png b/dojox/gantt/resources/images/parentnode_filled.png
new file mode 100644
index 0000000..d2bba7b
Binary files /dev/null and b/dojox/gantt/resources/images/parentnode_filled.png differ
diff --git a/dojox/gantt/resources/images/plus.gif b/dojox/gantt/resources/images/plus.gif
new file mode 100644
index 0000000..ff22238
Binary files /dev/null and b/dojox/gantt/resources/images/plus.gif differ
diff --git a/dojox/gantt/resources/images/pm.png b/dojox/gantt/resources/images/pm.png
new file mode 100644
index 0000000..0e01327
Binary files /dev/null and b/dojox/gantt/resources/images/pm.png differ
diff --git a/dojox/gantt/resources/images/progress_bg.png b/dojox/gantt/resources/images/progress_bg.png
new file mode 100644
index 0000000..69205da
Binary files /dev/null and b/dojox/gantt/resources/images/progress_bg.png differ
diff --git a/dojox/gantt/resources/images/progress_filled.png b/dojox/gantt/resources/images/progress_filled.png
new file mode 100644
index 0000000..6f2c1c7
Binary files /dev/null and b/dojox/gantt/resources/images/progress_filled.png differ
diff --git a/dojox/gantt/resources/images/projProgressBg.png b/dojox/gantt/resources/images/projProgressBg.png
new file mode 100644
index 0000000..e58367b
Binary files /dev/null and b/dojox/gantt/resources/images/projProgressBg.png differ
diff --git a/dojox/gantt/resources/images/projProgressFilled.png b/dojox/gantt/resources/images/projProgressFilled.png
new file mode 100644
index 0000000..d2bba7b
Binary files /dev/null and b/dojox/gantt/resources/images/projProgressFilled.png differ
diff --git a/dojox/gantt/resources/images/rbg.png b/dojox/gantt/resources/images/rbg.png
new file mode 100644
index 0000000..71f7daa
Binary files /dev/null and b/dojox/gantt/resources/images/rbg.png differ
diff --git a/dojox/gantt/resources/images/resourceBg.png b/dojox/gantt/resources/images/resourceBg.png
new file mode 100644
index 0000000..71f7daa
Binary files /dev/null and b/dojox/gantt/resources/images/resourceBg.png differ
diff --git a/dojox/gantt/resources/images/resourceHeader.png b/dojox/gantt/resources/images/resourceHeader.png
new file mode 100644
index 0000000..b6f7c6a
Binary files /dev/null and b/dojox/gantt/resources/images/resourceHeader.png differ
diff --git a/dojox/gantt/resources/images/rheader.png b/dojox/gantt/resources/images/rheader.png
new file mode 100644
index 0000000..b6f7c6a
Binary files /dev/null and b/dojox/gantt/resources/images/rheader.png differ
diff --git a/dojox/gantt/resources/images/rowHighlight.png b/dojox/gantt/resources/images/rowHighlight.png
new file mode 100644
index 0000000..3dd4e94
Binary files /dev/null and b/dojox/gantt/resources/images/rowHighlight.png differ
diff --git a/dojox/gantt/resources/images/save.png b/dojox/gantt/resources/images/save.png
new file mode 100644
index 0000000..0527fc5
Binary files /dev/null and b/dojox/gantt/resources/images/save.png differ
diff --git a/dojox/gantt/resources/images/taskArrow.gif b/dojox/gantt/resources/images/taskArrow.gif
new file mode 100644
index 0000000..3bd0863
Binary files /dev/null and b/dojox/gantt/resources/images/taskArrow.gif differ
diff --git a/dojox/gantt/resources/images/taskBar.png b/dojox/gantt/resources/images/taskBar.png
new file mode 100644
index 0000000..e5245d2
Binary files /dev/null and b/dojox/gantt/resources/images/taskBar.png differ
diff --git a/dojox/gantt/resources/images/taskProgressBg.png b/dojox/gantt/resources/images/taskProgressBg.png
new file mode 100644
index 0000000..69205da
Binary files /dev/null and b/dojox/gantt/resources/images/taskProgressBg.png differ
diff --git a/dojox/gantt/resources/images/taskProgressFilled.png b/dojox/gantt/resources/images/taskProgressFilled.png
new file mode 100644
index 0000000..6f2c1c7
Binary files /dev/null and b/dojox/gantt/resources/images/taskProgressFilled.png differ
diff --git a/dojox/gantt/resources/images/zoomin.png b/dojox/gantt/resources/images/zoomin.png
new file mode 100644
index 0000000..254c5cb
Binary files /dev/null and b/dojox/gantt/resources/images/zoomin.png differ
diff --git a/dojox/gantt/resources/images/zoomintime.png b/dojox/gantt/resources/images/zoomintime.png
new file mode 100644
index 0000000..459346a
Binary files /dev/null and b/dojox/gantt/resources/images/zoomintime.png differ
diff --git a/dojox/gantt/resources/images/zoomout.png b/dojox/gantt/resources/images/zoomout.png
new file mode 100644
index 0000000..dfc2dc0
Binary files /dev/null and b/dojox/gantt/resources/images/zoomout.png differ
diff --git a/dojox/gantt/resources/images/zoomouttime.png b/dojox/gantt/resources/images/zoomouttime.png
new file mode 100644
index 0000000..beea687
Binary files /dev/null and b/dojox/gantt/resources/images/zoomouttime.png differ
diff --git a/dojox/gantt/tests/saveGanttData.php b/dojox/gantt/tests/saveGanttData.php
new file mode 100644
index 0000000..ce77663
--- /dev/null
+++ b/dojox/gantt/tests/saveGanttData.php
@@ -0,0 +1,8 @@
+<?php
+$filename = $_POST['filename'];
+$data = $_POST['data'];
+$file = $filename;
+$f = fopen($file, 'w');
+fwrite($f, $data);
+fclose($f);
+?>
diff --git a/dojox/gantt/tests/test_Gantt.html b/dojox/gantt/tests/test_Gantt.html
new file mode 100644
index 0000000..2934cb9
--- /dev/null
+++ b/dojox/gantt/tests/test_Gantt.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+	<head>
+		<title>Gantt Chart</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>
+		<!-- required: the default dijit theme: -->
+		<link id="themeStyles" rel="stylesheet" href="../../../dijit/themes/claro/claro.css"/>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true">
+		</script>
+		<link type="text/css" rel="stylesheet" href="../resources/gantt.css">
+		<script type="text/javascript" language="JavaScript">
+			dojo.require("dojo.parser"); // scan page for widgets and instantiate them
+			dojo.require("dojox.gantt.GanttChart");
+			
+			dojo.addOnLoad(function(){
+				var projectDev = new dojox.gantt.GanttProjectItem({
+					id: 1,
+					name: "Development Project",
+					startDate: new Date(2006, 5, 11)
+				});
+				
+				var taskRequirement = new dojox.gantt.GanttTaskItem({
+					id: 1,
+					name: "Requirement",
+					startTime: new Date(2006, 5, 11),
+					duration: 50,
+					percentage: 50,
+					taskOwner: "Jack"
+				});
+				var taskAnalysis = new dojox.gantt.GanttTaskItem({
+					id: 2,
+					name: "Analysis",
+					startTime: new Date(2006, 5, 18),
+					duration: 40,
+					percentage: 80,
+					previousTaskId: "1",
+					taskOwner: "Michael"
+				});
+				var taskDesign = new dojox.gantt.GanttTaskItem({
+					id: 3,
+					name: "Design",
+					startTime: new Date(2006, 5, 18),
+					duration: 60,
+					percentage: 80,
+					previousTaskId: "1",
+					taskOwner: "Jason"
+				});
+				var taskDetailDesign = new dojox.gantt.GanttTaskItem({
+					id: 4,
+					name: "Detail design",
+					startTime: new Date(2006, 5, 18),
+					duration: 30,
+					percentage: 50,
+					previousTaskId: "1",
+					taskOwner: "Michael"
+				});
+				var taskDevelopmentDoc = new dojox.gantt.GanttTaskItem({
+					id: 5,
+					name: "Development doc",
+					startTime: new Date(2006, 5, 20),
+					duration: 20,
+					percentage: 10,
+					previousTaskId: "1",
+					taskOwner: "Rock;Jack"
+				});
+				
+				projectDev.addTask(taskRequirement);
+				projectDev.addTask(taskAnalysis);
+				projectDev.addTask(taskDesign);
+				projectDev.addTask(taskDetailDesign);
+				projectDev.addTask(taskDevelopmentDoc);
+				
+				var taskSketch = new dojox.gantt.GanttTaskItem({
+					id: 6,
+					name: "Sketch",
+					startTime: new Date(2006, 6, 1),
+					duration: 20,
+					percentage: 50,
+					previousTaskId: "3",
+					taskOwner: "Rock"
+				});
+				var taskPrototype = new dojox.gantt.GanttTaskItem({
+					id: 7,
+					name: "Prototype",
+					startTime: new Date(2006, 6, 6),
+					duration: 60,
+					percentage: 80,
+					previousTaskId: "6",
+					taskOwner: "Rock"
+				});
+				var taskImplementation = new dojox.gantt.GanttTaskItem({
+					id: 8,
+					name: "Implementation",
+					startTime: new Date(2006, 6, 6),
+					duration: 30,
+					percentage: 80,
+					previousTaskId: "6",
+					taskOwner: "Jason"
+				});
+				var taskDetailImplement = new dojox.gantt.GanttTaskItem({
+					id: 9,
+					name: "Detail Implement",
+					startTime: new Date(2006, 6, 17),
+					duration: 120,
+					percentage: 50,
+					previousTaskId: "7",
+					taskOwner: "Jason"
+				});
+				var taskDeliver = new dojox.gantt.GanttTaskItem({
+					id: 10,
+					name: "Deliver",
+					startTime: new Date(2006, 6, 18),
+					duration: 100,
+					percentage: 30,
+					previousTaskId: "8",
+					taskOwner: "Michael;Jason"
+				});
+				
+				projectDev.addTask(taskSketch);
+				projectDev.addTask(taskPrototype);
+				projectDev.addTask(taskImplementation);
+				projectDev.addTask(taskDetailImplement);
+				projectDev.addTask(taskDeliver);
+				
+				// Create Gantt control
+				var ganttChart = new dojox.gantt.GanttChart({
+					//readOnly: true,			//optional: gantt chart editable
+					//dataFilePath: "gnt.json",	//optional: json data file path for load and save, default is "gantt_default.json"
+					//withTaskId: false,		//optional: if true, task id will be on the right of task name, default value is !readOnly.
+					//animation: false,			//optional: whether you need animation when changing granularity of time line 
+					height: 400,				//optional: chart height in pixel, default is 400px
+					width: 1200,				//optional: chart width in pixel, default is 600px
+					withResource: true			//optional: with the resource chart or not
+				}, "gantt"); 					//"gantt" is the node container id of gantt chart widget
+				
+				// Add project data to gantt chart widget
+				ganttChart.addProject(projectDev);
+				
+				// Initialize and Render
+				ganttChart.init();
+				
+			});
+		</script>
+	</head>
+	<body class="claro">
+		<div class="ganttContent">
+			<div id="gantt">
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/geo/charting/Map.js b/dojox/geo/charting/Map.js
index 7979195..1f72ceb 100644
--- a/dojox/geo/charting/Map.js
+++ b/dojox/geo/charting/Map.js
@@ -9,7 +9,7 @@ dojo.declare("dojox.geo.charting.Map", null, {
 	//	summary:
 	//		Map widget interacted with charting.
 	//	description:
-	//		Support rendering Americas, AsiaPacific, ContinentalEurope, EuropeMiddleEastAfrica, 
+	//		Support rendering Americas, AsiaPacific, ContinentalEurope, EuropeMiddleEastAfrica,
 	//		USStates, WorldCountries, and WorldCountriesMercator by default.
 	//	example:
 	//	|	var usaMap = new dojox.geo.charting.Map(srcNode, "dojotoolkit/dojox/geo/charting/resources/data/USStates.json");
@@ -29,7 +29,7 @@ dojo.declare("dojox.geo.charting.Map", null, {
 		//		map container html node/id
 		//	shapeFile:
 		//		map shape data url, handled as json style
-		//		data format: 
+		//		data format:
 		
 		// get map container coords
 		dojo.style(container, "display", "block");
@@ -56,7 +56,7 @@ dojo.declare("dojox.geo.charting.Map", null, {
 	},
 	setMarkerData: function(/*String*/ markerFile){
 		//	summary:
-		//		import markers from outside file, associate with map feature by feature id 
+		//		import markers from outside file, associate with map feature by feature id
 		//		which identified in map shape file, e.g: "NY":"New York"
 		//	markerFile:
 		//		outside marker data url, handled as json style.
@@ -100,7 +100,7 @@ dojo.declare("dojox.geo.charting.Map", null, {
 			y:shapeData.layerExtent[1]
 		};
 		this.mapObj.setTransform([
-			dojox.gfx.matrix.scale(this.mapObj.scale), 
+			dojox.gfx.matrix.scale(this.mapObj.scale),
 			dojox.gfx.matrix.translate(-shapeData.layerExtent[0], -shapeData.layerExtent[1])
 		]);
 
diff --git a/dojox/gfx.js b/dojox/gfx.js
index 0b78ffb..e809d2d 100644
--- a/dojox/gfx.js
+++ b/dojox/gfx.js
@@ -4,55 +4,24 @@ 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.
+	// 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;
-	if(!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.
+	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;
-			return;
+			break;
 		}
 		var renderers = (typeof dojo.config.gfxRenderer == "string" ?
-			dojo.config.gfxRenderer : "svg,vml,silverlight,canvas").split(",");
-
-		// mobile platform detection
-		// TODO: move to the base?
-
-		var ua = navigator.userAgent, iPhoneOsBuild = 0, androidVersion = 0;
-		if(dojo.isSafari >= 3){
-			// detect mobile version of WebKit starting with "version 3"
-
-			//	comprehensive iPhone test.  Have to figure out whether it's SVG or Canvas based on the build.
-			//	iPhone OS build numbers from en.wikipedia.org.
-			if(ua.indexOf("iPhone") >= 0 || ua.indexOf("iPod") >= 0){
-				//	grab the build out of this.  Expression is a little nasty because we want
-				//		to be sure we have the whole version string.
-				match = ua.match(/Version\/(\d(\.\d)?(\.\d)?)\sMobile\/([^\s]*)\s?/);
-				if(match){
-					//	grab the build out of the match.  Only use the first three because of specific builds.
-					iPhoneOsBuild = parseInt(match[4].substr(0,3), 16);
-				}
-			}
-		}
-		if(dojo.isWebKit){
-			// Android detection
-			if(!iPhoneOsBuild){
-				match = ua.match(/Android\s+(\d+\.\d+)/);
-				if(match){
-					androidVersion = parseFloat(match[1]);
-					// Android 1.0-1.1 doesn't support SVG but supports Canvas
-				}
-			}
-		}
-
+			dojo.config.gfxRenderer : "svg,vml,canvas,silverlight").split(",");
 		for(var i = 0; i < renderers.length; ++i){
 			switch(renderers[i]){
 				case "svg":
-					//	iPhone OS builds greater than 5F1 should have SVG.
-					if(!dojo.isIE && (!iPhoneOsBuild || iPhoneOsBuild >= 0x5f1) && !androidVersion && !dojo.isAIR){
+					// the next test is from https://github.com/phiggins42/has.js
+					if("SVGAngle" in dojo.global){
 						dojox.gfx.renderer = "svg";
 					}
 					break;
@@ -78,25 +47,34 @@ dojo.loadInit(function(){
 					}finally{
 						sl = null;
 					}
-					if(flag){ dojox.gfx.renderer = "silverlight"; }
+					if(flag){
+						dojox.gfx.renderer = "silverlight";
+					}
 					break;
 				case "canvas":
-					//TODO: need more comprehensive test for Canvas
-					if(!dojo.isIE){
+					if(dojo.global.CanvasRenderingContext2D){
 						dojox.gfx.renderer = "canvas";
 					}
 					break;
 			}
-			if(dojox.gfx.renderer){ break; }
-		}
-		if(dojo.config.isDebug){
-			console.log("gfx renderer = " + dojox.gfx.renderer);
+			if(gfx.renderer){
+				break;
+			}
 		}
+		break;
+	}
+	
+	if(dojo.config.isDebug){
+		console.log("gfx renderer = " + gfx.renderer);
 	}
-});
 
-// include a renderer conditionally
-dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg");
-dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml");
-dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight");
-dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas");
+	// 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);
+	}
+});
diff --git a/dojox/gfx/Moveable.js b/dojox/gfx/Moveable.js
index 5a0796b..ebc027b 100644
--- a/dojox/gfx/Moveable.js
+++ b/dojox/gfx/Moveable.js
@@ -33,8 +33,9 @@ dojo.declare("dojox.gfx.Moveable", null, {
 		// 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.events.push(this.shape.connect("onmouseup", this, "onMouseUp"));
+			this.events.push(
+				this.shape.connect("onmousemove", this, "onMouseMove"),
+				this.shape.connect("onmouseup", this, "onMouseUp"));
 			this._lastX = e.clientX;
 			this._lastY = e.clientY;
 		}else{
diff --git a/dojox/gfx/_base.js b/dojox/gfx/_base.js
index bdecc6d..c3d1a49 100644
--- a/dojox/gfx/_base.js
+++ b/dojox/gfx/_base.js
@@ -11,7 +11,7 @@ dojo.provide("dojox.gfx._base");
 		// return (new RegExp('(^|\\s+)'+classStr+'(\\s+|$)')).test(node.className)	// Boolean
 		var cls = node.getAttribute("className");
 		return cls && (" " + cls + " ").indexOf(" " + classStr + " ") >= 0;  // Boolean
-	}
+	};
 	g._addClass = function(/*DomNode*/node, /*String*/classStr){
 		//	summary:
 		//		Adds the specified classes to the end of the class list on the
@@ -20,17 +20,17 @@ dojo.provide("dojox.gfx._base");
 		if(!cls || (" " + cls + " ").indexOf(" " + classStr + " ") < 0){
 			node.setAttribute("className", cls + (cls ? " " : "") + classStr);
 		}
-	}
+	};
 	g._removeClass = function(/*DomNode*/node, /*String*/classStr){
 		//	summary: Removes classes from node.
 		var cls = node.getAttribute("className");
 		if(cls){
 			node.setAttribute(
-				"className", 
+				"className",
 				cls.replace(new RegExp('(^|\\s+)' + classStr + '(\\s+|$)'), "$1$2")
 			);
 		}
-	}
+	};
 
 	// candidate for dojox.html.metrics (dynamic font resize handler is not implemented here)
 
@@ -52,20 +52,19 @@ dojo.provide("dojox.gfx._base");
 		}
 
 		//	set up the measuring node.
-		var div = dojo.doc.createElement("div");
-		var s = div.style;
-		s.position = "absolute";
-		s.left = "-100px";
-		s.top = "0px";
-		s.width = "30px";
-		s.height = "1000em";
-		s.borderWidth = "0px";
-		s.margin = "0px";
-		s.padding = "0px";
-		s.outline = "none";
-		s.lineHeight = "1";
-		s.overflow = "hidden";
-		dojo.body().appendChild(div);
+		var div = dojo.create("div", {style: {
+				position: "absolute",
+				left: "0",
+				top: "-100px",
+				width: "30px",
+				height: "1000em",
+				borderWidth: "0",
+				margin: "0",
+				padding: "0",
+				outline: "none",
+				lineHeight: "1",
+				overflow: "hidden"
+			}}, dojo.body());
 
 		//	do the measurements.
 		for(var p in heights){
@@ -74,7 +73,6 @@ dojo.provide("dojox.gfx._base");
 		}
 
 		dojo.body().removeChild(div);
-		div = null;
 		return heights; 	//	object
 	};
 
@@ -95,18 +93,16 @@ dojo.provide("dojox.gfx._base");
 								/*String?*/ className){
 		var m, s, al = arguments.length;
 		if(!measuringNode){
-			m = measuringNode = dojo.doc.createElement("div");
-			s = m.style;
-			s.position = "absolute";
-			s.left = "-10000px";
-			s.top = "0";
-			dojo.body().appendChild(m);
-		}else{
-			m = measuringNode;
-			s = m.style;
+			measuringNode = dojo.create("div", {style: {
+				position: "absolute",
+				top: "-10000px",
+				left: "0"
+			}}, dojo.body());
 		}
+		m = measuringNode;
 		// reset styles
 		m.className = "";
+		s = m.style;
 		s.borderWidth = "0";
 		s.margin = "0";
 		s.padding = "0";
@@ -183,7 +179,7 @@ dojo.mixin(dojox.gfx, {
 
 	// default geometric attributes
 	defaultStroke: {
-		type: "stroke", color: "black", style: "solid", width: 1, 
+		type: "stroke", color: "black", style: "solid", width: 1,
 		cap: "butt", join: 4
 	},
 	defaultLinearGradient: {
@@ -202,7 +198,7 @@ dojo.mixin(dojox.gfx, {
 		type: "pattern", x: 0, y: 0, width: 0, height: 0, src: ""
 	},
 	defaultFont: {
-		type: "font", style: "normal", variant: "normal", 
+		type: "font", style: "normal", variant: "normal",
 		weight: "normal", size: "10pt", family: "serif"
 	},
 
@@ -366,5 +362,16 @@ dojo.mixin(dojox.gfx, {
 	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];
+			});
+		}
 	}
 });
diff --git a/dojox/gfx/arc.js b/dojox/gfx/arc.js
index 30c8cea..6e5df46 100644
--- a/dojox/gfx/arc.js
+++ b/dojox/gfx/arc.js
@@ -4,23 +4,24 @@ dojo.require("dojox.gfx.matrix");
 
 (function(){
 	var m = dojox.gfx.matrix,
-		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
-			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
-				s:  {x: cosa, y: -sina},
-				c1: {x: p2.x, y: -p2.y},
-				c2: p2,
-				e:  {x: cosa, y: sina}
-			};
-		},
 		twoPI = 2 * Math.PI, pi4 = Math.PI / 4, pi8 = Math.PI / 8,
 		pi48 = pi4 + pi8, curvePI4 = unitArcAsBezier(pi8);
 
-	dojo.mixin(dojox.gfx.arc, {
+	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
+		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
+			s:  {x: cosa, y: -sina},
+			c1: {x: p2.x, y: -p2.y},
+			c2: p2,
+			e:  {x: cosa, y: sina}
+		};
+	}
+
+	dojox.gfx.arc = {
 		unitArcAsBezier: unitArcAsBezier,
 		curvePI4: curvePI4,
 		arcAsBezier: function(last, rx, ry, xRotg, large, sweep, x, y){
@@ -114,5 +115,5 @@ dojo.require("dojox.gfx.matrix");
 			}
 			return result;	// Array
 		}
-	});
+	};
 })();
diff --git a/dojox/gfx/attach.js b/dojox/gfx/attach.js
index 901f66f..f306b59 100644
--- a/dojox/gfx/attach.js
+++ b/dojox/gfx/attach.js
@@ -1,7 +1,11 @@
+dojo.provide("dojox.gfx.attach");
+
 dojo.require("dojox.gfx");
 
-// include an attacher conditionally
-dojo.requireIf(dojox.gfx.renderer == "svg", "dojox.gfx.svg_attach");
-dojo.requireIf(dojox.gfx.renderer == "vml", "dojox.gfx.vml_attach");
-dojo.requireIf(dojox.gfx.renderer == "silverlight", "dojox.gfx.silverlight_attach");
-dojo.requireIf(dojox.gfx.renderer == "canvas", "dojox.gfx.canvas_attach");
+// rename an attacher conditionally
+
+(function(){
+	var r = dojox.gfx.svg.attach[dojox.gfx.renderer];
+	dojo.gfx.attachSurface = r.attachSurface;
+	dojo.gfx.attachNode = r.attachNode;
+})();
diff --git a/dojox/gfx/canvas.js b/dojox/gfx/canvas.js
index 758605e..26061fe 100644
--- a/dojox/gfx/canvas.js
+++ b/dojox/gfx/canvas.js
@@ -9,10 +9,11 @@ dojo.require("dojox.gfx.decompose");
 dojo.experimental("dojox.gfx.canvas");
 
 (function(){
-	var d = dojo, g = dojox.gfx, gs = g.shape, ga = g.arc,
-		m = g.matrix, mp = m.multiplyPoint, pi = Math.PI, twoPI = 2 * pi, halfPI = pi /2;
+	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.extend(g.Shape, {
+	d.declare("dojox.gfx.canvas.Shape", gs.Shape, {
 		_render: function(/* Object */ ctx){
 			// summary: render the shape
 			ctx.save();
@@ -39,12 +40,32 @@ dojo.experimental("dojox.gfx.canvas");
 		},
 		_renderFill: function(/* Object */ ctx, /* Boolean */ apply){
 			if("canvasFill" in this){
+				var fs = this.fillStyle;
 				if("canvasFillImage" in this){
-					this.canvasFill = ctx.createPattern(this.canvasFillImage, "repeat");
+					var w = fs.width, h = fs.height,
+						iw = this.canvasFillImage.width, ih = this.canvasFillImage.height,
+						// let's match the svg default behavior wrt. aspect ratio: xMidYMid meet
+						sx = w == iw ? 1 : w / iw,
+						sy = h == ih ? 1 : h / ih,
+						s = Math.min(sx,sy), //meet->math.min , slice->math.max
+						dx = (w - s * iw)/2,
+						dy = (h - s * ih)/2;
+					// the buffer used to scaled the image
+					pattrnbuffer.width = w; pattrnbuffer.height = h;
+					var copyctx = pattrnbuffer.getContext("2d");
+					copyctx.clearRect(0, 0, w, h);
+					copyctx.drawImage(this.canvasFillImage, 0, 0, iw, ih, dx, dy, s*iw, s*ih);
+					this.canvasFill = ctx.createPattern(pattrnbuffer, "repeat");
 					delete this.canvasFillImage;
 				}
 				ctx.fillStyle = this.canvasFill;
-				if(apply){ ctx.fill(); }
+				if(apply){
+					// offset the pattern
+					if (fs.type==="pattern" && (fs.x !== 0 || fs.y !== 0)) {
+						ctx.translate(fs.x,fs.y);
+					}
+					ctx.fill();
+				}
 			}else{
 				ctx.fillStyle = "rgba(0,0,0,0.0)";
 			}
@@ -88,7 +109,7 @@ dojo.experimental("dojox.gfx.canvas");
 				};
 		};
 
-	modifyMethod(g.Shape, "setTransform",
+	modifyMethod(canvas.Shape, "setTransform",
 		function(){
 			// prepare Canvas-specific structures
 			if(this.matrix){
@@ -98,7 +119,7 @@ dojo.experimental("dojox.gfx.canvas");
 			}
 		});
 
-	modifyMethod(g.Shape, "setFill",
+	modifyMethod(canvas.Shape, "setFill",
 		function(){
 			// prepare Canvas-specific structures
 			var fs = this.fillStyle, f;
@@ -116,7 +137,13 @@ dojo.experimental("dojox.gfx.canvas");
 							});
 							break;
 						case "pattern":
-							var img = new Image(fs.width, fs.height);
+							if (!pattrnbuffer) {
+								pattrnbuffer = document.createElement("canvas");
+							}
+							// no need to scale the image since the canvas.createPattern uses
+							// the original image data and not the scaled ones (see spec.)
+							// the scaling needs to be done at rendering time in a context buffer
+							var img =new Image();
 							this.surface.downloadImage(img, fs.src);
 							this.canvasFillImage = img;
 					}
@@ -130,10 +157,10 @@ dojo.experimental("dojox.gfx.canvas");
 			}
 		});
 
-	modifyMethod(g.Shape, "setStroke");
-	modifyMethod(g.Shape, "setShape");
+	modifyMethod(canvas.Shape, "setStroke");
+	modifyMethod(canvas.Shape, "setShape");
 
-	dojo.declare("dojox.gfx.Group", g.Shape, {
+	dojo.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(){
@@ -143,8 +170,6 @@ dojo.experimental("dojox.gfx.canvas");
 			// summary: render the group
 			ctx.save();
 			this._renderTransform(ctx);
-			this._renderFill(ctx);
-			this._renderStroke(ctx);
 			for(var i = 0; i < this.children.length; ++i){
 				this.children[i]._render(ctx);
 			}
@@ -152,7 +177,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Rect", gs.Rect, {
+	dojo.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),
@@ -185,10 +210,10 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	})();
 
-	dojo.declare("dojox.gfx.Ellipse", gs.Ellipse, {
+	dojo.declare("dojox.gfx.canvas.Ellipse", [canvas.Shape, gs.Ellipse], {
 		// summary: an ellipse shape (Canvas)
 		setShape: function(){
-			g.Ellipse.superclass.setShape.apply(this, arguments);
+			this.inherited(arguments);
 			// prepare Canvas-specific structures
 			var s = this.shape, t, c1, c2, r = [],
 				M = m.normalize([m.translate(s.cx, s.cy), m.scale(s.rx, s.ry)]);
@@ -214,7 +239,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Circle", gs.Circle, {
+	dojo.declare("dojox.gfx.canvas.Circle", [canvas.Shape, gs.Circle], {
 		// summary: a circle shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
@@ -223,7 +248,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Line", gs.Line, {
+	dojo.declare("dojox.gfx.canvas.Line", [canvas.Shape, gs.Line], {
 		// summary: a line shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
@@ -233,11 +258,10 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Polyline", gs.Polyline, {
+	dojo.declare("dojox.gfx.canvas.Polyline", [canvas.Shape, gs.Polyline], {
 		// summary: a polyline/polygon shape (Canvas)
 		setShape: function(){
-			g.Polyline.superclass.setShape.apply(this, arguments);
-			// dojo.inherited("setShape", arguments);
+			this.inherited(arguments);
 			// prepare Canvas-specific structures
 			var p = this.shape.points, f = p[0], r = [], c, i;
 			if(p.length){
@@ -261,7 +285,6 @@ dojo.experimental("dojox.gfx.canvas");
 			return this;
 		},
 		_renderShape: function(/* Object */ ctx){
-			// console.debug("Polyline::_renderShape");
 			var p = this.canvasPolyline;
 			if(p.length){
 				ctx.beginPath();
@@ -273,10 +296,10 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Image", gs.Image, {
+	dojo.declare("dojox.gfx.canvas.Image", [canvas.Shape, gs.Image], {
 		// summary: an image shape (Canvas)
 		setShape: function(){
-			g.Image.superclass.setShape.apply(this, arguments);
+			this.inherited(arguments);
 			// prepare Canvas-specific structures
 			var img = new Image();
 			this.surface.downloadImage(img, this.shape.src);
@@ -288,43 +311,110 @@ dojo.experimental("dojox.gfx.canvas");
 			ctx.drawImage(this.canvasImage, s.x, s.y, s.width, s.height);
 		}
 	});
-
-	dojo.declare("dojox.gfx.Text", gs.Text, {
-		// summary: a text shape (Canvas)
-		_renderShape: function(/* Object */ ctx){
-			var s = this.shape;
-			// nothing for the moment
+	
+	dojo.declare("dojox.gfx.canvas.Text", [canvas.Shape, gs.Text], {
+		_setFont:function(){
+			if (this.fontStyle){
+				this.canvasFont = g.makeFontString(this.fontStyle);
+			} else {
+				delete this.canvasFont;
+			}
+		},
+		
+		getTextWidth: function(){
+			// summary: get the text width in pixels
+			var s = this.shape, w = 0, ctx;
+			if(s.text && s.text.length > 0){
+				ctx = this.surface.rawNode.getContext("2d");
+				ctx.save();
+				this._renderTransform(ctx);
+				this._renderFill(ctx, false);
+				this._renderStroke(ctx, false);
+				if (this.canvasFont)
+					ctx.font = this.canvasFont;
+				w = ctx.measureText(s.text).width;
+				ctx.restore();
+			}
+			return w;
+		},
+		
+		// override to apply first fill and stroke (
+		// the base implementation is for path-based shape that needs to first define the path then to fill/stroke it.
+		// Here, we need the fillstyle or strokestyle to be set before calling fillText/strokeText.
+		_render: function(/* Object */ctx){
+			// summary: render the shape
+			// ctx : Object: the drawing context.
+			ctx.save();
+			this._renderTransform(ctx);
+			this._renderFill(ctx, false);
+			this._renderStroke(ctx, false);
+			this._renderShape(ctx);
+			ctx.restore();
+		},
+		
+		_renderShape: function(ctx){
+			// summary: a text shape (Canvas)
+			// ctx : Object: the drawing context.
+			var ta, s = this.shape;
+			if(!s.text || s.text.length == 0){
+				return;
+			}
+			// text align
+			ta = s.align === 'middle' ? 'center' : s.align;
+			ctx.textAlign = ta;
+			if(this.canvasFont){
+				ctx.font = this.canvasFont;
+			}
+			if(this.canvasFill){
+				ctx.fillText(s.text, s.x, s.y);
+			}
+			if(this.strokeStyle){
+				ctx.beginPath(); // fix bug in FF3.6. Fixed in FF4b8
+				ctx.strokeText(s.text, s.x, s.y);
+				ctx.closePath();
+			}
 		}
 	});
-	modifyMethod(g.Text, "setFont");
+	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(){}
+		});
+	}
+	
 
 	var pathRenderers = {
-		M: "_moveToA", m: "_moveToR",
-		L: "_lineToA", l: "_lineToR",
-		H: "_hLineToA", h: "_hLineToR",
-		V: "_vLineToA", v: "_vLineToR",
-		C: "_curveToA", c: "_curveToR",
-		S: "_smoothCurveToA", s: "_smoothCurveToR",
-		Q: "_qCurveToA", q: "_qCurveToR",
-		T: "_qSmoothCurveToA", t: "_qSmoothCurveToR",
-		A: "_arcTo", a: "_arcTo",
-		Z: "_closePath", z: "_closePath"
-	};
+			M: "_moveToA", m: "_moveToR",
+			L: "_lineToA", l: "_lineToR",
+			H: "_hLineToA", h: "_hLineToR",
+			V: "_vLineToA", v: "_vLineToR",
+			C: "_curveToA", c: "_curveToR",
+			S: "_smoothCurveToA", s: "_smoothCurveToR",
+			Q: "_qCurveToA", q: "_qCurveToR",
+			T: "_qSmoothCurveToA", t: "_qSmoothCurveToR",
+			A: "_arcTo", a: "_arcTo",
+			Z: "_closePath", z: "_closePath"
+		};
 
-	dojo.declare("dojox.gfx.Path", g.path.Path, {
+	dojo.declare("dojox.gfx.canvas.Path", [canvas.Shape, g.path.Path], {
 		// summary: a path shape (Canvas)
 		constructor: function(){
 			this.lastControl = {};
 		},
 		setShape: function(){
 			this.canvasPath = [];
-			return g.Path.superclass.setShape.apply(this, arguments);
+			return this.inherited(arguments);
 		},
 		_updateWithSegment: function(segment){
 			var last = d.clone(this.last);
 			this[pathRenderers[segment.action]](this.canvasPath, segment.action, segment.args);
 			this.last = last;
-			g.Path.superclass._updateWithSegment.apply(this, arguments);
+			this.inherited(arguments);
 		},
 		_renderShape: function(/* Object */ ctx){
 			var r = this.canvasPath;
@@ -533,18 +623,24 @@ dojo.experimental("dojox.gfx.canvas");
 	});
 	d.forEach(["moveTo", "lineTo", "hLineTo", "vLineTo", "curveTo",
 		"smoothCurveTo", "qCurveTo", "qSmoothCurveTo", "arcTo", "closePath"],
-		function(method){ modifyMethod(g.Path, method); }
+		function(method){ modifyMethod(canvas.Path, method); }
 	);
 
-	dojo.declare("dojox.gfx.TextPath", g.path.TextPath, {
+	dojo.declare("dojox.gfx.canvas.TextPath", [canvas.Shape, g.path.TextPath], {
 		// summary: a text shape (Canvas)
 		_renderShape: function(/* Object */ ctx){
 			var s = this.shape;
 			// nothing for the moment
+		},
+		_setText: function(){
+			// not implemented
+		},
+		_setFont: function(){
+			// not implemented
 		}
 	});
 
-	dojo.declare("dojox.gfx.Surface", gs.Surface, {
+	dojo.declare("dojox.gfx.canvas.Surface", gs.Surface, {
 		// summary: a surface object to be used for drawings (Canvas)
 		constructor: function(){
 			gs.Container._init.call(this);
@@ -615,7 +711,7 @@ dojo.experimental("dojox.gfx.canvas");
 		disconnect:		function(){}
 	});
 
-	g.createSurface = function(parentNode, width, height){
+	canvas.createSurface = function(parentNode, width, height){
 		// summary: creates a surface (Canvas)
 		// parentNode: Node: a parent node
 		// width: String: width of surface, e.g., "100px"
@@ -633,12 +729,12 @@ dojo.experimental("dojox.gfx.canvas");
 			height = height + "px";
 		}
 
-		var s = new g.Surface(),
+		var s = new canvas.Surface(),
 			p = d.byId(parentNode),
 			c = p.ownerDocument.createElement("canvas");
 
-		c.width  = dojox.gfx.normalizedLength(width);	// in pixels
-		c.height = dojox.gfx.normalizedLength(height);	// in pixels
+		c.width  = g.normalizedLength(width);	// in pixels
+		c.height = g.normalizedLength(height);	// in pixels
 
 		p.appendChild(c);
 		s.rawNode = c;
@@ -672,7 +768,7 @@ dojo.experimental("dojox.gfx.canvas");
 		}
 	};
 
-	d.mixin(gs.Creator, {
+	var Creator = {
 		// summary: Canvas shape creators
 		createObject: function(shapeType, rawShape) {
 			// summary: creates an instance of the passed shapeType class
@@ -685,11 +781,19 @@ dojo.experimental("dojox.gfx.canvas");
 			this.add(shape);
 			return shape;	// dojox.gfx.Shape
 		}
-	});
-
-	d.extend(g.Group, Container);
-	d.extend(g.Group, gs.Creator);
+	};
 
-	d.extend(g.Surface, Container);
-	d.extend(g.Surface, gs.Creator);
+	d.extend(canvas.Group, Container);
+	d.extend(canvas.Group, gs.Creator);
+	d.extend(canvas.Group, Creator);
+
+	d.extend(canvas.Surface, Container);
+	d.extend(canvas.Surface, gs.Creator);
+	d.extend(canvas.Surface, Creator);
+	
+	// see if we are required to initilize
+	if(g.loadAndSwitch === "canvas"){
+		g.switchTo("canvas");
+		delete g.loadAndSwitch;
+	}
 })();
diff --git a/dojox/gfx/canvas_attach.js b/dojox/gfx/canvas_attach.js
index 82ccd13..85e846c 100644
--- a/dojox/gfx/canvas_attach.js
+++ b/dojox/gfx/canvas_attach.js
@@ -1,8 +1,10 @@
+dojo.provide("dojox.gfx.canvas_attach");
+
 dojo.require("dojox.gfx.canvas");
 
 dojo.experimental("dojox.gfx.canvas_attach");
 
 // not implemented
-dojox.gfx.attachNode = function(){
+dojox.gfx.canvas.attachSurface = dojox.gfx.canvas.attachNode = function(){
 	return null;	// for now
 };
diff --git a/dojox/gfx/decompose.js b/dojox/gfx/decompose.js
index 997c60d..8e91e5a 100644
--- a/dojox/gfx/decompose.js
+++ b/dojox/gfx/decompose.js
@@ -5,12 +5,12 @@ dojo.require("dojox.gfx.matrix");
 (function(){
 	var m = dojox.gfx.matrix;
 
-	var eq = function(/* Number */ a, /* Number */ b){
+	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
-	};
+	}
 
-	var calcFromValues = function(/* Number */ r1, /* Number */ m1, /* Number */ r2, /* Number */ m2){
+	function calcFromValues(/* Number */ r1, /* Number */ m1, /* Number */ r2, /* Number */ m2){
 		// summary: uses two close FP ration and their original magnitudes to approximate the result
 		if(!isFinite(r1)){
 			return r2;	// Number
@@ -19,19 +19,19 @@ dojo.require("dojox.gfx.matrix");
 		}
 		m1 = Math.abs(m1), m2 = Math.abs(m2);
 		return (m1 * r1 + m2 * r2) / (m1 + m2);	// Number
-	};
+	}
 
-	var transpose = function(/* dojox.gfx.matrix.Matrix2D */ matrix){
+	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
-	};
+	}
 
-	var scaleSign = function(/* dojox.gfx.matrix.Matrix2D */ matrix){
+	function scaleSign(/* dojox.gfx.matrix.Matrix2D */ matrix){
 		return (matrix.xx * matrix.yy < 0 || matrix.xy * matrix.yx > 0) ? -1 : 1;	// Number
-	};
+	}
 
-	var eigenvalueDecomposition = function(/* dojox.gfx.matrix.Matrix2D */ matrix){
+	function eigenvalueDecomposition(/* dojox.gfx.matrix.Matrix2D */ matrix){
 		// matrix: dojox.gfx.matrix.Matrix2D: a 2D matrix-like object
 		var M = m.normalize(matrix),
 			b = -M.xx - M.yy,
@@ -74,9 +74,9 @@ dojo.require("dojox.gfx.matrix");
 			vector1: {x: vx1, y: vy1},
 			vector2: {x: vx2, y: vy2}
 		};
-	};
+	}
 
-	var decomposeSR = function(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
+	function decomposeSR(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
 		// summary: decomposes a matrix into [scale, rotate]; no checks are done.
 		var sign = scaleSign(M),
 			a = result.angle1 = (Math.atan2(M.yx, M.yy) + Math.atan2(-sign * M.xy, sign * M.xx)) / 2,
@@ -84,9 +84,9 @@ dojo.require("dojox.gfx.matrix");
 		result.sx = calcFromValues(M.xx / cos, cos, -M.xy / sin, sin);
 		result.sy = calcFromValues(M.yy / cos, cos,  M.yx / sin, sin);
 		return result;	// Object
-	};
+	}
 
-	var decomposeRS = function(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
+	function decomposeRS(/* dojox.gfx.matrix.Matrix2D */ M, /* Object */ result){
 		// summary: decomposes a matrix into [rotate, scale]; no checks are done
 		var sign = scaleSign(M),
 			a = result.angle2 = (Math.atan2(sign * M.yx, sign * M.xx) + Math.atan2(-M.xy, M.yy)) / 2,
@@ -94,7 +94,7 @@ dojo.require("dojox.gfx.matrix");
 		result.sx = calcFromValues(M.xx / cos, cos,  M.yx / sin, sin);
 		result.sy = calcFromValues(M.yy / cos, cos, -M.xy / sin, sin);
 		return result;	// Object
-	};
+	}
 
 	dojox.gfx.decompose = function(matrix){
 		// summary: decompose a 2D matrix into translation, scaling, and rotation components
diff --git a/dojox/gfx/fx.js b/dojox/gfx/fx.js
index c0cefff..1d783c6 100644
--- a/dojox/gfx/fx.js
+++ b/dojox/gfx/fx.js
@@ -7,97 +7,85 @@ dojo.require("dojox.gfx.matrix");
 
 	// Generic interpolators. Should they be moved to dojox.fx?
 
-	var InterpolNumber = function(start, end){
+	function InterpolNumber(start, end){
 		this.start = start, this.end = end;
+	}
+	InterpolNumber.prototype.getValue = function(r){
+		return (this.end - this.start) * r + this.start;
 	};
-	d.extend(InterpolNumber, {
-		getValue: function(r){
-			return (this.end - this.start) * r + this.start;
-		}
-	});
 
-	var InterpolUnit = function(start, end, units){
+	function InterpolUnit(start, end, units){
 		this.start = start, this.end = end;
 		this.units = units;
+	}
+	InterpolUnit.prototype.getValue = function(r){
+		return (this.end - this.start) * r + this.start + this.units;
 	};
-	d.extend(InterpolUnit, {
-		getValue: function(r){
-			return (this.end - this.start) * r + this.start + this.units;
-		}
-	});
 
-	var InterpolColor = function(start, end){
+	function InterpolColor(start, end){
 		this.start = start, this.end = end;
 		this.temp = new dojo.Color();
+	}
+	InterpolColor.prototype.getValue = function(r){
+		return d.blendColors(this.start, this.end, r, this.temp);
 	};
-	d.extend(InterpolColor, {
-		getValue: function(r){
-			return d.blendColors(this.start, this.end, r, this.temp);
-		}
-	});
 
-	var InterpolValues = function(values){
+	function InterpolValues(values){
 		this.values = values;
 		this.length = values.length;
+	}
+	InterpolValues.prototype.getValue = function(r){
+		return this.values[Math.min(Math.floor(r * this.length), this.length - 1)];
 	};
-	d.extend(InterpolValues, {
-		getValue: function(r){
-			return this.values[Math.min(Math.floor(r * this.length), this.length - 1)];
-		}
-	});
 
-	var InterpolObject = function(values, def){
+	function InterpolObject(values, def){
 		this.values = values;
 		this.def = def ? def : {};
-	};
-	d.extend(InterpolObject, {
-		getValue: function(r){
-			var ret = dojo.clone(this.def);
-			for(var i in this.values){
-				ret[i] = this.values[i].getValue(r);
-			}
-			return ret;
+	}
+	InterpolObject.prototype.getValue = function(r){
+		var ret = dojo.clone(this.def);
+		for(var i in this.values){
+			ret[i] = this.values[i].getValue(r);
 		}
-	});
+		return ret;
+	};
 
-	var InterpolTransform = function(stack, original){
+	function InterpolTransform(stack, original){
 		this.stack = stack;
 		this.original = original;
+	}
+	InterpolTransform.prototype.getValue = function(r){
+		var ret = [];
+		dojo.forEach(this.stack, function(t){
+			if(t instanceof m.Matrix2D){
+				ret.push(t);
+				return;
+			}
+			if(t.name == "original" && this.original){
+				ret.push(this.original);
+				return;
+			}
+			if(!(t.name in m)){ return; }
+			var f = m[t.name];
+			if(typeof f != "function"){
+				// constant
+				ret.push(f);
+				return;
+			}
+			var val = dojo.map(t.start, function(v, i){
+							return (t.end[i] - v) * r + v;
+						}),
+				matrix = f.apply(m, val);
+			if(matrix instanceof m.Matrix2D){
+				ret.push(matrix);
+			}
+		}, this);
+		return ret;
 	};
-	d.extend(InterpolTransform, {
-		getValue: function(r){
-			var ret = [];
-			dojo.forEach(this.stack, function(t){
-				if(t instanceof m.Matrix2D){
-					ret.push(t);
-					return;
-				}
-				if(t.name == "original" && this.original){
-					ret.push(this.original);
-					return;
-				}
-				if(!(t.name in m)){ return; }
-				var f = m[t.name];
-				if(typeof f != "function"){
-					// constant
-					ret.push(f);
-					return;
-				}
-				var val = dojo.map(t.start, function(v, i){
-								return (t.end[i] - v) * r + v;
-							}),
-					matrix = f.apply(m, val);
-				if(matrix instanceof m.Matrix2D){
-					ret.push(matrix);
-				}
-			}, this);
-			return ret;
-		}
-	});
 
 	var transparent = new d.Color(0, 0, 0, 0);
 
-	var getColorInterpol = function(prop, obj, name, def){
+	function getColorInterpol(prop, obj, name, def){
 		if(prop.values){
 			return new InterpolValues(prop.values);
 		}
@@ -116,9 +104,9 @@ dojo.require("dojox.gfx.matrix");
 			end = value;
 		}
 		return new InterpolColor(start, end);
-	};
+	}
 
-	var getNumberInterpol = function(prop, obj, name, def){
+	function getNumberInterpol(prop, obj, name, def){
 		if(prop.values){
 			return new InterpolValues(prop.values);
 		}
@@ -137,7 +125,7 @@ dojo.require("dojox.gfx.matrix");
 			end = value;
 		}
 		return new InterpolNumber(start, end);
-	};
+	}
 
 	g.fx.animateStroke = function(/*Object*/ args){
 		// summary:
diff --git a/dojox/gfx/path.js b/dojox/gfx/path.js
index 37a52ce..3df64e6 100644
--- a/dojox/gfx/path.js
+++ b/dojox/gfx/path.js
@@ -3,7 +3,7 @@ dojo.provide("dojox.gfx.path");
 dojo.require("dojox.gfx.matrix");
 dojo.require("dojox.gfx.shape");
 
-dojo.declare("dojox.gfx.path.Path", dojox.gfx.Shape, {
+dojo.declare("dojox.gfx.path.Path", dojox.gfx.shape.Shape, {
 	// summary: a generalized path shape
 
 	constructor: function(rawNode){
@@ -69,7 +69,7 @@ dojo.declare("dojox.gfx.path.Path", dojox.gfx.Shape, {
 
 	_applyTransform: function(){
 		this.tbbox = null;
-		return dojox.gfx.Shape.prototype._applyTransform.call(this);
+		return this.inherited(arguments);
 	},
 
 	// segment interpretation
@@ -196,7 +196,7 @@ dojo.declare("dojox.gfx.path.Path", dojox.gfx.Shape, {
 		if(typeof this.shape.path == "string"){
 			this.shape.path += path.join("");
 		}else{
-			Array.prototype.push.apply(this.shape.path, path);
+			Array.prototype.push.apply(this.shape.path, path); //FIXME: why not simple push()?
 		}
 	},
 
@@ -366,7 +366,7 @@ dojo.declare("dojox.gfx.path.Path", dojox.gfx.Shape, {
 	setShape: function(newShape){
 		// summary: forms a path using a shape
 		// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
-		dojox.gfx.Shape.prototype.setShape.call(this, typeof newShape == "string" ? {path: newShape} : newShape);
+		this.inherited(arguments, [typeof newShape == "string" ? {path: newShape} : newShape]);
 		
 		this.segmented = false;
 		this.segments = [];
diff --git a/dojox/gfx/shape.js b/dojox/gfx/shape.js
index fc8f18b..1ebaa7a 100644
--- a/dojox/gfx/shape.js
+++ b/dojox/gfx/shape.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.gfx.shape");
 
 dojo.require("dojox.gfx._base");
 
-dojo.declare("dojox.gfx.Shape", null, {
+dojo.declare("dojox.gfx.shape.Shape", null, {
 	// summary: a Shape object, which knows how to apply
 	// graphical attributes and transformations
 
@@ -339,7 +339,7 @@ dojox.gfx.shape._eventsProcessing = {
 	}
 };
 
-dojo.extend(dojox.gfx.Shape, dojox.gfx.shape._eventsProcessing);
+dojo.extend(dojox.gfx.shape.Shape, dojox.gfx.shape._eventsProcessing);
 
 dojox.gfx.shape.Container = {
 	// summary: a container of shapes, which can be used
@@ -492,7 +492,7 @@ dojo.declare("dojox.gfx.Rectangle", null, {
 	//	You should use the naked object instead: {x: 1, y: 2, width: 100, height: 200}.
 });
 
-dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.Shape, {
+dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.shape.Shape, {
 	// summary: a generic rectangle
 	constructor: function(rawNode){
 		// rawNode: Node: a DOM Node
@@ -505,7 +505,7 @@ dojo.declare("dojox.gfx.shape.Rect", dojox.gfx.Shape, {
 	}
 });
 
-dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.Shape, {
+dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.shape.Shape, {
 	// summary: a generic ellipse
 	constructor: function(rawNode){
 		// rawNode: Node: a DOM Node
@@ -523,7 +523,7 @@ dojo.declare("dojox.gfx.shape.Ellipse", dojox.gfx.Shape, {
 	}
 });
 
-dojo.declare("dojox.gfx.shape.Circle", dojox.gfx.Shape, {
+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){
@@ -542,7 +542,7 @@ dojo.declare("dojox.gfx.shape.Circle", dojox.gfx.Shape, {
 	}
 });
 
-dojo.declare("dojox.gfx.shape.Line", dojox.gfx.Shape, {
+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){
@@ -565,7 +565,7 @@ dojo.declare("dojox.gfx.shape.Line", dojox.gfx.Shape, {
 	}
 });
 
-dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.Shape, {
+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){
@@ -579,12 +579,12 @@ dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.Shape, {
 		// closed: Boolean: close the polyline to make a polygon
 		if(points && points instanceof Array){
 			// points: Array: an array of points
-			dojox.gfx.Shape.prototype.setShape.call(this, {points: points});
+			this.inherited(arguments, [{points: points}]);
 			if(closed && this.shape.points.length){
 				this.shape.points.push(this.shape.points[0]);
 			}
 		}else{
-			dojox.gfx.Shape.prototype.setShape.call(this, points);
+			this.inherited(arguments, [points]);
 		}
 		return this;	// self
 	},
@@ -624,7 +624,7 @@ dojo.declare("dojox.gfx.shape.Polyline", dojox.gfx.Shape, {
 	}
 });
 
-dojo.declare("dojox.gfx.shape.Image", dojox.gfx.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){
@@ -646,7 +646,7 @@ dojo.declare("dojox.gfx.shape.Image", dojox.gfx.Shape, {
 	}
 });
 
-dojo.declare("dojox.gfx.shape.Text", dojox.gfx.Shape, {
+dojo.declare("dojox.gfx.shape.Text", dojox.gfx.shape.Shape, {
 	// summary: a generic text
 	constructor: function(rawNode){
 		// rawNode: Node: a DOM Node
@@ -678,8 +678,8 @@ dojox.gfx.shape.Creator = {
 		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.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);
diff --git a/dojox/gfx/silverlight.js b/dojox/gfx/silverlight.js
index 589cbd7..f5b653d 100644
--- a/dojox/gfx/silverlight.js
+++ b/dojox/gfx/silverlight.js
@@ -6,722 +6,723 @@ dojo.require("dojox.gfx.path");
 
 dojo.experimental("dojox.gfx.silverlight");
 
-dojox.gfx.silverlight.dasharray = {
-	solid:				"none",
-	shortdash:			[4, 1],
-	shortdot:			[1, 1],
-	shortdashdot:		[4, 1, 1, 1],
-	shortdashdotdot:	[4, 1, 1, 1, 1, 1],
-	dot:				[1, 3],
-	dash:				[4, 3],
-	longdash:			[8, 3],
-	dashdot:			[4, 3, 1, 3],
-	longdashdot:		[8, 3, 1, 3],
-	longdashdotdot:		[8, 3, 1, 3, 1, 3]
-};
-
-dojox.gfx.silverlight.fontweight = {
-	normal: 400,
-	bold:   700
-};
-
-dojox.gfx.silverlight.caps  = {butt: "Flat", round: "Round", square: "Square"};
-dojox.gfx.silverlight.joins = {bevel: "Bevel", round: "Round"};
-
-dojox.gfx.silverlight.fonts = {
-	serif: "Times New Roman",
-	times: "Times New Roman",
-	"sans-serif": "Arial",
-	helvetica: "Arial",
-	monotone: "Courier New",
-	courier: "Courier New"
-};
-
-dojox.gfx.silverlight.hexColor = function(/*String|Array|dojo.Color*/ color){
-	// summary: converts a color object to a Silverlight hex color string (#aarrggbb)
-	var c = dojox.gfx.normalizeColor(color),
-		t = c.toHex(), a = Math.round(c.a * 255);
-	a = (a < 0 ? 0 : a > 255 ? 255 : a).toString(16);
-	return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1);	// String
-};
-
-dojo.extend(dojox.gfx.Shape, {
-	// summary: Silverlight-specific implementation of dojox.gfx.Shape methods
-
-	setFill: function(fill){
-		// summary: sets a fill object (Silverlight)
-		// fill: Object: a fill object
-		//	(see dojox.gfx.defaultLinearGradient,
-		//	dojox.gfx.defaultRadialGradient,
-		//	dojox.gfx.defaultPattern,
-		//	or dojo.Color)
-
-		var p = this.rawNode.getHost().content, r = this.rawNode, f;
-		if(!fill){
-			// don't fill
-			this.fillStyle = null;
-			this._setFillAttr(null);
-			return this;	// self
-		}
-		if(typeof(fill) == "object" && "type" in fill){
-			// gradient
-			switch(fill.type){
-				case "linear":
-					this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultLinearGradient, fill);
-					var lgb = p.createFromXaml("<LinearGradientBrush/>");
-					lgb.mappingMode = "Absolute";
-					lgb.startPoint = f.x1 + "," + f.y1;
-					lgb.endPoint = f.x2 + "," + f.y2;
-					dojo.forEach(f.colors, function(c){
-						var t = p.createFromXaml("<GradientStop/>");
-						t.offset = c.offset;
-						t.color = dojox.gfx.silverlight.hexColor(c.color);
-						lgb.gradientStops.add(t);
-					});
-					this._setFillAttr(lgb);
-					break;
-				case "radial":
-					this.fillStyle = f = dojox.gfx.makeParameters(dojox.gfx.defaultRadialGradient, fill);
-					var rgb = p.createFromXaml("<RadialGradientBrush/>"),
-						c = dojox.gfx.matrix.multiplyPoint(
-								dojox.gfx.matrix.invert(this._getAdjustedMatrix()), f.cx, f.cy),
-						pt = c.x + "," + c.y;
-					rgb.mappingMode = "Absolute";
-					rgb.gradientOrigin = pt;
-					rgb.center = pt;
-					rgb.radiusX = rgb.radiusY = f.r;
-					dojo.forEach(f.colors, function(c){
-						var t = p.createFromXaml("<GradientStop/>");
-						t.offset = c.offset;
-						t.color = dojox.gfx.silverlight.hexColor(c.color);
-						rgb.gradientStops.add(t);
-					});
-					this._setFillAttr(rgb);
-					break;
-				case "pattern":
-					// don't fill: Silverlight doesn't define TileBrush for some reason
-					this.fillStyle = null;
-					this._setFillAttr(null);
-					break;
+(function(){
+	var d = dojo, g = dojox.gfx, gs = g.shape, sl = g.silverlight;
+
+	var dasharray = {
+			solid:				"none",
+			shortdash:			[4, 1],
+			shortdot:			[1, 1],
+			shortdashdot:		[4, 1, 1, 1],
+			shortdashdotdot:	[4, 1, 1, 1, 1, 1],
+			dot:				[1, 3],
+			dash:				[4, 3],
+			longdash:			[8, 3],
+			dashdot:			[4, 3, 1, 3],
+			longdashdot:		[8, 3, 1, 3],
+			longdashdotdot:		[8, 3, 1, 3, 1, 3]
+		},
+		fontweight = {
+			normal: 400,
+			bold:   700
+		},
+		caps  = {butt: "Flat", round: "Round", square: "Square"},
+		joins = {bevel: "Bevel", round: "Round"},
+		fonts = {
+			serif: "Times New Roman",
+			times: "Times New Roman",
+			"sans-serif": "Arial",
+			helvetica: "Arial",
+			monotone: "Courier New",
+			courier: "Courier New"
+		};
+
+	function hexColor(/*String|Array|dojo.Color*/ color){
+		// summary: converts a color object to a Silverlight hex color string (#aarrggbb)
+		var c = g.normalizeColor(color),
+			t = c.toHex(), a = Math.round(c.a * 255);
+		a = (a < 0 ? 0 : a > 255 ? 255 : a).toString(16);
+		return "#" + (a.length < 2 ? "0" + a : a) + t.slice(1);	// String
+	}
+
+	d.declare("dojox.gfx.silverlight.Shape", gs.Shape, {
+		// summary: Silverlight-specific implementation of dojox.gfx.Shape methods
+
+		setFill: function(fill){
+			// summary: sets a fill object (Silverlight)
+			// fill: Object: a fill object
+			//	(see dojox.gfx.defaultLinearGradient,
+			//	dojox.gfx.defaultRadialGradient,
+			//	dojox.gfx.defaultPattern,
+			//	or dojo.Color)
+
+			var p = this.rawNode.getHost().content, r = this.rawNode, f;
+			if(!fill){
+				// don't fill
+				this.fillStyle = null;
+				this._setFillAttr(null);
+				return this;	// self
 			}
-			return this;	// self
-		}
-		// color object
-		this.fillStyle = f = dojox.gfx.normalizeColor(fill);
-		var scb = p.createFromXaml("<SolidColorBrush/>");
-		scb.color = f.toHex();
-		scb.opacity = f.a;
-		this._setFillAttr(scb);
-		return this;	// self
-	},
-	_setFillAttr: function(f){
-		this.rawNode.fill = f;
-	},
-
-	setStroke: function(stroke){
-		// summary: sets a stroke object (Silverlight)
-		// stroke: Object: a stroke object
-		//	(see dojox.gfx.defaultStroke)
-
-		var p = this.rawNode.getHost().content, r = this.rawNode;
-		if(!stroke){
-			// don't stroke
-			this.strokeStyle = null;
-			r.stroke = null;
-			return this;
-		}
-		// normalize the stroke
-		if(typeof stroke == "string" || dojo.isArray(stroke) || stroke instanceof dojo.Color){
-			stroke = {color: stroke};
-		}
-		var s = this.strokeStyle = dojox.gfx.makeParameters(dojox.gfx.defaultStroke, stroke);
-		s.color = dojox.gfx.normalizeColor(s.color);
-		// generate attributes
-		if(s){
+			if(typeof(fill) == "object" && "type" in fill){
+				// gradient
+				switch(fill.type){
+					case "linear":
+						this.fillStyle = f = g.makeParameters(g.defaultLinearGradient, fill);
+						var lgb = p.createFromXaml("<LinearGradientBrush/>");
+						lgb.mappingMode = "Absolute";
+						lgb.startPoint = f.x1 + "," + f.y1;
+						lgb.endPoint = f.x2 + "," + f.y2;
+						d.forEach(f.colors, function(c){
+							var t = p.createFromXaml("<GradientStop/>");
+							t.offset = c.offset;
+							t.color = hexColor(c.color);
+							lgb.gradientStops.add(t);
+						});
+						this._setFillAttr(lgb);
+						break;
+					case "radial":
+						this.fillStyle = f = g.makeParameters(g.defaultRadialGradient, fill);
+						var rgb = p.createFromXaml("<RadialGradientBrush/>"),
+							c = g.matrix.multiplyPoint(g.matrix.invert(this._getAdjustedMatrix()), f.cx, f.cy),
+							pt = c.x + "," + c.y;
+						rgb.mappingMode = "Absolute";
+						rgb.gradientOrigin = pt;
+						rgb.center = pt;
+						rgb.radiusX = rgb.radiusY = f.r;
+						d.forEach(f.colors, function(c){
+							var t = p.createFromXaml("<GradientStop/>");
+							t.offset = c.offset;
+							t.color = hexColor(c.color);
+							rgb.gradientStops.add(t);
+						});
+						this._setFillAttr(rgb);
+						break;
+					case "pattern":
+						// don't fill: Silverlight doesn't define TileBrush for some reason
+						this.fillStyle = null;
+						this._setFillAttr(null);
+						break;
+				}
+				return this;	// self
+			}
+			// color object
+			this.fillStyle = f = g.normalizeColor(fill);
 			var scb = p.createFromXaml("<SolidColorBrush/>");
-			scb.color = s.color.toHex();
-			scb.opacity = s.color.a;
-			r.stroke = scb;
-			r.strokeThickness = s.width;
-			r.strokeStartLineCap = r.strokeEndLineCap = r.strokeDashCap =
-				dojox.gfx.silverlight.caps[s.cap];
-			if(typeof s.join == "number"){
-				r.strokeLineJoin = "Miter";
-				r.strokeMiterLimit = s.join;
-			}else{
-				r.strokeLineJoin = dojox.gfx.silverlight.joins[s.join];
+			scb.color = f.toHex();
+			scb.opacity = f.a;
+			this._setFillAttr(scb);
+			return this;	// self
+		},
+		_setFillAttr: function(f){
+			this.rawNode.fill = f;
+		},
+
+		setStroke: function(stroke){
+			// summary: sets a stroke object (Silverlight)
+			// stroke: Object: a stroke object
+			//	(see dojox.gfx.defaultStroke)
+
+			var p = this.rawNode.getHost().content, r = this.rawNode;
+			if(!stroke){
+				// don't stroke
+				this.strokeStyle = null;
+				r.stroke = null;
+				return this;
 			}
-			var da = s.style.toLowerCase();
-			if(da in dojox.gfx.silverlight.dasharray){ da = dojox.gfx.silverlight.dasharray[da]; }
-			if(da instanceof Array){
-				da = dojo.clone(da);
-				var i;
-				/*
-				for(var i = 0; i < da.length; ++i){
-					da[i] *= s.width;
+			// normalize the stroke
+			if(typeof stroke == "string" || d.isArray(stroke) || stroke instanceof d.Color){
+				stroke = {color: stroke};
+			}
+			var s = this.strokeStyle = g.makeParameters(g.defaultStroke, stroke);
+			s.color = g.normalizeColor(s.color);
+			// generate attributes
+			if(s){
+				var scb = p.createFromXaml("<SolidColorBrush/>");
+				scb.color = s.color.toHex();
+				scb.opacity = s.color.a;
+				r.stroke = scb;
+				r.strokeThickness = s.width;
+				r.strokeStartLineCap = r.strokeEndLineCap = r.strokeDashCap =
+					caps[s.cap];
+				if(typeof s.join == "number"){
+					r.strokeLineJoin = "Miter";
+					r.strokeMiterLimit = s.join;
+				}else{
+					r.strokeLineJoin = joins[s.join];
 				}
-				*/
-				if(s.cap != "butt"){
-					for(i = 0; i < da.length; i += 2){
-						//da[i] -= s.width;
-						--da[i]
-						if(da[i] < 1){ da[i] = 1; }
+				var da = s.style.toLowerCase();
+				if(da in dasharray){ da = dasharray[da]; }
+				if(da instanceof Array){
+					da = d.clone(da);
+					var i;
+					/*
+					for(var i = 0; i < da.length; ++i){
+						da[i] *= s.width;
 					}
-					for(i = 1; i < da.length; i += 2){
-						//da[i] += s.width;
-						++da[i];
+					*/
+					if(s.cap != "butt"){
+						for(i = 0; i < da.length; i += 2){
+							//da[i] -= s.width;
+							--da[i]
+							if(da[i] < 1){ da[i] = 1; }
+						}
+						for(i = 1; i < da.length; i += 2){
+							//da[i] += s.width;
+							++da[i];
+						}
 					}
+					r.strokeDashArray = da.join(",");
+				}else{
+					r.strokeDashArray = null;
 				}
-				r.strokeDashArray = da.join(",");
+			}
+			return this;	// self
+		},
+
+		_getParentSurface: function(){
+			var surface = this.parent;
+			for(; surface && !(surface instanceof g.Surface); surface = surface.parent);
+			return surface;
+		},
+
+		_applyTransform: function() {
+			var tm = this._getAdjustedMatrix(), r = this.rawNode;
+			if(tm){
+				var p = this.rawNode.getHost().content,
+					mt = p.createFromXaml("<MatrixTransform/>"),
+					mm = p.createFromXaml("<Matrix/>");
+				mm.m11 = tm.xx;
+				mm.m21 = tm.xy;
+				mm.m12 = tm.yx;
+				mm.m22 = tm.yy;
+				mm.offsetX = tm.dx;
+				mm.offsetY = tm.dy;
+				mt.matrix = mm;
+				r.renderTransform = mt;
 			}else{
-				r.strokeDashArray = null;
+				r.renderTransform = null;
 			}
+			return this;
+		},
+
+		setRawNode: function(rawNode){
+			// summary:
+			//	assigns and clears the underlying node that will represent this
+			//	shape. Once set, transforms, gradients, etc, can be applied.
+			//	(no fill & stroke by default)
+			rawNode.fill = null;
+			rawNode.stroke = null;
+			this.rawNode = rawNode;
+		},
+
+		// move family
+
+		_moveToFront: function(){
+			// summary: moves a shape to front of its parent's list of shapes (Silverlight)
+			var c = this.parent.rawNode.children, r = this.rawNode;
+			c.remove(r);
+			c.add(r);
+			return this;	// self
+		},
+		_moveToBack: function(){
+			// summary: moves a shape to back of its parent's list of shapes (Silverlight)
+			var c = this.parent.rawNode.children, r = this.rawNode;
+			c.remove(r);
+			c.insert(0, r);
+			return this;	// self
+		},
+
+		_getAdjustedMatrix: function(){
+			// summary: returns the adjusted ("real") transformation matrix
+			return this.matrix;	// dojox.gfx.Matrix2D
 		}
-		return this;	// self
-	},
-
-	_getParentSurface: function(){
-		var surface = this.parent;
-		for(; surface && !(surface instanceof dojox.gfx.Surface); surface = surface.parent);
-		return surface;
-	},
-
-	_applyTransform: function() {
-		var tm = this._getAdjustedMatrix(), r = this.rawNode;
-		if(tm){
-			var p = this.rawNode.getHost().content,
-				m = p.createFromXaml("<MatrixTransform/>"),
-				mm = p.createFromXaml("<Matrix/>");
-			mm.m11 = tm.xx;
-			mm.m21 = tm.xy;
-			mm.m12 = tm.yx;
-			mm.m22 = tm.yy;
-			mm.offsetX = tm.dx;
-			mm.offsetY = tm.dy;
-			m.matrix = mm;
-			r.renderTransform = m;
-		}else{
-			r.renderTransform = null;
+	});
+
+	d.declare("dojox.gfx.silverlight.Group", sl.Shape, {
+		// summary: a group shape (Silverlight), which can be used
+		//	to logically group shapes (e.g, to propagate matricies)
+		constructor: function(){
+			gs.Container._init.call(this);
+		},
+		setRawNode: function(rawNode){
+			// summary: sets a raw Silverlight node to be used by this shape
+			// rawNode: Node: an Silverlight node
+			this.rawNode = rawNode;
 		}
-		return this;
-	},
-
-	setRawNode: function(rawNode){
-		// summary:
-		//	assigns and clears the underlying node that will represent this
-		//	shape. Once set, transforms, gradients, etc, can be applied.
-		//	(no fill & stroke by default)
-		rawNode.fill = null;
-		rawNode.stroke = null;
-		this.rawNode = rawNode;
-	},
-
-	// move family
-
-	_moveToFront: function(){
-		// summary: moves a shape to front of its parent's list of shapes (Silverlight)
-		var c = this.parent.rawNode.children, r = this.rawNode;
-		c.remove(r);
-		c.add(r);
-		return this;	// self
-	},
-	_moveToBack: function(){
-		// summary: moves a shape to back of its parent's list of shapes (Silverlight)
-		var c = this.parent.rawNode.children, r = this.rawNode;
-		c.remove(r);
-		c.insert(0, r);
-		return this;	// self
-	},
-
-	_getAdjustedMatrix: function(){
-		// summary: returns the adjusted ("real") transformation matrix
-		return this.matrix;	// dojox.gfx.Matrix2D
-	}
-});
-
-dojo.declare("dojox.gfx.Group", dojox.gfx.Shape, {
-	// summary: a group shape (Silverlight), which can be used
-	//	to logically group shapes (e.g, to propagate matricies)
-	constructor: function(){
-		dojox.gfx.silverlight.Container._init.call(this);
-	},
-	setRawNode: function(rawNode){
-		// summary: sets a raw Silverlight node to be used by this shape
-		// rawNode: Node: an Silverlight node
-		this.rawNode = rawNode;
-	}
-});
-dojox.gfx.Group.nodeType = "Canvas";
-
-dojo.declare("dojox.gfx.Rect", dojox.gfx.shape.Rect, {
-	// summary: a rectangle shape (Silverlight)
-	setShape: function(newShape){
-		// summary: sets a rectangle shape object (Silverlight)
-		// newShape: Object: a rectangle shape object
-		this.shape = dojox.gfx.makeParameters(this.shape, newShape);
-		this.bbox = null;
-		var r = this.rawNode, n = this.shape;
-		r.width   = n.width;
-		r.height  = n.height;
-		r.radiusX = r.radiusY = n.r;
-		return this._applyTransform();	// self
-	},
-	_getAdjustedMatrix: function(){
-		// summary: returns the adjusted ("real") transformation matrix
-		var m = this.matrix, s = this.shape, d = {dx: s.x, dy: s.y};
-		return new dojox.gfx.Matrix2D(m ? [m, d] : d);	// dojox.gfx.Matrix2D
-	}
-});
-dojox.gfx.Rect.nodeType = "Rectangle";
-
-dojo.declare("dojox.gfx.Ellipse", dojox.gfx.shape.Ellipse, {
-	// summary: an ellipse shape (Silverlight)
-	setShape: function(newShape){
-		// summary: sets an ellipse shape object (Silverlight)
-		// newShape: Object: an ellipse shape object
-		this.shape = dojox.gfx.makeParameters(this.shape, newShape);
-		this.bbox = null;
-		var r = this.rawNode, n = this.shape;
-		r.width  = 2 * n.rx;
-		r.height = 2 * n.ry;
-		return this._applyTransform();	// self
-	},
-	_getAdjustedMatrix: function(){
-		// summary: returns the adjusted ("real") transformation matrix
-		var m = this.matrix, s = this.shape, d = {dx: s.cx - s.rx, dy: s.cy - s.ry};
-		return new dojox.gfx.Matrix2D(m ? [m, d] : d);	// dojox.gfx.Matrix2D
-	}
-});
-dojox.gfx.Ellipse.nodeType = "Ellipse";
-
-dojo.declare("dojox.gfx.Circle", dojox.gfx.shape.Circle, {
-	// summary: a circle shape (Silverlight)
-	setShape: function(newShape){
-		// summary: sets a circle shape object (Silverlight)
-		// newShape: Object: a circle shape object
-		this.shape = dojox.gfx.makeParameters(this.shape, newShape);
-		this.bbox = null;
-		var r = this.rawNode, n = this.shape;
-		r.width = r.height = 2 * n.r;
-		return this._applyTransform();	// self
-	},
-	_getAdjustedMatrix: function(){
-		// summary: returns the adjusted ("real") transformation matrix
-		var m = this.matrix, s = this.shape, d = {dx: s.cx - s.r, dy: s.cy - s.r};
-		return new dojox.gfx.Matrix2D(m ? [m, d] : d);	// dojox.gfx.Matrix2D
-	}
-});
-dojox.gfx.Circle.nodeType = "Ellipse";
-
-dojo.declare("dojox.gfx.Line", dojox.gfx.shape.Line, {
-	// summary: a line shape (Silverlight)
-	setShape: function(newShape){
-		// summary: sets a line shape object (Silverlight)
-		// newShape: Object: a line shape object
-		this.shape = dojox.gfx.makeParameters(this.shape, newShape);
-		this.bbox = null;
-		var r = this.rawNode, n = this.shape;
-		r.x1 = n.x1; r.y1 = n.y1; r.x2 = n.x2; r.y2 = n.y2;
-		return this;	// self
-	}
-});
-dojox.gfx.Line.nodeType = "Line";
-
-dojo.declare("dojox.gfx.Polyline", dojox.gfx.shape.Polyline, {
-	// summary: a polyline/polygon shape (Silverlight)
-	setShape: function(points, closed){
-		// summary: sets a polyline/polygon shape object (Silverlight)
-		// points: Object: a polyline/polygon shape object
-		if(points && points instanceof Array){
-			// branch
-			// points: Array: an array of points
-			this.shape = dojox.gfx.makeParameters(this.shape, {points: points});
-			if(closed && this.shape.points.length){
-				this.shape.points.push(this.shape.points[0]);
-			}
-		}else{
-			this.shape = dojox.gfx.makeParameters(this.shape, points);
+	});
+	sl.Group.nodeType = "Canvas";
+
+	d.declare("dojox.gfx.silverlight.Rect", [sl.Shape, gs.Rect], {
+		// summary: a rectangle shape (Silverlight)
+		setShape: function(newShape){
+			// summary: sets a rectangle shape object (Silverlight)
+			// newShape: Object: a rectangle shape object
+			this.shape = g.makeParameters(this.shape, newShape);
+			this.bbox = null;
+			var r = this.rawNode, n = this.shape;
+			r.width   = n.width;
+			r.height  = n.height;
+			r.radiusX = r.radiusY = n.r;
+			return this._applyTransform();	// self
+		},
+		_getAdjustedMatrix: function(){
+			// summary: returns the adjusted ("real") transformation matrix
+			var matrix = this.matrix, s = this.shape, delta = {dx: s.x, dy: s.y};
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
 		}
-		this.bbox = null;
-		this._normalizePoints();
-		var p = this.shape.points, rp = [];
-		for(var i = 0; i < p.length; ++i){
-			rp.push(p[i].x, p[i].y);
+	});
+	sl.Rect.nodeType = "Rectangle";
+
+	d.declare("dojox.gfx.silverlight.Ellipse", [sl.Shape, gs.Ellipse], {
+		// summary: an ellipse shape (Silverlight)
+		setShape: function(newShape){
+			// summary: sets an ellipse shape object (Silverlight)
+			// newShape: Object: an ellipse shape object
+			this.shape = g.makeParameters(this.shape, newShape);
+			this.bbox = null;
+			var r = this.rawNode, n = this.shape;
+			r.width  = 2 * n.rx;
+			r.height = 2 * n.ry;
+			return this._applyTransform();	// self
+		},
+		_getAdjustedMatrix: function(){
+			// summary: returns the adjusted ("real") transformation matrix
+			var matrix = this.matrix, s = this.shape, delta = {dx: s.cx - s.rx, dy: s.cy - s.ry};
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
 		}
-		this.rawNode.points = rp.join(",");
-		return this;	// self
-	}
-});
-dojox.gfx.Polyline.nodeType = "Polyline";
-
-dojo.declare("dojox.gfx.Image", dojox.gfx.shape.Image, {
-	// summary: an image (Silverlight)
-	setShape: function(newShape){
-		// summary: sets an image shape object (Silverlight)
-		// newShape: Object: an image shape object
-		this.shape = dojox.gfx.makeParameters(this.shape, newShape);
-		this.bbox = null;
-		var r = this.rawNode, n = this.shape;
-		r.width  = n.width;
-		r.height = n.height;
-		r.source = n.src;
-		return this._applyTransform();	// self
-	},
-	_getAdjustedMatrix: function(){
-		// summary: returns the adjusted ("real") transformation matrix
-		var m = this.matrix, s = this.shape, d = {dx: s.x, dy: s.y};
-		return new dojox.gfx.Matrix2D(m ? [m, d] : d);	// dojox.gfx.Matrix2D
-	},
-	setRawNode: function(rawNode){
-		// summary:
-		//	assigns and clears the underlying node that will represent this
-		//	shape. Once set, transforms, gradients, etc, can be applied.
-		//	(no fill & stroke by default)
-		this.rawNode = rawNode;
-	}
-});
-dojox.gfx.Image.nodeType = "Image";
-
-dojo.declare("dojox.gfx.Text", dojox.gfx.shape.Text, {
-	// summary: an anchored text (Silverlight)
-	setShape: function(newShape){
-		// summary: sets a text shape object (Silverlight)
-		// newShape: Object: a text shape object
-		this.shape = dojox.gfx.makeParameters(this.shape, newShape);
-		this.bbox = null;
-		var r = this.rawNode, s = this.shape;
-		r.text = s.text;
-		r.textDecorations = s.decoration === "underline" ? "Underline" : "None";
-		r["Canvas.Left"] = -10000;
-		r["Canvas.Top"]  = -10000;
-		if(!this._delay){
-			this._delay = window.setTimeout(dojo.hitch(this, "_delayAlignment"), 10);
+	});
+	sl.Ellipse.nodeType = "Ellipse";
+
+	d.declare("dojox.gfx.silverlight.Circle", [sl.Shape, gs.Circle], {
+		// summary: a circle shape (Silverlight)
+		setShape: function(newShape){
+			// summary: sets a circle shape object (Silverlight)
+			// newShape: Object: a circle shape object
+			this.shape = g.makeParameters(this.shape, newShape);
+			this.bbox = null;
+			var r = this.rawNode, n = this.shape;
+			r.width = r.height = 2 * n.r;
+			return this._applyTransform();	// self
+		},
+		_getAdjustedMatrix: function(){
+			// summary: returns the adjusted ("real") transformation matrix
+			var matrix = this.matrix, s = this.shape, delta = {dx: s.cx - s.r, dy: s.cy - s.r};
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
 		}
-		return this;	// self
-	},
-	_delayAlignment: function(){
-		// handle alignment
-		var r = this.rawNode, s = this.shape,
-			w = r.actualWidth, h = r.actualHeight, x = s.x, y = s.y - h * 0.75;
-		switch(s.align){
-			case "middle":
-				x -= w / 2;
-				break;
-			case "end":
-				x -= w;
-				break;
+	});
+	sl.Circle.nodeType = "Ellipse";
+
+	d.declare("dojox.gfx.silverlight.Line", [sl.Shape, gs.Line], {
+		// summary: a line shape (Silverlight)
+		setShape: function(newShape){
+			// summary: sets a line shape object (Silverlight)
+			// newShape: Object: a line shape object
+			this.shape = g.makeParameters(this.shape, newShape);
+			this.bbox = null;
+			var r = this.rawNode, n = this.shape;
+			r.x1 = n.x1; r.y1 = n.y1; r.x2 = n.x2; r.y2 = n.y2;
+			return this;	// self
 		}
-		this._delta = {dx: x, dy: y};
-		r["Canvas.Left"] = 0;
-		r["Canvas.Top"]  = 0;
-		this._applyTransform();
-		delete this._delay;
-	},
-	_getAdjustedMatrix: function(){
-		// summary: returns the adjusted ("real") transformation matrix
-		var m = this.matrix, d = this._delta, x;
-		if(m){
-			x = d ? [m, d] : m;
-		}else{
-			x = d ? d : {};
+	});
+	sl.Line.nodeType = "Line";
+
+	d.declare("dojox.gfx.silverlight.Polyline", [sl.Shape, gs.Polyline], {
+		// summary: a polyline/polygon shape (Silverlight)
+		setShape: function(points, closed){
+			// summary: sets a polyline/polygon shape object (Silverlight)
+			// points: Object: a polyline/polygon shape object
+			if(points && points instanceof Array){
+				// branch
+				// points: Array: an array of points
+				this.shape = g.makeParameters(this.shape, {points: points});
+				if(closed && this.shape.points.length){
+					this.shape.points.push(this.shape.points[0]);
+				}
+			}else{
+				this.shape = g.makeParameters(this.shape, points);
+			}
+			this.bbox = null;
+			this._normalizePoints();
+			var p = this.shape.points, rp = [];
+			for(var i = 0; i < p.length; ++i){
+				rp.push(p[i].x, p[i].y);
+			}
+			this.rawNode.points = rp.join(",");
+			return this;	// self
 		}
-		return new dojox.gfx.Matrix2D(x);
-	},
-	setStroke: function(){
-		// summary: ignore setting a stroke style
-		return this;	// self
-	},
-	_setFillAttr: function(f){
-		this.rawNode.foreground = f;
-	},
-	setRawNode: function(rawNode){
-		// summary:
-		//	assigns and clears the underlying node that will represent this
-		//	shape. Once set, transforms, gradients, etc, can be applied.
-		//	(no fill & stroke by default)
-		this.rawNode = rawNode;
-	},
-	getTextWidth: function(){
-		// summary: get the text width in pixels
-		return this.rawNode.actualWidth;
-	}
-});
-dojox.gfx.Text.nodeType = "TextBlock";
-
-dojo.declare("dojox.gfx.Path", dojox.gfx.path.Path, {
-	// summary: a path shape (Silverlight)
-	_updateWithSegment: function(segment){
-		// summary: updates the bounding box of path with new segment
-		// segment: Object: a segment
-		dojox.gfx.Path.superclass._updateWithSegment.apply(this, arguments);
-		var p = this.shape.path;
-		if(typeof(p) == "string"){
+	});
+	sl.Polyline.nodeType = "Polyline";
+
+	d.declare("dojox.gfx.silverlight.Image", [sl.Shape, gs.Image], {
+		// summary: an image (Silverlight)
+		setShape: function(newShape){
+			// summary: sets an image shape object (Silverlight)
+			// newShape: Object: an image shape object
+			this.shape = g.makeParameters(this.shape, newShape);
+			this.bbox = null;
+			var r = this.rawNode, n = this.shape;
+			r.width  = n.width;
+			r.height = n.height;
+			r.source = n.src;
+			return this._applyTransform();	// self
+		},
+		_getAdjustedMatrix: function(){
+			// summary: returns the adjusted ("real") transformation matrix
+			var matrix = this.matrix, s = this.shape, delta = {dx: s.x, dy: s.y};
+			return new g.Matrix2D(matrix ? [matrix, delta] : delta);	// dojox.gfx.Matrix2D
+		},
+		setRawNode: function(rawNode){
+			// summary:
+			//	assigns and clears the underlying node that will represent this
+			//	shape. Once set, transforms, gradients, etc, can be applied.
+			//	(no fill & stroke by default)
+			this.rawNode = rawNode;
+		}
+	});
+	sl.Image.nodeType = "Image";
+
+	d.declare("dojox.gfx.silverlight.Text", [sl.Shape, gs.Text], {
+		// summary: an anchored text (Silverlight)
+		setShape: function(newShape){
+			// summary: sets a text shape object (Silverlight)
+			// newShape: Object: a text shape object
+			this.shape = g.makeParameters(this.shape, newShape);
+			this.bbox = null;
+			var r = this.rawNode, s = this.shape;
+			r.text = s.text;
+			r.textDecorations = s.decoration === "underline" ? "Underline" : "None";
+			r["Canvas.Left"] = -10000;
+			r["Canvas.Top"]  = -10000;
+			if(!this._delay){
+				this._delay = window.setTimeout(d.hitch(this, "_delayAlignment"), 10);
+			}
+			return this;	// self
+		},
+		_delayAlignment: function(){
+			// handle alignment
+			var r = this.rawNode, s = this.shape, w, h;
+			try{
+				w = r.actualWidth;
+				h = r.actualHeight;
+			}catch(e){
+				// bail out if the node is hidden
+				return;
+			}
+			var x = s.x, y = s.y - h * 0.75;
+			switch(s.align){
+				case "middle":
+					x -= w / 2;
+					break;
+				case "end":
+					x -= w;
+					break;
+			}
+			this._delta = {dx: x, dy: y};
+			r["Canvas.Left"] = 0;
+			r["Canvas.Top"]  = 0;
+			this._applyTransform();
+			delete this._delay;
+		},
+		_getAdjustedMatrix: function(){
+			// summary: returns the adjusted ("real") transformation matrix
+			var matrix = this.matrix, delta = this._delta, x;
+			if(matrix){
+				x = delta ? [matrix, delta] : matrix;
+			}else{
+				x = delta ? delta : {};
+			}
+			return new g.Matrix2D(x);
+		},
+		setStroke: function(){
+			// summary: ignore setting a stroke style
+			return this;	// self
+		},
+		_setFillAttr: function(f){
+			this.rawNode.foreground = f;
+		},
+		setRawNode: function(rawNode){
+			// summary:
+			//	assigns and clears the underlying node that will represent this
+			//	shape. Once set, transforms, gradients, etc, can be applied.
+			//	(no fill & stroke by default)
+			this.rawNode = rawNode;
+		},
+		getTextWidth: function(){
+			// summary: get the text width in pixels
+			return this.rawNode.actualWidth;
+		}
+	});
+	sl.Text.nodeType = "TextBlock";
+
+	d.declare("dojox.gfx.silverlight.Path", [sl.Shape, g.path.Path], {
+		// summary: a path shape (Silverlight)
+		_updateWithSegment: function(segment){
+			// summary: updates the bounding box of path with new segment
+			// segment: Object: a segment
+			this.inherited(arguments);
+			var p = this.shape.path;
+			if(typeof(p) == "string"){
+				this.rawNode.data = p ? p : null;
+			}
+		},
+		setShape: function(newShape){
+			// summary: forms a path using a shape (Silverlight)
+			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+			this.inherited(arguments);
+			var p = this.shape.path;
 			this.rawNode.data = p ? p : null;
+			return this;	// self
 		}
-	},
-	setShape: function(newShape){
-		// summary: forms a path using a shape (Silverlight)
-		// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
-		dojox.gfx.Path.superclass.setShape.apply(this, arguments);
-		var p = this.shape.path;
-		this.rawNode.data = p ? p : null;
-		return this;	// self
-	}
-});
-dojox.gfx.Path.nodeType = "Path";
-
-dojo.declare("dojox.gfx.TextPath", dojox.gfx.path.TextPath, {
-	// summary: a textpath shape (Silverlight)
-	_updateWithSegment: function(segment){
-		// summary: updates the bounding box of path with new segment
-		// segment: Object: a segment
-	},
-	setShape: function(newShape){
-		// summary: forms a path using a shape (Silverlight)
-		// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
-	},
-	_setText: function(){
-	}
-});
-dojox.gfx.TextPath.nodeType = "text";
-
-dojox.gfx.silverlight.surfaces = {};
-dojox.gfx.silverlight.nullFunc = function(){};
-
-dojo.declare("dojox.gfx.Surface", dojox.gfx.shape.Surface, {
-	// summary: a surface object to be used for drawings (Silverlight)
-	constructor: function(){
-		dojox.gfx.silverlight.Container._init.call(this);
-	},
-	destroy: function(){
-		window[this._onLoadName] = dojox.gfx.silverlight.nullFunc;
-		delete dojox.gfx.silverlight.surfaces[this.rawNode.name];
-		this.inherited(arguments);
-	},
-	setDimensions: function(width, height){
-		// summary: sets the width and height of the rawNode
+	});
+	sl.Path.nodeType = "Path";
+
+	d.declare("dojox.gfx.silverlight.TextPath", [sl.Shape, g.path.TextPath], {
+		// summary: a textpath shape (Silverlight)
+		_updateWithSegment: function(segment){
+			// summary: updates the bounding box of path with new segment
+			// segment: Object: a segment
+		},
+		setShape: function(newShape){
+			// summary: forms a path using a shape (Silverlight)
+			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
+		},
+		_setText: function(){
+		}
+	});
+	sl.TextPath.nodeType = "text";
+
+	var surfaces = {}, nullFunc = new Function;
+
+	d.declare("dojox.gfx.silverlight.Surface", gs.Surface, {
+		// summary: a surface object to be used for drawings (Silverlight)
+		constructor: function(){
+			gs.Container._init.call(this);
+		},
+		destroy: function(){
+			window[this._onLoadName] = nullFunc;
+			delete surfaces[this._nodeName];
+			this.inherited(arguments);
+		},
+		setDimensions: function(width, height){
+			// summary: sets the width and height of the rawNode
+			// width: String: width of surface, e.g., "100px"
+			// height: String: height of surface, e.g., "100px"
+			this.width  = g.normalizedLength(width);	// in pixels
+			this.height = g.normalizedLength(height);	// in pixels
+			var p = this.rawNode && this.rawNode.getHost();
+			if(p){
+				p.width = width;
+				p.height = height;
+			}
+			return this;	// self
+		},
+		getDimensions: function(){
+			// summary: returns an object with properties "width" and "height"
+			var p = this.rawNode && this.rawNode.getHost();
+			var t = p ? {width: p.content.actualWidth, height: p.content.actualHeight} : null;
+			if(t.width  <= 0){ t.width  = this.width; }
+			if(t.height <= 0){ t.height = this.height; }
+			return t;	// Object
+		}
+	});
+
+	sl.createSurface = function(parentNode, width, height){
+		// summary: creates a surface (Silverlight)
+		// parentNode: Node: a parent node
 		// width: String: width of surface, e.g., "100px"
 		// height: String: height of surface, e.g., "100px"
-		this.width  = dojox.gfx.normalizedLength(width);	// in pixels
-		this.height = dojox.gfx.normalizedLength(height);	// in pixels
-		var p = this.rawNode && this.rawNode.getHost();
-		if(p){
-			p.width = width;
-			p.height = height;
+
+		if(!width && !height){
+			var pos = d.position(parentNode);
+			width  = width  || pos.w;
+			height = height || pos.h;
+		}
+		if(typeof width == "number"){
+			width = width + "px";
+		}
+		if(typeof height == "number"){
+			height = height + "px";
 		}
-		return this;	// self
-	},
-	getDimensions: function(){
-		// summary: returns an object with properties "width" and "height"
-		var p = this.rawNode && this.rawNode.getHost();
-		var t = p ? {width: p.content.actualWidth, height: p.content.actualHeight} : null;
-		if(t.width  <= 0){ t.width  = this.width; }
-		if(t.height <= 0){ t.height = this.height; }
-		return t;	// Object
-	}
-});
-
-dojox.gfx.createSurface = function(parentNode, width, height){
-	// summary: creates a surface (Silverlight)
-	// parentNode: Node: a parent node
-	// width: String: width of surface, e.g., "100px"
-	// height: String: height of surface, e.g., "100px"
-
-	if(!width && !height){
-		var pos = d.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 dojox.gfx.Surface();
-	parentNode = dojo.byId(parentNode);
-	s._parent = parentNode;
-
-	// create an empty canvas
-	var t = parentNode.ownerDocument.createElement("script");
-	t.type = "text/xaml";
-	t.id = dojox.gfx._base._getUniqueId();
-	t.text = "<?xml version='1.0'?><Canvas xmlns='http://schemas.microsoft.com/client/2007' Name='" +
-		dojox.gfx._base._getUniqueId() + "'/>";
-	parentNode.parentNode.insertBefore(t, parentNode);
-	s._nodes.push(t);
-
-	// build the object
-	var obj, pluginName = dojox.gfx._base._getUniqueId(),
-		onLoadName = "__" + dojox.gfx._base._getUniqueId() + "_onLoad";
-	s._onLoadName = onLoadName;
-	window[onLoadName] = function(sender){
-		console.log("Silverlight: loaded");
-		if(!s.rawNode){
-			s.rawNode = dojo.byId(pluginName).content.root;
+		var s = new sl.Surface();
+		parentNode = d.byId(parentNode);
+		s._parent = parentNode;
+		s._nodeName = g._base._getUniqueId();
+
+		// create an empty canvas
+		var t = parentNode.ownerDocument.createElement("script");
+		t.type = "text/xaml";
+		t.id = g._base._getUniqueId();
+		t.text = "<?xml version='1.0'?><Canvas xmlns='http://schemas.microsoft.com/client/2007' Name='" +
+			s._nodeName + "'/>";
+		parentNode.parentNode.insertBefore(t, parentNode);
+		s._nodes.push(t);
+
+		// build the object
+		var obj, pluginName = g._base._getUniqueId(),
+			onLoadName = "__" + g._base._getUniqueId() + "_onLoad";
+		s._onLoadName = onLoadName;
+		window[onLoadName] = function(sender){
+			if(!s.rawNode){
+				s.rawNode = d.byId(pluginName).content.root;
+				// register the plugin with its parent node
+				surfaces[s._nodeName] = parentNode;
+				s.onLoad(s);
+			}
+		};
+		if(d.isSafari){
+			obj = "<embed type='application/x-silverlight' id='" +
+			pluginName + "' width='" + width + "' height='" + height +
+			" background='transparent'" +
+			" source='#" + t.id + "'" +
+			" windowless='true'" +
+			" maxFramerate='60'" +
+			" onLoad='" + onLoadName + "'" +
+			" onError='__dojoSilverlightError'" +
+			" /><iframe style='visibility:hidden;height:0;width:0'/>";
+		}else{
+			obj = "<object type='application/x-silverlight' data='data:application/x-silverlight,' id='" +
+			pluginName + "' width='" + width + "' height='" + height + "'>" +
+			"<param name='background' value='transparent' />" +
+			"<param name='source' value='#" + t.id + "' />" +
+			"<param name='windowless' value='true' />" +
+			"<param name='maxFramerate' value='60' />" +
+			"<param name='onLoad' value='" + onLoadName + "' />" +
+			"<param name='onError' value='__dojoSilverlightError' />" +
+			"</object>";
+		}
+		parentNode.innerHTML = obj;
+
+		var pluginNode = d.byId(pluginName);
+		if(pluginNode.content && pluginNode.content.root){
+			// the plugin was created synchronously
+			s.rawNode = pluginNode.content.root;
 			// register the plugin with its parent node
-			dojox.gfx.silverlight.surfaces[s.rawNode.name] = parentNode;
-			s.onLoad(s);
-			console.log("Silverlight: assigned");
+			surfaces[s._nodeName] = parentNode;
+		}else{
+			// the plugin is being created asynchronously
+			s.rawNode = null;
+			s.isLoaded = false;
 		}
+		s._nodes.push(pluginNode);
+
+		s.width  = g.normalizedLength(width);	// in pixels
+		s.height = g.normalizedLength(height);	// in pixels
+
+		return s;	// dojox.gfx.Surface
 	};
-	if(dojo.isSafari){
-		obj = "<embed type='application/x-silverlight' id='" +
-		pluginName + "' width='" + width + "' height='" + height +
-		" background='transparent'" +
-		" source='#" + t.id + "'" +
-		" windowless='true'" +
-		" maxFramerate='60'" +
-		" onLoad='" + onLoadName + "'" +
-		" onError='__dojoSilverlightError'" +
-		" /><iframe style='visibility:hidden;height:0;width:0'/>";
-	}else{
-		obj = "<object type='application/x-silverlight' data='data:application/x-silverlight,' id='" +
-		pluginName + "' width='" + width + "' height='" + height + "'>" +
-		"<param name='background' value='transparent' />" +
-		"<param name='source' value='#" + t.id + "' />" +
-		"<param name='windowless' value='true' />" +
-		"<param name='maxFramerate' value='60' />" +
-		"<param name='onLoad' value='" + onLoadName + "' />" +
-		"<param name='onError' value='__dojoSilverlightError' />" +
-		"</object>";
-	}
-	parentNode.innerHTML = obj;
-
-	var pluginNode = dojo.byId(pluginName);
-	if(pluginNode.content && pluginNode.content.root){
-		// the plugin was created synchronously
-		s.rawNode = pluginNode.content.root;
-		// register the plugin with its parent node
-		dojox.gfx.silverlight.surfaces[s.rawNode.name] = parentNode;
-	}else{
-		// the plugin is being created asynchronously
-		s.rawNode = null;
-		s.isLoaded = false;
-	}
-	s._nodes.push(pluginNode);
-
-	s.width  = dojox.gfx.normalizedLength(width);	// in pixels
-	s.height = dojox.gfx.normalizedLength(height);	// in pixels
-
-	return s;	// dojox.gfx.Surface
-};
-
-// the function below is meant to be global, it is called from
-// the Silverlight's error handler
-__dojoSilverlightError = function(sender, err){
-	var t = "Silverlight Error:\n" +
-		"Code: " + err.ErrorCode + "\n" +
-		"Type: " + err.ErrorType + "\n" +
-		"Message: " + err.ErrorMessage + "\n";
-	switch(err.ErrorType){
-		case "ParserError":
-			t += "XamlFile: " + err.xamlFile + "\n" +
-				"Line: " + err.lineNumber + "\n" +
-				"Position: " + err.charPosition + "\n";
-			break;
-		case "RuntimeError":
-			t += "MethodName: " + err.methodName + "\n";
-			if(err.lineNumber != 0){
-				t +=
+
+	// the function below is meant to be global, it is called from
+	// the Silverlight's error handler
+	__dojoSilverlightError = function(sender, err){
+		var t = "Silverlight Error:\n" +
+			"Code: " + err.ErrorCode + "\n" +
+			"Type: " + err.ErrorType + "\n" +
+			"Message: " + err.ErrorMessage + "\n";
+		switch(err.ErrorType){
+			case "ParserError":
+				t += "XamlFile: " + err.xamlFile + "\n" +
 					"Line: " + err.lineNumber + "\n" +
 					"Position: " + err.charPosition + "\n";
-			}
-			break;
-	}
-	console.error(t);
-};
-
-// Extenders
-
-dojox.gfx.silverlight.Font = {
-	_setFont: function(){
-		// summary: sets a font object (Silverlight)
-		var f = this.fontStyle, r = this.rawNode,
-			fw = dojox.gfx.silverlight.fontweight,
-			fo = dojox.gfx.silverlight.fonts, t = f.family.toLowerCase();
-		r.fontStyle = f.style == "italic" ? "Italic" : "Normal";
-		r.fontWeight = f.weight in fw ? fw[f.weight] : f.weight;
-		r.fontSize = dojox.gfx.normalizedLength(f.size);
-		r.fontFamily = t in fo ? fo[t] : f.family;
-
-		// update the transform
-		if(!this._delay){
-			this._delay = window.setTimeout(dojo.hitch(this, "_delayAlignment"), 10);
+				break;
+			case "RuntimeError":
+				t += "MethodName: " + err.methodName + "\n";
+				if(err.lineNumber != 0){
+					t +=
+						"Line: " + err.lineNumber + "\n" +
+						"Position: " + err.charPosition + "\n";
+				}
+				break;
 		}
-	}
-};
-
-dojox.gfx.silverlight.Container = {
-	_init: function(){
-		dojox.gfx.shape.Container._init.call(this);
-	},
-	add: function(shape){
-		// summary: adds a shape to a group/surface
-		// shape: dojox.gfx.Shape: a Silverlight shape object
-		if(this != shape.getParent()){
-			//dojox.gfx.Group.superclass.add.apply(this, arguments);
-			//this.inherited(arguments);
-			dojox.gfx.shape.Container.add.apply(this, arguments);
-			this.rawNode.children.add(shape.rawNode);
+	};
+
+	// Extenders
+
+	var Font = {
+		_setFont: function(){
+			// summary: sets a font object (Silverlight)
+			var f = this.fontStyle, r = this.rawNode, t = f.family.toLowerCase();
+			r.fontStyle = f.style == "italic" ? "Italic" : "Normal";
+			r.fontWeight = f.weight in fontweight ? fontweight[f.weight] : f.weight;
+			r.fontSize = g.normalizedLength(f.size);
+			r.fontFamily = t in fonts ? fonts[t] : f.family;
+
+			// update the transform
+			if(!this._delay){
+				this._delay = window.setTimeout(d.hitch(this, "_delayAlignment"), 10);
+			}
 		}
-		return this;	// self
-	},
-	remove: function(shape, silently){
-		// summary: remove a shape from a group/surface
-		// shape: dojox.gfx.Shape: a Silverlight shape object
-		// silently: Boolean?: if true, regenerate a picture
-		if(this == shape.getParent()){
-			var parent = shape.rawNode.getParent();
-			if(parent){
-				parent.children.remove(shape.rawNode);
+	};
+
+	var C = gs.Container, Container = {
+		add: function(shape){
+			// summary: adds a shape to a group/surface
+			// shape: dojox.gfx.Shape: a Silverlight shape object
+			if(this != shape.getParent()){
+				C.add.apply(this, arguments);
+				this.rawNode.children.add(shape.rawNode);
+			}
+			return this;	// self
+		},
+		remove: function(shape, silently){
+			// summary: remove a shape from a group/surface
+			// shape: dojox.gfx.Shape: a Silverlight shape object
+			// silently: Boolean?: if true, regenerate a picture
+			if(this == shape.getParent()){
+				var parent = shape.rawNode.getParent();
+				if(parent){
+					parent.children.remove(shape.rawNode);
+				}
+				C.remove.apply(this, arguments);
 			}
-			//dojox.gfx.Group.superclass.remove.apply(this, arguments);
-			//this.inherited(arguments);
-			dojox.gfx.shape.Container.remove.apply(this, arguments);
+			return this;	// self
+		},
+		clear: function(){
+			// summary: removes all shapes from a group/surface
+			this.rawNode.children.clear();
+			return C.clear.apply(this, arguments);
+		},
+		_moveChildToFront: C._moveChildToFront,
+		_moveChildToBack:  C._moveChildToBack
+	};
+
+	var Creator = {
+		createObject: function(shapeType, rawShape){
+			// summary: creates an instance of the passed shapeType class
+			// shapeType: Function: a class constructor to create an instance of
+			// rawShape: Object: properties to be passed in to the classes "setShape" method
+			if(!this.rawNode){ return null; }
+			var shape = new shapeType();
+			var node = this.rawNode.getHost().content.createFromXaml("<" + shapeType.nodeType + "/>");
+			shape.setRawNode(node);
+			shape.setShape(rawShape);
+			this.add(shape);
+			return shape;	// dojox.gfx.Shape
 		}
-		return this;	// self
-	},
-	clear: function(){
-		// summary: removes all shapes from a group/surface
-		this.rawNode.children.clear();
-		//return this.inherited(arguments);	// self
-		return dojox.gfx.shape.Container.clear.apply(this, arguments);
-	},
-	_moveChildToFront: dojox.gfx.shape.Container._moveChildToFront,
-	_moveChildToBack:  dojox.gfx.shape.Container._moveChildToBack
-};
-
-dojo.mixin(dojox.gfx.shape.Creator, {
-	createObject: function(shapeType, rawShape){
-		// summary: creates an instance of the passed shapeType class
-		// shapeType: Function: a class constructor to create an instance of
-		// rawShape: Object: properties to be passed in to the classes "setShape" method
-		if(!this.rawNode){ return null; }
-		var shape = new shapeType();
-		var node = this.rawNode.getHost().content.createFromXaml("<" + shapeType.nodeType + "/>");
-		shape.setRawNode(node);
-		shape.setShape(rawShape);
-		this.add(shape);
-		return shape;	// dojox.gfx.Shape
-	}
-});
+	};
 
-dojo.extend(dojox.gfx.Text, dojox.gfx.silverlight.Font);
-//dojo.extend(dojox.gfx.TextPath, dojox.gfx.silverlight.Font);
+	d.extend(sl.Text, Font);
+	//d.extend(sl.TextPath, Font);
 
-dojo.extend(dojox.gfx.Group, dojox.gfx.silverlight.Container);
-dojo.extend(dojox.gfx.Group, dojox.gfx.shape.Creator);
+	d.extend(sl.Group, Container);
+	d.extend(sl.Group, gs.Creator);
+	d.extend(sl.Group, Creator);
 
-dojo.extend(dojox.gfx.Surface, dojox.gfx.silverlight.Container);
-dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
+	d.extend(sl.Surface, Container);
+	d.extend(sl.Surface, gs.Creator);
+	d.extend(sl.Surface, Creator);
 
-(function(){
-	var surfaces = dojox.gfx.silverlight.surfaces;
-	var mouseFix = function(s, a){
-		var ev = {target: s, currentTarget: s,
-			preventDefault: function(){}, stopPropagation: function(){}};
+	function mouseFix(s, a){
+		var ev = {target: s, currentTarget: s, preventDefault: function(){}, stopPropagation: function(){}};
+		try{
+			if(a.source){
+				// support silverlight 2.0
+				ev.target = a.source;
+			}
+		}catch(e){
+			// a.source does not exist in 1.0
+		}
+	
 		if(a){
 			try{
 				ev.ctrlKey = a.ctrl;
@@ -731,7 +732,7 @@ dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
 				ev.y = ev.offsetY = ev.layerY = p.y;
 				// calculate clientX and clientY
 				var parent = surfaces[s.getHost().content.root.name];
-				var t = dojo.position(parent);
+				var t = d.position(parent);
 				ev.clientX = t.x + p.x;
 				ev.clientY = t.y + p.y;
 			}catch(e){
@@ -739,15 +740,25 @@ dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
 			}
 		}
 		return ev;
-	};
-	var keyFix = function(s, a){
+	}
+	
+	function keyFix(s, a){
 		var ev = {
 			keyCode:  a.platformKeyCode,
 			ctrlKey:  a.ctrl,
 			shiftKey: a.shift
 		};
+		try{
+			if(a.source){
+				// source is defined from Silverlight 2+
+				ev.target = a.source;
+			}
+		}catch(e){
+			// a.source does not exist in 1.0
+		}
 		return ev;
-	};
+	}
+	
 	var eventNames = {
 		onclick:		{name: "MouseLeftButtonUp", fix: mouseFix},
 		onmouseenter:	{name: "MouseEnter", fix: mouseFix},
@@ -760,13 +771,14 @@ dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
 		onkeydown:		{name: "KeyDown", fix: keyFix},
 		onkeyup:		{name: "KeyUp", fix: keyFix}
 	};
+	
 	var eventsProcessing = {
 		connect: function(name, object, method){
 			var token, n = name in eventNames ? eventNames[name] :
 				{name: name, fix: function(){ return {}; }};
 			if(arguments.length > 2){
 				token = this.getEventSource().addEventListener(n.name,
-					function(s, a){ dojo.hitch(object, method)(n.fix(s, a)); });
+					function(s, a){ d.hitch(object, method)(n.fix(s, a)); });
 			}else{
 				token = this.getEventSource().addEventListener(n.name,
 					function(s, a){ object(n.fix(s, a)); });
@@ -774,13 +786,27 @@ dojo.extend(dojox.gfx.Surface, dojox.gfx.shape.Creator);
 			return {name: n.name, token: token};
 		},
 		disconnect: function(token){
-			this.getEventSource().removeEventListener(token.name, token.token);
+			try{
+				this.getEventSource().removeEventListener(token.name, token.token);
+			}catch(e){
+				// bail out if the node is hidden
+			}
 		}
 	};
-	dojo.extend(dojox.gfx.Shape, eventsProcessing);
-	dojo.extend(dojox.gfx.Surface, eventsProcessing);
-	dojox.gfx.equalSources = function(a, b){
+	
+	d.extend(sl.Shape, eventsProcessing);
+	d.extend(sl.Surface, eventsProcessing);
+	
+	// patch dojox.gfx
+	g.equalSources = function(a, b){
+		// summary: compares event sources, returns true if they are equal
 		return a && b && a.equals(b);
+	};
+	
+	// see if we are required to initilize
+	if(g.loadAndSwitch === "silverlight"){
+		g.switchTo("silverlight");
+		delete g.loadAndSwitch;
 	}
-
 })();
+
diff --git a/dojox/gfx/silverlight_attach.js b/dojox/gfx/silverlight_attach.js
index f426db8..491a58c 100644
--- a/dojox/gfx/silverlight_attach.js
+++ b/dojox/gfx/silverlight_attach.js
@@ -1,87 +1,21 @@
+dojo.provide("dojox.gfx.silverlight_attach");
+
 dojo.require("dojox.gfx.silverlight");
 
 dojo.experimental("dojox.gfx.silverlight_attach");
 
 (function(){
-	dojox.gfx.attachNode = function(node){
+	var g = dojox.gfx, sl = g.silverlight;
+	
+	sl.attachNode = function(node){
 		// summary: creates a shape from a Node
 		// node: Node: an Silverlight node
-		return null;	// for now
-		if(!node) return null;
-		var s = null;
-		switch(node.tagName.toLowerCase()){
-			case dojox.gfx.Rect.nodeType:
-				s = new dojox.gfx.Rect(node);
-				break;
-			case dojox.gfx.Ellipse.nodeType:
-				if(node.width == node.height){
-					s = new dojox.gfx.Circle(node);
-				}else{
-					s = new dojox.gfx.Ellipse(node);
-				}
-				break;
-			case dojox.gfx.Polyline.nodeType:
-				s = new dojox.gfx.Polyline(node);
-				break;
-			case dojox.gfx.Path.nodeType:
-				s = new dojox.gfx.Path(node);
-				break;
-			case dojox.gfx.Line.nodeType:
-				s = new dojox.gfx.Line(node);
-				break;
-			case dojox.gfx.Image.nodeType:
-				s = new dojox.gfx.Image(node);
-				break;
-			case dojox.gfx.Text.nodeType:
-				s = new dojox.gfx.Text(node);
-				attachFont(s);
-				break;
-			default:
-				//console.debug("FATAL ERROR! tagName = " + node.tagName);
-				return null;
-		}
-		attachShape(s);
-		if(!(s instanceof dojox.gfx.Image)){
-			attachFill(s);
-			attachStroke(s);
-		}
-		attachTransform(s);
-		return s;	// dojox.gfx.Shape
+		return null;	// not implemented
 	};
 
-	dojox.gfx.attachSurface = function(node){
+	sl.attachSurface = function(node){
 		// summary: creates a surface from a Node
 		// node: Node: an Silverlight node
 		return null;	// dojox.gfx.Surface
 	};
-
-	var attachFill = function(rawNode){
-		// summary: deduces a fill style from a Node.
-		// rawNode: Node: an Silverlight node
-		return null;	// Object
-	};
-
-	var attachStroke = function(rawNode){
-		// summary: deduces a stroke style from a Node.
-		// rawNode: Node: an SVG node
-		return null;	// Object
-	};
-
-	var attachTransform = function(rawNode){
-		// summary: deduces a transformation matrix from a Node.
-		// rawNode: Node: an Silverlight node
-		return null;	// dojox.gfx.matrix.Matrix
-	};
-
-	var attachFont = function(rawNode){
-		// summary: deduces a font style from a Node.
-		// rawNode: Node: an Silverlight node
-		return null;	// Object
-	};
-
-	var attachShape = function(rawNode){
-		// summary: builds a shape from a Node.
-		// rawNode: Node: an Silverlight node
-		return null;	// dojox.gfx.Shape
-	};
 })();
diff --git a/dojox/gfx/svg.js b/dojox/gfx/svg.js
index dc2fe89..8355fc8 100644
--- a/dojox/gfx/svg.js
+++ b/dojox/gfx/svg.js
@@ -6,9 +6,9 @@ dojo.require("dojox.gfx.path");
 
 (function(){
 	var d = dojo, g = dojox.gfx, gs = g.shape, svg = g.svg;
-	svg.useSvgWeb = (typeof(window.svgweb)!=='undefined');
+	svg.useSvgWeb = (typeof window.svgweb != "undefined");
 	
-	var _createElementNS = function(ns, nodeType){
+	function _createElementNS(ns, nodeType){
 		// summary:
 		//		Internal helper to deal with creating elements that
 		//		are namespaced.  Mainly to get SVG markup output
@@ -20,18 +20,18 @@ dojo.require("dojox.gfx.path");
 		}
 	}
 	
-	var _createTextNode = function(text) {
-		if (svg.useSvgWeb) {
+	function _createTextNode(text){
+		if(svg.useSvgWeb){
 			return dojo.doc.createTextNode(text, true);
-		} else {
+		}else{
 			return dojo.doc.createTextNode(text);
 		}
 	}
 	
-	var _createFragment = function() {
-		if (svg.useSvgWeb) {
+	function _createFragment(){
+		if(svg.useSvgWeb){
 			return dojo.doc.createDocumentFragment(true);
-		} else {
+		}else{
 			return dojo.doc.createDocumentFragment();
 		}
 	}
@@ -70,7 +70,7 @@ dojo.require("dojox.gfx.path");
 		longdashdotdot:		[8, 3, 1, 3, 1, 3]
 	};
 
-	d.extend(g.Shape, {
+	d.declare("dojox.gfx.svg.Shape", gs.Shape, {
 		// summary: SVG-specific implementation of dojox.gfx.Shape methods
 
 		setFill: function(fill){
@@ -284,7 +284,9 @@ dojo.require("dojox.gfx.path");
 			//	or dojox.gfx.defaultImage)
 			this.shape = g.makeParameters(this.shape, newShape);
 			for(var i in this.shape){
-				if(i != "type"){ this.rawNode.setAttribute(i, this.shape[i]); }
+				if(i != "type"){
+					this.rawNode.setAttribute(i, this.shape[i]);
+				}
 			}
 			this.bbox = null;
 			return this;	// self
@@ -304,11 +306,11 @@ dojo.require("dojox.gfx.path");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Group", g.Shape, {
+	dojo.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(){
-			svg.Container._init.call(this);
+			gs.Container._init.call(this);
 		},
 		setRawNode: function(rawNode){
 			// summary: sets a raw SVG node to be used by this shape
@@ -316,9 +318,9 @@ dojo.require("dojox.gfx.path");
 			this.rawNode = rawNode;
 		}
 	});
-	g.Group.nodeType = "g";
+	svg.Group.nodeType = "g";
 
-	dojo.declare("dojox.gfx.Rect", gs.Rect, {
+	dojo.declare("dojox.gfx.svg.Rect", [svg.Shape, gs.Rect], {
 		// summary: a rectangle shape (SVG)
 		setShape: function(newShape){
 			// summary: sets a rectangle shape object (SVG)
@@ -326,7 +328,9 @@ dojo.require("dojox.gfx.path");
 			this.shape = g.makeParameters(this.shape, newShape);
 			this.bbox = null;
 			for(var i in this.shape){
-				if(i != "type" && i != "r"){ this.rawNode.setAttribute(i, this.shape[i]); }
+				if(i != "type" && i != "r"){
+					this.rawNode.setAttribute(i, this.shape[i]);
+				}
 			}
 			if(this.shape.r){
 				this.rawNode.setAttribute("ry", this.shape.r);
@@ -335,18 +339,18 @@ dojo.require("dojox.gfx.path");
 			return this;	// self
 		}
 	});
-	g.Rect.nodeType = "rect";
+	svg.Rect.nodeType = "rect";
 
-	g.Ellipse = gs.Ellipse;
-	g.Ellipse.nodeType = "ellipse";
+	dojo.declare("dojox.gfx.svg.Ellipse", [svg.Shape, gs.Ellipse], {});
+	svg.Ellipse.nodeType = "ellipse";
 
-	g.Circle = gs.Circle;
-	g.Circle.nodeType = "circle";
+	dojo.declare("dojox.gfx.svg.Circle", [svg.Shape, gs.Circle], {});
+	svg.Circle.nodeType = "circle";
 
-	g.Line = gs.Line;
-	g.Line.nodeType = "line";
+	dojo.declare("dojox.gfx.svg.Line", [svg.Shape, gs.Line], {});
+	svg.Line.nodeType = "line";
 
-	dojo.declare("dojox.gfx.Polyline", gs.Polyline, {
+	dojo.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)
@@ -371,9 +375,9 @@ dojo.require("dojox.gfx.path");
 			return this;	// self
 		}
 	});
-	g.Polyline.nodeType = "polyline";
+	svg.Polyline.nodeType = "polyline";
 
-	dojo.declare("dojox.gfx.Image", gs.Image, {
+	dojo.declare("dojox.gfx.svg.Image", [svg.Shape, gs.Image], {
 		// summary: an image (SVG)
 		setShape: function(newShape){
 			// summary: sets an image shape object (SVG)
@@ -382,16 +386,18 @@ dojo.require("dojox.gfx.path");
 			this.bbox = null;
 			var rawNode = this.rawNode;
 			for(var i in this.shape){
-				if(i != "type" && i != "src"){ rawNode.setAttribute(i, this.shape[i]); }
+				if(i != "type" && i != "src"){
+					rawNode.setAttribute(i, this.shape[i]);
+				}
 			}
 			rawNode.setAttribute("preserveAspectRatio", "none");
 			rawNode.setAttributeNS(svg.xmlns.xlink, "xlink:href", this.shape.src);
 			return this;	// self
 		}
 	});
-	g.Image.nodeType = "image";
+	svg.Image.nodeType = "image";
 
-	dojo.declare("dojox.gfx.Text", gs.Text, {
+	dojo.declare("dojox.gfx.svg.Text", [svg.Shape, gs.Text], {
 		// summary: an anchored text (SVG)
 		setShape: function(newShape){
 			// summary: sets a text shape object (SVG)
@@ -441,14 +447,14 @@ else
 			return _width;
 		}
 	});
-	g.Text.nodeType = "text";
+	svg.Text.nodeType = "text";
 
-	dojo.declare("dojox.gfx.Path", g.path.Path, {
+	dojo.declare("dojox.gfx.svg.Path", [svg.Shape, g.path.Path], {
 		// summary: a path shape (SVG)
 		_updateWithSegment: function(segment){
 			// summary: updates the bounding box of path with new segment
 			// segment: Object: a segment
-			g.Path.superclass._updateWithSegment.apply(this, arguments);
+			this.inherited(arguments);
 			if(typeof(this.shape.path) == "string"){
 				this.rawNode.setAttribute("d", this.shape.path);
 			}
@@ -456,25 +462,29 @@ else
 		setShape: function(newShape){
 			// summary: forms a path using a shape (SVG)
 			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
-			g.Path.superclass.setShape.apply(this, arguments);
-			this.rawNode.setAttribute("d", this.shape.path);
+			this.inherited(arguments);
+			if(this.shape.path){
+				this.rawNode.setAttribute("d", this.shape.path);
+			}else{
+				this.rawNode.removeAttribute("d");
+			}
 			return this;	// self
 		}
 	});
-	g.Path.nodeType = "path";
+	svg.Path.nodeType = "path";
 
-	dojo.declare("dojox.gfx.TextPath", g.path.TextPath, {
+	dojo.declare("dojox.gfx.svg.TextPath", [svg.Shape, g.path.TextPath], {
 		// summary: a textpath shape (SVG)
 		_updateWithSegment: function(segment){
 			// summary: updates the bounding box of path with new segment
 			// segment: Object: a segment
-			g.Path.superclass._updateWithSegment.apply(this, arguments);
+			this.inherited(arguments);
 			this._setTextPath();
 		},
 		setShape: function(newShape){
 			// summary: forms a path using a shape (SVG)
 			// newShape: Object: an SVG path string or a path object (see dojox.gfx.defaultPath)
-			g.Path.superclass.setShape.apply(this, arguments);
+			this.inherited(arguments);
 			this._setTextPath();
 			return this;	// self
 		},
@@ -538,12 +548,12 @@ else
 			r.firstChild.data = t.text;
 		}
 	});
-	g.TextPath.nodeType = "text";
+	svg.TextPath.nodeType = "text";
 
-	dojo.declare("dojox.gfx.Surface", gs.Surface, {
+	dojo.declare("dojox.gfx.svg.Surface", gs.Surface, {
 		// summary: a surface object to be used for drawings (SVG)
 		constructor: function(){
-			svg.Container._init.call(this);
+			gs.Container._init.call(this);
 		},
 		destroy: function(){
 			this.defNode = null;	// release the external reference
@@ -567,13 +577,13 @@ else
 		}
 	});
 
-	g.createSurface = function(parentNode, width, height){
+	svg.createSurface = function(parentNode, width, height){
 		// summary: creates a surface (SVG)
 		// parentNode: Node: a parent node
 		// width: String: width of surface, e.g., "100px"
 		// height: String: height of surface, e.g., "100px"
 
-		var s = new g.Surface();
+		var s = new svg.Surface();
 		s.rawNode = _createElementNS(svg.xmlns.svg, "svg");
 		if(width){
 			s.rawNode.setAttribute("width",  width);
@@ -594,7 +604,7 @@ else
 
 	// Extenders
 
-	svg.Font = {
+	var Font = {
 		_setFont: function(){
 			// summary: sets a font object (SVG)
 			var f = this.fontStyle;
@@ -608,10 +618,7 @@ else
 		}
 	};
 
-	svg.Container = {
-		_init: function(){
-			gs.Container._init.call(this);
-		},
+	var C = gs.Container, Container = {
 		openBatch: function() {
 			// summary: starts a new batch, subsequent new child shapes will be held in
 			//	the batch instead of appending to the container directly
@@ -633,9 +640,7 @@ else
 				} else {
 					this.rawNode.appendChild(shape.rawNode);
 				}
-				//dojox.gfx.Group.superclass.add.apply(this, arguments);
-				//this.inherited(arguments);
-				gs.Container.add.apply(this, arguments);
+				C.add.apply(this, arguments);
 			}
 			return this;	// self
 		},
@@ -650,9 +655,7 @@ else
 				if(this.fragment && this.fragment == shape.rawNode.parentNode){
 					this.fragment.removeChild(shape.rawNode);
 				}
-				//dojox.gfx.Group.superclass.remove.apply(this, arguments);
-				//this.inherited(arguments);
-				gs.Container.remove.apply(this, arguments);
+				C.remove.apply(this, arguments);
 			}
 			return this;	// self
 		},
@@ -669,14 +672,13 @@ else
 				}
 				r.appendChild(defNode);
 			}
-			//return this.inherited(arguments);	// self
-			return gs.Container.clear.apply(this, arguments);
+			return C.clear.apply(this, arguments);
 		},
-		_moveChildToFront: gs.Container._moveChildToFront,
-		_moveChildToBack:  gs.Container._moveChildToBack
+		_moveChildToFront: C._moveChildToFront,
+		_moveChildToBack:  C._moveChildToBack
 	};
 
-	d.mixin(gs.Creator, {
+	var Creator = {
 		// summary: SVG shape creators
 		createObject: function(shapeType, rawShape){
 			// summary: creates an instance of the passed shapeType class
@@ -692,27 +694,28 @@ else
 			this.add(shape);
 			return shape;	// dojox.gfx.Shape
 		}
-	});
+	};
 
-	d.extend(g.Text, svg.Font);
-	d.extend(g.TextPath, svg.Font);
+	d.extend(svg.Text, Font);
+	d.extend(svg.TextPath, Font);
 
-	d.extend(g.Group, svg.Container);
-	d.extend(g.Group, gs.Creator);
+	d.extend(svg.Group, Container);
+	d.extend(svg.Group, gs.Creator);
+	d.extend(svg.Group, Creator);
 
-	d.extend(g.Surface, svg.Container);
-	d.extend(g.Surface, gs.Creator);
+	d.extend(svg.Surface, Container);
+	d.extend(svg.Surface, gs.Creator);
+	d.extend(svg.Surface, Creator);
 
 
 	// some specific override for svgweb + flash
-	if (svg.useSvgWeb) {
-		
+	if(svg.useSvgWeb){
 		// override createSurface()
-		g.createSurface = function(parentNode, width, height) {
-			var s = new g.Surface();
+		svg.createSurface = function(parentNode, width, height){
+			var s = new svg.Surface();
 
 			// ensure width / height
-			if (!width || !height) {
+			if(!width || !height){
 				var pos = d.position(parentNode);
 				width  = width  || pos.w;
 				height = height || pos.h;
@@ -730,7 +733,7 @@ else
 			svgweb.appendChild(mockSvg, parentNode);
 
 			// notice: any call to the raw node before flash init will fail.
-			mockSvg.addEventListener('SVGLoad', function() {
+			mockSvg.addEventListener('SVGLoad', function(){
 				// become loaded
 				s.rawNode = this;
 				s.isLoaded = true;
@@ -748,35 +751,43 @@ else
 			// flash not loaded yet
 			s.isLoaded = false;
 			return s;
-		}
+		};
 		
 		// override Surface.destroy()
-		dojo.extend(dojox.gfx.shape.Surface, {
-			destroy: function() {
+		svg.Surface.extend({
+			destroy: function(){
 				var mockSvg = this.rawNode;
 				svgweb.removeChild(mockSvg, mockSvg.parentNode);
 			}
 		});
 
 		// override connect() & disconnect() for Shape & Surface event processing
-		gs._eventsProcessing.connect = function(name, object, method) {
-			// connect events using the mock addEventListener() provided by svgweb
-			if (name.substring(0, 2)==='on') { name = name.substring(2); }
-			if (arguments.length == 2) {
-				method = object;
-			} else {
-				method = d.hitch(object, method);
-			}
-			this.getEventSource().addEventListener(name, method, false);
-			return [this, name, method];
-		}
-		gs._eventsProcessing.disconnect = function(token) {
-			// disconnect events using the mock removeEventListener() provided by svgweb
-			this.getEventSource().removeEventListener(token[1], token[2], false);
-			delete token[0];
-		}
-		dojo.extend(dojox.gfx.Shape, dojox.gfx.shape._eventsProcessing);
-		dojo.extend(dojox.gfx.shape.Surface, dojox.gfx.shape._eventsProcessing);
+		var _eventsProcessing = {
+			connect: function(name, object, method){
+				// connect events using the mock addEventListener() provided by svgweb
+				if (name.substring(0, 2)==='on') { name = name.substring(2); }
+				if (arguments.length == 2) {
+					method = object;
+				} else {
+					method = d.hitch(object, method);
+				}
+				this.getEventSource().addEventListener(name, method, false);
+				return [this, name, method];
+			},
+			disconnect: function(token){
+				// disconnect events using the mock removeEventListener() provided by svgweb
+				this.getEventSource().removeEventListener(token[1], token[2], false);
+				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;
+	}
 })();
diff --git a/dojox/gfx/svg_attach.js b/dojox/gfx/svg_attach.js
index a7f6c88..af1ea33 100644
--- a/dojox/gfx/svg_attach.js
+++ b/dojox/gfx/svg_attach.js
@@ -1,50 +1,56 @@
+dojo.provide("dojox.gfx.svg_attach");
+
 dojo.require("dojox.gfx.svg");
 
 dojo.experimental("dojox.gfx.svg_attach");
 
 (function(){
-	dojox.gfx.attachNode = function(node){
+	var g = dojox.gfx, svg = g.svg;
+	
+	svg.attachNode = function(node){
 		// summary: creates a shape from a Node
 		// node: Node: an SVG node
-		if(!node) return null;
+		if(!node){
+			return null;
+		}
 		var s = null;
 		switch(node.tagName.toLowerCase()){
-			case dojox.gfx.Rect.nodeType:
-				s = new dojox.gfx.Rect(node);
+			case svg.Rect.nodeType:
+				s = new svg.Rect(node);
 				attachRect(s);
 				break;
-			case dojox.gfx.Ellipse.nodeType:
-				s = new dojox.gfx.Ellipse(node);
-				attachShape(s, dojox.gfx.defaultEllipse);
+			case svg.Ellipse.nodeType:
+				s = new svg.Ellipse(node);
+				attachShape(s, g.defaultEllipse);
 				break;
-			case dojox.gfx.Polyline.nodeType:
-				s = new dojox.gfx.Polyline(node);
-				attachShape(s, dojox.gfx.defaultPolyline);
+			case svg.Polyline.nodeType:
+				s = new svg.Polyline(node);
+				attachShape(s, g.defaultPolyline);
 				break;
-			case dojox.gfx.Path.nodeType:
-				s = new dojox.gfx.Path(node);
-				attachShape(s, dojox.gfx.defaultPath);
+			case svg.Path.nodeType:
+				s = new svg.Path(node);
+				attachShape(s, g.defaultPath);
 				break;
-			case dojox.gfx.Circle.nodeType:
-				s = new dojox.gfx.Circle(node);
-				attachShape(s, dojox.gfx.defaultCircle);
+			case svg.Circle.nodeType:
+				s = new svg.Circle(node);
+				attachShape(s, g.defaultCircle);
 				break;
-			case dojox.gfx.Line.nodeType:
-				s = new dojox.gfx.Line(node);
-				attachShape(s, dojox.gfx.defaultLine);
+			case svg.Line.nodeType:
+				s = new svg.Line(node);
+				attachShape(s, g.defaultLine);
 				break;
-			case dojox.gfx.Image.nodeType:
-				s = new dojox.gfx.Image(node);
-				attachShape(s, dojox.gfx.defaultImage);
+			case svg.Image.nodeType:
+				s = new svg.Image(node);
+				attachShape(s, g.defaultImage);
 				break;
-			case dojox.gfx.Text.nodeType:
+			case svg.Text.nodeType:
 				var t = node.getElementsByTagName("textPath");
 				if(t && t.length){
-					s = new dojox.gfx.TextPath(node);
-					attachShape(s, dojox.gfx.defaultPath);
+					s = new svg.TextPath(node);
+					attachShape(s, g.defaultPath);
 					attachTextPath(s);
 				}else{
-					s = new dojox.gfx.Text(node);
+					s = new svg.Text(node);
 					attachText(s);
 				}
 				attachFont(s);
@@ -53,7 +59,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 				//console.debug("FATAL ERROR! tagName = " + node.tagName);
 				return null;
 		}
-		if(!(s instanceof dojox.gfx.Image)){
+		if(!(s instanceof svg.Image)){
 			attachFill(s);
 			attachStroke(s);
 		}
@@ -61,10 +67,10 @@ dojo.experimental("dojox.gfx.svg_attach");
 		return s;	// dojox.gfx.Shape
 	};
 
-	dojox.gfx.attachSurface = function(node){
+	svg.attachSurface = function(node){
 		// summary: creates a surface from a Node
 		// node: Node: an SVG node
-		var s = new dojox.gfx.Surface();
+		var s = new svg.Surface();
 		s.rawNode = node;
 		var def_elems = node.getElementsByTagName("defs");
 		if(def_elems.length == 0){
@@ -74,7 +80,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 		return s;	// dojox.gfx.Surface
 	};
 
-	var attachFill = function(object){
+	function attachFill(object){
 		// summary: deduces a fill style from a node.
 		// object: dojox.gfx.Shape: an SVG shape
 		var fill = object.rawNode.getAttribute("fill");
@@ -82,17 +88,17 @@ dojo.experimental("dojox.gfx.svg_attach");
 			object.fillStyle = null;
 			return;
 		}
-		var fillStyle = null, gradient = dojox.gfx.svg.getRef(fill);
+		var fillStyle = null, gradient = svg.getRef(fill);
 		if(gradient){
 			switch(gradient.tagName.toLowerCase()){
 				case "lineargradient":
-					fillStyle = _getGradient(dojox.gfx.defaultLinearGradient, gradient);
+					fillStyle = _getGradient(g.defaultLinearGradient, gradient);
 					dojo.forEach(["x1", "y1", "x2", "y2"], function(x){
 						fillStyle[x] = gradient.getAttribute(x);
 					});
 					break;
 				case "radialgradient":
-					fillStyle = _getGradient(dojox.gfx.defaultRadialGradient, gradient);
+					fillStyle = _getGradient(g.defaultRadialGradient, gradient);
 					dojo.forEach(["cx", "cy", "r"], function(x){
 						fillStyle[x] = gradient.getAttribute(x);
 					});
@@ -101,11 +107,11 @@ dojo.experimental("dojox.gfx.svg_attach");
 					fillStyle.r  = gradient.getAttribute("r");
 					break;
 				case "pattern":
-					fillStyle = dojo.lang.shallowCopy(dojox.gfx.defaultPattern, true);
+					fillStyle = dojo.clone(g.defaultPattern);
 					dojo.forEach(["x", "y", "width", "height"], function(x){
 						fillStyle[x] = gradient.getAttribute(x);
 					});
-					fillStyle.src = gradient.firstChild.getAttributeNS(dojox.gfx.svg.xmlns.xlink, "href");
+					fillStyle.src = gradient.firstChild.getAttributeNS(svg.xmlns.xlink, "href");
 					break;
 			}
 		}else{
@@ -114,9 +120,9 @@ dojo.experimental("dojox.gfx.svg_attach");
 			if(opacity != null){ fillStyle.a = opacity; }
 		}
 		object.fillStyle = fillStyle;
-	};
+	}
 
-	var _getGradient = function(defaultGradient, gradient){
+	function _getGradient(defaultGradient, gradient){
 		var fillStyle = dojo.clone(defaultGradient);
 		fillStyle.colors = [];
 		for(var i = 0; i < gradient.childNodes.length; ++i){
@@ -126,9 +132,9 @@ dojo.experimental("dojox.gfx.svg_attach");
 			});
 		}
 		return fillStyle;
-	};
+	}
 
-	var attachStroke = function(object){
+	function attachStroke(object){
 		// summary: deduces a stroke style from a node.
 		// object: dojox.gfx.Shape: an SVG shape
 		var rawNode = object.rawNode, stroke = rawNode.getAttribute("stroke");
@@ -136,7 +142,7 @@ dojo.experimental("dojox.gfx.svg_attach");
 			object.strokeStyle = null;
 			return;
 		}
-		var strokeStyle = object.strokeStyle = dojo.clone(dojox.gfx.defaultStroke);
+		var strokeStyle = object.strokeStyle = dojo.clone(g.defaultStroke);
 		var color = new dojo.Color(stroke);
 		if(color){
 			strokeStyle.color = color;
@@ -149,15 +155,15 @@ dojo.experimental("dojox.gfx.svg_attach");
 			}
 			strokeStyle.style = rawNode.getAttribute("dojoGfxStrokeStyle");
 		}
-	};
+	}
 
-	var attachTransform = function(object){
+	function attachTransform(object){
 		// summary: deduces a transformation matrix from a node.
 		// object: dojox.gfx.Shape: an SVG shape
 		var matrix = object.rawNode.getAttribute("transform");
 		if(matrix.match(/^matrix\(.+\)$/)){
 			var t = matrix.slice(7, -1).split(",");
-			object.matrix = dojox.gfx.matrix.normalize({
+			object.matrix = g.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])
@@ -165,21 +171,21 @@ dojo.experimental("dojox.gfx.svg_attach");
 		}else{
 			object.matrix = null;
 		}
-	};
+	}
 
-	var attachFont = function(object){
+	function attachFont(object){
 		// summary: deduces a font style from a Node.
 		// object: dojox.gfx.Shape: an SVG shape
-		var fontStyle = object.fontStyle = dojo.clone(dojox.gfx.defaultFont),
+		var fontStyle = object.fontStyle = dojo.clone(g.defaultFont),
 			r = object.rawNode;
 		fontStyle.style = r.getAttribute("font-style");
 		fontStyle.variant = r.getAttribute("font-variant");
 		fontStyle.weight = r.getAttribute("font-weight");
 		fontStyle.size = r.getAttribute("font-size");
 		fontStyle.family = r.getAttribute("font-family");
-	};
+	}
 
-	var attachShape = function(object, def){
+	function attachShape(object, def){
 		// summary: builds a shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
 		// def: Object: a default shape template
@@ -187,19 +193,19 @@ dojo.experimental("dojox.gfx.svg_attach");
 		for(var i in shape) {
 			shape[i] = r.getAttribute(i);
 		}
-	};
+	}
 
-	var attachRect = function(object){
+	function attachRect(object){
 		// summary: builds a rectangle shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
-		attachShape(object, dojox.gfx.defaultRect);
+		attachShape(object, g.defaultRect);
 		object.shape.r = Math.min(object.rawNode.getAttribute("rx"), object.rawNode.getAttribute("ry"));
-	};
+	}
 
-	var attachText = function(object){
+	function attachText(object){
 		// summary: builds a text shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
-		var shape = object.shape = dojo.clone(dojox.gfx.defaultText),
+		var shape = object.shape = dojo.clone(g.defaultText),
 			r = object.rawNode;
 		shape.x = r.getAttribute("x");
 		shape.y = r.getAttribute("y");
@@ -208,17 +214,17 @@ dojo.experimental("dojox.gfx.svg_attach");
 		shape.rotated = parseFloat(r.getAttribute("rotate")) != 0;
 		shape.kerning = r.getAttribute("kerning") == "auto";
 		shape.text = r.firstChild.nodeValue;
-	};
+	}
 
-	var attachTextPath = function(object){
+	function attachTextPath(object){
 		// summary: builds a textpath shape from a node.
 		// object: dojox.gfx.Shape: an SVG shape
-		var shape = object.shape = dojo.clone(dojox.gfx.defaultTextPath),
+		var shape = object.shape = dojo.clone(g.defaultTextPath),
 			r = object.rawNode;
 		shape.align = r.getAttribute("text-anchor");
 		shape.decoration = r.getAttribute("text-decoration");
 		shape.rotated = parseFloat(r.getAttribute("rotate")) != 0;
 		shape.kerning = r.getAttribute("kerning") == "auto";
 		shape.text = r.firstChild.nodeValue;
-	};
+	}
 })();
diff --git a/dojox/gfx/tests/decompose.js b/dojox/gfx/tests/decompose.js
index f49a81b..7fa061a 100644
--- a/dojox/gfx/tests/decompose.js
+++ b/dojox/gfx/tests/decompose.js
@@ -14,8 +14,8 @@ dojo.require("dojox.gfx.decompose");
 	};
 	var compose = function(r){
 		return m.normalize([
-			m.translate(r.dx, r.dy), 
-			m.rotate(r.angle2), 
+			m.translate(r.dx, r.dy),
+			m.rotate(r.angle2),
 			m.scale(r.sx, r.sy),
 			m.rotate(r.angle1)
 		]);
diff --git a/dojox/gfx/tests/test.roundrect.html b/dojox/gfx/tests/test.roundrect.html
index 3f0ff1c..43ead48 100644
--- a/dojox/gfx/tests/test.roundrect.html
+++ b/dojox/gfx/tests/test.roundrect.html
@@ -7,7 +7,7 @@
 </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="../vml.js"></script>
 <!--<script type="text/javascript" src="../svg.js"></script>-->
 <!--<script type="text/javascript" src="../silverlight.js"></script>-->
 <script type="text/javascript">
@@ -15,14 +15,17 @@ dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.move");
 dojo.require("dojo.colors");
 
-makeShapes = function(){
-    var g = dojox.gfx;
-	var surface = g.createSurface("test", 800, 600)
+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 g.Moveable(rect1);
+	new dojox.gfx.Moveable(rect1);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_bezier.html b/dojox/gfx/tests/test_bezier.html
index 0387ddb..6d5d71a 100644
--- a/dojox/gfx/tests/test_bezier.html
+++ b/dojox/gfx/tests/test_bezier.html
@@ -18,8 +18,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
-	var surface = dojox.gfx.createSurface("test", 500, 300);
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var g = surface.createGroup();
 	
 	// create a reference ellipse
@@ -68,7 +72,7 @@ makeShapes = function(){
 	g.setTransform([dojox.gfx.matrix.translate(250, 150), dojox.gfx.matrix.rotateg(axisAngle)]);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_destroy.html b/dojox/gfx/tests/test_destroy.html
index 4122dc2..1d4bf13 100644
--- a/dojox/gfx/tests/test_destroy.html
+++ b/dojox/gfx/tests/test_destroy.html
@@ -18,18 +18,12 @@ dojo.require("dojox.gfx");
 
 surface = null;
 
-makeShapes = function(){
-	if(surface){
-		surface.destroy();
-		surface = null;
-		var t = dojo.byId("test").innerHTML;
-		if(t){
-			console.error("Garbage detected: " + t);
-		}else{
-			console.log("The parent node was cleaned up properly.");
-		}
-	}
+createSurface = function(){
 	surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(){
 	var path = surface.createPath("");
 	// form concentric circles
 	var center = {x: 250, y: 250};
@@ -43,12 +37,26 @@ makeShapes = function(){
 	path.setFill("red").setStroke("black");
 };
 
-dojo.addOnLoad(makeShapes);
+cleanUp = function(){
+	if(surface){
+		surface.destroy();
+		surface = null;
+		var t = dojo.byId("test").innerHTML;
+		if(t){
+			console.error("Garbage detected: " + t);
+		}else{
+			console.log("The parent node was cleaned up properly.");
+		}
+	}
+	createSurface();
+}
+
+dojo.addOnLoad(createSurface);
 </script>
 </head>
 <body>
 	<h1>Testing surface.destroy()</h1>
-	<p><button onclick="makeShapes();">Regenerate</button></p>
+	<p><button onclick="cleanUp();">Regenerate</button></p>
 	<p><em>See the firebug log for detailed reports.</em></p>
 	<div id="test" style="width: 500px; height: 500px;"></div>
 	<p>That's all Folks!</p>
diff --git a/dojox/gfx/tests/test_fill.html b/dojox/gfx/tests/test_fill.html
index 54962d4..50536fa 100644
--- a/dojox/gfx/tests/test_fill.html
+++ b/dojox/gfx/tests/test_fill.html
@@ -16,8 +16,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
+createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var path = surface.createPath("");
 	// form concentric circles
 	var center = {x: 250, y: 250};
@@ -31,13 +35,13 @@ makeShapes = function(){
 	path.setFill("red").setStroke("black");
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
 <body>
 	<h1>Testing fill rule</h1>
-<div id="test" style="width: 500px; height: 500px;"></div>
-<p>That's all Folks!</p>
+	<div id="test" style="width: 500px; height: 500px;"></div>
+	<p>That's all Folks!</p>
 </body>
 </html>
diff --git a/dojox/gfx/tests/test_fx.html b/dojox/gfx/tests/test_fx.html
index 800b0f5..8b7319b 100644
--- a/dojox/gfx/tests/test_fx.html
+++ b/dojox/gfx/tests/test_fx.html
@@ -26,8 +26,12 @@ dojo.require("dojo.colors");
 
 var rect, text;
 
-var makeShapes = function(){
+function createSurface(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+function makeShapes(surface){
 	rect = surface.createRect({x: 100, y: 100, width: 300, height: 300}).
 		setFill("yellow").setStroke({
 			color: "green",
@@ -38,7 +42,7 @@ var makeShapes = function(){
 		.setFill("black").setFont({family: "serif", size: "10pt"});
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 var animateStroke = function(){
 	var anim = dojox.gfx.fx.animateStroke({
diff --git a/dojox/gfx/tests/test_fx_shapes.html b/dojox/gfx/tests/test_fx_shapes.html
index 07726ff..941c026 100644
--- a/dojox/gfx/tests/test_fx_shapes.html
+++ b/dojox/gfx/tests/test_fx_shapes.html
@@ -9,14 +9,13 @@
             dojo.require("dojox.gfx");
             dojo.require("dojo.fx");
             dojo.require("dojo.fx.easing");
-            dojo.require("dojox.fx.easing");
             
             var WIDTH = 600, HEIGHT = 400,
                 BAR_GAP = 20, BAR_WIDTH = 76,
                 BAR_FILL = "red", BAR_STROKE = "black",
                 CHAIN_DURATION = 250, COMBINE_DURATION = 1000;
             
-            var surface, rects = [];
+            var rects = [];
             
             var enable = function(enabled){
                 // enable/disable controls on the page
@@ -79,10 +78,7 @@
                 masterAnimation.play();
             }
             
-            var init = function(){
-                // create surface
-                surface = dojox.gfx.createSurface(dojo.byId("surface"), 600, 400);
-                
+            var init = function(surface){
                 // create rectangles
                 for(var w = BAR_GAP; w < WIDTH - BAR_WIDTH; w += BAR_WIDTH + BAR_GAP){
                     rects.push(surface.createRect({
@@ -93,15 +89,17 @@
                 
                 // prepare and enable controls
                 populateSelect("dojo.fx.easing", "easing");
-                if(dojox.fx.easing !== dojo.fx.easing){
-                    populateSelect("dojox.fx.easing", "easing");
-                }
                 dojo.attr("chain", "checked", false);
                 dojo.connect(dojo.byId("animate"), "onclick", animate);
                 enable(true);
             };
             
-            dojo.addOnLoad(init);
+			function createSurface(){
+                var surface = dojox.gfx.createSurface(dojo.byId("surface"), 600, 400);
+				surface.whenLoaded(init);
+			};
+
+            dojo.addOnLoad(createSurface);
         </script>
     </head>
     <body>
diff --git a/dojox/gfx/tests/test_gfx.html b/dojox/gfx/tests/test_gfx.html
index e13d78b..e977dc4 100644
--- a/dojox/gfx/tests/test_gfx.html
+++ b/dojox/gfx/tests/test_gfx.html
@@ -69,7 +69,7 @@
 
 		   var descRow = document.createElement('tr');
 		   var desc = document.createElement('td');
-		   desc.innerHTML = testDescription;
+		   desc.innerHTML = testDescription || testName;
 		   descRow.appendChild(desc);
 		   gTestContainer.appendChild(descRow);
 
@@ -84,9 +84,11 @@
 		   try {
 		      var t = gTests[testName];
 		      if (!t) {
-		         return 'no test named ' + t;
+		         return 'no test named ' + testName;
 		      }
-		      t(testName);
+			  getTestSurface(testName).whenLoaded(function(surface){
+				t(testName, surface);
+			  });
 		      return null; // the success condition
 		   } catch (e) {
 		      return e.message;
@@ -96,9 +98,11 @@
 		function runTest_debug(testName){
 		      var t = gTests[testName];
 		      if (!t) {
-		         return 'no test named ' + t;
+		         return 'no test named ' + testName;
 		      }
-		      t(testName);
+			  getTestSurface(testName).whenLoaded(function(surface){
+				t(testName, surface);
+			  });
 		      return null; // the success condition
 		}
 
@@ -108,8 +112,7 @@
 			gTestContainer = dojo.byId('testcontainer');
 			var rect = { x: 0, y: 0, width: 100, height: 100 };
 
-			addTest('rect', function(testName){
-				var surface = getTestSurface(testName, 'translucent rect with rounded stroke');
+			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" });
@@ -118,15 +121,13 @@
 				red_rect.connect("onclick", function(){ alert("red"); });
 			});
 
-			addTest('straight_rect', function(testName){
-				var surface = getTestSurface(testName, 'translucent rect with no stroke');
+			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){
-				var surface = getTestSurface(testName, '30g CCW blue translucent rounded rect');
+			addTest('rotated_rect', function(testName, surface){
 				console.debug('rotated_rect');
 				// anonymous 30 degree CCW rotated green rectangle
 				surface.createRect({r: 20})
@@ -136,8 +137,7 @@
 					;
 			});
 
-			addTest('skew_rect', function(testName){
-				var surface = getTestSurface(testName, 'skewed rects' );
+			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)
@@ -152,9 +152,7 @@
 					.setTransform(dojox.gfx.matrix.translate(100, 100));
 			});
 
-			addTest('matrix_rect', function(testName){
-				var surface = getTestSurface(testName, 'all matrix operations, check debug output for more details');
-
+			addTest('matrix_rect', function(testName, surface){
 				var group = surface.createGroup();
 		
 				var blue_rect = group.createRect(rect).setFill([0, 0, 255, 0.5]).applyTransform(dojox.gfx.matrix.identity);
@@ -194,8 +192,7 @@
 					;
 			});
 
-			addTest('attach', function(testName){
-				var surface = getTestSurface(testName, 'Attach to existed shape');
+			addTest('attach', function(testName, surface){
 				var red_rect = surface.createRect(rect)
 					.setShape({ width: 75 })
 					.setFill([255, 0, 0, 0.5])
@@ -220,43 +217,37 @@
 			});
 	
 			// test circle
-			addTest('circle', function(testName){
-				var surface = getTestSurface(testName, 'translucent green 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){
-				var surface = getTestSurface(testName, 'straight red 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){
-				var surface = getTestSurface(testName, 'translucent cyan 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){
-				var surface = getTestSurface(testName, 'unfilled open 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){
-				var surface = getTestSurface(testName, 'filled 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){
-				var surface = getTestSurface(testName, 'lineTo, moveTo, closePath');
+			addTest('lineTo', function(testName, surface){
 				surface.createPath()
 					.moveTo(10, 20).lineTo(80, 150)
 					.setAbsoluteMode(false).lineTo(40, 0)
@@ -269,8 +260,7 @@
 					;
 			});
 
-			addTest('setPath', function(testName){
-				var surface = getTestSurface(testName, 'setPath example with lineTo moveTo');
+			addTest('setPath', function(testName, surface){
 				surface.createPath()
 					.moveTo(10, 20).lineTo(80, 150)
 					.setAbsoluteMode(false).lineTo(40,0)
@@ -291,9 +281,7 @@
 			});
 
 			// test arcTo 
-			addTest('arcTo', function(testName){
-				var surface = getTestSurface(testName, 'arcTo: from 0 to 360 degree, w/ 30 degree of x axis rotation, rendered with different color');
-
+			addTest('arcTo', function(testName, surface){
 				var m = dojox.gfx.matrix;
 				var g1 = surface.createGroup();
 				var g2 = g1.createGroup();
@@ -328,8 +316,7 @@
 			});
 
 			// test path: curveTo, smoothCurveTo
-			addTest('curveTo', function(testName) {
-				var surface = getTestSurface(testName, '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 })
@@ -337,8 +324,7 @@
 			});
 
 			// test path: curveTo, smoothCurveTo with relative.
-			addTest('curveTo2', function(testName) {
-				var surface = getTestSurface(testName, 'curveTo, smoothCurveTo with relative coordination');
+			addTest('curveTo2', function(testName, surface) {
 				surface.createPath()
 					.moveTo(10, 20).curveTo(50, 50, 50, 100, 150, 100)
 					.setAbsoluteMode(false).smoothCurveTo(150, 200, 50, 100)
@@ -348,16 +334,14 @@
 			});
 
 			// test path: curveTo, smoothCurveTo with relative.
-			addTest('qCurveTo', function(testName) {
-				var surface = getTestSurface(testName, 'qCurveTo, qSmoothCurveTo' );
+			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) {
-				var surface = getTestSurface(testName, 'qCurveTo, qSmoothCurveTo with relative' );
+			addTest('qCurveTo2', function(testName, surface) {
 				surface.createPath()
 					.moveTo(10, 20).qCurveTo(50, 50, 100, 100)
 					.setAbsoluteMode(false).qSmoothCurveTo(50, -80)
@@ -367,8 +351,7 @@
 			});
 
 			// test defines, linearGradient
-			addTest('linearGradient', function(testName) {
-				var surface = getTestSurface(testName, 'linear gradient fill');
+			addTest('linearGradient', function(testName, surface) {
 				// this is an example to split the linearGradient from setFill:
 				var lg = {
 					type: "linear",
@@ -382,8 +365,7 @@
 			});
 
 			// TODO: test radialGradient
-			addTest('radialGradient', function(testName) {
-				var surface = getTestSurface(testName, 'radial gradient fill');
+			addTest('radialGradient', function(testName, surface) {
 				// this is a total inline implementation compared with previous one.
 				var rg = {
 					type: "radial",
@@ -408,8 +390,7 @@
 		//			;
 			});
 
-			addTest('attach_gradient', function(testName) {
-				var surface = getTestSurface(testName, 'attach gradient fill');
+			addTest('attach_gradient', function(testName, surface) {
 				// this is an example to split the linearGradient from setFill:
 				var lg = {
 					type: "linear",
diff --git a/dojox/gfx/tests/test_gradient.html b/dojox/gfx/tests/test_gradient.html
index 3aa6ffa..251fc0a 100644
--- a/dojox/gfx/tests/test_gradient.html
+++ b/dojox/gfx/tests/test_gradient.html
@@ -14,7 +14,12 @@
 dojo.require("dojox.gfx");
 dojo.require("dojo.colors"); // pull in CSS3 color names
 
-makeShapes = function(){
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("grad", 300, 300);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var SIDE = 10;
 	var fillObj = {
 		colors: [
@@ -23,7 +28,6 @@ makeShapes = function(){
 			{ offset: 1,   color: [255, 255, 0, 0] }
 		]
 	};
-	var surface = dojox.gfx.createSurface(dojo.byId("grad"), 300, 300);
 	// create a background
 	for(var i = 0; i < 300; i += SIDE){
 		for(var j = 0; j < 300; j += SIDE){
@@ -53,7 +57,7 @@ makeShapes = function(){
 		cy: 200
 	}, fillObj));
 };
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 </script>
 <style type="text/css">
 #grad { width: 300px; height: 300px; }
diff --git a/dojox/gfx/tests/test_group1.html b/dojox/gfx/tests/test_group1.html
index 92f336d..0b265e6 100644
--- a/dojox/gfx/tests/test_group1.html
+++ b/dojox/gfx/tests/test_group1.html
@@ -22,8 +22,12 @@ var g1 = null;
 var g2 = null;
 var r1 = null;
 
-makeShapes = function(){
-	surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+createSurface = function(){
+	surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	// make a checkerboard
 	for(var i = 0; i < 500; i += 100){
 		for(var j = 0; j < 500; j += 100){
@@ -52,7 +56,7 @@ switchRect = function(){
 	}
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_image1.html b/dojox/gfx/tests/test_image1.html
index 436da3b..dacd984 100644
--- a/dojox/gfx/tests/test_image1.html
+++ b/dojox/gfx/tests/test_image1.html
@@ -13,8 +13,12 @@ dojo.require("dojox.gfx");
 var image = null, grid_size = 500, grid_step = 50,
 	m = dojox.gfx.matrix;
 
-makeShapes = function(){
+createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	for(var i = 0; i <= grid_size; i += grid_step){
 		surface.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("black");
 		surface.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("black");
@@ -47,7 +51,7 @@ transformImage = function(){
 	}
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_image2.html b/dojox/gfx/tests/test_image2.html
index faecf90..e4ff8d5 100644
--- a/dojox/gfx/tests/test_image2.html
+++ b/dojox/gfx/tests/test_image2.html
@@ -12,8 +12,12 @@ dojo.require("dojox.gfx");
 var grid_size = 500, grid_step = 50;
 var main = null, g = null, image = null, rect = null;
 
-makeShapes = function(){
-	var s = dojox.gfx.createSurface("test", 800, 600);
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(s){
 	for(var i = 0; i <= grid_size; i += grid_step){
 		s.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("black");
 		s.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("black");
@@ -42,7 +46,7 @@ trans = function(){
 	main.setTransform([dojox.gfx.matrix.rotategAt(45, 200, 200), {dx: 200, dy: 200}]);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_image3.html b/dojox/gfx/tests/test_image3.html
index cb889b4..23fe299 100755
--- a/dojox/gfx/tests/test_image3.html
+++ b/dojox/gfx/tests/test_image3.html
@@ -13,18 +13,26 @@ dojo.require("dojox.gfx");
 var surface, image = null, grid_size = 1000, grid_step = 50, surface2, image2
 	m = dojox.gfx.matrix;
 
-makeShapes = function(){
+createSurface = function(){
 	surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+
+    //create second test
+    surface2 = dojox.gfx.createSurface("test2", 600, 600);
+	surface2.whenLoaded(makeShapes2);
+};
+
+makeShapes = function(surface){
 	for(var i = 0; i <= grid_size; i += grid_step){
 		surface.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("black");
 		surface.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("black");
 	}
     image = surface.createImage({width: 150, height: 100, src: "images/eugene-sm.jpg"});
     image.connect("onclick", function(){ alert("You didn't expect a download, did you?"); });
+};
 
-    //create second test
-    surface2 = dojox.gfx.createSurface("test2", 600, 600);
-    image2 = surface2.createImage({width: 150, height: 100, src: "images/eugene-sm.jpg"});
+makeShapes2 = function(surface){
+    image2 = surface.createImage({width: 150, height: 100, src: "images/eugene-sm.jpg"});
 };
 
 transformImage = function(){
@@ -44,7 +52,7 @@ transformImage = function(){
 	window.scaled=!window.scaled;
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_image4.html b/dojox/gfx/tests/test_image4.html
index 8454345..c79f1d5 100644
--- a/dojox/gfx/tests/test_image4.html
+++ b/dojox/gfx/tests/test_image4.html
@@ -14,11 +14,16 @@
 dojo.require("dojox.gfx");
 dojo.require("dojo.colors");
 
-makeShapes = function(){
+var grid_size = 200, grid_step = 20;
+
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", grid_size, grid_size)
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
     var g = dojox.gfx, m = g.matrix;
     
-	var grid_size = 200, grid_step = 20,
-        surface = g.createSurface("test", grid_size, grid_size)
 	for(var i = 0; i <= grid_size; i += grid_step){
 		surface.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("grey");
 		surface.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("grey");
@@ -40,7 +45,7 @@ makeShapes = function(){
     rect3.connect("onclick", function(){ alert("green"); });
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_image5.html b/dojox/gfx/tests/test_image5.html
index 48882b0..91eac54 100644
--- a/dojox/gfx/tests/test_image5.html
+++ b/dojox/gfx/tests/test_image5.html
@@ -15,11 +15,15 @@ dojo.require("dojox.gfx");
 dojo.require("dojox.gfx.move");
 dojo.require("dojo.colors");
 
-makeShapes = function(){
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
     var g = dojox.gfx, m = g.matrix;
     
-	var grid_size = 800, grid_step = 50,
-        surface = g.createSurface("test", 800, 600)
+	var grid_size = 800, grid_step = 50;
 	for(var i = 0; i <= grid_size; i += grid_step){
 		surface.createLine({x1: 0, x2: grid_size, y1: i, y2: i}).setStroke("grey");
 		surface.createLine({y1: 0, y2: grid_size, x1: i, x2: i}).setStroke("grey");
@@ -43,7 +47,7 @@ makeShapes = function(){
 	new g.Moveable(img3);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_linearGradient.html b/dojox/gfx/tests/test_linearGradient.html
index c3513d6..4f08fa7 100644
--- a/dojox/gfx/tests/test_linearGradient.html
+++ b/dojox/gfx/tests/test_linearGradient.html
@@ -21,7 +21,12 @@
 dojo.require("dojox.gfx");
 dojo.require("dojo.colors");
 
-makeShapes = function(){
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("grad", 300, 300);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var lg1 = {
 		type: "linear",
 		x1: 0, y1: 0,
@@ -47,7 +52,6 @@ makeShapes = function(){
 			{ offset: 0.3, color: "yellow" }
 		]
 	};
-	var surface = dojox.gfx.createSurface(dojo.byId("grad"), 300, 300);
 	var group = surface.createGroup();
 	var rect1 = surface.createRect({ 
 		width:  300,
@@ -63,7 +67,7 @@ makeShapes = function(){
 	group.add(rect1);
 	group.add(rect2);
 };
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 </script>
 <style>
 v:group { text-align: left; }
diff --git a/dojox/gfx/tests/test_linestyle.html b/dojox/gfx/tests/test_linestyle.html
index c48ec17..96adc9d 100644
--- a/dojox/gfx/tests/test_linestyle.html
+++ b/dojox/gfx/tests/test_linestyle.html
@@ -16,8 +16,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
-	var surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var styles = ["none", "Solid", "ShortDash", "ShortDot", "ShortDashDot", "ShortDashDotDot", 
 		"Dot", "Dash", "LongDash", "DashDot", "LongDashDot", "LongDashDotDot"];
 	var font = "normal normal normal 10pt Arial";	// CSS font style
@@ -29,7 +33,7 @@ makeShapes = function(){
 	}
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_pattern.html b/dojox/gfx/tests/test_pattern.html
index 9060d0b..f5e5e3b 100644
--- a/dojox/gfx/tests/test_pattern.html
+++ b/dojox/gfx/tests/test_pattern.html
@@ -16,20 +16,24 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 800, 600);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
     var pattern = {
         type: "pattern",
-        x: 0, y: 0, width: 75, height: 50,
+        x: 30, y: 20, width: 75, height: 60,
         src: "images/eugene-sm.jpg"
     };
 	var ellipse = {cx: 400, cy: 200, rx: 350, ry: 150};
-	var surface = dojox.gfx.createSurface("test", 800, 600);
 	surface.createEllipse(ellipse)
         .setStroke({color: "blue", width: 1 })
         .setFill(pattern);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_poly.html b/dojox/gfx/tests/test_poly.html
index 26f4041..eeb1060 100644
--- a/dojox/gfx/tests/test_poly.html
+++ b/dojox/gfx/tests/test_poly.html
@@ -18,8 +18,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
+createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var line = surface.createLine({x1: 250, y1: 50, x2: 250, y2: 250})
 		.setStroke({color: "blue"})
 		;
@@ -37,7 +41,7 @@ makeShapes = function(){
 	);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_refproj.html b/dojox/gfx/tests/test_refproj.html
index 13df02c..c4a682c 100644
--- a/dojox/gfx/tests/test_refproj.html
+++ b/dojox/gfx/tests/test_refproj.html
@@ -6,7 +6,7 @@
         @import "../../../dojo/resources/dojo.css";
         @import "../../../dijit/themes/tundra/tundra.css";
     </style>
-    <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
+    <script src="../../../dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
     <script>
         dojo.require("dojox.gfx");
         dojo.require("dojo.colors");
@@ -79,9 +79,7 @@
             updatePoints();
         }
 
-        run = function(){
-            dojo.attr("start", "disabled", true);
-            surface = dojox.gfx.createSurface("surf", W, H);
+        run = function(surface){
             makeGrid(surface, W, 50);
             shape = surface.createLine(line).setStroke("black");
             dojo.connect(dijit.byId("shifter"), "onChange", shiftVector);
@@ -89,12 +87,16 @@
             shiftVector(0);
         };
         
-        dojo.addOnLoad(run);
+		createSurface = function(){
+			surface = dojox.gfx.createSurface("surf", W, H);
+			surface.whenLoaded(run);
+		};
+
+        dojo.addOnLoad(createSurface);
     </script>
 </head>
 <body class="tundra">
     <h1>Test Reflection and Projection matrices</h1>
-    <p><button id="start" onclick="run();">Start!</button></p>
     <div id="shifter" dojoType="dijit.form.HorizontalSlider" 
             value="0" minimum="-100" maximum="100" value="0" discreteValues="21" showButtons="false" intermediateChanges="true" style="width: 500px;">
         <div dojoType="dijit.form.HorizontalRule" container="topDecoration" count="21" style="height: 5px;"></div>
diff --git a/dojox/gfx/tests/test_resize.html b/dojox/gfx/tests/test_resize.html
index 8a99fbe..75cc236 100644
--- a/dojox/gfx/tests/test_resize.html
+++ b/dojox/gfx/tests/test_resize.html
@@ -20,8 +20,12 @@ dojo.require("dojox.gfx");
 
 var surface;
 
-makeShapes = function(){
+createSurface = function(){
 	surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(){
 	surface.createRect({width: 300, height: 300}).setFill([255, 0, 0, 0.3]).setStroke("red");
 	surface.createRect({x: 200, y: 200, width: 300, height: 300}).setFill([0, 0, 255, 0.3]).setStroke("green");
 };
@@ -35,7 +39,7 @@ make500x500 = function(){ surface.setDimensions(500, 500); };
 make400x400 = function(){ surface.setDimensions(400, 400); };
 make300x300 = function(){ surface.setDimensions(300, 300); };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_setPath.html b/dojox/gfx/tests/test_setPath.html
index 7a1f010..45edc95 100644
--- a/dojox/gfx/tests/test_setPath.html
+++ b/dojox/gfx/tests/test_setPath.html
@@ -15,8 +15,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
+createSurface = function(){
 	var surface = dojox.gfx.createSurface("test", 500, 400);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	// relative path with cubic beziers
 	surface
 		.createPath("m100 100 100 0 0 100c0 50-50 50-100 0s-50-100 0-100z")
@@ -61,7 +65,7 @@ makeShapes = function(){
 		;
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_tbbox.html b/dojox/gfx/tests/test_tbbox.html
index 7d64566..4b85e39 100644
--- a/dojox/gfx/tests/test_tbbox.html
+++ b/dojox/gfx/tests/test_tbbox.html
@@ -18,8 +18,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
-	var surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var g1 = surface.createGroup();
 	// make a checkerboard
 	for(var i = 0; i < 500; i += 100){
@@ -96,7 +100,7 @@ makeShapes = function(){
 	surface.createPolyline(a).setStroke("green");
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 <!--
diff --git a/dojox/gfx/tests/test_text.html b/dojox/gfx/tests/test_text.html
index ea5b9c7..826cead 100644
--- a/dojox/gfx/tests/test_text.html
+++ b/dojox/gfx/tests/test_text.html
@@ -35,8 +35,12 @@ var makeText = function(surface, text, font, fill, stroke){
 	return t;
 };
 
-makeShapes = function(){
+createSurface = function(){
 	surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(){
 	var m = dojox.gfx.matrix;
 	surface.createLine({x1: 250, y1: 0, x2: 250, y2: 500}).setStroke("green");
 	t1 = makeText(surface, {x: 250, y: 50, text: "Start", align: "start"}, 
@@ -65,15 +69,15 @@ getSizes = function(){
 	dojo.byId("sizes").innerHTML = t.join("<br/>");
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
 <body>
 	<h1>dojox.gfx Text test</h1>
-<div id="test" style="width: 500px; height: 500px;"></div>
-<div><button onclick="surface.clear();">Clear</button> <button onclick="getSizes();">Get sizes</button></div>
-<p id="sizes"> </p>
-<p>That's all Folks!</p>
+	<div id="test" style="width: 500px; height: 500px;"></div>
+	<div><button onclick="surface.clear();">Clear</button> <button onclick="getSizes();">Get sizes</button></div>
+	<p id="sizes"> </p>
+	<p>That's all Folks!</p>
 </body>
 </html>
diff --git a/dojox/gfx/tests/test_textpath.html b/dojox/gfx/tests/test_textpath.html
index 201b0b5..e9c4e60 100644
--- a/dojox/gfx/tests/test_textpath.html
+++ b/dojox/gfx/tests/test_textpath.html
@@ -30,8 +30,12 @@ var makeText = function(surface, text, font, fill, stroke){
 	return t;
 };
 
-makeShapes = function(){
+createSurface = function(){
 	surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(){
 	var p = surface.createPath({})
 		.setStroke("green")
 		.moveTo(0, 100)
@@ -42,7 +46,6 @@ makeShapes = function(){
 		.curveTo(CPD, 0, 100 - CPD, -300, 100, -300)
 		.curveTo(CPD, 0, 100 - CPD,  300, 100,  300)
 		;
-	console.debug(p);
 	var t = surface.createTextPath({
 			text: "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Praesent erat. " + 
 					"In malesuada ultricies velit. Vestibulum tempor odio vitae diam. " + 
@@ -61,16 +64,15 @@ makeShapes = function(){
 		.setFont({family: "times", size: "12pt"})
 		.setFill("blue")
 		;
-	console.debug(t);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
 <body>
 	<h1>dojox.gfx Text on a Path test</h1>
-<div id="test" style="width: 500px; height: 500px;"></div>
-<p>That's all Folks!</p>
+	<div id="test" style="width: 500px; height: 500px;"></div>
+	<p>That's all Folks!</p>
 </body>
 </html>
diff --git a/dojox/gfx/tests/test_transform.html b/dojox/gfx/tests/test_transform.html
index 00820be..036e2e0 100644
--- a/dojox/gfx/tests/test_transform.html
+++ b/dojox/gfx/tests/test_transform.html
@@ -13,8 +13,12 @@
 <script type="text/javascript">
 dojo.require("dojox.gfx");
 
-makeShapes = function(){
-	var surface = dojox.gfx.createSurface(document.getElementById("test"), 500, 500);
+createSurface = function(){
+	var surface = dojox.gfx.createSurface("test", 500, 500);
+	surface.whenLoaded(makeShapes);
+};
+
+makeShapes = function(surface){
 	var g1 = surface.createGroup();
 	// make a checkerboard
 	for(var i = 0; i < 500; i += 100){
@@ -82,7 +86,7 @@ makeShapes = function(){
 	//g1.setTransform([dojox.gfx.matrix.scaleAt(2, 1, 250, 250), dojox.gfx.matrix.rotategAt(-45, 250, 250)]);
 };
 
-dojo.addOnLoad(makeShapes);
+dojo.addOnLoad(createSurface);
 
 </script>
 </head>
diff --git a/dojox/gfx/tests/test_utils.html b/dojox/gfx/tests/test_utils.html
index 008a495..02d4c9d 100755
--- a/dojox/gfx/tests/test_utils.html
+++ b/dojox/gfx/tests/test_utils.html
@@ -188,7 +188,8 @@
 	</head>
 	<body class="tundra">
 		<h1>Test of GFX Utils functions</h1>
-		This page is intended for testing of the functions of the utils package, such as toJson, fromJson, and toSvg.
+		<p>This page is intended for testing of the functions of the utils package, such as toJson, fromJson, and toSvg.</p>
+		<p>This test is not adapted for Silverlight or Canvas.</p>
 		<div id="gfxObject"></div>
 		<div id="scratchObject"></div>
 		<div>
diff --git a/dojox/gfx/tests/test_vectortext_draw.html b/dojox/gfx/tests/test_vectortext_draw.html
index d71bb70..76e6f92 100644
--- a/dojox/gfx/tests/test_vectortext_draw.html
+++ b/dojox/gfx/tests/test_vectortext_draw.html
@@ -6,20 +6,19 @@
 			@import "../../../dojo/resources/dojo.css";
 			@import "../../../dijit/tests/css/dijitTests.css";
 		</style>
-		<script type="text/javascript" src="../../../dojo/dojo.js" 
-			djConfig="isDebug: true, gfxRenderer: 'svg,vml,silverlight,canvas'"></script>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
 		<script type="text/javascript">
 			dojo.require("dojox.gfx");
 			dojo.require("dojox.gfx.fx");
 			dojo.require("dojox.gfx.VectorText");
 
 			var bg="#181818", fill="#a36e2c";
-			dojo.addOnLoad(function(){
+			
+			function makeShapes(surface){
 				var url = dojo.moduleUrl("dojox", "gfx/resources/Gillius.svg");
 				var f = new dojox.gfx.VectorFont(url);
 
 				//	draw out the glyphs for testing.
-				var surface = dojox.gfx.createSurface("test", 600, 400);
 				var rect = surface.createRect({ x: 0, y: 0, width: 600, height: 400 })
 					.setFill(bg);
 
@@ -46,7 +45,14 @@
 						{ name: "scale", start: [0.1, 0.1], end:[1, 1 ] } 
 					]
 				}).play();
-			});
+			}
+			
+			function createSurface(){
+				var surface = dojox.gfx.createSurface("test", 600, 400);
+				surface.whenLoaded(makeShapes);
+			}
+
+			dojo.ready(createSurface);
 		</script>
 	</head>
 	<body>
diff --git a/dojox/gfx/tests/test_vectortext_load.html b/dojox/gfx/tests/test_vectortext_load.html
index c8f03ab..751d51b 100644
--- a/dojox/gfx/tests/test_vectortext_load.html
+++ b/dojox/gfx/tests/test_vectortext_load.html
@@ -13,12 +13,12 @@
 			dojo.require("dojox.gfx.VectorText");
 
 			var bg="#181818", fill="#464b44", padding=32;
-			dojo.addOnLoad(function(){
+			
+			function makeShapes(surface){
 				var url = dojo.moduleUrl("dojox", "gfx/resources/Gillius.svg");
 				var f = new dojox.gfx.VectorFont(url);
 
 				//	draw out the glyphs for testing.
-				var surface = dojox.gfx.createSurface("test", 500, 560);
 				var rect = surface.createRect({ x: 0, y: 0, width: 500, height: 560 })
 					.setFill(bg);
 				var g = surface.createGroup(), cx=0, count=0;
@@ -66,9 +66,14 @@
 							.setFill(s);
 					}
 				}
+			}
+			
+			function createSurface(){
+				var surface = dojox.gfx.createSurface("test", 500, 560);
+				surface.whenLoaded(makeShapes);
+			}
 
-
-			});
+			dojo.ready(createSurface);
 		</script>
 	</head>
 	<body>
diff --git a/dojox/gfx/utils.js b/dojox/gfx/utils.js
index f5c5fb3..b6f5c00 100644
--- a/dojox/gfx/utils.js
+++ b/dojox/gfx/utils.js
@@ -91,7 +91,7 @@ dojo.require("dojox.gfx");
 
 		toSvg: function(/*GFX object*/surface){
 			// summary:
-			//		Function to serialize a GFX surface to SVG text.  
+			//		Function to serialize a GFX surface to SVG text.
 			// description:
 			//		Function to serialize a GFX surface to SVG text.  The value of this output
 			//		is that there are numerous serverside parser libraries that can render
@@ -140,7 +140,7 @@ dojo.require("dojox.gfx");
 						//Create temp surface to render object to and render.
 						var ts = gu._gfxSvgProxy[dojox._scopeName].gfx.createSurface(node, width, height);
 
-						//It's apparently possible that a suface creation is async, so we need to use 
+						//It's apparently possible that a suface creation is async, so we need to use
 						//the whenLoaded function.  Probably not needed for SVG, but making it common
 						var draw = function(surface) {
 							try{
@@ -166,7 +166,7 @@ dojo.require("dojox.gfx");
 				if(gu._initSvgSerializerDeferred.fired > 0){
 					serializer();
 				}else{
-					gu._initSvgSerializerDeferred.addCallback(serializer);		
+					gu._initSvgSerializerDeferred.addCallback(serializer);
 				}
 			}
 			return deferred; //dojo.Deferred that will be called when serialization finishes.
@@ -180,7 +180,7 @@ dojo.require("dojox.gfx");
 
 		_svgSerializerInitialized: function() {
 			// summary:
-			//		Internal function to call when the serializer init completed.	
+			//		Internal function to call when the serializer init completed.
 			// tags:
 			//		private
 			gu._initSvgSerializerDeferred.callback(true);
@@ -208,7 +208,7 @@ dojo.require("dojox.gfx");
 						if(f.contentWindow.document.readyState == "complete"){
 							f.onreadystatechange = function() {};
 							intv = setInterval(function() {
-								if(f.contentWindow[dojo._scopeName] && 
+								if(f.contentWindow[dojo._scopeName] &&
 								   f.contentWindow[dojox._scopeName].gfx &&
 								   f.contentWindow[dojox._scopeName].gfx.utils){
 									clearInterval(intv);
@@ -222,7 +222,7 @@ dojo.require("dojox.gfx");
 					f.onload = function(){
 						f.onload = function() {};
 						intv = setInterval(function() {
-							if(f.contentWindow[dojo._scopeName] && 
+							if(f.contentWindow[dojo._scopeName] &&
 							   f.contentWindow[dojox._scopeName].gfx &&
 							   f.contentWindow[dojox._scopeName].gfx.utils){
 								clearInterval(intv);
@@ -267,7 +267,7 @@ dojo.require("dojox.gfx");
 					svg = svg.substring(4, svg.length);
 					svg = "<svg xmlns=\"http://www.w3.org/2000/svg\"" + svg;
 				}
-				//Do some other cleanup, like stripping out the 
+				//Do some other cleanup, like stripping out the
 				//dojoGfx attributes.
 				svg = svg.replace(/\bdojoGfx\w*\s*=\s*(['"])\w*\1/g, "");
 			}
diff --git a/dojox/gfx/vml.js b/dojox/gfx/vml.js
index e3537fa..56e8332 100644
--- a/dojox/gfx/vml.js
+++ b/dojox/gfx/vml.js
@@ -23,7 +23,7 @@ dojo.require("dojox.gfx.gradient");
 
 	vml._bool = {"t": 1, "true": 1};
 
-	d.extend(g.Shape, {
+	d.declare("dojox.gfx.vml.Shape", gs.Shape, {
 		// summary: VML-specific implementation of dojox.gfx.Shape methods
 
 		setFill: function(fill){
@@ -150,6 +150,10 @@ dojo.require("dojox.gfx.gradient");
 			fo.method = "any";
 			fo.type = "solid";
 			fo.opacity = this.fillStyle.a;
+			var alphaFilter = this.rawNode.filters["DXImageTransform.Microsoft.Alpha"];
+			if(alphaFilter){
+				alphaFilter.opacity = Math.round(this.fillStyle.a * 100);
+			}
 			this.rawNode.fillcolor = this.fillStyle.toHex();
 			this.rawNode.filled = true;
 			return this;	// self
@@ -283,11 +287,11 @@ dojo.require("dojox.gfx.gradient");
 		}
 	});
 
-	dojo.declare("dojox.gfx.Group", g.Shape, {
+	dojo.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(){
-			vml.Container._init.call(this);
+			gs.Container._init.call(this);
 		},
 		// apply transformation
 		_applyTransform: function(){
@@ -316,9 +320,9 @@ dojo.require("dojox.gfx.gradient");
 			return this; // self
 		}
 	});
-	g.Group.nodeType = "group";
+	vml.Group.nodeType = "group";
 
-	dojo.declare("dojox.gfx.Rect", gs.Rect, {
+	dojo.declare("dojox.gfx.vml.Rect", [vml.Shape, gs.Rect], {
 		// summary: a rectangle shape (VML)
 		setShape: function(newShape){
 			// summary: sets a rectangle shape object (VML)
@@ -363,10 +367,9 @@ dojo.require("dojox.gfx.gradient");
 			return this.setTransform(this.matrix).setFill(this.fillStyle).setStroke(this.strokeStyle);	// self
 		}
 	});
-	g.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected
+	vml.Rect.nodeType = "roundrect"; // use a roundrect so the stroke join type is respected
 
-
-	dojo.declare("dojox.gfx.Ellipse", gs.Ellipse, {
+	dojo.declare("dojox.gfx.vml.Ellipse", [vml.Shape, gs.Ellipse], {
 		// summary: an ellipse shape (VML)
 		setShape: function(newShape){
 			// summary: sets an ellipse shape object (VML)
@@ -381,9 +384,9 @@ dojo.require("dojox.gfx.gradient");
 			return this.setTransform(this.matrix);	// self
 		}
 	});
-	g.Ellipse.nodeType = "oval";
+	vml.Ellipse.nodeType = "oval";
 
-	dojo.declare("dojox.gfx.Circle", gs.Circle, {
+	dojo.declare("dojox.gfx.vml.Circle", [vml.Shape, gs.Circle], {
 		// summary: a circle shape (VML)
 		setShape: function(newShape){
 			// summary: sets a circle shape object (VML)
@@ -398,9 +401,9 @@ dojo.require("dojox.gfx.gradient");
 			return this;	// self
 		}
 	});
-	g.Circle.nodeType = "oval";
+	vml.Circle.nodeType = "oval";
 
-	dojo.declare("dojox.gfx.Line", gs.Line, {
+	dojo.declare("dojox.gfx.vml.Line", [vml.Shape, gs.Line], {
 		// summary: a line shape (VML)
 		constructor: function(rawNode){
 			if(rawNode) rawNode.setAttribute("dojoGfxType", "line");
@@ -415,9 +418,9 @@ dojo.require("dojox.gfx.gradient");
 			return this.setTransform(this.matrix);	// self
 		}
 	});
-	g.Line.nodeType = "shape";
+	vml.Line.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.Polyline", gs.Polyline, {
+	dojo.declare("dojox.gfx.vml.Polyline", [vml.Shape, gs.Polyline], {
 		// summary: a polyline/polygon shape (VML)
 		constructor: function(rawNode){
 			if(rawNode) rawNode.setAttribute("dojoGfxType", "polyline");
@@ -452,9 +455,9 @@ dojo.require("dojox.gfx.gradient");
 			return this.setTransform(this.matrix);	// self
 		}
 	});
-	g.Polyline.nodeType = "shape";
+	vml.Polyline.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.Image", gs.Image, {
+	dojo.declare("dojox.gfx.vml.Image", [vml.Shape, gs.Image], {
 		// summary: an image (VML)
 		setShape: function(newShape){
 			// summary: sets an image shape object (VML)
@@ -521,9 +524,9 @@ dojo.require("dojox.gfx.gradient");
 			return this;	// self
 		}
 	});
-	g.Image.nodeType = "rect";
+	vml.Image.nodeType = "rect";
 
-	dojo.declare("dojox.gfx.Text", gs.Text, {
+	dojo.declare("dojox.gfx.vml.Text", [vml.Shape, gs.Text], {
 		// summary: an anchored text (VML)
 		constructor: function(rawNode){
 			if(rawNode){rawNode.setAttribute("dojoGfxType", "text");}
@@ -591,7 +594,7 @@ dojo.require("dojox.gfx.gradient");
 			// summary: returns the cumulative ("real") transformation matrix
 			//	by combining the shape's matrix with its parent's matrix;
 			//	it makes a correction for a font size
-			var matrix = g.Shape.prototype._getRealMatrix.call(this);
+			var matrix = this.inherited(arguments);
 			// It appears that text is always aligned vertically at a middle of x-height (???).
 			// It is impossible to obtain these metrics from VML => I try to approximate it with
 			// more-or-less util value of 0.7 * FontSize, which is typical for European fonts.
@@ -610,9 +613,9 @@ dojo.require("dojox.gfx.gradient");
 			return _width;
 		}
 	});
-	g.Text.nodeType = "shape";
+	vml.Text.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.Path", g.path.Path, {
+	dojo.declare("dojox.gfx.vml.Path", [vml.Shape, g.path.Path], {
 		// summary: a path shape (VML)
 		constructor: function(rawNode){
 			if(rawNode && !rawNode.getAttribute("dojoGfxType")){
@@ -625,7 +628,7 @@ dojo.require("dojox.gfx.gradient");
 			// summary: updates the bounding box of path with new segment
 			// segment: Object: a segment
 			var last = d.clone(this.last);
-			g.Path.superclass._updateWithSegment.apply(this, arguments);
+			this.inherited(arguments);
 			if(arguments.length > 1){ return; } // skip transfomed bbox calculations
 			// add a VML path segment
 			var path = this[this.renderers[segment.action]](segment, last);
@@ -633,7 +636,7 @@ dojo.require("dojox.gfx.gradient");
 				this.vmlPath += path.join("");
 				this.rawNode.path.v = this.vmlPath + " r0,0 e";
 			}else{
-				Array.prototype.push.apply(this.vmlPath, path);
+				Array.prototype.push.apply(this.vmlPath, path); //FIXME: why not push()?
 			}
 		},
 		setShape: function(newShape){
@@ -641,7 +644,7 @@ dojo.require("dojox.gfx.gradient");
 			// newShape: Object: an VML path string or a path object (see dojox.gfx.defaultPath)
 			this.vmlPath = [];
 			this.lastControl.type = "";	// no prior control point
-			g.Path.superclass.setShape.apply(this, arguments);
+			this.inherited(arguments);
 			this.vmlPath = this.vmlPath.join("");
 			this.rawNode.path.v = this.vmlPath + " r0,0 e";
 			return this;
@@ -864,9 +867,9 @@ dojo.require("dojox.gfx.gradient");
 			return ["x"];
 		}
 	});
-	g.Path.nodeType = "shape";
+	vml.Path.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.TextPath", g.Path, {
+	dojo.declare("dojox.gfx.vml.TextPath", [vml.Path, g.path.TextPath], {
 		// summary: a textpath shape (VML)
 		constructor: function(rawNode){
 			if(rawNode){rawNode.setAttribute("dojoGfxType", "textpath");}
@@ -938,12 +941,12 @@ dojo.require("dojox.gfx.gradient");
 			}
 		}
 	});
-	g.TextPath.nodeType = "shape";
+	vml.TextPath.nodeType = "shape";
 
-	dojo.declare("dojox.gfx.Surface", gs.Surface, {
+	dojo.declare("dojox.gfx.vml.Surface", gs.Surface, {
 		// summary: a surface object to be used for drawings (VML)
 		constructor: function(){
-			vml.Container._init.call(this);
+			gs.Container._init.call(this);
 		},
 		setDimensions: function(width, height){
 			// summary: sets the width and height of the rawNode
@@ -982,7 +985,7 @@ dojo.require("dojox.gfx.gradient");
 		}
 	});
 
-	g.createSurface = function(parentNode, width, height){
+	vml.createSurface = function(parentNode, width, height){
 		// summary: creates a surface (VML)
 		// parentNode: Node: a parent node
 		// width: String: width of surface, e.g., "100px"
@@ -1000,7 +1003,7 @@ dojo.require("dojox.gfx.gradient");
 			height = height + "px";
 		}
 
-		var s = new g.Surface(), p = d.byId(parentNode),
+		var s = new vml.Surface(), p = d.byId(parentNode),
 			c = s.clipNode = p.ownerDocument.createElement("div"),
 			r = s.rawNode = p.ownerDocument.createElement("v:group"),
 			cs = c.style, rs = r.style;
@@ -1044,25 +1047,40 @@ dojo.require("dojox.gfx.gradient");
 	};
 
 	// Extenders
+	
+	// copied from dojox.gfx.utils
+	function forEach(object, f, o){
+		o = o || d.global;
+		f.call(o, object);
+		if(object instanceof g.Surface || object instanceof g.Group){
+			d.forEach(object.children, function(shape){
+				forEach(shape, f, o);
+			});
+		}
+	}
 
-
-	vml.Container = {
-		_init: function(){
-			gs.Container._init.call(this);
-		},
+	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);
-				if(!shape.getParent()){
-					// reapply visual attributes
-					shape.setFill(shape.getFill());
-					shape.setStroke(shape.getStroke());
-				}
-				//dojox.gfx.Group.superclass.add.apply(this, arguments);
-				//this.inherited(arguments);
-				gs.Container.add.apply(this, arguments);
+				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
 		},
@@ -1074,9 +1092,7 @@ dojo.require("dojox.gfx.gradient");
 				if(this.rawNode == shape.rawNode.parentNode){
 					this.rawNode.removeChild(shape.rawNode);
 				}
-				//dojox.gfx.Group.superclass.remove.apply(this, arguments);
-				//this.inherited(arguments);
-				gs.Container.remove.apply(this, arguments);
+				C.remove.apply(this, arguments);
 			}
 			return this;	// self
 		},
@@ -1091,18 +1107,17 @@ dojo.require("dojox.gfx.gradient");
 					r.removeChild(r.lastChild);
 				}
 			}
-			//return this.inherited(arguments);	// self
-			return gs.Container.clear.apply(this, arguments);
+			return C.clear.apply(this, arguments);
 		},
-		_moveChildToFront: gs.Container._moveChildToFront,
-		_moveChildToBack:  gs.Container._moveChildToBack
+		_moveChildToFront: C._moveChildToFront,
+		_moveChildToBack:  C._moveChildToBack
 	};
 
-	dojo.mixin(gs.Creator, {
+	var Creator = {
 		// summary: VML shape creators
 		createGroup: function(){
 			// summary: creates a VML group shape
-			var node = this.createObject(g.Group, null);	// dojox.gfx.Group
+			var node = this.createObject(vml.Group, null);	// dojox.gfx.Group
 			// create a background rectangle, which is required to show all other shapes
 			var r = node.rawNode.ownerDocument.createElement("v:rect");
 			r.style.left = r.style.top = 0;
@@ -1117,7 +1132,7 @@ dojo.require("dojox.gfx.gradient");
 			// summary: creates a VML image shape
 			// image: Object: an image object (see dojox.gfx.defaultImage)
 			if(!this.rawNode) return null;
-			var shape = new g.Image(),
+			var shape = new vml.Image(),
 				doc = this.rawNode.ownerDocument,
 				node = doc.createElement('v:rect');
 			node.stroked = "f";
@@ -1135,7 +1150,7 @@ dojo.require("dojox.gfx.gradient");
 			// summary: creates a rectangle shape
 			// rect: Object: a path object (see dojox.gfx.defaultRect)
 			if(!this.rawNode) return null;
-			var shape = new g.Rect,
+			var shape = new vml.Rect,
 				node = this.rawNode.ownerDocument.createElement("v:roundrect");
 			if(d.isIE > 7){
 				node.style.display = "inline-block";
@@ -1157,13 +1172,13 @@ dojo.require("dojox.gfx.gradient");
 			shape.setRawNode(node);
 			this.rawNode.appendChild(node);
 			switch(shapeType){
-				case g.Group:
-				case g.Line:
-				case g.Polyline:
-				case g.Image:
-				case g.Text:
-				case g.Path:
-				case g.TextPath:
+				case vml.Group:
+				case vml.Line:
+				case vml.Polyline:
+				case vml.Image:
+				case vml.Text:
+				case vml.Path:
+				case vml.TextPath:
 					this._overrideSize(node);
 			}
 			shape.setShape(rawShape);
@@ -1176,12 +1191,19 @@ dojo.require("dojox.gfx.gradient");
 			node.style.height = h;
 			node.coordsize = parseInt(w) + " " + parseInt(h);
 		}
-	});
+	};
 
-	d.extend(g.Group, vml.Container);
-	d.extend(g.Group, gs.Creator);
+	d.extend(vml.Group, Container);
+	d.extend(vml.Group, gs.Creator);
+	d.extend(vml.Group, Creator);
 
-	d.extend(g.Surface, vml.Container);
-	d.extend(g.Surface, gs.Creator);
+	d.extend(vml.Surface, Container);
+	d.extend(vml.Surface, gs.Creator);
+	d.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
diff --git a/dojox/gfx/vml_attach.js b/dojox/gfx/vml_attach.js
index 99008d9..2b920c3 100644
--- a/dojox/gfx/vml_attach.js
+++ b/dojox/gfx/vml_attach.js
@@ -3,57 +3,59 @@ dojo.require("dojox.gfx.vml");
 dojo.experimental("dojox.gfx.vml_attach");
 
 (function(){
-	dojox.gfx.attachNode = function(node){
+	var g = dojox.gfx, m = g.matrix, vml = g.vml;
+	
+	vml.attachNode = function(node){
 		// summary: creates a shape from a Node
 		// node: Node: an VML node
 		if(!node) return null;
 		var s = null;
 		switch(node.tagName.toLowerCase()){
-			case dojox.gfx.Rect.nodeType:
-				s = new dojox.gfx.Rect(node);
+			case vml.Rect.nodeType:
+				s = new vml.Rect(node);
 				attachRect(s);
 				break;
-			case dojox.gfx.Ellipse.nodeType:
+			case vml.Ellipse.nodeType:
 				if(node.style.width == node.style.height){
-					s = new dojox.gfx.Circle(node);
+					s = new vml.Circle(node);
 					attachCircle(s);
 				}else{
-					s = new dojox.gfx.Ellipse(node);
+					s = new vml.Ellipse(node);
 					attachEllipse(s);
 				}
 				break;
-			case dojox.gfx.Path.nodeType:
+			case vml.Path.nodeType:
 				switch(node.getAttribute("dojoGfxType")){
 					case "line":
-						s = new dojox.gfx.Line(node);
+						s = new vml.Line(node);
 						attachLine(s);
 						break;
 					case "polyline":
-						s = new dojox.gfx.Polyline(node);
+						s = new vml.Polyline(node);
 						attachPolyline(s);
 						break;
 					case "path":
-						s = new dojox.gfx.Path(node);
+						s = new vml.Path(node);
 						attachPath(s);
 						break;
 					case "text":
-						s = new dojox.gfx.Text(node);
+						s = new vml.Text(node);
 						attachText(s);
 						attachFont(s);
 						attachTextTransform(s);
 						break;
 					case "textpath":
-						s = new dojox.gfx.TextPath(node);
+						s = new vml.TextPath(node);
 						attachPath(s);
 						attachText(s);
 						attachFont(s);
 						break;
 				}
 				break;
-			case dojox.gfx.Image.nodeType:
+			case vml.Image.nodeType:
 				switch(node.getAttribute("dojoGfxType")){
 					case "image":
-						s = new dojox.gfx.Image(node);
+						s = new vml.Image(node);
 						attachImage(s);
 						attachImageTransform(s);
 						break;
@@ -63,20 +65,20 @@ dojo.experimental("dojox.gfx.vml_attach");
 				//console.debug("FATAL ERROR! tagName = " + node.tagName);
 				return null;
 		}
-		if(!(s instanceof dojox.gfx.Image)){
+		if(!(s instanceof vml.Image)){
 			attachFill(s);
 			attachStroke(s);
-			if(!(s instanceof dojox.gfx.Text)){
+			if(!(s instanceof vml.Text)){
 				attachTransform(s);
 			}
 		}
 		return s;	// dojox.gfx.Shape
 	};
 
-	dojox.gfx.attachSurface = function(node){
+	vml.attachSurface = function(node){
 		// summary: creates a surface from a Node
 		// node: Node: an VML node
-		var s = new dojox.gfx.Surface();
+		var s = new vml.Surface();
 		s.clipNode = node;
 		var r = s.rawNode = node.firstChild;
 		var b = r.firstChild;
@@ -92,8 +94,8 @@ dojo.experimental("dojox.gfx.vml_attach");
 		// object: dojox.gfx.Shape: an VML shape
 		var fillStyle = null, r = object.rawNode, fo = r.fill;
 		if(fo.on && fo.type == "gradient"){
-			var fillStyle = dojo.clone(dojox.gfx.defaultLinearGradient),
-				rad = dojox.gfx.matrix._degToRad(fo.angle);
+			var fillStyle = dojo.clone(g.defaultLinearGradient),
+				rad = m._degToRad(fo.angle);
 			fillStyle.x2 = Math.cos(rad);
 			fillStyle.y2 = Math.sin(rad);
 			fillStyle.colors = [];
@@ -101,10 +103,10 @@ dojo.experimental("dojox.gfx.vml_attach");
 			for(var i = 0; i < stops.length; ++i){
 				var t = stops[i].match(/\S+/g);
 				if(!t || t.length != 2){ continue; }
-				fillStyle.colors.push({offset: dojox.gfx.vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
+				fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
 			}
 		}else if(fo.on && fo.type == "gradientradial"){
-			var fillStyle = dojo.clone(dojox.gfx.defaultRadialGradient),
+			var fillStyle = dojo.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;
@@ -114,12 +116,12 @@ dojo.experimental("dojox.gfx.vml_attach");
 			for(var i = stops.length - 1; i >= 0; --i){
 				var t = stops[i].match(/\S+/g);
 				if(!t || t.length != 2){ continue; }
-				fillStyle.colors.push({offset: dojox.gfx.vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
+				fillStyle.colors.push({offset: vml._parseFloat(t[0]), color: new dojo.Color(t[1])});
 			}
 		}else if(fo.on && fo.type == "tile"){
-			var fillStyle = dojo.clone(dojox.gfx.defaultPattern);
-			fillStyle.width  = dojox.gfx.pt2px(fo.size.x); // from pt
-			fillStyle.height = dojox.gfx.pt2px(fo.size.y); // from pt
+			var fillStyle = dojo.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;
 			fillStyle.y = fo.origin.y * fillStyle.height;
 			fillStyle.src = fo.src;
@@ -139,10 +141,10 @@ dojo.experimental("dojox.gfx.vml_attach");
 			object.strokeStyle = null;
 			return;
 		}
-		var strokeStyle = object.strokeStyle = dojo.clone(dojox.gfx.defaultStroke),
+		var strokeStyle = object.strokeStyle = dojo.clone(g.defaultStroke),
 			rs = r.stroke;
 		strokeStyle.color = new dojo.Color(r.strokecolor.value);
-		strokeStyle.width = dojox.gfx.normalizedLength(r.strokeweight+"");
+		strokeStyle.width = g.normalizedLength(r.strokeweight+"");
 		strokeStyle.color.a = rs.opacity;
 		strokeStyle.cap = this._translate(this._capMapReversed, rs.endcap);
 		strokeStyle.join = rs.joinstyle == "miter" ? rs.miterlimit : rs.joinstyle;
@@ -153,13 +155,13 @@ dojo.experimental("dojox.gfx.vml_attach");
 		// summary: deduces a transformation matrix from a node.
 		// object: dojox.gfx.Shape: an VML shape
 		var s = object.rawNode.skew, sm = s.matrix, so = s.offset;
-		object.matrix = dojox.gfx.matrix.normalize({
+		object.matrix = m.normalize({
 			xx: sm.xtox,
 			xy: sm.ytox,
 			yx: sm.xtoy,
 			yy: sm.ytoy,
-			dx: dojox.gfx.pt2px(so.x),
-			dy: dojox.gfx.pt2px(so.y)
+			dx: g.pt2px(so.x),
+			dy: g.pt2px(so.y)
 		});
 	};
 
@@ -176,9 +178,9 @@ dojo.experimental("dojox.gfx.vml_attach");
 		// a workaround for the VML's arcsize bug: cannot read arcsize of an instantiated node
 		var r = object.rawNode, arcsize = r.outerHTML.match(/arcsize = \"(\d*\.?\d+[%f]?)\"/)[1],
 			style = r.style, width = parseFloat(style.width), height = parseFloat(style.height);
-		arcsize = (arcsize.indexOf("%") >= 0) ? parseFloat(arcsize) / 100 : dojox.gfx.vml._parseFloat(arcsize);
+		arcsize = (arcsize.indexOf("%") >= 0) ? parseFloat(arcsize) / 100 : vml._parseFloat(arcsize);
 		// make an object
-		object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultRect, {
+		object.shape = g.makeParameters(g.defaultRect, {
 			x: parseInt(style.left),
 			y: parseInt(style.top),
 			width:  width,
@@ -193,7 +195,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 		var style = object.rawNode.style,
 			rx = parseInt(style.width ) / 2,
 			ry = parseInt(style.height) / 2;
-		object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultEllipse, {
+		object.shape = g.makeParameters(g.defaultEllipse, {
 			cx: parseInt(style.left) + rx,
 			cy: parseInt(style.top ) + ry,
 			rx: rx,
@@ -205,7 +207,7 @@ dojo.experimental("dojox.gfx.vml_attach");
 		// summary: builds a circle shape from a node.
 		// object: dojox.gfx.Shape: an VML shape
 		var style = object.rawNode.style, r = parseInt(style.width) / 2;
-		object.shape = dojox.gfx.makeParameters(dojox.gfx.defaultCircle, {
+		object.shape = g.makeParameters(g.defaultCircle, {
 			cx: parseInt(style.left) + r,
 			cy: parseInt(style.top)  + r,
 			r:  r
@@ -215,8 +217,8 @@ 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(dojox.gfx.defaultLine),
-			p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp);
+		var shape = object.shape = dojo.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; }
 			shape.x1 = parseInt(p[1]);
@@ -229,8 +231,8 @@ 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(dojox.gfx.defaultPolyline),
-			p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp);
+		var shape = object.shape = dojo.clone(g.defaultPolyline),
+			p = object.rawNode.path.v.match(g.pathVmlRegExp);
 		do{
 			if(p.length < 3 || p[0] != "m"){ break; }
 			var x = parseInt(p[0]), y = parseInt(p[1]);
@@ -249,29 +251,29 @@ 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(dojox.gfx.defaultImage);
+		object.shape = dojo.clone(g.defaultImage);
 		object.shape.src = object.rawNode.firstChild.src;
 	};
 
 	var attachImageTransform = function(object) {
 		// summary: deduces a transformation matrix from a node.
 		// object: dojox.gfx.Shape: an VML shape
-		var m = object.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
-		object.matrix = dojox.gfx.matrix.normalize({
-			xx: m.M11,
-			xy: m.M12,
-			yx: m.M21,
-			yy: m.M22,
-			dx: m.Dx,
-			dy: m.Dy
+		var mm = object.rawNode.filters["DXImageTransform.Microsoft.Matrix"];
+		object.matrix = m.normalize({
+			xx: mm.M11,
+			xy: mm.M12,
+			yx: mm.M21,
+			yy: mm.M22,
+			dx: mm.Dx,
+			dy: mm.Dy
 		});
 	};
 
 	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(dojox.gfx.defaultText),
-			r = object.rawNode, p = r.path.v.match(dojox.gfx.pathVmlRegExp);
+		var shape = object.shape = dojo.clone(g.defaultText),
+			r = object.rawNode, p = r.path.v.match(g.pathVmlRegExp);
 		do{
 			if(!p || p.length != 7){ break; }
 			var c = r.childNodes, i = 0;
@@ -295,8 +297,8 @@ dojo.experimental("dojox.gfx.vml_attach");
 			}
 			shape.y = parseInt(p[2]);
 			shape.decoration = s["text-decoration"];
-			shape.rotated = s["v-rotate-letters"].toLowerCase() in dojox.gfx.vml._bool;
-			shape.kerning = s["v-text-kern"].toLowerCase() in dojox.gfx.vml._bool;
+			shape.rotated = s["v-rotate-letters"].toLowerCase() in vml._bool;
+			shape.kerning = s["v-text-kern"].toLowerCase() in vml._bool;
 			return;
 		}while(false);
 		object.shape = null;
@@ -305,7 +307,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(dojox.gfx.defaultFont),
+		var fontStyle = object.fontStyle = dojo.clone(g.defaultFont),
 			c = object.rawNode.childNodes, i = 0;
 		for(; i < c.length && c[i].tagName == "textpath"; ++i);
 		if(i >= c.length){
@@ -327,16 +329,16 @@ dojo.experimental("dojox.gfx.vml_attach");
 		var matrix = object.matrix, fs = object.fontStyle;
 		// see comments in _getRealMatrix()
 		if(matrix && fs){
-			object.matrix = dojox.gfx.matrix.multiply(matrix, {dy: dojox.gfx.normalizedLength(fs.size) * 0.35});
+			object.matrix = m.multiply(matrix, {dy: g.normalizedLength(fs.size) * 0.35});
 		}
 	};
 
 	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(dojox.gfx.defaultPath),
-			p = object.rawNode.path.v.match(dojox.gfx.pathVmlRegExp),
-			t = [], skip = false, map = dojox.gfx.Path._pathVmlToSvgMap;
+		var shape = object.shape = dojo.clone(g.defaultPath),
+			p = object.rawNode.path.v.match(g.pathVmlRegExp),
+			t = [], skip = false, map = g.Path._pathVmlToSvgMap;
 		for(var i = 0; i < p.length; ++p){
 			var s = p[i];
 			if(s in map) {
diff --git a/dojox/gfx3d/lighting.js b/dojox/gfx3d/lighting.js
index de4f495..c663ff2 100644
--- a/dojox/gfx3d/lighting.js
+++ b/dojox/gfx3d/lighting.js
@@ -93,7 +93,7 @@ dojo.require("dojox.gfx._base");
 		specular: function(normal, v, roughness, lights){
 			var c = lite.black();
 			for(var i = 0; i < lights.length; ++i){
-				var l = lights[i], 
+				var l = lights[i],
 					h = lite.normalize(lite.add(lite.normalize(l.direction), v)),
 					s = Math.pow(Math.max(0, lite.dot(normal, h)), 1 / roughness);
 				c = lite.addColor(c, lite.scaleColor(s, l.color));
diff --git a/dojox/gfx3d/matrix.js b/dojox/gfx3d/matrix.js
index 6c1a2de..62ddca8 100644
--- a/dojox/gfx3d/matrix.js
+++ b/dojox/gfx3d/matrix.js
@@ -6,7 +6,7 @@ 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, 
+	// 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
@@ -92,7 +92,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	rotateX: function(angle){
 		// summary: forms a rotating matrix (about the x axis)
-		// description: The resulting matrix is used to rotate points 
+		// 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);
@@ -109,7 +109,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	rotateY: function(angle){
 		// summary: forms a rotating matrix (about the y axis)
-		// description: The resulting matrix is used to rotate points 
+		// 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);
@@ -126,7 +126,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	rotateZ: function(angle){
 		// summary: forms a rotating matrix (about the z axis)
-		// description: The resulting matrix is used to rotate points 
+		// 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);
@@ -159,7 +159,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	cameraRotateX: function(angle){
 		// summary: forms a rotating matrix (about the x axis) in cameraTransform manner
-		// description: The resulting matrix is used to rotate points 
+		// 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);
@@ -176,7 +176,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	cameraRotateY: function(angle){
 		// summary: forms a rotating matrix (about the y axis) in cameraTransform manner
-		// description: The resulting matrix is used to rotate points 
+		// 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);
@@ -193,7 +193,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	cameraRotateZ: function(angle){
 		// summary: forms a rotating matrix (about the z axis) in cameraTransform manner
-		// description: The resulting matrix is used to rotate points 
+		// 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);
@@ -277,7 +277,7 @@ dojo.mixin(dojox.gfx3d.matrix, {
 	},
 	multiply: function(matrix){
 		// summary: combines matrices by multiplying them sequentially in the given order
-		// matrix: dojox.gfx3d.matrix.Matrix3D...: a 3D matrix-like object, 
+		// 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
@@ -308,8 +308,8 @@ dojo.mixin(dojox.gfx3d.matrix, {
 		// 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, 
+			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){
diff --git a/dojox/gfx3d/object.js b/dojox/gfx3d/object.js
index 85038a7..6d446bd 100644
--- a/dojox/gfx3d/object.js
+++ b/dojox/gfx3d/object.js
@@ -42,7 +42,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 		// parent: a reference for parent, Scene or Viewport object
 		this.parent = null;
 
-		// strokeStyle: Object: a stroke object 
+		// strokeStyle: Object: a stroke object
 		this.strokeStyle = null;
 		// fillStyle: Object: a fill object or texture object
 		this.fillStyle = null;
@@ -66,7 +66,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 	setTransform: function(matrix){
 		// summary: sets a transformation matrix
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix 
+		//	(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);
 		return this;	// self
@@ -78,7 +78,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 		// summary: multiplies the existing matrix with an argument on right side
 		//	(this.matrix * matrix)
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix 
+		//	(see an argument of dojox.gfx.matrix.Matrix
 		//	constructor for a list of acceptable arguments)
 		return matrix ? this.setTransform([this.matrix, matrix]) : this;	// self
 	},
@@ -86,7 +86,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 		// summary: multiplies the existing matrix with an argument on left side
 		//	(matrix * this.matrix)
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix 
+		//	(see an argument of dojox.gfx.matrix.Matrix
 		//	constructor for a list of acceptable arguments)
 		return matrix ? this.setTransform([matrix, this.matrix]) : this;	// self
 	},
@@ -94,19 +94,19 @@ dojo.declare("dojox.gfx3d.Object", null, {
 	applyTransform: function(matrix){
 		// summary: a shortcut for dojox.gfx.Shape.applyRightTransform
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix 
+		//	(see an argument of dojox.gfx.matrix.Matrix
 		//	constructor for a list of acceptable arguments)
 		return matrix ? this.setTransform([this.matrix, matrix]) : this;	// self
 	},
 	
 	setFill: function(fill){
 		// summary: sets a fill object
-		// (the default implementation is to delegate to 
+		// (the default implementation is to delegate to
 		// the underlying 2D shape).
 		// fill: Object: a fill object
-		//	(see dojox.gfx.defaultLinearGradient, 
-		//	dojox.gfx.defaultRadialGradient, 
-		//	dojox.gfx.defaultPattern, 
+		//	(see dojox.gfx.defaultLinearGradient,
+		//	dojox.gfx.defaultRadialGradient,
+		//	dojox.gfx.defaultPattern,
 		//	dojo.Color
 		//	or dojox.gfx.MODEL)
 		this.fillStyle = fill;
@@ -117,7 +117,7 @@ dojo.declare("dojox.gfx3d.Object", null, {
 		// summary: sets a stroke object
 		//	(the default implementation simply ignores it)
 		// stroke: Object: a stroke object
-		//	(see dojox.gfx.defaultStroke) 
+		//	(see dojox.gfx.defaultStroke)
 		this.strokeStyle = stroke;
 		return this;
 	},
@@ -225,7 +225,7 @@ dojo.declare("dojox.gfx3d.Scene", dojox.gfx3d.Object, {
 
 dojo.declare("dojox.gfx3d.Edges", dojox.gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic edge in 3D viewport 
+		// summary: a generic edge in 3D viewport
 		this.object = dojo.clone(dojox.gfx3d.defaultEdges);
 	},
 
@@ -282,7 +282,7 @@ dojo.declare("dojox.gfx3d.Edges", dojox.gfx3d.Object, {
 
 dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic edge in 3D viewport 
+		// summary: a generic edge in 3D viewport
 		this.object = dojo.clone(dojox.gfx3d.defaultOrbit);
 	},
 
@@ -291,7 +291,7 @@ dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
 		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){
-			return {x: this.center.x + this.radius * Math.cos(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);
 
@@ -341,7 +341,7 @@ dojo.declare("dojox.gfx3d.Orbit", dojox.gfx3d.Object, {
 		var c = Math.pow(probes[1].x, 2);
 		var d = Math.pow(probes[1].y, 2);
 
-		// the invert matrix is 
+		// 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) );
@@ -445,7 +445,7 @@ dojo.declare("dojox.gfx3d.Path3d", dojox.gfx3d.Object, {
 			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])
-				path += " " + pt.x + " " + pt.y; 
+				path += " " + pt.x + " " + pt.y;
 			}
 		});
 
@@ -459,7 +459,7 @@ dojo.declare("dojox.gfx3d.Path3d", dojox.gfx3d.Object, {
 
 dojo.declare("dojox.gfx3d.Triangles", dojox.gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle 
+		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
 		this.object = dojo.clone(dojox.gfx3d.defaultTriangles);
 	},
@@ -522,7 +522,7 @@ dojo.declare("dojox.gfx3d.Triangles", dojox.gfx3d.Object, {
 
 	getZOrder: function(){
 		var zOrder = 0;
-		dojo.forEach(this.cache, function(item){ 
+		dojo.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;
 	}
@@ -530,7 +530,7 @@ dojo.declare("dojox.gfx3d.Triangles", dojox.gfx3d.Object, {
 
 dojo.declare("dojox.gfx3d.Quads", dojox.gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle 
+		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
 		this.object = dojo.clone(dojox.gfx3d.defaultQuads);
 	},
@@ -604,7 +604,7 @@ dojo.declare("dojox.gfx3d.Quads", dojox.gfx3d.Object, {
 
 dojo.declare("dojox.gfx3d.Polygon", dojox.gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle 
+		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
 		this.object = dojo.clone(dojox.gfx3d.defaultPolygon);
 	},
@@ -652,7 +652,7 @@ dojo.declare("dojox.gfx3d.Polygon", dojox.gfx3d.Object, {
 
 dojo.declare("dojox.gfx3d.Cube", dojox.gfx3d.Object, {
 	constructor: function(){
-		// summary: a generic triangle 
+		// summary: a generic triangle
 		//	(this is a helper object, which is defined for convenience)
 		this.object = dojo.clone(dojox.gfx3d.defaultCube);
 		this.polygons = [];
@@ -722,12 +722,12 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 	},
 
 	render: function(camera){
-		// get the bottom surface first 
+		// get the bottom surface first
 		var m = dojox.gfx3d.matrix.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){
-			return {x: this.center.x + this.radius * Math.cos(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);
 
@@ -771,7 +771,7 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 		var c = Math.pow(probes[1].x, 2);
 		var d = Math.pow(probes[1].y, 2);
 
-		// the invert matrix is 
+		// 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));
@@ -782,8 +782,8 @@ 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 = dojox.gfx3d.matrix.multiplyPoint(m,
+			dojox.gfx3d.vector.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);
@@ -818,7 +818,7 @@ dojo.declare("dojox.gfx3d.Cylinder", dojox.gfx3d.Object, {
 			.lineTo(0, c.rx)
 			.arcTo(c.ry, c.rx, 0, true, true, 0, -c.rx)
 			.setFill(c.gradient).setStroke(this.strokeStyle)
-			.setTransform([m.translate(centers[0]), 
+			.setTransform([m.translate(centers[0]),
 				m.rotate(Math.atan2(centers[1].y - centers[0].y, centers[1].x - centers[0].x))]);
 
 		if(c.rx > 0 && c.ry > 0){
@@ -861,7 +861,7 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 	setCameraTransform: function(matrix){
 		// summary: sets a transformation matrix
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx.matrix.Matrix 
+		//	(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.invalidate();
@@ -872,7 +872,7 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// summary: multiplies the existing matrix with an argument on right side
 		//	(this.matrix * matrix)
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix 
+		//	(see an argument of dojox.gfx3d.matrix.Matrix
 		//	constructor for a list of acceptable arguments)
 		return matrix ? this.setCameraTransform([this.camera, matrix]) : this;	// self
 	},
@@ -881,7 +881,7 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		// summary: multiplies the existing matrix with an argument on left side
 		//	(matrix * this.matrix)
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix 
+		//	(see an argument of dojox.gfx3d.matrix.Matrix
 		//	constructor for a list of acceptable arguments)
 		return matrix ? this.setCameraTransform([matrix, this.camera]) : this;	// self
 	},
@@ -889,12 +889,12 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 	applyCameraTransform: function(matrix){
 		// summary: a shortcut for dojox.gfx3d.Object.applyRightTransform
 		// matrix: dojox.gfx3d.matrix.Matrix: a matrix or a matrix-like object
-		//	(see an argument of dojox.gfx3d.matrix.Matrix 
+		//	(see an argument of dojox.gfx3d.matrix.Matrix
 		//	constructor for a list of acceptable arguments)
 		return this.applyCameraRightTransform(matrix); // self
 	},
 
-	setLights: function(/* Array || Object */lights, /* Color, optional */ ambient, 
+	setLights: function(/* Array || Object */lights, /* Color, optional */ ambient,
 		/* Color, optional */ specular){
 		// summary: set the lights
 		// lights: Array: an array of light object
@@ -904,7 +904,7 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		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 dojox.gfx3d.lighting.Model(view, this.lights.sources,
 				this.lights.ambient, this.lights.specular);
 		this.invalidate();
 		return this;
@@ -917,13 +917,13 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 	},
 
 	addTodo: function(newObject){
-		// NOTE: Viewport implements almost the same addTodo, 
+		// NOTE: Viewport implements almost the same addTodo,
 		// 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(dojo.every(this.todos,
 			function(item){
-				return item != newObject; 
+				return item != newObject;
 			}
 		)){
 			this.todos.push(newObject);
@@ -939,9 +939,12 @@ dojo.declare("dojox.gfx3d.Viewport", dojox.gfx.Group, {
 		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 trs = this.rawNode.style;
-			trs.height = h;
-			trs.width = w;
+			// there is no rawNode in canvas GFX implementation
+			if(this.rawNode){
+				var trs = this.rawNode.style;
+				trs.height = h;
+				trs.width = w;
+			}
 			this.dimension = {
 				width:  w,
 				height: h
@@ -980,51 +983,51 @@ dojox.gfx3d.Viewport.nodeType = dojox.gfx.Group.nodeType;
 dojox.gfx3d._creators = {
 	// summary: object creators
 	createEdges: function(edges, style){
-		// summary: creates an edge object 
+		// 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
 	},
 	createTriangles: function(tris, style){
-		// summary: creates an edge object 
+		// 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
 	},
 	createQuads: function(quads, style){
-		// summary: creates an edge object 
+		// 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
 	},
 	createPolygon: function(points){
-		// summary: creates an triangle object 
-		// points: Array of points || Object 
+		// summary: creates an triangle object
+		// points: Array of points || Object
 		return this.create3DObject(dojox.gfx3d.Polygon, points);	// dojox.gfx3d.Polygon
 	},
 
 	createOrbit: function(orbit){
-		// summary: creates an triangle object 
-		// points: Array of points || Object 
+		// summary: creates an triangle object
+		// points: Array of points || Object
 		return this.create3DObject(dojox.gfx3d.Orbit, orbit);	// dojox.gfx3d.Cube
 	},
 
 	createCube: function(cube){
-		// summary: creates an triangle object 
-		// points: Array of points || Object 
+		// summary: creates an triangle object
+		// points: Array of points || Object
 		return this.create3DObject(dojox.gfx3d.Cube, cube);	// dojox.gfx3d.Cube
 	},
 
 	createCylinder: function(cylinder){
-		// summary: creates an triangle object 
-		// points: Array of points || Object 
+		// summary: creates an triangle object
+		// points: Array of points || Object
 		return this.create3DObject(dojox.gfx3d.Cylinder, cylinder);	// dojox.gfx3d.Cube
 	},
 
 	createPath3d: function(path){
-		// summary: creates an edge object 
+		// summary: creates an edge object
 		// line: Object: a edge object (see dojox.gfx3d.defaultPath)
 		return this.create3DObject(dojox.gfx3d.Path3d, path);	// dojox.gfx3d.Edge
 	},
 	createScene: function(){
-		// summary: creates an triangle object 
+		// summary: creates an triangle object
 		// line: Object: a triangle object (see dojox.gfx3d.defaultPath)
 		return this.create3DObject(dojox.gfx3d.Scene);	// dojox.gfx3d.Scene
 	},
diff --git a/dojox/gfx3d/scheduler.js b/dojox/gfx3d/scheduler.js
index 518d3b2..2b47ca1 100644
--- a/dojox/gfx3d/scheduler.js
+++ b/dojox/gfx3d/scheduler.js
@@ -33,16 +33,16 @@ dojo.mixin(dojox.gfx3d.scheduler, {
 dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 	constructor: function(obj, outline){
 		// summary: build the binary search tree, using binary space partition algorithm.
-		// The idea is for any polygon, for example, (a, b, c), the space is divided by 
-		// the plane into two space: plus and minus. 
-		// 
+		// The idea is for any polygon, for example, (a, b, c), the space is divided by
+		// the plane into two space: plus and minus.
+		//
 		// for any arbitary vertex p, if(p - a) dotProduct n = 0, p is inside the plane,
-		// > 0, p is in the plus space, vice versa for minus space. 
+		// > 0, p is in the plus space, vice versa for minus space.
 		// n is the normal vector that is perpendicular the plate, defined as:
 		//            n = ( b - a) crossProduct ( c - a )
 		//
 		// in this implementation, n is declared as normal, ,a is declared as orient.
-		// 
+		//
 		// obj: object: dojox.gfx3d.Object
 		this.plus = null;
 		this.minus = null;
@@ -72,8 +72,8 @@ dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 				this.minus = new BST(obj, outline);
 			}
 		}else if(
-			dojo.every(o, function(item){ 
-				return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0; 
+			dojo.every(o, function(item){
+				return Math.floor(epsilon + v.dotProduct(n, v.substract(item, a))) >= 0;
 			})
 		){
 			if(this.plus){
@@ -104,13 +104,13 @@ dojo.declare("dojox.gfx3d.scheduler.BinarySearchTree", null, {
 			subs = [this.minus, this.plus];
 		}
 
-		if(subs[0]){ 
+		if(subs[0]){
 			sorted = sorted.concat(subs[0].iterate());
 		}
 
 		sorted.push(this.object);
 
-		if(subs[1]){ 
+		if(subs[1]){
 			sorted = sorted.concat(subs[1].iterate());
 		}
 		return sorted;
@@ -137,6 +137,6 @@ dojo.mixin(dojox.gfx3d.drawer, {
 			item.draw(viewport.lighting);
 		});
 	}
-	// More aggrasive optimization may re-order the DOM nodes using the order 
+	// More aggrasive optimization may re-order the DOM nodes using the order
 	// of objects, and only elements of todos call setShape.
 });
diff --git a/dojox/gfx3d/vector.js b/dojox/gfx3d/vector.js
index f2cbcf6..db62210 100644
--- a/dojox/gfx3d/vector.js
+++ b/dojox/gfx3d/vector.js
@@ -13,7 +13,7 @@ dojo.mixin(dojox.gfx3d.vector, {
 		var l = arguments.length;
 		if(l == 0){
 			return {x: 0, y: 0, z: 0};
-		} 
+		}
 		var v = dojox.gfx3d.vector.sum(arguments);
 		return {x: v.x/l, y: v.y/l, z: v.z/l};
 	},
@@ -92,7 +92,7 @@ dojo.mixin(dojox.gfx3d.vector, {
 		// a: Object: a point
 		// b: Object: a point
 		// c: Object: a point
-		var l, m, n; 
+		var l, m, n;
 		if(a instanceof Array){
 			l = a[0]; m = a[1]; n = a[2];
 		}else{
diff --git a/dojox/grid/DataGrid.js b/dojox/grid/DataGrid.js
index 17aeb90..9746080 100644
--- a/dojox/grid/DataGrid.js
+++ b/dojox/grid/DataGrid.js
@@ -170,7 +170,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 
 		if(idx >= 0){
 			// When a row is deleted, all rest rows are shifted down,
-			// and migrate from page to page. If some page is not 
+			// and migrate from page to page. If some page is not
 			// loaded yet empty rows can migrate to initialized pages
 			// without refreshing. It causes empty rows in some pages, see:
 			// http://bugs.dojotoolkit.org/ticket/6818
@@ -212,14 +212,12 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	
 	_setQuery: function(query, queryOptions){
 		this.query = query;
-		this.queryOptions = queryOptions || this.queryOptions;		
+		this.queryOptions = queryOptions || this.queryOptions;
 	},
 
 	_setStore: function(store){
-		if(this.store&&this._store_connects){
-			dojo.forEach(this._store_connects,function(arr){
-				dojo.forEach(arr, dojo.disconnect);
-			});
+		if(this.store && this._store_connects){
+			dojo.forEach(this._store_connects, this.disconnect, this);
 		}
 		this.store = store;
 
@@ -274,13 +272,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 			dojo.forEach(items, function(item, idx){
 				this._addItem(item, req.start+idx, true);
 			}, this);
-			if(this._autoHeight){
-				this._skipRowRenormalize = true;
-			}
 			this.updateRows(req.start, items.length);
-			if(this._autoHeight){
-				this._skipRowRenormalize = false;
-			}			
 			if(req.isRender){
 				this.setScrollTop(0);
 				this.postrender();
@@ -484,6 +476,7 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 	},
 
 	sort: function(){
+		this.edit.apply();
 		this._lastScrollTop = this.scrollTop;
 		this._refresh();
 	},
@@ -598,11 +591,11 @@ dojo.declare("dojox.grid.DataGrid", dojox.grid._Grid, {
 				if(items.length){
 					dojo.forEach(items, this.store.deleteItem, this.store);
 					this.selection.clear();
-				}			
+				}
 			});
 			if(this.allItemsSelected){
 				this.store.fetch({
-							query: this.query, 
+							query: this.query,
 							queryOptions: this.queryOptions,
 							onComplete: fx});
 			}else{
@@ -628,6 +621,6 @@ 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, 
+	return dojox.grid._Grid.markupFactory(props, node, ctor,
 					dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
 };
diff --git a/dojox/grid/EnhancedGrid.js b/dojox/grid/EnhancedGrid.js
index b9f9dfd..86c6cba 100644
--- a/dojox/grid/EnhancedGrid.js
+++ b/dojox/grid/EnhancedGrid.js
@@ -1,28 +1,22 @@
 dojo.provide("dojox.grid.EnhancedGrid");
 
 dojo.require("dojox.grid.DataGrid");
-dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced._PluginManager");
 dojo.requireLocalization("dojox.grid.enhanced", "EnhancedGrid");
 
 dojo.experimental("dojox.grid.EnhancedGrid");
 
 dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
-	//	summary:
-	//		Provides enhanced features for DataGrid, including:
-	//		1. Nested Sorting
-	//		2. Built-in support for Indirect Selection (radio buttons and check boxes)
-	//		3. Declarative context menu
-	//		4. Selecting rows/columns via swipe
-	//		5. Drag-n-drop: columns,rows - MOVE
+	// summary:
+	//		Provides enhanced features based on DataGrid
 	//
-	//	description:
+	// description:
 	//		EnhancedGrid features are implemented as plugins that could be loaded on demand.
 	//		Explicit dojo.require() is needed to use these feature plugins.
 	//
-	//	
-	//  example:
-	//		A quick sample to use all EnhancedGrid features:
-	//      
+	// example:
+	//		A quick sample to use EnhancedGrid features:
+	//
 	//	   Step 1. Load EnhancedGrid and required features
 	// |   <script type="text/javascript">
 	// |		dojo.require("dojox.grid.EnhancedGrid");
@@ -35,107 +29,84 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 	//		Step 2. Use EnhancedGrid
 	//		- Via HTML markup
 	// |	<div dojoType="dojox.grid.EnhancedGrid" ...
-	// |		 plugins="{nestedSorting: true, dnd: true, indirectSelection: true, 
-	// |		 menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",  
-    // |         selectedRegionMenu:"selectedRegionMenuId"}}">
+	// |		plugins="{nestedSorting: true, dnd: true, indirectSelection: true,
+	// |		menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
+	// |		selectedRegionMenu:"selectedRegionMenuId"}}">
 	// |			...
 	// |	</div>
 	//
 	//		- Or via JavaScript
 	// |	<script type="text/javascript">
-	// |		var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true, 
+	// |		var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true, dnd: true, indirectSelection: true,
 	// |	               menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",selectedRegionMenu:"selectedRegionMenuId"}},
 	// |			       ... }, dojo.byId('gridDiv'));
 	// |		grid.startup();
 	// |	</script>
+	//
+	//
+	//		Plugin Support
+	//		[Note: Plugin support is still experimental]
+	//
+	//		You can either customize the default plugins or add new ones, more details please see
+	//		- dojox.grid.enhanced._PluginManager
+	//		- dojox.grid.enhanced._Plugin
+	//		- dojox.grid.enhanced.plugins.*
 
 	//plugins: Object
 	//		Plugin properties, e.g. {nestedSorting: true, dnd: true, ...}
 	plugins: null,
 
 	//pluginMgr: Object
-	//		Singleton plugin manager	
+	//		Singleton plugin manager
 	pluginMgr: null,
-	
-	//doubleAffordance: Boolean
-	//		For special cell hover style
-	doubleAffordance: false,
-	
-	//minRowHeight: Integer
-	//		Minimal row height	
-	minRowHeight: 10,	
 
-	//keepSortSelection: Boolean
-	//		Whether keep selection after sort - only applicable when client-side data store is used.	
-	keepSortSelection: false,
-	
-	//rowSelectionChangedTopic: String
-	//		Topic fired when row selection is changed 
-	rowSelectionChangedTopic: 'ROW_SELECTION_CHANGED',
+	//keepSelection: Boolean
+	//		Whether keep selection after sort, filter, pagination etc.
+	keepSelection: false,
 	
-	//sortRowSelectionChangedTopic: String
-	//		Topic only fired when row selection is changed by sorting.
-	sortRowSelectionChangedTopic: 'SORT_ROW_SELECTION_CHANGED',
-	
-	//rowMovedTopic: String
-	//		Topic fired when selected rows are moved.
-	rowMovedTopic: 'ROW_MOVED',		
+	//_pluginMgrClass: Object
+	//		Default plugin manager class
+	_pluginMgrClass: dojox.grid.enhanced._PluginManager,
 
 	postMixInProperties: function(){
 		//load nls bundle
 		this._nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "EnhancedGrid", this.lang);
 		this.inherited(arguments);
 	},
-
 	postCreate: function(){
 		//create plugin manager
-		this.pluginMgr = new dojox.grid.enhanced._Plugin(this);
+		this.pluginMgr = new this._pluginMgrClass(this);
 		this.pluginMgr.preInit();
 		this.inherited(arguments);
 		this.pluginMgr.postInit();
 	},
-	
-	_fillContent: function(){
-		//cached for menu use(menu declared within Grid HTML markup)
-		this.menuContainer = this.srcNodeRef;
-		this.inherited(arguments);
+	plugin: function(/*String*/name){
+		// summary:
+		//		An easier way for getting a plugin, e.g. grid.plugin('dnd')
+		return this.pluginMgr.getPlugin(name);
 	},
-	
 	startup: function(){
-		this.menuContainer && this._initMenus && this._initMenus();
 		this.inherited(arguments);
-		if(this.doubleAffordance){
-			dojo.addClass(this.domNode, 'dojoxGridDoubleAffordance');
-		}
+		this.pluginMgr.startup();
 	},
-	
-	textSizeChanged: function(){
+	createSelection: function(){
+		this.selection = new dojox.grid.enhanced.DataSelection(this);
+	},
+	canSort: function(colIndex, field){
 		// summary:
-		//		Overwritten, see _Grid.textSizeChanged()	
-		//      fix #10088 - in Webkit, this method is invoked by two parallel threads which caused #10088
-		if(!dojo.isWebKit){
-			this.inherited(arguments);
-		}else{
-			if(this.textSizeChanging){ return; }
-			this.textSizeChanging = true;
-			this.inherited(arguments);
-			this.textSizeChanging = false;
-		}
+		//		Overwritten
+		return true;
 	},
-	
-	removeSelectedRows: function(){
+	doKeyEvent: function(e){
 		// summary:
-		//		Overwritten, see DataGrid.removeSelectedRows()
-		if(this.indirectSelection && this._canEdit){
-			//cache the selected info before cleaned by DataGrid
-			var selected = dojo.clone(this.selection.selected);
-			this.inherited(arguments);
-			dojo.forEach(selected, function(value, index){
-				value && this.grid.rowSelectCell.toggleRow(index, false);
-			});
-		}
+		//		Overwritten, see _Grid.doKeyEvent()
+		try{
+			var view = this.focus.focusView;
+			view.content.decorateEvent(e);
+			if(!e.cell){ view.header.decorateEvent(e); }
+		}catch(e){}
+		this.inherited(arguments);
 	},
-	
 	doApplyCellEdit: function(inValue, inRowIndex, inAttrName){
 		// summary:
 		//		Overwritten, see DataGrid.doApplyCellEdit()
@@ -144,28 +115,142 @@ dojo.declare("dojox.grid.EnhancedGrid", dojox.grid.DataGrid, {
 			return;
 		}
 		this.inherited(arguments);
-	},	
-	
+	},
 	mixin: function(target, source){
 		var props = {};
-		for(p in source){
-			if(p == '_inherited' || p == 'declaredClass' || p == 'constructor'){ continue; }
+		for(var p in source){
+			if(p == '_inherited' || p == 'declaredClass' || p == 'constructor' ||
+				source['privates'] && source['privates'][p]){
+				continue;
+			}
 			props[p] = source[p];
 		}
 		dojo.mixin(target, props);
 	},
-	
 	_copyAttr: function(idx, attr){
 		// summary:
 		//		Overwritten, see DataGrid._copyAttr()
-		//		Fix cell TAB navigation for single click editting
-		if(!attr) return;
+		//		Fix cell TAB navigation for single click editing
+		if(!attr){ return; }
 		return this.inherited(arguments);
+	},
+	_getHeaderHeight: function(){
+		// summary:
+		//		Overwritten, see _Grid._getHeaderHeight()
+		//		Should include borders/margins of this.viewsHeaderNode
+		this.inherited(arguments);
+		return dojo.marginBox(this.viewsHeaderNode).h;
+	},
+	_fetch: function(start, isRender){
+		// summary:
+		//		Overwritten, see DataGrid._fetch()
+		if(this.items){
+			return this.inherited(arguments);
+		}
+		start = start || 0;
+		if(this.store && !this._pending_requests[start]){
+			if(!this._isLoaded && !this._isLoading){
+				this._isLoading = true;
+				this.showMessage(this.loadingMessage);
+			}
+			this._pending_requests[start] = true;
+			try{
+				var req = {
+					start: start,
+					count: this.rowsPerPage,
+					query: this.query,
+					sort: this.getSortProps(),
+					queryOptions: this.queryOptions,
+					isRender: isRender,
+					onBegin: dojo.hitch(this, "_onFetchBegin"),
+					onComplete: dojo.hitch(this, "_onFetchComplete"),
+					onError: dojo.hitch(this, "_onFetchError")
+				};
+				this._storeLayerFetch(req);
+			}catch(e){
+				this._onFetchError(e, {start: start, count: this.rowsPerPage});
+			}
+		}
+		return 0;
+	},
+	_storeLayerFetch: function(req){
+		// summary:
+		//		Extracted fetch specifically for store layer use
+		this.store.fetch(req);
+	},
+	getCellByField: function(field){
+		return dojo.filter(this.layout.cells, function(cell){
+			return cell.field == field;
+		})[0];
+	},
+	onMouseUp: function(e){	},
+	createView: function(){
+		// summary
+		//		Overwrite: rewrite getCellX of view.header
+		var view = this.inherited(arguments);
+		if(dojo.isMoz){
+			var ascendDom = function(inNode, inWhile){
+				for(var n = inNode; n && inWhile(n); n = n.parentNode){}
+				return n;
+			};//copied from dojox.grid._Builder
+			var makeNotTagName = function(inTagName){
+				var name = inTagName.toUpperCase();
+				return function(node){ return node.tagName != name; };
+			};//copied from dojox.grid._Builder
+
+			var func = view.header.getCellX;
+			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; }
+				return x;
+			};
+		}
+		return view;
+	},
+	destroy: function(){
+		// 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, {
+	constructor: function(grid){
+		if(grid.keepSelection){
+			this.preserver = new dojox.grid.enhanced.plugins._SelectionPreserver(this);
+		}
+	},
+	_range: function(inFrom, inTo){
+		this.grid._selectingRange = true;
+		this.inherited(arguments);
+		this.grid._selectingRange = false;
+		this.onChanged();
+	},
+	deselectAll: function(inItemOrIndex){
+		this.grid._selectingRange = true;
+		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){
-	return dojox.grid._Grid.markupFactory(props, node, ctor, 
+	return dojox.grid._Grid.markupFactory(props, node, ctor,
 					dojo.partial(dojox.grid.DataGrid.cell_markupFactory, cellFunc));
 };
+
+dojox.grid.EnhancedGrid.registerPlugin = function(clazz, props){
+	dojox.grid.enhanced._PluginManager.registerPlugin(clazz, props);
+};
\ No newline at end of file
diff --git a/dojox/grid/LazyTreeGrid.js b/dojox/grid/LazyTreeGrid.js
new file mode 100644
index 0000000..666cf1d
--- /dev/null
+++ b/dojox/grid/LazyTreeGrid.js
@@ -0,0 +1,833 @@
+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,
+	view: null,
+	rowIdx: -1,
+	expandoCell: null,
+	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){}
+	},
+	
+	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});
+			g.expandoFetch(this.rowIdx, open);
+			this.open = open;
+		}
+		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);
+			this.expandoInner.innerHTML = state ? "-" : "+";
+			dojo.toggleClass(this.domNode, "dojoxGridExpandoOpened", state);
+			dijit.setWaiState(this.domNode.parentNode, "expanded", state);
+		}
+	},
+	
+	setRowNode: function(rowIdx, rowNode, view){
+		if(this.cellIdx < 0 || !this.itemId){ return false; }
+		this._initialized = false;
+		this.view = view;
+		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));
+		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 html = this.getTableArray(),
+			grid = this.grid,
+			v = this.view,
+			cells = v.structure.cells,
+			item = grid.getItem(inRowIndex),
+			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++){
+			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 = [];
+			if(mergedCells){
+				dojo.forEach(mergedCells, function(c){
+					for(var i = 0, cell;(cell = row[i]); i++){
+						if(i >= c.start && i <= c.end){
+							totalWidth += this._getCellWidth(row, i);
+						}
+					}
+					totalWidthes.push(totalWidth);
+					totalWidth = 0;
+				}, this);
+			}
+			for(var i = 0, cell, m, cc, cs; (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;
+					if(i == primaryIdx){
+						m[5] = cell.formatAtLevel(rowStack, item, level, false, toggleClasses[0], cc, inRowIndex);
+						// classes
+						m[1] = cc.join(' ');
+						// styles
+						var pbm = dojo.marginBox(cell.getHeaderNode()).w - dojo.contentBox(cell.getHeaderNode()).w;
+						cs = cell.customStyles = ['width:' + (totalWidthes[k] - pbm) + "px"];
+						m[3] = cs.join(';');
+						html.push.apply(html, m);
+					}else if(i == mergedCells[k].end){
+						k++;
+						continue;
+					}else{
+						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[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;
+		}
+	},
+	
+	_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){
+			return cell.hidden;
+		})){
+			var headerNodePos = dojo.position(cells[colIndex].view.headerContentNode.firstChild);
+			return headerNodePos.x + headerNodePos.w - dojo.position(node).x;
+		}else{
+			var nextNode = cells[colIndex + 1].getHeaderNode();
+			return dojo.position(nextNode).x - dojo.position(node).x;
+		}
+	}
+});
+
+dojo.declare("dojox.grid._TreeGridView", [dojox.grid._View], {
+	
+	_contentBuilderClass: dojox.grid._TreeGridContentBuilder,
+	
+	postCreate: function(){
+		this.inherited(arguments);
+		this._expandos = {};
+		this.connect(this.grid, '_cleanupExpandoCache', '_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]){
+				this._expandos[i].destroy();
+			}
+		}
+		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){
+			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;
+					expando = this._expandos[idty];
+				}
+				if(expando){
+					dojo.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){
+						this._expandos[idty] = expando;
+					}
+				}
+				if(!expando.setRowNode(inRowIndex, inRowNode, this)){
+					expando.domNode.parentNode.removeChild(expando.domNode);
+				}
+			}
+		}, this);
+		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>';
+		}
+		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);
+		}
+		return result;
+	},
+	
+	formatIndexes: function(inRowIndex, inRowIndexes, inItem, 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);
+		}else{
+			return this._defaultFormat(d, [d, inRowIndex, level, this]);
+		}
+	}
+});
+
+dojo.declare("dojox.grid._LazyTreeLayout", dojox.grid._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);
+		})){
+			s = arguments[0] = [{cells:[s]}];//intentionally change arguments[0]
+		}
+		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){
+		var obj = this.inherited(arguments);
+		return dojo.mixin(obj, dojox.grid.cells.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
+		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]);
+			}
+		}
+		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);
+		}
+	},
+	
+	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);
+			}
+		}
+	},
+	
+	emptyCache: function(){
+		this.unInit = true;
+		this._buildCache(this.rowsPerPage);
+	},
+	
+	cleanupCache: function(){
+		this.items = null;
+	}
+	
+});
+
+dojo.declare("dojox.grid.LazyTreeGrid", dojox.grid.TreeGrid, {
+	// summary:
+	//		An enhanced TreeGrid widget which supports lazy-loading nested-level 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
+	//
+	//		Most methods and properties pertaining to the dojox.grid.DataGrid
+	//		and dojox.grid.TreeGrid also apply here
+	//
+	//		LazyTreeGrid does not support summary row/items aggregate for the
+	//		lazy-loading reason.
+	
+	treeModel: null,
+	
+	_layoutClass: dojox.grid._LazyTreeLayout,
+	
+	// colSpans: Object
+	//		a json object that defines column span of each level rows
+	//		attributes:
+	//			0/1/..: which level need to colspan
+	//			start: start column index of colspan
+	//			end: end column index of colspan
+	//			primary: index of column which content will be displayed (default is value of start).
+	//		example:
+	//		|	colSpans = {
+	//		|	0:	[
+	//		|			{start: 0, end: 1, primary: 0},
+	//		|			{start: 2, end: 4, primary: 3}
+	//		|		],
+	//		|	1:	[
+	//		|			{start: 0, end: 3, primary: 1}
+	//		|		]
+	//		|	};
+	colSpans: null,
+	
+	postCreate: function(){
+		this.inherited(arguments);
+		this.cache = new dojox.grid.TreeGridItemCache(this);
+		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");
+		}
+		dojo.addClass(this.domNode, "dojoxGridTreeModel");
+		dojo.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);
+	},
+
+	createSelection: function(){
+		this.selection = new dojox.grid.DataSelection(this);
+	},
+	
+	setModel: function(treeModel){
+		if(!treeModel){
+			return;
+		}
+		this._setModel(treeModel);
+		this._refresh(true);
+	},
+	
+	setStore: function(store, query, queryOptions){
+		if(!store){
+			return;
+		}
+		this._setQuery(query, queryOptions);
+		this.treeModel.query = query;
+		this.treeModel.store = store;
+		this.treeModel.root.children = [];
+		this.setModel(this.treeModel);
+	},
+	
+	_setQuery: function(query, queryOptions){
+		this.inherited(arguments);
+		this.treeModel.query = query;
+	},
+	
+	destroy: function(){
+		this._cleanup();
+		this.inherited(arguments);
+	},
+	
+	_cleanup: function(){
+		this.cache.emptyCache();
+		this._cleanupExpandoCache();
+	},
+	
+	setSortIndex: function(inIndex, inAsc){
+		// Need to clean up the cache before sorting
+		if(this.canSort(inIndex + 1)){
+			this._cleanup();
+		}
+		this.inherited(arguments);
+	},
+	
+	_refresh: function(isRender){
+		this._cleanup();
+		this.inherited(arguments);
+	},
+	
+	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){
+			return c === parentInfo.attribute;
+		})){
+			isAddingChild = true;
+			info = this.cache.getInfoByItem(parentInfo.item);
+		}
+		if(!isAddingChild){
+			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);
+		}
+	},
+	
+	_onDelete: function(item){
+		this._pages = [];
+		this._bop = -1;
+		this._eop = -1;
+		this._refresh();
+	},
+	
+	_cleanupExpandoCache: function(index, identity, item){},
+	
+	_fetch: function(start, isRender){
+		// summary:
+		//		Function for fetch data when initializing TreeGrid and
+		//		scroll the TreeGrid
+		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));
+			}else{
+				break;
+			}
+		}
+		if(fetchedItems.length === count){// || !this.cache.getTreePathByRowIndex(start + fetchedItems.length)){
+			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);
+				}else{
+					count++;
+				}
+			}
+			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"));
+			}
+		}
+	},
+	
+	_fetchItems: function(idx, onBegin, onComplete, onError){
+		if(!this._loading){
+			this._loading = true;
+			this.showMessage(this.loadingMessage);
+		}
+		var level = this.reqQueue[idx].startTreePath.split("/").length - 1;
+		this._pending_requests[this.reqQueue[idx].startRowIdx] = true;
+		if(level === 0){
+			this.store.fetch({
+				start: parseInt(this.reqQueue[idx].startTreePath, 10),
+				startRowIdx: this.reqQueue[idx].startRowIdx,
+				count: this.reqQueue[idx].count,
+				query: this.query,
+				sort: this.getSortProps(),
+				queryOptions: this.queryOptions,
+				onBegin: onBegin,
+				onComplete: onComplete,
+				onError: onError
+			});
+		}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,
+				parentId: parentId,
+				sort: this.getSortProps()
+			};
+			this.treeModel.getChildren(parentItem, onComplete, onError, this.queryObj);
+		}
+	},
+	
+	_onFetchBegin: function(size, request){
+		this.cache.initCache(size);
+		size = this.cache.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
+					});
+				}
+			}
+		}
+		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._loading){
+			this._loading = false;
+			if(!this.cache.items.length){
+				this.showMessage(this.noDataMessage);
+			}else{
+				this.showMessage();
+			}
+		}
+		
+	},
+	
+	expandoFetch: function(rowIndex, open){
+		// summary:
+		//		Function for fetch children of a given row
+		if(this._loading){return;}
+		this._loading = true;
+		this.toggleLoadingClass(true);
+		var item = this.cache.getItemByRowIndex(rowIndex);
+		this.expandoRowIndex = rowIndex;
+		this._pages = [];
+		if(open){
+			var parentId = this.store.getIdentity(item);
+			var queryObj = {
+				start: 0,
+				count: this.keepRows,
+				parentId: parentId,
+				sort: this.getSortProps()
+			};
+			this.treeModel.getChildren(item, dojo.hitch(this, "_onExpandoComplete"), dojo.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);
+			}
+			this.toggleLoadingClass(false);
+		}
+	},
+	
+	_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});
+		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);
+		}
+		
+		this.toggleLoadingClass(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);
+		}
+	},
+	
+	styleRowNode: function(inRowIndex, inRowNode){
+		if(inRowNode){
+			this.rows.styleRowNode(inRowIndex, inRowNode);
+		}
+	},
+	
+	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);
+	},
+	
+	dokeydown: 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){
+			expando.onToggle();
+		}
+		this.onKeyDown(e);
+	}
+});
+
+dojox.grid.LazyTreeGrid.markupFactory = function(props, node, ctor, cellFunc){
+	return dojox.grid.TreeGrid.markupFactory(props, node, ctor, cellFunc);
+};
diff --git a/dojox/grid/LazyTreeGridStoreModel.js b/dojox/grid/LazyTreeGridStoreModel.js
new file mode 100644
index 0000000..aadccff
--- /dev/null
+++ b/dojox/grid/LazyTreeGridStoreModel.js
@@ -0,0 +1,105 @@
+dojo.provide("dojox.grid.LazyTreeGridStoreModel");
+
+dojo.require("dijit.tree.ForestStoreModel");
+
+dojo.declare("dojox.grid.LazyTreeGridStoreModel", dijit.tree.ForestStoreModel, {
+
+	// There are different approaches to get children for client-side
+	// DataStore (e.g. dojo.data.ItemFileReadStore) or server-side DataStore
+	// (e.g. dojox.data.QueryReadStore), so we need to be sure what kind of
+	// DataStore is being used
+	serverStore: false, // server side store
+	
+	constructor: function(/* Object */ args){
+		this.serverStore = args.serverStore === true ? true : false;
+	},
+
+	mayHaveChildren: function(/*dojo.data.Item*/ item){
+		var children = null;
+		return dojo.some(this.childrenAttrs, function(attr){
+				children = this.store.getValue(item, attr);
+				if(dojo.isString(children)){
+					return parseInt(children, 10) > 0 || children.toLowerCase() === "true" ? true : false;
+				}else if(typeof children == "number"){
+					return children > 0;
+				}else if(typeof children == "boolean"){
+					return children;
+				}else if(this.store.isItem(children)){
+					children = this.store.getValues(item, attr);
+					return dojo.isArray(children) ? children.length > 0 : false;
+				}else{
+					return false;
+				}
+		}, this);
+	},
+	
+	getChildren: function(/*dojo.data.Item*/parentItem, /*function(items, size)*/onComplete, /*function*/ onError, /*object*/queryObj){
+		if(queryObj){
+			var start = queryObj.start || 0,
+				count = queryObj.count,
+				parentId = queryObj.parentId,
+				sort = queryObj.sort;
+			if(parentItem === this.root){
+				this.root.size = 0;
+				this.store.fetch({
+					start: start,
+					count: count,
+					sort: sort,
+					query: this.query,
+					onBegin: dojo.hitch(this, function(size){
+						this.root.size = size;
+					}),
+					onComplete: dojo.hitch(this, function(items){
+						onComplete(items, queryObj, this.root.size);
+					}),
+					onError: onError
+				});
+			}else{
+				var store = this.store;
+				if(!store.isItemLoaded(parentItem)){
+					var getChildren = dojo.hitch(this, arguments.callee);
+					store.loadItem({
+						item: parentItem,
+						onItem: function(parentItem){
+							getChildren(parentItem, onComplete, onError, queryObj);
+						},
+						onError: onError
+					});
+					return;
+				}
+				if(this.serverStore && !this._isChildrenLoaded(parentItem)){
+					this.childrenSize = 0;
+					this.store.fetch({
+						start: start,
+						count: count,
+						sort: sort,
+						query: dojo.mixin({parentId: parentId}, this.query || {}),
+						onBegin: dojo.hitch(this, function(size){
+							this.childrenSize = size;
+						}),
+						onComplete: dojo.hitch(this, function(items){
+							onComplete(items, queryObj, this.childrenSize);
+						}),
+						onError: onError
+					});
+				}else{
+					this.inherited(arguments);
+				}
+			}
+		}else{
+			this.inherited(arguments);
+		}
+	},
+	
+	_isChildrenLoaded: function(parentItem){
+		// summary:
+		//		Check if all children of the given item have been loaded
+		var children = null;
+		return dojo.every(this.childrenAttrs, function(attr){
+			children = this.store.getValues(parentItem, attr);
+			return dojo.every(children, function(c){
+				return this.store.isItemLoaded(c);
+			}, this);
+		}, this);
+	}
+});
diff --git a/dojox/grid/README b/dojox/grid/README
index 7f34392..6d3dc3c 100644
--- a/dojox/grid/README
+++ b/dojox/grid/README
@@ -65,20 +65,28 @@ Project state
 alpha
 -------------------------------------------------------------------------------
 Credits
-	David Schwartz (drschwar at us.ibm.com)
-	Wei Huang (hwcdl at cn.ibm.com)
-	Guang Hong (hongg at cn.ibm.com)
+	David Schwartz (drschwar at us.ibm.com, IBM, CCLA) - Author, UX design
+	Wei Huang (evan at dojotoolkit.org) - Author, IndirectSelection, Menus
+	Xiao Wen Zhu (xwzhu at cn.ibm.com, IBM, CCLA) 
+	  - Filter, Exporter, Printer, Selector, DnD, CellMerge, Cookie, Search
+	Qiang Wang (wangqsh at cn.ibm.com, IBM, CCLA) - Pagination
+	Pei Wang (wpei at cn.ibm.com, IBM, CCLA) - NestedSorting
 -------------------------------------------------------------------------------
 Project description
 
 Enhanced Grid inherits base DataGrid and provides the following enhanced features:
-
  1. Nested Sorting
  2. Built-in declarative Indirect Selection (radio buttons and check boxes)
- 3. Declarative context menu
- 4. Selecting rows/columns via swipe
- 5. Drag-n-drop: columns,rows - MOVE
-
+ 3. Context menu for header, row, column and selected region
+ 4. Advanced Selector: support selecting rows/columns/cells via swipe
+ 5. Drag-n-drop: columns,rows - MOVE, cells - MOVE/COPY
+ 6. Filter: filter grid content in various data types
+ 7. Exporter: export grid content to various formats
+ 8. Printer: provide convenient ways for printing grid
+ 9. Pagination: an alternative to deal with huge data set besides the default virtual scrolling way
+ 10.CellMerge: merge adjacent cells within a row
+ 11.Cookie: persist grid preferences including column width, column order, sorting order etc.
+ 12.Search: a handy way for searching grid content by regular expressions
 -------------------------------------------------------------------------------
 Dependencies
 
@@ -90,16 +98,51 @@ http://docs.dojocampus.org/dojox/grid/EnhancedGrid
 -------------------------------------------------------------------------------
 Installation instructions
 
-Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/enhanced/test_enhanced_grid.html
+Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/enhanced/*.html
 -------------------------------------------------------------------------------
 Known issues
 
- - Enhanced Grid doesn't support complicated layouts (e.g. multiple rows in column header) and TreeGrid(SubGrid).
- - Indirect Selection is not compatible with "autoHeight" mode due to a known issue in DataGrid(http://trac.dojotoolkit.org/ticket/11101)
+ - 'Claro' is the major supported theme for EnhancedGrid features
+ - EnhancedGrid features are not fully compatible with complicated layouts (e.g. multiple rows in column header) and TreeGrid(SubGrid).
+ - Indirect Selection is not fully compatible with Advanced Selector(for selecting row/column/cells) and DnD
+ - RTL support is still in progress for Nested Sorting 
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+2. dojox.grid.LazyTreeGrid
+-------------------------------------------------------------------------------
+Version 0.9
+Release date: 
+-------------------------------------------------------------------------------
+Project state
+
+alpha
+-------------------------------------------------------------------------------
+Credits
+	Qiang Wang (wangqsh at cn.ibm.com, IBM, CCLA)
+	Wei Huang (evan at dojotoolkit.org)
+-------------------------------------------------------------------------------
+Project description
+
+LazyTreeGrid 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
 -------------------------------------------------------------------------------
-Possible future changes
+Dependencies
+
+Dojo Core, dojox.grid.TreeGrid
+-------------------------------------------------------------------------------
+Documentation
+
+http://docs.dojocampus.org/dojox/grid/LazyTreeGrid
+-------------------------------------------------------------------------------
+Installation instructions
+
+Same as dojox.grid, for detail sample usages, please refer to /dojox/grid/tests/test_treegrid_lazyloading.html
+-------------------------------------------------------------------------------
+Known issues
 
- 1. A rich set of new features to be added, e.g. Exporter, Printer, Filter, Pagination ...
- 2. An activity of setting up a plug-in platform is in progress for future Grid versions, 
-   by then all the EnhancedGrid features will be re-cast as separate plug-ins loaded on demand.
+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/TreeGrid.js b/dojox/grid/TreeGrid.js
index 7dc14fb..a435107 100644
--- a/dojox/grid/TreeGrid.js
+++ b/dojox/grid/TreeGrid.js
@@ -103,7 +103,7 @@ dojo.declare("dojox.grid._TreeAggregator", null, {
 		}
 
 		// See if they have specified a valid field
-		var field = ((cell.parentCell && cell.parentCell.itemAggregates) ? 
+		var field = ((cell.parentCell && cell.parentCell.itemAggregates) ?
 							cell.parentCell.itemAggregates[cell.idxInParent] : "")||"";
 		if(field && store.hasAttribute(item, field)){
 			return this._cacheValue(typeCache, level, store.getValue(item, field));
@@ -165,7 +165,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 dojox.grid._TreeAggregator({cells: tree.cells[0],
 														grid: g,
 														childFields: cFields});
 		if(g.scroller && g.defaultOpen){
@@ -183,7 +183,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 		if(g && g.treeModel && !dojo.every(s, function(i){
 			return ("cells" in i);
 		})){
-			s = arguments[0] = [{cells:[s]}];			
+			s = arguments[0] = [{cells:[s]}];
 		}
 		if(s.length == 1 && s[0].cells.length == 1){
 			if(g && g.treeModel){
@@ -196,7 +196,7 @@ dojo.declare("dojox.grid._TreeLayout", dojox.grid._Layout, {
 				});
 				if(childCells.length === 1){
 					this._isCollapsable = true;
-				}			
+				}
 			}
 		}
 		if(this._isCollapsable && (!g || !g.treeModel)){
@@ -524,7 +524,7 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 	//		the values of subrows
 	//
 	// description:
-	//		TreeGrid currently only works on "simple" structures.  That is, 
+	//		TreeGrid currently only works on "simple" structures.  That is,
 	//		single-view structures with a single row in them.
 	//
 	//		The TreeGrid works using the concept of "levels" - level 0 are the
@@ -643,18 +643,30 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 		}
 		var s = this.store;
 		var itm = dojox.grid.DataGrid.prototype.getItem.call(this, idx[0]);
-		var cf;
+		var cf, i, j;
 		if(this.aggregator){
 			cf = this.aggregator.childFields||[];
+			if(cf){
+				for(i = 0; i < idx.length - 1 && itm; i++){
+					if(cf[i]){
+						itm = (s.getValues(itm, cf[i])||[])[idx[i + 1]];
+					}else{
+						itm = null;
+					}
+				}
+			}
 		}else if(this.treeModel){
 			cf = this.treeModel.childrenAttrs||[];
-		}
-		if(cf){
-			for(var i = 0; i < idx.length - 1 && itm; i++){
-				if(cf[i]){
-					itm = (s.getValues(itm, cf[i])||[])[idx[i + 1]];
-				}else{
-					itm = null;
+			if(cf&&itm){
+				for(i=1, il=idx.length; (i<il) && itm; i++) {
+					for(j=0, jl=cf.length; j<jl; j++) {
+						if(cf[j]){
+							itm = (s.getValues(itm, cf[j])||[])[idx[i]];
+						}else{
+							itm = null;
+						}
+						if(itm){ break; }
+					}
 				}
 			}
 		}
@@ -718,7 +730,7 @@ dojo.declare("dojox.grid.TreeGrid", dojox.grid.DataGrid, {
 	
 	_setModel: function(treeModel){
 		if(treeModel && (!dijit.tree.ForestStoreModel || !(treeModel instanceof dijit.tree.ForestStoreModel))){
-			throw new Error("dojox.grid.TreeGrid: treeModel must be an instance of dijit.tree.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);
@@ -880,7 +892,7 @@ dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 					type: d.trim(d.attr(th, "cellType")||""),
 					field: d.trim(d.attr(th, "field")||"")
 				};
-				if(cell.type){ 
+				if(cell.type){
 					cell.type = d.getObject(cell.type);
 				}
 				
@@ -890,8 +902,8 @@ dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 					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); 
+						cell.itemAggregates = d.map(d.attr(th, "itemAggregates").split(","), function(v){
+							return d.trim(v);
 						});
 					}else{
 						cell.itemAggregates = [];
@@ -901,7 +913,7 @@ dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 					}
 					cell.type = cell.type || dojox.grid.cells.SubtableCell;
 				}else{
-					// Grab our other stuff we need (mostly what's in the normal 
+					// 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")){
@@ -919,7 +931,7 @@ dojox.grid.TreeGrid.markupFactory = function(props, node, ctor, cellFunc){
 				}
 				if(cell.type && cell.type.markupFactory){
 					cell.type.markupFactory(th, cell);
-				}			
+				}
 				return cell;
 			});
 		}
diff --git a/dojox/grid/_Builder.js b/dojox/grid/_Builder.js
index 499dc17..fb7b29f 100644
--- a/dojox/grid/_Builder.js
+++ b/dojox/grid/_Builder.js
@@ -89,7 +89,7 @@ dojo.require("dojo.dnd.Moveable");
 			}
 			// result[0] => td opener, style
 			result.push(html.join(''));
-			// SLOT: result[1] => td classes 
+			// SLOT: result[1] => td classes
 			result.push('');
 			html = ['" idx="', inCell.index, '" style="'];
 			if(inMoreStyles && inMoreStyles[inMoreStyles.length-1] != ';'){
@@ -101,7 +101,7 @@ dojo.require("dojo.dnd.Moveable");
 			}
 			// result[2] => markup
 			result.push(html.join(''));
-			// SLOT: result[3] => td style 
+			// SLOT: result[3] => td style
 			result.push('');
 			html = [ '"' ];
 			if(inCell.attrs){
@@ -127,8 +127,8 @@ dojo.require("dojo.dnd.Moveable");
 		},
 		
 		getCellNode: function(inRowNode, inCellIndex){
-			for(var i=0, row; (row=getTr(inRowNode.firstChild, i)); i++){
-				for(var j=0, cell; (cell=row.cells[j]); j++){
+			for(var i=0, row; ((row = getTr(inRowNode.firstChild, i)) && row.cells); i++){
+				for(var j=0, cell; (cell = row.cells[j]); j++){
 					if(this.getCellNodeIndex(cell) == inCellIndex){
 						return cell;
 					}
@@ -161,7 +161,7 @@ dojo.require("dojo.dnd.Moveable");
 			while(n && (n!=this.domNode) && (!(inTag in n) || (gridViewTag in n && n[gridViewTag] != this.view.id))){
 				n = n.parentNode;
 			}
-			return (n != this.domNode) ? n : null; 
+			return (n != this.domNode) ? n : null;
 		},
 
 		findRowTarget: function(inSource){
@@ -180,7 +180,7 @@ dojo.require("dojo.dnd.Moveable");
 		isIntraRowEvent: function(e){
 			try{
 				var row = e.relatedTarget && this.findRowTarget(e.relatedTarget);
-				return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);			
+				return !row && (e.rowIndex==-1) || row && (e.rowIndex==row.gridRowIndex);
 			}catch(x){
 				// e.relatedTarget on INPUT has permission problem in FF: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
 				return false;
@@ -220,7 +220,7 @@ dojo.require("dojo.dnd.Moveable");
 		}
 	});
 
-	// Produces html for grid data content. Owned by grid and used internally 
+	// 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);
@@ -284,7 +284,7 @@ dojo.require("dojo.dnd.Moveable");
 		}
 	});
 
-	// Produces html for grid header content. Owned by grid and used internally 
+	// 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){
 		this.moveable = null;
@@ -350,7 +350,7 @@ dojo.require("dojo.dnd.Moveable");
 		// event helpers
 		getCellX: function(e){
 			var n, x = e.layerX;
-			if(dojo.isMoz){
+			if(dojo.isMoz || dojo.isIE >= 9){
 				n = ascendDom(e.target, makeNotTagName("th"));
 				x -= (n && n.offsetLeft) || 0;
 				var t = e.sourceView.getScrollbarWidth();
@@ -397,7 +397,7 @@ dojo.require("dojo.dnd.Moveable");
 			if(!e.cellNode || e.cellNode.colSpan > 1){
 				return false;
 			}
-			var cell = this.grid.getCell(e.cellIndex); 
+			var cell = this.grid.getCell(e.cellIndex);
 			return !cell.noresize && cell.canResize();
 		},
 
@@ -408,20 +408,20 @@ dojo.require("dojo.dnd.Moveable");
 			}
 			//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 
+			//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){
 				var tN = e.target;
-				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") || 
+				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
 					dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
 					return false;
 				}
 			}
 
 			if(dojo._isBodyLtr()){
-				return (e.cellIndex>0) && (e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
+				return (e.cellIndex>0) && (e.cellX > 0 && e.cellX < this.overResizeWidth) && this.prepareResize(e, -1);
 			}
-			var t = e.cellNode && (e.cellX < this.overResizeWidth);
+			var t = e.cellNode && (e.cellX > 0 && e.cellX < this.overResizeWidth);
 			return t;
 		},
 
@@ -432,11 +432,11 @@ dojo.require("dojo.dnd.Moveable");
 			}
 			//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 
+			//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){
 				var tN = e.target;
-				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") || 
+				if(dojo.hasClass(tN, "dojoxGridArrowButtonNode") ||
 					dojo.hasClass(tN, "dojoxGridArrowButtonChar")){
 					return false;
 				}
@@ -496,17 +496,17 @@ dojo.require("dojo.dnd.Moveable");
 			// Also called from keyboard shift-arrow event when focus is on a header
 			var headContentBox = dojo.contentBox(e.sourceView.headerNode);
 			
-			if(isMouse){  //IE draws line even with no mouse down so separate from keyboard 
+			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);
 				//fix #11340
-				var l = e.clientX;
+				var l = e.pageX;
 				if(!dojo._isBodyLtr() && dojo.isIE < 8){
 					l -= dojox.html.metrics.getScrollbar().w;
-				}				
+				}
 				dojo.style(this.lineDiv, {
 					top: vw.y + "px",
 					left: l + "px",
@@ -612,6 +612,7 @@ dojo.require("dojo.dnd.Moveable");
 				};
 				// Only resize the columns when the drag has finished
 				this.doResizeNow(inDrag, data);
+				delete this.dragRecord;
 			}
 			
 			dojo.destroy(this.lineDiv);
@@ -634,10 +635,12 @@ dojo.require("dojo.dnd.Moveable");
 			var i, s, sw, f, fl;
 			for(i=0; (s=inDrag.spanners[i]); i++){
 				sw = s.width + data.deltaX;
-				s.node.style.width = sw + 'px';
-				inDrag.view.setColWidth(s.index, sw);
+				if(sw > 0){
+					s.node.style.width = sw + 'px';
+					inDrag.view.setColWidth(s.index, sw);
+				}
 			}
-			if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339			
+			if(dojo._isBodyLtr() || !dojo.isIE){//fix #11339
 				for(i=0; (f=inDrag.followers[i]); i++){
 					fl = f.left + data.deltaX;
 					f.node.style.left = fl + 'px';
diff --git a/dojox/grid/_EditManager.js b/dojox/grid/_EditManager.js
index 850d0e8..7477c71 100644
--- a/dojox/grid/_EditManager.js
+++ b/dojox/grid/_EditManager.js
@@ -9,9 +9,10 @@ dojo.declare("dojox.grid._EditManager", null, {
 		// inGrid: dojox.Grid
 		//		The dojox.Grid this editor should be attached to
 		this.grid = inGrid;
-		this.connections = [];
 		if(dojo.isIE){
-			this.connections.push(dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus")));
+			this.connections = [dojo.connect(document.body, "onfocus", dojo.hitch(this, "_boomerangFocus"))];
+		}else{
+			this.connections = [dojo.connect(this.grid, 'onBlur', this, 'apply')];
 		}
 	},
 	
@@ -143,7 +144,7 @@ dojo.declare("dojox.grid._EditManager", null, {
 		}
 		if(inEditing){
 			this.info = { cell: inCell, rowIndex: inRowIndex };
-			this.grid.doStartEdit(inCell, inRowIndex); 
+			this.grid.doStartEdit(inCell, inRowIndex);
 			this.grid.updateRow(inRowIndex);
 		}else{
 			this.info = {};
diff --git a/dojox/grid/_Events.js b/dojox/grid/_Events.js
index 06d8bc4..77aeace 100644
--- a/dojox/grid/_Events.js
+++ b/dojox/grid/_Events.js
@@ -3,7 +3,7 @@ dojo.provide("dojox.grid._Events");
 dojo.declare("dojox.grid._Events", null, {
 	// summary:
 	//		_Grid mixin that provides default implementations for grid events.
-	// description: 
+	// description:
 	//		Default synthetic events dispatched for _Grid. dojo.connect to events to
 	//		retain default implementation or override them for custom handling.
 	
@@ -77,6 +77,7 @@ 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);
 				}
 				break;
 			case dk.SPACE:
diff --git a/dojox/grid/_FocusManager.js b/dojox/grid/_FocusManager.js
index 42db940..5048812 100644
--- a/dojox/grid/_FocusManager.js
+++ b/dojox/grid/_FocusManager.js
@@ -12,6 +12,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		this.cell = null;
 		this.rowIndex = -1;
 		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"));
@@ -23,6 +24,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	},
 	destroy: function(){
 		dojo.forEach(this._connects, dojo.disconnect);
+		dojo.forEach(this._headerConnects, dojo.disconnect);
 		delete this.grid;
 		delete this.cell;
 	},
@@ -33,7 +35,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	focusClass: "dojoxGridCellFocus",
 	focusView: null,
 	initFocusView: function(){
-		this.focusView = this.grid.views.getFirstScrollingView() || this.focusView;
+		this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
 		this._initColumnHeaders();
 	},
 	isFocusCell: function(inCell, inRowIndex){
@@ -66,7 +68,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		// summary:
 		//	states whether currently navigating among column headers.
 		// returns:
-		//	true if focus is on a column header; false otherwise. 
+		//	true if focus is on a column header; false otherwise.
 		return (!!this._colHeadNode);
 	},
 	getHeaderIndex: function(){
@@ -100,14 +102,14 @@ dojo.declare("dojox.grid._FocusManager", null, {
 				return;
 		}
 		var n = this.cell && this.cell.getNode(this.rowIndex);
-		if(n){ 
+		if(n){
 			try{
 				if(!this.grid.edit.isEditing()){
 					dojo.toggleClass(n, this.focusClass, true);
 					this.blurHeader();
 					dojox.grid.util.fire(n, "focus");
 				}
-			} 
+			}
 			catch(e){}
 		}
 	},
@@ -118,10 +120,12 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		}
 	},
 	_initColumnHeaders: function(){
+		dojo.forEach(this._headerConnects, dojo.disconnect);
+		this._headerConnects = [];
 		var headers = this._findHeaderCells();
 		for(var i = 0; i < headers.length; i++){
-			this._connects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
-			this._connects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
+			this._headerConnects.push(dojo.connect(headers[i], "onfocus", this, "doColHeaderFocus"));
+			this._headerConnects.push(dojo.connect(headers[i], "onblur", this, "doColHeaderBlur"));
 		}
 	},
 	_findHeaderCells: function(){
@@ -219,7 +223,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	_isHeaderHidden: function(){
 		// summary:
 		//		determine if the grid headers are hidden
-		//		relies on documented technique of setting .dojoxGridHeader { display:none; } 
+		//		relies on documented technique of setting .dojoxGridHeader { display:none; }
 		// returns: Boolean
 		//		true if headers are hidden
 		//		false if headers are not hidden
@@ -231,8 +235,8 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			for (var i = 0, cView; (cView = this.grid.views.views[i]); i++) {
 				if(cView.headerNode ){
 					curView=cView;
-					break;		
-				}	
+					break;
+				}
 			}
 		}
 		return (curView && dojo.getComputedStyle(curView.headerNode).display == "none");
@@ -245,20 +249,20 @@ dojo.declare("dojox.grid._FocusManager", null, {
 				// find first view with a tableMap in order to work with empty grid
 				if(cView.header.tableMap.map ){
 					view=cView;
-					break;		
+					break;
 				}
 			}
 		}
 		var curHeader = headers[colIdx];
 		if (!view || (colIdx == headers.length-1 && colIdx === 0)){
 			return; // can't adjust single col. grid
-		}	
+		}
 		view.content.baseDecorateEvent(e);
 		// need to adjust event with header cell info since focus is no longer on header cell
 		e.cellNode = curHeader; //this.findCellTarget(e.target, e.rowNode);
 		e.cellIndex = view.content.getCellNodeIndex(e.cellNode);
 		e.cell = (e.cellIndex >= 0 ? this.grid.getCell(e.cellIndex) : null);
-		if (view.header.canResize(e)){ 
+		if (view.header.canResize(e)){
 			var deltaObj = {
 				l: delta
 			};
@@ -321,7 +325,8 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			}
 			if(this.grid.edit.isEditing()){ //when editing, only navigate to editable cells
 				var nextCell = this.grid.getCell(col);
-				if (!this.isLastFocusCell() && !nextCell.editable){
+				if (!this.isLastFocusCell() && (!nextCell.editable ||
+					this.grid.canEdit && !this.grid.canEdit(nextCell, row))){
 					this.cell=nextCell;
 					this.rowIndex=row;
 					this.next();
@@ -410,6 +415,19 @@ dojo.declare("dojox.grid._FocusManager", null, {
 					// don't change col if would move to hidden
 					col = i;
 				}
+				//skip hidden row|cell
+				var n = cell.getNode(row);
+				if(!n && inRowDelta){
+					if((row + inRowDelta) >= 0 && (row + inRowDelta) <= rc){
+						this.move(inRowDelta > 0 ? ++inRowDelta : --inRowDelta, inColDelta);
+					}
+					return;
+				}else if((!n || dojo.style(n, "display") === "none") && inColDelta){
+					if((col + inRowDelta) >= 0 && (col + inRowDelta) <= cc){
+						this.move(inRowDelta, inColDelta > 0 ? ++inColDelta : --inColDelta);
+					}
+					return;
+				}
 				this.setFocusIndex(row, col);
 				if(inRowDelta){
 					this.grid.updateRow(r);
@@ -439,7 +457,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			this.focusHeader();
 			dojo.stopEvent(e);
 		}else if(this.isNavHeader()){
-			// if tabbing from col header, then go to grid proper. 
+			// if tabbing from col header, then go to grid proper.
 			this.blurHeader();
 			if(!this.findAndFocusGridCell()){
 				this.tabOut(this.grid.lastFocusNode);
@@ -465,7 +483,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	},
 	findAndFocusGridCell: function(){
 		// summary:
-		//		find the first focusable grid cell 
+		//		find the first focusable grid cell
 		// returns: Boolean
 		//		true if focus was set to a cell
 		//		false if no cell found to set focus onto
@@ -476,7 +494,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 			var cellIdx = 0;
 			var cell = this.grid.getCell(cellIdx);
 			if (cell.hidden) {
-				// if first cell isn't visible, use _colHeadFocusIdx 
+				// if first cell isn't visible, use _colHeadFocusIdx
 				// could also use a while loop to find first visible cell - not sure that is worth it
 				cellIdx = this.isNavHeader() ? this._colHeadFocusIdx : 0;
 			}
@@ -484,7 +502,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 		}
 		else if (this.cell && !isEmpty){
 			if (this.focusView && !this.focusView.rowNodes[this.rowIndex]){
-				// if rowNode for current index is undefined (likely as a result of a sort and because of #7304) 
+				// if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
 				// scroll to that row
 				this.grid.scrollToRow(this.rowIndex);
 			}
@@ -565,7 +583,7 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	doContextMenu: function(e){
 	//stop contextMenu event if no header Menu to prevent default/browser contextMenu
 		if (!this.headerMenu){
-			dojo.stopEvent(e); 
+			dojo.stopEvent(e);
 		}
 	},
 	doLastNodeFocus: function(e){
@@ -592,5 +610,5 @@ dojo.declare("dojox.grid._FocusManager", null, {
 	},
 	doColHeaderBlur: function(e){
 		dojo.toggleClass(e.target, this.focusClass, false);
-	}		
+	}
 });
diff --git a/dojox/grid/_Grid.js b/dojox/grid/_Grid.js
index ef3d9d6..a5d590a 100644
--- a/dojox/grid/_Grid.js
+++ b/dojox/grid/_Grid.js
@@ -207,7 +207,7 @@ dojo.requireLocalization("dijit", "loading");
 		// initialWidth: String
 		//		A css string to use to set our initial width (only used if autoWidth
 		//		is true).  The first rendering of the grid will be this width, any
-		//		resizing of columns, etc will result in the grid switching to 
+		//		resizing of columns, etc will result in the grid switching to
 		//		autoWidth mode.  Note, this width will override any styling in a
 		//		stylesheet or directly on the node.
 		initialWidth: "",
@@ -223,7 +223,7 @@ dojo.requireLocalization("dijit", "loading");
 		//		If rowHeight is set to a positive number, it will define the height of the rows
 		//		in pixels. This can provide a significant performance advantage, since it
 		//		eliminates the need to measure row sizes during rendering, which is one
-		// 		the primary bottlenecks in the DataGrid's performance. 
+		// 		the primary bottlenecks in the DataGrid's performance.
 		rowHeight: 0,
 		
 		// autoRender: Boolean
@@ -290,21 +290,21 @@ dojo.requireLocalization("dijit", "loading");
 		errorMessage: "<span class='dojoxGridError'>${errorState}</span>",
 
 		// noDataMessage: String
-		//  Message that shows if the grid has no data - wrap it in a 
+		//  Message that shows if the grid has no data - wrap it in a
 		//  span with class 'dojoxGridNoData' if you want it to be
 		//  styled similar to the loading and error messages
 		noDataMessage: "",
 		
 		// escapeHTMLInData: Boolean
-		//		This will escape HTML brackets from the data to prevent HTML from 
-		// 		user-inputted data being rendered with may contain JavaScript and result in 
-		// 		XSS attacks. This is true by default, and it is recommended that it remain 
-		// 		true. Setting this to false will allow data to be displayed in the grid without 
-		// 		filtering, and should be only used if it is known that the data won't contain 
-		// 		malicious scripts. If HTML is needed in grid cells, it is recommended that 
-		// 		you use the formatter function to generate the HTML (the output of 
+		//		This will escape HTML brackets from the data to prevent HTML from
+		// 		user-inputted data being rendered with may contain JavaScript and result in
+		// 		XSS attacks. This is true by default, and it is recommended that it remain
+		// 		true. Setting this to false will allow data to be displayed in the grid without
+		// 		filtering, and should be only used if it is known that the data won't contain
+		// 		malicious scripts. If HTML is needed in grid cells, it is recommended that
+		// 		you use the formatter function to generate the HTML (the output of
 		// 		formatter functions is not filtered, even with escapeHTMLInData set to true).
-		escapeHTMLInData: true,	
+		escapeHTMLInData: true,
 		
 		// formatterScope: Object
 		//		An object to execute format functions within.  If not set, the
@@ -314,7 +314,7 @@ dojo.requireLocalization("dijit", "loading");
 		
 		// editable: boolean
 		// indicates if the grid contains editable cells, default is false
-		// set to true if editable cell encountered during rendering 
+		// set to true if editable cell encountered during rendering
 		editable: false,
 		
 		// private
@@ -426,7 +426,7 @@ dojo.requireLocalization("dijit", "loading");
 					ah = false;
 				}
 				// Autoheight must be at least 1, if it's a number.  If it's
-				// less than 0, we'll take that to mean "all" rows (same as 
+				// less than 0, we'll take that to mean "all" rows (same as
 				// autoHeight=true - if it is equal to zero, we'll take that
 				// to mean autoHeight=false
 				if(ah < 0){
@@ -514,6 +514,7 @@ dojo.requireLocalization("dijit", "loading");
 			this.viewsNode.appendChild(view.domNode);
 			this.viewsHeaderNode.appendChild(view.headerNode);
 			this.views.addView(view);
+			dojo.attr(this.domNode, "align", dojo._isBodyLtr() ? 'left' : 'right');
 			return view;
 		},
 
@@ -527,7 +528,7 @@ dojo.requireLocalization("dijit", "loading");
 		_setStructureAttr: function(structure){
 			var s = structure;
 			if(s && dojo.isString(s)){
-				dojo.deprecated("dojox.grid._Grid.attr('structure', 'objVar')", "use dojox.grid._Grid.attr('structure', objVar) instead", "2.0");
+				dojo.deprecated("dojox.grid._Grid.set('structure', 'objVar')", "use dojox.grid._Grid.set('structure', objVar) instead", "2.0");
 				s=dojo.getObject(s);
 			}
 			this.structure = s;
@@ -539,6 +540,7 @@ dojo.requireLocalization("dijit", "loading");
 				}
 			}
 			this.views.destroyViews();
+			this.focus.focusView = null;
 			if(s !== this.layout.structure){
 				this.layout.setStructure(s);
 			}
@@ -548,7 +550,7 @@ dojo.requireLocalization("dijit", "loading");
 		setStructure: function(/* dojox.grid.__ViewDef|dojox.grid.__ViewDef[]|dojox.grid.__CellDef[]|Array[dojox.grid.__CellDef[]] */ inStructure){
 			// summary:
 			//		Install a new structure and rebuild the grid.
-			dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.attr('structure', obj) instead.", "2.0");
+			dojo.deprecated("dojox.grid._Grid.setStructure(obj)", "use dojox.grid._Grid.set('structure', obj) instead.", "2.0");
 			this._setStructureAttr(inStructure);
 		},
 		
@@ -575,14 +577,14 @@ dojo.requireLocalization("dijit", "loading");
 							}
 							checked = dojo.filter(self.layout.cells, function(c){
 								if(c.menuItems.length > 1){
-									dojo.forEach(c.menuItems, "item.attr('disabled', false);");
+									dojo.forEach(c.menuItems, "item.set('disabled', false);");
 								}else{
-									c.menuItems[0].attr('disabled', false);
+									c.menuItems[0].set('disabled', false);
 								}
 								return !c.hidden;
 							});
 							if(checked.length == 1){
-								dojo.forEach(checked[0].menuItems, "item.attr('disabled', true);");
+								dojo.forEach(checked[0].menuItems, "item.set('disabled', true);");
 							}
 						}
 					},
@@ -618,7 +620,7 @@ dojo.requireLocalization("dijit", "loading");
 		},
 
 		setHeaderMenu: function(/* dijit.Menu */ menu){
-			dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.attr('headerMenu', obj) instead.", "2.0");
+			dojo.deprecated("dojox.grid._Grid.setHeaderMenu(obj)", "use dojox.grid._Grid.set('headerMenu', obj) instead.", "2.0");
 			this._setHeaderMenuAttr(menu);
 		},
 		
@@ -668,7 +670,7 @@ dojo.requireLocalization("dijit", "loading");
 			//		Update the grid's rendering dimensions and resize it
 			
 			// Calling sizeChange calls update() which calls _resize...so let's
-			// save our input values, if any, and use them there when it gets 
+			// 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.
 			this._pendingChangeSize = changeSize;
@@ -708,7 +710,6 @@ dojo.requireLocalization("dijit", "loading");
 			// grid height
 			if(this._autoHeight){
 				this.domNode.style.height = 'auto';
-				this.viewsNode.style.height = '';
 			}else if(typeof this.autoHeight == "number"){
 				h = hh = this._getHeaderHeight();
 				h += (this.scroller.averageRowHeight * this.autoHeight);
@@ -969,7 +970,7 @@ dojo.requireLocalization("dijit", "loading");
 				if(this.layout.cells.length){
 					this.scroller.updateRowCount(inRowCount);
 				}
-				this._resize();				
+				this._resize();
 				if(this.layout.cells.length){
 					this.setScrollTop(this.scrollTop);
 				}
@@ -1345,7 +1346,7 @@ dojo.requireLocalization("dijit", "loading");
 						cell.relWidth = window.parseInt(dojo.attr(th, "relWidth"), 10);
 					}
 					if(d.hasAttr(th, "hidden")){
-						cell.hidden = d.attr(th, "hidden") == "true";
+						cell.hidden = (d.attr(th, "hidden") == "true" || d.attr(th, "hidden") === true/*always boolean true in Chrome*/);
 					}
 
 					if(cellFunc){
diff --git a/dojox/grid/_Layout.js b/dojox/grid/_Layout.js
index 5bd2039..8d35b2d 100644
--- a/dojox/grid/_Layout.js
+++ b/dojox/grid/_Layout.js
@@ -67,6 +67,17 @@ dojo.declare("dojox.grid._Layout", null, {
 				}
 			}
 		}
+		
+		//Fix #9481 - reset idx in cell markup
+		dojo.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){
+				marks[1] = "idx=\"" + c.index + "\"";
+				c.markup[2] = marks.join(" ");
+			}
+		});
+		
 		this.grid.setupHeaderMenu();
 		//this.grid.renderOnIdle();
 	},
@@ -116,10 +127,10 @@ dojo.declare("dojox.grid._Layout", null, {
 			return new_cell;
 		}
 
-		var cell_type = inDef.type || this._defaultCellProps.type || dojox.grid.cells.Cell;
+		var cell_type = inDef.type || inDef.cellType || this._defaultCellProps.type || this._defaultCellProps.cellType || dojox.grid.cells.Cell;
 
 		props.unitWidth = getCellWidth(inDef);
-		return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));	
+		return new cell_type(dojo.mixin({}, this._defaultCellProps, inDef, props));
 	},
 	
 	addRowDef: function(inRowIndex, inDef){
@@ -138,7 +149,7 @@ dojo.declare("dojox.grid._Layout", null, {
 					pctSum += window.parseInt(w, 10);
 				}else if(w == "auto"){
 					// relative widths doesn't play nice with auto - since we
-					// don't have a way of knowing how much space the auto is 
+					// don't have a way of knowing how much space the auto is
 					// supposed to take up.
 					doRel = false;
 				}
@@ -167,7 +178,7 @@ dojo.declare("dojox.grid._Layout", null, {
 				result.push(this.addRowDef(0, inDef));
 			}
 		}
-		return result;	
+		return result;
 	},
 	
 	addViewDef: function(inDef){
diff --git a/dojox/grid/_RowManager.js b/dojox/grid/_RowManager.js
index f82e0c0..1d81884 100644
--- a/dojox/grid/_RowManager.js
+++ b/dojox/grid/_RowManager.js
@@ -19,7 +19,7 @@ dojo.provide("dojox.grid._RowManager");
 		// styles
 		prepareStylingRow: function(inRowIndex, inRowNode){
 			return {
-				index: inRowIndex, 
+				index: inRowIndex,
 				node: inRowNode,
 				odd: Boolean(inRowIndex&1),
 				selected: !!this.grid.selection.isSelected(inRowIndex),
diff --git a/dojox/grid/_RowSelector.js b/dojox/grid/_RowSelector.js
index 14a47b7..08c1e67 100644
--- a/dojox/grid/_RowSelector.js
+++ b/dojox/grid/_RowSelector.js
@@ -11,7 +11,7 @@ dojo.declare('dojox.grid._RowSelector', dojox.grid._View, {
 		this.inherited('buildRendering', arguments);
 		this.scrollboxNode.style.overflow = "hidden";
 		this.headerNode.style.visibility = "hidden";
-	},	
+	},
 	getWidth: function(){
 		return this.viewWidth || this.defaultWidth;
 	},
diff --git a/dojox/grid/_Scroller.js b/dojox/grid/_Scroller.js
index 35961f4..59f36ef 100644
--- a/dojox/grid/_Scroller.js
+++ b/dojox/grid/_Scroller.js
@@ -259,7 +259,7 @@ dojo.provide("dojox.grid._Scroller");
 			// Calculate the average row height and update the defaults (row and page).
 			var needPage = (!this._invalidating);
 			if(!needPage){
-				var ah = this.grid.attr("autoHeight");
+				var ah = this.grid.get("autoHeight");
 				if(typeof ah == "number" && ah <= Math.min(this.rowsPerPage, this.rowCount)){
 					needPage = true;
 				}
@@ -284,7 +284,7 @@ dojo.provide("dojox.grid._Scroller");
 			this.height += inDh;
 			this.resize();
 		},
-		updatePageHeight: function(inPageIndex, fromBuild){
+		updatePageHeight: function(inPageIndex, fromBuild, fromAsynRendering){
 			if(this.pageExists(inPageIndex)){
 				var oh = this.getPageHeight(inPageIndex);
 				var h = (this.measurePage(inPageIndex));
@@ -294,9 +294,15 @@ dojo.provide("dojox.grid._Scroller");
 				this.pageHeights[inPageIndex] = h;
 				if(oh != h){
 					this.updateContentHeight(h - oh);
-					var ah = this.grid.attr("autoHeight");
+					var ah = this.grid.get("autoHeight");
 					if((typeof ah == "number" && ah > this.rowCount)||(ah === true && !fromBuild)){
-						this.grid.sizeChange();
+						if(!fromAsynRendering){
+							this.grid.sizeChange();
+						}else{//fix #11101 by using fromAsynRendering to avoid deadlock
+							var ns = this.grid.viewsNode.style;
+							ns.height = parseInt(ns.height) + h - oh + 'px';
+							this.repositionPages(inPageIndex);
+						}
 					}else{
 						this.repositionPages(inPageIndex);
 					}
@@ -305,8 +311,8 @@ dojo.provide("dojox.grid._Scroller");
 			}
 			return 0;
 		},
-		rowHeightChanged: function(inRowIndex){
-			this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false);
+		rowHeightChanged: function(inRowIndex, fromAsynRendering){
+			this.updatePageHeight(Math.floor(inRowIndex / this.rowsPerPage), false, fromAsynRendering);
 		},
 		// scroller core
 		invalidateNodes: function(){
@@ -356,7 +362,7 @@ dojo.provide("dojox.grid._Scroller");
 		needPage: function(inPageIndex, inPos){
 			var h = this.getPageHeight(inPageIndex), oh = h;
 			if(!this.pageExists(inPageIndex)){
-				this.buildPage(inPageIndex, this.keepPages&&(this.stack.length >= this.keepPages), inPos);
+				this.buildPage(inPageIndex, (!this.grid._autoHeight/*fix #10543*/ && this.keepPages&&(this.stack.length >= this.keepPages)), inPos);
 				h = this.updatePageHeight(inPageIndex, true);
 			}else{
 				this.positionPage(inPageIndex, inPos);
@@ -482,6 +488,7 @@ dojo.provide("dojox.grid._Scroller");
 				t += this.getPageHeight(i);
 			}
 			this.pageTop = t;
+			this.page = rowPage;//fix #10543
 			this.needPage(rowPage, this.pageTop);
 
 			var nodes = this.getDefaultNodes();
diff --git a/dojox/grid/_Selector.js b/dojox/grid/_Selector.js
index 618214e..04e18fd 100644
--- a/dojox/grid/_Selector.js
+++ b/dojox/grid/_Selector.js
@@ -37,8 +37,8 @@ dojo.require("dojox.grid._Builder");
 	},dojox.grid._ContentBuilder.prototype,{
 		generateHtml: function(inDataIndex, inRowIndex){
 			var w = this.view.contentWidth || 0;
-			return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' + 
-				'cellspacing="0" cellpadding="0" role="presentation"><tr>' + 
+			return '<table class="dojoxGridRowbarTable" style="width:' + w + 'px;" border="0" ' +
+				'cellspacing="0" cellpadding="0" role="presentation"><tr>' +
 				'<td  style="text-align: center;" class="dojoxGridRowbarInner">' + this.getCellContent(inRowIndex) + '</td></tr></table>';
 		},
 		getCellContent: function(inRowIndex){
@@ -110,7 +110,7 @@ dojo.require("dojox.grid._Builder");
 		buildRendering: function(){
 			this.inherited(arguments);
 			this.scrollboxNode.style.overflow = "hidden";
-		},	
+		},
 		getWidth: function(){
 			return this.viewWidth || this.defaultWidth;
 		},
@@ -201,7 +201,7 @@ dojo.require("dojox.grid._Builder");
 			this._updateVisibility(this.grid.rowCount);
 		},
 		_updateVisibility: function(rowCount){
-			this.headerNode.style.visibility = rowCount ? "" : "hidden";		
+			this.headerNode.style.visibility = rowCount ? "" : "hidden";
 		},
 		onSelectionChanged: function(){
 			if(this._selectionChanging){ return; }
diff --git a/dojox/grid/_TreeView.js b/dojox/grid/_TreeView.js
index 75e764b..3b4d555 100644
--- a/dojox/grid/_TreeView.js
+++ b/dojox/grid/_TreeView.js
@@ -30,7 +30,7 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 			if(p){
 				dojo.query("tr[dojoxTreeGridPath^=\"" + p + "/\"]", this.rowNode).forEach(function(n){
 					var en = dojo.query(".dojoxGridExpando", n)[0];
-					if(en && en.parentNode && en.parentNode.parentNode && 
+					if(en && en.parentNode && en.parentNode.parentNode &&
 								!dojo.hasClass(en.parentNode.parentNode, "dojoxGridNoChildren")){
 						var ew = dijit.byNode(en);
 						if(ew){
@@ -168,7 +168,7 @@ dojo.declare("dojox.grid._Expando", [ dijit._Widget, dijit._Templated ], {
 		this.open = this.expandoCell.getOpenState(this.itemId);
 		if(view.grid.treeModel){
 			// TODO: Rather than hard-code the 18px and 3px, we should probably
-			// calculate them based off css or something...  However, all the 
+			// 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");
 			if(this.domNode.parentNode){
@@ -197,7 +197,7 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 				if(html[0].indexOf('dojoxGridRowTableNeedsRowUpdate') == -1){
 					html[0] = html[0].replace("dojoxGridRowTable", "dojoxGridRowTable dojoxGridRowTableNeedsRowUpdate");
 				}
-				return; 
+				return;
 			}
 			var rowNodeIdx = html.length;
 			toggleClasses = toggleClasses || [];
@@ -271,7 +271,7 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 						iStack.push(values.length);
 						createRow(level, rowItem, true, toggleClasses, iStack, parentOpen);
 					}else{
-						html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';					
+						html[rowNodeIdx] = '<tr class="' + tcString + ' dojoxGridNoChildren" dojoxTreeGridPath="' + rowStack.join('/') + '">';
 					}
 				}else{
 					if(!store.isItemLoaded(rowItem)){
@@ -296,7 +296,7 @@ dojo.declare("dojox.grid._TreeContentBuilder", dojox.grid._ContentBuilder, {
 			}
 			n = n.parentNode;
 		}
-		return (n != this.domNode) ? n : null; 
+		return (n != this.domNode) ? n : null;
 	},
 	getCellNode: function(inRowNode, inCellIndex){
 		var node = dojo.query("td[idx='" + inCellIndex + "']", inRowNode)[0];
diff --git a/dojox/grid/_View.js b/dojox/grid/_View.js
index a5a407c..102ade6 100644
--- a/dojox/grid/_View.js
+++ b/dojox/grid/_View.js
@@ -10,12 +10,12 @@ dojo.require("dojo.dnd.Source");
 dojo.require("dojo.dnd.Manager");
 
 (function(){
-	// private
+	// a private function
 	var getStyleText = function(inNode, inStyleText){
 		return inNode.style.cssText == undefined ? inNode.getAttribute("style") : inNode.style.cssText;
 	};
 
-	// public
+	// some public functions
 	dojo.declare('dojox.grid._View', [dijit._Widget, dijit._Templated], {
 		// summary:
 		//		A collection of grid columns. A grid is comprised of a set of views that stack horizontally.
@@ -78,7 +78,7 @@ dojo.require("dojo.dnd.Manager");
 			this.inherited(arguments);
 		},
 
-		// focus 
+		// focus
 		focus: function(){
 			if(dojo.isIE || dojo.isWebKit || dojo.isOpera){
 				this.hiddenFocusNode.focus();
@@ -556,7 +556,7 @@ dojo.require("dojo.dnd.Manager");
 				this.contentWidth = this.getContentWidth();
 				this.headerContentNode.firstChild.style.width = this.contentWidth;
 			}
-			// FIXME: it should be easier to get w from this.scrollboxNode.clientWidth, 
+			// FIXME: it should be easier to get w from this.scrollboxNode.clientWidth,
 			// but clientWidth seemingly does not include scrollbar width in some cases
 			var w = this.scrollboxNode.offsetWidth - this.getScrollbarWidth();
 			if(!this._removingColumn){
@@ -615,7 +615,7 @@ dojo.require("dojo.dnd.Manager");
 		},
 
 		buildRowContent: function(inRowIndex, inRowNode){
-			inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex); 
+			inRowNode.innerHTML = this.content.generateHtml(inRowIndex, inRowIndex);
 			if(this.flexCells && this.contentWidth){
 				// FIXME: accessing firstChild here breaks encapsulation
 				inRowNode.firstChild.style.width = this.contentWidth;
diff --git a/dojox/grid/_ViewManager.js b/dojox/grid/_ViewManager.js
index 348df1c..a20a6ab 100644
--- a/dojox/grid/_ViewManager.js
+++ b/dojox/grid/_ViewManager.js
@@ -76,9 +76,9 @@ dojo.declare('dojox.grid._ViewManager', null, {
 		if(this.grid.rowHeight){
 			h = this.grid.rowHeight;
 		}else{
-			if(inRowNodes.length <= 1){ 
+			if(inRowNodes.length <= 1){
 				// no need to normalize if we are the only one...
-				return; 
+				return;
 			}
 			for(var i=0, n; (n=inRowNodes[i]); i++){
 				// We only care about the height - so don't use marginBox.  This
@@ -189,7 +189,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 					hs.right = l + v.getScrollbarWidth() + 'px';
 					hs.width = parseInt(hs.width, 10) - v.getScrollbarWidth() + 'px';
 				}else{
-					hs.right = l + 'px';					
+					hs.right = l + 'px';
 				}
 			}else{
 				ds.left = l + 'px';
@@ -199,7 +199,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 			hs.top = 0;
 		};
 		// for views left of the client
-		//BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with 
+		//BiDi TODO: The left and right should not appear in BIDI environment. Should be replaced with
 		//leading and tailing concept.
 		for(i=0; (v=this.views[i])&&(i<c); i++){
 			// get width
@@ -215,7 +215,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 			// update position
 			l += vw;
 		}
-		// next view (is the client, i++ == c) 
+		// next view (is the client, i++ == c)
 		i++;
 		// start from the right edge
 		var r = w;
@@ -234,7 +234,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 		}
 		if(c<len){
 			v = this.views[c];
-			// position the client box between left and right boxes	
+			// position the client box between left and right boxes
 			vw = Math.max(1, r-l);
 			// set size
 			v.setSize(vw + 'px', 0);
@@ -290,7 +290,7 @@ dojo.declare('dojox.grid._ViewManager', null, {
 	},
 	
 	getFirstScrollingView: function(){
-		// summary: Returns the first grid view with a scroll bar 
+		// summary: Returns the first grid view with a scroll bar
 		for(var i=0, v; (v=this.views[i]); i++){
 			if(v.hasHScrollbar() || v.hasVScrollbar()){
 				return v;
diff --git a/dojox/grid/cells/dijit.js b/dojox/grid/cells/dijit.js
index 43708cb..c10ae1f 100644
--- a/dojox/grid/cells/dijit.js
+++ b/dojox/grid/cells/dijit.js
@@ -33,18 +33,18 @@ dojo.require("dijit.Editor");
 			return "<div></div>";
 		},
 		getValue: function(inRowIndex){
-			return this.widget.attr('value');
+			return this.widget.get('value');
 		},
 		setValue: function(inRowIndex, inValue){
-			if(this.widget&&this.widget.attr){
+			if(this.widget&&this.widget.set){
 				//Look for lazy-loading editor and handle it via its deferred.
 				if(this.widget.onLoadDeferred){
 					var self = this;
 					this.widget.onLoadDeferred.addCallback(function(){
-						self.widget.attr("value",inValue===null?"":inValue); 
+						self.widget.set("value",inValue===null?"":inValue);
 					});
 				}else{
-					this.widget.attr("value", inValue); 
+					this.widget.set("value", inValue);
 				}
 			}else{
 				this.inherited(arguments);
@@ -80,7 +80,8 @@ dojo.require("dijit.Editor");
 				this.attachWidget.apply(this, arguments);
 			}
 			this.sizeWidget.apply(this, arguments);
-			this.grid.rowHeightChanged(inRowIndex);
+			this.grid.views.renormalizeRow(inRowIndex);
+			this.grid.scroller.rowHeightChanged(inRowIndex, true/*fix #11101*/);
 			this.focus();
 			return undefined;
 		},
@@ -100,6 +101,9 @@ dojo.require("dijit.Editor");
 		_finish: function(inRowIndex){
 			this.inherited(arguments);
 			dojox.grid.util.removeNode(this.widget.domNode);
+			if(dojo.isIE){
+				dojo.setSelectable(this.widget.domNode, true);
+			}
 		}
 	});
 	dgc._Widget.markupFactory = function(node, cell){
@@ -135,8 +139,8 @@ dojo.require("dijit.Editor");
 		getValue: function(){
 			var e = this.widget;
 			// make sure to apply the displayed value
-			e.attr('displayedValue', e.attr('displayedValue'));
-			return e.attr('value');
+			e.set('displayedValue', e.get('displayedValue'));
+			return e.get('value');
 		}
 	});
 	dgc.ComboBox.markupFactory = function(node, cell){
@@ -155,7 +159,7 @@ dojo.require("dijit.Editor");
 		widgetClass: dijit.form.DateTextBox,
 		setValue: function(inRowIndex, inValue){
 			if(this.widget){
-				this.widget.attr('value', new Date(inValue));
+				this.widget.set('value', new Date(inValue));
 			}else{
 				this.inherited(arguments);
 			}
@@ -177,7 +181,7 @@ dojo.require("dijit.Editor");
 		},
 		setValue: function(inRowIndex, inValue){
 			if(this.widget&&this.widget.attributeMap.checked){
-				this.widget.attr("checked", inValue);
+				this.widget.set("checked", inValue);
 			}else{
 				this.inherited(arguments);
 			}
@@ -216,7 +220,7 @@ dojo.require("dijit.Editor");
 			}
 		},
 		populateEditor: function(){
-			this.widget.attr('value', this.content);
+			this.widget.set('value', this.content);
 			this.widget.placeCursorAtEnd();
 		}
 	});
diff --git a/dojox/grid/cells/tree.js b/dojox/grid/cells/tree.js
index fd5abf3..19a5118 100644
--- a/dojox/grid/cells/tree.js
+++ b/dojox/grid/cells/tree.js
@@ -4,12 +4,12 @@ dojo.require("dojox.grid.cells");
 
 dojox.grid.cells.TreeCell = {
 	formatAggregate: function(inItem, level, inRowIndexes){
-		var f, g=this.grid, i=g.edit.info, 
+		var f, g=this.grid, i=g.edit.info,
 			d=g.aggregator ? g.aggregator.getForCell(this, level, inItem, level === this.level ? "cnt" : this.parentCell.aggregate) : (this.value || this.defaultValue);
 		return this._defaultFormat(d, [d, level - this.level, inRowIndexes, this]);
 	},
 	formatIndexes: function(inRowIndexes, inItem){
-		var f, g=this.grid, i=g.edit.info, 
+		var f, g=this.grid, i=g.edit.info,
 			d=this.get ? this.get(inRowIndexes[0], inItem, inRowIndexes) : (this.value || this.defaultValue);
 		if(this.editable && (this.alwaysEditing || (i.rowIndex==inRowIndexes[0] && i.cell==this))){
 			return this.formatEditing(d, inRowIndexes[0], inRowIndexes);
diff --git a/dojox/grid/enhanced/_Builder.js b/dojox/grid/enhanced/_Builder.js
deleted file mode 100644
index 39c9fe3..0000000
--- a/dojox/grid/enhanced/_Builder.js
+++ /dev/null
@@ -1,115 +0,0 @@
-dojo.provide("dojox.grid.enhanced._Builder");
-
-dojo.require("dojox.grid._Builder");
-
-dojo.declare("dojox.grid.enhanced._BuilderMixin", null, {
-	// summary:
-	//		Common methods shared between dojox.grid.enhanced._HeaderBuilder and dojox.grid.enhanced._ContentBuilder
-	generateCellMarkup: function(inCell, inMoreStyles, inMoreClasses, isHeader){
-		// summary:
-		//		Overwritten, see dojox.grid._Builder.generateCellMarkup()
-		//		Add special css classes when nested sorting is on
-		var result = this.inherited(arguments);
-		if(!isHeader){
-			result[4] += '<div class="dojoxGridCellContent">';
-			result[6] = '</div></td>';
-		}
-		return result;
-	},
-	
-	domouseup: function(e){
-	//summary:
-	//		Handler when there is a mouse up event either in header or grid content 
-	//e: Event
-	//		The mouse up event
-		if(e.cellNode)
-			this.grid.onMouseUp(e);
-	}	
-});
-
-dojo.declare("dojox.grid.enhanced._HeaderBuilder", [dojox.grid._HeaderBuilder, dojox.grid.enhanced._BuilderMixin], {
-	// summary:
-	//		Extending dojox.grid._HeaderBuilder to overwrite some default behavior
-	getCellX: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._HeaderBuilder.getCellX()		
-		if(this.grid.nestedSorting){
-			var ascendDom = function(inNode, inWhile){
-				for(var n=inNode; n && inWhile(n); n=n.parentNode);
-				return n;
-			};			
-			var makeNotTagName = function(inTagName){
-				var name = inTagName.toUpperCase();
-				return function(node){ return node.tagName != name; };
-			};
-			var no = ascendDom(e.target, makeNotTagName("th"));
-            //console.log(dojo.coords(no).x, e.clientX);
-			var x = no ? e.pageX - dojo.coords(no, true).x : -1;
-			if(dojo.isIE){
-				//fix zoom issue in IE				
-				var rect = dojo.body().getBoundingClientRect();
-				var zoomLevel = (rect.right - rect.left) / document.body.clientWidth;
-				// console.log('zoomlevel', zoomLevel);
-				return parseInt(x / zoomLevel);
-			}
-            return x;
-		}
-		return this.inherited(arguments);
-	},
-	
-	decorateEvent: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._HeaderBuilder.decorateEvent()
-		var result = this.inherited(arguments);
-		
-		//add action types for nested sorting and column selection
-		if(this.grid.nestedSorting){
-			var sortInfo = this.grid._getSortEventInfo(e);
-			e.unarySortChoice = sortInfo.unarySortChoice;
-			e.nestedSortChoice = sortInfo.nestedSortChoice;
-			e.selectChoice = sortInfo.selectChoice;				
-		}
-		return result;
-	},
-	
-	doclick: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._HeaderBuilder.doclick()
-		if((this._skipBogusClicks && !this.grid.nestedSorting)
-		   ||(this.grid.nestedSorting && this.grid.ignoreEvent(e))){
-			dojo.stopEvent(e);
-			return true;
-		}
-	},
-	
-	colResizeSetup: function(e, isMouse){
-		// summary:
-		//		Overwritten, see dojox.grid._HeaderBuilder.colResizeSetup()
-		//		Set minimal column width for unfixed cells when nested sorting is on
-		var origMinColWidthRef = this.minColWidth;
-		//if(e.sourceView.grid.nestedSorting && this.minColWidths[e.cellIndex + '']){
-		if(e.sourceView.grid.nestedSorting && !this.grid.pluginMgr.isFixedCell(e.cell)){
-			this.minColWidth =  this.grid.getMinColWidth();
-			//this.minColWidth = this.minColWidths[e.cellIndex + ''];
-			var conn = dojo.connect(this, 'endResizeColumn', dojo.hitch(this,function(){
-				this.minColWidth = origMinColWidthRef;
-				dojo.disconnect(conn);
-			}));
-		}
-		var drag = this.inherited(arguments);
-		if(!dojo._isBodyLtr() && dojo.isIE && drag.followers){
-			//fix RTL in IE - left is NaN
-			dojo.forEach(drag.followers, function(follower){
-				if(!follower.left){
-					follower.left = dojo.position(follower.node).x;
-				}
-			});
-		}
-		return drag;
-	}	
-});
-
-dojo.declare("dojox.grid.enhanced._ContentBuilder", [dojox.grid._ContentBuilder, dojox.grid.enhanced._BuilderMixin], {
-	// summary:
-	// 		Extending dojox.grid._ContentBuilder to overwrite some default behavior
-});
diff --git a/dojox/grid/enhanced/_Events.js b/dojox/grid/enhanced/_Events.js
index 86ff028..e5fd1c5 100644
--- a/dojox/grid/enhanced/_Events.js
+++ b/dojox/grid/enhanced/_Events.js
@@ -3,36 +3,32 @@ dojo.provide("dojox.grid.enhanced._Events");
 dojo.declare("dojox.grid.enhanced._Events", null, {
 	// summary:
 	//		Overwrite some default events of DataGrid
-	//		
-	// description: 
-	//		Methods are copied or replaced for overwriting, this might be refined once 
+	//
+	// description:
+	//		Methods are copied or replaced for overwriting, this might be refined once
 	//		an overall plugin architecture is set up for DataGrid.
 
 	//_events: Object
 	//		Method map cached from dojox.grid._Events().
 	_events: null,
 
-	//headerCellActiveClass: String
-	// 		css class to apply to grid header cells when activated(mouse down)
+	// headerCellActiveClass: String
+	//		css class to apply to grid header cells when activated(mouse down)
 	headerCellActiveClass: 'dojoxGridHeaderActive',
 	
-	//cellActiveClass: String
-	// 		css class to apply to grid content cells when activated(mouse down)
+	// cellActiveClass: String
+	//		css class to apply to grid content cells when activated(mouse down)
 	cellActiveClass: 'dojoxGridCellActive',
 	
-	//rowActiveClass: String
-	// 		css class to apply to grid rows when activated(mouse down)
-	rowActiveClass: 'dojoxGridRowActive',		
-
-	//selectRegionHoverClass: String
-	// 		css class to apply to select regions in header cells when mouse over
-	selectRegionHoverClass: 'dojoxGridSelectRegionHover',	
+	// rowActiveClass: String
+	//		css class to apply to grid rows when activated(mouse down)
+	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(p in this._events){
+		for(var p in this._events){
 			if(!this[p]){
 				this.p = this._events.p;
 			}
@@ -40,285 +36,71 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 		//mixin "this" to Grid
 		inGrid.mixin(inGrid, this);
 	},
-	
-	onStyleRow: function(inRow){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onStyleRow()
-		var i = inRow;
-		i.customClasses += (i.odd?" dojoxGridRowOdd":"") + (i.selected?" dojoxGridRowSelected":"") + (i.over/*&&!this.isDndSelectEnable*/?" dojoxGridRowOver":"");
-		this.focus.styleRow(inRow);
-		this.edit.styleRow(inRow);
-	},
-	
-	dokeyup: function(e) {
+	dokeyup: function(e){
 		// summary:
-		// 		Grid key up event handler.
+		//		Grid key up event handler.
 		// e: Event
 		//		Un-decorated event object
-		this.indirectSelection && !this.pluginMgr.inSingleSelection() && this.indirectSelector.dokeyup(e);
+		this.focus.currentArea().keyup(e);
 	},
-	
 	onKeyDown: function(e){
 		// summary:
-		// 		Overwritten, see dojox.grid._Events.onKeyDown()
+		//		Overwritten, see dojox.grid._Events.onKeyDown();
 		if(e.altKey || e.metaKey){ return; }
-		
-		if (e.ctrlKey && !e.shiftKey){
-			dojo.publish("CTRL_KEY_DOWN", [this, e]);
-		}
-		var executed = false;
-		
-		if(this.isDndSelectEnable && !e.ctrlKey){
-			this.select.keepState = false;
-		}
-		if(this.isDndSelectEnable && !e.shiftKey){
-			this.select.extendSelect = false;
-		}
 		var dk = dojo.keys;
+		var focus = this.focus;
 		switch(e.keyCode){
-			case dk.ENTER:
-				executed = true;
-				if(!this.edit.isEditing()){
-					var colIdx = this.focus.getHeaderIndex();
-					if(colIdx >= 0){
-						this.nestedSorting && this.focus.focusView.header.decorateEvent(e);
-						var isRowSelector = e.cell && this.pluginMgr.isFixedCell(e.cell);
-						!e.selectChoice && !isRowSelector && this.setSortIndex(colIdx, null, e);
-						break;
-					}else{
-						!this.indirectSelection && this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
-					}
-					dojo.stopEvent(e);
-				}
-				if(!e.shiftKey){
-					var isEditing = this.edit.isEditing();
-					this.edit.apply();
-					if(!isEditing && !this.pluginMgr.isFixedCell(this.focus.cell)){
-						this.edit.setEditCell(this.focus.cell, this.focus.rowIndex);
-					}
-				}
-				if (!this.edit.isEditing()){
-					var curView = this.focus.focusView || this.views.views[0];  //if no focusView than only one view
-					curView.content.decorateEvent(e);
-					this.onRowClick(e);
-				}
+			case dk.TAB:
+				if(e.ctrlKey){ return; }
+				focus.tab(e.shiftKey ? -1:1,e);
 				break;
-			case dk.SPACE:
-				executed = true;
-				if(!this.edit.isEditing()){
-					var colIdx = this.focus.getHeaderIndex();
-					if(colIdx >= 0) {
-						//this.nestedSorting && this.focus.focusView.header.decorateEvent(e);
-						this.focus.focusView.header.decorateEvent(e);
-						if(this.indirectSelection && e.cell && e.cell.isRowSelector){
-							return;
-						}
-						if (this.isDndSelectEnable && (!this.nestedSorting && !this.canSort() || this.nestedSorting && e.selectChoice)){
-							this.inDNDKeySelectingColumnMode = true;
-							
-							this.select.keepState = e.ctrlKey;
-							this.select.extendSelect = e.shiftKey;
-							if (!this.select.extendSelect) {
-								this.select.drugSelectionStart.colIndex = colIdx;
-							}
-							this.select.drugSelectColumn(colIdx);
-						} else {
-							//this.nestedSorting && this.focus.focusView.header.decorateEvent(e);
-							var isRowSelector = e.cell && this.pluginMgr.isFixedCell(e.cell);
-							!isRowSelector && e.rowIndex == -1 && e.cell && this.setSortIndex(colIdx, null, e);
-						}
-						break;
-					}else if(this.isDndSelectEnable && this.focus.isRowBar()){
-						this.inDNDKeySelectingRowMode = true;
-						this.select.keepState = e.ctrlKey;
-						this.select.extendSelect = e.shiftKey;
-						if(!this.select.extendSelect || this.pluginMgr.inSingleSelection()){
-							this.select.drugSelectionStart.rowIndex = this.focus.getFocusedRowIndex();
-						} 
-						this.select.drugSelectRow(this.focus.getFocusedRowIndex());
-					}else {
-						!this.indirectSelection && this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
-					}
-					dojo.stopEvent(e);
-				}
+			case dk.UP_ARROW:
+			case dk.DOWN_ARROW:
+				focus.currentArea().move(e.keyCode == dk.UP_ARROW ? -1 : 1, 0, e);
 				break;
 			case dk.LEFT_ARROW:
 			case dk.RIGHT_ARROW:
-				executed = true;
-				this.nestedSorting && this.focus.focusView.header.decorateEvent(e);
-				var needDndSelect = this.isDndSelectEnable && e.shiftKey;
-				var isRowSelector = e.cell && this.pluginMgr.isFixedCell(e.cell);
-				if(this.nestedSorting && this.focus.isNavHeader() && !needDndSelect && !isRowSelector){
-					//dojo.stopEvent(e);
-					this.focus.navHeader(e);
-					return;
-				}
-				if(!this.edit.isEditing()){
-					var keyCode = e.keyCode;  // IE seems to lose after stopEvent when modifier keys
-					dojo.stopEvent(e);
-					var origColIdx = this.focus.getHeaderIndex();
-					if (origColIdx >= 0 && (e.shiftKey && e.ctrlKey)){
-						this.focus.colSizeAdjust(e, origColIdx, (keyCode == dk.LEFT_ARROW ? -1 : 1)*5);
-						return;
-					}
-					var offset = (keyCode == dk.LEFT_ARROW) ? 1 : -1;
-					if(dojo._isBodyLtr()){ offset *= -1; }
-					//var origColSelected = this.select.isColSelected(origColIdx);
-					if(this.nestedSorting && this.focus.isNavHeader() && (needDndSelect || isRowSelector)){
-						this.focus.navHeaderNode(offset, true);
-					}else if(!(this.isDndSelectEnable && this.focus.isRowBar())){ //fix DnD, if is DnDSelectEnable, and foucus on RowBar, invaild the left & right key
-						this.focus.move(0, offset);
-					}
-					//if(this.isDndSelectEnable && e.shiftKey) {
-					if(needDndSelect) {
-						var colIdx = this.focus.getHeaderIndex();
-						if(!this.select.isColSelected(origColIdx)){
-							this.inDNDKeySelectingColumnMode = true;
-							this.select.drugSelectionStart.colIndex = origColIdx;
-						} else if(this.select.drugSelectionStart.colIndex == -1){
-							this.select.restorLastDragPoint();
-						}
-						if(e.ctrlKey){
-							this.select.drugSelectColumnToMax(e.keyCode==dk.LEFT_ARROW?"left":"right");
-						} else {
-							this.select.drugSelectColumn(colIdx);
-						}
-					}
-				}
+				var offset = (e.keyCode == dk.LEFT_ARROW) ? 1 : -1;
+				if(dojo._isBodyLtr()){ offset *= -1; }
+				focus.currentArea().move(0, offset, e);
 				break;
-			case dk.UP_ARROW:
-			case dk.DOWN_ARROW:
-				executed = true;
-				if(this.nestedSorting && this.focus.isNavHeader()){
-					return;
-				}
-				var delta = e.keyCode == dk.UP_ARROW ? -1 : 1;
-			    if(this.isDndSelectEnable){
-					var origRowIdx = this.focus.getFocusedRowIndex();
-				}
-				if(this.isDndSelectEnable && this.focus.isRowBar()){
-					this.focus[e.keyCode == dk.UP_ARROW ? 'focusPrevRowBar' : 'focusNextRowBar']();
-					dojo.stopEvent(e);
-				}else if(!this.edit.isEditing() && this.store && 0 <= (this.focus.rowIndex + delta) && (this.focus.rowIndex + delta) < this.rowCount){
-					dojo.stopEvent(e);
-					this.focus.move(delta, 0);
-					this.indirectSelection && this.focus.cell && this.focus.cell.focus(this.focus.rowIndex);			
-					!this.indirectSelection && this.selection.clickSelect(this.focus.rowIndex, dojo.isCopyKey(e), e.shiftKey);
-				}
-				if(this.isDndSelectEnable && this.focus.isRowBar() && e.shiftKey && !this.pluginMgr.inSingleSelection()) {
-					if(!this.select.isRowSelected(origRowIdx)){
-						this.inDNDKeySelectingRowMode = true;
-						this.select.drugSelectionStart.rowIndex = origRowIdx;
-					} else if(this.select.drugSelectionStart.rowIndex == -1) {
-						this.select.restorLastDragPoint();
-					}
-					if (e.ctrlKey) {
-						this.select.drugSelectRowToMax(e.keyCode == dk.UP_ARROW ? "up" : "down");
-					} else {
-						var rowIdy = this.focus.getFocusedRowIndex();
-						this.select.drugSelectRow(rowIdy);
-					}
-				} else if(this.indirectSelection && e.shiftKey && !this.pluginMgr.inSingleSelection() && this.focus.rowIndex >= 0) {
-					this.focus.focusView.content.decorateEvent(e);
-					if(e.cellIndex != 0 || e.rowIndex == 0 && delta == -1){
-						return;
-					}
-					this.indirectSelector.swipeSelectionByKey(e, delta);
+			case dk.F10:
+				if(this.menus && e.shiftKey){
+					this.onRowContextMenu(e);
 				}
 				break;
-			case dk.ESCAPE:
-				try{
-					this.select.cancelDND();
-				} catch(e) {
-					console.debug(e);
-				}
+			default:
+				focus.currentArea().keydown(e);
 				break;
 		}
-		//invoke dojox.grid._Events.onKeyDown()
-		!executed && (dojo.hitch(this, this._events.onKeyDown)(e));
 	},
-
-	onMouseDown: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onMouseDown()
-				
-		//invoke dojox.grid._Events.onMouseDown()
-		dojo.hitch(this, this._events.onMouseDown)(e);
-		if(this.isDndSelectEnable && !e.shiftKey){			
-			this.select.setDrugStartPoint(e.cellIndex, e.rowIndex);
+	//TODO - make the following events more reasonalble - e.g. more accurate conditions
+	//events for row selectors
+	domouseup: function(e){
+		if(e.cellNode){
+			this.onMouseUp(e);
+		}else{
+			this.onRowSelectorMouseUp(e);
+		}
+	},
+	domousedown: function(e){
+		if(!e.cellNode){
+			this.onRowSelectorMouseDown(e);
 		}
 	},
-	
 	onMouseUp: function(e){
 		// summary:
 		//		New - Event fired when mouse is up inside grid.
 		// e: Event
 		//		Decorated event object that contains reference to grid, cell, and rowIndex
-		e.rowIndex == -1 ? this.onHeaderCellMouseUp(e) : this.onCellMouseUp(e);
+		this[e.rowIndex == -1 ? "onHeaderCellMouseUp" : "onCellMouseUp"](e);
 	},
-	
-	onMouseOutRow: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onMouseOutRow()
-		if (this.isDndSelectEnable) {
-			//waiting ...
-			return;
-		}
-		//invoke dojox.grid._Events.onMouseOutRow()
-		dojo.hitch(this, this._events.onMouseOutRow)(e);
-	},
-	
-	onMouseDownRow: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onMouseDownRow()
-		if (this.isDndSelectEnable) {
-			//waiting ...
-			return;
-		}
-		//invoke dojox.grid._Events.onMouseDownRow()
-		dojo.hitch(this, this._events.onMouseDownRow)(e);
-	},
-
-	onCellMouseOver: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onCellMouseOver()
-		
-		//invoke dojox.grid._Events.onCellMouseOver()
-		dojo.hitch(this, this._events.onCellMouseOver)(e);
-		var inIndirectSelectionMode = this.pluginMgr.isFixedCell(e.cell) || this.rowSelectCell && this.rowSelectCell.inIndirectSelectionMode();
-		if(this.isDndSelectEnable && !inIndirectSelectionMode){
-			if(this.select.isInSelectingMode("col")){
-				this.select.drugSelectColumn(e.cell.index);
-			}else if(this.select.isInSelectingMode("cell")){
-				this.select.drugSelectCell(e.cellIndex, e.rowIndex);
-			}else{
-				this.select.setDrugCoverDivs(e.cellIndex, e.rowIndex);
-			}
-		}
-	},
-	
-	onCellMouseOut: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onCellMouseOut()
-		
-		//invoke dojox.grid._Events.onCellMouseOut()
-		dojo.hitch(this, this._events.onCellMouseOut)(e);	
-		this.doubleAffordance && e.cellNode && dojo.removeClass(e.cellNode, this.cellActiveClass);
-	},
-	
 	onCellMouseDown: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onCellMouseDown()
 		dojo.addClass(e.cellNode, this.cellActiveClass);
 		dojo.addClass(e.rowNode, this.rowActiveClass);
-		if(this.isDndSelectEnable){
-			this.focus._blurRowBar();
-			if(e.cellIndex > this.select.exceptColumnsTo){
-				this.select.setInSelectingMode("cell", true);
-			}
-		}
 	},
-	
 	onCellMouseUp: function(e){
 		// summary:
 		//		New - Event fired when mouse is up inside content cell.
@@ -327,83 +109,52 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 		dojo.removeClass(e.cellNode, this.cellActiveClass);
 		dojo.removeClass(e.rowNode, this.rowActiveClass);
 	},
-
 	onCellClick: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onCellClick()
-		if(this.isDndSelectEnable){
-			this.focus._blurRowBar();	//fix DnD blur
-			this._click[0] = this._click[1];
-			this._click[1] = e;
-			this.select.cellClick(e.cellIndex, e.rowIndex);
-			!this.edit.isEditCell(e.rowIndex, e.cellIndex) && !this.edit.isEditing() && this.select.cleanAll();
-			this.focus.setFocusCell(e.cell, e.rowIndex);
-		}else{
-			//invoke dojox.grid._Events.onCellClick()
-			dojo.hitch(this, this._events.onCellClick)(e);
-		} 
-	},
 
+		//invoke dojox.grid._Events.onCellClick()
+		this._events.onCellClick.call(this, e);
+		//move mouse events to the focus manager.
+		this.focus.contentMouseEvent(e);//TODO
+	},
 	onCellDblClick: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onCellDblClick()
 		if(this.pluginMgr.isFixedCell(e.cell)){ return; }
-		this._click.length > 1 && (!this._click[0] || !this._click[1]) && (this._click[0] = this._click[1] = e);
+		if(this._click.length > 1 && (!this._click[0] || !this._click[1])){
+			this._click[0] = this._click[1] = e;
+		}
 		//invoke dojox.grid._Events.onCellDblClick()
-		dojo.hitch(this, this._events.onCellDblClick)(e);
+		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);
-		!this.indirectSelection && this.selection.clickSelectEvent(e);
-	},
-
-	onRowMouseOver: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onRowMouseOver()
-		if(this.isDndSelectEnable && !this.pluginMgr.inSingleSelection()){
-			if(this.select.isInSelectingMode("row")){
-				this.select.drugSelectRow(e.rowIndex);
-			}else{
-				//this.select.setDrugCoverDivs(e.cellIndex, e.rowIndex);
-			}
-		}
-		//indirect selection
-		if(!e.cell && e.cellIndex < 0/*row selector view*/ || e.cell && (e.cell != this.rowSelectCell) && this.indirectSelection){
-			var _rowSelectCell = this.rowSelectCell;
-			_rowSelectCell && _rowSelectCell.onRowMouseOver && _rowSelectCell.onRowMouseOver(e);			
+		if(!e.cell || (!e.cell.isRowSelector && (!this.rowSelectCell || !this.rowSelectCell.disabled(e.rowIndex)))){
+			this.selection.clickSelectEvent(e);
 		}
 	},
-
-	onRowMouseOut: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onRowMouseOut()
-		if(this.isDndSelectEnable){
-			if(this.select.isInSelectingMode("row")){
-				this.select.drugSelectRow(e.rowIndex);
-			}
-		}
-	},
-
 	onRowContextMenu: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onRowContextMenu()
-		!this.edit.isEditing() && this.menus && this.showRowCellMenu(e);
-		//dojo.stopEvent(e);
+		if(!this.edit.isEditing() && this.menus){
+			this.showMenu(e);
+		}
 	},
-	
 	onSelectedRegionContextMenu: function(e){
 		// summary:
 		//		New - Event fired when a selected region context menu is accessed via mouse right click.
 		// e: Event
-		//		Decorated event object which contains reference to grid and info of selected 
+		//		Decorated event object which contains reference to grid and info of selected
 		//		regions(selection type - row|column, selected index - [...])
 		if(this.selectedRegionMenu){
 			this.selectedRegionMenu._openMyself({
 				target: e.target,
-				coords: "pageX" in e ? {
+				coords: e.keyCode !== dojo.keys.F10 && "pageX" in e ? {
 					x: e.pageX,
 					y: e.pageY
 				} : null
@@ -411,102 +162,51 @@ dojo.declare("dojox.grid.enhanced._Events", null, {
 			dojo.stopEvent(e);
 		}
 	},
-
-	onHeaderCellMouseOver: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onHeaderCellMouseOver()
-		if(e.cellNode){
-			dojo.addClass(e.cellNode, this.cellOverClass);
-			if(this.nestedSorting && !this._inResize(e.sourceView) && !this.pluginMgr.isFixedCell(e.cell) && !(this.isDndSelectEnable && this.select.isInSelectingMode("col"))){
-				this.addHoverSortTip(e);
-			}			
-			if(this.isDndSelectEnable){
-				if(this.select.isInSelectingMode("col")){
-					this.select.drugSelectColumn(e.cell.index);
-				}else{
-					this.select.clearDrugDivs();
-				}
-			}
-		}
-	},
-
 	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);
-			if(this.nestedSorting && !this.pluginMgr.isFixedCell(e.cell)){
-				if(this.focus.headerCellInFocus(e.cellIndex)){
-					this._toggleHighlight(e.sourceView, e, true);
-				}else{
-					this.removeHoverSortTip(e);					
-				}
-			}
 		}
 	},
-	
 	onHeaderCellMouseDown: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onHeaderCellMouseDown()
-		var node = !this.nestedSorting ? e.cellNode : this._getChoiceRegion(e.cellNode, e/*also contains choice info*/);
-		node && dojo.addClass(node, this.headerCellActiveClass);
-		if(this.nestedSorting && !e.selectChoice){ return; }
-		if(this.isDndSelectEnable){
-			this.focus._blurRowBar(); //fix DnD blur
-			try{
-				this.focus.focusHeaderNode(e.cellIndex, false, true);
-			}catch(e){
-				console.debug("Error fired in dojox.grid._event.js onHeaderCellMouseDown():" + e);
-			}
-			if(e.button == 2){
-				return;//always return for oncontextmenu event to only show menu
-			}
-			if(e.cellNode){
-				this.select.setInSelectingMode("col", true);
-				this.select.keepState = e.ctrlKey;
-				this.select.extendSelect = e.shiftKey;
-				if(this.select.extendSelect){
-					this.select.restorLastDragPoint();
-				} else {
-					this.select.drugSelectionStart.colIndex = e.cellIndex;
-				}
-				this.select.drugSelectColumn(e.cellIndex);
-			}
+		if(e.cellNode){//TBD - apply to selection region for nested sorting?
+			dojo.addClass(e.cellNode, this.headerCellActiveClass);
 		}
 	},
-	
 	onHeaderCellMouseUp: function(e){
 		// summary:
-		//		Overwritten, see dojox.grid._Events.onHeaderCellMouseUp()
-		var node = !this.nestedSorting ? e.cellNode : this._getChoiceRegion(e.cellNode, e/*also contains choice info*/);
-		if(node){
-			dojo.removeClass(node, this.headerCellActiveClass);
-			e.selectChoice && dojo.addClass(node, this.selectRegionHoverClass);
+		//		New event
+		if(e.cellNode){
+			dojo.removeClass(e.cellNode, this.headerCellActiveClass);
 		}
 	},
-
 	onHeaderCellClick: function(e){
 		// summary:
 		//		Overwritten, see dojox.grid._Events.onHeaderCellClick()
-		if(this.nestedSorting){
-			if((e.unarySortChoice || e.nestedSortChoice) && !this._inResize(e.sourceView)){
-				this.setSortIndex(e.cell.index, null, e);//nested sorting
-			}
-		}else if(!(this.indirectSelection && e.cell && e.cell.isRowSelector)){
-			this.setSortIndex(e.cell.index);//single sorting
+		//move focus to header.
+		this.focus.currentArea("header");
+		//invoke dojox.grid._Events.onHeaderCellClick()
+		if(!e.cell.isRowSelector){
+			this._events.onHeaderCellClick.call(this, e);
 		}
-		//invoke dojox.grid._Events.onHeaderClick()
-		dojo.hitch(this, this._events.onHeaderClick)(e);
+		//move mouse events to the focus manager.
+		this.focus.headerMouseEvent(e);
+	},
+	onRowSelectorMouseDown: function(e){
+		this.focus.focusArea("rowHeader", e);
 	},
 	
-	onHeaderContextMenu: function(e){
-		// summary:
-		//		Overwritten, see dojox.grid._Events.onHeaderContextMenu()
-		if(this.nestedSorting && this.headerMenu){
-			this._toggleHighlight(e.sourceView, e, true);
+	onRowSelectorMouseUp: function(e){},
+	
+	//triggered in _View, see Selector plugin
+	onMouseUpRow: function(e){
+		if(e.rowIndex != -1){
+			this.onRowMouseUp(e);
 		}
-		//invoke dojox.grid._Events.onHeaderContextMenu()		
-		dojo.hitch(this, this._events.onHeaderContextMenu)(e);
-	}
-});
+	},
+	onRowMouseUp: function(e){}
+});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/_FocusManager.js b/dojox/grid/enhanced/_FocusManager.js
new file mode 100644
index 0000000..e7b519e
--- /dev/null
+++ b/dojox/grid/enhanced/_FocusManager.js
@@ -0,0 +1,755 @@
+dojo.provide("dojox.grid.enhanced._FocusManager");
+
+dojo.declare("dojox.grid.enhanced._FocusArea",null,{
+	// summary:
+	//		This is a friend class of _FocusManager
+/*=====
+		// name: string
+		//		Name of this area.
+		name: "",
+		
+		// onFocus: function(event, step)
+		//		Called when this area logically gets focus.
+		//		event: Event object
+		//				May be unavailable, should check before use.
+		//		step: Integer
+		//				The distance in the tab sequence from last focused area to this area.
+		//		returns:
+		//				whether this area is successfully focused. If not, the next area will get focus.
+		onFocus: function(event, step){return true;},
+		
+		// onBlur: function(event, step)
+		//		Called when this area logically loses focus.
+		//		event: Event object
+		//				May be unavailable, should check before use.
+		//		step: Integer
+		//				The distance in the tab sequence from this area to the area to focus.
+		//		returns:
+		//				If Boolean, means whether this area has successfully blurred. If not, the next area to focus is still this one.
+		//				If String, means the next area to focus is given by this returned name.
+		onBlur: function(event, step){return true;},
+		
+		// onMove: function(rowStep, colStep, event)
+		//		Called when focus is moving around within this area.
+		//		rowStep: Integer
+		//		colStep: Integer
+		//		event: Event object
+		//				May be unavailable, should check before use.
+		onMove: function(rowStep, colStep, event){},
+		
+		// onKey: function(event, isBubble)
+		//		Called when some key is pressed when focus is logically in this area.
+		//		event: Event object
+		//		isBubble: Boolean
+		//				Whether is in bubble stage (true) or catch stage (false).
+		//		returns:
+		//				If you do NOT want the event to propagate any further along the area stack, return exactly false.
+		//				So if you return nothing (undefined), this event is still propagating.
+		onKey: function(event, isBubble){return true},
+		
+		// getRegions: function()
+		//		Define the small regions (dom nodes) in this area.
+		//		returns: Array of dom nodes.
+		getRegions: function(){},
+		
+		// onRegionFocus: function(event)
+		//		Connected to the onfocus event of the defined regions (if any)
+		onRegionFocus: function(event){},
+		
+		// onRegionBlur: function(event)
+		//		Connected to the onblur event of the defined regions (if any)
+		onRegionBlur: function(event){},
+=====*/
+	constructor: function(area, focusManager){
+		this._fm = focusManager;
+		this._evtStack = [area.name];
+		var dummy = function(){return true;};
+		area.onFocus = area.onFocus || dummy;
+		area.onBlur = area.onBlur || dummy;
+		area.onMove = area.onMove || dummy;
+		area.onKeyUp = area.onKeyUp || dummy;
+		area.onKeyDown = area.onKeyDown || dummy;
+		dojo.mixin(this, area);
+	},
+	move: function(rowStep, colStep, evt){
+		if(this.name){
+			var i, len = this._evtStack.length;
+			for(i = len - 1; i >= 0; --i){
+				if(this._fm._areas[this._evtStack[i]].onMove(rowStep, colStep, evt) === false){
+					return false;
+				}
+			}
+		}
+		return true;
+	},
+	_onKeyEvent: function(evt, funcName){
+		if(this.name){
+			var i, len = this._evtStack.length;
+			for(i = len - 1; i >= 0; --i){
+				if(this._fm._areas[this._evtStack[i]][funcName](evt, false) === false){
+					return false;
+				}
+			}
+			for(i = 0; i < len; ++i){
+				if(this._fm._areas[this._evtStack[i]][funcName](evt, true) === false){
+					return false;
+				}
+			}
+		}
+		return true;
+	},
+	keydown: function(evt){
+		return this._onKeyEvent(evt, "onKeyDown");
+	},
+	keyup: function(evt){
+		return this._onKeyEvent(evt, "onKeyUp");
+	},
+	contentMouseEventPlanner: function(){
+		return 0;
+	},
+	headerMouseEventPlanner: function(){
+		return 0;
+	}
+});
+dojo.declare("dojox.grid.enhanced._FocusManager", dojox.grid._FocusManager, {
+	_stopEvent: function(evt){
+		try{
+			if(evt && evt.preventDefault){
+				dojo.stopEvent(evt);
+			}
+		}catch(e){}
+	},
+	
+	constructor: function(grid){
+		this.grid = grid;
+		this._areas = {};
+		this._areaQueue = [];
+		this._contentMouseEventHandlers = [];
+		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.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)
+		});
+		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)
+		});
+		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),
+			contentMouseEventPlanner: function(evt, areas){ return -1; }
+		});
+		this.placeArea("header");
+		this.placeArea("content");
+		this.placeArea("editableCell");
+		this.placeArea("editableCell","above","content");
+	},
+	destroy: function(){
+		for(var name in this._areas){
+			var area = this._areas[name];
+			dojo.forEach(area._connects, dojo.disconnect);
+			area._connects = null;
+			if(area.uninitialize){
+				area.uninitialize();
+			}
+		}
+		this.inherited(arguments);
+	},
+	addArea: function(area){
+		if(area.name && dojo.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);
+			}
+			this._areas[area.name] = new dojox.grid.enhanced._FocusArea(area, this);
+			if(area.onHeaderMouseEvent){
+				this._headerMouseEventHandlers.push(area.name);
+			}
+			if(area.onContentMouseEvent){
+				this._contentMouseEventHandlers.push(area.name);
+			}
+		}
+	},
+	getArea: function(areaName){
+		return this._areas[areaName];
+	},
+	_bindAreaEvents: function(){
+		var area, hdl, areas = this._areas;
+		dojo.forEach(this._areaQueue, function(name){
+			area = areas[name];
+			if(!area._initialized && dojo.isFunction(area.initialize)){
+				area.initialize();
+				area._initialized = true;
+			}
+			if(area.getRegions){
+				area._regions = area.getRegions() || [];
+				dojo.forEach(area._connects || [], dojo.disconnect);
+				area._connects = [];
+				dojo.forEach(area._regions, function(r){
+					if(area.onRegionFocus){
+						hdl = dojo.connect(r, "onfocus", area.onRegionFocus);
+						area._connects.push(hdl);
+					}
+					if(area.onRegionBlur){
+						hdl = dojo.connect(r, "onblur", area.onRegionBlur);
+						area._connects.push(hdl);
+					}
+				});
+			}
+		});
+	},
+	removeArea: function(areaName){
+		var area = this._areas[areaName];
+		if(area){
+			this.ignoreArea(areaName);
+			var i = dojo.indexOf(this._contentMouseEventHandlers, areaName);
+			if(i >= 0){
+				this._contentMouseEventHandlers.splice(i, 1);
+			}
+			i = dojo.indexOf(this._headerMouseEventHandlers, areaName);
+			if(i >= 0){
+				this._headerMouseEventHandlers.splice(i, 1);
+			}
+			dojo.forEach(area._connects, dojo.disconnect);
+			if(area.uninitialize){
+				area.uninitialize();
+			}
+			delete this._areas[areaName];
+		}
+	},
+	currentArea: function(areaName, toBlurOld){
+		// summary:
+		//		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(cai != idx){
+				this.tabbingOut = false;
+				if(toBlurOld && cai >= 0 && cai < this._areaQueue.length){
+					this._areas[this._areaQueue[cai]].onBlur();
+				}
+				this._currentAreaIdx = idx;
+			}
+		}else{
+			return (cai < 0 || cai >= this._areaQueue.length) ?
+				new dojox.grid.enhanced._FocusArea({}, this) :
+				this._areas[this._areaQueue[this._currentAreaIdx]];
+		}
+		return null;
+	},
+	placeArea: function(name, pos, otherAreaName){
+		// summary:
+		//		Place the area refered by *name* at some logical position relative to an existing area.
+		// example:
+		//		placeArea("myarea","before"|"after",...)
+		//		placeArea("myarea","below"|"above",...)
+		if(!this._areas[name]){ return; }
+		var idx = dojo.indexOf(this._areaQueue,otherAreaName);
+		switch(pos){
+			case "after":
+				if(idx >= 0){ ++idx; }
+				//intentional drop through
+			case "before":
+				if(idx >= 0){
+					this._areaQueue.splice(idx,0,name);
+					break;
+				}
+				//intentional drop through
+			default:
+				this._areaQueue.push(name);
+				break;
+			case "above":
+				var isAbove = true;
+				//intentional drop through
+			case "below":
+				var otherArea = this._areas[otherAreaName];
+				if(otherArea){
+					if(isAbove){
+						otherArea._evtStack.push(name);
+					}else{
+						otherArea._evtStack.splice(0,0,name);
+					}
+				}
+		}
+	},
+	ignoreArea: function(name){
+		this._areaQueue = dojo.filter(this._areaQueue,function(areaName){
+			return areaName != name;
+		});
+	},
+	focusArea: function(/* int|string|areaObj */areaId,evt){
+		var idx;
+		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));
+		}
+		if(idx < 0){ idx = 0; }
+		var step = idx - this._currentAreaIdx;
+		this._gridBlured = false;
+		if(step){
+			this.tab(step, evt);
+		}else{
+			this.currentArea().onFocus(evt, step);
+		}
+	},
+	tab: function(step,evt){
+		//console.log("===========tab",step,"curArea",this._currentAreaIdx,"areaCnt",this._areaQueue.length);
+		this._gridBlured = false;
+		this.tabbingOut = false;
+		if(step === 0){
+			return;
+		}
+		var cai = this._currentAreaIdx;
+		var dir = step > 0 ? 1:-1;
+		if(cai < 0 || cai >= this._areaQueue.length){
+			cai = (this._currentAreaIdx += step);
+		}else{
+			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);
+			}
+		}
+		//console.log("target area:",cai);
+		for(; cai >= 0 && cai < this._areaQueue.length; cai += dir){
+			this._currentAreaIdx = cai;
+			if(this._areaQueue[cai] && this._areas[this._areaQueue[cai]].onFocus(evt,step)){
+				//console.log("final target area:",this._currentAreaIdx);
+				return;
+			}
+		}
+		//console.log("tab out");
+		this.tabbingOut = true;
+		if(step < 0){
+			this._currentAreaIdx = -1;
+			dijit.focus(this.grid.domNode);
+		}else{
+			this._currentAreaIdx = this._areaQueue.length;
+			dijit.focus(this.grid.lastFocusNode);
+		}
+	},
+	_onMouseEvent: function(type, evt){
+		var lowercase = type.toLowerCase(),
+			handlers = this["_" + lowercase + "MouseEventHandlers"],
+			res = dojo.map(handlers, function(areaName){
+				return {
+					"area": areaName,
+					"idx": this._areas[areaName][lowercase + "MouseEventPlanner"](evt, handlers)
+				};
+			}, this).sort(function(a, b){
+				return b.idx - a.idx;
+			}),
+			resHandlers = dojo.map(res, function(handler){
+				return res.area;
+			}),
+			i = res.length;
+		while(--i >= 0){
+			if(this._areas[res[i].area]["on" + type + "MouseEvent"](evt, resHandlers) === false){
+				return;
+			}
+		}
+	},
+	contentMouseEvent: function(evt){
+		this._onMouseEvent("Content", evt);
+	},
+	headerMouseEvent: function(evt){
+		this._onMouseEvent("Header", evt);
+	},
+	initFocusView: function(){
+		// summary:
+		//		Overwritten
+		this.focusView = this.grid.views.getFirstScrollingView() || this.focusView || this.grid.views.views[0];
+		this._bindAreaEvents();
+	},
+	isNavHeader: function(){
+		// summary:
+		//		Overwritten
+		//		Check whether currently navigating among column headers.
+		// return:
+		//		true - focus is on a certain column header | false otherwise
+		return this._areaQueue[this._currentAreaIdx] == "header";
+	},
+	previousKey: function(e){
+		// summary:
+		//		Overwritten
+		this.tab(-1,e);
+	},
+	nextKey: function(e){
+		// summary:
+		//		Overwritten
+		this.tab(1,e);
+	},
+	setFocusCell: function(/* Object */inCell, /* Integer */inRowIndex){
+		// summary:
+		//		Overwritten - focuses the given grid cell
+		if(inCell){
+			this.currentArea(this.grid.edit.isEditing() ? "editableCell" : "content", true);
+			//This is very slow when selecting cells!
+			//this.focusGridView();
+			this._focusifyCellNode(false);
+			this.cell = inCell;
+			this.rowIndex = inRowIndex;
+			this._focusifyCellNode(true);
+		}
+		this.grid.onCellFocus(this.cell, this.rowIndex);
+	},
+	doFocus: function(e){
+		// summary:
+		//		Overwritten
+		//		trap focus only for grid dom node
+		//		do not focus for scrolling if grid is about to blur
+		if(e && e.target == e.currentTarget && !this.tabbingOut){
+			if(this._gridBlured){
+				this._gridBlured = false;
+				if(this._currentAreaIdx < 0 || this._currentAreaIdx >= this._areaQueue.length){
+					this.focusArea(0, e);
+				}else{
+					this.focusArea(this._currentAreaIdx, e);
+				}
+			}
+		}else{
+			this.tabbingOut = false;
+		}
+		dojo.stopEvent(e);
+	},
+	_doBlur: function(){
+		this._gridBlured = true;
+	},
+	doLastNodeFocus: function(e){
+		// summary:
+		//		Overwritten
+		if(this.tabbingOut){
+			this.tabbingOut = false;
+		}else{
+			this.focusArea(-1, e);
+		}
+	},
+	_delayedHeaderFocus: function(){
+		// summary:
+		//		Overwritten
+		if(this.isNavHeader()){
+			this.focusHeader();
+		}
+	},
+	_delayedCellFocus: function(){
+		// summary:
+		//		Overwritten
+		this.currentArea("header", true);
+		this.focusArea(this._currentAreaIdx);
+	},
+	_changeMenuBindNode: function(oldBindNode, newBindNode){
+		var hm = this.grid.headerMenu;
+		if(hm && this._contextMenuBindNode == oldBindNode){
+			hm.unBindDomNode(oldBindNode);
+			hm.bindDomNode(newBindNode);
+			this._contextMenuBindNode = newBindNode;
+		}
+	},
+	//---------------Header Area------------------------------------------
+	focusHeader: function(evt, step){ //need a further look why these changes to parent's
+		// summary:
+		//		Overwritten
+		var didFocus = false;
+		this.inherited(arguments);
+		if(this._colHeadNode && dojo.style(this._colHeadNode, 'display') != "none"){
+			dijit.focus(this._colHeadNode);
+			this._stopEvent(evt);
+			didFocus = true;
+		}
+		return didFocus;
+	},
+	_blurHeader: function(evt,step){
+		// summary:
+		//		Overwritten
+		if(this._colHeadNode){
+			dojo.removeClass(this._colHeadNode, this.focusClass);
+		}
+		dojo.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
+		this._colHeadNode = this._colHeadFocusIdx = null;
+		return true;
+	},
+	_navHeader: function(rowStep, colStep, evt){
+		var colDir = colStep < 0 ? -1 : 1,
+			savedIdx = dojo.indexOf(this._findHeaderCells(), this._colHeadNode);
+		if(savedIdx >= 0 && (evt.shiftKey && evt.ctrlKey)){
+			this.colSizeAdjust(evt, savedIdx, colDir * 5);
+			return;
+		}
+		this.move(rowStep, colStep);
+	},
+	_onHeaderKeyDown: function(e, isBubble){
+		if(isBubble){
+			var dk = dojo.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);
+					}
+					break;
+			}
+		}
+		return true;
+	},
+	_setActiveColHeader: function(){
+		// summary:
+		//		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);
+	},
+	//---------------Content Area------------------------------------------
+	findAndFocusGridCell: function(){
+		// summary:
+		//		Overwritten
+		this._focusContent();
+	},
+	_focusContent: function(evt,step){
+		var didFocus = true;
+		var isEmpty = (this.grid.rowCount === 0); // If grid is empty this.grid.rowCount == 0
+		if(this.isNoFocusCell() && !isEmpty){
+			//skip all the hidden cells
+			for(var i = 0, cell = this.grid.getCell(0); cell && cell.hidden; cell = this.grid.getCell(++i)){}
+			this.setFocusIndex(0, cell ? i : 0);
+		}else if(this.cell && !isEmpty){
+			if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
+				// if rowNode for current index is undefined (likely as a result of a sort and because of #7304)
+				// scroll to that row
+				this.grid.scrollToRow(this.rowIndex);
+				this.focusGrid();
+			}else{
+				this.setFocusIndex(this.rowIndex, this.cell.index);
+			}
+		}else{
+			didFocus = false;
+		}
+		if(didFocus){ this._stopEvent(evt); }
+		return didFocus;
+	},
+	_blurContent: function(evt,step){
+		this._focusifyCellNode(false);
+		return true;
+	},
+	_navContent: function(rowStep, colStep, evt){
+		if((this.rowIndex === 0 && rowStep < 0) || (this.rowIndex === this.grid.rowCount - 1 && rowStep > 0)){
+			return;
+		}
+		this._colHeadNode = null;
+		this.move(rowStep, colStep, evt);
+		if(evt){
+			dojo.stopEvent(evt);
+		}
+	},
+	_onContentKeyDown: function(e, isBubble){
+		if(isBubble){
+			var dk = dojo.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.onRowClick(e);
+					dojo.stopEvent(e);
+					break;
+				case dk.PAGE_UP:
+					if(this.rowIndex !== 0){
+						if(this.rowIndex != s.firstVisibleRow + 1){
+							this._navContent(s.firstVisibleRow - this.rowIndex, 0);
+						}else{
+							this.grid.setScrollTop(s.findScrollTop(this.rowIndex - 1));
+							this._navContent(s.firstVisibleRow - s.lastVisibleRow + 1, 0);
+						}
+						dojo.stopEvent(e);
+					}
+					break;
+				case dk.PAGE_DOWN:
+					if(this.rowIndex + 1 != this.grid.rowCount){
+						dojo.stopEvent(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);
+					}
+					break;
+			}
+		}
+		return true;
+	},
+	//------------------editable content area-------------------------
+	_blurFromEditableCell: false,
+	_isNavigating: false,
+	_navElems: null,
+	_focusEditableCell: function(evt,step){
+		var didFocus = false;
+		if(this._isNavigating){
+			didFocus = true;
+		}else if(this.grid.edit.isEditing() && this.cell){
+			if(this._blurFromEditableCell || !this._blurEditableCell(evt, step)){
+				this.setFocusIndex(this.rowIndex,this.cell.index);
+				didFocus = true;
+			}
+			this._stopEvent(evt);
+		}
+		return didFocus;
+	},
+	_applyEditableCell: function(){
+		try{
+			this.grid.edit.apply();
+		}catch(e){
+			console.warn("_FocusManager._applyEditableCell() error:", e);
+		}
+	},
+	_blurEditableCell: function(evt,step){
+		this._blurFromEditableCell = false;
+		if(this._isNavigating){
+			var toBlur = true;
+			if(evt){
+				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;
+				toBlur = target == (step > 0 ? lastElem : firstElem);
+			}
+			if(toBlur){
+				this._isNavigating = false;
+				return "content";
+			}
+			return false;
+		}else if(this.grid.edit.isEditing() && this.cell){
+			if(!step || typeof step != "number"){ return false; }
+			var dir = step > 0 ? 1 : -1;
+			var cc = this.grid.layout.cellCount;
+			for(var cell, col = this.cell.index + dir; col >= 0 && col < cc; col += dir){
+				cell = this.grid.getCell(col);
+				if(cell.editable){
+					this.cell = cell;
+					this._blurFromEditableCell = true;
+					return false;
+				}
+			}
+			if((this.rowIndex > 0 || dir == 1) && (this.rowIndex < this.grid.rowCount || dir == -1)){
+				this.rowIndex += dir;
+				//this.cell = this.grid.getCell(0); //There must be an editable cell, so this is not necessary.
+				for(col = dir > 0 ? 0 : cc - 1; col >= 0 && col < cc; col += dir){
+					cell = this.grid.getCell(col);
+					if(cell.editable){
+						this.cell = cell;
+						break;
+					}
+				}
+				this._applyEditableCell();
+				return "content";
+			}
+		}
+		return true;
+	},
+	_initNavigatableElems: function(){
+		this._navElems = dijit._getTabNavigable(this.cell.getNode(this.rowIndex));
+	},
+	_onEditableCellKeyDown: function(e, isBubble){
+		var dk = dojo.keys,
+			g = this.grid,
+			edit = g.edit,
+			editApplied = false,
+			toPropagate = true;
+		switch(e.keyCode){
+			case dk.ENTER:
+				if(isBubble && edit.isEditing()){
+					this._applyEditableCell();
+					editApplied = true;
+					dojo.stopEvent(e);
+				}
+				//intentional drop through
+			case dk.SPACE:
+				if(!isBubble && this._isNavigating){
+					toPropagate = false;
+					break;
+				}
+				if(isBubble){
+					if(!this.cell.editable && this.cell.navigatable){
+						this._initNavigatableElems();
+						var toFocus = this._navElems.lowest || this._navElems.first;
+						if(toFocus){
+							this._isNavigating = true;
+							dijit.focus(toFocus);
+							dojo.stopEvent(e);
+							this.currentArea("editableCell", true);
+							break;
+						}
+					}
+					if(!editApplied && !edit.isEditing() && !g.pluginMgr.isFixedCell(this.cell)){
+						edit.setEditCell(this.cell, this.rowIndex);
+					}
+					if(editApplied){
+						this.currentArea("content", true);
+					}else if(this.cell.editable && g.canEdit()){
+						this.currentArea("editableCell", true);
+					}
+				}
+				break;
+			case dk.PAGE_UP:
+			case dk.PAGE_DOWN:
+				if(!isBubble && edit.isEditing()){
+					//prevent propagating to content area
+					toPropagate = false;
+				}
+				break;
+			case dk.ESCAPE:
+				if(!isBubble){
+					edit.cancel();
+					this.currentArea("content", true);
+				}
+		}
+		return toPropagate;
+	},
+	_onEditableCellMouseEvent: function(evt){
+		if(evt.type == "click"){
+			var cell = this.cell || evt.cell;
+			if(cell && !cell.editable && cell.navigatable){
+				this._initNavigatableElems();
+				if(this._navElems.lowest || this._navElems.first){
+					var target = dojo.isIE ? evt.srcElement : evt.target;
+					if(target != cell.getNode(evt.rowIndex)){
+						this._isNavigating = true;
+						this.focusArea("editableCell", evt);
+						dijit.focus(target);
+						return false;
+					}
+				}
+			}else if(this.grid.singleClickEdit){
+				this.currentArea("editableCell");
+				return false;
+			}
+		}
+		return true;
+	}
+});
diff --git a/dojox/grid/enhanced/_Plugin.js b/dojox/grid/enhanced/_Plugin.js
index 7a30cd2..6fd68f4 100644
--- a/dojox/grid/enhanced/_Plugin.js
+++ b/dojox/grid/enhanced/_Plugin.js
@@ -1,363 +1,163 @@
 dojo.provide("dojox.grid.enhanced._Plugin");
 
-dojo.require("dojox.grid.enhanced._Builder");
-dojo.require("dojox.grid.enhanced._Events");
-
+dojo.require("dojox.grid.EnhancedGrid");
 dojo.declare("dojox.grid.enhanced._Plugin", null, {
-	//	summary:
-	//		Singleton plugin manager 
+	// summary:
+	//		Base class for all plugins.
 	//
-	//	description:
-	//		Plugin manager is responsible for 
-	//		1. Loading required plugins
-	//		2. Handling collaboration and dependencies among plugins
-	//		3. Overwriting some default behavior of DataGrid
-	//		
-	//		Note: Mixin and method caching are used for #3, this might be refined once 
-	//		an overall plugin architecture is set up for DataGrid.
+	// description:
+	//		Provides common plugin functionality and basic life cycle management.
 	//
-	//      Some plugin dependencies:
-    //	   	- DnD plugin depends on NestedSorting plugin
-	//		- RowSelector should be used for DnD plugin. 
-	//		  e.g. <div dojoType="dojox.grid.EnhancedGrid"  plugins='{dnd: true, ...}}' rowSelector="20px" .../>
-	//		- "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
-		
-	//fixedCellNum: Integer
-	//		Number of fixed cells(columns), e.g. cell(column) of indirect selection is fixed and can't be moved	
-	fixedCellNum: -1,
-	
-	//funcMap: Object
-	//		Map for caching default DataGrid methods.
-	funcMap:{},
+	//		Each concrete plugin must have a name field and is responsible for registering itself to the global plugin registry
+	//		e.g. for dnd plugin:
+	// |		dojox.grid.EnhancedGrid.registerPlugin("dnd" /*plugin name*/,
+	// |												dojox.grid.enhanced.plugins.DnD /*full class name of a plugin*/
+	// |												{"preInit": false, "dependency": ["nestedSorting"]} /*properties*/);
+	//
+	//		[Keywords] of plugin properties(case sensitive)
+	//		- "preInit": boolean, whether a plugin should be created before EnhancedGrid.postCreate(),
+	//		   false by default(plugins are created after EnhancedGrid.postCreate()).
+	//		- "dependency": array or string, plugin(s) indicated by "dependency" will be created before the current one.
+	//		   Note: recursive cycle dependencies are not supported e.g. following dependency is invalid:
+	//		   pluginA -> pluginB -> pluginA
+	//
+	// example:
+	//		1. Customize default DnD plugin
+	// |	dojo.declare("mygrid.MyDnD", dojox.grid.enhanced.plugins.DnD, {
+	// |		name:"dnd" //still reuse the plugin name
+	// |		constructor: function(inGrid, option){ ... }
+	// |	});
+	// |	dojox.grid.EnhancedGrid.registerPlugin("dnd", mygrid.MyDnD);
+	//
+	//		2. Add new plugin - PluginA
+	// |	dojo.declare("mygrid.PluginA", dojox.grid.enhanced._Plugin, {
+	// |		name: "pA",
+	// |		constructor: function(inGrid, option){ ... }
+	// |	});
+	// |	dojox.grid.EnhancedGrid.registerPlugin("pA",mygrid.PluginA);
+	//
+	//		3. Use plugins
+	// |	dojo.require("mygrid.MyDnD");
+	// |	dojo.require("mygrid.PluginA");
+	
+	// |	<script type="text/javascript">
+	// |		var grid = new dojox.grid.EnhancedGrid(
+	// |		{plugins: {dnd:true, pA:true}, ... }, dojo.byId("gridDiv"));
+	// |		grid.startup();
+	// |	</script>
 
-	constructor: function(inGrid){
-		this.grid = inGrid;
-		this._parseProps(this.grid);
-	},
-	
-	_parseProps: function(grid){
-		// summary:
-		//		Parse plugins properties
-		// grid: Grid
-		//		Grid this plugin manager belongs to
-		
-		//mixin all plugin properties into Grid
-		grid.plugins && dojo.mixin(grid, grid.plugins);
-		
-		//cell(column) of indirect selection
-		grid.rowSelectCell = null;
-		
-		//DnD plugin depends on NestedSorting plugin
-		grid.dnd && (grid.nestedSorting = true);
-		
-		//"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
-		(grid.dnd || grid.indirectSelection) && (grid.columnReordering = false);
-	},
+	//name: String
+	//		Plugin name, e.g. 'nestedSorting', 'dnd'...
+	name: 'plugin',
 	
-	preInit: function(){
-		// summary:
-		//		Pre initialization, some plugins must be loaded before DataGrid.postCreate(). 
-		//		See EnhancedGrid.postCreate()
-		var grid = this.grid;
-		//load Indirect Selection plugin
-		grid.indirectSelection && (new (this.getPluginClazz('dojox.grid.enhanced.plugins.IndirectSelection'))(grid));
-		if(grid.dnd && (!grid.rowSelector || grid.rowSelector=="false")) {
-			//RowSelector should be used for DnD plugin.
-			grid.rowSelector = "20px";
-		}
-		//overwrite header and content builders
-		if(grid.nestedSorting){
-			dojox.grid._View.prototype._headerBuilderClass = dojox.grid.enhanced._HeaderBuilder;			
-		}
-		dojox.grid._View.prototype._contentBuilderClass = dojox.grid.enhanced._ContentBuilder;
-	},
-	
-	postInit: function(){
-		// summary:
-		//		Post initialization, by default, plugins are loaded after DataGrid.postCreate(). 
-		//		See EnhancedGrid.postCreate()
-		var grid = this.grid;
-		
-		//overwrite some default events of DataGrid
-		new dojox.grid.enhanced._Events(grid);
-		
-		//load Menu plugin
-		grid.menus && (new (this.getPluginClazz('dojox.grid.enhanced.plugins.Menu'))(grid));
-		
-		//load NestedSorting plugin
-		grid.nestedSorting && (new (this.getPluginClazz('dojox.grid.enhanced.plugins.NestedSorting'))(grid));
-		
-		//load DnD plugin
-		if(grid.dnd){
-			grid.isDndSelectEnable = grid.dnd;
-			//by default disable cell selection for EnhancedGrid M1
-			grid.dndDisabledTypes =  ["cell"];
-			//new dojox.grid.enhanced.dnd._DndMovingManager(grid);			
-			new (this.getPluginClazz('dojox.grid.enhanced.plugins.DnD'))(grid);
-		}
-		
-		//TODO - see if any better ways for this
-		//fix inherit issue for mixin, an null/undefined exception will be thrown from the "this.inherited(...)" in
-		//the following functions, like saying there is no "startup" in "this" scope
-		dojo.isChrome < 3 && (grid.constructor.prototype.startup = grid.startup);
-		//grid.constructor.prototype.onStyleRow = grid.onStyleRow;
-		
-		//get fixed cell(column) number
-		this.fixedCellNum = this.getFixedCellNumber();
-		
-		//overwrite some default methods of DataGrid by method caching
-		this.grid.plugins && this._bindFuncs();
-	},
-	
-	getPluginClazz: function(clazzStr){
-		//summary:
-		//		Load target plugin which must be already required (dojo.require(..))
-		//clazzStr: String
-		//		Plugin class name
-		var clazz = dojo.getObject(clazzStr);
-		if(clazz){
-			return clazz;
-		}
-		throw new Error('Please make sure class "' + clazzStr + '" is required.');			
-	},
+	//grid: Object
+	//		Grid that the plugin belongs to
+	grid: null,
+
+	//option: Object
+	//		Plugin properties - leveraged with default and user specified properties.
+	//		e.g. for dnd plugin, it may look like {"class": dojox.grid.enhanced.plugins.DnD, "dependency": ["nestedSorting"], ...}
+	option: {},
+
+	//_connects: Array
+	//		List of all connections.
+	_connects: [],
 	
-	isFixedCell: function(cell) {
-		//summary:
-		//		See if target cell(column) is fixed or not.
-		//cell: Object
-		//		Target cell(column)
-		//return: Boolean
-		//		True - fixed| False - not fixed
+	//_subscribes: Array
+	//		List of all subscribes.
+	_subscribes: [],
 
-		//target cell can use Boolean attributes named "isRowSelector" or "positionFixed" to mark it's a fixed cell(column)
-		return cell && (cell.isRowSelector || cell.positionFixed);
-	},
+	//privates: Object
+	//		Private properties/methods shouldn't be mixin-ed anytime.
+	privates: {},
 	
-	getFixedCellNumber: function(){
-		//summary:
-		//		See if target cell(column) is fixed or not.
-		//return: Number
-		//		True - fixed| False - not fixed
-		if(this.fixedCellNum >= 0){
-			return this.fixedCellNum;
-		}
-		var i = 0;
-		dojo.forEach(this.grid.layout.cells, dojo.hitch(this, function(cell){
-			this.isFixedCell(cell) && (i++);
-		}));
-		return i;
+	constructor: function(inGrid, option){
+		this.grid = inGrid;
+		this.option = option;
+		this._connects = [];
+		this._subscribes = [];
+		this.privates = dojo.mixin({},dojox.grid.enhanced._Plugin.prototype);
+		this.init();
 	},
 	
-	inSingleSelection: function(){
-		//summary:
-		//		See if Grid is in single selection mode
-		//return: Boolean
-		//		True - in single selection mode | False - not in single selection mode
-		return this.grid.selectionMode && this.grid.selectionMode == 'single';
-	},
+	init: function(){},
 	
-	needUpdateRow: function(){
-		//summary:
-		//		See if needed to update row. See this.updateRow()
-		//return: Boolean
-		//		True - need update row | False - don't update row
-		
-		//always true when either indirect selection or DnD disabled
-		return ((this.grid.indirectSelection || this.grid.isDndSelectEnable) ? this.grid.edit.isEditing() : true);		
-	},				
+	onPreInit: function(){},
 	
-	_bindFuncs: function(){
-		//summary:
-		//		Overwrite some default methods of DataGrid by method caching		
-		dojo.forEach(this.grid.views.views, dojo.hitch(this, function(view){
-			//add more events handler - _View
-			dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", ['mouseup', 'mousemove']);
-			dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
-			
-			//overwrite _View.setColumnsWidth()
-			this.funcMap[view.id + '-' +'setColumnsWidth'] = view.setColumnsWidth;
-			view.setColumnsWidth =  this.setColumnsWidth;
-			
-			//overwrite _View._getHeaderContent()
-			this.grid.nestedSorting && (view._getHeaderContent = this.grid._getNestedSortHeaderContent);
-			
-			//overwrite _View.setScrollTop(),
-			//#10273 fix of base DataGrid seems to bring some side effects to Enhanced Grid, 
-			//TODO - need a more close look post v.1.4 rather than simply overwrite it
-			this.grid.dnd && (view.setScrollTop = this.setScrollTop);
-		}));
-		
-		//overwrite _FocusManager.nextKey()
-		this.funcMap['nextKey'] = this.grid.focus.nextKey;
-		this.grid.focus.nextKey = this.nextKey;
-
-		//overwrite _FocusManager.previousKey()
-		this.funcMap['previousKey'] = this.grid.focus.previousKey;
-		this.grid.focus.previousKey = this.previousKey;
-
-		//overwrite _Scroller.renderPage()
-		if(this.grid.indirectSelection){
-			this.funcMap['renderPage'] = this.grid.scroller.renderPage;
-			this.grid.scroller.renderPage = this.renderPage;	
-			this.funcMap['measurePage'] = this.grid.scroller.measurePage;
-			this.grid.scroller.measurePage = this.measurePage;	
-		}
-		
-		//overwrite _Grid.updateRow()
-		this.funcMap['updateRow'] = this.grid.updateRow;		
-		this.grid.updateRow = this.updateRow;	
-		
-		if(this.grid.nestedSorting && dojox.grid.cells._Widget){			
-			 dojox.grid.cells._Widget.prototype.sizeWidget = this.sizeWidget;
-		}
-		dojox.grid.cells._Base.prototype.getEditNode = this.getEditNode;
-		dojox.grid._EditManager.prototype.styleRow = function(inRow){};		
-	},
+	onPostInit: function(){},
 	
-	setColumnsWidth: function(width){
-		//summary:
-		//		Overwrite _View.setColumnsWidth(), "this" - _View scope
-		//		Fix rtl issue in IE.
-		if(dojo.isIE && !dojo._isBodyLtr()) {
-			this.headerContentNode.style.width = width + 'px';
-			this.headerContentNode.parentNode.style.width = width + 'px';			
-		}
-		//invoke _View.setColumnsWidth()
-		dojo.hitch(this, this.grid.pluginMgr.funcMap[this.id + '-' +'setColumnsWidth'])(width);
-	},
+	onStartUp: function(){},
 	
-	previousKey: function(e){
-		//summary:
-		//		Overwrite _FocusManager.previousKey(), "this" - _FocusManager scope		
-		var isEditing = this.grid.edit.isEditing();
-		if(!isEditing && !this.isNavHeader() && !this._isHeaderHidden()) {
-			if(!this.grid.isDndSelectEnable){
-				this.focusHeader();
-			}else{
-				if(!this.isRowBar()){
-					this.focusRowBar();
-				} else {
-					this._blurRowBar();
-					this.focusHeader();
-				}
+	connect: function(obj, event, method){
+		// summary:
+		//		Connects specified obj/event to specified method of this object.
+		// example:
+		//	|	var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+		//	|	// when foo.bar() is called, call the listener in the scope of plugin
+		//	|	plugin.connect(foo, "bar", function(){
+		//	|		console.debug(this.xxx());//"this" - plugin scope
+		//	|	});
+		var conn = dojo.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){
+			if(conn == handle){
+				dojo.disconnect(handle);
+				conns.splice(i, 1);
+				return true;
 			}
-			dojo.stopEvent(e);
-			return;
-		}
-		//invoke _FocusManager.previousKey()
-		dojo.hitch(this, this.grid.pluginMgr.funcMap['previousKey'])(e);
+			return false;
+		});
 	},
-
-	nextKey: function(e) {
-		//summary:
-		//		Overwrite _FocusManager.nextKey(), "this" - _FocusManager scope		
-		var isEmpty = this.grid.rowCount == 0;
-		var isRootEvt = (e.target === this.grid.domNode);
-		if(!isRootEvt && this.grid.isDndSelectEnable && this.isNavHeader()){
-			// if tabbing from col header, then go to grid proper. If grid is empty this.grid.rowCount == 0
-			this._colHeadNode = this._colHeadFocusIdx= null;
-			this.focusRowBar();
-			return;
-		}else if(!isRootEvt && (!this.grid.isDndSelectEnable && this.isNavHeader()) || (this.grid.isDndSelectEnable && this.isRowBar())){
-			this._colHeadNode = this._colHeadFocusIdx= null;
-			if (this.grid.isDndSelectEnable) {
-				this._blurRowBar();
-			}
-			if(this.isNoFocusCell() && !isEmpty){
-				this.setFocusIndex(0, 0);
-			}else if(this.cell && !isEmpty){
-				if(this.focusView && !this.focusView.rowNodes[this.rowIndex]){
-				// if rowNode for current index is undefined (likely as a result of a sort and because of #7304) 
-				// scroll to that row
-					this.grid.scrollToRow(this.rowIndex);
-				}
-				this.focusGrid();
-			}else if(!this.findAndFocusGridCell()){
-				this.tabOut(this.grid.lastFocusNode);
+	subscribe: function(topic, method){
+		// summary:
+		//		Subscribes to the specified topic and calls the specified method
+		//		of this object.
+		// example:
+		//	|	var plugin = new dojox.grid.enhanced._Plugin(grid,"myPlugin",{...});
+		//	|	// when /my/topic is published, call the subscriber in the scope of plugin
+		//	|	// with passed parameter - "v"
+		//	|	plugin.subscribe("/my/topic", function(v){
+		//	|		console.debug(this.xxx(v));//"this" - plugin scope
+		//	|	});
+		var subscribe = dojo.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){
+			if(subscribe == handle){
+				dojo.unsubscribe(handle);
+				subscribes.splice(i, 1);
+				return true;
 			}
-			return;
-		}
-		//invoke _FocusManager.nextKey()
-		dojo.hitch(this, this.grid.pluginMgr.funcMap['nextKey'])(e);
-	},
-	
-	renderPage: function(inPageIndex){
-		//summary:
-		//		Overwrite _Scroller.renderPage(), "this" - _Scroller scope
-		//		To add progress cursor when rendering the indirect selection cell(column) with checkbox
-		for(var i=0, j=inPageIndex*this.rowsPerPage; (i<this.rowsPerPage)&&(j<this.rowCount); i++, j++){}
-		this.grid.lastRenderingRowIdx = --j;
-		dojo.addClass(this.grid.domNode, 'dojoxGridSortInProgress');
-		
-		//invoke _Scroller.renderPage()
-		dojo.hitch(this, this.grid.pluginMgr.funcMap['renderPage'])(inPageIndex);
-	},
-	
-	measurePage: function(inPageIndex){
-		//summary:
-		//		Overwrite _Scroller.measurePage(), "this" - _Scroller scope
-		//		Fix a regression similar as #5552
-		//		invoke _Scroller.measurePage()
-		var pageHeight = dojo.hitch(this, this.grid.pluginMgr.funcMap['measurePage'])(inPageIndex);
-		return (!dojo.isIE || this.grid.rowHeight || pageHeight > this.rowsPerPage * this.grid.minRowHeight) ? pageHeight : undefined;
+			return false;
+		});
 	},
-	
-	updateRow: function(inRowIndex){
-		//summary:
-		//		Overwrite _Scroller.renderPage(), "this" - _Grid scope
-		var caller = arguments.callee.caller;
-		if(caller.nom == "move" && /* caller.ctor.prototype.declaredClass == "dojox.grid._FocusManager" && */ !this.pluginMgr.needUpdateRow()){
-			//if is called from dojox.grid._FocusManager.move(), and no need to update row, then return
-			return;
-		}
-		//invoke _Grid.updateRow()
-		dojo.hitch(this, this.pluginMgr.funcMap['updateRow'])(inRowIndex);
-	},
-	
-	getEditNode: function(inRowIndex) {
-		//summary:
-		//		Overwrite dojox.grid.cells._Base.getEditNode, "this" - _Base scope
-		return ((this.getNode(inRowIndex) || 0).firstChild || 0).firstChild || 0;
-	},
-	
-	sizeWidget: function(inNode, inDatum, inRowIndex){
-		//summary:
-		//		Overwrite dojox.grid.cells._Widget.sizeWidget, "this" - _Widget scope
-		var p = this.getNode(inRowIndex).firstChild, 
-		box = dojo.contentBox(p);
-		dojo.marginBox(this.widget.domNode, {w: box.w});
-	},
-	
-	setScrollTop: function(inTop){
-		//summary:
-		//		Overwrite dojox.grid._View.setScrollTop, "this" - _View scope
-		this.lastTop = inTop;
-		this.scrollboxNode.scrollTop = inTop;
-		return this.scrollboxNode.scrollTop;
+	onSetStore: function(store){
+		// summary:
+		//		Called when store is changed.
 	},
-	
-	getViewByCellIdx: function(cellIdx){
-		//summary:
-		//		Find view that contains the cell with 'cellIdx'
-		//cellIdx: Integer
-		//		Index of target cell
-		//return: Object
-		//		Matched view
-		var cellMatched = function(cells){
-			var j = 0, matched = false;
-			for(; j < cells.length; j++){
-				if(dojo.isArray(cells[j])){
-					if(cellMatched(cells[j])){ return true;}
-				}else if(cells[j].index == cellIdx){
-					return true;
-				}
-			}
-		};
-		var i = 0, views = this.grid.views.views;
-		for(; i < views.length; i++){
-			cells = views[i].structure.cells;
-			if(cellMatched(cells)){ return views[i]; }
-		}
-		return null;
-	}	
+	destroy: function(){
+		// summary:
+		//		Destroy all resources.
+		dojo.forEach(this._connects, dojo.disconnect);
+		dojo.forEach(this._subscribes, dojo.unsubscribe);
+		delete this._connects;
+		delete this._subscribes;
+		delete this.option;
+		delete this.privates;
+		//console.log('Plugin [', this.name, '].destroy() executed!');
+	}
 });
+
+//Each plugin is responsible for registering itself
+// e.g. for DnD plugin(name:'dnd'):
+// |	dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*class*/,
+// |		{"dependency": ["nestedSorting"]}/*Optional - properties*/);
diff --git a/dojox/grid/enhanced/_PluginManager.js b/dojox/grid/enhanced/_PluginManager.js
new file mode 100644
index 0000000..4537145
--- /dev/null
+++ b/dojox/grid/enhanced/_PluginManager.js
@@ -0,0 +1,264 @@
+dojo.provide("dojox.grid.enhanced._PluginManager");
+
+dojo.require("dojox.grid.enhanced._Events");
+dojo.require("dojox.grid.enhanced._FocusManager");
+
+dojo.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
+	//
+	//      Some plugin dependencies:
+	//		- "columnReordering" attribute won't work when either DnD or Indirect Selections plugin is on.
+		
+	//_options: Object
+	//		Normalized plugin options
+	_options: null,
+
+	//_plugins: Array
+	//		Plugin list
+	_plugins: null,
+
+	//_connects: Array
+	//		Connection list
+	_connects: null,
+
+	constructor: function(inGrid){
+		this.grid = inGrid;
+		this._store = inGrid.store;
+		this._options = {};
+		this._plugins = [];
+		this._connects = [];
+		this._parseProps(this.grid.plugins);
+		
+		inGrid.connect(inGrid, "_setStore", dojo.hitch(this, function(store){
+			if(this._store !== store){
+				this.forEach('onSetStore', [store, this._store]);
+				this._store = store;
+			}
+		}));
+	},
+	startup: function(){
+		this.forEach('onStartUp');
+	},
+	preInit: function(){
+		// summary:
+		//		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._init(true);
+		this.forEach('onPreInit');
+	},
+	postInit: function(){
+		// summary:
+		//		Load plugins after DataGrid.postCreate() - the default phase when plugins are created
+		//		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)));
+			
+		if(this._plugins.length > 0){
+			var edit = this.grid.edit;
+			if(edit){ edit.styleRow = function(inRow){}; }
+		}
+		this.forEach('onPostInit');
+	},
+	forEach: function(func, args){
+		dojo.forEach(this._plugins, function(p){
+			if(!p || !p[func]){ return; }
+			p[func].apply(p, args ? args : []);
+		});
+	},
+	_parseProps: function(plugins){
+		// summary:
+		//		Parse plugins properties
+		// plugins: Object
+		//		Plugin properties defined by user
+		if(!plugins){ return; }
+		
+		var p, loading = {}, options = this._options, grid = this.grid;
+		var registry = dojox.grid.enhanced._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);
+			}
+		}
+		//"columnReordering" attribute won't work when either DnD or Indirect Selections plugin is used.
+		if(options.dnd || options.indirectSelection){
+			options.columnReordering = false;
+		}
+		
+		//mixin all plugin properties into Grid
+		dojo.mixin(grid, options);
+	},
+	_normalize: function(p, plugins, registry, loading){
+		// summary:
+		//		Normalize plugin properties especially the dependency chain
+		// p: String
+		//		Plugin name
+		// plugins: Object
+		//		Plugin properties set by user
+		// registry: Object
+		//		The global plugin registry
+		// loading: Object
+		//		Map for checking process state
+		if(!registry[p]){ throw new Error('Plugin ' + p + ' is required.');}
+		
+		if(loading[p]){ throw new Error('Recursive cycle dependency is not supported.'); }
+		
+		var options = this._options;
+		if(options[p]){ return options[p]; }
+		
+		loading[p] = true;
+		//TBD - more strict conditions?
+		options[p] = dojo.mixin({}, registry[p], dojo.isObject(plugins[p]) ? plugins[p] : {});
+		
+		var dependencies = options[p]['dependency'];
+		if(dependencies){
+			if(!dojo.isArray(dependencies)){
+				dependencies = options[p]['dependency'] = [dependencies];
+			}
+			dojo.forEach(dependencies, function(dependency){
+				if(!this._normalize(dependency, plugins, registry, loading)){
+					throw new Error('Plugin ' + dependency + ' is required.');
+				}
+			}, this);
+		}
+		delete loading[p];
+		return options[p];
+	},
+	_init: function(pre){
+		// summary:
+		//		Find appropriate plugins and load them
+		// pre: Boolean
+		//		True - preInit | False - postInit(by default)
+		var p, preInit, options = this._options;
+		for(p in options){
+			preInit = options[p]['preInit'];
+			if((pre ? preInit : !preInit) && options[p]['class'] && !this.pluginExisted(p)){
+				this.loadPlugin(p);
+			}
+		}
+	},
+	loadPlugin: function(name){
+		// summary:
+		//		Load required plugin("name")
+		// name: String
+		//		Plugin name
+		// return: Object
+		//		The newly loaded plugin
+		var option = this._options[name];
+		if(!option){ return null; } //return if no plugin option
+		
+		var plugin = this.getPlugin(name);
+		if(plugin){ return plugin; } //return if plugin("name") already existed
+		
+		var dependencies = option['dependency'];
+		dojo.forEach(dependencies, function(dependency){
+			if(!this.loadPlugin(dependency)){
+				throw new Error('Plugin ' + dependency + ' is required.');
+			}
+		}, this);
+		var cls = option['class'];
+		delete option['class'];//remove it for safety
+		plugin = new this.getPluginClazz(cls)(this.grid, option);
+		this._plugins.push(plugin);
+		return plugin;
+	},
+	_initView: function(view){
+		// summary:
+		//		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']);
+	},
+	pluginExisted: function(name){
+		// summary:
+		//		Check if plugin("name") existed
+		// name: String
+		//		Plugin name
+		// return: Boolean
+		//		True - existed | False - not existed
+		return !!this.getPlugin(name);
+	},
+	getPlugin: function(name){
+		// summary:
+		//		Get plugin("name")
+		// name: String
+		//		Plugin name
+		// return: Object
+		//		Plugin instance
+		var plugins = this._plugins;
+		name = name.toLowerCase();
+		for(var i = 0, len = plugins.length; i < len; i++){
+			if(name == plugins[i]['name'].toLowerCase()){
+				return plugins[i];
+			}
+		}
+		return null;
+	},
+	getPluginClazz: function(clazz){
+		// summary:
+		//		Load target plugin which must be already required (dojo.require(..))
+		// clazz: class | String
+		//		Plugin class
+		if(dojo.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);
+			if(!cls){ throw new Error(errorMsg); }
+			return cls;
+		}catch(e){
+			throw new Error(errorMsg);
+		}
+	},
+	isFixedCell: function(cell){
+		// summary:
+		//		See if target cell(column) is fixed or not.
+		// cell: Object
+		//		Target cell(column)
+		// return: Boolean
+		//		True - fixed| False - not fixed
+
+		//target cell can use Boolean attributes named "isRowSelector" or "fixedPos" to mark it's a fixed cell(column)
+		return cell && (cell.isRowSelector || cell.fixedPos);
+	},
+	destroy: function(){
+		// summary:
+		//		Destroy all resources
+		dojo.forEach(this._connects, dojo.disconnect);
+		this.forEach('destroy');
+		if(this.grid.unwrap){
+			this.grid.unwrap();
+		}
+		delete this._connects;
+		delete this._plugins;
+		delete this._options;
+	}
+});
+
+dojox.grid.enhanced._PluginManager.registerPlugin = function(clazz, props){
+		// summary:
+		//		Register plugins - TODO, a better way rather than global registry?
+		// clazz: String
+		//		Full class name, e.g. "dojox.grid.enhanced.plugins.DnD"
+		// props: Object - Optional
+		//		Plugin properties e.g. {"dependency": ["nestedSorting"], ...}
+	if(!clazz){
+		console.warn("Failed to register plugin, class missed!");
+		return;
+	}
+	var cls = dojox.grid.enhanced._PluginManager;
+	cls.registry = cls.registry || {};
+	cls.registry[clazz.prototype.name]/*plugin name*/ = dojo.mixin({"class": clazz}, (props ? props : {}));
+};
diff --git a/dojox/grid/enhanced/dnd/_DndBuilder.js b/dojox/grid/enhanced/dnd/_DndBuilder.js
deleted file mode 100644
index d3e0793..0000000
--- a/dojox/grid/enhanced/dnd/_DndBuilder.js
+++ /dev/null
@@ -1,36 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndBuilder");
-dojo.declare("dojox.grid.enhanced.dnd._DndBuilder", null, {
-	//summary:
-	//		This class declaration is used to be mixed in to dojox.grid._Builder
-	//		to enable the _Builder to handle mouse up event for DND feature
-	
-	domouseup:function(e){
-	//summary:
-	//		Handle when there is a mouse up event 
-	//e: Event
-	//		The mouse up event
-		if(this.grid.select.isInSelectingMode("col")) {
-			this.grid.nestedSorting ? this.grid.focus.focusSelectColEndingHeader(e) : this.grid.focus.focusHeaderNode(e.cellIndex);
-		}
-		if (e.cellNode)
-			this.grid.onMouseUp(e);
-		this.grid.onMouseUpRow(e)
-	}
-});
-
-dojo.declare("dojox.grid.enhanced.dnd._DndHeaderBuilder", null, {
-	//summary:
-	//		This class declaration is used to be mixed in to dojox.grid._HeadBuilder
-	//		to enable the _HeadBuilder to handle mouse up event for DND feature
-	
-	domouseup: function(e){
-		//summary:
-		//		Handle when there is a mouse up event 
-		//e: Event
-		//		The mouse up event
-		if(this.grid.select.isInSelectingMode("col")) {
-			this.grid.nestedSorting ? this.grid.focus.focusSelectColEndingHeader(e) : this.grid.focus.focusHeaderNode(e.cellIndex);
-		}
-		this.grid.onMouseUp(e);
-	}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndEvents.js b/dojox/grid/enhanced/dnd/_DndEvents.js
deleted file mode 100644
index 8624f35..0000000
--- a/dojox/grid/enhanced/dnd/_DndEvents.js
+++ /dev/null
@@ -1,84 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndEvents");
-
-dojo.declare("dojox.grid.enhanced.dnd._DndEvents", null, {
-	//summary:
-	//		This class declaration is used to be mixed in to dojox.grid._Event
-	//		to enable the _Event to handle several events for DND feature
-
-	//rowActiveClass: String
-	// 		css class to apply to grid rows when activated(mouse down)	
-	rowBarActiveClass: 'dojoxGridRowBarActive',
-		
-	onMouseUp: function(e){
-		// summary:
-		//		Event fired when mouse is up inside grid.
-		// e: Event
-		//		Decorated event object that contains reference to grid, cell, and rowIndex		
-		e.rowIndex == -1 ? this.onHeaderCellMouseUp(e) : this.onCellMouseUp(e);
-		this.select.resetStartPoint();
-		this.select.clearInSelectingMode();
-		!isNaN(e.rowIndex) && e.cellIndex == -1 && this.focus.focusRowBarNode(e.rowIndex);
-	},
-	
-	onMouseUpRow: function(e){
-		// summary:
-		//		Event fired when mouse is up inside grid row
-		// e: Event
-		//		Decorated event object that contains reference to grid, cell, and rowIndex
-		if (this.dndSelectable) {
-			//waiting ...
-		} else if(e.rowIndex != -1)
-			this.onRowMouseUp(e);
-	},
-	
-	onCellMouseUp: function(e){
-		// summary:
-		//		Event fired when mouse is up in a cell.
-		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
-		if (e.cellIndex > this.select.exceptColumnsTo) {
-			this.select.setInSelectingMode("cell", true);
-		}
-	},
-
-	onRowHeaderMouseDown: function(e) {		
-		//summary:
-		//		Handle when there is a mouse down event on row header (row bar), 
-		//		Call the dnd select to add the row to select
-		//e: Event
-		//		The mouse down event
-		//blur column header focus
-		this.focus._colHeadNode = this.focus._colHeadFocusIdx = null;
-		this.focus.focusRowBarNode(e.rowIndex);	
-		if(e.button == 2) {
-			return;//alwarys return for oncontextmenu event to only show menu
-		}
-		this.select.setInSelectingMode("row", true);
-		this.select.keepState = e.ctrlKey && !this.pluginMgr.inSingleSelection();
-		this.select.extendSelect = e.shiftKey;
-		this.select.setDrugStartPoint(-1, e.rowIndex);
-		if(this.select.extendSelect && !this.pluginMgr.inSingleSelection()){
-			this.select.restorLastDragPoint();
-		} 
-		this.select.drugSelectRow(e.rowIndex);
-		dojo.addClass(e.rowNode, this.rowBarActiveClass);
-		dojo.stopEvent(e);
-	},
-	
-	onRowHeaderMouseUp: function(e) {
-		//summary:
-		//		Handle when there is a mouse up event on row header (row bar), 
-		//e: Event
-		//		The mouse up event
-		this.onMouseUp(e);
-		dojo.removeClass(e.rowNode, this.rowBarActiveClass);
-	},
-	
-	onRowMouseUp: function(e){
-		// summary:
-		//		Event fired when mouse is up in a row.
-		// e: Event
-		// 		Decorated event object which contains reference to grid, cell, and rowIndex
-		this.select.setInSelectingMode("row", false);
-	}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndFocusManager.js b/dojox/grid/enhanced/dnd/_DndFocusManager.js
deleted file mode 100644
index 53a2b29..0000000
--- a/dojox/grid/enhanced/dnd/_DndFocusManager.js
+++ /dev/null
@@ -1,127 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndFocusManager");
-
-dojo.declare("dojox.grid.enhanced.dnd._DndFocusManager", null, {
-	//summary:
-	//		This class declaration is used to be mixed in to dojox.grid._FocusManager
-	//		to enable  DND feature by changing some focus behavior in _FocusManager
-	
-	//_rowBarNode: Object
-	//		reference to a row bar DOM node
-    _rowBarNode: null,
-	
-	//_rowBarFocusIdy: Integer
-	//		The value of the ID, which is from the row node that is focused
-    _rowBarFocusIdy: null,
-	
-    isRowBar: function(){
-		//summary:
-		//		states whether currently navigating among row bar nodes.
-		// returns:
-		//		true if focus is on a row bar node; false otherwise. 
-        return (!!this._rowBarNode);
-    },
-    
-	getRowBarNode: function(inIdx){
-		//summary:
-		//		get a reference of a row bar DOM node which has the same idx value with inIdx
-		//inIdx: Integer
-		//		The idx value of the row bar DOM node that will be got
-		return this.grid.views.views[0].getCellNode(inIdx, 0);
-	},
-	
-    focusRowBar: function(){
-		//summary:
-		//		Move the focud to the first row bar node		
-        this.focusRowBarNode(0);
-		this._focusifyCellNode(false);
-        
-    },
-    
-    focusRowBarNode: function(rowIndex){
-		//summary:
-		//		move the focus to the row bar DOM node with the row index same as rowIndex
-		//rowIndex: Integer
-		//		The row index value of the row bar node that will be focused		
-		this._blurRowBar();
-		this._focusifyCellNode(false);
-		var node = this.getRowBarNode(rowIndex);
-		if(!node) return;
-        this._rowBarNode = node;
-        this._rowBarFocusIdy = rowIndex;
-		this._rowBarNode.tabIndex = -1;
-        dojox.grid.util.fire(this._rowBarNode, "focus");
-        dojo.toggleClass(this._rowBarNode, this.focusClass, true);
-    },
-    
-    _blurRowBar: function(){
-		//summary:
-		//		blur the focus on the focused row bar node
-		if(this._rowBarNode){
-			dojo.toggleClass(this._rowBarNode, this.focusClass, false);
-        	this._rowBarNode = this._rowBarFocusIdy = null;
-		}
-       
-    },
-    
-    focusNextRowBar: function(){
-		//summary:
-		//		move the focus to the next row bar node of the the current focused node		
-        var sc = this.grid.scroller, r = this._rowBarFocusIdy, rc = this.grid.rowCount - 1, row = Math.min(rc, Math.max(0, r + 1));
-        var currentY = this._rowBarFocusIdy + 1;
-        if (row > sc.getLastPageRow(sc.page)) {
-            //need to load additional data, let scroller do that
-            this.grid.setScrollTop(this.grid.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(r));
-        }
-      
-        this.focusRowBarNode(currentY);
-        this.scrollRowBarIntoView();
-    },
-    
-    focusPrevRowBar: function(){
-		//summary:
-		//		move the focus to the previous row bar node of the the current focused node		
-        var sc = this.grid.scroller, r = this._rowBarFocusIdy, rc = this.grid.rowCount - 1, row = Math.min(rc, Math.max(0, r - 1));
-        var currentY = this._rowBarFocusIdy - 1;
-        if (currentY < 0) {
-            return;
-        }
-        if (currentY <= sc.getPageRow(sc.page)) {
-            this.grid.setScrollTop(this.grid.scrollTop - sc.findScrollTop(r) - sc.findScrollTop(row));
-        }
-        
-        this.focusRowBarNode(currentY);
-        this.scrollRowBarIntoView();
-    },
-    
-    getFocusedRowIndex: function(){
-		//summary:
-		//		get the index of the node which is focused
-		//return: Integer
-		//		the index of the node which is focused
-        return this._rowBarFocusIdy;
-    },
-	
-    scrollRowBarIntoView: function(){
-    	//summary:
-		//		scroll the row bar view to make the focused row bar show in the view
-		
-        //Fake a cell object to do scroll
-        this.cell = this._rowBarNode;
-        this.cell.view = this.grid.views.views[0];
-        this.cell.getNode = function(index){
-            return this.cell;
-        };        
-        
-        this.rowIndex = this._rowBarFocusIdy;
-        this.scrollIntoView();
-		this.cell = null;
-    },
-	
-	focusHeaderNode: function(inHeaderNodeIdx){
-		//summary:
-		//		move the focus to col header
-		this._colHeadFocusIdx = inHeaderNodeIdx;
-		this.focusHeader.apply(this, arguments);
-		//this.focusHeader();
-	}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndGrid.js b/dojox/grid/enhanced/dnd/_DndGrid.js
deleted file mode 100644
index f529ba0..0000000
--- a/dojox/grid/enhanced/dnd/_DndGrid.js
+++ /dev/null
@@ -1,41 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndGrid");
-dojo.require("dojox.grid.enhanced.dnd._DndEvents");
-dojo.declare("dojox.grid.enhanced.dnd._DndGrid", dojox.grid.enhanced.dnd._DndEvents, {
-	//summary:
-	//		This class declaration is used to be mixed in to dojox.grid._Grid
-	//		to enable DND feature in _Grid.
-	
-		//select: _DndSelectingManager
-		//		handle the DND selecting operation
-	    select: null, 
-		
-		//dndSelectable: Boolean
-		//		whether the DND feature is enabled for the grid
-		dndSelectable: true,
-		
-		constructor: function(dndManager){
-			//summary:
-			//		constructor, store the reference of the instance of_DndSelectingManager
-			this.select = dndManager;
-		},
-		
-		domousedown: function(e){
-			//summary:
-			//		handle the mouse down event
-			//e: Event
-			//		the mouse down event on grid			
-			if(!e.cellNode){
-				this.onRowHeaderMouseDown(e);
-			}
-		},
-		
-		domouseup: function(e){
-			//summary:
-			//		handle the mouse up event
-			//e: Event
-			//		the mouse up event on grid			
-			if(!e.cellNode){
-				this.onRowHeaderMouseUp(e);
-			}
-		}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndMover.js b/dojox/grid/enhanced/dnd/_DndMover.js
deleted file mode 100644
index ab979d7..0000000
--- a/dojox/grid/enhanced/dnd/_DndMover.js
+++ /dev/null
@@ -1,40 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndMover");
-
-dojo.require("dojo.dnd.move");
-
-dojo.declare("dojox.grid.enhanced.dnd._DndMover", dojo.dnd.Mover, {
-	
-	onMouseMove: function(e){
-		// summary:
-		//		Overwritten, see dojo.dnd.Mover.onMouseMove()
-		dojo.dnd.autoScroll(e);
-		var m = this.marginBox;
-		this.host.onMove(this, {l: m.l + e.pageX, t: m.t + e.pageY}, {x:e.pageX, y:e.pageY});
-		dojo.stopEvent(e);
-	}
-});
-
-dojo.declare("dojox.grid.enhanced.dnd._DndBoxConstrainedMoveable", dojo.dnd.move.boxConstrainedMoveable, {
-	//movingType: String
-	//		Row moving - 'row' or column moving - 'col'
-	movingType: 'row',
-	
-	constructor: function(node, params){
-		if(!params || !params.movingType){ return; }
-		this.movingType = params.movingType;
-	},
-	
-	onFirstMove: function(/* dojo.dnd.Mover */ mover){
-		// summary:
-		//		Overwritten, see dojo.dnd.move.constrainedMoveable.onFirstMove()
-		this.inherited(arguments);
-		if(this.within){
-			var c = this.constraintBox, mb = dojo.marginBox(mover.node);
-			if(this.movingType == 'row'){
-				c.r += mb.w;	
-			}else if(this.movingType == 'col'){
-				c.b += mb.h;
-			}
-		}
-	}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndMovingManager.js b/dojox/grid/enhanced/dnd/_DndMovingManager.js
deleted file mode 100644
index 5fccb99..0000000
--- a/dojox/grid/enhanced/dnd/_DndMovingManager.js
+++ /dev/null
@@ -1,988 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndMovingManager");
-
-dojo.require("dojox.grid.enhanced.dnd._DndSelectingManager");
-dojo.require("dojox.grid.enhanced.dnd._DndMover");
-dojo.require("dojo.dnd.move");
-
-dojo.declare("dojox.grid.enhanced.dnd._DndMovingManager", dojox.grid.enhanced.dnd._DndSelectingManager, {
-	//summary:
-	//		_DndMovingManager is used to enable grid DND moving feature
-	
-	//exceptRowsTo: Integer
-	//		the value to which that rows, that should not be moved, with index from the -1
-	exceptRowsTo: -1,
-	
-	//exceptColumnsTo: Integer
-	//		the value to which that columns, that should not be moved, with index from the -1
-	exceptColumnsTo: -1,
-	
-	//coverDIVs: Array
-	//		the list that keep the reference to all cover DIVs for DND moving
-	coverDIVs: [],
-	
-	//movers: Array
-	//		the list that keep the reference to all dnd movers for DND moving
-	movers:[],
-	
-	constructor: function(inGrid){
-		//summary:
-		//		constructor, set the exceptColumnsTo value if the indirect selection feature is enabled 
-		if(this.grid.indirectSelection){
-			this.exceptColumnsTo = this.grid.pluginMgr.getFixedCellNumber() - 1;
-		}
-		this.coverDIVs = this.movers = [];
-			
-		dojo.subscribe("CTRL_KEY_DOWN", dojo.hitch(this,function(publisher, keyEvent){
-			if(publisher == this.grid && publisher != this){
-				this.keyboardMove(keyEvent);
-			}
-		}));
-		
-		dojo.forEach(this.grid.views.views, function(view){
-			//fix the jumping issue of cover div when scrolled
-			dojo.connect(view.scrollboxNode, 'onscroll', dojo.hitch(this, function(){
-				this.clearDrugDivs();
-			}));
-		}, this);		
-	},
-	
-	getGridWidth: function(){		
-		//summary:
-		//		get the width of the grid
-		//return: Integer
-		//		the width of the grid
-		return dojo.contentBox(this.grid.domNode).w - this.grid.views.views[0].getWidth().replace("px","");
-	},
-	
-	isColSelected: function(inColIndex){
-		//summary:
-		//		whether the specified column is selected
-		//inColIndex: Integer
-		//		the index value of the column
-		//return: Boolean
-		//		whether the specified column is selected
-		return this.selectedColumns[inColIndex] && inColIndex > this.exceptColumnsTo;
-	},
-	
-	getHScrollBarHeight: function(){
-		//summary:
-		//		get the horizontal sroll bar height
-		//return: Integer
-		//		 the horizontal sroll bar height
-		this.scrollbarHeight = 0;
-		dojo.forEach(this.grid.views.views, function(view, index){
-			if(view.scrollboxNode){
-				var thisbarHeight = view.scrollboxNode.offsetHeight - view.scrollboxNode.clientHeight;
-				this.scrollbarHeight = thisbarHeight > this.scrollbarHeight ? thisbarHeight : this.scrollbarHeight;
-			}
-		}, this);
-		return this.scrollbarHeight;
-	},
-	
-	getExceptionalColOffsetWidth: function(){
-		//summary:
-		//		get the width of all un-movable columns
-		//return: Integer
-		//		the width of all un-movable columns
-		if(!this.grid.indirectSelection || !this.grid.rowSelectCell){ return 0; }
-		var offsetWidth = (normalizedOffsetWidth = 0), viewNode = this.grid.rowSelectCell.view.scrollboxNode;
-		dojo.forEach(this.getHeaderNodes(), function(node, index){
-			if(index <= this.exceptColumnsTo){
-				var coord = dojo.coords(node);
-				offsetWidth += coord.w;
-			}
-		}, this);
-		normalizedOffsetWidth = offsetWidth - viewNode.scrollLeft * (dojo._isBodyLtr() ? 1 : (dojo.isMoz ? -1 : 1));
-		return normalizedOffsetWidth > 0 ? normalizedOffsetWidth : 0;		
-	},
-	
-	getGridCoords: function(noCache){
-		//summary:
-		//		get the coords values of the grid
-		// noCache: Boolean
-		//		force a realtime calculation
-		//return: Object
-		//		the coords values of the grid
-		if(!this.gridCoords || noCache){
-			this.gridCoords = new Object();
-			if(!this.headerHeight){
-				this.headerHeight = dojo.coords(this.getHeaderNodes()[0]).h;
-			}
-			var rowBarDomNodeCoords = dojo.coords(this.grid.views.views[0].domNode);
-			var gridDomCoords = dojo.coords(this.grid.domNode);
-			var gridDomBox = dojo.contentBox(this.grid.domNode);//use contentBox.h/w to exclude any margins
-			this.gridCoords.h = gridDomBox.h - this.headerHeight - this.getHScrollBarHeight();
-			this.gridCoords.t = gridDomCoords.y;
-			this.gridCoords.l = dojo._isBodyLtr() ? (gridDomCoords.x + rowBarDomNodeCoords.w) : gridDomCoords.x;
-			this.gridCoords.w = gridDomBox.w - rowBarDomNodeCoords.w;
-		}
-		return this.gridCoords;
-	},
-	
-	createAvatar: function(width, height, left, top, includeHScroll){
-		// Summary:
-		//		Create a avatar div to DND
-		// width: Integer
-		//		width of avatar
-		// height: Integer
-		//		height of avatar
-		// left: Integer
-		//		left position of avatar
-		// top: Integer
-		// 		top position of avatar
-		// includeHScroll: Boolean
-		// 		whether to include the H-scroll height	
-		// Return: Dom node
-		//		the avatar DIV node
-		this.gridCoords = null;
-		var getGridCoords = this.getGridCoords();
-		
-		var avatar = dojo.doc.createElement("DIV");
-		avatar.className = "dojoxGridSelectedDIV";
-		avatar.id = "grid_dnd_cover_div_" + left + "_" + top;
-
-		avatar.style.width = width + "px";
-		
-		var _docScroll = dojo._docScroll();
-		
-		var topDelta = top < getGridCoords.t + this.headerHeight
-			? getGridCoords.t + this.headerHeight - top : 0;
-		var gridBottom = getGridCoords.t + getGridCoords.h + this.headerHeight;
-		
-		var avatarTop = 0;
-		if(top < getGridCoords.t + this.headerHeight){
-			avatarTop = (getGridCoords.t + this.headerHeight);
-		}else if(top > gridBottom){
-			//avatar should not be shown
-			avatarTop = 10000;
-		}else{
-			avatarTop = top ;
-		}
-	
-		avatar.style.top = avatarTop + _docScroll.y + "px";
-		avatar.style.left = (left + _docScroll.x) + "px";
-		
-		var avatarBottom = avatarTop + height - topDelta;
-		if(avatarBottom > gridBottom + (includeHScroll ? this.scrollbarHeight : 0)){
-			avatarBottom = gridBottom;
-		}
-		
-		avatar.style.height = ((avatarBottom - avatarTop) >= 0 ? (avatarBottom - avatarTop) : 0) + "px";
-		
-		dojo.doc.body.appendChild(avatar);
-		avatar.connections = [];
-		avatar.connections.push(dojo.connect(avatar, "onmouseout", this, function(){
-			this.clearDrugDivs();
-		}));
-		
-		avatar.connections.push(dojo.connect(avatar, "onclick", this, "avataDivClick"));
-		avatar.connections.push(dojo.connect(avatar, "keydown", this, function(e){
-			this.handleESC(e, this);
-		}));
-		this.coverDIVs.push(avatar);
-		
-		return avatar;
-	},
-	
-	handleESC: function(e, select){
-		//Summary:
-		//		 handle the esc down event, stop DND operation
-		//e: Event
-		//		the keydown event
-		//select: _DndSelectingManager
-		//		the reference to the instance of _DndSelectingManager
-		var dk = dojo.keys;
-		switch(e.keyCode){
-			case dk.ESCAPE:
-				try{
-					this.cancelDND();
-				}catch(e){
-					console.debug(e);
-				}
-			break;
-		}
-	}, 
-	
-	cancelDND: function(){
-		//Summary:
-		//		Stop the DND operation
-		this.cleanAll();
-		this.clearDrugDivs();
-		if(this.mover){
-			this.mover.destroy();
-		}
-		this.cleanAll();
-	},
-	
-	createCoverMover: function(width, height, left, top, type){
-		//Summary:
-		//		Create the mover according to the avatar, 
-		//		and set the move constraint box to make it move horizontally or vertically
-		
-		var gridCoords = this.getGridCoords(), includeHScroll = (type == "col" ? true : false);
-		var params = {box: {l: (type == "row" ? left : gridCoords.l) + dojo._docScroll().x, 
-						 t: (type == "col" ? top : gridCoords.t + this.headerHeight) + dojo._docScroll().y, 
-						 w: type == "row" ? 1 : gridCoords.w,					// keep the moving horizontally
-						 h: type == "col" ? 1 : gridCoords.h // keep the moving vertically
-						 }, within:true, movingType: type,
-				   mover: dojox.grid.enhanced.dnd._DndMover};
-		return new dojox.grid.enhanced.dnd._DndBoxConstrainedMoveable(this.createAvatar(width, height, left, top, includeHScroll), 
-		params);
-	},
-	
-	getBorderDiv: function(){
-		//summary:
-		//		get the border DIV that is used identify the moving position
-		//return: Object
-		//		 the border DIV that is used identify the moving position
-		var borderDIV = dojo.byId("borderDIV" + this.grid.id);
-		if(borderDIV == null){
-			borderDIV = dojo.doc.createElement("DIV");
-			borderDIV.id = "borderDIV" + this.grid.id;
-			borderDIV.className = "dojoxGridBorderDIV";
-			dojo.doc.body.appendChild(borderDIV);
-		}
-		return borderDIV;
-	},
-	
-	setBorderDiv: function(width, height, left, top){
-		//summary:
-		//		set the position and shape of the border DIV that is used identify the moving position
-		//width: Integer
-		//height: Integer
-		//left: Integer
-		//top: Integer
-		//		the position and shape of the border DIV		
-		var borderDIV = this.getBorderDiv();
-		dojo.style(borderDIV, {"height" : height + "px", "top" : top + "px", "width" : width + "px", "left" : left + "px"});
-		return borderDIV;
-	},
-	
-	removeOtherMovers: function(id){
-		//summary:
-		//		remove other movers than the specified one
-		//id: Integer
-		//		the id of the specified mover
-		if(!this.coverDIVs.hasRemovedOtherMovers){
-			var movingDIV;
-			dojo.forEach(this.coverDIVs, function(div){
-				if(div.id != id){
-					dojo.doc.body.removeChild(div);
-				}else{
-					movingDIV = div;
-				}
-			}, this);
-			this.coverDIVs = [movingDIV];
-			this.coverDIVs.hasRemovedOtherMovers = true;
-		}
-	},
-	
-	addColMovers: function(){
-		// Summary:
-		//		Add DND movers for column DND
-		var startSetDiv = -1;
-		dojo.forEach(this.selectedColumns,function(col, index){
-			if(this.isColSelected(index)){
-				if(startSetDiv == -1){
-					startSetDiv = index;
-				}
-				if(this.selectedColumns[index + 1] == null){
-					this.addColMover(startSetDiv, index);
-					startSetDiv = -1;
-				}
-			}
-		}, this);
-	},
-	
-	addColMover: function(leadingBorderIdx, trailingBorderIdx){
-		// Summary:
-		//		Add DND mover for column DND
-		// leadingBorderIdx: Integer
-		//		the first column index for mover to cover
-		// trailingBorderIdx: Integer
-		//		the last column index for mover to cover
-		//console.debug("add mover: " + this.lock + "  l=" + leadingBorderIdx);
-		if(this.lock){
-			//console.debug("locked");
-			return;
-		}
-		var leftPosition = (rightPosition = 0);
-		var top = null, headerHeight = null;
-		if(dojo._isBodyLtr()){
-			dojo.forEach(this.getHeaderNodes(), function(node, index){
-				var coord = dojo.coords(node);
-				if(index == leadingBorderIdx){
-					leftPosition = coord.x;
-					top = coord.y + coord.h;
-					headerHeight = coord.h;
-				}
-				if(index == trailingBorderIdx){
-					rightPosition = coord.x + coord.w;
-				}
-			});
-		}else{
-			dojo.forEach(this.getHeaderNodes(), function(node, index){
-				var coord = dojo.coords(node);
-				if(index == leadingBorderIdx){
-					rightPosition = coord.x + coord.w;
-					headerHeight = coord.h;
-				}
-				if(index == trailingBorderIdx){
-					leftPosition = coord.x;
-					top = coord.y + coord.h;
-				}
-			});
-		}
-		
-		var coords = this.normalizeColMoverCoords(leftPosition, rightPosition, leadingBorderIdx, trailingBorderIdx);
-		var height = coords.h, width = coords.w;
-		leftPosition = coords.l, rightPosition = coords.r;
-		
-		var coverMover = this.createCoverMover(width, height, leftPosition, top, "col");
-		this.movers.push(coverMover);
-		var borderDIV = this.setBorderDiv(3, height, -1000, top + dojo._docScroll().y);
-		dojo.attr(borderDIV, 'colH', coords.colH);
-			
-		dojo.connect(coverMover, "onMoveStart", dojo.hitch(this, function(mover, leftTop){
-			this.mover = mover;
-			this.removeOtherMovers(mover.node.id);
-		}));
-		dojo.connect(coverMover, "onMove", dojo.hitch(this, function(mover, leftTop, mousePos){
-			if(mover.node == null || mover.node.parentNode == null){
-				return;
-			}
-			this.isMoving = true;
-			this.moveColBorder(mover, mousePos, borderDIV);
-		}));
-		dojo.connect(coverMover, "onMoveStop", dojo.hitch(this,function(mover){
-			if(this.drugDestIndex == null || this.isContinuousSelection(this.selectedColumns) 
-			   && (this.drugDestIndex == leadingBorderIdx || this.drugDestIndex == trailingBorderIdx || this.drugDestIndex == (trailingBorderIdx + 1) && this.drugBefore)){ 
-			   this.movingIgnored = true;
-			   if(this.isMoving){
-			   		this.isMoving = false;
-					this.clearDrugDivs();
-			   }
-			   return; 
-			}			
-			this.isMoving = false;
-			this.mover = null;
-			this.startMoveCols();
-			this.drugDestIndex = null;
-		}));
-	},
-	
-	normalizeColMoverCoords: function(leftPosition, rightPosition, leadingBorderIdx, trailingBorderIdx){
-		// Summary:
-		//		Normalize width/height, view column height and left/right x coordinates for column cover div
-		// leftPosition: Integer
-		//		Left side x coordinate of column mover
-		// rightPosition: Integer
-		//		Right side x coordinate of column mover
-		// leadingBorderIdx: Integer
-		//		The leftmost column index for mover to cover
-		// trailingBorderIdx: Integer
-		//		The rightmost column index for mover to cover
-		// return:Object
-		//		Normalized width and coordinates, e.g.{'w': 100, 'h': 200, 'l': 150, 'r': 250, 'colH': 50}
-		var width = rightPosition - leftPosition, views = this.grid.views.views, pluginMgr = this.grid.pluginMgr;
-		var coords = {'w': width, 'h': 0, 'l': leftPosition, 'r': rightPosition, 'colH': 0};
-		var gridWidth = this.getGridWidth() - views[views.length-1].getScrollbarWidth();
-		
-		var rtl = !dojo._isBodyLtr();
-		var leftView = pluginMgr.getViewByCellIdx(!rtl ? leadingBorderIdx : trailingBorderIdx); 
-		var rightView = pluginMgr.getViewByCellIdx(!rtl ? trailingBorderIdx : leadingBorderIdx);
-		var inSameView = (leftView == rightView);
-		
-		if(!leftView || !rightView){ return coords;}
-		
-		var leftBoundary = dojo.coords(leftView.scrollboxNode).x + (rtl && dojo.isIE ? leftView.getScrollbarWidth() : 0);
-		var rightViewCoords = dojo.coords(rightView.scrollboxNode);
-		var rightBoundary = rightViewCoords.x + rightViewCoords.w - ((!rtl || !dojo.isIE) ? rightView.getScrollbarWidth() : 0);
-		
-		if(coords.l < leftBoundary){
-			coords.w = coords.r - leftBoundary;
-			coords.l = leftBoundary;
-		}
-		if(coords.r > rightBoundary){
-			coords.w = rightBoundary - coords.l;
-		}
-
-		var i, rowBarView = this.grid.views.views[0], colHeight =  dojo.coords(rowBarView.contentNode).h;;
-		var view = rightView/*use right view as default*/, viewHeight = rightViewCoords.h;
-		coords.colH = colHeight;
-		viewHeight = !inSameView ? viewHeight : (viewHeight - (view.scrollboxNode.offsetHeight - view.scrollboxNode.clientHeight));
-		coords.h = colHeight < viewHeight ? colHeight : viewHeight;
-		return coords;
-	},	
-	
-	moveColBorder: function(mover, mousePos, borderDIV){
-		//Summary:
-		//		Column border identify the dnd dest position. move the border according to avatar move
-		//mover: Object
-		//		the reference to the dnd mover
-		//mousePos: Object
-		//		the current position of the mover - {x:.., Y:..}	
-		//borderDIV:Object
-		//		reference to the borderDIV
-		var docScroll = dojo._docScroll(), rtl = !dojo._isBodyLtr();
-		mousePos.x -= docScroll.x;		
-
-		var views = this.grid.views.views, gridCoords = this.getGridCoords();
-		var leftViewNode = views[!rtl ? 1 : views.length-1].scrollboxNode;
-		var rightViewNode = views[!rtl ? views.length-1 : 1].scrollboxNode;
-			
-		var leftX = (!rtl || !dojo.isIE) ? gridCoords.l : (gridCoords.l + leftViewNode.offsetWidth - leftViewNode.clientWidth);
-		var rightX = (!rtl || dojo.isMoz) ? (gridCoords.l + gridCoords.w - (rightViewNode.offsetWidth - rightViewNode.clientWidth)) : (gridCoords.l + gridCoords.w);
-		
-		dojo.forEach(this.getHeaderNodes(), dojo.hitch(this,function(node, index){
-			if(index > this.exceptColumnsTo){
-				var x, coord = dojo.coords(node);
-				if(mousePos.x >= coord.x && mousePos.x <= coord.x + coord.w){
-					if(!this.selectedColumns[index] || !this.selectedColumns[index - 1]){
-						x = coord.x +  docScroll.x + (rtl ? coord.w : 0);
-						if(mousePos.x < leftX || mousePos.x > rightX || x < leftX || x > rightX){ return; }
-						dojo.style(borderDIV, 'left', x + 'px');
-						this.drugDestIndex = index;
-						this.drugBefore = true;
-						!dojo.isIE && this.normalizeColBorderHeight(borderDIV, index);
-					}
-				}else if(this.getHeaderNodes()[index + 1] == null && (!rtl ? (mousePos.x > coord.x + coord.w) : (mousePos.x < coord.x))){
-						x = mousePos.x < leftX ? leftX : (mousePos.x > rightX ? rightX : (coord.x + docScroll.x + (rtl ? 0 : coord.w)));
-						dojo.style(borderDIV, 'left', x + 'px');
-						this.drugDestIndex = index;
-						this.drugBefore = false;
-						!dojo.isIE && this.normalizeColBorderHeight(borderDIV, index);
-				}
-			}
-		}));
-	},
-	
-	normalizeColBorderHeight: function(borderDiv, colIdx){
-		// Summary:
-		//		Normalize height of mover border div - for column moving
-		// borderDiv: Dom node
-		//		Mover border div dom node
-		// colIdx: Integer
-		//		Column index
-		var view = this.grid.pluginMgr.getViewByCellIdx(colIdx);
-		if(!view){ return; }
-		
-		var node = view.scrollboxNode, colHeight = dojo.attr(borderDiv, 'colH');
-		var viewHeight = dojo.coords(node).h - (node.offsetHeight - node.clientHeight);
-		viewHeight = colHeight > 0 && colHeight < viewHeight ? colHeight : viewHeight;
-		dojo.style(borderDiv, 'height', viewHeight + 'px');
-	},
-	
-	avataDivClick: function(e){
-		//Summary:
-		//		handle click on avatar, hide the avatar
-		if(this.movingIgnored){
-			this.movingIgnored = false;
-			return;
-		}
-		this.cleanAll();
-		this.clearDrugDivs();
-	},
-	
-	startMoveCols: function(){
-		// Summary:
-		//		start to move the selected columns to target position
-		this.changeCursorState("wait");
-		this.srcIndexdelta = 0;
-		deltaColAmount = 0;
-		dojo.forEach(this.selectedColumns, dojo.hitch(this, function(col, index){
-			if(this.isColSelected(index)){				
-				if(this.drugDestIndex > index){
-					index -= deltaColAmount;
-				}
-				deltaColAmount += 1;
-				var srcViewIndex = this.grid.layout.cells[index].view.idx;
-				var destViewIndex = this.grid.layout.cells[this.drugDestIndex].view.idx;
-				if(index != this.drugDestIndex){
-					this.grid.layout.moveColumn(srcViewIndex,destViewIndex,index,this.drugDestIndex,this.drugBefore);
-				}
-				if(this.drugDestIndex <= index && this.drugDestIndex + 1 < this.grid.layout.cells.length){
-					this.drugDestIndex += 1;
-				}				
-			}
-		}));
-		
-		var dest = this.drugDestIndex + (this.drugBefore? 0:1);
-		this.clearDrugDivs();
-		this.cleanAll();
-		this.resetCellIdx();
-		this.drugSelectionStart.colIndex = dest - deltaColAmount;
-		this.drugSelectColumn(this.drugSelectionStart.colIndex +  deltaColAmount - 1);		
-	},
-	
-	changeCursorState: function(state){
-		//summary:
-		//		change the cursor state
-		//state: String
-		//		the state that the cursor will be changed to
-		dojo.forEach(this.coverDIVs, function(div){
-			div.style.cursor = "wait";
-		});
-	},	
-	
-	addRowMovers: function(){
-		// Summary:
-		//		Add DND movers for row DND
-		var startSetDiv = -1;
-		dojo.forEach(this.grid.selection.selected,function(row, index){
-			var rowBarView = this.grid.views.views[0];
-			if(row && rowBarView.rowNodes[index]/*row bar node with 'index' must exist*/){
-				if(startSetDiv == -1){
-					startSetDiv = index;
-				}
-				if(this.grid.selection.selected[index + 1] == null || !rowBarView.rowNodes[index + 1]){
-					this.addRowMover(startSetDiv, index);
-					startSetDiv = -1;
-				}
-			}
-		}, this);
-	},
-	
-	addRowMover: function(from, to){
-		// Summary:
-		//		Add DND mover for row DND
-		// from: 
-		//		the first row index for mover to cover
-		// to:
-		//		the last row index for mover to cover
-
-		// scroll bar width sum, to fix the insufficient width of borderDIV/coverDIV for 2+ views
-		var scrollBarWidthSum = 0, views = this.grid.views.views;
-		dojo.forEach(views, function(view, index){
-			scrollBarWidthSum += view.getScrollbarWidth();
-		});
-		var lastScrollBarWidth = views[views.length-1].getScrollbarWidth();
-		var widthDelta = !dojo._isBodyLtr() ? (dojo.isIE ? scrollBarWidthSum - lastScrollBarWidth : scrollBarWidthSum) : 0;
-		
-		// get grid width except the scroll bar width of trailing view
-		//var gridWidth = this.getGridWidth() + scrollBarWidthSum - lastScrollBarWidth;
-		var gridWidth = this.getGridWidth() - lastScrollBarWidth;
-		
-		// use rowBar as row position identifier
-		var rowBarView = this.grid.views.views[0];
-		var startBarNode = rowBarView.rowNodes[from],
-			endBarNode = rowBarView.rowNodes[to];			
-			
-		// get the start and end postion of selected area
-		if(!startBarNode || !endBarNode){
-			return; // row not loaded
-		}
-		var	startCoord = dojo.coords(startBarNode), endCoord = dojo.coords(endBarNode);
-		var exceptionalColOffsetWidth = this.getExceptionalColOffsetWidth(); 
-		
-		var coverMover = this.createCoverMover(gridWidth - exceptionalColOffsetWidth, // width
-											   (endCoord.y - startCoord.y + endCoord.h), // height
-												dojo._isBodyLtr() ? (startCoord.x + startCoord.w + exceptionalColOffsetWidth) : (startCoord.x - gridWidth - widthDelta),
-											    startCoord.y,
-												"row"); // top
-		var borderDIV = this.setBorderDiv(gridWidth, 3,  // width & height
-									(dojo._isBodyLtr() ? (endCoord.x + endCoord.w) : (endCoord.x - gridWidth - widthDelta)) + dojo._docScroll().x, -100); // top
-			
-		var avaMoveStart = dojo.connect(coverMover, "onMoveStart", dojo.hitch(this, function(mover, leftTop){
-			this.mover = mover;
-			this.removeOtherMovers(mover.node.id);
-		}));
-		
-        var avaMove = dojo.connect(coverMover, "onMove", dojo.hitch(this, function(mover, leftTop, mousePos){
-			if(mover.node == null || mover.node.parentNode == null){
-				return;
-			}
-            this.isMoving = true;
-            this.moveRowBorder(mover, leftTop, borderDIV, mousePos);
-        }));
-		
-		var avaMoveStop = dojo.connect(coverMover, "onMoveStop", dojo.hitch(this,function(mover){
-			if(this.avaOnRowIndex == null || this.isContinuousSelection(this.grid.selection.selected) && (this.avaOnRowIndex == from || this.avaOnRowIndex == (to + 1))){
-			   	this.movingIgnored = true;
-				if(this.isMoving){
-					this.isMoving = false;
-					this.clearDrugDivs();
-				}
-				return; 
-			}			
-			this.isMoving = false;
-			this.mover = null;
-			this.grid.select.outRangeY = false;
-			this.grid.select.moveOutTop = false;
-			/*fix - blank Grid page when moving rows at bottom page, this only occurs the first time Grid get loaded*/		
-			this.grid.scroller.findScrollTop(this.grid.scroller.page * this.grid.scroller.rowsPerPage);
-			this.startMoveRows();
-			this.avaOnRowIndex = null;
-			delete coverMover;
-		}));
-		
-//		var avaKEY = dojo.connect(coverMover.node, "keydown",  dojo.hitch(this,function(e){
-//			var dk = dojo.keys;
-//			switch(e.keyCode){
-//				case dk.ESCAPE:
-//					try{
-//						this.cleanAll();
-//						this.clearDrugDivs();
-//						this.mover.destroy();
-//						this.cleanAll();
-//					}catch(e){
-//						console.debug(e);
-//					}
-//					break;
-//			}
-//		}));
-	},
-	
-	moveRowBorder: function(mover, leftTop, borderDIV, mousePos){
-		//summary:
-		//		move the border DIV to specified position when moving row
-		//mover: Object
-		//		the reference to the dnd mover
-		//leftTop: Object
-		//		the leftTop position of the mover
-		//borderDIV:Object
-		//		reference to the borderDIV
-		//mousePos: Object
-		//		the current position of the mover - {x:.., Y:..}	
-		var gridCoords = this.getGridCoords(true), docScroll = dojo._docScroll();
-		var gridBottomY = gridCoords.t + this.headerHeight + gridCoords.h
-		leftTop.t -= docScroll.y, mousePos.y -= docScroll.y;
-		if(mousePos.y >= gridBottomY){
-            this.grid.select.outRangeY = true;
-            this.autoMoveToNextRow();
-        }else if(mousePos.y <= gridCoords.t + this.headerHeight){
-        	this.grid.select.moveOutTop = true;
-            this.autoMoveToPreRow();
-		}else{
-            this.grid.select.outRangeY = this.grid.select.moveOutTop = false;
-			var rowBarView = this.grid.views.views[0], rowBarNodes = rowBarView.rowNodes;
-			var colHeight =  dojo.coords(rowBarView.contentNode).h;
-			var rowCount = 0, bottomRowIndex = -1;
-			for(i in rowBarNodes){
-				i = parseInt(i);
-				++rowCount;
-				if(i > bottomRowIndex){ bottomRowIndex = i; }
-			}
-			var bottomRowCoords = dojo.coords(rowBarNodes[bottomRowIndex]);
-			
-			if(colHeight < gridCoords.h && mousePos.y > (bottomRowCoords.y + bottomRowCoords.h)){
-				this.avaOnRowIndex = rowCount;
-				dojo.style(borderDIV, {"top" : bottomRowCoords.y + bottomRowCoords.h + docScroll.y + "px"});
-				return;
-			}
-			
-			var coord, rowBarNode, inView;
-			for(var index in rowBarNodes){
-				index = parseInt(index);
-				if(isNaN(index)){ continue; }
-				rowBarNode = rowBarNodes[index];
-				if(!rowBarNode){ continue; }
-				coord = dojo.coords(rowBarNode), inView = (coord.y <= gridBottomY);
-				if(inView && mousePos.y > coord.y && mousePos.y < coord.y + coord.h){
-					if(!this.grid.selection.selected[index] || !this.grid.selection.selected[index - 1]){
-						this.avaOnRowIndex = index;
-						dojo.style(borderDIV, {"top" : coord.y + docScroll.y + "px"});
-					}
-				}
-			}
-        }
-	},
-	
-	autoMoveToPreRow: function(){
-		//summary:
-		//		auto move the mover to the previous row of the current one
-		if(this.grid.select.moveOutTop){	
-			if(this.grid.scroller.firstVisibleRow > 0){
-				this.grid.scrollToRow(this.grid.scroller.firstVisibleRow - 1);
-				this.autoMoveBorderDivPre();
-				setTimeout(dojo.hitch(this, 'autoMoveToPreRow'), this.autoScrollRate);
-			}
-		}
-	},
-	
-	autoMoveBorderDivPre: function(){
-		//summary:
-		//		auto move the border DIV to the previous row of the current one
-		var docScroll = dojo._docScroll(), gridCoords = this.getGridCoords();
-		var viewTopY = gridCoords.t + this.headerHeight + docScroll.y;
-		var preRowY, borderDIV = this.getBorderDiv();
-		if(this.avaOnRowIndex - 1 <= 0){
-			this.avaOnRowIndex = 0;
-			preRowY = viewTopY;
-		}else{
-			this.avaOnRowIndex--;
-			preRowY = dojo.coords(this.grid.views.views[0].rowNodes[this.avaOnRowIndex]).y + docScroll.y;
-		}
-		borderDIV.style.top = (preRowY < viewTopY ? viewTopY : preRowY)+ "px";
-	},
-	
-	autoMoveToNextRow: function(){
-		//summary:
-		//		auto move the mover to the next row of the current one
-		if(this.grid.select.outRangeY){
-			if(this.avaOnRowIndex + 1 <= this.grid.scroller.rowCount){
-				this.grid.scrollToRow(this.grid.scroller.firstVisibleRow + 1);
-				this.autoMoveBorderDiv();
-				setTimeout(dojo.hitch(this, 'autoMoveToNextRow'), this.autoScrollRate);
-			}
-		}
-	},
-	
-	autoMoveBorderDiv: function(){
-		//Summary:
-		//		auto move the drop indicator to the next row when avatar is moved out of the grid bottom
-		var docScroll = dojo._docScroll(), gridCoords = this.getGridCoords();
-		var viewBottomY = gridCoords.t + this.headerHeight + gridCoords.h + docScroll.y;
-		var nextRowY, borderDIV = this.getBorderDiv();
-		if(this.avaOnRowIndex + 1 >= this.grid.scroller.rowCount){
-			this.avaOnRowIndex = this.grid.scroller.rowCount;
-			nextRowY = viewBottomY;
-		}else{
-			this.avaOnRowIndex++;
-			nextRowY = dojo.coords(this.grid.views.views[0].rowNodes[this.avaOnRowIndex]).y + docScroll.y;
-		}
-		borderDIV.style.top = (nextRowY > viewBottomY ? viewBottomY : nextRowY) + "px";
-	},
-	
-	startMoveRows: function(){
-		//summary:
-		//		start to move the selected rows to target position
-		var start = Math.min(this.avaOnRowIndex, this.getFirstSelected());
-		var end = Math.max(this.avaOnRowIndex - 1, this.getLastSelected());
-		this.moveRows(start, end, this.getPageInfo());
-	},
-	
-	moveRows: function(start, end, pageInfo){
-		//summary:
-		//		Only move visible rows to avoid performance issue especially 
-		//		when there are many disperse selected rows across not-rendered pages
-		//start:Integer
-		//		the first row of the selected area to move
-		//end:Integer
-		//		the first row of the selected area to move deltaRowAmount
-		//pageInfo:Object
-		//		{topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
-		var i, rowMoved = false, selectedRows = (selectedRowsAboveBorderDIV = 0), tempArray = [];//all rows to be updated
-		var scroller = this.grid.scroller, rowsPerPage = scroller.rowsPerPage;
-		var topRow = pageInfo.topPage * rowsPerPage, bottomRow = (pageInfo.bottomPage + 1) * rowsPerPage - 1;
-		
-		var pushUnselectedRows = dojo.hitch(this, function(from, to){
-			for(i = from; i < to; i++){
-				if(!this.grid.selection.selected[i] || !this.grid._by_idx[i]){
-					tempArray.push(this.grid._by_idx[i]);
-				}
-			}
-		});
-		
-		//push unselected rows above borderDIV to temp array
-		pushUnselectedRows(start, this.avaOnRowIndex);
-		
-		//push selected rows to temp array
-		for(i = start; i <= end; i++){
-			if(this.grid.selection.selected[i] && this.grid._by_idx[i]){
-				tempArray.push(this.grid._by_idx[i]);
-				selectedRows++;
-				if(this.avaOnRowIndex > i){ selectedRowsAboveBorderDIV++; } 
-			}
-		}
-		
-		//push unselected rows below borderDIV to temp array
-		pushUnselectedRows(this.avaOnRowIndex, end + 1);
-		
-		//update changed region
-		for(i = start, j = 0; i <= end; i++){
-			this.grid._by_idx[i] = tempArray[j++];
-			if(i >= topRow && i <= bottomRow){
-				this.grid.updateRow(i);
-				rowMoved = true;
-			}
-		}
-		this.avaOnRowIndex += selectedRows - selectedRowsAboveBorderDIV;
-		try{
-			this.clearDrugDivs();
-			this.cleanAll();
-			this.drugSelectionStart.rowIndex = this.avaOnRowIndex - selectedRows;
-			this.drugSelectRow(this.drugSelectionStart.rowIndex +  selectedRows - 1);
-			if(rowMoved){
-				var stack = scroller.stack;
-				dojo.forEach(pageInfo.invalidPages, function(pageIndex){
-					scroller.destroyPage(pageIndex);
-					i = dojo.indexOf(stack, pageIndex);
-					if(i >= 0){
-						stack.splice(i, 1);
-					}
-				});			
-			}
-			this.publishRowMove();
-		}catch(e){
-			console.debug(e);
-		}
-	},
-	
-	clearDrugDivs: function(){
-		//summary:
-		//		remove cover DIVs for dnd moving
-		if(!this.isMoving){ 
-			var borderDIV = this.getBorderDiv();
-	        borderDIV.style.top = -100 + "px";
-			borderDIV.style.height = "0px";
-			borderDIV.style.left = -100 + "px";
-			
-	        dojo.forEach(this.coverDIVs, function(div){
-				//console.debug("del id=" + div.id);
-				dojo.forEach(div.connections, function(connection){
-					dojo.disconnect(connection);
-				});
-	            dojo.doc.body.removeChild(div);
-				delete div;
-	        }, this);
-	        this.coverDIVs = [];
-		}
-	},	
-	
-	setDrugCoverDivs: function(inColIndex, inRowIndex){
-		// Summary:
-		//		set the cover divs for DND
-		if(!this.isMoving){
-			if(this.isColSelected(inColIndex)){
-				this.addColMovers();
-			}else if( this.grid.selection.selected[inRowIndex]){
-				this.addRowMovers();
-			}else{
-				this.clearDrugDivs();
-			}
-		}
-	},
-	
-	getPageInfo: function(){
-		//summary:
-		//		Find pages that contain visible rows
-		//return: Object
-		//		{topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
-		var scroller = this.grid.scroller, topPage = (bottomPage = scroller.page);
-		var firstVisibleRow = scroller.firstVisibleRow, lastVisibleRow = scroller.lastVisibleRow;
-		var rowsPerPage = scroller.rowsPerPage, renderedPages = scroller.pageNodes[0];		
-		var topRow, bottomRow, invalidPages = [], matched;
-		
-		dojo.forEach(renderedPages, function(page, pageIndex){
-			if(!page){ return; }
-			matched = false;
-			topRow = pageIndex * rowsPerPage;
-			bottomRow = (pageIndex + 1) * rowsPerPage - 1;
-			if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){
-				topPage = pageIndex;
-				matched = true;
-			}
-			if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){
-				bottomPage = pageIndex;
-				matched = true;
-			}
-			if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){
-				invalidPages.push(pageIndex);				
-			}
-		});
-		return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
-	},
-	
-	resetCellIdx: function(){
-		// Summary:
-		//			reset the 'idx' attributes of cells' DOM node and structures
-		var lastMax = 0;
-		var thisMax = -1;
-		dojo.forEach(this.grid.views.views, function(view, index){
-			if(index == 0){
-				return;
-			}
-			if(view.structure.cells && view.structure.cells[0]){
-				dojo.forEach(view.structure.cells[0], function(cell, index){
-					var marks = cell.markup[2].split(" ");
-					var idx = lastMax + index;
-					marks[1] = "idx=\"" + idx + "\"";
-					cell.markup[2] = marks.join(" ");
-				});
-			}
-			for(i in view.rowNodes){
-				if(!view.rowNodes[i]){ return;/* row not loaded */}
-				dojo.forEach(view.rowNodes[i].firstChild.rows[0].cells, function(cell, cellIndex){
-					if(cell && cell.attributes ){
-						if(cellIndex + lastMax > thisMax){
-							thisMax = cellIndex + lastMax;
-						}
-						var idx = document.createAttribute("idx");
-						idx.value = cellIndex + lastMax;
-						cell.attributes.setNamedItem(idx);
-					}
-				});
-			}
-			lastMax = thisMax + 1;
-		});
-	},
-	
-	publishRowMove: function(){
-		//summary:
-		//		publish a topic to notify the row movement
-		dojo.publish(this.grid.rowMovedTopic, [this]);
-	},
-	
-	keyboardMove: function(keyEvent){
-		//summary:
-		//		handle keyboard dnd
-		var inColSelection = this.selectedColumns.length > 0;
-		var inRowSelection = dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype['getFirstSelected'])() >= 0;
-		var i, colAmount, dk = dojo.keys, keyCode = keyEvent.keyCode;
-		if(!dojo._isBodyLtr()){
-			keyCode = (keyEvent.keyCode == dk.LEFT_ARROW) ? dk.RIGHT_ARROW : (keyEvent.keyCode == dk.RIGHT_ARROW ? dk.LEFT_ARROW : keyCode);
-		}
-		switch(keyCode){
-			case dk.LEFT_ARROW:
-				if(!inColSelection){return;}
-				colAmount = this.getHeaderNodes().length;
-				for(i = 0; i < colAmount; i++){
-					if(this.isColSelected(i)){
-						this.drugDestIndex = i - 1;
-						this.drugBefore = true;
-						break;
-					}
-				}
-				var minBoundary = this.grid.indirectSelection ? 1 : 0;
-				(this.drugDestIndex >= minBoundary) ? this.startMoveCols() : (this.drugDestIndex = minBoundary);
-			break;
-			case dk.RIGHT_ARROW:
-				if(!inColSelection){return;}
-				colAmount = this.getHeaderNodes().length;
-				this.drugBefore = true;
-				for(i = 0; i < colAmount; i++){
-					if(this.isColSelected(i) && !this.isColSelected(i + 1)){
-						this.drugDestIndex = i + 2;
-						if(this.drugDestIndex == colAmount){
-							this.drugDestIndex--;
-							this.drugBefore = false;
-						}
-						break;
-					}
-				}
-				if(this.drugDestIndex < colAmount){
-					this.startMoveCols();
-				}
-			break;
-			case dk.UP_ARROW:
-				if(!inRowSelection){return;}
-				this.avaOnRowIndex = dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype['getFirstSelected'])() - 1;
-				if(this.avaOnRowIndex > -1){
-					this.startMoveRows();
-				}
-			break;
-			case dk.DOWN_ARROW:
-				if(!inRowSelection){return;}
-				for(i = 0; i < this.grid.rowCount; i++){
-					if(this.grid.selection.selected[i] && !this.grid.selection.selected[i + 1]){
-						this.avaOnRowIndex = i + 2;
-						break;
-					}
-				}
-				if(this.avaOnRowIndex <= this.grid.rowCount){
-					this.startMoveRows();
-				}
-		}
-	}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndRowSelector.js b/dojox/grid/enhanced/dnd/_DndRowSelector.js
deleted file mode 100644
index 5511381..0000000
--- a/dojox/grid/enhanced/dnd/_DndRowSelector.js
+++ /dev/null
@@ -1,30 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndRowSelector");
-dojo.declare("dojox.grid.enhanced.dnd._DndRowSelector", null, {
-	//summary:
-	//		This class declaration is used to be mixed in to dojox.grid._RowSelector
-	//		to enable DND feature in _RowSelector.
-
-	domousedown: function(e){
-	//summary:
-	//		Handle when there is a mouse down event 
-	//e: Event
-	//		The mouse down event
-		this.grid.onMouseDown(e);
-	},
-	
-	domouseup: function(e){
-	//summary:
-	//		Handle when there is a mouse up event 
-	//e: Event
-	//		The mouse up event
-		this.grid.onMouseUp(e);
-	},
-	
-	dofocus:function(e){
-	//summary:
-	//		Handle when there is a focus event 
-	//e: Event
-	//		The focus event
-		e.cellNode.style.border = "solid 1px";
-	}
-});
diff --git a/dojox/grid/enhanced/dnd/_DndSelectingManager.js b/dojox/grid/enhanced/dnd/_DndSelectingManager.js
deleted file mode 100644
index b81b08d..0000000
--- a/dojox/grid/enhanced/dnd/_DndSelectingManager.js
+++ /dev/null
@@ -1,735 +0,0 @@
-dojo.provide("dojox.grid.enhanced.dnd._DndSelectingManager");
-
-dojo.require("dojox.grid.util");
-dojo.require("dojox.grid._Builder");
-dojo.require("dojox.grid.enhanced.dnd._DndGrid");
-dojo.require("dojox.grid.enhanced.dnd._DndBuilder");
-dojo.require("dojox.grid.enhanced.dnd._DndRowSelector");
-dojo.require("dojox.grid.enhanced.dnd._DndFocusManager");
-dojo.declare("dojox.grid.enhanced.dnd._DndSelectingManager", null, {
-	//summary:
-	//		_DndSelectingManager is used to enable grid DND selecting feature
-	//		
-	
-	// list, each item record whether the type is in selecting mode
-	// type: row, cell, col
-	typeSelectingMode: [],
-	
-	// list, each item record whether the type selecting is disabled
-	// type: row, cell, col
-	selectingDisabledTypes:[],
-	
-	// The start point of drag selection
-	drugSelectionStart: null,
-	
-	// The point that fire drug select
-	drugCurrentPoint : null,
-	
-	// Should be col, row or cell
-	drugMode: null,
-	
-	// If user drag select with ctrl key down
-	// selected cells should be kept state as selected
-	keepState: false,
-	
-	extendSelect: false,
-	
-	// keep the dom nodes of header in a list
-	headerNodes: null,
-	
-	// Record the selected cells
-	selectedCells : null,
-	
-	// Record the columns selected
-	selectedColumns : [],
-	
-	// Record the rows selected
-    //selectedRows : [],
-	
-	selectedClass: "dojoxGridRowSelected",
-	
-	autoScrollRate: 1000,
-	
-	constructor: function(inGrid){
-		// inGrid: dojox.Grid
-		//		The dojox.Grid this editor should be attached to
-		this.grid = inGrid;
-		this.typeSelectingMode = [];
-		this.selectingDisabledTypes = [];
-		this.selectedColumns = [];
-		
-		// Init the dnd selection start point
-		this.drugSelectionStart = new Object();
-		this.drugCurrentPoint = new Object();
-		this.resetStartPoint();
-		
-		this.extendGridForDnd(inGrid);
-		
-		this.selectedCells = [];
-		
-		dojo.connect(this.grid, "_onFetchComplete",dojo.hitch(this, "refreshColumnSelection"));
-		dojo.connect(this.grid.scroller, "scroll",dojo.hitch(this, "refreshColumnSelection"));
-		//dojo.connect(document, 'onmousedown', this.grid.focus, '_blurRowBar');
-		
-		dojo.subscribe(this.grid.rowSelectionChangedTopic, dojo.hitch(this,function(publisher){
-			try{
-				if(publisher.grid == this.grid && publisher != this){
-					this.cleanCellSelection();
-				}
-			}catch(e){
-				console.debug(e);
-			}
-		}));
-	},
-	
-	extendGridForDnd: function(inGrid){
-		//summary:
-		//       Ectend the current class to enable the DND feature
-		//		 inclucing:
-		//				dojox.Grid
-		//				dojox._FocusManager
-		//				dojox.Selection
-		//				dojox._Builder
-		//				dojox._HeaderBuilder
-		//				dojox._RowSelector
-		//		 Change the funnelEvents of views, add mouseup and mouseover event
-		
-		//extend dojox.Grid
-		var _ctr = inGrid.constructor;
-		inGrid.mixin(inGrid, dojo.hitch(new dojox.grid.enhanced.dnd._DndGrid(this)));
-		inGrid.constructor = _ctr;
-		
-		// workaround for mixin related issues
-		//inGrid.constructor.prototype.startup = inGrid.startup;
-		//inGrid.constructor.prototype.onStyleRow = inGrid.onStyleRow;
-		
-		//extend dojox._FocusManager
-		inGrid.mixin(inGrid.focus, new dojox.grid.enhanced.dnd._DndFocusManager());
-		
-		// rewrite the clickSelect function of Selection
-		inGrid.mixin(inGrid.selection, {clickSelect:function(){}});
-		
-		dojo.forEach(inGrid.views.views, function(view){
-			//extend dojox._Builder
-			inGrid.mixin(view.content, new dojox.grid.enhanced.dnd._DndBuilder());
-			//extend dojox._HeaderBuilder
-			inGrid.mixin(view.header, new dojox.grid.enhanced.dnd._DndHeaderBuilder());
-			if(view.declaredClass =="dojox.grid._RowSelector"){
-				//extend dojox._RowSelector
-				inGrid.mixin(view, new dojox.grid.enhanced.dnd._DndRowSelector());
-			}
-			// Change the funnelEvents of views, add mouseup and mouseover event
-			//dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", [ 'mouseup','mouseover', 'mouseout', 'click', 'dblclick', 'contextmenu', 'mousedown' ]);
-			dojox.grid.util.funnelEvents(view.contentNode, view, "doContentEvent", [ 'mouseup']);
-			//dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", [ 'dblclick','mouseup', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'click', 'contextmenu' ]);
-			dojox.grid.util.funnelEvents(view.headerNode, view, "doHeaderEvent", ['mouseup']);
-
-		});
-		dojo.forEach(this.grid.dndDisabledTypes, function(type){
-			this.disableSelecting(type);
-		}, this);
-		this.disableFeatures();
-	},
-	
-	disableFeatures: function(){
-		//summary:
-		//		disable selecting features according to the configuration
-		if(this.selectingDisabledTypes["cell"]){
-			this.cellClick = function(){/*console.debug("_DndSelectingManager.cellClick is disabled");*/};
-			this.drugSelectCell = function(){/*console.debug("_DndSelectingManager.drugSelectCell is disabled");*/};
-		}
-		if(this.selectingDisabledTypes["row"]){
-			this.drugSelectRow = function(){/*console.debug("_DndSelectingManager.drugSelectRow is disabled");*/};
-		}
-		if(this.selectingDisabledTypes["col"]){
-			this.selectColumn = function(){/*console.debug("_DndSelectingManager.selectColumn is disabled");*/};
-			this.drugSelectColumn = function(){/*console.debug("_DndSelectingManager.drugSelectColumn is disabled");*/};
-		}
-	},
-	
-	disableSelecting: function(type){
-		//summary:
-		//		set selecting feature of 'type' disabled in the disabled feature list
-		//type: Sting
-		//		the feature that will be disabled, should be 'cell', 'row', or 'col'
-		this.selectingDisabledTypes[type] = true;
-	},
-	
-	isInSelectingMode: function(type){
-		//summary:
-		//		whether the selecting manager is in 'type' selecting mode
-		//type: String
-		//		the selecting mode type
-		//return: Boolean
-		//		whether the selecting manager is in 'type' selecting mode
-		return !!this.typeSelectingMode[type];
-	},
-	
-	setInSelectingMode: function(type, isEnable){
-		//summary:
-		//		set the selecting manager to 'type' selecting mode
-		//type: String
-		//		the selecting mode will be set, should be 'cell', 'row', or 'col'
-		//isEnable: Boolean
-		//		the 'type' selecting mode is 'isEnable'ed
-		this.typeSelectingMode[type] = isEnable;
-	},
-	
-	getSelectedRegionInfo: function(){
-		//summary:
-		//		Get the selected region info
-		//return: Array
-		//		Array of selected index, might be index of rows | columns | cells
-		var selectedIdx = [], type = '';
-		if(this.selectedColumns.length > 0){
-			type = 'col';
-			dojo.forEach(this.selectedColumns, function(item, index){
-				!!item && selectedIdx.push(index);
-			});
-		}else if(this.grid.selection.getSelectedCount() > 0){
-			type = 'row';
-			selectedIdx = dojox.grid.Selection.prototype.getSelected.call(this.grid.selection);
-		}
-		return {'selectionType': type, 'selectedIdx': selectedIdx};
-		//TODO for future cells
-	},
-	
-	clearInSelectingMode: function(){
-		//summary:
-		//		clear all selecting mode
-		this.typeSelectingMode = [];
-	},
-	
-	getHeaderNodes: function(){
-		//summary:
-		//       Util function 
-		//		 Get  the header nodes list of the grid
-		// return:
-		//		 the header nodes list of the grid 
-		return this.headerNodes == null? dojo.query("[role*='columnheader']", this.grid.viewsHeaderNode) : this.headerNode;
-	},
-
-	_range: function(inFrom, inTo, func){
-		//summary:
-		// 		fire a function for each item in a range
-		var s = (inFrom >= 0 ? inFrom : inTo), e = inTo;
-		if(s > e){
-			e = s;
-			s = inTo;
-		}
-		for(var i=s; i<=e; i++){
-			func(i);
-		}
-	},
-	
-	cellClick: function(inColIndex, inRowIndex){
-		//summary:
-		// 		handle the click event on cell, select the cell call this.addCellToSelection
-		// inColIndex: Integer
-		//		the Y position  of the cell that fired the click event
-		// inRowIndex: Integer
-		//		the Y position of the cell that fired the click event
-		if(inColIndex > this.exceptColumnsTo){
-			this.grid.selection.clear();
-			this.publishRowChange();
-			var cellNode = this.getCellNode(inColIndex, inRowIndex);
-			this.cleanAll();
-			this.addCellToSelection(cellNode);
-		}
-	},
-	
-	setDrugStartPoint: function(inColIndex, inRowIndex){
-		//summary:
-		//		set drug selecting start point
-		//		also add mouse move and mouse up handler on the whole window to monitor whether the mouse move out of the grid when druging
-		// inColIndex: Integer
-		//			column index of the point
-		//inRowIndex: Integer
-		//			row index of the point
-		this.drugSelectionStart.colIndex = inColIndex;
-		this.drugSelectionStart.rowIndex = inRowIndex;
-		this.drugCurrentPoint.colIndex = inColIndex;
-		this.firstOut = true;
-		
-		// monitor mouse move
-		// when move out the grid bottom, auto scroll the grid
-		var moveHandler = dojo.connect(dojo.doc, "onmousemove", dojo.hitch(this, function(e){
-			this.outRangeValue = e.clientY - dojo.coords(this.grid.domNode).y/*this.grid.domNode.offsetTop*/ - this.grid.domNode.offsetHeight;
-			if(this.outRangeValue > 0){
-				if(this.drugSelectionStart.colIndex == -1){
-					if(!this.outRangeY){
-						this.autoRowScrollDrug(e);
-					}
-				}else if(this.drugSelectionStart.rowIndex == -1){
-					//...
-				}else {
-					this.autoCellScrollDrug(e);
-				}
-			}else {
-				this.firstOut = true;
-				this.outRangeY = false;
-			}
-		}));
-		// monitor the mouse up event
-		// when mouse up during drug selecting, stop the auto scroll and clean the handlers
-		var upHandler = dojo.connect(dojo.doc, "onmouseup", dojo.hitch(this, function(e){
-			this.outRangeY = false;
-			dojo.disconnect(upHandler);
-			dojo.disconnect(moveHandler);
-			this.grid.onMouseUp(e);
-		}));
-		
-	}, 
-	
-	autoRowScrollDrug: function(e){
-		//summary:
-		//		start auto scroll and select the next row
-		this.outRangeY = true;
-		this.autoSelectNextRow();
-	},
-	
-	autoSelectNextRow: function(){
-		//summary:
-		//		auto scroll the grid to next row and select the row
-		if(this.grid.select.outRangeY ){			
-			this.grid.scrollToRow(this.grid.scroller.firstVisibleRow + 1);
-			this.drugSelectRow(this.drugCurrentPoint.rowIndex + 1);
-			setTimeout(dojo.hitch(this, 'autoSelectNextRow', this.drugCurrentPoint.rowIndex + 1), this.getAutoScrollRate());
-		}
-	},
-	
-	autoCellScrollDrug: function(e){
-		//summary:
-		// 		start auto scroll the grid to next row
-		//		reset the selected column range when mouse move to another column
-		var mouseOnCol = null;
-		dojo.forEach(this.getHeaderNodes(), function(node){
-			var coord = dojo.coords(node);
-			if(e.clientX >= coord.x && e.clientX <=coord.x+coord.w){
-				mouseOnCol = Number(node.attributes.getNamedItem("idx").value);
-			}
-		});
-		if(mouseOnCol != this.drugCurrentPoint.colIndex || this.firstOut){
-			if(!this.firstOut){
-				this.colChanged = true;
-				this.drugCurrentPoint.colIndex = mouseOnCol;
-			}
-			this.firstOut = false;
-			this.outRangeY = true;
-			dojo.hitch(this, "autoSelectCellInNextRow")();
-		}
-	},
-	
-	autoSelectCellInNextRow: function(){
-		//summary:
-		//		auto scroll the grid to next row and select the cells
-		if(this.grid.select.outRangeY ){			
-			this.grid.scrollToRow(this.grid.scroller.firstVisibleRow + 1);
-			this.drugSelectCell(this.drugCurrentPoint.colIndex, this.drugCurrentPoint.rowIndex + 1);
-			if(this.grid.select.colChanged){
-				this.grid.select.colChanged = false;
-			}else {
-				setTimeout(dojo.hitch(this, 'autoSelectCellInNextRow', this.drugCurrentPoint.rowIndex + 1), this.getAutoScrollRate());
-			}
-		}
-	},
-	
-	getAutoScrollRate: function(){
-		//summary:
-		//		get the auto scroll time rate
-		//return: Integer:
-		//		the auto scroll time rate
-		return this.autoScrollRate;
-	},
-	
-	
-	resetStartPoint: function(){
-		//summary:
-		//		reset the DND selecting start point
-		if(this.drugSelectionStart.colIndex == -1 && this.drugSelectionStart.rowIndex == -1){
-			return;
-		}
-		this.lastDrugSelectionStart = dojo.clone(this.drugSelectionStart);
-		this.drugSelectionStart.colIndex = -1;
-		this.drugSelectionStart.rowIndex = -1;
-	},
-	
-	restorLastDragPoint: function(){
-		//summary:
-		//		restore the DND selecting start point to last one
-		this.drugSelectionStart = dojo.clone(this.lastDrugSelectionStart);
-	},
-	
-	drugSelectCell : function(inColumnIndex, inRowIndex){
-		//summary:
-		// Handle the Dnd selecting cell operation
-		// use this.grid.drugSelectionStart as the start point
-		// inRowIndex:
-		//		The end point Y position of the Dnd operation
-		// inColumnIndex:
-		//		The end point X position of the Dnd operation
-		
-		
-		// clear the pre selected cells
-		this.cleanAll();
-		
-		this.drugCurrentPoint.columnIndex = inColumnIndex;
-		this.drugCurrentPoint.rowIndex = inRowIndex;
-		
-		var fromRow, toRow, fromCol, toCol;
-		
-		// Use Min(inRowIndex, this.drugSelectionStart.rowIndex) as the Y value of top left point
-		//	   Max(inRowIndex, this.drugSelectionStart.rowIndex) as the Y value bottum right point
-		if(inRowIndex < this.drugSelectionStart.rowIndex){
-			fromRow = inRowIndex;
-			toRow = this.drugSelectionStart.rowIndex;
-		}else {
-			fromRow = this.drugSelectionStart.rowIndex;
-			toRow = inRowIndex;
-		}
-		
-		// Use Min(inColumnIndex, this.drugSelectionStart.colIndex) as the X value of top left point
-		//	   Max(inColumnIndex, this.drugSelectionStart.colIndex) as the X value bottum right point
-		if(inColumnIndex < this.drugSelectionStart.colIndex){
-			fromCol = inColumnIndex;
-			toCol = this.drugSelectionStart.colIndex;
-		}else {
-			fromCol = this.drugSelectionStart.colIndex;
-			toCol = inColumnIndex;
-		}
-		for(var i = fromCol; i <= toCol; i++){
-			this.addColumnRangeToSelection(i, fromRow, toRow);
-		}
-		
-	},
-	
-	selectColumn : function (columnIndex){
-		//summary:
-		// 		Handle the header cell click event
-		// columnIndex:
-		//		the colIndex of the header cell that fired the click event
-		this.addColumnToSelection(columnIndex);
-		
-	},
-	
-	drugSelectColumn : function(currentColumnIndex){
-		//summary:		
-		// 		Handle Dnd select operation
-		// currentColumnIndex:
-		// 		the colIndex of the col that fired mouseover event
-		this.selectColumnRange(this.drugSelectionStart.colIndex, currentColumnIndex);
-	}, 
-	
-	drugSelectColumnToMax: function(dir){
-		//summary:
-		//		select the column to the last one in the direction 'dir'
-		//dir: String
-		//		the direction to extend column selection
-		if(dir == "left"){
-			this.selectColumnRange(this.drugSelectionStart.colIndex, 0);
-		}else {
-			this.selectColumnRange(this.drugSelectionStart.colIndex, this.getHeaderNodes().length -1);
-		}
-	},
-	
-	selectColumnRange : function(startIndex, endIndex){
-		//summary:
-		// 		select a range of columns
-		// startIndex:
-		//		the start col index of the range
-		// endIndex:
-		//		the end col index of the range
-		if(!this.keepState)
-			this.cleanAll();
-		this._range(startIndex, endIndex, dojo.hitch(this, "addColumnToSelection"));
-		//this.clearDrugDivs();
-		//this.setSelectedColDivs();
-	},
-		
-	addColumnToSelection : function (columnIndex){
-		//summary:
-		// 		add all the cells in a column to selection
-		// columnIndex:
-		//		the index of the col
-		this.selectedColumns[columnIndex] = true;
-		dojo.toggleClass(this.getHeaderNodes()[columnIndex], "dojoxGridHeaderSelected", true);
-		//this.addColumnRangeToSelection(columnIndex, -1, Number.POSITIVE_INFINITY);
-		this._rangCellsInColumn(columnIndex, -1, Number.POSITIVE_INFINITY, this.addCellToSelection);
-		//this.setSelectedDiv();
-	},
-	
-	addColumnRangeToSelection : function (columnIndex, from, to){
-		//summary:
-		// Add a range of cells in the specified column to selection
-		// columnIndex:
-		//		the Column Index
-		// from:
-		//		the top cell of the range
-		// to:
-		//		the bottom cell of the range
-		
-		var viewManager = this.grid.views;
-		var columnCellNodes = [];
-		var dndManager = this;
-		
-		// As there's no reference of domNode for cell, get it manully
-		dojo.forEach(viewManager.views, function(view){
-			dojo.forEach(this.getViewRowNodes(view.rowNodes), function(rowNode, rowIndex){
-				if(!rowNode){ return; /* row not loaded */}
-				if(rowIndex >= from && rowIndex <= to){
-					dojo.forEach(rowNode.firstChild.rows[0].cells, function(cell){
-						
-						// get the cells of the row in the view by 
-						// rowNode.firstChild.rows[0].cells
-						// rowNode is the Div which is the domNode for a row, the firstChild is a table, and each row should have only one
-						// row in the table, so get rows[0] should be ok.
-						
-						if(cell && cell.attributes && (idx = cell.attributes.getNamedItem("idx")) && Number(idx.value) == columnIndex ){
-							dndManager.addCellToSelection(cell);
-						}
-					});
-				}
-			}, this);
-		}, this);		
-	},
-	
-	_rangCellsInColumn : function (columnIndex, from, to, func){
-		//summary:
-		// 		Add a range of cells in the specified column to selection
-		// 		columnIndex:
-		//		the Column Index
-		// from:
-		//		the top cell of the range
-		// to:
-		//		the bottom cell of the range
-		
-		var viewManager = this.grid.views;
-		var columnCellNodes = [];
-		var dndManager = this;
-		
-		// As there's no reference of domNode for cell, get it manully
-		dojo.forEach(viewManager.views, function(view){
-			dojo.forEach(this.getViewRowNodes(view.rowNodes), function(rowNode, rowIndex){
-				if(!rowNode){return;/* row not loaded */}
-				if(rowIndex >= from && rowIndex <= to){
-					dojo.forEach(rowNode.firstChild.rows[0].cells, function(cell){
-						// get the cells of the row in the view by 
-						// rowNode.firstChild.rows[0].cells
-						// rowNode is the Div which is the domNode for a row, the firstChild is a table, and each row should have only one
-						// row in the table, so get rows[0] should be ok.
-						if(cell && cell.attributes && (idx = cell.attributes.getNamedItem("idx")) && Number(idx.value) == columnIndex ){
-							func(cell, dndManager);
-						}
-					});
-				}
-			}, this);
-		}, this);		
-	},
-	
-	drugSelectRow : function(inRowIndex){
-		//summary:
-		// 		Handle dnd select rows
-		// 		call the dojox.grid.Selection to perform the operation
-		// inRowIndex:
-		//		the index of the row that fired mouseover event
-		
-		this.drugCurrentPoint.rowIndex = inRowIndex;
-		
-		this.cleanCellSelection();
-		this.clearDrugDivs();
-	
-		var selection = this.grid.selection;
-		selection._beginUpdate();
-		if(!this.keepState)
-			selection.deselectAll();
-		
-		selection.selectRange(this.drugSelectionStart.rowIndex, inRowIndex);
-		selection._endUpdate();
-		
-		this.publishRowChange();
-	},
-	
-	drugSelectRowToMax: function(dir){
-		//summary:
-		//		select the row to the last one in the direction 'dir'
-		//dir: String
-		//		the direction to extend row selection		
-		if(dir == "up"){
-			this.drugSelectRow(0);
-		}else {
-			this.drugSelectRow(this.grid.rowCount);
-		}
-	},
-
-	getCellNode: function(inCellIndex, inRowIndex){
-		//summary:
-		//		As there's no reference of domNode for cell, get it manully
-		//inCellIndex: Integer
-		//		Offset of the cell in the row, stands for the X index of the cell in the grid
-		//inRowIndex : Integer
-		//		Offset of the row in the grid, stands forthe Y index of the cell in the grid
-		//Description: Integer
-		//		Get the DOM node for the cell in a give position
-		//Return: Object
-		//		DOM node reference of the cell
-		var rowNodes = [], cellNode = null;
-		var viewManager = this.grid.views;
-		for(var i=0, v, n; (v=viewManager.views[i])&&(n=v.getRowNode(inRowIndex)); i++){
-			rowNodes.push(n);
-		}
-		dojo.forEach(rowNodes, dojo.hitch(function(rowNode, viewIndex){
-			if(cellNode){ return;/* get the cell from the previous view */}
-			var cells = dojo.query("[idx='" + inCellIndex + "']",rowNode);
-			if(cells && cells[0]){
-				cellNode = cells[0];
-			}
-		}));
-		return cellNode;
-	},
-	
-	addCellToSelection : function(cellNode, dndManager){
-		//summary:
-		//	 	add a cell to selection list and change it into selected state
-		//cellNode: Object
-		//		the cell node will be added to select
-		//dndManager: _DndSelectionManager
-		//		reference to the instance of _DndSelectionManager
-		if(!dndManager){
-			dndManager = this;
-		}
-		dndManager.selectedCells[dndManager.selectedCells.length] = cellNode;
-		dojo.toggleClass(cellNode, dndManager.selectedClass, true);
-	},
-	
-	isColSelected: function(inColIndex){
-		//summary:
-		//		wether the column in of index value "inColIndex" is selected
-		//inColIndex: Integer
-		//		the index value of the column
-		//return: Boolean
-		//		wether the column in of index value "inColIndex" is selected
-		return this.selectedColumns[inColIndex];
-	},
-	
-	isRowSelected: function(inRowIndex){
-		//summary:
-		//		wether the row in of index value "inRowIndex" is selected
-		//inRowIndex: Integer
-		//		the index value of the row
-		//return: Boolean
-		//		wether the row in of index value "inRowIndex" is selected
-		return this.grid.selection.selected[inRowIndex];
-	},
-	
-	isContinuousSelection: function(selected){
-		//summary:
-		//		Whether a selection is continuous
-		//selected: Array
-		//		the selection states for columns or rows
-		//return: Boolean 
-		var preSelectedIdx = -1;
-		for(var i = 0; i < selected.length; i++){
-			if(!selected[i]){ continue; }
-			if(preSelectedIdx < 0 || i - preSelectedIdx == 1 ){ preSelectedIdx = i; }
-			else if(i - preSelectedIdx >= 2 ){ return false; }
-		}
-		return preSelectedIdx >= 0 ? true : false;
-	},
-	
-	cleanCellSelection : function(){
-		//summary:
-		//		change all the selected cell to unselected and umpty the selected-cell list
-		dojo.forEach(this.selectedCells, dojo.hitch(this, "removeCellSelectedState"));
-		this.selectedCells = [];
-		dojo.forEach(this.selectedColumns, function(selected, index){
-			if(selected){
-				dojo.toggleClass(this.getHeaderNodes()[index], "dojoxGridHeaderSelected", false);
-			}
-		}, this);
-		
-		this.selectedColumns = [];
-		this.grid.edit.isEditing() && this.grid.edit.apply();
-	},
-	
-	removeCellSelectedState : function(cell){
-		//summary:
-		//		change the cell style to un-selected
-		//cell:
-		//		the cell dom-node the style to be changed
-		dojo.toggleClass(cell, this.selectedClass, false);
-	}, 
-	
-	cleanAll : function(){
-		//summary:
-		//Clear all the selected cells, columns and rows
-		// row selection is reused from dojox.grid._Selection, 
-		// so clear it by call the clear function of dojox.grid._Selection
-		
-		// clear cell and column selection effect 
-		this.cleanCellSelection();
-		// clear row selection effect
-		this.grid.selection.clear();
-		// clear Column/Row 
-		//this.selectedColumns = [];
-		//this.selectedRows = [];
-		this.publishRowChange();
-	},
-	
-	refreshColumnSelection: function(){
-		//summary:
-		//		handle grid scroll, keep column selected state
-		dojo.forEach(this.selectedColumns, dojo.hitch(this, function(selectedColumn, colIndex){
-			if(selectedColumn){
-				this.grid.select.addColumnToSelection(colIndex);
-			}
-		}));
-	},
-	
-	inSelectedArea: function(inColIndex, inRowIndex){
-		//summary:
-		//		whether the specified point is in selected area
-		//inColIndex: Integer
-		//		the col index of the point
-		//inRowIndex: Integer
-		//		the row index of the point
-		//return: Boolean
-		//		whether the specified point is in selected area
-		return this.selectedColumns[inColIndex] || this.gird.selection.selecteded[inRowIndex];
-	},
-	
-	publishRowChange: function(){
-		//summary:
-		//		publish a topic to notify that row selection changed
-		dojo.publish(this.grid.rowSelectionChangedTopic, [this]);
-	}, 
-	
-	getViewRowNodes: function(viewRowNodes){
-		//summary:
-		//		Get view row nodes in array form
-		var rowNodes = [];
-		for(i in viewRowNodes){
-			rowNodes.push(viewRowNodes[i]);
-		}
-		return rowNodes;
-	},
-	
-	getFirstSelected: function(){
-		//summary:
-		//		Get the first selected row index
-		//return: Integer
-		//		First selected row index
-		return dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype.getFirstSelected)();
-	},
-	
-	getLastSelected: function(){
-		//summary:
-		//		Get the last selected row index
-		//return: Integer
-		//		Last selected row index
-		var selected = this.grid.selection.selected;
-		for(var i = selected.length - 1; i >= 0; i--){
-			if(selected[i]){ return i; }
-		}
-		return -1;
-	}
-});
diff --git a/dojox/grid/enhanced/nls/EnhancedGrid.js b/dojox/grid/enhanced/nls/EnhancedGrid.js
index 651ab50..9099ec8 100644
--- a/dojox/grid/enhanced/nls/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/EnhancedGrid.js
@@ -4,5 +4,8 @@
 	ascending: "Ascending",
 	descending: "Descending",
 	sortingState: "${0} - ${1}",
-	unsorted: "Do not sort this column"
+	unsorted: "Do not sort this column",
+	indirectSelectionRadio: "Row ${0}, single selection, radio box",
+	indirectSelectionCheckBox: "Row ${0}, multiple selection, check box",
+	selectAll: "Select all"
 })
diff --git a/dojox/grid/enhanced/nls/Filter.js b/dojox/grid/enhanced/nls/Filter.js
new file mode 100644
index 0000000..d6ebf6b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/Filter.js
@@ -0,0 +1,85 @@
+({
+	"clearFilterDialogTitle": "Clear Filter",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Rule ${0}",
+	
+	"conditionEqual": "equal",
+	"conditionNotEqual": "does not equal",
+	"conditionLess": "is less than",
+	"conditionLessEqual": "less than or equal",
+	"conditionLarger": "is greater than",
+	"conditionLargerEqual": "greater than or equal",
+	"conditionContains": "contains",
+	"conditionIs": "is",
+	"conditionStartsWith": "starts with",
+	"conditionEndWith": "ends with",
+	"conditionNotContain": "does not contain",
+	"conditionIsNot": "is not",
+	"conditionNotStartWith": "does not start with",
+	"conditionNotEndWith": "does not end with",
+	"conditionBefore": "before",
+	"conditionAfter": "after",
+	"conditionRange": "range",
+	"conditionIsEmpty": "is empty",
+	
+	"all": "all",
+	"any": "any",
+	"relationAll": "all rules",
+	"waiRelAll": "Match all of the following rules:",
+	"relationAny": "any rules",
+	"waiRelAny": "Match any of the following rules:",
+	"relationMsgFront": "Match",
+	"relationMsgTail": "",
+	"and": "and",
+	"or": "or",
+	
+	"addRuleButton": "Add Rule",
+	"waiAddRuleButton": "Add a new rule",
+	"removeRuleButton": "Remove Rule",
+	"waiRemoveRuleButtonTemplate": "Remove rule ${0}",
+	
+	"cancelButton": "Cancel",
+	"waiCancelButton": "Cancel this dialog",
+	"clearButton": "Clear",
+	"waiClearButton": "Clear the filter",
+	"filterButton": "Filter",
+	"waiFilterButton": "Submit the filter",
+	
+	"columnSelectLabel": "Column",
+	"waiColumnSelectTemplate": "Column for rule ${0}",
+	"conditionSelectLabel": "Condition",
+	"waiConditionSelectTemplate": "Condition for rule ${0}",
+	"valueBoxLabel": "Value",
+	"waiValueBoxTemplate": "Enter value to filter for rule ${0}",
+	
+	"rangeTo": "to",
+	"rangeTemplate": "from ${0} to ${1}",
+	
+	"statusTipHeaderColumn": "Column",
+	"statusTipHeaderCondition": "Rules",
+	"statusTipTitle": "Filter Bar",
+	"statusTipMsg": "Click the filter bar here to filter on values in ${0}.",
+	"anycolumn": "any column",
+	"statusTipTitleNoFilter": "Filter Bar",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Match",
+	"statusTipRelPost": "rules.",
+	
+	"defaultItemsName": "items",
+	"filterBarMsgHasFilterTemplate": "${0} of ${1} ${2} shown.",
+	"filterBarMsgNoFilterTemplate": "No filter applied",
+	
+	"filterBarDefButton": "Define filter",
+	"waiFilterBarDefButton": "Filter the table",
+	"a11yFilterBarDefButton": "Filter...",
+	"filterBarClearButton": "Clear filter",
+	"waiFilterBarClearButton": "Clear the filter",
+	"closeFilterBarBtn": "Close filter bar",
+	
+	"clearFilterMsg": "This will remove the filter and show all available records.",
+	"anyColumnOption": "Any Column",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
diff --git a/dojox/grid/enhanced/nls/Pagination.js b/dojox/grid/enhanced/nls/Pagination.js
new file mode 100644
index 0000000..7d5bff1
--- /dev/null
+++ b/dojox/grid/enhanced/nls/Pagination.js
@@ -0,0 +1,17 @@
+({
+	"descTemplate": "${2} - ${3} of ${1} ${0}",
+	"firstTip": "First Page",
+	"lastTip": "Last Page",
+	"nextTip": "Next Page",
+	"prevTip": "Previous Page",
+	"itemTitle": "items",
+	"pageStepLabelTemplate": "Page ${0}",
+	"pageSizeLabelTemplate": "${0} items per page",
+	"allItemsLabelTemplate": "All items",
+	"gotoButtonTitle": "Go to a specific page",
+	"dialogTitle": "Go to Page",
+	"dialogIndication": "Specify the page number",
+	"pageCountIndication": " (${0} pages)",
+	"dialogConfirm": "Go",
+	"dialogCancel": "Cancel"
+})
diff --git a/dojox/grid/enhanced/nls/ar/EnhancedGrid.js b/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
index 4c5bab4..35401bc 100644
--- a/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ar/EnhancedGrid.js
@@ -3,6 +3,10 @@
 	nestedSort: "فرز متداخل",
 	ascending: "تصاعدي",
 	descending: "تنازلي",
-	unsorted: "عدم فرز هذا العمود"
+	sortingState: "${0} - ${1}",
+	unsorted: "عدم فرز هذا العمود",
+	indirectSelectionRadio: "الصف ${0}، اختيار منفرد، اختيار دائري",
+	indirectSelectionCheckBox: "الصف ${0}، اختيارات متعددة، مربع اختيار",
+	selectAll: "تحديد كل"
 })
 
diff --git a/dojox/grid/enhanced/nls/ar/Filter.js b/dojox/grid/enhanced/nls/ar/Filter.js
new file mode 100644
index 0000000..78132c7
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ar/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "محو ترشيح البيانات",
+	"filterDefDialogTitle": "ترشيح البيانات",
+	"ruleTitleTemplate": "القاعدة ${0}",
+	
+	"conditionEqual": "يساوي",
+	"conditionNotEqual": "لا يساوي",
+	"conditionLess": "أصغر من",
+	"conditionLessEqual": "أصغر من أو يساوي",
+	"conditionLarger": "أكبر من",
+	"conditionLargerEqual": "أكبر من أو يساوي",
+	"conditionContains": "يتضمن",
+	"conditionIs": "هو",
+	"conditionStartsWith": "يبدأ بالحروف",
+	"conditionEndWith": "ينتهي بالحروف",
+	"conditionNotContain": "لا يتضمن",
+	"conditionIsNot": "ليس",
+	"conditionNotStartWith": "لا يبدأ بالحروف",
+	"conditionNotEndWith": "لا ينتهي بالحروف",
+	"conditionBefore": "قبل",
+	"conditionAfter": "بعد",
+	"conditionRange": "المدى",
+	"conditionIsEmpty": "خالي",
+	
+	"all": "كل",
+	"any": "أي",
+	"relationAll": "كل القواعد",
+	"waiRelAll": "مطابقة كل القواعد التالية:",
+	"relationAny": "أية قواعد",
+	"waiRelAny": "مطابقة أي من القواعد التالية:",
+	"relationMsgFront": "مطابقة",
+	"relationMsgTail": "",
+	"and": "and",
+	"or": "or",
+	
+	"addRuleButton": "اضافة قاعدة",
+	"waiAddRuleButton": "اضافة قاعدة جديدة",
+	"removeRuleButton": "ازالة قاعدة",
+	"waiRemoveRuleButtonTemplate": "ازالة القاعدة ${0}",
+	
+	"cancelButton": "الغاء",
+	"waiCancelButton": "الغاء مربع الحوار هذا",
+	"clearButton": "محو",
+	"waiClearButton": "محو ترشيح البيانات",
+	"filterButton": "ترشيح البيانات",
+	"waiFilterButton": "احالة ترشيح البيانات",
+	
+	"columnSelectLabel": "العمود",
+	"waiColumnSelectTemplate": "العمود للقاعدة ${0}",
+	"conditionSelectLabel": "الشرط",
+	"waiConditionSelectTemplate": "الشرط للقاعدة ${0}",
+	"valueBoxLabel": "القيمة",
+	"waiValueBoxTemplate": "أدخل قيمة لترشيح البيانات للقاعدة ${0}",
+	
+	"rangeTo": "الى",
+	"rangeTemplate": "من ${0} الى ${1}",
+	
+	"statusTipHeaderColumn": "العمود",
+	"statusTipHeaderCondition": "القواعد",
+	"statusTipTitle": "خط ترشيح البيانات",
+	"statusTipMsg": "اضغط على خط ترشيح البيانات هنا لترشيح البيانات بناءا على القيم التي توجد في ${0}.",
+	"anycolumn": "أي عمود",
+	"statusTipTitleNoFilter": "خط ترشيح البيانات",
+	"statusTipTitleHasFilter": "ترشيح البيانات",
+	"statusTipRelPre": "مطابقة",
+	"statusTipRelPost": "قواعد.",
+	
+	"defaultItemsName": "بنود",
+	"filterBarMsgHasFilterTemplate": "يتم عرض ${0} من ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "لم يتم تطبيق أي ترشيح للبيانات.",
+	
+	"filterBarDefButton": "تعريف ترشيح البيانات",
+	"waiFilterBarDefButton": "ترشيح بيانات الجدول",
+	"a11yFilterBarDefButton": "ترشيح البيانات...",
+	"filterBarClearButton": "محو ترشيح البيانات",
+	"waiFilterBarClearButton": "محو ترشيح البيانات",
+	"closeFilterBarBtn": "اغلاق خط ترشيح البيانات",
+	
+	"clearFilterMsg": "سيؤدي هذا الى ازالة ترشيح البيانات وعرض كل السجلات المتاحة.",
+	"anyColumnOption": "أي عمود",
+	
+	"trueLabel": "متحقق",
+	"falseLabel": "غير متحقق"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/ar/Pagination.js b/dojox/grid/enhanced/nls/ar/Pagination.js
new file mode 100644
index 0000000..6e03e28
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ar/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} من ${1} ${0}",
+	"firstTip": "الصفحة الأولى",
+	"lastTip": "الصفحة الأخيرة",
+	"nextTip": "الصفحة التالية",
+	"prevTip": "الصفحة السابقة",
+	"itemTitle": "بنود",
+	"pageStepLabelTemplate": "الصفحة ${0}",
+	"pageSizeLabelTemplate": "${0} بند/بنود بكل صفحة",
+	"allItemsLabelTemplate": "كل البنود",
+	"gotoButtonTitle": "اذهب الى الصفحة المحددة",
+	"dialogTitle": "اذهب الى الصفحة",
+	"dialogIndication": "حدد رقم الصفحة",
+	"pageCountIndication": " (${0} صفحات)",
+	"dialogConfirm": "بدء",
+	"dialogCancel": "الغاء"
+})
+
diff --git a/dojox/grid/enhanced/nls/ca/Filter.js b/dojox/grid/enhanced/nls/ca/Filter.js
new file mode 100644
index 0000000..0025e79
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ca/Filter.js
@@ -0,0 +1,88 @@
+({
+	"clearFilterDialogTitle": "Netejar el filtre",
+	"filterDefDialogTitle": "Filtre",
+	"incompleteRuleTip": "Aquesta regla no està completa",
+	"ruleTitleTemplate": "Regla ${0}",
+	
+	"conditionEqual": "igual que",
+	"conditionNotEqual": "no és igual que",
+	"conditionLess": "és menys que",
+	"conditionLessEqual": "és menys o igual que",
+	"conditionLarger": "és més que",
+	"conditionLargerEqual": "és més o igual que",
+	"conditionContains": "conté",
+	"conditionIs": "és",
+	"conditionStartsWith": "comença per",
+	"conditionEndWith": "acaba per",
+	"conditionNotContain": "no conté",
+	"conditionIsNot": "no és",
+	"conditionNotStartWith": "no comença per",
+	"conditionNotEndWith": "no acaba per",
+	"conditionBefore": "abans",
+	"conditionAfter": "després",
+	"conditionRange": "interval",
+	
+	"all": "tot",
+	"any": "qualsevol",
+	"relationAll": "totes les regles",
+	"waiRelAll": "Fes coincidir totes les regles següents:",
+	"relationAny": "qualsevol regla",
+	"waiRelAny": "Fes coincidir qualsevol de les regles següents:",
+	"relationMsgFront": "Coincidència",
+	"relationMsgTail": "",
+	"and": "i",
+	"or": "o",
+	
+	"addRuleButton": "Afegeix regla",
+	"waiAddRuleButton": "Afegeix una regla nova",
+	"removeRuleButton": "Elimina regla",
+	"waiRemoveRuleButtonTemplate": "Elimina la regla ${0}",
+	
+	"cancelButton": "Cancel·la",
+	"waiCancelButton": "Cancel·la aquest diàleg",
+	"clearButton": "Esborra",
+	"waiClearButton": "Neteja el filtre",
+	"filterButton": "Filtre",
+	"waiFilterButton": "Envia el filtre",
+	
+	"columnSelectLabel": "Columna",
+	"waiColumnSelectTemplate": "Columna per a la regla ${0}",
+	"conditionSelectLabel": "Condició",
+	"waiConditionSelectTemplate": "Condició per a la regla ${0}",
+	"valueBoxLabel": "Valor",
+	"waiValueBoxTemplate": "Especifiqueu el valor de filtre per a la regla ${0}",
+	
+	"rangeTo": "a",
+	"rangeTemplate": "de ${0} a ${1}",
+	
+	"statusTipHeaderColumn": "Columna",
+	"statusTipHeaderCondition": "Regles",
+	"statusTipTitle": "Barra de filtre",
+	"statusTipMsg": "Feu clic aquí a la barra de filtre per filtrar els valors a ${0}.",
+	"anycolumn": "qualsevol columna",
+	"statusTipTitleNoFilter": "Barra de filtre",
+	"statusTipTitleHasFilter": "Filtre",
+	"statusTipRelPre": "Coincidència",
+	"statusTipRelPost": "regles.",
+	
+	"defaultItemsName": "elements",
+	"filterBarMsgHasFilterTemplate": "Es mostren ${0} de ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "No s'ha aplicat cap filtre",
+	
+	"filterBarDefButton": "Defineix filtre",
+	"waiFilterBarDefButton": "Filtra la taula",
+	"a11yFilterBarDefButton": "Filtre...",
+	"filterBarClearButton": "Netejar filtre",
+	"waiFilterBarClearButton": "Neteja el filtre",
+	"closeFilterBarBtn": "Tancar la barra de filtre",
+	
+	"clearFilterMsg": "Això eliminarà el filtre i mostrarà tots els registres disponibles.",
+	"anyColumnOption": "Qualsevol columna",
+	
+	"trueLabelEditable": "Seleccionat",
+	"trueLabel": "Cert",
+	"falseLabel": "Fals"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/ca/Pagination.js b/dojox/grid/enhanced/nls/ca/Pagination.js
new file mode 100644
index 0000000..d616a0b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ca/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} de ${1} ${0}",
+	"firstTip": "Primera pàgina",
+	"lastTip": "Darrera pàgina",
+	"nextTip": "Pàgina següent",
+	"prevTip": "Pàgina anterior",
+	"itemTitle": "elements",
+	"pageStepLabelTemplate": "Pàgina ${0}",
+	"pageSizeLabelTemplate": "${0} elements per pàgina",
+	"allItemsLabelTemplate": "Tots els elements",
+	"gotoButtonTitle": "Vés a una pàgina específica",
+	"dialogTitle": "Vés a pàgina",
+	"dialogIndication": "Especifiqueu el número de pàgina",
+	"pageCountIndication": " (${0} pàgines)",
+	"dialogConfirm": "Vés-hi",
+	"dialogCancel": "Cancel·la"
+})
+
diff --git a/dojox/grid/enhanced/nls/cs/EnhancedGrid.js b/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
index d626406..f6db50e 100644
--- a/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/cs/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Jednoduché řazení",
+	singleSort: "Jednotlivé řazení",
 	nestedSort: "Vnořené řazení",
 	ascending: "Vzestupně",
 	descending: "Sestupně",
-	unsorted: "Tento sloupec neřadit"
+	sortingState: "${0} - ${1}",
+	unsorted: "Neřadit tento sloupec",
+	indirectSelectionRadio: "Řádek ${0}, jednotlivý výběr, přepínač",
+	indirectSelectionCheckBox: "Řádek ${0}, vícenásobný výběr, zaškrtávací políčko",
+	selectAll: "Vybrat vše"
 })
 
diff --git a/dojox/grid/enhanced/nls/cs/Filter.js b/dojox/grid/enhanced/nls/cs/Filter.js
new file mode 100644
index 0000000..c212c55
--- /dev/null
+++ b/dojox/grid/enhanced/nls/cs/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Vymazat filtr",
+	"filterDefDialogTitle": "Filtr",
+	"ruleTitleTemplate": "Pravidlo ${0}",
+	
+	"conditionEqual": "rovná se",
+	"conditionNotEqual": "nerovná se",
+	"conditionLess": "méně než",
+	"conditionLessEqual": "méně nebo rovno",
+	"conditionLarger": "více než",
+	"conditionLargerEqual": "více nebo rovno",
+	"conditionContains": "obsahuje",
+	"conditionIs": "je",
+	"conditionStartsWith": "začíná",
+	"conditionEndWith": "končí",
+	"conditionNotContain": "neobsahuje",
+	"conditionIsNot": "není",
+	"conditionNotStartWith": "nezačíná",
+	"conditionNotEndWith": "nekončí",
+	"conditionBefore": "před",
+	"conditionAfter": "po",
+	"conditionRange": "rozsah",
+	"conditionIsEmpty": "je prázdné",
+	
+	"all": "vše",
+	"any": "jakékoli",
+	"relationAll": "všechna pravidla",
+	"waiRelAll": "Porovnat všechna tato pravidla:",
+	"relationAny": "jakákoli pravidla",
+	"waiRelAny": "Porovnat jakákoli z těchto pravidel:",
+	"relationMsgFront": "Shoda",
+	"relationMsgTail": "",
+	"and": "a",
+	"or": "nebo",
+	
+	"addRuleButton": "Přidat pravidlo",
+	"waiAddRuleButton": "Přidat nové pravidlo",
+	"removeRuleButton": "Odebrat pravidlo",
+	"waiRemoveRuleButtonTemplate": "Odebrat pravidlo ${0}",
+	
+	"cancelButton": "Storno",
+	"waiCancelButton": "Zrušit toto dialogové okno",
+	"clearButton": "Vymazat",
+	"waiClearButton": "Vymazat filtr",
+	"filterButton": "Filtr",
+	"waiFilterButton": "Odeslat filtr",
+	
+	"columnSelectLabel": "Sloupec",
+	"waiColumnSelectTemplate": "Sloupec pro pravidlo ${0}",
+	"conditionSelectLabel": "Podmínka",
+	"waiConditionSelectTemplate": "Podmínka pro pravidlo ${0}",
+	"valueBoxLabel": "Hodnota",
+	"waiValueBoxTemplate": "Zadejte hodnotu do filtru pro pravidlo ${0}",
+	
+	"rangeTo": "do",
+	"rangeTemplate": "z ${0} do ${1}",
+	
+	"statusTipHeaderColumn": "Sloupec",
+	"statusTipHeaderCondition": "Pravidla",
+	"statusTipTitle": "Panel filtrování",
+	"statusTipMsg": "Klepněte zde na panel filtrování, abyste filtrovali hodnoty v ${0}.",
+	"anycolumn": "jakýkoli sloupec",
+	"statusTipTitleNoFilter": "Panel filtrování",
+	"statusTipTitleHasFilter": "Filtr",
+	"statusTipRelPre": "Shoda",
+	"statusTipRelPost": "pravidla.",
+	
+	"defaultItemsName": "položek",
+	"filterBarMsgHasFilterTemplate": "${0} z ${1} ${2} zobrazeno.",
+	"filterBarMsgNoFilterTemplate": "Není použitý žádný filtr",
+	
+	"filterBarDefButton": "Definovat filtr",
+	"waiFilterBarDefButton": "Filtrovat tabulku",
+	"a11yFilterBarDefButton": "Filtrovat...",
+	"filterBarClearButton": "Vymazat filtr",
+	"waiFilterBarClearButton": "Vymazat filtr",
+	"closeFilterBarBtn": "Zavřít panel filtrování",
+	
+	"clearFilterMsg": "Tímto se odebere filtr a zobrazí všechny dostupné záznamy.",
+	"anyColumnOption": "Jakýkoli sloupec",
+	
+	"trueLabel": "Pravda",
+	"falseLabel": "Nepravda"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/cs/Pagination.js b/dojox/grid/enhanced/nls/cs/Pagination.js
new file mode 100644
index 0000000..18478cc
--- /dev/null
+++ b/dojox/grid/enhanced/nls/cs/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} z ${1} ${0}",
+	"firstTip": "První strana",
+	"lastTip": "Poslední strana",
+	"nextTip": "Další strana",
+	"prevTip": "Předchozí strana",
+	"itemTitle": "položek",
+	"pageStepLabelTemplate": "Stránka ${0}",
+	"pageSizeLabelTemplate": "${0} položek na stránce",
+	"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)",
+	"dialogConfirm": "Přejít",
+	"dialogCancel": "Storno"
+})
+
diff --git a/dojox/grid/enhanced/nls/da/EnhancedGrid.js b/dojox/grid/enhanced/nls/da/EnhancedGrid.js
index a9f99fd..c707b5c 100644
--- a/dojox/grid/enhanced/nls/da/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/da/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Enkel sortering",
+	singleSort: "Enkelt sortering",
 	nestedSort: "Indlejret sortering",
 	ascending: "Stigende",
 	descending: "Faldende",
-	unsorted: "Sortér ikke denne kolonne"
+	sortingState: "${0} - ${1}",
+	unsorted: "Sortér ikke denne kolonne",
+	indirectSelectionRadio: "Række ${0}, enkelt valg, valgknap",
+	indirectSelectionCheckBox: "Række ${0}, flere valg, afkrydsningsfelt",
+	selectAll: "Markér alle"
 })
 
diff --git a/dojox/grid/enhanced/nls/da/Filter.js b/dojox/grid/enhanced/nls/da/Filter.js
new file mode 100644
index 0000000..73c0d1c
--- /dev/null
+++ b/dojox/grid/enhanced/nls/da/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Ryd filter",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Regel ${0}",
+	
+	"conditionEqual": "lig med",
+	"conditionNotEqual": "er forskellig fra",
+	"conditionLess": "er mindre end",
+	"conditionLessEqual": "mindre end eller lig med",
+	"conditionLarger": "er større end",
+	"conditionLargerEqual": "større end eller lig med",
+	"conditionContains": "indeholder",
+	"conditionIs": "er",
+	"conditionStartsWith": "begynder med",
+	"conditionEndWith": "slutter med",
+	"conditionNotContain": "indeholder ikke",
+	"conditionIsNot": "er ikke",
+	"conditionNotStartWith": "begynder ikke med",
+	"conditionNotEndWith": "slutter ikke med",
+	"conditionBefore": "før",
+	"conditionAfter": "efter",
+	"conditionRange": "interval",
+	"conditionIsEmpty": "er tom",
+	
+	"all": "alle",
+	"any": "vilkårlig",
+	"relationAll": "alle regler",
+	"waiRelAll": "Matcher alle følgende regler:",
+	"relationAny": "vilkårlige regler",
+	"waiRelAny": "Matcher en eller flere af følgende regler:",
+	"relationMsgFront": "Match",
+	"relationMsgTail": "",
+	"and": "og",
+	"or": "eller",
+	
+	"addRuleButton": "Tilføj regel",
+	"waiAddRuleButton": "Tilføj en ny regel",
+	"removeRuleButton": "Fjern regel",
+	"waiRemoveRuleButtonTemplate": "Fjern reglen ${0}",
+	
+	"cancelButton": "Annullér",
+	"waiCancelButton": "Annullér denne dialogboks",
+	"clearButton": "Ryd",
+	"waiClearButton": "Ryd filtret",
+	"filterButton": "Filter",
+	"waiFilterButton": "Send filtret",
+	
+	"columnSelectLabel": "Kolonne",
+	"waiColumnSelectTemplate": "Kolonne for reglen ${0}",
+	"conditionSelectLabel": "Betingelse",
+	"waiConditionSelectTemplate": "Betingelse for reglen ${0}",
+	"valueBoxLabel": "Værdi",
+	"waiValueBoxTemplate": "Angiv værdi, der skal filtreres efter for reglen ${0}",
+	
+	"rangeTo": "til",
+	"rangeTemplate": "fra ${0} til ${1}",
+	
+	"statusTipHeaderColumn": "Kolonne",
+	"statusTipHeaderCondition": "Regler",
+	"statusTipTitle": "Filterlinje",
+	"statusTipMsg": "Klik på filterlinjen for at filtrere efter værdier i ${0}.",
+	"anycolumn": "vilkårlig kolonne",
+	"statusTipTitleNoFilter": "Filterlinje",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Match",
+	"statusTipRelPost": "regler.",
+	
+	"defaultItemsName": "elementer",
+	"filterBarMsgHasFilterTemplate": "${0} af ${1} ${2} vist.",
+	"filterBarMsgNoFilterTemplate": "Intet filter anvendt",
+	
+	"filterBarDefButton": "Definér filter",
+	"waiFilterBarDefButton": "Filtrér tabellen",
+	"a11yFilterBarDefButton": "Filtrér...",
+	"filterBarClearButton": "Ryd filter",
+	"waiFilterBarClearButton": "Ryd filtret",
+	"closeFilterBarBtn": "Luk filterlinje",
+	
+	"clearFilterMsg": "Denne funktion fjerner filtret og viser alle tilgængelige records.",
+	"anyColumnOption": "Vilkårlig kolonne",
+	
+	"trueLabel": "Sand",
+	"falseLabel": "Falsk"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/da/Pagination.js b/dojox/grid/enhanced/nls/da/Pagination.js
new file mode 100644
index 0000000..fd139bf
--- /dev/null
+++ b/dojox/grid/enhanced/nls/da/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} af ${1} ${0}",
+	"firstTip": "Første side",
+	"lastTip": "Sidste side",
+	"nextTip": "Næste side",
+	"prevTip": "Forrige side",
+	"itemTitle": "elementer",
+	"pageStepLabelTemplate": "Side ${0}",
+	"pageSizeLabelTemplate": "${0} elementer pr. side",
+	"allItemsLabelTemplate": "Alle elementer",
+	"gotoButtonTitle": "Gå til en bestemt side",
+	"dialogTitle": "Gå til side",
+	"dialogIndication": "Angiv sidetallet",
+	"pageCountIndication": " (${0} sider)",
+	"dialogConfirm": "Gå",
+	"dialogCancel": "Annullér"
+})
+
diff --git a/dojox/grid/enhanced/nls/de/EnhancedGrid.js b/dojox/grid/enhanced/nls/de/EnhancedGrid.js
index 58794db..c36bcfd 100644
--- a/dojox/grid/enhanced/nls/de/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/de/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Einfache Sortierung",
+	singleSort: "Einzelne Sortierung",
 	nestedSort: "Verschachtelte Sortierung",
 	ascending: "Aufsteigend",
 	descending: "Absteigend",
-	unsorted: "Spalte nicht sortieren"
+	sortingState: "${0} - ${1}",
+	unsorted: "Diese Spalte nicht sortieren",
+	indirectSelectionRadio: "Zeile ${0}, einzelne Auswahl, Optionsfeld",
+	indirectSelectionCheckBox: "Zeile ${0}, Mehrfachauswahl, Kontrollkästchen",
+	selectAll: "Alles auswählen"
 })
 
diff --git a/dojox/grid/enhanced/nls/de/Filter.js b/dojox/grid/enhanced/nls/de/Filter.js
new file mode 100644
index 0000000..31f6236
--- /dev/null
+++ b/dojox/grid/enhanced/nls/de/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Filter löschen",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Regel ${0}",
+	
+	"conditionEqual": "gleich",
+	"conditionNotEqual": "ungleich",
+	"conditionLess": "kleiner als",
+	"conditionLessEqual": "kleiner-gleich",
+	"conditionLarger": "größer als",
+	"conditionLargerEqual": "größer-gleich",
+	"conditionContains": "enthält",
+	"conditionIs": "ist",
+	"conditionStartsWith": "beginnt mit",
+	"conditionEndWith": "endet mit",
+	"conditionNotContain": "enthält nicht",
+	"conditionIsNot": "ist nicht",
+	"conditionNotStartWith": "beginnt nicht mit",
+	"conditionNotEndWith": "endet nicht mit",
+	"conditionBefore": "vorher",
+	"conditionAfter": "danach",
+	"conditionRange": "Bereich",
+	"conditionIsEmpty": "ist leer",
+	
+	"all": "alle",
+	"any": "beliebige",
+	"relationAll": "alle Regeln",
+	"waiRelAll": "Stimmt mit allen der folgenden Regeln überein:",
+	"relationAny": "beliebige Regeln",
+	"waiRelAny": "Stimmt mit einer beliebigen der folgenden Regeln überein:",
+	"relationMsgFront": "Übereinstimmung",
+	"relationMsgTail": "",
+	"and": "und",
+	"or": "oder",
+	
+	"addRuleButton": "Regel hinzufügen",
+	"waiAddRuleButton": "Neue Regel hinzufügen",
+	"removeRuleButton": "Regel entfernen",
+	"waiRemoveRuleButtonTemplate": "Regel ${0} entfernen",
+	
+	"cancelButton": "Abbrechen",
+	"waiCancelButton": "Diesen Dialog abbrechen",
+	"clearButton": "Löschen",
+	"waiClearButton": "Den Filter löschen",
+	"filterButton": "Filter",
+	"waiFilterButton": "Den Filter abschicken",
+	
+	"columnSelectLabel": "Spalte",
+	"waiColumnSelectTemplate": "Spalte für Regel ${0}",
+	"conditionSelectLabel": "Bedingung",
+	"waiConditionSelectTemplate": "Bedingung für Regel ${0}",
+	"valueBoxLabel": "Wert",
+	"waiValueBoxTemplate": "Wert eingeben, um nach Regel ${0} zu filtern",
+	
+	"rangeTo": "bis",
+	"rangeTemplate": "von ${0} bis ${1}",
+	
+	"statusTipHeaderColumn": "Spalte",
+	"statusTipHeaderCondition": "Regeln",
+	"statusTipTitle": "Filterleiste",
+	"statusTipMsg": "Klicken Sie auf die Filterleiste hier, um nach Werten in ${0} zu filtern.",
+	"anycolumn": "beliebige Spalte",
+	"statusTipTitleNoFilter": "Filterleiste",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Übereinstimmung",
+	"statusTipRelPost": "Regeln.",
+	
+	"defaultItemsName": "Elemente",
+	"filterBarMsgHasFilterTemplate": "${0} von ${1} ${2} angezeigt.",
+	"filterBarMsgNoFilterTemplate": "Kein Filter angewendet",
+	
+	"filterBarDefButton": "Filter definieren",
+	"waiFilterBarDefButton": "Die Tabelle filtern",
+	"a11yFilterBarDefButton": "Filter...",
+	"filterBarClearButton": "Filter löschen",
+	"waiFilterBarClearButton": "Den Filter löschen",
+	"closeFilterBarBtn": "Filterleiste schließen",
+	
+	"clearFilterMsg": "Damit wird der Filter gelöscht und es werden alle verfügbaren Sätze angezeigt.",
+	"anyColumnOption": "Beliebige Spalte",
+	
+	"trueLabel": "Wahr",
+	"falseLabel": "Falsch"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/de/Pagination.js b/dojox/grid/enhanced/nls/de/Pagination.js
new file mode 100644
index 0000000..05e0e64
--- /dev/null
+++ b/dojox/grid/enhanced/nls/de/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} von ${1} ${0}",
+	"firstTip": "Erste Seite",
+	"lastTip": "Letzte Seite",
+	"nextTip": "Nächste Seite",
+	"prevTip": "Vorherige Seite",
+	"itemTitle": "Elemente",
+	"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.",
+	"pageCountIndication": " (${0} Seiten)",
+	"dialogConfirm": "Start",
+	"dialogCancel": "Abbrechen"
+})
+
diff --git a/dojox/grid/enhanced/nls/el/Filter.js b/dojox/grid/enhanced/nls/el/Filter.js
new file mode 100644
index 0000000..4111980
--- /dev/null
+++ b/dojox/grid/enhanced/nls/el/Filter.js
@@ -0,0 +1,88 @@
+({
+	"clearFilterDialogTitle": "Εκκαθάριση φίλτρου",
+	"filterDefDialogTitle": "Φίλτρο",
+	"incompleteRuleTip": "Αυτός ο κανόνας δεν είναι πλήρης.",
+	"ruleTitleTemplate": "Κανόνας ${0}",
+	
+	"conditionEqual": "ίσο",
+	"conditionNotEqual": "όχι ίσο",
+	"conditionLess": "είναι μικρότερο από",
+	"conditionLessEqual": "μικρότερο ή ίσο",
+	"conditionLarger": "είναι μεγαλύτερο από",
+	"conditionLargerEqual": "μεγαλύτερο ή ίσο",
+	"conditionContains": "περιέχει",
+	"conditionIs": "είναι",
+	"conditionStartsWith": "αρχίζει από",
+	"conditionEndWith": "τελειώνει σε",
+	"conditionNotContain": "δεν περιέχει",
+	"conditionIsNot": "δεν είναι",
+	"conditionNotStartWith": "δεν αρχίζει από",
+	"conditionNotEndWith": "δεν τελειώνει σε",
+	"conditionBefore": "πριν",
+	"conditionAfter": "μετά",
+	"conditionRange": "εύρος",
+	
+	"all": "όλα",
+	"any": "οποιοδήποτε",
+	"relationAll": "όλοι οι κανόνες",
+	"waiRelAll": "Αντιστοιχία με όλους τους παρακάτω κανόνες:",
+	"relationAny": "οποιοσδήποτε κανόνας",
+	"waiRelAny": "Αντιστοιχία με οποιονδήποτε από τους παρακάτω κανόνες:",
+	"relationMsgFront": "Αντιστοιχία",
+	"relationMsgTail": "",
+	"and": "και",
+	"or": "ή",
+	
+	"addRuleButton": "Προσθήκη κανόνα",
+	"waiAddRuleButton": "Προσθήκη νέου κανόνα",
+	"removeRuleButton": "Αφαίρεση κανόνα",
+	"waiRemoveRuleButtonTemplate": "Αφαίρεση κανόνα ${0}",
+	
+	"cancelButton": "Ακύρωση",
+	"waiCancelButton": "Ακύρωση αυτού του πλαισίου διαλόγου",
+	"clearButton": "Εκκαθάριση",
+	"waiClearButton": "Εκκαθάριση του φίλτρου",
+	"filterButton": "Φίλτρο",
+	"waiFilterButton": "Υποβολή του φίλτρου",
+	
+	"columnSelectLabel": "Στήλη",
+	"waiColumnSelectTemplate": "Στήλη για τον κανόνα ${0}",
+	"conditionSelectLabel": "Συνθήκη",
+	"waiConditionSelectTemplate": "Συνθήκη για τον κανόνα ${0}",
+	"valueBoxLabel": "Τιμή",
+	"waiValueBoxTemplate": "Καταχωρήστε τιμή φίλτρου για τον κανόνα ${0}",
+	
+	"rangeTo": "έως",
+	"rangeTemplate": "από ${0} έως ${1}",
+	
+	"statusTipHeaderColumn": "Στήλη",
+	"statusTipHeaderCondition": "Κανόνες",
+	"statusTipTitle": "Γραμμή φίλτρου",
+	"statusTipMsg": "Πατήστε στη γραμμή φίλτρου για φιλτράρισμα με βάση τις τιμές στο ${0}.",
+	"anycolumn": "οποιαδήποτε στήλη",
+	"statusTipTitleNoFilter": "Γραμμή φίλτρου",
+	"statusTipTitleHasFilter": "Φίλτρο",
+	"statusTipRelPre": "Αντιστοιχία",
+	"statusTipRelPost": "κανόνες.",
+	
+	"defaultItemsName": "στοιχεία",
+	"filterBarMsgHasFilterTemplate": "Εμφανίζονται ${0} από ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Δεν έχει εφαρμοστεί φίλτρο",
+	
+	"filterBarDefButton": "Ορισμός φίλτρου",
+	"waiFilterBarDefButton": "Φιλτράρισμα του πίνακα",
+	"a11yFilterBarDefButton": "Φιλτράρισμα...",
+	"filterBarClearButton": "Εκκαθάριση φίλτρου",
+	"waiFilterBarClearButton": "Εκκαθάριση του φίλτρου",
+	"closeFilterBarBtn": "Κλείσιμο γραμμής φίλτρου",
+	
+	"clearFilterMsg": "Με την επιλογή αυτή θα αφαιρεθεί το φίλτρο και θα εμφανιστούν όλες οι διαθέσιμες εγγραφές.",
+	"anyColumnOption": "Οποιαδήποτε στήλη",
+	
+	"trueLabelEditable": "Επιλεγμένο",
+	"trueLabel": "Αληθές",
+	"falseLabel": "Ψευδές"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/el/Pagination.js b/dojox/grid/enhanced/nls/el/Pagination.js
new file mode 100644
index 0000000..bb4ad80
--- /dev/null
+++ b/dojox/grid/enhanced/nls/el/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} από ${1} ${0}",
+	"firstTip": "Πρώτη σελίδα",
+	"lastTip": "Τελευταία σελίδα",
+	"nextTip": "Επόμενη σελίδα",
+	"prevTip": "Προηγούμενη σελίδα",
+	"itemTitle": "στοιχεία",
+	"pageStepLabelTemplate": "Σελίδα ${0}",
+	"pageSizeLabelTemplate": "${0} στοιχεία ανά σελίδα",
+	"allItemsLabelTemplate": "Όλα τα στοιχεία",
+	"gotoButtonTitle": "Μετάβαση σε συγκεκριμένη σελίδα",
+	"dialogTitle": "Μετάβαση σε σελίδα",
+	"dialogIndication": "Καθορίστε τον αριθμό της σελίδας",
+	"pageCountIndication": " (${0} σελίδες)",
+	"dialogConfirm": "Μετάβαση",
+	"dialogCancel": "Ακύρωση"
+})
+
diff --git a/dojox/grid/enhanced/nls/es/EnhancedGrid.js b/dojox/grid/enhanced/nls/es/EnhancedGrid.js
index 5cb045f..38614ca 100644
--- a/dojox/grid/enhanced/nls/es/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/es/EnhancedGrid.js
@@ -3,6 +3,10 @@
 	nestedSort: "Orden anidado",
 	ascending: "Ascendente",
 	descending: "Descendente",
-	unsorted: "No ordenar esta columna"
+	sortingState: "${0} - ${1}",
+	unsorted: "No ordenar esta columna",
+	indirectSelectionRadio: "Fila ${0}, selección única, botón de selección",
+	indirectSelectionCheckBox: "Fila ${0}, selección múltiple, recuadro de selección",
+	selectAll: "Seleccionar todo"
 })
 
diff --git a/dojox/grid/enhanced/nls/es/Filter.js b/dojox/grid/enhanced/nls/es/Filter.js
new file mode 100644
index 0000000..a858170
--- /dev/null
+++ b/dojox/grid/enhanced/nls/es/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Borrar filtro",
+	"filterDefDialogTitle": "Filtro",
+	"ruleTitleTemplate": "Regla ${0}",
+	
+	"conditionEqual": "es igual a",
+	"conditionNotEqual": "no es igual a",
+	"conditionLess": "es menor que",
+	"conditionLessEqual": "es menor o igual que",
+	"conditionLarger": "es mayor que",
+	"conditionLargerEqual": "es mayor o igual que",
+	"conditionContains": "contiene",
+	"conditionIs": "es",
+	"conditionStartsWith": "empieza por",
+	"conditionEndWith": "acaba por",
+	"conditionNotContain": "no contiene",
+	"conditionIsNot": "no es",
+	"conditionNotStartWith": "no empieza por",
+	"conditionNotEndWith": "no acaba por",
+	"conditionBefore": "antes",
+	"conditionAfter": "después",
+	"conditionRange": "rango",
+	"conditionIsEmpty": "está vacío",
+	
+	"all": "todas",
+	"any": "cualquiera",
+	"relationAll": "todas las reglas",
+	"waiRelAll": "Coincidir con todas las reglas siguientes:",
+	"relationAny": "cualquier regla",
+	"waiRelAny": "Coincidir con cualquiera de las reglas siguientes:",
+	"relationMsgFront": "Coincidir",
+	"relationMsgTail": "",
+	"and": "y",
+	"or": "o",
+	
+	"addRuleButton": "Añadir regla",
+	"waiAddRuleButton": "Añadir una regla nueva",
+	"removeRuleButton": "Eliminar regla",
+	"waiRemoveRuleButtonTemplate": "Eliminar la regla ${0}",
+	
+	"cancelButton": "Cancelar",
+	"waiCancelButton": "Cancelar este diálogo",
+	"clearButton": "Borrar",
+	"waiClearButton": "Borrar el filtro",
+	"filterButton": "Filtrar",
+	"waiFilterButton": "Enviar el filtro",
+	
+	"columnSelectLabel": "Columna",
+	"waiColumnSelectTemplate": "Columna para la regla ${0}",
+	"conditionSelectLabel": "Condición",
+	"waiConditionSelectTemplate": "Condición para la regla ${0}",
+	"valueBoxLabel": "Valor",
+	"waiValueBoxTemplate": "Escriba el valor que se debe filtrar para la regla ${0}",
+	
+	"rangeTo": "a",
+	"rangeTemplate": "de ${0} a ${1}",
+	
+	"statusTipHeaderColumn": "Columna",
+	"statusTipHeaderCondition": "Reglas",
+	"statusTipTitle": "Barra de filtro",
+	"statusTipMsg": "Pulse aquí en la barra de filtro para filtrar por los valores de ${0}.",
+	"anycolumn": "cualquier columna",
+	"statusTipTitleNoFilter": "Barra de filtro",
+	"statusTipTitleHasFilter": "Filtro",
+	"statusTipRelPre": "Coincidir",
+	"statusTipRelPost": "reglas.",
+	
+	"defaultItemsName": "elementos",
+	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} mostrados.",
+	"filterBarMsgNoFilterTemplate": "Ningún filtro aplicado",
+	
+	"filterBarDefButton": "Definir filtro",
+	"waiFilterBarDefButton": "Filtrar la tabla",
+	"a11yFilterBarDefButton": "Filtrar...",
+	"filterBarClearButton": "Borrar filtro",
+	"waiFilterBarClearButton": "Borrar el filtro",
+	"closeFilterBarBtn": "Cerrar barra de filtro",
+	
+	"clearFilterMsg": "Esto eliminará el filtro y mostrará todos los registros disponibles.",
+	"anyColumnOption": "Cualquier columna",
+	
+	"trueLabel": "Verdadero",
+	"falseLabel": "Falso"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/es/Pagination.js b/dojox/grid/enhanced/nls/es/Pagination.js
new file mode 100644
index 0000000..fb950e5
--- /dev/null
+++ b/dojox/grid/enhanced/nls/es/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} de ${1} ${0}",
+	"firstTip": "Primera página",
+	"lastTip": "Última página",
+	"nextTip": "Página siguiente",
+	"prevTip": "Página anterior",
+	"itemTitle": "elementos",
+	"pageStepLabelTemplate": "Página ${0}",
+	"pageSizeLabelTemplate": "${0} elementos por página",
+	"allItemsLabelTemplate": "Todos los elementos",
+	"gotoButtonTitle": "Ir a una página específica",
+	"dialogTitle": "Ir a página",
+	"dialogIndication": "Especifique el número de página",
+	"pageCountIndication": " (${0} páginas)",
+	"dialogConfirm": "Ir",
+	"dialogCancel": "Cancelar"
+})
+
diff --git a/dojox/grid/enhanced/nls/fi/EnhancedGrid.js b/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
index f88be60..524eceb 100644
--- a/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/fi/EnhancedGrid.js
@@ -3,6 +3,10 @@
 	nestedSort: "Sisäkkäinen lajittelu",
 	ascending: "Nouseva",
 	descending: "Laskeva",
-	unsorted: "Älä lajittele tätä saraketta"
+	sortingState: "${0} - ${1}",
+	unsorted: "Älä lajittele tätä saraketta",
+	indirectSelectionRadio: "Rivi ${0}, yksittäisvalinta, ruutu",
+	indirectSelectionCheckBox: "Rivi ${0}, monivalinta, valintaruutu",
+	selectAll: "Valitse kaikki"
 })
 
diff --git a/dojox/grid/enhanced/nls/fi/Filter.js b/dojox/grid/enhanced/nls/fi/Filter.js
new file mode 100644
index 0000000..2842259
--- /dev/null
+++ b/dojox/grid/enhanced/nls/fi/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Tyhjennä suodatin",
+	"filterDefDialogTitle": "Suodatin",
+	"ruleTitleTemplate": "Sääntö ${0}",
+	
+	"conditionEqual": "yhtä suuri kuin",
+	"conditionNotEqual": "ei ole yhtä suuri kuin",
+	"conditionLess": "on pienempi kuin",
+	"conditionLessEqual": "pienempi tai yhtä suuri kuin",
+	"conditionLarger": "on suurempi kuin",
+	"conditionLargerEqual": "suurempi tai yhtä suuri kuin",
+	"conditionContains": "sisältää",
+	"conditionIs": "on",
+	"conditionStartsWith": "alussa on",
+	"conditionEndWith": "lopussa on",
+	"conditionNotContain": "ei sisällä",
+	"conditionIsNot": "ei ole",
+	"conditionNotStartWith": "alussa ei ole",
+	"conditionNotEndWith": "lopussa ei ole",
+	"conditionBefore": "ennen",
+	"conditionAfter": "jälkeen",
+	"conditionRange": "vaihtelualue",
+	"conditionIsEmpty": "on tyhjä",
+	
+	"all": "kaikki",
+	"any": "mikä tahansa",
+	"relationAll": "kaikki säännöt",
+	"waiRelAll": "Täsmäytä kaikki seuraavat säännöt:",
+	"relationAny": "mitkä tahansa säännöt",
+	"waiRelAny": "Täsmäytä mitkä tahansa seuraavista säännöistä:",
+	"relationMsgFront": "Vastine",
+	"relationMsgTail": "",
+	"and": "ja",
+	"or": "tai",
+	
+	"addRuleButton": "Lisää sääntö",
+	"waiAddRuleButton": "Lisää uusi sääntö",
+	"removeRuleButton": "Poista sääntö",
+	"waiRemoveRuleButtonTemplate": "Poista sääntö ${0}",
+	
+	"cancelButton": "Peruuta",
+	"waiCancelButton": "Peruuta keskustelu",
+	"clearButton": "Tyhjennä",
+	"waiClearButton": "Tyhjennä suodatin",
+	"filterButton": "Suodata",
+	"waiFilterButton": "Lähetä suodatin",
+	
+	"columnSelectLabel": "Sarake",
+	"waiColumnSelectTemplate": "Säännön ${0} sarake",
+	"conditionSelectLabel": "Ehto",
+	"waiConditionSelectTemplate": "Säännön ${0} ehto",
+	"valueBoxLabel": "Arvo",
+	"waiValueBoxTemplate": "Syötä säännön ${0} suodatettava arvo",
+	
+	"rangeTo": "kohde",
+	"rangeTemplate": "lähde ${0}, kohde ${1}",
+	
+	"statusTipHeaderColumn": "Sarake",
+	"statusTipHeaderCondition": "Säännöt",
+	"statusTipTitle": "Suodatinpalkki",
+	"statusTipMsg": "Napsauta suodatinpalkkia kohteen ${0} arvojen suodattamiseksi.",
+	"anycolumn": "mikä tahansa sarake",
+	"statusTipTitleNoFilter": "Suodatinpalkki",
+	"statusTipTitleHasFilter": "Suodatin",
+	"statusTipRelPre": "Vastine",
+	"statusTipRelPost": "säännöt.",
+	
+	"defaultItemsName": "nimikkeet",
+	"filterBarMsgHasFilterTemplate": "näkyvissä ${0} / ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Mikään suodatin ei ole käytössä",
+	
+	"filterBarDefButton": "Määritä suodatin",
+	"waiFilterBarDefButton": "Suodata taulukko",
+	"a11yFilterBarDefButton": "Suodata...",
+	"filterBarClearButton": "Tyhjennä suodatin",
+	"waiFilterBarClearButton": "Tyhjennä suodatin",
+	"closeFilterBarBtn": "Sulje suodatinpalkki",
+	
+	"clearFilterMsg": "Tämä toimenpide poistaa suodattimen ja näyttää kaikki saatavilla olevat tallenteet.",
+	"anyColumnOption": "Mikä tahansa sarake",
+	
+	"trueLabel": "Tosi",
+	"falseLabel": "Epätosi"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/fi/Pagination.js b/dojox/grid/enhanced/nls/fi/Pagination.js
new file mode 100644
index 0000000..8447738
--- /dev/null
+++ b/dojox/grid/enhanced/nls/fi/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} / ${1} ${0}",
+	"firstTip": "Ensimmäinen sivu",
+	"lastTip": "Viimeinen sivu",
+	"nextTip": "Seuraava sivu",
+	"prevTip": "Edellinen sivu",
+	"itemTitle": "nimikkeet",
+	"pageStepLabelTemplate": "Sivu ${0}",
+	"pageSizeLabelTemplate": "${0} nimikettä sivua kohti",
+	"allItemsLabelTemplate": "Kaikki nimikkeet",
+	"gotoButtonTitle": "Siirry tietylle sivulle",
+	"dialogTitle": "Siirry sivulle",
+	"dialogIndication": "Kirjoita sivunumero",
+	"pageCountIndication": " (${0} sivua)",
+	"dialogConfirm": "Siirry",
+	"dialogCancel": "Peruuta"
+})
+
diff --git a/dojox/grid/enhanced/nls/fr/EnhancedGrid.js b/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
index 25e455f..d7c7205 100644
--- a/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/fr/EnhancedGrid.js
@@ -1,8 +1,12 @@
-({
-	singleSort: "Tri unique",
+({
+	singleSort: "Tri simple",
 	nestedSort: "Tri imbriqué",
 	ascending: "Croissant",
 	descending: "Décroissant",
-	unsorted: "Ne pas trier cette colonne"
+	sortingState: "${0} - ${1}",
+	unsorted: "Ne pas trier cette colonne",
+	indirectSelectionRadio: "Ligne ${0}, sélection unique, bouton radio",
+	indirectSelectionCheckBox: "Ligne ${0}, sélection multiple, case à cocher",
+	selectAll: "Tout sélectionner"
 })
 
diff --git a/dojox/grid/enhanced/nls/fr/Filter.js b/dojox/grid/enhanced/nls/fr/Filter.js
new file mode 100644
index 0000000..7b3dcd4
--- /dev/null
+++ b/dojox/grid/enhanced/nls/fr/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Effacer le filtre",
+	"filterDefDialogTitle": "Filtrer",
+	"ruleTitleTemplate": "Règle ${0}",
+	
+	"conditionEqual": "égal",
+	"conditionNotEqual": "est différent de",
+	"conditionLess": "est inférieur à",
+	"conditionLessEqual": "inférieur ou égal",
+	"conditionLarger": "est supérieur à",
+	"conditionLargerEqual": "supérieur ou égal",
+	"conditionContains": "contient",
+	"conditionIs": "est",
+	"conditionStartsWith": "commence par",
+	"conditionEndWith": "se termine par",
+	"conditionNotContain": "ne contient pas",
+	"conditionIsNot": "n'est pas",
+	"conditionNotStartWith": "ne commence pas par",
+	"conditionNotEndWith": "ne se termine pas par",
+	"conditionBefore": "avant",
+	"conditionAfter": "après",
+	"conditionRange": "plage",
+	"conditionIsEmpty": "est vide",
+	
+	"all": "tout",
+	"any": "n'importe quelle",
+	"relationAll": "toutes les règles",
+	"waiRelAll": "Satisfaire à toutes les règles suivantes :",
+	"relationAny": "n'importe quelles règles",
+	"waiRelAny": "Satisfaire à une quelconque des règles suivantes :",
+	"relationMsgFront": "Satisfaire",
+	"relationMsgTail": "",
+	"and": "et",
+	"or": "ou",
+	
+	"addRuleButton": "Ajouter une règle",
+	"waiAddRuleButton": "Ajouter une nouvelle règle",
+	"removeRuleButton": "Supprimer la règle",
+	"waiRemoveRuleButtonTemplate": "Supprimer la règle ${0}",
+	
+	"cancelButton": "Annuler",
+	"waiCancelButton": "Annuler cette boîte de dialogue",
+	"clearButton": "Effacer",
+	"waiClearButton": "Effacer le filtre",
+	"filterButton": "Filtrer",
+	"waiFilterButton": "Soumettre le filtre",
+	
+	"columnSelectLabel": "Colonne",
+	"waiColumnSelectTemplate": "Colonne pour la règle ${0}",
+	"conditionSelectLabel": "Condition",
+	"waiConditionSelectTemplate": "Condition pour la règle ${0}",
+	"valueBoxLabel": "Valeur",
+	"waiValueBoxTemplate": "Saisir la valeur à filtrer pour la règle ${0}",
+	
+	"rangeTo": "à",
+	"rangeTemplate": "de ${0} à ${1}",
+	
+	"statusTipHeaderColumn": "Colonne",
+	"statusTipHeaderCondition": "Règles",
+	"statusTipTitle": "Barre de filtre",
+	"statusTipMsg": "Cliquer sur la barre de filtre ici pour filtrer sur les valeurs de ${0}.",
+	"anycolumn": "n'importe quelle colonne",
+	"statusTipTitleNoFilter": "Barre de filtre",
+	"statusTipTitleHasFilter": "Filtrer",
+	"statusTipRelPre": "Satisfaire",
+	"statusTipRelPost": "règles.",
+	
+	"defaultItemsName": "éléments",
+	"filterBarMsgHasFilterTemplate": "${0} sur ${1} ${2} affichés.",
+	"filterBarMsgNoFilterTemplate": "Aucun filtre appliqué",
+	
+	"filterBarDefButton": "Définir le filtre",
+	"waiFilterBarDefButton": "Filtrer le tableau",
+	"a11yFilterBarDefButton": "Filtrer...",
+	"filterBarClearButton": "Effacer le filtre",
+	"waiFilterBarClearButton": "Effacer le filtre",
+	"closeFilterBarBtn": "Fermer la barre de filtre",
+	
+	"clearFilterMsg": "Cela supprimera le filtre et affichera tous les enregistrements disponibles.",
+	"anyColumnOption": "N'importe quelle colonne",
+	
+	"trueLabel": "Vrai",
+	"falseLabel": "Faux"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/fr/Pagination.js b/dojox/grid/enhanced/nls/fr/Pagination.js
new file mode 100644
index 0000000..bae2b9d
--- /dev/null
+++ b/dojox/grid/enhanced/nls/fr/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"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",
+	"pageStepLabelTemplate": "Page ${0}",
+	"pageSizeLabelTemplate": "${0} éléments par page",
+	"allItemsLabelTemplate": "Tous les éléments",
+	"gotoButtonTitle": "Aller à une page donnée",
+	"dialogTitle": "Aller à la page",
+	"dialogIndication": "Indiquer le numéro de page",
+	"pageCountIndication": " (${0} pages)",
+	"dialogConfirm": "Aller",
+	"dialogCancel": "Annuler"
+})
+
diff --git a/dojox/grid/enhanced/nls/he/EnhancedGrid.js b/dojox/grid/enhanced/nls/he/EnhancedGrid.js
index 06b5242..db4ed87 100644
--- a/dojox/grid/enhanced/nls/he/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/he/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
 	singleSort: "מיון יחיד",
-	nestedSort: "מיון מקונן ",
+	nestedSort: "מיון מקונן",
 	ascending: "עולה",
 	descending: "יורד",
-	unsorted: "לא למיין עמודה זו "
+	sortingState: "${0} - ${1}",
+	unsorted: "אין למיין עמודה זו",
+	indirectSelectionRadio: "שורה ${0}, בחירה יחידה, תיבת בחירה",
+	indirectSelectionCheckBox: "שורה ${0}, בחירה מרובה, תיבת סימון",
+	selectAll: "בחירת הכל"
 })
 
diff --git a/dojox/grid/enhanced/nls/he/Filter.js b/dojox/grid/enhanced/nls/he/Filter.js
new file mode 100644
index 0000000..63fa21a
--- /dev/null
+++ b/dojox/grid/enhanced/nls/he/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "ניקוי מסנן",
+	"filterDefDialogTitle": "מסנן",
+	"ruleTitleTemplate": "כלל ${0}",
+	
+	"conditionEqual": "שווה",
+	"conditionNotEqual": "לא שווה",
+	"conditionLess": "קטן מ",
+	"conditionLessEqual": "קטן או שווה",
+	"conditionLarger": "גדול מ",
+	"conditionLargerEqual": "גדול או שווה",
+	"conditionContains": "מכיל",
+	"conditionIs": "הוא",
+	"conditionStartsWith": "מתחיל ב",
+	"conditionEndWith": "מסתיים ב",
+	"conditionNotContain": "לא מכיל",
+	"conditionIsNot": "אינו",
+	"conditionNotStartWith": "לא מתחיל ב",
+	"conditionNotEndWith": "לא מסתיים ב",
+	"conditionBefore": "לפני",
+	"conditionAfter": "אחרי",
+	"conditionRange": "טווח",
+	"conditionIsEmpty": "ריק",
+	
+	"all": "הכל",
+	"any": "כל",
+	"relationAll": "כל הכללים",
+	"waiRelAll": "התאמה לכל הכללים הבאים:",
+	"relationAny": "כל כלל שהוא",
+	"waiRelAny": "התאמה לכל אחד מהכללים הבאים:",
+	"relationMsgFront": "התאמה",
+	"relationMsgTail": "",
+	"and": "ו",
+	"or": "או",
+	
+	"addRuleButton": "הוספת כלל",
+	"waiAddRuleButton": "הוספת כלל חדש",
+	"removeRuleButton": "סילוק כלל",
+	"waiRemoveRuleButtonTemplate": "סילוק כלל ${0}",
+	
+	"cancelButton": "ביטול",
+	"waiCancelButton": "ביטול תיבת דו-שיח זו",
+	"clearButton": "ניקוי",
+	"waiClearButton": "ניקוי המסנן",
+	"filterButton": "מסנן",
+	"waiFilterButton": "הגשת המסנן",
+	
+	"columnSelectLabel": "עמודה",
+	"waiColumnSelectTemplate": "עמודה עבור כלל ${0}",
+	"conditionSelectLabel": "תנאי",
+	"waiConditionSelectTemplate": "תנאי עבור כלל ${0}",
+	"valueBoxLabel": "ערך",
+	"waiValueBoxTemplate": "ציון ערך לסינון עבור כלל ${0}",
+	
+	"rangeTo": "עד",
+	"rangeTemplate": "מ-${0} עד ${1}",
+	
+	"statusTipHeaderColumn": "עמודה",
+	"statusTipHeaderCondition": "כללים",
+	"statusTipTitle": "סרגל סינון",
+	"statusTipMsg": "לחצו על סרגל הסינון כאן כדי לסנן ערכים ב-${0}.",
+	"anycolumn": "כל עמודה",
+	"statusTipTitleNoFilter": "סרגל סינון",
+	"statusTipTitleHasFilter": "מסנן",
+	"statusTipRelPre": "התאמה",
+	"statusTipRelPost": "כללים.",
+	
+	"defaultItemsName": "פריטים",
+	"filterBarMsgHasFilterTemplate": "מוצג ${0} מתוך ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "לא הוחל מסנן",
+	
+	"filterBarDefButton": "הגדרת מסנן",
+	"waiFilterBarDefButton": "סינון הטבלה",
+	"a11yFilterBarDefButton": "מסנן...",
+	"filterBarClearButton": "ניקוי מסנן",
+	"waiFilterBarClearButton": "ניקוי המסנן",
+	"closeFilterBarBtn": "סגירת סרגל סינון",
+	
+	"clearFilterMsg": "פעולה זו תגרום לסילוק המסנן ולהצגת כל הרשומות הזמינות.",
+	"anyColumnOption": "כל עמודה",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/he/Pagination.js b/dojox/grid/enhanced/nls/he/Pagination.js
new file mode 100644
index 0000000..c7e3d66
--- /dev/null
+++ b/dojox/grid/enhanced/nls/he/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} מתוך ${1} ${0}",
+	"firstTip": "עמוד ראשון",
+	"lastTip": "עמוד אחרון",
+	"nextTip": "העמוד הבא",
+	"prevTip": "העמוד הקודם",
+	"itemTitle": "פריטים",
+	"pageStepLabelTemplate": "עמוד ${0}",
+	"pageSizeLabelTemplate": "${0} פריטים לעמוד",
+	"allItemsLabelTemplate": "כל הפריטים",
+	"gotoButtonTitle": "מעבר לעמוד ספציפי",
+	"dialogTitle": "מעבר לעמוד",
+	"dialogIndication": "ציון מספר העמוד",
+	"pageCountIndication": " (${0} עמודים)",
+	"dialogConfirm": "ביצוע",
+	"dialogCancel": "ביטול"
+})
+
diff --git a/dojox/grid/enhanced/nls/hr/EnhancedGrid.js b/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
new file mode 100644
index 0000000..ffc8e0b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/hr/EnhancedGrid.js
@@ -0,0 +1,12 @@
+({
+	singleSort: "Jedan sort",
+	nestedSort: "Ugniježđeni sort",
+	ascending: "Uzlazno",
+	descending: "Silazno",
+	sortingState: "${0} - ${1}",
+	unsorted: "Ne sortiraj ovaj stupac",
+	indirectSelectionRadio: "Red ${0}, jedan izbor, radio kućica",
+	indirectSelectionCheckBox: "Red ${0}, više izbora, kontrolna kućica",
+	selectAll: "Izaberi sve"
+})
+
diff --git a/dojox/grid/enhanced/nls/hr/Filter.js b/dojox/grid/enhanced/nls/hr/Filter.js
new file mode 100644
index 0000000..58cb3c9
--- /dev/null
+++ b/dojox/grid/enhanced/nls/hr/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Brisanje filtera",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Pravilo ${0}",
+	
+	"conditionEqual": "jednako",
+	"conditionNotEqual": "nije jednako",
+	"conditionLess": "je manje od",
+	"conditionLessEqual": "manje ili jednako",
+	"conditionLarger": "je veće od",
+	"conditionLargerEqual": "veće ili jednako",
+	"conditionContains": "sadrži",
+	"conditionIs": "je",
+	"conditionStartsWith": "počinje sa",
+	"conditionEndWith": "završava sa",
+	"conditionNotContain": "ne sadrži",
+	"conditionIsNot": "nije",
+	"conditionNotStartWith": "ne počinje sa",
+	"conditionNotEndWith": "ne završava sa",
+	"conditionBefore": "prije",
+	"conditionAfter": "poslije",
+	"conditionRange": "raspon",
+	"conditionIsEmpty": "je prazan",
+	
+	"all": "svi",
+	"any": "bilo koji",
+	"relationAll": "sva pravila",
+	"waiRelAll": "Usporedi sva sljedeća pravila:",
+	"relationAny": "bilo koja pravila",
+	"waiRelAny": "Usporedi bilo koje od sljedećih pravila:",
+	"relationMsgFront": "Odgovara",
+	"relationMsgTail": "",
+	"and": "i",
+	"or": "ili",
+	
+	"addRuleButton": "Bilo koje pravilo",
+	"waiAddRuleButton": "Dodaj novo pravilo",
+	"removeRuleButton": "Ukloni pravilo",
+	"waiRemoveRuleButtonTemplate": "Ukloni pravilo ${0}",
+	
+	"cancelButton": "Opoziv",
+	"waiCancelButton": "Opoziv ovog dijaloga",
+	"clearButton": "Obriši",
+	"waiClearButton": "Obriši filter",
+	"filterButton": "Filter",
+	"waiFilterButton": "Predaj filter",
+	
+	"columnSelectLabel": "Stupac",
+	"waiColumnSelectTemplate": "Stupac za pravilo ${0}",
+	"conditionSelectLabel": "Uvjet",
+	"waiConditionSelectTemplate": "Uvjet za pravilo ${0}",
+	"valueBoxLabel": "Vrijednost",
+	"waiValueBoxTemplate": "Unesite vrijednost filtera za pravilo ${0}",
+	
+	"rangeTo": "do",
+	"rangeTemplate": "od ${0} do ${1}",
+	
+	"statusTipHeaderColumn": "Stupac",
+	"statusTipHeaderCondition": "Pravila",
+	"statusTipTitle": "Traka filtera",
+	"statusTipMsg": "Kliknite traku filtera za filtriranje po vrijednostima u ${0}.",
+	"anycolumn": "bilo koji stupac",
+	"statusTipTitleNoFilter": "Traka filtera",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Odgovara",
+	"statusTipRelPost": "pravila.",
+	
+	"defaultItemsName": "stavke",
+	"filterBarMsgHasFilterTemplate": "${0} od ${1} ${2} prikazano.",
+	"filterBarMsgNoFilterTemplate": "Filter nije primijenjen",
+	
+	"filterBarDefButton": "Definiraj filter",
+	"waiFilterBarDefButton": "Filtriraj tablicu",
+	"a11yFilterBarDefButton": "Filtriraj...",
+	"filterBarClearButton": "Obriši filter",
+	"waiFilterBarClearButton": "Obriši filter",
+	"closeFilterBarBtn": "Zatvori traku filtera",
+	
+	"clearFilterMsg": "Ovo uklanja filter i prikazuje sve raspoložive slogove.",
+	"anyColumnOption": "Bilo koji stupac",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/hr/Pagination.js b/dojox/grid/enhanced/nls/hr/Pagination.js
new file mode 100644
index 0000000..5205ad0
--- /dev/null
+++ b/dojox/grid/enhanced/nls/hr/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} od ${1} ${0}",
+	"firstTip": "Prva stranica",
+	"lastTip": "Zadnja stranica",
+	"nextTip": "Sljedeća stranica",
+	"prevTip": "Prethodna stranica",
+	"itemTitle": "stavke",
+	"pageStepLabelTemplate": "Strana ${0}",
+	"pageSizeLabelTemplate": "${0} stavki po stranici",
+	"allItemsLabelTemplate": "Sve stavke",
+	"gotoButtonTitle": "Idi na određenu stranicu",
+	"dialogTitle": "Idi na stranicu",
+	"dialogIndication": "Navedite broj stranice",
+	"pageCountIndication": " (${0} stranica)",
+	"dialogConfirm": "Idi",
+	"dialogCancel": "Opoziv"
+})
+
diff --git a/dojox/grid/enhanced/nls/hu/EnhancedGrid.js b/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
index de91f1d..f20fd41 100644
--- a/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/hu/EnhancedGrid.js
@@ -3,6 +3,10 @@
 	nestedSort: "Beágyazott rendezés",
 	ascending: "Növekvő",
 	descending: "Csökkenő",
-	unsorted: "Az oszlop nincs rendezve"
+	sortingState: "${0} - ${1}",
+	unsorted: "Ne rendezze ezt az oszlopot",
+	indirectSelectionRadio: "${0} sor, egyetlen kijelölés, választógomb",
+	indirectSelectionCheckBox: "${0} sor, több kijelölés, jelölőnégyzet",
+	selectAll: "Összes kijelölése"
 })
 
diff --git a/dojox/grid/enhanced/nls/hu/Filter.js b/dojox/grid/enhanced/nls/hu/Filter.js
new file mode 100644
index 0000000..babd050
--- /dev/null
+++ b/dojox/grid/enhanced/nls/hu/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Szűrő törlése",
+	"filterDefDialogTitle": "Szűrő",
+	"ruleTitleTemplate": "${0} szabály",
+	
+	"conditionEqual": "egyenlő",
+	"conditionNotEqual": "nem egyenlő",
+	"conditionLess": "kisebb mint",
+	"conditionLessEqual": "kisebb vagy egyenlő",
+	"conditionLarger": "nagyobb mint",
+	"conditionLargerEqual": "nagyobb vagy egyenlő",
+	"conditionContains": "tartalmazza",
+	"conditionIs": "pontosan",
+	"conditionStartsWith": "kezdete",
+	"conditionEndWith": "vége",
+	"conditionNotContain": "nem tartalmazza",
+	"conditionIsNot": "nem",
+	"conditionNotStartWith": "nem kezdete",
+	"conditionNotEndWith": "nem vége",
+	"conditionBefore": "előtt",
+	"conditionAfter": "után",
+	"conditionRange": "tartomány",
+	"conditionIsEmpty": "üres",
+	
+	"all": "mind",
+	"any": "bármely",
+	"relationAll": "minden szabály",
+	"waiRelAll": "Megfelel a következő összes szabálynak:",
+	"relationAny": "bármely szabály",
+	"waiRelAny": "Megfelel a következő bármely szabálynak:",
+	"relationMsgFront": "Egyezik",
+	"relationMsgTail": "",
+	"and": "és",
+	"or": "vagy",
+	
+	"addRuleButton": "Szabály hozzáadása",
+	"waiAddRuleButton": "Új szabály hozzáadása",
+	"removeRuleButton": "Szabály eltávolítása",
+	"waiRemoveRuleButtonTemplate": "${0} szabály eltávolítása",
+	
+	"cancelButton": "Mégse",
+	"waiCancelButton": "A párbeszédablak bezárása",
+	"clearButton": "Törlés",
+	"waiClearButton": "A szűrő törlése",
+	"filterButton": "Szűrő",
+	"waiFilterButton": "A szűrő elküldése",
+	
+	"columnSelectLabel": "Oszlop",
+	"waiColumnSelectTemplate": "Oszlop a(z) ${0} szabályhoz",
+	"conditionSelectLabel": "Feltétel",
+	"waiConditionSelectTemplate": "Feltétel a(z) ${0} szabályhoz",
+	"valueBoxLabel": "Érték",
+	"waiValueBoxTemplate": "Írja be a szűrni kívánt értéket a(z) ${0} szabályhoz",
+	
+	"rangeTo": "-",
+	"rangeTemplate": "${0} - ${1}",
+	
+	"statusTipHeaderColumn": "Oszlop",
+	"statusTipHeaderCondition": "Szabályok",
+	"statusTipTitle": "Szűrősáv",
+	"statusTipMsg": "Kattintson a szűrősávra az értékek szűréséhez a következőben: ${0}.",
+	"anycolumn": "bármely oszlop",
+	"statusTipTitleNoFilter": "Szűrősáv",
+	"statusTipTitleHasFilter": "Szűrő",
+	"statusTipRelPre": "Egyezik",
+	"statusTipRelPost": "szabályok.",
+	
+	"defaultItemsName": "elemek",
+	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} megjelenítve.",
+	"filterBarMsgNoFilterTemplate": "Nincs szűrő alkalmazva.",
+	
+	"filterBarDefButton": "Szűrő meghatározása",
+	"waiFilterBarDefButton": "Táblázat szűrése",
+	"a11yFilterBarDefButton": "Szűrés...",
+	"filterBarClearButton": "Szűrő törlése",
+	"waiFilterBarClearButton": "A szűrő törlése",
+	"closeFilterBarBtn": "Szűrősáv bezárása",
+	
+	"clearFilterMsg": "Eltávolítja a szűrőt és megjeleníti az összes elérhető rekordot.",
+	"anyColumnOption": "Bármely oszlop",
+	
+	"trueLabel": "Igaz",
+	"falseLabel": "Hamis"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/hu/Pagination.js b/dojox/grid/enhanced/nls/hu/Pagination.js
new file mode 100644
index 0000000..367f69f
--- /dev/null
+++ b/dojox/grid/enhanced/nls/hu/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} / ${1} ${0}",
+	"firstTip": "Első oldal",
+	"lastTip": "Utolsó oldal",
+	"nextTip": "Következő oldal",
+	"prevTip": "Előző oldal",
+	"itemTitle": "elemek",
+	"pageStepLabelTemplate": "${0}. oldal",
+	"pageSizeLabelTemplate": "${0} elem oldalanként",
+	"allItemsLabelTemplate": "Összes elem",
+	"gotoButtonTitle": "Ugrás adott oldalra",
+	"dialogTitle": "Ugrás adott oldalra",
+	"dialogIndication": "Adja meg az oldalszámot",
+	"pageCountIndication": " (${0} oldal)",
+	"dialogConfirm": "Mehet",
+	"dialogCancel": "Mégse"
+})
+
diff --git a/dojox/grid/enhanced/nls/it/EnhancedGrid.js b/dojox/grid/enhanced/nls/it/EnhancedGrid.js
index be73514..e2b2175 100644
--- a/dojox/grid/enhanced/nls/it/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/it/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Ordinamento singolo",
-	nestedSort: "Ordinamento nidificato",
-	ascending: "Crescente",
+	singleSort: "Ordine singolo",
+	nestedSort: "Ordine nidificato",
+	ascending: "Ascendente",
 	descending: "Decrescente",
-	unsorted: "Non ordinare questa colonna"
+	sortingState: "${0} - ${1}",
+	unsorted: "Non ordinare questa colonna",
+	indirectSelectionRadio: "Riga ${0}, selezione singola, casella di opzione",
+	indirectSelectionCheckBox: "Riga ${0}, selezione multipla, casella di spunta",
+	selectAll: "Seleziona tutto"
 })
 
diff --git a/dojox/grid/enhanced/nls/it/Filter.js b/dojox/grid/enhanced/nls/it/Filter.js
new file mode 100644
index 0000000..87860e4
--- /dev/null
+++ b/dojox/grid/enhanced/nls/it/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Cancella filtro",
+	"filterDefDialogTitle": "Filtro",
+	"ruleTitleTemplate": "Regola ${0}",
+	
+	"conditionEqual": "uguale a",
+	"conditionNotEqual": "non uguale a",
+	"conditionLess": "minore di",
+	"conditionLessEqual": "minore di o uguale a",
+	"conditionLarger": "maggiore di",
+	"conditionLargerEqual": "maggiore di o uguale a",
+	"conditionContains": "contiene",
+	"conditionIs": "è",
+	"conditionStartsWith": "inizia con",
+	"conditionEndWith": "finisce con",
+	"conditionNotContain": "non contiene",
+	"conditionIsNot": "non è",
+	"conditionNotStartWith": "non inizia con",
+	"conditionNotEndWith": "non finisce con",
+	"conditionBefore": "prima",
+	"conditionAfter": "dopo",
+	"conditionRange": "intervallo",
+	"conditionIsEmpty": "è vuoto",
+	
+	"all": "tutte",
+	"any": "qualsiasi",
+	"relationAll": "tutte le regole",
+	"waiRelAll": "Confronta con tutte le seguenti regole:",
+	"relationAny": "qualsiasi regola",
+	"waiRelAny": "Confronta con qualsiasi delle seguenti regole:",
+	"relationMsgFront": "Confronta",
+	"relationMsgTail": "",
+	"and": "e",
+	"or": "o",
+	
+	"addRuleButton": "Aggiungi regola",
+	"waiAddRuleButton": "Aggiungi una nuova regola",
+	"removeRuleButton": "Rimuovi regola",
+	"waiRemoveRuleButtonTemplate": "Rimuovi regola ${0}",
+	
+	"cancelButton": "Annulla",
+	"waiCancelButton": "Annulla questa finestra di dialogo",
+	"clearButton": "Cancella",
+	"waiClearButton": "Cancella il filtro",
+	"filterButton": "Filtro",
+	"waiFilterButton": "Inoltra il filtro",
+	
+	"columnSelectLabel": "Colonna",
+	"waiColumnSelectTemplate": "Colonna per la regola ${0}",
+	"conditionSelectLabel": "Condizione",
+	"waiConditionSelectTemplate": "Condizione per la regola ${0}",
+	"valueBoxLabel": "Valore",
+	"waiValueBoxTemplate": "Immettere il valore da filtrare per la regola ${0}",
+	
+	"rangeTo": "a",
+	"rangeTemplate": "da ${0} a ${1}",
+	
+	"statusTipHeaderColumn": "Colonna",
+	"statusTipHeaderCondition": "Regole",
+	"statusTipTitle": "Barra di filtro",
+	"statusTipMsg": "Fare clic sulla barra di filtro qui per filtrare sui valori in ${0}.",
+	"anycolumn": "qualsiasi colonna",
+	"statusTipTitleNoFilter": "Barra di filtro",
+	"statusTipTitleHasFilter": "Filtro",
+	"statusTipRelPre": "Confronta",
+	"statusTipRelPost": "regole.",
+	
+	"defaultItemsName": "elementi",
+	"filterBarMsgHasFilterTemplate": "${0} di ${1} ${2} visualizzati.",
+	"filterBarMsgNoFilterTemplate": "Nessun filtro applicato",
+	
+	"filterBarDefButton": "Definisci filtro",
+	"waiFilterBarDefButton": "Filtra la tabella",
+	"a11yFilterBarDefButton": "Filtro...",
+	"filterBarClearButton": "Cancella filtro",
+	"waiFilterBarClearButton": "Cancella il filtro",
+	"closeFilterBarBtn": "Chiudi barra di filtro",
+	
+	"clearFilterMsg": "Questo rimuoverà il filtro e visualizzerà tutti i record disponibili.",
+	"anyColumnOption": "Qualsiasi colonna",
+	
+	"trueLabel": "Vero",
+	"falseLabel": "Falso"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/it/Pagination.js b/dojox/grid/enhanced/nls/it/Pagination.js
new file mode 100644
index 0000000..1de040b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/it/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} di ${1} ${0}",
+	"firstTip": "Prima pagina",
+	"lastTip": "Ultima pagina",
+	"nextTip": "Pagina successiva",
+	"prevTip": "Pagina precedente",
+	"itemTitle": "elementi",
+	"pageStepLabelTemplate": "Pagina ${0}",
+	"pageSizeLabelTemplate": "${0} elementi per pagina",
+	"allItemsLabelTemplate": "Tutti gli elementi",
+	"gotoButtonTitle": "Vai a una pagina specifica",
+	"dialogTitle": "Vai alla pagina",
+	"dialogIndication": "Specificare il numero di pagina",
+	"pageCountIndication": " (${0} pagine)",
+	"dialogConfirm": "Vai",
+	"dialogCancel": "Annulla"
+})
+
diff --git a/dojox/grid/enhanced/nls/ja/EnhancedGrid.js b/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
index 2fa1310..7c9f49e 100644
--- a/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ja/EnhancedGrid.js
@@ -1,8 +1,11 @@
 ({
 	singleSort: "単一ソート",
-	nestedSort: "ネストされたソート",
+	nestedSort: "ネスト・ソート",
 	ascending: "昇順",
 	descending: "降順",
-	unsorted: "この列はソートしないでください"
+	sortingState: "${0} - ${1}",
+	unsorted: "この列をソートしない",
+	indirectSelectionRadio: "行 ${0}、単一選択、ラジオ・ボックス",
+	indirectSelectionCheckBox: "行 ${0}、複数選択、チェック・ボックス",
+	selectAll: "すべてを選択"
 })
-
diff --git a/dojox/grid/enhanced/nls/ja/Filter.js b/dojox/grid/enhanced/nls/ja/Filter.js
new file mode 100644
index 0000000..d673843
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ja/Filter.js
@@ -0,0 +1,85 @@
+({
+	"clearFilterDialogTitle": "フィルターのクリア",
+	"filterDefDialogTitle": "フィルター",
+	"ruleTitleTemplate": "ルール ${0}",
+	
+	"conditionEqual": "等しい",
+	"conditionNotEqual": "等しくない",
+	"conditionLess": "より小",
+	"conditionLessEqual": "より小または等しい",
+	"conditionLarger": "より大",
+	"conditionLargerEqual": "より大または等しい",
+	"conditionContains": "含む",
+	"conditionIs": "該当する",
+	"conditionStartsWith": "先頭",
+	"conditionEndWith": "末尾",
+	"conditionNotContain": "含まない",
+	"conditionIsNot": "該当しない",
+	"conditionNotStartWith": "先頭が異なる",
+	"conditionNotEndWith": "末尾が異なる",
+	"conditionBefore": "より前",
+	"conditionAfter": "より後",
+	"conditionRange": "範囲",
+	"conditionIsEmpty": "空である",
+	
+	"all": "すべて",
+	"any": "いずれか",
+	"relationAll": "すべてのルール",
+	"waiRelAll": "次のルールのすべてに一致:",
+	"relationAny": "いずれかのルール",
+	"waiRelAny": "次のルールのいずれかに一致:",
+	"relationMsgFront": "一致",
+	"relationMsgTail": "",
+	"and": "かつ",
+	"or": "または",
+	
+	"addRuleButton": "ルールの追加",
+	"waiAddRuleButton": "新規ルールの追加",
+	"removeRuleButton": "ルールの削除",
+	"waiRemoveRuleButtonTemplate": "ルール ${0} の削除",
+	
+	"cancelButton": "キャンセル",
+	"waiCancelButton": "このダイアログをキャンセル",
+	"clearButton": "クリア",
+	"waiClearButton": "フィルターのクリア",
+	"filterButton": "フィルター",
+	"waiFilterButton": "フィルターの実行依頼",
+	
+	"columnSelectLabel": "列",
+	"waiColumnSelectTemplate": "ルール ${0} の列",
+	"conditionSelectLabel": "条件",
+	"waiConditionSelectTemplate": "ルール ${0} の条件",
+	"valueBoxLabel": "値",
+	"waiValueBoxTemplate": "ルール ${0} を検出するフィルター操作のための値を入力",
+	
+	"rangeTo": "範囲",
+	"rangeTemplate": "${0} から ${1} まで",
+	
+	"statusTipHeaderColumn": "列",
+	"statusTipHeaderCondition": "ルール",
+	"statusTipTitle": "フィルター・バー",
+	"statusTipMsg": "このフィルター・バーをクリックして、${0} の値にフィルターを適用します。",
+	"anycolumn": "いずれかの列",
+	"statusTipTitleNoFilter": "フィルター・バー",
+	"statusTipTitleHasFilter": "フィルター",
+	"statusTipRelPre": "一致",
+	"statusTipRelPost": "ルール",
+	
+	"defaultItemsName": "項目",
+	"filterBarMsgHasFilterTemplate": "${0}/${1} ${2} が表示されました。",
+	"filterBarMsgNoFilterTemplate": "フィルターが適用されていません",
+	
+	"filterBarDefButton": "フィルターの定義",
+	"waiFilterBarDefButton": "表のフィルタリング",
+	"a11yFilterBarDefButton": "フィルター...",
+	"filterBarClearButton": "フィルターのクリア",
+	"waiFilterBarClearButton": "フィルターのクリア",
+	"closeFilterBarBtn": "フィルター・バーを閉じる",
+	
+	"clearFilterMsg": "これによりフィルターが解除され、使用可能なレコードがすべて表示されます。",
+	"anyColumnOption": "いずれかの列",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
diff --git a/dojox/grid/enhanced/nls/ja/Pagination.js b/dojox/grid/enhanced/nls/ja/Pagination.js
new file mode 100644
index 0000000..a2c1487
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ja/Pagination.js
@@ -0,0 +1,17 @@
+({
+	"descTemplate": "${2} - ${3}/${1} ${0}",
+	"firstTip": "最初のページ",
+	"lastTip": "最後のページ",
+	"nextTip": "次のページ",
+	"prevTip": "前のページ",
+	"itemTitle": "項目",
+	"pageStepLabelTemplate": "ページ ${0}",
+	"pageSizeLabelTemplate": "ページ当たり ${0} 項目",
+	"allItemsLabelTemplate": "すべての項目",
+	"gotoButtonTitle": "特定のページに移動",
+	"dialogTitle": "ページの移動",
+	"dialogIndication": "ページ番号を指定してください",
+	"pageCountIndication": " (${0} ページ)",
+	"dialogConfirm": "移動",
+	"dialogCancel": "キャンセル"
+})
diff --git a/dojox/grid/enhanced/nls/kk/EnhancedGrid.js b/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
new file mode 100644
index 0000000..01ee777
--- /dev/null
+++ b/dojox/grid/enhanced/nls/kk/EnhancedGrid.js
@@ -0,0 +1,8 @@
+({
+	singleSort: "Бір рет сұрыптау",
+	nestedSort: "Кірістірілген сұрыптау",
+	ascending: "Өсу реті бойынша",
+	descending: "Кему",
+	unsorted: "Бұл бағанды сұрыптамау"
+})
+
diff --git a/dojox/grid/enhanced/nls/kk/Filter.js b/dojox/grid/enhanced/nls/kk/Filter.js
new file mode 100644
index 0000000..1215640
--- /dev/null
+++ b/dojox/grid/enhanced/nls/kk/Filter.js
@@ -0,0 +1,88 @@
+({
+	"clearFilterDialogTitle": "Сүзгіні тазалау",
+	"filterDefDialogTitle": "Сүзгі",
+	"incompleteRuleTip": "Бұл ереже толық емес.",
+	"ruleTitleTemplate": "${0} ережесі",
+	
+	"conditionEqual": "тең",
+	"conditionNotEqual": "тең емес",
+	"conditionLess": "аздау",
+	"conditionLessEqual": "аздау немесе тең",
+	"conditionLarger": "үлкендеу",
+	"conditionLargerEqual": "үлкендеу немесе тең",
+	"conditionContains": "құрамында бар",
+	"conditionIs": "–",
+	"conditionStartsWith": "басталады",
+	"conditionEndWith": "аяқталады",
+	"conditionNotContain": "құрамында жоқ",
+	"conditionIsNot": "емес",
+	"conditionNotStartWith": "басталмайды",
+	"conditionNotEndWith": "аяқталмайды",
+	"conditionBefore": "алдында",
+	"conditionAfter": "артында",
+	"conditionRange": "ауқым",
+	
+	"all": "барлығы",
+	"any": "кез келген",
+	"relationAll": "барлық ережелер",
+	"waiRelAll": "Барлық мына ережелерге сәйкес:",
+	"relationAny": "кез келген ереже",
+	"waiRelAny": "Мына ережелерге сәйкес:",
+	"relationMsgFront": "Сәйкес келу",
+	"relationMsgTail": "",
+	"and": "және",
+	"or": "немесе",
+	
+	"addRuleButton": "Ереже қосу",
+	"waiAddRuleButton": "Жаңа ереже қосу",
+	"removeRuleButton": "Ережені алып тастау",
+	"waiRemoveRuleButtonTemplate": "${0} ережесін алып тастау",
+	
+	"cancelButton": "Болдырмау",
+	"waiCancelButton": "Осы тілқатысу терезесін болдырмау",
+	"clearButton": "Тазалау ",
+	"waiClearButton": "Сүзгіні тазалау",
+	"filterButton": "Сүзгі",
+	"waiFilterButton": "Сүзгіні жіберу",
+	
+	"columnSelectLabel": "Баған",
+	"waiColumnSelectTemplate": "${0} ережесінің бағаны",
+	"conditionSelectLabel": "Шарт",
+	"waiConditionSelectTemplate": "${0} ережесінің шарты",
+	"valueBoxLabel": "Мән",
+	"waiValueBoxTemplate": "${0} ережесін сүзу үшін мәнді енгізу",
+	
+	"rangeTo": "неге",
+	"rangeTemplate": "${0} мәнінен ${1} мәніне",
+	
+	"statusTipHeaderColumn": "Баған",
+	"statusTipHeaderCondition": "Ережелер",
+	"statusTipTitle": "Сүзгі тақтасы",
+	"statusTipMsg": "${0} ішіндегі мәндер бойынша сүзу үшін сүзгі тақтасын нұқыңыз.",
+	"anycolumn": "кез келген баған",
+	"statusTipTitleNoFilter": "Сүзгі тақтасы",
+	"statusTipTitleHasFilter": "Сүзгі",
+	"statusTipRelPre": "Сәйкес келу",
+	"statusTipRelPost": "ережелер.",
+	
+	"defaultItemsName": "элементтер",
+	"filterBarMsgHasFilterTemplate": "${1} ${2} ішінен ${0} көрсетілді.",
+	"filterBarMsgNoFilterTemplate": "Сүзгі қолданылмады",
+	
+	"filterBarDefButton": "Сүзгіні анықтау",
+	"waiFilterBarDefButton": "Кестені сүзу",
+	"a11yFilterBarDefButton": "Сүзгі...",
+	"filterBarClearButton": "Сүзгіні тазалау",
+	"waiFilterBarClearButton": "Сүзгіні тазалау",
+	"closeFilterBarBtn": "Сүзгі тақтасын жабу",
+	
+	"clearFilterMsg": "Бұл сүзгіні жояды және барлық қол жетімді жазбаларды көрсетеді.",
+	"anyColumnOption": "Кез келген баған",
+	
+	"trueLabelEditable": "Белгіленген",
+	"trueLabel": "Шын",
+	"falseLabel": "Жалған"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/kk/Pagination.js b/dojox/grid/enhanced/nls/kk/Pagination.js
new file mode 100644
index 0000000..736f4da
--- /dev/null
+++ b/dojox/grid/enhanced/nls/kk/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${1} ${0} элементтің ${2} - ${3} элементі",
+	"firstTip": "Бірінші бет",
+	"lastTip": "Соңғы бет",
+	"nextTip": "Келесі бет",
+	"prevTip": "Алдыңғы бет",
+	"itemTitle": "элементтер",
+	"pageStepLabelTemplate": "Бет ${0}",
+	"pageSizeLabelTemplate": "Бетіне ${0} элемент",
+	"allItemsLabelTemplate": "Барлық элементтер",
+	"gotoButtonTitle": "Белгілі бір бетке өту",
+	"dialogTitle": "Бетке өту",
+	"dialogIndication": "Бет нөмірін көрсету",
+	"pageCountIndication": " (${0} бет)",
+	"dialogConfirm": "Өту",
+	"dialogCancel": "Болдырмау"
+})
+
diff --git a/dojox/grid/enhanced/nls/ko/EnhancedGrid.js b/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
index 8096438..83cf705 100644
--- a/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ko/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
 	singleSort: "단일 정렬",
-	nestedSort: "중첩 정렬",
+	nestedSort: "중첩된 정렬",
 	ascending: "오름차순",
 	descending: "내림차순",
-	unsorted: "이 열을 정렬하지 않음"
+	sortingState: "${0} - ${1}",
+	unsorted: "이 컬럼은 정렬하지 마십시오",
+	indirectSelectionRadio: "행 ${0}, 단일 선택, 라디오 상자",
+	indirectSelectionCheckBox: "행 ${0}, 다중 선택, 선택란",
+	selectAll: "모두 선택"
 })
 
diff --git a/dojox/grid/enhanced/nls/ko/Filter.js b/dojox/grid/enhanced/nls/ko/Filter.js
new file mode 100644
index 0000000..31cc104
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ko/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "필터 지우기",
+	"filterDefDialogTitle": "필터",
+	"ruleTitleTemplate": "규칙 ${0}",
+	
+	"conditionEqual": "같음",
+	"conditionNotEqual": "같지 않음",
+	"conditionLess": "미만",
+	"conditionLessEqual": "이하",
+	"conditionLarger": "초과",
+	"conditionLargerEqual": "이상",
+	"conditionContains": "포함",
+	"conditionIs": "다음과 같음",
+	"conditionStartsWith": "다음으로 시작",
+	"conditionEndWith": "다음으로 종료",
+	"conditionNotContain": "포함하지 않음",
+	"conditionIsNot": "다음이 아님",
+	"conditionNotStartWith": "다음으로 시작하지 않음",
+	"conditionNotEndWith": "다음으로 종료하지 않음",
+	"conditionBefore": "이전",
+	"conditionAfter": "이후",
+	"conditionRange": "범위",
+	"conditionIsEmpty": "다음이 비어있음",
+	
+	"all": "모두",
+	"any": "임의",
+	"relationAll": "모든 규칙",
+	"waiRelAll": "다음 규칙에 모두 일치:",
+	"relationAny": "임의 규칙",
+	"waiRelAny": "다음 규칙 중에 일치:",
+	"relationMsgFront": "일치",
+	"relationMsgTail": "",
+	"and": "및",
+	"or": "또는",
+	
+	"addRuleButton": "규칙 추가",
+	"waiAddRuleButton": "새 규칙 추가",
+	"removeRuleButton": "규칙 제거",
+	"waiRemoveRuleButtonTemplate": "${0} 규칙 제거",
+	
+	"cancelButton": "취소",
+	"waiCancelButton": "이 대화 상자 취소",
+	"clearButton": "지우기",
+	"waiClearButton": "해당 필터 지우기",
+	"filterButton": "필터",
+	"waiFilterButton": "필터 제출",
+	
+	"columnSelectLabel": "컬럼",
+	"waiColumnSelectTemplate": "${0} 규칙에 대한 컬럼",
+	"conditionSelectLabel": "조건",
+	"waiConditionSelectTemplate": "${0} 규칙에 대한 조건",
+	"valueBoxLabel": "값",
+	"waiValueBoxTemplate": "${0} 규칙에 대해 필터링할 값 입력",
+	
+	"rangeTo": "다음에서 종료",
+	"rangeTemplate": "${0}에서 ${1}까지",
+	
+	"statusTipHeaderColumn": "컬럼",
+	"statusTipHeaderCondition": "규칙",
+	"statusTipTitle": "필터 표시줄",
+	"statusTipMsg": "${0}의 값을 필터링하려면 이 필터 표시줄을 클릭하십시오.",
+	"anycolumn": "임의의 컬럼",
+	"statusTipTitleNoFilter": "필터 표시줄",
+	"statusTipTitleHasFilter": "필터",
+	"statusTipRelPre": "일치",
+	"statusTipRelPost": "규칙",
+	
+	"defaultItemsName": "항목",
+	"filterBarMsgHasFilterTemplate": "${0}/${1} ${2} 표시됨",
+	"filterBarMsgNoFilterTemplate": "적용된 필터 없음",
+	
+	"filterBarDefButton": "필터 정의",
+	"waiFilterBarDefButton": "표 필터링",
+	"a11yFilterBarDefButton": "필터...",
+	"filterBarClearButton": "필터 지우기",
+	"waiFilterBarClearButton": "해당 필터 지우기",
+	"closeFilterBarBtn": "필터 표시줄 닫기",
+	
+	"clearFilterMsg": "이로 인해 해당 필터가 제거되며 사용 가능한 모든 레코드가 표시됩니다.",
+	"anyColumnOption": "임의의 컬럼",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/ko/Pagination.js b/dojox/grid/enhanced/nls/ko/Pagination.js
new file mode 100644
index 0000000..d1b5187
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ko/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3}/${1} ${0}",
+	"firstTip": "첫 페이지",
+	"lastTip": "마지막 페이지",
+	"nextTip": "다음 페이지",
+	"prevTip": "이전 페이지",
+	"itemTitle": "항목",
+	"pageStepLabelTemplate": "${0} 페이지",
+	"pageSizeLabelTemplate": "페이지당 ${0} 항목",
+	"allItemsLabelTemplate": "모든 항목",
+	"gotoButtonTitle": "특정 페이지로 이동",
+	"dialogTitle": "페이지 이동",
+	"dialogIndication": "페이지 번호 지정",
+	"pageCountIndication": " (${0}페이지)",
+	"dialogConfirm": "이동",
+	"dialogCancel": "취소"
+})
+
diff --git a/dojox/grid/enhanced/nls/nb/EnhancedGrid.js b/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
index 3c84862..18b5989 100644
--- a/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/nb/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Enkel sortering",
+	singleSort: "Enkeltsortering",
 	nestedSort: "Nestet sortering",
 	ascending: "Stigende",
 	descending: "Synkende",
-	unsorted: "Ikke sorter denne kolonnen"
+	sortingState: "${0} - ${1}",
+	unsorted: "Ikke sorter denne kolonnen",
+	indirectSelectionRadio: "Rad ${0}, enkeltvalg, valgknapp",
+	indirectSelectionCheckBox: "Rad ${0}, flervalg, avmerkingsboks",
+	selectAll: "Velg alle"
 })
 
diff --git a/dojox/grid/enhanced/nls/nb/Filter.js b/dojox/grid/enhanced/nls/nb/Filter.js
new file mode 100644
index 0000000..03f4cbc
--- /dev/null
+++ b/dojox/grid/enhanced/nls/nb/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Tøm filter",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Regel ${0}",
+	
+	"conditionEqual": "er lik",
+	"conditionNotEqual": "er ikke lik",
+	"conditionLess": "er mindre enn",
+	"conditionLessEqual": "mindre enn eller lik",
+	"conditionLarger": "er større enn",
+	"conditionLargerEqual": "større enn eller lik",
+	"conditionContains": "inneholder",
+	"conditionIs": "er",
+	"conditionStartsWith": "starter med",
+	"conditionEndWith": "slutter med",
+	"conditionNotContain": "inneholder ikke",
+	"conditionIsNot": "er ikke",
+	"conditionNotStartWith": "starter ikke med",
+	"conditionNotEndWith": "slutter ikke med",
+	"conditionBefore": "før",
+	"conditionAfter": "etter",
+	"conditionRange": "område",
+	"conditionIsEmpty": "er tom",
+	
+	"all": "alle",
+	"any": "minst en",
+	"relationAll": "alle regler",
+	"waiRelAll": "Samsvar med alle disse reglene:",
+	"relationAny": "minst en regel",
+	"waiRelAny": "Samsvar med minst en av disse reglene:",
+	"relationMsgFront": "Samsvar med",
+	"relationMsgTail": "",
+	"and": "og",
+	"or": "eller",
+	
+	"addRuleButton": "Legg til regel",
+	"waiAddRuleButton": "Legg til en ny regel",
+	"removeRuleButton": "Fjern regel",
+	"waiRemoveRuleButtonTemplate": "Fjern regel ${0}",
+	
+	"cancelButton": "Avbryt",
+	"waiCancelButton": "Avbryt denne dialogboksen",
+	"clearButton": "Tøm",
+	"waiClearButton": "Tøm filteret",
+	"filterButton": "Filtrer",
+	"waiFilterButton": "Send filteret",
+	
+	"columnSelectLabel": "Kolonne",
+	"waiColumnSelectTemplate": "Kolonne for regel ${0}",
+	"conditionSelectLabel": "Betingelse",
+	"waiConditionSelectTemplate": "Betingelse for regel ${0}",
+	"valueBoxLabel": "Verdi",
+	"waiValueBoxTemplate": "Oppgi verdi som skal filtreres for regel ${0}",
+	
+	"rangeTo": "til",
+	"rangeTemplate": "fra ${0} til ${1}",
+	
+	"statusTipHeaderColumn": "Kolonne",
+	"statusTipHeaderCondition": "Regler",
+	"statusTipTitle": "Filterlinje",
+	"statusTipMsg": "Klikk på filterlinjen her for å filtrere på verdiene i ${0}.",
+	"anycolumn": "enhver kolonne",
+	"statusTipTitleNoFilter": "Filterlinje",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Samsvar med",
+	"statusTipRelPost": "regler.",
+	
+	"defaultItemsName": "elementer",
+	"filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} vist.",
+	"filterBarMsgNoFilterTemplate": "Ikke brukt filter",
+	
+	"filterBarDefButton": "Definer filter",
+	"waiFilterBarDefButton": "Filtrer tabellen",
+	"a11yFilterBarDefButton": "Filtrer...",
+	"filterBarClearButton": "Tøm filter",
+	"waiFilterBarClearButton": "Tøm filteret",
+	"closeFilterBarBtn": "Lukk filterlinjen",
+	
+	"clearFilterMsg": "Dette fjerner filteret og viser alle tilgjengelige poster.",
+	"anyColumnOption": "Minst en kolonne",
+	
+	"trueLabel": "Sann",
+	"falseLabel": "Usann"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/nb/Pagination.js b/dojox/grid/enhanced/nls/nb/Pagination.js
new file mode 100644
index 0000000..2e8a3f9
--- /dev/null
+++ b/dojox/grid/enhanced/nls/nb/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} av ${1} ${0}",
+	"firstTip": "Første side",
+	"lastTip": "Siste side",
+	"nextTip": "Neste side",
+	"prevTip": "Forrige side",
+	"itemTitle": "elementer",
+	"pageStepLabelTemplate": "Side ${0}",
+	"pageSizeLabelTemplate": "${0} elementer per side",
+	"allItemsLabelTemplate": "Alle elementer",
+	"gotoButtonTitle": "Gå til en bestemt side",
+	"dialogTitle": "Gå til side",
+	"dialogIndication": "Oppgi sidetallet",
+	"pageCountIndication": " (${0} sider)",
+	"dialogConfirm": "Utfør",
+	"dialogCancel": "Avbryt"
+})
+
diff --git a/dojox/grid/enhanced/nls/nl/EnhancedGrid.js b/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
index 848d4af..36f32b4 100644
--- a/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/nl/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Enkele sorteerbewerking",
-	nestedSort: "Geneste sorteerbewerking",
+	singleSort: "Enkelvoudig sorteren",
+	nestedSort: "Genest sorteren",
 	ascending: "Oplopend",
 	descending: "Aflopend",
-	unsorted: "Deze kolom niet sorteren"
+	sortingState: "${0} - ${1}",
+	unsorted: "Deze kolom niet sorteren",
+	indirectSelectionRadio: "Rij ${0}, enkele selectie, keuzerondje",
+	indirectSelectionCheckBox: "Rij ${0}, meerdere selecties, selectievakje",
+	selectAll: "Alles selecteren"
 })
 
diff --git a/dojox/grid/enhanced/nls/nl/Filter.js b/dojox/grid/enhanced/nls/nl/Filter.js
new file mode 100644
index 0000000..b1c1ce0
--- /dev/null
+++ b/dojox/grid/enhanced/nls/nl/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Filter wissen",
+	"filterDefDialogTitle": "Filteren",
+	"ruleTitleTemplate": "Regel ${0}",
+	
+	"conditionEqual": "gelijk aan",
+	"conditionNotEqual": "niet gelijk aan",
+	"conditionLess": "is kleiner dan",
+	"conditionLessEqual": "kleiner dan of gelijk aan",
+	"conditionLarger": "is groter dan",
+	"conditionLargerEqual": "groter dan of gelijk aan",
+	"conditionContains": "bevat",
+	"conditionIs": "is",
+	"conditionStartsWith": "begint met",
+	"conditionEndWith": "eindigt op",
+	"conditionNotContain": "bevat niet",
+	"conditionIsNot": "is niet",
+	"conditionNotStartWith": "begint niet met",
+	"conditionNotEndWith": "eindigt niet op",
+	"conditionBefore": "voor",
+	"conditionAfter": "na",
+	"conditionRange": "bereik",
+	"conditionIsEmpty": "is leeg",
+	
+	"all": "alle",
+	"any": "een of meer",
+	"relationAll": "alle regels",
+	"waiRelAll": "Voldoen aan al deze regels:",
+	"relationAny": "een of meer regels",
+	"waiRelAny": "Voldoen aan een van deze regels:",
+	"relationMsgFront": "Voldoen aan",
+	"relationMsgTail": "",
+	"and": "en",
+	"or": "of",
+	
+	"addRuleButton": "Regel toevoegen",
+	"waiAddRuleButton": "Een nieuwe regel toevoegen",
+	"removeRuleButton": "Regel verwijderen",
+	"waiRemoveRuleButtonTemplate": "Regel ${0} verwijderen",
+	
+	"cancelButton": "Annuleren",
+	"waiCancelButton": "Dit dialoogvenster annuleren",
+	"clearButton": "Leegmaken",
+	"waiClearButton": "Het filter wissen",
+	"filterButton": "Filteren",
+	"waiFilterButton": "Het filter verzenden",
+	
+	"columnSelectLabel": "Kolom",
+	"waiColumnSelectTemplate": "Kolom voor regel ${0}",
+	"conditionSelectLabel": "Voorwaarde",
+	"waiConditionSelectTemplate": "Voorwaarde voor regel ${0}",
+	"valueBoxLabel": "Waarde",
+	"waiValueBoxTemplate": "Geef een filterwaarde op voor regel ${0}",
+	
+	"rangeTo": "tot",
+	"rangeTemplate": "van ${0} tot ${1}",
+	
+	"statusTipHeaderColumn": "Kolom",
+	"statusTipHeaderCondition": "Regels",
+	"statusTipTitle": "Filterbalk",
+	"statusTipMsg": "Klik hier op de filterbalk om te filteren op waarden in ${0}.",
+	"anycolumn": "een kolom",
+	"statusTipTitleNoFilter": "Filterbalk",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Voldoen aan",
+	"statusTipRelPost": "regel.",
+	
+	"defaultItemsName": "items",
+	"filterBarMsgHasFilterTemplate": "${0} van ${1} ${2} afgebeeld.",
+	"filterBarMsgNoFilterTemplate": "Geen filter toegepast",
+	
+	"filterBarDefButton": "Filter definiëren",
+	"waiFilterBarDefButton": "De tabel filteren",
+	"a11yFilterBarDefButton": "Filteren...",
+	"filterBarClearButton": "Filter wissen",
+	"waiFilterBarClearButton": "Het filter wissen",
+	"closeFilterBarBtn": "Filterbalk sluiten",
+	
+	"clearFilterMsg": "Hiermee verwijdert u het filter en worden alle beschikbare records afgebeeld.",
+	"anyColumnOption": "Een kolom",
+	
+	"trueLabel": "Waar",
+	"falseLabel": "Onwaar"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/nl/Pagination.js b/dojox/grid/enhanced/nls/nl/Pagination.js
new file mode 100644
index 0000000..b972dda
--- /dev/null
+++ b/dojox/grid/enhanced/nls/nl/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} van ${1} ${0}",
+	"firstTip": "Eerste pagina",
+	"lastTip": "Laatste pagina",
+	"nextTip": "Volgende pagina",
+	"prevTip": "Vorige pagina",
+	"itemTitle": "items",
+	"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:",
+	"pageCountIndication": " (${0} pagina's)",
+	"dialogConfirm": "Start",
+	"dialogCancel": "Annuleren"
+})
+
diff --git a/dojox/grid/enhanced/nls/pl/EnhancedGrid.js b/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
index 85cf13f..c5baab4 100644
--- a/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/pl/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Sortowanie pojedyncze",
-	nestedSort: "Sortowanie zagnieżdżone",
+	singleSort: "Pojedyncze sortowanie",
+	nestedSort: "Zagnieżdżone sortowanie",
 	ascending: "Rosnąco",
 	descending: "Malejąco",
-	unsorted: "Nie sortuj tej kolumny"
+	sortingState: "${0} - ${1}",
+	unsorted: "Nie sortuj tej kolumny",
+	indirectSelectionRadio: "Wiersz ${0}, pojedynczy wybór, zestaw przełączników",
+	indirectSelectionCheckBox: "Wiersz ${0}, wybór wielokrotny, pole wyboru",
+	selectAll: "Wybierz wszystko"
 })
 
diff --git a/dojox/grid/enhanced/nls/pl/Filter.js b/dojox/grid/enhanced/nls/pl/Filter.js
new file mode 100644
index 0000000..d533d1a
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pl/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Wyczyść filtr",
+	"filterDefDialogTitle": "Filtr",
+	"ruleTitleTemplate": "Reguła ${0}",
+	
+	"conditionEqual": "równe",
+	"conditionNotEqual": "różne od",
+	"conditionLess": "mniejsze od",
+	"conditionLessEqual": "mniejsze lub równe",
+	"conditionLarger": "większe od",
+	"conditionLargerEqual": "większe lub równe",
+	"conditionContains": "zawiera",
+	"conditionIs": "jest",
+	"conditionStartsWith": "zaczyna się od",
+	"conditionEndWith": "kończy się na",
+	"conditionNotContain": "nie zawiera",
+	"conditionIsNot": "nie jest",
+	"conditionNotStartWith": "nie zaczyna się od",
+	"conditionNotEndWith": "nie kończy się na",
+	"conditionBefore": "przed",
+	"conditionAfter": "po",
+	"conditionRange": "zakres",
+	"conditionIsEmpty": "jest pusty",
+	
+	"all": "wszystkie",
+	"any": "dowolne",
+	"relationAll": "wszystkie reguły",
+	"waiRelAll": "Dopasuj wszystkie poniższe reguły:",
+	"relationAny": "dowolna reguła",
+	"waiRelAny": "Dopasuj dowolną z poniższych reguł:",
+	"relationMsgFront": "Dopasuj",
+	"relationMsgTail": "",
+	"and": "i",
+	"or": "lub",
+	
+	"addRuleButton": "Dodaj regułę",
+	"waiAddRuleButton": "Dodaj nową regułę",
+	"removeRuleButton": "Usuń regułę",
+	"waiRemoveRuleButtonTemplate": "Usuń regułę ${0}",
+	
+	"cancelButton": "Anuluj",
+	"waiCancelButton": "Anuluj to okno dialogowe",
+	"clearButton": "Wyczyść",
+	"waiClearButton": "Wyczyść filtr",
+	"filterButton": "Filtruj",
+	"waiFilterButton": "Wprowadź ten filtr",
+	
+	"columnSelectLabel": "Kolumna",
+	"waiColumnSelectTemplate": "Kolumna dla reguły ${0}",
+	"conditionSelectLabel": "Warunek",
+	"waiConditionSelectTemplate": "Warunek dla reguły ${0}",
+	"valueBoxLabel": "Wartość",
+	"waiValueBoxTemplate": "Wprowadź wartość, aby filtrować dla reguły ${0}",
+	
+	"rangeTo": "do",
+	"rangeTemplate": "od ${0} do ${1}",
+	
+	"statusTipHeaderColumn": "Kolumna",
+	"statusTipHeaderCondition": "Reguły",
+	"statusTipTitle": "Pasek filtru",
+	"statusTipMsg": "Kliknij pasek filtru tutaj, aby filtrować według wartości w ${0}.",
+	"anycolumn": "dowolna kolumna",
+	"statusTipTitleNoFilter": "Pasek filtru",
+	"statusTipTitleHasFilter": "Filtr",
+	"statusTipRelPre": "Dopasuj",
+	"statusTipRelPost": "reguły.",
+	
+	"defaultItemsName": "elementy",
+	"filterBarMsgHasFilterTemplate": "Wyświetlane ${0} z ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Filtr wyłączony",
+	
+	"filterBarDefButton": "Zdefiniuj filtr",
+	"waiFilterBarDefButton": "Filtruj tabelę",
+	"a11yFilterBarDefButton": "Filtruj...",
+	"filterBarClearButton": "Wyczyść filtr",
+	"waiFilterBarClearButton": "Wyczyść filtr",
+	"closeFilterBarBtn": "Zamknij pasek filtru",
+	
+	"clearFilterMsg": "Filtr zostanie usunięty i wyświetlone będą wszystkie dostępne rekordy.",
+	"anyColumnOption": "Dowolna kolumna",
+	
+	"trueLabel": "Prawda",
+	"falseLabel": "Fałsz"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/pl/Pagination.js b/dojox/grid/enhanced/nls/pl/Pagination.js
new file mode 100644
index 0000000..50e4f98
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pl/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} z ${1} ${0}",
+	"firstTip": "Pierwsza strona",
+	"lastTip": "Ostatnia strona",
+	"nextTip": "Następna strona",
+	"prevTip": "Poprzednia strona",
+	"itemTitle": "elementy",
+	"pageStepLabelTemplate": "Strona ${0}",
+	"pageSizeLabelTemplate": "${0} elementów na stronę",
+	"allItemsLabelTemplate": "Wszystkie elementy",
+	"gotoButtonTitle": "Idź do określonej strony",
+	"dialogTitle": "Idź do strony",
+	"dialogIndication": "Podaj numer strony",
+	"pageCountIndication": " (${0} stron)",
+	"dialogConfirm": "Idź",
+	"dialogCancel": "Anuluj"
+})
+
diff --git a/dojox/grid/enhanced/nls/pt-pt/Filter.js b/dojox/grid/enhanced/nls/pt-pt/Filter.js
new file mode 100644
index 0000000..e5d139b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt-pt/Filter.js
@@ -0,0 +1,88 @@
+({
+	"clearFilterDialogTitle": "Limpar filtro",
+	"filterDefDialogTitle": "Filtro",
+	"incompleteRuleTip": "Esta regra não está completa.",
+	"ruleTitleTemplate": "Regra ${0}",
+	
+	"conditionEqual": "igual",
+	"conditionNotEqual": "não é igual",
+	"conditionLess": "é menor do que",
+	"conditionLessEqual": "menor ou igual",
+	"conditionLarger": "é maior do que",
+	"conditionLargerEqual": "maior 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",
+	
+	"all": "tudo",
+	"any": "qualquer",
+	"relationAll": "todas as regras",
+	"waiRelAll": "Corresponder a todas as seguintes regras:",
+	"relationAny": "quaisquer regras",
+	"waiRelAny": "Corresponder a qualquer uma das seguintes regras:",
+	"relationMsgFront": "Corresponder",
+	"relationMsgTail": "",
+	"and": "and",
+	"or": "or",
+	
+	"addRuleButton": "Adicionar regra",
+	"waiAddRuleButton": "Adicionar uma nova regra",
+	"removeRuleButton": "Remover regra",
+	"waiRemoveRuleButtonTemplate": "Remover regra ${0}",
+	
+	"cancelButton": "Cancelar",
+	"waiCancelButton": "Cancelar esta caixa de diálogo",
+	"clearButton": "Limpar",
+	"waiClearButton": "Limpar o filtro",
+	"filterButton": "Filtro",
+	"waiFilterButton": "Submeter o filtro",
+	
+	"columnSelectLabel": "Coluna",
+	"waiColumnSelectTemplate": "Coluna para a regra ${0}",
+	"conditionSelectLabel": "Condição",
+	"waiConditionSelectTemplate": "Condição para a regra ${0}",
+	"valueBoxLabel": "Valor",
+	"waiValueBoxTemplate": "Introduzir valor para filtrar para a regra ${0}",
+	
+	"rangeTo": "a",
+	"rangeTemplate": "de ${0} a ${1}",
+	
+	"statusTipHeaderColumn": "Coluna",
+	"statusTipHeaderCondition": "Regras",
+	"statusTipTitle": "Barra do filtro",
+	"statusTipMsg": "Faça clique na barra de filtro para filtrar os valores em ${0}.",
+	"anycolumn": "qualquer coluna",
+	"statusTipTitleNoFilter": "Barra do filtro",
+	"statusTipTitleHasFilter": "Filtro",
+	"statusTipRelPre": "Correspondência",
+	"statusTipRelPost": "regras.",
+	
+	"defaultItemsName": "itens",
+	"filterBarMsgHasFilterTemplate": "${0} de ${1} ${2} apresentado(s).",
+	"filterBarMsgNoFilterTemplate": "Nenhum filtro aplicado",
+	
+	"filterBarDefButton": "Definir filtro",
+	"waiFilterBarDefButton": "Filtrar a tabela",
+	"a11yFilterBarDefButton": "Filtrar...",
+	"filterBarClearButton": "Limpar filtro",
+	"waiFilterBarClearButton": "Limpar o filtro",
+	"closeFilterBarBtn": "Fechar barra de filtro",
+	
+	"clearFilterMsg": "Este procedimento irá remover o filtro e apresentar todos os registos disponíveis.",
+	"anyColumnOption": "Qualquer coluna",
+	
+	"trueLabelEditable": "Verificado",
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/pt-pt/Pagination.js b/dojox/grid/enhanced/nls/pt-pt/Pagination.js
new file mode 100644
index 0000000..d76cd3d
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt-pt/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} de ${1} ${0}",
+	"firstTip": "Primeira página",
+	"lastTip": "Última página",
+	"nextTip": "Página seguinte",
+	"prevTip": "Página anterior",
+	"itemTitle": "itens",
+	"pageStepLabelTemplate": "Página ${0}",
+	"pageSizeLabelTemplate": "${0} itens por página",
+	"allItemsLabelTemplate": "Todos os itens",
+	"gotoButtonTitle": "Avançar para uma página específica",
+	"dialogTitle": "Avançar para a página",
+	"dialogIndication": "Especificar o número de página",
+	"pageCountIndication": " (${0} páginas)",
+	"dialogConfirm": "Ir",
+	"dialogCancel": "Cancelar"
+})
+
diff --git a/dojox/grid/enhanced/nls/pt/Filter.js b/dojox/grid/enhanced/nls/pt/Filter.js
new file mode 100644
index 0000000..0f47217
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt/Filter.js
@@ -0,0 +1,86 @@
+({
+	"clearFilterDialogTitle": "Limpar Filtro",
+	"filterDefDialogTitle": "Filtrar",
+	"incompleteRuleTip": "Esta regra não está completa.",
+	"ruleTitleTemplate": "Regra ${0}",
+
+	"conditionEqual": "igual",
+	"conditionNotEqual": "não é igual",
+	"conditionLess": "é menor que",
+	"conditionLessEqual": "menor ou igual a",
+	"conditionLarger": "é maior que",
+	"conditionLargerEqual": "maior ou igual a",
+	"conditionContains": "contém",
+	"conditionIs": "é",
+	"conditionStartsWith": "inicia com",
+	"conditionEndWith": "termina com",
+	"conditionNotContain": "não contém",
+	"conditionIsNot": "não é",
+	"conditionNotStartWith": "não inicia com",
+	"conditionNotEndWith": "não termina com",
+	"conditionBefore": "antes",
+	"conditionAfter": "depois",
+	"conditionRange": "intervalo",
+
+	"all": "todos",
+	"any": "qualquer um",
+	"relationAll": "todas as regras",
+	"waiRelAll": "Corresponder a todas as seguintes regras:",
+	"relationAny": "qualquer regra",
+	"waiRelAny": "Corresponder a qualquer uma das seguintes regras:",
+	"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": "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",
+	"statusTipMsg": "Clique na barra de filtragem aqui para filtrar os valores de ${0}.",
+	"anycolumn": "qualquer coluna",
+	"statusTipTitleNoFilter": "Barra de Filtragem",
+	"statusTipTitleHasFilter": "Filtrar",
+	"statusTipRelPre": "Corresponder",
+	"statusTipRelPost": "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"
+})
+
diff --git a/dojox/grid/enhanced/nls/pt/Pagination.js b/dojox/grid/enhanced/nls/pt/Pagination.js
new file mode 100644
index 0000000..4d68a04
--- /dev/null
+++ b/dojox/grid/enhanced/nls/pt/Pagination.js
@@ -0,0 +1,17 @@
+({
+	"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",
+	"pageStepLabelTemplate": "Página ${0}",
+	"pageSizeLabelTemplate": "${0} itens por página",
+	"allItemsLabelTemplate": "Todos os itens",
+	"gotoButtonTitle": "Acesse uma página específica",
+	"dialogTitle": "Acesse a Página",
+	"dialogIndication": "Especifique o número da página",
+	"pageCountIndication": " (${0} páginas)",
+	"dialogConfirm": "Ir",
+	"dialogCancel": "Cancelar"
+})
diff --git a/dojox/grid/enhanced/nls/ro/EnhancedGrid.js b/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
index 398a766..9ce83fb 100644
--- a/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ro/EnhancedGrid.js
@@ -1,9 +1,8 @@
 ({
-	singleSort: "Sortare singulară ",
+	singleSort: "Sortare singură",
 	nestedSort: "Sortare imbricată",
 	ascending: "Crescător",
 	descending: "Descrescător",
-	sortingState: "${0} - ${1}",
-	unsorted: "Nu sortaţi această coloană "
+	unsorted: "Nu sortaţi această coloană"
 })
 
diff --git a/dojox/grid/enhanced/nls/ro/Filter.js b/dojox/grid/enhanced/nls/ro/Filter.js
new file mode 100644
index 0000000..7be1915
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ro/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Ştergere filtru",
+	"filterDefDialogTitle": "Filtru",
+	"ruleTitleTemplate": "Regulă ${0}",
+	
+	"conditionEqual": "egal",
+	"conditionNotEqual": "nu este egal",
+	"conditionLess": "este mai mic decât",
+	"conditionLessEqual": "mai mic sau egal",
+	"conditionLarger": "este mai mare decât",
+	"conditionLargerEqual": "mai mare sau egal",
+	"conditionContains": "conţine",
+	"conditionIs": "este",
+	"conditionStartsWith": "începe cu",
+	"conditionEndWith": "se termină cu",
+	"conditionNotContain": "nu conţine",
+	"conditionIsNot": "nu este",
+	"conditionNotStartWith": "nu începe cu ",
+	"conditionNotEndWith": "nu se termină cu",
+	"conditionBefore": "înaintea",
+	"conditionAfter": "după",
+	"conditionRange": "interval",
+	"conditionIsEmpty": "este gol",
+	
+	"all": "toate",
+	"any": "oricare",
+	"relationAll": "toate regulile",
+	"waiRelAll": "Răspundeţi tuturor regulilor următoare:",
+	"relationAny": "oricare reguli",
+	"waiRelAny": "Răspundeţi oricărei dintre regulile următoare:",
+	"relationMsgFront": "Răspuns",
+	"relationMsgTail": "",
+	"and": "şi",
+	"or": "sau",
+	
+	"addRuleButton": "Adăugare regulă",
+	"waiAddRuleButton": "Adăugare regulă nouă",
+	"removeRuleButton": "Înlăturare regulă",
+	"waiRemoveRuleButtonTemplate": "Înlăturare regulă ${0}",
+	
+	"cancelButton": "Anulare",
+	"waiCancelButton": "Anulaţi acest dialog",
+	"clearButton": "Ştergere",
+	"waiClearButton": "Ştergeţi filtrul",
+	"filterButton": "Filtru",
+	"waiFilterButton": "Lansaţi în execuţie filtrul",
+	
+	"columnSelectLabel": "Coloană",
+	"waiColumnSelectTemplate": "Coloană pentru regulă ${0}",
+	"conditionSelectLabel": "Condiţie",
+	"waiConditionSelectTemplate": "Condiţie pentru regula ${0}",
+	"valueBoxLabel": "Valoare",
+	"waiValueBoxTemplate": "Introduceţi valoarea pentru filtrarea pentru regulă ${0}",
+	
+	"rangeTo": "la",
+	"rangeTemplate": "din ${0} la ${1}",
+	
+	"statusTipHeaderColumn": "Coloană",
+	"statusTipHeaderCondition": "Reguli",
+	"statusTipTitle": "Bară de filtru",
+	"statusTipMsg": "Faceţi clic pe bara de filtru aici pentru a filtra valorile în ${0}.",
+	"anycolumn": "orice coloană",
+	"statusTipTitleNoFilter": "Bară de filtru",
+	"statusTipTitleHasFilter": "Filtru",
+	"statusTipRelPre": "Îndeplinire",
+	"statusTipRelPost": "reguli.",
+	
+	"defaultItemsName": "articole",
+	"filterBarMsgHasFilterTemplate": "${0} din ${1} ${2} afişate.",
+	"filterBarMsgNoFilterTemplate": "Niciun filtru nu este aplicat",
+	
+	"filterBarDefButton": "Definire filtru",
+	"waiFilterBarDefButton": "Filtrare tabelă",
+	"a11yFilterBarDefButton": "Filtru...",
+	"filterBarClearButton": "Ştergere filtru",
+	"waiFilterBarClearButton": "Ştergeţi filtrul",
+	"closeFilterBarBtn": "Închidere bară de filtru",
+	
+	"clearFilterMsg": "Aceasta va înlătura filtrul şi va afişa toate înregistrările disponibile.",
+	"anyColumnOption": "Orice coloană",
+	
+	"trueLabel": "Adevărat",
+	"falseLabel": "Fals"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/ro/Pagination.js b/dojox/grid/enhanced/nls/ro/Pagination.js
new file mode 100644
index 0000000..b897e77
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ro/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} din ${1} ${0}",
+	"firstTip": "Prima pagină",
+	"lastTip": "Ultima pagină",
+	"nextTip": "Următoarea pagină",
+	"prevTip": "Pagina anterioarp",
+	"itemTitle": "articole",
+	"pageStepLabelTemplate": "Pagina ${0}",
+	"pageSizeLabelTemplate": "${0} articole pe pagină",
+	"allItemsLabelTemplate": "Toate articolele",
+	"gotoButtonTitle": "Deplasare la o pagină anumită",
+	"dialogTitle": "Deplasare la pagină",
+	"dialogIndication": "Specificaţi numărul de pagină",
+	"pageCountIndication": " (${0} pagini)",
+	"dialogConfirm": "Deplasare",
+	"dialogCancel": "Anulare"
+})
+
diff --git a/dojox/grid/enhanced/nls/ru/EnhancedGrid.js b/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
index d4caf2a..ef48b03 100644
--- a/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/ru/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Однократная сортировка",
+	singleSort: "Простая сортировка",
 	nestedSort: "Вложенная сортировка",
 	ascending: "По возрастанию",
 	descending: "По убыванию",
-	unsorted: "Не сортировать этот столбец"
+	sortingState: "${0} - ${1}",
+	unsorted: "Не сортировать этот столбец",
+	indirectSelectionRadio: "Строка ${0}, один выбор, радиокнопка",
+	indirectSelectionCheckBox: "Строка ${0}, несколько выборов, переключатель",
+	selectAll: "Выбрать все"
 })
 
diff --git a/dojox/grid/enhanced/nls/ru/Filter.js b/dojox/grid/enhanced/nls/ru/Filter.js
new file mode 100644
index 0000000..b50c35f
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ru/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Удалить фильтр",
+	"filterDefDialogTitle": "Фильтр",
+	"ruleTitleTemplate": "Правило ${0}",
+	
+	"conditionEqual": "равно",
+	"conditionNotEqual": "не равно",
+	"conditionLess": "меньше, чем",
+	"conditionLessEqual": "меньше или равно",
+	"conditionLarger": "больше, чем",
+	"conditionLargerEqual": "больше или равно",
+	"conditionContains": "содержит",
+	"conditionIs": "является",
+	"conditionStartsWith": "начинается с",
+	"conditionEndWith": "заканчивается на",
+	"conditionNotContain": "не содержит",
+	"conditionIsNot": "не является",
+	"conditionNotStartWith": "не начинается с",
+	"conditionNotEndWith": "не заканчивается на",
+	"conditionBefore": "до",
+	"conditionAfter": "после",
+	"conditionRange": "диапазон",
+	"conditionIsEmpty": "пустое",
+	
+	"all": "все",
+	"any": "любое",
+	"relationAll": "все правила",
+	"waiRelAll": "Соответствие всем следующим правилам:",
+	"relationAny": "любое правило",
+	"waiRelAny": "Соответствие любому из следующих правил:",
+	"relationMsgFront": "Соответствие",
+	"relationMsgTail": "",
+	"and": "и",
+	"or": "или",
+	
+	"addRuleButton": "Добавить правило",
+	"waiAddRuleButton": "Добавить новое правило",
+	"removeRuleButton": "Удалить правило",
+	"waiRemoveRuleButtonTemplate": "Удалить правило ${0}",
+	
+	"cancelButton": "Отмена",
+	"waiCancelButton": "Отменить этот диалог",
+	"clearButton": "Удалить",
+	"waiClearButton": "Удалить фильтр",
+	"filterButton": "Фильтр",
+	"waiFilterButton": "Передать фильтр",
+	
+	"columnSelectLabel": "Столбец",
+	"waiColumnSelectTemplate": "Столбец для правила ${0}",
+	"conditionSelectLabel": "Условие",
+	"waiConditionSelectTemplate": "Условие для правила ${0}",
+	"valueBoxLabel": "Значение",
+	"waiValueBoxTemplate": "Задайте значение фильтра для правила ${0}",
+	
+	"rangeTo": "до",
+	"rangeTemplate": "от ${0} до ${1}",
+	
+	"statusTipHeaderColumn": "Столбец",
+	"statusTipHeaderCondition": "Правила",
+	"statusTipTitle": "Панель фильтра",
+	"statusTipMsg": "Щелкните по панели фильтра, чтобы применить фильтр к значениям в ${0}.",
+	"anycolumn": "любой столбец",
+	"statusTipTitleNoFilter": "Панель фильтра",
+	"statusTipTitleHasFilter": "Фильтр",
+	"statusTipRelPre": "Соответствие",
+	"statusTipRelPost": "правила.",
+	
+	"defaultItemsName": "элементов",
+	"filterBarMsgHasFilterTemplate": "Показано ${0} из ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Фильтр не применен",
+	
+	"filterBarDefButton": "Задать фильтр",
+	"waiFilterBarDefButton": "Применить фильтр к таблице",
+	"a11yFilterBarDefButton": "Фильтр...",
+	"filterBarClearButton": "Удалить фильтр",
+	"waiFilterBarClearButton": "Удалить фильтр",
+	"closeFilterBarBtn": "Закрыть панель фильтра",
+	
+	"clearFilterMsg": "Фильтр будет удален, и будут показаны все записи.",
+	"anyColumnOption": "Любой столбец",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/ru/Pagination.js b/dojox/grid/enhanced/nls/ru/Pagination.js
new file mode 100644
index 0000000..864395c
--- /dev/null
+++ b/dojox/grid/enhanced/nls/ru/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} из ${1} ${0}",
+	"firstTip": "Первая страница",
+	"lastTip": "Последняя страница",
+	"nextTip": "Следующая страница",
+	"prevTip": "Предыдущая страница",
+	"itemTitle": "элементов",
+	"pageStepLabelTemplate": "Страница ${0}",
+	"pageSizeLabelTemplate": "${0} элементов на странице",
+	"allItemsLabelTemplate": "Все элементы",
+	"gotoButtonTitle": "Перейти на конкретную страницу",
+	"dialogTitle": "Перейти на страницу",
+	"dialogIndication": "Укажите номер страницы",
+	"pageCountIndication": " (${0} страниц)",
+	"dialogConfirm": "Перейти",
+	"dialogCancel": "Отмена"
+})
+
diff --git a/dojox/grid/enhanced/nls/sk/Filter.js b/dojox/grid/enhanced/nls/sk/Filter.js
new file mode 100644
index 0000000..b2303f3
--- /dev/null
+++ b/dojox/grid/enhanced/nls/sk/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Zrušiť filter",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Pravidlo ${0}",
+	
+	"conditionEqual": "rovné",
+	"conditionNotEqual": "nerovné",
+	"conditionLess": "menšie ako",
+	"conditionLessEqual": "menšie ako alebo rovné",
+	"conditionLarger": "väčšie ako",
+	"conditionLargerEqual": "väčšie ako alebo rovné",
+	"conditionContains": "obsahuje",
+	"conditionIs": "je",
+	"conditionStartsWith": "začína s",
+	"conditionEndWith": "končí s",
+	"conditionNotContain": "neobsahuje",
+	"conditionIsNot": "nie je",
+	"conditionNotStartWith": "nezačína s",
+	"conditionNotEndWith": "nekončí s",
+	"conditionBefore": "pred",
+	"conditionAfter": "za",
+	"conditionRange": "rozsah",
+	"conditionIsEmpty": "je prázdne",
+	
+	"all": "všetko",
+	"any": "žiadne",
+	"relationAll": "všetky pravidlá",
+	"waiRelAll": "Vyhovovať všetkým týmto pravidlám:",
+	"relationAny": "ľubovoľné pravidlá",
+	"waiRelAny": "Vyhovovať ľubovoľným z týchto pravidiel:",
+	"relationMsgFront": "Vyhovieť",
+	"relationMsgTail": "",
+	"and": "a",
+	"or": "alebo",
+	
+	"addRuleButton": "Pridať pravidlo",
+	"waiAddRuleButton": "Pridať nové pravidlo",
+	"removeRuleButton": "Odstrániť pravidlo",
+	"waiRemoveRuleButtonTemplate": "Odstrániť pravidlo ${0}",
+	
+	"cancelButton": "Zrušiť",
+	"waiCancelButton": "Zrušiť toto dialógové okno",
+	"clearButton": "Zrušiť",
+	"waiClearButton": "Zrušiť filter",
+	"filterButton": "Filtrovať",
+	"waiFilterButton": "Odoslať filter",
+	
+	"columnSelectLabel": "Stĺpec",
+	"waiColumnSelectTemplate": "Stĺpec pre pravidlo ${0}",
+	"conditionSelectLabel": "Podmienka",
+	"waiConditionSelectTemplate": "Podmienka pre pravidlo ${0}",
+	"valueBoxLabel": "Hodnota",
+	"waiValueBoxTemplate": "Zadajte hodnotu na filtrovanie pre pravidlo ${0}",
+	
+	"rangeTo": "do",
+	"rangeTemplate": "od ${0} do ${1}",
+	
+	"statusTipHeaderColumn": "Stĺpec",
+	"statusTipHeaderCondition": "Pravidlá",
+	"statusTipTitle": "Lišta filtra",
+	"statusTipMsg": "Kliknite na lištu filtra, ak chcete filtrovať podľa hodnôt v ${0}.",
+	"anycolumn": "ľubovoľný stĺpec",
+	"statusTipTitleNoFilter": "Lišta filtra",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Vyhovieť",
+	"statusTipRelPost": "pravidlá.",
+	
+	"defaultItemsName": "položky",
+	"filterBarMsgHasFilterTemplate": "Zobrazuje sa ${0} z ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Nepoužíva sa žiadny filter",
+	
+	"filterBarDefButton": "Definovať filter",
+	"waiFilterBarDefButton": "Filtrovať tabuľku",
+	"a11yFilterBarDefButton": "Filtrovať...",
+	"filterBarClearButton": "Zrušiť filter",
+	"waiFilterBarClearButton": "Zrušiť filter",
+	"closeFilterBarBtn": "Zatvoriť lištu filtra",
+	
+	"clearFilterMsg": "Toto odstráni filter a zobrazí všetky dostupné záznamy",
+	"anyColumnOption": "Ľubovoľný stĺpec",
+	
+	"trueLabel": "Pravda",
+	"falseLabel": "Nepravda"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/sk/Pagination.js b/dojox/grid/enhanced/nls/sk/Pagination.js
new file mode 100644
index 0000000..d1afa89
--- /dev/null
+++ b/dojox/grid/enhanced/nls/sk/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} z ${1} ${0}",
+	"firstTip": "Prvá strana",
+	"lastTip": "Posledná strana",
+	"nextTip": "Ďalšia strana",
+	"prevTip": "Predošlá strana",
+	"itemTitle": "položiek",
+	"pageStepLabelTemplate": "Strana ${0}",
+	"pageSizeLabelTemplate": "${0} položiek na strane",
+	"allItemsLabelTemplate": "Všetky položky",
+	"gotoButtonTitle": "Prejsť na špecifickú stranu",
+	"dialogTitle": "Prejsť na stranu",
+	"dialogIndication": "Zadajte číslo strany",
+	"pageCountIndication": " (${0} strán)",
+	"dialogConfirm": "Prejsť",
+	"dialogCancel": "Zrušiť"
+})
+
diff --git a/dojox/grid/enhanced/nls/sl/EnhancedGrid.js b/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
index 6726cd3..7201d7f 100644
--- a/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sl/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Razvrsti po vrsti",
-	nestedSort: "Ugnezdena razvrstitev",
+	singleSort: "Enostavno razvrščanje",
+	nestedSort: "Ugnezdeno razvrščanje",
 	ascending: "Naraščajoče",
 	descending: "Padajoče",
-	unsorted: "Ne razvrsti tega stolpca"
+	sortingState: "${0} - ${1}",
+	unsorted: "Ne razvrščaj tega stolpca",
+	indirectSelectionRadio: "Vrstica ${0}, izbira enega elementa, okence z izbirnim gumbom",
+	indirectSelectionCheckBox: "Vrstica ${0}, izbira več elementov, okence s potrditvenimi polji",
+	selectAll: "Izberi vse"
 })
 
diff --git a/dojox/grid/enhanced/nls/sl/Filter.js b/dojox/grid/enhanced/nls/sl/Filter.js
new file mode 100644
index 0000000..7d1e47b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/sl/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Počisti filter",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Pravilo ${0}",
+	
+	"conditionEqual": "je enako",
+	"conditionNotEqual": "ni enako",
+	"conditionLess": "je manjše kot",
+	"conditionLessEqual": "je manjše kot ali enako",
+	"conditionLarger": "je večje kot",
+	"conditionLargerEqual": "je večje kot ali enako",
+	"conditionContains": "vsebuje",
+	"conditionIs": "je",
+	"conditionStartsWith": "se začne s",
+	"conditionEndWith": "se konča s",
+	"conditionNotContain": "ne vsebuje",
+	"conditionIsNot": "ni",
+	"conditionNotStartWith": "se ne začne s",
+	"conditionNotEndWith": "se ne konča s",
+	"conditionBefore": "pred",
+	"conditionAfter": "za",
+	"conditionRange": "obseg",
+	"conditionIsEmpty": "je prazno",
+	
+	"all": "vse",
+	"any": "karkoli",
+	"relationAll": "vsa pravila",
+	"waiRelAll": "Ujema se z vsemi od naslednjih pravil:",
+	"relationAny": "katerakoli pravila",
+	"waiRelAny": "Ujema se s katerimkoli od naslednjih pravil:",
+	"relationMsgFront": "Ujemanje",
+	"relationMsgTail": "",
+	"and": "in",
+	"or": "ali",
+	
+	"addRuleButton": "Dodaj pravilo",
+	"waiAddRuleButton": "Dodaj novo pravilo",
+	"removeRuleButton": "Odstrani pravilo",
+	"waiRemoveRuleButtonTemplate": "Odstrani pravilo ${0}",
+	
+	"cancelButton": "Prekliči",
+	"waiCancelButton": "Prekliči to pogovorno okno",
+	"clearButton": "Počisti",
+	"waiClearButton": "Počisti filter",
+	"filterButton": "Filter",
+	"waiFilterButton": "Predloži filter",
+	
+	"columnSelectLabel": "Stolpec",
+	"waiColumnSelectTemplate": "Stolpec za pravilo ${0}",
+	"conditionSelectLabel": "Pogoj",
+	"waiConditionSelectTemplate": "Pogoj za pravilo ${0}",
+	"valueBoxLabel": "Vrednost",
+	"waiValueBoxTemplate": "Vnesite vrednost za filter pravila ${0}",
+	
+	"rangeTo": "do",
+	"rangeTemplate": "od ${0} do ${1}",
+	
+	"statusTipHeaderColumn": "Stolpec",
+	"statusTipHeaderCondition": "Pravila",
+	"statusTipTitle": "Vrstica za filtriranje",
+	"statusTipMsg": "Kliknite vrstico za filtriranje tukaj, da prefiltrirate vrednosti v ${0}.",
+	"anycolumn": "katerikoli stolpec",
+	"statusTipTitleNoFilter": "Vrstica za filtriranje",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Ujemanje",
+	"statusTipRelPost": "pravila.",
+	
+	"defaultItemsName": "postavke",
+	"filterBarMsgHasFilterTemplate": "Prikazanih je ${0} od ${1} ${2}.",
+	"filterBarMsgNoFilterTemplate": "Uveljavljen ni noben filter.",
+	
+	"filterBarDefButton": "Definiraj filter",
+	"waiFilterBarDefButton": "Filtriraj tabelo",
+	"a11yFilterBarDefButton": "Filtriraj ...",
+	"filterBarClearButton": "Počisti filter",
+	"waiFilterBarClearButton": "Počisti filter",
+	"closeFilterBarBtn": "Zapri vrstico za filtriranje",
+	
+	"clearFilterMsg": "S tem boste odstranili filter in prikazali se bodo vsi razpoložljivi zapisi.",
+	"anyColumnOption": "Katerikoli stolpec",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/sl/Pagination.js b/dojox/grid/enhanced/nls/sl/Pagination.js
new file mode 100644
index 0000000..935f3a9
--- /dev/null
+++ b/dojox/grid/enhanced/nls/sl/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} od ${1} ${0}",
+	"firstTip": "Prva stran",
+	"lastTip": "Zadnja stran",
+	"nextTip": "Naslednja stran",
+	"prevTip": "Prejšnja stran",
+	"itemTitle": "postavke",
+	"pageStepLabelTemplate": "Stran ${0}",
+	"pageSizeLabelTemplate": "${0} postavk na stran",
+	"allItemsLabelTemplate": "Vse postavke",
+	"gotoButtonTitle": "Pojdi na specifično stran",
+	"dialogTitle": "Pojdi na stran",
+	"dialogIndication": "Podajte številko strani",
+	"pageCountIndication": " (${0} strani)",
+	"dialogConfirm": "Pojdi",
+	"dialogCancel": "Prekliči"
+})
+
diff --git a/dojox/grid/enhanced/nls/sv/EnhancedGrid.js b/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
index 8e06f85..2d23b4a 100644
--- a/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/sv/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "enkel sortering",
-	nestedSort: "nästlad sortering",
-	ascending: "stigande",
-	descending: "fallande",
-	unsorted: "Sortera inte den här kolumnen"
+	singleSort: "Enkel sortering",
+	nestedSort: "Nästlad sortering",
+	ascending: "Stigande",
+	descending: "Fallande",
+	sortingState: "${0} - ${1}",
+	unsorted: "Sortera inte den här kolumnen",
+	indirectSelectionRadio: "Rad ${0}, ett enda val, alternativruta",
+	indirectSelectionCheckBox: "Rad ${0}, flera val, kryssruta",
+	selectAll: "Markera alla "
 })
 
diff --git a/dojox/grid/enhanced/nls/sv/Filter.js b/dojox/grid/enhanced/nls/sv/Filter.js
new file mode 100644
index 0000000..efe276e
--- /dev/null
+++ b/dojox/grid/enhanced/nls/sv/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Rensa filter",
+	"filterDefDialogTitle": "Filter",
+	"ruleTitleTemplate": "Regel ${0}",
+	
+	"conditionEqual": "lika med",
+	"conditionNotEqual": "inte lika med",
+	"conditionLess": "är mindre än",
+	"conditionLessEqual": "mindre eller lika med",
+	"conditionLarger": "är större än",
+	"conditionLargerEqual": "större än eller lika med",
+	"conditionContains": "innehåller",
+	"conditionIs": "är",
+	"conditionStartsWith": "börjar med",
+	"conditionEndWith": "slutar med",
+	"conditionNotContain": "innehåller inte",
+	"conditionIsNot": "är inte",
+	"conditionNotStartWith": "börjar inte med",
+	"conditionNotEndWith": "slutar inte med",
+	"conditionBefore": "före",
+	"conditionAfter": "efter",
+	"conditionRange": "intervall",
+	"conditionIsEmpty": "är tom",
+	
+	"all": "alla",
+	"any": "någon",
+	"relationAll": "alla regler",
+	"waiRelAll": "Matcha alla följande regler:",
+	"relationAny": "någon regel",
+	"waiRelAny": "Matcha någon av följande regler:",
+	"relationMsgFront": "Matcha",
+	"relationMsgTail": "",
+	"and": "och",
+	"or": "eller",
+	
+	"addRuleButton": "Lägg till regel",
+	"waiAddRuleButton": "Lägg till en ny regel",
+	"removeRuleButton": "Ta bort regel",
+	"waiRemoveRuleButtonTemplate": "Ta bort regel ${0}",
+	
+	"cancelButton": "Avbryt",
+	"waiCancelButton": "Avbryt dialogen",
+	"clearButton": "Rensa",
+	"waiClearButton": "Rensa filtret",
+	"filterButton": "Filtrera",
+	"waiFilterButton": "Filtrera",
+	
+	"columnSelectLabel": "Kolumn",
+	"waiColumnSelectTemplate": "Kolumn för regel ${0}",
+	"conditionSelectLabel": "Villkor",
+	"waiConditionSelectTemplate": "Villkor för regel ${0}",
+	"valueBoxLabel": "Värde",
+	"waiValueBoxTemplate": "Ange värde för filtrering efter regeln ${0}",
+	
+	"rangeTo": "till",
+	"rangeTemplate": "från ${0} till ${1}",
+	
+	"statusTipHeaderColumn": "Kolumn",
+	"statusTipHeaderCondition": "Regler",
+	"statusTipTitle": "Filterfält",
+	"statusTipMsg": "Klicka på filterfältet om du vill filtrera värden i ${0}.",
+	"anycolumn": "alla kolumner",
+	"statusTipTitleNoFilter": "Filterfält",
+	"statusTipTitleHasFilter": "Filter",
+	"statusTipRelPre": "Matcha",
+	"statusTipRelPost": "regler.",
+	
+	"defaultItemsName": "objekt",
+	"filterBarMsgHasFilterTemplate": "${0} av ${1} ${2} visas.",
+	"filterBarMsgNoFilterTemplate": "Inget filter tillämpat",
+	
+	"filterBarDefButton": "Definiera filter",
+	"waiFilterBarDefButton": "Filtrera tabellen",
+	"a11yFilterBarDefButton": "Filter...",
+	"filterBarClearButton": "Rensa filter",
+	"waiFilterBarClearButton": "Rensa filtret",
+	"closeFilterBarBtn": "Stäng filterfält",
+	
+	"clearFilterMsg": "Tar bort filtret och visar alla tillgängliga poster.",
+	"anyColumnOption": "Alla kolumner",
+	
+	"trueLabel": "Sant",
+	"falseLabel": "Falskt"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/sv/Pagination.js b/dojox/grid/enhanced/nls/sv/Pagination.js
new file mode 100644
index 0000000..cb2c9b9
--- /dev/null
+++ b/dojox/grid/enhanced/nls/sv/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} av ${1} ${0}",
+	"firstTip": "Första sidan",
+	"lastTip": "Sista sidan",
+	"nextTip": "Nästa sida",
+	"prevTip": "Föregående sida",
+	"itemTitle": "objekt",
+	"pageStepLabelTemplate": "Sida ${0}",
+	"pageSizeLabelTemplate": "${0} objekt per sida",
+	"allItemsLabelTemplate": "Alla objekt",
+	"gotoButtonTitle": "Gå till en viss sida",
+	"dialogTitle": "Gå till sidan",
+	"dialogIndication": "Ange sidnummer",
+	"pageCountIndication": " (${0} sidor)",
+	"dialogConfirm": "Gå",
+	"dialogCancel": "Avbryt"
+})
+
diff --git a/dojox/grid/enhanced/nls/th/Filter.js b/dojox/grid/enhanced/nls/th/Filter.js
new file mode 100644
index 0000000..d190f9c
--- /dev/null
+++ b/dojox/grid/enhanced/nls/th/Filter.js
@@ -0,0 +1,88 @@
+({
+	"clearFilterDialogTitle": "ลบตัวกรอง",
+	"filterDefDialogTitle": "ตัวกรอง",
+	"incompleteRuleTip": "กฏนี้ยังไม่สมบูรณ์",
+	"ruleTitleTemplate": "กฏ ${0}",
+	
+	"conditionEqual": "เท่ากับ",
+	"conditionNotEqual": "ไม่เท่ากับ",
+	"conditionLess": "น้อยกว่า",
+	"conditionLessEqual": "น้อยกว่าหรือเท่ากับ",
+	"conditionLarger": "มากกว่า",
+	"conditionLargerEqual": "มากกว่าหรือเท่ากับ",
+	"conditionContains": "ประกอบด้วย",
+	"conditionIs": "เป็น",
+	"conditionStartsWith": "เริ่มต้นด้วย",
+	"conditionEndWith": "ลงท้ายด้วย",
+	"conditionNotContain": "ไม่ประกอบด้วย",
+	"conditionIsNot": "ไม่",
+	"conditionNotStartWith": "ไม่เริ่มต้นด้วย",
+	"conditionNotEndWith": "ไม่ลงท้ายด้วย",
+	"conditionBefore": "ก่อน",
+	"conditionAfter": "หลัง",
+	"conditionRange": "ช่วง",
+	
+	"all": "ทั้งหมด",
+	"any": "ใด",
+	"relationAll": "กฏทั้งหมด",
+	"waiRelAll": "ตรงกับกฏทั้งหมดต่อไปนี้:",
+	"relationAny": "กฏใดๆ",
+	"waiRelAny": "ตรงกับกฏใดๆต่อไปนี้:",
+	"relationMsgFront": "ตรงกับ",
+	"relationMsgTail": "",
+	"and": "และ",
+	"or": "หรือ",
+	
+	"addRuleButton": "เพิ่มกฏ",
+	"waiAddRuleButton": "เพิ่มกฏใหม่",
+	"removeRuleButton": "ลบกฏ",
+	"waiRemoveRuleButtonTemplate": "ลบกฏ ${0}",
+	
+	"cancelButton": "ยกเลิก",
+	"waiCancelButton": "ยกเลิกไดอะล็อกนี้",
+	"clearButton": "ลบ",
+	"waiClearButton": "ลบตัวกรอง",
+	"filterButton": "ตัวกรอง",
+	"waiFilterButton": "ส่งตัวกรอง",
+	
+	"columnSelectLabel": "คอลัมน์",
+	"waiColumnSelectTemplate": "คอลัมน์สำหรับกฏ ${0}",
+	"conditionSelectLabel": "เงื่อนไข",
+	"waiConditionSelectTemplate": "เงื่อนไขสำหรับกฏ ${0}",
+	"valueBoxLabel": "ค่า",
+	"waiValueBoxTemplate": "ป้อนค่าให้กับตัวกรองสำหรับกฏ ${0}",
+	
+	"rangeTo": "ถึง",
+	"rangeTemplate": "จาก ${0} ถึง ${1}",
+	
+	"statusTipHeaderColumn": "คอลัมน์",
+	"statusTipHeaderCondition": "กฏ",
+	"statusTipTitle": "แถบตัวกรอง",
+	"statusTipMsg": "คลิกที่แถบตัวกรองที่นี่เพื่อกรองค่าใน ${0}",
+	"anycolumn": "คอลัมน์ใดๆ",
+	"statusTipTitleNoFilter": "แถบตัวกรอง",
+	"statusTipTitleHasFilter": "ตัวกรอง",
+	"statusTipRelPre": "ตรงกับ",
+	"statusTipRelPost": "กฏ",
+	
+	"defaultItemsName": "ไอเท็ม",
+	"filterBarMsgHasFilterTemplate": "${0} ของ ${1} ${2} จะถูกแสดง",
+	"filterBarMsgNoFilterTemplate": "ไม่นำตัวกรองไปใช้",
+	
+	"filterBarDefButton": "กำหนดตัวกรอง",
+	"waiFilterBarDefButton": "กรองตาราง",
+	"a11yFilterBarDefButton": "ตัวกรอง...",
+	"filterBarClearButton": "ลบตัวกรอง",
+	"waiFilterBarClearButton": "ลบตัวกรอง",
+	"closeFilterBarBtn": "ปิดแถบตัวกรอง",
+	
+	"clearFilterMsg": "ซึ่งจะลบตัวกรองออกและแสดงเร็กคอร์ดที่พร้อมใช้งานทั้งหมด",
+	"anyColumnOption": "คอลัมน์ใดๆ",
+	
+	"trueLabelEditable": "ได้รับการตรวจสอบ",
+	"trueLabel": "จริง",
+	"falseLabel": "เท็จ"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/th/Pagination.js b/dojox/grid/enhanced/nls/th/Pagination.js
new file mode 100644
index 0000000..603c03f
--- /dev/null
+++ b/dojox/grid/enhanced/nls/th/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} จาก ${1} ${0}",
+	"firstTip": "หน้าแรก",
+	"lastTip": "หน้าสุดท้าย",
+	"nextTip": "หน้าถัดไป",
+	"prevTip": "หน้าก่อนหน้านี้",
+	"itemTitle": "ไอเท็ม",
+	"pageStepLabelTemplate": "หน้า ${0}",
+	"pageSizeLabelTemplate": "${0} ไอเท็มต่อหน้า",
+	"allItemsLabelTemplate": "รายการ ทั้งหมด",
+	"gotoButtonTitle": "ไปที่หน้าที่ระบุ",
+	"dialogTitle": "ไปที่หน้า",
+	"dialogIndication": "ระบุหมายเลขหน้า",
+	"pageCountIndication": " (${0} หน้า)",
+	"dialogConfirm": "ไปที่",
+	"dialogCancel": "ยกเลิก"
+})
+
diff --git a/dojox/grid/enhanced/nls/tr/EnhancedGrid.js b/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
index 0c1d0a8..1b87ce0 100644
--- a/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/tr/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "Tek Sıralama",
+	singleSort: "Tekli Sıralama",
 	nestedSort: "İç İçe Sıralama",
-	ascending: "Artan",
-	descending: "Azalan",
-	unsorted: "Bu sütunu sıralama"
+	ascending: "Artan Düzende",
+	descending: "Azalan Düzende",
+	sortingState: "${0} - ${1}",
+	unsorted: "Bu sütunu sıralama",
+	indirectSelectionRadio: "Satır ${0}, tek seçimli, radyo düğmesi",
+	indirectSelectionCheckBox: "Satır ${0}, çok seçimli, radyo düğmesi",
+	selectAll: "Tümünü seç"
 })
 
diff --git a/dojox/grid/enhanced/nls/tr/Filter.js b/dojox/grid/enhanced/nls/tr/Filter.js
new file mode 100644
index 0000000..6083c2b
--- /dev/null
+++ b/dojox/grid/enhanced/nls/tr/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "Süzgeci Kaldır",
+	"filterDefDialogTitle": "Süzgeç",
+	"ruleTitleTemplate": "Kural ${0}",
+	
+	"conditionEqual": "eşittir",
+	"conditionNotEqual": "eşit değildir",
+	"conditionLess": "küçüktür",
+	"conditionLessEqual": "küçüktür veya eşittir",
+	"conditionLarger": "büyüktür",
+	"conditionLargerEqual": "büyüktür veya eşittir",
+	"conditionContains": "içerir",
+	"conditionIs": "şudur",
+	"conditionStartsWith": "şununla başlar",
+	"conditionEndWith": "şununla biter",
+	"conditionNotContain": "içermez",
+	"conditionIsNot": "şu değildir",
+	"conditionNotStartWith": "şununla başlamaz",
+	"conditionNotEndWith": "şununla bitmez",
+	"conditionBefore": "önce",
+	"conditionAfter": "sonra",
+	"conditionRange": "aralık",
+	"conditionIsEmpty": "boş",
+	
+	"all": "tümü",
+	"any": "herhangi biri",
+	"relationAll": "tüm kurallar",
+	"waiRelAll": "Aşağıdaki tüm kurallarla eşleştir",
+	"relationAny": "kuralların herhangi biri",
+	"waiRelAny": "Aşağıdaki kuralların herhangi biri ile eşleştir",
+	"relationMsgFront": "Eşleştir",
+	"relationMsgTail": "",
+	"and": "ve",
+	"or": "veya",
+	
+	"addRuleButton": "Kural Ekle",
+	"waiAddRuleButton": "Yeni bir kural ekle",
+	"removeRuleButton": "Kuralı Kaldır",
+	"waiRemoveRuleButtonTemplate": "${0} kuralını kaldır",
+	
+	"cancelButton": "İptal",
+	"waiCancelButton": "Bu iletişim kutusunu iptal et",
+	"clearButton": "Kaldır",
+	"waiClearButton": "Süzgeci kaldır",
+	"filterButton": "Süzgeç",
+	"waiFilterButton": "Süzgeci gönder",
+	
+	"columnSelectLabel": "Sütun",
+	"waiColumnSelectTemplate": "${0} kuralı için sütun",
+	"conditionSelectLabel": "Koşul",
+	"waiConditionSelectTemplate": "${0} kuralı için koşul",
+	"valueBoxLabel": "Değer",
+	"waiValueBoxTemplate": "${0} kuralı için süzülecek değeri girin",
+	
+	"rangeTo": "bitiş",
+	"rangeTemplate": "${0} - ${1}",
+	
+	"statusTipHeaderColumn": "Sütun",
+	"statusTipHeaderCondition": "Kurallar",
+	"statusTipTitle": "Süzgeç Çubuğu",
+	"statusTipMsg": "${0} içindeki değerlere göre süzmek için burada süzgeç çubuğunu tıklatın.",
+	"anycolumn": "herhangi bir sütun",
+	"statusTipTitleNoFilter": "Süzgeç Çubuğu",
+	"statusTipTitleHasFilter": "Süzgeç",
+	"statusTipRelPre": "Eşleştir",
+	"statusTipRelPost": "kurallar.",
+	
+	"defaultItemsName": "öğe",
+	"filterBarMsgHasFilterTemplate": "${0} / ${1} ${2} gösteriliyor.",
+	"filterBarMsgNoFilterTemplate": "Süzgeç uygulanmadı",
+	
+	"filterBarDefButton": "Süzgeç tanımla",
+	"waiFilterBarDefButton": "Tabloyu süz",
+	"a11yFilterBarDefButton": "Süz...",
+	"filterBarClearButton": "Süzgeci kaldır",
+	"waiFilterBarClearButton": "Süzgeci kaldır",
+	"closeFilterBarBtn": "Süzgeç çubuğunu kapat",
+	
+	"clearFilterMsg": "Bu seçenek süzgeci kaldırır ve tüm kullanılabilir kayıtları gösterir.",
+	"anyColumnOption": "Herhangi Bir Sütun",
+	
+	"trueLabel": "Doğru",
+	"falseLabel": "Yanlış"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/tr/Pagination.js b/dojox/grid/enhanced/nls/tr/Pagination.js
new file mode 100644
index 0000000..4750df9
--- /dev/null
+++ b/dojox/grid/enhanced/nls/tr/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${3} / ${1} ${0}",
+	"firstTip": "İlk Sayfa",
+	"lastTip": "Son Sayfa",
+	"nextTip": "Sonraki Sayfa",
+	"prevTip": "Önceki Sayfa",
+	"itemTitle": "öğe",
+	"pageStepLabelTemplate": "Sayfa ${0}",
+	"pageSizeLabelTemplate": "Sayfa başına ${0} öğe",
+	"allItemsLabelTemplate": "Tüm öğeler",
+	"gotoButtonTitle": "Belirli bir sayfaya git",
+	"dialogTitle": "Sayfaya Git",
+	"dialogIndication": "Sayfa numarasını belirtin",
+	"pageCountIndication": " (${0} sayfa)",
+	"dialogConfirm": "Git",
+	"dialogCancel": "İptal"
+})
+
diff --git a/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js b/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
index 48b5638..3963132 100644
--- a/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/zh-tw/EnhancedGrid.js
@@ -2,7 +2,11 @@
 	singleSort: "單一排序",
 	nestedSort: "巢狀排序",
 	ascending: "遞增",
-	descending: "遞減",
-	unsorted: "不排序此直欄"
+	descending: "降冪",
+	sortingState: "${0} - ${1}",
+	unsorted: "請勿對此欄執行排序",
+	indirectSelectionRadio: "第 ${0} 行,單一選項,圓鈕框",
+	indirectSelectionCheckBox: "第 ${0} 行,多重選項,勾選框",
+	selectAll: "全選"
 })
 
diff --git a/dojox/grid/enhanced/nls/zh-tw/Filter.js b/dojox/grid/enhanced/nls/zh-tw/Filter.js
new file mode 100644
index 0000000..feefdb7
--- /dev/null
+++ b/dojox/grid/enhanced/nls/zh-tw/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "清除過濾器",
+	"filterDefDialogTitle": "過濾器",
+	"ruleTitleTemplate": "規則 ${0}",
+	
+	"conditionEqual": "等於",
+	"conditionNotEqual": "不等於",
+	"conditionLess": "是小於",
+	"conditionLessEqual": "小於或等於",
+	"conditionLarger": "是大於",
+	"conditionLargerEqual": "大於或等於",
+	"conditionContains": "內容",
+	"conditionIs": "是",
+	"conditionStartsWith": "開始於",
+	"conditionEndWith": "結束於",
+	"conditionNotContain": "不包含",
+	"conditionIsNot": "不是",
+	"conditionNotStartWith": "不開始於",
+	"conditionNotEndWith": "不結束於",
+	"conditionBefore": "之前",
+	"conditionAfter": "之後",
+	"conditionRange": "範圍",
+	"conditionIsEmpty": "為空",
+	
+	"all": "全部",
+	"any": "任何",
+	"relationAll": "所有規則",
+	"waiRelAll": "符合下列所有規則:",
+	"relationAny": "任何規則",
+	"waiRelAny": "符合下列任何規則:",
+	"relationMsgFront": "符合",
+	"relationMsgTail": "",
+	"and": "和",
+	"or": "或",
+	
+	"addRuleButton": "新增規則",
+	"waiAddRuleButton": "新增規則",
+	"removeRuleButton": "移除規則",
+	"waiRemoveRuleButtonTemplate": "移除規則 ${0}",
+	
+	"cancelButton": "取消",
+	"waiCancelButton": "取消此對話",
+	"clearButton": "清除",
+	"waiClearButton": "清除過濾器",
+	"filterButton": "過濾器",
+	"waiFilterButton": "提交過濾器",
+	
+	"columnSelectLabel": "直欄",
+	"waiColumnSelectTemplate": "規則 ${0} 的直欄",
+	"conditionSelectLabel": "條件",
+	"waiConditionSelectTemplate": "規則 ${0} 的條件",
+	"valueBoxLabel": "值",
+	"waiValueBoxTemplate": "輸入要針對規則 ${0} 過濾的值",
+	
+	"rangeTo": "至",
+	"rangeTemplate": "從 ${0} 至 ${1}",
+	
+	"statusTipHeaderColumn": "直欄",
+	"statusTipHeaderCondition": "規則",
+	"statusTipTitle": "過濾器列",
+	"statusTipMsg": "按一下這裡的過濾器列以過濾 ${0} 中的值。",
+	"anycolumn": "任何直欄",
+	"statusTipTitleNoFilter": "過濾器列",
+	"statusTipTitleHasFilter": "過濾器",
+	"statusTipRelPre": "符合",
+	"statusTipRelPost": "規則。",
+	
+	"defaultItemsName": "項目",
+	"filterBarMsgHasFilterTemplate": "顯示 ${1} ${2} 之 ${0}。",
+	"filterBarMsgNoFilterTemplate": "未套用過濾器",
+	
+	"filterBarDefButton": "定義過濾器",
+	"waiFilterBarDefButton": "過濾表格",
+	"a11yFilterBarDefButton": "過濾器...",
+	"filterBarClearButton": "清除過濾器",
+	"waiFilterBarClearButton": "清除過濾器",
+	"closeFilterBarBtn": "關閉過濾器列",
+	
+	"clearFilterMsg": "這將會移除過濾器並顯示所有的可用記錄。",
+	"anyColumnOption": "任何直欄",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/zh-tw/Pagination.js b/dojox/grid/enhanced/nls/zh-tw/Pagination.js
new file mode 100644
index 0000000..82c929f
--- /dev/null
+++ b/dojox/grid/enhanced/nls/zh-tw/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${1} ${0} 之 ${3}",
+	"firstTip": "首頁",
+	"lastTip": "末頁",
+	"nextTip": "下一頁",
+	"prevTip": "上一頁",
+	"itemTitle": "項目",
+	"pageStepLabelTemplate": "頁面 ${0}",
+	"pageSizeLabelTemplate": "每頁 ${0} 個項目",
+	"allItemsLabelTemplate": "所有項目",
+	"gotoButtonTitle": "跳至特定的頁面",
+	"dialogTitle": "跳至頁面",
+	"dialogIndication": "指定頁碼",
+	"pageCountIndication": " (${0} 頁)",
+	"dialogConfirm": "執行",
+	"dialogCancel": "取消"
+})
+
diff --git a/dojox/grid/enhanced/nls/zh/EnhancedGrid.js b/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
index a0dff12..d44a0af 100644
--- a/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
+++ b/dojox/grid/enhanced/nls/zh/EnhancedGrid.js
@@ -1,8 +1,12 @@
 ({
-	singleSort: "单一排序",
+	singleSort: "单层排序",
 	nestedSort: "嵌套排序",
 	ascending: "升序",
 	descending: "降序",
-	unsorted: "不要对此列排序"
+	sortingState: "${0} - ${1}",
+	unsorted: "请勿对此列进行排序",
+	indirectSelectionRadio: "第 ${0} 行,单选,单选框",
+	indirectSelectionCheckBox: "第 ${0} 行,多选,复选框",
+	selectAll: "全部选中"
 })
 
diff --git a/dojox/grid/enhanced/nls/zh/Filter.js b/dojox/grid/enhanced/nls/zh/Filter.js
new file mode 100644
index 0000000..c9da151
--- /dev/null
+++ b/dojox/grid/enhanced/nls/zh/Filter.js
@@ -0,0 +1,87 @@
+({
+	"clearFilterDialogTitle": "清除过滤器",
+	"filterDefDialogTitle": "过滤器",
+	"ruleTitleTemplate": "规则 ${0}",
+	
+	"conditionEqual": "等于",
+	"conditionNotEqual": "不等于",
+	"conditionLess": "小于",
+	"conditionLessEqual": "小于或等于",
+	"conditionLarger": "大于",
+	"conditionLargerEqual": "大于或等于",
+	"conditionContains": "包含",
+	"conditionIs": "是",
+	"conditionStartsWith": "开始于",
+	"conditionEndWith": "结束于",
+	"conditionNotContain": "不包含",
+	"conditionIsNot": "非",
+	"conditionNotStartWith": "不是开始于",
+	"conditionNotEndWith": "不是结束于",
+	"conditionBefore": "先于",
+	"conditionAfter": "后于",
+	"conditionRange": "范围",
+	"conditionIsEmpty": "为空",
+	
+	"all": "全部",
+	"any": "任何",
+	"relationAll": "所有规则",
+	"waiRelAll": "符合以下所有规则:",
+	"relationAny": "任何规则",
+	"waiRelAny": "符合以下任何规则:",
+	"relationMsgFront": "符合",
+	"relationMsgTail": "",
+	"and": "和",
+	"or": "或",
+	
+	"addRuleButton": "添加规则",
+	"waiAddRuleButton": "添加新规则",
+	"removeRuleButton": "除去规则",
+	"waiRemoveRuleButtonTemplate": "除去规则 ${0}",
+	
+	"cancelButton": "取消",
+	"waiCancelButton": "取消该对话",
+	"clearButton": "清除",
+	"waiClearButton": "清除过滤器",
+	"filterButton": "过滤器",
+	"waiFilterButton": "提交过滤器",
+	
+	"columnSelectLabel": "列",
+	"waiColumnSelectTemplate": "规则 ${0} 的列",
+	"conditionSelectLabel": "条件",
+	"waiConditionSelectTemplate": "规则 ${0} 的条件",
+	"valueBoxLabel": "值",
+	"waiValueBoxTemplate": "将规则 ${0} 的值输入过滤器",
+	
+	"rangeTo": "到",
+	"rangeTemplate": "从 ${0} 到 ${1}",
+	
+	"statusTipHeaderColumn": "列",
+	"statusTipHeaderCondition": "规则",
+	"statusTipTitle": "过滤器栏",
+	"statusTipMsg": "单击此处的过滤器栏以过滤 ${0} 中的值。",
+	"anycolumn": "任何列",
+	"statusTipTitleNoFilter": "过滤器栏",
+	"statusTipTitleHasFilter": "过滤器",
+	"statusTipRelPre": "符合",
+	"statusTipRelPost": "规则。",
+	
+	"defaultItemsName": "项目",
+	"filterBarMsgHasFilterTemplate": "显示的 ${1} ${2} 的 ${0}。",
+	"filterBarMsgNoFilterTemplate": "未使用过滤器",
+	
+	"filterBarDefButton": "定义过滤器",
+	"waiFilterBarDefButton": "过滤表",
+	"a11yFilterBarDefButton": "过滤器...",
+	"filterBarClearButton": "清除过滤器",
+	"waiFilterBarClearButton": "清除过滤器",
+	"closeFilterBarBtn": "关闭过滤器栏",
+	
+	"clearFilterMsg": "该操作将除去过滤器并显示所有现有记录。",
+	"anyColumnOption": "任何列",
+	
+	"trueLabel": "True",
+	"falseLabel": "False"
+})
+
+
+
diff --git a/dojox/grid/enhanced/nls/zh/Pagination.js b/dojox/grid/enhanced/nls/zh/Pagination.js
new file mode 100644
index 0000000..d8cdd27
--- /dev/null
+++ b/dojox/grid/enhanced/nls/zh/Pagination.js
@@ -0,0 +1,18 @@
+({
+	"descTemplate": "${2} - ${1} ${0} 的 ${3}",
+	"firstTip": "第一页",
+	"lastTip": "最后一页",
+	"nextTip": "下一页",
+	"prevTip": "上一页",
+	"itemTitle": "项目",
+	"pageStepLabelTemplate": "第 ${0} 页",
+	"pageSizeLabelTemplate": "每页的 ${0} 项目",
+	"allItemsLabelTemplate": "所有项目",
+	"gotoButtonTitle": "转到指定页面",
+	"dialogTitle": "转到页面",
+	"dialogIndication": "指定页数",
+	"pageCountIndication": " (${0} 页)",
+	"dialogConfirm": "确定",
+	"dialogCancel": "取消"
+})
+
diff --git a/dojox/grid/enhanced/plugins/AutoScroll.js b/dojox/grid/enhanced/plugins/AutoScroll.js
new file mode 100644
index 0000000..12ecb04
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/AutoScroll.js
@@ -0,0 +1,171 @@
+dojo.provide("dojox.grid.enhanced.plugins.AutoScroll");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid.enhanced.plugins.AutoScroll", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Provides horizontal and vertical auto-scroll for grid.
+	
+	// name: String
+	//		Plugin name
+	name: "autoScroll",
+	
+	// autoScrollInterval: Integer
+	//		The time interval (in miliseconds) between 2 scrolling.
+	autoScrollInterval: 1000,
+	
+	// autoScrollMargin: Integer
+	//		The width (in pixel) of the margin area where autoscroll can be triggered.
+	autoScrollMargin: 30,
+	
+	constructor: function(grid, args){
+		this.grid = grid;
+		this.readyForAutoScroll = false;
+		this._scrolling = false;
+		args = dojo.isObject(args) ? args : {};
+		if("interval" in args){
+			this.autoScrollInterval = args.interval;
+		}
+		if("margin" in args){
+			this.autoScrollMargin = args.margin;
+		}
+		this._initEvents();
+		this._mixinGrid();
+	},
+	_initEvents: function(){
+		var g = this.grid;
+		this.connect(g, "onCellMouseDown", function(){
+			this.readyForAutoScroll = true;
+		});
+		this.connect(g, "onHeaderCellMouseDown", function(){
+			this.readyForAutoScroll = true;
+		});
+		this.connect(g, "onRowSelectorMouseDown", function(){
+			this.readyForAutoScroll = true;
+		});
+		this.connect(dojo.doc, "onmouseup", function(evt){
+			this._manageAutoScroll(true);
+			this.readyForAutoScroll = false;
+		});
+		this.connect(dojo.doc, "onmousemove", function(evt){
+			if(this.readyForAutoScroll){
+				this._event = evt;
+				var gridPos = dojo.position(g.domNode),
+					hh = g._getHeaderHeight(),
+					margin = this.autoScrollMargin,
+					ey = evt.clientY, ex = evt.clientX,
+					gy = gridPos.y, gx = gridPos.x,
+					gh = gridPos.h, gw = gridPos.w;
+				if(ex >= gx && ex <= gx + gw){
+					if(ey >= gy + hh && ey < gy + hh + margin){
+						this._manageAutoScroll(false, true, false);
+						return;
+					}else if(ey > gy + gh - margin && ey <= gy + gh){
+						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){
+								return false;
+							}
+							var viewPos = dojo.position(view.domNode);
+							if(ex < viewPos.x + margin && ex >= viewPos.x){
+								this._manageAutoScroll(false, false, false, view);
+								return true;
+							}else if(ex > viewPos.x + viewPos.w - margin && ex < viewPos.x + viewPos.w){
+								this._manageAutoScroll(false, false, true, view);
+								return true;
+							}
+							return false;
+						}, this);
+						if(withinSomeview){
+							return;
+						}
+					}
+				}
+				//stop autoscroll.
+				this._manageAutoScroll(true);
+			}
+		});
+	},
+	_mixinGrid: function(){
+		var g = this.grid;
+		g.onStartAutoScroll = function(/*isVertical, isForward*/){};
+		g.onEndAutoScroll = function(/*isVertical, isForward, view, scrollToRowIndex, event*/){};
+	},
+	_fireEvent: function(eventName, args){
+		var g = this.grid;
+		switch(eventName){
+			case "start":
+				g.onStartAutoScroll.apply(g, args);
+				break;
+			case "end":
+				g.onEndAutoScroll.apply(g, args);
+				break;
+		}
+	},
+	_manageAutoScroll: function(toStop, isVertical, isForward, view){
+		if(toStop){
+			this._scrolling = false;
+			clearInterval(this._handler);
+		}else if(!this._scrolling){
+			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);
+		}
+	},
+	_autoScroll: function(isVertical, isForward, view){
+		var g = this.grid,
+			target = null;
+		if(isVertical){
+			var targetRow = g.scroller.firstVisibleRow + (isForward ? 1 : -1);
+			if(targetRow >= 0 && targetRow < g.rowCount){
+				g.scrollToRow(targetRow);
+				target = targetRow;
+			}
+		}else{
+			target = this._scrollColumn(isForward, view);
+		}
+		if(target !== null){
+			this._fireEvent("end", [isVertical, isForward, view, target, this._event]);
+		}
+	},
+	_scrollColumn: function(isForward, view){
+		var node = view.scrollboxNode,
+			target = null;
+		if(node.clientWidth < node.scrollWidth){
+			var cells = dojo.filter(this.grid.layout.cells, function(cell){
+				return !cell.hidden;
+			});
+			var viewPos = dojo.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());
+					edge = headerPos.x - viewPos.x + headerPos.w;
+					if(edge > limit){
+						target = cells[i].index;
+						node.scrollLeft += edge - limit + 10;
+						break;
+					}
+				}
+			}else{
+				limit = 0;
+				for(i = cells.length - 1; i >= 0; --i){
+					headerPos = dojo.position(cells[i].getHeaderNode());
+					edge = headerPos.x - viewPos.x;
+					if(edge < limit){
+						target = cells[i].index;
+						node.scrollLeft += edge - limit - 10;
+						break;
+					}
+				}
+			}
+		}
+		return target;
+	}
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.AutoScroll/*name:'autoScroll'*/);
diff --git a/dojox/grid/enhanced/plugins/CellMerge.js b/dojox/grid/enhanced/plugins/CellMerge.js
new file mode 100644
index 0000000..cc2accb
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/CellMerge.js
@@ -0,0 +1,266 @@
+dojo.provide("dojox.grid.enhanced.plugins.CellMerge");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.CellMerge", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		This plugin provides functions to merge(un-merge) adjacent cells within one row.
+	//		Acceptable plugin paramters:
+	//		1. mergedCells: Array
+	//			An array of objects with structure:
+	//			{
+	//				row: function(Integer)|Integer
+	//					If it's a function, it's a predicate to decide which rows are to be merged.
+	//					It takes an integer (the row index), and should return true or false;
+	//				start: Integer
+	//					The column index of the left most cell that shall be merged.
+	//				end: Integer
+	//					The column index of the right most cell that shall be merged.
+	//				major: Integer
+	//					The column index of the cell whose content should be used as the content of the merged cell.
+	//					It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+	//					If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+	//			}
+	
+	// name: String
+	//		Plugin name
+	name: "cellMerge",
+	
+	constructor: function(grid, args){
+		this.grid = grid;
+		this._records = [];
+		this._merged = {};
+		if(args && dojo.isObject(args)){
+			this._setupConfig(args.mergedCells);
+		}
+		this._initEvents();
+		this._mixinGrid();
+	},
+	//----------------Public----------------------------
+	mergeCells: function(rowTester, startColumnIndex, endColumnIndex, majorColumnIndex){
+		// summary:
+		//		Merge cells from *startColumnIndex* to *endColumnIndex* at rows that make *rowTester* return true,
+		//		using the content of the cell at *majorColumnIndex*
+		// tags:
+		//		public
+		// rowTester: function(Integer)|Integer
+		//		If it's a function, it's a predicate to decide which rows are to be merged.
+		//		It takes an integer (the row index), and should return true or false;
+		// startColumnIndex: Integer
+		//		The column index of the left most cell that shall be merged.
+		// endColumnIndex: Integer
+		//		The column index of the right most cell that shall be merged.
+		// majorColumnIndex: Integer?
+		//		The column index of the cell whose content should be used as the content of the merged cell.
+		//		It must be larger than or equal to the startColumnIndex, and less than or equal to the endColumnIndex.
+		//		If it is omitted, the content of the leading edge (left-most for ltr, right most for rtl) cell will be used.
+		// return: Object | null
+		//		A handler for the merged cells created by a call of this function.
+		//		This handler can be used later to unmerge cells using the function unmergeCells
+		//		If the merge is not valid, returns null;
+		var item = this._createRecord({
+			"row": rowTester,
+			"start": startColumnIndex,
+			"end": endColumnIndex,
+			"major": majorColumnIndex
+		});
+		if(item){
+			this._updateRows(item);
+		}
+		return item;
+	},
+	unmergeCells: function(mergeHandler){
+		// summary:
+		//		Unmerge the cells that are merged by the *mergeHandler*, which represents a call to the function mergeCells.
+		// tags:
+		//		public
+		// 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){
+			this._records.splice(idx, 1);
+			this._updateRows(mergeHandler);
+		}
+	},
+	getMergedCells: function(){
+		// summary:
+		//		Get all records of currently merged cells.
+		// tags:
+		//		public
+		// return: Array
+		//		An array of records for merged-cells.
+		//		The record has the following structure:
+		//		{
+		//			"row": 1, //the row index
+		//			"start": 2, //the start column index
+		//			"end": 4, //the end column index
+		//			"major": 3, //the major column index
+		//			"handle": someHandle, //The handler that covers this merge cell record.
+		//		}
+		var res = [];
+		for(var i in this._merged){
+			res = res.concat(this._merged[i]);
+		}
+		return res;
+	},
+	getMergedCellsByRow: function(rowIndex){
+		// summary:
+		//		Get the records of currently merged cells at the given row.
+		// tags:
+		//		public
+		// return: Array
+		//		An array of records for merged-cells. See docs of getMergedCells.
+		return this._merged[rowIndex] || [];
+	},
+	
+	//----------------Private--------------------------
+	_setupConfig: function(config){
+		dojo.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));
+		}, 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");
+	},
+	_getWidth: function(colIndex){
+		var node = this.grid.layout.cells[colIndex].getHeaderNode();
+		return dojo.position(node).w;
+	},
+	_onAfterRow: function(viewIdx, rowIndex, subrows){
+		try{
+			if(rowIndex < 0){
+				return;
+			}
+			var result = [], i, j, len = this._records.length,
+				cells = this.grid.layout.cells;
+			//Apply merge-cell requests one by one.
+			for(i = 0; i < len; ++i){
+				var item = this._records[i];
+				var storeItem = this.grid._by_idx[rowIndex];
+				if(item.view == viewIdx && item.row(rowIndex, storeItem && storeItem.item, this.grid.store)){
+					var res = {
+						record: item,
+						hiddenCells: [],
+						totalWidth: 0,
+						majorNode: cells[item.major].getNode(rowIndex),
+						majorHeaderNode: cells[item.major].getHeaderNode()
+					};
+					//Calculated the width of merged cell.
+					for(j = item.start; j <= item.end; ++j){
+						var w = this._getWidth(j, rowIndex);
+						res.totalWidth += w;
+						if(j != item.major){
+							res.hiddenCells.push(cells[j].getNode(rowIndex));
+						}
+					}
+					//If width is valid, remember it. There may be multiple merges within one row.
+					if(subrows.length != 1 || res.totalWidth > 0){
+						//Remove conflicted merges.
+						for(j = result.length - 1; j >= 0; --j){
+							var r = result[j].record;
+							if((r.start >= item.start && r.start <= item.end) ||
+								(r.end >= item.start && r.end <= item.end)){
+								result.splice(j, 1);
+							}
+						}
+						result.push(res);
+					}
+				}
+			}
+			this._merged[rowIndex] = [];
+			dojo.forEach(result, function(res){
+				dojo.forEach(res.hiddenCells, function(node){
+					dojo.style(node, "display", "none");
+				});
+				var pbm = dojo.marginBox(res.majorHeaderNode).w - dojo.contentBox(res.majorHeaderNode).w;
+				var tw = res.totalWidth;
+				
+				//Tricky for WebKit.
+				if(!dojo.isWebKit){
+					tw -= pbm;
+				}
+				
+				dojo.style(res.majorNode, "width", tw + "px");
+				//In case we're dealing with multiple subrows.
+				dojo.attr(res.majorNode, "colspan", res.hiddenCells.length + 1);
+	
+				this._merged[rowIndex].push({
+					"row": rowIndex,
+					"start": res.record.start,
+					"end": res.record.end,
+					"major": res.record.major,
+					"handle": res.record
+				});
+			}, this);
+		}catch(e){
+			console.warn("CellMerge._onAfterRow() error: ", rowIndex, e);
+		}
+	},
+	_createRecord: function(item){
+		if(this._isValid(item)){
+			item = {
+				"row": item.row,
+				"start": item.start,
+				"end": item.end,
+				"major": item.major
+			};
+			var cells = this.grid.layout.cells;
+			item.view = cells[item.start].view.index;
+			item.major = typeof item.major == "number" && !isNaN(item.major) ? item.major : item.start;
+			if(typeof item.row == "number"){
+				var r = item.row;
+				item.row = function(rowIndex){
+					return rowIndex === r;
+				};
+			}else if(typeof item.row == "string"){
+				var id = item.row;
+				item.row = function(rowIndex, storeItem, store){
+					try{
+						if(store && storeItem && store.getFeatures()['dojo.data.api.Identity']){
+							return store.getIdentity(storeItem) == id;
+						}
+					}catch(e){
+						console.error(e);
+					}
+					return false;
+				};
+			}
+			if(dojo.isFunction(item.row)){
+				this._records.push(item);
+				return item;
+			}
+		}
+		return null;
+	},
+	_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) &&
+			item.start >= 0 && item.start < colCount &&
+			item.end > item.start && item.end < colCount &&
+			cells[item.start].view.index == cells[item.end].view.index &&
+			cells[item.start].subrow == cells[item.end].subrow &&
+			!(typeof item.major == "number" && (item.major < item.start || item.major > item.end)));
+	},
+	_updateRows: function(item){
+		var min = null;
+		for(var i = 0, count = this.grid.rowCount; i < count; ++i){
+			var storeItem = this.grid._by_idx[i];
+			if(storeItem && item.row(i, storeItem && storeItem.item, this.grid.store)){
+				this.grid.views.updateRow(i);
+				if(min === null){ min = i; }
+			}
+		}
+		if(min >= 0){
+			this.grid.scroller.rowHeightChanged(min);
+		}
+	}
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.CellMerge/*name:'cellMerge'*/);
diff --git a/dojox/grid/enhanced/plugins/Cookie.js b/dojox/grid/enhanced/plugins/Cookie.js
new file mode 100644
index 0000000..a5c0302
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Cookie.js
@@ -0,0 +1,345 @@
+dojo.provide("dojox.grid.enhanced.plugins.Cookie");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojo.cookie");
+dojo.require("dojox.grid._RowSelector");
+dojo.require("dojox.grid.cells._base");
+
+(function(){
+	// Generate a cookie key for the given grid.
+	var _cookieKeyBuilder = function(grid){
+		return window.location + "/" + grid.id;
+	};
+	
+	//Utilities:
+	var _getCellsFromStructure = function(structure){
+		var cells = [];
+		if(!dojo.isArray(structure)){
+			structure = [structure];
+		}
+		dojo.forEach(structure,function(viewDef){
+			if(dojo.isArray(viewDef)){
+				viewDef = {"cells" : viewDef};
+			}
+			var rows = viewDef.rows || viewDef.cells;
+			if(dojo.isArray(rows)){
+				if(!dojo.isArray(rows[0])){
+					rows = [rows];
+				}
+				dojo.forEach(rows, function(row){
+					if(dojo.isArray(row)){
+						dojo.forEach(row, function(cell){
+							cells.push(cell);
+						});
+					}
+				});
+			}
+		});
+		return cells;
+	};
+	
+	// Persist column width
+	var _loadColWidth = function(colWidths, grid){
+		if(dojo.isArray(colWidths)){
+			var oldFunc = grid._setStructureAttr;
+			grid._setStructureAttr = function(structure){
+				if(!grid._colWidthLoaded){
+					grid._colWidthLoaded = true;
+					var cells = _getCellsFromStructure(structure);
+					for(var i = cells.length - 1; i >= 0; --i){
+						if(typeof colWidths[i] == "number"){
+							cells[i].width = colWidths[i] + "px";
+						}
+					}
+				}
+				oldFunc.call(grid, structure);
+				grid._setStructureAttr = oldFunc;
+			};
+		}
+	};
+	
+	var _saveColWidth = function(grid){
+		return dojo.map(dojo.filter(grid.layout.cells, function(cell){
+			return !(cell.isRowSelector || cell instanceof dojox.grid.cells.RowIndex);
+		}), function(cell){
+			return dojo[dojo.isWebKit ? "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;
+			});
+		})){
+			var oldFunc = grid._setStructureAttr;
+			var isCell = function(def){
+				return ("name" in def || "field" in def || "get" in def);
+			};
+			var isView = function(def){
+				return (def !== null && dojo.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 = [{ cells: structure }];
+					}else if(isView(structure)){
+						structure = [structure];
+					}
+					var cells = _getCellsFromStructure(structure);
+					dojo.forEach(dojo.isArray(structure) ? structure : [structure], function(viewDef, viewIdx){
+						var cellArray = viewDef;
+						if(dojo.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){
+								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)){
+										break;
+									}
+								}
+								if(i < cells.length){
+									cellArray.push(cell);
+								}
+							});
+						});
+					});
+				}
+				oldFunc.call(grid, structure);
+			};
+		}
+	};
+	
+	var _saveColumnOrder = function(grid){
+		var colOrder = dojo.map(dojo.filter(grid.views.views, function(view){
+			return !(view instanceof dojox.grid._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);
+				}), function(cell){
+					return {
+						"name": cell.name,
+						"field": cell.field
+					};
+				});
+			});
+		});
+		return colOrder;
+	};
+	
+	// Persist sorting order
+	var _loadSortOrder = function(sortOrder, grid){
+		try{
+			if(dojo.isObject(sortOrder)){
+				grid.setSortIndex(sortOrder.idx, sortOrder.asc);
+			}
+		}catch(e){
+			//setSortIndex will finally call _fetch, some exceptions will be throw
+			//'cause the grid hasn't be fully loaded now. Just ignore them.
+		}
+	};
+	
+	var _saveSortOrder = function(grid){
+		return {
+			idx: grid.getSortIndex(),
+			asc: grid.getSortAsc()
+		};
+	};
+	
+	if(!dojo.isIE){
+		// 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){
+					widget.destroyRecursive();
+				}
+			});
+		});
+	}
+	
+	dojo.declare("dojox.grid.enhanced.plugins.Cookie", dojox.grid.enhanced._Plugin, {
+		// summary:
+		//		This plugin provides a way to persist some grid features in cookie.
+		//		Default persistable features are:
+		//		column width:	"columnWidth" (handler name)
+		//		column order:	"columnOrder"
+		//		sorting order:	"sortOrder"
+		//
+		//		Grid users can define new persistable features
+		//		by calling the following before grid is initialized (that is, during "preInit");
+		//		|	grid.addCookieHandler({
+		//		|		name: "a name for the new persistable feature",
+		//		|		onLoad: function(savedObject, grid){
+		//		|			//load the cookie.
+		//		|		},
+		//		|		onSave: function(grid){
+		//		|			//save the cookie.
+		//		|		}
+		//		|	});
+		
+		// name: String
+		//		Plugin name
+		name: "cookie",
+		
+		_cookieEnabled: true,
+		
+		constructor: function(grid, args){
+			this.grid = grid;
+			args = (args && dojo.isObject(args)) ? args : {};
+			this.cookieProps = args.cookieProps;
+			this._cookieHandlers = [];
+			this._mixinGrid();
+			
+			//Column width & simple sorting & column reorder are base grid features, so they must be supported.
+			this.addCookieHandler({
+				name: "columnWidth",
+				onLoad: _loadColWidth,
+				onSave: _saveColWidth
+			});
+			this.addCookieHandler({
+				name: "columnOrder",
+				onLoad: _loadColumnOrder,
+				onSave: _saveColumnOrder
+			});
+			this.addCookieHandler({
+				name: "sortOrder",
+				onLoad: _loadSortOrder,
+				onSave: _saveSortOrder
+			});
+			
+			dojo.forEach(this._cookieHandlers, function(handler){
+				if(args[handler.name] === false){
+					handler.enable = false;
+				}
+			}, this);
+		},
+		destroy:function(){
+			this._saveCookie();
+			this._cookieHandlers = null;
+			this.inherited(arguments);
+		},
+		_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");
+		},
+		_saveCookie: function(){
+			if(this.getCookieEnabled()){
+				var cookie = {},
+					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);
+					}
+				}
+				cookieProps = dojo.isObject(this.cookieProps) ? this.cookieProps : {};
+				dojo.cookie(cookieKey, dojo.toJson(cookie), cookieProps);
+			}else{
+				this.removeCookie();
+			}
+		},
+		onPreInit: function(){
+			var grid = this.grid,
+				chs = this._cookieHandlers,
+				cookieKey = _cookieKeyBuilder(grid),
+				cookie = dojo.cookie(cookieKey);
+			if(cookie){
+				cookie = dojo.fromJson(cookie);
+				for(var i = 0; i < chs.length; ++i){
+					if(chs[i].name in cookie && chs[i].enabled){
+						//Do the real loading work here.
+						chs[i].onLoad(cookie[chs[i].name], grid);
+					}
+				}
+			}
+			this._cookie = cookie || {};
+			this._cookieStartedup = true;
+		},
+		addCookieHandler: function(args){
+			// summary:
+			//		If a grid plugin wants cookie service, call this.
+			//		This must be called during preInit.
+			// args: Object
+			//		An object with the following structure:
+			//	|	{
+			//	|		name: "some-string",
+			//	|		onLoad: /* void */ function(/* object */partOfCookie, /* EDG */grid){...},
+			//	|		onSave: /* object */ function(/* EDG */grid){...}
+			//	|	}
+			if(args.name){
+				var dummy = function(){};
+				args.onLoad = args.onLoad || dummy;
+				args.onSave = args.onSave || dummy;
+				if(!("enabled" in args)){
+					args.enabled = true;
+				}
+				for(var i = this._cookieHandlers.length - 1; i >= 0; --i){
+					if(this._cookieHandlers[i].name == args.name){
+						this._cookieHandlers.splice(i, 1);
+					}
+				}
+				this._cookieHandlers.push(args);
+				if(this._cookieStartedup && args.name in this._cookie){
+					args.onLoad(this._cookie[args.name], this.grid);
+				}
+			}
+		},
+		removeCookie: function(){
+			// summary:
+			//		Remove cookie for this grid.
+			var key = _cookieKeyBuilder(this.grid);
+			dojo.cookie(key, null, {expires: -1});
+		},
+		setCookieEnabled: function(cookieName, enabled){
+			// summary:
+			//		A setter to enable|disable cookie support for a particular Grid feature.
+			// cookieName: String?
+			//		Name of a cookie handler if provided, otherwise for all cookies.
+			// enabled: Boolean
+			if(arguments.length == 2){
+				var chs = this._cookieHandlers;
+				for(var i = chs.length - 1; i >= 0; --i){
+					if(chs[i].name === cookieName){
+						chs[i].enabled = !!enabled;
+					}
+				}
+			}else{
+				this._cookieEnabled = !!cookieName;
+				if(!this._cookieEnabled){ this.removeCookie(); }
+			}
+		},
+		getCookieEnabled: function(cookieName){
+			// summary:
+			//		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)){
+				var chs = this._cookieHandlers;
+				for(var i = chs.length - 1; i >= 0; --i){
+					if(chs[i].name == cookieName){ return chs[i].enabled; }
+				}
+				return false;
+			}
+			return this._cookieEnabled;
+		}
+	});
+	dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Cookie/*name:'cookie'*/, {"preInit": true});
+})();
diff --git a/dojox/grid/enhanced/plugins/Dialog.js b/dojox/grid/enhanced/plugins/Dialog.js
new file mode 100644
index 0000000..d7e4053
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Dialog.js
@@ -0,0 +1,34 @@
+dojo.provide("dojox.grid.enhanced.plugins.Dialog");
+
+dojo.require("dijit.Dialog");
+dojo.require("dojo.window");
+
+dojo.declare("dojox.grid.enhanced.plugins.Dialog", dijit.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;
+			}
+		}
+		this.inherited(arguments);
+	}
+});
diff --git a/dojox/grid/enhanced/plugins/DnD.js b/dojox/grid/enhanced/plugins/DnD.js
index 12b37c6..65d6150 100644
--- a/dojox/grid/enhanced/plugins/DnD.js
+++ b/dojox/grid/enhanced/plugins/DnD.js
@@ -1,10 +1,1074 @@
 dojo.provide("dojox.grid.enhanced.plugins.DnD");
 
-dojo.require("dojox.grid.enhanced.dnd._DndMovingManager");
+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");
 
-dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced.dnd._DndMovingManager, {
-	//	summary:
-	//		 Provides dnd support for row(s) and column(s)
-	// example:
-	// 		 <div dojoType="dojox.grid.EnhancedGrid" plugins="{dnd: true}" ...></div>
+(function(){
+var _devideToArrays = function(a){
+		a.sort(function(v1, v2){
+			return v1 - v2;
+		});
+		var arr = [[a[0]]];
+		for(var i = 1, j = 0; i < a.length; ++i){
+			if(a[i] == a[i-1] + 1){
+				arr[j].push(a[i]);
+			}else{
+				arr[++j] = [a[i]];
+			}
+		}
+		return arr;
+	},
+	_joinToArray = function(arrays){
+		var a = arrays[0];
+		for(var i = 1; i < arrays.length; ++i){
+			a = a.concat(arrays[i]);
+		}
+		return a;
+	};
+dojo.declare("dojox.grid.enhanced.plugins.DnD", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Provide drag and drop for grid columns/rows/cells within grid and out of grid.
+	//		The store of grid must implement dojo.data.api.Write.
+	//		DnD selected columns:
+	//			Support moving within grid, moving/copying out of grid to a non-grid DnD target.
+	//		DnD selected rows:
+	//			Support moving within grid, moving/copying out of grid to any DnD target.
+	//		DnD selected cells (in rectangle shape only):
+	//			Support moving/copying within grid, moving/copying out of grid to any DnD target.
+	//
+	
+	// name: String,
+	//		plugin name;
+	name: "dnd",
+	
+	_targetAnchorBorderWidth: 2,
+	_copyOnly: false,
+	_config: {
+		"row":{
+			"within":true,
+			"in":true,
+			"out":true
+		},
+		"col":{
+			"within":true,
+			"in":true,
+			"out":true
+		},
+		"cell":{
+			"within":true,
+			"in":true,
+			"out":true
+		}
+	},
+	constructor: function(grid, args){
+		this.grid = grid;
+		this._config = dojo.clone(this._config);
+		args = dojo.isObject(args) ? args : {};
+		this.setupConfig(args.dndConfig);
+		this._copyOnly = !!args.copyOnly;
+		
+		//Get the plugins we are dependent on.
+		this._mixinGrid();
+		this.selector = grid.pluginMgr.getPlugin("selector");
+		this.rearranger = grid.pluginMgr.getPlugin("rearrange");
+		//TODO: waiting for a better plugin framework to pass args to dependent plugins.
+		this.rearranger.setArgs(args);
+		
+		//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, {
+			"grid": grid,
+			"dndElem": this._elem,
+			"dnd": this
+		});
+		this._container = dojo.query(".dojoxGridMasterView", this.grid.domNode)[0];
+		this._initEvents();
+	},
+	destroy: function(){
+		this.inherited(arguments);
+		this._clear();
+		this._source.destroy();
+		this._elem.destroy();
+		this._container = null;
+		this.grid = null;
+		this.selector = null;
+		this.rearranger = null;
+		this._config = null;
+	},
+	_mixinGrid: function(){
+		// summary:
+		//		Provide APIs for grid.
+		this.grid.setupDnDConfig = dojo.hitch(this, "setupConfig");
+		this.grid.dndCopyOnly = dojo.hitch(this, "copyOnly");
+	},
+	setupConfig: function(config){
+		// summary:
+		//		Configure which DnD functionalities are needed.
+		//		Combination of any item from type set ("row", "col", "cell")
+		//		and any item from mode set("within", "in", "out") is configurable.
+		//
+		//		"row", "col", "cell" are straitforward, while the other 3 are explained below:
+		//		"within": DnD within grid, that is, column/row reordering and cell moving/copying.
+		//		"in": Whether allowed to accept rows/cells (currently not support columns) from another grid.
+		//		"out": Whether allowed to drag out of grid, to another grid or even to any other DnD target.
+		//
+		//		If not provided in the config, will use the default.
+		//		When declared together, Mode set has higher priority than type set.
+		// config: Object
+		//		DnD configuration object.
+		//		See the examples below.
+		// example:
+		//		The following code disables row DnD within grid,
+		//		but still can drag rows out of grid or drag rows from other gird.
+		//	|	setUpConfig({
+		//	|		"row": {
+		//	|			"within": false
+		//	|		}
+		//	|	});
+		//
+		//		The opposite way is also okay:
+		//	|	setUpConfig({
+		//	|		"within": {
+		//	|			"row": false
+		//	|		}
+		//	|	});
+		//
+		//		And if you'd like to disable/enable a whole set, here's a shortcut:
+		//	|	setUpConfig({
+		//	|		"cell", true,
+		//	|		"out": false
+		//	|	});
+		//
+		//		Because mode has higher priority than type, the following will disable row dnd within grid:
+		//	|	setUpConfig({
+		//	|		"within", {
+		//	|			"row": false;
+		//	|		},
+		//	|		"row", {
+		//	|			"within": true
+		//	|		}
+		//	|	});
+		if(config && dojo.isObject(config)){
+			var firstLevel = ["row", "col", "cell"],
+				secondLevel = ["within", "in", "out"],
+				cfg = this._config;
+			dojo.forEach(firstLevel, function(type){
+				if(type in config){
+					var t = config[type];
+					if(t && dojo.isObject(t)){
+						dojo.forEach(secondLevel, function(mode){
+							if(mode in t){
+								cfg[type][mode] = !!t[mode];
+							}
+						});
+					}else{
+						dojo.forEach(secondLevel, function(mode){
+							cfg[type][mode] = !!t;
+						});
+					}
+				}
+			});
+			dojo.forEach(secondLevel, function(mode){
+				if(mode in config){
+					var m = config[mode];
+					if(m && dojo.isObject(m)){
+						dojo.forEach(firstLevel, function(type){
+							if(type in m){
+								cfg[type][mode] = !!m[type];
+							}
+						});
+					}else{
+						dojo.forEach(firstLevel, function(type){
+							cfg[type][mode] = !!m;
+						});
+					}
+				}
+			});
+		}
+	},
+	copyOnly: function(isCopyOnly){
+		// summary:
+		//		Setter/getter of this._copyOnly.
+		if(typeof isCopyOnly != "undefined"){
+			this._copyOnly = !!isCopyOnly;
+		}
+		return this._copyOnly;
+	},
+	_isOutOfGrid: function(evt){
+		var gridPos = dojo.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;
+	},
+	_onMouseMove: function(evt){
+		if(this._dndRegion && !this._dnding && !this._externalDnd){
+			this._dnding = true;
+			this._startDnd(evt);
+		}else{
+			if(this._isMouseDown && !this._dndRegion){
+				delete this._isMouseDown;
+				this._oldCursor = dojo.style(dojo.body(), "cursor");
+				dojo.style(dojo.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.
+			var isOut = this._isOutOfGrid(evt);
+			if(!this._alreadyOut && isOut){
+				this._alreadyOut = true;
+				if(this._dnding){
+					this._destroyDnDUI(true, false);
+				}
+				this._moveEvent = evt;
+				this._source.onOutEvent();
+			}else if(this._alreadyOut && !isOut){
+				this._alreadyOut = false;
+				if(this._dnding){
+					this._createDnDUI(evt, true);
+				}
+				this._moveEvent = evt;
+				this._source.onOverEvent();
+			}
+		}
+	},
+	_onMouseUp: function(){
+		if(!this._extDnding && !this._isSource){
+			var isInner = this._dnding && !this._alreadyOut;
+			if(isInner && this._config[this._dndRegion.type]["within"]){
+				this._rearrange();
+			}
+			this._endDnd(isInner);
+		}
+		dojo.style(dojo.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(g, "onCellMouseOver", function(evt){
+			if(!this._dnding && !s.isSelecting() && !evt.ctrlKey){
+				this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+				s.selectEnabled(!this._dndReady);
+			}
+		});
+		this.connect(g, "onHeaderCellMouseOver", function(evt){
+			if(this._dndReady){
+				s.selectEnabled(true);
+			}
+		});
+		this.connect(g, "onRowMouseOver", function(evt){
+			if(this._dndReady && !evt.cell){
+				s.selectEnabled(true);
+			}
+		});
+		this.connect(g, "onCellMouseDown", function(evt){
+			if(!evt.ctrlKey && this._dndReady){
+				this._dndRegion = this._getDnDRegion(evt.rowIndex, evt.cell.index);
+				this._isMouseDown = true;
+			}
+		});
+		this.connect(g, "onCellMouseUp", function(evt){
+			if(!this._dndReady && !s.isSelecting() && evt.cell){
+				this._dndReady = s.isSelected("cell", evt.rowIndex, evt.cell.index);
+				s.selectEnabled(!this._dndReady);
+			}
+		});
+		this.connect(g, "onCellClick", function(evt){
+			if(this._dndReady && !evt.ctrlKey && !evt.shiftKey){
+				s.select("cell", evt.rowIndex, evt.cell.index);
+			}
+		});
+		this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target, evt){
+			if(this._dnding){
+				this._markTargetAnchor(evt);
+			}
+		});
+		this.connect(dojo.doc, "onkeydown", function(evt){
+			if(evt.keyCode == dojo.keys.ESCAPE){
+				this._endDnd(false);
+			}else if(evt.keyCode == dojo.keys.CTRL){
+				s.selectEnabled(true);
+				this._isCopy = true;
+			}
+		});
+		this.connect(dojo.doc, "onkeyup", function(evt){
+			if(evt.keyCode == dojo.keys.CTRL){
+				s.selectEnabled(!this._dndReady);
+				this._isCopy = false;
+			}
+		});
+	},
+	_clear: function(){
+		this._dndRegion = null;
+		this._target = null;
+		this._moveEvent = null;
+		this._targetAnchor = {};
+		this._dnding = false;
+		this._externalDnd = false;
+		this._isSource = false;
+		this._alreadyOut = false;
+		this._extDnding = false;
+	},
+	_getDnDRegion: function(rowIndex, colIndex){
+		var s = this.selector,
+			selected = s._selected,
+			flag = (!!selected.cell.length) | (!!selected.row.length << 1) | (!!selected.col.length << 2),
+			type;
+		switch(flag){
+			case 1:
+				type = "cell";
+				if(!this._config[type]["within"] && !this._config[type]["out"]){
+					return null;
+				}
+				var cells = this.grid.layout.cells,
+					getCount = function(range){
+						var hiddenColCnt = 0;
+						for(var i = range.min.col; i <= range.max.col; ++i){
+							if(cells[i].hidden){
+								++hiddenColCnt;
+							}
+						}
+						return (range.max.row - range.min.row + 1) * (range.max.col - range.min.col + 1 - hiddenColCnt);
+					},
+					inRange = function(item, range){
+						return item.row >= range.min.row && item.row <= range.max.row &&
+							item.col >= range.min.col && item.col <= range.max.col;
+					},
+					range = {
+						max: {
+							row: -1,
+							col: -1
+						},
+						min: {
+							row: Infinity,
+							col: Infinity
+						}
+					};
+				
+				dojo.forEach(selected[type], function(item){
+					if(item.row < range.min.row){
+						range.min.row = item.row;
+					}
+					if(item.row > range.max.row){
+						range.max.row = item.row;
+					}
+					if(item.col < range.min.col){
+						range.min.col = item.col;
+					}
+					if(item.col > range.max.col){
+						range.max.col = item.col;
+					}
+				});
+				if(dojo.some(selected[type], function(item){
+					return item.row == rowIndex && item.col == colIndex;
+				})){
+					if(getCount(range) == selected[type].length && dojo.every(selected[type], function(item){
+						return inRange(item, range);
+					})){
+						return {
+							"type": type,
+							"selected": [range],
+							"handle": {
+								"row": rowIndex,
+								"col": colIndex
+							}
+						};
+					}
+				}
+				return null;
+			case 2: case 4:
+				type = flag == 2 ? "row" : "col";
+				if(!this._config[type]["within"] && !this._config[type]["out"]){
+					return null;
+				}
+				var res = s.getSelected(type);
+				if(res.length){
+					return {
+						"type": type,
+						"selected": _devideToArrays(res),
+						"handle": flag == 2 ? rowIndex : colIndex
+					};
+				}
+				return null;
+		}
+		return null;
+	},
+	_startDnd: function(evt){
+		this._createDnDUI(evt);
+	},
+	_endDnd: function(destroySource){
+		this._destroyDnDUI(false, destroySource);
+		this._clear();
+	},
+	_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");
+		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");
+		}catch(e){
+			console.warn("DnD._createDnDUI() error:", e);
+		}
+	},
+	_destroyDnDUI: function(isMovingOut, destroySource){
+		try{
+			if(destroySource){
+				this._destroySource();
+			}
+			this._unmarkTargetAnchor();
+			if(!isMovingOut){
+				this._destroyMoveable();
+			}
+			dojo.style(dojo.body(), "cursor", this._oldCursor);
+		}catch(e){
+			console.warn("DnD._destroyDnDUI() error:", this.grid.id, e);
+		}
+	},
+	_createSource: function(evt){
+		this._elem.createDnDNodes(this._dndRegion);
+		var m = dojo.dnd.manager();
+		var oldMakeAvatar = m.makeAvatar;
+		m._dndPlugin = this;
+		m.makeAvatar = function(){
+			var avatar = new dojox.grid.enhanced.plugins.GridDnDAvatar(m);
+			delete m._dndPlugin;
+			return avatar;
+		};
+		m.startDrag(this._source, this._elem.getDnDNodes(), evt.ctrlKey);
+		m.makeAvatar = oldMakeAvatar;
+		m.onMouseMove(evt);
+	},
+	_destroySource: function(){
+		dojo.publish("/dnd/cancel");
+		this._elem.destroyDnDNodes();
+	},
+	_createMoveable: function(evt){
+		if(!this._markTagetAnchorHandler){
+			this._markTagetAnchorHandler = this.connect(dojo.doc, "onmousemove", "_markTargetAnchor");
+		}
+	},
+	_destroyMoveable: function(){
+		this.disconnect(this._markTagetAnchorHandler);
+		delete this._markTagetAnchorHandler;
+	},
+	_calcColTargetAnchorPos: function(evt, containerPos){
+		// summary:
+		//		Calculate the position of the column DnD avatar
+		var i, headPos, left, target, ex = evt.clientX,
+			cells = this.grid.layout.cells,
+			ltr = dojo._isBodyLtr(),
+			headers = this._getVisibleHeaders();
+		for(i = 0; i < headers.length; ++i){
+			headPos = dojo.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);
+				break;
+			}else if(ltr ? (i === headers.length - 1 && ex >= headPos.x + headPos.w) :
+				(i === headers.length - 1 && ex < headPos.x)){
+				++i;
+				left = headPos.x + (ltr ? headPos.w : 0);
+				break;
+			}
+		}
+		if(i < headers.length){
+			target = headers[i].cell.index;
+			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){
+						target = ranges[i][0];
+						headPos = dojo.position(cells[target].getHeaderNode());
+						left = headPos.x + (ltr ? 0 : headPos.w);
+						break;
+					}
+				}
+			}
+		}else{
+			target = cells.length;
+		}
+		this._target = target;
+		return left - containerPos.x;
+	},
+	_calcRowTargetAnchorPos: function(evt, containerPos){
+		// summary:
+		//		Calculate the position of the row DnD avatar
+		var g = this.grid, top, i = 0,
+			cells = g.layout.cells;
+		while(cells[i].hidden){ ++i; }
+		var cell = g.layout.cells[i],
+			rowIndex = g.scroller.firstVisibleRow,
+			nodePos = dojo.position(cell.getNode(rowIndex));
+		while(nodePos.y + nodePos.h < evt.clientY){
+			if(++rowIndex >= g.rowCount){
+				break;
+			}
+			nodePos = dojo.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){
+						rowIndex = ranges[i][0];
+						nodePos = dojo.position(cell.getNode(rowIndex));
+						break;
+					}
+				}
+			}
+			top = nodePos.y;
+		}else{
+			top = nodePos.y + nodePos.h;
+		}
+		this._target = rowIndex;
+		return top - containerPos.y;
+	},
+	_calcCellTargetAnchorPos: function(evt, containerPos, targetAnchor){
+		// summary:
+		//		Calculate the position of the cell DnD avatar
+		var s = this._dndRegion.selected[0],
+			origin = this._dndRegion.handle,
+			g = this.grid, ltr = dojo._isBodyLtr(),
+			cells = g.layout.cells, headPos,
+			minPos, maxPos, headers,
+			height, width, left, top,
+			minCol, maxCol, i,
+			preSpan = origin.col - s.min.col,
+			postSpan = s.max.col - origin.col,
+			leftTopDiv, rightBottomDiv;
+		if(!targetAnchor.childNodes.length){
+			leftTopDiv = dojo.create("div", {
+				"class": "dojoxGridCellBorderLeftTopDIV"
+			}, targetAnchor);
+			rightBottomDiv = dojo.create("div", {
+				"class": "dojoxGridCellBorderRightBottomDIV"
+			}, targetAnchor);
+		}else{
+			leftTopDiv = dojo.query(".dojoxGridCellBorderLeftTopDIV", targetAnchor)[0];
+			rightBottomDiv = dojo.query(".dojoxGridCellBorderRightBottomDIV", targetAnchor)[0];
+		}
+		for(i = s.min.col + 1; i < origin.col; ++i){
+			if(cells[i].hidden){
+				--preSpan;
+			}
+		}
+		for(i = origin.col + 1; i < s.max.col; ++i){
+			if(cells[i].hidden){
+				--postSpan;
+			}
+		}
+		headers = this._getVisibleHeaders();
+		//calc width
+		for(i = preSpan; i < headers.length - postSpan; ++i){
+			headPos = dojo.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)) ||
+				//post to this column, but within range
+				(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);
+					minCol = minCol.cell.index;
+					maxCol = maxCol.cell.index;
+					left = ltr ? minPos.x : maxPos.x;
+					width = ltr ? (maxPos.x + maxPos.w - minPos.x) : (minPos.x + minPos.w - maxPos.x);
+					break;
+			}
+		}
+		//calc height
+		i = 0;
+		while(cells[i].hidden){ ++i; }
+		var cell = cells[i],
+			rowIndex = g.scroller.firstVisibleRow,
+			nodePos = dojo.position(cell.getNode(rowIndex));
+		while(nodePos.y + nodePos.h < evt.clientY){
+			if(++rowIndex < g.rowCount){
+				nodePos = dojo.position(cell.getNode(rowIndex));
+			}else{
+				break;
+			}
+		}
+		var minRow = rowIndex >= origin.row - s.min.row ? rowIndex - origin.row + s.min.row : 0;
+		var maxRow = minRow + s.max.row - s.min.row;
+		if(maxRow >= g.rowCount){
+			maxRow = g.rowCount - 1;
+			minRow = maxRow - s.max.row + s.min.row;
+		}
+		minPos = dojo.position(cell.getNode(minRow));
+		maxPos = dojo.position(cell.getNode(maxRow));
+		top = minPos.y;
+		height = maxPos.y + maxPos.h - minPos.y;
+		this._target = {
+			"min":{
+				"row": minRow,
+				"col": minCol
+			},
+			"max":{
+				"row": maxRow,
+				"col": maxCol
+			}
+		};
+		var anchorBorderSize = (dojo.marginBox(leftTopDiv).w - dojo.contentBox(leftTopDiv).w) / 2;
+		var leftTopCellPos = dojo.position(cells[minCol].getNode(minRow));
+		dojo.style(leftTopDiv, {
+			"width": (leftTopCellPos.w - anchorBorderSize) + "px",
+			"height": (leftTopCellPos.h - anchorBorderSize) + "px"
+		});
+		var rightBottomCellPos = dojo.position(cells[maxCol].getNode(maxRow));
+		dojo.style(rightBottomDiv, {
+			"width": (rightBottomCellPos.w - anchorBorderSize) + "px",
+			"height": (rightBottomCellPos.h - anchorBorderSize) + "px"
+		});
+		return {
+			h: height,
+			w: width,
+			l: left - containerPos.x,
+			t: top - containerPos.y
+		};
+	},
+	_markTargetAnchor: function(evt){
+		try{
+		var t = this._dndRegion.type;
+		if(this._alreadyOut || (this._dnding && !this._config[t]["within"]) || (this._extDnding && !this._config[t]["in"])){
+			return;
+		}
+		var height, width, left, top,
+			targetAnchor = this._targetAnchor[t],
+			pos = dojo.position(this._container);
+		if(!targetAnchor){
+			targetAnchor = this._targetAnchor[t] = dojo.create("div", {
+				"class": (t == "cell") ? "dojoxGridCellBorderDIV" : "dojoxGridBorderDIV"
+			});
+			dojo.style(targetAnchor, "display", "none");
+			this._container.appendChild(targetAnchor);
+		}
+		switch(t){
+			case "col":
+				height = pos.h;
+				width = this._targetAnchorBorderWidth;
+				left = this._calcColTargetAnchorPos(evt, pos);
+				top = 0;
+				break;
+			case "row":
+				height = this._targetAnchorBorderWidth;
+				width = pos.w;
+				left = 0;
+				top = this._calcRowTargetAnchorPos(evt, pos);
+				break;
+			case "cell":
+				var cellPos = this._calcCellTargetAnchorPos(evt, pos, targetAnchor);
+				height = cellPos.h;
+				width = cellPos.w;
+				left = cellPos.l;
+				top = cellPos.t;
+		}
+		if(typeof height == "number" && typeof width == "number" && typeof left == "number" && typeof top == "number"){
+			dojo.style(targetAnchor, {
+				"height": height + "px",
+				"width": width + "px",
+				"left": left + "px",
+				"top": top + "px"
+			});
+			dojo.style(targetAnchor, "display", "");
+		}else{
+			this._target = null;
+		}
+		}catch(e){
+			console.warn("DnD._markTargetAnchor() error:",e);
+		}
+	},
+	_unmarkTargetAnchor: function(){
+		if(this._dndRegion){
+			var targetAnchor = this._targetAnchor[this._dndRegion.type];
+			if(targetAnchor){
+				dojo.style(this._targetAnchor[this._dndRegion.type], "display", "none");
+			}
+		}
+	},
+	_getVisibleHeaders: function(){
+		return dojo.map(dojo.filter(this.grid.layout.cells, function(cell){
+			return !cell.hidden;
+		}), function(cell){
+			return {
+				"node": cell.getHeaderNode(),
+				"cell": cell
+			};
+		});
+	},
+	_rearrange: function(){
+		if(this._target === null){
+			return;
+		}
+		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);
+		}else{
+			this.rearranger[t == "col" ? "moveColumns" : "moveRows"](_joinToArray(ranges), this._target);
+		}
+		this._target = null;
+	},
+	onDraggingOver: function(sourcePlugin){
+		if(!this._dnding && sourcePlugin){
+			sourcePlugin._isSource = true;
+			this._extDnding = true;
+			if(!this._externalDnd){
+				this._externalDnd = true;
+				this._dndRegion = this._mapRegion(sourcePlugin.grid, sourcePlugin._dndRegion);
+			}
+			this._createDnDUI(this._moveEvent,true);
+			this.grid.pluginMgr.getPlugin("autoScroll").readyForAutoScroll = true;
+		}
+	},
+	_mapRegion: function(srcGrid, dndRegion){
+		if(dndRegion.type === "cell"){
+			var srcRange = dndRegion.selected[0];
+			var cells = this.grid.layout.cells;
+			var srcCells = srcGrid.layout.cells;
+			var c, cnt = 0;
+			for(c = srcRange.min.col; c <= srcRange.max.col; ++c){
+				if(!srcCells[c].hidden){
+					++cnt;
+				}
+			}
+			for(c = 0; cnt > 0; ++c){
+				if(!cells[c].hidden){
+					--cnt;
+				}
+			}
+			var region = dojo.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){
+				if(!srcCells[c].hidden){
+					++cnt;
+				}
+			}
+			for(c = 0; cnt > 0; ++c){
+				if(!cells[c].hidden){
+					--cnt;
+				}
+			}
+			region.handle.col = c;
+		}
+		return dndRegion;
+	},
+	onDraggingOut: function(sourcePlugin){
+		if(this._externalDnd){
+			this._extDnding = false;
+			this._destroyDnDUI(true, false);
+			if(sourcePlugin){
+				sourcePlugin._isSource = false;
+			}
+		}
+	},
+	onDragIn: function(sourcePlugin, isCopy){
+		var success = false;
+		if(this._target !== null){
+			var type = sourcePlugin._dndRegion.type;
+			var ranges = sourcePlugin._dndRegion.selected;
+			switch(type){
+				case "cell":
+					this.rearranger.changeCells(sourcePlugin.grid, ranges[0], this._target);
+					break;
+				case "row":
+					var range = _joinToArray(ranges);
+					this.rearranger.insertRows(sourcePlugin.grid, range, this._target);
+					break;
+			}
+			success = true;
+		}
+		this._endDnd(true);
+		if(sourcePlugin.onDragOut){
+			sourcePlugin.onDragOut(success && !isCopy);
+		}
+	},
+	onDragOut: function(isMove){
+		if(isMove && !this._copyOnly){
+			var type = this._dndRegion.type;
+			var ranges = this._dndRegion.selected;
+			switch(type){
+				case "cell":
+					this.rearranger.clearCells(ranges[0]);
+					break;
+				case "row":
+					this.rearranger.removeRows(_joinToArray(ranges));
+					break;
+			}
+		}
+		this._endDnd(true);
+	},
+	_canAccept: function(sourcePlugin){
+		if(!sourcePlugin){
+			return false;
+		}
+		var srcRegion = sourcePlugin._dndRegion;
+		var type = srcRegion.type;
+		if(!this._config[type]["in"] || !sourcePlugin._config[type]["out"]){
+			return false;
+		}
+		var g = this.grid;
+		var ranges = srcRegion.selected;
+		var colCnt = dojo.filter(g.layout.cells, function(cell){
+			return !cell.hidden;
+		}).length;
+		var rowCnt = g.rowCount;
+		var res = true;
+		switch(type){
+			case "cell":
+				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){
+						return cell.index >= ranges.min.col && cell.index <= ranges.max.col && !cell.hidden;
+					}).length <= colCnt;
+				//intentional drop through - don't break
+			case "row":
+				if(sourcePlugin._allDnDItemsLoaded()){
+					return res;
+				}
+		}
+		return false;
+	},
+	_allDnDItemsLoaded: function(){
+		if(this._dndRegion){
+			var type = this._dndRegion.type,
+				ranges = this._dndRegion.selected,
+				rows = [];
+			switch(type){
+				case "cell":
+					for(var i = ranges[0].min.row, max = ranges[0].max.row; i <= max; ++i){
+						rows.push(i);
+					}
+					break;
+				case "row":
+					rows = _joinToArray(ranges);
+					break;
+				default:
+					return false;
+			}
+			var cache = this.grid._by_idx;
+			return dojo.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 + ")";
+	}
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.DnD/*name:'dnd'*/, {
+	"dependency": ["selector", "rearrange"]
+});
+})();
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Exporter.js b/dojox/grid/enhanced/plugins/Exporter.js
new file mode 100644
index 0000000..9e48569
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Exporter.js
@@ -0,0 +1,231 @@
+dojo.provide("dojox.grid.enhanced.plugins.Exporter");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid._RowSelector");
+
+dojo.declare("dojox.grid.enhanced.plugins.Exporter", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Provide functions to export the grid data into a given format.
+	//
+	//		Acceptable plugin parameters:
+	//		1. exportFormatter: function(data, cell, rowIndex, item)
+	//				Provide a way to customize how data should look in exported string.
+	//				Note that usually the formatter of grid cell should not be used here (it can return HTML or even widget).
+	// example:
+	//	|	function onExported(exported_text){
+	//	|		//custom code here...
+	//	|	}
+	//	|	dijit.byId("my_grid_id").exportTo("csv",	//registered export format, mandatory
+	//	|		{										//the whole object is optional.
+	//	|			fetchArgs: {start:0,count:1000},	//keywordArgs for fetch, optional
+	//	|			writerArgs: {separator:';'},		//export writer specific arguments, optional
+	//	|		},
+	//	|		function(str){
+	//	|			//call back function, mandatory
+	//	|	});
+	//	|	var result = dijit.byId("my_grid_id").exportSelectedTo("table",     //registered export format, mandatory
+	//	|														{separator:'|'} //export writer specific arguments, optional
+	//	|	);
+	//
+
+	// name: String
+	//		Plugin name.
+	name: "exporter",
+	
+	constructor: function(grid, args){
+		// summary:
+		//		only newed by _Plugin
+		// grid: EnhancedGrid
+		//		The grid to plug in to.
+		this.grid = grid;
+		this.formatter = (args && dojo.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);
+	},
+	setExportFormatter: function(formatter){
+		this.formatter = formatter;
+	},
+	exportGrid: function(type, args, onExported){
+		// summary:
+		//		Export required rows(fetchArgs) to a kind of format(type)
+		//		using the corresponding writer with given arguments(writerArgs),
+		//		then pass the exported text to a given function(onExported).
+		// tags:
+		//		public
+		// type: string
+		//		A registered export format name
+		// args: object?
+		//		includes:
+		//		{
+		//			fetchArgs: object?
+		//				Any arguments for store.fetch
+		//			writerArgs: object?
+		//				Arguments for the given format writer
+		//		}
+		// onExported: function(string)
+		//		Call back function when export result is ready
+		if(dojo.isFunction(args)){
+			onExported = args;
+			args = {};
+		}
+		if(!dojo.isString(type) || !dojo.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 : {},
+			oldFunc = fetchArgs.onComplete;
+		if(g.store){
+			fetchArgs.onComplete = function(items, request){
+				if(oldFunc){
+					oldFunc(items, request);
+				}
+				onExported(_this._goThroughGridData(items, writer));
+			};
+			fetchArgs.sort = fetchArgs.sort || g.getSortProps();
+			g._storeLayerFetch(fetchArgs);
+		}else{
+			//Data is defined directly in the structure;
+			var start = fetchArgs.start || 0,
+				count = fetchArgs.count || -1,
+				items = [];
+			for(var i = start; i != start + count && i < g.rowCount; ++i){
+				items.push(g.getItem(i));
+			}
+			onExported(this._goThroughGridData(items, writer));
+		}
+	},
+	exportSelected: function(type, writerArgs){
+		// summary:
+		//		Only export selected rows.
+		// tags:
+		//		public
+		// type: string
+		//		A registered export format name
+		// writerArgs: object?
+		//		Arguments for the given format writer
+		// returns: string
+		//		The exported string
+		if(!dojo.isString(type)){
+			return "";
+		}
+		var writer = this._getExportWriter(type, writerArgs);
+		return this._goThroughGridData(this.grid.selection.getSelected(), writer);	//String
+	},
+	_buildRow: function(/* object */arg_obj,/* ExportWriter */writer){
+		// summary:
+		//		Use the given export writer(writer) to go through a single row
+		//		which is given in the context object(arg_obj).
+		// tags:
+		//		private
+		// returns:
+		//		undefined
+		var _this = this;
+		dojo.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){
+					arg_obj.subrow = subrow;
+					arg_obj.subrowIdx = srIdx;
+					if(writer.beforeSubrow(arg_obj)){
+						dojo.forEach(subrow, function(cell, cIdx){
+							if(arg_obj.isHeader && _this._isSpecialCol(cell)){
+								arg_obj.spCols.push(cell.index);
+							}
+							arg_obj.cell = cell;
+							arg_obj.cellIdx = cIdx;
+							writer.handleCell(arg_obj);
+						});
+						writer.afterSubrow(arg_obj);
+					}
+				});
+				writer.afterView(arg_obj);
+			}
+		});
+	},
+	_goThroughGridData: function(/* Array */items,/* ExportWriter */writer){
+		// summary:
+		//		Use the given export writer(writer) to go through the grid structure
+		//		and the given rows(items), then return the writer output.
+		// tags:
+		//		private
+		var grid = this.grid,
+			views = dojo.filter(grid.views.views, function(view){
+				return !(view instanceof dojox.grid._RowSelector);
+			}),
+			arg_obj = {
+				'grid': grid,
+				'isHeader': true,
+				'spCols': [],
+				'_views': views,
+				'colOffset': (views.length < grid.views.views.length ? -1 : 0)
+			};
+		//go through header
+		if(writer.beforeHeader(grid)){
+			this._buildRow(arg_obj,writer);
+			writer.afterHeader();
+		}
+		//go through content
+		arg_obj.isHeader = false;
+		if(writer.beforeContent(items)){
+			dojo.forEach(items, function(item, rIdx){
+				arg_obj.row = item;
+				arg_obj.rowIdx = rIdx;
+				if(writer.beforeContentRow(arg_obj)){
+					this._buildRow(arg_obj, writer);
+					writer.afterContentRow(arg_obj);
+				}
+			}, this);
+			writer.afterContent();
+		}
+		return writer.toString();
+	},
+	_isSpecialCol: function(/* dojox.grid.__CellDef */header_cell){
+		// summary:
+		//		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
+	},
+	_getExportWriter: function(/* string */ fileType, /* object? */ writerArgs){
+		// summary:
+		//		Use the given export format type(fileType)
+		//		and writer arguments(writerArgs) to create
+		//		a ExportWriter and return it.
+		// tags:
+		//		private
+		var writerName, cls,
+			expCls = dojox.grid.enhanced.plugins.Exporter;
+		if(expCls.writerNames){
+			writerName = expCls.writerNames[fileType.toLowerCase()];
+			cls = dojo.getObject(writerName);
+			if(cls){
+				var writer = new cls(writerArgs);
+				writer.formatter = this.formatter;
+				return writer;	//ExportWriter
+			}else{
+				throw new Error('Please make sure class "' + writerName + '" is required.');
+			}
+		}
+		throw new Error('The writer for "' + fileType + '" has not been registered.');
+	}
+});
+dojox.grid.enhanced.plugins.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;
+};
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Exporter/*name:'exporter'*/);
diff --git a/dojox/grid/enhanced/plugins/Filter.js b/dojox/grid/enhanced/plugins/Filter.js
new file mode 100644
index 0000000..6783ace
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Filter.js
@@ -0,0 +1,160 @@
+dojo.provide("dojox.grid.enhanced.plugins.Filter");
+
+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, {
+		// summary:
+		//		Provide filter functionality for grid.
+		//
+		//		Acceptable plugin parameters:
+		//		1. itemsName: string
+		//			the name shown on the filter bar.
+		//		2. statusTipTimeout: number
+		//			when does the status tip show.
+		//		3. ruleCount: number
+		//			default to 3, should not change to more. The Claro theme limits it.
+		//		4. disabledConditions: object
+		//			If you don't need all of the conditions provided for a data type,
+		//			you can explicitly declare them here:
+		//			e.g.: disabledConditions: {string: ["contains", "is"], number: ["equalto"], ...}
+		//		5. isServerSide: boolean
+		//			Whether to use server side filtering. Default to false.
+		//		6. isStateful: boolean
+		//			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.
+		//
+		//		Acceptable cell parameters defined in layout:
+		//		1. filterable: boolean
+		//			The column is not filterable only when this is set to false explicitly.
+		//		2. datatype: string
+		//			The data type of this column. Can be "string", "number", "date", "time", "boolean".
+		//			Default to "string".
+		//		3. autoComplete: boolean
+		//			If need auto-complete in the ComboBox for String type, set this to true.
+		//		4. dataTypeArgs: object
+		//			Some arguments helping convert store data to something the filter UI understands.
+		//			Different data type arguments can be provided to different data types.
+		//			For date/time, this is a dojo.date.locale.__FormatOptions, so the DataTimeBox can understand the store data.
+		//			For boolean, this object contains:
+		//				trueLabel: string
+		//					A label to display in the filter definition dialog for true value. Default to "True".
+		//				falseLable: string
+		//					A label to display in the filter definition dialog for false value. Default to "False".
+		//		5. disabledConditions: object
+		//			If you don't need all of the conditions provided by the filter UI on this column, you can explicitly say it out here.
+		//			e.g.: disabledConditions: ["contains", "is"]
+		//			This will disable the "contains" condition for this column, if this column is of string type.
+		//			For full set of conditions, please refer to dojox.grid.enhanced.plugins.filter.FilterDefDialog._setupData.
+		// example:
+		//	|	<div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: true}" ...></div>
+		//	|	or provide some parameters:
+		//	|	<div dojoType="dojox.grid.EnhancedGrid" plugins="{GridFilter: {itemsName: 'songs'}}" ...></div>
+		//	|	Customize columns for filter:
+		//	|	var layout = [
+		//	|		...
+		//	|		//define a column to be un-filterable in layout/structure
+		//	|		{field: "Genre", filterable: false, ...}
+		//	|		//define a column of type string and supports autoComplete when you type in filter conditions.
+		//	|		{field: "Writer", datatype: "string", autoCommplete: true, ...}
+		//	|		//define a column of type date and the data in store has format: "yyyy/M/d"
+		//	|		{field: "Publish Date", datatype: "date", dataTypeArgs: {datePattern: "yyyy/M/d"}, ...}
+		//	|		//disable some conditions for a column
+		//	|		{field: "Track", disabledConditions: ["equalto","notequalto"], ...}
+		//	|		...
+		//	|	];
+		
+		// name: String
+		//		plugin name
+		name: "filter",
+		
+		constructor: function(grid, args){
+			// summary:
+			//		See constructor of dojox.grid.enhanced._Plugin.
+			this.grid = grid;
+			this.nls = dojo.i18n.getLocalization("dojox.grid.enhanced", "Filter");
+			
+			args = this.args = dojo.isObject(args) ? args : {};
+			if(typeof args.ruleCount != 'number' || args.ruleCount < 0){
+				args.ruleCount = 3;
+			}
+			
+			//Install filter layer
+			this._wrapStore();
+			
+			//Install UI components
+			var obj = { "plugin": this };
+			this.clearFilterDialog = new dojox.grid.enhanced.plugins.Dialog({
+				refNode: this.grid.domNode,
+				title: this.nls["clearFilterDialogTitle"],
+				content: new fns.ClearFilterConfirm(obj)
+			});
+			this.filterDefDialog = new fns.FilterDefDialog(obj);
+			this.filterBar = new fns.FilterBar(obj);
+			this.filterStatusTip = new fns.FilterStatusTip(obj);
+			
+			//Expose the layer event to grid.
+			grid.onFilterDefined = function(){};
+			this.connect(grid.layer("filter"), "onFilterDefined", function(filter){
+				grid.onFilterDefined(grid.getFilter(), grid.getFilterRelation());
+			});
+		},
+		destroy: function(){
+			this.inherited(arguments);
+			try{
+				this.grid.unwrap("filter");
+				this.filterBar.destroyRecursive();
+				this.filterBar = null;
+				this.clearFilterDialog.destroyRecursive();
+				this.clearFilterDialog = null;
+				this.filterStatusTip.destroy();
+				this.filterStatusTip = null;
+				this.filterDefDialog.destroy();
+				this.filterDefDialog = null;
+				this.grid = null;
+				this.nls = null;
+				this.args = null;
+			}catch(e){
+				console.warn("Filter.destroy() error:",e);
+			}
+		},
+		_wrapStore: function(){
+			var g = this.grid;
+			var args = this.args;
+			var filterLayer = args.isServerSide ? new fns.ServerSideFilterLayer(args) :
+				new fns.ClientSideFilterLayer({
+					cacheSize: args.filterCacheSize,
+					fetchAll: args.fetchAllOnFirstFilter,
+					getter: this._clientFilterGetter
+				});
+			ns.wrap(g, "_storeLayerFetch", filterLayer);
+			
+			this.connect(g, "_onDelete", dojo.hitch(filterLayer, "invalidate"));
+		},
+		onSetStore: function(store){
+			this.filterDefDialog.clearFilter(true);
+		},
+		_clientFilterGetter: function(/* data item */ datarow,/* cell */cell, /* int */rowIndex){
+			// summary:
+			//		Define the grid-specific way to get data from a row.
+			//		Argument "cell" is provided by FilterDefDialog when defining filter expressions.
+			//		Argument "rowIndex" is provided by FilterLayer when checking a row.
+			//		FilterLayer also provides a forth argument: "store", which is grid.store,
+			//		but we don't need it here.
+			return cell.get(rowIndex, datarow);
+		}
+	});
+})();
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Filter/*name:'filter'*/);
diff --git a/dojox/grid/enhanced/plugins/GridSource.js b/dojox/grid/enhanced/plugins/GridSource.js
new file mode 100644
index 0000000..fa7fdfa
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/GridSource.js
@@ -0,0 +1,148 @@
+dojo.provide("dojox.grid.enhanced.plugins.GridSource");
+
+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){
+		a = a.concat(arrays[i]);
+	}
+	return a;
+};
+dojo.declare("dojox.grid.enhanced.plugins.GridSource", dojo.dnd.Source, {
+	// summary:
+	//		A special source that can accept grid contents.
+	//		Only for non-grid widgets or domNodes.
+	accept: ["grid/cells", "grid/rows", "grid/cols", "text"],
+	
+	// insertNodesForGrid:
+	//		If you'd like to insert some sort of nodes into your dnd source, turn this on,
+	//		and override getCellContent/getRowContent/getColumnContent
+	//		to populate the dnd data in your desired format.
+	insertNodesForGrid: false,
+	
+	markupFactory: function(params, node){
+		return new dojox.grid.enhanced.plugins.GridSource(node, params);
+	},
+	checkAcceptance: function(source, nodes){
+		if(source instanceof dojox.grid.enhanced.plugins.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) &&
+					!source.dndPlugin._allDnDItemsLoaded()){
+					return false;
+				}
+			}
+			this.sourcePlugin = source.dndPlugin;
+		}
+		return this.inherited(arguments);
+	},
+	onDraggingOver: function(){
+		if(this.sourcePlugin){
+			this.sourcePlugin._isSource = true;
+		}
+	},
+	onDraggingOut: function(){
+		if(this.sourcePlugin){
+			this.sourcePlugin._isSource = false;
+		}
+	},
+	onDropExternal: function(source, nodes, copy){
+		if(source instanceof dojox.grid.enhanced.plugins.GridDnDSource){
+			var ranges = dojo.map(nodes, function(node){
+				return source.getItem(node.id).data;
+			});
+			var item = source.getItem(nodes[0].id);
+			var grid = item.dndPlugin.grid;
+			var type = item.type[0];
+			var range;
+			try{
+				switch(type){
+					case "grid/cells":
+						nodes[0].innerHTML = this.getCellContent(grid, ranges[0].min, ranges[0].max) || "";
+						this.onDropGridCells(grid, ranges[0].min, ranges[0].max);
+						break;
+					case "grid/rows":
+						range = _joinToArray(ranges);
+						nodes[0].innerHTML = this.getRowContent(grid, range) || "";
+						this.onDropGridRows(grid, range);
+						break;
+					case "grid/cols":
+						range = _joinToArray(ranges);
+						nodes[0].innerHTML = this.getColumnContent(grid, range) || "";
+						this.onDropGridColumns(grid, range);
+						break;
+				}
+				if(this.insertNodesForGrid){
+					this.selectNone();
+					this.insertNodes(true, [nodes[0]], this.before, this.current);
+				}
+				item.dndPlugin.onDragOut(!copy);
+			}catch(e){
+				console.warn("GridSource.onDropExternal() error:",e);
+			}
+		}else{
+			this.inherited(arguments);
+		}
+	},
+	getCellContent: function(grid, leftTopCell, rightBottomCell){
+		// summary:
+		//		Fill node innerHTML for dnd grid cells.
+		// sample code:
+		//		var cells = grid.layout.cells;
+		//		var store = grid.store;
+		//		var cache = grid._by_idx;
+		//		var res = "Grid Cells from " + grid.id + ":<br/>";
+		//		for(var r = leftTopCell.row; r <= rightBottomCell.row; ++r){
+		//			for(var c = leftTopCell.col; c <= rightBottomCell.col; ++c){
+		//				res += store.getValue(cache[r].item, cells[c].field) + ", ";
+		//			}
+		//			res = res.substring(0, res.length - 2) + ";<br/>";
+		//		}
+		//		return res;
+	},
+	getRowContent: function(grid, rowIndexes){
+		// summary:
+		//		Fill node innerHTML for dnd grid rows.
+		// sample code:
+		//		var cells = grid.layout.cells;
+		//		var store = grid.store;
+		//		var cache = grid._by_idx;
+		//		var res = "Grid Rows from " + grid.id + ":<br/>";
+		//		for(var i = 0; i < rowIndexes.length; ++i){
+		//			var r = rowIndexes[i];
+		//			res += "Row " + r + ": ";
+		//			for(var j = 0; j < cells.length; ++j){
+		//				if(!cells[j].hidden){
+		//					res += store.getValue(cache[r].item, cells[j].field) + ", ";
+		//				}
+		//			}
+		//			res = res.substring(0, res.length - 2) + ";<br/>";
+		//		}
+		//		return res;
+	},
+	getColumnContent: function(grid, colIndexes){
+		// summary:
+		//		Fill node innerHTML for dnd grid columns.
+		// sample code:
+		//		var cells = grid.layout.cells;
+		//		var res = "Grid Columns from " + grid.id + ":";
+		//		for(var i = 0; i < colIndexes.length; ++i){
+		//			var c = colIndexes[i];
+		//			res += (cells[c].name || cells[c].field) + ", ";
+		//		}
+		//		return res.substring(0, res.length - 2);
+	},
+	onDropGridCells: function(grid, leftTopCell, rightBottomCell){
+		
+	},
+	onDropGridRows: function(grid, rowIndexes){
+		
+	},
+	onDropGridColumns: function(grid, colIndexes){
+		
+	}
+});
+})();
diff --git a/dojox/grid/enhanced/plugins/IndirectSelection.js b/dojox/grid/enhanced/plugins/IndirectSelection.js
index 2abba9b..1e5493e 100644
--- a/dojox/grid/enhanced/plugins/IndirectSelection.js
+++ b/dojox/grid/enhanced/plugins/IndirectSelection.js
@@ -1,54 +1,64 @@
 dojo.provide("dojox.grid.enhanced.plugins.IndirectSelection");
 
+dojo.require('dojo.string');
 dojo.require("dojox.grid.cells.dijit");
-dojo.require("dojox.grid.cells._base");
+dojo.require("dojox.grid.enhanced._Plugin");
 
-dojo.declare("dojox.grid.enhanced.plugins.IndirectSelection", null, {
-	//	summary:
-	//		 Provides indirect selection feature - swipe selecting row(s)
+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>	
+	//		<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>
 
-	constructor: function(inGrid){
-		this.grid = inGrid;
-		//Hook grid.layout.setStructure(), so that indirect selection cell is included in the new structure
-		dojo.connect(inGrid.layout, 'setStructure', dojo.hitch(inGrid.layout, this.addRowSelectCell));
-	},
+	//name: String
+	//		Plugin name
+	name: "indirectSelection",
 	
-	addRowSelectCell: function(){
-		//summary:
-		//		Add the indirect selection cell(mapped to a column of checkboxes) to grid layout structure
+	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.DijitMultipleRowSelector, name: '', editable: true, width:'30px', styles:'text-align: center;'};
-		dojo.forEach(this.structure, dojo.hitch(this, function(view){
+		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']){
+				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.DijitSingleRowSelector : dojox.grid.cells.DijitMultipleRowSelector;
-				if(!dojo.isObject(this.grid.indirectSelection)){
-					selectDef = dojo.mixin(defaultCellDef, {type: cellType});
-				}else{
-					selectDef = dojo.mixin(defaultCellDef, this.grid.indirectSelection, {type: cellType, editable: true});
-					dojo.forEach(inValidFields, function(field){//remove invalid feilds
-						if(field in selectDef){ delete selectDef[field]; }
-					});
-				}
-				cells.length > 1 && (selectDef["rowSpan"] = cells.length);//for complicate layout
+				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.debug('Error:IndirectSelection.addRowSelectCell()-  cell ' + i + ' has no index!');
+						console.warn('Error:IndirectSelection.addRowSelectCell()-  cell ' + i + ' has no index!');
 					}
 				});
 				var rowSelectCell = this.addCellDef(0, 0, selectDef);
@@ -57,120 +67,282 @@ dojo.declare("dojox.grid.enhanced.plugins.IndirectSelection", null, {
 				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._SingleRowSelectorMixin", null, {
-	//	summary:
-	//		 Common attributes and functions to be mixed in for single selection	
+dojo.declare("dojox.grid.cells.RowSelector", dojox.grid.cells._Widget, {
+	// summary:
+	//		 Common attributes & functions for row selectors(Radio|CheckBox)
 
-	//alwaysEditing: Boolean
-	//		Overwritten, see dojox.grid.cells._Widget
-	//		True - always show the radio or checkbox widget
-	alwaysEditing: true,
+	//inputType: String
+	//		Input type - Radio|CheckBox
+	inputType: "",
 	
-	//widgetMap: Object
-	//		Cache all the radio or checkbox widgets
-	widgetMap:{},
+	//map: Object
+	//		Cache div refs of radio|checkbox to avoid querying each time
+	map: null,
 	
-	//widget: Object
-	//		The currently focused widget
-	widget: null,
+	//disabledMap: Object
+	//		Cache index of disabled rows
+	disabledMap: null,
 	
 	//isRowSelector: Boolean
-	//		Marker of indirect selection cell(column)
+	//		Marker of indirectSelection cell(column)
 	isRowSelector: true,
 
-	//defaultValue: Boolean
-	//		Default value for radio or checkbox widget
-	defaultValue: false,
+	//_connects: Array
+	//		List of all connections.
+	_connects: null,
+	
+	//_subscribes: Array
+	//		List of all subscribes.
+	_subscribes: null,
+
+	//checkedText: String
+	//		Checked character for high contrast mode
+	checkedText: '√',
 
-	formatEditing: function(inDatum, inRowIndex){
+	//unCheckedText: String
+	//		Unchecked character for high contrast mode
+	unCheckedText: 'O',
+
+	constructor: function(){
+		this.map = {}; this.disabledMap = {}, this.disabledCount= 0;
+		this._connects = []; this._subscribes = [];
+		this.inA11YMode = dojo.hasClass(dojo.body(), "dijit_a11y");
+		
+		this.baseClass = "dojoxGridRowSelector dijitReset dijitInline dijit" + this.inputType;
+		this.checkedClass = " dijit" + this.inputType + "Checked";
+		this.disabledClass = " dijit" + this.inputType + "Disabled";
+		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'));
+	},
+	formatter: function(data, rowIndex){
 		// summary:
 		//		Overwritten, see dojox.grid.cells._Widget
-		this.needFormatNode(inDatum, inRowIndex);
+		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; }
+		}else if(disabled){
+			clazz += this.disabledClass;
+		}
+		return ["<div tabindex = -1 ",
+				"id = '" + this.grid.id + "_rowSelector_" + rowIndex + "' ",
+				"name = '" + this.grid.id + "_rowSelector' class = '" + clazz + "' ",
+				"role = 'presentation' aria-pressed = '" + checked + "' aria-disabled = '" + disabled +
+				"' aria-label = '" + dojo.string.substitute(this.grid._nls["indirectSelection" + this.inputType], [rowIndex + 1]) + "'>",
+				"<span class = '" + this.statusTextClass + "'>" + (checked ? this.checkedText : this.unCheckedText) + "</span>",
+				"</div>"].join("");
 	},
-	
-	_formatNode: function(inDatum, inRowIndex){
+	setValue: function(rowIndex, inValue){
 		// summary:
-		//		Overwritten, see dojox.grid.cells._Base
-		this.formatNode(inDatum, inRowIndex);
+		//		Overwritten, see dojox.grid.cells._Widget
+		//		Simply return, no action
 	},
-
-	setValue: function(inRowIndex, inValue){
+	getValue: function(rowIndex){
 		// summary:
 		//		Overwritten, see dojox.grid.cells._Widget
-		//		Simpily return, no action
-		return;
+		return this.grid.selection.isSelected(rowIndex);
 	},
-	
-	get: function(inRowIndex){
+	toggleRow: function(index, value){
 		// summary:
-		//		Overwritten, see dojox.grid.cells._Base
-		//		return widget value of row(inRowIndex) -  true | false
-		var widget = this.widgetMap[this.view.id] ? this.widgetMap[this.view.id][inRowIndex] : null;
-		var value = widget ? widget.attr('checked') : '';
-		return value;
+		//		toggle checked | unchecked state for given row
+		// index: Integer
+		//		Row index
+		// value: Boolean
+		//		True - checked | False - unchecked
+		this._nativeSelect(index, value);
 	},
-	
-	_fireSelectionChanged: function(){
+	setDisabled: function(index, disabled){
 		// summary:
-		//		Publish rowSelectionChangedTopic when new row selection is made
-		dojo.publish(this.grid.rowSelectionChangedTopic,[this]);
+		//		toggle disabled | enabled state for given row
+		// idx: Integer
+		//		Row index
+		// disabled: Boolean
+		//		True - disabled | False - enabled
+		if(index < 0){ return; }
+		this._toggleDisabledStyle(index, disabled);
 	},
-	
-	_selectionChanged: function(obj){
+	disabled: function(index){
 		// summary:
-		//		Subscriber of rowSelectionChangedTopic, update row selection accordingly
-		// obj: Object
-		//		Object that fired the rowSelectionChangedTopic
-		if(obj == this || obj.grid && obj.grid != this.grid){
-			//ignore if the topic is published by self
-			return;
+		//		Check if one row is disabled
+		return !!this.disabledMap[index];
+	},
+	_onClick: function(e){
+		// summary:
+		//		When mouse click on the selector cell, select/deselect the row.
+		if(e.cell === this){
+			this._selectRow(e);
 		}
-		for (var i in this.widgetMap[this.view.id]){
-			var idx = new Number(i);
-			var widget = this.widgetMap[this.view.id][idx];
-			var value = !!this.grid.selection.selected[idx];
-			widget.attr('checked', value);
+	},
+	_dokeyup: function(e){
+		// summary:
+		//		Event handler for key up event
+		//		- from dojox.grid.enhanced._Events.dokeyup()
+		// e: Event
+		//		Key up event
+		if(e.cellIndex == this.index && e.rowIndex >= 0 && e.keyCode == dojo.keys.SPACE){
+			this._selectRow(e);
 		}
-		this.defaultValue = false;
-		this.grid.edit.isEditing() && this.grid.edit.apply();
 	},
-	
-	_toggleSingleRow: function(idx, value){
+	focus: function(rowIndex){
 		// summary:
-		//		toggle selection of a single row
-		// idx: Integer
-		//		Target row index
-		// value: Boolean
-		//		True - checked | False - unchecked
-		var widget;
-		dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[value ? 'addToSelection' : 'deselect'])(idx);
-		if(this.widgetMap[this.view.id] && (widget = this.widgetMap[this.view.id][idx])){
-			widget.attr('checked', value);			
+		//		Set focus to given row
+		// rowIndex: Integer
+		//		Target row
+		var selector = this.map[rowIndex];
+		if(selector){ selector.focus(); }
+	},
+	_focusEndingCell: function(rowIndex, cellIndex){
+		// summary:
+		//		Set focus to the ending grid cell(rowIndex,cellIndex) when swipe selection finished
+		// rowIndex: Integer
+		//		Row index
+		// cellIndex: Integer
+		//		Column index
+		var cell = this.grid.getCell(cellIndex);
+		this.grid.focus.setFocusCell(cell, rowIndex);
+	},
+	_nativeSelect: function(index, value){
+		// summary:
+		//		Use grid's native selection
+		this.grid.selection[value ? 'select' : 'deselect'](index);
+	},
+	_onSelected: function(index){
+		// summary:
+		//		Triggered when a row is selected
+		this._toggleCheckedStyle(index, true);
+	},
+	_onDeselected: function(index){
+		// summary:
+		//		Triggered when a row is deselected
+		this._toggleCheckedStyle(index, false);
+	},
+	_onUpdateRow: function(index){
+		// summary:
+		//		Clear cache when row is re-built.
+		delete this.map[index];
+	},
+	_toggleCheckedStyle: function(index, value){
+		// summary:
+		//		Change css styles for checked | unchecked
+		var selector = this._getSelector(index);
+		if(selector){
+			dojo.toggleClass(selector, this.checkedClass, value);
+			if(this.disabledMap[index]){
+				dojo.toggleClass(selector, this.checkedDisabledClass, value);
+			}
+			dijit.setWaiState(selector, 'pressed', value);
+			if(this.inA11YMode){
+				dojo.attr(selector.firstChild, 'innerHTML', value ? this.checkedText : this.unCheckedText);
+			}
 		}
-		this._fireSelectionChanged();
-	},	
-
-	inIndirectSelectionMode: function(){},
-	
-	toggleAllSelection: function(){}
+	},
+	_toggleDisabledStyle: function(index, disabled){
+		// summary:
+		//		Change css styles for disabled | enabled
+		var selector = this._getSelector(index);
+		if(selector){
+			dojo.toggleClass(selector, this.disabledClass, disabled);
+			if(this.getValue(index)){
+				dojo.toggleClass(selector, this.checkedDisabledClass, disabled);
+			}
+			dijit.setWaiState(selector, 'disabled', disabled);
+		}
+		this.disabledMap[index] = disabled;
+		if(index >= 0){
+			this.disabledCount += disabled ? 1 : -1;
+		}
+	},
+	_getSelector: function(index){
+		// summary:
+		//		Find selector for given row caching it if 1st time found
+		var selector = this.map[index];
+		if(!selector){//use accurate query for better performance
+			var rowNode = this.view.rowNodes[index];
+			if(rowNode){
+				selector = dojo.query('.dojoxGridRowSelector', rowNode)[0];
+				if(selector){ this.map[index] = selector; }
+			}
+		}
+		return selector;
+	},
+	_pageDestroyed: function(pageIndex){
+		// summary:
+		//		Explicitly empty map cache when a page destroyed
+		//		See dojox.grid._Scroller.invalidatePageNode()
+		// pageIndex: Integer
+		//		Index of destroyed page
+		var rowsPerPage = this.grid.scroller.rowsPerPage;
+		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]);
+			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]);
+			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);
+		delete this._connects;
+		delete this._subscribes;
+		//console.log('Single(Multiple)RowSelector.destroy() executed!');
+	}
 });
 
-dojo.declare("dojox.grid.cells._MultipleRowSelectorMixin", null, {
-	//	summary:
-	//		 Common attributes and functions to be mixed in for multiple selection
+dojo.declare("dojox.grid.cells.SingleRowSelector", dojox.grid.cells.RowSelector, {
+	// summary:
+	//		IndirectSelection cell(column) for single selection mode, using styles of dijit.form.RadioButton
+	inputType: "Radio",
 
+	_selectRow: function(e){
+		// summary:
+		//		Select the target row
+		// e: Event
+		//		Event fired on the target row
+		var index = e.rowIndex;
+		if(this.disabledMap[index]){ return; }
+		this._focusEndingCell(index, 0);
+		this._nativeSelect(index, !this.grid.selection.selected[index]);
+	}
+});
+
+dojo.declare("dojox.grid.cells.MultipleRowSelector", dojox.grid.cells.RowSelector, {
+	// summary:
+	//		Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
+	inputType: "CheckBox",
+	
 	//swipeStartRowIndex: Integer
 	//		Start row index for swipe selection
 	swipeStartRowIndex: -1,
 
 	//swipeMinRowIndex: Integer
-	//		Min row index for swipe selection	
+	//		Min row index for swipe selection
 	swipeMinRowIndex: -1,
 	
 	//swipeMinRowIndex: Integer
@@ -178,393 +350,256 @@ dojo.declare("dojox.grid.cells._MultipleRowSelectorMixin", null, {
 	swipeMaxRowIndex: -1,
 	
 	//toSelect: Boolean
-	//		selection new state
+	//		new state for selection
 	toSelect: false,
 	
 	//lastClickRowIdx: Integer
-	//		Row index for last click, used for range selection via Shift + click	
+	//		Row index for last click, used for range selection via Shift + click
 	lastClickRowIdx: -1,
 	
 	//toggleAllTrigerred: Boolean
-	//		Whether toggle all has been triggered or not	
+	//		Whether toggle all has been triggered or not
 	toggleAllTrigerred: false,
+	
+	unCheckedText: '□',
 
-	//_inDndSelection: Boolean
-	//		Whether in DnD row selection progress or not	
-	_inDndSelection: false,
-
-	domousedown: function(e){
-		//summay:
-		//		Event hanlder for mouse down event
-		// e: Event
-		//		Mouse down event
-		if(e.target.tagName == 'INPUT'){
-			this._startSelection(e.rowIndex);
-			//console.debug('domousedown()- set swipeStartRowIndex='+this.swipeStartRowIndex + ' toSelect='+this.toSelect);
+	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'));
+		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._toggletHeader();//TBD - a better way
+				}
+			}));
 		}
-		dojo.stopEvent(e);
 	},
-	
-	domousemove: function(e){
-		// summay:
-		//		Event hanlder for mouse move event
-		// e: Event
-		//		Mouse move event
-		this._updateSelection(e, 0);
+	toggleAllSelection:function(checked){
+		// summary:
+		//		Toggle select all|deselect all
+		// checked: Boolean
+		//		True - select all, False - deselect all
+		var grid = this.grid, selection = grid.selection;
+		if(checked){
+			selection.selectRange(0, grid.rowCount-1);
+		}else{
+			selection.deselectAll();
+		}
+		this.toggleAllTrigerred = true;
 	},
-		
-	onRowMouseOver: function(e){
+	_onMouseDown: function(e){
+		if(e.cell == this){
+			this._startSelection(e.rowIndex);
+			dojo.stopEvent(e);
+		}
+	},
+	_onRowMouseOver: function(e){
 		// summary:
-		//		Event fired when mouse moves over a data row.
+		//		Event fired when mouse moves over a data row(outside of this column).
+		//      - from dojox.grid.enhanced._Events.onRowMouseOver()
 		// e: Event
 		//		Decorated event object which contains reference to grid, cell, and rowIndex
 		this._updateSelection(e, 0);
-		if(this.grid.dnd){
-			this._inDndSelection = this.grid.select.isInSelectingMode('row');
-		}
 	},
-	
-	domouseup: function(e){
-		// summay:
-		//		Event hanlder for mouse up event
+	_domouseup: function(e){
+		// summary:
+		//		Event handler for mouse up event - from dojo.doc.domouseup()
 		// e: Event
 		//		Mouse up event
-		dojo.isIE && this.view.content.decorateEvent(e);//TODO - why only e in IE hasn't been decoreated?
-		var inSwipeSelection = e.cellIndex >= 0 && (this.inIndirectSelectionMode() || this._inDndSelection) && !this.grid.edit.isEditRow(e.rowIndex);
-		inSwipeSelection && this._focusEndingCell(e.rowIndex, e.cellIndex);
-		this._finisheSelect();
+		if(dojo.isIE){
+			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);
+		if(inSwipeSelection){
+			this._focusEndingCell(e.rowIndex, e.cellIndex);
+		}
+		this._finishSelect();
 	},
-	
-	dokeyup: function(e){
-		// summay:
-		//		Event hanlder for key up event
+	_dokeyup: function(e){
+		// summary:
+		//		Event handler for key up event
+		//		- from dojox.grid.enhanced._Events.dokeyup()
 		// e: Event
 		//		Key up event
+		this.inherited(arguments);
 		if(!e.shiftKey){
-			this._finisheSelect();
+			this._finishSelect();
 		}
 	},
-	
 	_startSelection: function(rowIndex){
-		// summay:
-		//		Initilize parameters to start a new swipe selection
+		// summary:
+		//		Initialize parameters to start a new swipe selection
 		// rowIndex: Integer
 		//		Index of the start row
 		this.swipeStartRowIndex = this.swipeMinRowIndex = this.swipeMaxRowIndex = rowIndex;
-		this.toSelect = !this.widgetMap[this.view.id][rowIndex].attr('checked');
+		this.toSelect = !this.getValue(rowIndex);
 	},
-	
 	_updateSelection: function(e, delta){
-		// summay:
+		// summary:
 		//		Update row selections, fired during a swipe selection
 		// e: Event
 		//		Event of the current row,
 		// delta: Integer
-		//		Row index delta, used for swipe selection via Shift + Cursor
-		//		0: not via Shift + Cursor, -1 : Shift +  Up, 1 : Shift + Down
-		if(this.swipeStartRowIndex < 0){
-			return;
+		//		Row index delta, used for swipe selection via Shift + Arrow key
+		//		0: not via key, -1 : Shift +  Up, 1 : Shift + Down
+		if(!this.inSwipeSelection()){ return; }
+		
+		var byKey = delta !== 0;//whether via Shift + Arrow Key
+		var currRow = e.rowIndex, deltaRow = currRow - this.swipeStartRowIndex + delta;
+		if(deltaRow > 0 && this.swipeMaxRowIndex < currRow + delta){
+			this.swipeMaxRowIndex = currRow + delta;
 		}
-		var byKey = delta !=0;//whether via Shift + Cursor
-		//this.defaultValue = false;
-		//index delta between the current row and starting row
-		var deltaRow = e.rowIndex - this.swipeStartRowIndex + delta;
-		deltaRow > 0 && (this.swipeMaxRowIndex < e.rowIndex + delta) && (this.swipeMaxRowIndex = e.rowIndex + delta)
-		deltaRow < 0 && (this.swipeMinRowIndex > e.rowIndex + delta) && (this.swipeMinRowIndex = e.rowIndex + delta);
-		// only when the min != max, there is a RANGE for selection
-		if (this.swipeMinRowIndex != this.swipeMaxRowIndex) {
-			for (var i in this.widgetMap[this.view.id]) {
-				var idx = new Number(i);
-				var inRange = (idx >= (deltaRow > 0 ? this.swipeStartRowIndex : e.rowIndex + delta) &&
-				idx <= (deltaRow > 0 ? e.rowIndex + delta : this.swipeStartRowIndex));
-				var outOfRange = (idx >= this.swipeMinRowIndex && idx <= this.swipeMaxRowIndex);
-				if (inRange && !(deltaRow == 0 && !this.toSelect)) {
-					(this.widgetMap[this.view.id][idx]).attr('checked', this.toSelect);
-					dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[this.toSelect ? 'addToSelection' : 'deselect'])(idx);
-				//}else if (outOfRange && (this.toSelect || !byKey)) {
-				}else if (outOfRange && !byKey) {
-					(this.widgetMap[this.view.id][idx]).attr('checked', !this.toSelect);
-					dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[!this.toSelect ? 'addToSelection' : 'deselect'])(idx);
-				}
+		if(deltaRow < 0 && this.swipeMinRowIndex > currRow + delta){
+			this.swipeMinRowIndex = currRow + delta;
+		}
+
+		var min = deltaRow > 0 ? this.swipeStartRowIndex : currRow + delta;
+		var max = deltaRow > 0 ? currRow + delta : this.swipeStartRowIndex;
+		for(var i = this.swipeMinRowIndex; i <= this.swipeMaxRowIndex; i++){
+			if(this.disabledMap[i] || i < 0){ continue; }
+			if(i >= min && i <= max){//deltaRow != 0 || this.toSelect
+				this._nativeSelect(i, this.toSelect);
+			}else if(!byKey){
+				this._nativeSelect(i, !this.toSelect);
 			}
 		}
-		this._fireSelectionChanged();
 	},
-	
-	swipeSelectionByKey: function(e, delta){
-		// summay:
+	_swipeByKey: function(rowOffset, colOffset, e){
+		// summary:
 		//		Update row selections, fired when Shift + Cursor is used for swipe selection
 		//		See dojox.grid.enhanced._Events.onKeyDown
 		// e: Event
 		//		Event of the current row,
-		// delta: Integer
-		//		Row index delta, used for swipe selection via Shift + Cursor
+		// rowOffset: Integer
+		//		Row offset, used for swipe selection via Shift + Cursor
 		//		-1 : Shift +  Up, 1 : Shift + Down
-		if(this.swipeStartRowIndex < 0) {
-			//A new swipe selection starts via Shift + Cursor			
-			this.swipeStartRowIndex = e.rowIndex;
-			if(delta > 0){//Shift + Down
-				this.swipeMaxRowIndex = e.rowIndex + delta;
-				this.swipeMinRowIndex = e.rowIndex;
+		if(!e || rowOffset === 0 || !e.shiftKey || e.cellIndex != this.index ||
+			this.grid.focus.rowIndex < 0){ //TBD - e.rowIndex == 0 && delta == -1
+			return;
+		}
+		var rowIndex = e.rowIndex;
+		if(this.swipeStartRowIndex < 0){
+			//A new swipe selection starts via Shift + Arrow key
+			this.swipeStartRowIndex = rowIndex;
+			if(rowOffset > 0){//Shift + Down
+				this.swipeMaxRowIndex = rowIndex + rowOffset;
+				this.swipeMinRowIndex = rowIndex;
 			}else{//Shift + UP
-				this.swipeMinRowIndex = e.rowIndex + delta;
-				this.swipeMaxRowIndex = e.rowIndex;	
+				this.swipeMinRowIndex = rowIndex + rowOffset;
+				this.swipeMaxRowIndex = rowIndex;
 			}
-			this.toSelect = this.widgetMap[this.view.id][e.rowIndex].attr('checked');
+			this.toSelect = this.getValue(rowIndex);
 		}
-		this._updateSelection(e, delta);
+		this._updateSelection(e, rowOffset);
 	},
-	
-	_finisheSelect: function(){
-		// summay:
+	_finishSelect: function(){
+		// summary:
 		//		Reset parameters to end a swipe selection
 		this.swipeStartRowIndex = -1;
 		this.swipeMinRowIndex = -1;
 		this.swipeMaxRowIndex = -1;
 		this.toSelect = false;
 	},
-	
-	inIndirectSelectionMode: function(){
-		// summay:
-		//		Reset parameters to end a swipe selection
+	inSwipeSelection: function(){
+		// summary:
+		//		Check if during a swipe selection
 		// return: Boolean
-		//		Whether in swipe selection		
+		//		Whether in swipe selection
 		return this.swipeStartRowIndex >= 0;
 	},
-	
-	toggleAllSelection:function(checked){
-		// summay:
-		//		Toggle between select all and deselect all
-		// checked: Boolean
-		//		True - select all, False - deselect all
-		for (var i in this.widgetMap[this.view.id]){
-			var idx = new Number(i);
-			var widget = this.widgetMap[this.view.id][idx];
-			widget.attr('checked', checked);
-			dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[checked ? 'addToSelection' : 'deselect'])(idx);
-		}
-		!checked && this.grid.selection.deselectAll();
-		this.defaultValue = checked;
-		this.toggleAllTrigerred = true;
-		this._fireSelectionChanged();
-	}
-});
-
-dojo.declare("dojox.grid.cells.DijitSingleRowSelector", [dojox.grid.cells._Widget, dojox.grid.cells._SingleRowSelectorMixin], {
-	//	summary:
-	//		Indirect selection cell for single selection mode, using dijit.form.RadioButton
-
-	//widgetClass: Class
-	//		widget class that will be used for indirect selection cell(column)
-	widgetClass: dijit.form.RadioButton,
-	
-	constructor: function(){
-		dojo.subscribe(this.grid.rowSelectionChangedTopic, this, this._selectionChanged);
-		dojo.subscribe(this.grid.sortRowSelectionChangedTopic, this, this._selectionChanged);
-		this.grid.indirectSelector = this;
+	_nativeSelect: function(index, value){
+		// summary:
+		//		Overwritten
+		this.grid.selection[value ? 'addToSelection' : 'deselect'](index);
 	},
-
-	formatNode: function(inDatum, inRowIndex){
+	_selectRow: function(e){
 		// summary:
-		//		Overwritten, see dojox.grid.cells._Widget
-		if(!this.widgetClass){
-			return inDatum;
-		}
-		!this.widgetMap[this.view.id] && (this.widgetMap[this.view.id] = {});
-		var currWidget = this.widgetMap[this.view.id][inRowIndex];
-		
-		var cellNode = this.getNode(inRowIndex);
-		if(!cellNode){
-			return;
-		}
-		var noAttachedWidget = !cellNode.firstChild || (currWidget && currWidget.domNode != cellNode.firstChild);
-		var inNode = noAttachedWidget && !cellNode.firstChild ? cellNode.appendChild(dojo.create('div')) : cellNode.firstChild;
+		//		Select the target row or range or rows
+		// e: Event
+		//		Event fired on the target row
+		var rowIndex = e.rowIndex;
+		if(this.disabledMap[rowIndex]){ return; }
+		dojo.stopEvent(e);
+		this._focusEndingCell(rowIndex, 0);
 		
-		if(!currWidget || dojo.isIE){
-			!this.widgetProps && (this.widgetProps = {});
-			this.widgetProps.name = 'select_' + this.view.id;
-			var value = this.getDefaultValue(currWidget, inRowIndex);
-			this.widget = currWidget = this.createWidget(inNode, inDatum, inRowIndex);
-			this.widgetMap[this.view.id][inRowIndex] = currWidget;
-			this.widget.attr('checked', value);
-			dojo.connect(currWidget, '_onClick', dojo.hitch(this, function(e){
-				this._selectRow(e, inRowIndex);
-			}));
-			dojo.connect(currWidget.domNode, 'onkeyup', dojo.hitch(this, function(e){
-				e.keyCode == dojo.keys.SPACE && this._selectRow(e, inRowIndex, true);					
-			}));			
-			dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[value ? 'addToSelection' : 'deselect'])(inRowIndex);
+		var delta = rowIndex - this.lastClickRowIdx;
+		var newValue = !this.grid.selection.selected[rowIndex];
+		if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){
+			var min = delta > 0 ? this.lastClickRowIdx : rowIndex;
+			var max = delta > 0 ? rowIndex : this.lastClickRowIdx;
+			for(var i = min; i >= 0 && i <= max; i++){
+				this._nativeSelect(i, newValue);
+			}
 		}else{
-			this.widget = currWidget;
-			dojo.addClass(this.widget.domNode, 'dojoxGridWidgetHidden');
-			noAttachedWidget && this.attachWidget(inNode, inDatum, inRowIndex);
+			this._nativeSelect(rowIndex, newValue);
 		}
-		this.grid.rowHeightChanged(inRowIndex);
-		//this.focus(inRowIndex);
-		dojo.removeClass(this.widget.domNode, 'dojoxGridWidgetHidden');
-		(inRowIndex == this.grid.lastRenderingRowIdx) && dojo.removeClass(this.grid.domNode, 'dojoxGridSortInProgress');
+		this.lastClickRowIdx = rowIndex;
 	},
-	
-	getDefaultValue: function(widget, inRowIndex){
+	getValue: function(rowIndex){
 		// summary:
-		//		Get defaulst value for a widget
-		// widget: Object
-		//		Target widget
-		// inRowIndex: Integer
-		//		Row index of the widget			
-		// return: Boolean
-		//		True - checked | False - unchecked
-		var value = widget ? widget.attr('checked') : this.defaultValue;
-		if(!widget){
-			if(this.grid.nestedSorting){
-				value =  value || this.grid.getStoreSelectedValue(inRowIndex);	
-			}
-			value = this.grid.selection.isSelected(inRowIndex) ? true : value;
-		}
-		return value;
-	},
-	
-	focus: function(inRowIndex){
-		// summary:
-		//		Set focus to the widget in the target row
-		// inRowIndex: Integer
-		//		Target row			
-		var widget = this.widgetMap[this.view.id][inRowIndex];
-		if(widget){
-			setTimeout(dojo.hitch(widget, function(){
-				dojox.grid.util.fire(this, "focus");
-			}), 0);
+		//		Overwritten
+		if(rowIndex == -1){//header selector
+			var g = this.grid;
+			return g.rowCount > 0 && g.rowCount <= g.selection.getSelectedCount();
 		}
+		return this.inherited(arguments);
 	},
-	
-	_focusEndingCell: function(inRowIndex, cellIndex){
-		// summary:
-		//		At the end of a swipe selection, set focus to the ending grid cell(inRowIndex,cellIndex)
-		// inRowIndex: Integer
-		//		Row index
-		// cellIndex: Integer
-		//		Column index							
-		var cell = this.grid.getCell(cellIndex);
-		this.grid.focus.setFocusCell(cell, inRowIndex);
-		this.grid.isDndSelectEnable && this.grid.focus._blurRowBar();
-	},
-
-	_selectRow: function(e, inRowIndex, preChange){
+	_addHeaderSelector: function(){
 		// summary:
-		//		Select the target row
-		// e: Event
-		//		Event fired on the target row		
-		// inRowIndex: Integer
-		//		Target row index
-		// preChange: Boolean
-		//		Whether triggered before the selection state change of the target row
-											
-		//if(preChange){ //fix seleting radio by space only works in Moz
-		if(dojo.isMoz && preChange){
-			return;
-		}
-		dojo.stopEvent(e);
-		//this.grid.selection.clickSelect(inRowIndex);
-		this._focusEndingCell(inRowIndex, 0);
-
-		var value = !this.grid.selection.selected[inRowIndex];
-		this.grid.selection.deselectAll();
-		this.grid.selection.addToSelection(inRowIndex);
-		
-		if (!dojo.isMoz) {//fix seleting radio by space only works in Moz
-			var widget = this.widgetMap[this.view.id][inRowIndex];
-			widget.attr('checked', true);
+		//		Add selector in column header for selecting|deselecting all
+		var headerCellNode = this.view.getHeaderCellNode(this.index);
+		if(!headerCellNode){ return; }
+		dojo.empty(headerCellNode);
+		var g = this.grid;
+		var selector = headerCellNode.appendChild(dojo.create("div", {
+			"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;'>" +
+				g._nls["selectAll"] + "</span>"
+		}));
+		this.map[-1] = selector;
+		var idx = this._headerSelectorConnectIdx;
+		if(idx !== undefined){
+			dojo.disconnect(this._connects[idx]);
+			this._connects.splice(idx, 1);
 		}
-		this._fireSelectionChanged();
+		this._headerSelectorConnectIdx = this._connects.length;
+		this._connects.push(dojo.connect(selector, 'onclick', this, '_toggletHeader'));
+		this._onSelectionChanged();
 	},
-	
-	toggleRow: function(idx, value) {
+	_toggletHeader: function(){
 		// summary:
-		//		toggle selection of a single row
-		// idx: Integer
-		//		Target row index
-		// value: Boolean
-		//		True - checked | False - unchecked
-		var currSelectIdx = dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype.getFirstSelected)();
-		if(idx != currSelectIdx && !value || idx == currSelectIdx && value){return;}
-		
-		var widget;			
-		if(idx != currSelectIdx && value && this.widgetMap[this.view.id] && (widget = this.widgetMap[this.view.id][currSelectIdx])){
-			//fix - current selected widget isn't unchecked
-			widget.attr('checked', false);			
-		}
-		this.grid.selection.deselectAll();
-		this._toggleSingleRow(idx, value);
+		//		Toggle state for head selector
+		if(!!this.disabledMap[-1]){ return; }
+		this.grid._selectingRange = true;
+		this.toggleAllSelection(!this.getValue(-1));
+		this._onSelectionChanged();
+		this.grid._selectingRange = false;
 	},
-	
-	setDisabled: function(idx, disabled){
+	_onSelectionChanged: function(){
 		// summary:
-		//		toggle 'disabled' | 'enabled' of the selector widget in row idx
-		// idx: Integer
-		//		Row index
-		// disabled: Boolean
-		//		True - disabled | False - enabled
-		if(this.widgetMap[this.view.id]){
-			var widget = this.widgetMap[this.view.id][idx];
-			widget && widget.attr('disabled', disabled);
-		} 
-	}
-});
-
-dojo.declare("dojox.grid.cells.DijitMultipleRowSelector", [dojox.grid.cells.DijitSingleRowSelector, dojox.grid.cells._MultipleRowSelectorMixin], {
-	//summary:
-	//		Indirect selection cell for multiple or extended mode, using dijit.form.CheckBox
-
-	//widgetClass: Class
-	//		widget class that will be used for indirect selection cell(column)
-	widgetClass: dijit.form.CheckBox,
-	
-	constructor: function(){
-		dojo.connect(dojo.doc, 'onmouseup', this, 'domouseup');
-		this.grid.indirectSelector = this;
+		//		Update header selector anytime selection changed
+		var g = this.grid;
+		if(!this.map[-1] || g._selectingRange){ return; }
+		this._toggleCheckedStyle(-1, this.getValue(-1));
 	},
-	
-	_selectRow: function(e, inRowIndex, preChange){
+	_toggleDisabledStyle: function(index, disabled){
 		// summary:
-		//		Select the target row or range or rows
-		// e: Event
-		//		Event fired on the target row		
-		// inRowIndex: Integer
-		//		Target row index
-		// preChange: Boolean
-		//		Whether triggered before the selection state change of the target row
-		
-		dojo.stopEvent(e);
-		this._focusEndingCell(inRowIndex, 0);
-		var delta = inRowIndex - this.lastClickRowIdx;
-		if(this.lastClickRowIdx >= 0 && !e.ctrlKey && !e.altKey && e.shiftKey){
-			var newValue = this.widgetMap[this.view.id][inRowIndex].attr('checked');
-			newValue = preChange ? !newValue : newValue;
-			for (var i in this.widgetMap[this.view.id]) {
-				var idx = new Number(i);
-				var inRange = (idx >= (delta > 0 ? this.lastClickRowIdx : inRowIndex) 
-				  			   && idx <= (delta > 0 ? inRowIndex :this.lastClickRowIdx));
-				if(inRange){
-					var widget = this.widgetMap[this.view.id][idx];
-					widget.attr('checked', newValue);
-					dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[newValue ? 'addToSelection' : 'deselect'])(idx);
-				}
+		//		Overwritten
+		this.inherited(arguments);
+		if(this.headerSelector){
+			var allDisabled = (this.grid.rowCount == this.disabledCount);
+			if(allDisabled != !!this.disabledMap[-1]){//only if needed
+				arguments[0] = -1;
+				arguments[1] = allDisabled;
+				this.inherited(arguments);
 			}
-		}else{
-			//this.grid.selection.clickSelect(inRowIndex, true);	
-			var value = !this.grid.selection.selected[inRowIndex];
-			var widget = this.widgetMap[this.view.id][inRowIndex];
-			widget.attr('checked', value);
-			dojo.hitch(this.grid.selection, dojox.grid.Selection.prototype[value ? 'addToSelection' : 'deselect'])(inRowIndex);
 		}
-		//this.defaultValue = false;
-		this.lastClickRowIdx = inRowIndex;
-		this._fireSelectionChanged();
-	},
-
-	toggleRow: function(idx, value) {
-		// summary:
-		//		Overwritten
-		this._toggleSingleRow(idx, value);
-	}	
+	}
 });
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.IndirectSelection/*name:'indirectSelection'*/, {"preInit": true});
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Menu.js b/dojox/grid/enhanced/plugins/Menu.js
index fb9f363..4110976 100644
--- a/dojox/grid/enhanced/plugins/Menu.js
+++ b/dojox/grid/enhanced/plugins/Menu.js
@@ -1,131 +1,120 @@
 dojo.provide("dojox.grid.enhanced.plugins.Menu");
 
-dojo.declare("dojox.grid.enhanced.plugins.Menu", null, {
-	//	summary:
+dojo.require("dojox.grid.enhanced._Plugin");
+
+dojo.declare("dojox.grid.enhanced.plugins.Menu", dojox.grid.enhanced._Plugin, {
+	// summary:
 	//		 Provides context menu support, including header menu, row menu, cell menu and selected region menu
 	// example:
-	// 		 <div dojoType="dojox.grid.EnhancedGrid" 
-	//			  plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId", 
+	//		<div dojoType="dojox.grid.EnhancedGrid"
+	//			plugins="{menus:{headerMenu:"headerMenuId", rowMenu:"rowMenuId", cellMenu:"cellMenuId",
 	//							   selectedRegionMenu:"selectedRegionMenuId"}}" ...>
 	//		</div>
+	
+	//name: String
+	//		Plugin name
+	name: "menus",
 
-	constructor: function(inGrid){
-		inGrid.mixin(inGrid, this);
-	},
+	//name: [const] Array
+	//		menu types
+	types: ['headerMenu', 'rowMenu', 'cellMenu', 'selectedRegionMenu'],
 	
-	_initMenus: function(){
-		//summary:
-		//		Initilize all the required menus
-		var wrapper = this.menuContainer;
-		!this.headerMenu && (this.headerMenu = this._getMenuWidget(this.menus['headerMenu']));		
-		!this.rowMenu && (this.rowMenu = this._getMenuWidget(this.menus['rowMenu']));
-		!this.cellMenu && (this.cellMenu = this._getMenuWidget(this.menus['cellMenu']));
-		!this.selectedRegionMenu && (this.selectedRegionMenu = this._getMenuWidget(this.menus['selectedRegionMenu']));
-		this.headerMenu && this.set('headerMenu', this.headerMenu) && this.setupHeaderMenu();
-		this.rowMenu && this.set('rowMenu', this.rowMenu);
-		this.cellMenu && this.set('cellMenu', this.cellMenu);
-		this.isDndSelectEnable && this.selectedRegionMenu && dojo.connect(this.select, 'setDrugCoverDivs', dojo.hitch(this, this._bindDnDSelectEvent));
+	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');
 	},
-	
-	_getMenuWidget: function(menuId){
-		//summary:
-		//		Fetch the required menu widget(should already been created)
-		//menuId: String
-		//		Id of the target menu widget
-		//return: Widget
-		//		Target menu widget
-		if(!menuId){
-			return;
+	onStartUp: function(){
+		var type, option = this.option;
+		for(type in option){
+			if(dojo.indexOf(this.types, type) >= 0 && option[type]){
+				this._initMenu(type, option[type]);
+			}
 		}
-		var menu = dijit.byId(menuId);
-		if(!menu){
-			throw new Error("Menu '" + menuId +"' not existed");	
+	},
+	_initMenu: function(/*String*/menuType, /*String | Widget(dijit.Menu)*/menu){
+		var g = this.grid;
+		if(!g[menuType]){//in case already created in _Grid.postCreate()
+			var m = this._getMenuWidget(menu);
+			if(!m){return;}
+			g.set(menuType, m);
+			if(menuType != "headerMenu"){
+				m._scheduleOpen = function(){return;};
+			}
 		}
-		return menu;
 	},
-
-	_bindDnDSelectEvent: function(){
-		//summary:
-		//		Hook callback to DnD, so othat appropriate menu will be shown on selected regions	
-		dojo.forEach(this.select.coverDIVs, dojo.hitch(this, function(cover){
-			//this.selectedRegionMenu.unBindDomNode(this.domNode);
-			this.selectedRegionMenu.bindDomNode(cover);
-			dojo.connect(cover, "contextmenu", dojo.hitch(this, function(e){
-				dojo.mixin(e, this.select.getSelectedRegionInfo());
-				this.onSelectedRegionContextMenu(e);
-			}));
-		}));
+	_getMenuWidget: function(/*String|Widget(dijit.Menu)*/menu){
+		// summary:
+		//		Fetch the required menu widget(should already been created)
+		return (menu instanceof dijit.Menu) ? menu : dijit.byId(menu);
 	},
-	
-	_setRowMenuAttr: function(menu){
-		//summary:
+	_setRowMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+		// summary:
 		//		Set row menu widget
-		//menu: Widget - dijit.Menu
-		//		Row menu widget
-		this._setRowCellMenuAttr(menu, 'rowMenu');
+		this._setMenuAttr(menu, 'rowMenu');
 	},
-	
-	_setCellMenuAttr: function(menu){
-		//summary:
+	_setCellMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+		// summary:
 		//		Set cell menu widget
-		//menu: Widget - dijit.Menu
-		//		Cell menu widget		
-		this._setRowCellMenuAttr(menu, 'cellMenu');
+		this._setMenuAttr(menu, 'cellMenu');
 	},
-	
-	_setRowCellMenuAttr: function(menu, menuType){
-		//summary:
-		//		Bind menus to Grid
-		//menu: Widget - dijit.Menu
-		//		Menu widget	
-		//menuType: String
-		//		Menu type
-		if(!menu){ return; }
-		if(this[menuType]){
-			this[menuType].unBindDomNode(this.domNode);
+	_setSelectedRegionMenuAttr: function(/*Widget(dijit.Menu)*/menu){
+		// summary:
+		//		Set row menu widget
+		this._setMenuAttr(menu, 'selectedRegionMenu');
+	},
+	_setMenuAttr: function(/*Widget(dijit.Menu)*/menu, /*String*/menuType){
+		// summary:
+		//		Bind menus to Grid.
+		var g = this.grid, n = g.domNode;
+		if(!menu || !(menu instanceof dijit.Menu)){
+			console.warn(menuType, " of Grid ", g.id, " is not existed!");
+			return;
 		}
-		this[menuType] = menu;
-		this[menuType].bindDomNode(this.domNode);
+		if(g[menuType]){
+			g[menuType].unBindDomNode(n);
+		}
+		g[menuType] = menu;
+		g[menuType].bindDomNode(n);
 	},
-
-	// TODO: this code is not accessible.  Shift-F10 won't open a menu.  (I think
-	// this function never even gets called.)
-	showRowCellMenu: function(e){
-		//summary:
-		//		Show row or cell menus
-		//e: Event
-		//		Fired from dojox.grid.enhanced._Events.onRowContextMenu
-		var inRowSelectorView = e.sourceView.declaredClass == 'dojox.grid._RowSelector';
-		// !e.cell means the cell is in the rowbar.
-		// this.selection.isSelected(e.rowIndex) should remove?
-		//if(this.rowMenu && (!e.cell || this.selection.isSelected(e.rowIndex)) && (!this.focus.cell || this.focus.cell != e.cell)){
-		if(this.rowMenu && (!e.cell || this.selection.isSelected(e.rowIndex))){
-			this.rowMenu._openMyself({
-				target: e.target,
-				coords: "pageX" in e ? {
-					x: e.pageX,
-					y: e.pageY
-				} : null
-			});
-			dojo.stopEvent(e);
+	showMenu: function(/*Event*/e){
+		// summary:
+		//		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')));
+		
+		if(inSelectedRegion && this.selectedRegionMenu){
+			this.onSelectedRegionContextMenu(e);
 			return;
 		}
-		if(inRowSelectorView || e.cell && e.cell.isRowSelector){
+		
+		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'))){
+			this.rowMenu._openMyself(info);
 			dojo.stopEvent(e);
-			return;	
-		}
-		if(this.isDndSelectEnable) {
-			this.select.cellClick(e.cellIndex, e.rowIndex);
-			this.focus.setFocusCell(e.cell, e.rowIndex);
+			return;
 		}
+
 		if(this.cellMenu){
-			this.cellMenu._openMyself({
-				target: e.target,
-				coords: "pageX" in e ? {
-					x: e.pageX,
-					y: e.pageY
-				} : null
-			});
+			this.cellMenu._openMyself(info);
 		}
+		dojo.stopEvent(e);
+	},
+	destroy: function(){
+		// summary:
+		//		Destroy all resources.
+		//		_Grid.destroy() will unbind headerMenu
+		var g = this.grid;
+		if(g.headerMenu){g.headerMenu.unBindDomNode(g.viewsHeaderNode);}
+		if(g.rowMenu){g.rowMenu.unBindDomNode(g.domNode);}
+		if(g.cellMenu){g.cellMenu.unBindDomNode(g.domNode);}
+		if(g.selectedRegionMenu){g.selectedRegionMenu.destroy();}
+		this.inherited(arguments);
 	}
 });
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Menu/*name:'menus'*/);
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/NestedSorting.js b/dojox/grid/enhanced/plugins/NestedSorting.js
index ec4e62a..c0b9970 100644
--- a/dojox/grid/enhanced/plugins/NestedSorting.js
+++ b/dojox/grid/enhanced/plugins/NestedSorting.js
@@ -1,1308 +1,591 @@
 dojo.provide("dojox.grid.enhanced.plugins.NestedSorting");
 
-dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", null, {
-	//	summary:
-	//		 Provides nested sorting feature
-	// example:
-	// 		 <div dojoType="dojox.grid.EnhancedGrid" plugins="{nestedSorting: true}" ...></div>
+dojo.require("dojox.grid.enhanced._Plugin");
 
-	//sortAttrs: Array
-	//		Sorting attributes, e.g.[{attr: 'col1', asc: 1|-1|0, cell: cell, cellNode: node}, {...}, ...]
-	sortAttrs: [],
+dojo.declare("dojox.grid.enhanced.plugins.NestedSorting", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Provides nested sorting feature
+	//
+	// description:
+	//		A flexible way to control multiple column sorting, including
+	//		1. Set default sorting order
+	//		2. Disable sorting for certain columns
+	//		3. Set sorting order dynamically with JS API
+	//
+	// example:
+	// |	<script type="text/javascript">
+	// |		var grid = new dojox.grid.EnhancedGrid({plugins : {nestedSorting: true}},
+	// |	               sortFields: [{attribute: 'col4', descending: false},...],//set default sorting order
+	// |			       canSort: function(index, field){ return true},//disable sorting for a column
+	// |				   ... }, dojo.byId('gridDiv'));
+	// |		grid.startup();
+	// |		//set new sorting order
+	// |		grid.setSortIndex([{attribute: 'col3', descending: true},...])
+	// |	</script>
 	
-	//_unarySortCell: Object
-	//		Cache for the current unary sort cell(the 1st column in sorting sequence)
-	//		will be set as {cell: cell, cellNode: node}
-	_unarySortCell:{},
+	// name: String
+	//		Plugin name
+	name: "nestedSorting",
 	
-	//_minColWidth: Integer
-	//		Used for calculating min cell width, will be updated dynamically
-	_minColWidth: 63,//58
-
-	//_widthDelta: Integer
-	//		Min width delta
-	_widthDelta: 23,//18
+	_currMainSort: 'none',//'none'|'asc'|'desc'
 	
-	//_minColWidthUpdated: Boolean
-	//		Flag to indicate whether the min col width has been updated
-	_minColWidthUpdated: false,
-
-	//_sortTipMap: Object
-	//		Cache the tip on/off status for each cell, e.g. {cellIndex: true|false}
-	_sortTipMap:{},
+	_currRegionIdx: -1,
 	
-	//_overResizeWidth: Integer
-	//		Overwrite the default over resize width, 
-	//		so that the resize cursor is more obvious when leveraged with sorting hover tips
-	_overResizeWidth: 3,
-
-	//storeItemSelected: String
-	//		Attribute used in data store to mark which row(s) are selected accross sortings
-	storeItemSelected: 'storeItemSelectedAttr',
-
-	//exceptionalSelectedItems: Array
-	//		Cache data store items with exceptional selection state.
-	//		Used to retain selection states accross sortings. User may first select/deselect all rows
-	//		and then deselect/select certain rows, these later changed rows have a different state
-	//		with the global selection state, that is exceptional selection state
-	exceptionalSelectedItems: [],
-
-	//_a11yText: Object
-	//		Characters for sorting arrows, used for a11y high contrast mode
 	_a11yText: {
 		'dojoxGridDescending'   : '▾',
 		'dojoxGridAscending'    : '▴',
-		'dojoxGridAscendingTip' : '۸',	
+		'dojoxGridAscendingTip' : '۸',
 		'dojoxGridDescendingTip': '۷',
 		'dojoxGridUnsortedTip'  : 'x' //'✖'
 	},
 	
-	constructor: function(inGrid){
-		// summary:
-		//		Mixin in all the properties and methods into DataGrid		
-		inGrid.mixin(inGrid, this);		
-		//init views
-		dojo.forEach(inGrid.views.views, function(view){
-			//some init work for the header cells
-			dojo.connect(view, 'renderHeader', dojo.hitch(view, inGrid._initSelectCols));	
-			dojo.connect(view.header, 'domousemove', view.grid, '_sychronizeResize');					
-		});	
-		//init sorting
-		this.initSort(inGrid);	
-		//keep selection after sorting if required		
-		inGrid.keepSortSelection && dojo.connect(inGrid, '_onFetchComplete', inGrid, 'updateNewRowSelection');
-		
-		if(inGrid.indirectSelection && inGrid.rowSelectCell.toggleAllSelection){
-			dojo.connect(inGrid.rowSelectCell, 'toggleAllSelection', inGrid, 'allSelectionToggled');			
-		}
-		
-		dojo.subscribe(inGrid.rowMovedTopic, inGrid, inGrid.clearSort);		
-		dojo.subscribe(inGrid.rowSelectionChangedTopic, inGrid, inGrid._selectionChanged);
-		
-		//init focus manager for nested sorting
-		inGrid.focus.destroy();
-		inGrid.focus = new dojox.grid.enhanced.plugins._NestedSortingFocusManager(inGrid);
-		
-		//set a11y ARAI information
-		dojo.connect(inGrid.views, 'render', inGrid, 'initAriaInfo');
-	},
-	
-	initSort: function(inGrid){
-		// summary:
-		//		initiate sorting		
-		inGrid.getSortProps = inGrid._getDsSortAttrs;
-		//TODO - set default sorting order
-	},
-	
-	setSortIndex: function(inIndex, inAsc, e){
-		// summary:
-		//		Sorting entry that overwrites parent(_Grid.js) when nested sorting is enabled
-		// 		Sort the grid on multiple columns in a nested sorting sequence
-		// inIndex: Integer
-		// 		Column index on which to sort.
-		// inAsc: Integer
-		// 		1:  sort the target column in ascending order
-		//		-1: sort the target column in descending order
-		//      0:  revert the target column back to unsorted state
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		if(!this.nestedSorting){
-			this.inherited(arguments);
-		}else{
-			//cache last selection status
-			this.keepSortSelection && this.retainLastRowSelection();			
-			//var desc = c["sortDesc"]; //TODO when is c["sortDesc"] used?
-			this.inSorting = true;
-			this._toggleProgressTip(true, e); //turn on progress cursor
-			this._updateSortAttrs(e, inAsc);
-			this.focus.addSortFocus(e);
-			if(this.canSort()){
-				this.sort();
-				this.edit.info = {};
-				this.update();
+	constructor: function(){
+		this._sortDef = [];
+		this._sortData = {};
+		this._headerNodes = {};
+		//column index that are hidden, un-sortable or indirect selection etc.
+		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');
+		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'));
+	},
+	onStartUp: function(){
+		//overwrite base Grid functions
+		this.inherited(arguments);
+		this.connect(this.grid, 'onHeaderCellClick', '_onHeaderCellClick');
+		this.connect(this.grid, 'onHeaderCellMouseOver', '_onHeaderCellMouseOver');
+		this.connect(this.grid, 'onHeaderCellMouseOut', '_onHeaderCellMouseOut');
+	},
+	_onColumnDnD: function(type, mapping){
+		// summary:
+		//		Update nested sorting after column moved		
+		if(type !== 'col'){return;}
+		var m = mapping, obj = {}, d = this._sortData, p;
+		var cr = this._getCurrentRegion();
+		this._blurRegion(cr);
+		var idx = dojo.attr(this._getRegionHeader(cr), 'idx');
+		for(p in m){
+			if(d[p]){
+				obj[m[p]] = d[p];
+				delete d[p];
 			}
-			this._toggleProgressTip(false, e);//turn off progress cursor
-			this.inSorting = false;
-		}
-	},
-	
-	_updateSortAttrs: function(e, inAsc){
-		// summary:
-		//		 Update the sorting sequence
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		// inAsc: Integer
-		// 		1:  sort the target column in ascending order
-		//		-1: sort the target column in descending order
-		//      0:  revert the target column back to unsorted state
-		var existing = false;
-		var unarySort = !!e.unarySortChoice;//true - unary sort | false - nested sort
-		if(unarySort){
-			//unary sort
-			var cellSortInfo = this.getCellSortInfo(e.cell);
-			var asc  = (this.sortAttrs.length > 0 && cellSortInfo["sortPos"] != 1) ? cellSortInfo["unarySortAsc"]
-					    : this._getNewSortState(cellSortInfo["unarySortAsc"]);
-			if(asc && asc != 0){
-				//update unary sorting info 
-				this.sortAttrs = [{attr: e.cell.field, asc: asc, cell: e.cell, cellNode: e.cellNode}];
-				this._unarySortCell = {cell: e.cell, node: e.cellNode};
-			}else{
-				//asc = 0, so empty sorting sequence
-				this.sortAttrs = [];
-				this._unarySortCell = null;
+			if(p === idx){
+				idx = m[p];
 			}
-		}else{
-			//nested sort
-			this.setCellSortInfo(e, inAsc);
 		}
-	},
-	
-	getCellSortInfo: function(cell){
-		// summay: 
-		//		Get sorting info of the cell
-		// cell: Cell
-		//		Target header cell
-		// return:
-		//		Sort info e.g. {unarySortAsc: 1|-1|0, nestedSortAsc: 1|-1|0, sortPos:1|2...}
-		if(!cell){return false;}
-		var cellSortInfo = null;
-		var _sortAttrs = this.sortAttrs;
-		dojo.forEach(_sortAttrs, function(attr, index, attrs){
-			if(attr && attr["attr"] == cell.field && attr["cell"] == cell){
-				cellSortInfo = {unarySortAsc: attrs[0] ? attrs[0]["asc"] : undefined,
-								nestedSortAsc:attr["asc"],
-								sortPos: index + 1
+		for(p in obj){
+			d[p] = obj[p];
+		}
+		var c = this._headerNodes[idx];
+		this._currRegionIdx = dojo.indexOf(this._getRegions(), c.firstChild);
+		this._initSort(false);
+	},
+	_setGridSortIndex: function(inIndex, inAsc, noRefresh){
+		if(dojo.isArray(inIndex)){
+			var i, d, cell;
+			for(i = 0; i < inIndex.length; i++){
+				d = inIndex[i];
+				cell = this.grid.getCellByField(d.attribute);
+				if(!cell){
+					console.warn('Invalid sorting option, column ', d.attribute, ' not found.');
+					return;
 				}
-			}
-		});
-		return cellSortInfo ? cellSortInfo : {unarySortAsc: _sortAttrs && _sortAttrs[0] ? _sortAttrs[0]["asc"] : undefined, 
-								              nestedSortAsc: undefined, sortPos:-1};
-	},
-	
-	setCellSortInfo: function(e, inAsc){
-		// summary:
-		//		Update nested sorting sequence with the new state of target cell
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		// inAsc: Integer
-		// 		1:  sort the target column in ascending order
-		//		-1: sort the target column in descending order
-		//      0:  revert the target column back to unsorted state
-		var cell = e.cell;
-		var existing = false;
-		var delAttrs = [];//cells to be removed from sorting sequence
-		var _sortAttrs = this.sortAttrs;
-		dojo.forEach(_sortAttrs, dojo.hitch(this, function(attr, index){
-			if(attr && attr["attr"] == cell.field){
-				var si = inAsc ? inAsc : this._getNewSortState(attr["asc"]);
-				if(si == 1 || si == -1){
-					attr["asc"] = si;
-				}else if(si == 0){
-					delAttrs.push(index);
-				}else{
-					throw new Exception('Illegal nested sorting status - ' + si);
+				if(cell['nosort'] || !this.grid.canSort(cell.index, cell.field)){
+					console.warn('Invalid sorting option, column ', d.attribute, ' is unsortable.');
+					return;
 				}
-				existing = true;
-			}
-		}));
-		
-		var minus = 0;
-		//remove unsorted columns from sorting sequence
-		dojo.forEach(delAttrs, function(delIndex){
-			_sortAttrs.splice((delIndex - minus++), 1);
-		});
-		//add new column to sorting sequence
-		if(!existing){
-			var si = inAsc ? inAsc : 1;
-			if(si != 0){
-				_sortAttrs.push({
-					attr: cell.field,
-					asc: si,
-					cell: e.cell,
-					cellNode: e.cellNode
-				});
 			}
+			this.clearSort();
+			dojo.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');
+			}, this);
+		}else if(!isNaN(inIndex)){
+			if(inAsc === undefined){ return; }//header click from base DataGrid
+			this.setSortData(inIndex, 'order', inAsc ? 'asc' : 'desc');
+		}else{
+			return;
 		}
-		//cache unary sort cell
-		if(delAttrs.length > 0){
-			this._unarySortCell = {cell: _sortAttrs[0]['cell'], node: _sortAttrs[0]['cellNode']};
+		this._updateSortDef();
+		if(!noRefresh){
+			this.grid.sort();
 		}
 	},
-	
-	_getDsSortAttrs: function(){
+	getSortProps: function(){
 		// summary:
-		//		Get the sorting attributes for Data Store
-		// return: Object
-		//		Sorting attributes used by Data Store e.g. {attribute: 'xxx', descending: true|false}
-		var dsSortAttrs = [];
-		var si = null;
-		dojo.forEach(this.sortAttrs, function(attr){
-			if(attr && (attr["asc"] == 1 || attr["asc"] == -1)){
-				dsSortAttrs.push({attribute:attr["attr"], descending: (attr["asc"] == -1)});
-			}
-		});
-		return dsSortAttrs.length > 0 ? dsSortAttrs : null;
-	},
-	
-	_getNewSortState: function(si/*int 1|-1|0*/){
-		//summay:
-		//		Get the next sort sate
-		//si: Integer
-		//		Current sorting state
-		//return: Integer
-		//		Next new sorting state
-		return si ? (si == 1 ? -1 : (si == -1 ? 0 : 1)) : 1;
+		//		Overwritten, see DataGrid.getSortProps()
+		return this._sortDef.length ? this._sortDef : null;
 	},
-	
-	sortStateInt2Str: function(si){
-		//summay: 
-		//		Map sort sate from integer to string
-		//si: Integer
-		//		Sorting state integer
-		//return: String
-		//		Sort info string
-		if(!si){
-			return 'Unsorted';
-		}
-		switch (si){
-			case 1:
-				return 'Ascending';//'SortUp';
-			case -1:
-				return 'Descending';//'SortDown';
-			default:
-				return 'Unsorted';
+	_initSort: function(postSort){
+		// 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);
+		if(len > 0){
+			this._currMainSort = this._sortDef[0].descending ? 'desc' : 'asc';
 		}
-	}, 
-	
-	clearSort: function(){
-		//summay: 
-		//		Clear the sorting sequence
-		dojo.query("[id*='Sort']", this.viewsHeaderNode).forEach(function(region){
-			dojo.addClass(region, 'dojoxGridUnsorted');
+		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']))){
+				excluded.push(idx);
+			}
 		});
-		this.sortAttrs = [];
-		this.focus.clearHeaderFocus();
-	},
-	
-	_getNestedSortHeaderContent: function(inCell){
-		//summay: 
-		//		Callback to render the innHTML for a header cell, 
-		//		see _View.renderHeader() and _View.header.generateHtml()
-		//inCell: Cell
-		//		Header cell for rendering
-		//return: String
-		//		InnerHTML for the header cell
-		var n = inCell.name || inCell.grid.getCellName(inCell);
-		if(inCell.grid.pluginMgr.isFixedCell(inCell)){
-			return [
-				'<div class="dojoxGridCellContent">',
-				n,
-				'</div>'
-			].join('');
+		this._headerNodes.forEach(this._initHeaderNode, this);
+		this._initFocus();
+		if(postSort){
+			this._focusHeader();
 		}
-		
-		//e.g.{unarySortAsc: 1|-1|0, nestedSortAsc: 1|-1|0, sortPos:1|2...}
-		var cellSortInfo = inCell.grid.getCellSortInfo(inCell);
-		var _sortAttrs = inCell.grid.sortAttrs;
-		var inNestedSort = (_sortAttrs && _sortAttrs.length > 1 && cellSortInfo["sortPos"] >= 1);
-		var inUnarySort =  (_sortAttrs && _sortAttrs.length == 1 && cellSortInfo["sortPos"] == 1);
-		
-		var _grid = inCell.grid;
-		var ret	= ['<div class="dojoxGridSortRoot">',
-		              '<div class="dojoxGridSortWrapper">',
-	 					   //[0] => select-sort Separator
-					   	   '<span id="selectSortSeparator' + inCell.index+ '" class="dojoxGridSortSeparatorOff"></span>', 						   
-						   '<span class="dojoxGridNestedSortWrapper" tabindex="-1">',
-							   //[1] => nested sort position
-							   '<span id="' + inCell.view.id + 'SortPos' + inCell.index + '" class="dojoxGridSortPos ' + (inNestedSort ? '' : 'dojoxGridSortPosOff') + '">' + 
-							   (inNestedSort ? cellSortInfo["sortPos"] : '') + '</span>',
-				
-							   //[2] => nested sort choice
-							   '<span id="nestedSortCol' + inCell.index  + '" class="dojoxGridSort dojoxGridNestedSort ' + 
-							   (inNestedSort ? ('dojoxGrid'+ _grid.sortStateInt2Str(cellSortInfo["nestedSortAsc"])) : 'dojoxGridUnsorted') + '">',
-							   _grid._a11yText['dojoxGrid' + _grid.sortStateInt2Str(cellSortInfo["nestedSortAsc"])] || '.',
-							   '</span>',
-						   '</span>',
-						   	
-						   //[3] => sortSeparator mark
-						   '<span id="SortSeparator' + inCell.index + '" class="dojoxGridSortSeparatorOff"></span>',
-							
-						   //[4] => unary sort choice position
-						   //only shown when this cell is the only one in sort sequence
-						   '<span class="dojoxGridUnarySortWrapper" tabindex="-1"><span id="unarySortCol' + inCell.index  + '" class="dojoxGridSort dojoxGridUnarySort ' + 
-						   (inUnarySort ? ('dojoxGrid'+ _grid.sortStateInt2Str(cellSortInfo["unarySortAsc"])) : 'dojoxGridUnsorted') + '">',
-						   _grid._a11yText['dojoxGrid' + _grid.sortStateInt2Str(cellSortInfo["unarySortAsc"])] || '.',
-						   '</span></span>',
-				   '</div>',						
-				   //[5] => select region
-					 '<div tabindex="-1" id="selectCol' + inCell.index  + '" class="dojoxGridHeaderCellSelectRegion"><span id="caption' + inCell.index + '">' + n + '<span></div>',
-				 '</div>'
-		];
-		return ret.join('');
 	},
-
-	
-	addHoverSortTip: function(e){
+	_initHeaderNode: function(node){
 		// summary:
-		//		Add sorting tip for target cell
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		this._sortTipMap[e.cellIndex] = true;
-		
-		var cellSortInfo = this.getCellSortInfo(e.cell);
-		if(!cellSortInfo){return;} 
-
-		//get all related region elements 
-		var elements = this._getCellElements(e.cellNode);
-		if(!elements){return;}
-		
-		var _sortAttrs = this.sortAttrs;	
-		//Grid has not been sorted			
-		var notSorted = !_sortAttrs || _sortAttrs.length < 1;		
-		//only this cell is in sorting sequence
-		var inUnarySort = (_sortAttrs && _sortAttrs.length == 1 && cellSortInfo["sortPos"] == 1);
-		
-		dojo.addClass(elements['selectSortSeparator'], "dojoxGridSortSeparatorOn");
-
-		if(notSorted || inUnarySort){
-			this._addHoverUnarySortTip(elements, cellSortInfo, e);
-		}else{
-			//if in nested sort - "this" cell sort position > 1, then set nested sort state
-			this._addHoverNestedSortTip(elements, cellSortInfo, e);
-			//update the min cell width for column resizing
-			this.updateMinColWidth(elements['nestedSortPos']);			
+		//		Initiate sort for each header cell node
+		var sortNode = dojo.query('.dojoxGridSortNode', node)[0];
+		if(sortNode){
+			dojo.toggleClass(sortNode, 'dojoxGridSortNoWrap', true);
 		}
-				
-		var selectRegion = elements['selectRegion'];
-		this._fixSelectRegion(selectRegion);//resize selection region
-		if(!dijit.hasWaiRole(selectRegion)){
-			dijit.setWaiState(selectRegion, 'label', 'Column ' + (e.cellIndex + 1) + ' ' +  e.cell.field);
+		if(dojo.indexOf(this._excludedCoIdx, dojo.attr(node,'idx')) >= 0){
+			dojo.addClass(node, 'dojoxGridNoSort');
+			return;
 		}
-		
-		this._toggleHighlight(e.sourceView, e);		
-		this.focus._updateFocusBorder();
-	},
-	
-	_addHoverUnarySortTip: function(elements, cellSortInfo, e){
-		// summary:
-		//		Add hover tip for unary sorting
-		// elements: Object
-		//		Json object contains all dom nodes of sort regions
-		// cellSortInfo: Object
-		//		Json object that contains detail sorting info
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-				
-		//this cell would be or is already the single unary cell
-		dojo.addClass(elements['nestedSortWrapper'], "dojoxGridUnsorted");
-		var stateStr = this.sortStateInt2Str(this._getNewSortState(cellSortInfo["unarySortAsc"]));
-		dijit.setWaiState(elements['unarySortWrapper'], 'label', 'Column ' + (e.cellIndex + 1) + ' ' + e.cell.field + ' - Choose ' + stateStr.toLowerCase() + ' single sort');
-		//set unary sort state
-		var className = "dojoxGrid" + stateStr +"Tip";
-		dojo.addClass(elements['unarySortChoice'], className);
-		elements['unarySortChoice'].innerHTML = this._a11yText[className];
-		this._addTipInfo(elements['unarySortWrapper'], this._composeSortTip(stateStr, 'singleSort'));
-	},
-	
-	_addHoverNestedSortTip: function(elements, cellSortInfo, e){
-		// summary:
-		//		Add hover tip for nested sorting
-		// elements: Object
-		//		Json object contains all dom nodes of sort regions
-		// cellSortInfo: Object
-		//		Json object that contains detail sorting info
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.		
-		var nestedSortPos     = elements['nestedSortPos'];
-		var unarySortWrapper  = elements['unarySortWrapper'];
-		var nestedSortWrapper = elements['nestedSortWrapper'];
-		var _sortAttrs = this.sortAttrs;
-		
-		dojo.removeClass(nestedSortWrapper, "dojoxGridUnsorted");
-		var stateStr = this.sortStateInt2Str(this._getNewSortState(cellSortInfo["nestedSortAsc"]));
-		dijit.setWaiState(nestedSortWrapper, 'label', 'Column ' + (e.cellIndex + 1) + ' ' + e.cell.field + ' - Choose ' + stateStr.toLowerCase() + ' nested sort');				
-		var className = "dojoxGrid" + stateStr +"Tip";
-		this._addA11yInfo(elements['nestedSortChoice'], className);
-		this._addTipInfo(nestedSortWrapper, this._composeSortTip(stateStr, 'nestedSort'));
-		
-		//set unary sort state
-		stateStr = this.sortStateInt2Str(cellSortInfo["unarySortAsc"]);
-		dijit.setWaiState(unarySortWrapper, 'label', 'Column ' + (e.cellIndex + 1) + ' ' + e.cell.field + ' - Choose ' + stateStr.toLowerCase() + ' single sort');		
-		className = "dojoxGrid" + stateStr +"Tip";
-		this._addA11yInfo(elements['unarySortChoice'], className);
-		this._addTipInfo(unarySortWrapper, this._composeSortTip(stateStr, 'singleSort'));			
-		
-		//show separator
-		dojo.addClass(elements['sortSeparator'], "dojoxGridSortSeparatorOn");
-		dojo.removeClass(nestedSortPos, "dojoxGridSortPosOff");
-		
-		//set sort position info
-		if(cellSortInfo["sortPos"] < 1){
-			//this would be a new cell to sort sequence, a new sort position is needed
-			nestedSortPos.innerHTML = (_sortAttrs ? _sortAttrs.length : 0) + 1;
-			if(!this._unarySortInFocus() && _sortAttrs && _sortAttrs.length == 1){
-				//this cell will be in the 2nd sort position, sort position info should be turn on for unary sort column				
-				var unaryNode = this._getUnaryNode();
-				unaryNode.innerHTML = '1';
-				dojo.removeClass(unaryNode, "dojoxGridSortPosOff");
-				dojo.removeClass(unaryNode.parentNode, "dojoxGridUnsorted");
-				this._fixSelectRegion(this._getCellElements(unaryNode)['selectRegion']);						
+		if(!dojo.query('.dojoxGridSortBtn', node).length){
+			//clear any previous connects
+			this._connects = dojo.filter(this._connects, function(conn){
+				if(conn._sort){
+					dojo.disconnect(conn);
+					return false;
+				}
+				return true;
+			});
+			var n = dojo.create('a', {
+				className: 'dojoxGridSortBtn dojoxGridSortBtnNested',
+				title: this.nls.nestedSort + ' - ' + this.nls.ascending,
+				innerHTML: '1'
+			}, node.firstChild, 'last');
+			n.onmousedown = dojo.stopEvent;
+			n = dojo.create('a', {
+				className: 'dojoxGridSortBtn dojoxGridSortBtnSingle',
+				title: this.nls.singleSort + ' - ' + this.nls.ascending
+			}, node.firstChild, 'last');
+			n.onmousedown = dojo.stopEvent;
+		}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];
+			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');
+		}
+		this._updateHeaderNodeUI(node);
+	},
+	_onHeaderCellClick: function(e){
+		// summary
+		//		See dojox.grid.enhanced._Events._onHeaderCellClick()
+		this._focusRegion(e.target);
+		if(dojo.hasClass(e.target, 'dojoxGridSortBtn')){
+			this._onSortBtnClick(e);
+			dojo.stopEvent(e);
+			this._focusRegion(this._getCurrentRegion());
+		}
+	},
+	_onHeaderCellMouseOver: function(e){
+		// summary
+		//		See dojox.grid._Events._onHeaderCellMouseOver()
+		//		When user mouseover other columns than sorted column in a single sorted grid,
+		//		We need to show 1 in the sorted column
+		if(!e.cell){return; }
+		if(this._sortDef.length > 1){ return; }
+		if(this._sortData[e.cellIndex] && this._sortData[e.cellIndex].index === 0){ return; }
+		var p;
+		for(p in this._sortData){
+			if(this._sortData[p] && this._sortData[p].index === 0){
+				dojo.addClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+				break;
 			}
 		}
-	},
-	
-	_unarySortInFocus: function(){
-		// summary:
-		//		See if the unary sort node is in keyboard focus
-		// return: Boolean
-		return this._unarySortCell.cell && this.focus.headerCellInFocus(this._unarySortCell.cell.index);
-	},
-	
-	_composeSortTip: function(state, type){
-		// summary:
-		//		Get properties from nls bundle and compose appropriate sorting tips
-		// state: String
-		//		Sorting state
-		// type: String
-		//		Sorting type
-		state = state.toLowerCase();
-		if(state == "unsorted"){
-			return this._nls[state];
+		if(!dojo.hasClass(dojo.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 sortMode = 'none';
+		if(dojo.hasClass(this.grid.domNode, 'dojoxGridSingleSorted')){
+			sortMode = 'single';
+		}else if(dojo.hasClass(this.grid.domNode, 'dojoxGridNestSorted')){
+			sortMode = 'nested';
+		}
+		var nestedIndex = dojo.attr(nestedSortBtn, 'orderIndex');
+		if(nestedIndex === null || nestedIndex === undefined){
+			dojo.attr(nestedSortBtn, 'orderIndex', nestedSortBtn.innerHTML);
+			nestedIndex = nestedSortBtn.innerHTML;
+		}
+		if(this.isAsc(i)){
+			nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridDescending;
+		}else if(this.isDesc(i)){
+			nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridUnsortedTip;
 		}else{
-			var tip = dojo.string.substitute(this._nls['sortingState'], [this._nls[type], this._nls[state]]);
-			return tip;
-		}
-	},
-	
-	_addTipInfo: function(node, text){
-		// summary:
-		//		Add title tip to target node and also all the descendants
-		// node: Dom node
-		//		Target node
-		// text: String
-		//		Tip string		
-		dojo.attr(node, 'title', text);
-		dojo.query('span', node).forEach(function(n){
-			dojo.attr(n, 'title', text);
-		});
-	},
-
-	_addA11yInfo:function(node,className){
-		// summary:
-		//		Add related class and a11y sorting arrow character
-		// node: Dom node
-		//		Decorated event object which contains reference to grid, target cell etc.	
-		// className: String
-		//		CSS class name mapped to a11y sorting arrow character
-		dojo.addClass(node, className);
-		node.innerHTML = this._a11yText[className];
-	},
-	
-	removeHoverSortTip: function(e){
-		// summary:
-		//		Remove sorting tip for target cell
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		if(!this._sortTipMap[e.cellIndex]){return; /*tip already removed*/}
-
-		var cellSortInfo = this.getCellSortInfo(e.cell);
-		if(!cellSortInfo){return;} 
-
-		//get all related region elements 
-		var elements = this._getCellElements(e.cellNode);
-		if(!elements){return;}
-
-		var nestedSortChoice  = elements.nestedSortChoice;
-		var unarySortChoice   = elements.unarySortChoice;
-		var unarySortWrapper  = elements.unarySortWrapper;
-		var nestedSortWrapper = elements.nestedSortWrapper;
-		
-		//remove all highlights
-		this._toggleHighlight(e.sourceView, e, true);
-		
-		//dojo.removeClass doesn't support Reg Exp?
-		function _removeTipClass(nodes){
-			dojo.forEach(nodes, function(node){
-				var newClasses = dojo.trim((" " + node["className"] + " ").replace(/\sdojoxGrid\w+Tip\s/g, " "));
-				if(node["className"] != newClasses){ node["className"] = newClasses; }
-			});
-		}
-		_removeTipClass([nestedSortChoice, unarySortChoice]);
-		
-		unarySortChoice.innerHTML = this._a11yText['dojoxGrid' + this.sortStateInt2Str(cellSortInfo["unarySortAsc"])] || '.';
-		nestedSortChoice.innerHTML = this._a11yText['dojoxGrid' + this.sortStateInt2Str(cellSortInfo["nestedSortAsc"])] || '.';
-		
-		dojo.removeClass(elements['selectSortSeparator'], "dojoxGridSortSeparatorOn");
-		dojo.removeClass(elements['sortSeparator'], "dojoxGridSortSeparatorOn");
-		
-		if(cellSortInfo["sortPos"] == 1 && this.focus.isNavHeader() && !this.focus.headerCellInFocus(e.cellIndex)){
-			dojo.removeClass(elements['nestedSortWrapper'], "dojoxGridUnsorted");
-		}
-
-		var _sortAttrs = this.sortAttrs;
-		if(!isNaN(cellSortInfo["sortPos"])/* fix sortPos missed issue*/ && cellSortInfo["sortPos"] < 1){
-			//sort position info for this cell should also be cleared
-			elements['nestedSortPos'].innerHTML = "";	
-			dojo.addClass(nestedSortWrapper, "dojoxGridUnsorted");
-			if(!this.focus._focusBorderBox && _sortAttrs && _sortAttrs.length == 1){
-				//clear the sort position info for unary sort column
-				var unaryNode = this._getUnaryNode();
-				unaryNode.innerHTML = '';
-				dojo.addClass(unaryNode, "dojoxGridSortPosOff");
-				this._fixSelectRegion(this._getCellElements(unaryNode)['selectRegion']);						
+			nestedSortBtn.innerHTML = nestedIndex + this._a11yText.dojoxGridAscending;
+		}
+		if(this._currMainSort === 'none'){
+			singleSortBtn.innerHTML = this._a11yText.dojoxGridAscending;
+		}else if(this._currMainSort === 'asc'){
+			singleSortBtn.innerHTML = this._a11yText.dojoxGridDescending;
+		}else if(this._currMainSort === 'desc'){
+			singleSortBtn.innerHTML = this._a11yText.dojoxGridUnsortedTip;
+		}
+	},
+	_onHeaderCellMouseOut: function(e){
+		// summary
+		//		See dojox.grid.enhanced._Events._onHeaderCellMouseOut()
+		var p;
+		for(p in this._sortData){
+			if(this._sortData[p] && this._sortData[p].index === 0){
+				dojo.removeClass(this._headerNodes[p], 'dojoxGridCellShowIndex');
+				break;
 			}
 		}
-		this._fixSelectRegion(elements['selectRegion']);		
-		
-		dijit.removeWaiState(nestedSortWrapper, 'label');
-		dijit.removeWaiState(unarySortWrapper, 'label');
-		
-		if(cellSortInfo["sortPos"] >= 0){
-			var singleSort = (_sortAttrs.length == 1);
-			var node = singleSort ? unarySortWrapper : nestedSortWrapper;
-			this._setSortRegionWaiState(singleSort, e.cellIndex, e.cell.field, cellSortInfo["sortPos"], node);
-		}
-
-		this.focus._updateFocusBorder();
-		this._sortTipMap[e.cellIndex] = false;
 	},
-
-	_getUnaryNode: function(){
+	_onSortBtnClick: function(e){
 		// summary:
-		//		Get the sort position DOM node of unary column (1st in the sort sequence)
-		// return: Dom node
-		for(var i = 0; i < this.views.views.length; i++){
-			var n = dojo.byId(this.views.views[i].id + 'SortPos' + this._unarySortCell.cell.index);
-			if(n) return n;
+		//		If the click target is single sort button, do single sort.
+		//		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')){
+			this._prepareSingleSort(cellIdx);
+		}else if(dojo.hasClass(e.target, 'dojoxGridSortBtnNested')){
+			this._prepareNestedSort(cellIdx);
+		}else{
+			return;
 		}
+		dojo.stopEvent(e);
+		this._doSort(cellIdx);
 	},
-
-	_fixSelectRegion: function(selectRegion){
-		// summary:
-		//		Resize or recover the selection region, so that content in header cell are not messed up.
-		// selectRegion: Dom node
-		//		Dom node of selection region
-		var sortWrapper = selectRegion.previousSibling;
-		var parentBox = dojo.contentBox(selectRegion.parentNode);
-		var selectRegionBox = dojo.marginBox(selectRegion);
-		var sortWrapperBox = dojo.marginBox(sortWrapper);
-						
-		//fix rtl in IE
-		if(dojo.isIE && !dojo._isBodyLtr()){
-			var w = 0;
-			dojo.forEach(sortWrapper.childNodes, function(node){
-				w += dojo.marginBox(node).w;
-			})
-			sortWrapperBox.w = w;
-			sortWrapperBox.l = (sortWrapperBox.t = 0);
-			dojo.marginBox(sortWrapper, sortWrapperBox);
-		}				
-		if(selectRegionBox.w != (parentBox.w - sortWrapperBox.w)){
-			selectRegionBox.w = parentBox.w - sortWrapperBox.w;
-			if(!dojo.isWebKit){
-				dojo.marginBox(selectRegion,selectRegionBox);	
-			}else{//fix insufficient width of select region in Safari & Chrome when zoomed in
-				selectRegionBox.h = dojo.contentBox(parentBox).h;
-				dojo.style(selectRegion, "width", (selectRegionBox.w - 4) + "px");
-			}
+	_doSort: function(cellIdx){
+		if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+			this.setSortData(cellIdx, 'order', 'asc');	//no sorting data
+		}else if(this.isAsc(cellIdx)){
+			this.setSortData(cellIdx, 'order', 'desc');	//change to 'desc'
+		}else if(this.isDesc(cellIdx)){
+			this.removeSortData(cellIdx); //remove from sorting sequence
 		}
+		this._updateSortDef();
+		this.grid.sort();
+		this._initSort(true);
 	},
-	
-	updateMinColWidth: function(nestedSortPos){
-		// summary:
-		//		Calculate and update the min cell width. So that sort tip and partial caption are visible when resized.
-		// nestedSortPos: Dom node
-		//		Dom node of nested sorting position
-		if(this._minColWidthUpdated){ return; }	
-		var oldValue = nestedSortPos.innerHTML;
-		nestedSortPos.innerHTML = dojo.query('.dojoxGridSortWrapper', this.viewsHeaderNode).length;
-		var sortWrapper = nestedSortPos.parentNode.parentNode;
-		this._minColWidth = dojo.marginBox(sortWrapper).w + this._widthDelta;
-		nestedSortPos.innerHTML = oldValue;
-		this._minColWidthUpdated = true;
-	},
-
-	getMinColWidth: function(){
-		// summary:
-		//		Fetch the min column width
-		return this._minColWidth;
-	},
-	
-	_initSelectCols: function(){
+	setSortData: function(cellIdx, attr, value){
 		// summary:
-		//		Some initial works on the header cells, like event binding, resizing parameters etc.
-		var selectRegions      = dojo.query(".dojoxGridHeaderCellSelectRegion", this.headerContentNode);
-		var unarySortWrappers  = dojo.query(".dojoxGridUnarySortWrapper", this.headerContentNode);
-		var nestedSortWrappers = dojo.query(".dojoxGridNestedSortWrapper", this.headerContentNode);
-		
-		selectRegions.concat(unarySortWrappers).concat(nestedSortWrappers).forEach(function(region){
-			dojo.connect(region, 'onmousemove', dojo.hitch(this.grid, this.grid._toggleHighlight, this/*view*/));
-			dojo.connect(region, 'onmouseout', dojo.hitch(this.grid, this.grid._removeActiveState));
-		}, this);
-		
-		this.grid._fixHeaderCellStyle(selectRegions, this/*view*/);
-		
-		//fix rtl in IE
-		if(dojo.isIE && !dojo._isBodyLtr()){
-			this.grid._fixAllSelectRegion();
+		//		Set sorting data for a column.
+		var sd = this._sortData[cellIdx];
+		if(!sd){
+			sd = this._sortData[cellIdx] = {};
 		}
+		sd[attr] = value;
 	},
-	
-	_fixHeaderCellStyle: function(selectRegions, cellView){
-		// summary:
-		//		Fix some style issues when header cells are created
-		//		TBD, see if these can be fixed through CSS
-		// selectRegions: Node list
-		//		Node list of dom nodes for selection regions
-		// cellView: View
-		//		View that contains related cells
-		dojo.forEach(selectRegions, dojo.hitch(this, function(selectRegion){
-			var selectRegionBox = dojo.marginBox(selectRegion),
-				elements = this._getCellElements(selectRegion),
-				sortWrapper = elements.sortWrapper;
-			sortWrapper.style.height = selectRegionBox.h + 'px';
-			sortWrapper.style.lineHeight = selectRegionBox.h + 'px';
-			var selectSortSeparator = elements['selectSortSeparator'], sortSeparator = elements['sortSeparator'];
-			sortSeparator.style.height = selectSortSeparator.style.height = selectRegionBox.h * 3/5 + 'px';
-			sortSeparator.style.marginTop = selectSortSeparator.style.marginTop = selectRegionBox.h * 1/5 + 'px';
-			cellView.header.overResizeWidth = this._overResizeWidth;
-		}));
-	},
-
-	_fixAllSelectRegion: function (){
-		// summary:
-		//		Fix rtl in IE
-		var nodes = dojo.query('.dojoxGridHeaderCellSelectRegion', this.viewsHeaderNode);
-		dojo.forEach(nodes, dojo.hitch(this, function(node){
-			this._fixSelectRegion(node);
-		}));
-	},
-
-	_toggleHighlight: function(cellView, e, allOff){
-		// summary:
-		//		Toggle hover state for selection region, unary sort region (unarySortWrapper) 
-		//		and nested sort region (unarySortWrapper)
-		// cellView: View
-		//		View that contains related cell
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.		
-		// allOff: Boolean
-		//		True - to trun off all highlight | False - by default
-		if(!e.target || !e.type || !e.type.match(/mouse|contextmenu/)){
-			//don't highlight for key events or when in keyboard focus
-			return;
-		}
-		//console.debug("onmousemove,info.selectChoice="+info.selectChoice + ' info.nestedSortChoice='+info.nestedSortChoice+' info.unarySortChoice='+info.unarySortChoice);
-		var elements = this._getCellElements(e.target);
-		if(!elements){return;}
-		
-		var selectRegion      = elements['selectRegion'];
-		var nestedSortWrapper = elements['nestedSortWrapper'];
-		var unarySortWrapper  = elements['unarySortWrapper'];
-				
-		dojo.removeClass(selectRegion, 'dojoxGridSelectRegionHover');
-		dojo.removeClass(nestedSortWrapper, 'dojoxGridSortHover');
-		dojo.removeClass(unarySortWrapper, 'dojoxGridSortHover');	
-
-		if(!allOff && !cellView.grid._inResize(cellView)){
-			var info = this._getSortEventInfo(e);
-			if(info.selectChoice){//highlight selection region
-				dojo.addClass(selectRegion, 'dojoxGridSelectRegionHover');
-			}else if(info.nestedSortChoice){//highlight nested sort region
-				dojo.addClass(nestedSortWrapper, 'dojoxGridSortHover');
-			}else if(info.unarySortChoice){//highlight unary sort region
-				dojo.addClass(unarySortWrapper, 'dojoxGridSortHover');
+	removeSortData: function(cellIdx){
+		var d = this._sortData, i = d[cellIdx].index, p;
+		delete d[cellIdx];
+		for(p in d){
+			if(d[p].index > i){
+				d[p].index--;
 			}
 		}
 	},
-	
-	_removeActiveState: function(e){
-		// summary:
-		//		Remove active state for the event target 
-		// e: Event
-		if(!e.target || !e.type || !e.type.match(/mouse|contextmenu/)){
-			return;
+	_prepareSingleSort: function(cellIdx){
+		// summary:
+		//		Prepare the single sort, also called main sort, this will clear any existing sorting and just sort the grid by current column.
+		var d = this._sortData, p;
+		for(p in d){
+			delete d[p];
+		}
+		this.setSortData(cellIdx, 'index', 0);
+		this.setSortData(cellIdx, 'order', this._currMainSort === 'none' ? null : this._currMainSort);
+		if(!this._sortData[cellIdx] || !this._sortData[cellIdx].order){
+			this._currMainSort = 'asc';
+		}else if(this.isAsc(cellIdx)){
+			this._currMainSort = 'desc';
+		}else if(this.isDesc(cellIdx)){
+			this._currMainSort = 'none';
+		}
+	},
+	_prepareNestedSort: function(cellIdx){
+		// summary
+		//		Prepare the nested sorting, this will order the column on existing sorting result.
+		var i = this._sortData[cellIdx] ? this._sortData[cellIdx].index : null;
+		if(i === 0 || !!i){ return; }
+		this.setSortData(cellIdx, 'index', this._sortDef.length);
+	},
+	_updateSortDef: function(){
+		this._sortDef.length = 0;
+		var d = this._sortData, p;
+		for(p in d){
+			this._sortDef[d[p].index] = {
+				attribute: this.grid.layout.cells[p].field,
+				descending: d[p].order === 'desc'
+			};
+		}
+	},
+	_updateHeaderNodeUI: function(node){
+		// summary:
+		//		Update the column header UI based on current sorting state.
+		//		Show indicator of the sorting order of the column, no order no indicator
+		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];
+		
+		dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnAsc', this._currMainSort === 'asc');
+		dojo.toggleClass(singleSortBtn, 'dojoxGridSortBtnDesc', this._currMainSort === 'desc');
+		if(this._currMainSort === 'asc'){
+			singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.descending;
+		}else if(this._currMainSort === 'desc'){
+			singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.unsorted;
+		}else{
+			singleSortBtn.title = this.nls.singleSort + ' - ' + this.nls.ascending;
 		}
-		var node = this._getChoiceRegion(e.target, this._getSortEventInfo(e));
-		node && dojo.removeClass(node, this.headerCellActiveClass);
-	},
-	
-	_toggleProgressTip: function(on, e){
-		// summary:
-		//		Change the cursor to progress or vice versa
-		// on: Boolean
-		//		True - change to progress cursor, false - recover back to original style
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		var tipNodes  = [this.domNode, e ? e.cellNode : null];
-		setTimeout(function(){
-			dojo.forEach(tipNodes, function(node){
-				if(node){
-					if(on && !dojo.hasClass(node, 'dojoxGridSortInProgress')){
-						dojo.addClass(node, 'dojoxGridSortInProgress');
-					}else if(!on && dojo.hasClass(node, 'dojoxGridSortInProgress')){
-						dojo.removeClass(node, 'dojoxGridSortInProgress');									
-					}
-				}
-			});
-		}, 0.1);
-	},
-	
-	_getSortEventInfo: function(e){
-		// summary:
-		//		Get sort event type from the event 
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		// return; Object
-		//      Sort event type e.g. {unarySortChoice: true|false, nestedSortChoice: true|false, selectChoice: true|false}
-		var _isRegionTypeByCSS = function (node, css){
-			return dojo.hasClass(node, css) || (node.parentNode && dojo.hasClass(node.parentNode, css));
-		};
-		return {selectChoice 	 : _isRegionTypeByCSS(e.target, 'dojoxGridHeaderCellSelectRegion'),
-				unarySortChoice  : _isRegionTypeByCSS(e.target, 'dojoxGridUnarySortWrapper'),
-				nestedSortChoice : _isRegionTypeByCSS(e.target, 'dojoxGridNestedSortWrapper')};
-	},
-	
-	ignoreEvent: function(e){
-		// summary:
-		//		See if the event should be ignored when nested sorting is enabled
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		// return: Boolean
-		//		True - ignore this event, false - don't ignore
-		return !(e.nestedSortChoice || e.unarySortChoice || e.selectChoice);
-	},
-	
-	_sychronizeResize: function(e){
-		// summary:
-		//		Each time mouse moved in view.headerNode, check if need to add or remove sort tip
-		//      This is used so that when mouse moves in resize area, sort tip is turned off, when mouse
-		//		moves out of resize area, sort tip is turned on if necessary. Sort tip is also off during resizing
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		if(!e.cell || e.cell.isRowSelector || this.focus.headerCellInFocus(e.cellIndex)){
+		
+		var _this = this;
+		function setWaiState(){
+			var columnInfo = 'Column ' + (cell.index + 1) + ' ' + cell.field;
+			var orderState = 'none';
+			var orderAction = 'ascending';
+			if(data){
+				orderState = data.order === 'asc' ? 'ascending' : 'descending';
+				orderAction = data.order === 'asc' ? 'descending' : 'none';
+			}
+			var a11ySingleLabel = columnInfo + ' - is sorted by ' + orderState;
+			var a11yNestedLabel = columnInfo + ' - is nested sorted by ' + orderState;
+			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);
+			
+			var handles = [
+				_this.connect(singleSortBtn, "onmouseover", function(){
+					dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabelHover);
+				}),
+				_this.connect(singleSortBtn, "onmouseout", function(){
+					dijit.setWaiState(singleSortBtn, 'label', a11ySingleLabel);
+				}),
+				_this.connect(nestedSortBtn, "onmouseover", function(){
+					dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabelHover);
+				}),
+				_this.connect(nestedSortBtn, "onmouseout", function(){
+					dijit.setWaiState(nestedSortBtn, 'label', a11yNestedLabel);
+				})
+			];
+			dojo.forEach(handles, function(handle){ handle._sort = true; });
+		}
+		setWaiState();
+
+		var a11y = dojo.hasClass(dojo.body(), "dijit_a11y");
+		if(!data){
+			nestedSortBtn.innerHTML = this._sortDef.length + 1;
 			return;
 		}
-		if(!this._inResize(e.sourceView)){
-			this.addHoverSortTip(e);
-		}else{
-			var idx = e.cellIndex;
-			if(!this._sortTipMap[e.cellIndex]){
-				e.cellIndex = this._sortTipMap[idx + 1] ? (idx + 1) : (this._sortTipMap[idx - 1] ? (idx - 1) : idx);
-				e.cellNode = e.cellNode.parentNode.childNodes[e.cellIndex];
-			}
-			this.removeHoverSortTip(e);
+		if(data.index || (data.index === 0 && this._sortDef.length > 1)){
+			nestedSortBtn.innerHTML = data.index + 1;
 		}
-	},
-	
-	_getCellElements: function(node){
-		// summary:
-		//		Fetch all dom nodes related with sorting, using dojo.query()
-		//		to search from top 'th' parent of the given node
-		// node: Dom node
-		//		Target node.
-		// return: Object
-		//		Json object contains all dom nodes related with sorting	
-		try{
-			while(node && node.nodeName.toLowerCase() != 'th'){
-				node = node.parentNode;
-			}
-			if(!node){return null;}
-			// try to get dojoxGridSortRoot
-			var ns = dojo.query(".dojoxGridSortRoot", node);
-			if(ns.length != 1){return null;}
-			var n = ns[0];
-			return {
-				'selectSortSeparator': dojo.query("[id^='selectSortSeparator']", n)[0],
-				'nestedSortPos'		 : dojo.query(".dojoxGridSortPos", n)[0],
-				'nestedSortChoice'	 : dojo.query("[id^='nestedSortCol']", n)[0],
-				'sortSeparator'		 : dojo.query("[id^='SortSeparator']", n)[0],
-				'unarySortChoice'	 : dojo.query("[id^='unarySortCol']", n)[0],
-				'selectRegion'		 : dojo.query(".dojoxGridHeaderCellSelectRegion", n)[0],
-				'sortWrapper'		 : dojo.query(".dojoxGridSortWrapper", n)[0],
-				'unarySortWrapper'	 : dojo.query(".dojoxGridUnarySortWrapper", n)[0],
-				'nestedSortWrapper'	 : dojo.query(".dojoxGridNestedSortWrapper", n)[0],
-				'sortRoot'			 : n,
-				'headCellNode'		 : node
-			}		
-		}catch(e){
-			console.debug('NestedSorting._getCellElemets() error:' + e);
+		dojo.addClass(sortNode, 'dojoxGridSortNodeSorted');
+		if(this.isAsc(cellIdx)){
+			dojo.addClass(sortNode, 'dojoxGridSortNodeAsc');
+			nestedSortBtn.title = 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;
+			if(a11y){sortNode.innerHTML = this._a11yText.dojoxGridDescendingTip;}
 		}
-		return null;
+		dojo.addClass(sortNode, (data.index === 0 ? 'dojoxGridSortNodeMain' : 'dojoxGridSortNodeSub'));
 	},
-	
-	_getChoiceRegion: function(target, choiceInfo){
-		// summary:
-		//		Find an appropriate region node for the choice event
-		// target: Dom Node
-		//		Choice event target
-		// choiceInfo: Object
-		//		Choice info e.g. 'unarySortChoice' | 'nestedSortChoice' | 'selectChoice'
-		// return: Dom Node
-		//		Appropriate choice region node
-		var node, elements = this._getCellElements(target);
-		if(!elements){ return; }
-		choiceInfo.unarySortChoice && (node = elements['unarySortWrapper']);
-		choiceInfo.nestedSortChoice && (node = elements['nestedSortWrapper']);
-		choiceInfo.selectChoice && (node = elements['selectRegion']);
-		return node;	
+	isAsc: function(cellIndex){
+		return this._sortData[cellIndex].order === 'asc';
 	},
-
-	_inResize: function(view){
-		// summary:
-		//		See if current view is in resizing state(including if the cursor is in resize area)
-		// view: View
-		//		Target view
-		// return: Boolean
-		//		True - in resizing state, false - not in resizing state
-		return view.header.moverDiv || dojo.hasClass(view.headerNode, "dojoxGridColResize") || dojo.hasClass(view.headerNode, "dojoxGridColNoResize");		
+	isDesc: function(cellIndex){
+		return this._sortData[cellIndex].order === 'desc';
 	},
-	
-	retainLastRowSelection: function(){
-		// summary:
-		//		Retain selected rows before sorting
-		dojo.forEach(this._by_idx, function(o, idx){
-			if(!o || !o.item){return;}
-			var selected = !!this.selection.isSelected(idx);
-			o.item[this.storeItemSelected] = [selected];
-			if(this.indirectSelection && this.rowSelectCell.toggleAllTrigerred && selected != this.toggleAllValue){
-				this.exceptionalSelectedItems.push(o.item);
+	_getCellByNode: function(node){
+		var i;
+		for(i = 0; i < this._headerNodes.length; i++){
+			if(this._headerNodes[i] === node){
+				return this.grid.layout.cells[i];
 			}
-		}, this);
-		//clear all row selections
-		this.selection.selected = [];
-		dojo.publish(this.sortRowSelectionChangedTopic,[this]);
-	},
-	
-	updateNewRowSelection: function(items, req){
-		// summary:
-		//		Fired when row selection is changed, connected from DataGrid._onFetchComplete();
-		dojo.forEach(items, function(item, idx){
-			if(this.indirectSelection && this.rowSelectCell.toggleAllTrigerred){
-				if(dojo.indexOf(this.exceptionalSelectedItems, item) < 0){
-					item[this.storeItemSelected] = [this.toggleAllValue];	
-				}				
-			}
-			if(item[this.storeItemSelected] && item[this.storeItemSelected][0]){
-				//don't invoke addToSelection to avoid any onSelected events
-				var rowIndex = req.start + idx;
-				this.selection.selectedIndex = rowIndex;
-				this.selection.selected[rowIndex] = true;
-				this.updateRowStyles(rowIndex);
-			}
-		}, this);
-		dojo.publish(this.sortRowSelectionChangedTopic,[this]);
-		if(dojo.isMoz && this._by_idx.length == 0){
-			//Fix a weird issue in FF, when there are empty rows after page loaded
-			this.update();
 		}
-	}, 
-
-	allSelectionToggled: function(checked){
-		// summary:
-		//		Fired when toggleAllSelection is triggered in indirect selection		
-		this.exceptionalSelectedItems = [];
-		this.toggleAllValue = this.rowSelectCell.defaultValue;
+		return null;
 	},
-	
-	_selectionChanged: function(obj){
-		// summary:
-		//		Subscriber of rowSelectionChangedTopic, update global row selection state accordingly
-		// obj: Object
-		//		Object that fired the rowSelectionChangedTopic		
-		obj == this.select && (this.toggleAllValue = false);//from DnD
+	clearSort: function(){
+		this._sortData = {};
+		this._sortDef.length = 0;
 	},
 	
-	getStoreSelectedValue: function(rowIdx){
-		// summary:
-		//		Get whether a give row is selected across sortings
-		// rowIdx: Integer
-		//		Target row index
-		var data = this._by_idx[rowIdx];
-		return data && data.item && !!(data.item[this.storeItemSelected] && data.item[this.storeItemSelected][0]);
+	//persistence
+	initCookieHandler: function(){
+		if(this.grid.addCookieHandler){
+			this.grid.addCookieHandler({
+				name: "sortOrder",
+				onLoad: dojo.hitch(this, '_loadNestedSortingProps'),
+				onSave: dojo.hitch(this, '_saveNestedSortingProps')
+			});
+		}
 	},
-	
-	initAriaInfo: function(){
-		// summary:
-		//		Add ARIA attributes for A11Y	
-		var _sortAttrs = this.sortAttrs;
-		dojo.forEach(_sortAttrs, dojo.hitch(this, function(attr, index){
-			if(!attr.cell || !attr.cellNode){return;}
-			var cellNode = attr.cell.getHeaderNode();
-			var elements = this._getCellElements(cellNode);
-			if(!elements){return;}
-			var selectRegion = elements['selectRegion'];
-			//dijit.setWaiRole(selectRegion, 'columnheader');
-			dijit.setWaiState(selectRegion, 'label', 'Column ' + (attr.cell.index+1) + ' ' +  attr.attr);
-			
-			var singleSort = (_sortAttrs.length == 1);
-			var sortState = this.sortStateInt2Str(attr.asc).toLowerCase();
-			var node = singleSort ? elements['unarySortWrapper'] : elements['nestedSortWrapper'];
-			dijit.setWaiState(node, 'sort', sortState);
-			this._setSortRegionWaiState(singleSort, attr.cell.index, attr.attr, index + 1, node);
-		}));
+	_loadNestedSortingProps: function(sortInfo, grid){
+		this._setGridSortIndex(sortInfo);
 	},
-	
-	_setSortRegionWaiState: function(singleSort, cellIdx, field, sortPos, node){
-		// summary:
-		//		Add ARIA Wai sate for sort regions
-		if(sortPos < 0) return;
-		var sortType = singleSort ? 'single sort' : 'nested sort';
-		var ariaValue = 'Column ' + (cellIdx + 1) + ' ' + field + ' ' + sortType + ' ' + (!singleSort ? (' sort position ' + sortPos) : '');
-		dijit.setWaiState(node, 'label', ariaValue);
+	_saveNestedSortingProps: function(grid){
+		return this.getSortProps();
 	},
-
-	_inPage: function(rowIndex){
-		// summary:
-		//		See if the given row is in the current page
-		// rowIndex: Integer
-		//		Target row
-		// return: Boolean
-		//		True - in the current page | False - not in the current page
-		return rowIndex < this._bop || rowIndex >= this._eop;
-	}
-});
-
-dojo.declare("dojox.grid.enhanced.plugins._NestedSortingFocusManager", dojox.grid._FocusManager, {
-	// summary:
-	//		Provides keyboard focus support for nested sorting
-
-	//lastHeaderFocus: Object
-	//		Last header focus info
-	lastHeaderFocus :{cellNode:null, regionIdx:-1},
 	
-	//currentHeaderFocusEvt: Object
-	//		Dummy event for current header focus	
-	currentHeaderFocusEvt: null,
-
-	//cssMarkers: Array
-	//		CSS class markers for select region, nested sort wrapper and unary sort wrapper
-	cssMarkers : ['dojoxGridHeaderCellSelectRegion', 'dojoxGridNestedSortWrapper', 'dojoxGridUnarySortWrapper'],
-
-	//_focusBorderBox: Dom node
-	//		Root of focus border divs
-	_focusBorderBox: null,
-	
-	_initColumnHeaders: function(){
-		// summary:
-		//		Bind onfocus and onblur hanlders to regions in each header cell node
-		var headerNodes = this._findHeaderCells();
-		dojo.forEach(headerNodes, dojo.hitch(this, function(headerNode){
-			var selectRegion = dojo.query('.dojoxGridHeaderCellSelectRegion', headerNode);
-			var sortRegions = dojo.query("[class*='SortWrapper']", headerNode);
-			selectRegion = selectRegion.concat(sortRegions);
-			selectRegion.length == 0 && (selectRegion = [headerNode]);
-			dojo.forEach(selectRegion, dojo.hitch(this, function(node){
-				this._connects.push(dojo.connect(node, "onfocus", this, "doColHeaderFocus"));				
-				this._connects.push(dojo.connect(node, "onblur", this, "doColHeaderBlur"));
-			}));
-		}));
+	//focus & keyboard
+	_initFocus: function(){
+		var f = this.focus = this.grid.focus;
+		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._regions = [];
+			area.getRegions = null;
+			this.connect(this.grid, 'onBlur', '_blurHeader');
+		}
 	},
-
-	focusHeader: function(leadingDir, delayed, ignoreRegionPos){
+	_focusHeader: function(evt){
 		// summary:
 		//		Overwritten, see _FocusManager.focusHeader()
-		//leadingDir: Boolean
-		//		If focus is switching to leading direction
 		//delayed: Boolean
-		//		If called from "this._delayedHeaderFocus()"
-		//ignoreRegionPos: Boolean
-		//		If always focus on the 1st region(select region) for each header cell node
-		if(!this.isNavHeader()){
-			//focus navigated from cells
-			this.inherited(arguments);	
+		//		If called from "this.focus._delayedHeaderFocus()"
+		if(this._currRegionIdx === -1){
+			this._onMove(0, 1, null);
 		}else{
-			var headerNodes = this._findHeaderCells();
-			this._colHeadNode = headerNodes[this._colHeadFocusIdx];
-			delayed && (this.lastHeaderFocus.cellNode = this._colHeadNode);
+			this._focusRegion(this._getCurrentRegion());
 		}
-		if(!this._colHeadNode){
+		try{
+			dojo.stopEvent(evt);
+		}catch(e){}
+		return true;
+	},
+	_blurHeader: function(evt){
+		this._blurRegion(this._getCurrentRegion());
+		return true;
+	},
+	_onMove: function(rowStep, colStep, evt){
+		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'){
+			//if the region is invisible, keep finding next
+			this._onMove(rowStep, colStep + (colStep > 0 ? 1 : -1), evt);
 			return;
 		}
-		//jump over the 1st indirect selection cell(column)
-		if(this.grid.indirectSelection && this._colHeadFocusIdx == 0){
-			this._colHeadNode = this._findHeaderCells()[++this._colHeadFocusIdx];
-		}		
-		var focusRegionIdx = ignoreRegionPos ? 0 : (this.lastHeaderFocus.regionIdx >= 0 ? this.lastHeaderFocus.regionIdx : (leadingDir ? 2 : 0));
-		var focusRegion = dojo.query('.' + this.cssMarkers[focusRegionIdx], this._colHeadNode)[0] || this._colHeadNode;
-		this.grid.addHoverSortTip(this.currentHeaderFocusEvt = this._mockEvt(focusRegion));
-		this.lastHeaderFocus.regionIdx = focusRegionIdx;
-		focusRegion && dojox.grid.util.fire(focusRegion, "focus");
-	},
-	
-	focusSelectColEndingHeader: function(e){
-		// summary:
-		//		Put focus on the ending column header cell for swipe column selecting(when DnD plugin is on).
-		//		See dojox.grid.enhanced.dnd._DndBuilder.domouseup()
-		// e: Event
-		//		Decorated event object that contains reference to grid header or content
-		if(!e || !e.cellNode) return ;
-		this._colHeadFocusIdx = e.cellIndex;
-		this.focusHeader(null, false, true);
-	},
-	
-	_delayedHeaderFocus: function(){
-		// summary:
-		//		Overwritten, see _FocusManager._delayedHeaderFocus()		
-		//this.needFocusSupport() && this.isNavHeader() && this.focusHeader(null, true);
-		this.isNavHeader() && this.focusHeader(null, true);
-	},
-	
-	_setActiveColHeader: function(/*Node*/colHeaderNode, /*Integer*/colFocusIdx, /*Integer*/ prevColFocusIdx){
-		// summary:
-		//		Overwritten, see _FocusManager._setActiveColHeader()		
-		dojo.attr(this.grid.domNode, "aria-activedescendant",colHeaderNode.id);
-		this._colHeadNode = colHeaderNode;
-		this._colHeadFocusIdx = colFocusIdx;
-	},
-	
-	doColHeaderFocus: function(e){
-		// summary:
-		//		Overwritten, see _FocusManager.doColHeaderFocus()		
-        this.lastHeaderFocus.cellNode = this._colHeadNode;
-		if(e.target == this._colHeadNode){
-			this._scrollHeader(this.getHeaderIndex());
-		}else{
-			var focusView = this.getFocusView(e);
-			if(!focusView){ return; }		
-			focusView.header.baseDecorateEvent(e);
-			this._addFocusBorder(e.target);
-			this._colHeadFocusIdx = e.cellIndex;
-			this._colHeadNode = this._findHeaderCells()[this._colHeadFocusIdx];
-			// try to avoid the e.cell is undefined error.
-			this._colHeadNode && this.getHeaderIndex() != -1 && this._scrollHeader(this._colHeadFocusIdx);
-		}
-		this._focusifyCellNode(false);
-		this.grid.isDndSelectEnable && this.grid.focus._blurRowBar();
-		//fix sort position of first column is missed when 2nd column is added using keyboard.
-		this.grid.addHoverSortTip(this.currentHeaderFocusEvt = this._mockEvt(e.target));
-		
-		//fix ie rtl, focus add a border to the element, so need to change width of selection region
-		if(dojo.isIE && !dojo._isBodyLtr()){
-			this.grid._fixAllSelectRegion();
-		}
-	},
-	
-	doColHeaderBlur: function(e){
-		// summary:
-		//		Overwritten, see _FocusManager.doColHeaderBlur()		
-		this.inherited(arguments);
-		this._removeFocusBorder();
-		//if(!this.isNavHeader() || this.lastHeaderFocus.cellNode && this.lastHeaderFocus.cellNode != this._colHeadNode){
-		if(!this.isNavCellRegion){
-			var focusView = this.getFocusView(e);
-			if(!focusView){ return; }		
-			focusView.header.baseDecorateEvent(e);
-			this.grid.removeHoverSortTip(e);
-			this.lastHeaderFocus.cellNode = this._colHeadNode;
-		}
-	},
-	
-	getFocusView: function(e){
-		// summary:
-		//		Get the current focus view
-		// e: Event
-		//		Event that triggers the current focus
-		// return: Object
-		//		The current focus view
-		var focusView;
-		dojo.forEach(this.grid.views.views, function(view){
-			if(!focusView){
-				var viewBox = dojo.coords(view.domNode), targetBox = dojo.coords(e.target);
-				var inRange = targetBox.x >= viewBox.x && targetBox.x <= (viewBox.x + viewBox.w);
-				inRange && (focusView = view);
-			}
-		});
-		return (this.focusView = focusView);
-	},
-		
-	_mockEvt: function(region){
-		// summary:
-		//		Return a mocked decorated event for currently focused column header cell.
-		// region: Dom node
-		//		Target dom node			
-		// return: Object
-		//		Overwritten, see _FocusManager.doColHeaderBlur()		
-		var cell = this.grid.getCell(this._colHeadFocusIdx);
-		return {target:region, cellIndex: this._colHeadFocusIdx, cell: cell,
-				cellNode: this._colHeadNode, clientX:-1, sourceView: cell.view};
-	},
-	
-	navHeader: function(e){
-		// summary:
-		//		Navigate focus across column header cells or regions.
-		// e: Event
-		//		Un-decorated event object
-		var offset= e.ctrlKey ? 0 : (e.keyCode == dojo.keys.LEFT_ARROW) ? -1 : 1;
-		!dojo._isBodyLtr() && (offset *= -1);
-		this.focusView.header.baseDecorateEvent(e);
-		dojo.forEach(this.cssMarkers, dojo.hitch(this, function(css, index){
-			if(dojo.hasClass(e.target, css)){
-				var newPos = index + offset,region,nextRegion;
-				do{
-					region = dojo.query('.'+this.cssMarkers[newPos], e.cellNode)[0];
-					if(region && dojo.style(region.lastChild || region.firstChild, 'display') != 'none'){
-						nextRegion = region;
-						break;	
+		this._focusRegion(region);
+		//keep grid body scrolled by header
+		var view = this._getRegionView(region);
+		view.scrollboxNode.scrollLeft = view.headerNode.scrollLeft;
+	},
+	_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')){
+						this._onSortBtnClick(e);
 					}
-					newPos += offset;
-				}while(newPos >=0 && newPos < this.cssMarkers.length);
-				if(nextRegion && newPos >= 0 && newPos < this.cssMarkers.length){
-					if(e.ctrlKey){return;}
-					//in IE, avoid removing hover tip during cell region navigation, see this.grid.removeHoverSortTip(e)
-					dojo.isIE && (this.grid._sortTipMap[e.cellIndex] = false);
-					this.navCellRegion(nextRegion, newPos);
-					return;
-				}
-				var delta = newPos < 0 ? -1 : (newPos >= this.cssMarkers.length ? 1 : 0);
-				this.navHeaderNode(delta);
 			}
-		}));
-	},
-	
-	navHeaderNode: function(delta, ignoreRegionPos){
-		// summary:
-		//		Navigate focus across column header cells.
-		// delta: Integer
-		//		1 | 0 | -1, navigating direction
-		// ignoreRegionPos: Boolean
-		//		If always focus on the 1st region(select region) for each header cell node		
-		var _newColHeadFocusIdx = this._colHeadFocusIdx + delta;
-		var headers = this._findHeaderCells();
-		while(_newColHeadFocusIdx >=0 && _newColHeadFocusIdx < headers.length 
-			&& headers[_newColHeadFocusIdx].style.display == "none"){
-			// skip over hidden column headers
-			_newColHeadFocusIdx += delta;
 		}
-		
-		if(this.grid.indirectSelection && _newColHeadFocusIdx == 0){
-			return;//simply ignore indirect selection column
-		}
-		if(delta != 0 && _newColHeadFocusIdx >= 0 && _newColHeadFocusIdx < this.grid.layout.cells.length){
-			this.lastHeaderFocus.cellNode = this._colHeadNode;
-			this.lastHeaderFocus.regionIdx = -1;
-			this._colHeadFocusIdx = _newColHeadFocusIdx;
-			this.focusHeader(delta < 0 ? true/*navigate towards leading direction*/ : false/*navigate towards trail direction*/, false, ignoreRegionPos);				
-		}
-	},
-	
-	navCellRegion:function(nextRegion, newPos){
-		// summary:
-		//		Navigate focus across regions within a column header cell.
-		// nextRegion: Dom node
-		//		Next region node to be focused
-		// newPos: Integer
-		//		New region index			
-		this.isNavCellRegion = true;
-		dojox.grid.util.fire(nextRegion, "focus");
-		this.currentHeaderFocusEvt.target = nextRegion;
-		this.lastHeaderFocus.regionIdx = newPos;
-		var selectRegion = newPos == 0 ? nextRegion : nextRegion.parentNode.nextSibling;
-		selectRegion && this.grid._fixSelectRegion(selectRegion);
-		this.isNavCellRegion = false;
-	},
-
-	headerCellInFocus: function(cellIndex){
-		// summary:
-		//		See if column header cell(with cellIndex) is now having focus
-		// cellIndex: Integer
-		//		Cell (column) index
-		// return: Boolean
-		//		If the column header cell(with cellIndex) is now having focus.
-		return (this._colHeadFocusIdx == cellIndex) && this._focusBorderBox;
-	},
-	
-	clearHeaderFocus: function(){
-		// summary:
-		//		Clear focus in column header cell		
-		this._colHeadNode = this._colHeadFocusIdx = null;
-		this.lastHeaderFocus = {cellNode:null, regionIdx:-1};
 	},
-
-	addSortFocus: function(e){
-		// summary:
-		//		 Add focus to sort region in column header cell by mouse click
-		//		 See NestedSorting.setSortIndex()
-		// e: Event
-		//		Decorated event object which contains reference to grid, target cell etc.
-		var cellSortInfo = this.grid.getCellSortInfo(e.cell);
-		if(!cellSortInfo) 
-			return;
-		var _sortAttrs = this.grid.sortAttrs;		
-		var notSorted = !_sortAttrs || _sortAttrs.length < 1;		
-		var inUnarySort = (_sortAttrs && _sortAttrs.length == 1 && cellSortInfo["sortPos"] == 1);
-		this._colHeadFocusIdx = e.cellIndex;
-		this._colHeadNode = e.cellNode;
-		this.currentHeaderFocusEvt = {};
-		this.lastHeaderFocus.regionIdx = (notSorted || inUnarySort) ? 2 : (e.nestedSortChoice ? 1 : 0);
-	},	
-	
-	_addFocusBorder: function(node){
-		// summary:
-		//		 Add focus borders to node, use this instead of native CSS way to fix border wobbling issue
-		// node: Dom node
-		//		Target node to add focus borders	
-		if(!node) return ;
-		this._removeFocusBorder();
-		this._focusBorderBox = dojo.create('div');
-		this._focusBorderBox.className = 'dojoxGridFocusBorderBox';
-		dojo.toggleClass(node, "dojoxGridSelectRegionFocus", true);
-		dojo.toggleClass(node, "dojoxGridSelectRegionHover", false);
-		
-		//cache the height - in IE6 the value will be doubled after 'node.insertBefore()'
-		var nodeH = node.offsetHeight;
-		if(node.hasChildNodes()){
-			node.insertBefore(this._focusBorderBox, node.firstChild);
-		}else{
-			node.appendChild(this._focusBorderBox);
+	_getRegionView: function(region){
+		var header = region;
+		while(header && !dojo.hasClass(header, 'dojoxGridHeader')){ header = header.parentNode; }
+		if(header){
+			return dojo.filter(this.grid.views.views, function(view){
+				return view.headerNode === header;
+			})[0] || null;
 		}
-		
-		var _d = {'l': 0, 't': 0, 'r': 0, 'b': 0};		
-		for(var i in _d){
-			_d[i] = dojo.create('div');
-		}
-		
-		var pos = {
-			x: dojo.coords(node).x - dojo.coords(this._focusBorderBox).x ,
-			y: dojo.coords(node).y - dojo.coords(this._focusBorderBox).y,
-			w: node.offsetWidth,
-			h: nodeH
-		};
-		for(var i in _d){
-			var n = _d[i];
-			dojo.addClass(n, 'dojoxGridFocusBorder');
-			dojo.style(n, 'top', pos.y + 'px');
-			dojo.style(n, 'left', pos.x + 'px');
-			this._focusBorderBox.appendChild(n);
-		}
-		var normalize = function(val){
-			return val > 0 ? val : 0;
-		}
-		dojo.style(_d.r, 'left',   normalize(pos.x + pos.w - 1) + 'px');
-		dojo.style(_d.b, 'top',    normalize(pos.y + pos.h - 1) + 'px');		
-		dojo.style(_d.l, 'height', normalize(pos.h - 1) + 'px');
-		dojo.style(_d.r, 'height', normalize(pos.h - 1) + 'px');
-		dojo.style(_d.t, 'width',  normalize(pos.w - 1) + 'px');
-		dojo.style(_d.b, 'width',  normalize(pos.w - 1) + 'px');
-	},
-	
-	_updateFocusBorder: function(){
-		// summary:
-		//		 Update focus borders.
-		if(this._focusBorderBox == null){
-			return;
-		}
-		this._addFocusBorder(this._focusBorderBox.parentNode);
+		return null;
 	},
-
-	_removeFocusBorder: function(){
-		// summary:
-		//		 Remove focus borders.		
-		if(this._focusBorderBox && this._focusBorderBox.parentNode){
-			dojo.toggleClass(this._focusBorderBox.parentNode, "dojoxGridSelectRegionFocus", false);
-			this._focusBorderBox.parentNode.removeChild(this._focusBorderBox);
-			
-		}			
-		this._focusBorderBox = null;
+	_getRegions: function(){
+		var regions = [], cells = this.grid.layout.cells;
+		this._headerNodes.forEach(function(n, i){
+			if(dojo.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);
+					regions.push(node);
+			});
+		},this);
+		return regions;
+	},
+	_focusRegion: function(region){
+		// summary
+		//		Focus the given region
+		if(!region){return;}
+		var currRegion = this._getCurrentRegion();
+		if(currRegion && region !== currRegion){
+			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');
+		}
+		region.focus();
+		this.focus.currentArea('header');
+		this._currRegionIdx = dojo.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');
+		}
+		region.blur();
+	},
+	_getCurrentRegion: function(){
+		return this._focusRegions[this._currRegionIdx];
+	},
+	_getRegionHeader: function(region){
+		while(region && !dojo.hasClass(region, 'dojoxGridCell')){
+			region = region.parentNode;
+		}
+		return region;
+	},
+	destroy: function(){
+		this._sortDef = this._sortData = null;
+		this._headerNodes = this._focusRegions = null;
+		this.inherited(arguments);
 	}
 });
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.NestedSorting);
diff --git a/dojox/grid/enhanced/plugins/Pagination.js b/dojox/grid/enhanced/plugins/Pagination.js
new file mode 100644
index 0000000..b6df641
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Pagination.js
@@ -0,0 +1,1224 @@
+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");
+		
+		this._wrapStoreLayer();
+		this._createPaginators(this.option);
+		
+		this._regApis();
+	},
+	
+	_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(){
+		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);
+		}
+	},
+
+	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();
+		}
+	},
+	
+	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);
+	},
+	
+	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);
+		}
+		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);
+		});
+	},
+	
+	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);
+	},
+	
+	getTotalRowCount: function(){
+		// summary:
+		//		Function for get total row count
+		return this._maxSize;
+	}
+});
+
+dojo.declare("dojox.grid.enhanced.plugins._ForcedPageStoreLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+	tags: ["presentation"],
+	
+	constructor: function(plugin){
+		this._plugin = plugin;
+	},
+	
+	_fetch: function(request){
+		var self = this,
+			plugin = self._plugin,
+			grid = plugin.grid,
+			scope = request.scope || dojo.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.onBegin = function(size, req){
+				plugin._maxSize = plugin.pageSize = size;
+				self.startIdx = 0;
+				self.endIdx = size - 1;
+				dojo.forEach(plugin.paginators, function(f){
+					f.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;
+				plugin._maxSize = size;
+				self.endIdx = self.endIdx >= size ? (size - 1) : self.endIdx;
+				if(self.startIdx > size && size !== 0){
+					grid._pending_requests[req.start] = false;
+					plugin.gotoFirstPage();
+				}
+				dojo.forEach(plugin.paginators, function(f){
+					f.update();
+				});
+				req.onBegin = onBegin;
+				req.onBegin.call(scope, Math.min(plugin.pageSize, (size - self.startIdx)), req);
+			};
+		}
+		return dojo.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,
+	
+	constructor: function(params){
+		dojo.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");
+		g.resize = function(changeSize, resultSize){
+			self._changeSize = g._pendingChangeSize = changeSize;
+			self._resultSize = g._pendingResultSize = resultSize;
+			g.sizeChange();
+		};
+		this._placeSelf();
+	},
+	
+	destroy: function(){
+		this.inherited(arguments);
+		this.grid.focus.removeArea("pagination" + this.position.toLowerCase());
+		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(){
+		// 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){
+		// 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)
+		});
+		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;
+		}
+	},
+	
+	_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;
+		}
+	},
+	
+	_resetGridHeight: function(changeSize, resultSize){
+		// summary:
+		//		Function of resize grid height to place this pagination bar.
+		//		Since the grid would be able to add other element in its domNode, we have
+		//		change the grid view size to place the pagination bar.
+		//		This function will resize the grid viewsNode height, scorllboxNode height
+		var g = this.grid;
+		changeSize = changeSize || this._changeSize;
+		resultSize = resultSize || this._resultSize;
+		delete this._changeSize;
+		delete this._resultSize;
+		if(g._autoHeight){
+			return;
+		}
+		var padBorder = g._getPadBorder().h;
+		if(!this.plugin.gh){
+			this.plugin.gh = dojo.contentBox(g.domNode).h + 2 * padBorder;
+		}
+		if(resultSize){
+			changeSize = resultSize;
+		}
+		if(changeSize){
+			this.plugin.gh = dojo.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"){
+			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);
+		}else{
+			var h = gh - ph - hh - padBorder;
+			dojo.style(g.viewsNode, "height", h + "px");
+			var hasHScroller = dojo.some(g.views.views, function(v){
+				return v.hasHScrollbar();
+			});
+			dojo.forEach(g.viewsNode.childNodes, function(c, idx){
+				dojo.style(c, "height", h + "px");
+			});
+			dojo.forEach(g.views.views, function(v, idx){
+				if(v.scrollboxNode){
+					if(!v.hasHScrollbar() && hasHScroller){
+						dojo.style(v.scrollboxNode, "height", (h - dojox.html.metrics.getScrollbar().h) + "px");
+					}else{
+						dojo.style(v.scrollboxNode, "height", h + "px");
+					}
+				}
+			});
+			this._styleMsgNode(hh, dojo.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"});
+	},
+	
+	_updateDescription: function(){
+		// summary:
+		//		Update size information.
+		var s = this.plugin.forcePageStoreLayer;
+		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);
+		}
+	},
+	
+	_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
+			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;
+	},
+	
+	_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){
+			// 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");
+			// for accessibility
+			dijit.setWaiState(node, "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");
+			});
+			this.plugin.connect(node, "onmouseout", function(e){
+				dojo.removeClass(e.target, "dojoxGridPageTextHover");
+			});
+			// create a separation node
+			node = dojo.create("span", {innerHTML: "|"}, this.sizeSwitchTd, "last");
+			dojo.addClass(node, "dojoxGridSeparator");
+		}, this);
+		// delete last separation node
+		dojo.destroy(node);
+		this.initializedSizeNode = true;
+		if(this.sizeSwitchWidth){
+			dojo.style(this.sizeSwitchTd, "width", this.sizeSwitchWidth);
+		}
+	},
+	
+	_updateSwitchNodeClass: 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;
+			}else{
+				dojo.addClass(node, "dojoxGridInactiveSwitch");
+				dojo.attr(node, "tabindex", "0");
+			}
+		};
+		dojo.forEach(this.sizeSwitchTd.childNodes, function(node){
+			if(node.value){
+				size = node.value;
+				dojo.removeClass(node);
+				if(this.pageSizeValue){
+					styleNode(node, size === this.pageSizeValue && !hasActivedNode);
+				}else{
+					if(size.toLowerCase() == "all"){
+						size = this._maxItemSize;
+					}
+					styleNode(node, this.currentPageSize === parseInt(size, 10) && !hasActivedNode);
+				}
+			}
+		}, 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");
+			return;
+		}else{
+			dojo.style(this.pageStepperTd, "display", "");
+		}
+		if(this.pageStepperDiv.childNodes.length < 1){
+			this._createPageStepNodes();
+			this._createWardBtns();
+		}else{
+			this._resetPageStepNodes();
+		}
+		this._updatePageStepNodeClass();
+		
+		this._moveToNextActivableNode(this._getAllPageStepNodes(), this.pageStepValue);
+		this.pageStepValue = null;
+	},
+	
+	_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);
+			// connect event
+			this.plugin.connect(node, "onclick", dojo.hitch(this, "_onPageStep"));
+			this.plugin.connect(node, "onmouseover", function(e){
+				dojo.addClass(e.target, "dojoxGridPageTextHover");
+			});
+			this.plugin.connect(node, "onmouseout", function(e){
+				dojo.removeClass(e.target, "dojoxGridPageTextHover");
+			});
+			dojo.style(node, "display", i < startPage + stepSize ? "block" : "none");
+		}
+		if(this.pageStepperWidth){
+			dojo.style(this.pageStepperTd, "width", this.pageStepperWidth);
+		}
+	},
+	
+	_createWardBtns: function(){
+		// summary:
+		//		Create the previous/next/first/last button
+		var self = this;
+		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);
+			// for high contrast
+			var highConrastNode = dojo.create("span", {value: value, title: label, innerHTML: highContrastLabel[value]}, node, position);
+			dojo.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");
+	},
+	
+	_resetPageStepNodes: function(){
+		// summary:
+		//		The page step nodes might be changed when fetch data, we need to
+		//		update/reset them
+		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 = 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 + ""]));
+			}else{
+				dojo.style(node, "display", "none");
+			}
+		}
+	},
+	
+	_updatePageStepNodeClass: function(){
+		// summary:
+		//		Update the style of the page step nodes
+		var value = null,
+			curPage = this._getCurrentPageNo(),
+			pageCount = this._getPageCount(),
+			visibleNodeLen = 0;
+			
+		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");
+			}else{
+				dojo.addClass(node, enableClass);
+				dojo.attr(node, "tabindex", "0");
+			}
+		};
+		dojo.forEach(this.pageStepperDiv.childNodes, function(node){
+			dojo.removeClass(node);
+			if(isNaN(parseInt(node.value, 10))){
+				dojo.addClass(node, "dojoxGridWardButton");
+				var disablePageNum = node.value == "prevPage" || node.value == "firstPage" ? 1 : pageCount;
+				updateClass(node, true, (curPage == disablePageNum));
+			}else{
+				value = parseInt(node.value, 10);
+				updateClass(node, false, (value === curPage || dojo.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;
+			}
+			return;
+		}
+		if(!this.gotoPageTd){
+			this._createGotoNode();
+		}
+		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);
+		}else{
+			this._currentFocusNode = this.gotoPageDiv;
+		}
+		if(this.focusArea != "pageStep"){
+			this.focusArea = "pageStep";
+		}
+		this._gotoPageDialog.updatePageCount();
+		this._gotoPageDialog.showDialog();
+	},
+	
+	// ===== focus handlers ===== //
+	_onFocusPaginator: function(event, step){
+		// 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){
+			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){
+			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];
+		}
+		dijit.focus(node);
+		this._currentFocusNode = node;
+	},
+	
+	// ===== pagination events handlers ===== //
+	_onSwitchPageSize: function(/*Event*/e){
+		// summary:
+		//		The handler of switch the page size
+		var size = this.pageSizeValue = e.target.value;
+		if(!size){
+			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);
+	},
+	
+	_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(!isNaN(parseInt(value, 10))){
+			p.gotoPage(value);
+		}else{
+			switch(e.target.value){
+				case "prevPage":
+					p.prevPage();
+					break;
+				case "nextPage":
+					p.nextPage();
+					break;
+				case "firstPage":
+					p.gotoFirstPage();
+					break;
+				case "lastPage":
+					p.gotoLastPage();
+			}
+		}
+	},
+	
+	// ===== 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){
+			return 1;
+		}else{
+			if(pc - cp < ms && cp - this.maxPageStep >= 0){
+				return pc - this.maxPageStep + 1;
+			}else{
+				return (cp - ms);
+			}
+		}
+	},
+	
+	_getStepPageSize: function(){
+		var sp = this._getStartPage();
+		var count = this._getPageCount();
+		if((sp + this.maxPageStep) > count){
+			return count - sp + 1;
+		}else{
+			return this.maxPageStep;
+		}
+	}
+
+});
+
+dojo.declare("dojox.grid.enhanced.plugins.pagination._GotoPageDialog", null, {
+	
+	pageCount: 0,
+	
+	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();
+	},
+	
+	_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"));
+	},
+	
+	_styleContent: function(){
+		dojo.addClass(this._specifyNode, "dojoxGridDialogMargin");
+		dojo.addClass(this._pageInputDiv, "dojoxGridDialogMargin");
+		dojo.addClass(this._buttonDiv, "dojoxGridDialogButton");
+		dojo.style(this._pageTextBox.domNode, "width", "50px");
+	},
+	
+	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]));
+	},
+	
+	showDialog: function(){
+		this._gotoPageDialog.show();
+	},
+	
+	_onConfirm: function(event){
+		// 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();
+		}
+		this.plugin._stopEvent(event);
+	},
+	
+	_onCancel: function(event){
+		// summary:
+		//		Cancel action and hide the dialog
+		this._pageTextBox.reset();
+		this._gotoPageDialog.hide();
+		this.plugin._stopEvent(event);
+	},
+	
+	_onKeyDown: function(event){
+		if(event.altKey || event.metaKey){
+			return;
+		}
+		var dk = dojo.keys;
+		if(event.keyCode === dk.ENTER){
+			this._onConfirm(event);
+		}
+	},
+	
+	_setConfirmBtnState: function(){
+		if(this._pageTextBox.isValid() && this._pageTextBox.getDisplayedValue() !== ""){
+			this._confirmBtn.set("disabled", false);
+		}else{
+			this._confirmBtn.set("disabled", true);
+		}
+	},
+	
+	destroy: function(){
+		this._pageTextBox.destroy();
+		this._confirmBtn.destroy();
+		this._cancelBtn.destroy();
+		this._gotoPageDialog.destroy();
+		
+		dojo.destroy(this._specifyNode);
+		dojo.destroy(this._pageInputDiv);
+		dojo.destroy(this._pageLabel);
+		dojo.destroy(this._buttonDiv);
+		dojo.destroy(this._dialogNode);
+	}
+});
+
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Pagination/*name:'pagination'*/);
\ No newline at end of file
diff --git a/dojox/grid/enhanced/plugins/Printer.js b/dojox/grid/enhanced/plugins/Printer.js
new file mode 100644
index 0000000..d96bfd1
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Printer.js
@@ -0,0 +1,258 @@
+dojo.provide("dojox.grid.enhanced.plugins.Printer");
+
+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, {
+	// summary:
+	//		Provide printGrid function to the grid.
+	// example:
+	//	|	dojo.require("dojox.grid.enhanced.plugins.Printer");
+	//	|	dijit.byId("grid1").printGrid("my grid",					//A title for the grid,optional
+	//	|								["cssfile1.css","cssfile2.css"],//An array of css files to decorate the printed gird,optional
+	//	|								{table:"border='border'"}		//tagName:"attrbuteList" pairs, optional,
+	//	|																//control the html tags in the generated html
+	//	|	);
+	
+	// __printArgs: {
+	//		title: String
+	//			A title of the printed page can be specified. Optional.
+	//			If given, it's shown in an <h1> tag at the top of the page.
+	//		cssFiles: Array | String
+	//			CSS file paths. Optional.
+	//			Every row and column is given CSS classes, including:
+	//				grid_row_{row-number}, grid_odd_row, grid_even_row, grid_header,
+	//				grid_col_{col-number}, grid_odd_col, grid_even_col
+	//			{row_number} and {col-number} are both integers starting from 1.
+	//			Row classes are for <thead> and <tbody> tags.
+	//			Column classes are for <th> and <td> tags.
+	//			Users can use these classes in the CSS files, but cannot define their own.
+	//		writerArgs: Object (Association Array)
+	//			Arguments for TableWriter.
+	//		fetchArgs: object?
+	//			Any arguments for store.fetch
+	// }
+	
+	// name: String
+	//		Plugin name
+	name: "printer",
+	
+	constructor: function(grid){
+		// summary:
+		//		only newed by _Plugin
+		// inGrid: EnhancedGrid
+		//		The grid to plug in to.
+		this.grid = grid;
+		this._mixinGrid(grid);
+		
+		//For print, we usually need the HTML instead of raw data.
+		grid.setExportFormatter(function(data, cell, rowIndex, rowItem){
+			return cell.format(rowIndex, rowItem);
+		});
+	},
+	_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);
+	},
+	printGrid: function(args){
+		// summary:
+		//		Print all the data in the grid, using title as a title,
+		//		decorating generated html by cssFiles,
+		//		using tagName:"attrbuteList" pairs(writerArgs) to control html tags
+		//		in the generated html string.
+		// tags:
+		//		public
+		// args: __printArgs?
+		//		Arguments for print.
+		this.exportToHTML(args, dojo.hitch(this, this._print));
+	},
+	printSelected: function(args){
+		// summary:
+		//		Print selected data. All other features are the same as printGrid.
+		//		For meaning of arguments see function *printGrid*
+		// tags:
+		//		public
+		// args: __printArgs?
+		//		Arguments for print.
+		this._print(this.exportSelectedToHTML(args));
+	},
+	exportToHTML: function(args, onExported){
+		// summary:
+		//		Export to HTML string, but do NOT print.
+		//		Users can use this to implement print preview.
+		//		For meaning of the 1st-3rd arguments see function *printGrid*.
+		// tags:
+		//		public
+		// args: __printArgs?
+		//		Arguments for print.
+		// onExported: function(string)
+		//		call back function
+		args = this._formalizeArgs(args);
+		var _this = this;
+		this.grid.exportGrid("table", args, function(str){
+			onExported(_this._wrapHTML(args.title, args.cssFiles, args.titleInBody + str));
+		});
+	},
+	exportSelectedToHTML: function(args){
+		// summary:
+		//		Export selected rows to HTML string, but do NOT print.
+		//		Users can use this to implement print preview.
+		//		For meaning of arguments see function *printGrid*
+		// tags:
+		//		public
+		// 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
+	},
+	_print: function(/* string */htmlStr){
+		// summary:
+		//		Do the print job.
+		// tags:
+		//		private
+		// htmlStr: String
+		//		The html content string to be printed.
+		// returns:
+		//		undefined
+		var win, _this = this,
+			fillDoc = function(w){
+				var doc = win.document;
+				doc.open();
+				doc.write(htmlStr);
+				doc.close();
+				_this.normalizeRowHeight(doc);
+			};
+		if(!window.print){
+			//We don't have a print facility.
+			return;
+		}else if(dojo.isChrome || dojo.isOpera){
+			//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");
+			fillDoc(win);
+			//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.
+			var fn = this._printFrame,
+				dn = this.grid.domNode;
+			if(!fn){
+				var frameId = dn.id + "_print_frame";
+				if(!(fn = dojo.byId(frameId))){
+					//create an iframe to store the grid data.
+					fn = dojo.create("iframe");
+					fn.id = frameId;
+					fn.frameBorder = 0;
+					dojo.style(fn, {
+						width: "1px",
+						height: "1px",
+						position: "absolute",
+						right: 0,
+						bottoom: 0,
+						border: "none",
+						overflow: "hidden"
+					});
+					if(!dojo.isIE){
+						dojo.style(fn, "visibility","hidden");
+					}
+					dn.appendChild(fn);
+				}
+				//Reuse this iframe
+				this._printFrame = fn;
+			}
+			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);
+			win.print();
+		}
+	},
+	_wrapHTML: function(/* string */title, /* Array */cssFiles, /* string */body_content){
+		// summary:
+		//		Put title, cssFiles, and body_content together into an HTML string.
+		// tags:
+		//		private
+		// title: String
+		//		A title for the html page.
+		// cssFiles: Array
+		//		css file pathes.
+		// body_content: String
+		//		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,
+					'</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
+	},
+	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 rowsPerView = dojo.map(views, function(view){
+			return dojo.query("tbody.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;
+			if(h > maxHeight){
+				maxHeight = h;
+			}
+		}
+		for(v = views.length - 1; v >= 0; --v){
+			dojo.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;
+				if(h > maxHeight){
+					maxHeight = h;
+				}
+			}
+			for(v = views.length - 1; v >= 0; --v){
+				dojo.style(rowsPerView[v][i], "height", maxHeight + "px");
+			}
+		}
+		var left = 0;
+		for(v = 0; v < views.length; ++v){
+			dojo.style(views[v], "left", left + "px");
+			left += dojo.marginBox(views[v]).w;
+		}
+	},
+	_formalizeArgs: function(args){
+		args = (args && dojo.isObject(args)) ? args : {};
+		args.title = String(args.title) || "";
+		if(!dojo.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'*/, {
+	"dependency": ["exporter"]
+});
diff --git a/dojox/grid/enhanced/plugins/Rearrange.js b/dojox/grid/enhanced/plugins/Rearrange.js
new file mode 100644
index 0000000..29684e8
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Rearrange.js
@@ -0,0 +1,481 @@
+dojo.provide("dojox.grid.enhanced.plugins.Rearrange");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojox.grid.enhanced.plugins._RowMapLayer");
+
+dojo.declare("dojox.grid.enhanced.plugins.Rearrange", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Provides a set of method to re-arrange the structure of grid.
+	
+	// name: String
+	//		plugin name
+	name: "rearrange",
+	
+	constructor: function(grid, args){
+		this.grid = grid;
+		this.setArgs(args);
+		var rowMapLayer = new dojox.grid.enhanced.plugins._RowMapLayer(grid);
+		dojox.grid.enhanced.plugins.wrap(grid, "_storeLayerFetch", rowMapLayer);
+	},
+	setArgs: function(args){
+		this.args = dojo.mixin(this.args || {}, args || {});
+		this.args.setIdentifierForNewItem = this.args.setIdentifierForNewItem || function(v){return v;};
+	},
+	destroy: function(){
+		this.inherited(arguments);
+		this.grid.unwrap("rowmap");
+	},
+	onSetStore: function(store){
+		this.grid.layer("rowmap").clearMapping();
+	},
+	_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){
+				return s.getIdentityAttributes(g._by_idx[point.r].item) == cells[point.c].field;
+			})){
+				return true;
+			}
+		}
+		return false;
+	},
+	moveColumns: function(colsToMove, targetPos){
+		// summary:
+		//		Move a set of columns to a given position.
+		// tag:
+		//		public
+		// colsToMove: Integer[]
+		//		Array of column indexes.
+		// targetPos: Integer
+		//		The target position
+		var g = this.grid,
+			layout = g.layout,
+			cells = layout.cells,
+			colIndex, i, delta = 0,
+			before = true, tmp = {}, mapping = {};
+		colsToMove.sort(function(a, b){
+			return a - b;
+		});
+		for(i = 0; i < colsToMove.length; ++i){
+			tmp[colsToMove[i]] = i;
+			if(colsToMove[i] < targetPos){
+				++delta;
+			}
+		}
+		var leftCount = 0;
+		var rightCount = 0;
+		var maxCol = Math.max(colsToMove[colsToMove.length - 1], targetPos);
+		if(maxCol == cells.length){
+			--maxCol;
+		}
+		for(i = colsToMove[0]; 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;
+			}
+		}
+		//console.log("mapping:", mapping, ", colsToMove:", colsToMove,", target:", targetPos);
+		delta = 0;
+		if(targetPos == cells.length){
+			--targetPos;
+			before = false;
+		}
+		g._notRefreshSelection = true;
+		for(i = 0; i < colsToMove.length; ++i){
+			colIndex = colsToMove[i];
+			if(colIndex < targetPos){
+				colIndex -= delta;
+			}
+			++delta;
+			if(colIndex != targetPos){
+				layout.moveColumn(cells[colIndex].view.idx, cells[targetPos].view.idx, colIndex, targetPos, before);
+				cells = layout.cells;
+			}
+			if(targetPos <= colIndex){
+				++targetPos;
+			}
+		}
+		delete g._notRefreshSelection;
+		dojo.publish("dojox/grid/rearrange/move/" + g.id, ["col", mapping, colsToMove]);
+	},
+	moveRows: function(rowsToMove, targetPos){
+		// summary:
+		//		Move a set of rows to a given position
+		// tag:
+		//		public
+		// rowsToMove: Integer[]
+		//		Array of row indexes.
+		// targetPos: Integer
+		//		The target position
+		var g = this.grid,
+			mapping = {},
+			preRowsToMove = [],
+			postRowsToMove = [],
+			len = rowsToMove.length,
+			i, r, k, arr, rowMap, lastPos;
+			
+		for(i = 0; i < len; ++i){
+			r = rowsToMove[i];
+			if(r >= targetPos){
+				break;
+			}
+			preRowsToMove.push(r);
+		}
+		postRowsToMove = rowsToMove.slice(i);
+		
+		arr = preRowsToMove;
+		len = arr.length;
+		if(len){
+			rowMap = {};
+			dojo.forEach(arr, function(r){
+				rowMap[r] = true;
+			});
+			mapping[arr[0]] = targetPos - len;
+			for(k = 0, i = arr[k] + 1, lastPos = i - 1; i < targetPos; ++i){
+				if(!rowMap[i]){
+					mapping[i] = lastPos;
+					++lastPos;
+				}else{
+					++k;
+					mapping[i] = targetPos - len + k;
+				}
+			}
+		}
+		arr = postRowsToMove;
+		len = arr.length;
+		if(len){
+			rowMap = {};
+			dojo.forEach(arr, function(r){
+				rowMap[r] = true;
+			});
+			mapping[arr[len - 1]] = targetPos + len - 1;
+			for(k = len - 1, i = arr[k] - 1, lastPos = i + 1; i >= targetPos; --i){
+				if(!rowMap[i]){
+					mapping[i] = lastPos;
+					--lastPos;
+				}else{
+					--k;
+					mapping[i] = targetPos + k;
+				}
+			}
+		}
+		var tmpMapping = dojo.clone(mapping);
+		g.layer("rowmap").setMapping(mapping);
+		g.forEachLayer(function(layer){
+			if(layer.name() != "rowmap"){
+				layer.invalidate();
+				return true;
+			}else{
+				return false;
+			}
+		}, false);
+		g.selection.selected = [];
+		g._noInternalMapping = true;
+		g._refresh();
+		setTimeout(function(){
+			dojo.publish("dojox/grid/rearrange/move/" + g.id, ["row", tmpMapping, rowsToMove]);
+			g._noInternalMapping = false;
+		}, 0);
+	},
+	moveCells: function(cellsToMove, target){
+		var g = this.grid,
+			s = g.store;
+		if(s.getFeatures()["dojo.data.api.Write"]){
+			if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+				//Same position, no need to move
+				return;
+			}
+			var cells = g.layout.cells,
+				cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+				r, c, tr, tc,
+				sources = [], targets = [];
+			for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+				for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+					while(cells[c] && cells[c].hidden){
+						++c;
+					}
+					while(cells[tc] && cells[tc].hidden){
+						++tc;
+					}
+					sources.push({
+						"r": r,
+						"c": c
+					});
+					targets.push({
+						"r": tr,
+						"c": tc,
+						"v": cells[c].get(r, g._by_idx[r].item)
+					});
+				}
+			}
+			if(this._hasIdentity(sources.concat(targets))){
+				console.warn("Can not write to identity!");
+				return;
+			}
+			dojo.forEach(sources, function(point){
+				s.setValue(g._by_idx[point.r].item, cells[point.c].field, "");
+			});
+			dojo.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", {
+						"from": cellsToMove,
+						"to": target
+					}]);
+				}
+			});
+		}
+	},
+	copyCells: function(cellsToMove, target){
+		var g = this.grid,
+			s = g.store;
+		if(s.getFeatures()["dojo.data.api.Write"]){
+			if(cellsToMove.min.row == target.min.row && cellsToMove.min.col == target.min.col){
+				return;
+			}
+			var cells = g.layout.cells,
+				cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+				r, c, tr, tc,
+				targets = [];
+			for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+				for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+					while(cells[c] && cells[c].hidden){
+						++c;
+					}
+					while(cells[tc] && cells[tc].hidden){
+						++tc;
+					}
+					targets.push({
+						"r": tr,
+						"c": tc,
+						"v": cells[c].get(r, g._by_idx[r].item)
+					});
+				}
+			}
+			if(this._hasIdentity(targets)){
+				console.warn("Can not write to identity!");
+				return;
+			}
+			dojo.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", {
+							"from": cellsToMove,
+							"to": target
+						}]);
+					}, 0);
+				}
+			});
+		}
+	},
+	changeCells: function(sourceGrid, cellsToMove, target){
+		var g = this.grid,
+			s = g.store;
+		if(s.getFeatures()["dojo.data.api.Write"]){
+			var srcg = sourceGrid,
+				cells = g.layout.cells,
+				srccells = srcg.layout.cells,
+				cnt = cellsToMove.max.row - cellsToMove.min.row + 1,
+				r, c, tr, tc, targets = [];
+			for(r = cellsToMove.min.row, tr = target.min.row; r <= cellsToMove.max.row; ++r, ++tr){
+				for(c = cellsToMove.min.col, tc = target.min.col; c <= cellsToMove.max.col; ++c, ++tc){
+					while(srccells[c] && srccells[c].hidden){
+						++c;
+					}
+					while(cells[tc] && cells[tc].hidden){
+						++tc;
+					}
+					targets.push({
+						"r": tr,
+						"c": tc,
+						"v": srccells[c].get(r, srcg._by_idx[r].item)
+					});
+				}
+			}
+			if(this._hasIdentity(targets)){
+				console.warn("Can not write to identity!");
+				return;
+			}
+			dojo.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]);
+				}
+			});
+		}
+	},
+	clearCells: function(cellsToClear){
+		var g = this.grid,
+			s = g.store;
+		if(s.getFeatures()["dojo.data.api.Write"]){
+			var cells = g.layout.cells,
+				cnt = cellsToClear.max.row - cellsToClear.min.row + 1,
+				r, c, targets = [];
+			for(r = cellsToClear.min.row; r <= cellsToClear.max.row; ++r){
+				for(c = cellsToClear.min.col; c <= cellsToClear.max.col; ++c){
+					while(cells[c] && cells[c].hidden){
+						++c;
+					}
+					targets.push({
+						"r": r,
+						"c": c
+					});
+				}
+			}
+			if(this._hasIdentity(targets)){
+				console.warn("Can not write to identity!");
+				return;
+			}
+			dojo.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]);
+				}
+			});
+		}
+	},
+	insertRows: function(sourceGrid, rowsToMove, targetPos){
+		try{
+			var g = this.grid,
+				s = g.store,
+				rowCnt = g.rowCount,
+				mapping = {},
+				obj = {idx: 0},
+				newRows = [], i,
+				_this = this;
+			var len = rowsToMove.length;
+			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];
+					}
+					var attrs = s.getAttributes(thisItem.item);
+					var rowsToFetch = [];
+					dojo.forEach(rowsToMove, function(rowIndex, i){
+						var item = {};
+						var srcItem = srcg._by_idx[rowIndex];
+						if(srcItem){
+							dojo.forEach(attrs, function(attr){
+								item[attr] = srcs.getValue(srcItem.item, attr);
+							});
+							item = _this.args.setIdentifierForNewItem(item, s, rowCnt + obj.idx) || item;
+							try{
+								s.newItem(item);
+								newRows.push(targetPos + i);
+								mapping[rowCnt + obj.idx] = targetPos + i;
+								++obj.idx;
+							}catch(e){
+								console.log("insertRows newItem:",e,item);
+							}
+						}else{
+							rowsToFetch.push(rowIndex);
+						}
+					});
+				}else if(rowsToMove.length && dojo.isObject(rowsToMove[0])){
+					dojo.forEach(rowsToMove, function(rowData, i){
+						var item = _this.args.setIdentifierForNewItem(rowData, s, rowCnt + obj.idx) || rowData;
+						try{
+							s.newItem(item);
+							newRows.push(targetPos + i);
+							mapping[rowCnt + obj.idx] = targetPos + i;
+							++obj.idx;
+						}catch(e){
+							console.log("insertRows newItem:",e,item);
+						}
+					});
+				}else{
+					return;
+				}
+				g.layer("rowmap").setMapping(mapping);
+				s.save({
+					onComplete: function(){
+						g._refresh();
+						setTimeout(function(){
+							dojo.publish("dojox/grid/rearrange/insert/" + g.id, ["row", newRows]);
+						}, 0);
+					}
+				});
+			}
+		}catch(e){
+			console.log("insertRows:",e);
+		}
+	},
+	removeRows: function(rowsToRemove){
+		var g = this.grid;
+		var s = g.store;
+		try{
+			dojo.forEach(dojo.map(rowsToRemove, function(rowIndex){
+				return g._by_idx[rowIndex];
+			}), function(row){
+				if(row){
+					s.deleteItem(row.item);
+				}
+			});
+			s.save({
+				onComplete: function(){
+					dojo.publish("dojox/grid/rearrange/remove/" + g.id, ["row", rowsToRemove]);
+				}
+			});
+		}catch(e){
+			console.log("removeRows:",e);
+		}
+	},
+	_getPageInfo: function(){
+		// summary:
+		//		Find pages that contain visible rows
+		// return: Object
+		//		{topPage: xx, bottomPage: xx, invalidPages: [xx,xx,...]}
+		var scroller = this.grid.scroller,
+			topPage = scroller.page,
+			bottomPage = scroller.page,
+			firstVisibleRow = scroller.firstVisibleRow,
+			lastVisibleRow = scroller.lastVisibleRow,
+			rowsPerPage = scroller.rowsPerPage,
+			renderedPages = scroller.pageNodes[0],
+			topRow, bottomRow, matched,
+			invalidPages = [];
+		
+		dojo.forEach(renderedPages, function(page, pageIndex){
+			if(!page){ return; }
+			matched = false;
+			topRow = pageIndex * rowsPerPage;
+			bottomRow = (pageIndex + 1) * rowsPerPage - 1;
+			if(firstVisibleRow >= topRow && firstVisibleRow <= bottomRow){
+				topPage = pageIndex;
+				matched = true;
+			}
+			if(lastVisibleRow >= topRow && lastVisibleRow <= bottomRow){
+				bottomPage = pageIndex;
+				matched = true;
+			}
+			if(!matched && (topRow > lastVisibleRow || bottomRow < firstVisibleRow)){
+				invalidPages.push(pageIndex);
+			}
+		});
+		return {topPage: topPage, bottomPage: bottomPage, invalidPages: invalidPages};
+	}
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Rearrange/*name:'rearrange'*/);
diff --git a/dojox/grid/enhanced/plugins/Search.js b/dojox/grid/enhanced/plugins/Search.js
new file mode 100644
index 0000000..4df51f4
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Search.js
@@ -0,0 +1,109 @@
+dojo.provide("dojox.grid.enhanced.plugins.Search");
+
+dojo.require("dojox.grid.enhanced._Plugin");
+dojo.require("dojo.data.util.filter");
+
+dojo.declare("dojox.grid.enhanced.plugins.Search", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Search the grid using wildcard string or Regular Expression.
+	
+	// name: String
+	//		plugin name
+	name: "search",
+	
+	constructor: function(grid, args){
+		this.grid = grid;
+		args = (args && dojo.isObject(args)) ? args : {};
+		this._cacheSize = args.cacheSize || -1;
+		grid.searchRow = dojo.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);
+		}
+		var isGlobal = false;
+		if(searchArgs instanceof RegExp){
+			isGlobal = true;
+		}else if(dojo.isObject(searchArgs)){
+			var isEmpty = true;
+			for(var field in searchArgs){
+				if(dojo.isString(searchArgs[field])){
+					searchArgs[field] = dojo.data.util.filter.patternToRegExp(searchArgs[field]);
+				}
+				isEmpty = false;
+			}
+			if(isEmpty){ return; }
+		}else{
+			return;
+		}
+		this._search(searchArgs, 0, onSearched, isGlobal);
+	},
+	_search: function(/* Object|RegExp */searchArgs, /* Integer */start, /* function(Integer, item) */onSearched, /* Boolean */isGlobal){
+		var _this = this,
+			cnt = this._cacheSize,
+			args = {
+				"start": start,
+				"onBegin": function(size){
+					_this._storeSize = size;
+				},
+				"onComplete": function(items){
+					if(!dojo.some(items, function(item, i){
+						if(_this._checkRow(item, searchArgs, isGlobal)){
+							onSearched(start + i, item);
+							return true;
+						}
+						return false;
+					})){
+						if(cnt > 0 && start + cnt < _this._storeSize){
+							_this._search(searchArgs, start + cnt, onSearched, isGlobal);
+						}else{
+							onSearched(-1, null);
+						}
+					}
+				}
+			};
+		if(cnt > 0){
+			args.count = cnt;
+		}
+		this.grid._storeLayerFetch(args);
+	},
+	_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){
+				return !cell.hidden;
+			});
+		if(isGlobal){
+			return dojo.some(cells, function(cell){
+				try{
+					if(cell.field){
+						return String(s.getValue(item, cell.field)).search(searchArgs) >= 0;
+					}
+				}catch(e){
+					console.log("Search._checkRow() error: ", e);
+				}
+				return false;
+			});
+		}else{
+			for(field in searchArgs){
+				if(searchArgs[field] instanceof RegExp){
+					for(i = cells.length - 1; i >= 0; --i){
+						if(cells[i].field == field){
+							try{
+								if(String(s.getValue(item, field)).search(searchArgs[field]) < 0){
+									return false;
+								}
+								break;
+							}catch(e){
+								return false;
+							}
+						}
+					}
+					if(i < 0){ return false; }
+				}
+			}
+			return true;
+		}
+	}
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Search/*name:'search'*/);
diff --git a/dojox/grid/enhanced/plugins/Selector.js b/dojox/grid/enhanced/plugins/Selector.js
new file mode 100644
index 0000000..51f01d6
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/Selector.js
@@ -0,0 +1,1447 @@
+dojo.provide("dojox.grid.enhanced.plugins.Selector");
+
+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:
+	//		An abstract representation of an item.
+});
+dojo.declare("__SelectCellItem", __SelectItem,{
+	// summary:
+	//		An abstract representation of a cell.
+	
+	// row: Integer
+	//		Row index of this cell
+	row: 0,
+	
+	// col: Integer
+	//		Column index of this cell
+	col: 0
+});
+dojo.declare("__SelectRowItem", __SelectItem,{
+	// summary:
+	//		An abstract representation of a row.
+	
+	// row: Integer
+	//		Row index of this row
+	row: 0,
+	
+	// except: Integer[]
+	//		An array of column indexes of all the unselected cells in this row.
+	except: []
+});
+dojo.declare("__SelectColItem", __SelectItem,{
+	// summary:
+	//		An abstract representation of a column.
+	
+	// col: Integer
+	//		Column index of this column
+	col: 0,
+	
+	// except: Integer[]
+	//		An array of row indexes of all the unselected cells in this column.
+	except: []
+});
+=====*/
+
+var DISABLED = 0, SINGLE = 1, MULTI = 2,
+	_theOther = { col: "row", row: "col" },
+	_inRange = function(type, value, start, end, halfClose){
+		if(type !== "cell"){
+			value = value[type];
+			start = start[type];
+			end = end[type];
+			if(typeof value !== "number" || typeof start !== "number" || typeof end !== "number"){
+				return false;
+			}
+			return halfClose ? ((value >= start && value < end) || (value > end && value <= start))
+							: ((value >= start && value <= end) || (value >= end && value <= start));
+		}else{
+			return _inRange("col", value, start, end, halfClose) && _inRange("row", value, start, end, halfClose);
+		}
+	},
+	_isEqual = function(type, v1, v2){
+		try{
+			if(v1 && v2){
+				switch(type){
+					case "col": case "row":
+						return v1[type] == v2[type] && typeof v1[type] == "number" &&
+								!(_theOther[type] in v1) && !(_theOther[type] in v2);
+					case "cell":
+						return v1.col == v2.col && v1.row == v2.row && typeof v1.col == "number" && typeof v1.row == "number";
+				}
+			}
+		}catch(e){}
+		return false;
+	},
+	_stopEvent = function(evt){
+		try{
+			if(evt && evt.preventDefault){
+				dojo.stopEvent(evt);
+			}
+		}catch(e){}
+	},
+	_createItem = function(type, rowIndex, colIndex){
+		switch(type){
+			case "col":
+				return {
+					"col": typeof colIndex == "undefined" ? rowIndex : colIndex,
+					"except": []
+				};
+			case "row":
+				return {
+					"row": rowIndex,
+					"except": []
+				};
+			case "cell":
+				return {
+					"row": rowIndex,
+					"col": colIndex
+				};
+		}
+		return null;
+	};
+dojo.declare("dojox.grid.enhanced.plugins.Selector", dojox.grid.enhanced._Plugin, {
+	// summary:
+	//		Provides standard extended selection for grid.
+	//		Supports mouse/keyboard selection, multi-selection, and de-selection.
+	//		Acceptable plugin parameters:
+	//			The whole plugin parameter object is a config object passed to the setupConfig function.
+	//
+	//		Acceptable cell parameters defined in layout:
+	//		1. notselectable: boolean
+	//			Whether this column is (and all the cells in it are) selectable.
+	
+	// name: String
+	//		plugin name
+	name: "selector",
+/*
+	//	_config: null,
+	//	_enabled: true,
+	//	_selecting: {
+	//		row: false,
+	//		col: false,
+	//		cell: false
+	//	},
+	//	_selected: {
+	//		row: [],
+	//		col: [],
+	//		cell: []
+	//	},
+	//	_startPoint: {},
+	//	_currentPoint: {},
+	//	_lastAnchorPoint: {},
+	//	_lastEndPoint: {},
+	//	_lastSelectedAnchorPoint: {},
+	//	_lastSelectedEndPoint: {},
+	//	_keyboardSelect: {
+	//		row: 0,
+	//		col: 0,
+	//		cell: 0
+	//	},
+	//	_curType: null,
+	//	_lastType: null,
+	//	_usingKeyboard: false,
+	//	_toSelect: true,
+*/
+
+	constructor: function(grid, args){
+		this.grid = grid;
+		this._config = {
+			row: MULTI,
+			col: MULTI,
+			cell: MULTI
+		};
+		this.setupConfig(args);
+		if(grid.selectionMode === "single"){
+			this._config.row = SINGLE;
+		}
+		this._enabled = true;
+		this._selecting = {};
+		this._selected = {
+			"col": [],
+			"row": [],
+			"cell": []
+		};
+		this._startPoint = {};
+		this._currentPoint = {};
+		this._lastAnchorPoint = {};
+		this._lastEndPoint = {};
+		this._lastSelectedAnchorPoint = {};
+		this._lastSelectedEndPoint = {};
+		this._keyboardSelect = {};
+		this._lastType = null;
+		this._selectedRowModified = {};
+		this._hacks();
+		this._initEvents();
+		this._initAreas();
+		this._mixinGrid();
+	},
+	destroy: function(){
+		this.inherited(arguments);
+	},
+	//------------public--------------------
+	setupConfig: function(config){
+		// summary:
+		//		Set selection mode for row/col/cell.
+		// config: Object
+		//		An object with the following structure (all properties are optional):
+		//		{
+		//			//Default is "multi", all other values are same as "multi".
+		//			row: false|"disabled"|"single",
+		//			col: false|"disabled"|"single",
+		//			cell: false|"disabled"|"single"
+		//		}
+		if(!config || !dojo.isObject(config)){
+			return;
+		}
+		var types = ["row", "col", "cell"];
+		for(var type in config){
+			if(dojo.indexOf(types, type) >= 0){
+				if(!config[type] || config[type] == "disabled"){
+					this._config[type] = DISABLED;
+				}else if(config[type] == "single"){
+					this._config[type] = SINGLE;
+				}else{
+					this._config[type] = MULTI;
+				}
+			}
+		}
+		
+		//Have to set mode to default grid selection.
+		var mode = ["none","single","extended"][this._config.row];
+		this.grid.selection.setMode(mode);
+	},
+	isSelected: function(type, rowIndex, colIndex){
+		// summary:
+		//		Check whether a location (a cell, a column or a row) is selected.
+		// tag:
+		//		public
+		// type: String
+		//		"row" or "col" or "cell"
+		// rowIndex: Integer
+		//		If type is "row" or "cell", this is the row index.
+		//		If type if "col", this is the column index.
+		// colIndex: Integer?
+		//		Only valid when type is "cell"
+		// return: Boolean
+		//		true if selected, false if not. If cell is covered by a selected column, it's selected.
+		return this._isSelected(type, _createItem(type, rowIndex, colIndex));
+	},
+	toggleSelect: function(type, rowIndex, colIndex){
+		this._startSelect(type, _createItem(type, rowIndex, colIndex), this._config[type] === MULTI, false, false, !this.isSelected(type, rowIndex, colIndex));
+		this._endSelect(type);
+	},
+	select: function(type, rowIndex, colIndex){
+		// summary:
+		//		Select a location (a cell, a column or a row).
+		// tag:
+		//		public
+		// type: String
+		//		"row" or "col" or "cell"
+		// rowIndex: Integer
+		//		If type is "row" or "cell", this is the row index.
+		//		If type if "col", this is the column index.
+		// colIndex: Integer?
+		//		Only valid when type is "cell"
+		if(!this.isSelected(type, rowIndex, colIndex)){
+			this.toggleSelect(type, rowIndex, colIndex);
+		}
+	},
+	deselect: function(type, rowIndex, colIndex){
+		if(this.isSelected(type, rowIndex, colIndex)){
+			this.toggleSelect(type, rowIndex, colIndex);
+		}
+	},
+	selectRange: function(type, start, end, toSelect){
+		// summary:
+		//		Select a continuous range (a block of cells, a set of continuous columns or rows)
+		// tag:
+		//		public
+		// type: String
+		//		"row" or "col" or "cell"
+		// start: Integer | Object
+		//		If type is "row" or "col", this is the index of the starting row or column.
+		//		If type if "cell", this is the left-top cell of the range.
+		// end: Integer | Object
+		//		If type is "row" or "col", this is the index of the ending row or column.
+		//		If type if "cell", this is the right-bottom cell of the range.
+		this.grid._selectingRange = true;
+		var startPoint = type == "cell" ? _createItem(type, start.row, start.col) : _createItem(type, start),
+			endPoint = type == "cell" ? _createItem(type, end.row, end.col) : _createItem(type, end);
+		this._startSelect(type, startPoint, false, false, false, toSelect);
+		this._highlight(type, endPoint, toSelect === undefined ? true : toSelect);
+		this._endSelect(type);
+		this.grid._selectingRange = false;
+	},
+	clear: function(type){
+		// summary:
+		//		Clear all selections.
+		// tag:
+		//		public
+		// type: String?
+		//		"row" or "col" or "cell". If omitted, clear all.
+		this._clearSelection(type || "all");
+	},
+	isSelecting: function(type){
+		// summary:
+		//		Check whether the user is currently selecting something.
+		// tag:
+		//		public
+		// type: String
+		//		"row" or "col" or "cell"
+		// return: Boolean
+		//		true if is selection, false otherwise.
+		if(typeof type == "undefined"){
+			return this._selecting.col || this._selecting.row || this._selecting.cell;
+		}
+		return this._selecting[type];
+	},
+	selectEnabled: function(toEnable){
+		// summary:
+		//		Turn on/off this selection functionality if *toEnable* is provided.
+		//		Check whether this selection functionality is enabled if nothing is passed in.
+		// tag:
+		//		public
+		// toEnable: Boolean?
+		//		To enable or not. Optional.
+		// return: Boolean | undefined
+		//		Enabled or not.
+		if(typeof toEnable != "undefined" && !this.isSelecting()){
+			this._enabled = !!toEnable;
+		}
+		return this._enabled;
+	},
+	getSelected: function(type, includeExceptions){
+		// summary:
+		//		Get an array of selected locations.
+		// tag:
+		//		public
+		// type: String
+		//		"row" or "col" or "cell"
+		// includeExceptions: Boolean
+		//		Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+		// return: __SelectItem[]
+		switch(type){
+			case "cell":
+				return dojo.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 item.except.length === 0;
+				}), function(item){
+					return includeExceptions ? item : item[type];
+				});
+		}
+		return [];
+	},
+	getSelectedCount: function(type, includeExceptions){
+		// summary:
+		//		Get the number of selected items.
+		// tag:
+		//		public
+		// type: String
+		//		"row" or "col" or "cell"
+		// includeExceptions: Boolean
+		//		Only meaningful for rows/columns. If true, all selected rows/cols, even they are partly selected, are all returned.
+		// return: Integer
+		//		The number of selected items.
+		switch(type){
+			case "cell":
+				return this._selected[type].length;
+			case "col": case "row":
+				return (includeExceptions ? this._selected[type]
+				: dojo.filter(this._selected[type], function(item){
+					return item.except.length === 0;
+				})).length;
+		}
+		return 0;
+	},
+	getSelectedType: function(){
+		// summary:
+		//		Get the type of selected items.
+		// tag:
+		//		public
+		// return: String
+		//		"row" or "col" or "cell", or any mix of these (separator is | ).
+		var s = this._selected;
+		return ["",		"cell",		"row",		"row|cell",
+				"col",	"col|cell",	"col|row",	"col|row|cell"
+			][(!!s.cell.length) | (!!s.row.length << 1) | (!!s.col.length << 2)];
+	},
+	getLastSelectedRange: function(type){
+		// summary:
+		//		Get last selected range of the given type.
+		// tag:
+		//		public
+		// return: Object
+		//		{start: __SelectItem, end: __SelectItem}
+		//		return null if nothing is selected.
+		return this._lastAnchorPoint[type] ? {
+			"start": this._lastAnchorPoint[type],
+			"end": this._lastEndPoint[type]
+		} : null;
+	},
+	
+	//--------------------------private----------------------------
+	_hacks: function(){
+		// summary:
+		//		Complete the event system of grid, hack some grid functions to prevent default behavior.
+		var g = this.grid;
+		var doContentMouseUp = function(e){
+			if(e.cellNode){
+				g.onMouseUp(e);
+			}
+			g.onMouseUpRow(e);
+		};
+		var mouseUp = dojo.hitch(g, "onMouseUp");
+		var mouseDown = dojo.hitch(g, "onMouseDown");
+		var doRowSelectorFocus = function(e){
+			e.cellNode.style.border = "solid 1px";
+		};
+		dojo.forEach(g.views.views, function(view){
+			view.content.domouseup = doContentMouseUp;
+			view.header.domouseup = mouseUp;
+			if(view.declaredClass == "dojox.grid._RowSelector"){
+				view.domousedown = mouseDown;
+				view.domouseup = mouseUp;
+				view.dofocus = doRowSelectorFocus;
+			}
+		});
+		//Disable default selection.
+		g.selection.clickSelect = function(){};
+		
+		this._oldDeselectAll = g.selection.deselectAll;
+		var _this = this;
+		g.selection.selectRange = function(from, to){
+			_this.selectRange("row", from, to, true);
+			if(g.selection.preserver){
+				g.selection.preserver._updateMapping(true, true, false, from, to);
+			}
+			g.selection.onChanged();
+		};
+		g.selection.deselectRange = function(from, to){
+			_this.selectRange("row", from, to, false);
+			if(g.selection.preserver){
+				g.selection.preserver._updateMapping(true, false, false, from, to);
+			}
+			g.selection.onChanged();
+		};
+		g.selection.deselectAll = function(){
+			g._selectingRange = true;
+			_this._oldDeselectAll.apply(g.selection, arguments);
+			_this._clearSelection("row");
+			g._selectingRange = false;
+			if(g.selection.preserver){
+				g.selection.preserver._updateMapping(true, false, true);
+			}
+			g.selection.onChanged();
+		};
+		
+		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){
+			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));
+			};
+		}
+		this.connect(g, "updateRow", function(rowIndex){
+			dojo.forEach(g.layout.cells, function(cell){
+				if(this.isSelected("cell", rowIndex, cell.index)){
+					this._highlightNode(cell.getNode(rowIndex), true);
+				}
+			}, this);
+		});
+	},
+	_mixinGrid: function(){
+		// summary:
+		//		Expose events to grid.
+		var g = this.grid;
+		g.setupSelectorConfig = dojo.hitch(this, this.setupConfig);
+		g.onStartSelect = function(){};
+		g.onEndSelect = function(){};
+		g.onStartDeselect = function(){};
+		g.onEndDeselect = function(){};
+		g.onSelectCleared = function(){};
+	},
+	_initEvents: function(){
+		// summary:
+		//		Connect events, create event handlers.
+		var g = this.grid,
+			_this = this,
+			dp = dojo.partial,
+			starter = function(type, e){
+				if(type === "row"){
+					_this._isUsingRowSelector = true;
+				}
+				//only left mouse button can select.
+				if(_this.selectEnabled() && _this._config[type] && e.button != 2){
+					if(_this._keyboardSelect.col || _this._keyboardSelect.row || _this._keyboardSelect.cell){
+						_this._endSelect("all");
+						_this._keyboardSelect.col = _this._keyboardSelect.row = _this._keyboardSelect.cell = 0;
+					}
+					if(_this._usingKeyboard){
+						_this._usingKeyboard = false;
+					}
+					var target = _createItem(type, e.rowIndex, e.cell && e.cell.index);
+					_this._startSelect(type, target, e.ctrlKey, e.shiftKey);
+				}
+			},
+			ender = dojo.hitch(this, "_endSelect");
+		this.connect(g, "onHeaderCellMouseDown", dp(starter, "col"));
+		this.connect(g, "onHeaderCellMouseUp", dp(ender, "col"));
+		
+		this.connect(g, "onRowSelectorMouseDown", dp(starter, "row"));
+		this.connect(g, "onRowSelectorMouseUp", dp(ender, "row"));
+		
+		this.connect(g, "onCellMouseDown", function(e){
+			if(e.cell && e.cell.isRowSelector){ return; }
+			if(g.singleClickEdit){
+				_this._singleClickEdit = true;
+				g.singleClickEdit = false;
+			}
+			starter(_this._config["cell"] == DISABLED ? "row" : "cell", e);
+		});
+		this.connect(g, "onCellMouseUp", function(e){
+			if(_this._singleClickEdit){
+				delete _this._singleClickEdit;
+				g.singleClickEdit = true;
+			}
+			ender("all", e);
+		});
+		
+		this.connect(g, "onCellMouseOver", function(e){
+			if(_this._curType != "row" && _this._selecting[_this._curType] && _this._config[_this._curType] == MULTI){
+				_this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+				if(!_this._keyboardSelect.cell){
+					_this._highlight("cell", _createItem("cell", e.rowIndex, e.cell.index), _this._toSelect);
+				}
+			}
+		});
+		this.connect(g, "onHeaderCellMouseOver", function(e){
+			if(_this._selecting.col && _this._config.col == MULTI){
+				_this._highlight("col", _createItem("col", e.cell.index), _this._toSelect);
+			}
+		});
+		this.connect(g, "onRowMouseOver", function(e){
+			if(_this._selecting.row && _this._config.row == MULTI){
+				_this._highlight("row", _createItem("row", e.rowIndex), _this._toSelect);
+			}
+		});
+		
+		//When row order has changed in a unpredictable way (sorted or filtered), map the new rowindex.
+		this.connect(g, "onSelectedById", "_onSelectedById");
+		
+		//When the grid refreshes, all those selected should still appear selected.
+		this.connect(g, "_onFetchComplete", function(){
+			//console.debug("refresh after buildPage:", g._notRefreshSelection);
+			if(!g._notRefreshSelection){
+				this._refreshSelected(true);
+			}
+		});
+
+		//Small scroll might not refresh the grid.
+		this.connect(g.scroller, "buildPage", function(){
+			//console.debug("refresh after buildPage:", g._notRefreshSelection);
+			if(!g._notRefreshSelection){
+				this._refreshSelected(true);
+			}
+		});
+		
+		//Whenever the mouse is up, end selecting.
+		this.connect(dojo.doc, "onmouseup", dp(ender, "all"));
+		
+		//If autoscroll is enabled, connect to it.
+		this.connect(g, "onEndAutoScroll", function(isVertical, isForward, view, target){
+			var selectCell = _this._selecting.cell,
+				type, current, dir = isForward ? 1 : -1;
+			if(isVertical && (selectCell || _this._selecting.row)){
+				type = selectCell ? "cell" : "row";
+				current = _this._currentPoint[type];
+				_this._highlight(type, _createItem(type, current.row + dir, current.col), _this._toSelect);
+			}else if(!isVertical && (selectCell || _this._selecting.col)){
+				type = selectCell ? "cell" : "col";
+				current = _this._currentPoint[type];
+				_this._highlight(type, _createItem(type, current.row, target), _this._toSelect);
+			}
+		});
+		//If the grid is changed, selection should be consistent.
+		this.subscribe("dojox/grid/rearrange/move/" + g.id, "_onInternalRearrange");
+		this.subscribe("dojox/grid/rearrange/copy/" + g.id, "_onInternalRearrange");
+		this.subscribe("dojox/grid/rearrange/change/" + g.id, "_onExternalChange");
+		this.subscribe("dojox/grid/rearrange/insert/" + g.id, "_onExternalChange");
+		this.subscribe("dojox/grid/rearrange/remove/" + g.id, "clear");
+		
+		//have to also select when the grid's default select is used.
+		this.connect(g, "onSelected", function(rowIndex){
+			if(this._selectedRowModified && this._isUsingRowSelector){
+				delete this._selectedRowModified;
+			}else if(!this.grid._selectingRange){
+				this.select("row", rowIndex);
+			}
+		});
+		this.connect(g, "onDeselected", function(rowIndex){
+			if(this._selectedRowModified && this._isUsingRowSelector){
+				delete this._selectedRowModified;
+			}else if(!this.grid._selectingRange){
+				this.deselect("row", rowIndex);
+			}
+		});
+	},
+	_onSelectedById: function(id, newIndex, isSelected){
+		if(this.grid._noInternalMapping){
+			return;
+		}
+		var pointSet = [this._lastAnchorPoint.row, this._lastEndPoint.row,
+			this._lastSelectedAnchorPoint.row, this._lastSelectedEndPoint.row];
+		pointSet = pointSet.concat(this._selected.row);
+		var found = false;
+		dojo.forEach(pointSet, function(item){
+			if(item){
+				if(item.id === id){
+					found = true;
+					item.row = newIndex;
+				}else if(item.row === newIndex && item.id){
+					item.row = -1;
+				}
+			}
+		});
+		if(!found && isSelected){
+			dojo.some(this._selected.row, function(item){
+				if(item && !item.id && !item.except.length){
+					item.id = id;
+					item.row = newIndex;
+					return true;
+				}
+				return false;
+			});
+		}
+		found = false;
+		pointSet = [this._lastAnchorPoint.cell, this._lastEndPoint.cell,
+			this._lastSelectedAnchorPoint.cell, this._lastSelectedEndPoint.cell];
+		pointSet = pointSet.concat(this._selected.cell);
+		dojo.forEach(pointSet, function(item){
+			if(item){
+				if(item.id === id){
+					found = true;
+					item.row = newIndex;
+				}else if(item.row === newIndex && item.id){
+					item.row = -1;
+				}
+			}
+		});
+	},
+	onSetStore: function(){
+		this._clearSelection("all");
+	},
+	_onInternalRearrange: function(type, mapping){
+		try{
+		//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){
+				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");
+		});
+		
+		var cleanUp = function(item){
+			if(item){
+				delete item.converted;
+			}
+		},
+		pointSet = [this._lastAnchorPoint[type], this._lastEndPoint[type],
+			this._lastSelectedAnchorPoint[type], this._lastSelectedEndPoint[type]];
+		
+		if(type === "cell"){
+			this.selectRange("cell", mapping.to.min, mapping.to.max);
+			var cells = this.grid.layout.cells;
+			dojo.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){
+						while(cells[c].hidden){ ++c; }
+						while(cells[tc].hidden){ ++tc; }
+						if(item.row == r && item.col == c){
+							//console.log('mapping found: (', item.row, ",",item.col,") to (", tr, ",", tc,")");
+							item.row = tr;
+							item.col = tc;
+							item.converted = true;
+							return;
+						}
+					}
+				}
+			});
+		}else{
+			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){
+				if(item && !item.converted){
+					var from = item[type];
+					if(from in mapping){
+						item[type] = mapping[from];
+					}
+					item.converted = true;
+				}
+			});
+			dojo.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){
+						item.except[i] = mapping[from];
+					}
+				}
+			});
+		}
+		
+		dojo.forEach(pointSet, cleanUp);
+		
+		this._refreshSelected(true);
+		this._focusPoint(type, this._lastEndPoint);
+		}catch(e){
+			console.warn("Selector._onInternalRearrange() error",e);
+		}
+	},
+	_onExternalChange: function(type, target){
+		var start = type == "cell" ? target.min : target[0],
+			end = type == "cell" ? target.max : target[target.length - 1];
+		this.selectRange(type, start, end);
+	},
+	_refresh: function(type, toHighlight){
+		if(!this._keyboardSelect[type]){
+			dojo.forEach(this._selected[type], function(item){
+				this._highlightSingle(type, toHighlight, item, undefined, true);
+			}, this);
+		}
+	},
+	_refreshSelected: function(){
+		this._refresh("col", true);
+		this._refresh("row", true);
+		this._refresh("cell", true);
+	},
+	_initAreas: function(){
+		var g = this.grid, f = g.focus, _this = this, dk = dojo.keys,
+			keyboardSelectReady = 1, duringKeyboardSelect = 2,
+			onmove = function(type, createNewEnd, rowStep, colStep, evt){
+				//Keyboard swipe selection is SHIFT + Direction Keys.
+				var ks = _this._keyboardSelect;
+				//Tricky, rely on valid status not being 0.
+				if(evt.shiftKey && ks[type]){
+					if(ks[type] === keyboardSelectReady){
+						if(type === "cell"){
+							var item = _this._lastEndPoint[type];
+							if(f.cell != g.layout.cells[item.col + colStep] || f.rowIndex != item.row + rowStep){
+								ks[type] = 0;
+								return;
+							}
+						}
+						//If selecting is not started, start it
+						_this._startSelect(type, _this._lastAnchorPoint[type], true, false, true);
+						_this._highlight(type, _this._lastEndPoint[type], _this._toSelect);
+						ks[type] = duringKeyboardSelect;
+					}
+					//Highlight to the new end point.
+					var newEnd = createNewEnd(type, rowStep, colStep, evt);
+					if(_this._isValid(type, newEnd, g)){
+						_this._highlight(type, newEnd, _this._toSelect);
+					}
+					_stopEvent(evt);
+				}
+			},
+			onkeydown = function(type, getTarget, evt, isBubble){
+				if(isBubble && _this.selectEnabled() && _this._config[type] != DISABLED){
+					switch(evt.keyCode){
+						case dk.SPACE:
+							//Keyboard single point selection is SPACE.
+							_this._startSelect(type, getTarget(), evt.ctrlKey, evt.shiftKey);
+							_this._endSelect(type);
+							break;
+						case dk.SHIFT:
+							//Keyboard swipe selection starts with SHIFT.
+							if(_this._config[type] == MULTI && _this._isValid(type, _this._lastAnchorPoint[type], g)){
+								//End last selection if any.
+								_this._endSelect(type);
+								_this._keyboardSelect[type] = keyboardSelectReady;
+								_this._usingKeyboard = true;
+							}
+					}
+				}
+			},
+			onkeyup = function(type, evt, isBubble){
+				if(isBubble && evt.keyCode == dojo.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){
+			this._lastFocusedRowBarIdx = 0;
+			f.addArea({
+				name:"rowHeader",
+				onFocus: function(evt, step){
+					var view = g.views.views[0];
+					if(view instanceof dojox.grid._RowSelector){
+						var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+						if(rowBarNode){
+							dojo.toggleClass(rowBarNode, f.focusClass, false);
+						}
+						//evt might not be real event, it may be a mock object instead.
+						if(evt && "rowIndex" in evt){
+							if(evt.rowIndex >= 0){
+								_this._lastFocusedRowBarIdx = evt.rowIndex;
+							}else if(!_this._lastFocusedRowBarIdx){
+								_this._lastFocusedRowBarIdx = 0;
+							}
+						}
+						rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+						if(rowBarNode){
+							dijit.focus(rowBarNode);
+							dojo.toggleClass(rowBarNode, f.focusClass, true);
+						}
+						f.rowIndex = _this._lastFocusedRowBarIdx;
+						_stopEvent(evt);
+						return true;
+					}
+					return false;
+				},
+				onBlur: function(evt, step){
+					var view = g.views.views[0];
+					if(view instanceof dojox.grid._RowSelector){
+						var rowBarNode = view.getCellNode(_this._lastFocusedRowBarIdx, 0);
+						if(rowBarNode){
+							dojo.toggleClass(rowBarNode, f.focusClass, false);
+						}
+						_stopEvent(evt);
+					}
+					return true;
+				},
+				onMove: function(rowStep, colStep, evt){
+					var view = g.views.views[0];
+					if(rowStep && view instanceof dojox.grid._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);
+							//If the row is not fetched, fetch it.
+							var sc = g.scroller;
+							var lastPageRow = sc.getLastPageRow(sc.page);
+							var rc = g.rowCount - 1, row = Math.min(rc, next);
+							if(next > lastPageRow){
+								g.setScrollTop(g.scrollTop + sc.findScrollTop(row) - sc.findScrollTop(_this._lastFocusedRowBarIdx));
+							}
+							//Now we have fetched the row.
+							rowBarNode = view.getCellNode(next, 0);
+							dijit.focus(rowBarNode);
+							dojo.toggleClass(rowBarNode, f.focusClass, true);
+							_this._lastFocusedRowBarIdx = next;
+							//If the row is out of view, scroll to it.
+							f.cell = rowBarNode;
+							f.cell.view = view;
+							f.cell.getNode = function(index){
+								return f.cell;
+							};
+							f.rowIndex = _this._lastFocusedRowBarIdx;
+							f.scrollIntoView();
+							f.cell = null;
+						}
+					}
+				}
+			});
+			f.placeArea("rowHeader","before","content");
+		}
+		//Support keyboard selection.
+		f.addArea({
+			name:"cellselect",
+			onMove: dojo.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(){
+				return _createItem("cell", f.rowIndex, f.cell.index);
+			}),
+			onKeyUp: dojo.partial(onkeyup, "cell")
+		});
+		f.placeArea("cellselect","below","content");
+		f.addArea({
+			name:"colselect",
+			onMove: dojo.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(){
+				return _createItem("col", f.getHeaderIndex());
+			}),
+			onKeyUp: dojo.partial(onkeyup, "col")
+		});
+		f.placeArea("colselect","below","header");
+		f.addArea({
+			name:"rowselect",
+			onMove: dojo.partial(onmove, "row", function(type, rowStep, colStep, evt){
+				return _createItem("row", f.rowIndex);
+			}),
+			onKeyDown: dojo.partial(onkeydown, "row", function(){
+				return _createItem("row", f.rowIndex);
+			}),
+			onKeyUp: dojo.partial(onkeyup, "row")
+		});
+		f.placeArea("rowselect","below","rowHeader");
+	},
+	_clearSelection: function(type, reservedItem){
+		// summary:
+		//		Clear selection for given type and fire events, but retain the highlight for *reservedItem*,
+		//		thus avoid "flashing".
+		// tag:
+		//		private
+		// type: String
+		//		"row", "col", or "cell
+		// reservedItem: __SelectItem
+		//		The item to retain highlight.
+		if(type == "all"){
+			this._clearSelection("cell", reservedItem);
+			this._clearSelection("col", reservedItem);
+			this._clearSelection("row", reservedItem);
+			return;
+		}
+		this._isUsingRowSelector = true;
+		dojo.forEach(this._selected[type], function(item){
+			if(!_isEqual(type, reservedItem, item)){
+				this._highlightSingle(type, false, item);
+			}
+		}, this);
+		this._blurPoint(type, this._currentPoint);
+		this._selecting[type] = false;
+		this._startPoint[type] = this._currentPoint[type] = null;
+		this._selected[type] = [];
+		
+		//Have to also deselect default grid selection.
+		if(type == "row" && !this.grid._selectingRange){
+			this._oldDeselectAll.call(this.grid.selection);
+			this.grid.selection._selectedById = {};
+		}
+		
+		//Fire events.
+		this.grid.onEndDeselect(type, null, null, this._selected);
+		this.grid.onSelectCleared(type);
+	},
+	_startSelect: function(type, start, extending, isRange, mandatarySelect, toSelect){
+		// summary:
+		//		Start selection, setup start point and current point, fire events.
+		// tag:
+		//		private
+		// type: String
+		//		"row", "col", or "cell"
+		// extending: Boolean
+		//		Whether this is a multi selection
+		// isRange: Boolean
+		//		Whether this is a range selection (i.e. select from the last end point to this point)
+		// start: __SelectItem
+		//		The start point
+		// mandatarySelect: Boolean
+		//		If true, toSelect will be same as the original selection status.
+		if(!this._isValid(type, start)){
+			return;
+		}
+		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 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._toSelect = toSelect === undefined ? true : toSelect;
+		}
+		
+		this._selecting[type] = true;
+		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(type === "row"){
+				this._isUsingRowSelector = true;
+			}
+			this._startPoint[type] = this._lastEndPoint[type];
+			this._highlight(type, this._startPoint[type]);
+			this._isUsingRowSelector = false;
+		}else{
+			this._startPoint[type] = start;
+		}
+		//Now start selection
+		this._curType = type;
+		this._fireEvent("start", type);
+		this._isStartFocus = true;
+		this._isUsingRowSelector = true;
+		this._highlight(type, start, this._toSelect);
+		this._isStartFocus = false;
+	},
+	_endSelect: function(type){
+		// summary:
+		//		End selection. Keep records, fire events and cleanup status.
+		// tag:
+		//		private
+		// type: String
+		//		"row", "col", or "cell"
+		if(type === "row"){
+			delete this._isUsingRowSelector;
+		}
+		if(type == "all"){
+			this._endSelect("col");
+			this._endSelect("row");
+			this._endSelect("cell");
+		}else if(this._selecting[type]){
+			this._addToSelected(type);
+			this._lastAnchorPoint[type] = this._startPoint[type];
+			this._lastEndPoint[type] = this._currentPoint[type];
+			if(this._toSelect){
+				this._lastSelectedAnchorPoint[type] = this._lastAnchorPoint[type];
+				this._lastSelectedEndPoint[type] = this._lastEndPoint[type];
+			}
+			this._startPoint[type] = this._currentPoint[type] = null;
+			this._selecting[type] = false;
+			this._lastType = type;
+			this._fireEvent("end", type);
+		}
+	},
+	_fireEvent: function(evtName, type){
+		switch(evtName){
+			case "start":
+				this.grid[this._toSelect ? "onStartSelect" : "onStartDeselect"](type, this._startPoint[type], this._selected);
+				break;
+			case "end":
+				this.grid[this._toSelect ? "onEndSelect" : "onEndDeselect"](type, this._lastAnchorPoint[type], this._lastEndPoint[type], this._selected);
+				break;
+		}
+	},
+	_calcToHighlight: function(type, target, toHighlight, toSelect){
+		// summary:
+		//		Calculate what status should *target* have.
+		//		If *toSelect* is not provided, this is a no op.
+		// This function is time-critical!!
+		if(toSelect !== undefined){
+			var sltd;
+			if(this._usingKeyboard && !toHighlight){
+				var last = this._isInLastRange(this._lastType, target);
+				if(last){
+					sltd = this._isSelected(type, target);
+					//This 2 cases makes the keyboard swipe selection valid!
+					if(toSelect && sltd){
+						return false;
+					}
+					if(!toSelect && !sltd && this._isInLastRange(this._lastType, target, true)){
+						return true;
+					}
+				}
+			}
+			return toHighlight ? toSelect : (sltd || this._isSelected(type, target));
+		}
+		return toHighlight;
+	},
+	_highlightNode: function(node, toHighlight){
+		// summary:
+		//		Do the actual highlight work.
+		if(node){
+			var selectCSSClass = "dojoxGridRowSelected";
+			var selectCellClass = "dojoxGridCellSelected";
+			dojo.toggleClass(node, selectCSSClass, toHighlight);
+			dojo.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);
+	},
+	_highlightRowSelector: function(rowIdx, toHighlight){
+		//var t1 = (new Date()).getTime();
+		var rowSelector = this.grid.views.views[0];
+		if(rowSelector instanceof dojox.grid._RowSelector){
+			var node = rowSelector.getRowNode(rowIdx);
+			if(node){
+				var selectedClass = "dojoxGridRowSelectorSelected";
+				dojo.toggleClass(node, selectedClass, toHighlight);
+			}
+		}
+		//console.log((new Date()).getTime() - t1);
+	},
+	_highlightSingle: function(type, toHighlight, target, toSelect, isRefresh){
+		// summary:
+		//		Highlight a single item.
+		// This function is time critical!!
+		var _this = this, toHL, g = _this.grid, cells = g.layout.cells;
+		switch(type){
+			case "cell":
+				toHL = this._calcToHighlight(type, target, toHighlight, toSelect);
+				var c = cells[target.col];
+				if(!c.hidden && !c.notselectable){
+					this._highlightNode(target.node || c.getNode(target.row), toHL);
+				}
+				break;
+			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){
+					var rowNode = cells[target.col].view.content.findRowTarget(cellNode);
+					if(rowNode){
+						var rowIndex = rowNode[dojox.grid.util.rowIndexTag];
+						_this._highlightSingle("cell", toHL, {
+							"row": rowIndex,
+							"col": target.col,
+							"node": cellNode
+						});
+					}
+				});
+				break;
+			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)
+					});
+				});
+				//To avoid dead lock
+				this._selectedRowModified = true;
+				if(!isRefresh){
+					g.selection.setSelected(target.row, toHL);
+				}
+		}
+	},
+	_highlight: function(type, target, toSelect){
+		// summary:
+		//		Highlight from start point to target.
+		// toSelect: Boolean
+		//		Whether we are selecting or deselecting.
+		// This function is time critical!!
+		if(this._selecting[type] && target !== null){
+			var start = this._startPoint[type],
+				current = this._currentPoint[type],
+				_this = this,
+				highlight = function(from, to, toHL){
+					_this._forEach(type, from, to, function(item){
+						_this._highlightSingle(type, toHL, item, toSelect);
+					}, true);
+				};
+			switch(type){
+				case "col": case "row":
+					if(current !== null){
+						if(_inRange(type, target, start, current, true)){
+							//target is between start and current, some selected should be deselected.
+							highlight(current, target, false);
+						}else{
+							if(_inRange(type, start, target, current, true)){
+								//selection has jumped to different direction, all should be deselected.
+								highlight(current, start, false);
+								current = start;
+							}
+							highlight(target, current, true);
+						}
+					}else{
+						//First time select.
+						this._highlightSingle(type, true, target, toSelect);
+					}
+					break;
+				case "cell":
+					if(current !== null){
+						if(_inRange("row", target, start, current, true) ||
+							_inRange("col", target, start, current, true) ||
+							_inRange("row", start, target, current, true) ||
+							_inRange("col", start, target, current, true)){
+							highlight(start, current, false);
+						}
+					}
+					highlight(start, target, true);
+			}
+			this._currentPoint[type] = target;
+			this._focusPoint(type, this._currentPoint);
+		}
+	},
+	_focusPoint: function(type, point){
+		// summary:
+		//		Focus the current point, so when you move mouse, the focus indicator follows you.
+		if(!this._isStartFocus){
+			var current = point[type],
+				f = this.grid.focus;
+			if(type == "col"){
+				f._colHeadFocusIdx = current.col;
+				f.focusArea("header");
+			}else if(type == "row"){
+				f.focusArea("rowHeader", {
+					"rowIndex": current.row
+				});
+			}else if(type == "cell"){
+				f.setFocusIndex(current.row, current.col);
+			}
+		}
+	},
+	_blurPoint: function(type, point){
+		// summary:
+		//		Blur the current point.
+		var f = this.grid.focus;
+		if(type == "col"){
+			f._blurHeader();
+		}else if(type == "cell"){
+			f._blurContent();
+		}
+	},
+	_addToSelected: function(type){
+		// summary:
+		//		Record the selected items.
+		var toSelect = this._toSelect, _this = this,
+			toAdd = [], toRemove = [],
+			start = this._startPoint[type],
+			end = this._currentPoint[type];
+		if(this._usingKeyboard){
+			//If using keyboard, selection will be ended after every move. But we have to remember the original selection status,
+			//so as to return to correct status when we shrink the selection region.
+			this._forEach(type, this._lastAnchorPoint[type], this._lastEndPoint[type], function(item){
+				//If the original selected item is not in current range, change its status.
+				if(!_inRange(type, item, start, end)){
+					(toSelect ? toRemove : toAdd).push(item);
+				}
+			});
+		}
+		this._forEach(type, start, end, function(item){
+			var isSelected = _this._isSelected(type, item);
+			if(toSelect && !isSelected){
+				//Add new selected items
+				toAdd.push(item);
+			}else if(!toSelect){
+				//Remove deselected items.
+				toRemove.push(item);
+			}
+		});
+		this._add(type, toAdd);
+		this._remove(type, toRemove);
+		
+		// have to keep record in original grid selection
+		dojo.forEach(this._selected.row, function(item){
+			if(item.except.length > 0){
+				//to avoid dead lock
+				this._selectedRowModified = true;
+				this.grid.selection.setSelected(item.row, false);
+			}
+		}, this);
+	},
+	_forEach: function(type, start, end, func, halfClose){
+		// summary:
+		//		Go through items from *start* point to *end* point.
+		// This function is time critical!!
+		if(!this._isValid(type, start, true) || !this._isValid(type, end, true)){
+			return;
+		}
+		switch(type){
+			case "col": case "row":
+				start = start[type];
+				end = end[type];
+				var dir = end > start ? 1 : -1;
+				if(!halfClose){
+					end += dir;
+				}
+				for(; start != end; start += dir){
+					func(_createItem(type, start));
+				}
+				break;
+			case "cell":
+				var colDir = end.col > start.col ? 1 : -1,
+					rowDir = end.row > start.row ? 1 : -1;
+				for(var i = start.row, p = end.row + rowDir; i != p; i += rowDir){
+					for(var j = start.col, q = end.col + colDir; j != q; j += colDir){
+						func(_createItem(type, i, j));
+					}
+				}
+		}
+	},
+	_makeupForExceptions: function(type, newCellItems){
+		// 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){
+				if(v1[type] == v2[type]){
+					var pos = dojo.indexOf(v1.except, v2[_theOther[type]]);
+					if(pos >= 0){
+						v1.except.splice(pos, 1);
+					}
+					makedUps.push(v2);
+				}
+			});
+		});
+		return makedUps;
+	},
+	_makeupForCells: function(type, newItems){
+		// summary:
+		//		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){
+				if(v1[type] == v2[type]){
+					toRemove.push(v1);
+					return true;
+				}
+				return false;
+			});
+		});
+		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]);
+				if(pos >= 0){
+					v1.except.splice(pos, 1);
+				}
+			});
+		});
+	},
+	_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){
+				v1.except.push(v2[_theOther[type]]);
+			});
+		});
+	},
+	_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){
+				if(v1[type] == v2[type]){
+					v1.except.push(v2[_theOther[type]]);
+				}
+			});
+		});
+	},
+	_add: function(type, items){
+		// summary:
+		//		Add to the selection record.
+		var cells = this.grid.layout.cells;
+		if(type == "cell"){
+			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 &&
+					!cells[item.col].hidden && !cells[item.col].notselectable;
+			});
+		}else{
+			if(type == "col"){
+				//Step over hidden columns.
+				items = dojo.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){
+					return v[type] !== item[type];
+				});
+			});
+		}
+		if(type != "col" && this.grid._hasIdentity){
+			dojo.forEach(items, function(item){
+				var record = this.grid._by_idx[item.row];
+				if(record){
+					item.id = record.idty;
+				}
+			}, this);
+		}
+		this._selected[type] = this._selected[type].concat(items);
+	},
+	_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){
+				return comp(v1, v2);
+			});
+		});
+		if(type == "cell"){
+			this._addCellException("col", items);
+			this._addCellException("row", items);
+		}else{
+			this._addException(_theOther[type], items);
+		}
+	},
+	_isCellNotInExcept: function(type, item){
+		// 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;
+		});
+	},
+	_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 ret = _isEqual(type, item, v);
+			if(ret && type !== "cell"){
+				return v.except.length === 0;
+			}
+			return ret;
+		});
+		if(!res && type === "cell"){
+			res = (this._isCellNotInExcept("col", item) || this._isCellNotInExcept("row", item));
+			if(type === "cell"){
+				res = res && !this.grid.layout.cells[item.col].notselectable;
+			}
+		}
+		return res;
+	},
+	_isInLastRange: function(type, item, isSelected){
+		// summary:
+		//		Return true only when the item is in the last seletion/deseletion range.
+		var start = this[isSelected ? "_lastSelectedAnchorPoint" : "_lastAnchorPoint"][type],
+			end = this[isSelected ? "_lastSelectedEndPoint" : "_lastEndPoint"][type];
+		if(!item || !start || !end){ return false; }
+		return _inRange(type, item, start, end);
+	},
+	_isValid: function(type, item, allowNotSelectable){
+		// summary:
+		//		Check whether the item is a valid __SelectItem for the given type.
+		if(!item){ return false; }
+		try{
+			var g = this.grid, index = item[type];
+			switch(type){
+				case "col":
+					return index >= 0 && index < g.layout.cells.length && dojo.isArray(item.except) &&
+							(allowNotSelectable || !g.layout.cells[index].notselectable);
+				case "row":
+					return index >= 0 && index < g.rowCount && dojo.isArray(item.except);
+				case "cell":
+					return item.col >= 0 && item.col < g.layout.cells.length &&
+							item.row >= 0 && item.row < g.rowCount &&
+							(allowNotSelectable || !g.layout.cells[item.col].notselectable);
+			}
+		}catch(e){}
+		return false;
+	}
+});
+dojox.grid.EnhancedGrid.registerPlugin(dojox.grid.enhanced.plugins.Selector/*name:'selector'*/, {
+	"dependency": ["autoScroll"]
+});
+})();
diff --git a/dojox/grid/enhanced/plugins/_RowMapLayer.js b/dojox/grid/enhanced/plugins/_RowMapLayer.js
new file mode 100644
index 0000000..d543fb8
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/_RowMapLayer.js
@@ -0,0 +1,204 @@
+dojo.provide("dojox.grid.enhanced.plugins._RowMapLayer");
+
+dojo.require("dojox.grid.enhanced.plugins._StoreLayer");
+
+(function(){
+var _devideToArrays = function(a){
+	a.sort(function(v1, v2){
+		return v1 - v2;
+	});
+	var arr = [[a[0]]];
+	for(var i = 1, j = 0; i < a.length; ++i){
+		if(a[i] == a[i-1] + 1){
+			arr[j].push(a[i]);
+		}else{
+			arr[++j] = [a[i]];
+		}
+	}
+	return arr;
+},
+hitchIfCan = function(scope, func){
+	return func ? dojo.hitch(scope || dojo.global, func) : function(){};
+};
+
+dojo.declare("dojox.grid.enhanced.plugins._RowMapLayer", dojox.grid.enhanced.plugins._StoreLayer, {
+	tags: ["reorder"],
+	constructor: function(grid){
+		this._map = {};
+		this._revMap = {};
+		this.grid = grid;
+		this._oldOnDelete = grid._onDelete;
+		var _this = this;
+		grid._onDelete = function(item){
+			_this._onDelete(item);
+			_this._oldOnDelete.call(grid, item);
+		};
+		this._oldSort = grid.sort;
+		grid.sort = function(){
+			_this.clearMapping();
+			_this._oldSort.apply(grid, arguments);
+		};
+	},
+	uninitialize: function(){
+		this.grid._onDelete = this._oldOnDelete;
+		this.grid.sort = this._oldSort;
+	},
+	setMapping: function(mapping){
+		// summary:
+		//		Remember the row mapping.
+		// mapping: Object
+		//		keys are original rowIndexes, values are new rowIndexes.
+		this._store.forEachLayer(function(layer){
+			if(layer.name() === "rowmap"){
+				return false;
+			}else if(layer.onRowMappingChange){
+				layer.onRowMappingChange(mapping);
+			}
+			return true;
+		}, false);
+		var from, to, origin, revmap = {};
+		for(from in mapping){
+			from = parseInt(from, 10);
+			to = mapping[from];
+			if(typeof to == "number"){
+				if(from in this._revMap){
+					origin = this._revMap[from];
+					delete this._revMap[from];
+				}else{
+					origin = from;
+				}
+				if(origin == to){
+					delete this._map[origin];
+					revmap[to] = "eq";
+				}else{
+					this._map[origin] = to;
+					revmap[to] = origin;
+				}
+			}
+		}
+		for(to in revmap){
+			if(revmap[to] === "eq"){
+				delete this._revMap[parseInt(to, 10)];
+			}else{
+				this._revMap[parseInt(to, 10)] = revmap[to];
+			}
+		}
+	},
+	clearMapping: function(){
+		this._map = {};
+		this._revMap = {};
+	},
+	_onDelete: function(item){
+		var idx = this.grid._getItemIndex(item, true);
+		if(idx in this._revMap){
+			var rowIdxArr = [], r, i, origin = this._revMap[idx];
+			delete this._map[origin];
+			delete this._revMap[idx];
+			for(r in this._revMap){
+				r = parseInt(r, 10);
+				if(this._revMap[r] > origin){
+					--this._revMap[r];
+				}
+			}
+			for(r in this._revMap){
+				r = parseInt(r, 10);
+				if(r > idx){
+					rowIdxArr.push(r);
+				}
+			}
+			rowIdxArr.sort(function(a, b){
+				return b - a;
+			});
+			for(i = rowIdxArr.length - 1; i >= 0; --i){
+				r = rowIdxArr[i];
+				this._revMap[r - 1] = this._revMap[r];
+				delete this._revMap[r];
+			}
+			this._map = {};
+			for(r in this._revMap){
+				this._map[this._revMap[r]] = r;
+			}
+		}
+	},
+	_fetch: function(userRequest){
+		var mapCount = 0, r;
+		var start = userRequest.start || 0;
+		for(r in this._revMap){
+			r = parseInt(r, 10);
+			if(r >= start){
+				++mapCount;
+			}
+		}
+		if(mapCount > 0){
+			//Row mapping is in use.
+			var rows = [], i, map = {},
+				count = userRequest.count > 0 ? userRequest.count : -1;
+			if(count > 0){
+				for(i = 0; i < count; ++i){
+					r = start + i;
+					r = r in this._revMap ? this._revMap[r] : r;
+					map[r] = i;
+					rows.push(r);
+				}
+			}else{
+				//We don't have a count, must create our own.
+				for(i = 0;; ++i){
+					r = start + i;
+					if(r in this._revMap){
+						--mapCount;
+						r = this._revMap[r];
+					}
+					map[r] = i;
+					rows.push(r);
+					if(mapCount <= 0){
+						break;
+					}
+				}
+			}
+			this._subFetch(userRequest, this._getRowArrays(rows), 0, [], map, userRequest.onComplete, start, count);
+			return userRequest;
+		}else{
+			//No row mapping at all.
+			return dojo.hitch(this._store, this._originFetch)(userRequest);
+		}
+	},
+	_getRowArrays: function(rows){
+		return _devideToArrays(rows);
+	},
+	_subFetch: function(userRequest, rowArrays, index, result, map, oldOnComplete, start, count){
+		var arr = rowArrays[index], _this = this;
+		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){
+				var r = urstart + i;
+				if(r in map){
+					result[map[r]] = item;
+				}
+			});
+			if(++index == rowArrays.length){
+				//mapped rows are all fetched.
+				if(count > 0){
+					userRequest.start = start;
+					userRequest.count = count;
+					userRequest.onComplete = oldOnComplete;
+					hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+				}else{
+					userRequest.start = userRequest.start + items.length;
+					delete userRequest.count;
+					userRequest.onComplete = function(items){
+						result = result.concat(items);
+						userRequest.start = start;
+						userRequest.onComplete = oldOnComplete;
+						hitchIfCan(userRequest.scope, oldOnComplete)(result, userRequest);
+					};
+					_this.originFetch(userRequest);
+				}
+			}else{
+				_this._subFetch(userRequest, rowArrays, index, result, map, oldOnComplete, start, count);
+			}
+		};
+		_this.originFetch(userRequest);
+	}
+});
+})();
diff --git a/dojox/grid/enhanced/plugins/_SelectionPreserver.js b/dojox/grid/enhanced/plugins/_SelectionPreserver.js
new file mode 100644
index 0000000..732f85b
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/_SelectionPreserver.js
@@ -0,0 +1,127 @@
+dojo.provide("dojox.grid.enhanced.plugins._SelectionPreserver");
+
+dojo.declare("dojox.grid.enhanced.plugins._SelectionPreserver", null, {
+	// 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.
+	//		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)
+	//
+	// 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;
+		grid.onSelectedById = this.onSelectedById;
+		this.reset();
+
+		var oldClearData = grid._clearData;
+		var _this = this;
+		grid._clearData = function(){
+			_this._updateMapping(!grid._noInternalMapping);
+			_this._trustSelection = [];
+			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));
+	},
+	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;
+	},
+	reset: function(){
+		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.
+		var s = this.selection, g = this.grid;
+		if(item && g._hasIdentity){
+			var id = g.store.getIdentity(item);
+			if(this._selectedById[id] === undefined){
+				if(!this._trustSelection[index]){
+					s.selected[index] = this._defaultSelected;
+				}
+			}else{
+				s.selected[index] = this._selectedById[id];
+			}
+			this._idMap.push(id);
+			g.onSelectedById(id, index, s.selected[index]);
+		}
+	},
+	_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{
+			this._trustSelection[inItemOrIndex] = true;
+		}
+	},
+	onSelectedById: function(id, rowIndex, value){},
+	
+	_updateMapping: function(trustSelection, isSelect, isForAll, from, to){
+		// summary:
+		//		This function trys 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.
+		var s = this.selection, g = this.grid, flag = 0, unloaded = 0, i, id;
+		for(i = g.rowCount - 1; i >= 0; --i){
+			if(!g._by_idx[i]){
+				++unloaded;
+				flag += s.selected[i] ? 1 : -1;
+			}else{
+				id = g._by_idx[i].idty;
+				if(id && (trustSelection || this._selectedById[id] === undefined)){
+					this._selectedById[id] = !!s.selected[i];
+				}
+			}
+		}
+		if(unloaded){
+			this._defaultSelected = flag > 0;
+		}
+		if(!isForAll && from !== undefined && to !== undefined){
+			isForAll = !g.usingPagination && Math.abs(to - from + 1) === g.rowCount;
+		}
+		// 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){
+				this._selectedById[this._idMap[i]] = isSelect;
+			}
+		}
+	}
+});
diff --git a/dojox/grid/enhanced/plugins/_StoreLayer.js b/dojox/grid/enhanced/plugins/_StoreLayer.js
new file mode 100644
index 0000000..9d94b07
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/_StoreLayer.js
@@ -0,0 +1,383 @@
+dojo.provide("dojox.grid.enhanced.plugins._StoreLayer");
+// summary:
+//		The dojo.data.api.Read API is powerful, but it's difficult to give the store some special commands before
+//		fetch, so that the store content can be temporarily modified or transformed, and acts as another store. The
+//		parameter *query* or *queryOptions* in keywordArgs for *fetch* is not enough because:
+//		1.	users do not have the opportunity to response to the store actions when these options or queries are applied,
+//			especially when the real store is at server side.
+//		2.	the store implementation must be changed to support any new options in 'query' or 'queryOptions', so it'll be
+//			difficult if this implementation is not able to or very hard to be changed, or some new options are required to
+//			be valid for all stores.
+//		This *StoreLayer* framework is dedicated to provide a uniform way for configuring an existing store, so that
+//		it can be easily extended to have special behaviors or act like a totally different store.
+//		The major approach is to wrap the *fetch* function of store, layer by layer. Every layer treats the incoming
+//		store.fetch as a 'black box', thus maintaining the independence between layers.
+//		*fetch* is the most important data retriever in the Read API, almost all other functions are used for a single
+//		item, and require that this item is already retrieved (by and only by *fetch*). So once we've controlled this
+//		*fetch* function, we've controlled almost the whole store. This fact simplifies our implementation of StoreLayer.
+// example:
+//		//ns is for namespace, i.e.:dojox.grid.enhanced.plugins
+//		ns.wrap(ns.wrap(ns.wrap(store, new ns.FilterLayer()), new ns.UniqueLayer()), new ns.TransformLayer());
+//
+//		//every layer has a name, it should be given in the document of this layer.
+//		//if you don't know it's name, you can get it by: ns.SomeLayer.prototype.name();
+//		store.layer("filter").filterDef(...);
+//		store.layer("unique").setUniqueColumns(...);
+//		store.layer("transform").setScheme(...);
+//
+//		//now use the store as usual...
+//
+//		store.unwrap("transform"); //remove the transform layer but retain the other two.
+//
+//		//now use the store as usual...
+//
+//		store.unwrap(); //remove all the layers, get the original store back.
+(function(){
+	var ns = dojox.grid.enhanced.plugins,
+	
+	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]);
+			if(p >= 0 && p <= idx){
+				idx = p;
+			}
+		}
+		if(idx < tagList.length - 1){
+			return tagList.slice(0, idx + 1);
+		}else{
+			return tagList;
+		}
+	},
+	
+	unwrap = function(/* string? */layerName){
+		// summary:
+		//		Unwrap the layers of the store
+		// tags:
+		//		public
+		// returns:
+		//		The unwrapped store, for nested use only.
+		var i, layers = this._layers, len = layers.length;
+		if(layerName){
+			for(i = len-1; i >= 0; --i){
+				if(layers[i].name() == layerName){
+					layers[i]._unwrap(layers[i + 1]);
+					break;
+				}
+			}
+			layers.splice(i, 1);
+		}else{
+			for(i = len - 1; i >= 0; --i){
+				layers[i]._unwrap();
+			}
+		}
+		if(!layers.length){
+			delete this._layers;
+			delete this.layer;
+			delete this.unwrap;
+			delete this.forEachLayer;
+		}
+		//console.log("layers:",this._layers);
+		return this;	//Read-store
+	},
+	
+	getLayer = function(layerName){
+		// summary:
+		//		Get a layer of the store, so we can configure that layer.
+		// tags:
+		//		public (scope is store)
+		// layerName: string
+		//		the name of the layer
+		// returns:
+		//		the store layer object
+		var i, layers = this._layers;
+		if(typeof layerName == "undefined"){
+			return layers.length;	//Integer
+		}
+		if(typeof layerName == "number"){
+			return layers[layerName];	//_StoreLayer
+		}
+		for(i = layers.length - 1; i >= 0; --i){
+			if(layers[i].name() == layerName){
+				return layers[i];	//_StoreLayer
+			}
+		}
+		return null;	//_StoreLayer
+	},
+	
+	forEachLayer = function(callback, isInnerToOuter){
+		// summary:
+		//		Visit the layers one by one. From the outer most to inner most by default.
+		// callback: Function
+		//		The function to callback.
+		//		If return false, break the loop.
+		// isInnerToOuter: Boolean
+		//		Whether visit from the inner most layer to the outer most layer.
+		var len = this._layers.length, start, end, dir;
+		if(isInnerToOuter){
+			start = 0;
+			end = len;
+			dir = 1;
+		}else{
+			start = len - 1;
+			end = -1;
+			dir = -1;
+		}
+		for(var i = start; i != end; i += dir){
+			if(callback(this._layers[i], i) === false){
+				return i;
+			}
+		}
+		return end;
+	};
+	ns.wrap = function(store, funcName, layer, layerFuncName){
+		// summary:
+		//		Wrap the store with the given layer.
+		// tags:
+		//		public
+		// store: Read-store
+		//		The store to be wrapped.
+		// layer: _StoreLayer
+		//		The layer to be used
+		// returns
+		//		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);
+		}
+		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;
+			})){
+				return false;
+			}else{
+				store._layers.splice(i, 0, layer);
+				layer._wrap(store, funcName, layerFuncName, lyr);
+				return true;
+			}
+		})){
+			store._layers.push(layer);
+			layer._wrap(store, funcName, layerFuncName);
+		}
+		//console.log("wrapped layers:", dojo.map(store._layers, function(lyr){return lyr.name();}));
+		return store;	//Read-store
+	};
+
+	dojo.declare("dojox.grid.enhanced.plugins._StoreLayer", null, {
+		// summary:
+		//		The most abstract class of store layers, provides basic utilities and some interfaces.
+		// tags:
+		//		abstract
+/*=====
+		// _store: [protected] Read-store
+		//		The wrapped store.
+		_store: null,
+		
+		// _originFetch: [protected] function
+		//		The original fetch function of the store.
+		_originFetch: null,
+		
+		// __enabled: [private] Boolean
+		//		To control whether this layer is valid.
+		__enabled: true,
+=====*/
+		tags: ["normal"],
+		
+		layerFuncName: "_fetch",
+		
+		constructor: function(){
+			this._store = null;
+			this._originFetch = null;
+			this.__enabled = true;
+		},
+		initialize: function(store){
+			// summary:
+			//
+		},
+		uninitialize: function(store){
+			// summary:
+			//
+		},
+		invalidate: function(){
+			
+		},
+		_wrap: function(store, funcName, layerFuncName, nextLayer){
+			// summary:
+			//		Do the actual wrapping (or 'hacking' if you like) to the store.
+			// tags:
+			//		internal
+			// store: Read-store
+			//		The store to be wrapped.
+			this._store = store;
+			this._funcName = funcName;
+			var fetchFunc = dojo.hitch(this, function(){
+				return (this.enabled() ? this[layerFuncName || this.layerFuncName] : this.originFetch).apply(this, arguments);
+			});
+			if(nextLayer){
+				this._originFetch = nextLayer._originFetch;
+				nextLayer._originFetch = fetchFunc;
+			}else{
+				this._originFetch = store[funcName] || function(){};
+				store[funcName] = fetchFunc;
+			}
+			this.initialize(store);
+		},
+		_unwrap: function(nextLayer){
+			// summary:
+			//		Do the actual unwrapping to the store.
+			// tags:
+			//		internal
+			// store: Read-store
+			//		The store to be unwrapped.
+			this.uninitialize(this._store);
+			if(nextLayer){
+				nextLayer._originFetch = this._originFetch;
+			}else{
+				this._store[this._funcName] = this._originFetch;
+			}
+			this._originFetch = null;
+			this._store = null;
+		},
+		enabled: function(/* bool? */toEnable){
+			// summary:
+			//		The get/set function of the enabled status of this layer
+			// tags:
+			//		public
+			// toEnable: Boolean?
+			//		If given, is a setter, otherwise, it's getter.
+			if(typeof toEnable != "undefined"){
+				this.__enabled = !!toEnable;
+			}
+			return this.__enabled;	//Boolean
+		},
+		name: function(){
+			// summary:
+			//		Get the name of this store layer.
+			//		The default name retrieved from class name, which should have a pattern of "{name}Layer".
+			//		If this pattern does not exist, the whole class name will be this layer's name.
+			//		It's better to override this method if your class name is too complicated.
+			// tags:
+			//		public extension
+			// returns:
+			//		The name of this layer.
+			if(!this.__name){
+				var m = this.declaredClass.match(/(?:\.(?:_*)([^\.]+)Layer$)|(?:\.([^\.]+)$)/i);
+				this.__name = m ? (m[1] || m[2]).toLowerCase() : this.declaredClass;
+			}
+			return this.__name;
+		},
+		originFetch: function(){
+			return (dojo.hitch(this._store, this._originFetch)).apply(this, arguments);
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins._ServerSideLayer", ns._StoreLayer, {
+		// summary:
+		//		The most abstract class for all server side store layers.
+		// tags:
+		//		abstract
+/*=====
+		// _url: [protected] string
+		//		The url of the server
+		_url: "",
+		// __cmds [private] object
+		//		The command object to be sent to server.
+		__cmds: {},
+=====*/
+		constructor: function(args){
+			args = args || {};
+			this._url = args.url || "";
+			this._isStateful = !!args.isStateful;
+			this._onUserCommandLoad = args.onCommandLoad || function(){};
+			this.__cmds = {cmdlayer:this.name(), enable:true};
+			
+			//Only for stateful server, sending commands before fetch makes sense.
+			this.useCommands(this._isStateful);
+		},
+		enabled: function(/* bool? */toEnable){
+			// summary:
+			//		Overrided from _StoreLayer.enabled
+			var res = this.inherited(arguments);
+			this.__cmds.enable = this.__enabled;
+			return res;
+		},
+		useCommands: function(/* bool? */toUse){
+			// summary:
+			//		If you only want to modify the user request, instead of sending a separate command
+			//		to server before fetch, just call:
+			//			this.useCommand(false);
+			// tags:
+			//		public
+			// toUse: Boolean?
+			//		If provided, it's a setter, otherwise, it's a getter
+			if(typeof toUse != "undefined"){
+				this.__cmds.cmdlayer = (toUse && this._isStateful) ? this.name() : null;
+			}
+			return !!(this.__cmds.cmdlayer);	//Boolean
+		},
+		_fetch: function(/* keywordArgs */userRequest){
+			// summary:
+			//		Implementation of _StoreLayer._fetch
+			if(this.__cmds.cmdlayer){
+				//We're gonna send command to server before fetch.
+				dojo.xhrPost({
+					url: this._url || this._store.url,
+					content: this.__cmds,
+					load: dojo.hitch(this, function(responce){
+						this.onCommandLoad(responce, userRequest);
+						this.originFetch(userRequest);
+					}),
+					error: dojo.hitch(this, this.onCommandError)
+				});
+			}else{
+				//The user only wants to modify the request object.
+				this.onCommandLoad("", userRequest);
+				this.originFetch(userRequest);
+			}
+			return userRequest;	//dojo.data.api.Request
+		},
+		command: function(/* string */cmdName,/* (string|number|bool|...)? */cmdContent){
+			// summary:
+			//		get/set a command (a name-value pair)
+			// tags:
+			//		public
+			// cmdName: string
+			//		The name of the command
+			// cmdContent: anything
+			//		The content of the command
+			// returns:
+			//		The content of the command if cmdContent is undefined
+			var cmds = this.__cmds;
+			if(cmdContent === null){
+				delete cmds[cmdName];
+			}else if(typeof cmdContent !== "undefined"){
+				cmds[cmdName] = cmdContent;
+			}
+			return cmds[cmdName];	//anything
+		},
+		onCommandLoad: function(/* string */response, /* keywordArgs */userRequest){
+			// summary:
+			//		When the server gives back *response* for the commands, you can do something here.
+			// tags:
+			//		callback extension
+			// response: string
+			//		server response
+			// userRequest: [in|out] dojo.data.api.Request
+			//		The request object for *fetch*. You can modify this object according to the *response*
+			//		so as to change the behavior of *fetch*
+			this._onUserCommandLoad(this.__cmds, userRequest, response);
+		},
+		onCommandError: function(error){
+			// summary:
+			//		handle errors when sending commands.
+			// tags:
+			//		callback extension
+			// error: Error
+			console.log(error);
+			throw error;
+		}
+	});
+})();
diff --git a/dojox/grid/enhanced/plugins/exporter/CSVWriter.js b/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
new file mode 100644
index 0000000..b26b48c
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/exporter/CSVWriter.js
@@ -0,0 +1,79 @@
+dojo.provide("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+
+dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+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, {
+	// summary:
+	//		Export grid to CSV format.
+	_separator: ',',
+	_newline: "\r\n",
+	constructor: function(/* object? */writerArgs){
+		// summary:
+		//		CSV default separator is ','.
+		//		But we can also use our own.
+		// writerArgs: object?
+		//		{separator:'...'}
+		if(writerArgs){
+			this._separator = writerArgs.separator ? writerArgs.separator : this._separator;
+			this._newline = writerArgs.newline ? writerArgs.newline : this._newline;
+		}
+		this._headers = [];
+		this._dataRows = [];
+	},
+	_formatCSVCell: function(/* string */cellValue){
+		// summary:
+		//		Format cell value to follow CSV standard.
+		//		See: http://en.wikipedia.org/wiki/Comma-separated_values
+		// tags:
+		//		private
+		// cellValue: string
+		//		The value in a cell.
+		// returns:
+		//		The formatted content of a cell
+		if(cellValue === null || cellValue === undefined){
+			return '';
+		}
+		var result = String(cellValue).replace(/"/g, '""');
+		if(result.indexOf(this._separator) >= 0 || result.search(/[" \t\r\n]/) >= 0){
+			result = '"' + result + '"';
+		}
+		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){
+			//We are not interested in indirect selectors and row indexes.
+			if(!cell.hidden && dojo.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)));
+			}
+		}, this);
+		this._dataRows.push(row);
+		//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){
+			this._headers.push(cell.name || cell.field);
+		}
+	},
+	toString: function(){
+		// summary:
+		//		Overrided from _ExportWriter
+		var result = this._headers.join(this._separator);
+		for(var i = this._dataRows.length - 1; i >= 0; --i){
+			this._dataRows[i] = this._dataRows[i].join(this._separator);
+		}
+		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
new file mode 100644
index 0000000..7fc10d0
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/exporter/TableWriter.js
@@ -0,0 +1,145 @@
+dojo.provide("dojox.grid.enhanced.plugins.exporter.TableWriter");
+
+dojo.require("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+dojox.grid.enhanced.plugins.Exporter.registerWriter("table",
+	"dojox.grid.enhanced.plugins.exporter.TableWriter");
+	
+dojo.declare("dojox.grid.enhanced.plugins.exporter.TableWriter",
+	dojox.grid.enhanced.plugins.exporter._ExportWriter, {
+	// summary:
+	//		Export grid to HTML table format. Primarily used by Printer plugin.
+	constructor: function(/* object? */writerArgs){
+		// summary:
+		//		The generated table only defines the col/rowspan, height and width of
+		//		all the cells in the style attribute, no other attributes
+		//		(like border, cellspacing, etc.) are used.
+		//		Users can define these attributes in the writerArgs object, like:
+		//		{table:"border='border'",thead:"cellspacing='3'"}
+		this._viewTables = [];
+		this._tableAttrs = writerArgs || {};
+	},
+	_getTableAttrs: function(/* string */tagName){
+		// summary:
+		//		Get html attribute string for the given kind of tag.
+		// tags:
+		//		private
+		// tagName: string
+		//		An html tag name
+		// returns:
+		//		The well formatted attributes for the given html table.tag
+		var attrs = this._tableAttrs[tagName] || '';
+		//To ensure the attribute list starts with a space
+		if(attrs && attrs[0] != ' '){
+			attrs = ' ' + attrs;
+		}
+		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('');
+	},
+	_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
+				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;
+		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._width = width;
+		if(arg_obj.isHeader){
+			tagName = 'thead';
+			height = dojo.contentBox(arg_obj.view.headerContentNode).h;
+		}else{
+			tagName = 'tbody';
+			var rowNode = arg_obj.grid.getRowNode(arg_obj.rowIdx);
+			if(rowNode){
+				height = dojo.contentBox(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), '>');
+		return true;	//Boolean
+	},
+	afterView: function(/* object */arg_obj){
+		// summary:
+		//		Overrided from _ExportWriter
+		this._viewTables[arg_obj.viewIdx].push(arg_obj.isHeader ? '</thead>' : '</tbody>');
+	},
+	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){
+			//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;"',
+					this._getTableAttrs(cellTagName),
+					' class="', this._getColumnClass(arg_obj), '"'].join(''),
+			table = this._viewTables[arg_obj.viewIdx];
+		table.push('<', cellTagName, attrs, '>');
+		if(arg_obj.isHeader){
+			table.push(cell.name || cell.field);
+		} else{
+			table.push(this._getExportDataForCell(arg_obj.rowIdx, arg_obj.row, cell, arg_obj.grid));
+		}
+		table.push('</', cellTagName, '>');
+	},
+	afterContent: function(){
+		// summary:
+		//		Overrided from _ExportWriter
+		dojo.forEach(this._viewTables, function(table){
+			table.push('</table>');
+		});
+	},
+	toString: function(){
+		// summary:
+		//		Overrided from _ExportWriter
+		var viewsHTML = dojo.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
new file mode 100644
index 0000000..1c0feee
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/exporter/_ExportWriter.js
@@ -0,0 +1,267 @@
+dojo.provide("dojox.grid.enhanced.plugins.exporter._ExportWriter");
+
+//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, {
+	// 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,
+	//		and provide interfaces for all of them.
+	//			Implementations might choose some of the functions in this class to override,
+	//		thus providing their own functionalities.
+	//			The Exporter will go through the grid line by line. So in every line, all the Views
+	//		will be reached, and the header line is only handled once.
+	//			An *argObj* object is passed to most functions of this class.
+	//		It carries context arguments that make sense when they are called.
+
+/*=====
+	argObj: {
+		// grid: EnhancedGrid
+		//		The grid object we are now handling.
+		grid: null,
+		
+		// isHeader: bool
+		//		Indicating which context we're handling, header or content.
+		isHeader: true,
+		
+		// view: _View
+		//		Reference to the current _View object.
+		view: null,
+		
+		// viewIdx: int
+		//		The index of the current _View object in the views array.
+		//		If the grid does not have any rowselector view, it conforms to the index
+		//		in the _ViewManager.views.
+		viewIdx: -1,
+		
+		// subrow: _View.structure.cells[i]
+		//		Reference to the current subrow.
+		//		A subrow describe the innter structure of a row in a view, it's an array of cells
+		subrow: null,
+		
+		// subrowIdx: int
+		//		The index of the current subrow in the subrow array: _View.structure.cells.
+		subrowIdx: -1,
+		
+		// cell: dojox.grid.__CellDef
+		//		Reference to the current cell.
+		cell: null,
+		
+		//cellIdx: int
+		//		The index of the current cell in the current subrow.
+		//		It's different from cell.index, which is the index in the whole line.
+		cellIdx: -1,
+		
+		//row: item
+		//		The current row of data (logically), a.k.a.: current item.
+		row: null,
+		
+		//rowIdx: int
+		//		The index of the current row (item).
+		rowIdx: -1,
+		
+		// spCols: Array<int>
+		//		An array of special column indexes(flat,not regarding structure).
+		//		Special columns are typically attached to grid as a kind of UI facility
+		//		by the grid widget, instead of some real data.
+		//		For example, indirect selectors and row indexers.
+		//		Users can choose to export it or not.
+		spCols: [],
+		
+		// colOffset: int
+		//		If the grid has a _RowSelector view or something else, this view will NOT be
+		//		passed to the user in argObj. So the column index (cell.index) will appear shifted
+		//		(start from 1 instead of 0). This colOffset is provided to remove this shift.
+		// usage:
+		//		var correctColIndex = argObj.cell.index + argObj.colOffset;
+		colOffset: 0
+	},
+=====*/
+
+	constructor: function(/* object? */writerArgs){
+		// summary:
+		//		Writer initializations goes here.
+		// writerArgs: object?
+		//		Any implementation of this class might accept a writerArgs object (optional),
+		//		which contains some writer-specific arguments given by the user.
+	},
+	_getExportDataForCell: function(rowIndex, rowItem, cell, grid){
+		var data = (cell.get || grid.get).call(cell, rowIndex, rowItem);
+		if(this.formatter){
+			return this.formatter(data, cell, rowIndex, rowItem);
+		}else{
+			return data;
+		}
+	},
+	beforeHeader: function(/* EnhancedGrid */grid){
+		// summary:
+		//		We are going to start the travel in the grid.
+		//		Is there anything we should do now?
+		// tags:
+		//		protected extension
+		// return:
+		//		true: go on hanling the header row and then call afterHeader.
+		//		false: skip the header row, won't call afterHeader.
+		return true;	//Boolean
+	},
+	afterHeader: function(){
+		// summary:
+		//		The header line has been handled.
+		// tags:
+		//		protected extension
+		// returns:
+		//		undefined
+	},
+	beforeContent: function(/* Array */items){
+		// summary:
+		//		We are ready to go through all the contents(items).
+		// tags:
+		//		protected extension
+		// items:
+		//		All the items fetched from the store
+		// return:
+		//		true: go on handling the contents and then call afterContent.
+		//		false: skip all the contents, won't call afterContent.
+		return true;	//Boolean
+	},
+	afterContent: function(){
+		// summary:
+		//		We have finished the entire grid travel.
+		//		Do some clean up work if you need to.
+		// tags:
+		//		protected extension
+		// returns:
+		//		undefined
+	},
+	beforeContentRow: function(/* object */argObj){
+		// summary:
+		//		Before handling a line of data (not header).
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			row,rowIdx,
+		//			spCols
+		//		}
+		// return:
+		//		true: go on handling the current data row and then call afterContentRow.
+		//		false: skip the current data row, won't call afterContentRow.
+		return true;	//Boolean
+	},
+	afterContentRow: function(/* object */argObj){
+		// summary:
+		//		After handling a line of data (not header).
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			row,rowIdx,
+		//			spCols
+		//		}
+		// returns:
+		//		undefined
+	},
+	beforeView: function(/* object */argObj){
+		// summary:
+		//		Before handling a view.
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			view,viewIdx,
+		//			spCols(if isHeader==false)
+		//		}
+		// return:
+		//		true: go on handling the current view and then call afterView.
+		//		false: skip the current view, won't call afterView.
+		return true;	//Boolean
+	},
+	afterView: function(/* object */argObj){
+		// summary:
+		//		After handling a view.
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			view,viewIdx,
+		//			spCols(if isHeader==false)
+		//		}
+		// tags:
+		//		protected extension
+		// returns:
+		//		undefined
+	},
+	beforeSubrow: function(/* object */argObj){
+		// summary:
+		//		Before handling a subrow in a line (defined in the grid structure).
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			row,rowIdx,
+		//			view,viewIdx,
+		//			subrow,subrowIdx,
+		//			spCols(if isHeader==false)
+		//		}
+		// return:
+		//		true: go on handling the current subrow and then call afterSubrow.
+		//		false: skip the current subrow, won't call afterSubrow.
+		return true;	//Boolean
+	},
+	afterSubrow: function(/* object */argObj){
+		// summary:
+		//		Before handling a subrow in a line (defined in the grid structure).
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			row,rowIdx,
+		//			view,viewIdx,
+		//			subrow,subrowIdx,
+		//			spCols(if isHeader==false)
+		//		}
+		// returns:
+		//		undefined
+	},
+	handleCell: function(/* object */argObj){
+		// summary:
+		//		Handle a header cell or data cell.
+		// tags:
+		//		protected extension
+		// argObj:
+		//		An object with at least the following context properties available:
+		//		{
+		//			grid,isHeader,
+		//			row,rowIdx,
+		//			view,viewIdx,
+		//			subrow,subrowIdx,
+		//			cell,cellIdx,
+		//			spCols(if isHeader==false)
+		//		}
+		// returns:
+		//		undefined
+	},
+	toString: function(){
+		// summary:
+		//		Export to a string.
+		// tags:
+		//		protected extension
+		// returns:
+		//		The exported result string.
+		return '';	//String
+	}
+});
diff --git a/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js b/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
new file mode 100644
index 0000000..10cad70
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/ClearFilterConfirm.js
@@ -0,0 +1,33 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm");
+
+dojo.require("dijit.form.Button");
+
+dojo.declare("dojox.grid.enhanced.plugins.filter.ClearFilterConfirm",[dijit._Widget,dijit._Templated],{
+	// summary:
+	//		The UI for user to confirm the operation of clearing filter.
+	templateString: dojo.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"]);
+	},
+	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
new file mode 100644
index 0000000..44a7c42
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/FilterBar.js
@@ -0,0 +1,369 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBar");
+
+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);
+			}
+		}catch(e){}
+	};
+	
+dojo.declare("dojox.grid.enhanced.plugins.filter.FilterBar",[dijit._Widget, dijit._Templated],{
+	// summary:
+	//		The filter bar UI.
+	templateString: dojo.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;
+		this._filterBarDefBtnLabel = nls["filterBarDefButton"];
+		this._filterBarClearBtnLabel = nls["filterBarClearButton"];
+		this._closeFilterBarBtnLabel = nls["closeFilterBarBtn"];
+		var itemsName = plugin.args.itemsName || nls["defaultItemsName"];
+		this._noFilterMsg = dojo.string.substitute(nls["filterBarMsgNoFilterTemplate"], ["", itemsName]);
+		
+		var t = this.plugin.args.statusTipTimeout;
+		if(typeof t == 'number'){
+			this._timeout_statusTooltip = t;
+		}
+		
+		var g = plugin.grid;
+		g.showFilterBar = dojo.hitch(this, "showFilterBar");
+		g.toggleFilterBar = dojo.hitch(this, "toggleFilterBar");
+		g.isFilterBarShown = dojo.hitch(this, "isFilterBarShown");
+	},
+	postCreate: function(){
+		this.inherited(arguments);
+		if(!this.plugin.args.closeFilterbarButton){
+			dojo.style(this.closeFilterBarButton.domNode, "display", "none");
+		}
+		var _this = this,
+			g = this.plugin.grid,
+			old_func = this.oldGetHeaderHeight = dojo.hitch(g,g._getHeaderHeight);
+		
+		this.placeAt(g.viewsHeaderNode, "after");
+		this.connect(this.plugin.filterDefDialog, "showDialog", "_onShowFilterDefDialog");
+		this.connect(this.plugin.filterDefDialog, "closeDialog", "_onCloseFilterDefDialog");
+		this.connect(g.layer("filter"), "onFiltered", this._onFiltered);
+		
+		this.defineFilterButton.domNode.title = this.plugin.nls["filterBarDefButton"];
+		if(dojo.hasClass(dojo.body(), "dijit_a11y")){
+			this.defineFilterButton.set("label", this.plugin.nls["a11yFilterBarDefButton"]);
+		}
+		this.connect(this.defineFilterButton.domNode, "click", _stopEvent);
+		this.connect(this.clearFilterButton.domNode, "click", _stopEvent);
+		this.connect(this.closeFilterBarButton.domNode, "click", _stopEvent);
+		
+		this.toggleClearFilterBtn(true);
+		this._initAriaInfo();
+		
+		//Hack the header height to include filter bar height;
+		g._getHeaderHeight = function(){
+			return old_func() + dojo.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)
+		});
+		g.focus.placeArea("filterbar","after","header");
+	},
+	uninitialize: function(){
+		var g = this.plugin.grid;
+		g._getHeaderHeight = this.oldGetHeaderHeight;
+		g.focus.removeArea("filterbar");
+		this.plugin = null;
+	},
+	isFilterBarShown: function(){
+		return dojo.style(this.domNode, "display") != "none";
+	},
+	showFilterBar: function(toShow, useAnim, animArgs){
+		var g = this.plugin.grid;
+		if(useAnim){
+			if(Boolean(toShow) == this.isFilterBarShown()){ return; }
+			animArgs = animArgs || {};
+			var anims = [], defaultDuration = 500;
+			anims.push(dojo.fx[toShow ? "wipeIn" : "wipeOut"](dojo.mixin({
+				"node": this.domNode,
+				"duration": defaultDuration
+			}, animArgs)));
+			var curHeight = g.views.views[0].domNode.offsetHeight;
+			var prop = {
+				"duration": defaultDuration,
+				"properties": {
+					"height": {
+						"end": dojo.hitch(this, function(){
+							var barHeight = this.domNode.scrollHeight;
+							if(dojo.isFF){
+								barHeight -= 2;
+							}
+							return toShow ? (curHeight - barHeight) : (curHeight + barHeight);
+						})
+					}
+				}
+			};
+			dojo.forEach(g.views.views, function(view){
+				anims.push(dojo.animateProperty(dojo.mixin({
+					"node": view.domNode
+				}, prop, animArgs)), dojo.animateProperty(dojo.mixin({
+					"node": view.scrollboxNode
+				}, prop, animArgs)));
+			});
+			anims.push(dojo.animateProperty(dojo.mixin({
+				"node": g.viewsNode
+			}, prop, animArgs)));
+			dojo.fx.combine(anims).play();
+		}else{
+			dojo.style(this.domNode, "display", toShow ? "" : "none");
+			g.update();
+		}
+	},
+	toggleFilterBar: function(useAnim, animArgs){
+		this.showFilterBar(!this.isFilterBarShown(), useAnim, animArgs);
+	},
+	getColumnIdx: function(/* int */coordX){
+		var headers = dojo.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]);
+			if(coordX >= coord.x && coordX < coord.x + coord.w){
+				idx = i;
+				break;
+			}
+		}
+		if(idx >= 0 && this.plugin.grid.layout.cells[idx].filterable !== false){
+			return idx; //Integer
+		}else{
+			return -1; //Integer
+		}
+	},
+	toggleClearFilterBtn: function(toHide){
+		dojo.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(){
+				this.showFilterBar(false, true);
+				dojo.disconnect(handle);
+			});
+			this._clearFilterDefDialog(e);
+		}else{
+			this.showFilterBar(false, true);
+		}
+	},
+
+	_showFilterDefDialog: function(e){
+		_stopEvent(e);
+		this.plugin.filterDefDialog.showDialog(this._curColIdx);
+		this.plugin.grid.focus.focusArea("filterbar");
+	},
+	_clearFilterDefDialog: function(e){
+		_stopEvent(e);
+		this.plugin.filterDefDialog.onClearFilter();
+		this.plugin.grid.focus.focusArea("filterbar");
+	},
+	_onEnterButton: function(e){
+		//If mouse is hovering the btn, which means the user is about to click,
+		//we should not show status tip on the btn!
+		this._onBlurFilterBar();
+		_stopEvent(e);
+	},
+	_onMoveButton: function(e){
+		this._onBlurFilterBar();
+	},
+	_onLeaveButton: function(e){
+		this._leavingBtn = true;
+	},
+	_onShowFilterDefDialog: function(/* Integer */colIdx){
+		if(typeof colIdx == "number"){
+			this._curColIdx = colIdx;
+		}
+		this._defPaneIsShown = true;
+	},
+	_onCloseFilterDefDialog: function(){
+		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);
+	},
+	_onClickFilterBar: function(/* event */e){
+		_stopEvent(e);
+		this._clearStatusTipTimeout();
+		this.plugin.grid.focus.focusArea("filterbar");
+		this.plugin.filterDefDialog.showDialog(this.getColumnIdx(e.clientX));
+	},
+	_onMouseEnter: function(/* event */e){
+		this._onFocusFilterBar(true, null);
+		this._updateTipPosition(e);
+		this._setStatusTipTimeout();
+	},
+	_onMouseMove: function(/* event */e){
+		if(this._leavingBtn){
+			this._onFocusFilterBar(true, null);
+			this._leavingBtn = false;
+		}
+		if(this._isFocused){
+			this._setStatusTipTimeout();
+			this._highlightHeader(this.getColumnIdx(e.clientX));
+			if(this._handle_statusTooltip){
+				this._updateTipPosition(e);
+			}
+		}
+	},
+	_onMouseLeave: function(e){
+		this._onBlurFilterBar();
+	},
+	_updateTipPosition: function(evt){
+		this._tippos = {
+			x: evt.pageX,
+			y: evt.pageY
+		};
+	},
+	_onFocusFilterBar: function(highlightOnly, evt, step){
+		if(!this.isFilterBarShown()){
+			return false;
+		}
+		this._isFocused = true;
+		dojo.addClass(this.domNode,_focusClass);
+		if(!highlightOnly){
+			var hasFilter = dojo.style(this.clearFilterButton.domNode, "display") !== "none";
+			var hasCloseButton = dojo.style(this.closeFilterBarButton.domNode, "display") !== "none";
+			if(typeof this._focusPos == "undefined"){
+				if(step > 0){
+					this._focusPos = 0;
+				}else{
+					if(hasCloseButton){
+						this._focusPos = 1;
+					}else{
+						this._focusPos = 0;
+					}
+					if(hasFilter){
+						++this._focusPos;
+					}
+				}
+			}
+			if(this._focusPos === 0){
+				dijit.focus(this.defineFilterButton.focusNode);
+			}else if(this._focusPos === 1 && hasFilter){
+				dijit.focus(this.clearFilterButton.focusNode);
+			}else{
+				dijit.focus(this.closeFilterBarButton.focusNode);
+			}
+		}
+		_stopEvent(evt);
+		return true;
+	},
+	_onBlurFilterBar: function(evt, step){
+		if(this._isFocused){
+			this._isFocused = false;
+			dojo.removeClass(this.domNode,_focusClass);
+			this._clearStatusTipTimeout();
+			this._clearHeaderHighlight();
+		}
+		var toBlur = true;
+		if(step){
+			var buttonCount = 3;
+			if(dojo.style(this.closeFilterBarButton.domNode, "display") === "none"){
+				--buttonCount;
+			}
+			if(dojo.style(this.clearFilterButton.domNode, "display") === "none"){
+				--buttonCount;
+			}
+			if(buttonCount == 1){
+				delete this._focusPos;
+			}else{
+				var current = this._focusPos;
+				for(var next = current + step; next < 0; next += buttonCount){}
+				next %= buttonCount;
+				if((step > 0 && next < current) || (step < 0 && next > current)){
+					delete this._focusPos;
+				}else{
+					this._focusPos = next;
+					toBlur = false;
+				}
+			}
+		}
+		return toBlur;
+	},
+	_onFiltered: function(/* int */filteredSize,/* int */originSize){
+		var p = this.plugin,
+			itemsName = p.args.itemsName || p.nls["defaultItemsName"],
+			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);
+		}else{
+			msg = dojo.string.substitute(p.nls["filterBarMsgNoFilterTemplate"], [originSize, itemsName]);
+			dojo.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"]);
+	},
+	_isInColumn: function(/* int */mousePos_x, /* domNode */headerNode, /* int */colIndex){
+		var coord = dojo.coords(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);
+		}
+	},
+	_clearStatusTipTimeout: function(){
+		clearTimeout(this._handle_statusTooltip);
+		this._handle_statusTooltip = null;
+	},
+	_showStatusTooltip: function(){
+		this._handle_statusTooltip = null;
+		this.plugin.filterStatusTip.showDialog(this._tippos.x, this._tippos.y, this.getColumnIdx(this._tippos.x));
+	},
+	_highlightHeader: function(/* int */colIdx){
+		if(colIdx != this._previousHeaderIdx){
+			var g = this.plugin.grid,
+			cell = g.getCell(this._previousHeaderIdx);
+			if(cell){
+				dojo.removeClass(cell.getHeaderNode(), "dojoxGridCellOver");
+			}
+			cell = g.getCell(colIdx);
+			if(cell){
+				dojo.addClass(cell.getHeaderNode(), "dojoxGridCellOver");
+			}
+			this._previousHeaderIdx = colIdx;
+		}
+	},
+	_clearHeaderHighlight: function(){
+		if(typeof this._previousHeaderIdx != "undefined"){
+			var g = this.plugin.grid,
+			cell = g.getCell(this._previousHeaderIdx);
+			if(cell){
+				g.onHeaderCellMouseOut({
+					cellNode: cell.getHeaderNode()
+				});
+			}
+			delete this._previousHeaderIdx;
+		}
+	}
+});
+})();
+
diff --git a/dojox/grid/enhanced/plugins/filter/FilterBuilder.js b/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
new file mode 100644
index 0000000..f4f166c
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/FilterBuilder.js
@@ -0,0 +1,78 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterBuilder");
+dojo.require("dojox.grid.enhanced.plugins.filter._FilterExpr");
+
+(function(){
+var fns = dojox.grid.enhanced.plugins.filter,
+	bdr = function(opCls){
+		return dojo.partial(function(cls,operands){
+			return new fns[cls](operands);
+		},opCls);
+	},
+	bdr_not = function(opCls){
+		return dojo.partial(function(cls,operands){
+			return new fns.LogicNOT(new fns[cls](operands));
+		},opCls);
+	};
+dojo.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));
+		}else{
+			var args = dojo.mixin(this.defaultArgs[def.datatype], def.args || {});
+			return new this.supportedTypes[def.datatype](def.data, def.isColumn, args);
+		}
+	},
+	supportedOps: {
+	// summary:
+	//		The builders of all supported operations
+		"equalto": bdr("EqualTo"),
+		"lessthan": bdr("LessThan"),
+		"lessthanorequalto": bdr("LessThanOrEqualTo"),
+		"largerthan": bdr("LargerThan"),
+		"largerthanorequalto": bdr("LargerThanOrEqualTo"),
+		"contains": bdr("Contains"),
+		"startswith": bdr("StartsWith"),
+		"endswith": bdr("EndsWith"),
+		"notequalto": bdr_not("EqualTo"),
+		"notcontains": bdr_not("Contains"),
+		"notstartswith": bdr_not("StartsWith"),
+		"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])
+			);
+		},
+		"logicany": bdr("LogicANY"),
+		"logicall": bdr("LogicALL")
+	},
+	supportedTypes: {
+		"number": fns.NumberExpr,
+		"string": fns.StringExpr,
+		"boolean": fns.BooleanExpr,
+		"date": fns.DateExpr,
+		"time": fns.TimeExpr
+	},
+	defaultArgs: {
+		"boolean": {
+			"falseValue": "false",
+			"convert": function(dataValue, args){
+				var falseValue = args.falseValue;
+				var trueValue = args.trueValue;
+				if(dojo.isString(dataValue)){
+					if(trueValue && dataValue.toLowerCase() == trueValue){
+						return true;
+					}
+					if(falseValue && dataValue.toLowerCase() == falseValue){
+						return false;
+					}
+				}
+				return !!dataValue;
+			}
+		}
+	}
+});
+})();
diff --git a/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js b/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
new file mode 100644
index 0000000..e88657f
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/FilterDefDialog.js
@@ -0,0 +1,1229 @@
+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 = {
+		// summary:
+		//		Define tabindexes for elements in the filter definition dialog
+		relSelect: 60,
+		accordionTitle: 70,
+		removeCBoxBtn: -1,
+		colSelect: 90,
+		condSelect: 95,
+		valueBox: 10,
+		addCBoxBtn: 20,
+		filterBtn: 30,
+		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;
+		});
+		
+		plugin.connect(plugin.grid.layout, "moveColumn", dojo.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;
+			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);
+				}
+			});
+		}
+	},
+	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"}
+				]
+			}
+		};
+	},
+	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);
+		}
+	},
+	getFilter: function(){
+		return dojo.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) : "";
+		}
+	},
+	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 "";
+	},
+	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;
+		}
+		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;
+		}
+		for(; cnt > 0; --cnt){
+			cbox = new fns.CriteriaBox({
+				dlg: this
+			});
+			cbs.push(cbox);
+			cc.addChild(cbox);
+		}
+		//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();
+			}
+		}
+	},
+	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);
+					}
+				}
+			}
+			start = cbs.length;
+		}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;
+				}
+			}
+			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;
+		}
+		if(this._savedCriterias && this._savedCriterias[idx]){
+			return dojo.mixin({
+				relation: this._relOpCls == "logicall" ? this.plugin.nls.and : this.plugin.nls.or
+			},this._savedCriterias[idx]);
+		}
+		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)
+			};
+		}else{
+			return this.getExprForColumn(rule.value, rule.column, rule.type, rule.condition);
+		}
+	},
+	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
+		};
+	},
+	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;
+	},
+	//////////////////////////////////////////////////////////////////////////////////////////////////////////
+	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();
+		}
+	},
+	showDialog: function(/* int */colIndex){
+		// summary:
+		//		Show the filter defintion dialog.
+		this._defPane.show();
+		this.plugin.filterStatusTip.closeDialog();
+		this._prepareDialog(colIndex);
+	},
+	closeDialog: function(){
+		// summary:
+		//		Close the filter definition dialog.
+		this._defPane.hide();
+	},
+	onFilter: function(e){
+		// summary:
+		//		Triggered when the "Filter" button is clicked.
+		if(this.canFilter()){
+			this._defineFilter();
+			this._closeDlgAndUpdateGrid();
+			this.plugin.filterBar.toggleClearFilterBtn(false);
+		}
+	},
+	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);
+			}
+		}
+	},
+	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();
+	},
+	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);
+		}
+	},
+	_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"),
+	widgetsInTemplate: true,
+	dlg: null,
+	postMixInProperties: function(){
+		this.plugin = this.dlg.plugin;
+		this._curValueBox = null;
+		
+		var nls = this.plugin.nls;
+		this._colSelectLabel = nls.columnSelectLabel;
+		this._condSelectLabel = nls.conditionSelectLabel;
+		this._valueBoxLabel = nls.valueBoxLabel;
+		this._anyColumnOption = nls.anyColumnOption;
+	},
+	postCreate: function(){
+		var dlg = this.dlg, g = this.plugin.grid;
+		//Select Column
+		this._colSelect.set("tabIndex", _tabIdxes.colSelect);
+		this._colOptions = this._getColumnOptions();
+		this._colSelect.addOption([
+			{label: this.plugin.nls.anyColumnOption, value: "anycolumn", selected: dlg.curColIdx < 0},
+			{value: ""}
+		].concat(this._colOptions));
+		//Select Condition
+		this._condSelect.set("tabIndex", _tabIdxes.condSelect);
+		this._condSelect.addOption(this._getUsableConditions(dlg.getColumnType(dlg.curColIdx)));
+		this._showSelectOrLabel(this._condSelect, this._condSelectAlt);
+		
+		this.connect(g.layout, "moveColumn", "onMoveColumn");
+	},
+	_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 !(cell.filterable === false || cell.hidden);
+		}), function(cell){
+			return {
+				label: cell.name || cell.field,
+				value: String(cell.index),
+				selected: colIdx == String(cell.index)
+			};
+		});
+	},
+	onMoveColumn: function(){
+		var tmp = this._onChangeColumn;
+		this._onChangeColumn = function(){};
+		var option = this._colSelect.get("selectedOptions");
+		this._colSelect.removeOption(this._colOptions);
+		this._colOptions = this._getColumnOptions();
+		this._colSelect.addOption(this._colOptions);
+		var i = 0;
+		for(; i < this._colOptions.length; ++i){
+			if(this._colOptions[i].label == option.label){
+				break;
+			}
+		}
+		if(i < this._colOptions.length){
+			this._colSelect.set("value", this._colOptions[i].value);
+		}
+		var _this = this;
+		setTimeout(function(){
+			_this._onChangeColumn = tmp;
+		}, 0);
+	},
+	onRemove: function(){
+		this.dlg.removeCriteriaBoxes(this);
+	},
+	uninitialize: function(){
+		if(this._curValueBox){
+			this._curValueBox.destroyRecursive();
+			this._curValueBox = null;
+		}
+		this.plugin = null;
+		this.dlg = null;
+	},
+	_showSelectOrLabel: function(sel, alt){
+		var options = sel.getOptions();
+		if(options.length == 1){
+			alt.innerHTML = options[0].label;
+			dojo.style(sel.domNode, "display", "none");
+			dojo.style(alt, "display", "");
+		}else{
+			dojo.style(sel.domNode, "display", "");
+			dojo.style(alt, "display", "none");
+		}
+	},
+	_onChangeColumn: function(val){
+		this._checkValidCriteria();
+		var type = this.dlg.getColumnType(val);
+		this._setConditionsByType(type);
+		this._setValueBoxByType(type);
+		this._updateValueBox();
+	},
+	_onChangeCondition: function(val){
+		this._checkValidCriteria();
+		var f = (val == "range");
+		if(f ^ this._isRange){
+			this._isRange = f;
+			this._setValueBoxByType(this.dlg.getColumnType(this._colSelect.get("value")));
+		}
+		this._updateValueBox();
+	},
+	_updateValueBox: function(cond){
+		this._curValueBox.set("disabled", this._condSelect.get("value") == "isempty");
+	},
+	_checkValidCriteria: function(){
+		// summary:
+		//		Check whether the given criteria box is completed. If it is, mark it.
+		setTimeout(dojo.hitch(this, function(){
+			this.updateRuleTitle();
+			this.dlg._updatePane();
+		}),0);
+	},
+	_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,{
+			tabIndex: _tabIdxes.valueBox,
+			onKeyPress: func,
+			onChange: func,
+			"class": "dojoxGridFCBoxValueBox"
+		}));
+	},
+	_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,{
+			tabIndex: _tabIdxes.valueBox,
+			onKeyPress: func,
+			onChange: func
+		});
+		var div = dojo.create("div", {"class": "dojoxGridFCBoxValueBox"}),
+			start = new cls(arg),
+			txt = dojo.create("span", {"class": "dojoxGridFCBoxRangeValueTxt", "innerHTML": this.plugin.nls.rangeTo}),
+			end = new cls(arg);
+		dojo.addClass(start.domNode, "dojoxGridFCBoxStartValue");
+		dojo.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)){
+				start.set("value", args.start);
+				end.set("value", args.end);
+			}
+		};
+		div.get = function(){
+			var s = start.get("value"),
+				e = end.get("value");
+			return s && e ? {start: s, end: e} : "";
+		};
+		return div;
+	},
+	changeCurrentColumn: function(/* bool */selectCurCol){
+		var colIdx = this.dlg.curColIdx;
+		//Re-populate the columns in case some of them are set to hidden.
+		this._colSelect.removeOption(this._colOptions);
+		this._colOptions = this._getColumnOptions();
+		this._colSelect.addOption(this._colOptions);
+		this._colSelect.set('value', colIdx >= 0 ? String(colIdx) : "anycolumn");
+		this.updateRuleTitle(true);
+	},
+	curColumn: function(){
+		return this._colSelect.getOptions(this._colSelect.get("value")).label;
+	},
+	curCondition: function(){
+		return this._condSelect.getOptions(this._condSelect.get("value")).label;
+	},
+	curValue: function(){
+		var cond = this._condSelect.get("value");
+		if(cond == "isempty"){return "";}
+		return this._curValueBox ? this._curValueBox.get("value") : "";
+	},
+	save: function(){
+		if(this.isEmpty()){
+			return null;
+		}
+		var colIdx = this._colSelect.get("value"),
+			type = this.dlg.getColumnType(colIdx),
+			value = this.curValue(),
+			cond = this._condSelect.get("value");
+		return {
+			"column": colIdx,
+			"condition": cond,
+			"value": value,
+			"formattedVal": this.formatValue(type, cond, value),
+			"type": type,
+			"colTxt": this.curColumn(),
+			"condTxt": this.curCondition()
+		};
+	},
+	load: function(obj){
+		var tmp = [
+			this._onChangeColumn,
+			this._onChangeCondition
+		];
+		this._onChangeColumn = this._onChangeCondition = function(){};
+		if(obj.column){
+			this._colSelect.set("value", obj.column);
+		}
+		if(obj.condition){
+			this._condSelect.set("value", obj.condition);
+		}
+		if(obj.type){
+			this._setValueBoxByType(obj.type);
+		}else{
+			obj.type = this.dlg.getColumnType(this._colSelect.get("value"));
+		}
+		var value = obj.value || "";
+		if(value || (obj.type != "date" && obj.type != "time")){
+			this._curValueBox.set("value", value);
+		}
+		this._updateValueBox();
+		setTimeout(dojo.hitch(this, function(){
+			this._onChangeColumn = tmp[0];
+			this._onChangeCondition = tmp[1];
+		}), 0);
+	},
+	getExpr: function(){
+		if(this.isEmpty()){
+			return null;
+		}
+		var colval = this._colSelect.get("value");
+		return this.dlg.getExprForCriteria({
+			"type": this.dlg.getColumnType(colval),
+			"column": colval,
+			"condition": this._condSelect.get("value"),
+			"value": this.curValue()
+		});
+	},
+	isEmpty: function(){
+		var cond = this._condSelect.get("value");
+		if(cond == "isempty"){return false;}
+		var v = this.curValue();
+		return v === "" || v === null || typeof v == "undefined" || (typeof v == "number" && isNaN(v));
+	},
+	updateRuleTitle: function(isEmpty){
+		var node = this._pane._buttonWidget.titleTextNode;
+		var title = [
+			"<div class='dojoxEllipsis'>"
+		];
+		if(isEmpty || this.isEmpty()){
+			node.title = dojo.string.substitute(this.plugin.nls.ruleTitleTemplate, [this._ruleIndex || 1]);
+			title.push(node.title);
+		}else{
+			var type = this.dlg.getColumnType(this._colSelect.get("value"));
+			var column = this.curColumn();
+			var condition = this.curCondition();
+			var value = this.formatValue(type, this._condSelect.get("value"), this.curValue());
+			title.push(
+				column,
+				" <span class='dojoxGridRuleTitleCondition'>",
+				condition,
+				"</span> ",
+				value
+			);
+			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;
+		}
+	},
+	updateRuleIndex: function(index){
+		if(this._ruleIndex != index){
+			this._ruleIndex = index;
+			if(this.isEmpty()){
+				this.updateRuleTitle();
+			}
+		}
+	},
+	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 = [];
+		}
+		if(!dojo.isArray(colDisabledConds)){
+			colDisabledConds = [];
+		}
+		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);
+			});
+		}
+		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.
+		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){
+		// 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}]
+					}
+				});
+			}
+		}else if(type == "boolean"){
+			dojo.mixin(res, this.dlg.builder.defaultArgs["boolean"]);
+		}
+		if(cell && cell.dataTypeArgs){
+			dojo.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 = 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;
+		}
+		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";
+	}
+});
+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;
+		}
+		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");
+			}
+		}
+		pane.destroyRecursive();
+	},
+	selectChild: function(child){
+		if(child._pane){
+			arguments[0] = child._pane;
+		}
+		this.inherited(arguments);
+	},
+	resize: function(){
+		this.inherited(arguments);
+		dojo.forEach(this.getChildren(), this._setupTitleDom);
+	},
+	startup: function(){
+		if(this._started){
+			return;
+		}
+		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);
+		}
+		dojo.forEach(this.getChildren(), function(child){
+			this._modifyChild(child, true);
+		}, this);
+	},
+	_onKeyPress: function(/*Event*/ e, /*dijit._Widget*/ fromTitle){
+		// summary:
+		//		Overrides base class method, make left/right button do other things.
+		if(this.disabled || e.altKey || !(fromTitle || e.ctrlKey)){
+			return;
+		}
+		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;
+		}else{
+			return;
+		}
+		if(toNext !== null){
+			this._adjacent(toNext)._buttonWidget._onTitleClick();
+		}
+		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);
+		}
+		dijit.focus(this.selectedChildWidget[this._focusOnRemoveBtn ? "_removeCBoxBtn" : "_buttonWidget"].focusNode);
+	},
+	_modifyChild: function(child, isFirst){
+		if(!child || !this._started){
+			return;
+		}
+		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", "");
+				}
+			}
+		}
+		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;
+				}
+			}
+		}
+		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();
+	},
+	_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);
+	},
+	_onKey: function(evt){
+		if(evt.charOrCode === dojo.keys.ENTER && this._opened){
+			dojo.stopEvent(evt);
+		}
+		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();
+	},
+	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);
+		}
+	}
+});
+})();
diff --git a/dojox/grid/enhanced/plugins/filter/FilterLayer.js b/dojox/grid/enhanced/plugins/filter/FilterLayer.js
new file mode 100644
index 0000000..d479379
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/FilterLayer.js
@@ -0,0 +1,404 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterLayer");
+
+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];
+			}
+		}
+		return res;
+	};
+	dojo.declare("dojox.grid.enhanced.plugins.filter._FilterLayerMixin", null, {
+/*=====
+		// _filter: _ConditionExpr
+		//		The filter definition
+		_filter: null,
+		
+		filterDef: function(filter){
+			// summary:
+			//		Get/set/clear the filter definition
+			// tags:
+			//		public
+			// filter: (_ConditionExpr|null)?
+			//		null: clear filter definition
+			//		undefined: it's getter
+			// returns:
+			//		A filter definition if it's getter.
+		},
+=====*/
+		tags: ["sizeChange"],
+		name: function(){
+			// summary:
+			//		override from _StoreLayer.name
+			return "filter";	//string
+		},
+		onFilterDefined: function(filter){},
+		
+		onFiltered: function(filteredSize, totalSize){
+			// summary:
+			//		Called when store data is filtered. This event is before *onComplete*, after *onBegin*.
+			// tags:
+			//		callback extension
+			// filteredSize: Integer
+			//		The number of remaining fetched items after filtering.
+			// totalSize: Integer
+			//		The number of original fetched items.
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.ServerSideFilterLayer", [ns._ServerSideLayer, ns.filter._FilterLayerMixin], {
+		constructor: function(args){
+			this._onUserCommandLoad = args.setupFilterQuery || this._onUserCommandLoad;
+			this.filterDef(null);
+		},
+		filterDef: function(/* (_ConditionExpr|null)? */filter){
+			// summary:
+			//		See _FilterLayerMixin.filterDef
+			if(filter){
+				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(cmdClearFilter, null);
+				this.useCommands(true);
+				this.onFilterDefined(filter);
+			}else if(filter === null){
+				this._filter = null;
+				this.command(cmdSetFilter, null);
+				this.command(cmdClearFilter, true);
+				this.useCommands(true);
+				this.onFilterDefined(null);
+			}
+			return this._filter;	//_ConditionExpr
+		},
+		onCommandLoad: function(/* (in)string */responce, /* (in|out)keywordArgs */ userRequest){
+			// summary:
+			//		override from _ServerSideLayer.onCommandLoad
+			this.inherited(arguments);
+			var oldOnBegin = userRequest.onBegin;
+			if(this._isStateful){
+				var filteredSize;
+				if(responce){
+					this.command(cmdSetFilter, null);
+					this.command(cmdClearFilter, null);
+					this.useCommands(false);
+					var sizes = responce.split(',');
+					if(sizes.length >= 2){
+						filteredSize = this._filteredSize = parseInt(sizes[0], 10);
+						this.onFiltered(filteredSize, parseInt(sizes[1], 10));
+					}else{
+						//Error here.
+						return;
+					}
+				}else{
+					filteredSize = this._filteredSize;
+				}
+				if(this.enabled()){
+					userRequest.onBegin = function(size, req){
+						hitchIfCan(userRequest.scope, oldOnBegin)(filteredSize, req);
+					};
+				}
+			}else{
+				var _this = this;
+				userRequest.onBegin = function(size, req){
+					if(!_this._filter){
+						_this._storeSize = size;
+					}
+					_this.onFiltered(size, _this._storeSize || size);
+					req.onBegin = oldOnBegin;
+					hitchIfCan(userRequest.scope, oldOnBegin)(size, req);
+				};
+			}
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.ClientSideFilterLayer", [ns._StoreLayer, ns.filter._FilterLayerMixin], {
+		// summary:
+		//		Add a client side filter layer on top of the data store,
+		//		so any filter expression can be applied to the store.
+/*=====
+		//_items: Array,
+		//		Cached items (may contain holes)
+		_items: [],
+		
+		//_result: Array,
+		//		Current fetch result
+		_result: [],
+		
+		//_resultStartIdx: Integer,
+		//		The index in cache of the first result item
+		_resultStartIdx: 0,
+		
+		//_indexMap: Array,
+		//		A map from the row index of this._items to the row index of the original store.
+		_indexMap: null,
+		
+		//_getter: function(datarow, colArg, rowIndex, store);
+		//		A user defined way to get data from store
+		_getter: null,
+		
+		// _nextUnfetchedIdx: Integer
+		//		The index of the next item in the store that is never fetched.
+		_nextUnfetchedIdx: 0,
+=====*/
+		// _storeSize: Integer
+		//		The actual size of the original store
+		_storeSize: -1,
+		
+		// _fetchAll
+		//		If the store is small or store size must be correct when onBegin is called,
+		//		we should fetch and filter all the items on the first query.
+		_fetchAll: true,
+		
+		constructor: function(args){
+			this.filterDef(null);
+			args = dojo.isObject(args) ? args : {};
+			this.fetchAllOnFirstFilter(args.fetchAll);
+			this._getter = dojo.isFunction(args.getter) ? args.getter : this._defaultGetter;
+		},
+		_defaultGetter: function(datarow, colName, rowIndex, store){
+			return store.getValue(datarow, colName);
+		},
+		filterDef: function(/* (_ConditionExpr|null)? */filter){
+			// summary:
+			//		See _FilterLayerMixin.filterDef
+			if(filter !== undefined){
+				this._filter = filter;
+				this.invalidate();
+				this.onFilterDefined(filter);
+			}
+			return this._filter;	//_ConditionExpr
+		},
+		setGetter: function(/* function */getter){
+			// summary:
+			//		Set the user defined way to retrieve data from store.
+			// tags:
+			//		public
+			// getter: function(datarow, colArg, rowIndex, store);
+			if(dojo.isFunction(getter)){
+				this._getter = getter;
+			}
+		},
+		fetchAllOnFirstFilter: function(/* bool? */toFetchAll){
+			// summary:
+			//		The get/set function for fetchAll.
+			// tags:
+			//		public
+			// toFetchAll: boolean?
+			//		If provided, it's a set function, otherwise it's a get function.
+			// returns:
+			//		Whether fetch all on first filter if this is a getter
+			if(toFetchAll !== undefined){
+				this._fetchAll = !!toFetchAll;
+			}
+			return this._fetchAll;	//Boolean
+		},
+		invalidate: function(){
+			// summary:
+			//		Clear all the status information of this layer
+			// tags:
+			//		private
+			this._items = [];
+			this._nextUnfetchedIdx = 0;
+			this._result = [];
+			this._indexMap = [];
+			this._resultStartIdx = 0;
+		},
+		//----------------Private Functions-----------------------------
+		_fetch: function(userRequest,filterRequest){
+			// summary:
+			//		Implement _StoreLayer._fetch
+			// tags:
+			//		private callback
+			// filterRequest: dojo.data.api.Request
+			//		The actual request used in store.fetch.
+			//		This function is called recursively to fill the result store items
+			//		until the user specified item count is reached. Only in recursive calls,
+			//		this parameter is valid.
+			if(!this._filter){
+				//If we don't have any filter, use the original request and fetch.
+				var old_onbegin = userRequest.onBegin, _this = this;
+				userRequest.onBegin = function(size, r){
+					hitchIfCan(userRequest.scope, old_onbegin)(size, r);
+					_this.onFiltered(size, size);
+				};
+				this.originFetch(userRequest);
+				return userRequest;
+			}
+			try{
+				//If the fetch is at the beginning, user's start position is used;
+				//If we are in a recursion, our own request is used.
+				var start = filterRequest ? filterRequest._nextResultItemIdx : userRequest.start;
+				start = start || 0;
+				if(!filterRequest){
+					//Initially, we have no results.
+					this._result = [];
+					this._resultStartIdx = start;
+					var sortStr;
+					if(dojo.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){
+						//If we should sort data, all the old caches are no longer valid.
+						this.invalidate();
+						this._lastSortInfo = sortStr;
+					}
+				}
+				//this._result contains the current fetch result (of every recursion).
+				var end = typeof userRequest.count == "number" ?
+					start + userRequest.count - this._result.length : this._items.length;
+				//Try to retrieve all the items from our cache.
+				//Only need items after userRequest.start, test it in case start is smaller.
+				if(this._result.length){
+					this._result = this._result.concat(this._items.slice(start, end));
+				}else{
+					this._result = this._items.slice(userRequest.start, typeof userRequest.count == "number" ?
+						userRequest.start + userRequest.count : this._items.length);
+				}
+				if(this._result.length >= userRequest.count || this._hasReachedStoreEnd()){
+					//We already have had enough items, or we have to stop fetching because there's nothing more to fetch.
+					this._completeQuery(userRequest);
+				}else{
+					//User's request hasn't been finished yet. Fetch more.
+					if(!filterRequest){
+						//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){
+							//We've fetched some more, so march ahead!
+							this._nextUnfetchedIdx += items.length;
+							//Actual filtering work goes here. Survived items are added to our cache.
+							//req is our own request object.
+							this._doFilter(items, req.start, userRequest);
+							//Recursively call this function. Let's do this again!
+							this._fetch(userRequest, req);
+						});
+					}
+					//Fetch starts from the next unfetched item.
+					filterRequest.start = this._nextUnfetchedIdx;
+					//If store is small, we should only fetch once.
+					if(this._fetchAll){
+						delete filterRequest.count;
+					}
+					//Remember we've (maybe) already added something to our result array, so next time we should not start over again.
+					filterRequest._nextResultItemIdx = end < this._items.length ? end : this._items.length;
+					//Actual fetch work goes here.
+					this.originFetch(filterRequest);
+				}
+			}catch(e){
+				if(userRequest.onError){
+					hitchIfCan(userRequest.scope, userRequest.onError)(e, userRequest);
+				}else{
+					throw e;
+				}
+			}
+			return userRequest;
+		},
+		_hasReachedStoreEnd: function(){
+			// summary:
+			//		Check whether all the items in the original store have been fetched.
+			// tags:
+			//		private
+			return this._storeSize >= 0 && this._nextUnfetchedIdx >= this._storeSize;	//Boolean
+		},
+		_applyFilter: function(/* data item */datarow,/* Integer */rowIndex){
+			// summary:
+			//		Apply the filter to a row of data
+			// tags:
+			//		private
+			// returns:
+			//		whether this row survived the filter.
+			var g = this._getter, s = this._store;
+			try{
+				return !!(this._filter.applyRow(datarow, function(item, arg){
+					return g(item, arg, rowIndex, s);
+				}).getValue());
+			}catch(e){
+				console.warn("FilterLayer._applyFilter() error: ", e);
+				return false;
+			}
+		},
+		_doFilter: function(/* Array */items,/* Integer */startIdx,/* object */userRequest){
+			// summary:
+			//		Use the filter expression to filter items. Survived items are stored in this._items.
+			//		The given items start from "startIdx" in the original store.
+			// tags:
+			//		private
+			for(var i = 0, cnt = 0; i < items.length; ++i){
+				if(this._applyFilter(items[i], startIdx + i)){
+					hitchIfCan(userRequest.scope, userRequest.onItem)(items[i], userRequest);
+					cnt += this._addCachedItems(items[i], this._items.length);
+					this._indexMap.push(startIdx + i);
+				}
+			}
+		},
+		_onFetchBegin: function(/* Integer */size,/* request object */req){
+			// summary:
+			//		This function is used to replace the user's onFetchBegin in store.fetch
+			// tags:
+			//		private
+			this._storeSize = size;
+		},
+		_completeQuery: function(/* request object */userRequest){
+			// summary:
+			//		Logically, the user's query is completed here, i.e., all the filtered results are ready.
+			//		(or their index mappings are ready)
+			// tags:
+			//		private
+			var size = this._items.length;
+			if(this._nextUnfetchedIdx < this._storeSize){
+				//FIXME: There's still some items in the original store that are not fetched & filtered.
+				//So we have to estimate a little bigger size to allow scrolling to these unfetched items.
+				//However, this behavior is ONLY correct in Grid! Any better way to do this?
+				size++;
+			}
+			hitchIfCan(userRequest.scope, userRequest.onBegin)(size,userRequest);
+			this.onFiltered(this._items.length, this._storeSize);
+			hitchIfCan(userRequest.scope, userRequest.onComplete)(this._result, userRequest);
+		},
+		_addCachedItems: function(/* Array */items,/* Integer */filterStartIdx){
+			// summary:
+			//		Add data items to the cache. The insert point is at *filterStartIdx*
+			// tags:
+			//		private
+			// items: Array
+			//		Data items to add.
+			// filterStartIdx: Integer
+			//		The start point to insert in the cache.
+			if(!dojo.isArray(items)){
+				items = [items];
+			}
+			for(var k = 0; k < items.length; ++k){
+				this._items[filterStartIdx + k] = items[k];
+			}
+			return items.length;
+		},
+		onRowMappingChange: function(mapping){
+			//This function runs in FilterLayer scope!
+			if(this._filter){
+				var m = dojo.clone(mapping),
+					alreadyUpdated = {};
+				for(var r in m){
+					r = parseInt(r, 10);
+					mapping[this._indexMap[r]] = this._indexMap[m[r]];
+					if(!alreadyUpdated[this._indexMap[r]]){
+						alreadyUpdated[this._indexMap[r]] = true;
+					}
+					if(!alreadyUpdated[r]){
+						alreadyUpdated[r] = true;
+						delete mapping[r];
+					}
+				}
+			}
+		}
+	});
+})();
diff --git a/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js b/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
new file mode 100644
index 0000000..e37e718
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/FilterStatusTip.js
@@ -0,0 +1,139 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter.FilterStatusTip");
+
+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");
+
+(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, {
+		// summary:
+		//		Create the status tip UI.
+		constructor: function(args){
+			var plugin = this.plugin = args.plugin;
+			this._statusHeader = ["<table border='0' cellspacing='0' class='",
+				gridCssCls, "'><thead><tr class='",
+				headerCssCls, "'><th class='",
+				cellCssCls, "'><div>", plugin.nls["statusTipHeaderColumn"], "</div></th><th class='",
+				cellCssCls, " lastColumn'><div>", plugin.nls["statusTipHeaderCondition"], "</div></th></tr></thead><tbody>"
+			].join('');
+			this._removedCriterias = [];
+			this._rules = [];
+			this.statusPane = new dojox.grid.enhanced.plugins.filter.FilterStatusPane();
+			this._dlg = new dijit.TooltipDialog({
+				"class": "dojoxGridFStatusTipDialog",
+				content: this.statusPane,
+				autofocus: false,
+				onMouseLeave: dojo.hitch(this,function(){
+					this.closeDialog();
+				})
+			});
+			this._dlg.connect(this._dlg.domNode,"click", dojo.hitch(this, this._modifyFilter));
+		},
+		destroy: function(){
+			this._dlg.destroyRecursive();
+		},
+		//-----------------Public Functions------------------------
+		showDialog: function(/* int */pos_x,/* int */pos_y, columnIdx){
+			this._pos = {x:pos_x,y:pos_y};
+			dijit.popup.close(this._dlg);
+			this._removedCriterias = [];
+			this._rules = [];
+			this._updateStatus(columnIdx);
+			dijit.popup.open({
+				popup: this._dlg,
+				parent: this.plugin.filterBar,
+				x:pos_x - 12,
+				y:pos_y - 3
+			});
+		},
+		closeDialog: function(){
+			dijit.popup.close(this._dlg);
+			if(this._removedCriterias.length){
+				this.plugin.filterDefDialog.removeCriteriaBoxes(this._removedCriterias);
+				this._removedCriterias = [];
+				this.plugin.filterDefDialog.onFilter();
+			}
+		},
+		//-----------------Private Functions---------------------------
+		_updateStatus: function(columnIdx){
+			var res, p = this.plugin,
+				nls = p.nls,
+				sp = this.statusPane,
+				fdg = p.filterDefDialog;
+			if(fdg.getCriteria() === 0){
+				sp.statusTitle.innerHTML = nls["statusTipTitleNoFilter"];
+				sp.statusRel.innerHTML = sp.statusRelPre.innerHTML = sp.statusRelPost.innerHTML = "";
+				var cell = p.grid.layout.cells[columnIdx];
+				var colName = cell ? "'" + (cell.name || cell.field) + "'" : nls["anycolumn"];
+				res = dojo.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"];
+				
+				this._rules = [];
+				var i = 0, c = fdg.getCriteria(i++);
+				while(c){
+					c.index = i - 1;
+					this._rules.push(c);
+					c = fdg.getCriteria(i++);
+				}
+				res = this._createStatusDetail();
+			}
+			sp.statusDetailNode.innerHTML = res;
+			this._addButtonForRules();
+		},
+		_createStatusDetail: function(){
+			return this._statusHeader + dojo.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({
+						label: this.plugin.nls["removeRuleButton"],
+						showLabel: false,
+						iconClass: _removeRuleIconCls,
+						onClick: dojo.hitch(this, function(e){
+							e.stopPropagation();
+							this._removedCriterias.push(this._rules[idx].index);
+							this._rules.splice(idx,1);
+							this.statusPane.statusDetailNode.innerHTML = this._createStatusDetail();
+							this._addButtonForRules();
+						})
+					})).placeAt(nd, "last");
+				}));
+			}
+		},
+		_getCriteriaStr: function(/* object */c, /* int */rowIdx){
+			var res = ["<tr class='", rowCssCls,
+				" ", (rowIdx % 2 ? oddRowCssCls : ""),
+				"'><td class='", cellCssCls, "'>", c.colTxt,
+				"</td><td class='", cellCssCls,
+				"'><div class='", handleHolderCssCls, "'><span class='", conditionCssCls,
+				"'>", c.condTxt, " </span>",
+				c.formattedVal, "</div></td></tr>"];
+			return res.join('');
+		},
+		_modifyFilter: function(){
+			this.closeDialog();
+			var p = this.plugin;
+			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")
+	});
+})();
diff --git a/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js b/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
new file mode 100644
index 0000000..6ae9325
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/_ConditionExpr.js
@@ -0,0 +1,215 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter._ConditionExpr");
+
+(function(){
+	var fns = dojox.grid.enhanced.plugins.filter;
+	
+dojo.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)
+	//		and generate a result condition expression.
+	// tags:
+	//		abstract
+	
+	_name: "expr",
+	applyRow: function(/* data item */datarow,/* function(row,colArg) */getter){
+		// summary:
+		//		*Unimplemented Interface*
+		//		Apply this condition expression on the given datarow, return a result expression.
+		// taqs:
+		//		public extension
+		// datarow: object
+		//		A data item of a store.
+		// getter: function(datarow, colArg)
+		//		A user defined function that extract cell data from *datarow*.
+		//		*colArg* is an argument that provides a kind of column information.
+		//		It is defined by user in the constructor of a _DataExpr object.
+		// returns:
+		//		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.
+		// tags:
+		//		public extension
+		// returns:
+		//		An object for serialization.
+		return {};	//Object
+	},
+	getName: function(){
+		// summary:
+		//		Get the name of this kind of expression.
+		// tags:
+		//		public extension
+		// returns:
+		//		the name of this kind of expression
+		return this._name;	//String
+	}
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._DataExpr", fns._ConditionExpr, {
+	// summary:
+	//		The most abstract class for all data expressions.
+	//		A _DataExpr is a condition expression for a single data value.
+	//		If the data value to be represent is a pure value (literal value, like string/number/Date/...)
+	//		this _DataExpr is nothing more than a simple wrapper.
+	//		If the data value to be represent is in a store, then _DataExpr is responsible to extract it
+	//		from the store when this condition is applied to a data row.
+	// private fields:
+	//		_value: anything
+	//		_colArg: anything
+	_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.
+		//		If the second argument is exactly a boolean true (no implict type transformation,
+		//		so as to allow derived classes accept more arguments while retain *isColumn* to be optional),
+		//		then this _DataExpr represents a column, and it's applyRow method is not a no-op.
+		// dataValue: anything
+		//		If *isColumn* is a boolean true, then it should be a kind of column information, like field name
+		//		or column index. Otherwise, it is regarded as a pure value, and the getValue method will simply
+		//		return it.
+		// 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(isColumn){
+			this._colArg = dataValue;
+		}else{
+			this._value = this._convertData(dataValue, this._convertArgs);
+		}
+	},
+	getValue: function(){
+		// summary:
+		//		If this is a pure value wrapper, simply return the value.
+		//		Otherwise (it's a column), return is undefined.
+		// tags:
+		//		public
+		// returns:
+		//		the value of this data expression.
+		return this._value;	//String
+	},
+	applyRow: function(/* data item */datarow,/* function(row,colIdx) */getter){
+		// summary:
+		//		Implement _ConditionExpr.applyRow.
+		//		If this is a pure value, simply return self.
+		//		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))(
+				this._convertData(getter(datarow, this._colArg), this._convertArgs)
+			);
+	},
+	_convertData: function(/* anything */dataValue){
+		// summary:
+		//
+		// tags:
+		//		protected extension
+		// dataValue: anything
+		//		This argument should come from a store.
+		// returns:
+		return dataValue;
+	},
+	toObject: function(){
+		// summary:
+		//		Overrided from _ConditionExpr.toObject
+		return {															//String
+			op: this.getName(),
+			data: this._colArg === undefined ? this._value : this._colArg,
+			isCol: this._colArg !== undefined
+		};
+	}
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._OperatorExpr", fns._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])){
+			this._operands = arguments[0];
+		}else{
+			this._operands = [];
+			for(var i = 0; i < arguments.length; ++i){
+				this._operands.push(arguments[i]);
+			}
+		}
+	},
+	toObject: function(){
+		// summary:
+		//		Overrided from _ConditionExpr.toObject
+		return {											//Object
+			op: this.getName(),
+			data: dojo.map(this._operands,function(operand){
+				return operand.toObject();
+			})
+		};
+	}
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._UniOpExpr", fns._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)){
+			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*
+		//		Do the actrual work of applyRow here.
+		// tags:
+		//		protected extension
+		// operand: _ConditionExpr
+		// datarow: object
+		// getter: function(row,colArg)
+		// returns:
+		//		MUST return a _ConditionExpr object.
+		throw new Error("_UniOpExpr._calculate: unimplemented interface");
+	}
+});
+dojo.declare("dojox.grid.enhanced.plugins.filter._BiOpExpr", fns._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)){
+			throw new Error("_BiOpExpr: left operand is not expression.");
+		}else if(!(this._operands[1] instanceof fns._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*
+		//		Do the actrual work of applyRow here.
+		// tags:
+		//		protected extension
+		// left_operand: _ConditionExpr
+		// right_operand: _ConditionExpr
+		// datarow: object
+		// getter: function(row,colArg)
+		// returns:
+		//		MUST return a _ConditionExpr object.
+		throw new Error("_BiOpExpr._calculate: unimplemented interface");
+	}
+});
+})();
diff --git a/dojox/grid/enhanced/plugins/filter/_DataExprs.js b/dojox/grid/enhanced/plugins/filter/_DataExprs.js
new file mode 100644
index 0000000..387db38
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/_DataExprs.js
@@ -0,0 +1,78 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter._DataExprs");
+
+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, {
+		// summary:
+		//		A condition expression wrapper for boolean values
+		_name: "bool",
+		_convertData: function(/* anything */dataValue){
+			// summary:
+			//		override from _DataExpr
+			return !!dataValue;	//Boolean
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.StringExpr", fns._DataExpr, {
+		// summary:
+		//		A condition expression wrapper for string values
+		_name: "string",
+		_convertData: function(/* anything */dataValue){
+			// summary:
+			//		override from _DataExpr
+			return String(dataValue);	//String
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.NumberExpr", fns._DataExpr, {
+		// summary:
+		//		A condition expression wrapper for number values
+		_name: "number",
+		_convertDataToExpr: function(/* anything */dataValue){
+			// summary:
+			//		override from _DataExpr
+			return parseFloat(dataValue);	//Number
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.DateExpr", fns._DataExpr, {
+		// summary:
+		//		A condition expression wrapper for date values
+		_name: "date",
+		_convertData: function(/* anything */dataValue){
+			// summary:
+			//		override from _DataExpr
+			if(dataValue instanceof Date){
+				return dataValue;
+			}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));
+				if(!res){
+					throw new Error("Datetime parse failed: " + dataValue);
+				}
+				return res;
+			}
+		},
+		toObject: function(){
+			// summary:
+			//		Overrided from _DataExpr.toObject
+			if(this._value instanceof Date){
+				var tmp = this._value;
+				this._value = this._value.valueOf();
+				var res = this.inherited(arguments);
+				this._value = tmp;
+				return res;
+			}else{
+				return this.inherited(arguments);
+			}
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.TimeExpr", fns.DateExpr, {
+		// summary:
+		//		A condition expression wrapper for time values
+		_name: "time"
+	});
+})();
+
diff --git a/dojox/grid/enhanced/plugins/filter/_FilterExpr.js b/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
new file mode 100644
index 0000000..b8c545e
--- /dev/null
+++ b/dojox/grid/enhanced/plugins/filter/_FilterExpr.js
@@ -0,0 +1,228 @@
+dojo.provide("dojox.grid.enhanced.plugins.filter._FilterExpr");
+//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, {
+		// summary:
+		//		A logic AND condition expression.
+		_name: "and",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = left_operand.applyRow(datarow, getter).getValue() &&
+				right_operand.applyRow(datarow, getter).getValue();
+			return new fns.BooleanExpr(res);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicOR", fns._BiOpExpr, {
+		// summary:
+		//		A logic OR condition expression.
+		_name: "or",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = left_operand.applyRow(datarow, getter).getValue() ||
+				right_operand.applyRow(datarow, getter).getValue();
+			return new fns.BooleanExpr(res);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicXOR", fns._BiOpExpr, {
+		// summary:
+		//		A logic XOR condition expression.
+		_name: "xor",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		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
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicNOT", fns._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
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicALL", fns._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){
+				res = this._operands[i].applyRow(datarow,getter).getValue();
+			}
+			return new fns.BooleanExpr(res);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LogicANY", fns._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){
+				res = this._operands[i].applyRow(datarow,getter).getValue();
+			}
+			return new fns.BooleanExpr(res);	//_ConditionExpr
+		}
+	});
+	
+	/* Comparison Operations */
+	function compareFunc(left,right,row,getter){
+		left = left.applyRow(row, getter);
+		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");
+		}else{
+			if(left instanceof fns.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, {
+		// summary:
+		//		An "equal to" condition expression.
+		_name: "equal",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = compareFunc(left_operand,right_operand,datarow,getter);
+			return new fns.BooleanExpr(res === 0);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LessThan", fns._BiOpExpr, {
+		// summary:
+		//		A "less than" condition expression.
+		_name: "less",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = compareFunc(left_operand,right_operand,datarow,getter);
+			return new fns.BooleanExpr(res < 0);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LessThanOrEqualTo", fns._BiOpExpr, {
+		// summary:
+		//		A "less than or equal to" condition expression.
+		_name: "lessEqual",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = compareFunc(left_operand,right_operand,datarow,getter);
+			return new fns.BooleanExpr(res <= 0);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThan", fns._BiOpExpr, {
+		// summary:
+		//		A "larger than" condition expression.
+		_name: "larger",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = compareFunc(left_operand,right_operand,datarow,getter);
+			return new fns.BooleanExpr(res > 0);	//_ConditionExpr
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.LargerThanOrEqualTo", fns._BiOpExpr, {
+		// summary:
+		//		A "larger than or equal to" condition expression.
+		_name: "largerEqual",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = compareFunc(left_operand,right_operand,datarow,getter);
+			return new fns.BooleanExpr(res >= 0);	//_ConditionExpr
+		}
+	});
+	
+	/* String Operations */
+	dojo.declare("dojox.grid.enhanced.plugins.filter.Contains", fns._BiOpExpr, {
+		// summary:
+		//		A "contains" condition expression.
+		_name: "contains",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		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
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.StartsWith", fns._BiOpExpr, {
+		// summary:
+		//		A "starts with" condition expression.
+		_name: "startsWith",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		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
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.EndsWith", fns._BiOpExpr, {
+		// summary:
+		//		An "ends with" condition expression.
+		_name: "endsWith",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		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
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.Matches", fns._BiOpExpr, {
+		// summary:
+		//		A "regular expression match" condition expression.
+		//		The second operand's value will be regarded as an regular expression string.
+		_name: "matches",
+		_calculate: function(/* _ConditionExpr */left_operand,/* _ConditionExpr */right_operand,
+							/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		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
+		}
+	});
+	dojo.declare("dojox.grid.enhanced.plugins.filter.IsEmpty", fns._UniOpExpr, {
+		// summary:
+		//		Check empty
+		_name: "isEmpty",
+		_calculate: function(/* _ConditionExpr */operand,/* data item*/datarow,/* function(row,colIdx) */getter){
+			// summary:
+			//		Override from _BiOpExpr
+			var res = operand.applyRow(datarow, getter).getValue();
+			return new fns.BooleanExpr(res === "" || res == null);
+		}
+	});
+})();
diff --git a/dojox/grid/enhanced/resources/Common.css b/dojox/grid/enhanced/resources/Common.css
new file mode 100644
index 0000000..d2842f1
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Common.css
@@ -0,0 +1,36 @@
+.dojoxGrid {
+	border:1px solid #DBDBDB;
+}
+.dojoxGridCellContent {
+	padding:3px;
+}
+.dojoxGridSortNode {
+	padding:3px;
+}
+.dojoxGridInProgress {
+	cursor:progress;
+}
+/* Indirect Selection */
+.dojoxGridRowSelectorStatusText{
+	visibility:hidden;
+}
+.dijit_a11y .dojoxGridRowSelected {
+	opacity:0.8 !important;
+}
+.dijit_a11y .dojoxGridBorderDIV {
+	border:2px solid #000 !important;
+}
+.dijit_a11y .dojoxGridRowSelector {
+	height:100% !important;
+}
+.dijit_a11y .dojoxGridRowSelectorStatusText{
+	font-size:larger !important;
+	visibility:visible;
+}
+.dijit_a11y .dijitCheckBox .dojoxGridRowSelectorStatusText{
+	font-weight:bolder !important;
+	font-size:x-large !important;
+}
+.dijit_a11y .dijitCheckBoxChecked .dojoxGridRowSelectorStatusText{
+	font-size:small !important;
+}
diff --git a/dojox/grid/enhanced/resources/Common_rtl.css b/dojox/grid/enhanced/resources/Common_rtl.css
new file mode 100644
index 0000000..796e935
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Common_rtl.css
@@ -0,0 +1,15 @@
+.dojoxGridRtl .dojoxGridLoading, 
+.dojoxGridRtl .dojoxGridError,
+.dojoxGridRtl .dojoxGridNoData {
+	background-position:right;
+	padding-right:25px;
+	padding-left:0px;
+}
+.dojoxGridRtl .dojoxGridHeader {
+	margin-left: 0;
+	margin-right: -1px;
+}
+
+.dojoxGridRtl .dojoxGridCell {
+	text-align: right;
+}
diff --git a/dojox/grid/enhanced/resources/DnD.css b/dojox/grid/enhanced/resources/DnD.css
new file mode 100644
index 0000000..c364b0e
--- /dev/null
+++ b/dojox/grid/enhanced/resources/DnD.css
@@ -0,0 +1,78 @@
+.dojoxGridBorderDIV {
+	width:2px;
+	background-color: gray;
+	font-size:0em;
+	position:absolute;
+	z-index:9999;
+}
+.dojoxGridCellBorderDIV {
+	position:absolute;
+	background-color: transparent;
+	border: none;
+}
+.dojoxGridCellBorderLeftTopDIV {
+	position: absolute;
+	left: 0;
+	top: 0;
+	border-style: solid;
+	border-width: 2px 0 0 2px;
+	border-color: gray transparent transparent gray;
+}
+.dojoxGridCellBorderRightBottomDIV {
+	position: absolute;
+	right: 0;
+	bottom: 0;
+	border-style: solid;
+	border-width: 0 2px 2px 0;
+	border-color: transparent gray gray transparent;
+}
+.dojoxGridDnDItemIcon {
+	background-image: url("images/sprite_icons.png");
+}
+.dojoxGridDnDIconRowSingle {
+	background-position: -256px 5px;
+}
+.dojoxGridDnDIconRowMulti {
+	background-position: -256px -16px;
+}
+.dojoxGridDnDIconColSingle {
+	background-position: -277px 3px;
+}
+.dojoxGridDnDIconColMulti {
+	background-position: -277px -17px;
+}
+.dojoxGridDnDIconCellSingle {
+	background-position: -235px 5px;
+}
+.dojoxGridDnDIconCellMulti {
+	background-position: -236px -16px;
+}
+.dojoxGridDndAvatar {
+	background-color:white;
+	border: 1px solid #CCCCCC;
+	padding: 0px;
+	-moz-box-shadow: 5px 5px 7px #999;
+	-webkit-box-shadow: 5px 5px 7px #999;
+	box-shadow: 5px 5px 7px #999;
+	z-index: 999;
+}
+.dojoxGridDndAvatar td {
+	padding: 3px;
+}
+.dojoxGridDnDIcon,
+.dojoxGridDnDItemIcon {
+	width: 16px;
+	height: 16px;
+}
+.dojoDndMove .dojoxGridDnDIcon {
+	background: url(../../../../dojo/resources/images/dndNoMove.png) no-repeat center center;
+}
+.dojoDndCopy .dojoxGridDnDIcon {
+	background: url(../../../../dojo/resources/images/dndNoCopy.png) no-repeat center center;
+}
+.dojoDndMove .dojoDndAvatarCanDrop .dojoxGridDnDIcon {
+	background: url(../../../../dojo/resources/images/dndMove.png) no-repeat center center;
+}
+.dojoDndCopy .dojoDndAvatarCanDrop .dojoxGridDnDIcon {
+	background: url(../../../../dojo/resources/images/dndCopy.png) no-repeat center center;
+}
diff --git a/dojox/grid/enhanced/resources/DnD_rtl.css b/dojox/grid/enhanced/resources/DnD_rtl.css
new file mode 100644
index 0000000..d7f270f
--- /dev/null
+++ b/dojox/grid/enhanced/resources/DnD_rtl.css
@@ -0,0 +1,12 @@
+.dojoxGridRtl .dojoxGridCellBorderLeftTopDIV{
+	left: auto;
+	right: 0;
+	border-width: 2px 2px 0 0;
+	border-color: gray gray transparent transparent;
+}
+.dojoxGridRtl .dojoxGridCellBorderRightBottomDIV{
+	right: auto;
+	left: 0;
+	border-width: 0 0 2px 2px;
+	border-color: transparent transparent gray gray;
+}
diff --git a/dojox/grid/enhanced/resources/EnhancedGrid.css b/dojox/grid/enhanced/resources/EnhancedGrid.css
index 26a7aec..7f02773 100644
--- a/dojox/grid/enhanced/resources/EnhancedGrid.css
+++ b/dojox/grid/enhanced/resources/EnhancedGrid.css
@@ -1,190 +1,8 @@
-.dojoxGridCellContent {
-	padding:3px;
-}
+ at import url("Common.css");
+ at import url("Filter.css");
+ at import url("Pagination.css");
+ at import url("DnD.css");
+ at import url("Sorter.css");
+ at import url("../../../widget/Toaster/Toaster.css");
+ at import url("../../../html/resources/ellipsis.css");
 
-.dojoxGridSortNode {
-	padding:3px;
-}
-
-.dojoxGridSortRoot {
-	position: relative; 
-	width: 100%;
-	text-align:left; /*fix the selection region jumping when hover in IE7*/
-}
-
-.dojoxGridHeaderCellSelectRegion {
-	text-align: left;
-	padding:3px;
-	/*position:absolute;*/
-	overflow: hidden;
-	white-space:nowrap;
-}
-
-.dj_ie .dojoxGridHeaderCellSelectRegion {
-	padding-left:4px;
-}
-
-.dojoxGridSortWrapper {
-	/*float:right;*/
-	position:absolute;
-	right:0px;
-	/*left: auto;*/
-	z-index: 1;
-}
-
-.dojoxGridNestedSortWrapper {
-	float:left;
-}
-
-.dojoxGridSortPos {
-	float:left;
-	margin-left:3px;
-}
-
-.dj_ff2 .dojoxGridSortPos {
-	padding: 3px 0;
-	line-height: normal;
-}
-
-.dojoxGridSortPosOff {
-	display:none;
-}
-
-.dojoxGridNestedSort {
-	text-indent: -5000em;
-}
-
-.dojoxGridUnarySortWrapper {
-	float:left;
-}
-
-.dojoxGridSort {
-	display: block;
-	float: left;
-	background:url("images/nestedSortArrows.png") no-repeat left center;
-	width: 8px;
-	margin-right:3px;
-	margin-left:3px;
-	text-align:center;
-}
-
-.dojoxGridUnarySort {
-	text-indent: -5000em;
-	margin-left:4px;
-}
-
-.dojoxGridAscending {
-	background-position: -9px;
-}
-
-.dojoxGridUnsorted {
-	display:none;
-}
-
-.dojoxGridAscendingTip {
-	background:url("images/nestedSortArrows.png") no-repeat left center;
-	background-position: -30px;
-	display:block;
-	cursor:pointer;
-}
-
-.dojoxGridDescendingTip {
-	background:url("images/nestedSortArrows.png") no-repeat left center;
-	background-position: -20px;
-	display:block;
-	cursor:pointer;
-}
-
-.dojoxGridUnsortedTip {
-	background:url("images/nestedSortArrows.png") no-repeat left center;
-	background-position: -39.5px;
-	display:block;
-	cursor:pointer;
-}
-
-.dojoxGridSortHiddenTip {
-	display:none;
-}
-
-.dojoxGridSortSeparatorOff {
-	width: 0px;
-	border-right-color: #999999;
-	border-right-style:solid;
-	border-right-width:1px;
-	display: none;
-}
-
-.dojoxGridSortSeparatorOn {
-	display: block;
-	float: left;
-}
-
-.dojoxGridSortInProgress {
-	cursor:progress;
-}
-
-/* Indirect Selection */
-.dojoxGridWidgetHidden {
-	visibility:hidden;
-}
-
-.dijit_a11y .dojoxGridNestedSort, .dijit_a11y .dojoxGridUnarySort {
-	text-indent: 0;
-	/* background-image: none !important; - for testing*/
-}
-
-.dojoxGridFocusBorderBox {
-	position: relative;
-	top: 0;
-	left: 0;
-	width: 0;
-	height: 0;
-}
-
-.dojoxGridFocusBorder {
-	width: 0px;
-	height: 0px;
-	overflow: hidden;
-	position: absolute;
-	z-index: 999;
-	top: 0;
-	left: 0;
-}
-
-/** dnd **/
-.dojoxGridSelectedDIV {
-	background-color: #3366CC;
-	position:absolute;
-	opacity:0.2;
-	cursor:move;
-	z-index:999;
-}
-
-.dj_ie .dojoxGridSelectedDIV {
-	filter: alpha(opacity = 30);
-}
-
-.dojoxGridBorderDIV {
-	width:3px;
-	background-color: gray;
-	font-size:0em;
-	position:absolute;
-	z-index:9999;
-}
-
-.dojoxGrid {
-	border:1px solid #DBDBDB;
-}
-
-.dijit_a11y .dojoxGridRowSelected {
-	opacity:0.4 !important;
-}
-
-.dijit_a11y .dojoxGridSelectedDIV {
-	opacity:0.4 !important;
-	border:3px solid #000 !important;
-}
-
-.dijit_a11y .dojoxGridBorderDIV {
-	border:2px solid #000 !important;
-}
diff --git a/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css b/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
index b191473..0aae662 100644
--- a/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
+++ b/dojox/grid/enhanced/resources/EnhancedGrid_rtl.css
@@ -1,31 +1,6 @@
 @import url("../../resources/Grid_rtl.css");
-
-.dojoxGridRtl .dojoxGridNestedSort, 
-.dojoxGridRtl .dojoxGridUnarySort {
-	text-align: right;
-}
-
-.dojoxGridRtl .dojoxGridSortWrapper {
-	left: 0;
-	right: auto;
-}
-
-.dojoxGridRtl .dojoxGridCell .dojoxGridHeaderCellSelectRegion {
-	float: right;
-	text-align: right;
-	padding-right:4px;
-}
-
-.dojoxGridRtl .dojoxGridSortSeparatorOn,
-.dojoxGridRtl .dojoxGridNestedSortWrapper,
-.dojoxGridRtl .dojoxGridUnarySortWrapper {
-	float: right;
-}
-
-.dojoxGridRtl .dojoxGridLoading, 
-.dojoxGridRtl .dojoxGridError,
-.dojoxGridRtl .dojoxGridNoData {
-	background-position:right;
-	padding-right:25px;
-	padding-left:0px;
-}
+ at import url("Common_rtl.css");
+ at import url("Filter_rtl.css");
+ at import url("Pagination_rtl.css");
+ at import url("DnD_rtl.css");
+ at import url("Sorter_rtl.css");
diff --git a/dojox/grid/enhanced/resources/Filter.css b/dojox/grid/enhanced/resources/Filter.css
new file mode 100644
index 0000000..1c7039c
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Filter.css
@@ -0,0 +1,292 @@
+/* filter bar */
+.dojoxGridFBar {
+	width: 100%;
+	cursor: pointer;
+}
+.dojoxGridFBar .dojoxGridFBarBtn {
+	margin: 0;
+}
+.dojoxGridFBarBtnTD {
+	width: 38px;
+}
+.dojoxGridFBar .dojoxGridFBarBtn .dijitButtonNode {
+	-moz-border-radius: 1px;
+	-webkit-border-radius: 1px;
+	padding-top: 0;
+	padding-bottom: 0;
+	padding-right: 2px;
+}
+.dojoxGridFBarDefFilterBtnIcon {
+	background: url("images/sprite_icons.png") no-repeat;
+	background-position: -100px -18px;
+	width: 14px;
+	height: 14px;
+}
+.dj_ie .dojoxGridFBarInner{
+	display: inline-block;
+	width: 100%;
+}
+.dojoxGridFBarStatus {
+	margin-left: 9px;
+	float: left;
+}
+.dojoxGridFBarClearFilterBtn {
+	margin: 0 0 0 10px;
+	vertical-align: top;
+	float: left;
+}
+.dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn .dijitButtonNode,
+.dojoxGridFBarInfoTD .dojoxGridFBarCloseBtn .dijitButtonNode,
+.dojoxGridFDPane .dijitAccordionTitle .dijitButtonNode,
+.dojoxGridFStatusTipDetail .dijitButton .dijitButtonNode {
+	-moz-border-radius: 0;
+	-moz-box-shadow: none;
+	-webkit-border-radius: 0;
+	-webkit-box-shadow: none;
+	background-image: none;
+	background-color: transparent;
+	margin: 0;
+	padding: 0;
+	border: none;
+}
+.dj_ie .dojoxGridFBarInner {
+	position: relative;
+}
+.dojoxGridFBarCloseBtn {
+	margin: 0 4px 0 0;
+	float: right;
+}
+.dj_ie .dojoxGridFBarCloseBtn {
+	float: none;
+	position: absolute;
+	right: 0;
+}
+.dojoxGridFBarCloseBtnIcon {
+	background: url("images/sprite_icons.png") no-repeat;
+	background-position: -119px -20px;
+	width: 14px;
+	height: 14px;
+}
+.dijitButtonHover .dojoxGridFBarCloseBtnIcon {
+	background-position: -140px -20px;
+}
+.dijitButtonActive .dojoxGridFBarCloseBtnIcon {
+	background-position: -160px -20px;
+}
+
+/* filter def dialog */
+.dojoxGridFDTitlePane {
+	width: 316px;
+	height: 330px;
+}
+.dijit_a11y .dojoxGridFDTitlePane .dijitArrowButtonInner{
+	/* This should be fixed in dijit */
+	display:none !important;
+}
+.dojoxGridFDTitlePane .dijitDialogPaneContent {
+	padding: 7px 5px 9px 5px;
+	height: 290px !important;
+}
+.dojoxGridFDTitlePane .dijitTitlePaneTitle {
+	cursor: move;
+}
+.dojoxGridFDPaneRelation {
+	margin: 0 0 3px 4px;
+}
+.dojoxGridFDPane {
+	width: 100%;
+	height: 100%;
+	position: relative;
+}
+.dojoxGridFDPaneRulePane {
+	height: 222px;
+	overflow: auto;
+	/* for ie6/7 only */
+	position: relative;
+}
+.dj_ie6 .dojoxGridFDPaneRulePane {
+	width: 100%;
+}
+.dojoxGridFDPane .dijitAccordionContainer .dijitContentPane {
+	padding: 6px 9px;
+}
+.dojoxGridFDPane .dijitAccordionTitle {
+	position: relative;
+	/* for non-claro theme, this can ensure a correct height change when adding/removing child */
+	min-height: 17px;
+}
+.dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+	position: absolute;
+	margin: 0;
+	right: 3px;
+	top: 4px;
+}
+.dj_ie6 .dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+	top: 2px;
+}
+.dojoxGridFDPane .dijitAccordionTitleFocus {
+	margin-right: 14px;
+}
+.dojoxGridFDPane .dijitAccordionText {
+	display: inline-block;
+	position: relative;
+}
+.dojoxGridFCBoxRemoveCBoxBtnIcon {
+	background-image: url("images/sprite_icons.png");
+	background-position: -198px -18px;
+	width: 16px;
+	height: 16px;
+}
+.dijitButtonHover .dojoxGridFCBoxRemoveCBoxBtnIcon {
+	background-position: -198px 2px;
+}
+.dojoxGridRuleTitleCondition {
+	font-style: italic;
+}
+.dojoxGridFDPaneModes .dijitSelect {
+	position: relative;
+}
+.dojoxGridFDPaneBtns {
+	position: absolute;
+	right: 0;
+	bottom: 0;
+}
+.dj_ie7 .dojoxGridFDPaneBtns,
+.dj_ie6 .dojoxGridFDPaneBtns {
+	z-index: -1;
+}
+.dojoxGridFDPaneBtns .dijitButton {
+	float: right;
+}
+.dojoxGridFDPaneAddCBoxBtn {
+	margin-top: 9px;
+}
+.dojoxGridFDPaneAddCBoxBtnIcon {
+	background-image: url("images/sprite_icons.png");
+	background-position: -218px 2px;
+	width: 16px;
+	height: 16px;
+}
+.dijitButtonDisabled .dojoxGridFDPaneAddCBoxBtnIcon {
+	background-position: -218px -18px;
+}
+
+/* criteria box */
+.dojoxGridFCBox {
+	height: 125px;
+}
+.dojoxGridFCBoxSelCol, 
+.dojoxGridFCBoxCondition {
+	height: 40px;
+}
+.dojoxGridFCBox .dojoxGridFCBoxColSelect, 
+.dojoxGridFCBox .dojoxGridFCBoxCondSelect, 
+.dojoxGridFCBox .dojoxGridFCBoxValueBox {
+	margin: 5px 0 0 0;
+	width: 100%;
+	/* inherited is inline-block this will cause width "error" in non IE for html tables */
+	display: inline-table;
+}
+.dojoxGridFCBoxCondSelectAlt {
+	width: 100%;
+	padding: 5px 0 0 0;
+	font-weight: bold;
+}
+.dojoxGridFCBox .dijitSelect .dijitArrowButton {
+	width: 18px;
+}
+.dojoxGridFCBoxStartValue {
+	width: 45%;	
+}
+.dojoxGridFCBoxEndValue {
+	float: right;
+	width: 45%;
+}
+.dojoxGridFCBoxRangeValueTxt {
+	margin-left: 4px;
+}
+
+/* status tip */
+.dojoxGridFStatusTipDialog .dijitTooltipContainer {
+	padding: 9px 5px;
+}
+.dojoxGridFStatusTip thead,
+.dojoxGridFStatusTip tr {
+	height: 19px;
+}
+.dojoxGridFStatusTip th {
+	max-width: 150px;
+	width: expression(this.clientWidth > 150 ? "150px" : "auto");
+}
+.dojoxGridFStatusTip th div {
+	padding: 2px 5px;
+}
+.dojoxGridFStatusTip td {
+	padding: 2px 6px;
+	max-width: 150px;
+	overflow: hidden;
+	width: expression(this.clientWidth > 150 ? "150px" : "auto");
+}
+.dojoxGridFStatusTipHead {
+	margin-bottom: 9px;
+}
+.dojoxGridFStatusTipTitle {
+	font-weight: bold;
+	margin-right: 1em;
+}
+.dojoxGridFStatusTipHandle {
+	position: relative;
+	padding-right: 16px;
+}
+.dojoxGridFStatusTipDetail .dijitButton {
+	position: absolute;
+	margin: 0;
+	padding: 0;
+	top: -1px;
+	right:0;
+}
+.dojoxGridFStatusTipDelRuleBtnIcon {
+	background-image: url("images/sprite_icons.png");
+	background-position: -198px -18px;
+	height: 16px;
+	width: 16px;
+}
+.dijitButtonHover .dojoxGridFStatusTipDelRuleBtnIcon {
+	background-position: -198px 2px;
+}
+
+/* clear dlg */
+.dj_ie7 .dojoxGridClearFilterConfirm,
+.dj_ie6 .dojoxGridClearFilterConfirm {
+	width: 300px;
+}
+.dojoxGridClearFilterBtns{
+	padding: 10px;
+	height: 18px;
+}
+.dojoxGridClearFilterBtns .dijitButton {
+	float: right;
+}
+
+/* bool value box */
+.dojoxGridTrueBox {
+	float: left;
+	width: 49%;
+}
+.dojoxGridFalseBox {
+	float: left;
+	width: 49%;
+}
+.dojoxGridBoolValueBox .dijitRadio {
+	vertical-align: middle;
+} 
+.dojoxGridTrueLabel,
+.dojoxGridFalseLabel {
+	width: 116px;
+	display:inline-block;
+	vertical-align: middle;
+}
+.dj_ie7 .dojoxGridTrueLabel,
+.dj_ie7 .dojoxGridFalseLabel {
+	display: inline;
+}
diff --git a/dojox/grid/enhanced/resources/Filter_rtl.css b/dojox/grid/enhanced/resources/Filter_rtl.css
new file mode 100644
index 0000000..54683c4
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Filter_rtl.css
@@ -0,0 +1,80 @@
+/* filter bar */
+.dojoxGridRtl .dojoxGridFBarStatus {
+	margin-left: 0;
+	margin-right: 9px;
+	float: right;
+}
+.dojoxGridRtl .dojoxGridFBarClearFilterBtn {
+	margin-left: 0;
+	margin-right: 10px;
+	float: right;
+}
+.dojoxGridRtl .dojoxGridFBarCloseBtn {
+	margin: 0 0 0 4px;
+	float: left;
+}
+.dj_ie .dojoxGridRtl .dojoxGridFBarCloseBtn {
+	left: 2px;
+	right: auto;
+}
+/* filter def dialog */
+.dijitRtl .dojoxGridFDPaneRelation {
+	margin: 0 4px 3px 0;
+}  
+.dijitRtl .dojoxGridFDPane .dijitAccordionTitleFocus {
+	margin-right: 0;
+	margin-left: 14px;
+}
+.dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton {
+	left: 3px;
+	right: auto;
+}
+.dj_ie6 .dijitRtl .dojoxGridFDPane .dijitAccordionTitle .dijitButton{
+	left: -290px;
+}
+.dijitRtl .dojoxGridFDPaneBtns {
+	left: 0;
+	right: auto;
+}
+.dijitRtl .dojoxGridFDPaneBtns .dijitButton,
+.dijitRtl .dojoxGridClearFilterBtns .dijitButton,
+.dijitRtl .dojoxGridFCBoxEndValue {
+	float: left;
+}
+.dijitRtl .dojoxGridFCBoxRangeValueTxt {
+	margin-left: 0;
+	margin-right: 4px;
+}
+
+/* status tip */
+.dijitRtl .dojoxGridFStatusTipTitle {
+	margin-left: 1em;
+	margin-right: 0;
+}
+.dijitRtl .dojoxGridFStatusTipHandle {
+	padding-left: 16px;
+	padding-right: 0;
+}
+.dijitRtl .dojoxGridFStatusTipDetail .dijitButton {
+	left: 0;
+	right: auto;
+}
+
+/* bool value box */
+.dijitRtl .dojoxGridTrueBox,
+.dijitRtl .dojoxGridFalseBox {
+	float: right;
+}
+
+/* For Claro */
+.claro .dojoxGridRtl .dojoxGridFBar {
+	border-right: 1px solid white;
+}
+
+.claro .dijitRtl .dojoxGridFStatusTip th div {
+	border-left: 1px solid #BCBCBC;
+	border-right: 1px solid white;
+}
+.claro .dijitRtl .dojoxGridFStatusTip th.lastColumn div {
+	border-left: 1px solid #BCBCBC;
+}
diff --git a/dojox/grid/enhanced/resources/Pagination.css b/dojox/grid/enhanced/resources/Pagination.css
new file mode 100644
index 0000000..8eaa176
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Pagination.css
@@ -0,0 +1,138 @@
+.dojoxGridPaginator {
+	border-top:1px #DBDBDB solid;
+	text-align:center;
+	width: 100%;
+	height: 24px;
+	table-layout : fixed;
+	background-color: #EAEAEA;
+}
+.dojoxGridDescriptionTd {
+	text-align: left;
+	width: 35%;
+}
+.dojoxGridDescription {
+	text-align: left;
+	margin-left: 9px;
+	overflow: hidden;
+}
+.dojoxGridPaginatorFastStep {
+	text-align: right;
+	width: 35%;
+	overflow: hidden;
+}
+.dojoxGridPaginatorStep {
+	float: right;
+}
+.dojoxGridPaginatorGotoTd {
+	width: 20px!important;
+}
+.dojoxGridPaginatorGotoDiv {
+	cursor: pointer;
+	width: 12px!important;
+	height: 16px!important;
+	margin: 0 6px 0 2px;
+	background: url("images/sprite_icons.png") no-repeat -77px 4px;
+}
+.dojoxGridPaginatorGotoDivDisabled {
+	background: url("images/sprite_icons.png") no-repeat -77px -16px;
+}
+.dojoxGridWardButton {
+	margin-top: 2px;
+	width: 12px!important;
+	height: 12px!important;
+	float: left;
+	background: url("images/sprite_icons.png") no-repeat;
+}
+.dojoxGridWardButtonInner {
+	visibility: hidden;
+}
+.dijit_a11y .dojoxGridWardButtonInner {
+	visibility: visible;
+	margin-bottom: 8px;
+}
+.dojoxGridfirstPageBtn {
+	cursor: pointer;
+	margin-left: 1px;
+	background-position: -57px 3px;
+}
+.dojoxGridfirstPageBtnDisable {
+	margin-left: 1px;
+	background-position: -57px -17px;
+}
+.dojoxGridprevPageBtn {
+	cursor: pointer;
+	margin: 2px 2px 0 9px;
+	background-position: 3px 3px;
+}
+.dojoxGridprevPageBtnDisable {
+	margin: 2px 2px 0 9px;
+	background-position: 3px -17px;
+}
+.dojoxGridlastPageBtn {
+	cursor: pointer;
+	margin: 2px 9px 0 9px;
+	background-position: -37px 3px;
+}
+.dojoxGridlastPageBtnDisable {
+	margin: 2px 9px 0 9px;
+	background-position: -37px -17px;
+}
+
+.dojoxGridnextPageBtn {
+	cursor: pointer;
+	margin-left: 3px;
+	background-position: -17px 3px;
+}
+.dojoxGridnextPageBtnDisable {
+	margin-left: 3px;
+	background-position: -17px -17px;
+}
+.dojoxGridInactived {
+	font-weight: normal;
+	color: #5D88AF;
+	cursor: pointer;
+	margin: 1px 6px 0 5px;
+	float: left;
+	zoom: 1; /* for IE */
+}
+.dojoxGridActived {
+	font-weight: bold;
+	color: black;
+	margin: 1px 6px 0 5px;
+	float: left;
+	text-decoration: none!important; 
+	zoom: 1; /* for IE */
+}
+.dojoxGridInactiveSwitch {
+	font-weight: normal;
+	color: #5D88AF;
+	float: left;
+	cursor: pointer;
+	margin: 1px 7px 0 7px;
+	zoom: 1; /* for IE */
+}
+.dojoxGridActivedSwitch {
+	font-weight: bold;
+	color: black;
+	float: left;
+	margin: 1px 7px 0 7px;
+	text-decoration: none!important; 
+	zoom: 1; /* for IE */
+}
+.dojoxGridSeparator {
+	float: left;
+}
+.dojoxGridPageTextHover {
+	text-decoration: underline;
+}
+.dojoxGridDialogMargin {
+	width: 220px!important;
+	margin-bottom: 10px;
+}
+.dj_ie6 .dojoxGridDialogMargin {
+	position: relative;
+}
+.dojoxGridDialogButton {
+	width: 220px!important;
+	text-align: right;
+}
diff --git a/dojox/grid/enhanced/resources/Pagination_rtl.css b/dojox/grid/enhanced/resources/Pagination_rtl.css
new file mode 100644
index 0000000..1175570
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Pagination_rtl.css
@@ -0,0 +1,68 @@
+.dojoxGridRtl .dojoxGridDescription {
+	text-align: right;
+	margin-right: 9px;
+}
+.dojoxGridRtl .dojoxGridPaginatorStep {
+	float: left;
+}
+.dojoxGridRtl .dojoxGridPaginatorGotoDiv {
+	margin: 0 2px 0 6px;
+}
+.dojoxGridRtl .dojoxGridWardButton {
+	float: right;
+}
+.dojoxGridRtl .dojoxGridInactived {
+	margin: 1px 5px 0 6px;
+	float: right;
+}
+.dojoxGridRtl .dojoxGridActived {
+	margin: 1px 5px 0 6px;
+	float: right;
+}
+.dijitRtl .dojoxGridDialogButton {
+	float: left;
+	margin-bottom: 10px;
+}
+.dijitRtl .dojoxGridInactiveSwitch {
+	float: right;
+}
+.dijitRtl .dojoxGridActivedSwitch {
+	float: right;
+}
+.dijitRtl .dojoxGridSeparator {
+	float: right;
+}
+.dijitRtl .dojoxGridfirstPageBtn {
+	cursor: pointer;
+	margin: 2px 1px 0 0;
+	background-position: -37px 3px;
+}
+.dijitRtl .dojoxGridfirstPageBtnDisable {
+	margin: 2px 1px 0 0;
+	background-position: -37px -17px;
+}
+.dijitRtl .dojoxGridprevPageBtn {
+	cursor: pointer;
+	margin: 2px 9px 0 5px;
+	background-position: -17px 3px;
+}
+.dijitRtl .dojoxGridprevPageBtnDisable {
+	margin: 2px 9px 0 5px;
+	background-position: -17px -17px;
+}
+.dijitRtl .dojoxGridlastPageBtn {
+	cursor: pointer;
+	background-position: -57px 3px;
+}
+.dijitRtl .dojoxGridlastPageBtnDisable {
+	background-position: -57px -17px;
+}
+.dijitRtl .dojoxGridnextPageBtn {
+	cursor: pointer;
+	margin: 2px 3px 0 0;
+	background-position: 3px 3px;
+}
+.dijitRtl .dojoxGridnextPageBtnDisable {
+	margin: 2px 3px 0 0;
+	background-position: 3px -17px;
+}
diff --git a/dojox/grid/enhanced/resources/Sorter.css b/dojox/grid/enhanced/resources/Sorter.css
new file mode 100644
index 0000000..bfa909c
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Sorter.css
@@ -0,0 +1,178 @@
+/*
+.dojoxGrid
+    Sorted, SingleSorted | NestSorted
+.dojoxGridCell
+    Over, SortFocus, ShowIndex
+.dojoxGridSortNode
+    Asc | Desc, Main|Sub
+.dojoxGridSortBtn
+    :hover, Single|Nested
+*/
+.dojoxGrid .dojoxGridSortNode {
+	position: relative;
+	border: 1px solid transparent;
+}
+.dj_ie6 .dojoxGrid .dojoxGridSortNode,
+.dj_ie7 .dojoxGrid .dojoxGridSortNode {
+	overflow: hidden;
+	width:100%;	
+}
+.dojoxGrid .dojoxGridSortNoWrap {
+	white-space:nowrap;
+	cursor: pointer;
+}
+.dojoxGridSortBtn {
+	width: 10px;
+	height:100%;
+	visibility: hidden;
+	top: 0;
+	display:block;
+	position: absolute;
+	color: #000;
+	background: #DFEAF1 url(images/sprite_icons.png) no-repeat 100px 0;
+	text-decoration: none;
+	outline: none;
+	right: 0;
+	border: 1px solid transparent;
+	box-sizing: border-box; /* css3 rec */
+	-moz-box-sizing: border-box; /* ff */
+	-ms-box-sizing: border-box; /* ie8 */
+	-webkit-box-sizing: border-box; /* safari3 */
+	-khtml-box-sizing: border-box; /* konqueror */
+}
+.dj_ie6 .dojoxGridSortBtn,
+.dj_ie6 .dojoxGrid .dojoxGridSortNode {
+	border: none;
+}
+.dojoxGridSortBtnNested {
+	right: 10px;
+}
+.dojoxGridCellSortFocus  .dojoxGridSortBtn {
+	border-left: 1px solid #999999;
+	background-color: #DFEAF1;
+}
+.dojoxGridCellOver .dojoxGridSortBtn {
+	border-left: 1px solid #999999;
+	background-color: #9dcfff;
+}
+.dojoxGridSortNode {
+	outline: none;
+}
+
+/*Control the title node width*/
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dojoxGridCellSortFocus .dojoxGridSortNode,
+.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+	margin-right: 5px;
+}
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+	margin-right: 24px;
+}
+/*html > body used for !dj_ie6, TBD - a better way*/
+html > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle {
+	right: -5px;
+}
+html > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+	right: -10px;
+}
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+html > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+	right: -28px;
+}
+html > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+html > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	right: -17px;
+}
+
+.dojoxGrid .dojoxGridHeader .dojoxGridRowTable .dojoxGridNoSort .dojoxGridSortNode {
+	margin: 0!important;
+}
+
+.dj_ie7 .dojoxGridSortBtn {
+	right: 0!important;
+}
+.dj_ie7 .dojoxGridSortBtnNested {
+	right: 10px!important;
+}
+
+/*Focus border*/
+/*Control visibility*/
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle,					/* single sort btn is always visible when mouseover*/
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnNested,				/* in a sorted grid, nest btn is always visible when mouseover (except 1)*/
+.dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnNested,
+.dojoxGrid .dojoxGridCellShowIndex .dojoxGridSortNode .dojoxGridSortBtnNested,		/* in a single sort grid, when mouseover other columns, show 1 on the main sort column*/
+.dojoxGrid .dojoxGridSortNodeSorted .dojoxGridSortBtn {										/* in a sorted column, single or nested sort btn are always visible (except 2)*/
+	visibility: visible;
+}
+.dojoxGridSingleSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnNested,	/*(1)in a single sorted grid, nest btn is hidden in sort column when mouseover*/
+.dojoxGridSingleSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnNested,
+.dojoxGridSingleSorted .dojoxGridSortNode .dojoxGridSortBtnNested {							/*(2)all nested btn is hidden in single sort grid without mouse over*/
+	visibility: hidden;
+}
+
+/*
+-119 asc
+-99 desc
+-159 do asc
+-139 do desc
+-179 no sort
+*/
+/*Control background image*/
+.dojoxGridSortNodeAsc .dojoxGridSortBtnSingle {
+	background-position: -119px 5px;
+	visibility: visible;
+}
+.dojoxGridSortNodeDesc .dojoxGridSortBtnSingle {
+	background-position: -99px  5px;
+	visibility: visible;
+}
+/*hover single sort*/
+.dojoxGridCellOver .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+	background-position: -159px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc,
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc {
+	background-position: -139px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, 
+.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, 
+.dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc, 
+.dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc {
+	background-position: -179px 5px;
+}
+/*hover nested sort*/
+.dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	background-position: -149px 5px;
+	width: 19px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+	background-position: -129px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+	background-position: -169px 5px;
+}
+.dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+	background-position: -159px 5px;
+}
+.dojoxGridCellOver .dojoxGridSortBtn:hover {
+	background-color:#A3E4FF;  
+}
+.dojoxGrid .dojoxGridSortNodeFocus,
+.dojoxGridCellSortFocus .dojoxGridRowSelector,
+.dojoxGridCellSortFocus .dojoxGridSortBtnFocus {
+	border: 1px dashed #666;
+}
\ No newline at end of file
diff --git a/dojox/grid/enhanced/resources/Sorter_rtl.css b/dojox/grid/enhanced/resources/Sorter_rtl.css
new file mode 100644
index 0000000..3faaedb
--- /dev/null
+++ b/dojox/grid/enhanced/resources/Sorter_rtl.css
@@ -0,0 +1,78 @@
+.dojoxGridRtl .dojoxGridSortBtnSingle {
+	right: auto;
+	left: 0px;
+}
+.dojoxGridRtl .dojoxGridSortBtnNested {
+	right: auto;
+	left: 10px;
+}
+
+.dojoxGridRtl .dojoxGridCellOver  .dojoxGridSortBtn,
+.dj_ie6 dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtn,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtn {
+	border-left: none;
+	border-right: 1px solid #999999;
+}
+
+/*Control the title node width*/
+.dijitRtl .dojoxGridCellOver .dojoxGridSortNode,
+.dijitRtl .dojoxGridCellSortFocus .dojoxGridSortNode,
+.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.dijitRtl .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+	margin-right: auto;
+	margin-left: 10px;
+}
+.dijitRtl .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.dijitRtl .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+	margin-right: auto;
+	margin-left: 24px;
+}
+/*html > body used for !dj_ie6, TBD - a better way*/
+html.dijitRtl > body .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle {
+	right: auto;
+	left: -10px;
+}
+html.dijitRtl > body .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+	right: auto;
+	left: -10px;
+}
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+html.dijitRtl > body .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+	right: auto;
+	left: -28px;
+}
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+html.dijitRtl > body .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	right: auto;
+	left: -17px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	background-position: -159px 5px;
+	padding-left:8px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+	background-position: -139px 5px;
+}
+
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+	background-position: -179px 5px;
+}
+.dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	padding-left: 8px;
+	padding-right: 0;
+}
+
+.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellOver .dojoxGridSortBtnNested,
+.dj_ie6 .dojoxGridRtl .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	padding-left:0px;
+}
diff --git a/dojox/grid/enhanced/resources/claro/Common.css b/dojox/grid/enhanced/resources/claro/Common.css
new file mode 100644
index 0000000..102f703
--- /dev/null
+++ b/dojox/grid/enhanced/resources/claro/Common.css
@@ -0,0 +1,99 @@
+/* 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 {
+	background-color:#91c9fe;
+}
+.claro td.dojoxGridRowSelected {
+	border-collapse:separate;
+	background:url("../../../resources/images/row_back.png") #CEE6FA repeat-x;
+}
+.claro .dojoxGridRowOver td.dojoxGridRowSelected {
+	border-top:1px solid #769DC0;
+	border-bottom:1px solid #769DC0;
+}
+.claro .dojoxGridRowActive td.dojoxGridRowSelected {
+	background-image:url("../../../resources/images/td_button_down.png");
+}
+.dj_ie6 .claro .dojoxGridRowOver .dojoxGridCell {
+	border-color: #ABD6FF;
+}
+.dj_ie6 .claro .dojoxGridRowActive .dojoxGridCell {
+	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;
+	/*background-color: #EAF1F6;*/
+}
diff --git a/dojox/grid/enhanced/resources/claro/EnhancedGrid.css b/dojox/grid/enhanced/resources/claro/EnhancedGrid.css
new file mode 100644
index 0000000..5c3b1a6
--- /dev/null
+++ b/dojox/grid/enhanced/resources/claro/EnhancedGrid.css
@@ -0,0 +1,4 @@
+ at import url("../../../resources/claroGrid.css");
+ at import url("../EnhancedGrid.css");
+ at import url("Common.css");
+ at import url("Filter.css");
diff --git a/dojox/grid/enhanced/resources/claro/Filter.css b/dojox/grid/enhanced/resources/claro/Filter.css
new file mode 100644
index 0000000..4574142
--- /dev/null
+++ b/dojox/grid/enhanced/resources/claro/Filter.css
@@ -0,0 +1,59 @@
+.claro .dojoxGridFBarInfoTD {
+	background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom;
+	background: -moz-linear-gradient(top, #F2F9FF, #EAF5FF);
+	background: -webkit-gradient(linear, left top, left bottom, from(#F2F9FF), to(#EAF5FF));
+	filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#FFF2F9FF, endColorstr=#FFEAF5FF);
+}
+.claro .dojoxGridFBarHover .dojoxGridFBarInfoTD {
+	background: url("../../../resources/images/header_shadow.png") #F2F9FF repeat-x bottom;
+	background: -moz-linear-gradient(top, #ECF6FF 2px, #F2F9FF, #EAF5FF 6px);
+	background: -webkit-gradient(linear, left top, left bottom, color-stop(0.1, #ECF6FF), color-stop(0.6, #F2F9FF), color-stop(0.8, #EAF5FF));
+}
+.dj_gecko .claro .dojoxGridFBarInfoTD,
+.dj_webkit .claro .dojoxGridFBarInfoTD {
+	border-top: 1px solid #BFD6EB;
+	border-bottom: 1px solid #BFD6EB;
+}
+.dj_ie .claro .dojoxGridFBarInner{
+	border-top: 1px solid #BFD6EB;
+	border-bottom: 1px solid #BFD6EB;
+	display:inline-block;
+	width: 100%;
+}
+.claro .dojoxGridFBarClearFilterBtn {
+	color: #5B83B6;
+}
+.claro .dojoxGridFBarInfoTD .dojoxGridFBarClearFilterBtn.dijitButtonHover .dijitButtonText {
+	text-decoration: underline;
+}
+.claro .dojoxGridFBar {
+	border-left: 1px solid white;
+}
+.claro .dojoxGridFStatusTip table {
+	border: 1px solid #BCBCBC;
+}
+.claro .dojoxGridFStatusTip th {
+	background-color: #E8EFF4;
+	border-bottom: 1px solid #BCBCBC;
+}
+.claro .dojoxGridFStatusTip th div {
+	background-color: #E8EFF4;
+	border-left: 1px solid white;
+	border-right: 1px solid #BCBCBC;
+	border-top: 1px solid white;
+	border-bottom: 1px solid white;
+}
+.claro .dojoxGridFStatusTip th.lastColumn div {
+	border-right: 1px solid white;
+}
+.claro .dojoxGridFStatusTip td {
+	border-top: 1px solid white;
+	border-bottom: 1px solid white;
+}
+.claro .dojoxGridFStatusTipRel,
+.claro .dojoxGridFStatusTipCondition {
+	font-style: italic;
+}
+.claro .dojoxGridFStatusTipOddRow {
+	background-color: #F1F8FF;
+}
diff --git a/dojox/grid/enhanced/resources/claroEnhancedGrid.css b/dojox/grid/enhanced/resources/claroEnhancedGrid.css
deleted file mode 100644
index 50390d5..0000000
--- a/dojox/grid/enhanced/resources/claroEnhancedGrid.css
+++ /dev/null
@@ -1,104 +0,0 @@
- at import url("EnhancedGrid.css");
- at import url("../../resources/claroGrid.css");
-
-/* overwrite claroGrid.css */
-.claro .dojoxGridRowbarInner {
-	width:20px;
-}
-/* end overwrite */
-
-/* header cell root container */
-.claro .dojoxGridSortHover {
-	border-color:#a5beda; 
-	border-bottom-color:#5c7590; 
-	color:#243C5F;
-	cursor:pointer;
-	background-color:#abd5fd;
-}
-.claro .dojoxGridSortRoot {
-	background:url("../../resources/images/header_shadow.png") repeat-x bottom;
-	color:#000;
-	text-decoration:none;
-	border:1px solid #e0eefb;
-	height:100%;
-	display:block;
-	margin-left:-1px;
-}
-.dj_ie .claro .dojoxGridSortRoot {
-	border-right:1px solid #bcbcbc;
-}
-
-/* header cell sorting wrapper & selection region (for selecting column) */
-.claro .dojoxGridHeaderCellSelectRegion {
-	padding:4px 0px 5px 6px;
-}
-.claro .dojoxGridSelectRegionHover {
-	cursor:pointer;
-	color:#243C5F;
-	text-decoration:none;
-}
-.claro .dojoxGridSelectRegionHover,
-.claro .dojoxGridCellOver .dojoxGridSortWrapper,
-.claro .dojoxGridHeaderSelected .dojoxGridHeaderCellSelectRegion {
-	background:url("../../resources/images/header.png") #abd5fd repeat-x bottom;
-}
-.claro .dojoxGridCellOver .dojoxGridSortWrapper {
-	background-color:transparent;
-}
-.claro .dojoxGridHeaderSelected .dojoxGridHeaderActive {
-	background-color:#91c9fe;
-}
-
-/* column selection */
-.claro td.dojoxGridRowSelected {
-	border-collapse:separate;
-	border:1px solid #BFD6EB;
-	border-bottom:1px solid transparent;
-	background:url("../../resources/images/row_back.png") #e3f2ff repeat-x;
-	/*border:solid 1px #A0BFDD;*/
-}
-.dj_ie6 .claro td.dojoxGridRowSelected,
-.dj_ie6 .claro .dojoxGridRowOdd td.dojoxGridRowSelected {
-	border-color:#BFD6EB;
-}
-.claro .dojoxGridRowOver td.dojoxGridRowSelected {
-	border-top:1px solid #769DC0;
-	border-bottom:1px solid #769DC0;
-}
-.claro .dojoxGridRowActive td.dojoxGridRowSelected {
-	background-image:url("../../resources/images/td_button_down.png");
-}
-
-/* focus border */
-.claro .dojoxGridFocusBorder {
-	border-top: 1px dashed darkblue;
-	border-left: 1px dashed darkblue;
-}
-
-/** dnd **/
-.claro .dojoxGridSelectedDIV {
-	background-color: #3366CC;
-}
-.dj_ie .claro .dojoxGridSelectedDIV {
-	filter: alpha(opacity = 30);
-}
-.claro .dojoxGridBorderDIV {
-	background-color:#769DC0;
-}
-
-.dj_ie6 .claro .dojoxGridSortRoot,
-.dj_ie6 .claro .dojoxGridSelectRegionHover,
-.dj_ie6 .claro .dojoxGridCellOver .dojoxGridSortWrapper,
-.dj_ie6 .claro .dojoxGridHeaderSelected .dojoxGridHeaderCellSelectRegion {
-	background-image:none;
-}
-
-/* Don't need any explicit outlines */
-.claro .dojoxGridCell,
-.claro .dojoxGridCellFocus,
-.claro .dojoxGridHeaderCellSelectRegion,
-.claro .dojoxGridUnarySortWrapper,
-.claro .dojoxGridNestedSortWrapper,
-.claro .dojoxGridSortRoot {
-	outline: none;
-}
diff --git a/dojox/grid/enhanced/resources/images/nestedSortArrows.png b/dojox/grid/enhanced/resources/images/nestedSortArrows.png
deleted file mode 100644
index 96fa7e4..0000000
Binary files a/dojox/grid/enhanced/resources/images/nestedSortArrows.png and /dev/null differ
diff --git a/dojox/grid/enhanced/resources/images/sprite_icons.png b/dojox/grid/enhanced/resources/images/sprite_icons.png
new file mode 100644
index 0000000..565e63f
Binary files /dev/null and b/dojox/grid/enhanced/resources/images/sprite_icons.png differ
diff --git a/dojox/grid/enhanced/resources/tundra/Common.css b/dojox/grid/enhanced/resources/tundra/Common.css
new file mode 100644
index 0000000..81287aa
--- /dev/null
+++ b/dojox/grid/enhanced/resources/tundra/Common.css
@@ -0,0 +1,40 @@
+/* overwrite */
+.tundra .dojoxGridHeader .dojoxGridCell{
+	background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+	border-top: 1px solid #bfbfbf;
+	/*border-left-width: 0px;*/
+}
+.tundra .dojoxGridCell {
+	padding:0px;
+	/*display:inline;*/
+	/*position:relative;*/
+	/*border-left-width: 0px;*/
+}
+.dj_ie6 .tundra .dojoxGridMasterView .dojoxGridCellOver{
+	border: 1px dashed #e9e9e9;
+}
+.dj_ie6 .tundra .dojoxGridHeader .dojoxGridCellOver{
+	border-bottom: none !important;
+	border-right: 1px solid #D5CDB5 !important;
+	border-top: 1px solid #D5CDB5 !important;
+}
+.tundra .dojoxGridRowbarInner {
+	width:20px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode {
+	cursor:pointer;
+	background: #f8fafd url("../../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x;
+}
+/* end overwrite */
+
+/* fix safari focus border - overwrite */
+.dj_webkit .tundra .dojoxGridCell,
+.dj_webkit .tundra .dojoxGridCellFocus {
+	outline: none;
+}
+
+/*Pagination*/
+.tundra .dojoxGridPaginator {
+	background: url("../../../../../dijit/themes/tundra/images/titleBar.png") repeat-x top left;
+}
diff --git a/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css b/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css
new file mode 100644
index 0000000..f8159c8
--- /dev/null
+++ b/dojox/grid/enhanced/resources/tundra/EnhancedGrid.css
@@ -0,0 +1,5 @@
+ at import url("../../../resources/tundraGrid.css");
+ at import url("../EnhancedGrid.css");
+ at import url("Common.css");
+ at import url("Filter.css");
+ at import url("Sorter.css");
diff --git a/dojox/grid/enhanced/resources/tundra/Filter.css b/dojox/grid/enhanced/resources/tundra/Filter.css
new file mode 100644
index 0000000..b7b7b83
--- /dev/null
+++ b/dojox/grid/enhanced/resources/tundra/Filter.css
@@ -0,0 +1,38 @@
+.tundra .dojoxGridFBar {
+	background-color: #eeeeee;
+	border: 1px solid #bfbfbf;
+}
+.tundra .dojoxGridFBarFiltered {
+	background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+}
+.tundra .dojoxGridFBarHover {
+	background-color: #cccccc;
+	background-image: none;
+}
+.tundra .dojoxGridFStatusTip table {
+	border: 1px solid #eeeeee;
+}
+.tundra .dojoxGridFStatusTip th {
+	background: #fafafa url(../../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
+	border-bottom: 1px solid #eeeeee;
+}
+.tundra .dojoxGridFStatusTip th div {
+	border-left: 1px solid white;
+	border-right: 1px solid #eeeeee;
+	border-top: 1px solid white;
+	border-bottom: 1px solid white;
+}
+.tundra .dojoxGridFStatusTip th.lastColumn div {
+	border-right: 1px solid white;
+}
+.tundra .dojoxGridFStatusTip td {
+	border-top: 1px solid white;
+	border-bottom: 1px solid white;
+}
+.tundra .dojoxGridFStatusTipRel,
+.tundra .dojoxGridFStatusTipCondition {
+	font-style: italic;
+}
+.tundra .dojoxGridFStatusTipOddRow {
+	background-color: #f2f5f9;
+}
diff --git a/dojox/grid/enhanced/resources/tundra/Sorter.css b/dojox/grid/enhanced/resources/tundra/Sorter.css
new file mode 100644
index 0000000..480dd7e
--- /dev/null
+++ b/dojox/grid/enhanced/resources/tundra/Sorter.css
@@ -0,0 +1,83 @@
+.tundra .dojoxGridSortBtn {
+	padding-top: 3px;
+}
+.tundra .dojoxGridSortBtnNested {
+	right: 11px;
+}
+.tundra .dojoxGridCellOver  .dojoxGridSortBtn,
+.tundra .dojoxGridCellSortFocus  .dojoxGridSortBtn {
+	background-color: #ccc;
+}
+
+/*Control the title node width*/
+.tundra .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode,
+.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellOver .dojoxGridSortNodeMain,
+.tundra .dojoxGridSingleSorted .dojoxGridHeader .dojoxGridCellSortFocus .dojoxGridSortNodeMain {
+	margin-right: 12px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNode,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNode {
+	margin-right: 31px;
+}
+
+/*ie 6 doesn't need below*/
+.tundra .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle  {
+	right: -12px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortNodeMain .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortNodeMain .dojoxGridSortBtnSingle {
+	right: -31px;
+}
+.tundra .dojoxGridSorted .dojoxGridCellOver .dojoxGridSortBtnNested,
+.tundra .dojoxGridSorted .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	right: -20px;
+}
+/*ie6 hack end*/
+
+/*Control background image*/
+.tundra .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle {
+	background-position: -119px 8px;
+}
+.tundra .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle {
+	background-position: -99px  8px;
+}
+/*hover single sort*/
+.tundra .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+	background-position: -159px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnSingle,
+.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnAsc,
+.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnAsc {
+	background-position: -139px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, 
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnSingle, 
+.tundra .dojoxGrid .dojoxGridCellOver .dojoxGridSortNode .dojoxGridSortBtnDesc,
+.tundra .dojoxGrid .dojoxGridCellSortFocus .dojoxGridSortNode .dojoxGridSortBtnDesc {
+	background-position: -179px 8px;
+}
+/*hover nested sort*/
+.tundra .dojoxGridCellOver .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortBtnNested {
+	background-position: -150px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeAsc .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeAsc .dojoxGridSortBtnNested {
+	background-position: -130px 8px;
+}
+.tundra .dojoxGridCellOver .dojoxGridSortNodeDesc .dojoxGridSortBtnNested,
+.tundra .dojoxGridCellSortFocus .dojoxGridSortNodeDesc .dojoxGridSortBtnNested {
+	background-position: -170px 8px;
+}
+.tundra .dojoxGridNestSorted .dojoxGridCellOver .dojoxGridSortBtnSingle,
+.tundra .dojoxGridNestSorted .dojoxGridCellSortFocus .dojoxGridSortBtnSingle {
+	background-position: -159px 8px;
+}
\ No newline at end of file
diff --git a/dojox/grid/enhanced/resources/tundraEnhancedGrid.css b/dojox/grid/enhanced/resources/tundraEnhancedGrid.css
deleted file mode 100644
index 09a94fc..0000000
--- a/dojox/grid/enhanced/resources/tundraEnhancedGrid.css
+++ /dev/null
@@ -1,86 +0,0 @@
- at import url("EnhancedGrid.css");
- at import url("../../resources/tundraGrid.css");
-
-/* overwrite */
-.tundra .dojoxGridHeader .dojoxGridCell{
-	background: #fafafa url(../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
-	border-top: 1px solid #bfbfbf;
-	/*border-left-width: 0px;*/
-}
-
-.tundra .dojoxGridCell {
-	padding:0px;
-	/*display:inline;*/
-	/*position:relative;*/
-	/*border-left-width: 0px;*/
-}
-
-.dj_ie6 .tundra .dojoxGridMasterView .dojoxGridCellOver{
-	border: 1px dashed #e9e9e9;
-}
-
-.dj_ie6 .tundra .dojoxGridHeader .dojoxGridCellOver{
-	border-bottom: none !important;
-	border-right: 1px solid #D5CDB5 !important;
-	border-top: 1px solid #D5CDB5 !important;
-}
-
-.tundra .dojoxGridRowbarInner {
-	width:20px;
-}
-
-.tundra .dojoxGridCellOver .dojoxGridSortNode{
-	cursor:pointer;
-	background: #f8fafd url("../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x;
-}
-/* end overwrite */
-
-.tundra .dojoxGridSelectRegionHover{
-	border-color:		#a5beda; 
-	border-bottom-color:#5c7590; 
-	cursor:pointer;
-	color:#243C5F;
-	background: #f8fafd url("../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x;
-}
-
-.tundra .dojoxGridSortHover{
-	border-color:		#a5beda; 
-	border-bottom-color:#5c7590; 
-	color:#243C5F;
-	background: #f8fafd url("../../../../dijit/themes/tundra/images/accordionItemHover.gif") bottom repeat-x;
-	cursor:pointer;
-}
-
-.tundra .dojoxGridSortWrapper{
-	background: #fafafa url(../../../../dijit/themes/tundra/images/titleBar.png) repeat-x bottom left;
-}
-
-
-/* fix safari focus border - overwrite */
-.dj_webkit .tundra .dojoxGridCell,
-.dj_webkit .tundra .dojoxGridCellFocus,
-.dj_webkit .tundra .dojoxGridHeaderCellSelectRegion,
-.dj_webkit .tundra .dojoxGridUnarySortWrapper,
-.dj_webkit .tundra .dojoxGridNestedSortWrapper,
-.dj_webkit .tundra .dojoxGridSortRoot{
-	outline: none;
-}
-
-/* focus border */
-.tundra .dojoxGridFocusBorder {
-	border-top: 1px dashed darkblue;
-	border-left: 1px dashed darkblue;
-}
-
-/** dnd **/
-.tundra .dojoxGridSelectedDIV{
-	background-color: #3366CC;
-}
-
-.dj_ie .tundra .dojoxGridSelectedDIV{
-	filter: alpha(opacity = 30);
-}
-
-.tundra .dojoxGridBorderDIV{
-	background-color: gray;
-}
diff --git a/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html b/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html
new file mode 100644
index 0000000..1637b2e
--- /dev/null
+++ b/dojox/grid/enhanced/templates/ClearFilterConfirmPane.html
@@ -0,0 +1,9 @@
+<div class="dojoxGridClearFilterConfirm">
+	<div class="dojoxGridClearFilterMsg">
+		${_clearFilterMsg}
+	</div>
+	<div class="dojoxGridClearFilterBtns" dojoAttachPoint="btnsNode">
+		<span dojoType="dijit.form.Button" label="${_cancelBtnLabel}" dojoAttachPoint="cancelBtn" dojoAttachEvent="onClick:_onCancel"></span>
+		<span dojoType="dijit.form.Button" label="${_clearBtnLabel}" dojoAttachPoint="clearBtn" dojoAttachEvent="onClick:_onClear"></span>
+	</div>
+</div>
diff --git a/dojox/grid/enhanced/templates/CriteriaBox.html b/dojox/grid/enhanced/templates/CriteriaBox.html
new file mode 100644
index 0000000..ad9a1ec
--- /dev/null
+++ b/dojox/grid/enhanced/templates/CriteriaBox.html
@@ -0,0 +1,20 @@
+<div class="dojoxGridFCBox">
+	<div class="dojoxGridFCBoxSelCol" dojoAttachPoint="selColNode">
+		<span class="dojoxGridFCBoxField">${_colSelectLabel}</span>
+		<select dojoAttachPoint="_colSelect" dojoType="dijit.form.Select" 
+			class="dojoxGridFCBoxColSelect"
+			dojoAttachEvent="onChange:_onChangeColumn">
+		</select>
+	</div>
+	<div class="dojoxGridFCBoxCondition" dojoAttachPoint="condNode">
+		<span class="dojoxGridFCBoxField">${_condSelectLabel}</span>
+		<select dojoAttachPoint="_condSelect" dojoType="dijit.form.Select" 
+			class="dojoxGridFCBoxCondSelect"
+			dojoAttachEvent="onChange:_onChangeCondition">
+		</select>
+		<div class="dojoxGridFCBoxCondSelectAlt" dojoAttachPoint="_condSelectAlt" style="display:none;"></div>
+	</div>
+	<div class="dojoxGridFCBoxValue" dojoAttachPoint="valueNode">
+		<span class="dojoxGridFCBoxField">${_valueBoxLabel}</span>
+	</div>
+</div>
diff --git a/dojox/grid/enhanced/templates/FilterBar.html b/dojox/grid/enhanced/templates/FilterBar.html
new file mode 100644
index 0000000..cbcb68d
--- /dev/null
+++ b/dojox/grid/enhanced/templates/FilterBar.html
@@ -0,0 +1,15 @@
+<table class="dojoxGridFBar" border="0" cellspacing="0" dojoAttachEvent="onclick:_onClickFilterBar, onmouseenter:_onMouseEnter, onmouseleave:_onMouseLeave, onmousemove:_onMouseMove"
+	><tr><td class="dojoxGridFBarBtnTD"
+		><span dojoType="dijit.form.Button" class="dojoxGridFBarBtn" dojoAttachPoint="defineFilterButton" label="..." iconClass="dojoxGridFBarDefFilterBtnIcon" showLabel="true" dojoAttachEvent="onClick:_showFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+	></td><td class="dojoxGridFBarInfoTD"
+		><span class="dojoxGridFBarInner"
+			><span class="dojoxGridFBarStatus" dojoAttachPoint="statusBarNode">${_noFilterMsg}</span
+			><span dojoType="dijit.form.Button" class="dojoxGridFBarClearFilterBtn" dojoAttachPoint="clearFilterButton" 
+				label="${_filterBarClearBtnLabel}" iconClass="dojoxGridFBarClearFilterBtnIcon" showLabel="true" 
+				dojoAttachEvent="onClick:_clearFilterDefDialog, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+			><span dojotype="dijit.form.Button" class="dojoxGridFBarCloseBtn" dojoAttachPoint="closeFilterBarButton" 
+				label="${_closeFilterBarBtnLabel}" iconClass="dojoxGridFBarCloseBtnIcon" showLabel="false" 
+				dojoAttachEvent="onClick:_closeFilterBar, onMouseEnter:_onEnterButton, onMouseLeave:_onLeaveButton, onMouseMove:_onMoveButton"></span
+		></span
+	></td></tr
+></table>
diff --git a/dojox/grid/enhanced/templates/FilterBoolValueBox.html b/dojox/grid/enhanced/templates/FilterBoolValueBox.html
new file mode 100644
index 0000000..6779e70
--- /dev/null
+++ b/dojox/grid/enhanced/templates/FilterBoolValueBox.html
@@ -0,0 +1,11 @@
+<div class="dojoxGridBoolValueBox">
+	<div class="dojoxGridTrueBox">
+		<input dojoType="dijit.form.RadioButton" type='radio' name='a1' id='${_baseId}_rbTrue' checked="true" 
+			dojoAttachPoint="rbTrue" dojoAttachEvent="onChange: onChange"/>
+		<div class="dojoxGridTrueLabel" for='${_baseId}_rbTrue'>${_lblTrue}</div>
+	</div>
+	<div class="dojoxGridFalseBox">
+		<input dojoType="dijit.form.RadioButton" dojoAttachPoint="rbFalse" type='radio' name='a1' id='${_baseId}_rbFalse'/>
+		<div class="dojoxGridTrueLabel" for='${_baseId}_rbFalse'>${_lblFalse}</div>
+	</div>
+</div>
diff --git a/dojox/grid/enhanced/templates/FilterDefPane.html b/dojox/grid/enhanced/templates/FilterDefPane.html
new file mode 100644
index 0000000..5783f36
--- /dev/null
+++ b/dojox/grid/enhanced/templates/FilterDefPane.html
@@ -0,0 +1,27 @@
+<div class="dojoxGridFDPane">
+	<div class="dojoxGridFDPaneRelation">${_relMsgFront}
+	<span class="dojoxGridFDPaneModes" dojoAttachPoint="criteriaModeNode">
+		<select dojoAttachPoint="_relSelect" dojoType="dijit.form.Select" dojoAttachEvent="onChange: _onRelSelectChange">
+			<option value="0">${_relAll}</option>
+			<option value="1">${_relAny}</option>
+		</select>
+	</span>
+	${_relMsgTail}
+	</div>
+	<div dojoAttachPoint="criteriaPane" class="dojoxGridFDPaneRulePane"></div>
+	<div dojoAttachPoint="_addCBoxBtn" dojoType="dijit.form.Button" 
+		class="dojoxGridFDPaneAddCBoxBtn" iconClass="dojoxGridFDPaneAddCBoxBtnIcon"
+		dojoAttachEvent="onClick:_onAddCBox" label="${_addRuleBtnLabel}" showLabel="false">
+	</div>
+	<div class="dojoxGridFDPaneBtns" dojoAttachPoint="buttonsPane">
+		<span dojoAttachPoint="_cancelBtn" dojoType="dijit.form.Button" 
+			dojoAttachEvent="onClick:_onCancel" label="${_cancelBtnLabel}">
+		</span>
+		<span dojoAttachPoint="_clearFilterBtn" dojoType="dijit.form.Button" 
+			dojoAttachEvent="onClick:_onClearFilter" label="${_clearBtnLabel}" disabled="true">
+		</span>
+		<span dojoAttachPoint="_filterBtn" dojoType="dijit.form.Button" 
+			dojoAttachEvent="onClick:_onFilter" label="${_filterBtnLabel}" disabled="true">
+		</span>
+	</div>
+</div>
diff --git a/dojox/grid/enhanced/templates/FilterStatusPane.html b/dojox/grid/enhanced/templates/FilterStatusPane.html
new file mode 100644
index 0000000..f832b9b
--- /dev/null
+++ b/dojox/grid/enhanced/templates/FilterStatusPane.html
@@ -0,0 +1,9 @@
+<div class="dojoxGridFStatusTip">
+	<div class="dojoxGridFStatusTipHead">
+		<span class="dojoxGridFStatusTipTitle" dojoAttachPoint="statusTitle"></span
+		><span class="dojoxGridFStatusTipRelPre" dojoAttachPoint="statusRelPre"></span
+		><span class="dojoxGridFStatusTipRel" dojoAttachPoint="statusRel"></span
+		><span class="dojoxGridFStatusTipRelPost" dojoAttachPoint="statusRelPost"></span>
+	</div>
+	<div class="dojoxGridFStatusTipDetail" dojoAttachPoint="statusDetailNode"></div>
+</div>
diff --git a/dojox/grid/enhanced/templates/Pagination.html b/dojox/grid/enhanced/templates/Pagination.html
new file mode 100644
index 0000000..e26a8e5
--- /dev/null
+++ b/dojox/grid/enhanced/templates/Pagination.html
@@ -0,0 +1,13 @@
+<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>
diff --git a/dojox/grid/resources/Grid.css b/dojox/grid/resources/Grid.css
index 05ff524..037d906 100644
--- a/dojox/grid/resources/Grid.css
+++ b/dojox/grid/resources/Grid.css
@@ -88,10 +88,6 @@
 	padding-bottom: 0;
 	border-bottom-width: 3px;
 }
-
-.dojoxGridSortNode{
-	white-space:nowrap;
-}
 .dojoxGridArrowButtonNode {
 	display: none;
 	padding-left: 16px;
@@ -99,9 +95,6 @@
 .dojoxGridArrowButtonChar {
 	display:inline;
 }
-.dojoxGridColCaption {
-	overflow:hidden;
-}
 
 /* Need to explicitly define how to treat hovering over the arrow on IE */ 
 .dojoxGridArrowButtonNode:hover {
@@ -407,7 +400,7 @@
 
 /* Tree Grid */
 .dojoxGridExpandoCell {
-	vertical-align: top;
+	vertical-align: middle;
 }
 .dojoxGridSummarySpan {
 	visibility: hidden;
diff --git a/dojox/grid/resources/View.html b/dojox/grid/resources/View.html
index 4c32705..578b705 100644
--- a/dojox/grid/resources/View.html
+++ b/dojox/grid/resources/View.html
@@ -1,12 +1,12 @@
-<div class="dojoxGridView" wairole="presentation">
-	<div class="dojoxGridHeader" dojoAttachPoint="headerNode" wairole="presentation">
-		<div dojoAttachPoint="headerNodeContainer" style="width:9000em" wairole="presentation">
-			<div dojoAttachPoint="headerContentNode" wairole="row"></div>
+<div class="dojoxGridView" role="presentation">
+	<div class="dojoxGridHeader" dojoAttachPoint="headerNode" role="presentation">
+		<div dojoAttachPoint="headerNodeContainer" style="width:9000em" role="presentation">
+			<div dojoAttachPoint="headerContentNode" role="row"></div>
 		</div>
 	</div>
-	<input type="checkbox" class="dojoxGridHiddenFocus" dojoAttachPoint="hiddenFocusNode" wairole="presentation" />
-	<input type="checkbox" class="dojoxGridHiddenFocus" wairole="presentation" />
-	<div class="dojoxGridScrollbox" dojoAttachPoint="scrollboxNode" wairole="presentation">
-		<div class="dojoxGridContent" dojoAttachPoint="contentNode" hidefocus="hidefocus" wairole="presentation"></div>
+	<input type="checkbox" class="dojoxGridHiddenFocus" dojoAttachPoint="hiddenFocusNode" role="presentation" />
+	<input type="checkbox" class="dojoxGridHiddenFocus" role="presentation" />
+	<div class="dojoxGridScrollbox" dojoAttachPoint="scrollboxNode" role="presentation">
+		<div class="dojoxGridContent" dojoAttachPoint="contentNode" hidefocus="hidefocus" role="presentation"></div>
 	</div>
 </div>
diff --git a/dojox/grid/resources/_Grid.html b/dojox/grid/resources/_Grid.html
index 3e0cf33..2db90e1 100644
--- a/dojox/grid/resources/_Grid.html
+++ b/dojox/grid/resources/_Grid.html
@@ -1,6 +1,6 @@
-<div hidefocus="hidefocus" wairole="grid" dojoAttachEvent="onmouseout:_mouseOut">
-	<div class="dojoxGridMasterHeader" dojoAttachPoint="viewsHeaderNode" wairole="presentation"></div>
-	<div class="dojoxGridMasterView" dojoAttachPoint="viewsNode" wairole="presentation"></div>
+<div hidefocus="hidefocus" role="grid" dojoAttachEvent="onmouseout:_mouseOut">
+	<div class="dojoxGridMasterHeader" dojoAttachPoint="viewsHeaderNode" role="presentation"></div>
+	<div class="dojoxGridMasterView" dojoAttachPoint="viewsNode" role="presentation"></div>
 	<div class="dojoxGridMasterMessages" style="display: none;" dojoAttachPoint="messagesNode"></div>
 	<span dojoAttachPoint="lastFocusNode" tabindex="0"></span>
 </div>
diff --git a/dojox/grid/resources/claroGrid.css b/dojox/grid/resources/claroGrid.css
index f1100b5..867a765 100644
--- a/dojox/grid/resources/claroGrid.css
+++ b/dojox/grid/resources/claroGrid.css
@@ -122,10 +122,10 @@
 	background:url("images/row_back.png") #fff repeat-x;
 }
 .claro .dojoxGridRowOdd .dojoxGridRowTable tr {
-	background-color:#f4f9fd;
+	background-color:#f7fcff;
 }
 .claro .dojoxGridRowSelected .dojoxGridRowTable tr {
-	background-color:#d3e9fb;
+	background-color:#cee6fa;
 }
 
 /* cells */
@@ -157,7 +157,7 @@
 
 /*  Single Affordance Hover Effect */
 .claro .dojoxGridRowOver .dojoxGridCell {
-	background:url("images/row_back.png") #ABD6FF;
+	background:url("images/row_back.png") #ABD6FF repeat-x;
 	border-top:1px solid #769DC0;
 	border-bottom:1px solid #769DC0;
 }
@@ -194,7 +194,7 @@
 /* editing */
 .claro .dojoxGridRowEditing td {
 	/* background-color: #F4FFF4; */
-	background-color: #60a1ea; 
+	background-color: #cee6fa; 
 	/* padding: 0px 3px 0px 3px; */
 }
 .claro .dojoxGridRow-inserting td {
@@ -213,4 +213,71 @@
 }
 .claro .dojoxGrid .dojoDndItemAfter {
 	border-right-color: #3559ac;
-}
\ No newline at end of file
+}
+
+/* Tree Grid */
+.claro .dojoxGridExpando {
+	float: left;
+	height: 18px;
+	width: 18px;
+	text-align: center;
+	margin-top: -3px;
+}
+.dijitRtl .claro .dojoxGridExpando {
+	float: right;
+}
+.claro .dojoxGridExpandoCell {
+	padding-top: 5px;
+	background-position: left top !important;
+}
+.claro .dojoxGridExpandoNode {
+	background-image: url('../../../dijit/themes/claro/images/treeExpandImages.png');
+    width: 16px;
+    height: 16px;
+	background-position: 1px 0px; /* for closed state */
+}
+.dj_ie6 .claro .dojoxGridExpandoNode {
+	background-image: url('../../../dijit/themes/claro/images/treeExpandImages8bit.png');
+}
+.claro .dojoxGridRowOver .dojoxGridExpandoNode {
+	background-position: -17px 0px;
+}
+.claro .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+	background-position: -35px 0px;
+}
+.claro .dojoxGridRowOver .dojoxGridExpandoOpened .dojoxGridExpandoNode {
+	background-position: -53px 0px;
+}
+.claro .dojoxGridExpandoLoading .dojoxGridExpandoNode {
+	background-image: url('../../../dijit/themes/claro/images/loadingAnimation.gif');
+}
+.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpando {
+	visibility: visible !important;
+	width: 18px !important;
+}
+.claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode,
+.dj_ie6 .claro .dojoxGridTreeModel .dojoxGridNoChildren .dojoxGridExpandoNode {
+	background-image:none;
+}
+.claro .dojoxGridExpandoNodeInner {
+	visibility: hidden;
+}
+.dijit_a11y .dojoxGridExpandoNodeInner {
+	visibility: visible;
+}
+
+.claro .dojoxGridSummaryRow .dojoxGridCell {
+	border:1px solid transparent;
+}
+.dj_ie6 .claro .dojoxGridSummaryRow .dojoxGridCell {
+	border-color:#fff
+}
+.claro tr.dojoxGridSubRowAlt {
+	background-color:#f4f9fd;
+}
+.claro .dojoxGridRowOdd tr.dojoxGridSubRowAlt {
+	background-color:#fff;
+}
+.claro .dojoxGridRow .dojoxGridRowTable tr.dojoxGridRowSelected {
+	background-color:#cee6fa;
+}
diff --git a/dojox/grid/resources/soriaGrid.css b/dojox/grid/resources/soriaGrid.css
index 3a169b2..330ddf3 100644
--- a/dojox/grid/resources/soriaGrid.css
+++ b/dojox/grid/resources/soriaGrid.css
@@ -105,6 +105,14 @@
 	color:#fff;
 }
 
+.soria .dojoxGridRowOver .dojoxGridCell .dijit {
+	color: #000;
+}
+
+.soria .dojoxGridRowOver .dojoxGridCell .dijitDisabled {
+	color: gray;
+}
+
 .soria .dojoxGridRowOdd {
 	background-color: #f2f5f9;
 }
diff --git a/dojox/grid/tests/databaseModel.js b/dojox/grid/tests/databaseModel.js
index 01b7a4e..5e29e9c 100644
--- a/dojox/grid/tests/databaseModel.js
+++ b/dojox/grid/tests/databaseModel.js
@@ -1,10 +1,10 @@
 dojo.provide("dojox.grid.tests.databaseModel");
 dojo.require("dojox.grid._data.model");
 
-// Provides a sparse array that is also traversable inorder 
+// 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 
+//   - 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, {
@@ -20,10 +20,10 @@ dojo.declare("dojox.grid.Sparse", null, {
 	},
 	set: function(inIndex, inValue) {
 		for (var i=0,l=this.indices.length; i<l; i++) {
-			if (this.indices[i] >= inIndex) 
+			if (this.indices[i] >= inIndex)
 				break;
 		}
-		if (this.indices[i] != inIndex) 
+		if (this.indices[i] != inIndex)
 			this.indices.splice(i, 0, inIndex);
 		this.values[inIndex] = inValue;
 	},
@@ -31,7 +31,7 @@ dojo.declare("dojox.grid.Sparse", null, {
 		return this.values[inIndex];
 	},
 	remove: function(inIndex) {
-		for (var i=0,l=this.indices.length; i<l; i++) 
+		for (var i=0,l=this.indices.length; i<l; i++)
 			if (this.indices[i] == inIndex) {
 				this.indices.splice(i, 1);
 				break;
@@ -135,7 +135,7 @@ dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
 		return d;
 	},
 	_callback: function(cb, eb, data) {
-		try{ cb && cb(data); } 
+		try{ cb && cb(data); }
 		catch(e){ eb && eb(data, e); }
 	},
 	receive: function(inCallbacks, inData) {
@@ -170,21 +170,21 @@ dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
 	},
 	// NOTE: supported only in tables with pk
 	commitDelete: function(inRows, inCallbacks) {
-		var params = { 
+		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), 
+			callback: dojo.hitch(this, this.callbacks.update, inRowIndex),
 			errback: dojo.hitch(this, this.callbacks.updateError, inRowIndex)
 		};
 	},
@@ -193,7 +193,7 @@ dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
 		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;		
+		return -1;
 	},
 	// model implementations
 	update: function(inOldData, inNewData, inRowIndex) {
@@ -231,7 +231,7 @@ dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
 			this.removeInsert(inRowIndex);
 		} else
 			this.finishUpdate(inRowIndex);
-	},	
+	},
 	finishUpdate: function(inRowIndex, inData) {
 		this.clearState(inRowIndex);
 		var d = (inData&&inData[0]) || this.cache[inRowIndex];
@@ -246,20 +246,20 @@ dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
 		this.clearState(inRowIndex);
 		dojox.grid._data.Dynamic.prototype.remove.call(this, [inRowIndex]);
 	},
-	// request data 
+	// request data
 	requestRows: function(inRowIndex, inCount)	{
-		var params = { 
+		var params = {
 			command: 'select',
-			orderby: this.sortField, 
+			orderby: this.sortField,
 			desc: (this.sortDesc ? "true" : ''),
-			offset: inRowIndex, 
+			offset: inRowIndex,
 			limit: inCount
 		}
 		this.send(true, params, {callback: dojo.hitch(this, this.callbacks.rows, inRowIndex)});
 	},
 	// sorting
-	canSort: function () { 
-		return true; 
+	canSort: function () {
+		return true;
 	},
 	setSort: function(inSortIndex) {
 		this.sortField = this.fields.get(Math.abs(inSortIndex) - 1).name || inSortIndex;
@@ -281,7 +281,7 @@ dojo.declare("dojox.grid._data.DbTable", dojox.grid._data.Dynamic, {
 			if(!dojox.grid.util.arrayCompare(cache, data)){
 				m = true;
 				this.update(cache, data, inRowIndex);
-			}	
+			}
 		}
 		if (!m)
 			this.cancelModifyRow(inRowIndex);
diff --git a/dojox/grid/tests/enhanced/support/common.css b/dojox/grid/tests/enhanced/support/common.css
new file mode 100644
index 0000000..5e4a5d4
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/common.css
@@ -0,0 +1,8 @@
+ at import "../../../../../dojo/resources/dojo.css";
+ at import "../../../../../dijit/tests/css/dijitTests.css";
+ at import "../../../../../dijit/themes/claro/claro.css";		
+ at import "../../../../../dijit/themes/claro/document.css";
+ at import "../../../../../dijit/themes/tundra/tundra.css";
+ at import "../../../enhanced/resources/claro/EnhancedGrid.css";
+ at import "../../../enhanced/resources/tundra/EnhancedGrid.css";
+ at import "../../../enhanced/resources/EnhancedGrid_rtl.css";
\ No newline at end of file
diff --git a/dojox/grid/tests/enhanced/support/music-for-demo.part.csv b/dojox/grid/tests/enhanced/support/music-for-demo.part.csv
deleted file mode 100644
index 9109713..0000000
--- a/dojox/grid/tests/enhanced/support/music-for-demo.part.csv
+++ /dev/null
@@ -1,309 +0,0 @@
-Genre,Artist,Year,Album,Name,Length,Track,Composer
-Easy Listening,Bette Midler,2003,Bette Midler Sings the Rosemary Clooney Songbook,Hey There,3:31,4,"Ross, Jerry 1926-1956 -w Adler, Richard 1921-"
-Classic Rock,Jimi Hendrix,1993,Are You Experienced,Love Or Confusion,3:15,4,Jimi Hendrix
-Jazz,Andy Narell,1992,Down the Road,Sugar Street,7:00,8,Andy Narell
-Progressive Rock,"Emerson, Lake & Palmer",1992,The Atlantic Years,Tarkus,20:40,5,Greg Lake/Keith Emerson
-Rock,"Blood, Sweat & Tears",1968,Child Is Father To The Man,Somethin' Goin' On,8:00,9,
-Jazz,Andy Narell,1989,Little Secrets,Armchair Psychology,8:20,5,Andy Narell
-Easy Listening,Frank Sinatra,1991,Sinatra Reprise: The Very Good Years,Luck Be A Lady,5:16,4,F. Loesser
-Progressive Rock,Dixie dregs,1977,Free Fall,Sleep,1:58,6,Steve Morse
-Classic Rock,Black Sabbath,2004,Master of Reality,Sweet Leaf,5:04,1,Bill Ward/Geezer Butler/Ozzy Osbourne/Tony Iommi
-Blues,Buddy Guy,1991,"Damn Right, I've Got The Blues",Five Long Years,8:27,3,Eddie Boyd/John Lee Hooker
-Easy Listening,Frank Sinatra,1991,Sinatra Reprise: The Very Good Years,The Way You Look Tonight,3:23,5,D. Fields/J. Kern
-World,Andy Statman & David Grisman,1995,Songs Of Our Fathers,Chassidic Medley: Adir Hu / Moshe Emes,4:14,2,Shlomo Carlebach; Trad.
-Classic Rock,Jimi Hendrix,1968,Electric Ladyland,Long Hot Summer Night,3:27,6,Jimi Hendrix
-Classical,Andres Segovia,2004,The Best Of Andres Segovia,"Asturias (Suite Espanola, Op. 47)",6:25,6,Isaac Albeniz
-Jazz,Andy Narell,1989,Little Secrets,We Kinda Music,8:22,3,Andy Narell
-Pop and R&B,Joni Mitchell,2000,Both Sides Now,Comes Love,4:29,3,Charles Tobias/Sammy Stept/Lew Brown
-Pop and R&B,Joni Mitchell,1974,Court And Spark,Court And Spark,2:46,1,Joni Mitchell
-Easy Listening,Frank Sinatra,1962,Sinatra and Swinging Brass,Serenade in Blue,3:00,10,"Harry Warren, Mack Gordon"
-Classical,Julian Bream,1957,Fret Works: Dowland & Villa-Lobos,Queen Elizabeth's Galliard,1:33,1,John Dowland
-Progressive Rock,Dixie dregs,1977,Free Fall,Free Fall,4:41,1,Steve Morse
-Classic Rock,Black Sabbath,2004,Master of Reality,After Forever,5:26,2,Tony Iommi
-Classic Rock,Jimi Hendrix,1993,Are You Experienced,The Wind Cries Mary,3:23,7,Jimi Hendrix
-Rock,Dave Matthews,1998,Before These Crowded Streets,Don't Drink the Water,7:01,4,"Beauford, Carter/Matthews, David J."
-Jazz,Charlie Hunter,2004,Friends Seen and Unseen,Eleven Bars for Gandhi,6:57,7,Charlie Hunter
-World,Andy Statman & David Grisman,1995,Songs Of Our Fathers,L'Ma'an Achai V'Re'ei,5:56,8,Shlomo Carlebach
-Jazz,Bill Evans,1958,Everybody Digs Bill Evans,Minority,5:22,1,Gigi Gryce
-Classical,Julian Bream,1992,Nocturnal,Britten: Nocturnal - 1. Musingly (Meditativo),2:14,5,Benjamin Britten
-Classical,Andres Segovia,1955,The Art Of Segovia [Disc 1],Tarrega: Recuerdos de la Alhambra,5:16,1,Francisco Tarrega
-Rock,"Blood, Sweat & Tears",1968,Child Is Father To The Man,Overture,1:32,1,
-World,Andy Statman Quartet,2005,Between Heaven & Earth,Tzamah Nafshi,8:00,8,Karlin-Stolin
-Blues,B.B. King,2005,80,The Thrill Is Gone,5:03,3,
-Rock,Dave Matthews,1998,Before These Crowded Streets,Stay (Wasting Time),5:35,5,"Lessard, Stefan/Beauford, Carter/Moore, Leroi"
-Pop and R&B,Joni Mitchell,2000,Both Sides Now,Answer Me My Love,3:24,5,Carl Sigman/Gerhard Winkler/Fred Rauch
-Rock,Dave Matthews,1996,Crash,Two Step,6:29,2,Dave Matthews
-Progressive Rock,Dixie dregs,1978,What if,Little Kids,2:07,6,
-Easy Listening,Bette Midler,2003,Bette Midler Sings the Rosemary Clooney Songbook,Come On-A My House,1:50,6,"Saroyan, William 1908-1981 -w Bagdasarian, Ross 1919-1972"
-Classical,Julian Bream,1957,Fret Works: Dowland & Villa-Lobos,King of Denmark's Galliard,1:15,8,John Dowland
-Classical,Andres Segovia,2004,The Best Of Andres Segovia,Recuerdos De La Alhambra,5:12,5,Francisco Tarrega
-Classic Rock,Jimi Hendrix,1968,Electric Ladyland,Voodoo Chile,14:59,4,Jimi Hendrix
-Classical,Julian Bream,1957,Fret Works: Dowland & Villa-Lobos,Fantasia,5:02,7,John Dowland
-Blues,B.B. King,1997,Deuces Wild,There Must Be A Better World Somewhere,4:51,7,Rebennack/Pomus
-Jazz,Andy Narell,1992,Down the Road,Green Ballet: 2nd Position for Steel Orchestra,3:41,6,Vince Mendoza
-Jazz,Bill Evans,1962,Interplay,I'll Never Smile Again (Take 7),6:33,3,Ruth Lowe
-Blues,Buddy Guy,1993,Feels Like Rain,I Go Crazy,2:26,2,James Brown
-Jazz,Bill Evans,1978,Affinity,The Other Side of Midnight (Noelle's Theme),3:23,7,Michel Legrand
-Classic Rock,Jimi Hendrix,1968,Electric Ladyland,...And the Gods Made Love,1:23,1,Jimi Hendrix
-Pop and R&B,Joni Mitchell,2000,Both Sides Now,At Last,4:28,2,Mack Gordon/Harry Warren
-Easy Listening,Bette Midler,1993,Experience the Divine,Miss Ottis Regrets,2:40,8,Cole Porter
-Blues,Buddy Guy,1993,Feels Like Rain,Change in the Weather,4:38,7,John Fogerty
-Easy Listening,Bette Midler,2003,Bette Midler Sings the Rosemary Clooney Songbook,This Ole House,3:03,2,"Hamblen, Stuart 1908-1989"
-Progressive Rock,Dixie dregs,1977,Free Fall,Holiday,4:29,2,Steven J. Morse
-Rock,"Blood, Sweat & Tears",1969,"Blood, Sweat & Tears",Smiling Phases,5:11,2,"Jim Capaldi, Steve Winwood, Chris Wood"
-Jazz,Andy Narell,1992,Down the Road,Disorderly Conduct,6:40,4,Andy Narell
-Classic Rock,Jimi Hendrix,1993,Are You Experienced,Purple Haze,2:53,1,Jimi Hendrix
-Jazz,Andy Narell,1992,Down the Road,Green Ballet: 1st Position for Steel Orchestra,2:16,5,Vince Mendoza
-Rock,"Blood, Sweat & Tears",1968,Child Is Father To The Man,Just One Smile,4:38,6,
-Rock,"Blood, Sweat & Tears",1969,"Blood, Sweat & Tears",More And More,3:04,4,"Don Juan, Pea Vee"
-Classic Rock,Jimi Hendrix,1968,Electric Ladyland,Have You Ever Been (To Electric Ladyland),2:10,2,Jimi Hendrix
-Rock,"Blood, Sweat & Tears",1968,Child Is Father To The Man,I Love You More Than You'll Ever Know,5:57,2,
-Blues,B.B. King,1997,Deuces Wild,Rock Me Baby,6:38,3,B.B. King/Joe Josea
-Blues,Buddy Guy,1993,Feels Like Rain,Sufferin' Mind,3:33,6,E. Jones
-Pop and R&B,Joni Mitchell,2000,Both Sides Now,You're My Thrill,3:52,1,Jay Gorney/Sindney Clare
-Easy Listening,Bette Midler,1993,Experience the Divine,Chapel Of Love,2:54,4,Ellie Greenwich/Jeff Barry/Phil Spector
-Blues,B.B. King,2005,80,Hummingbird,4:42,6,
-Progressive Rock,"Emerson, Lake & Palmer",1996,Brain Salad Surgery [Rhino],Jerusalem,2:44,1,Charles Hubert Hastings Parry/William Blake
-Progressive Rock,"Emerson, Lake & Palmer",,The Atlantic Years,Fanfare For The Common Man,5:41,9,
-Jazz,Bill Evans,1962,Interplay,Wrap Your Troubles In Dreams (And Dream Your Troubles Away),6:21,7,Billy Moll/Harry Barris/Ted Koehler
-Classical,Andres Segovia,2004,The Best Of Andres Segovia,"Bouree (Suite In E Minor, BWV 996 - Bach)",1:32,2,Johann Sebastian Bach (1685-1750)
-Rock,Dave Matthews,1996,Crash,Crash Into Me,5:18,3,Dave Matthews
-Easy Listening,Frank Sinatra,1990,The Capitol Years [Disc 1],Someone To Watch Over Me,2:57,12,George & Ira Gershwin/George Gershwin
-Rock,Dave Matthews,1998,Before These Crowded Streets,The Last Stop,6:58,3,"Lessard, Stefan/Beauford, Carter"
-Classic Rock,Jimi Hendrix,1968,Electric Ladyland,Crosstown Traffic,2:26,3,Jimi Hendrix
-Jazz,Bill Evans,1978,Affinity,I Do It For Your Love,7:23,1,Paul Simon
-World,Andy Statman & David Grisman,1995,Songs Of Our Fathers,Dovid Melech Yisrael,2:07,6,Shlomo Carlebach
-Progressive Rock,Dixie dregs,1977,Free Fall,Dig the Ditch,3:51,9,Steven J. Morse
-Rock,Dave Matthews,1996,Crash,Too Much,4:24,4,Dave Matthews
-Classic Rock,Black Sabbath,2004,Master of Reality,Into the Void,6:12,8,Bill Ward/Geezer Butler/Ozzy Osbourne/Tony Iommi
-Easy Listening,Bette Midler,1993,Experience the Divine,From A Distance,4:39,3,Julie Gold
-Classical,Julian Bream,1957,Fret Works: Dowland & Villa-Lobos,Lachrimae Antiquae Galliard,2:59,2,John Dowland
-Rock,Dave Matthews,1996,Crash,Let You Down,4:09,8,Dave Matthews
-Jazz,Bill Evans,1958,Everybody Digs Bill Evans,Night and Day,7:35,4,Cole Porter
-Classic Rock,Black Sabbath,2004,Black Sabbath,Black Sabbath,6:18,1,Bill Ward/Geezer Butler/Ozzy Osbourne/Tony Iommi
-Blues,Buddy Guy,1993,Feels Like Rain,She's Nineteen Years Old,5:43,4,Muddy Waters
-Jazz,Bill Evans,1978,Affinity,The Days of Wine and Roses,6:43,4,"Henry Mancini, Johnny Mercer"
-Progressive Rock,"Emerson, Lake & Palmer",,The Atlantic Years,The Endless Enigma (Part 1),6:41,7,
-Easy Listening,Frank Sinatra,1991,Sinatra Reprise: The Very Good Years,It Was A Very Good Year,4:29,9,E. Drake
-Pop and R&B,Joni Mitchell,1974,Court And Spark,Help Me,3:22,2,Joni Mitchell
-Classical,Julian Bream,1965,"Julian Bream Edition, Vol. 20","Bach: Lute Suite In A Minor, BWV 997 - Praeludium",3:06,7,Johann Sebastian Bach
-Jazz,Bill Evans,1962,Interplay,You And The Night And The Music,7:05,1,Arthur Schwartz/Howard Dietz
-Classical,Julian Bream,1965,"Julian Bream Edition, Vol. 20","Bach: Lute Suite In E Minor, BWV 996 - Sarabande",4:45,4,Johann Sebastian Bach
-Jazz,Charlie Hunter,2004,Friends Seen and Unseen,One for the Kelpers,6:31,1,John Ellis
-Easy Listening,Bette Midler,2003,Bette Midler Sings the Rosemary Clooney Songbook,You'll Never Know,1:44,1,"Warren, Harry 1893-1981 -w Gordon, Mac 1904-1959"
-Progressive Rock,"Emerson, Lake & Palmer",1992,The Atlantic Years,Tank,6:47,4,Carl Palmer/Keith Emerson
-Classic Rock,Jimi Hendrix,1968,Electric Ladyland,"Come On, Pt. 1",4:10,7,Earl King
-World,Andy Statman & David Grisman,1995,Songs Of Our Fathers,Der Rebbe,3:59,9,Trad.
-Blues,B.B. King,2005,80,Early in the Morning,4:50,1,
-Classical,Julian Bream,1992,Nocturnal,Martin: Quatre Pièces Breves - 3. Plainte: Sans Lenteur,2:59,3,Frank Martin
-Jazz,Bill Evans,1958,Everybody Digs Bill Evans,What Is There to Say?,4:54,8,Duke
-Jazz,Andy Narell,1989,Little Secrets,Don't Look Back,9:39,6,Andy Narell
-Progressive Rock,Dixie dregs,1978,What if,What if,5:02,3,Steve Morse
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
-,,,,,
diff --git a/dojox/grid/tests/enhanced/support/print_style1.css b/dojox/grid/tests/enhanced/support/print_style1.css
new file mode 100644
index 0000000..5959a3a
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/print_style1.css
@@ -0,0 +1,20 @@
+/* Printed grid may have a title, which is included in an <h1> tag */
+h1{
+	text-align: center;
+	color: blue;
+}
+table{
+	color: black;
+}
+.grid_header{
+	color: red;
+	background-color: green;
+	font-style: italic;
+	font-weight: bold;
+}
+.grid_odd_row{
+	background-color: RGB(237,227,205);
+}
+.grid_row_1,.grid_row_2,.grid_row_5,.grid_row_6{
+	background-color: yellow;
+}
diff --git a/dojox/grid/tests/enhanced/support/print_style2.css b/dojox/grid/tests/enhanced/support/print_style2.css
new file mode 100644
index 0000000..2060a13
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/print_style2.css
@@ -0,0 +1,7 @@
+.grid_even_column{
+	background-color: #808000;
+	color: white;
+}
+.grid_header .grid_column_3{
+	background-color: blue;
+}
diff --git a/dojox/grid/tests/enhanced/support/test_layout_music.js b/dojox/grid/tests/enhanced/support/test_layout_music.js
new file mode 100644
index 0000000..f94427f
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/test_layout_music.js
@@ -0,0 +1,174 @@
+dojo.require("dijit.form.DateTextBox");
+var formatDate = function(inDatum){
+	var dtb = new dijit.form.DateTextBox({});
+	var res = dojo.date.locale.parse(inDatum,{
+		selector: "date",
+		datePattern: "yyyy/MM/dd"
+	});
+	dtb.set("value",res);
+	return dtb;
+};
+var layout = [
+	[{//--------------------------------------------------------------------------0
+		defaultCell: {editable: true, autoComplete:true, type: dojox.grid.cells._Widget},
+		cells:
+		[
+			{ field: "id", name:"Index", datatype:"number", width: 2.5},
+			{ 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},
+			{ field: "Album", name:"Album", datatype:"string", width: 10},
+			{ field: "Name", name:"Name", datatype:"string", width: 8, disabledConditions: [
+				"contains", "notcontains"
+			]},
+			{ field: "Length", name:"Length", datatype:"string", width: 4},
+			{ field: "Track", name:"Track", datatype:"number", width: 3
+//				,get: function(rowIndex, item){
+//					if(item){
+//						return "Track " + this.grid.store.getValue(item, this.field);
+//					}else{
+//						return this.value || this.defaultValue;
+//					}
+//				}
+			},
+			{ field: "Composer", name:"Composer", datatype:"string", width: 12},
+			{ field: "Download Date", name:"Download Date", datatype:"date", width: 12,
+				navigatable: true, editable: false,
+				//formatter: formatDate,
+				dataTypeArgs: {
+					datePattern: "yyyy/M/d"
+				}
+			},
+			{ field: "Last Played", name:"Last Played", datatype:"time", width: 6,
+				dataTypeArgs: {
+					timePattern: "HH:mm:ss"
+				}
+			},
+			{ field: "Heard", name: "Checked", datatype:"boolean", width: 6/*, type: dojox.grid.cells.CheckBox*/},
+			{ field: "Checked", name:"Checked (Customized Label)", editable: false, datatype:"boolean", width: 15, dataTypeArgs: {
+				trueLabel: "This sounds like a very old song.",
+				falseLabel: "Never heard of this song."
+			}}
+		]
+	}],
+	[{//--------------------------------------------------------------------------1
+		defaultCell: {},
+		rows:
+		[[
+//			{ field: "id", name:"Index(1)", width: "5px"},
+//			{ field: "Genre", name:"Genre(2)", width: "5px"},
+//			{ field: "Artist", name:"Artist(3)", width: "5px"},
+//			{ field: "Year", name:"Year(4)", width: "5px"},
+//			{ field: "Album", name:"Album(5)", width: "5px"},
+//			{ field: "Name", name:"Name(6)", width: "5px"},
+//			{ field: "Length", name:"Length(7)", width: "5px"},
+//			{ field: "Track", name:"Track(8)", width: "5px"},
+//			{ field: "Composer", name:"Composer(9)", width: "5px"},
+//			{ field: "Download Date", name:"Download Date(10)", width: "5px"},
+//			{ field: "Last Played", name:"Last Played(11)", width: "5px"}
+			
+			{ field: "id", name:"Index(1)", hidden: false},
+			{ field: "Genre", name:"Genre(2)", hidden: false},
+			{ field: "Artist", name:"Artist(3)", hidden: false},
+			{ field: "Year", name:"Year(4)", hidden: false},
+			{ field: "Album", name:"Album(5)", hidden: false},
+			{ field: "Name", name:"Name(6)", hidden: false},
+			{ field: "Length", name:"Length(7)", hidden: false},
+			{ field: "Track", name:"Track(8)", hidden: false},
+			{ field: "Composer", name:"Composer(9)", hidden: false},
+			{ field: "Download Date", name:"Download Date(10)", cellFormatter: {
+				selector: "date",
+				parse: {datePattern: "yyyy/M/d"},
+				format:{datePattern: "MMMM d, yyyy"}
+			}, hidden: false},
+			{ field: "Last Played", name:"Last Played(11)", hidden: false}
+		]]
+	}],
+	[//--------------------------------------------------------------------------2
+		{//first view
+			width: "300px",
+			rows:
+			[
+				{ field: "Genre", width: '6'},
+				{ field: "Artist", width: '5'},
+				{ field: "Year", width: '6'},
+				{ field: "Album", width: '10'}
+			]
+		},
+		{//second view
+			rows:
+			[
+				{ field: "Name", width: '17'},
+				{ field: "Length", width: '6'},
+				{ field: "Track", width: '6'},
+				{ field: "Composer", width: '15'}
+			]
+		}
+	],
+	[//--------------------------------------------------------------------------3
+		{//first view
+			rows:
+			[
+				{ field: "Genre", width: '8'},
+				{ field: "Artist", width: '6'},
+				{ field: "Year", width: '6'},
+				{ field: "Album", width: '10'},
+				{ field: "Name", width: '10'},
+				{ field: "Length", width: '6'},
+				{ field: "Track", width: '6'},
+				{ field: "Composer", width: '13'},
+				{ field: "Download Date", width: '10'},
+				{ field: "Last Played", width: '10'}
+			]
+		}
+	],
+	[{//--------------------------------------------------------------------------4
+		rows:
+		[
+			[
+				{ field: "Genre"},
+				{ field: "Artist"},
+				{ field: "Year"},
+				{ field: "Album"},
+				{ field: "Name"}
+			],[
+				{ field: "Length"},
+				{ field: "Track"},
+				{ field: "Composer"},
+				{ field: "Download Date"},
+				{ field: "Last Played"}
+			]
+		]}
+	],
+	[//--------------------------------------------------------------------------5
+		{//first view
+			rows:
+			[
+				[
+					{ field: "Genre", width: '10', rowSpan: 2},
+					{ field: "Artist", width: '15'},
+					{ field: "Year", width: '15'},
+				],[
+					{ field: "Album", colSpan: 2}
+				]
+			]
+		},
+		{//second view
+			rows:
+			[
+				[
+					{ field: "Name", width: '20', rowSpan: 2},
+					{ field: "Length", width: '20'},
+					{ field: "Track"}
+				],[
+					{ field: "Composer", colSpan: 2},
+					
+				],[
+					{ field: "Download Date"},
+					{ field: "Last Played"},
+					{ field: "Checked"}
+				]
+			]
+		}
+	]
+];
diff --git a/dojox/grid/tests/enhanced/support/test_repeat.js b/dojox/grid/tests/enhanced/support/test_repeat.js
new file mode 100644
index 0000000..7327fe8
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/test_repeat.js
@@ -0,0 +1,90 @@
+(function(){
+var gridIndex = startGridIndex || 0;
+var totalCount = repeatCount || 1000;
+var timeInterval = repeatInterval || 500;
+function createGrid(step){
+	try{
+		var g = dijit.byId("grid");
+		g && g.destroyRecursive();
+		dojo.publish("test_repeat_grid_destroyed");
+		for(gridIndex += step; gridIndex < 0; gridIndex += layout.length){}
+		gridIndex %= layout.length;
+		console.log("grid plugin args:", gridAttrs.plugins, gridIndex);
+		var t1 = (new Date()).getTime();
+		g = new dojox.grid.EnhancedGrid(dojo.mixin({
+			"id": "grid",
+			"store": test_store[0],
+			"structure": layout[gridIndex]
+		}, gridAttrs || {}));
+		g.placeAt(dojo.byId("gridContainer"));
+		g.startup();
+		dojo.byId("num").value = gridIndex;
+		console.log(gridIndex + "---------------------------------------------------------------", (new Date()).getTime() - t1, "ms");
+		dojo.publish("test_repeat_grid_created");
+		return g;
+	}catch(e){
+		console.log("createGrid:",e);
+	}
+}
+var cnt = totalCount;
+function start(){
+	if(cnt > 0){
+		--cnt;
+		createGrid(1);
+		setTimeout(start, timeInterval);
+	}else{
+		var g = dijit.byId("grid");
+		g && g.destroyRecursive();
+		cnt = totalCount;
+	}
+}
+function stop(){
+	cnt = 0;
+}
+function gotoGrid(){
+	var id = parseInt(dojo.byId('num').value) % layout.length;
+	gridIndex = isNaN(id) ? gridIndex : id;
+	createGrid(0);
+}
+function destroy(){
+	var g = dijit.byId("grid");
+	g && g.destroyRecursive();
+	dojo.publish("test_repeat_grid_destroyed");
+}
+dojo.addOnLoad(function(){
+	var btns = dojo.byId("ctrlBtns");
+	if(hideCtrlPanel){
+		dojo.style(btns, "display", "none");
+	}
+	btns.appendChild(dojo.create("button",{
+		"innerHTML": "Play",
+		"onclick": start
+	}));
+	btns.appendChild(dojo.create("button",{
+		"innerHTML": "Stop",
+		"onclick": stop
+	}));
+	btns.appendChild(dojo.create("button",{
+		"innerHTML": "Prev",
+		"onclick": dojo.partial(createGrid, -1)
+	}));
+	btns.appendChild(dojo.create("button",{
+		"innerHTML": "Next",
+		"onclick": dojo.partial(createGrid, 1)
+	}));
+	btns.appendChild(dojo.create("input",{
+		"id": "num",
+		"value": gridIndex,
+		"type": "text"
+	}));
+	btns.appendChild(dojo.create("button",{
+		"innerHTML": "Create",
+		"onclick": gotoGrid
+	}));
+	btns.appendChild(dojo.create("button",{
+		"innerHTML": "Destroy",
+		"onclick": destroy
+	}));
+	initialShowGrid && gotoGrid();
+});
+})();
diff --git a/dojox/grid/tests/enhanced/support/test_ue.js b/dojox/grid/tests/enhanced/support/test_ue.js
deleted file mode 100644
index fd5a539..0000000
--- a/dojox/grid/tests/enhanced/support/test_ue.js
+++ /dev/null
@@ -1,29 +0,0 @@
-//Customized sorters only for testing, as all testing data are not in the native format, and performance is bad if dojo.date.locale.parse is used.
-//in a real case, data should be stored as native format
-
-dojo.addOnLoad(function(){
-	if (csvStore1) {
-		csvStore1.comparatorMap = {};
-		csvStore1.comparatorMap['Length'] = function(dateStr1, dateStr2){
-			var date1 = _getDate(dateStr1);
-			var date2 = _getDate(dateStr2);
-			//console.log('in=',dateStr1, ' ', dateStr2, " | out=", date1, ' ', date2);
-			return (date1 > date2) ? 1 : (date1 < date2 ? -1 : 0);
-		};
-		
-		csvStore1.comparatorMap['Track'] = function(numStr1, numStr2){
-			var num1 = new Number(numStr1);
-			var num2 = new Number(numStr2);
-			return (num1 > num2) ? 1 : (num1 < num2 ? -1 : 0);
-		};
-	}
-	
-	_getDate = function(dateStr){
-		//item should be in HH:mm or HH:mm:ss so that dojo.date.stamp.fromISOString can parse it
-		var items = dateStr.split(':');
-		dojo.forEach(items, function(item, index, items){
-			item.length < 2 && (items[index] = '0' + item);
-		});
-		return dojo.date.stamp.fromISOString('T' + items.join(':'));
-	}
-});
diff --git a/dojox/grid/tests/enhanced/support/test_write_store_dnd.js b/dojox/grid/tests/enhanced/support/test_write_store_dnd.js
new file mode 100644
index 0000000..88e8b6f
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/test_write_store_dnd.js
@@ -0,0 +1,32 @@
+(function(){
+	// some sample data
+	var data = {
+		identifier: 'id',
+		label: 'id',
+		items: []
+	};
+	var cols = ["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"];
+	var data_list = [];
+	var i, row, j;
+	for(i = 0; i < 100; ++i){
+		row = {};
+		for(j = 0; j < cols.length; ++j){
+			row[cols[j]] = (i + 1) + cols[j];
+		}
+		data_list.push(row);
+	}
+	var len = data_list.length;
+	for(i=0; i < len ; ++i){
+		data.items.push(dojo.mixin({ 'id': i+1 }, data_list[i]));
+	}
+	
+	if(!this.test_store_data){
+		this.test_store_data = [];
+	}
+	this.test_store_data.push(dojo.clone(data));
+	
+	if(!this.test_store){
+		this.test_store = [];
+	}
+	this.test_store.push(new dojo.data.ItemFileWriteStore({data: data}));
+})();
diff --git a/dojox/grid/tests/enhanced/support/test_write_store_music.js b/dojox/grid/tests/enhanced/support/test_write_store_music.js
new file mode 100644
index 0000000..1357c34
--- /dev/null
+++ b/dojox/grid/tests/enhanced/support/test_write_store_music.js
@@ -0,0 +1,129 @@
+dojo.require("dojo.data.ItemFileWriteStore");
+(function(){
+	// some sample data
+	var data = {
+		identifier: 'id',
+		label: 'id',
+		items: []
+	};
+//^(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)\t(.*)$
+//		{"Checked": "True", "Genre":"$1",	"Artist":"$2",	"Year":$3,	"Album":"$4",	"Name":"$5",	"Length":"$6",	"Track":$7,	"Composer":"$8",	"Download Date":"$9",	"Last Played":"$10"},
+	var data_list = [
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":2003,	"Album":"Bette Midler Sings the Rosemary Clooney Songbook",	"Name":"Hey There",	"Length":"03:31",	"Track":4,	"Composer":"Ross, Jerry 1926-1956 -w Adler, Richard 1921-",	"Download Date":"1923/4/9",	"Last Played":"04:32:49"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1993,	"Album":"Are You Experienced",	"Name":"Love Or Confusion",	"Length":"03:15",	"Track":4,	"Composer":"Jimi Hendrix",	"Download Date":"1947/12/6",	"Last Played":"03:47:49"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1992,	"Album":"Down the Road",	"Name":"Sugar Street",	"Length":"07:00",	"Track":8,	"Composer":"Andy Narell",	"Download Date":"1906/3/22",	"Last Played":"21:56:15"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Emerson, Lake & Palmer",	"Year":1992,	"Album":"The Atlantic Years",	"Name":"Tarkus",	"Length":"20:40",	"Track":5,	"Composer":"Greg Lake/Keith Emerson",	"Download Date":"1994/11/29",	"Last Played":"03:25:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Blood, Sweat & Tears",	"Year":1968,	"Album":"Child Is Father To The Man",	"Name":"Somethin' Goin' On",	"Length":"08:00",	"Track":9,	"Composer":"",	"Download Date":"1973/9/11",	"Last Played":"19:49:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1989,	"Album":"Little Secrets",	"Name":"Armchair Psychology",	"Length":"08:20",	"Track":5,	"Composer":"Andy Narell",	"Download Date":"2010/4/15",	"Last Played":"01:13:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Frank Sinatra",	"Year":1991,	"Album":"Sinatra Reprise: The Very Good Years",	"Name":"Luck Be A Lady",	"Length":"05:16",	"Track":4,	"Composer":"F. Loesser",	"Download Date":"2035/4/12",	"Last Played":"06:16:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Dixie dregs",	"Year":1977,	"Album":"Free Fall",	"Name":"Sleep",	"Length":"01:58",	"Track":6,	"Composer":"Steve Morse",	"Download Date":"2032/11/21",	"Last Played":"08:23:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Black Sabbath",	"Year":2004,	"Album":"Master of Reality",	"Name":"Sweet Leaf",	"Length":"05:04",	"Track":1,	"Composer":"Bill Ward/Geezer Butler/Ozzy Osbourne/Tony Iommi",	"Download Date":"2036/5/26",	"Last Played":"22:10:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"Buddy Guy",	"Year":1991,	"Album":"Damn Right, I've Got The Blues",	"Name":"Five Long Years",	"Length":"08:27",	"Track":3,	"Composer":"Eddie Boyd/John Lee Hooker",	"Download Date":"1904/4/4",	"Last Played":"18:28:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Frank Sinatra",	"Year":1991,	"Album":"Sinatra Reprise: The Very Good Years",	"Name":"The Way You Look Tonight",	"Length":"03:23",	"Track":5,	"Composer":"D. Fields/J. Kern",	"Download Date":"1902/10/12",	"Last Played":"23:09:23"},
+		{"Heard": true, "Checked": "True", "Genre":"World",	"Artist":"Andy Statman & David Grisman",	"Year":1995,	"Album":"Songs Of Our Fathers",	"Name":"Chassidic Medley: Adir Hu / Moshe Emes",	"Length":"04:14",	"Track":2,	"Composer":"Shlomo Carlebach; Trad.",	"Download Date":"2035/2/9",	"Last Played":"00:11:15"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1968,	"Album":"Electric Ladyland",	"Name":"Long Hot Summer Night",	"Length":"03:27",	"Track":6,	"Composer":"Jimi Hendrix",	"Download Date":"1902/4/7",	"Last Played":"16:58:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Classical",	"Artist":"Andres Segovia",	"Year":2004,	"Album":"The Best Of Andres Segovia",	"Name":"Asturias (Suite Espanola, Op. 47)",	"Length":"06:25",	"Track":6,	"Composer":"Isaac Albeniz",	"Download Date":"1904/10/25",	"Last Played":"06:59:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1989,	"Album":"Little Secrets",	"Name":"We Kinda Music",	"Length":"08:22",	"Track":3,	"Composer":"Andy Narell",	"Download Date":"1905/5/22",	"Last Played":"23:43:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Pop and R&B",	"Artist":"Joni Mitchell",	"Year":2000,	"Album":"Both Sides Now",	"Name":"Comes Love",	"Length":"04:29",	"Track":3,	"Composer":"Charles Tobias/Sammy Stept/Lew Brown",	"Download Date":"1927/11/19",	"Last Played":"02:34:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Pop and R&B",	"Artist":"Joni Mitchell",	"Year":1974,	"Album":"Court And Spark",	"Name":"Court And Spark",	"Length":"02:46",	"Track":1,	"Composer":"Joni Mitchell",	"Download Date":"1927/5/24",	"Last Played":"13:27:11"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Frank Sinatra",	"Year":1962,	"Album":"Sinatra and Swinging Brass",	"Name":"Serenade in Blue",	"Length":"03:00",	"Track":10,	"Composer":"Harry Warren, Mack Gordon",	"Download Date":"1932/7/16",	"Last Played":"08:15:00"},
+		{"Heard": true, "Checked": "True", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1957,	"Album":"Fret Works: Dowland & Villa-Lobos",	"Name":"Queen Elizabeth's Galliard",	"Length":"01:33",	"Track":1,	"Composer":"John Dowland",	"Download Date":"2022/6/9",	"Last Played":"08:40:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Dixie dregs",	"Year":1977,	"Album":"Free Fall",	"Name":"Free Fall",	"Length":"04:41",	"Track":1,	"Composer":"Steve Morse",	"Download Date":"2022/6/6",	"Last Played":"01:27:11"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Black Sabbath",	"Year":2004,	"Album":"Master of Reality",	"Name":"After Forever",	"Length":"05:26",	"Track":2,	"Composer":"Tony Iommi",	"Download Date":"1996/4/7",	"Last Played":"03:53:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1993,	"Album":"Are You Experienced",	"Name":"The Wind Cries Mary",	"Length":"03:23",	"Track":7,	"Composer":"Jimi Hendrix",	"Download Date":"1941/4/23",	"Last Played":"04:52:30"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1998,	"Album":"Before These Crowded Streets",	"Name":"Don't Drink the Water",	"Length":"07:01",	"Track":4,	"Composer":"Beauford, Carter/Matthews, David J.",	"Download Date":"2019/8/19",	"Last Played":"12:45:00"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Charlie Hunter",	"Year":2004,	"Album":"Friends Seen and Unseen",	"Name":"Eleven Bars for Gandhi",	"Length":"06:57",	"Track":7,	"Composer":"Charlie Hunter",	"Download Date":"1973/9/24",	"Last Played":"15:02:49"},
+		{"Heard": true, "Checked": "True", "Genre":"World",	"Artist":"Andy Statman & David Grisman",	"Year":1995,	"Album":"Songs Of Our Fathers",	"Name":"L'Ma'an Achai V'Re'ei",	"Length":"05:56",	"Track":8,	"Composer":"Shlomo Carlebach",	"Download Date":"2007/10/27",	"Last Played":"20:23:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1958,	"Album":"Everybody Digs Bill Evans",	"Name":"Minority",	"Length":"05:22",	"Track":1,	"Composer":"Gigi Gryce",	"Download Date":"1912/6/9",	"Last Played":"09:30:56"},
+		{"Heard": false, "Checked": "False", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1992,	"Album":"Nocturnal",	"Name":"Britten: Nocturnal - 1. Musingly (Meditativo)",	"Length":"02:14",	"Track":5,	"Composer":"Benjamin Britten",	"Download Date":"1943/9/16",	"Last Played":"12:14:04"},
+		{"Heard": false, "Checked": "False", "Genre":"Classical",	"Artist":"Andres Segovia",	"Year":1955,	"Album":"The Art Of Segovia [Disc 1]",	"Name":"Tarrega: Recuerdos de la Alhambra",	"Length":"05:16",	"Track":1,	"Composer":"Francisco Tarrega",	"Download Date":"1946/10/11",	"Last Played":"09:14:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Blood, Sweat & Tears",	"Year":1968,	"Album":"Child Is Father To The Man",	"Name":"Overture",	"Length":"01:32",	"Track":1,	"Composer":"",	"Download Date":"1967/12/16",	"Last Played":"23:23:26"},
+		{"Heard": true, "Checked": "True", "Genre":"World",	"Artist":"Andy Statman Quartet",	"Year":2005,	"Album":"Between Heaven & Earth",	"Name":"Tzamah Nafshi",	"Length":"08:00",	"Track":8,	"Composer":"Karlin-Stolin",	"Download Date":"2002/10/10",	"Last Played":"01:21:34"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"B.B. King",	"Year":2005,	"Album":"80",	"Name":"The Thrill Is Gone",	"Length":"05:03",	"Track":3,	"Composer":"",	"Download Date":"1949/9/13",	"Last Played":"16:01:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1998,	"Album":"Before These Crowded Streets",	"Name":"Stay (Wasting Time)",	"Length":"05:35",	"Track":5,	"Composer":"Lessard, Stefan/Beauford, Carter/Moore, Leroi",	"Download Date":"2020/5/12",	"Last Played":"15:25:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Pop and R&B",	"Artist":"Joni Mitchell",	"Year":2000,	"Album":"Both Sides Now",	"Name":"Answer Me My Love",	"Length":"03:24",	"Track":5,	"Composer":"Carl Sigman/Gerhard Winkler/Fred Rauch",	"Download Date":"1962/4/10",	"Last Played":"19:52:30"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1996,	"Album":"Crash",	"Name":"Two Step",	"Length":"06:29",	"Track":2,	"Composer":"Dave Matthews",	"Download Date":"2025/6/27",	"Last Played":"12:14:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Dixie dregs",	"Year":1978,	"Album":"What if",	"Name":"Little Kids",	"Length":"02:07",	"Track":6,	"Composer":"",	"Download Date":"2008/6/9",	"Last Played":"15:53:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":2003,	"Album":"Bette Midler Sings the Rosemary Clooney Songbook",	"Name":"Come On-A My House",	"Length":"01:50",	"Track":6,	"Composer":"Saroyan, William 1908-1981 -w Bagdasarian, Ross 1919-1972",	"Download Date":"2018/8/13",	"Last Played":"19:21:34"},
+		{"Heard": false, "Checked": "False", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1957,	"Album":"Fret Works: Dowland & Villa-Lobos",	"Name":"King of Denmark's Galliard",	"Length":"01:15",	"Track":8,	"Composer":"John Dowland",	"Download Date":"2008/12/29",	"Last Played":"18:33:45"},
+		{"Heard": false, "Checked": "False", "Genre":"Classical",	"Artist":"Andres Segovia",	"Year":2004,	"Album":"The Best Of Andres Segovia",	"Name":"Recuerdos De La Alhambra",	"Length":"05:12",	"Track":5,	"Composer":"Francisco Tarrega",	"Download Date":"1906/3/11",	"Last Played":"17:54:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1968,	"Album":"Electric Ladyland",	"Name":"Voodoo Chile",	"Length":"14:59",	"Track":4,	"Composer":"Jimi Hendrix",	"Download Date":"1904/12/18",	"Last Played":"03:00:00"},
+		{"Heard": false, "Checked": "False", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1957,	"Album":"Fret Works: Dowland & Villa-Lobos",	"Name":"Fantasia",	"Length":"05:02",	"Track":7,	"Composer":"John Dowland",	"Download Date":"1907/4/11",	"Last Played":"17:37:30"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"B.B. King",	"Year":1997,	"Album":"Deuces Wild",	"Name":"There Must Be A Better World Somewhere",	"Length":"04:51",	"Track":7,	"Composer":"Rebennack/Pomus",	"Download Date":"1929/1/24",	"Last Played":"08:51:34"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1992,	"Album":"Down the Road",	"Name":"Green Ballet: 2nd Position for Steel Orchestra",	"Length":"03:41",	"Track":6,	"Composer":"Vince Mendoza",	"Download Date":"1921/3/29",	"Last Played":"13:38:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1962,	"Album":"Interplay",	"Name":"I'll Never Smile Again (Take 7)",	"Length":"06:33",	"Track":3,	"Composer":"Ruth Lowe",	"Download Date":"2019/4/14",	"Last Played":"16:21:34"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"Buddy Guy",	"Year":1993,	"Album":"Feels Like Rain",	"Name":"I Go Crazy",	"Length":"02:26",	"Track":2,	"Composer":"James Brown",	"Download Date":"1973/1/5",	"Last Played":"18:45:00"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1978,	"Album":"Affinity",	"Name":"The Other Side of Midnight (Noelle's Theme)",	"Length":"03:23",	"Track":7,	"Composer":"Michel Legrand",	"Download Date":"1938/6/17",	"Last Played":"10:04:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1968,	"Album":"Electric Ladyland",	"Name":"...And the Gods Made Love",	"Length":"01:23",	"Track":1,	"Composer":"Jimi Hendrix",	"Download Date":"2015/2/12",	"Last Played":"00:39:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Pop and R&B",	"Artist":"Joni Mitchell",	"Year":2000,	"Album":"Both Sides Now",	"Name":"At Last",	"Length":"04:28",	"Track":2,	"Composer":"Mack Gordon/Harry Warren",	"Download Date":"1933/3/16",	"Last Played":"21:00:00"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":1993,	"Album":"Experience the Divine",	"Name":"Miss Ottis Regrets",	"Length":"02:40",	"Track":8,	"Composer":"Cole Porter",	"Download Date":"2012/10/6",	"Last Played":"04:10:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"Buddy Guy",	"Year":1993,	"Album":"Feels Like Rain",	"Name":"Change in the Weather",	"Length":"04:38",	"Track":7,	"Composer":"John Fogerty",	"Download Date":"1917/9/28",	"Last Played":"09:42:11"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":2003,	"Album":"Bette Midler Sings the Rosemary Clooney Songbook",	"Name":"This Ole House",	"Length":"03:03",	"Track":2,	"Composer":"Hamblen, Stuart 1908-1989",	"Download Date":"1946/8/23",	"Last Played":"06:30:56"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Dixie dregs",	"Year":1977,	"Album":"Free Fall",	"Name":"Holiday",	"Length":"04:29",	"Track":2,	"Composer":"Steven J. Morse",	"Download Date":"2035/8/13",	"Last Played":"17:17:49"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Blood, Sweat & Tears",	"Year":1969,	"Album":"Blood, Sweat & Tears",	"Name":"Smiling Phases",	"Length":"05:11",	"Track":2,	"Composer":"Jim Capaldi, Steve Winwood, Chris Wood",	"Download Date":"1993/6/13",	"Last Played":"03:28:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1992,	"Album":"Down the Road",	"Name":"Disorderly Conduct",	"Length":"06:40",	"Track":4,	"Composer":"Andy Narell",	"Download Date":"1996/8/31",	"Last Played":"03:39:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1993,	"Album":"Are You Experienced",	"Name":"Purple Haze",	"Length":"02:53",	"Track":1,	"Composer":"Jimi Hendrix",	"Download Date":"2004/5/23",	"Last Played":"22:49:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1992,	"Album":"Down the Road",	"Name":"Green Ballet: 1st Position for Steel Orchestra",	"Length":"02:16",	"Track":5,	"Composer":"Vince Mendoza",	"Download Date":"1959/10/10",	"Last Played":"10:21:34"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Blood, Sweat & Tears",	"Year":1968,	"Album":"Child Is Father To The Man",	"Name":"Just One Smile",	"Length":"04:38",	"Track":6,	"Composer":"",	"Download Date":"1997/6/25",	"Last Played":"20:57:11"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Blood, Sweat & Tears",	"Year":1969,	"Album":"Blood, Sweat & Tears",	"Name":"More And More",	"Length":"03:04",	"Track":4,	"Composer":"Don Juan, Pea Vee",	"Download Date":"1901/5/3",	"Last Played":"10:27:11"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1968,	"Album":"Electric Ladyland",	"Name":"Have You Ever Been (To Electric Ladyland)",	"Length":"02:10",	"Track":2,	"Composer":"Jimi Hendrix",	"Download Date":"1926/6/26",	"Last Played":"16:52:30"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Blood, Sweat & Tears",	"Year":1968,	"Album":"Child Is Father To The Man",	"Name":"I Love You More Than You'll Ever Know",	"Length":"05:57",	"Track":2,	"Composer":"",	"Download Date":"1977/6/30",	"Last Played":"08:00:56"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"B.B. King",	"Year":1997,	"Album":"Deuces Wild",	"Name":"Rock Me Baby",	"Length":"06:38",	"Track":3,	"Composer":"B.B. King/Joe Josea",	"Download Date":"1997/12/14",	"Last Played":"01:13:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"Buddy Guy",	"Year":1993,	"Album":"Feels Like Rain",	"Name":"Sufferin' Mind",	"Length":"03:33",	"Track":6,	"Composer":"E. Jones",	"Download Date":"2016/4/6",	"Last Played":"18:28:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Pop and R&B",	"Artist":"Joni Mitchell",	"Year":2000,	"Album":"Both Sides Now",	"Name":"You're My Thrill",	"Length":"03:52",	"Track":1,	"Composer":"Jay Gorney/Sindney Clare",	"Download Date":"1906/9/20",	"Last Played":"21:16:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":1993,	"Album":"Experience the Divine",	"Name":"Chapel Of Love",	"Length":"02:54",	"Track":4,	"Composer":"Ellie Greenwich/Jeff Barry/Phil Spector",	"Download Date":"1914/5/21",	"Last Played":"22:55:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"B.B. King",	"Year":2005,	"Album":"80",	"Name":"Hummingbird",	"Length":"04:42",	"Track":6,	"Composer":"",	"Download Date":"1913/1/27",	"Last Played":"13:49:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Emerson, Lake & Palmer",	"Year":1996,	"Album":"Brain Salad Surgery [Rhino]",	"Name":"Jerusalem",	"Length":"02:44",	"Track":1,	"Composer":"Charles Hubert Hastings Parry/William Blake",	"Download Date":"2006/3/2",	"Last Played":"18:28:08"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Emerson, Lake & Palmer",	"Year":"",	"Album":"The Atlantic Years",	"Name":"Fanfare For The Common Man",	"Length":"05:41",	"Track":9,	"Composer":"",	"Download Date":"2023/7/1",	"Last Played":"23:00:56"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1962,	"Album":"Interplay",	"Name":"Wrap Your Troubles In Dreams (And Dream Your Troubles Away)",	"Length":"06:21",	"Track":7,	"Composer":"Billy Moll/Harry Barris/Ted Koehler",	"Download Date":"1921/12/8",	"Last Played":"16:55:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Classical",	"Artist":"Andres Segovia",	"Year":2004,	"Album":"The Best Of Andres Segovia",	"Name":"Bouree (Suite In E Minor, BWV 996 - Bach)",	"Length":"01:32",	"Track":2,	"Composer":"Johann Sebastian Bach (1685-1750)",	"Download Date":"1976/5/5",	"Last Played":"15:42:11"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1996,	"Album":"Crash",	"Name":"Crash Into Me",	"Length":"05:18",	"Track":3,	"Composer":"Dave Matthews",	"Download Date":"1912/10/25",	"Last Played":"07:01:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Frank Sinatra",	"Year":1990,	"Album":"The Capitol Years [Disc 1]",	"Name":"Someone To Watch Over Me",	"Length":"02:57",	"Track":12,	"Composer":"George & Ira Gershwin/George Gershwin",	"Download Date":"1909/8/12",	"Last Played":"03:16:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1998,	"Album":"Before These Crowded Streets",	"Name":"The Last Stop",	"Length":"06:58",	"Track":3,	"Composer":"Lessard, Stefan/Beauford, Carter",	"Download Date":"1979/5/27",	"Last Played":"21:22:30"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1968,	"Album":"Electric Ladyland",	"Name":"Crosstown Traffic",	"Length":"02:26",	"Track":3,	"Composer":"Jimi Hendrix",	"Download Date":"1989/6/5",	"Last Played":"04:24:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1978,	"Album":"Affinity",	"Name":"I Do It For Your Love",	"Length":"07:23",	"Track":1,	"Composer":"Paul Simon",	"Download Date":"1949/6/29",	"Last Played":"01:24:23"},
+		{"Heard": true, "Checked": "True", "Genre":"World",	"Artist":"Andy Statman & David Grisman",	"Year":1995,	"Album":"Songs Of Our Fathers",	"Name":"Dovid Melech Yisrael",	"Length":"02:07",	"Track":6,	"Composer":"Shlomo Carlebach",	"Download Date":"2001/12/27",	"Last Played":"10:46:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Dixie dregs",	"Year":1977,	"Album":"Free Fall",	"Name":"Dig the Ditch",	"Length":"03:51",	"Track":9,	"Composer":"Steven J. Morse",	"Download Date":"1994/10/6",	"Last Played":"18:00:00"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1996,	"Album":"Crash",	"Name":"Too Much",	"Length":"04:24",	"Track":4,	"Composer":"Dave Matthews",	"Download Date":"1926/1/4",	"Last Played":"00:02:49"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Black Sabbath",	"Year":2004,	"Album":"Master of Reality",	"Name":"Into the Void",	"Length":"06:12",	"Track":8,	"Composer":"Bill Ward/Geezer Butler/Ozzy Osbourne/Tony Iommi",	"Download Date":"1938/7/16",	"Last Played":"00:56:15"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":1993,	"Album":"Experience the Divine",	"Name":"From A Distance",	"Length":"04:39",	"Track":3,	"Composer":"Julie Gold",	"Download Date":"2029/2/25",	"Last Played":"21:14:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1957,	"Album":"Fret Works: Dowland & Villa-Lobos",	"Name":"Lachrimae Antiquae Galliard",	"Length":"02:59",	"Track":2,	"Composer":"John Dowland",	"Download Date":"1978/10/15",	"Last Played":"11:54:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Rock",	"Artist":"Dave Matthews",	"Year":1996,	"Album":"Crash",	"Name":"Let You Down",	"Length":"04:09",	"Track":8,	"Composer":"Dave Matthews",	"Download Date":"1906/1/5",	"Last Played":"20:20:38"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1958,	"Album":"Everybody Digs Bill Evans",	"Name":"Night and Day",	"Length":"07:35",	"Track":4,	"Composer":"Cole Porter",	"Download Date":"1953/5/20",	"Last Played":"10:24:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Black Sabbath",	"Year":2004,	"Album":"Black Sabbath",	"Name":"Black Sabbath",	"Length":"06:18",	"Track":1,	"Composer":"Bill Ward/Geezer Butler/Ozzy Osbourne/Tony Iommi",	"Download Date":"1908/7/24",	"Last Played":"16:38:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"Buddy Guy",	"Year":1993,	"Album":"Feels Like Rain",	"Name":"She's Nineteen Years Old",	"Length":"05:43",	"Track":4,	"Composer":"Muddy Waters",	"Download Date":"1971/2/24",	"Last Played":"01:01:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1978,	"Album":"Affinity",	"Name":"The Days of Wine and Roses",	"Length":"06:43",	"Track":4,	"Composer":"Henry Mancini, Johnny Mercer",	"Download Date":"1955/2/12",	"Last Played":"01:49:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Emerson, Lake & Palmer",	"Year":"",	"Album":"The Atlantic Years",	"Name":"The Endless Enigma (Part 1)",	"Length":"06:41",	"Track":7,	"Composer":"",	"Download Date":"1961/12/22",	"Last Played":"23:40:19"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Frank Sinatra",	"Year":1991,	"Album":"Sinatra Reprise: The Very Good Years",	"Name":"It Was A Very Good Year",	"Length":"04:29",	"Track":9,	"Composer":"E. Drake",	"Download Date":"1943/9/1",	"Last Played":"15:59:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Pop and R&B",	"Artist":"Joni Mitchell",	"Year":1974,	"Album":"Court And Spark",	"Name":"Help Me",	"Length":"03:22",	"Track":2,	"Composer":"Joni Mitchell",	"Download Date":"2013/12/5",	"Last Played":"09:59:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1965,	"Album":"Julian Bream Edition, Vol. 20",	"Name":"Bach: Lute Suite In A Minor, BWV 997 - Praeludium",	"Length":"03:06",	"Track":7,	"Composer":"Johann Sebastian Bach",	"Download Date":"2032/12/26",	"Last Played":"07:49:41"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1962,	"Album":"Interplay",	"Name":"You And The Night And The Music",	"Length":"07:05",	"Track":1,	"Composer":"Arthur Schwartz/Howard Dietz",	"Download Date":"2032/12/25",	"Last Played":"07:30:00"},
+		{"Heard": false, "Checked": "False", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1965,	"Album":"Julian Bream Edition, Vol. 20",	"Name":"Bach: Lute Suite In E Minor, BWV 996 - Sarabande",	"Length":"04:45",	"Track":4,	"Composer":"Johann Sebastian Bach",	"Download Date":"2017/1/6",	"Last Played":"05:54:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Charlie Hunter",	"Year":2004,	"Album":"Friends Seen and Unseen",	"Name":"One for the Kelpers",	"Length":"06:31",	"Track":1,	"Composer":"John Ellis",	"Download Date":"1988/6/13",	"Last Played":"09:22:30"},
+		{"Heard": true, "Checked": "True", "Genre":"Easy Listening",	"Artist":"Bette Midler",	"Year":2003,	"Album":"Bette Midler Sings the Rosemary Clooney Songbook",	"Name":"You'll Never Know",	"Length":"01:44",	"Track":1,	"Composer":"Warren, Harry 1893-1981 -w Gordon, Mac 1904-1959",	"Download Date":"1923/10/17",	"Last Played":"14:09:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Emerson, Lake & Palmer",	"Year":1992,	"Album":"The Atlantic Years",	"Name":"Tank",	"Length":"06:47",	"Track":4,	"Composer":"Carl Palmer/Keith Emerson",	"Download Date":"1996/11/14",	"Last Played":"00:36:34"},
+		{"Heard": true, "Checked": "True", "Genre":"Classic Rock",	"Artist":"Jimi Hendrix",	"Year":1968,	"Album":"Electric Ladyland",	"Name":"Come On, Pt. 1",	"Length":"04:10",	"Track":7,	"Composer":"Earl King",	"Download Date":"2008/3/1",	"Last Played":"14:48:45"},
+		{"Heard": true, "Checked": "True", "Genre":"World",	"Artist":"Andy Statman & David Grisman",	"Year":1995,	"Album":"Songs Of Our Fathers",	"Name":"Der Rebbe",	"Length":"03:59",	"Track":9,	"Composer":"Trad.",	"Download Date":"2021/5/21",	"Last Played":"11:45:56"},
+		{"Heard": true, "Checked": "True", "Genre":"Blues",	"Artist":"B.B. King",	"Year":2005,	"Album":"80",	"Name":"Early in the Morning",	"Length":"04:50",	"Track":1,	"Composer":"",	"Download Date":"2020/1/13",	"Last Played":"08:23:26"},
+		{"Heard": true, "Checked": "True", "Genre":"Classical",	"Artist":"Julian Bream",	"Year":1992,	"Album":"Nocturnal",	"Name":"Martin: Quatre Pièces Breves - 3. Plainte: Sans Lenteur",	"Length":"02:59",	"Track":3,	"Composer":"Frank Martin",	"Download Date":"1986/5/4",	"Last Played":"20:54:23"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Bill Evans",	"Year":1958,	"Album":"Everybody Digs Bill Evans",	"Name":"What Is There to Say?",	"Length":"04:54",	"Track":8,	"Composer":"Duke",	"Download Date":"1900/8/15",	"Last Played":"04:01:53"},
+		{"Heard": true, "Checked": "True", "Genre":"Jazz",	"Artist":"Andy Narell",	"Year":1989,	"Album":"Little Secrets",	"Name":"Don't Look Back",	"Length":"09:39",	"Track":6,	"Composer":"Andy Narell",	"Download Date":"1907/3/5",	"Last Played":"23:29:04"},
+		{"Heard": true, "Checked": "True", "Genre":"Progressive Rock",	"Artist":"Dixie dregs",	"Year":1978,	"Album":"What if",	"Name":"What if",	"Length":"05:02",	"Track":3,	"Composer":"Steve Morse",	"Download Date":"1992/3/28",	"Last Played":"00:22:30"}
+	];
+	var len = data_list.length;
+	var rounds = 1;
+	for(var i=0; i < rounds * len ; ++i){
+		data.items.push(dojo.mixin({'id': i+1 }, data_list[i%len]));
+	}
+	
+	if(!this.test_store_data){
+		this.test_store_data = [];
+	}
+	this.test_store_data.push(dojo.clone(data));
+	
+	if(!this.test_store){
+		this.test_store = [];
+	}
+	this.test_store.push(new dojo.data.ItemFileWriteStore({data: data}));
+})();
+
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid.html b/dojox/grid/tests/enhanced/test_enhanced_grid.html
deleted file mode 100644
index 011b3b9..0000000
--- a/dojox/grid/tests/enhanced/test_enhanced_grid.html
+++ /dev/null
@@ -1,181 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
-	"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<title>Test dojox.grid.EnhancedGrid</title>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
-	<style type="text/css">
-		@import "../../../../dojo/resources/dojo.css";
-		@import "../../../../dijit/themes/tundra/tundra.css";
-		@import "../../enhanced/resources/tundraEnhancedGrid.css";
-		@import "../../enhanced/resources/EnhancedGrid_rtl.css";
-		body {
-			font-size: 0.9em;
-			font-family: Geneva, Arial, Helvetica, sans-serif;
-			padding: 0.5em;
-		}
-		.title {
-			text-align:center;
-		}
-		
- 		#grid1, #grid2, #grid3 {
-			width: 85.2em;
-			height: 50em;
-		}
-
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
-	<script type="text/javascript">
-		dojo.require("dojox.grid.EnhancedGrid");
-		dojo.require("dojox.grid.enhanced.plugins.DnD");
-		dojo.require("dojox.grid.enhanced.plugins.Menu");
-		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
-		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
-		dojo.require("dojox.data.CsvStore");
-		dojo.require("dojo.parser");
-	</script>
-	<script type="text/javascript">
-		var layout = [{
-			defaultCell: { width: 8, editable: false, type: dojox.grid.cells._Widget },
-			rows:
-			[
-				{ field: "Genre", width: '6'},
-				{ field: "Artist", width: '10'},
-				{ field: "Year", width: '6'},
-				{ field: "Album", width: '12'},
-				{ field: "Name", width: '17'},
-				{ field: "Length", width: '6'},
-				{ field: "Track", width: '6'},
-				{ field: "Composer", width: '15'}				
-			]}
-		];
-
-		var csvStore1 = new dojox.data.CsvStore({id:'csvStore1', url:"support/music-for-demo.part.csv"});
-		
-		/* Un-comment this block to see more usages
-		var layout2 = [
-			[
-				{ field: "Genre", width: '10'},
-				{ field: "Artist", width: '10'},
-				{ field: "Year", width: '10'},
-				{ field: "Album", width: '15'},
-				{ field: "Name", width: '15'},
-				{ field: "Length", width: '10'},
-				{ field: "Track", width: '10'},
-				{ field: "Composer", width: '10'}				
-			]
-		];
-		dojo.addOnLoad(function(){
-			var grid = new dojox.grid.EnhancedGrid({
-				id: "grid3",
-				store: csvStore1,
-				structure: layout,
-				rowSelector: '20px',
-				plugins : {nestedSorting: true, dnd: true, indirectSelection: {name: "Selection", width:"70px", styles:"text-align: center;"}, menus:{headerMenu:"headerMenu", rowMenu:"rowMenu", cellMenu:"cellMenu", selectedRegionMenu:"selectedRegionMenu"}}
-			}, dojo.byId('gridDiv'));
-			grid.startup();
-		});
-		*/
-	</script>
-	<script type="text/javascript" src="support/test_ue.js"></script>
-</head>
-<body class="tundra">
-	<h1 class="title">Test dojox.grid.EnhancedGrid Phase 1 Features</h1>
-	<div>
-		<b>EnhancedGrid phase 1 provides the following features:</b>
-		<ol>
-			<li>Nested Sorting</li>
-			<li>Built-in support for Indirect Selection (radio buttons and check boxes)</li>
-			<li>Declarative context menu</li>
-			<li>Selecting rows/columns via swipe</li>
-			<li>Drag-n-drop: columns,rows - MOVE</li>
-		</ol>
-	</div>
-	
-	<div>
-		<b>Keyboard support:</b>
-		<ol>
-			<li>Use <b>TAB or SHIFT + TAB</b> to navigate keyboard focus among column headers, row headers and cell regions</li>
-			<li>When focus is on column header:<br>
-				<ol style="list-style: none;">
-					<li> - Use <b>LEFT/RIGHT</b> to navigate keyboard focus among column headers </li>
-					<li> - Use <b>SPACE</b> to choose a column or sorting choice</li>
-					<li> - Use <b>SHIFT + LEFT/RIGHT</b> to select multiple columns</li>
-					<li> - Use <b>CTRL + LEFT/RIGHT</b> to move columns</li>
-				</ol>
-			</li>
-			<li>When focus is on row header or column of checkbox:<br>
-				<ol style="list-style: none;">
-					<li> - Use <b>UP/DOWN</b> to navigate keyboard focus among row headers </li>
-					<li> - Use <b>SPACE</b> to choose a row</li>
-					<li> - Use <b>SHIFT + UP/DOWN</b> to select multiple rows</li>
-					<li> - Use <b>CTRL + UP/DOWN</b> to move rows</li>
-				</ol>
-			</li>
-		</ol>
-	</div>
-	
-	<div>
-		<b>Some known issues (plan to fix in phase 2):</b>
-		<ol>	
-			<li>EnhancedGrid doesn't support complicated layout(e.g. multiple rows in column header), TreeGrid(SubGrid).</li>
-		</ol>
-	</div>
-	<!--span dojoType="dojox.data.CsvStore" 
-		jsId="csvStore1" url="support/music-for-demo.part.csv">
-	</span-->
-	<div>
-		<b>
-		    Multiple selection mode:
-		</b>
-		<div id="grid1" dojoType="dojox.grid.EnhancedGrid" query="{ Track: '*' }" rowsPerPage="30" 
-			plugins='{nestedSorting: true, dnd: true, indirectSelection: true, menus:{headerMenu:"headerMenu", rowMenu:"rowMenu", cellMenu:"cellMenu", selectedRegionMenu:"selectedRegionMenu"}}'
-			store="csvStore1" structure="layout" rowSelector="20px">
-			<div dojoType="dijit.Menu" id="headerMenu"  style="display: none;">
-				<div dojoType="dijit.MenuItem">Header Menu Item 1</div>
-				<div dojoType="dijit.MenuItem">Header Menu Item 2</div>
-				<div dojoType="dijit.MenuItem">Header Menu Item 3</div>
-				<div dojoType="dijit.MenuItem">Header Menu Item 4</div>
-			</div>
-			<div dojoType="dijit.Menu" id="rowMenu"  style="display: none;">
-				<div dojoType="dijit.MenuItem">Row Menu Item 1</div>
-				<div dojoType="dijit.MenuItem">Row Menu Item 2</div>
-				<div dojoType="dijit.MenuItem">Row Menu Item 3</div>
-				<div dojoType="dijit.MenuItem">Row Menu Item 4</div>
-			</div>
-			<div dojoType="dijit.Menu" id="cellMenu"  style="display: none;">
-				<div dojoType="dijit.MenuItem">Cell Menu Item 1</div>
-				<div dojoType="dijit.MenuItem">Cell Menu Item 2</div>
-				<div dojoType="dijit.MenuItem">Cell Menu Item 3</div>
-				<div dojoType="dijit.MenuItem">Cell Menu Item 4</div>
-			</div>
-			<div dojoType="dijit.Menu" id="selectedRegionMenu"  style="display: none;">
-				<div dojoType="dijit.MenuItem">Action 1 for Selected Region</div>
-				<div dojoType="dijit.MenuItem">Action 2 for Selected Region</div>
-				<div dojoType="dijit.MenuItem">Action 3 for Selected Region</div>
-				<div dojoType="dijit.MenuItem">Action 4 for Selected Region</div>
-			</div>
-		</div>
-		<br/>
-		<input type='button' value='Select All' onclick='dijit.byId("grid1").rowSelectCell.toggleAllSelection(true)'/>
-		  
-		<input type='button' value='Deselect All' onclick='dijit.byId("grid1").rowSelectCell.toggleAllSelection(false)'/>
-	</div>
-	
-	<!-- Un-comment this block to see more usages
-	<div id="gridDiv"></div>
-	
-	<div>
-		<b>
-		    Single selection mode:
-		</b>
-		<div id="grid2" dojoType="dojox.grid.EnhancedGrid" query="{ Track: '*' }" rowsPerPage="30" selectionMode="single"
-			plugins='{nestedSorting: true, dnd: true, indirectSelection: {name: "Selection", width:"60px", styles:"text-align: center;"}, menus:{headerMenu:"headerMenu", rowMenu:"rowMenu", cellMenu:"cellMenu", selectedRegionMenu:"selectedRegionMenu"}}'
-			store="csvStore1" structure="layout" rowSelector="20px"  
-		</div>
-	</div>
-	-->
-
-</body>
-</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html b/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html
new file mode 100644
index 0000000..9cd5545
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_cellmerge.html
@@ -0,0 +1,242 @@
+<!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>Test CellMerge plugin of dojox.grid.EnhancedGrid</title>
+		<link rel=stylesheet href="support/common.css"/>
+		<style type="text/css">
+			body {
+				font-size: 0.9em;
+				font-family: Geneva, Arial, Helvetica, sans-serif;
+				padding: 0.5em;
+			}
+			.title {
+				text-align:center;
+				margin:1em;
+			}
+			.container {
+				display: block;
+				border: 3px solid #ccc;
+				padding: 1em 3em; 
+				cursor: default;
+				radius: 8pt;
+				background: #fff;
+				-moz-border-radius: 8pt 8pt;
+				display:inline-block;
+			}
+			table.merged th{
+				font-weight:bolder;
+			}
+			table.merged td{
+				text-align:center;
+			}
+			#grid{
+				margin-bottom: 30px;
+	 			width: 80em;
+				height: 30em;
+			}
+			/*Sample - overwrite default cell style
+			.claro .dojoxGridCell{
+				border-color: transparent #D5CDB5 #D5CDB5 transparent !important;
+			}
+			.dj_ie6 .claro .dojoxGridCell{
+				border: 1px solid #F1F1F1 !important;
+			}*/
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: true"></script>
+		<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+		<script type="text/javascript" src="support/test_write_store_music.js"></script>
+		<script type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("dijit.form.CheckBox");
+			dojo.require("dojox.grid.EnhancedGrid");
+			dojo.require("dojox.grid.enhanced.plugins.CellMerge");
+			
+			var layout = [{
+				cells: [
+					{ field: "id", name:"Identity", datatype:"number", width: 4, editable: false},
+					{ 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},
+					{ field: "Album", name:"Album", datatype:"string", width: 10},
+					{ field: "Name", name:"Name", datatype:"string", width: 8},
+					{ field: "Length", name:"Length", datatype:"string", width: 4},
+					{ field: "Track", name:"Track", datatype:"number", width: 3},
+					{ field: "Composer", name:"Composer", datatype:"string", width: 12},
+					{ field: "Download Date", name:"Download Date", datatype:"date", width: 12},
+					{ field: "Last Played", name:"Last Played", datatype:"time", width: 6},
+					{ field: "Heard", name: "Checked", datatype:"boolean", width: 6}
+				]
+			}];
+			var plugins = {
+				cellMerge: {
+					"mergedCells": [
+						{row: 0, start: 0, end: 5, major: 2}
+					]
+				}
+			};
+			
+			var mergedCellHandles = [];
+			var lastChild = null;
+			function updateMergedCells(){
+				mergedCellHandles = [];
+				var grid = dijit.byId("grid");
+				var res = ["<tbody>"];
+				var mergedCells = grid.getMergedCells();
+				dojo.forEach(mergedCells, function(item, i){
+					mergedCellHandles.push(item.handle);
+					res.push("<tr><td>", item.row,
+						"</td><td>", item.start + 1,
+						"</td><td>", item.end + 1,
+						"</td><td>", item.major + 1,
+						"</td><td><button onclick=\"unmergeCells(",i,")\">Unmerge</button>",
+						"</td></tr>"
+					);
+				});
+				res.push("</tbody>");
+				lastChild && dojo.byId("tblMergedCells").removeChild(lastChild);
+				lastChild = dojo._toDom(res.join(''));
+				dojo.byId("tblMergedCells").appendChild(lastChild);
+			};
+			function mergeCells(){
+				var rowIndex = parseInt(dojo.byId("inputRow").value, 10);
+				var start = parseInt(dojo.byId("inputStart").value, 10);
+				var end = parseInt(dojo.byId("inputEnd").value, 10);
+				var major = parseInt(dojo.byId("inputMajor").value, 10);
+				var grid = dijit.byId("grid");
+				grid.mergeCells(rowIndex, start, end, major);
+				updateMergedCells();
+			};
+			function unmergeCells(handleIdx){
+				dijit.byId("grid").unmergeCells(mergedCellHandles[handleIdx]);
+				updateMergedCells();
+			};
+			var mergeByIndexHandle;
+			function toggleMergeByIndex(){
+				var grid = dijit.byId("grid");
+				if(mergeByIndexHandle){
+					grid.unmergeCells(mergeByIndexHandle);
+					mergeByIndexHandle = null;
+				}else{
+					mergeByIndexHandle = grid.mergeCells(function(rowIndex){
+						return rowIndex % 2;
+					}, 1, 3, 2);
+				}
+			}
+			var mergeByIdHandle;
+			function toggleMergeById(){
+				var grid = dijit.byId("grid");
+				if(mergeByIdHandle){
+					grid.unmergeCells(mergeByIdHandle);
+					mergeByIdHandle = null;
+				}else{
+					mergeByIdHandle = grid.mergeCells(function(rowIndex, item, store){
+						if(item){
+							var id = parseInt(store.getIdentity(item), 10);
+							return !(id % 2);
+						}
+						return false;
+					}, 4, 6, 5);
+				}
+			}
+			dojo.addOnLoad(updateMergedCells);
+		</script>
+	</head>
+	<body class="claro">
+		<h1 class="title">dojox.grid.EnhancedGrid - Cell Merge</h1>
+		<div id="gridContainer">
+			<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+		</div><br/>
+		<div class="container">
+			<table>
+				<tr>
+					<td>At row (0 based)</td>
+					<td><input id="inputRow" type="text" value="5" size="3"/></td>
+				</tr>
+				<tr>
+					<td>From column</td>
+					<td><select id="inputStart">
+						<option value="0">1</option>
+						<option value="1">2</option>
+						<option value="2" selected="true">3</option>
+						<option value="3">4</option>
+						<option value="4">5</option>
+						<option value="5">6</option>
+						<option value="6">7</option>
+						<option value="7">8</option>
+						<option value="8">9</option>
+						<option value="9">10</option>
+						<option value="10">11</option>
+					</select></td>
+					<td>To column</td>
+					<td><select id="inputEnd">
+						<option value="0">1</option>
+						<option value="1">2</option>
+						<option value="2">3</option>
+						<option value="3">4</option>
+						<option value="4">5</option>
+						<option value="5">6</option>
+						<option value="6">7</option>
+						<option value="7" selected="true">8</option>
+						<option value="8">9</option>
+						<option value="9">10</option>
+						<option value="10">11</option>
+					</select></td>
+				</tr>
+				<tr>
+					<td>Use data of column</td>
+					<td><select id="inputMajor">
+						<option value="0">1</option>
+						<option value="1">2</option>
+						<option value="2">3</option>
+						<option value="3" selected="true">4</option>
+						<option value="4">5</option>
+						<option value="5">6</option>
+						<option value="6">7</option>
+						<option value="7">8</option>
+						<option value="8">9</option>
+						<option value="9">10</option>
+						<option value="10">11</option>
+						<option value="">(Use Default)</option>
+					</select></td>
+				</tr>
+				<tr>
+					<td colspan="2"><button onclick="mergeCells()">Merge Cells by Index</button></td>
+				</tr>
+			</table>
+			<h3>The Merged Cells</h3>
+			<table id="tblMergedCells" class="merged" cellpadding="1px" cellspacing="5px">
+				<thead><tr>
+					<th>
+						Row Index
+					</th>
+					<th>
+						Start Column
+					</th>
+					<th>
+						End Column
+					</th>
+					<th>
+						Major Column
+					</th>
+				</tr></thead>
+			</table>
+		</div>
+		<br />
+		<div class="container">
+			<div id="cb1" dojoType="dijit.form.CheckBox" onChange="toggleMergeByIndex()"></div><label for="cb1">Merge/Unmerge every second row by index</label><br />
+			<div id="cb2" dojoType="dijit.form.CheckBox" onChange="toggleMergeById()"></div><label for="cb2">Merge/Unmerge every second row by Identity</label>
+		</div>
+		
+		<h3>Notes:</h3>
+		<ul>
+			<li>Cells can be merged at both design- and run-time.</li>
+			<li>Cell merging is done only in grid UI; the data store is not affected.</li>
+			<li>Column sorting and cell merging by index are incompatible, because sorting is store's job, while merging is grid's job, and after sorting, grid can not get the mapping between the new row order and the old one.)</li>
+			<li>Column sorting and merging by id are compatible.</li>
+			<li>To get currently merged cells, use grid.getMergedCells();</li>
+			<li>The merged cell will use as default the content of the cell at the leading edge, if major cell is not indicated.</li>
+		</ul>
+		<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+	</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_claro.html b/dojox/grid/tests/enhanced/test_enhanced_grid_claro.html
deleted file mode 100644
index 63a5f7a..0000000
--- a/dojox/grid/tests/enhanced/test_enhanced_grid_claro.html
+++ /dev/null
@@ -1,70 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
-	"http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-	<title></title>
-	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
-	<style type="text/css">
-		@import "../../../../dojo/resources/dojo.css";
-		@import "../../../../dijit/themes/claro/claro.css";		
-		@import "../../enhanced/resources/claroEnhancedGrid.css";
-		body {
-			font-size: 0.9em;
-			padding: 0.5em;
-		}
-		.title {
-			padding-top: 1em;
-			padding-bottom: 0.5em;
-			font-weight:bold;
-		}
-		
- 		#grid1,#grid2,#grid3,#grid4{
-			width: 78em;
-			height: 40em;
-		}
-
-	</style>
-	<script type="text/javascript" src="../../../../dojo/dojo.js" 
-		djConfig="isDebug:true, parseOnLoad: true"></script>
-	<script type="text/javascript">
-		dojo.require("dojox.grid.EnhancedGrid");
-		dojo.require("dojox.grid.enhanced.plugins.DnD");
-		dojo.require("dojox.grid.enhanced.plugins.Menu");
-		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
-		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
-		dojo.require("dojox.data.CsvStore");
-		dojo.require("dojo.parser");
-	</script>
-	<script type="text/javascript">
-		var layout = [{
-			defaultCell: { width: 8, editable: false, type: dojox.grid.cells._Widget },
-			rows:
-			[
-				{ field: "Genre", width: '6'},
-				{ field: "Artist", width: '10'},
-				{ field: "Year", width: '6'},
-				{ field: "Album", width: '12'},
-				{ field: "Name", width: '17'},
-				{ field: "Length", width: '6'},
-				{ field: "Track", width: '6'},
-				{ field: "Composer", width: '15'}				
-			]}
-		];
-		var csvStore1 = new dojox.data.CsvStore({id:'csvStore1', url:"support/music-for-demo.part.csv"});
-	</script>
-	<script type="text/javascript" src="support/test_ue.js"></script>
-</head>
-<body class="claro">
-	<div class="title">Simple DataGrid</div>
-	<div id="grid1" dojoType="dojox.grid.EnhancedGrid" query="{ Track: '*' }" rowsPerPage="30"
-		 store="csvStore1" structure="layout" rowSelector="0px">
-	</div>
-
-	<br/>
-	<div class="title">Enhanced Grid</div>
-	<div id="grid3" dojoType="dojox.grid.EnhancedGrid" query="{ Track: '*' }" rowsPerPage="30"
-		plugins='{nestedSorting: true, dnd: true, indirectSelection: {width:"40px"}}'
-		store="csvStore1" structure="layout" rowSelector="20px">
-	</div>	
-</body>
-</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html b/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
new file mode 100644
index 0000000..e3c218e
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_cookie.html
@@ -0,0 +1,88 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test Cookie plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+ 		#grid{
+ 			width: 100em;
+			height: 30em;
+		}
+		/*Sample - overwrite default cell style
+		.claro .dojoxGridCell{
+			border-color: transparent #D5CDB5 #D5CDB5 transparent !important;
+		}
+		.dj_ie6 .claro .dojoxGridCell{
+			border: 1px solid #F1F1F1 !important;
+		}*/
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+		dojo.require("dojox.grid.enhanced.plugins.DnD");
+		dojo.require("dojox.grid.enhanced.plugins.Cookie");
+		
+		var layout = [
+			{//first view
+				defaultCell: {editable: true, type: dojox.grid.cells._Widget},
+				cells:
+				[
+					{ field: "id", width: 4},
+					{ field: "Genre", width: '5'},
+					{ field: "Artist", width: '5'},
+					{ field: "Year", width: '5'},
+					{ field: "Album", width: '5'}
+				]
+			},
+			{//second view
+				cells:
+				[
+					{ field: "Name", width: '17'},
+					{ field: "Length", width: '6'},
+					{ field: "Track", width: '6'},
+					{ field: "Composer", width: '15'}
+				]
+			}
+		];
+		var plugins = {
+			cookie: true,
+			nestedSorting: true,
+			dnd: true
+		};
+		function enableCookie(key, toEnable){
+			console.log(key,toEnable);
+			dijit.byId("grid").setCookieEnabled(key || toEnable, toEnable);
+		}
+		
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - Cookie</h1>
+	<div style="margin:10px;">
+		<h3>Options to persist preferences when refreshing the page:</h3><br/>
+		<input type="checkbox" onclick="enableCookie(null, !this.checked)"> Do not persist anything<br />
+		<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 />
+	</div>
+	<div id="gridContainer">
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+	</div><br/>
+	<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html b/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html
new file mode 100644
index 0000000..cfcb564
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_dnd.html
@@ -0,0 +1,294 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>Test Dnd plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		@import "/dojo/tests/dnd/dndDefault.css";
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+		.container {
+			display: block;
+			border: 3px solid #ccc;
+			padding: 1em 3em; 
+			cursor: default;
+			radius: 8pt;
+			background: #fff;
+			-moz-border-radius: 8pt 8pt;
+		}
+		.myblock{
+			float: left;
+			margin: 10px;
+			margin-top: 0;
+		}
+		.cfgtable th,
+		.cfgtable td{
+			font-weight: bolder;
+			padding: 5px;
+		}
+		h3{
+			margin: 0;
+		}
+ 		#grid1, #grid2{
+			margin-bottom: 0px;
+ 			width: 50em;
+			height: 30em;
+		}
+		/*Sample - overwrite default cell style
+		.claro .dojoxGridCell{
+			border-color: transparent #D5CDB5 #D5CDB5 transparent !important;
+		}
+		.dj_ie6 .claro .dojoxGridCell{
+			border: 1px solid #F1F1F1 !important;
+		}*/
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojox.data.AtomReadStore");
+		dojo.require("dojox.data.XmlStore");
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.Selector");
+		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+		dojo.require("dojox.grid.enhanced.plugins.DnD");
+		dojo.require("dojox.grid.enhanced.plugins.GridSource");
+		dojo.require("dojo.dnd.Source");
+		dojo.require("dijit.form.CheckBox");
+	</script>
+	<script type="text/javascript" src="support/test_write_store_dnd.js"></script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		var layout1 = [{
+			defaultCell: {width: 5},
+			rows: [
+				{field: "A"},
+				{field: "B"},
+				{field: "C"},
+				{field: "D"},
+				{field: "E"},
+				{field: "F"},
+				{field: "G", hidden: true},
+				{field: "H", hidden: true},
+				{field: "I", hidden: true},
+				{field: "J"},
+				{field: "K"},
+				{field: "L"},
+				{field: "M"},
+				{field: "N"},
+				{field: "O"},
+				{field: "P"},
+				{field: "Q"},
+				{field: "R"},
+				{field: "S"},
+				{field: "T"},
+				{field: "U"},
+				{field: "V"},
+				{field: "W"},
+				{field: "X"},
+				{field: "Y"},
+				{field: "Z"}
+			]
+		}];
+		var layout2 = [
+		{//first view
+			rows:
+			[
+				{ field: "Genre", width: '6'},
+				{ field: "Artist", width: '5'},
+				{ field: "Year", width: '6'},
+				{ field: "Album", width: '12'},
+				{ field: "Name", width: '17', hidden: true},
+				{ field: "Length", width: '6'},
+				{ field: "Track", width: '6'},
+				{ field: "Composer", width: '15'},
+				{ field: "Download Date", width: '10'},
+				{ field: "Last Played", width: '10'}
+			]
+		}
+		];
+		var store_copy = new dojo.data.ItemFileWriteStore({
+			data: test_store_data[0]
+		});
+		var setIdentifierForNewItem = function(item, store, index){
+			console.log("setIdentifierForNewItem", index);
+			var attrs = store.getIdentityAttributes(item);
+			for(var i = attrs.length - 1; i >= 0; --i){
+				item[attrs[i]] = index + (new Date()).getTime();
+			}
+			return item;
+		};
+		var setDnDConfig = function(gridId, type, mode, selected){
+			var config = {};
+			config[type] = {};
+			config[type][mode] = selected;
+			dijit.byId(gridId).setupDnDConfig(config);
+		};
+		var setCopyOnly = function(gridId, selected){
+			dijit.byId(gridId).dndCopyOnly(selected);
+		};
+		var getRowData = function(grid, rowIndexes){
+			var cells = grid.layout.cells;
+			var store = grid.store;
+			var cache = grid._by_idx;
+			var res = "Grid Rows from " + grid.id + ":<br/>";
+			for(var i = 0; i < rowIndexes.length; ++i){
+				var r = rowIndexes[i];
+				res += "Row " + r + ": ";
+				for(var j = 0; j < cells.length; ++j){
+					if(!cells[j].hidden){
+						res += store.getValue(cache[r].item, cells[j].field) + ", ";
+					}
+				}
+				res = res.substring(0, res.length - 2) + ";<br/>";
+			}
+			return res;
+		};
+		dojo.addOnLoad(function(){
+			dojo.query("input.cfgbox").forEach(function(cb){
+				cb.checked = true;
+			});
+			dojo.query("input.copyonlyCBox").forEach(function(cb){
+				cb.checked = false;
+			});
+		});
+		var newItem1 = {A: "new a1", B: "new b1", C: "new c1", D: "new d1",E: "new e1",F: "new f1",G: "new g1",H: "new h1",I: "new i1",J: "new j1",K: "new k1",L: "new l1",M: "new m1",N: "new n1",O: "new o1",P: "new c1",Q: "new q1",R: "new r1",S: "new s1",T: "new t1",U: "new u1",V: "new v1",W: "new w1",X: "new x1",Y: "new y1",Z: "new z1"};
+		var newItem2 = {A: "new a2", B: "new b2", C: "new c2", D: "new d2",E: "new e2",F: "new f2",G: "new g2",H: "new h2",I: "new i2",J: "new j2",K: "new k2",L: "new l2",M: "new m2",N: "new n2",O: "new o2",P: "new c2",Q: "new q2",R: "new r2",S: "new s2",T: "new t2",U: "new u2",V: "new v2",W: "new w2",X: "new x2",Y: "new y2",Z: "new z2"};
+		var newItem3 = {A: "new a3", B: "new b3", C: "new c3", D: "new d3",E: "new e3",F: "new f3",G: "new g3",H: "new h3",I: "new i3",J: "new j3",K: "new k3",L: "new l3",M: "new m3",N: "new n3",O: "new o3",P: "new c3",Q: "new q3",R: "new r3",S: "new s3",T: "new t3",U: "new u3",V: "new v3",W: "new w3",X: "new x3",Y: "new y3",Z: "new z3"};
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - DnD</h1>
+	<div class="myblock">
+		<h3>Grid 1</h3>
+		<div id="grid1" dojoType="dojox.grid.EnhancedGrid" rowsPerPage="16"
+			canSort="false",
+			plugins='{
+				dnd: {
+					"setIdentifierForNewItem": setIdentifierForNewItem, copyOnly: true,
+					"dndConfig": {
+					}
+				}
+			}' store="test_store[0]" structure="layout1" rowSelector="20px">
+		</div>
+	</div>
+	<div class="myblock">
+		<h3>Grid 2</h3>
+		<div id="grid2" dojoType="dojox.grid.EnhancedGrid" rowsPerPage="16"
+			canSort="false",
+			plugins='{
+				dnd: {
+					"setIdentifierForNewItem": setIdentifierForNewItem,
+					"dndConfig": {
+					}
+				}
+			}' store="store_copy" structure="layout1" rowSelector="20px">
+		</div>
+	</div>
+	<div class="myblock">
+		<h3>Grid 1 Configuration</h3>
+		<label style="font-weight: bolder;">Copy Only</label><input class="copyonlyCBox" type="checkbox" onchange="setCopyOnly('grid1', this.checked)" />
+		<table class="cfgtable" border="1">
+			<thead>
+				<tr>
+					<th>Drag</th>
+					<th>Within</th>
+					<th>In</th>
+					<th>Out</th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr>
+					<td>Rows</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'row', 'within', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'row', 'in', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'row', 'out', this.checked)"/></td>
+				</tr>
+				<tr>
+					<td>Columns</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'col', 'within', this.checked)"/></td>
+					<td>Not implemented</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'col', 'out', this.checked)"/></td>
+				</tr>
+				<tr>
+					<td>Cells</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'cell', 'within', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'cell', 'in', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid1', 'cell', 'out', this.checked)"/></td>
+				</tr>
+			</tbody>
+		</table>
+	</div>
+	<div class="myblock">
+		<h3>Grid 2 Configuration</h3>
+		<label style="font-weight: bolder;">Copy Only</label><input class="copyonlyCBox" type="checkbox" onchange="setCopyOnly('grid2', this.checked)" />
+		<table class="cfgtable" border="1">
+			<thead>
+				<tr>
+					<th>Drag</th>
+					<th>Within</th>
+					<th>In</th>
+					<th>Out</th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr>
+					<td>Rows</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'row', 'within', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'row', 'in', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'row', 'out', this.checked)"/></td>
+				</tr>
+				<tr>
+					<td>Columns</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'col', 'within', this.checked)"/></td>
+					<td>Not implemented</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'col', 'out', this.checked)"/></td>
+				</tr>
+				<tr>
+					<td>Cells</td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'cell', 'within', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'cell', 'in', this.checked)"/></td>
+					<td><input type="checkbox" class="cfgbox" onchange="setDnDConfig('grid2', 'cell', 'out', this.checked)"/></td>
+				</tr>
+			</tbody>
+		</table>
+	</div>
+	<div class="myblock" style="clear: left;">
+		<h3>Ordinary Target (Can not accept grid contents)</h3>
+		<div dojoType="dojo.dnd.Source" class="container">
+			<div class="dojoDndItem">Item <strong>X</strong></div>
+			<div class="dojoDndItem">Item <strong>Y</strong></div>
+			<div class="dojoDndItem">Item <strong>Z</strong></div>
+		</div>
+	</div>
+	<div class="myblock">
+		<h3>Target that can accept Grid</h3>
+		<div dojoType="dojox.grid.enhanced.plugins.GridSource" class="container" 
+			insertNodesForGrid="true" getRowContent="getRowData">
+			<div class="dojoDndItem">Item 1</div>
+			<div class="dojoDndItem">Item 2</div>
+			<div class="dojoDndItem">Item 3</div>
+		</div>
+	</div>
+	<div class="myblock">
+		<h3>Grid Acceptable Source (Drag item to grid)</h3>
+		<div dojoType="dojo.dnd.Source" class="container">
+			<div class="dojoDndItem" dndType="grid/rows" dndData="newItem1">Item 1</div>
+			<div class="dojoDndItem" dndType="grid/rows" dndData="newItem2">Item 2</div>
+			<div class="dojoDndItem" dndType="grid/rows" dndData="newItem3">Item 3</div>
+		</div>
+	</div>
+	<p style="clear: left;"><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html b/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html
new file mode 100644
index 0000000..5688a02
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_filter.html
@@ -0,0 +1,107 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>Test Filter plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding-right: 10em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+ 		#grid{
+			width: 100em;
+			height: 30em;
+		}
+	</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>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.Filter");
+		
+		var layout = [{//--------------------------------------------------------------------------0
+			defaultCell: {
+				editable: true, sortDesc: true, type: dojox.grid.cells._Widget,
+				//Use ComboBox instead of TextBox when setting filter for string columns
+				autoComplete:true
+			},
+			cells:
+			[
+				//5 kinds of datatype: string, number, date, time, boolean
+				{ field: "id", name:"Index", datatype:"number", width: 2.5, editable: false},
+				{ 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},
+				{ field: "Album", name:"Album", datatype:"string", width: 10,
+					dataTypeArgs: {
+					//turn off autoComplete for the ComboBox, but still use the suggestions.
+						autoComplete: false
+					}
+				},
+				{ field: "Name", name:"Name", datatype:"string", width: 8,
+					//Disable some filter conditions for this column 
+					disabledConditions: [
+						"contains", "notcontains"
+					]
+				},
+				{ field: "Length", name:"Length", datatype:"string", width: 4},
+				{ field: "Track", name:"Track", datatype:"number", width: 3},
+				{ field: "Composer", name:"Composer", datatype:"string", width: 12},
+				{ field: "Download Date", name:"Download Date", datatype:"date", width: 8, editable: false,
+					dataTypeArgs: {
+					//Tell the DateTextBox how to parse the store data
+						datePattern: "yyyy/M/d"
+					}
+				},
+				{ field: "Last Played", name:"Last Played", datatype:"time", width: 6, editable: false,
+					dataTypeArgs: {
+					//Tell the TimeTextBox how to parse the store data
+						timePattern: "HH:mm:ss"
+					}
+				},
+				{ field: "Heard", name: "Checked", datatype:"boolean", width: 6,
+					type: dojox.grid.cells._Widget, 
+					widgetClass: dijit.form.CheckBox
+				},
+				{ field: "Checked", name:"Checked (Customized Label)", 
+					type: dojox.grid.cells._Widget, 
+					widgetClass:dijit.form.CheckBox,
+					datatype:"boolean", width: 15, 
+					dataTypeArgs: {
+					//Define what does true/false mean here
+						trueLabel: "This sounds like a very old song.",
+						falseLabel: "Never heard of this song."
+					}
+				}
+			]
+		}];
+		var plugins = {
+			filter: {
+				itemsName: 'songs',
+				closeFilterbarButton: true,
+				ruleCount: 8
+			}
+		};
+		dojo.ready(function(){
+			dojo.connect(dijit.byId("grid"), "onFilterDefined", function(rules, rel){
+				console.log("Filter changed: ", rules, rel);
+			});
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - Filter</h1>
+	<div id="gridContainer">
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+	</div><br/>
+	<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html b/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html
new file mode 100644
index 0000000..a4e909a
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_indirectSelection.html
@@ -0,0 +1,105 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test IndirectSelection plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+		}
+ 		#grid1, #grid2 {
+			width: 85.2em;
+			height: 50em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+			var data = {
+				identifier: 'id',
+				label: 'id',
+				items: []
+			};
+			var data_list = [ 
+				{ col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10, col7: false },
+				{ col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7: false },
+				{ col1: "important", col2: false, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true },
+				{ col1: "note", col2: false, col3: "read", col4: 'However the reserved characters', col5: 15.63, col6: 0, col7: true },
+				{ col1: "normal", col2: false, col3: "replied", col4: 'It is therefore necessary', col5: 24.22, col6: 5.50, col7: true },
+				{ col1: "important", col2: false, col3: "replied", col4: 'To problems of corruption by', col5: 9.12, col6: -3, col7: true },
+				{ col1: "note", col2: false, col3: "replied", col4: 'Which would simply be awkward in', col5: 12.15, col6: -4, col7: false }
+			];
+			var rows = 300;
+			for(var i=0, l=data_list.length; i<rows; i++){
+				data.items.push(dojo.mixin({ id: i }, data_list[i%l]));
+			}
+		
+			// global var "test_store"
+			test_store = new dojo.data.ItemFileWriteStore({data: data});
+		
+			var layout = [[
+				{name: 'Column 1', field: 'id'},
+				{name: 'Column 2', field: 'col2'},
+				{name: 'Column 3', field: 'col3'},
+				{name: 'Column 4', field: 'col4', width: "150px"},
+				{name: 'Column 5', field: 'col5'},
+				{name: 'Column 6', field: 'col6'},
+				{name: 'Column 7', field: 'col7'},
+				{name: 'Column 8', field: 'col5'}
+			]];
+			
+			dojo.addOnLoad(function(){
+				grid = new dojox.grid.EnhancedGrid({
+					id: "grid1",
+					store: test_store,
+					structure: layout,
+					rowSelector: "20px",
+					plugins: {indirectSelection: {headerSelector:true, name: "Selection", width: "60px", styles: "text-align: center;"}}
+				});
+
+				dojo.byId("gridDiv").appendChild(grid.domNode);
+				grid.startup();
+			});
+		
+		var disabled = false;
+		function toggleDisabled(id){
+			disabled = !disabled;
+			for(var i = 0; i < rows; i++){				
+				dijit.byId(id).rowSelectCell.setDisabled(i, disabled);
+			}
+		}
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - IndirectSelection</h1>
+	<p>
+		<b>Multiple selection mode:</b>
+		<div id="gridDiv"></div><br/>
+		<input type='button' value='Select All' onclick='dijit.byId("grid1").rowSelectCell.toggleAllSelection(true)'/>  
+		<input type='button' value='Deselect All' onclick='dijit.byId("grid1").rowSelectCell.toggleAllSelection(false)'/>  
+		<input type='button' value='Toggle Disabled All' onclick='toggleDisabled("grid1")'/><br/><br/>	</p>
+	<p>
+		<b>
+		    Single selection mode:
+		</b>
+		<div id="grid2" dojoType="dojox.grid.EnhancedGrid" rowsPerPage="30" selectionMode="single"
+			plugins='{indirectSelection: {name: "Selection", width:"60px", styles:"text-align: left;"}}'
+			store="test_store" structure="layout" rowSelector="20px">
+		</div>
+	</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html
new file mode 100644
index 0000000..e9dbd91
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_programmatic.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<title>dojox.grid.EnhancedGrid Leak Test Programmatic</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+		<link rel=stylesheet href="support/common.css"/>
+		<style type="text/css">
+			body {
+				font-size: 0.9em;
+				font-family: Geneva, Arial, Helvetica, sans-serif;
+				padding: 0.5em;
+			}
+			.title {
+				text-align:center;
+			}
+			
+	 		#grid {
+	 			border: 1px solid #333;
+				width: 85.2em;
+				height: 50em;
+			}
+	
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" 
+			djConfig="isDebug:true, parseOnLoad: true"></script>
+		<script type="text/javascript">
+			dojo.require("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dojox.grid.EnhancedGrid");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.parser");
+			dojo.require("dojox.grid.enhanced.plugins.Filter");
+			dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+			dojo.require("dojox.grid.enhanced.plugins.Printer");
+			dojo.require("dojox.grid.enhanced.plugins.Cookie");
+			dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+			dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+			dojo.require("dojox.grid.enhanced.plugins.Selector");
+			dojo.require("dojox.grid.enhanced.plugins.Menu");
+			dojo.require("dojox.grid.enhanced.plugins.DnD");
+			dojo.require("dojox.grid.enhanced.plugins.Search");
+			dojo.require("dojox.grid.enhanced.plugins.CellMerge");
+			dojo.require("dojox.grid.enhanced.plugins.Pagination");
+			dojo.require('doh.runner');
+		</script>
+		<script type="text/javascript" src="../support/test_data.js"></script>
+		<script type="text/javascript">
+			var grid = null,
+				connecter = [];
+			var gridArgs = {
+			};
+			var plugins = {
+				"nestedSorting": {},
+				"indirectSelection": {
+					headerSelector: true,
+					name: "Selection", 
+					width:"70px", 
+					styles:"text-align: center;"
+				},
+				"menus": {
+				},
+				"exporter": {},
+				"printer": {},
+				"filter": {
+					closeFilterbarButton: true,
+					ruleCount: 0
+				},
+				"cookie": {},
+				"selector": {
+				},
+				"dnd": {
+					copyOnly: false
+				},
+				"cellMerge": {
+					"mergedCells": [
+						{row: "3", start: 1, end: 10, major: 3}
+					]
+				},
+				"search": {},
+				"pagination":
+				{
+					pageSizes: ["5", "10", "20", "50", "All"],	// Array, custom the items per page button
+					// itemTitle: "entrys", 	// String, custom the item' title of description
+					description: true,	// boolean, custom weather or not the discription will be displayed
+					sizeSwitch: true,	// boolean, custom weather or not the page size switch will be displayed
+					pageStepper: true,	// boolean, custom weather or not the page step will be displayed
+					gotoButton: true,
+					maxPageStep: 10,		// Integer, custom how many page step will be displayed
+					position: "bottom"		// String, custom the position of the paginator bar
+											// there're three options: top, bottom, both
+					// ,descTemplate: "${1} ${0}" // A template of the current position description.
+				}
+			};
+			
+			var layout = [[
+				{name: 'Column 1', field: 'col1'},
+				{name: 'Column 2', field: 'col2'},
+				{name: 'Column 3', field: 'col3'},
+				{name: 'Column 4', field: 'col4', width: "150px"},
+				{name: 'Column 5', field: 'col5'},
+				{name: 'Column 6', field: 'col6'},
+				{name: 'Column 7', field: 'col7'},
+				{name: 'Column 8', field: 'col5'}
+			]];
+			
+			dojo.addOnLoad(function() {
+				dojo.connect(dojo._listener, "add", function(obj, event, context, method){
+					connecter.push([obj, event, context, method]); // Handle
+				});
+			});
+
+			function toggleGrid() {
+				if (grid){
+					grid.destroy();
+					grid = null;
+					
+					doh.register("leak_programmatic", [
+						{
+							name: 'widget_destroy',
+							runTest: function(t){
+								for(var name in dijit.registry._hash){
+									t.assertEqual(dijit.registry._hash[name], undefined);
+								}
+							}
+						}, 
+						{
+							name: "connecter_destroy",
+							runTest: function(t){
+								dojo.forEach(connecter, function(conn){
+									var f = (conn[0] || dojo.global)[conn[1]];
+									if(f && f._listeners){
+										dojo.forEach(f._listeners, function(l){
+											t.assertEqual(l, undefined);
+										});
+									}
+								});
+							}
+						}, 
+						{
+							name: "topics_destroy",
+							runTest: function(t){
+									
+								for(var name in dojo._topics){
+									if(name === "dijit.Editor.getPlugin"){continue;}
+									var topic = dojo._topics[name];
+									dojo.forEach(topic._listeners, function(l){
+										t.assertEqual(l, undefined);
+									});
+								}
+							}
+						}
+					]);
+					
+					doh.run();
+				}
+				else {
+					grid = new dojox.grid.EnhancedGrid(dojo.mixin({
+						id: "grid",
+						store: test_store,
+						structure: layout,
+						plugins : plugins
+					}, gridArgs));
+
+					dojo.byId("gridContainer").appendChild(grid.domNode);
+					grid.startup();
+				}
+			}
+			
+			function leakTest(){
+				toggleGrid();
+			}
+		</script>
+	</head>
+	<body class="claro">
+		<div class="heading">dojox.grid.EnhancedGrid Leak Test Programmatic</div>
+		<div>
+		<p>Please follow below two steps and see the doh test output in console: ( TEST SUMMARY )</p>
+			<p>     1> click "Toggle Grid Programmatic" button, wait until grid created.</p>
+			<p>     2> click "Toggle Grid Programmatic" button again to destroy Grid,
+				all event connections, topics, and checkbox widgets should be destroyed, please check with debugging console, if there are no failures, means no leak. If there are one or more failures, means leak exist.</p>
+		</div>
+		<button id="leakTest" onClick="leakTest();">Toggle Grid Programmatic</button>
+		<div id="gridContainer"></div>
+	</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html
new file mode 100644
index 0000000..a8e45df
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_scroll.html
@@ -0,0 +1,175 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+	<head>
+		<title>Scorll Leak</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+		<link rel=stylesheet href="support/common.css"/>
+		<style type="text/css">
+			body {
+				font-size: 0.9em;
+				font-family: Geneva, Arial, Helvetica, sans-serif;
+				padding: 0.5em;
+			}
+			.title {
+				text-align:center;
+			}
+	 		#grid {
+	 			border: 1px solid #333;
+				width: 80em;
+				height: 45em;
+			}
+	
+		</style>
+		<script type="text/javascript" src="../../../../dojo/dojo.js" 
+			djConfig="isDebug:false, parseOnLoad: true"></script>
+		<script type="text/javascript">
+			dojo.require("dijit.dijit"); // optimize: load dijit layer
+			dojo.require("dojox.grid.EnhancedGrid");
+			dojo.require("dojo.data.ItemFileWriteStore");
+			dojo.require("dojo.parser");
+			dojo.require("dojox.grid.enhanced.plugins.Filter");
+			dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+			dojo.require("dojox.grid.enhanced.plugins.Printer");
+			dojo.require("dojox.grid.enhanced.plugins.Cookie");
+			dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+			dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+			dojo.require("dojox.grid.enhanced.plugins.Selector");
+			dojo.require("dojox.grid.enhanced.plugins.Menu");
+			dojo.require("dojox.grid.enhanced.plugins.DnD");
+			dojo.require("dojox.grid.enhanced.plugins.Search");
+			dojo.require("dojox.grid.enhanced.plugins.CellMerge");
+			dojo.require("dojox.grid.enhanced.plugins.Pagination");
+			dojo.require("dojox.grid.enhanced.plugins.GridSource");
+		</script>
+		<script type="text/javascript" src="../support/test_data.js"></script>
+		<script type="text/javascript">
+			//init data
+			var data = {
+				identifier: 'id',
+				label: 'id',
+				items: []
+			};
+			var data_list = [ 
+				{ col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10, col7: false },
+				{ col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7: false },
+				{ col1: "important", col2: false, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true },
+				{ col1: "note", col2: false, col3: "read", col4: 'However the reserved characters', col5: 15.63, col6: 0, col7: true },
+				{ col1: "normal", col2: false, col3: "replied", col4: 'It is therefore necessary', col5: 24.22, col6: 5.50, col7: true },
+				{ col1: "important", col2: false, col3: "replied", col4: 'To problems of corruption by', col5: 9.12, col6: -3, col7: true },
+				{ col1: "note", col2: false, col3: "replied", col4: 'Which would simply be awkward in', col5: 12.15, col6: -4, col7: false }
+			];
+			var rows = 500;
+			for(var i=0, l=data_list.length; i<rows; i++){
+				data.items.push(dojo.mixin({ id: i }, data_list[i%l]));
+			}
+		
+			// global var "test_store"
+			test_store = new dojo.data.ItemFileWriteStore({data: data});
+			
+			
+			var grid = null, delta = 1000, interval = 6000;
+			var plugins = {
+				"nestedSorting": {},
+				"indirectSelection": {
+					headerSelector: true,
+					name: "Selection", 
+					width:"70px", 
+					styles:"text-align: center;"
+				},
+				"menus": {
+					headerMenu: "headerMenu", 
+					rowMenu: "rowMenu", 
+					cellMenu: "cellMenu", 
+					selectedRegionMenu: "selectedRegionMenu"
+				},
+				"exporter": {},
+				"printer": {},
+				"filter": {
+					closeFilterbarButton: true,
+					ruleCount: 0
+				},
+				"cookie": {},
+				"selector": {},
+				"dnd": {
+					copyOnly: false
+				},
+				"cellMerge": {
+					"mergedCells": [
+						{row: "3", start: 1, end: 10, major: 3}
+					]
+				},
+//				"pagination":
+//				{
+//					pageSizes: ["5", "10", "20", "50", "All"],	// Array, custom the items per page button
+//					// itemTitle: "entrys", 	// String, custom the item' title of description
+//					description: true,	// boolean, custom weather or not the discription will be displayed
+//					sizeSwitch: true,	// boolean, custom weather or not the page size switch will be displayed
+//					pageStepper: true,	// boolean, custom weather or not the page step will be displayed
+//					gotoButton: true,
+//					maxPageStep: 10,		// Integer, custom how many page step will be displayed
+//					position: "bottom"		// String, custom the position of the paginator bar
+//											// there're three options: top, bottom, both
+//					// ,descTemplate: "${1} ${0}" // A template of the current position description.
+//				},
+				"search": {}
+			};
+			var gridArgs = {
+			};
+			var layout = [[
+				{name: 'Column 1', field: 'col1'},
+				{name: 'Column 2', field: 'col2'},
+				{name: 'Column 3', field: 'col3'},
+				{name: 'Column 4', field: 'col4', width: "150px"},
+				{name: 'Column 5', field: 'col5'},
+				{name: 'Column 6', field: 'col6'},
+				{name: 'Column 7', field: 'col7'},
+				{name: 'Column 8', field: 'col5'}
+			]];
+			
+			dojo.addOnLoad(function() {
+				grid = new dojox.grid.EnhancedGrid(dojo.mixin({
+					id: "grid",
+					store: test_store,
+					structure: layout,
+					rowsPerPage: 25,
+					keepRows: 75,
+					plugins : plugins
+				}, gridArgs));
+
+				dojo.byId("gridContainer").appendChild(grid.domNode);
+				grid.startup();
+			});
+
+			function scrollGrid() {
+				setTimeout(function(){
+					grid.scrollToRow(50);
+					setTimeout(function(){
+						grid.scrollToRow(100);
+						setTimeout(function(){
+							grid.scrollToRow(300);
+							setTimeout(function(){
+								grid.scrollToRow(400);
+								setTimeout(function(){
+									grid.scrollToRow(0);
+								}, delta);
+							}, delta);
+						}, delta);
+					}, delta);
+				}, delta);
+			}
+			
+			function leakTest(){
+				scrollGrid();
+				setInterval(function(){
+					scrollGrid();
+				}, interval);
+			}
+		</script>
+	</head>
+	<body class="claro">
+		<div class="heading">dojox.grid.EnhancedGrid Scorll Leak Test</div>
+		<button id="leakTest" onClick="leakTest();">EnhancedGrid Scorll Leak</button>
+		<div id="gridContainer"></div>
+	</body>
+</html>
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
new file mode 100644
index 0000000..90735cd
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_leak_with_plugin.html
@@ -0,0 +1,294 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>EnhancedGrid Memory Leak Test - Great/Destroy</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding-right: 5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+		.supporter {
+			display: block;
+			border: 3px solid #ccc;
+			width: 100em;
+			padding: 1em 3em; 
+			cursor: default;
+			radius: 8pt;
+			background: #fff;
+			-moz-border-radius: 8pt 8pt;
+		}
+		.selectReport {
+			display: inline-block;
+		}
+		.tutor h2{
+			font-weight: bolder;
+		}
+		.tutor td:first-child{
+			font-weight: bolder;
+		}
+ 		#gridContainer{
+			width: 100em;
+			height: 35em;
+			border: 1px solid #D5CDB5;
+		}
+		/*Sample - overwrite default cell style
+		.claro .dojoxGridCell{
+			border-color: transparent #D5CDB5 #D5CDB5 transparent !important;
+		}
+		.dj_ie6 .claro .dojoxGridCell{
+			border: 1px solid #F1F1F1 !important;
+		}*/
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dijit.form.CheckBox");
+		dojo.require("dojox.grid.enhanced.plugins.Filter");
+		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+		dojo.require("dojox.grid.enhanced.plugins.Printer");
+		dojo.require("dojox.grid.enhanced.plugins.Cookie");
+		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+		dojo.require("dojox.grid.enhanced.plugins.Selector");
+		dojo.require("dojox.grid.enhanced.plugins.Menu");
+		dojo.require("dojox.grid.enhanced.plugins.DnD");
+		dojo.require("dojox.grid.enhanced.plugins.Search");
+		dojo.require("dojox.grid.enhanced.plugins.CellMerge");
+		dojo.require("dojox.grid.enhanced.plugins.Pagination");
+		dojo.require("dojox.grid.enhanced.plugins.GridSource");
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojo.parser");
+		var startGridIndex = 0,
+			initialShowGrid = false,
+			hideCtrlPanel = false,
+		 	repeatCount = 100000,
+			repeatInterval = 500;
+			gridAttrs = {
+				rowsPerPage: 5,
+				keepSelection: true,
+				plugins: {}
+			};
+	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript" src="support/test_layout_music.js"></script>
+	<script type="text/javascript" src="support/test_repeat.js"></script>
+	<script type="text/javascript">
+		var plugins = {
+			"nestedSorting": {},
+			"indirectSelection": {
+				headerSelector: true
+			},
+			"menus": {
+				headerMenu: "headerMenu", 
+				rowMenu: "rowMenu", 
+				cellMenu: "cellMenu", 
+				selectedRegionMenu: "selectedRegionMenu"
+			},
+			"exporter": {},
+			"printer": {},
+			"filter": {
+				closeFilterbarButton: true,
+				ruleCount: 0
+			},
+			"cookie": {},
+			"selector": {
+				col: false
+			},
+			"dnd": {
+				copyOnly: false
+			},
+			"cellMerge": {
+				"mergedCells": [
+					{row: "3", start: 1, end: 10, major: 3}
+				]
+			},
+			"search": {},
+			"pagination":
+			{
+				pageSizes: ["5", "10", "20", "50", "All"],	// Array, custom the items per page button
+				// itemTitle: "entrys", 	// String, custom the item' title of description
+				description: true,	// boolean, custom weather or not the discription will be displayed
+				sizeSwitch: true,	// boolean, custom weather or not the page size switch will be displayed
+				pageStepper: true,	// boolean, custom weather or not the page step will be displayed
+				gotoButton: true,
+				maxPageStep: 10,		// Integer, custom how many page step will be displayed
+				position: "bottom"		// String, custom the position of the paginator bar
+										// there're three options: top, bottom, both
+				// ,descTemplate: "${1} ${0}" // A template of the current position description.
+			}
+		};
+		var gridFeatures = {
+			"canSort": {
+				label: "disable canSort",
+				value: function(colIndex){
+					return false;
+				}
+			},
+			"rowSelector": {
+				value: "20px"
+			},
+			"autoHeight": {
+				value: true
+			},
+			"autoWidth": {
+				value: true
+			},
+			"singleClickEdit": {
+				value: true
+			},
+			"selectionMode": {
+				label: "single selectionMode",
+				value: "single"
+			},
+			"columnReordering": {
+				value: true
+			}
+		};
+		function getTableString(){
+			var sb = ["<table><tbody>"];
+			for(var featureName in gridFeatures){
+				sb.push("<tr>");
+				sb.push("<td><input id='cbid", featureName, 
+					"' dojoType='dijit.form.CheckBox' dojoAttachPoint='cb", featureName, 
+					"'><label id='lbl", featureName, "' for='cbid", featureName, "'>",
+					gridFeatures[featureName].label || featureName, "</label></input></td>"
+				);
+				sb.push("</tr>");
+			}
+			sb.push("<tr><td><hr/></td></tr>",
+				"<tr><td><button onclick='selectAll()'>Select All</button>",
+				"<button onclick='deselectAll()'>Deselect All</button></td></tr>"
+			);
+			for(var pluginName in plugins){
+				sb.push("<tr>");
+				sb.push("<td><input id='cbid", pluginName, 
+					"' dojoType='dijit.form.CheckBox' dojoAttachPoint='cb", pluginName, 
+					"'><label id='lbl", pluginName, "' for='cbid", pluginName, "'>",
+					pluginName, "</label></input></td>"
+				);
+				sb.push("</tr>");
+			}
+			sb.push("</tbody></table>");
+			return sb.join('');
+		}
+		dojo.declare("PluginTable", [dijit._Widget, dijit._Templated], {
+			templateString: getTableString(),
+			widgetsInTemplate: true,
+			_onChangePlugin:  function(pluginName, cb, e){
+				var checked = cb.get("checked");
+				gridAttrs.plugins[pluginName] = checked ? plugins[pluginName] : false;
+				var nd = dojo.byId(pluginName + "Support");
+				if(nd){
+					dojo.style(nd, "display", checked ? "" : "none");
+				}
+			},
+			_onChangeFeature: function(featureName, cb, e){
+				var checked = cb.get("checked");
+				if(checked){
+					gridAttrs[featureName] = gridFeatures[featureName].value;
+				}else{
+					delete gridAttrs[featureName];
+				}
+			},
+			postCreate: function(){
+				var cb;
+				for(var featureName in gridFeatures){
+					cb = this["cb" + featureName];
+					this.connect(cb, "onChange", dojo.hitch(this, "_onChangeFeature", featureName, cb));
+				}
+				for(var pluginName in plugins){
+					cb = this["cb" + pluginName];
+					this.connect(cb, "onChange", dojo.hitch(this, "_onChangePlugin", pluginName, cb));
+				}
+			}
+		});
+		function selectAll(){
+			for(var pluginName in plugins){
+				dijit.byId("cbid" + pluginName).set("checked", true);
+			}
+		}
+		function deselectAll(){
+			for(var pluginName in plugins){
+				dijit.byId("cbid" + pluginName).set("checked", false);
+			}
+		}
+		function setupSelectorTest(){
+			var grid = dijit.byId("grid"),
+				func = function(type, start, end, selected){
+					fill("col", selected["col"]);
+					fill("row", selected["row"]);
+					fill("cell", selected["cell"]);
+				},
+				fill = function(type, selected){
+					var getString;
+					var cells = grid.layout.cells;
+					switch(type){
+						case "col":
+							getString = function(item){
+								return "Column " + item.col + ": " + dojo.toJson(item.except);
+							}
+							break;
+						case "row":
+							getString = function(item){
+								return "Row " + item.row + ": " + dojo.toJson(item.except);
+							}
+							break;
+						case "cell":
+							getString = function(item){
+								return "Cell " + item.row + " , " + item.col;
+							}
+					}
+				};
+		}
+		dojo.addOnLoad(function(){
+			dojo.subscribe("test_repeat_grid_created", function(){
+				var g = dijit.byId("grid");
+				g && g.setCookieEnabled && g.setCookieEnabled(false);
+			});
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">EnhancedGrid Memory Leak Test - Great/Destroy</h1>
+	<h2><p>Repeat creating/destroying Grid instances:</p></h2>
+	<div id="ctrlBtns"></div><br/>
+	<div id="pluginList" dojoType="PluginTable" style="float:right;"></div>
+	<div id="gridContainer"></div><br/>
+	<div id="ctrlBtns2"></div><br/>
+	<div id="menusSupport" style="display: none;">
+		<div dojoType="dijit.Menu" id="headerMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Header Menu Item 1</div>
+			<div dojoType="dijit.MenuItem">Header Menu Item 2</div>
+			<div dojoType="dijit.MenuItem">Header Menu Item 3</div>
+			<div dojoType="dijit.MenuItem">Header Menu Item 4</div>
+		</div>
+		<div dojoType="dijit.Menu" id="rowMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Row Menu Item 1</div>
+			<div dojoType="dijit.MenuItem">Row Menu Item 2</div>
+			<div dojoType="dijit.MenuItem">Row Menu Item 3</div>
+			<div dojoType="dijit.MenuItem">Row Menu Item 4</div>
+		</div>
+		<div dojoType="dijit.Menu" id="cellMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Cell Menu Item 1</div>
+			<div dojoType="dijit.MenuItem">Cell Menu Item 2</div>
+			<div dojoType="dijit.MenuItem">Cell Menu Item 3</div>
+			<div dojoType="dijit.MenuItem">Cell Menu Item 4</div>
+		</div>
+		<div dojoType="dijit.Menu" id="selectedRegionMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Action 1 for Selected Region</div>
+			<div dojoType="dijit.MenuItem">Action 2 for Selected Region</div>
+			<div dojoType="dijit.MenuItem">Action 3 for Selected Region</div>
+			<div dojoType="dijit.MenuItem">Action 4 for Selected Region</div>
+		</div>
+	</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html b/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html
new file mode 100644
index 0000000..d5f7453
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_menus.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test Menus plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+ 		#grid1, #grid2 {
+			width: 85.2em;
+			height: 50em;
+		}
+
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.Menu");
+		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript" src="../support/test_data.js"></script>
+	<script type="text/javascript">		
+		var layout = [[
+			{name: 'Column 1', field: 'id'},
+			{name: 'Column 2', field: 'col2'},
+			{name: 'Column 3', field: 'col3'},
+			{name: 'Column 4', field: 'col4', width: "150px"},
+			{name: 'Column 5', field: 'col5'},
+			{name: 'Column 6', field: 'col6'},
+			{name: 'Column 7', field: 'col7'},
+			{name: 'Column 8', field: 'col5'}
+		]];
+		
+		dojo.addOnLoad(function(){
+			var grid = new dojox.grid.EnhancedGrid({
+				id: "grid2",
+				store: test_store,
+				structure: layout,
+				rowSelector: '20px',
+				plugins : {menus:{headerMenu:"headerMenu", rowMenu:"rowMenu", cellMenu:"cellMenu", selectedRegionMenu:"selectedRegionMenu"},
+				indirectSelection: {headerSelector:true, name: "Selection", width: "60px", styles: "text-align: center;"}
+				}
+			}, dojo.byId('gridDiv'));
+			grid.startup();
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - Menus</h1>
+	<p>
+		<div id="grid1" dojoType="dojox.grid.EnhancedGrid" query="{ id: '*' }" rowsPerPage="30" 
+			plugins='{menus:{headerMenu:"headerMenu", rowMenu:"rowMenu", cellMenu:"cellMenu", selectedRegionMenu:"selectedRegionMenu"}}'
+			store="test_store" structure="layout" rowSelector="20px">
+			<div dojoType="dijit.Menu" id="headerMenu"  style="display: none;">
+				<div dojoType="dijit.MenuItem">Header Menu Item 1</div>
+				<div dojoType="dijit.MenuItem">Header Menu Item 2</div>
+				<div dojoType="dijit.MenuItem">Header Menu Item 3</div>
+				<div dojoType="dijit.MenuItem">Header Menu Item 4</div>
+			</div>
+			<div dojoType="dijit.Menu" id="rowMenu"  style="display: none;">
+				<div dojoType="dijit.MenuItem">Row Menu Item 1</div>
+				<div dojoType="dijit.MenuItem">Row Menu Item 2</div>
+				<div dojoType="dijit.MenuItem">Row Menu Item 3</div>
+				<div dojoType="dijit.MenuItem">Row Menu Item 4</div>
+			</div>
+			<div dojoType="dijit.Menu" id="cellMenu"  style="display: none;">
+				<div dojoType="dijit.MenuItem">Cell Menu Item 1</div>
+				<div dojoType="dijit.MenuItem">Cell Menu Item 2</div>
+				<div dojoType="dijit.MenuItem">Cell Menu Item 3</div>
+				<div dojoType="dijit.MenuItem">Cell Menu Item 4</div>
+			</div>
+			<div dojoType="dijit.Menu" id="selectedRegionMenu"  style="display: none;">
+				<div dojoType="dijit.MenuItem">Action 1 for Selected Region</div>
+				<div dojoType="dijit.MenuItem">Action 2 for Selected Region</div>
+				<div dojoType="dijit.MenuItem">Action 3 for Selected Region</div>
+				<div dojoType="dijit.MenuItem">Action 4 for Selected Region</div>
+			</div>
+		</div>
+	</p>
+	<p>
+		<div id="gridDiv"></div>
+	</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html b/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html
new file mode 100644
index 0000000..505b902
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_nestedsorting.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>Test Nested sorting plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+		}
+ 		#grid {
+			width: 85.2em;
+			height: 50em;
+		}
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+		dojo.require("dojo.data.ItemFileWriteStore");
+		dojo.require("dojo.parser");
+	</script>
+	<script type="text/javascript">
+			var layout = [[
+				{name: 'Column A', field: 'id'},
+				{name: 'Column B', field: 'col2', nosort: true},
+				{name: 'Column C', field: 'col3'},
+				{name: 'Column D', field: 'col4', width: "150px"},
+				{name: 'Column E', field: 'col5'},
+				{name: 'Column F', field: 'col6'},
+				{name: 'Column G', field: 'col7', width: "150px"},
+				{name: 'Column H', field: 'col1', width: "150px"}
+			]];
+			
+			dojo.addOnLoad(function(){
+				grid = new dojox.grid.EnhancedGrid({
+					id: "grid",
+					store: test_store,
+					structure: layout,
+					rowSelector: "20px",
+					sortFields: [{attribute: 'col4', descending: false},{attribute: 'col7', descending: true}],//default sorting order
+					canSort: function(colIndex, field){
+						return colIndex != 0 && field != 'col6';
+					},
+					plugins: {nestedSorting: true}
+				});
+
+				dojo.byId("gridDiv").appendChild(grid.domNode);
+				grid.startup();
+			});
+
+			function newSort(){
+				var sortFields = [{attribute: 'col3', descending: true},{attribute: 'col1', descending: false}];
+				var g = dijit.byId('grid');
+				g.setSortIndex(sortFields);
+			}
+	</script>
+	<script type="text/javascript" src="../../tests/support/test_data.js"></script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - NestedSorting</h1>
+	<p><h3>Column A, ColumnB Column F are unsortable</h3></p>
+	<p><div id="gridDiv"></div></p>
+	<p><h3>Set new sort order as:[Column C(desc), Column H(asc)]:</h3> <input type='button' value='Set new Sorting Order' onclick='newSort()'/></p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html b/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
new file mode 100644
index 0000000..e9f5656
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_pagination.html
@@ -0,0 +1,73 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>Test Pagination plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding-right: 10em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+ 		#grid{
+			width: 100em;
+			height: 30em;
+		}
+	</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>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.Pagination");
+		dojo.require("dojo.parser");
+		
+		var layout = [{
+			cells: [
+				{ field: "id", name:"Identity", datatype:"number", width: 4, editable: false},
+				{ 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},
+				{ field: "Album", name:"Album", datatype:"string", width: 10},
+				{ field: "Name", name:"Name", datatype:"string", width: 8},
+				{ field: "Length", name:"Length", datatype:"string", width: 4},
+				{ field: "Track", name:"Track", datatype:"number", width: 3},
+				{ field: "Composer", name:"Composer", datatype:"string", width: 12},
+				{ field: "Download Date", name:"Download Date", datatype:"date", width: 12},
+				{ field: "Last Played", name:"Last Played", datatype:"time", width: 6},
+				{ field: "Heard", name: "Checked", datatype:"boolean", width: 6}
+			]
+		}];
+		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
+				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.
+			}
+		};
+	</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>
+	<div id="gridContainer">
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+	</div><br/>
+	<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html b/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
new file mode 100644
index 0000000..94798cf
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_plugins.html
@@ -0,0 +1,875 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>Test all plugins of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding-right: 5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+		.supporter {
+			display: block;
+			border: 3px solid #ccc;
+			width: 100em;
+			padding: 1em 3em; 
+			cursor: default;
+			radius: 8pt;
+			background: #fff;
+			-moz-border-radius: 8pt 8pt;
+		}
+		.selectReport {
+			display: inline-block;
+		}
+		.tutor h2{
+			font-weight: bolder;
+		}
+		.tutor td:first-child{
+			font-weight: bolder;
+		}
+ 		#gridContainer{
+			width: 100em;
+			height: 35em;
+			border: 1px solid #D5CDB5;
+		}
+		/*Sample - overwrite default cell style
+		.claro .dojoxGridCell{
+			border-color: transparent #D5CDB5 #D5CDB5 transparent !important;
+		}
+		.dj_ie6 .claro .dojoxGridCell{
+			border: 1px solid #F1F1F1 !important;
+		}*/
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" 
+		djConfig="isDebug:false, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript">
+		dojo.require("dijit.form.CheckBox");
+		dojo.require("dojox.grid.enhanced.plugins.Filter");
+		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+		dojo.require("dojox.grid.enhanced.plugins.Printer");
+		dojo.require("dojox.grid.enhanced.plugins.Cookie");
+		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+		dojo.require("dojox.grid.enhanced.plugins.NestedSorting");
+		dojo.require("dojox.grid.enhanced.plugins.Selector");
+		dojo.require("dojox.grid.enhanced.plugins.Menu");
+		dojo.require("dojox.grid.enhanced.plugins.DnD");
+		dojo.require("dojox.grid.enhanced.plugins.Search");
+		dojo.require("dojox.grid.enhanced.plugins.CellMerge");
+		dojo.require("dojox.grid.enhanced.plugins.Pagination");
+		dojo.require("dojox.grid.enhanced.plugins.GridSource");
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojo.parser");
+		var startGridIndex = 0,
+			initialShowGrid = false,
+			hideCtrlPanel = false,
+		 	repeatCount = 100000,
+			repeatInterval = 500;
+			gridAttrs = {
+				rowsPerPage: 5,
+				keepSelection: true,
+				//sortFields: [{attribute: "Genre"}],
+				plugins: {
+				}
+			};
+	</script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript" src="support/test_layout_music.js"></script>
+	<script type="text/javascript" src="support/test_repeat.js"></script>
+	<script type="text/javascript">
+		var plugins = {
+			"nestedSorting": {},
+			"indirectSelection": {
+				headerSelector: true
+			},
+			"menus": {
+				headerMenu: "headerMenu", 
+				rowMenu: "rowMenu", 
+				cellMenu: "cellMenu", 
+				selectedRegionMenu: "selectedRegionMenu"
+			},
+			"exporter": {},
+			"printer": {},
+			"filter": {
+				closeFilterbarButton: true,
+				ruleCount: 0
+			},
+			"cookie": {},
+			"selector": {},
+			"dnd": {
+				copyOnly: true
+			},
+			"cellMerge": {
+				"mergedCells": [
+					{row: "3", start: 1, end: 10, major: 3}
+				]
+			},
+			"search": {},
+			"pagination":
+			{
+				pageSizes: ["5", "10", "20", "50", "All"],	// Array, custom the items per page button
+				// itemTitle: "entrys", 	// String, custom the item' title of description
+				description: true,	// boolean, custom weather or not the discription will be displayed
+				sizeSwitch: true,	// boolean, custom weather or not the page size switch will be displayed
+				pageStepper: true,	// boolean, custom weather or not the page step will be displayed
+				gotoButton: true,
+				maxPageStep: 10,		// Integer, custom how many page step will be displayed
+				position: "bottom"		// String, custom the position of the paginator bar
+										// there're three options: top, bottom, both
+				// ,descTemplate: "${1} ${0}" // A template of the current position description.
+			}
+		};
+		var gridFeatures = {
+			"canSort": {
+				label: "disable canSort",
+				value: function(colIndex){
+					return false;
+				}
+			},
+			"rowSelector": {
+				value: "20px"
+			},
+			"autoHeight": {
+				value: true
+			},
+			"autoWidth": {
+				value: true
+			},
+			"singleClickEdit": {
+				value: true
+			},
+			"selectionMode": {
+				label: "single selectionMode",
+				value: "single"
+			},
+			"columnReordering": {
+				value: true
+			}
+		};
+		function getTableString(){
+			var sb = ["<table><tbody>"];
+			for(var featureName in gridFeatures){
+				sb.push("<tr>");
+				sb.push("<td><input id='cbid", featureName, 
+					"' dojoType='dijit.form.CheckBox' dojoAttachPoint='cb", featureName, 
+					"'><label id='lbl", featureName, "' for='cbid", featureName, "'>",
+					gridFeatures[featureName].label || featureName, "</label></input></td>"
+				);
+				sb.push("</tr>");
+			}
+			sb.push("<tr><td><hr/></td></tr>",
+				"<tr><td><button onclick='selectAll()'>Select All</button>",
+				"<button onclick='deselectAll()'>Deselect All</button></td></tr>"
+			);
+			for(var pluginName in plugins){
+				sb.push("<tr>");
+				sb.push("<td><input id='cbid", pluginName, 
+					"' dojoType='dijit.form.CheckBox' dojoAttachPoint='cb", pluginName, 
+					"'><label id='lbl", pluginName, "' for='cbid", pluginName, "'>",
+					pluginName, "</label></input></td>"
+				);
+				sb.push("</tr>");
+			}
+			sb.push("</tbody></table>");
+			return sb.join('');
+		}
+		dojo.declare("PluginTable", [dijit._Widget, dijit._Templated], {
+			templateString: getTableString(),
+			widgetsInTemplate: true,
+			_onChangePlugin:  function(pluginName, cb, e){
+				var checked = cb.get("checked");
+				gridAttrs.plugins[pluginName] = checked ? plugins[pluginName] : false;
+				var nd = dojo.byId(pluginName + "Support");
+				if(nd){
+					dojo.style(nd, "display", checked ? "" : "none");
+				}
+			},
+			_onChangeFeature: function(featureName, cb, e){
+				var checked = cb.get("checked");
+				if(checked){
+					gridAttrs[featureName] = gridFeatures[featureName].value;
+				}else{
+					delete gridAttrs[featureName];
+				}
+			},
+			postCreate: function(){
+				var cb;
+				for(var featureName in gridFeatures){
+					cb = this["cb" + featureName];
+					this.connect(cb, "onChange", dojo.hitch(this, "_onChangeFeature", featureName, cb));
+				}
+				for(var pluginName in plugins){
+					cb = this["cb" + pluginName];
+					this.connect(cb, "onChange", dojo.hitch(this, "_onChangePlugin", pluginName, cb));
+				}
+			}
+		});
+		function selectAll(){
+			for(var pluginName in plugins){
+				dijit.byId("cbid" + pluginName).set("checked", true);
+			}
+		}
+		function deselectAll(){
+			for(var pluginName in plugins){
+				dijit.byId("cbid" + pluginName).set("checked", false);
+			}
+		}
+		function exportCSV(){
+			var g = dijit.byId("grid");
+			g && g.exportGrid("csv", {
+				writerArgs: {
+					separator: dojo.byId('sep').value
+				}
+			}, function(str){
+				dojo.byId("csvResults").value = str;
+			});
+		}
+		function exportSelected(){
+			var g = dijit.byId("grid");
+			if(g){
+				dojo.byId("csvResults").value = g.exportSelected("csv", {
+					separator: dojo.byId('sep').value
+				});	
+			}
+		}
+		function printGrid(){
+			var g = dijit.byId("grid");
+			if(g){
+//				g.setExportFormatter(function(data, cell, rowIndex, rowItem){
+//					if(cell.field === "Year"){
+//						return parseInt(data, 10) * 2;
+//					}else{
+//						return data;
+//					}
+//				});
+				g.printGrid({
+					title: dojo.byId('print_title').value,
+					cssFiles: ["support/print_style1.css","support/print_style2.css"]
+				});
+			}
+		}
+		function printSelected(){
+			var g = dijit.byId("grid");
+			g && g.printSelected({
+				title: dojo.byId('print_title').value,
+				cssFiles: ["support/print_style1.css", "support/print_style2.css"]
+			});
+		}
+		function printPreview(){
+			var g = dijit.byId("grid");
+			g && g.exportToHTML({
+				title: dojo.byId('print_title').value,
+				cssFiles: ["support/print_style1.css", "support/print_style2.css"]
+			}, function(str){
+				var win = window.open();
+				win.document.open();
+				win.document.write(str);
+				g.normalizePrintedGrid(win.document);
+				win.document.close();
+			});
+		}
+		function mergeCells(){
+			var rowIndex = parseInt(dojo.byId("inputRow").value, 10) - 1;
+			var start = parseInt(dojo.byId("inputStart").value, 10);
+			var end = parseInt(dojo.byId("inputEnd").value, 10);
+			var major = parseInt(dojo.byId("inputMajor").value, 10);
+			var grid = dijit.byId("grid");
+			grid.mergeCells(rowIndex, start, end, major);
+		}
+		function getInput(str){
+			var start = str.indexOf('/');
+			var end = str.lastIndexOf('/');
+			if(start == 0 || end > 1){
+				var regstr = str.substring(start + 1, end);
+				var modifiers = str.substring(end + 1, str.length);
+				str = new RegExp(regstr,modifiers);
+			}
+			console.log("input:", str);
+			return str;
+		}
+		function onSearched(resultId, rowIdx){
+			console.log("search result:", rowIdx);
+			if(rowIdx < 0){
+				dojo.byId(resultId).innerHTML = "Not Found!";
+			}else{
+				dojo.byId(resultId).innerHTML = "Search result is Row " + (rowIdx + 1);
+				dijit.byId("grid").scrollToRow(rowIdx, true);
+			}
+		}
+		function onSearch(){
+			var g = dijit.byId("grid");
+			if(g){
+				var args = {};
+				dojo.query(".searchInput").forEach(function(input){
+					var v = dojo.trim(input.value);
+					if(v){
+						args[input.name] = getInput(v);
+					}
+				});
+				console.log("search arguments:", args);
+				g.searchRow(args, dojo.partial(onSearched, "result2"));
+			}
+		}
+		function onSearchAll(input){
+			var g = dijit.byId("grid");
+			g && g.searchRow(getInput(input), dojo.partial(onSearched, "result1"));
+		}
+		function enableCookie(key, toEnable){
+			console.log(key,toEnable);
+			try{
+				var g = dijit.byId("grid");
+				if(g){
+					if(key){
+						g.setCookieEnabled(key, toEnable);
+					}else{
+						g.setCookieEnabled(toEnable);
+					}
+				}
+			}catch(e){
+				console.log(e);
+			}
+		}
+		function setupSelectorTest(){
+			var grid = dijit.byId("grid"),
+				func = function(type, start, end, selected){
+					fill("col", selected["col"]);
+					fill("row", selected["row"]);
+					fill("cell", selected["cell"]);
+				},
+				fill = function(type, selected){
+					var getString;
+					var cells = grid.layout.cells;
+					switch(type){
+						case "col":
+							getString = function(item){
+								return "Column " + item.col + ": " + dojo.toJson(item.except);
+							}
+							break;
+						case "row":
+							getString = function(item){
+								return "Row " + item.row + ": " + dojo.toJson(item.except);
+							}
+							break;
+						case "cell":
+							getString = function(item){
+								return "Cell " + item.row + " , " + item.col;
+							}
+					}
+					dojo.attr(dojo.byId(type + "s"), "value", dojo.map(selected, function(item){
+						return getString(item);
+					}).join('\n'));
+					dojo.attr(dojo.byId(type + "Cnt"), "value", selected.length);
+				};
+			grid.connect(grid, "onEndSelect", func);
+			grid.connect(grid, "onEndDeselect", func);
+		}
+		dojo.declare("TestWidget", [dijit._Widget,dijit._Templated], {
+			templateString: dojo.cache("dojox.grid", "enhanced/templates/ClearFilterConfirmPane.html"),
+			widgetsInTemplate: true,
+			_clearBtnLabel: "clearButton",
+			_cancelBtnLabel: "cancelButton",
+			_clearFilterMsg: "clearFilterMsg",
+			_onCancel: function(){},
+			_onClear: function(){}
+		});
+		var rpCnt = 0;
+		var dlg;
+		function testDialog(){
+			if(dlg){
+				dlg.destroyRecursive();
+				dlg = null;
+			}
+			dlg = new dijit.Dialog({
+				title: "title",
+				content: new TestWidget({})
+			});
+			dojo.byId("repeatcounter").innerHTML = ++rpCnt;
+			setTimeout(testDialog, 100);
+		}
+		function testStore(){
+			var store = test_store[0];
+			if(store.unwrap){
+				store.unwrap("sort").unwrap("unique").unwrap("filter");
+			}
+			var ns = dojox.grid.enhanced.plugins;
+			ns.wrap(ns.wrap(ns.wrap(store,
+				new ns.filter.ClientSideFilterLayer()),
+				new ns.filter.UniqueLayer()),
+				new ns.filter.SortLayer());
+			dojo.byId("repeatcounter").innerHTML = ++rpCnt;
+			setTimeout(testStore, 100);
+		}
+		var hdl;
+		function testConnect(){
+			if(hdl){
+				dojo.disconnect(hdl);
+			}
+			hdl = dojo.connect(undefined, "aaaaaa", window, function(){});
+			dojo.byId("repeatcounter").innerHTML = ++rpCnt;
+			setTimeout(testConnect, 100);
+		}
+		function scrollToRow(){
+			var g = dijit.byId("grid");
+			if(g){
+				var idx = parseInt(dojo.byId("inputScrollToRowIdx").value, 10);
+				console.log("scroll to ", idx);
+				g.scrollToRow(idx);
+			}
+		}
+		dojo.addOnLoad(function(){
+			var btns = dojo.byId("ctrlBtns2");
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Refresh",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					g && g._refresh();
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Delete Selected",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					g && g.removeSelectedRows();
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Set Store",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					var data = dojo.clone(test_store_data[0]);
+					data.items = data.items.slice(0, 50);
+					console.log(data);
+					g && g.setStore(new dojo.data.ItemFileWriteStore({
+						data: data
+					}));
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Set Structure",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					g && g.set("structure", layout[5]);
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Add Row",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					g && g.addRow();
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Get Selected",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						var s1 = g.selection.selected,
+							s2 = g.selection.getSelected();
+						console.log(s1.length, s1);
+						console.log(s2.length, s2);
+					}
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "resize",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						var cc = dojo.byId("gridContainer");
+						dojo.style(cc, "height", (dojo.contentBox(cc).h + 10) + "px");
+						dojo.style(cc, "width", (dojo.contentBox(cc).w - 10) + "px");
+						g.resize(dojo.contentBox(cc));
+					}
+				}
+			}));
+			var newID = 101;
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Add Item",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					g && g.store.newItem({
+						"id": newID++,
+						"Heard": true, 
+						"Checked": "True", 
+						"Genre":"Easy Listening",	
+						"Artist":"Bette Midler",	
+						"Year":2003,	
+						"Album":"Bette Midler Sings the Rosemary Clooney Songbook",	
+						"Name":"Hey There",	"Length":"03:31",	
+						"Track":4,	
+						"Composer":"Ross, Jerry 1926-1956 -w Adler, Richard 1921-",	
+						"Download Date":"1923/4/9",	
+						"Last Played":"04:32:49"
+					});
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "New item and scroll to",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						var item = g.store.newItem({
+							"id": newID++,
+							"Heard": true, 
+							"Checked": "True", 
+							"Genre":"Easy Listening",	
+							"Artist":"Bette Midler",	
+							"Year":2003,	
+							"Album":"Bette Midler Sings the Rosemary Clooney Songbook",	
+							"Name":"Hey There",	"Length":"03:31",	
+							"Track":4,	
+							"Composer":"Ross, Jerry 1926-1956 -w Adler, Richard 1921-",	
+							"Download Date":"1923/4/9",	
+							"Last Played":"04:32:49"
+						});
+						var rowCount = g.plugin('pagination') ? g.getTotalRowCount() : g.rowCount;
+						setTimeout(function(){g.scrollToRow(rowCount - 1);}, 600);
+						
+					}
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Select All",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						var t1 = (new Date()).getTime();
+						g.selection.selectRange(0, g.rowCount - 1);
+						console.log((new Date()).getTime() - t1);
+					}
+				}
+			}));
+			var toDisable = true;
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Disable 4th row selector",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						var cell = g.layout.cells[0];
+						if(cell.setDisabled){
+							cell.setDisabled(3, toDisable);
+							toDisable = !toDisable;
+						}
+					}
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "Select Unloaded",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					console.log(g);
+					if(g){
+						g.selection.selectRange(60, 100);
+					}
+				}
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "clear sort",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						g.setSortIndex([]);
+					}
+				}
+			}));
+			
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "show filter bar",
+				"onclick": function(){
+					var g = dijit.byId("grid");
+					if(g){
+						g.showFilterBar(true, true);
+					}
+				}
+			}));
+			/*btns.appendChild(dojo.create("button",{
+				"innerHTML": "dialog",
+				"onclick": testDialog
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "store",
+				"onclick": testStore
+			}));
+			btns.appendChild(dojo.create("button",{
+				"innerHTML": "connect",
+				"onclick": testConnect
+			}));*/
+			dojo.subscribe("test_repeat_grid_created", function(){
+				setupSelectorTest();
+				var g = dijit.byId("grid");
+				g && g.setCookieEnabled && g.setCookieEnabled(false);
+				dojo.byId("enableGridCookieCB").checked = true;
+				dojo.byId("enableGridCWidthCookieCB").checked = false;
+				dojo.byId("enableGridSortCookieCB").checked = false;
+				dojo.byId("enableGridNSortCookieCB").checked = false;
+				dojo.byId("enableGridCOrderCookieCB").checked = false;
+				/*if(g.setFilter){
+					g.setFilter([{
+						type: "string",
+						column: 2,
+						value: "Buddy",
+						condition: "contains"
+					},{
+						type: "string",
+						column: 2,
+						value: "King",
+						condition: "contains"
+					}], "logicany");
+				}*/
+			});
+			var formTarget = new dojox.grid.enhanced.plugins.GridSource(dojo.byId("songForm"),{
+		    	isSource: false
+		    });
+		    dojo.connect(formTarget, "onDropGridRows", function(grid, rowIndexes){
+		    	try{
+					var s = grid.store, row = rowIndexes[0], item = grid.getItem(row);
+					console.log("item:", item);
+					dojo.attr(dojo.byId("inputName"), "value", s.getValue(item, "Name"));
+					dojo.attr(dojo.byId("inputAuthor"), "value", s.getValue(item, "Artist"));
+					dojo.attr(dojo.byId("inputAlbum"), "value", s.getValue(item, "Album"));
+		    	}catch(e){
+		    		console.log("-----",e);
+		    	}
+		    });
+		});
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - plugins</h1>
+	<div id="ctrlBtns"></div><br/>
+	<div id="pluginList" dojoType="PluginTable" style="float:right;"></div>
+	<div id="gridContainer"></div><br/>
+	<div id="ctrlBtns2"></div><br/>
+	
+	<div id="menusSupport" style="display: none;">
+		<div dojoType="dijit.Menu" id="headerMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Header Menu Item 1</div>
+			<div dojoType="dijit.MenuItem">Header Menu Item 2</div>
+			<div dojoType="dijit.MenuItem">Header Menu Item 3</div>
+			<div dojoType="dijit.MenuItem">Header Menu Item 4</div>
+		</div>
+		<div dojoType="dijit.Menu" id="rowMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Row Menu Item 1</div>
+			<div dojoType="dijit.MenuItem">Row Menu Item 2</div>
+			<div dojoType="dijit.MenuItem">Row Menu Item 3</div>
+			<div dojoType="dijit.MenuItem">Row Menu Item 4</div>
+		</div>
+		<div dojoType="dijit.Menu" id="cellMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Cell Menu Item 1</div>
+			<div dojoType="dijit.MenuItem">Cell Menu Item 2</div>
+			<div dojoType="dijit.MenuItem">Cell Menu Item 3</div>
+			<div dojoType="dijit.MenuItem">Cell Menu Item 4</div>
+		</div>
+		<div dojoType="dijit.Menu" id="selectedRegionMenu"  style="display: none;">
+			<div dojoType="dijit.MenuItem">Action 1 for Selected Region</div>
+			<div dojoType="dijit.MenuItem">Action 2 for Selected Region</div>
+			<div dojoType="dijit.MenuItem">Action 3 for Selected Region</div>
+			<div dojoType="dijit.MenuItem">Action 4 for Selected Region</div>
+		</div>
+	</div>
+	<div id="exporterSupport" class="supporter" style="display: none;">
+		<input type='button' value='Export All to CSV' onclick='exportCSV()' />
+		<input type='button' value='Export Selected to CSV' onclick='exportSelected()' />
+		Separator is:<input id='sep' type='text' value=',' />
+		Results:<br />
+	    <textarea rows="10" cols="100" id="csvResults"></textarea>
+	</div>
+	<div id="printerSupport" class="supporter" style="display: none;">
+		<input type='button' value='Print All' onclick='printGrid()' />
+		<input type='button' value='Print Selected' onclick='printSelected()' />
+		<input type='button' value='Print Preview' onclick='printPreview()' />
+		Use Title:<input id='print_title' type='text' value='Favorite Music' />
+	</div>
+	<div id="cellMergeSupport" class="supporter" style="display: none;">
+		<table>
+			<tr>
+				<td>At Row</td>
+				<td><input id="inputRow" type="text" value="3"/></td>
+			</tr>
+			<tr>
+				<td>From Column</td>
+				<td><input id="inputStart" type="text" value="1"/></td>
+			</tr>
+			<tr>
+				<td>To Column</td>
+				<td><input id="inputEnd" type="text" value="3"/></td>
+			</tr>
+			<tr>
+				<td>Use Value of Column</td>
+				<td><input id="inputMajor" type="text" value="2"/></td>
+			</tr>
+			<tr>
+				<td><button onclick="mergeCells()">Merge Cells</button></td>
+			</tr>
+		</table>
+	</div>
+	<div id="searchSupport" class="supporter" style="display: none;">
+		Search all: Use "/.../" for Regular Expressions. Wildcards (* and ?) are available when not using "/.../".
+		<hr />
+		<div>Search all columns for<input id="allcolumnsInput" type="text" size="30" value="/void/i" />
+		<button onclick="onSearchAll(dojo.byId('allcolumnsInput').value)">Go =></button>
+		<span id="result1"></span>
+		</div>
+		<hr />
+		Search with a query object (extends the functionality of the standard store query).
+		<table>
+			<thead>
+				<tr>
+					<th>Column</th>
+					<th>Query String or Regular Expression</th>
+					<th></th>
+				</tr>
+			</thead>
+			<tbody>
+				<tr>
+					<td>id</td>
+					<td><input name="id" class="searchInput" type="text" size="30" /></td>
+					<td rowspan="11" align="center" valign="center" style="padding-left: 50px;">
+						<button onclick="onSearch()">Search =></button>
+						<span id="result2"></span>
+					</td>
+				</tr>
+				<tr>
+					<td>Genre</td>
+					<td><input name="Genre" class="searchInput" type="text" size="30" /></td>
+				</tr>
+				<tr>
+					<td>Artist</td>
+					<td><input name="Artist" class="searchInput" type="text" size="30" value="/an/i" /></td>
+				</tr>
+				<tr>
+					<td>Year</td>
+					<td><input name="Year" class="searchInput" type="text" size="30" /></td>
+				</tr>
+				<tr>
+					<td>Album</td>
+					<td><input name="Album" class="searchInput" type="text" size="30" value="/t.*t/i" /></td>
+				</tr>
+				<tr>
+					<td>Name</td>
+					<td><input name="Name" class="searchInput" type="text" size="30" /></td>
+				</tr>
+				<tr>
+					<td>Length</td>
+					<td><input name="Length" class="searchInput" type="text" size="30" /></td>
+				</tr>
+				<tr>
+					<td>Track</td>
+					<td><input name="Track" class="searchInput" type="text" size="30" /></td>
+				</tr>
+				<tr>
+					<td>Composer</td>
+					<td><input name="Composer" class="searchInput" type="text" size="30" value="*ss*" /></td>
+				</tr>
+				<tr>
+					<td>Download Date</td>
+					<td><input name="Download Date" class="searchInput" type="text" size="30" /></td>
+				</tr>
+				<tr>
+					<td>Last Played</td>
+					<td><input name="Last Played" class="searchInput" type="text" size="30" /></td>
+				</tr>
+			</tbody>
+		</table>
+	</div>
+	<div id="cookieSupport" class="supporter" style="display: none;">
+		<p>
+			When destroying the grid...
+		</p>
+		<input id='enableGridCookieCB' type="checkbox" onchange="enableCookie(null, !this.checked)" />Do not persist anything<br />
+		<input id='enableGridCWidthCookieCB' type="checkbox" onchange="enableCookie('cellWidths',!this.checked)" />Do not persist column width<br />
+		<input id='enableGridSortCookieCB' type="checkbox" onchange="enableCookie('sortProps',!this.checked)" />Do not persist single sorting order<br />
+		<input id='enableGridNSortCookieCB' type="checkbox" onchange="enableCookie('nestedSortProps',!this.checked)" />Do not persist nested sorting order<br />
+		<input id='enableGridCOrderCookieCB' type="checkbox" onchange="enableCookie('columnOrder',!this.checked)" />Do not persist column arrangement<br />
+	</div>
+	<div id="selectorSupport" class="supporter" style="display: none;">
+		<div class="selectReport">
+			<h2>Selected Cells:   
+			Count: <input type="text" id="cellCnt" value="0"/>
+			</h2>
+			<textarea id="cells" rows="10" cols="40"></textarea>
+		</div>
+		<div class="selectReport">
+			<h2>Selected Columns:   
+			Count: <input type="text" id="colCnt" value="0"/>
+			</h2>
+			<textarea id="cols" rows="10" cols="40"></textarea>	
+		</div>
+		<div class="selectReport">
+			<h2>Selected Rows:   
+			Count: <input type="text" id="rowCnt" value="0"/>
+			</h2>
+			<textarea id="rows" rows="10" cols="40"></textarea>	
+		</div>
+	</div>
+	<div id="dndSupport" class="supporter" style="display:none; width: 40em;">
+		<form id="songForm">
+		  <table>
+		    <tr>
+		      <td><label for="inputName">Song name</label></td>
+		      <td><input id="inputName" type="text" /></td>
+		    </tr>
+		    <tr>
+		      <td><label for="inputAuthor">Artist</label></td>
+		      <td><input id="inputAuthor" type="text" /></td>
+		    </tr>
+		    <tr>
+		      <td><label for="inputAlbum">Album</label></td>
+		      <td><input id="inputAlbum" type="text" /></td>
+		    </tr>
+		  </table>
+		</form>
+	</div>
+	<div id="paginationSupport" class="supporter" style="display:none;">
+		<table>
+			<tr>
+				<td><input id="inputScrollToRowIdx" type="text" /></td>
+				<td><button onclick="scrollToRow()">Scroll to row</button></td>
+			</tr>
+			<tr>
+				<td></td>
+				<td></td>
+			</tr>
+			<tr>
+				<td></td>
+				<td></td>
+			</tr>
+			<tr>
+				<td></td>
+				<td></td>
+			</tr>
+		</table>
+	</div>
+	<div class="tutor">
+		<p>
+			<h2>How to use this page:</h2>
+			<ol>
+				<li>Select plugins/options at right side.</li>
+				<li>Press "Create" button.</li>
+			</ol>	
+		</p>
+		<p>
+			<h2>Meaning of buttons:</h2>
+			<table>
+				<tr><td>Create</td><td>Create a grid using current plugins/options.</td></tr>
+				<tr><td>Destroy</td><td>Destroy the current grid.</td></tr>
+				<tr><td>Prev</td><td>Create a grid with previous layout</td></tr>
+				<tr><td>Next</td><td>Create a grid with next layout</td></tr>
+				<tr><td>Start</td><td>Keep creating and destorying grid (to test memory leak)</td></tr>
+				<tr><td>End</td><td>Stop the process that "Start" begins.</td></tr>
+				<tr><td>Select All</td><td>Select all plugins</td></tr>
+				<tr><td>Deselect All</td><td>Deselect all plugins</td></tr>
+				<tr><td>Refresh</td><td>Refresh the grid.</td></tr>
+			</table>
+		</p>
+	</div>
+	<div id="repeatcounter" style="float: left;"></div>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html b/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html
new file mode 100644
index 0000000..cd28153
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_print_export.html
@@ -0,0 +1,199 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test Print/Export plugins of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+ 		#grid{
+			width: 95em;
+			height: 50em;
+		}
+	</style>
+	<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="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.data.CsvStore");
+		dojo.require("dojox.grid.enhanced.plugins.exporter.CSVWriter");
+		dojo.require("dojox.grid.enhanced.plugins.Printer");
+		
+		var layout = [//--------------------------------------------------------------------------5
+			{//first view
+				rows:
+				[
+					[
+						{ field: "Genre", width: '10', rowSpan: 2},
+						{ field: "Artist", width: '15'},
+						{ field: "Year", width: '15'},
+					],[
+						{ field: "Album", colSpan: 2}
+					]
+				]
+			},
+			{//second view
+				rows:
+				[
+					[
+						{ field: "Name", width: '20', rowSpan: 2},
+						{ field: "Length", width: '20'},
+						{ field: "Track"}
+					],[
+						{ field: "Composer", colSpan: 2},
+						
+					],[
+						{ field: "Download Date"},
+						{ field: "Last Played"},
+						{ field: "Checked"}
+					]
+				]
+			}
+		];
+		var plugins = {
+			printer: true
+		};
+		function exportCSV(){
+			dijit.byId("grid").exportGrid("csv", {
+				writerArgs: {
+					separator: dojo.byId('sep').value
+				}
+			}, function(str){
+				dojo.byId("csvResults").value = str;
+			});
+		}
+		function exportSelected(){
+			var s = dojo.byId('sep').value;
+			dojo.byId("csvResults").value = dijit.byId("grid").exportSelected("csv", {
+				separator: s
+			});
+		}
+		function exportTable(){
+			dijit.byId("grid").exportGrid("table", function(str){
+				dojo.byId("csvResults").value = str;
+			});
+		}
+		function printGrid(){
+			dijit.byId("grid").printGrid({
+				title: dojo.byId('print_title').value,
+			    cssFiles: ["support/print_style1.css","support/print_style2.css"]
+			});
+		}
+		function printSelected(){
+			dijit.byId("grid").printSelected({
+				title: dojo.byId('print_title').value,
+				cssFiles: ["support/print_style1.css", "support/print_style2.css"]
+			});
+		}
+		function printPreview(){
+			var g = dijit.byId("grid");
+			g.exportToHTML({
+				title: dojo.byId('print_title').value, 
+				cssFiles: ["support/print_style1.css", "support/print_style2.css"]
+			}, function(str){
+				var win = window.open();
+				win.document.open();
+				win.document.write(str);
+				g.normalizePrintedGrid(win.document);
+				win.document.close();
+			});
+		}
+	</script>
+</head>
+<body class="claro">
+	<h1 class="title">dojox.grid.EnhancedGrid - Print, Export</h1>
+	<div id="gridContainer">
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+	</div><br/>
+	<div>
+		<h2>Printer API</h2>
+		<input type='button' value='Print All' onclick='printGrid()' />
+		<input type='button' value='Print Selected' onclick='printSelected()' />
+		<input type='button' value='Print Preview' onclick='printPreview()' />
+		Use Title:<input id='print_title' type='text' value='Favorite Music' />
+		<br/>
+		<h4>Usage 1:</h4>
+		<div style="width:100%;">
+			<pre style="float:left;">someGrid.printGrid({
+    title: "A title: All Content",
+    cssFiles: ["cssfile1.css","cssfile2.css"],
+    writerArgs: {table:"border='border'"},
+    fetchArgs: {start: 0, count: 100}
+});</pre>
+			<pre style="float:left;">someGrid.printSelected({
+    title: "A title: Only Selected",
+    cssFiles: ["cssfile1.css","cssfile2.css"],
+    writerArgs: {table:"border='border'"}
+});</pre>
+		</div>
+		<p style="width:100%;clear:left;">
+			Generate an HTML string containing all the content in the grid and then print it.
+		</p>
+		<ul>
+			<li>A title, an array of CSS files and an associative array containing HTML tag attributes can be provided.</li>
+			<li><b>All three arguments are optional</b>
+			<li>The generated HTML page assigns predefined CSS classes for grid rows and columns, so the user can design styles for every rows,columns or even a single cell.</li>
+		</ul>
+		<h4>Usage 2:</h4>
+		<div>
+			<pre style="float:left;">someGrid.exportToHTML({
+    title: "Export All To HTML",
+    cssFiles: ["cssfile1.css","cssfile2.css"],
+    writerArgs: {table:"border='border'"},
+    fetchArgs: {start: 0, count: 100}
+}, function(html){
+    /* do sth with the generated html page */
+});</pre>
+			<pre style="float:left;">var html = 
+someGrid.exportSelectedToHTML({
+    title: "Export Selected Rows to HTML",
+    cssFiles: ["cssfile1.css","cssfile2.css"],
+    writerArgs: {table:"border='border'"}
+});</pre>
+		</div>
+		<p style="width:100%;clear:left;">
+			Do not print, only generate html string. Users can use this to implement preview.
+		</p>
+		<hr/>
+		<h2>Exporter API</h2>
+		<input type='button' value='Export All to CSV' onclick='exportCSV()' />
+		<input type='button' value='Export Selected to CSV' onclick='exportSelected()' />
+		Separator is:<input id='sep' type='text' value=',' />
+		<input type='button' value='Export All to HTML Table' onclick='exportTable()' /><br/>
+		Results:<br />
+	    <textarea rows="10" cols="100" id="csvResults"></textarea>
+		<h4>Usage:</h4>
+		<pre style="float:left;">someGrid.exportGrid("csv", {
+	writerArgs: {separator:":"},
+	fetchArgs: {start: 0, count: 100}
+}, function(str){
+    /* do sth with str */
+});</pre>
+		<pre style="float:left;">var str = 
+someGrid.exportSelected("csv", {
+	writerArgs: {separator:"###"}
+});</pre>
+		<p style="width:100%;clear:left;">
+			Export grid content to a specified format.
+		</p>
+		<ul>
+			<li>The type argument is a supported format name, mandatory.</li>
+			<li>The writerArgs argument is a format-specific argument, optional.</li>
+			<li>If we are exporting everything, a callback function should be provided.</li>
+			<li>Actually, the printer is implemented using an HTML Table exporter</li>
+		</ul>
+	</div>
+<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_search.html b/dojox/grid/tests/enhanced/test_enhanced_grid_search.html
new file mode 100644
index 0000000..845c7e9
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_search.html
@@ -0,0 +1,186 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html dir="ltr">
+<head>
+	<title>Test Search plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+ 		#grid{
+			width: 90em;
+			height: 30em;
+		}
+		.outerdiv{
+			position: relative;
+			height: 300px;
+			width: 300px;
+			background-color:blue;
+		}
+		.innerdiv{
+			display:block;
+			position: absolute;
+			height: 100px;
+			width: 100px;
+			left: 50px;
+			top: 50px;
+			background-color:red;
+		}
+		.innerBtn{
+			position: absolute;
+			height: 100px;
+			width: 100px;
+			right: 50px;
+			bottom: 50px;
+			background-color:yellow;
+		}
+	</style>
+	<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="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.Search");
+		dojo.require("dojo.parser");
+		
+		var layout = [{
+			cells: [
+				{ field: "id", name:"Identity", datatype:"number", width: 4, editable: false},
+				{ 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},
+				{ field: "Album", name:"Album", datatype:"string", width: 10},
+				{ field: "Name", name:"Name", datatype:"string", width: 8},
+				{ field: "Length", name:"Length", datatype:"string", width: 4},
+				{ field: "Track", name:"Track", datatype:"number", width: 3},
+				{ field: "Composer", name:"Composer", datatype:"string", width: 12},
+				{ field: "Download Date", name:"Download Date", datatype:"date", width: 12},
+				{ field: "Last Played", name:"Last Played", datatype:"time", width: 6},
+				{ field: "Heard", name: "Checked", datatype:"boolean", width: 6}
+			]
+		}];
+		var plugins = {
+			search: true
+		};
+		var getInput = function(str){
+			var start = str.indexOf('/');
+			var end = str.lastIndexOf('/');
+			if(start == 0 || end > 1){
+				var regstr = str.substring(start + 1, end);
+				var modifiers = str.substring(end + 1, str.length);
+				str = new RegExp(regstr,modifiers);
+			}
+			console.log("input:", str);
+			return str;
+		};
+		var onSearched = function(resultId, rowIdx){
+			console.log("search result:", rowIdx);
+			if(rowIdx < 0){
+				dojo.byId(resultId).innerHTML = "Not Found!";
+			}else{
+				dojo.byId(resultId).innerHTML = "Search result is Row " + (rowIdx + 1);
+				dijit.byId("grid").scrollToRow(rowIdx, true);
+			}
+		};
+		var onSearch = function(){
+			var args = {};
+			dojo.query(".searchInput").forEach(function(input){
+				var v = dojo.trim(input.value);
+				if(v){
+					args[input.name] = getInput(v);
+				}
+			});
+			console.log("search arguments:", args);
+			dijit.byId("grid").searchRow(args, dojo.partial(onSearched, "result2"));
+		};
+		var onSearchAll = function(input){
+			dijit.byId("grid").searchRow(getInput(input), dojo.partial(onSearched, "result1"));
+		};
+	</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 - Search</h1>
+	<div id="gridContainer">
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"></div>
+	</div><br/>
+	<br />
+		Note: Use "/.../" for Regular Expressions. Wildcards (* and ?) are available when not using "/.../".
+	<hr />
+	<div>Search all columns for<input id="allcolumnsInput" type="text" size="30" value="/void/i" />
+	<button onclick="onSearchAll(dojo.byId('allcolumnsInput').value)">Go =></button>
+	<span id="result1"></span>
+	<hr />
+	Search with a query object (extends the functionality of the standard store query).
+	<table>
+		<thead>
+			<tr>
+				<th>Column</th>
+				<th>Query String or Regular Expression</th>
+				<th></th>
+			</tr>
+		</thead>
+		<tbody>
+			<tr>
+				<td>id</td>
+				<td><input name="id" class="searchInput" type="text" size="30" /></td>
+				<td rowspan="11" align="center" valign="center" style="padding-left: 50px;">
+					<button onclick="onSearch()">Search =></button>
+					<span id="result2"></span>
+				</td>
+			</tr>
+			<tr>
+				<td>Genre</td>
+				<td><input name="Genre" class="searchInput" type="text" size="30" /></td>
+			</tr>
+			<tr>
+				<td>Artist</td>
+				<td><input name="Artist" class="searchInput" type="text" size="30" value="/an/i" /></td>
+			</tr>
+			<tr>
+				<td>Year</td>
+				<td><input name="Year" class="searchInput" type="text" size="30" /></td>
+			</tr>
+			<tr>
+				<td>Album</td>
+				<td><input name="Album" class="searchInput" type="text" size="30" value="/t.*t/i" /></td>
+			</tr>
+			<tr>
+				<td>Name</td>
+				<td><input name="Name" class="searchInput" type="text" size="30" /></td>
+			</tr>
+			<tr>
+				<td>Length</td>
+				<td><input name="Length" class="searchInput" type="text" size="30" /></td>
+			</tr>
+			<tr>
+				<td>Track</td>
+				<td><input name="Track" class="searchInput" type="text" size="30" /></td>
+			</tr>
+			<tr>
+				<td>Composer</td>
+				<td><input name="Composer" class="searchInput" type="text" size="30" value="*ss*" /></td>
+			</tr>
+			<tr>
+				<td>Download Date</td>
+				<td><input name="Download Date" class="searchInput" type="text" size="30" /></td>
+			</tr>
+			<tr>
+				<td>Last Played</td>
+				<td><input name="Last Played" class="searchInput" type="text" size="30" /></td>
+			</tr>
+		</tbody>
+	</table>
+	<p><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html b/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html
new file mode 100644
index 0000000..ce79467
--- /dev/null
+++ b/dojox/grid/tests/enhanced/test_enhanced_grid_selector.html
@@ -0,0 +1,134 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
+	"http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+	<title>Test Selector plugin of dojox.grid.EnhancedGrid</title>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+	<link rel=stylesheet href="support/common.css"/>
+	<style type="text/css">
+		body {
+			font-size: 0.9em;
+			font-family: Geneva, Arial, Helvetica, sans-serif;
+			padding: 0.5em;
+		}
+		.title {
+			text-align:center;
+			margin:1em;
+		}
+ 		#grid{
+ 			width: 100em;
+			height: 40em;
+		}
+		.selectReport {
+			margin: 10px;
+			display: inline-block;
+		}
+		/*Sample - overwrite default cell style
+		.claro .dojoxGridCell{
+			border-color: transparent #D5CDB5 #D5CDB5 transparent !important;
+		}
+		.dj_ie6 .claro .dojoxGridCell{
+			border: 1px solid #F1F1F1 !important;
+		}*/
+	</style>
+	<script type="text/javascript" src="../../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../../dijit/tests/_testCommon.js"></script>
+	<script type="text/javascript" src="support/test_write_store_music.js"></script>
+	<script type="text/javascript">
+		dojo.require("dojo.parser");
+		dojo.require("dojox.grid.EnhancedGrid");
+		dojo.require("dojox.grid.enhanced.plugins.Selector");
+		dojo.require("dojox.grid.enhanced.plugins.IndirectSelection");
+		
+		var layout = [{
+			cells: [
+				{ field: "id", name:"Identity", datatype:"number", width: 4, editable: false},
+				{ 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},
+				{ field: "Album", name:"Album", datatype:"string", width: 10},
+				{ field: "Name", name:"Name", datatype:"string", width: 8},
+				{ field: "Length", name:"Length", datatype:"string", width: 4},
+				{ field: "Track", name:"Track", datatype:"number", width: 3},
+				{ field: "Composer", name:"Composer", datatype:"string", width: 12},
+				{ field: "Download Date", name:"Download Date", datatype:"date", width: 12},
+				{ field: "Last Played", name:"Last Played", datatype:"time", width: 6},
+				{ field: "Heard", name: "Checked", datatype:"boolean", width: 6}
+			]
+		}];
+		var plugins = {
+			selector: {
+				//col: false,
+				//row: false,
+				//cell: false
+			}
+		}
+		dojo.addOnLoad(function(){
+			var grid = dijit.byId("grid");
+			func = function(type, start, end, selected){
+				fill("col", selected["col"]);
+				fill("row", selected["row"]);
+				fill("cell", selected["cell"]);
+			},
+			fill = function(type, selected){
+				var getString;
+				var cells = grid.layout.cells;
+				switch(type){
+					case "col":
+						getString = function(item){
+							return "Column " + item.col + ": " + dojo.toJson(item.except);
+						}
+						break;
+					case "row":
+						getString = function(item){
+							return "Row " + item.row + ": " + dojo.toJson(item.except);
+						}
+						break;
+					case "cell":
+						getString = function(item){
+							return "Cell " + item.row + " , " + item.col;
+						}
+				}
+				dojo.attr(dojo.byId(type + "s"), "value", dojo.map(selected, function(item){
+					return getString(item);
+				}).join('\n'));
+				dojo.attr(dojo.byId(type + "Cnt"), "value", selected.length);
+			};
+			dojo.connect(grid, "onEndSelect", func);
+			dojo.connect(grid, "onEndDeselect", func);
+		});
+	</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 - Selector</h1>
+	<div id="gridContainer">
+		<div id="grid" dojoType="dojox.grid.EnhancedGrid" store="test_store[0]" structure="layout" plugins="plugins"
+			rowSelector="20px"
+		></div>
+	</div><br/>
+	<div>
+		<div class="selectReport">
+			<h2>Selected Cells:   
+			Count: <input type="text" id="cellCnt" value="0"/>
+			</h2>
+			<textarea id="cells" rows="10" cols="40"></textarea>
+		</div>
+		<div class="selectReport">
+			<h2>Selected Columns:   
+			Count: <input type="text" id="colCnt" value="0"/>
+			</h2>
+			<textarea id="cols" rows="10" cols="40"></textarea>	
+		</div>
+		<div class="selectReport">
+			<h2>Selected Rows:   
+			Count: <input type="text" id="rowCnt" value="0"/>
+			</h2>
+			<textarea id="rows" rows="10" cols="40"></textarea>	
+		</div>
+	</div>
+	<p style="float: left;"><strong>Note:</strong> To see the tundra theme, just append <b style="color:blue;">?theme=tundra</b> to the URL.</p>
+</body>
+</html>
diff --git a/dojox/grid/tests/performance/_gridPerfFramework.js b/dojox/grid/tests/performance/_gridPerfFramework.js
index 28733e6..16ed794 100644
--- a/dojox/grid/tests/performance/_gridPerfFramework.js
+++ b/dojox/grid/tests/performance/_gridPerfFramework.js
@@ -3,7 +3,7 @@ dojo.provide("dojox.grid.tests.performance._gridPerfFramework");
 
 (function(){
 	// some sample data
-	var data_list = [ 
+	var data_list = [
 		{ col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10, col7: false },
 		{ col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7: false },
 		{ col1: "important", col2: true, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true },
@@ -107,7 +107,7 @@ dojo.provide("dojox.grid.tests.performance._gridPerfFramework");
 	// not.
 	dojo.setObject("getRLSTests", function(getRunFunction, getSetUpFunction, getTearDownFunction){
 		var isTop = (window.top == window);
-		var obj = searchParamsAsObj(default_obj);		
+		var obj = searchParamsAsObj(default_obj);
 		var rows = parseInt(obj.rows, 10);
 		var layout = obj.layout;
 		var rowSelector = (obj.rowSelector.toLowerCase() == "true");
@@ -135,8 +135,8 @@ dojo.provide("dojox.grid.tests.performance._gridPerfFramework");
 				onchange: function(){
 					v = parseInt(this.value, 10);
 					if(v && !isNaN(v)){
-						window.location.search="?rows=" + v + 
-								"&layout=" + layout + 
+						window.location.search="?rows=" + v +
+								"&layout=" + layout +
 								"&rowSelector=" + (rowSelector ? "true" : "false") +
 								"&doProfiling=" + (doProfiling ? "true" : "false");
 					}
@@ -144,23 +144,23 @@ dojo.provide("dojox.grid.tests.performance._gridPerfFramework");
 			}, n, "after");
 			n = dojo.create("button", {
 				innerHTML: layout == "single" ? "Dual Layout" : "Single Layout",
-				onclick: function(){window.location.search="?rows=" + rows + 
-								"&layout=" + (layout == "single" ? "dual" : "single") + 
+				onclick: function(){window.location.search="?rows=" + rows +
+								"&layout=" + (layout == "single" ? "dual" : "single") +
 								"&rowSelector=" + (rowSelector ? "true" : "false") +
 								"&doProfiling=" + (doProfiling ? "true" : "false")}
 			}, n, "after");
 			n = dojo.create("button", {
 				innerHTML: rowSelector ? "Remove Row Selector" : "Add Row Selector",
-				onclick: function(){window.location.search="?rows=" + rows + 
-								"&layout=" + layout + 
+				onclick: function(){window.location.search="?rows=" + rows +
+								"&layout=" + layout +
 								"&rowSelector=" + (!rowSelector ? "true" : "false") +
 								"&doProfiling=" + (doProfiling ? "true" : "false")}
 			}, n, "after");
 			if(dojo.isMoz){
 				n = dojo.create("button", {
 					innerHTML: doProfiling ? "No Profiling" : "Do Profiling",
-					onclick: function(){window.location.search="?rows=" + rows + 
-									"&layout=" + layout + 
+					onclick: function(){window.location.search="?rows=" + rows +
+									"&layout=" + layout +
 									"&rowSelector=" + (rowSelector ? "true" : "false") +
 									"&doProfiling=" + (!doProfiling ? "true" : "false")}
 				}, n, "after");
diff --git a/dojox/grid/tests/performance/module.js b/dojox/grid/tests/performance/module.js
index 3d62ce6..db1a6e9 100644
--- a/dojox/grid/tests/performance/module.js
+++ b/dojox/grid/tests/performance/module.js
@@ -10,12 +10,12 @@ try{
 		dojo.forEach(layouts, function(l){
 			dojo.forEach(selectors, function(s){
 				// 5-minute timeout on each of these - since they can take quite a while...
-				doh.registerUrl("Grid Creation - " + r + " Rows, " + l + " Layout" + (s ? "w/ selector" : ""), 
-					dojo.moduleUrl("dojox.grid.tests.performance", "creation.html") + 
+				doh.registerUrl("Grid Creation - " + r + " Rows, " + l + " Layout" + (s ? "w/ selector" : ""),
+					dojo.moduleUrl("dojox.grid.tests.performance", "creation.html") +
 									"?rows=" + r + "&layout=" + l.toLowerCase() + "&rowSelector=" + s,
 					300000);
-				doh.registerUrl("Grid dojo.data Notification - " + r + " Rows, " + l + " Layout" + (s ? "w/ selector" : ""), 
-					dojo.moduleUrl("dojox.grid.tests.performance", "dataNotification.html") + 
+				doh.registerUrl("Grid dojo.data Notification - " + r + " Rows, " + l + " Layout" + (s ? "w/ selector" : ""),
+					dojo.moduleUrl("dojox.grid.tests.performance", "dataNotification.html") +
 									"?rows=" + r + "&layout=" + l.toLowerCase() + "&rowSelector=" + s,
 					300000);
 			});
diff --git a/dojox/grid/tests/robot/DataGrid_mouse.html b/dojox/grid/tests/robot/DataGrid_mouse.html
index c5a7a85..fdbea46 100755
--- a/dojox/grid/tests/robot/DataGrid_mouse.html
+++ b/dojox/grid/tests/robot/DataGrid_mouse.html
@@ -104,7 +104,7 @@
 						var d = new doh.Deferred();
 						var _this=this;
 						doh.robot.sequence(d.getTestCallback(function(){
-							_this.grid.attr("sortFields",[{attribute:"col3",descending:true},{attribute:"id",descending:true}]);
+							_this.grid.set("sortFields",[{attribute:"col3",descending:true},{attribute:"id",descending:true}]);
 							dojo.global.structure1_store1.setValue(dojo.global.structure1_store1._getItemByIdentity(1),"col3","read");
 							// must force refresh to resort
 							_this.grid.render();
@@ -118,7 +118,7 @@
 						return d;
 					},
 					tearDown: function(){
-						this.grid.attr("sortFields",[{attribute:"id",descending:false}]);
+						this.grid.set("sortFields",[{attribute:"id",descending:false}]);
 						dojo.global.structure1_store1.setValue(dojo.global.structure1_store1._getItemByIdentity(1),"col3","new");
 						this.grid.render();
 						this.grid = null;
diff --git a/dojox/grid/tests/robot/structures.js b/dojox/grid/tests/robot/structures.js
index 6bb27ab..a81f87c 100755
--- a/dojox/grid/tests/robot/structures.js
+++ b/dojox/grid/tests/robot/structures.js
@@ -16,24 +16,24 @@ structure1 = [{
 		{ name: 'Id', field: 'id', editable: false /* Can't edit ID's of dojo.data items */ },
 		{ name: 'Date', field: 'col8', width: 10,
 			type: dojox.grid.cells.DateTextBox,
-			formatter: formatDate, 
+			formatter: formatDate,
 			constraint: {formatLength: 'long', selector: "date"}},
-		{ name: 'Priority', styles: 'text-align: center;', field: 'col1', 
-			type: dojox.grid.cells.ComboBox, 
+		{ name: 'Priority', styles: 'text-align: center;', field: 'col1',
+			type: dojox.grid.cells.ComboBox,
 			options: ["normal", "note", "important"], width: 10},
-		{ name: 'Mark', field: 'col2', width: 3, styles: 'text-align: center;', 
+		{ name: 'Mark', field: 'col2', width: 3, styles: 'text-align: center;',
 			type: dojox.grid.cells.CheckBox},
 		{
-			field: 'col3', name: 'Status', 
-			styles: 'text-align: center;', 
-			type: dojox.grid.cells.Select, 
+			field: 'col3', name: 'Status',
+			styles: 'text-align: center;',
+			type: dojox.grid.cells.Select,
 			options: [ "new", "read", "replied" ]
 		},
-		{ name: 'Message', field: 'col4', styles: '', width: 'auto', 
+		{ name: 'Message', field: 'col4', styles: '', width: 'auto',
 			type: dojox.grid.cells.Editor, editorToolbar: true },
-		{ name: 'Amount', field: 'col5', formatter: formatCurrency, constraint: {currency: 'EUR'}, 
+		{ name: 'Amount', field: 'col5', formatter: formatCurrency, constraint: {currency: 'EUR'},
 			widgetClass: dijit.form.CurrencyTextBox },
-		{ name: 'Amount', field: 'col6', formatter: formatCurrency, constraint: {currency: 'EUR'}, 
+		{ name: 'Amount', field: 'col6', formatter: formatCurrency, constraint: {currency: 'EUR'},
 			widgetClass: dijit.form.HorizontalSlider, width: 10}
 	]
 }];
diff --git a/dojox/grid/tests/support/test_data.js b/dojox/grid/tests/support/test_data.js
index 8e7b4eb..9045e9b 100644
--- a/dojox/grid/tests/support/test_data.js
+++ b/dojox/grid/tests/support/test_data.js
@@ -7,7 +7,7 @@
 		label: 'id',
 		items: []
 	};
-	data_list = [ 
+	data_list = [
 		{ col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10, col7: false },
 		{ col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7: false },
 		{ col1: "important", col2: false, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true },
diff --git a/dojox/grid/tests/support/test_data_date.js b/dojox/grid/tests/support/test_data_date.js
index 0df33a6..11b7e24 100644
--- a/dojox/grid/tests/support/test_data_date.js
+++ b/dojox/grid/tests/support/test_data_date.js
@@ -8,7 +8,7 @@
 		items: []
 	};
 	var s = (new Date()).getTime();
-	data_list = [ 
+	data_list = [
 		{ col1: "normal", col2: false, col3: "new", col4: 'But are not followed by two hexadecimal', col5: 29.91, col6: 10, col7: false, col8: new Date() },
 		{ col1: "important", col2: false, col3: "new", col4: 'Because a % sign always indicates', col5: 9.33, col6: -5, col7: false, col8: new Date() },
 		{ col1: "important", col2: false, col3: "read", col4: 'Signs can be selectively', col5: 19.34, col6: 0, col7: true, col8: new Date() },
diff --git a/dojox/grid/tests/support/yahoo_search.js b/dojox/grid/tests/support/yahoo_search.js
index 84a2429..fd28d95 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", dojox.grid._data.dynamic,
 	function(inFields, inData) {
 		this.rowsPerPage = 20;
 		this.fieldNames = [];
@@ -37,7 +37,7 @@ dojo.declare("dojox.grid._data.yahooSearch", dojox.grid._data.dynamic,
 			mimetype: 'text/json',
 			sync: !inAsync,
 			load: turbo.bindArgs(this, "receive", inOnReceive, inOnError),
-			error: turbo.bindArgs(this, "error", inOnError) 
+			error: turbo.bindArgs(this, "error", inOnError)
 		});
 		this.onSend(inParams);
 	},
@@ -45,7 +45,7 @@ dojo.declare("dojox.grid._data.yahooSearch", dojox.grid._data.dynamic,
 		try {
 			inData = inData.ResultSet;
 			inOnReceive(inData);
-			this.onReceive(inData);					
+			this.onReceive(inData);
 		} catch(e) {
 			if (inOnError)
 				inOnError(inData);
@@ -60,10 +60,10 @@ dojo.declare("dojox.grid._data.yahooSearch", dojox.grid._data.dynamic,
 	fetchRowCount: function(inCallback) {
 		this.send(true, inCallback );
 	},
-	// request data 
+	// request data
 	requestRows: function(inRowIndex, inCount)	{
 		inRowIndex = (inRowIndex == undefined ? 0 : inRowIndex);
-		var params = { 
+		var params = {
 			start: inRowIndex + 1
 		}
 		this.send(true, params, turbo.bindArgs(this, this.processRows));
@@ -111,11 +111,11 @@ formatImage = function(inData, inRowIndex) {
 	if (!inData[0] || !inData[1])
 		return ' ';
 	var o = {
-		href: inData[0], 
+		href: inData[0],
 		src: inData[1].Url,
 		width: inData[1].Width,
 		height: inData[1].Height
-	}	
+	}
 	return turbo.supplant('<a href="{href}" target="_blank"><img border=0 src="{src}" width="{width}" height="{height}"></a>', o);
 };
 
diff --git a/dojox/grid/tests/test_change_structure.html b/dojox/grid/tests/test_change_structure.html
index b5e5fee..984d0ab 100644
--- a/dojox/grid/tests/test_change_structure.html
+++ b/dojox/grid/tests/test_change_structure.html
@@ -99,7 +99,7 @@
 		toggleStructure = function() {
 			l2 = !l2;
 			grid.scrollToRow(0);
-			grid.attr('structure', l2 ? structure2 : structure);
+			grid.set('structure', l2 ? structure2 : structure);
 		}
 </script>
 </head>
diff --git a/dojox/grid/tests/test_data_grid_edit.html b/dojox/grid/tests/test_data_grid_edit.html
index f97b06b..bee3ffd 100644
--- a/dojox/grid/tests/test_data_grid_edit.html
+++ b/dojox/grid/tests/test_data_grid_edit.html
@@ -6,7 +6,7 @@
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../resources/Grid.css";
-		@import "../resources/tundraGrid.css";
+		@import "../resources/claroGrid.css";
 		body {
 			font-size: 0.9em;
 			font-family: Geneva, Arial, Helvetica, sans-serif;
@@ -31,7 +31,7 @@
 	</script>
 	<script type="text/javascript" src="support/test_data.js"></script>
 </head>
-<body class="tundra">
+<body class="claro">
 	<div class="heading">dojox.grid.DataGrid Basic Editing Test</div>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
 		jsId="jsonStore" url="../../../dijit/tests/_data/countries.json">
diff --git a/dojox/grid/tests/test_expand.html b/dojox/grid/tests/test_expand.html
index 58a1568..5a10bcc 100644
--- a/dojox/grid/tests/test_expand.html
+++ b/dojox/grid/tests/test_expand.html
@@ -46,11 +46,11 @@
 			cells: [
 				[
 					{ name: 'Whatever', width: 4.5, get: getCheck, formatter: formatCheck, styles: 'text-align: center;' },
-					{name: 'Column 0'},
-					{name: 'Column 1'},
-					{name: 'Column 2'},
-					{name: 'Column 3'},
-					{name: 'Column 4'}
+					{name: 'Column 0', get: get},
+					{name: 'Column 1', get: get},
+					{name: 'Column 2', get: get},
+					{name: 'Column 3', get: get},
+					{name: 'Column 4', get: get}
 				],
 				[ { name: 'Detail', colSpan: 6, get: getDetail, formatter: formatDetail } ]
 			]
@@ -102,7 +102,7 @@
 <body>
 	<div class="heading">dojox.grid.Grid Expand Row Example</div>
 
-	<div id="grid" jsid="grid" dojoType="dojox.grid._Grid" get="get" 
+	<div id="grid" jsid="grid" dojoType="dojox.grid._Grid"
 		structure="structure" rowCount="100000" autoWidth="true" rowSelector="20px"></div>
 
 </body>
diff --git a/dojox/grid/tests/test_sizing.html b/dojox/grid/tests/test_sizing.html
index 930fc57..aa6cd7a 100644
--- a/dojox/grid/tests/test_sizing.html
+++ b/dojox/grid/tests/test_sizing.html
@@ -64,8 +64,8 @@
 		}
 		
 		function resizeGrid() {
-			grid.attr('autoHeight', false);
-			grid.attr('autoWidth', false);
+			grid.set('autoHeight', false);
+			grid.set('autoWidth', false);
 			var
 				w = Number(dojo.byId('gridWidth').value),
 				h = Number(dojo.byId('gridHeight').value);
@@ -75,26 +75,26 @@
 		}
 		
 		function fitWidth() {
-			grid.attr('autoHeight', false);
-			grid.attr('autoWidth', true);
+			grid.set('autoHeight', false);
+			grid.set('autoWidth', true);
 			grid.update();
 		}
 		
 		function fitHeight() {
-			grid.attr('autoHeight', true);
-			grid.attr('autoWidth', false);
+			grid.set('autoHeight', true);
+			grid.set('autoWidth', false);
 			grid.update();
 		}
 		
 		function fitBoth() {
-			grid.attr('autoHeight', true);
-			grid.attr('autoWidth', true);
+			grid.set('autoHeight', true);
+			grid.set('autoWidth', true);
 			grid.update();
 		}
 		
 		function sizeDefault() {
-			grid.attr('autoHeight', false);
-			grid.attr('autoWidth', false);
+			grid.set('autoHeight', false);
+			grid.set('autoWidth', false);
 			grid.domNode.style.width = '';
 			grid.domNode.style.height = 0;
 			grid.update();
diff --git a/dojox/grid/tests/test_treegrid.html b/dojox/grid/tests/test_treegrid.html
index b037772..0967bb7 100644
--- a/dojox/grid/tests/test_treegrid.html
+++ b/dojox/grid/tests/test_treegrid.html
@@ -6,7 +6,7 @@
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../resources/Grid.css";
-		@import "../resources/tundraGrid.css";
+		@import "../resources/claroGrid.css";
 		.grid {
 			width: 70em;
 			height: 15em;
@@ -85,7 +85,7 @@
 
 	</script>
 </head>
-<body class="tundra">
+<body class="claro">
 	<h1 class="testTitle">Test: dojox.tests.grid.TreeGrid</h1>
 	<span dojoType="dojo.data.ItemFileWriteStore" 
 		jsId="jsonStore" url="support/gamedata.json">
diff --git a/dojox/grid/tests/test_treegrid_lazyloading.html b/dojox/grid/tests/test_treegrid_lazyloading.html
new file mode 100644
index 0000000..1ccb2f0
--- /dev/null
+++ b/dojox/grid/tests/test_treegrid_lazyloading.html
@@ -0,0 +1,154 @@
+	<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+    <head>
+        <title>dojox.grid.TreeGrid Lazy-loading for children items test</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
+        <style type="text/css">
+            @import "../../../dojo/resources/dojo.css";
+            @import "../../../dijit/themes/claro/claro.css";
+            @import "../../../dojox/grid/resources/Grid.css";
+			@import "../../../dojox/grid/resources/tundraGrid.css";
+            @import "../../../dojox/grid/resources/claroGrid.css";
+            body {
+				font-size: 0.9em;
+				font-family: Geneva, Arial, Helvetica, sans-serif;
+				padding: 0.5em;
+			}
+			.title {
+				text-align:center;
+				margin:1em;
+			}
+			.grid {
+                width: 70em;
+                height: 30em;
+				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("dijit.tree.ForestStoreModel");
+            dojo.require("dojo.data.ItemFileWriteStore");
+            dojo.require("dojo.parser");
+			dojo.require("dijit.form.Button");
+
+			var rows = 5;
+			var continentItems = [
+				{name:'South America', type:'continent', population:'', area:''},
+				{name:'North America', type:'continent', population:'', area:''},
+				{name:'Asia', type:'continent', population:'', area:''},
+				{name:'Oceania', type:'continent', population:'', area:''},
+				{name:'Europe', type:'continent', population:'', area:''}
+			];
+			var continentChildrenList = [];
+			for(var i=0, l=continentItems.length; i<rows; i++){
+				continentChildrenList.push(dojo.mixin({ id: 'continent_' + i }, continentItems[i%l]));
+			}
+			
+			rows = 100;
+			var countryItems = [
+				{name:'Egypt', type:'country', population:'', area:''},
+				{name: 'Kenya', type: 'country', population:'', area:''},
+				{name:'Sudan', type:'country', population:'', area:''},
+				{name:'China', type:'country' , population:'', area:''},
+		        {name:'India', type:'country' , population:'', area:''},
+		        {name:'Russia', type:'country' , population:'', area:''},
+		        {name:'Mongolia', type:'country', population:'', area:'' },
+				{name:'Australia', type:'country', population:'21 million', area:''},
+		        {name:'Germany', type:'country', population:'', area:'' },
+		        {name:'France', type:'country', population:'', area:'' },
+		        {name:'Spain', type:'country', population:'', area:'' },
+		        {name:'Italy', type:'country', population:'', area:'' },
+		        {name:'Mexico', type:'country',  population:'108 million', area:'1,972,550 sq km'},
+				{name:'Canada', type:'country',  population:'33 million', area:'9,984,670 sq km'},
+				{name:'United States of America', type:'country', population:'', area:'' },
+				{name:'Brazil', type:'country', population:'186 million', area:'' },
+		        {name:'Argentina', type:'country', population:'40 million', area:'' }
+			];
+			
+			var countryChildrenList = [];
+			for(var i=0, l=countryItems.length; i<rows; i++){
+				countryChildrenList.push(dojo.mixin({ id: 'country_' + i }, countryItems[i%l]));
+			}
+			
+			cityItems = [
+				{name:'Nairobi', type:'city', population:'', area:''},
+		        {name:'Mombasa', type:'city', population:'', area:''},
+		        {name:'Khartoum', type:'city', population:'', area:''},
+				{name:'Mexico City', type:'city', population:'19 million', area:'', timezone:'-6 UTC'},
+		        {name:'Guadalajara', type:'city', population:'4 million', area:'', timezone:'-6 UTC' },
+		        {name:'Ottawa', type:'city', population:'0.9 million', area:'', timezone:'-5 UTC'},
+		        {name:'Toronto', type:'city', population:'2.5 million', area:'', timezone:'-5 UTC' },
+			];
+			
+			var cityChildrenList = [];
+			for(var i=0, l=cityItems.length; i<rows; i++){
+				cityChildrenList.push(dojo.mixin({ id: 'city_' + i }, cityItems[i%l]));
+			}
+
+			var dataItems = {
+				identifier: 'id',
+                label: 'name',
+				items: [
+					{id:'Continent', name:'Continent', type:'', population: '', area: '', children: continentChildrenList},
+					{id:"Country", name:"Country", type:"", population: '', area: '', children: countryChildrenList},
+					{id:"City", name:"City", type:"", population: '', area: '', children: cityChildrenList}
+				]
+			};
+			
+			function deleteItem() {
+				var item = grid.getItem(3);
+				grid.store.deleteItem(item);
+			}
+			
+			var idx = 1000;
+			function addItem(){
+				var item = {id:'test_' + idx, name:'test_' + idx, type:'', population: '', area: ''};
+				grid.store.newItem(item);
+				idx++;
+			}
+			
+			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++;
+				}});
+			}
+			
+			function removeSelected(){
+				grid.removeSelectedRows();
+			}
+
+        </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>
+    </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_model.html b/dojox/grid/tests/test_treegrid_model.html
index 6777229..00c994b 100644
--- a/dojox/grid/tests/test_treegrid_model.html
+++ b/dojox/grid/tests/test_treegrid_model.html
@@ -5,9 +5,9 @@
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8"></meta>
         <style type="text/css">
             @import "../../../dojo/resources/dojo.css";
-            @import "../../../dijit/themes/tundra/tundra.css";
+            @import "../../../dijit/themes/claro/claro.css";
             @import "../../../dojox/grid/resources/Grid.css";
-            @import "../../../dojox/grid/resources/tundraGrid.css";
+            @import "../../../dojox/grid/resources/claroGrid.css";
             .grid {
                 width: 70em;
                 height: 40em;
@@ -105,7 +105,7 @@
 			});
         </script>
     </head>
-    <body class="tundra">
+    <body class="claro">
         <h1 class="testTitle">Test: dojox.grid.TreeGrid - Model-based</h1>
         <span dojoType="dojo.data.ItemFileWriteStore"
               jsId="jsonStore" data="dataItems">
diff --git a/dojox/grid/tests/test_yahoo_search.html b/dojox/grid/tests/test_yahoo_search.html
index bc65865..9450dae 100644
--- a/dojox/grid/tests/test_yahoo_search.html
+++ b/dojox/grid/tests/test_yahoo_search.html
@@ -90,7 +90,7 @@
 			var web = dojo.byId('webRb').checked;
 			store.service = (web ? service.webSearch : service.imageSearch);
 			if(lastLayoutType != (web ? webLayout : imageLayout)){
-				grid.attr('structure', web ? webLayout : imageLayout);
+				grid.set('structure', web ? webLayout : imageLayout);
 			}
 			grid.filter({ query: value }, true);
 		}
diff --git a/dojox/grid/tests/yahooSearch.js b/dojox/grid/tests/yahooSearch.js
index 3d0fc3e..8637858 100644
--- a/dojox/grid/tests/yahooSearch.js
+++ b/dojox/grid/tests/yahooSearch.js
@@ -37,7 +37,7 @@ var getLink = function(inRowIndex, inItem){
 
 var formatLink = function(result){
 	return typeof result == 'object' ? dojo.string.substitute(
-		'<a target="_blank" href="${href}">${text}</a>', 
+		'<a target="_blank" href="${href}">${text}</a>',
 		result
 	) : result;
 }
@@ -65,7 +65,7 @@ var getImage = function(inRowIndex, inItem){
 var formatImage = function(result){
 	return typeof result == "object" ? dojo.string.substitute(
 		'<a href="${href}" target="_blank"><img border=0 src="${src}" width="${width}" height="${height}"></a>', result) :
-		result;	
+		result;
 }
 
 var getDimensions = function(inRowIndex, inItem){
diff --git a/dojox/highlight.js b/dojox/highlight.js
index 342bf75..a598862 100644
--- a/dojox/highlight.js
+++ b/dojox/highlight.js
@@ -1,2 +1,2 @@
 dojo.provide("dojox.highlight");
-dojo.require("dojox.highlight._base"); 
+dojo.require("dojox.highlight._base");
diff --git a/dojox/highlight/_base.js b/dojox/highlight/_base.js
index 8786cce..516cefa 100644
--- a/dojox/highlight/_base.js
+++ b/dojox/highlight/_base.js
@@ -1,16 +1,16 @@
 dojo.provide("dojox.highlight._base");
 /*=====
 	dojox.highlight = {
-		//	summary: 
+		//	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 
+		//		Released under CLA by the Dojo Toolkit, original BSD release
 		//		available from: http://softwaremaniacs.org/soft/highlight/
 		//
-		//		
+		//
 	};
 =====*/
 
@@ -35,7 +35,7 @@ dojo.provide("dojox.highlight._base");
 		},
 		QUOTE_STRING_MODE: {
 			className: 'string',
-			begin: '"', 
+			begin: '"',
 			end: '"',
 			illegal: '\\n',
 			contains: ['escape'],
@@ -98,7 +98,7 @@ dojo.provide("dojox.highlight._base");
 				var kw = mode.keywords[key];
     			if(kw instanceof Object){  // dojo.isObject?
 					mode.keywordGroups = mode.keywords;
-				}else{ 
+				}else{
 					mode.keywordGroups = {keyword: mode.keywords};
 				}
 				break;
@@ -362,7 +362,7 @@ dojo.provide("dojox.highlight._base");
 	}
 	function highlightStringLanguage(lang, str){
 		var highlight = new Highlighter(lang, str);
-		return {result:highlight.result, langName:lang, partialResult:highlight.partialResult};		
+		return {result:highlight.result, langName:lang, partialResult:highlight.partialResult};
 	}
 
 	function highlightLanguage(block, lang){
@@ -407,15 +407,15 @@ dojo.provide("dojox.highlight._base");
 
 	dojox.highlight.init = function(/* String|DomNode */ node){
 		//	summary: Highlight a passed node
-		//	
+		//
 		//	description:
-		//		
+		//
 		//		Syntax highlight a passed DomNode or String ID of a DomNode
 		//
-		// 
+		//
 		//	example:
 		//	|	dojox.highlight.init("someId");
-		//		
+		//
 		node = dojo.byId(node);
 		if(dojo.hasClass(node, "no-highlight")){ return; }
 		if(!verifyText(node)){ return; }
@@ -441,11 +441,11 @@ dojo.provide("dojox.highlight._base");
 		//		`dojox.highlight.init` directly.
 		//
 		//	props: Object?
-		//		Unused. Pass 'null' or {}. Positional usage to allow `dojo.parser` to instantiate 
+		//		Unused. Pass 'null' or {}. Positional usage to allow `dojo.parser` to instantiate
 		//		this class as other Widgets would be.
-		// 
+		//
 		//	node: String|DomNode
-		//		A String ID or DomNode reference to use as the root node of this instance. 
+		//		A String ID or DomNode reference to use as the root node of this instance.
 		//
 		//	example:
 		//	|	<pre><code dojoType="dojox.highlight.Code">for(var i in obj){ ... }</code></pre>
diff --git a/dojox/highlight/languages/cpp.js b/dojox/highlight/languages/cpp.js
index 6088f14..97b1af6 100644
--- a/dojox/highlight/languages/cpp.js
+++ b/dojox/highlight/languages/cpp.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.highlight.languages.cpp"); 
+dojo.provide("dojox.highlight.languages.cpp");
 
 dojo.require("dojox.highlight._base");
 
@@ -12,17 +12,17 @@ dojo.require("dojox.highlight._base");
 			contains: ['comment', 'string', 'number', 'preprocessor'],
 			keywords: {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
-				'char': 1, 'catch': 1, 'export': 1, 'virtual': 1, 
+				'char': 1, 'catch': 1, 'export': 1, 'virtual': 1,
 				'operator': 2, 'sizeof': 2, 'dynamic_cast': 2, 'typedef': 2,
 				'const_cast': 2, 'const': 1, 'struct': 1, 'for': 1,
 				'static_cast': 2, 'union': 1, 'namespace': 1, 'unsigned': 1,
-				'long': 1, 'throw': 1, 'volatile': 2, 'static': 1, 
-				'protected': 1, 'bool': 1, 'template': 1, 'mutable': 1, 
+				'long': 1, 'throw': 1, 'volatile': 2, 'static': 1,
+				'protected': 1, 'bool': 1, 'template': 1, 'mutable': 1,
 				'if': 1, 'public': 1, 'friend': 2, 'do': 1, 'return': 1,
-				'goto': 1, 'auto': 1, 'void': 2, 'enum': 1, 'else': 1, 
+				'goto': 1, 'auto': 1, 'void': 2, 'enum': 1, 'else': 1,
 				'break': 1, 'new': 1, 'extern': 1, 'using': 1, 'true': 1,
 				'class': 1, 'asm': 1, 'case': 1, 'typeid': 1, 'short': 1,
-				'reinterpret_cast': 2, 'default': 1, 'double': 1, 
+				'reinterpret_cast': 2, 'default': 1, 'double': 1,
 				'register': 1, 'explicit': 1, 'signed': 1, 'typename': 1,
 				'try': 1, 'this': 1, 'switch': 1, 'continue': 1, 'wchar_t': 1,
 				'inline': 1, 'delete': 1
@@ -36,7 +36,7 @@ dojo.require("dojox.highlight._base");
 			dhc.BACKSLASH_ESCAPE,
 			{
 				className: 'string',
-				begin: '\'', 
+				begin: '\'',
 				end: '[^\\\\]\'',
 				illegal: '[^\\\\][^\']'
 			},
diff --git a/dojox/highlight/languages/css.js b/dojox/highlight/languages/css.js
index b90ee74..c5b5cee 100644
--- a/dojox/highlight/languages/css.js
+++ b/dojox/highlight/languages/css.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.highlight.languages.css"); 
+dojo.provide("dojox.highlight.languages.css");
 
 dojo.require("dojox.highlight._base");
 dojo.require("dojox.highlight.languages.html");
@@ -33,7 +33,7 @@ dojo.require("dojox.highlight.languages.html");
 				begin: '{', end: '}',
 				lexems: ['[A-Za-z-]+'],
 				keywords: {
-					'play-during': 1, 'counter-reset': 1, 
+					'play-during': 1, 'counter-reset': 1,
 					'counter-increment': 1, 'min-height': 1, 'quotes': 1,
 					'border-top': 1, 'pitch': 1, 'font': 1, 'pause': 1,
 					'list-style-image': 1, 'border-width': 1, 'cue': 1,
@@ -41,7 +41,7 @@ dojo.require("dojox.highlight.languages.html");
 					'richness': 1, 'speech-rate': 1, 'border-bottom': 1,
 					'border-spacing': 1, 'background': 1, 'list-style-type': 1,
 					'text-align': 1, 'page-break-inside': 1, 'orphans': 1,
-					'page-break-before': 1, 'text-transform': 1, 
+					'page-break-before': 1, 'text-transform': 1,
 					'line-height': 1, 'padding-left': 1, 'font-size': 1,
 					'right': 1, 'word-spacing': 1, 'padding-top': 1,
 					'outline-style': 1, 'bottom': 1, 'content': 1,
@@ -49,7 +49,7 @@ dojo.require("dojox.highlight.languages.html");
 					'border-left-style': 1, 'voice-family': 1,
 					'background-color': 1, 'border-bottom-color': 1,
 					'outline-color': 1, 'unicode-bidi': 1, 'max-width': 1,
-					'font-family': 1, 'caption-side': 1, 
+					'font-family': 1, 'caption-side': 1,
 					'border-right-width': 1, 'pause-before': 1,
 					'border-top-style': 1, 'color': 1, 'border-collapse': 1,
 					'border-bottom-width': 1, 'float': 1, 'height': 1,
@@ -66,13 +66,13 @@ dojo.require("dojox.highlight.languages.html");
 					'list-style': 1, 'padding-bottom': 1, 'pause-after': 1,
 					'speak-numeral': 1, 'margin-left': 1, 'widows': 1,
 					'border': 1, 'font-style': 1, 'border-left-color': 1,
-					'pitch-range': 1, 'background-repeat': 1, 
-					'table-layout': 1, 'margin-bottom': 1, 
+					'pitch-range': 1, 'background-repeat': 1,
+					'table-layout': 1, 'margin-bottom': 1,
 					'speak-punctuation': 1, 'font-weight': 1,
-					'border-right-color': 1, 'page-break-after': 1, 
+					'border-right-color': 1, 'page-break-after': 1,
 					'position': 1, 'white-space': 1, 'text-indent': 1,
-					'background-image': 1, 'volume': 1, 'stress': 1, 
-					'outline': 1, 'clear': 1, 'z-index': 1, 
+					'background-image': 1, 'volume': 1, 'stress': 1,
+					'outline': 1, 'clear': 1, 'z-index': 1,
 					'text-decoration': 1, 'margin-top': 1, 'azimuth': 1,
 					'cue-after': 1, 'left': 1, 'list-style-position': 1
 				},
@@ -81,10 +81,10 @@ dojo.require("dojox.highlight.languages.html");
 			dhc.C_BLOCK_COMMENT_MODE,
 			{
 				className: 'value',
-				begin: ':', 
-				end: ';', 
-				endsWithParent: true, 
-				excludeBegin: true, 
+				begin: ':',
+				end: ';',
+				endsWithParent: true,
+				excludeBegin: true,
 				excludeEnd: true
 			}
 		]
diff --git a/dojox/highlight/languages/delphi.js b/dojox/highlight/languages/delphi.js
index c49e556..288c0ee 100644
--- a/dojox/highlight/languages/delphi.js
+++ b/dojox/highlight/languages/delphi.js
@@ -1,21 +1,21 @@
-dojo.provide("dojox.highlight.languages.delphi"); 
+dojo.provide("dojox.highlight.languages.delphi");
 
 dojo.require("dojox.highlight._base");
 
-(function(){ 
+(function(){
 	var DELPHI_KEYWORDS = {
-		'and': 1, 'safecall': 1, 'cdecl': 1, 'then': 1, 'string': 1, 
-		'exports': 1, 'library': 1, 'not': 1, 'pascal': 1, 'set': 1, 
+		'and': 1, 'safecall': 1, 'cdecl': 1, 'then': 1, 'string': 1,
+		'exports': 1, 'library': 1, 'not': 1, 'pascal': 1, 'set': 1,
 		'virtual': 1, 'file': 1, 'in': 1, 'array': 1, 'label': 1, 'packed': 1,
 		'end.': 1, 'index': 1, 'while': 1, 'const': 1, 'raise': 1, 'for': 1,
 		'to': 1, 'implementation': 1, 'with': 1, 'except': 1, 'overload': 1,
 		'destructor': 1, 'downto': 1, 'finally': 1, 'program': 1, 'exit': 1,
-		'unit': 1, 'inherited': 1, 'override': 1, 'if': 1, 'type': 1, 
+		'unit': 1, 'inherited': 1, 'override': 1, 'if': 1, 'type': 1,
 		'until': 1, 'function': 1, 'do': 1, 'begin': 1, 'repeat': 1, 'goto': 1,
-		'nil': 1, 'far': 1, 'initialization': 1, 'object': 1, 'else': 1, 
-		'var': 1, 'uses': 1, 'external': 1, 'resourcestring': 1, 
+		'nil': 1, 'far': 1, 'initialization': 1, 'object': 1, 'else': 1,
+		'var': 1, 'uses': 1, 'external': 1, 'resourcestring': 1,
 		'interface': 1, 'end': 1, 'finalization': 1, 'class': 1, 'asm': 1,
-		'mod': 1, 'case': 1, 'on': 1, 'shr': 1, 'shl': 1, 'of': 1, 
+		'mod': 1, 'case': 1, 'on': 1, 'shr': 1, 'shl': 1, 'of': 1,
 		'register': 1, 'xorwrite': 1, 'threadvar': 1, 'try': 1, 'record': 1,
 		'near': 1, 'stored': 1, 'constructor': 1, 'stdcall': 1, 'inline': 1,
 		'div': 1, 'out': 1, 'or': 1, 'procedure': 1
@@ -26,15 +26,15 @@ dojo.require("dojox.highlight._base");
 		'finally': 1, 'program': 1, 'inherited': 1, 'override': 1, 'then': 1,
 		'exports': 1, 'string': 1, 'read': 1, 'not': 1, 'mod': 1, 'shr': 1,
 		'try': 1, 'div': 1, 'shl': 1, 'set': 1, 'library': 1, 'message': 1,
-		'packed': 1, 'index': 1, 'for': 1, 'near': 1, 'overload': 1, 
+		'packed': 1, 'index': 1, 'for': 1, 'near': 1, 'overload': 1,
 		'label': 1, 'downto': 1, 'exit': 1, 'public': 1, 'goto': 1,
 		'interface': 1, 'asm': 1, 'on': 1, 'of': 1, 'constructor': 1, 'or': 1,
 		'private': 1, 'array': 1, 'unit': 1, 'raise': 1, 'destructor': 1,
-		'var': 1, 'type': 1, 'until': 1, 'function': 1, 'else': 1, 
+		'var': 1, 'type': 1, 'until': 1, 'function': 1, 'else': 1,
 		'external': 1, 'with': 1, 'case': 1, 'default': 1, 'record': 1,
-		'while': 1, 'protected': 1, 'property': 1, 'procedure': 1, 
-		'published': 1, 'and': 1, 'cdecl': 1, 'do': 1, 'threadvar': 1, 
-		'file': 1, 'in': 1, 'if': 1, 'end': 1, 'virtual': 1, 'write': 1, 
+		'while': 1, 'protected': 1, 'property': 1, 'procedure': 1,
+		'published': 1, 'and': 1, 'cdecl': 1, 'do': 1, 'threadvar': 1,
+		'file': 1, 'in': 1, 'if': 1, 'end': 1, 'virtual': 1, 'write': 1,
 		'far': 1, 'out': 1, 'begin': 1, 'repeat': 1, 'nil': 1,
 		'initialization': 1, 'object': 1, 'uses': 1, 'resourcestring': 1,
 		'class': 1, 'register': 1, 'xorwrite': 1, 'inline': 1
diff --git a/dojox/highlight/languages/django.js b/dojox/highlight/languages/django.js
index 68d676d..0e179f9 100644
--- a/dojox/highlight/languages/django.js
+++ b/dojox/highlight/languages/django.js
@@ -1,10 +1,10 @@
-dojo.provide("dojox.highlight.languages.django"); 
+dojo.provide("dojox.highlight.languages.django");
 
 dojo.require("dojox.highlight._base");
 dojo.require("dojox.highlight.languages.xml");
 dojo.require("dojox.highlight.languages.html");
 
-(function(){ 
+(function(){
 	var dh = dojox.highlight, dhc = dh.constants, dhl = dh.languages, x = dhl.xml, h = dhl.html;
 	dhl.django = {
 		defaultMode: {
@@ -31,7 +31,7 @@ dojo.require("dojox.highlight.languages.html");
 			h.HTML_VALUE,
 			{
 				className: 'template_comment',
-				begin: '\\{\\%\\s*comment\\s*\\%\\}', 
+				begin: '\\{\\%\\s*comment\\s*\\%\\}',
 				end: '\\{\\%\\s*endcomment\\s*\\%\\}'
 			},
 			{
@@ -45,8 +45,8 @@ dojo.require("dojox.highlight.languages.html");
 				keywords: {
 					'comment': 1, 'endcomment': 1, 'load': 1,
 					'templatetag': 1, 'ifchanged': 1, 'endifchanged': 1,
-					'if': 1, 'endif': 1, 'firstof': 1, 'for': 1, 
-					'endfor': 1, 'in': 1, 'ifnotequal': 1, 
+					'if': 1, 'endif': 1, 'firstof': 1, 'for': 1,
+					'endfor': 1, 'in': 1, 'ifnotequal': 1,
 					'endifnotequal': 1, 'widthratio': 1, 'extends': 1,
 					'include': 1, 'spaceless': 1, 'endspaceless': 1,
 					'regroup': 1, 'by': 1, 'as': 1, 'ifequal': 1,
@@ -76,7 +76,7 @@ dojo.require("dojox.highlight.languages.html");
 					'unordered_list': 1, 'urlencode': 1, 'timeuntil': 1,
 					'urlizetrunc': 1, 'wordcount': 1, 'stringformat': 1,
 					'linenumbers': 1, 'slice': 1, 'date': 1, 'dictsort': 1,
-					'dictsortreversed': 1, 'default_if_none': 1, 
+					'dictsortreversed': 1, 'default_if_none': 1,
 					'pluralize': 1, 'lower': 1, 'join': 1, 'center': 1,
 					'default': 1, 'truncatewords_html': 1, 'upper': 1,
 					'length': 1, 'phone2numeric': 1, 'wordwrap': 1, 'time': 1,
diff --git a/dojox/highlight/languages/groovy.js b/dojox/highlight/languages/groovy.js
index c1e2027..46d7454 100644
--- a/dojox/highlight/languages/groovy.js
+++ b/dojox/highlight/languages/groovy.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.highlight.languages.groovy"); 
+dojo.provide("dojox.highlight.languages.groovy");
 
 dojo.require("dojox.highlight._base");
 
@@ -6,16 +6,16 @@ dojo.require("dojox.highlight._base");
 	var dh = dojox.highlight, dhc = dh.constants;
 	var GROOVY_KEYWORDS = {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
-				'char': 1, 'catch': 1, 'abstract': 1, 'assert': 1, 
+				'char': 1, 'catch': 1, 'abstract': 1, 'assert': 1,
 				'const': 1, 'byte': 1, 'for': 1, 'final': 1,
 				'finally': 1, 'implements': 1, 'import': 1, 'extends': 1,
-				'long': 1, 'throw': 1, 'instanceof': 2, 'static': 1, 
-				'protected': 1, 'boolean': 1, 'interface': 2, 'native': 1, 
+				'long': 1, 'throw': 1, 'instanceof': 2, 'static': 1,
+				'protected': 1, 'boolean': 1, 'interface': 2, 'native': 1,
 				'if': 1, 'public': 1, 'new': 1, 'do': 1, 'return': 1,
-				'goto': 1, 'package': 2, 'void': 2, 'short': 1, 'else': 1, 
+				'goto': 1, 'package': 2, 'void': 2, 'short': 1, 'else': 1,
 				'break': 1, 'new': 1, 'strictfp': 1, 'super': 1, 'true': 1,
 				'class': 1, 'synchronized': 1, 'case': 1, 'this': 1, 'short': 1,
-				'throws': 1, 'transient': 1, 'double': 1, 'volatile': 1, 
+				'throws': 1, 'transient': 1, 'double': 1, 'volatile': 1,
 				'try': 1, 'this': 1, 'switch': 1, 'continue': 1, 'def': 2
 			}
 	dh.languages.groovy = {
@@ -35,7 +35,7 @@ dojo.require("dojox.highlight._base");
 				begin: '\"\"\"', end: '\"\"\"',
 				contains: ['escape'],
 				relevance: 0
-			},			
+			},
 			dhc.QUOTE_STRING_MODE,
 			dhc.BACKSLASH_ESCAPE,
  			{
@@ -43,7 +43,7 @@ dojo.require("dojox.highlight._base");
 				begin: '\'\'\'', end: '\'\'\'',
 				contains: ['escape'],
 				relevance: 0
-			},				
+			},
 			dhc.APOS_STRING_MODE,
 			{
 				className: 'function',
@@ -51,7 +51,7 @@ dojo.require("dojox.highlight._base");
 				end: '\\)',
 				contains: ['comment', 'number', 'string', 'function', 'block'],
 				keywords: GROOVY_KEYWORDS
-			},		
+			},
 			{
 				lexems: [dhc.UNDERSCORE_IDENT_RE],
 				className: 'block',
@@ -59,7 +59,7 @@ dojo.require("dojox.highlight._base");
 				end: '\\}',
 				contains: ['comment', 'string', 'number', 'function', 'block'],
 				keywords: GROOVY_KEYWORDS
-			}					
+			}
 		],
 		//exporting constants
 		GROOVY_KEYWORDS: GROOVY_KEYWORDS
diff --git a/dojox/highlight/languages/html.js b/dojox/highlight/languages/html.js
index ffca78e..1790dd3 100644
--- a/dojox/highlight/languages/html.js
+++ b/dojox/highlight/languages/html.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.highlight.languages.html"); 
+dojo.provide("dojox.highlight.languages.html");
 
 dojo.require("dojox.highlight._base");
 dojo.require("dojox.highlight.languages.xml");
@@ -10,12 +10,12 @@ dojo.require("dojox.highlight.languages.xml");
 		'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, 
+		'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, 
+		'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,
diff --git a/dojox/highlight/languages/java.js b/dojox/highlight/languages/java.js
index e51f37f..e34935b 100644
--- a/dojox/highlight/languages/java.js
+++ b/dojox/highlight/languages/java.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.highlight.languages.java"); 
+dojo.provide("dojox.highlight.languages.java");
 
 dojo.require("dojox.highlight._base");
 
@@ -6,16 +6,16 @@ dojo.require("dojox.highlight._base");
 	var dh = dojox.highlight, dhc = dh.constants;
 	var javakeywords = {
 				'false': 1, 'int': 1, 'float': 1, 'while': 1, 'private': 1,
-				'char': 1, 'catch': 1, 'abstract': 1, 'assert': 1, 
+				'char': 1, 'catch': 1, 'abstract': 1, 'assert': 1,
 				'const': 1, 'byte': 1, 'for': 1, 'final': 1,
 				'finally': 1, 'implements': 1, 'import': 1, 'extends': 1,
-				'long': 1, 'throw': 1, 'instanceof': 2, 'static': 1, 
-				'protected': 1, 'boolean': 1, 'interface': 2, 'native': 1, 
+				'long': 1, 'throw': 1, 'instanceof': 2, 'static': 1,
+				'protected': 1, 'boolean': 1, 'interface': 2, 'native': 1,
 				'if': 1, 'public': 1, 'new': 1, 'do': 1, 'return': 1,
-				'goto': 1, 'package': 2, 'void': 2, 'short': 1, 'else': 1, 
+				'goto': 1, 'package': 2, 'void': 2, 'short': 1, 'else': 1,
 				'break': 1, 'new': 1, 'strictfp': 1, 'super': 1, 'true': 1,
 				'class': 1, 'synchronized': 1, 'case': 1, 'this': 1, 'short': 1,
-				'throws': 1, 'transient': 1, 'double': 1, 'volatile': 1, 
+				'throws': 1, 'transient': 1, 'double': 1, 'volatile': 1,
 				'try': 1, 'this': 1, 'switch': 1, 'continue': 1
 			}
 	dh.languages.java = {
@@ -34,7 +34,7 @@ dojo.require("dojox.highlight._base");
 			dhc.BACKSLASH_ESCAPE,
 			{
 				className: 'string',
-				begin: '\'', 
+				begin: '\'',
 				end: '[^\\\\]\'',
 				illegal: '[^\\\\][^\']'
 			},
@@ -52,7 +52,7 @@ dojo.require("dojox.highlight._base");
 				end: '\\}',
 				contains: ['comment', 'string', 'number', 'function','block'],
 				keywords: javakeywords
-			}					
+			}
 		]
 	};
 })();
diff --git a/dojox/highlight/languages/pygments/_html.js b/dojox/highlight/languages/pygments/_html.js
index 4e3e1ea..146aae4 100644
--- a/dojox/highlight/languages/pygments/_html.js
+++ b/dojox/highlight/languages/pygments/_html.js
@@ -8,12 +8,12 @@ dojox.highlight.languages.pygments._html.tags = {
 	"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, 
+	"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, 
+	"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,
diff --git a/dojox/highlight/languages/pygments/css.js b/dojox/highlight/languages/pygments/css.js
index b45b447..cf360f4 100644
--- a/dojox/highlight/languages/pygments/css.js
+++ b/dojox/highlight/languages/pygments/css.js
@@ -69,7 +69,7 @@ dojo.require("dojox.highlight.languages.pygments._html");
 			},
 			{
 				className: "string double",
-				begin: '"', 
+				begin: '"',
 				end: '"',
 				illegal: "\\n",
 				relevance: 0
@@ -195,7 +195,7 @@ dojo.require("dojox.highlight.languages.pygments._html");
 					}
 				},
 				contains: [
-					"comment", "comment preproc", 
+					"comment", "comment preproc",
 					"number",
 					"string single", "string double",
 					"punctuation",
diff --git a/dojox/highlight/languages/pygments/html.js b/dojox/highlight/languages/pygments/html.js
index b818206..a86481a 100644
--- a/dojox/highlight/languages/pygments/html.js
+++ b/dojox/highlight/languages/pygments/html.js
@@ -45,7 +45,7 @@ dojo.require("dojox.highlight.languages.pygments._html");
 			},
 			{
 				className: "string",
-				begin: '"', 
+				begin: '"',
 				end: '"',
 				illegal: "\\n",
 				relevance: 0
diff --git a/dojox/highlight/languages/pygments/javascript.js b/dojox/highlight/languages/pygments/javascript.js
index 5606635..091c922 100644
--- a/dojox/highlight/languages/pygments/javascript.js
+++ b/dojox/highlight/languages/pygments/javascript.js
@@ -20,8 +20,8 @@ dojo.require("dojox.highlight._base");
 				"name builtin": {
 					"Array": 1, "Boolean": 1, "Date": 1, "Error": 1, "Function": 1, "Math": 1,
 					"netscape": 1, "Number": 1, "Object": 1, "Packages": 1, "RegExp": 1,
-					"String": 1, "sun": 1, "decodeURI": 1, "decodeURIComponent": 1, 
-					"encodeURI": 1, "encodeURIComponent": 1, "Error": 1, "eval": 1, 
+					"String": 1, "sun": 1, "decodeURI": 1, "decodeURIComponent": 1,
+					"encodeURI": 1, "encodeURIComponent": 1, "Error": 1, "eval": 1,
 					"isFinite": 1, "isNaN": 1, "parseFloat": 1, "parseInt": 1, "document": 1,
 					"window": 1
 				},
@@ -30,7 +30,7 @@ dojo.require("dojox.highlight._base");
 				}
 			},
 			contains: [
-				"comment single", "comment multiline", 
+				"comment single", "comment multiline",
 				"number integer", "number oct", "number hex", "number float",
 				"string single", "string double", "string regex",
 				"operator",
@@ -83,7 +83,7 @@ dojo.require("dojox.highlight._base");
 			},
 			{
 				className: "string double",
-				begin: '"', 
+				begin: '"',
 				end: '"',
 				illegal: "\\n",
 				contains: ["string escape"],
diff --git a/dojox/highlight/languages/pygments/xml.js b/dojox/highlight/languages/pygments/xml.js
index 6f59660..fe2388e 100644
--- a/dojox/highlight/languages/pygments/xml.js
+++ b/dojox/highlight/languages/pygments/xml.js
@@ -39,7 +39,7 @@ dojox.highlight.languages.xml = {
 		},
 		{
 			className: "string",
-			begin: '"', 
+			begin: '"',
 			end: '"',
 			illegal: "\\n",
 			relevance: 0
diff --git a/dojox/highlight/languages/python.js b/dojox/highlight/languages/python.js
index 3b71577..c1581ea 100644
--- a/dojox/highlight/languages/python.js
+++ b/dojox/highlight/languages/python.js
@@ -1,19 +1,19 @@
-dojo.provide("dojox.highlight.languages.python"); 
+dojo.provide("dojox.highlight.languages.python");
 
 dojo.require("dojox.highlight._base");
 
 (function(){
 	var dh = dojox.highlight, dhc = dh.constants;
 	dh.languages.python = {
-	    // summary: Python highlight definitions 
+	    // 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, 
+          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: [
@@ -25,7 +25,7 @@ dojo.require("dojox.highlight._base");
             keywords: {'def': 1},
             contains: ['title', 'params'],
             relevance: 10
-          }, 
+          },
           {
             className: 'class',
             lexems: [dhc.UNDERSCORE_IDENT_RE],
diff --git a/dojox/highlight/languages/sql.js b/dojox/highlight/languages/sql.js
index bb942d4..9980e6a 100644
--- a/dojox/highlight/languages/sql.js
+++ b/dojox/highlight/languages/sql.js
@@ -4,26 +4,26 @@ 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, 
-		'smallint': 1, 'indicator': 1, 'end-exec': 1, 'disconnect': 1, 
-		'zone': 1, 'with': 1, 'character': 1, 'assertion': 1, 'to': 1, 
+		'all': 1, 'partial': 1, 'global': 1, 'month': 1,
+		'current_timestamp': 1, 'using': 1, 'go': 1, 'revoke': 1,
+		'smallint': 1, 'indicator': 1, 'end-exec': 1, 'disconnect': 1,
+		'zone': 1, 'with': 1, 'character': 1, 'assertion': 1, 'to': 1,
 		'add': 1, 'current_user': 1, 'usage': 1, 'input': 1, 'local': 1,
-		'alter': 1, 'match': 1, 'collate': 1, 'real': 1, 'then': 1, 
+		'alter': 1, 'match': 1, 'collate': 1, 'real': 1, 'then': 1,
 		'rollback': 1, 'get': 1, 'read': 1, 'timestamp': 1,	'session_user': 1,
 		'not': 1, 'integer': 1, 'bit': 1, 'unique': 1, 'day': 1, 'minute': 1,
-		'desc': 1, 'insert': 1, 'execute': 1, 'like': 1, 'level': 1, 
+		'desc': 1, 'insert': 1, 'execute': 1, 'like': 1, 'level': 1,
 		'decimal': 1, 'drop': 1, 'continue': 1, 'isolation': 1, 'found': 1,
 		'where': 1, 'constraints': 1, 'domain': 1, 'right': 1, 'national': 1,
 		'some': 1, 'module': 1, 'transaction': 1, 'relative': 1, 'second': 1,
 		'connect': 1, 'escape': 1, 'close': 1, 'system_user': 1, 'for': 1,
 		'deferred': 1, 'section': 1, 'cast': 1, 'current': 1, 'sqlstate': 1,
-		'allocate': 1, 'intersect': 1, 'deallocate': 1, 'numeric': 1, 
+		'allocate': 1, 'intersect': 1, 'deallocate': 1, 'numeric': 1,
 		'public': 1, 'preserve': 1, 'full': 1, 'goto': 1, 'initially': 1,
 		'asc': 1, 'no': 1, 'key': 1, 'output': 1, 'collation': 1, 'group': 1,
 		'by': 1, 'union': 1, 'session': 1, 'both': 1, 'last': 1, 'language': 1,
 		'constraint': 1, 'column': 1, 'of': 1, 'space': 1, 'foreign': 1,
-		'deferrable': 1, 'prior': 1, 'connection': 1, 'unknown': 1, 
+		'deferrable': 1, 'prior': 1, 'connection': 1, 'unknown': 1,
 		'action': 1, 'commit': 1, 'view': 1, 'or': 1, 'first': 1, 'into': 1,
 		'float': 1, 'year': 1, 'primary': 1, 'cascaded': 1, 'except': 1,
 		'restrict': 1, 'set': 1, 'references': 1, 'names': 1, 'table': 1,
@@ -33,16 +33,16 @@ dojo.require("dojox.highlight._base");
 		'corresponding': 1, 'option': 1, 'declare': 1, 'precision': 1,
 		'immediate': 1, 'else': 1, 'timezone_minute': 1, 'external': 1,
 		'varying': 1, 'translation': 1, 'true': 1, 'case': 1, 'exception': 1,
-		'join': 1, 'hour': 1, 'default': 1, 'double': 1, 'scroll': 1, 
+		'join': 1, 'hour': 1, 'default': 1, 'double': 1, 'scroll': 1,
 		'value': 1, 'cursor': 1, 'descriptor': 1, 'values': 1, 'dec': 1,
-		'fetch': 1, 'procedure': 1, 'delete': 1, 'and': 1, 'false': 1, 
+		'fetch': 1, 'procedure': 1, 'delete': 1, 'and': 1, 'false': 1,
 		'int': 1, 'is': 1, 'describe': 1, 'char': 1, 'as': 1, 'at': 1, 'in': 1,
 		'varchar': 1, 'null': 1, 'trailing': 1, 'any': 1, 'absolute': 1,
 		'current_time': 1, 'end': 1, 'grant': 1, 'privileges': 1, 'when': 1,
 		'cross': 1, 'check': 1, 'write': 1, 'current_date': 1, 'pad': 1,
 		'begin': 1, 'temporary': 1, 'exec': 1, 'time': 1, 'update': 1,
 		'catalog': 1, 'user': 1, 'sql': 1, 'date': 1, 'on': 1, 'identity': 1,
-		'timezone_hour': 1, 'natural': 1, 'whenever': 1, 'interval': 1, 
+		'timezone_hour': 1, 'natural': 1, 'whenever': 1, 'interval': 1,
 		'work': 1, 'order': 1, 'cascade': 1, 'diagnostics': 1, 'nchar': 1,
 		'having': 1, 'left': 1
 	};
diff --git a/dojox/highlight/tests/example-java-source.java b/dojox/highlight/tests/example-java-source.java
new file mode 100644
index 0000000..ac5a1ba
--- /dev/null
+++ b/dojox/highlight/tests/example-java-source.java
@@ -0,0 +1,25 @@
+	// setup the database named query
+	dbStatements = new HashMap<String, String>();
+	dbStatements.put("getCreditDefaultSwapsByEntityName",
+		"select xmldocument( " +
+			"xmlquery(" +
+				"'declare default element namespace \"http://www.fpml.org/2009/FpML-4-7\"; " + 
+				"$DOCUMENT/FpML/trade/creditDefaultSwap' ) " +
+			" ) " +
+			"from fpmladmin.fpml43 where comment like ? and " +
+				"xmlexists(" +
+					"'declare default element namespace \"http://www.fpml.org/2009/FpML-4-7\"; " +
+					"$fpml/FpML/trade/creditDefaultSwap/generalTerms/referenceInformation/referenceEntity[entityName=$name]' " +
+					"passing document as \"fpml\", " +
+					"cast (? as varchar(100)) as \"name\")"
+	);
+	...
+	// create the executable and execute it with the JDBC resolver and entityName variable
+	Source source = new Source(FpMLServlet.class.getResource("/joinCreditDefaultSwap.xq").toString());
+	XQueryExecutable joinCreditDefaultSwapsXQ = factory.prepareXQuery(source, staticContext);
+	...
+	JDBCCollectionResolver inputResolver = new JDBCCollectionResolver(getConnection(), dbStatements);
+	dynamicContext.setCollectionResolver(inputResolver);
+	StreamSource source = new StreamSource(FpMLServlet.class.getResourceAsStream("/assets.xml"));
+	dynamicContext.bind(new QName("http://com.ibm.xml.samples", "entityName"), name);
+	XSequenceCursor output = joinCreditDefaultSwapsXQ.execute(source, dynamicContext);
\ No newline at end of file
diff --git a/dojox/highlight/tests/example-xml-data.xml b/dojox/highlight/tests/example-xml-data.xml
new file mode 100644
index 0000000..de5e387
--- /dev/null
+++ b/dojox/highlight/tests/example-xml-data.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<assets>
+	<equity>
+		<symbol>AGU</symbol>
+		<name>Agrium Inc.</name>
+		<currency>USD</currency>
+		<high>64.06</high>
+		<low>62.79</low>
+	</equity>
+	<equity>
+		<symbol>STM-FP</symbol>
+		<name>STMicroelectronics N.V.</name>
+		<currency>EUR</currency>
+		<high>6.92</high>
+		<low>7.2</low>
+	</equity>
+</assets>
\ No newline at end of file
diff --git a/dojox/highlight/tests/example-xml-resultdata.xml b/dojox/highlight/tests/example-xml-resultdata.xml
new file mode 100644
index 0000000..226183e
--- /dev/null
+++ b/dojox/highlight/tests/example-xml-resultdata.xml
@@ -0,0 +1 @@
+<a>this is simple</a>
\ No newline at end of file
diff --git a/dojox/highlight/tests/example-xquery-source.xquery b/dojox/highlight/tests/example-xquery-source.xquery
new file mode 100644
index 0000000..351e0a1
--- /dev/null
+++ b/dojox/highlight/tests/example-xquery-source.xquery
@@ -0,0 +1,27 @@
+declare variable $my:entityName as xs:string external;
+
+declare variable $databaseURI := concat('jdbc://getCreditDefaultSwapsByEntityName?cd%&', $my:entityName); 
+declare variable $creditDefaultSwaps := collection($databaseURI);
+
+declare function local:equityRows($root) {
+	for $equity in $root//equity
+	let $referenceEntity := $creditDefaultSwaps//fpml:referenceEntity
+	where $equity/name = $referenceEntity/fpml:entityName
+	return
+		<tr xmlns="http://www.w3.org/1999/xhtml">
+			<td>{ $equity/*:symbol/text() }</td>
+			<td>{ $equity/*:name/text() }</td>
+			<td>{ $equity/*:high/text() }</td>
+			<td>{ $equity/*:currency/text() }</td>
+		</tr>
+};
+
+<table border="1">
+<tr>
+	<th>Ticker Symbol</th>
+	<th>Company Name</th>
+	<th>High</th>
+	<th>Currency</th>
+</tr>
+{ local:equityRows(/) }
+</table>
\ No newline at end of file
diff --git a/dojox/highlight/tests/highlight.js b/dojox/highlight/tests/highlight.js
index 1fc000f..f3d42d4 100644
--- a/dojox/highlight/tests/highlight.js
+++ b/dojox/highlight/tests/highlight.js
@@ -21,6 +21,6 @@ doh.register("dojox.highlight.tests.highlight", [
 		var result = dojox.highlight.processString(unformatted, "javascript");
 		doh.assertEqual(unformatted, result.result);
 		doh.assertEqual(expected, result.partialResult);
-		doh.assertEqual("javascript", result.langName);		
+		doh.assertEqual("javascript", result.langName);
 	}
 	]);
\ No newline at end of file
diff --git a/dojox/highlight/tests/highlightRequires.js b/dojox/highlight/tests/highlightRequires.js
new file mode 100644
index 0000000..1b2f660
--- /dev/null
+++ b/dojox/highlight/tests/highlightRequires.js
@@ -0,0 +1,7 @@
+// Load Code formatting widget (supports line numbering, alternating line highlighting, line ranges and loading from remote url):
+dojo.require("dojox.highlight.widget.Code");
+// Load the languages and pygment renderers for the languages we're displaying...
+dojo.require("dojox.highlight.languages.xml");
+dojo.require("dojox.highlight.languages.pygments.xml");
+dojo.require("dojox.highlight.languages.java");
+dojo.require("dojox.highlight.languages.xquery");
\ No newline at end of file
diff --git a/dojox/highlight/tests/module.js b/dojox/highlight/tests/module.js
index a55dc05..766e782 100644
--- a/dojox/highlight/tests/module.js
+++ b/dojox/highlight/tests/module.js
@@ -1,5 +1,5 @@
 dojo.provide("dojox.highlight.tests.module");
-//This file loads in all the test definitions.  
+//This file loads in all the test definitions.
 
 try{
 	//Load in the highlight module test.
diff --git a/dojox/highlight/tests/pretty.css b/dojox/highlight/tests/pretty.css
new file mode 100644
index 0000000..099c2a2
--- /dev/null
+++ b/dojox/highlight/tests/pretty.css
@@ -0,0 +1,136 @@
+/* Pygments default style */
+
+/*code {background-color: #f8f8f8}
+*/
+code .comment {color: #408080; font-style: italic}
+code .comment {color: #408080; font-style: italic}
+
+code .comment.preproc {color: #bc7a00; font-style: normal}
+
+/*code .keyword {color: #008000; font-weight: bold}
+*/
+code .keyword {color: #008000; font-weight: normal}
+code .keyword.pseudo {font-weight: normal}
+
+code .operator {color: #666}
+code .operator.word {color: #a2f}
+
+code .name.builtin {color: #008000}
+code .name.function {color: #00f}
+code .name.class {color: #00f; font-weight: bold}
+code .name.namespace {color: #00f; font-weight: bold}
+code .name.exception {color: #d2413a; font-weight: bold}
+code .name.variable {color: #19177c}
+code .name.constant {color: #800}
+code .name.label {color: #a0a000}
+code .name.entity {color: #999; font-weight: bold}
+code .name.attribute {color: #7d9029}
+code .name.tag {color: #008000; font-weight: bold}
+code .name.decorator {color: #a2f}
+
+code .string {color: #ba2121}
+code .string.doc {font-style: italic}
+code .string.interpol {color: #b68; font-weight: bold}
+code .string.escape {color: #b62; font-weight: bold}
+code .string.regex {color: #b68}
+code .string.symbol {color: #19177c}
+code .string.other {color: #008000}
+
+code .number {color: #666}
+
+/* Pygments simulating SyntaxHighlighter's styles */
+
+/*code {background-color: #f8f8f8}
+*/
+code .comment {color: #080; font-style: italic}
+code .comment.preproc {font-style: normal}
+code .comment.special {font-style: normal; font-weight: bold}
+
+/*code .keyword {color: #a2f; font-weight: bold}
+*/
+code .keyword {color: #0000cc}
+code .keyword.pseudo {font-weight: normal}
+
+code .operator {color: #666}
+/*code .operator.word {color: #a2f; font-weight: bold}
+*/
+code .operator.word {color: #0000cc; font-weight: normal}
+
+/*code .name.builtin {color: #a2f}
+*/
+code .name.builtin {color: #0000cc; font-weight: normal}
+code .name.function {color: #00a000}
+code .name.class {color: #00f}
+code .name.namespace {color: #00f; font-weight: bold}
+code .name.exception {color: #d2413a; font-weight: bold}
+code .name.variable {color: #b8860b}
+code .name.constant {color: #800}
+code .name.label {color: #a0a000}
+code .name.entity {color: #999; font-weight: bold}
+code .name.attribute {color: #b44}
+/*code .name.tag {color: #008000; font-weight: bold}
+*/
+code .name.tag {color: #006699; font-weight: normal}
+code .name.decorator {color: #a2f}
+
+/*code .string {color: #b44}
+*/
+code .string {color: #b44}
+code .string.doc {font-style: italic}
+code .string.interpol {color: #b68; font-weight: bold}
+code .string.escape {color: #b62; font-weight: bold}
+code .string.regex {color: #b68}
+code .string.symbol {color: #b8860b}
+code .string.other {color: #008000}
+
+code .number {color: #666}
+
+pre {
+	padding:0;
+	margin:0;
+	display:block;
+}
+code {
+	background-color: #inherit;
+	line-height:1.2em;
+	display:block;
+}
+span.tab { padding-left:8px; }
+.formatted ol {
+	margin-left:50px;
+	padding:0;
+	background-color:#fff;
+	font-family: monospace;
+	list-style-type: decimal-leading-zero; 
+}
+
+.formatted ol li.even {
+	background-color:#d0d0d0;
+	border-left-style:solid;
+	border-color: #6ce26c;
+	color: #808080;
+}
+.formatted ol li.even pre {
+	background-color:#fff;
+	color: #000;
+	padding-left: 4px;
+}
+.formatted ol li.odd {
+	background-color:#d0d0d0;
+	border-left-style:solid;
+	border-color: #6ce26c;
+	color: #808080;
+}
+.formatted ol li.odd pre {
+	background-color:#f0f0f0;
+	color: #000;
+	padding-left: 4px;
+}
+
+#container {
+	width:90%;
+	margin:0 auto;
+}
+h1 {
+	font-size:20pt;
+}
\ No newline at end of file
diff --git a/dojox/highlight/tests/test_highlightWidget.html b/dojox/highlight/tests/test_highlightWidget.html
new file mode 100644
index 0000000..967b58e
--- /dev/null
+++ b/dojox/highlight/tests/test_highlightWidget.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+    <head>
+		<title>Dojo source code color syntax highlighting example</title>
+		<link rel="stylesheet" type="text/css" href="pretty.css" />
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+		<script type="text/javascript" src="highlightRequires.js"></script>
+    </head>
+    <body>
+		<div id="container">
+			<h1>Test Source Code Formatting</h1>
+			<p>View source to see how easy it is to use the Dojo code highlight in your documentation.</p>
+			<p>Mimic the format of SyntaxHighlighter, using dojox.highlight and stylesheets, and our simple Code widget extension.</p>
+			<h3>Java code (including SQL/XML statement definition):</h3>
+			<div lang="java" dojoType="highlight.Code" url="./example-java-source.java" style="height:200px; overflow:auto;"></div>	
+			<h3>XQuery code:</h3>
+			<div lang="xquery" dojoType="highlight.Code" url="./example-xquery-source.xquery" style="height:200px; overflow:auto;"></div>
+			<h3>XML result data:</h3>
+			<div lang="xml" dojoType="highlight.Code" url="./example-xml-resultdata.xml"></div>
+			<h3>XML doc:</h3>
+			<div lang="xml" dojoType="highlight.Code" url="./example-xml-data.xml" style="height:200px; overflow:auto;"></div>
+		</div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/dojox/highlight/widget/Code.js b/dojox/highlight/widget/Code.js
new file mode 100644
index 0000000..661642e
--- /dev/null
+++ b/dojox/highlight/widget/Code.js
@@ -0,0 +1,96 @@
+dojo.provide("dojox.highlight.widget.Code");
+dojo.require("dijit._Widget");
+dojo.require("dijit._Templated");
+dojo.require("dojox.highlight");
+
+// 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);
+		}
+	},
+	
+	_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();
+	},
+	
+	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);
+	}
+});
\ No newline at end of file
diff --git a/dojox/html/README b/dojox/html/README
index 1bb77d6..1f0abb8 100644
--- a/dojox/html/README
+++ b/dojox/html/README
@@ -14,7 +14,6 @@ Credits
 	Tom Trenka (ttrenka AT gmail.com)
 	Bryan Forbes (bryan AT reigndropsfall.net)
 	Mike Wilcox - dojox.html.styles (anm8tr AT yahoo.com)
-	Nathan Toone - dojox.html.ellipsis (toonetown AT dojotoolkit.org)
 	Jared Jurkiewicz - dojox.html.entites, dojox.html.format (jared.jurkiewicz AT gmail.com)
 -------------------------------------------------------------------------------
 Project description
@@ -25,8 +24,7 @@ measurement routines aren't used by the majority of developers, but are complex
 enough to not be duplicated.
 Styles adds the ability to create and remove dynamic cssRules, as well as 
 manipulate document style sheets.
-Ellipsis adds some css definitions and dojo.behavior rules (for FF) to support
-text-overflow: ellipsis
+Ellipsis adds support to match text-overflow: ellipsis for Firefox.
 -------------------------------------------------------------------------------
 Dependencies:
 
diff --git a/dojox/html/_base.js b/dojox/html/_base.js
index 3b895e1..2796932 100644
--- a/dojox/html/_base.js
+++ b/dojox/html/_base.js
@@ -10,7 +10,7 @@
 
 dojo.provide("dojox.html._base");
 
-dojo.require("dojo.html"); 
+dojo.require("dojo.html");
 
 (function() {
 
@@ -50,7 +50,7 @@ dojo.require("dojo.html");
 		//			@import 'level1/css/page.css' tv, screen;
 		//			...
 		//			background-image: url(level1/images/alphaimage.png);
-		//		
+		//
 		//		In IE it will also adjust relative paths in AlphaImageLoader()
 		//			filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='images/alphaimage.png');
 		//		will be adjusted to:
@@ -110,7 +110,7 @@ dojo.require("dojo.html");
 		return cont.replace(/(?:<style([^>]*)>([\s\S]*?)<\/style>|<link\s+(?=[^>]*rel=['"]?stylesheet)([^>]*?href=(['"])([^>]*?)\4[^>\/]*)\/?>)/gi,
 			function(ignore, styleAttr, cssText, linkAttr, delim, href){
 				// trim attribute
-				var i, attr = (styleAttr||linkAttr||"").replace(/^\s*([\s\S]*?)\s*$/i, "$1"); 
+				var i, attr = (styleAttr||linkAttr||"").replace(/^\s*([\s\S]*?)\s*$/i, "$1");
 				if(cssText){
 					i = styles.push(cssUrl ? adjustCssPaths(cssUrl, cssText) : cssText);
 				}else{
@@ -126,7 +126,7 @@ dojo.require("dojo.html");
 					}
 					styles.attributes[i - 1] = atObj;
 				}
-				return ""; // squelsh the <style> or <link>
+				return "";
 			}
 		);
 	};
@@ -134,14 +134,14 @@ dojo.require("dojo.html");
 	var snarfScripts = dojox.html._snarfScripts = function(cont, byRef){
 		// summary
 		//		strips out script tags from cont
-		// invoke with 
+		// invoke with
 		//	byRef = {errBack:function(){/*add your download error code here*/, downloadRemote: true(default false)}}
 		//	byRef will have {code: 'jscode'} when this scope leaves
 		byRef.code = "";
 
 		//Update script tags nested in comments so that the script tag collector doesn't pick
 		//them up.
-		cont = cont.replace(/<[!][-][-](.|\s){5,}?[-][-]>/g,
+		cont = cont.replace(/<[!][-][-](.|\s)*?[-][-]>/g,
 			function(comment){
 				return comment.replace(/<(\/?)script\b/ig,"<$1Script");
 			}
@@ -183,7 +183,7 @@ dojo.require("dojo.html");
 				return "";
 			}
 		);
-	}; 
+	};
 	
 	var evalInGlobal = dojox.html.evalInGlobal = function(code, appendNode){
 		// we do our own eval here as dojo.eval doesn't eval in global crossbrowser
@@ -202,7 +202,7 @@ dojo.require("dojo.html");
 		//		Only useful if you grab content from a another folder than the current one
 		adjustPaths: false,
 		referencePath: ".",
-		renderStyles: false, 
+		renderStyles: false,
 
 		executeScripts: false,
 		scriptHasHooks: false,
@@ -232,26 +232,26 @@ dojo.require("dojo.html");
 					st.appendChild(doc.createTextNode(cssText));
 				}
 			}
-		}, 
+		},
 
 		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(); 
-			//		It allows modification of any of the object properties - including the node and content 
+			//		Called after instantiation, but before set();
+			//		It allows modification of any of the object properties - including the node and content
 			//		provided - before the set operation actually takes place
-			//		This implementation extends that of dojo.html._ContentSetter 
+			//		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 cont = this.content,
+				node = this.node;
 				
 			var styles = this._styles;// init vars
 
@@ -264,10 +264,10 @@ dojo.require("dojo.html");
 					cont = snarfStyles(this.referencePath, cont, styles);
 				}
 
-				// because of a bug in IE, script tags that is first in html hierarchy doesnt make it into the DOM 
+				// because of a bug in IE, script tags that is first in html hierarchy doesnt make it into the DOM
 				//	when content is innerHTML'ed, so we can't use dojo.query to retrieve scripts from DOM
 				if(this.executeScripts){
-					var _t = this; 
+					var _t = this;
 					var byRef = {
 						downloadRemote: true,
 						errBack:function(e){
@@ -287,7 +287,7 @@ dojo.require("dojo.html");
 			//		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, 
+			var code = this._code,
 				styles = this._styles;
 				
 			// clear old stylenodes from the DOM
@@ -312,7 +312,7 @@ dojo.require("dojo.html");
 				}
 				if(this.scriptHasHooks){
 					// replace _container_ with this.scriptHookReplace()
-					// the scriptHookReplacement can be a string 
+					// the scriptHookReplacement can be a string
 					// or a function, which when invoked returns the string you want to substitute in
 					code = code.replace(/_container_(?!\s*=[^=])/g, this.scriptHookReplacement);
 				}
@@ -334,7 +334,7 @@ dojo.require("dojo.html");
 					dojo.destroy(this._styleNodes.pop());
 				}
 			}
-			delete this._styleNodes; 
+			delete this._styleNodes;
 			// reset the defaults from the prototype
 			dojo.mixin(this, dojo.getObject(this.declaredClass).prototype);
 		}
@@ -348,25 +348,25 @@ dojo.require("dojo.html");
 			//	node:
 			//		the parent element that will receive the content
 			//	cont:
-			//		the content to be set on the parent element. 
+			//		the content to be set on the parent element.
 			//		This can be an html string, a node reference or a NodeList, dojo.NodeList, Array or other enumerable list of nodes
-			//	params: 
+			//	params:
 			//		Optional flags/properties to configure the content-setting. See dojo.html._ContentSetter
 			//	example:
 			//		A safe string/node/nodelist content replacement/injection with hooks for extension
-			//		Example Usage: 
-			//		dojo.html.set(node, "some string"); 
-			//		dojo.html.set(node, contentNode, {options}); 
-			//		dojo.html.set(node, myNode.childNodes, {options}); 
+			//		Example Usage:
+			//		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);
-		}else{ 
+		}else{
 			// more options but slower
-			var op = new dojox.html._ContentSetter(dojo.mixin( 
-					params, 
-					{ content: cont, node: node } 
+			var op = new dojox.html._ContentSetter(dojo.mixin(
+					params,
+					{ content: cont, node: node }
 			));
 			return op.set();
 		}
diff --git a/dojox/html/ellipsis.js b/dojox/html/ellipsis.js
index 92fd620..a5cb1c3 100644
--- a/dojox/html/ellipsis.js
+++ b/dojox/html/ellipsis.js
@@ -12,8 +12,8 @@ dojox.html.ellipsis = {
 =====*/
 
 (function(d){
-	if(d.isMoz){
-		// The delay (in ms) to wait so that we don't keep querying when many 
+	if(d.isMoz){ //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
 		var delay = 1;
@@ -23,23 +23,28 @@ dojox.html.ellipsis = {
 				delay = 1;
 			}
 		}
-		
-		// Create our stub XUL elements for cloning later
-		var sNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
-		var xml = document.createElementNS(sNS, 'window');
-		var label = document.createElementNS(sNS, 'description');
-		label.setAttribute('crop', 'end');
-		xml.appendChild(label);
-		
-		var createXULEllipsis = function(/* Node */ n){
-			// Summary:
-			//		Given a node, it creates the XUL and sets its
-			//		content so that it will have an ellipsis
-			var x = xml.cloneNode(true);
-			x.firstChild.setAttribute('value', n.textContent);
-			n.innerHTML = '';
-			n.appendChild(x);
-		};
+		try{
+			var createXULEllipsis = (function(){
+				// Create our stub XUL elements for cloning later
+				// NOTE: this no longer works as of FF 4.0:
+				// https://developer.mozilla.org/En/Firefox_4_for_developers#Remote_XUL_support_removed
+				var sNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
+				var xml = document.createElementNS(sNS, 'window');
+				var label = document.createElementNS(sNS, 'description');
+				label.setAttribute('crop', 'end');
+				xml.appendChild(label);
+
+				return function(/* Node */ n){
+					// Summary:
+					//		Given a node, it creates the XUL and sets its
+					//		content so that it will have an ellipsis
+					var x = xml.cloneNode(true);
+					x.firstChild.setAttribute('value', n.textContent);
+					n.innerHTML = '';
+					n.appendChild(x);
+				};
+			})();
+		}catch(e){}
 		
 		// Create our iframe elements for cloning later
 		var create = d.create;
@@ -156,7 +161,7 @@ dojox.html.ellipsis = {
 			d.forEach(s[fn].apply(s, [opt]), function(n){
 				if(!n || n._djx_ellipsis_done){ return; }
 				n._djx_ellipsis_done = true;
-				if(n.textContent == n.innerHTML && !hc(n, "dojoxEllipsisSelectable")){
+				if(createXULEllipsis && n.textContent == n.innerHTML && !hc(n, "dojoxEllipsisSelectable")){
 					// We can do the faster XUL version, instead of calculating
 					createXULEllipsis(n);
 				}else{
diff --git a/dojox/html/entities.js b/dojox/html/entities.js
index 1b8fdf7..cff6fb5 100755
--- a/dojox/html/entities.js
+++ b/dojox/html/entities.js
@@ -1,21 +1,22 @@
-dojo.provide("dojox.html.entities");
+define("dojox/html/entities", ["dojo", "dojox"], function(dojo, dojox) {
 (function(){
 	// dojox.html.entities.html [public] Array
-	//		Entity characters for HTML, represented as an array of 
+	//		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 _applyEncodingMap = function(str, map){
 		// summary:
 		//		Private internal function for performing encoding of entity characters.
 		// tags:
 		//		private
-
+	
 		// Check to see if we have genned and cached a regexp for this map yet
 		// If we have, use it, if not, gen it, cache, then use.
 		var mapper, regexp;
-		if(map._encCache && 
-			map._encCache.regexp && 
-			map._encCache.mapper && 
+		if(map._encCache &&
+			map._encCache.regexp &&
+			map._encCache.mapper &&
 			map.length == map._encCache.length){
 			mapper = map._encCache.mapper;
 			regexp = map._encCache.regexp;
@@ -40,16 +41,16 @@ dojo.provide("dojox.html.entities");
 		});
 		return str;
 	};
-
+	
 	var _applyDecodingMap = function(str, map){
 		// summary:
 		//		Private internal function for performing decoding of entity characters.
 		// tags:
 		//		private
 		var mapper, regexp;
-		if(map._decCache && 
-			map._decCache.regexp && 
-			map._decCache.mapper && 
+		if(map._decCache &&
+			map._decCache.regexp &&
+			map._decCache.mapper &&
 			map.length == map._decCache.length){
 			mapper = map._decCache.mapper;
 			regexp = map._decCache.regexp;
@@ -76,14 +77,14 @@ dojo.provide("dojox.html.entities");
 		});
 		return str;
 	};
-
+	
 	dojox.html.entities.html = [
 		["\u0026","amp"], ["\u0022","quot"],["\u003C","lt"], ["\u003E","gt"],
 		["\u00A0","nbsp"]
 	];
-
+	
 	// dojox.html.entities.latin [public] Array
-	//		Entity characters for Latin characters and similar, represented as an array of 
+	//		Entity characters for Latin characters and similar, represented as an array of
 	//		character code, entity name (minus & and ; wrapping.
 	dojox.html.entities.latin = [
 		["\u00A1","iexcl"],["\u00A2","cent"],["\u00A3","pound"],["\u20AC","euro"],
@@ -100,12 +101,12 @@ dojo.provide("dojox.html.entities");
 		["\u00CC","Igrave"],["\u00CD","Iacute"],["\u00CE","Icirc"],["\u00CF","Iuml"],
 		["\u00D0","ETH"],["\u00D1","Ntilde"],["\u00D2","Ograve"],["\u00D3","Oacute"],
 		["\u00D4","Ocirc"],["\u00D5","Otilde"],["\u00D6","Ouml"],["\u00D7","times"],
-		["\u00D8","Oslash"],["\u00D9","Ugrave"],["\u00DA","Uacute"],["\u00DB","Ucirc"], 
+		["\u00D8","Oslash"],["\u00D9","Ugrave"],["\u00DA","Uacute"],["\u00DB","Ucirc"],
 		["\u00DC","Uuml"],["\u00DD","Yacute"],["\u00DE","THORN"],["\u00DF","szlig"],
 		["\u00E0","agrave"],["\u00E1","aacute"],["\u00E2","acirc"],["\u00E3","atilde"],
 		["\u00E4","auml"],["\u00E5","aring"],["\u00E6","aelig"],["\u00E7","ccedil"],
 		["\u00E8","egrave"],["\u00E9","eacute"],["\u00EA","ecirc"],["\u00EB","euml"],
-		["\u00EC","igrave"],["\u00ED","iacute"],["\u00EE","icirc"],["\u00EF","iuml"], 
+		["\u00EC","igrave"],["\u00ED","iacute"],["\u00EE","icirc"],["\u00EF","iuml"],
 		["\u00F0","eth"],["\u00F1","ntilde"],["\u00F2","ograve"],["\u00F3","oacute"],
 		["\u00F4","ocirc"],["\u00F5","otilde"],["\u00F6","ouml"],["\u00F7","divide"],
 		["\u00F8","oslash"],["\u00F9","ugrave"],["\u00FA","uacute"],["\u00FB","ucirc"],
@@ -115,32 +116,32 @@ dojo.provide("dojox.html.entities");
 		["\u0398","Theta"], ["\u0399","Iota"],["\u039A","Kappa"],["\u039B","Lambda"],
 		["\u039C","Mu"],["\u039D","Nu"],["\u039E","Xi"],["\u039F","Omicron"],
 		["\u03A0","Pi"],["\u03A1","Rho"],["\u03A3","Sigma"],["\u03A4","Tau"],
-		["\u03A5","Upsilon"],["\u03A6","Phi"],["\u03A7","Chi"],["\u03A8","Psi"], 
+		["\u03A5","Upsilon"],["\u03A6","Phi"],["\u03A7","Chi"],["\u03A8","Psi"],
 		["\u03A9","Omega"],["\u03B1","alpha"],["\u03B2","beta"],["\u03B3","gamma"],
 		["\u03B4","delta"],["\u03B5","epsilon"],["\u03B6","zeta"],["\u03B7","eta"],
 		["\u03B8","theta"],["\u03B9","iota"],["\u03BA","kappa"],["\u03BB","lambda"],
 		["\u03BC","mu"],["\u03BD","nu"],["\u03BE","xi"],["\u03BF","omicron"],
-		["\u03C0","pi"],["\u03C1","rho"],["\u03C2","sigmaf"],["\u03C3","sigma"], 
+		["\u03C0","pi"],["\u03C1","rho"],["\u03C2","sigmaf"],["\u03C3","sigma"],
 		["\u03C4","tau"],["\u03C5","upsilon"],["\u03C6","phi"],["\u03C7","chi"],
 		["\u03C8","psi"],["\u03C9","omega"],["\u03D1","thetasym"],["\u03D2","upsih"],
 		["\u03D6","piv"],["\u2022","bull"],["\u2026","hellip"],["\u2032","prime"],
 		["\u2033","Prime"],["\u203E","oline"],["\u2044","frasl"],["\u2118","weierp"],
-		["\u2111","image"],["\u211C","real"],["\u2122","trade"],["\u2135","alefsym"], 
+		["\u2111","image"],["\u211C","real"],["\u2122","trade"],["\u2135","alefsym"],
 		["\u2190","larr"],["\u2191","uarr"],["\u2192","rarr"],["\u2193","darr"],
 		["\u2194","harr"],["\u21B5","crarr"],["\u21D0","lArr"],["\u21D1","uArr"],
 		["\u21D2","rArr"],["\u21D3","dArr"],["\u21D4","hArr"],["\u2200","forall"],
 		["\u2202","part"],["\u2203","exist"],["\u2205","empty"],["\u2207","nabla"],
-		["\u2208","isin"],["\u2209","notin"],["\u220B","ni"],["\u220F","prod"], 
+		["\u2208","isin"],["\u2209","notin"],["\u220B","ni"],["\u220F","prod"],
 		["\u2211","sum"],["\u2212","minus"],["\u2217","lowast"],["\u221A","radic"],
 		["\u221D","prop"],["\u221E","infin"],["\u2220","ang"],["\u2227","and"],
 		["\u2228","or"],["\u2229","cap"],["\u222A","cup"],["\u222B","int"],
 		["\u2234","there4"],["\u223C","sim"],["\u2245","cong"],["\u2248","asymp"],
-		["\u2260","ne"],["\u2261","equiv"],["\u2264","le"],["\u2265","ge"], 
+		["\u2260","ne"],["\u2261","equiv"],["\u2264","le"],["\u2265","ge"],
 		["\u2282","sub"],["\u2283","sup"],["\u2284","nsub"],["\u2286","sube"],
 		["\u2287","supe"],["\u2295","oplus"],["\u2297","otimes"],["\u22A5","perp"],
 		["\u22C5","sdot"],["\u2308","lceil"],["\u2309","rceil"],["\u230A","lfloor"],
 		["\u230B","rfloor"],["\u2329","lang"],["\u232A","rang"],["\u25CA","loz"],
-		["\u2660","spades"],["\u2663","clubs"],["\u2665","hearts"],["\u2666","diams"], 
+		["\u2660","spades"],["\u2663","clubs"],["\u2665","hearts"],["\u2666","diams"],
 		["\u0152","Elig"],["\u0153","oelig"],["\u0160","Scaron"],["\u0161","scaron"],
 		["\u0178","Yuml"],["\u02C6","circ"],["\u02DC","tilde"],["\u2002","ensp"],
 		["\u2003","emsp"],["\u2009","thinsp"],["\u200C","zwnj"],["\u200D","zwj"],
@@ -149,15 +150,15 @@ dojo.provide("dojox.html.entities");
 		["\u201D","rdquo"],["\u201E","bdquo"],["\u2020","dagger"],["\u2021","Dagger"],
 		["\u2030","permil"],["\u2039","lsaquo"],["\u203A","rsaquo"]
 	];
-
+	
 	dojox.html.entities.encode = function(str/*string*/, m /*array?*/){
 		// summary:
 		//		Function to obtain an entity encoding for a specified character
 		// str:
 		//		The string to process for possible entity encoding.
 		// m:
-		//		An optional list of character to entity name mappings (array of 
-		//		arrays).  If not provided, it uses the and Latin entities as the 
+		//		An optional list of character to entity name mappings (array of
+		//		arrays).  If not provided, it uses the and Latin entities as the
 		//		set to map and escape.
 		// tags:
 		//		public
@@ -167,22 +168,22 @@ dojo.provide("dojox.html.entities");
 				// as well.
 				str = _applyEncodingMap(str, dojox.html.entities.html);
 				str = _applyEncodingMap(str, dojox.html.entities.latin);
-
+	
 			}else{
 				str = _applyEncodingMap(str, m);
 			}
 		}
 		return str;
 	};
-
+	
 	dojox.html.entities.decode = function(str/*string*/, m /*array?*/){
 		// summary:
 		//		Function to obtain an entity encoding for a specified character
 		// str:
 		//		The string to process for possible entity encoding to decode.
 		// m:
-		//		An optional list of character to entity name mappings (array of 
-		//		arrays).  If not provided, it uses the HTML and Latin entities as the 
+		//		An optional list of character to entity name mappings (array of
+		//		arrays).  If not provided, it uses the HTML and Latin entities as the
 		//		set to map and decode.
 		// tags:
 		//		public
@@ -192,7 +193,7 @@ dojo.provide("dojox.html.entities");
 				// as well.
 				str = _applyDecodingMap(str, dojox.html.entities.html);
 				str = _applyDecodingMap(str, dojox.html.entities.latin);
-
+	
 			}else{
 				str = _applyDecodingMap(str, m);
 			}
@@ -200,4 +201,5 @@ dojo.provide("dojox.html.entities");
 		return str;
 	};
 })();
+});
 
diff --git a/dojox/html/ext-dojo/style.js b/dojox/html/ext-dojo/style.js
index 8ca2d86..4ff6e66 100644
--- a/dojox/html/ext-dojo/style.js
+++ b/dojox/html/ext-dojo/style.js
@@ -100,7 +100,7 @@ dojo.mixin(dojox.html["ext-dojo"].style, {
 		});
 	},
 	_notSupported: function(){
-		console.warn("Sorry, this browser doesn't support transform and transform-origin");	
+		console.warn("Sorry, this browser doesn't support transform and transform-origin");
 	},
 	_setTransformOriginFilter: function(/*DomNode*/ node, /*String*/ transformOrigin){
 		var to = dojo.trim(transformOrigin)
diff --git a/dojox/html/format.js b/dojox/html/format.js
index cd87bb5..9146e1c 100755
--- a/dojox/html/format.js
+++ b/dojox/html/format.js
@@ -1,477 +1,474 @@
-dojo.provide("dojox.html.format");
+define("dojox/html/format", ["dojo", "dojox", "dojox/html/entities"], function(dojo, dojox) {
 
-dojo.require("dojox.html.entities");
+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;
 
-(function(){
-	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;
 
-		// Compile regexps once for this call.
-		var rgxp_fixIEAttrs = /[=]([^"']+?)(\s|>)/g;
-		var rgxp_styleMatch = /style=("[^"]*"|'[^']*'|\S*)/gi;
-		var rgxp_attrsMatch = /\s\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 += " ";
-			}
+	// 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;
+	//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;
+	// 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;
-			}
-		};
+	/** 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;
-		};
+	//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 sizeIndent = function(){
+		var i, txt = "";
+		for(i = 0; i < indentDepth; i++){
+			txt += iTxt;
 		}
+		return txt.length;
+	}
 
-		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 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 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;
+	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]);
-			}
-			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--){
+		// 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]);
+		}
+		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++){
 								// 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++){
-									// 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){
-								_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
+						}
+						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){
 							_iTxt = "";
 							for(i = 0; i < indentDepth; i++){
 								_iTxt += iTxt;
 							}
-							txt = _iTxt + txt + "\n";
-							lines.push(txt);
-							txt = null;
+							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;
 					}
-					return lines.join("");
-				}else{
-					_iTxt = "";
-					for(i = 0; i < indentDepth; i++){
-						_iTxt += iTxt;
-					}
-					txt = _iTxt + txt + "\n";
-					return txt;
 				}
+				return lines.join("");
 			}else{
-				return "";
+				_iTxt = "";
+				for(i = 0; i < indentDepth; i++){
+					_iTxt += iTxt;
+				}
+				txt = _iTxt + txt + "\n";
+				return txt;
 			}
-		};
+		}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 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;
-							}
-						}
-						_iTxt = "";
-						for(t = 0; t < indentDepth + iLevel; t++){
-							_iTxt += iTxt;
+	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;
 						}
-						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("");
+
 			}
-			return txt;
-		};
+			// 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);
+	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');
+		// 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);
-					}
-				});
-				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.
-					return "";
-				}else{
-					style += ";";
-					return sL + closure + style + closure;
+		// 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);
 				}
 			});
-
-			// Try and sort the attributes while we're at it.
-			var attrs = [];
-			tag = tag.replace(rgxp_attrsMatch, function(attr){
-				attrs.push(dojo.trim(attr));
+			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.
 				return "";
-			});
-			attrs = attrs.sort();
-
-			// Reassemble the tag with sorted attributes!
-			tag = "<" + name;
-			if(attrs.length){
-				 tag += " " + attrs.join(" ");
+			}else{
+				style += ";";
+				return sL + closure + style + closure;
 			}
+		});
 
-			// Determine closure status.  If xhtml, 
-			// then close the tag properly as needed.
-			if(nText.indexOf("</") != -1){
-				closeTags.push(name);
-				tag += ">";
+		// 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{
-				if(xhtml){
-					tag += " />";
-				}else{
-					tag += ">";
-				}
-				closeTags.push(false);
+				tag += ">";
 			}
+			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 = "";
-			}
+		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!
+		// 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 + ">";
 			if(!inline){
+				indentDepth--;
 				indent();
-				content.push(tag);
+				content.push(ct);
 				newline();
-				indentDepth++;
 			}else{
-				textContent += tag;
+				textContent += ct;
 			}
-			
-		};
-		
-		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--;	
-			}
-		};
+		}else{
+			indentDepth--;
+		}
+	};
 
-		var processCommentNode = function(n){
-			// summary:
-			//		Function to handle processing a comment node.
-			// n:
-			//		The comment node to process.
+	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();
-		};
+		//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);
-							}else{
-								processNode(n);
+	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";
 							}
-							closeTag();
+							content.push(preTxt);
+						}else{
+							processNode(n);
 						}
-					}else if(n.nodeType === 3 || n.nodeType === 4){
-						processTextNode(n);
-					}else if(n.nodeType === 8){
-						processCommentNode(n);
+						closeTag();
 					}
+				}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
+};
+});
 
diff --git a/dojox/html/metrics.js b/dojox/html/metrics.js
index 5b59f46..2c84199 100644
--- a/dojox/html/metrics.js
+++ b/dojox/html/metrics.js
@@ -61,7 +61,7 @@ dojo.provide("dojox.html.metrics");
 			m = measuringNode = dojo.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 = dojo.doc.createElement("div");
 			c.appendChild(m);
 			s = c.style;
 			s.overflow='scroll';
diff --git a/dojox/html/styles.js b/dojox/html/styles.js
index 584ff7e..90c8a47 100755
--- a/dojox/html/styles.js
+++ b/dojox/html/styles.js
@@ -1,27 +1,27 @@
 dojo.provide("dojox.html.styles");
-	
+
 	// summary:
 	//		Methods for creating and minipulating dynamic CSS Styles and Style Sheets
 	//
 	// example:
 	//		| dojox.html.createStyle("#myDiv input", "font-size:24px");
-	//			Creates Style #myDiv input, which can now be applied to myDiv, and 
+	//			Creates Style #myDiv input, which can now be applied to myDiv, and
 	//			the inner input will be targeted
 	//		| dojox.html.createStyle(".myStyle", "color:#FF0000");
 	//			Now the class myStyle can be assigned to a node's className
-	
+
 (function(){
-	
+
 	var dynamicStyleMap = {};
 	var pageStyleSheets = {};
 	var titledSheets = [];
 	var styleIndicies = [];
-	
+
 	dojox.html.insertCssRule = function(/*String*/selector, /*String*/declaration, /*String*/styleSheetName){
 		// summary:
 		//	Creates a style and attaches it to a dynamically created stylesheet
 		//	arguments:
-		//		selector: 	
+		//		selector:
 		//					A fully qualified class name, as it would appear in
 		//					a CSS dojo.doc. Start classes with periods, target
 		//					nodes with '#'. Large selectors can also be created
@@ -34,9 +34,9 @@ dojo.provide("dojox.html.styles");
 		//					in camel case, use as you would in a CSS dojo.doc:
 		//					| "color:#ffoooo;font-size:12px;margin-left:5px;"
 		//		styleSheetName: ( optional )
-		//					Name of the dynamic style sheet this rule should be 
+		//					Name of the dynamic style sheet this rule should be
 		//					inserted into. If is not found by that name, it is
-		//					created. If no name is passed, the name "default" is 
+		//					created. If no name is passed, the name "default" is
 		//					used.
 		//
 		var ss = dojox.html.getDynamicStyleSheet(styleSheetName);
@@ -52,15 +52,15 @@ dojo.provide("dojox.html.styles");
 			ss.appendChild(dojo.doc.createTextNode(styleText));
 		}
 		ss._indicies.push(selector+" "+declaration);
-		return selector; // String 
-	
+		return selector; // String
+
 	}
-	
+
 	dojox.html.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 
+		// description: Only removes DYNAMICALLY created cssRules. If you
 		//		created it with dojox.html.insertCssRule, it can be removed.
 		//
 		var ss;
@@ -84,12 +84,12 @@ dojo.provide("dojox.html.styles");
 			console.log("The css rule was not found and could not be removed.");
 			return false;
 		}
-		
+
 		ss._indicies.splice(index, 1);
-		
-		
-		
-		if(dojo.isIE){ 
+
+
+
+		if(dojo.isIE){
 			// Note: check for if(ss.removeRule) does not work
 			ss.removeRule(index);
 		}else if(ss.sheet){
@@ -99,19 +99,19 @@ dojo.provide("dojox.html.styles");
 			//
 		}
 		return true; //Boolean
-		
+
 	}
-	
+
 	/* TODO
 	dojox.html.modifyCssRule = function(selector, declaration, styleSheetName){
-		Not implemented - it seems to have some merit for changing some complex 
+		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){
 		// summary:
 		//		Returns a style sheet based on the argument.
@@ -119,30 +119,30 @@ dojo.provide("dojox.html.styles");
 		//		searches document style sheets.
 		//
 		// argument: (optional)
-		//		A title or an href to a style sheet. Title can be 
-		//		an attribute in a tag, or a dynamic style sheet 
+		//		A title or an href to a style sheet. Title can be
+		//		an attribute in a tag, or a dynamic style sheet
 		//		reference. Href can be the name of the file.
-		//		If no argument, the assumed created dynamic style 
+		//		If no argument, the assumed created dynamic style
 		//		sheet is used.
-		
-		// try dynamic sheets first 
+
+		// try dynamic sheets first
 		if(dynamicStyleMap[styleSheetName || "default"]){
 			return dynamicStyleMap[styleSheetName || "default"];
 		}
 		if(!styleSheetName){
-			// no arg is nly good for the default style sheet 
+			// no arg is nly good for the default style sheet
 			// and it has not been created yet.
 			return false;
 		}
-		
+
 		var allSheets = dojox.html.getStyleSheets();
-		
+
 		// now try document style sheets by name
 		if(allSheets[styleSheetName]){
 			return dojox.html.getStyleSheets()[styleSheetName];
 		}
-		
-		// check for partial matches in hrefs (so that a fully 
+
+		// check for partial matches in hrefs (so that a fully
 		//qualified name does not have to be passed)
 		for ( var nm in allSheets){
 			if(	allSheets[nm].href && allSheets[nm].href.indexOf(styleSheetName)>-1){
@@ -151,7 +151,7 @@ dojo.provide("dojox.html.styles");
 		}
 		return false; //StyleSheet or false
 	}
-	
+
 	dojox.html.getDynamicStyleSheet = function(/*String*/styleSheetName){
 		// summary:
 		//		Creates and returns a dynamically created style sheet
@@ -159,18 +159,20 @@ dojo.provide("dojox.html.styles");
 		//
 		//	argument:
 		//			styleSheetName /* optional String */
-		//			The name given the style sheet so that multiple 
-		//			style sheets can be created and referenced. If 
+		//			The name given the style sheet so that multiple
+		//			style sheets can be created and referenced. If
 		//			no argument is given, the name "default" is used.
 		//
 		if(!styleSheetName){ styleSheetName="default"; }
-		
+
 		if(!dynamicStyleMap[styleSheetName]){
 			if(dojo.doc.createStyleSheet){ //IE
-			
-				dynamicStyleMap[styleSheetName] = dojo.doc.createStyleSheet();
-				dynamicStyleMap[styleSheetName].title = styleSheetName;
 
+				dynamicStyleMap[styleSheetName] = dojo.doc.createStyleSheet();
+				if(dojo.isIE < 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].setAttribute("type", "text/css");
@@ -179,8 +181,8 @@ dojo.provide("dojox.html.styles");
 			}
 			dynamicStyleMap[styleSheetName]._indicies = [];
 		}
-		
-		
+
+
 		return dynamicStyleMap[styleSheetName]; //StyleSheet
 	}
 
@@ -190,11 +192,11 @@ dojo.provide("dojox.html.styles");
 		//		argument. Deafults to the default style sheet.
 		//
 		var ss = dojox.html.getStyleSheet(styleSheetName);
-		if(ss){ 
+		if(ss){
 			if(ss.sheet){
-				ss.sheet.disabled = false; 
+				ss.sheet.disabled = false;
 			}else{
-				ss.disabled = false; 
+				ss.disabled = false;
 			}
 		}
 	}
@@ -205,15 +207,15 @@ dojo.provide("dojox.html.styles");
 		//		argument. If no arg is passed, defaults to the default style sheet.
 		//
 		var ss = dojox.html.getStyleSheet(styleSheetName);
-		if(ss){ 
+		if(ss){
 			if(ss.sheet){
-				ss.sheet.disabled = true; 
+				ss.sheet.disabled = true;
 			}else{
-				ss.disabled = true; 
+				ss.disabled = true;
 			}
 		}
 	}
-	
+
 	dojox.html.activeStyleSheet = function(/*?String*/title){
 		// summary:
 		//		Getter/Setter
@@ -239,21 +241,21 @@ dojo.provide("dojox.html.styles");
 		}
 		return true; //StyleSheet or Boolean - FIXME - doesn't make a lot of sense
 	}
-	
+
 	dojox.html.getPreferredStyleSheet = function(){
 		// summary
 		//	Returns the style sheet that was initially enabled
 		//	on document launch.
-		
+
 		//TODO
 	}
-	
-	
-	
-	
+
+
+
+
 	dojox.html.getToggledStyleSheets = function(){
 		// summary:
-		//		Searches HTML for style sheets that are "toggle-able" - 
+		//		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:
@@ -266,7 +268,7 @@ dojo.provide("dojox.html.styles");
 		if(!titledSheets.length){
 			var sObjects = dojox.html.getStyleSheets();
 			for(var nm in sObjects){
-				
+
 				if(sObjects[nm].title){
 					//console.log("TITLE:", sObjects[nm].title, sObjects[nm])
 					titledSheets.push(sObjects[nm]);
@@ -275,21 +277,21 @@ dojo.provide("dojox.html.styles");
 		}
 		return titledSheets; //Array
 	}
-	
-	
+
+
 	dojox.html.getStyleSheets = function(){
 		// summary:
 		//		Collects all the style sheets referenced in the HTML page,
-		//		including any incuded via @import. 
+		//		including any incuded via @import.
 		//
-		//	returns: 
+		//	returns:
 		//		An hash map of all the style sheets.
 		//
 		//	TODO: 	Does not recursively search for @imports, so it will
 		//			only go one level deep.
 		//
 		if(pageStyleSheets.collected) {return pageStyleSheets;}
-		
+
 		var sheets = dojo.doc.styleSheets;
 		//console.log("styleSheets:", sheets);
 		dojo.forEach(sheets, function(n){
@@ -298,24 +300,24 @@ dojo.provide("dojox.html.styles");
 			if(dojo.isIE){
 				// IE attaches a style sheet for VML - do not include this
 				if(s.cssText.indexOf("#default#VML")==-1){
-					
-					
+
+
 					if(s.href){
-						// linked		
+						// linked
 						pageStyleSheets[name] = s;
-					
+
 					}else if(s.imports.length){
 						// Imported via @import
 						dojo.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;
@@ -327,17 +329,17 @@ dojo.provide("dojox.html.styles");
 						pageStyleSheets[r.href].id = s.ownerNode.id;
 					}
 				});
-			
+
 			}
-			
+
 		});
-		
+
 		//console.log("pageStyleSheets:", pageStyleSheets);
-		
-		
+
+
 		pageStyleSheets.collected = true;
 		return pageStyleSheets; //Object
 	}
-	
 
-})();
\ No newline at end of file
+
+})();
diff --git a/dojox/html/tests/entities.js b/dojox/html/tests/entities.js
index dfc1d36..9de34d2 100755
--- a/dojox/html/tests/entities.js
+++ b/dojox/html/tests/entities.js
@@ -1,12 +1,12 @@
 dojo.provide("dojox.html.tests.entities");
 dojo.require("dojox.html.entities");
 
-doh.register("dojox.html.tests.entities", 
+doh.register("dojox.html.tests.entities",
 	[
 		{
 			name: "Encode:  Basic HTML Entities",
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of basic encoding of characters considered HTML entities
 				//	description:
 				//		Simple test of basic encoding of characters considered HTML entities
@@ -19,7 +19,7 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Decode:  Basic HTML Entities",
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of basic encoding of characters considered HTML entities
 				//	description:
 				//		Simple test of basic encoding of characters considered HTML entities
@@ -32,7 +32,7 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Encode:  Basic Latin Entities",
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of basic encoding of characters considered Latin type entities
 				//	description:
 				//		Simple test of basic encoding of characters considered Latin type entities
@@ -51,7 +51,7 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Decode:  Basic Latin Entities",
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of basic decoding of characters considered Latin type entities
 				//	description:
 				//		Simple test of basic decoding of characters considered Latin type entities
@@ -70,7 +70,7 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Encode:  Custom entity map",
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of basic encoding using a custom map instead of the default ones.
 				//	description:
 				//		Simple test of basic encoding using a custom map instead of the default ones.
@@ -83,7 +83,7 @@ doh.register("dojox.html.tests.entities",
 		{
 			name: "Decode:  Custom entity map",
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of basic decoding using a custom map instead of the default ones.
 				//	description:
 				//		Simple test of basic decoding using a custom map instead of the default ones.
diff --git a/dojox/html/tests/format.js b/dojox/html/tests/format.js
index 4c4da04..16f5e1e 100755
--- a/dojox/html/tests/format.js
+++ b/dojox/html/tests/format.js
@@ -2,12 +2,12 @@ dojo.provide("dojox.html.tests.format");
 dojo.require("dojox.html.format");
 
 
-doh.register("dojox.html.tests.format", 
+doh.register("dojox.html.tests.format",
 	[
 		{
 			name: "Format:  Basic HTML Format test",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting.
 				// description:
 				//		Simple test of basic HTML formatting.
@@ -22,7 +22,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with three space indent",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
 				// description:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
@@ -37,7 +37,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with three space indent and custom encoding",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
 				// description:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
@@ -52,7 +52,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with comment node",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with a comment node"
 				// description:
 				//		Simple test of basic HTML formatting with a comment node"
@@ -74,7 +74,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with inline tags",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
 				// description:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
@@ -89,7 +89,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with inline tags (2)",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
 				// description:
 				//		Simple test of basic HTML formatting with spaced indenting instead of tab
@@ -106,7 +106,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with id",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an id attr set.
 				// description:
 				//		Simple test of basic HTML formatting with an id attr set.
@@ -121,7 +121,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with attributes (sorting attributes)",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an id attr set.
 				// description:
 				//		Simple test of basic HTML formatting with an id attr set.
@@ -136,7 +136,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with attributes (multiple unquoted)",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an id attr set.
 				// description:
 				//		Simple test of basic HTML formatting with an id attr set.
@@ -151,7 +151,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with style",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an id attr set.
 				// description:
 				//		Simple test of basic HTML formatting with an id attr set.
@@ -166,7 +166,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format test with multi style",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an id attr set.
 				// description:
 				//		Simple test of basic HTML formatting with an id attr set.
@@ -181,7 +181,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format with script test",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an embedded script tag.
 				// description:
 				//		Simple test of basic HTML formatting with an embedded script tag.
@@ -205,7 +205,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format with script test and three space indent",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an embedded script tag.
 				// description:
 				//		Simple test of basic HTML formatting with an embedded script tag.
@@ -229,7 +229,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format with script test and three space indent, XHTML",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an embedded script tag.
 				// description:
 				//		Simple test of basic HTML formatting with an embedded script tag.
@@ -255,7 +255,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format with <pre> tag",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an embedded pre tag.
 				// description:
 				//		Simple test of basic HTML formatting with an embedded pre tag.
@@ -280,7 +280,7 @@ doh.register("dojox.html.tests.format",
 		{
 			name: "Format:  Basic HTML Format with <pre> tag and three space indent",
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of basic HTML formatting with an embedded pre tag.
 				// description:
 				//		Simple test of basic HTML formatting with an embedded pre tag.
@@ -305,14 +305,14 @@ doh.register("dojox.html.tests.format",
 			name: "Format:  Semi-complex HTML format",
 			timeout: 10000,
 			runTest: function(t) {
-				// summary: 
+				// summary:
 				//		Simple test of somewhat complex HTML in an external file getting formatted.
 				// description:
 				//		Simple test of basic HTML formatting with an embedded pre tag.
 				if(!dojo.isIE){
 					// Still working out minor comparison issues on IE.  Sigh.
 					// the output is pretty accurate, just need to fix a few things.
-					// Like I think the newlines differ or somesuch.  
+					// Like I think the newlines differ or somesuch.
 					var deferred = new doh.Deferred();
 
 					var args = {
diff --git a/dojox/html/tests/test_metrics_getTextBox.html b/dojox/html/tests/test_metrics_getTextBox.html
new file mode 100644
index 0000000..020ec68
--- /dev/null
+++ b/dojox/html/tests/test_metrics_getTextBox.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<!--
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+-->
+    <head>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+        <style type="text/css">
+            @import "../../../dojo/resources/dojo.css";
+            @import "../../../dijit/tests/css/dijitTests.css";
+            .test { font-family: Times, Times New Roman, serif; font-weight: bold; font-size: 12pt; }
+            .sample { clear: both; float: left; background-color: #ffd; border: 1px black solid; margin: 0; padding: 0; overflow: hidden; } 
+        </style>
+        <script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug: true"></script>
+        <script type="text/javascript" src="../metrics.js"></script>
+        <script type="text/javascript">
+            dojo.require("dojox.html.metrics");
+
+            dojo.addOnLoad(function(){
+                dojo.connect(dojo.byId("submit"), "onclick", function(){
+                    var t = dojo.byId("input").value.replace(/\r?\n/g, "<br>");
+                    var r = dojox.html.metrics.getTextBox(t, null, "test");
+                    dojo.byId("output").innerHTML = dojo.toJson(r, true).
+                            replace(/\r?\n/g, "<br>").replace(/\t/g, "    ").replace(/\s/g, " ");
+                    dojo.attr("sample", {
+                        innerHTML: t,
+                        style: {
+                            width:  r.w + "px",
+                            height: r.h + "px"
+                        }
+                    });
+                });
+            });
+        </script>
+    </head>
+    <body>
+        <h1>Testing dojox.html.metrics.getTextBox()</h1>
+        <h2>Input</h2>
+        <div>
+            <textarea id="input" cols="40" rows="5"></textarea><br>
+            <button id="submit">Run</button>
+        </div>
+        <h2>Result as JSON</h2>
+        <p id="output"></p>
+        <h2>Sample output clipped</h2>
+        <div id="sample" class="sample test"></div>
+    </body>
+</html>
\ No newline at end of file
diff --git a/dojox/image/Badge.js b/dojox/image/Badge.js
index 7534b0f..17b2baa 100644
--- a/dojox/image/Badge.js
+++ b/dojox/image/Badge.js
@@ -22,7 +22,7 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 	rows: 4,
 	
 	// cols: Integer
-	//		Number of Columns to display 
+	//		Number of Columns to display
 	cols: 5,
 	
 	// cellSize: Integer
@@ -57,8 +57,8 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 	_init: function(){
 		// summary: Setup and layout the images
 	
-		var _row = 0, 
-			_w = this.cellSize; 
+		var _row = 0,
+			_w = this.cellSize;
 
 		dojo.style(this.domNode, {
 			width: _w * this.cols + "px",
@@ -89,7 +89,7 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 		var l = this._nl.length;
 		while(this.threads--){
 			var s = Math.floor(Math.random() * l);
-			setTimeout(dojo.hitch(this, "_enbiggen", { 
+			setTimeout(dojo.hitch(this, "_enbiggen", {
 				target: this._nl[s]
 			}), this.delay * this.threads);
 		}
@@ -131,7 +131,7 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 			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()); 
+				return Math.round(Math.random());
 			};
 			
 			if(_pos.x == this.cols - 1 || (_pos.x > 0 && _tehDecider() )){
@@ -150,14 +150,14 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 
 			dojo.animateProperty({ node: _pos.n, properties: props,
 				onEnd: dojo.hitch(this, "_loadUnder", _pos, props),
-				easing: this.easing 
+				easing: this.easing
 			}).play();
 			
 		}
 	},
 	
 	_loadUnder: function(info, props){
-		// summary: figure out which three images are being covered, and 
+		// summary: figure out which three images are being covered, and
 		//		determine if they need loaded or not
 
 		var idx = info.io;
@@ -197,13 +197,13 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 			props.top += this.cellSize;
 		}
 		if(props.left >= 0){
-			props.left += this.cellSize; 
+			props.left += this.cellSize;
 		}
 		var _cc = this.cellSize - (this.cellMargin * 2);
 		dojo.animateProperty({
-			node: info.n, 
+			node: info.n,
 			properties: dojo.mixin(props, {
-				width:_cc, 
+				width:_cc,
 				height:_cc
 			}),
 			onEnd: dojo.hitch(this, "_cycle", info, props)
@@ -213,7 +213,7 @@ dojo.declare("dojox.image.Badge", [dijit._Widget, dijit._Templated], {
 	_cycle: function(info, props){
 		// summary: Select an un-viewed image from the list, and show it
 
-		var bc = this.baseClass; 
+		var bc = this.baseClass;
 		dojo.removeClass(info.n, bc + "Top");
 		var ns = this._nl.filter(function(n){
 			return !dojo.hasClass(n, bc + "Seen")
diff --git a/dojox/image/Gallery.js b/dojox/image/Gallery.js
index 5439e76..6e1ddf8 100644
--- a/dojox/image/Gallery.js
+++ b/dojox/image/Gallery.js
@@ -1,8 +1,7 @@
 dojo.provide("dojox.image.Gallery");
 dojo.experimental("dojox.image.Gallery");
 //
-// dojox.image.Gallery courtesy Shane O Sullivan, licensed under a Dojo CLA 
-// @author  Copyright 2007 Shane O Sullivan (shaneosullivan1 at gmail.com)
+// dojox.image.Gallery courtesy Shane O Sullivan, licensed under a Dojo CLA
 //
 // For a sample usage, see http://www.skynet.ie/~sos/photos.php
 //
@@ -62,10 +61,10 @@ dojo.declare("dojox.image.Gallery",
 	//		Time, in seconds, between image changes in the slide show.
 	slideshowInterval: 3,
 	
-	templateString: dojo.cache("dojox.image", "resources/Gallery.html"), 
+	templateString: dojo.cache("dojox.image", "resources/Gallery.html"),
 
 	postCreate: function(){
-		// summary: 
+		// summary:
 		//		Initializes the widget, creates the ThumbnailPicker and SlideShow widgets
 		this.widgetid = this.id;
 		this.inherited(arguments)
@@ -81,14 +80,14 @@ dojo.declare("dojox.image.Gallery",
 		
 		
 		this.slideShow = new dojox.image.SlideShow({
-			imageHeight: this.imageHeight, 
+			imageHeight: this.imageHeight,
 			imageWidth: this.imageWidth,
 			autoLoad: this.autoLoad,
 			linkAttr: this.linkAttr,
 			imageLargeAttr: this.imageLargeAttr,
 			titleAttr: this.titleAttr,
 			slideshowInterval: this.slideshowInterval,
-			pageSize: this.pageSize 
+			pageSize: this.pageSize
 		}, this.slideShowNode);
 		
 		var _this = this;
@@ -96,7 +95,7 @@ dojo.declare("dojox.image.Gallery",
 		//in the ThumbnailPicker
 		dojo.subscribe(this.slideShow.getShowTopicName(), function(packet){
 			_this.thumbPicker._showThumbs(packet.index);
-		});	
+		});
 		//When the user clicks a thumbnail, show that image
 		dojo.subscribe(this.thumbPicker.getClickTopicName(), function(evt){
 			_this.slideShow.showImage(evt.index);
@@ -115,7 +114,7 @@ dojo.declare("dojox.image.Gallery",
 	},
 	  
   	setDataStore: function(dataStore, request, /*optional*/paramNames){
-		// summary: 
+		// summary:
 		//		Sets the data store and request objects to read data from.
 		// dataStore:
 		//		An implementation of the dojo.data.api.Read API. This accesses the image
@@ -139,7 +138,7 @@ dojo.declare("dojox.image.Gallery",
   	},
   
 	showNextImage: function(inTimer){
-		// summary: 
+		// summary:
 		//		Changes the image being displayed in the SlideShow to the next
 		//		image in the data store
 		// inTimer: Boolean
@@ -173,7 +172,7 @@ dojo.declare("dojox.image.Gallery",
 	},
 	
 	_centerChildren: function() {
-		// summary: 
+		// summary:
 		//		Ensures that the ThumbnailPicker and the SlideShow widgets
 		//		are centered.
 		var thumbSize = dojo.marginBox(this.thumbPicker.outerNode);
diff --git a/dojox/image/Lightbox.js b/dojox/image/Lightbox.js
index 8dd8833..1926e48 100644
--- a/dojox/image/Lightbox.js
+++ b/dojox/image/Lightbox.js
@@ -2,13 +2,13 @@ dojo.provide("dojox.image.Lightbox");
 dojo.experimental("dojox.image.Lightbox");
 
 dojo.require("dojo.window");
-dojo.require("dijit.Dialog"); 
+dojo.require("dijit.Dialog");
 dojo.require("dojox.fx._base");
 
 dojo.declare("dojox.image.Lightbox",
 	dijit._Widget, {
 	// summary:
-	//		A dojo-based Lightbox implementation. 
+	//		A dojo-based Lightbox implementation.
 	//
 	// description:
 	//	An Elegant, keyboard accessible, markup and store capable Lightbox widget to show images
@@ -19,15 +19,15 @@ dojo.declare("dojox.image.Lightbox",
 	//		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: 
+	// 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:	 
+	// 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>
@@ -36,7 +36,7 @@ dojo.declare("dojox.image.Lightbox",
 	//		Grouping images in a page with similar tags will provide a 'slideshow' like grouping of images
 	group: "",
 
-	// title: String 
+	// title: String
 	//		A string of text to be shown in the Lightbox beneath the image (empty if using a store)
 	title: "",
 
@@ -45,8 +45,8 @@ dojo.declare("dojox.image.Lightbox",
 	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 ...) 
+	//		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
@@ -91,7 +91,7 @@ dojo.declare("dojox.image.Lightbox",
 	},
 
 	_handleClick: function(/* Event */e){
-		// summary: Handle the click on the link 
+		// summary: Handle the click on the link
 		if(!this._allowPassthru){ e.preventDefault(); }
 		else{ return; }
 		this.show();
@@ -115,7 +115,7 @@ dojo.declare("dojox.image.Lightbox",
 
 	enable: function(){
 		// summary: Enables the dialog (prevents default link)
-		this._allowPassthru = false; 
+		this._allowPassthru = false;
 	},
 	
 	onClick: function(){
@@ -137,30 +137,30 @@ dojo.declare("dojox.image.LightboxDialog",
 	//		for programatic manipulation.
 	//
 	// description:
-	//	
-	//		A widget that intercepts anchor links (typically around images)		
+	//
+	//		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: 
+	//
+	//	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() 
+	//		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 
+	//		should not be populate manually. it is a placeholder for the currently
 	//		showing group of images in this master dialog
 	inGroup: null,
 
@@ -183,15 +183,22 @@ dojo.declare("dojox.image.LightboxDialog",
 	//		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,
-	
-	// an object of arrays, each array (of objects) being a unique 'group'
+
+/*=====
+	// _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.
@@ -201,6 +208,7 @@ dojo.declare("dojox.image.LightboxDialog",
 		//		'chaining' or var referencing with .startup()
 
 		this.inherited(arguments);
+		
 		this._animConnects = [];
 		this.connect(this.nextButtonNode, "onclick", "_nextImage");
 		this.connect(this.prevButtonNode, "onclick", "_prevImage");
@@ -223,8 +231,8 @@ dojo.declare("dojox.image.LightboxDialog",
 		this._lastGroup = groupData;
 		
 		// we only need to call dijit.Dialog.show() if we're not already open.
-		if(!_t.open){ 
-			_t.inherited(arguments); 
+		if(!_t.open){
+			_t.inherited(arguments);
 			_t._modalconnects.push(
 				dojo.connect(dojo.global, "onscroll", this, "_position"),
 				dojo.connect(dojo.global, "onresize", this, "_position"),
@@ -248,15 +256,15 @@ dojo.declare("dojox.image.LightboxDialog",
 			_t._wasStyled = false;
 		}
 		
-		dojo.style(_t.imgNode,"opacity","0"); 
+		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){ 
+		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 
+				// determine where we were or are in the show
 				dojo.forEach(_t.inGroup, function(g, i){
 					if(g.href == groupData.href){
 						_t._index = i;
@@ -267,7 +275,7 @@ dojo.declare("dojox.image.LightboxDialog",
 			}
 			if(!_t._index){
 				_t._index = 0;
-				var sr = _t.inGroup[_t._index]; 
+				var sr = _t.inGroup[_t._index];
 				src = (sr && sr.href) || _t.errorImg;
 			}
 			// FIXME: implement titleTemplate
@@ -286,7 +294,7 @@ dojo.declare("dojox.image.LightboxDialog",
 		_t._ready(src);
 	},
 	
-	_ready: function(src){	
+	_ready: function(src){
 		// summary: A function to trigger all 'real' showing of some src
 		
 		var _t = this;
@@ -308,8 +316,8 @@ dojo.declare("dojox.image.LightboxDialog",
 			});
 			// cleanup
 			dojo.disconnect(_t._imgConnect);
-			if(_t._imgError){ 
-				dojo.disconnect(_t._imgError); 
+			if(_t._imgError){
+				dojo.disconnect(_t._imgError);
 			}
 		});
 		
@@ -329,7 +337,7 @@ dojo.declare("dojox.image.LightboxDialog",
 
 	_prevImage: function(){
 		// summary: Load previous image in group
-		if(this.inGroup){ 
+		if(this.inGroup){
 			if(this._index == 0){
 				this._index = this.inGroup.length - 1;
 			}else{
@@ -340,18 +348,18 @@ dojo.declare("dojox.image.LightboxDialog",
 	},
 
 	_loadImage: function(){
-		// summary: Do the prep work before we can show another image 
+		// summary: Do the prep work before we can show another image
 		this._loadingAnim.play(1);
 	},
 
 	_prepNodes: function(){
 		// summary: A localized hook to accompany _loadImage
-		this._imageReady = false; 
+		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,
@@ -361,17 +369,22 @@ dojo.declare("dojox.image.LightboxDialog",
 		
 	},
 
+	_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" ? 
+		var adjustSize = dojo.boxModel == "border-box" ?
 			dojo._getBorderExtents(this.domNode).w : 0,
-			titleSize = forceTitle || { h:30 }
+			titleSize = forceTitle || this._calcTitleSize()
 		;
 		
 		this._lastTitleSize = titleSize;
 		
-		if(this.adjust && 
+		if(this.adjust &&
 			(size.h + titleSize.h + adjustSize + 80 > this._vp.h ||
 			 size.w + adjustSize + 60 > this._vp.w
 			)
@@ -381,7 +394,7 @@ dojo.declare("dojox.image.LightboxDialog",
 		}
 		this._currentSize = size;
 		
-		var _sizeAnim = dojox.fx.sizeTo({ 
+		var _sizeAnim = dojox.fx.sizeTo({
 			node: this.containerNode,
 			duration: size.duration||this.duration,
 			width: size.w + adjustSize,
@@ -395,17 +408,24 @@ dojo.declare("dojox.image.LightboxDialog",
 		// summary: resize an image to fit within the bounds of the viewport
 		// size: Object
 		//		The 'size' object passed around for this image
-		var ns = {};
 
-		// one of the dimensions is too big, go with the smaller viewport edge:
-		if(this._vp.h > this._vp.w){
-			// don't actually touch the edges:
-			ns.w = this._vp.w - 80;
-			ns.h = ns.w * (size.h / size.w);
+		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{
-			// give a little room for the titlenode, too:
-			ns.h = this._vp.h - 60 - this._lastTitleSize.h;
-			ns.w = ns.h * (size.w / size.h);
+			ns.w = imageAspect * nvp.h;
+			ns.h = nvp.h;
 		}
 
 		// we actually have to style this image, it's too big
@@ -464,9 +484,9 @@ dojo.declare("dojox.image.LightboxDialog",
 	hide: function(){
 		// summary: Hide the Master Lightbox
 		dojo.fadeOut({
-			node: this.titleNode, 
+			node: this.titleNode,
 			duration: 200,
-			// #5112 - if you _don't_ change the .src, safari will 
+			// #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;
@@ -491,11 +511,11 @@ dojo.declare("dojox.image.LightboxDialog",
 		//		attach to group of similar tag or null for individual image instance
 		var g = group;
 		if(!child.href){ return; }
-		if(g){	
+		if(g){
 			if(!this._groups[g]){
 				this._groups[g] = [];
 			}
-			this._groups[g].push(child); 
+			this._groups[g].push(child);
 		}else{ this._groups["XnoGroupX"].push(child); }
 	},
 
@@ -528,8 +548,8 @@ dojo.declare("dojox.image.LightboxDialog",
 		var dk = dojo.keys;
 		switch(e.charOrCode){
 			
-			case dk.ESCAPE: 
-				this.hide(); 
+			case dk.ESCAPE:
+				this.hide();
 				break;
 
 			case dk.DOWN_ARROW:
@@ -540,7 +560,7 @@ dojo.declare("dojox.image.LightboxDialog",
 
 			case dk.UP_ARROW:
 			case dk.LEFT_ARROW:
-			case 80: // key "p" 
+			case 80: // key "p"
 				this._prevImage();
 				break;
 		}
@@ -567,6 +587,7 @@ dojo.declare("dojox.image.LightboxDialog",
 	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);
diff --git a/dojox/image/LightboxNano.js b/dojox/image/LightboxNano.js
index 14b28a7..c45212b 100644
--- a/dojox/image/LightboxNano.js
+++ b/dojox/image/LightboxNano.js
@@ -1,21 +1,18 @@
-dojo.provide("dojox.image.LightboxNano");
-dojo.require("dojo.fx");
-
-(function(d){
+define("dojox/image/LightboxNano", ["dojo", "dojo/fx"], function(dojo, fx) {
 
 	var abs = "absolute",
 		vis = "visibility",
 		getViewport = function(){
 			//	summary: Returns the dimensions and scroll position of the viewable area of a browser window
-			var scrollRoot = (d.doc.compatMode == "BackCompat") ? d.body() : d.doc.documentElement,
+			var scrollRoot = (dojo.doc.compatMode == "BackCompat") ? dojo.body() : dojo.doc.documentElement,
 				scroll = dojo._docScroll();
 				return { w: scrollRoot.clientWidth, h: scrollRoot.clientHeight, l: scroll.x, t: scroll.y };
 			}
 	;
 
-	d.declare("dojox.image.LightboxNano", null, {
+	dojo.declare("dojox.image.LightboxNano", null, {
 		//	summary:
-		//		A simple "nano" version of the lightbox. 
+		//		A simple "nano" version of the lightbox.
 		//
 		//	description:
 		//		Very lightweight lightbox which only displays a larger image.  There is
@@ -48,22 +45,22 @@ dojo.require("dojo.fx");
 			// summary: Initializes the DOM node and connect onload event
 			var _this = this;
 
-			d.mixin(_this, p);
+			dojo.mixin(_this, p);
 			n = _this._node = dojo.byId(n);
 
 			// if we have a origin node, then prepare it to show the LightboxNano
 			if(n){
 				if(!/a/i.test(n.tagName)){
-					var a = d.create("a", { href: _this.href, "class": n.className }, n, "after");
+					var a = dojo.create("a", { href: _this.href, "class": n.className }, n, "after");
 					n.className = "";
 					a.appendChild(n);
 					n = a;
 				}
 
-				d.style(n, "position", "relative");
+				dojo.style(n, "position", "relative");
 				_this._createDiv("dojoxEnlarge", n);
-				d.setSelectable(n, false);
-				_this._onClickEvt = d.connect(n, "onclick", _this, "_load");
+				dojo.setSelectable(n, false);
+				_this._onClickEvt = dojo.connect(n, "onclick", _this, "_load");
 			}
 
 			if(_this.href){
@@ -78,32 +75,32 @@ dojo.require("dojo.fx");
 			// summary: Destroys the LightboxNano and it's DOM node
 			var a = this._connects || [];
 			a.push(this._onClickEvt);
-			d.forEach(a, d.disconnect);
-			d.destroy(this._node);
+			dojo.forEach(a, dojo.disconnect);
+			dojo.destroy(this._node);
 		},
 
 		_createDiv: function(/*String*/cssClass, /*DomNode*/refNode, /*boolean*/display){
 			// summary: Creates a div for the enlarge icon and loading indicator layers
-			return d.create("div", { // DomNode
-				"class": cssClass, 
-				style: { 
-					position: abs, 
-					display: display ? "" : "none" 
-				} 
-			}, refNode); 
+			return dojo.create("div", { // DomNode
+				"class": cssClass,
+				style: {
+					position: abs,
+					display: display ? "" : "none"
+				}
+			}, refNode);
 		},
-	
+
 		_load: function(/*Event*/e){
 			// summary: Creates the large image and begins to show it
 			var _this = this;
 
-			e && d.stopEvent(e);
+			e && dojo.stopEvent(e);
 
 			if(!_this._loading){
 				_this._loading = true;
 				_this._reset();
 
-				var i = _this._img = d.create("img", {
+				var i = _this._img = dojo.create("img", {
 						style: {
 							visibility: "hidden",
 							cursor: "pointer",
@@ -112,18 +109,18 @@ dojo.require("dojo.fx");
 							left: 0,
 							zIndex: 9999999
 						}
-					}, d.body()),
+					}, dojo.body()),
 					ln = _this._loadingNode,
-					n = d.query("img", _this._node)[0] || _this._node,
-					a = d.position(n, true),
-					c = d.contentBox(n),
-					b = d._getBorderExtents(n)
+					n = dojo.query("img", _this._node)[0] || _this._node,
+					a = dojo.position(n, true),
+					c = dojo.contentBox(n),
+					b = dojo._getBorderExtents(n)
 				;
 
 				if(ln == null){
 					_this._loadingNode = ln = _this._createDiv("dojoxLoading", _this._node, true);
-					var l = d.marginBox(ln);
-					d.style(ln, {
+					var l = dojo.marginBox(ln);
+					dojo.style(ln, {
 						left: parseInt((c.w - l.w) / 2) + "px",
 						top: parseInt((c.h - l.h) / 2) + "px"
 					});
@@ -133,7 +130,7 @@ dojo.require("dojo.fx");
 				c.y = a.y - 10 + b.t;
 				_this._start = c;
 
-				_this._connects = [d.connect(i, "onload", _this, "_show")];
+				_this._connects = [dojo.connect(i, "onload", _this, "_show")];
 
 				i.src = _this.href;
 			}
@@ -142,7 +139,7 @@ dojo.require("dojo.fx");
 		_hideLoading: function(){
 			// summary: Hides the animated loading indicator
 			if(this._loadingNode){
-				d.style(this._loadingNode, "display", "none");
+				dojo.style(this._loadingNode, "display", "none");
 			}
 			this._loadingNode = false;
 		},
@@ -155,33 +152,33 @@ dojo.require("dojo.fx");
 				h = _this._img.height,
 				vpw = parseInt((vp.w - 20) * 0.9),
 				vph = parseInt((vp.h - 20) * 0.9),
-				dd = d.doc,
-				bg = _this._bg = d.create("div", {
+				dd = dojo.doc,
+				bg = _this._bg = dojo.create("div", {
 					style: {
 						backgroundColor: "#000",
 						opacity: 0.0,
 						position: abs,
 						zIndex: 9999998
 					}
-				}, d.body()),
+				}, dojo.body()),
 				ln = _this._loadingNode
 			;
 
 			if(_this._loadingNode){
 				_this._hideLoading();
 			}
-			d.style(_this._img, {
+			dojo.style(_this._img, {
 				border: "10px solid #fff",
 				visibility: "visible"
 			});
-			d.style(_this._node, vis, "hidden");
+			dojo.style(_this._node, vis, "hidden");
 
 			_this._loading = false;
 
 			_this._connects = _this._connects.concat([
-				d.connect(dd, "onmousedown", _this, "_hide"),
-				d.connect(dd, "onkeypress", _this, "_key"),
-				d.connect(window, "onresize", _this, "_sizeBg")
+				dojo.connect(dd, "onmousedown", _this, "_hide"),
+				dojo.connect(dd, "onkeypress", _this, "_key"),
+				dojo.connect(window, "onresize", _this, "_sizeBg")
 			]);
 
 			if(w > vpw){
@@ -202,7 +199,7 @@ dojo.require("dojo.fx");
 
 			_this._sizeBg();
 
-			d.fx.combine([
+			dojo.fx.combine([
 				_this._anim(_this._img, _this._coords(_this._start, _this._end)),
 				_this._anim(bg, { opacity: 0.5 })
 			]).play();
@@ -210,8 +207,8 @@ dojo.require("dojo.fx");
 
 		_sizeBg: function(){
 			// summary: Resize the background to fill the page
-			var dd = d.doc.documentElement;
-			d.style(this._bg, {
+			var dd = dojo.doc.documentElement;
+			dojo.style(this._bg, {
 				top: 0,
 				left: 0,
 				width: dd.scrollWidth + "px",
@@ -221,7 +218,7 @@ dojo.require("dojo.fx");
 
 		_key: function(/*Event*/e){
 			// summary: A key was pressed, so hide the lightbox
-			d.stopEvent(e);
+			dojo.stopEvent(e);
 			this._hide();
 		},
 
@@ -232,15 +229,15 @@ dojo.require("dojo.fx");
 				top:	{ start: s.y, end: e.y },
 				width:	{ start: s.w, end: e.w },
 				height:	{ start: s.h, end: e.h }
-			}; 
+			};
 		},
 
 		_hide: function(){
 			// summary: Closes the lightbox
 			var _this = this;
-			d.forEach(_this._connects, d.disconnect);
+			dojo.forEach(_this._connects, dojo.disconnect);
 			_this._connects = [];
-			d.fx.combine([
+			dojo.fx.combine([
 				_this._anim(_this._img, _this._coords(_this._end, _this._start), "_reset"),
 				_this._anim(_this._bg, {opacity:0})
 			]).play();
@@ -248,48 +245,47 @@ dojo.require("dojo.fx");
 
 		_reset: function(){
 			// summary: Destroys the lightbox
-			d.style(this._node, vis, "visible");
-			d.forEach([this._img, this._bg], function(n){
-				d.destroy(n);
-				n = null;
-			});
+			dojo.style(this._node, vis, "visible");
+			dojo.destroy(this._img);
+			dojo.destroy(this._bg);
+			this._img = this._bg = null;
 			this._node.focus();
 		},
 
 		_anim: function(/*DomNode*/node, /*Object*/args, /*Function*/onEnd){
 			// summary: Creates the lightbox open/close and background fadein/out animations
-			return d.animateProperty({ // dojo.Animation
+			return dojo.animateProperty({ // dojo.Animation
 				node: node,
 				duration: this.duration,
 				properties: args,
-				onEnd: onEnd ? d.hitch(this, onEnd) : null
-			}); 
+				onEnd: onEnd ? dojo.hitch(this, onEnd) : null
+			});
 		},
 		
 		show: function(/*Object?*/args){
-			// summary: 
-			//		Shows this LightboxNano programatically. Allows passing a new href and 
+			// summary:
+			//		Shows this LightboxNano programatically. Allows passing a new href and
 			//		a programatic origin.
 			//
 			// args: Object?
 			//		An object with optional members of `href` and `origin`.
-			//		`origin` can be be a String|Id of a DomNode to use when 
+			//		`origin` can be be a String|Id of a DomNode to use when
 			//		animating the openeing of the image (the 'box' effect starts
 			//		from this origin point. eg: { origin: e.target })
 			//		If there's no origin, it will use the center of the viewport.
-			//		The `href` member is a string URL for the image to be 
+			//		The `href` member is a string URL for the image to be
 			//		displayed. Omiting either of these members will revert to
 			//		the default href (which could be absent in some cases) and
 			//		the original srcNodeRef for the widget.
-			args = args || {}; 
+			args = args || {};
 			this.href = args.href || this.href;
 
-			var n = d.byId(args.origin),
+			var n = dojo.byId(args.origin),
 				vp = getViewport();
 
 			// if we don't have a valid origin node, then create one as a reference
 			// that is centered in the viewport
-			this._node = n || d.create("div", {
+			this._node = n || dojo.create("div", {
 					style: {
 						position: abs,
 						width: 0,
@@ -297,7 +293,7 @@ dojo.require("dojo.fx");
 						left: (vp.l + (vp.w / 2)) + "px",
 						top: (vp.t + (vp.h / 2)) + "px"
 					}
-				}, d.body())
+				}, dojo.body())
 			;
 
 			this._load();
@@ -305,9 +301,10 @@ dojo.require("dojo.fx");
 			// if we don't have a valid origin node, then destroy the centered reference
 			// node since load() has already been called and it's not needed anymore.
 			if(!n){
-				d.destroy(this._node);
+				dojo.destroy(this._node);
 			}
 		}
 	});
 
-})(dojo);
+	return dojox.image.LightboxNano;
+});
diff --git a/dojox/image/Magnifier.js b/dojox/image/Magnifier.js
index a3d2839..c511a53 100644
--- a/dojox/image/Magnifier.js
+++ b/dojox/image/Magnifier.js
@@ -10,7 +10,7 @@ dojo.declare("dojox.image.Magnifier",
 	//
 	// description:
 	//		An unobtrusive way to add an unstyled overlay
-	// 		above the srcNode image element. The overlay/glass is a 
+	// 		above the srcNode image element. The overlay/glass is a
 	//		scaled version of the src image (so larger images sized down
 	//		are clearer).
 	//
@@ -49,7 +49,7 @@ dojo.declare("dojox.image.Magnifier",
 		;
 		
 		// with svg, our mouseout connection to the image surface doesn't
-		// fire, so we'r have to manually calculate offsets	
+		// 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{
@@ -66,7 +66,7 @@ dojo.declare("dojox.image.Magnifier",
 			y = (this._zoomSize.h * yOff * -1)+(this.glassSize*yOff)
 		;
 		// set the image offset
-		this.img.setShape({ x: x, y: y });	
+		this.img.setShape({ x: x, y: y });
 
 	}
 
diff --git a/dojox/image/MagnifierLite.js b/dojox/image/MagnifierLite.js
index 1de42de..ff7899d 100644
--- a/dojox/image/MagnifierLite.js
+++ b/dojox/image/MagnifierLite.js
@@ -8,7 +8,7 @@ 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 
+	// 		above the srcNode image element. The overlay/glass is a
 	//		scaled version of the src image (so larger images sized down
 	//		are clearer).
 	//
@@ -21,14 +21,14 @@ dojo.declare("dojox.image.MagnifierLite", dijit._Widget,
 	glassSize: 125,
 
 	// scale: Decimal
-	// 		the multiplier of the Mangification. 
+	// 		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		
+		// and skip using dijit._Templated
 		this._adjustScale();
 		this._createGlass();
 		
@@ -56,7 +56,7 @@ dojo.declare("dojox.image.MagnifierLite", dijit._Widget,
 		this.surfaceNode = node.appendChild(dojo.create('div'));
 
 		this.img = dojo.place(dojo.clone(this.domNode), node);
-		// float the image around inside the .glassNode 
+		// float the image around inside the .glassNode
 		dojo.style(this.img, {
 			position: "relative",
 			top: 0, left: 0,
@@ -83,7 +83,7 @@ dojo.declare("dojox.image.MagnifierLite", dijit._Widget,
 		dojo.style(this.glassNode, {
 			visibility: "visible",
 			display:""
-		});			
+		});
 		
 	},
 	
@@ -100,8 +100,8 @@ dojo.declare("dojox.image.MagnifierLite", dijit._Widget,
 
 		this._setImage(e);
 		var sub = Math.floor(this.glassSize / 2);
-		dojo.style(this.glassNode,{ 
-			top: Math.floor(e.pageY - sub) + "px", 
+		dojo.style(this.glassNode,{
+			top: Math.floor(e.pageY - sub) + "px",
 			left:Math.floor(e.pageX - sub) + "px"
 		});
 		
diff --git a/dojox/image/SlideShow.js b/dojox/image/SlideShow.js
index cee35b9..4521011 100644
--- a/dojox/image/SlideShow.js
+++ b/dojox/image/SlideShow.js
@@ -1,9 +1,8 @@
 dojo.provide("dojox.image.SlideShow");
 //
-// dojox.image.SlideShow courtesy Shane O Sullivan, licensed under a Dojo CLA 
+// dojox.image.SlideShow courtesy Shane O Sullivan, licensed under a Dojo CLA
 // For a sample usage, see http://www.skynet.ie/~sos/photos.php
 //
-// @author  Copyright 2007 Shane O Sullivan (shaneosullivan1 at gmail.com)
 //
 //	TODO: more cleanups
 //
@@ -15,7 +14,7 @@ dojo.require("dijit._Templated");
 dojo.declare("dojox.image.SlideShow",
 	[dijit._Widget, dijit._Templated],
 	{
-	// summary: 
+	// summary:
 	//		A Slideshow Widget
 
 	// imageHeight: Number
@@ -27,7 +26,7 @@ dojo.declare("dojox.image.SlideShow",
 	imageWidth: 500,
 
 	// title: String
-	//		The initial title of the SlideShow 
+	//		The initial title of the SlideShow
 	title: "",
 
 	// titleTemplate: String
@@ -108,7 +107,7 @@ dojo.declare("dojox.image.SlideShow",
 	_tmpImage: null,
 	
 	// _request: Object
-	//	Implementation of the dojo.data.api.Request API, which defines the query 
+	//	Implementation of the dojo.data.api.Request API, which defines the query
 	//	parameters for accessing the store.
 	_request: null,
 
@@ -125,7 +124,7 @@ dojo.declare("dojox.image.SlideShow",
 			dojo.connect(this.outerNode, "onmouseover", this, function(evt){
 				try{ this._showNav();}
 				catch(e){} //TODO: remove try/catch
-			});		
+			});
 			dojo.connect(this.outerNode, "onmouseout", this, function(evt){
 				try{ this._hideNav(evt);}
 				catch(e){} //TODO: remove try/catch
@@ -146,7 +145,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	setDataStore: function(dataStore, request, /*optional*/paramNames){
-		// summary: 
+		// summary:
 		//		Sets the data store and request objects to read data from.
 		// dataStore:
 		//		An implementation of the dojo.data.api.Read API. This accesses the image
@@ -169,13 +168,13 @@ dojo.declare("dojox.image.SlideShow",
 				_this.maxPhotos = count;
 			}
 		};
-		if(request.query){ 
-			dojo.mixin(this._request.query, request.query); 
+		if(request.query){
+			dojo.mixin(this._request.query, request.query);
 		}
 		if(paramNames){
 			dojo.forEach(["imageLargeAttr", "linkAttr", "titleAttr"], function(attrName){
-				if(paramNames[attrName]){ 
-					this[attrName] = paramNames[attrName]; 
+				if(paramNames[attrName]){
+					this[attrName] = paramNames[attrName];
 				}
 			}, this);
 		}
@@ -186,7 +185,7 @@ dojo.declare("dojox.image.SlideShow",
 			_this._request.onComplete = null;
 			if(_this.autoStart){
 				_this.imageIndex = -1;
-				_this.toggleSlideShow(); 
+				_this.toggleSlideShow();
 			} else {
 				_this.showImage(0);
 			}
@@ -200,9 +199,9 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	reset: function(){
-		// summary: 
+		// summary:
 		//		Resets the widget to its initial state
-		// description: 
+		// description:
 		//		Removes all previously loaded images, and clears all caches.
 		dojo.query("> *", this.largeNode).orphan();
 		this.largeNode.appendChild(this._tmpImage);
@@ -217,7 +216,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	isImageLoaded: function(index){
-		// summary: 
+		// summary:
 		//		Returns true if image at the specified index is loaded, false otherwise.
 		// index:
 		//		The number index in the data store to check if it is loaded.
@@ -225,7 +224,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	moveImageLoadingPointer: function(index){
-		// summary: 
+		// summary:
 		//		If 'autoload' is true, this tells the widget to start loading
 		//		images from the specified pointer.
 		// index:
@@ -248,8 +247,8 @@ dojo.declare("dojox.image.SlideShow",
 		if(inTimer && this._timerCancelled){ return false; }
 		
 		if(this.imageIndex + 1 >= this.maxPhotos){
-			if(inTimer && (this.loop || forceLoop)){ 
-				this.imageIndex = -1; 
+			if(inTimer && (this.loop || forceLoop)){
+				this.imageIndex = -1;
 			}else{
 				if(this._slideId){ this._stop(); }
 				return false;
@@ -263,7 +262,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	toggleSlideShow: function(){
-		// summary: 
+		// summary:
 		//		Switches the slideshow mode on and off.
 		
 		// If the slideshow is already running, stop it.
@@ -299,7 +298,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	getShowTopicName: function(){
-		// summary: 
+		// summary:
 		//		Returns the topic id published to when an image is shown
 		// description:
 		//		The information published is: index, title and url
@@ -307,7 +306,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	getLoadTopicName: function(){
-		// summary: 
+		// summary:
 		//		Returns the topic id published to when an image finishes loading.
 		// description:
 		//		The information published is the index position of the image loaded.
@@ -315,22 +314,22 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	showImage: function(index, /* Function? */callback){
-		// summary: 
+		// summary:
 		//		Shows the image at index 'index'.
 		// index: Number
 		//		The position of the image in the data store to display
 		// callback: Function
 		//		Optional callback function to call when the image has finished displaying.
 
-		if(!callback && this._slideId){ 
-			this.toggleSlideShow(); 
+		if(!callback && this._slideId){
+			this.toggleSlideShow();
 		}
 		var _this = this;
 		var current = this.largeNode.getElementsByTagName("div");
 		this.imageIndex = index;
 
 		var showOrLoadIt = function() {
-			//If the image is already loaded, then show it. 
+			//If the image is already loaded, then show it.
 			if(_this.images[index]){
 				while(_this.largeNode.firstChild){
 					_this.largeNode.removeChild(_this.largeNode.firstChild);
@@ -349,12 +348,12 @@ dojo.declare("dojox.image.SlideShow",
 						_this._showNav(true);
 					}
 					dojo.publish(_this.getShowTopicName(), [{
-						index: index,	
+						index: index,
 						title: title,
 						url: img.getAttribute("src")
 					}]);
 
-        				if(callback) { 
+        				if(callback) {
         					callback(a,b,c);
         				}
 					_this._setTitle(title);
@@ -369,13 +368,13 @@ dojo.declare("dojox.image.SlideShow",
 			}else{
 				//If the image is not loaded yet, load it first, then show it.
 				_this._loadImage(index, function(){
-					_this.showImage(index, callback);	
+					_this.showImage(index, callback);
 				});
 			}
 		};
 
 		//If an image is currently showing, fade it out, then show
-		//the new image. Otherwise, just show the new image. 	
+		//the new image. Otherwise, just show the new image.
 		if(current && current.length > 0){
 			dojo.fadeOut({
 				node: current[0],
@@ -391,7 +390,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 	
 	_fitSize: function(force){
-		// summary: 
+		// summary:
 		//		Fits the widget size to the size of the image being shown,
 		//		or centers the image, depending on the value of 'fixedHeight'
 		// force: Boolean
@@ -405,14 +404,14 @@ dojo.declare("dojox.image.SlideShow",
 	},
 	
 	_getTopPadding: function(){
-		// summary: 
+		// summary:
 		//		Returns the padding to place at the top of the image to center it vertically.
 		if(!this.fixedHeight){ return 0; }
 		return (this.imageHeight - this._currentImage.height) / 2;
 	},
 	
 	_loadNextImage: function(){
-		// summary: 
+		// summary:
 		//		Load the next unloaded image.
 
 		if(!this.autoLoad){
@@ -425,7 +424,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 	
 	_loadImage: function(index, callbackFn){
-		// summary: 
+		// summary:
 		//		Load image at specified index
 		// description:
 		//		This function loads the image at position 'index' into the
@@ -435,8 +434,8 @@ dojo.declare("dojox.image.SlideShow",
 		// callbackFn:
 		//		An optional function to execute when the image has finished loading.
 
-		if(this.images[index] || !this._request) { 
-			return; 
+		if(this.images[index] || !this._request) {
+			return;
 		}
 		
 		var pageStart = index - (index % (this._request.count || this.pageSize));
@@ -453,7 +452,7 @@ dojo.declare("dojox.image.SlideShow",
 
 		var _this = this;
 		var store = this.imageStore;
-		var loadIt = function(item){			
+		var loadIt = function(item){
 			var url = _this.imageStore.getValue(item, _this.imageLargeAttr);
 			
 			var img = new Image();	// when creating img with "createElement" IE doesnt has width and height, so use the Image object
@@ -463,8 +462,8 @@ dojo.declare("dojox.image.SlideShow",
 			div._img = img;
 
 			var link = _this.imageStore.getValue(item,_this.linkAttr);
-			if(!link || _this.noLink){ 
-				div.appendChild(img); 
+			if(!link || _this.noLink){
+				div.appendChild(img);
 			}else{
 				var a = dojo.create("a", {
 					"href": link,
@@ -481,10 +480,10 @@ dojo.declare("dojox.image.SlideShow",
 				_this._fitImage(img);
 				dojo.attr(div, {"width": _this.imageWidth, "height": _this.imageHeight});
 				
-				// make a short timeout to prevent IE6/7 stack overflow at line 0 ~ still occuring though for first image 
+				// make a short timeout to prevent IE6/7 stack overflow at line 0 ~ still occuring though for first image
 				dojo.publish(_this.getLoadTopicName(), [index]);
 
-				setTimeout(function(){_this._loadNextImage();}, 1);	
+				setTimeout(function(){_this._loadNextImage();}, 1);
 				if(callbackFn){ callbackFn(); }
 			});
 			_this.hiddenNode.appendChild(div);
@@ -497,13 +496,13 @@ dojo.declare("dojox.image.SlideShow",
 			dojo.attr(img, "src", url);
 			
 			var title = _this.imageStore.getValue(item, _this.titleAttr);
-			if(title){ dojo.attr(img, "title", title); } 
+			if(title){ dojo.attr(img, "title", title); }
 		}
 		this.imageStore.fetch(this._request);
 	},
 
 	_stop: function(){
-		// summary: 
+		// summary:
 		//		Stops a running slide show.
 		if(this._slideId){ clearTimeout(this._slideId); }
 		this._slideId = null;
@@ -512,7 +511,7 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	_prev: function(){
-		// summary: 
+		// summary:
 		//		Show the previous image.
 		// FIXME: either pull code from showNext/prev, or call it here
 		if(this.imageIndex < 1){ return; }
@@ -520,13 +519,13 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	_next: function(){
-		// summary: 
+		// summary:
 		//		Show the next image
 		this.showNextImage();
 	},
 
 	_startTimer: function(){
-		// summary: 
+		// summary:
 		//		Starts a timeout to show the next image when a slide show is active
 		var id = this.id;
 		this._slideId = setTimeout(function(){
@@ -543,7 +542,7 @@ dojo.declare("dojox.image.SlideShow",
 		dojo.style(this.navNode, "top", "-10000px");
 		
 		//Make the navigation controls visible
-		dojo._setOpacity(this.navNode, 99);
+		dojo._setOpacity(this.navNode, 1);
 		
 		this.navPlay._size = dojo.marginBox(this.navPlay);
 		this.navPrev._size = dojo.marginBox(this.navPrev);
@@ -555,20 +554,20 @@ dojo.declare("dojox.image.SlideShow",
 	},
 
 	_setTitle: function(title){
-		// summary: 
+		// summary:
 		//		Sets the title to the image being displayed
 		// title: String
 		//		The String title of the image
 
-		this.titleNode.innerHTML = dojo.string.substitute(this.titleTemplate,{ 
-			title: title, 
-			current: 1 + this.imageIndex, 
+		this.titleNode.innerHTML = dojo.string.substitute(this.titleTemplate,{
+			title: title,
+			current: 1 + this.imageIndex,
 			total: this.maxPhotos || ""
 		});
 	},
 	
 	_fitImage: function(img) {
-		// summary: 
+		// summary:
 		//		Ensures that the image width and height do not exceed the maximum.
 		// img: Node
 		//		The image DOM node to optionally resize
@@ -625,7 +624,7 @@ dojo.declare("dojox.image.SlideShow",
 		}
 		if(this._navShowing){ return; }
 		this._navAnim = dojo.fadeIn({
-			node: this.navNode, 
+			node: this.navNode,
 			duration: 300,
 			onEnd: function(){ _this._navAnim = null; }
 		});
diff --git a/dojox/image/ThumbnailPicker.js b/dojox/image/ThumbnailPicker.js
index e16b2af..3682b42 100644
--- a/dojox/image/ThumbnailPicker.js
+++ b/dojox/image/ThumbnailPicker.js
@@ -1,15 +1,14 @@
 dojo.provide("dojox.image.ThumbnailPicker");
 dojo.experimental("dojox.image.ThumbnailPicker");
 //
-// dojox.image.ThumbnailPicker courtesy Shane O Sullivan, licensed under a Dojo CLA 
-// @author  Copyright 2007 Shane O Sullivan (shaneosullivan1 at gmail.com)
+// dojox.image.ThumbnailPicker courtesy Shane O Sullivan, licensed under a Dojo CLA
 //
 // For a sample usage, see http://www.skynet.ie/~sos/photos.php
 //
 //	document topics.
 
 dojo.require("dojox.fx.scroll"); // is optional, but don't want to dojo[require] it
-dojo.require("dojo.fx.easing"); 
+dojo.require("dojo.fx.easing");
 
 dojo.require("dojo.fx");
 dojo.require("dijit._Widget");
@@ -18,7 +17,7 @@ dojo.require("dijit._Templated");
 dojo.declare("dojox.image.ThumbnailPicker",
 	[dijit._Widget, dijit._Templated],
 	{
-	// summary: A scrolling Thumbnail Picker widget 
+	// summary: A scrolling Thumbnail Picker widget
 	//
 	// imageStore: Object
 	// A data store that implements the dojo.data Read API.
@@ -78,7 +77,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 	
 	// imageThumbAttr: String
 	// The attribute name for accessing the thumbnail image url from the data store
-	imageThumbAttr: "imageUrlThumb",	
+	imageThumbAttr: "imageUrlThumb",
 	
 	// imageLargeAttr: String
 	// The attribute name for accessing the large image url from the data store
@@ -92,7 +91,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 	// The attribute name for accessing the title from the data store
 	titleAttr: "title",
 	
-	templateString: dojo.cache("dojox.image", "resources/ThumbnailPicker.html"), 
+	templateString: dojo.cache("dojox.image", "resources/ThumbnailPicker.html"),
 	
 	// thumbs: Array
 	// Stores the image nodes for the thumbnails.
@@ -113,7 +112,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 
 	postCreate: function(){
 		// summary:
-		//		Initializes styles and listeners		
+		//		Initializes styles and listeners
 		this.widgetid = this.id;
 		this.inherited(arguments);
 		this.pageSize = Number(this.pageSize);
@@ -155,12 +154,12 @@ dojo.declare("dojox.image.ThumbnailPicker",
 
 	init: function(){
 		// summary:
-		//		Creates DOM nodes for thumbnail images and initializes their listeners 
+		//		Creates DOM nodes for thumbnail images and initializes their listeners
 		if(this.isInitialized) {return false;}
 	
 		var classExt = this.isHorizontal ? "Horiz" : "Vert";
 	
-		// FIXME: can we setup a listener around the whole element and determine based on e.target?	  
+		// FIXME: can we setup a listener around the whole element and determine based on e.target?
 		dojo.addClass(this.navPrev, "prev" + classExt);
 		dojo.addClass(this.navNext, "next" + classExt);
 		dojo.addClass(this.thumbsNode, "thumb"+classExt);
@@ -189,7 +188,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 	},
 
 	getClickTopicName: function(){
-		// summary: 
+		// summary:
 		//		Returns the name of the dojo topic that can be
 		//		subscribed to in order to receive notifications on
 		//		which thumbnail was selected.
@@ -232,7 +231,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 	
 		if(paramNames){
 			dojo.forEach(["imageThumbAttr", "imageLargeAttr", "linkAttr", "titleAttr"], function(attrName){
-				if(paramNames[attrName]){ this[attrName] = paramNames[attrName]; }	
+				if(paramNames[attrName]){ this[attrName] = paramNames[attrName]; }
 			}, this);
 		}
 		
@@ -268,7 +267,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		var scrollAttr = this.isHorizontal ? "scrollLeft" : "scrollTop";
 		var offset = img[pos] - this.thumbsNode[pos];
 		return (offset >= this.thumbScroller[scrollAttr]
-			&& offset + img[size] <= this.thumbScroller[scrollAttr] + this._scrollerSize);	
+			&& offset + img[size] <= this.thumbScroller[scrollAttr] + this._scrollerSize);
 	},
 	
 	resize: function(dim){
@@ -348,7 +347,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 	
 		this._thumbIndex = index;
 	
-		//If we have not already requested the data from the store, do so. 
+		//If we have not already requested the data from the store, do so.
 		if(this.thumbsNode.offsetWidth - img.offsetLeft < (this._scrollerSize * 2)){
 			this._loadNextPage();
 		}
@@ -397,11 +396,11 @@ dojo.declare("dojox.image.ThumbnailPicker",
 				this.thumbScroller.scrollTop = top;
 			}
 			this._checkLoad(img, index);
-		}	
+		}
 	},
 	
 	markImageLoaded: function(index){
-		// summary: 
+		// summary:
 		//		Changes a visual cue to show the image is loaded
 		// description:
 		//		If 'useLoadNotifier' is set to true, then a visual cue is
@@ -435,7 +434,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		
 		var store = this.imageStore;
 		
-		//Define the function to call when the items have been 
+		//Define the function to call when the items have been
 		//returned from the data store.
 		var complete = function(items, request){
 			if(store != this.imageStore){
@@ -455,16 +454,16 @@ dojo.declare("dojox.image.ThumbnailPicker",
 				});
 				loadNext();
 
-				//Show or hide the navigation arrows on the thumbnails, 
+				//Show or hide the navigation arrows on the thumbnails,
 				//depending on whether or not the widget is at the start,
-				//end, or middle of the list of images. 
+				//end, or middle of the list of images.
 				this._updateNavControls();
 			}else{
 				this._loadInProgress = false;
 			}
 		};
 	
-		//Define the function to call if the store reports an error. 
+		//Define the function to call if the store reports an error.
 		var error = function(){
 			this._loadInProgress = false;
 			console.log("Error getting items");
@@ -474,11 +473,11 @@ dojo.declare("dojox.image.ThumbnailPicker",
 		this.request.onError = dojo.hitch(this, error);
 	
 		//Increment the start parameter. This is the dojo.data API's
-		//version of paging. 
+		//version of paging.
 		this.request.start = start;
 		this._noImages = false;
 		
-		//Execute the request for data. 
+		//Execute the request for data.
 		this.imageStore.fetch(this.request);
 	
 	},
@@ -546,7 +545,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 			dojo.publish(this.getClickTopicName(),	[{
 				index: evt.target._index,
 				data: evt.target._data,
-				url: img.getAttribute("src"), 
+				url: img.getAttribute("src"),
 				largeUrl: this.imageStore.getValue(data,this.imageLargeAttr),
 				title: this.imageStore.getValue(data,this.titleAttr),
 				link: this.imageStore.getValue(data,this.linkAttr)
@@ -562,7 +561,7 @@ dojo.declare("dojox.image.ThumbnailPicker",
 	},
 
 	_updateNavControls: function(){
-		// summary: 
+		// summary:
 		//		Updates the navigation controls to hide/show them when at
 		//		the first or last images.
 		var cells = [];
diff --git a/dojox/image/_base.js b/dojox/image/_base.js
index 12a1961..5322cf7 100644
--- a/dojox/image/_base.js
+++ b/dojox/image/_base.js
@@ -1,6 +1,6 @@
 dojo.provide("dojox.image._base");
 
-// summary: Core Image-related functionality 
+// summary: Core Image-related functionality
 ;(function(d){
 	
 	var cacheNode;
@@ -9,7 +9,7 @@ dojo.provide("dojox.image._base");
 		//
 		// urls: Array
 		//		The list of urls to load. Can be any valid .src attribute.
-		//	
+		//
 		//	example:
 		//	Load two images into cache:
 		//	|	dojox.image.preload(["foo.png", "bar.gif"]);
@@ -18,12 +18,12 @@ dojo.provide("dojox.image._base");
 		//	Using djConfig:
 		//	|	var djConfig = {
 		//	|		preloadImages:["bar.png", "baz.png", "http://example.com/icon.gif"]
-		//	|	};	
+		//	|	};
 		//
 		// returns: Array
-		//		An Array of DomNodes that have been cached. 
+		//		An Array of DomNodes that have been cached.
 		
-		if(!cacheNode){ 
+		if(!cacheNode){
 			cacheNode = d.create("div", {
 				style:{ position:"absolute", top:"-9999px", height:"1px", overflow:"hidden" }
 			}, d.body());
@@ -55,39 +55,39 @@ dojo.provide("dojox.image._base");
 //		//
 //		// example:
 //		//	| new dojox.Image({ src:"foo.png", id:"bar" });
-//		
+//
 //		alt: "",
 //		src: dojo._blankGif,
 //		title: "",
-//		
+//
 //		onLoad: function(e){
 //			// summary: Stub fired when this image is really ready.
 //		},
-//		
+//
 //		_onLoad: function(e){
 //			// summary: private function to normalize `onLoad` for this
 //			//	instance.
 //			this.onLoad(e);
 //		},
-//		
+//
 //		_setSrcAttr: function(newSrc){
 //			// summary: Function so widget.attr('src', someUrl) works
-//			
+//
 //			var ts = this.domNode, os = td.src;
 //			if(os !== newSrc){
 //				td.src = newSrc;
 //			}
 //		},
-//		
+//
 //		/* Sugar Functions: */
-//		
+//
 //		crossFade: function(newSrc){
 //			// summary: Set this Image to a new src with crossfading
 //			//
 //			// example:
 //			//	dijit.byId("bar").crossFade("/images/newImage.png");
 //			//
-//			
+//
 //			d.fadeOut({
 //				node: this.domNode,
 //				onEnd: d.hitch(this, function(){
@@ -99,16 +99,16 @@ dojo.provide("dojox.image._base");
 //				})
 //			}).play();
 //		},
-//				
+//
 //		/* Overrides */
-//		
+//
 //		buildRendering: function(){
 //			// override buildrendering to create a real "img" instead of a div
 //			// when no srcNodeRef is passed. also wire up single onload.
 //			this.domNode = this.srcNodeRef || d.create('img');
 //			this.connect(this.domNode, "onload", "_onload");
 //		}
-//			
+//
 //	});
 		
 })(dojo);
\ No newline at end of file
diff --git a/dojox/image/resources/Lightbox.css b/dojox/image/resources/Lightbox.css
index d450340..22faf48 100644
--- a/dojox/image/resources/Lightbox.css
+++ b/dojox/image/resources/Lightbox.css
@@ -2,10 +2,21 @@
 /* dojox.image.Lightbox:base */
 /* FIXME: should be be doing this? I want a black underlay, but this sets ALL dialogs to black,
     but because it's decendant of body, i can't set this color any other way ... */
-.dijitDialogUnderlay {
+.tundra .dijitDialogUnderlay, 
+.nihilo .dijitDialogUnderlay,
+.soria .dijitDialogUnderlay {
 	background-color:#000; 
 }
 
+.claro .dojoxLightbox .dijitDialogCloseIconHover,
+.nihilo .dojoxLightbox .dijitDialogCloseIconHover,
+.tundra .dojoxLightbox .dijitDialogCloseIconHover, 
+.tundra .dojoxLightbox .dijitDialogCloseIconActive,
+.nihilo .dojoxLightbox .dijitDialogCloseIconActive,
+.claro .dojoxLightbox .dijitDialogCloseIconActive {
+    background:url('images/close.png') no-repeat 0 0;
+}
+
 /* more specific to override .theme .dijitDialog name. might try baseClass="dojoxLightbox" 
    but that would require additional overriden CSS on top of the original Dialog.css       */
 .claro .dojoxLightbox,
@@ -17,7 +28,7 @@
 	overflow:hidden;
 	width:100px;
 	height:100px; 
-	border:11px solid #fff;
+	border:11px solid #fff !important; /* not happy, but all themes overwrite this to 1px */
 	background:#fff url('images/loading.gif') no-repeat center center;
 
 	/* special safari + FF specific rounding + shadows */
@@ -29,7 +40,8 @@
 
 .dojoxLightboxContainer {
 	position:absolute;
-	top:0; left:0; 
+	top:0; left:0;
+	background-color:#fff;
 }
 
 .dojoxLightboxFooter {
@@ -59,26 +71,37 @@
 
 /* dojox.image.Lightbox:tundra:nihilo */
 
+.claro .LightboxClose,
 .nihilo .LightboxClose,
 .tundra .LightboxClose {
 	background:url('images/close.png') no-repeat center center;
 }
+
+.di_ie6 .claro .LightboxClose,
 .di_ie6 .nihilo .LightboxClose,
 .dj_ie6 .tundra .LightboxClose {
 	background:url('images/close.gif') no-repeat center center;
 }
+
+.claro .LightboxNext, 
 .nihilo .LightboxNext,
 .tundra .LightboxNext {
 	background:url('images/right.png') no-repeat center center;
 }
+
+.dj_ie6 .claro .LightboxNext,
 .dj_ie6 .nihilo .LightboxNext,
 .dj_ie6 .tundra .LightboxNext {
 	background:url('images/right.gif') no-repeat center center;
 }
+
+.claro .LightboxPrev,
 .nihilo .LightboxPrev,
 .tundra .LightboxPrev {
 	background:url('images/left.png') no-repeat center center;
 }
+
+.dj_ie6 .claro .LightboxPrev,
 .dj_ie6 .nihilo .LightboxPrev,
 .dj_ie6 .tundra .LightboxPrev {
 	background:url('images/left.gif') no-repeat center center;
diff --git a/dojox/image/tests/images/supertall.gif b/dojox/image/tests/images/supertall.gif
new file mode 100644
index 0000000..f33b3b9
Binary files /dev/null and b/dojox/image/tests/images/supertall.gif differ
diff --git a/dojox/image/tests/images/superwide.gif b/dojox/image/tests/images/superwide.gif
new file mode 100644
index 0000000..cdf1340
Binary files /dev/null and b/dojox/image/tests/images/superwide.gif differ
diff --git a/dojox/image/tests/test_Lightbox.html b/dojox/image/tests/test_Lightbox.html
index 79fe083..bbcd34c 100644
--- a/dojox/image/tests/test_Lightbox.html
+++ b/dojox/image/tests/test_Lightbox.html
@@ -1,11 +1,11 @@
 <!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.image.Lightbox Tests | The Dojo Toolkit</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">
 	<link rel="stylesheet" href="../resources/image.css">
 	
 	<style type="text/css">
@@ -139,27 +139,23 @@
 				e.preventDefault();
 				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){
-				dojo.forEach(items,function(item){
+			if(items.length > 0){
+				var lightbox = dijit.byId("fromStore");
+				dojo.forEach(items, function(item){
 					var part = {
 						title: flickrStore.getValue(item,"title"),
 						href: flickrStore.getValue(item,"imageUrl")
 					};
-					// FIXME: make addImage more accessible, or do this internally
-					// _attachedDialog is dijit.byId("dojoxLightboxDialog"), and the
-					// is only one per page.
-					dijit.byId('fromStore')._attachedDialog.addImage(part,"flickrStore");
-				});
-				dojo.byId('flickrButton').disabled = false; 
+					this.addImage(part, "flickrStore");
+				}, lightbox);
+				dijit.byId('flickrButton').set("disabled", false); 
 			}
 		}
 
@@ -183,7 +179,7 @@
 
 
 </head>
-<body class="tundra">
+<body class="claro">
 
 	<div id="container" style="padding:20px;">
 		<h1 class="testTitle">a Dojo based Lightbox implementation:</h1>
@@ -193,8 +189,13 @@
 			<a href="images/imageVert.jpg" dojoType="dojox.image.Lightbox" title="More Guatemala...">tall</a>
 			<a href="images/imageHoriz.jpg" dojoType="dojox.image.Lightbox" title="Antigua, Guatemala">4:3 image</a>
 			<a href="images/broken.jpg" dojoType="dojox.image.Lightbox" title="broken href example">Broken link</a>
+		</p>
+
+		<h3>Oversized</h3>
+		<p>
+			<a href="images/supertall.gif" dojoType="dojox.image.Lightbox" title="a large image">super tall image</a>
+			<a href="images/superwide.gif" dojoType="dojox.image.Lightbox" title="a large image">super wide image</a>
 			<a href="images/huuuge.png" modal="true" dojoType="dojox.image.Lightbox" title="a large image">large than viewport?</a> (also modal, no click on underlay)
-			
 			<a href="images/huuuge.png" dojoType="dojox.image.Lightbox" title="a large image with a really really long multi-line-title because I can. Okay, this title has to be really really supremely long in order to occupy the full width of the viewport provided. yymv.">large than viewport, long title</a>
 		</p>
 
@@ -221,16 +222,21 @@
 			<a href="images/imageHoriz.jpg" dojoType="dojox.image.Lightbox" group="group3" title="Antigua, Guatemala">4:3 image</a>
 			<a href="images/imageVert.jpg" dojoType="dojox.image.Lightbox" group="group3" title="More Guatemala...">tall</a>
 		</p>
-        <p>
-                <a href='#' id="groupremover">remove one from group3, then show group</a> | <a href="#" id="groupkiller">remove group3</a>
-        </p>
+		<p>
+				<a href='#' id="groupremover">remove one from group3, then show group</a> | <a href="#" id="groupkiller">remove group3</a>
+		</p>
 
 		<h3>From dojox.data.FlickrStore:</h3>
 
 		<div dojoType="dojox.data.FlickrStore" jsId="flickrStore" label="title"></div>
-		<div id="fromStore" dojoType="dojox.image.Lightbox" store="flickrStore" group="flickrStore"></div>
-
-		<input id="flickrButton" type="button" onclick="dijit.byId('fromStore').show()" value="show flickr lightbox" disabled="disabled">
+		<div id="fromStore" dojoType="dojox.image.LightboxDialog" store="flickrStore" group="flickrStore"></div>
+
+		<button dojoType="dijit.form.Button" id="flickrButton" disabled="disabled">
+			Show Flickr lightbox
+			<script type="dojo/connect" event="onClick">
+				dijit.byId('fromStore').show({ group:"flickrStore" });
+			</script>
+		</button>
 	
 	</div>
 
diff --git a/dojox/io/OAuth.js b/dojox/io/OAuth.js
index a1e5e10..ebad428 100644
--- a/dojox/io/OAuth.js
+++ b/dojox/io/OAuth.js
@@ -10,7 +10,7 @@ dojox.io.OAuth = new (function(){
 	//		methods (such as dojo.xhr[verb], dojo.io.iframe, etc.).
 	//
 	//		The main method of dojox.io.OAuth is the sign method (see documentation for .sign);
-	//		the idea is that you will "sign" the kwArgs object you'd normally pass to any of 
+	//		the idea is that you will "sign" the kwArgs object you'd normally pass to any of
 	//		the Ajax methods, and then pass the signed object along.  As long as the token
 	//		object used is valid (and the client's date and time are synced with a public
 	//		time server), a signed object should be passed along correctly.
@@ -108,8 +108,8 @@ dojox.io.OAuth = new (function(){
 	function key(args){
 		//	summary:
 		//		return the key used to sign a message based on the token object.
-		return encode(args.consumer.secret) 
-			+ "&" 
+		return encode(args.consumer.secret)
+			+ "&"
 			+ (args.token && args.token.secret ? encode(args.token.secret) : "");
 	}
 
@@ -150,7 +150,7 @@ dojox.io.OAuth = new (function(){
 
 		//	pull anything off the query string
 		var map = parseUrl(args.url);
-		if(map.query){ 
+		if(map.query){
 			var tmp = dojo.queryToObject(map.query);
 			//	re-encode the values.  sigh
 			for(var p in tmp){ tmp[p] = encodeURIComponent(tmp[p]); }
@@ -200,7 +200,7 @@ dojox.io.OAuth = new (function(){
 		}).join("&");
 
 		var baseString = method.toUpperCase()
-			+ "&" + encode(args._url) 
+			+ "&" + encode(args._url)
 			+ "&" + encode(s);
 		return baseString;
 	}
@@ -236,7 +236,7 @@ dojox.io.OAuth = new (function(){
 		}
 	=====*/
 
-	/*	
+	/*
 	 *	Process goes something like this:
 	 *	1. prepare the base string
 	 *	2. create the key
@@ -268,10 +268,10 @@ dojox.io.OAuth = new (function(){
 		/*	summary:
 		 *		Make an XHR request that is OAuth signed.
 		 *	example:
-		 *	|	var dfd = dojox.io.OAuth.xhrGet({ 
+		 *	|	var dfd = dojox.io.OAuth.xhrGet({
 		 *	|		url: "http://someauthdomain.com/path?foo=bar",
-		 *	|		load: function(response, ioArgs){ } 
-		 *	|	}, 
+		 *	|		load: function(response, ioArgs){ }
+		 *	|	},
 		 *	|	{
 		 *	|		consumer:{ key: "lasdkf9asdnfsdf", secret: "9asdnfskdfysjr" }
 		 *	|	});
diff --git a/dojox/io/httpParse.js b/dojox/io/httpParse.js
index fe90113..0b3fd2a 100644
--- a/dojox/io/httpParse.js
+++ b/dojox/io/httpParse.js
@@ -3,22 +3,22 @@ dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Bool
 	// summary:
 	//		Parses an HTTP stream for a message.
 	// httpStream:
-	// 		HTTP stream to parse 
+	// 		HTTP stream to parse
 	// topHeaders:
 	//		Extra header information to add to each HTTP request (kind of HTTP inheritance)
 	// partial:
 	//		A true value indicates that the stream may not be finished, it may end arbitrarily in mid stream.
-	//		The last XHR object will have a special property _lastIndex that indicates the how far along 
+	//		The last XHR object will have a special property _lastIndex that indicates the how far along
 	// 		the httpStream could be successfully parsed into HTTP messages.
 	// return:
 	// 		Returns an array of XHR-like object for reading the headers for each message
-	//		 
+	//
 	var xhrs=[];
 	var streamLength = httpStream.length;
 	do{
 		var headers = {};
 		var httpParts = httpStream.match(/(\n*[^\n]+)/);
-		if(!httpParts){ 
+		if(!httpParts){
 			return null;
 		}
 		httpStream = httpStream.substring(httpParts[0].length+1);
@@ -34,22 +34,22 @@ dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Bool
 		for(var j = 0; j < headerParts.length; j++){
 			var colonIndex = headerParts[j].indexOf(':');
 			headers[headerParts[j].substring(0,colonIndex)] = headerParts[j].substring(colonIndex+1).replace(/(^[ \r\n]*)|([ \r\n]*)$/g,''); // trim
-		}										
+		}
 	
 		httpParts = httpParts.split(' ');
 		var xhr = { // make it look like an xhr object, at least for the response part of the API
 			status : parseInt(httpParts[1],10),
 			statusText : httpParts[2],
 			readyState : 3, // leave it at 3 until we get a full body
-			getAllResponseHeaders : function(){ 
+			getAllResponseHeaders : function(){
 				return headerStr;
 			},
 			getResponseHeader : function(name){
 				return headers[name];
 			}
-		}; 
+		};
 		var contentLength = headers['Content-Length'];
-		var content; 
+		var content;
 		if(contentLength){
 			if(contentLength <= httpStream.length){
 				content = httpStream.substring(0,contentLength);
@@ -69,7 +69,7 @@ dojox.io.httpParse = function(/*String*/httpStream, /*String?*/topHeaders,/*Bool
 		httpStream = httpStream.substring(content.length); // move along the stream
 		xhr.responseText = content;
 		xhr.readyState = 4;
-		xhr._lastIndex = streamLength - httpStream.length; // need to pick up from where we left on streaming connections 
+		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
diff --git a/dojox/io/proxy/xip.js b/dojox/io/proxy/xip.js
index 36af9f0..10fb54c 100644
--- a/dojox/io/proxy/xip.js
+++ b/dojox/io/proxy/xip.js
@@ -95,7 +95,7 @@ dojox.io.proxy.xip = {
 		var stateId = "XhrIframeProxy" + (this._stateIdCounter++);
 		facade._stateId = stateId;
 
-		var frameUrl = facade._ifpServerUrl + "#0:init:id=" + stateId + "&client=" 
+		var frameUrl = facade._ifpServerUrl + "#0:init:id=" + stateId + "&client="
 			+ encodeURIComponent(this.fullXipClientUrl) + "&callback=" + encodeURIComponent(this._callbackName);
 
 		this._state[stateId] = {
@@ -173,7 +173,7 @@ dojox.io.proxy.xip = {
 			uri: facade._uri
 		};
 		if(reqHeaders.length > 0){
-			requestData.requestHeaders = reqHeaders.join("\r\n");		
+			requestData.requestHeaders = reqHeaders.join("\r\n");
 		}
 		if(facade._method){
 			requestData.method = facade._method;
@@ -326,7 +326,7 @@ dojox.io.proxy.xip = {
 				this.setServerUrl(stateId, "ok");
 				break;
 			case "part":
-				state.responseMessage += msg.message;			
+				state.responseMessage += msg.message;
 				this.setServerUrl(stateId, "ok");
 				break;
 			case "end":
diff --git a/dojox/io/proxy/xip_client.html b/dojox/io/proxy/xip_client.html
index ff4e19b..7dcc566 100644
--- a/dojox/io/proxy/xip_client.html
+++ b/dojox/io/proxy/xip_client.html
@@ -1,6 +1,6 @@
 <!--
 	/*
-		Copyright (c) 2004-2010, The Dojo Foundation
+		Copyright (c) 2004-2011, The Dojo Foundation
 		All Rights Reserved.
 	
 		Licensed under the Academic Free License version 2.1 or above OR the
diff --git a/dojox/io/proxy/xip_server.html b/dojox/io/proxy/xip_server.html
index e55149d..90be252 100644
--- a/dojox/io/proxy/xip_server.html
+++ b/dojox/io/proxy/xip_server.html
@@ -1,6 +1,6 @@
 <!--
 	/*
-		Copyright (c) 2004-2010, The Dojo Foundation
+		Copyright (c) 2004-2011, The Dojo Foundation
 		All Rights Reserved.
 	
 		Licensed under the Academic Free License version 2.1 or above OR the
diff --git a/dojox/io/scriptFrame.js b/dojox/io/scriptFrame.js
index 0d197f2..5ed04dd 100644
--- a/dojox/io/scriptFrame.js
+++ b/dojox/io/scriptFrame.js
@@ -27,7 +27,7 @@ dojo.require("dojo.io.iframe");
 		},
 
 		_fixAttachUrl: function(/*String*/url){
-			//summary: fixes the URL so that 		
+			//summary: fixes the URL so that
 		},
 
 		_loaded: function(/*String*/frameId){
diff --git a/dojox/io/tests/windowName.html b/dojox/io/tests/windowName.html
index 762213d..680d01c 100644
--- a/dojox/io/tests/windowName.html
+++ b/dojox/io/tests/windowName.html
@@ -15,7 +15,7 @@ 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/37"),
+						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(){
diff --git a/dojox/io/tests/windowName.js b/dojox/io/tests/windowName.js
index 39d3250..5e5b337 100644
--- a/dojox/io/tests/windowName.js
+++ b/dojox/io/tests/windowName.js
@@ -17,8 +17,8 @@ doh.register("dojox.io.tests.xhrPlugins", [
 	},
 
 	function crossSiteRequest(t){
-		// Note: this isn't really testing much unless you are using IE8 (XDomainRequest) or a 
-		// browser that supports cross-site XHR (maybe FF3.1?) 
+		// Note: this isn't really testing much unless you are using IE8 (XDomainRequest) or a
+		// browser that supports cross-site XHR (maybe FF3.1?)
 		var d = new doh.Deferred();
 		// persevere supports both XDR and cross-site XHR so we can use it for cross-site testing for now
 		dojox.io.xhrPlugins.addXdr("http://persevere.sitepen.com/");
@@ -33,9 +33,9 @@ doh.register("dojox.io.tests.xhrPlugins", [
 			throw e;
 		}
 		dfd.addCallback(function(result){
-			d.callback(result.match(/transport/)); 
+			d.callback(result.match(/transport/));
 		});
-		// TODO: This should run off a fixed URL on some Dojo server.  
+		// 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/...");
diff --git a/dojox/io/tests/xhrPlugins.js b/dojox/io/tests/xhrPlugins.js
index 1ee086a..991a63c 100644
--- a/dojox/io/tests/xhrPlugins.js
+++ b/dojox/io/tests/xhrPlugins.js
@@ -17,8 +17,8 @@ doh.register("dojox.io.tests.xhrPlugins", [
 	},
 
 	function crossSiteRequest(t){
-		// Note: this isn't really testing much unless you are using IE8 (XDomainRequest) or a 
-		// browser that supports cross-site XHR (maybe FF3.1?) 
+		// Note: this isn't really testing much unless you are using IE8 (XDomainRequest) or a
+		// 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/");
@@ -32,9 +32,9 @@ doh.register("dojox.io.tests.xhrPlugins", [
 			throw e;
 		}
 		dfd.addCallback(function(result){
-			d.callback(result.match(/transport/)); 
+			d.callback(result.match(/transport/));
 		});
-		// TODO: This should run off a fixed URL on some Dojo server.  
+		// 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/...");
diff --git a/dojox/io/windowName.js b/dojox/io/windowName.js
index 5e63dbc..401ef0f 100644
--- a/dojox/io/windowName.js
+++ b/dojox/io/windowName.js
@@ -1,11 +1,11 @@
 dojo.provide("dojox.io.windowName");
-// Implements the window.name transport  
+// Implements the window.name transport
 
 dojox.io.windowName = {
 	send: function(/*String*/ method, /*dojo.__IoArgs*/ args){
 		// summary:
 		//		Provides secure cross-domain request capability.
-		// 		Sends a request using an iframe (POST or GET) and reads the response through the 
+		// 		Sends a request using an iframe (POST or GET) and reads the response through the
 		// 		frame's window.name.
 		//
 		//	method:
@@ -15,7 +15,7 @@ dojox.io.windowName = {
 		//		See dojo.xhr
 		//
 		//	args.authElement: DOMNode?
-		//		By providing an authElement, this indicates that windowName should use the 
+		//		By providing an authElement, this indicates that windowName should use the
 		// 		authorized window.name protocol, relying on
 		//		the loaded XD resource to return to the provided return URL on completion
 		//		of authorization/authentication. The provided authElement will be used to place
@@ -28,13 +28,13 @@ dojox.io.windowName = {
 		// 		the deferred callback function is called with the result). The primary use for this
 		// 		is to make the authElement visible to the user once the resource has loaded
 		// 		(this can be preferable to showing the iframe while the resource is loading
-		// 		since it may not require authorization, it may simply return the resource). 
-		//  
+		// 		since it may not require authorization, it may simply return the resource).
+		//
 		//	description:
 		//		In order to provide a windowname transport accessible resources/web services, a server
 		// 		should check for the presence of a parameter window.name=true and if a request includes
-		// 		such a parameter, it should respond to the request with an HTML 
-		// 		document that sets it's window.name to the string that is to be 
+		// 		such a parameter, it should respond to the request with an HTML
+		// 		document that sets it's window.name to the string that is to be
 		// 		delivered to the client. For example, if a client makes a window.name request like:
 		// 	|	http://othersite.com/greeting?windowname=true
 		// 		And server wants to respond to the client with "Hello", it should return an html page:
@@ -49,18 +49,18 @@ dojox.io.windowName = {
 		// 		And the server can respond like this:
 		// |	<html><script type="text/javascript">
 		// |	var loc = window.name;
-		// |	authorizationButton.onclick = function(){	
+		// |	authorizationButton.onclick = function(){
 		// |		window.name="Hello";
 		// |		location = loc;
 		// |	};
 		// |	</script></html>
-		//		When using windowName from a XD Dojo build, make sure to set the 
+		//		When using windowName from a XD Dojo build, make sure to set the
 		// 		dojo.dojoBlankHtmlUrl property to a local URL.
 		args.url += (args.url.match(/\?/) ? '&' : '?') + "windowname=" + (args.authElement ? "auth" : true); // indicate our desire for window.name communication
 		var authElement = args.authElement;
 		var cleanup = function(result){
 			try{
-				// we have to do this to stop the wait cursor in FF 
+				// we have to do this to stop the wait cursor in FF
 				var innerDoc = dfd.ioArgs.frame.contentWindow.document;
 				innerDoc.write(" ");
 				innerDoc.close();
@@ -117,7 +117,7 @@ dojox.io.windowName = {
 			doc = firstWindow.document;
 			doc.write("<html><body margin='0px'><iframe style='width:100%;height:100%;border:0px' name='protectedFrame'></iframe></body></html>");
 			doc.close();
-			var secondWindow = firstWindow[0]; 
+			var secondWindow = firstWindow[0];
 			firstWindow.__defineGetter__(0,function(){});
 			firstWindow.__defineGetter__("protectedFrame",function(){});
 			doc = secondWindow.document;
@@ -125,8 +125,15 @@ dojox.io.windowName = {
 			doc.close();
 			frameContainer = doc.body;
 		}
-
-		var frame = ioArgs.frame = frame = doc.createElement(dojo.isIE ? '<iframe name="' + frameName + '" onload="dojox.io.windowName['+frameNum+']()">' : 'iframe');
+		var frame;
+		if(dojo.isIE){
+			var div = doc.createElement("div");
+			div.innerHTML = '<iframe name="' + frameName + '" onload="dojox.io.windowName['+frameNum+']()">';
+			frame = div.firstChild;
+		}else{
+			frame = doc.createElement('iframe');
+		}
+		ioArgs.frame = frame;
 		styleFrame(frame);
 		ioArgs.outerFrame = outerFrame = outerFrame || frame;
 		if(!authTarget){
@@ -150,7 +157,7 @@ dojox.io.windowName = {
 					return;
 				}
 			}catch(e){
-				// if we are in the target domain, frame.contentWindow.location will throw an ignorable error 
+				// if we are in the target domain, frame.contentWindow.location will throw an ignorable error
 			}
 			if(!state){
 				// we have loaded the target resource, now time to navigate back to our domain so we can read the frame name
@@ -215,6 +222,6 @@ dojox.io.windowName = {
 			frame.contentWindow.name = frameName; // IE likes it afterwards
 		}
 	},
-	_frameNum: 0 
+	_frameNum: 0
 	
 }
diff --git a/dojox/io/xhrMultiPart.js b/dojox/io/xhrMultiPart.js
index b524118..157d8f9 100644
--- a/dojox/io/xhrMultiPart.js
+++ b/dojox/io/xhrMultiPart.js
@@ -101,7 +101,7 @@ dojo.require("dojox.uuid.generateRandomUuid");
 		//	error: Function?
 		//		function(response, ioArgs){}. response is an Object, ioArgs
 		//		is of type dojo.__IoCallbackArgs. The error function will
-		//		be called in an error case. 
+		//		be called in an error case.
 		//	handle: Function?
 		//		function(response, ioArgs){}. response is an Object, ioArgs
 		//		is of type dojo.__IoCallbackArgs. The handle function will
diff --git a/dojox/io/xhrPlugins.js b/dojox/io/xhrPlugins.js
index 9fb9883..2de3f57 100644
--- a/dojox/io/xhrPlugins.js
+++ b/dojox/io/xhrPlugins.js
@@ -17,11 +17,11 @@ dojo.require("dojo._base.xhr");
 			registry = new dojo.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);						
+				return registry.match.apply(registry,arguments);
 			};
 			registry.register(
 				"xhr",
-				function(method,args){ 
+				function(method,args){
 					if(!args.url.match(/^\w*:\/\//)){
 						// if it is not an absolute url (or relative to the
 						// protocol) we can use this plain XHR
@@ -54,8 +54,8 @@ dojo.require("dojo._base.xhr");
 				// this will match on URL
 
 				// really can be used for anything, but plain XHR will take
-				// precedent by order of loading 
-				return true; 
+				// precedent by order of loading
+				return true;
 			},
 			function(method,args,hasBody){
 				args.url = proxyUrl + encodeURIComponent(args.url);
@@ -67,16 +67,16 @@ dojo.require("dojo._base.xhr");
 		//	summary:
 		// 		Adds W3C Cross site XHR or XDomainRequest handling for the given URL prefix
 		//
-		// 	url: 
-		//		Requests that start with this URL will be considered for using 
+		// 	url:
+		//		Requests that start with this URL will be considered for using
 		// 		cross-site XHR.
 		//
-		// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be 
+		// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be
 		// 		sent with XDR, so you can use a convention for headers and PUT/DELETE methods.
 		//
 		//	description:
-		// 		This can be used for servers that support W3C cross-site XHR. In order for 
-		// 		a server to allow a client to make cross-site XHR requests, 
+		// 		This can be used for servers that support W3C cross-site XHR. In order for
+		// 		a server to allow a client to make cross-site XHR requests,
 		// 		it should respond with the header like:
 		//	|	Access-Control: allow <*>
 		//		see: http://www.w3.org/TR/access-control/
@@ -94,11 +94,11 @@ dojo.require("dojo._base.xhr");
 		}
 		dojox.io.xhrPlugins.register(
 			"cs-xhr",
-			function(method,args){ 
-				return (csXhrSupport || 
-						(window.XDomainRequest && args.sync !== true && 
+			function(method,args){
+				return (csXhrSupport ||
+						(window.XDomainRequest && args.sync !== true &&
 							(method == "GET" || method == "POST" || httpAdapter))) &&
-					(args.url.substring(0,url.length) == url); 
+					(args.url.substring(0,url.length) == url);
 			},
 			csXhrSupport ? plainXhr : function(){
 				var normalXhrObj = dojo._xhrObj;
@@ -108,12 +108,12 @@ dojo.require("dojo._base.xhr");
 					var xdr = new XDomainRequest();
 					xdr.readyState = 1;
 					xdr.setRequestHeader = function(){}; // just absorb them, we can't set headers :/
-					xdr.getResponseHeader = function(header){ // this is the only header we can access 
+					xdr.getResponseHeader = function(header){ // this is the only header we can access
 						return header == "Content-Type" ? xdr.contentType : null;
 					}
 					// adapt the xdr handlers to xhr
 					function handler(status, readyState){
-						return function(){							
+						return function(){
 							xdr.readyState = readyState;
 							xdr.status = status;
 						}
@@ -125,7 +125,7 @@ dojo.require("dojo._base.xhr");
 				};
 				var dfd = (httpAdapter ? httpAdapter(getPlainXhr()) : getPlainXhr()).apply(dojo,arguments);
 				dojo._xhrObj = normalXhrObj;
-				return dfd; 
+				return dfd;
 			}
 		);
 	};
diff --git a/dojox/io/xhrScriptPlugin.js b/dojox/io/xhrScriptPlugin.js
index e955b26..fe3eb81 100644
--- a/dojox/io/xhrScriptPlugin.js
+++ b/dojox/io/xhrScriptPlugin.js
@@ -11,13 +11,13 @@ dojox.io.xhrScriptPlugin = function(/*String*/url, /*String*/callbackParamName,
 	//		the site has full access to your JavaScript environment.
 	//	url:
 	//		Url prefix of the site which can handle JSONP requests.
-	// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be 
+	// 	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(
 		"script",
 		function(method,args){
-			 return args.sync !== true && 
-				(method == "GET" || httpAdapter) && 
+			 return args.sync !== true &&
+				(method == "GET" || httpAdapter) &&
 				(args.url.substring(0,url.length) == url);
 		},
 		function(method,args,hasBody){
diff --git a/dojox/io/xhrWindowNamePlugin.js b/dojox/io/xhrWindowNamePlugin.js
index 148115f..c8b1c27 100644
--- a/dojox/io/xhrWindowNamePlugin.js
+++ b/dojox/io/xhrWindowNamePlugin.js
@@ -10,19 +10,19 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 	//		dojox.io.windowName for more information on the transport.
 	//	url:
 	//		Url prefix of the site which can handle windowName requests.
-	// 	httpAdapter: This allows for adapting HTTP requests that could not otherwise be 
+	// 	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(
 		"windowName",
 		function(method,args){
-			 return args.sync !== true && 
-				(method == "GET" || method == "POST" || httpAdapter) && 
+			 return args.sync !== true &&
+				(method == "GET" || method == "POST" || httpAdapter) &&
 				(args.url.substring(0,url.length) == url);
 		},
 		function(method,args,hasBody){
 			var send = dojox.io.windowName.send;
-			var load = args.load; 
-			args.load = undefined; //we don't want send to set this callback 
+			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
 			dfd.addCallback(function(result){
 				var ioArgs = dfd.ioArgs;
@@ -38,13 +38,13 @@ dojox.io.xhrWindowNamePlugin = function(/*String*/url, /*Function?*/httpAdapter,
 					if(!trusted){
 						dojox.secure.capability.validate(result,["Date"],{});
 					}
-					return dojo.fromJson(result); 
+					return dojo.fromJson(result);
 				}
-				return dojo._contentHandlers[ioArgs.handleAs || "text"]({responseText:result}); 
+				return dojo._contentHandlers[ioArgs.handleAs || "text"]({responseText:result});
 			});
-			args.load = load; 
-			if(load){ 
- 				dfd.addCallback(load); 
+			args.load = load;
+			if(load){
+ 				dfd.addCallback(load);
  			}
 			return dfd;
 		}
diff --git a/dojox/jq.js b/dojox/jq.js
index f04d303..4e22bc3 100644
--- a/dojox/jq.js
+++ b/dojox/jq.js
@@ -6,7 +6,7 @@ dojo.require("dojo.NodeList-manipulate");
 dojo.require("dojo.io.script");
 
 /*
-To get jquery tests to pass: 
+To get jquery tests to pass:
 - add spaces between span>form selectors, other ones like one,two
 - .last() instead of :last
 - $("<div>").find("#foo") does not work unless the div is attached to the body.
@@ -140,7 +140,7 @@ dojo.query differences that cause some tests to fail:
 			$.ready(arg);
 			return $;
 		}else if(arg == document || arg == window){
-			//If the arg is the document or window, 
+			//If the arg is the document or window,
 			//then just use it directly.
 			return $._wrap([arg], null, $);
 		}else if(dojo.isArray(arg)){
@@ -324,7 +324,7 @@ dojo.query differences that cause some tests to fail:
 				if(cb.call(list[param], param, list[param]) === false){
 					break;
 				}
-			}		
+			}
 		}
 		return this;
 	};
@@ -496,7 +496,7 @@ dojo.query differences that cause some tests to fail:
 				}
 			}
 		}
-		return finalObj;		
+		return finalObj;
 	}
 
 	$.noConflict = function(/*Boolean*/extreme){
@@ -666,7 +666,7 @@ dojo.query differences that cause some tests to fail:
 	$.map = function(/*Array*/ary, /*Function*/callback){
 		//Hmm, this is not like array map/dojo.map where you get one item back for
 		//each input.
-		return f._buildArrayFromCallback.call(ary, callback);		
+		return f._buildArrayFromCallback.call(ary, callback);
 	}
 
 	$.inArray = function(value, /*Array*/ary){
@@ -698,7 +698,7 @@ dojo.query differences that cause some tests to fail:
 		var doc = iframeNode.contentDocument || // W3
 			(
 				(
-					(iframeNode.name) && (iframeNode.document) && 
+					(iframeNode.name) && (iframeNode.document) &&
 					(document.getElementsByTagName("iframe")[iframeNode.name].contentWindow) &&
 					(document.getElementsByTagName("iframe")[iframeNode.name].contentWindow.document)
 				)
@@ -769,7 +769,7 @@ dojo.query differences that cause some tests to fail:
 	}
 
 	//START jquery CSS API methods
-	//http://docs.jquery.com/CSS	
+	//http://docs.jquery.com/CSS
 	$.css = function(/*DOMNode*/node, /*String|Object*/name, /*String|Number?*/value){
 		name = cssNameToJs(name);
 		
@@ -828,7 +828,7 @@ dojo.query differences that cause some tests to fail:
 			//Just get first node's height.
 			//Hmm. width is negative when element is display none in FF3?
 			return Math.abs(Math.round(dojo[boxType](nl[0])[prop]));
-		}	
+		}
 	}
 
 	f.height = function(value){
@@ -1001,7 +1001,7 @@ dojo.query differences that cause some tests to fail:
 
 		var nodeId = node.getAttribute(eventAttr);
 		if(!nodeId){
-			return;		
+			return;
 		}
 
 		var evt = data[0];
@@ -1055,7 +1055,7 @@ dojo.query differences that cause some tests to fail:
 	}
 
 	f.trigger = function(/*String*/type, /*Array?*/data, /*Function?*/extraFunc){
-		//Copy data since we may need to modify by adding a 
+		//Copy data since we may need to modify by adding a
 		data = makeTriggerData(data, type);
 		var evt = data[0];
 		var type = getNonNamespacedName(evt.type);
@@ -1183,7 +1183,7 @@ dojo.query differences that cause some tests to fail:
 					}
 	
 					//Get the event listeners for the event name, the complete name.
-					var lls = listeners[nodeId];		
+					var lls = listeners[nodeId];
 					if(!lls[evtName]){
 						lls[evtName] = {
 							_connectId: domConnect(node, evtName)
@@ -1261,7 +1261,7 @@ dojo.query differences that cause some tests to fail:
 						if(param.indexOf(evtFullName) == param.length - evtFullName.length){
 							delete handles[param];
 						}
-					}				
+					}
 				}else{
 					delete handles[evtFullName];
 				}
@@ -1511,7 +1511,7 @@ dojo.query differences that cause some tests to fail:
 					speed,
 					null,
 					callback ? dojo.hitch(node, callback) : undefined
-				);				
+				);
 			}else{
 				dojo.style(node, "display", "block");
 				if(callback){
@@ -1630,7 +1630,7 @@ dojo.query differences that cause some tests to fail:
 						data[param] = data[param]();
 					}
 				}
-				args.content = data;	
+				args.content = data;
 			}
 		}
 
@@ -1706,7 +1706,7 @@ dojo.query differences that cause some tests to fail:
 				}
 				if(location.protocol != url.substring(0, colonIndex + 1) ||
 					location.hostname != url.substring(slashIndex + 2, lastSlash)){
-					useScript = true;	
+					useScript = true;
 				}
 			}
 		}
diff --git a/dojox/json/query.js b/dojox/json/query.js
index 6b7ee19..047d4f9 100644
--- a/dojox/json/query.js
+++ b/dojox/json/query.js
@@ -40,9 +40,9 @@ dojo.provide("dojox.json.query");
 		if(name instanceof Array){
 			// this is called when multiple items are in the brackets: [3,4,5]
 			if(name.length==1){
-				// this can happen as a result of the parser becoming confused about commas 
-				// in the brackets like [@.func(4,2)]. Fixing the parser would require recursive 
-				// analsys, very expensive, but this fixes the problem nicely. 
+				// this can happen as a result of the parser becoming confused about commas
+				// in the brackets like [@.func(4,2)]. Fixing the parser would require recursive
+				// analsys, very expensive, but this fixes the problem nicely.
 				return obj[name[0]];
 			}
 			for(var i = 0; i < name.length; i++){
@@ -69,7 +69,7 @@ dojo.provide("dojox.json.query");
 						outArr.push(value);
 					}
 				}else if(!primitives[value + typeof value]){
-					// with primitives we prevent duplicates by putting it in a map 
+					// with primitives we prevent duplicates by putting it in a map
 					primitives[value + typeof value] = true;
 					outArr.push(value);
 				}
@@ -85,7 +85,7 @@ dojo.provide("dojox.json.query");
 	}
 	dojox.json.query = function(/*String*/query,/*Object?*/obj){
 		// summary:
-		// 		Performs a JSONQuery on the provided object and returns the results. 
+		// 		Performs a JSONQuery on the provided object and returns the results.
 		// 		If no object is provided (just a query), it returns a "compiled" function that evaluates objects
 		// 		according to the provided query.
 		// query:
@@ -103,23 +103,23 @@ dojo.provide("dojox.json.query");
 		//		JSONQuery evaluations begin with the provided object, which can referenced with
 		// 		$. From
 		// 		the starting object, various operators can be successively applied, each operating
-		// 		on the result of the last operation. 
+		// 		on the result of the last operation.
 		//
 		// 		Supported Operators:
 		// 		--------------------
-		//		* .property - This will return the provided property of the object, behaving exactly 
-		// 		like JavaScript. 
-		// 		* [expression] - This returns the property name/index defined by the evaluation of 
+		//		* .property - This will return the provided property of the object, behaving exactly
+		// 		like JavaScript.
+		// 		* [expression] - This returns the property name/index defined by the evaluation of
 		// 		the provided expression, behaving exactly like JavaScript.
 		//		* [?expression] - This will perform a filter operation on an array, returning all the
 		// 		items in an array that match the provided expression. This operator does not
 		//		need to be in brackets, you can simply use ?expression, but since it does not
-		//		have any containment, no operators can be used afterwards when used 
+		//		have any containment, no operators can be used afterwards when used
 		// 		without brackets.
 		//		* [^?expression] - This will perform a distinct filter operation on an array. This behaves
-		//		as [?expression] except that it will remove any duplicate values/objects from the 
+		//		as [?expression] except that it will remove any duplicate values/objects from the
 		//		result set.
-		// 		* [/expression], [\expression], [/expression, /expression] - This performs a sort 
+		// 		* [/expression], [\expression], [/expression, /expression] - This performs a sort
 		// 		operation on an array, with sort based on the provide expression. Multiple comma delimited sort
 		// 		expressions can be provided for multiple sort orders (first being highest priority). /
 		//		indicates ascending order and \ indicates descending order
@@ -128,37 +128,37 @@ dojo.provide("dojox.json.query");
 		//		* [start:end:step] - This performs an array slice/range operation, returning the elements
 		//		from the optional start index to the optional end index, stepping by the optional step number.
 		// 		* [expr,expr] - This a union operator, returning an array of all the property/index values from
-		// 		the evaluation of the comma delimited expressions. 
-		// 		* .* or [*] - This returns the values of all the properties of the current object. 
-		// 		* $ - This is the root object, If a JSONQuery expression does not being with a $, 
-		// 		it will be auto-inserted at the beginning. 
+		// 		the evaluation of the comma delimited expressions.
+		// 		* .* or [*] - This returns the values of all the properties of the current object.
+		// 		* $ - This is the root object, If a JSONQuery expression does not being with a $,
+		// 		it will be auto-inserted at the beginning.
 		// 		* @ - This is the current object in filter, sort, and map expressions. This is generally
 		// 		not necessary, names are auto-converted to property references of the current object
-		// 		in expressions. 
+		// 		in expressions.
 		// 		*	..property - Performs a recursive search for the given property name, returning
 		// 		an array of all values with such a property name in the current object and any subobjects
 		// 		* expr = expr - Performs a comparison (like JS's ==). When comparing to
-		// 		a string, the comparison string may contain wildcards * (matches any number of 
+		// 		a string, the comparison string may contain wildcards * (matches any number of
 		// 		characters) and ? (matches any single character).
 		// 		* expr ~ expr - Performs a string comparison with case insensitivity.
-		//		* ..[?expression] - This will perform a deep search filter operation on all the objects and 
-		// 		subobjects of the current data. Rather than only searching an array, this will search 
+		//		* ..[?expression] - This will perform a deep search filter operation on all the objects and
+		// 		subobjects of the current data. Rather than only searching an array, this will search
 		// 		property values, arrays, and their children.
 		//		* $1,$2,$3, etc. - These are references to extra parameters passed to the query
 		//		function or the evaluator function.
 		//		* +, -, /, *, &, |, %, (, ), <, >, <=, >=, != - These operators behave just as they do
 		// 		in JavaScript.
-		//		
-		//	
-		//	
-		// 	|	dojox.json.query(queryString,object) 
+		//
+		//
+		//
+		// 	|	dojox.json.query(queryString,object)
 		// 		and
 		// 	|	dojox.json.query(queryString)(object)
 		// 		always return identical results. The first one immediately evaluates, the second one returns a
 		// 		function that then evaluates the object.
-		//  
+		//
 		// 	example:
-		// 	|	dojox.json.query("foo",{foo:"bar"}) 
+		// 	|	dojox.json.query("foo",{foo:"bar"})
 		// 		This will return "bar".
 		//
 		//	example:
@@ -175,21 +175,21 @@ dojo.provide("dojox.json.query");
 		// 	 	This finds objects in array with a price less than 15.00 and sorts then
 		// 		by rating, highest rated first, and returns the first ten items in from this
 		// 		filtered and sorted list.
-		var depth = 0;	
+		var depth = 0;
 		var str = [];
 		query = query.replace(/"(\\.|[^"\\])*"|'(\\.|[^'\\])*'|[\[\]]/g,function(t){
 			depth += t == '[' ? 1 : t == ']' ? -1 : 0; // keep track of bracket depth
 			return (t == ']' && depth > 0) ? '`]' : // we mark all the inner brackets as skippable
 					(t.charAt(0) == '"' || t.charAt(0) == "'") ? "`" + (str.push(t) - 1) :// and replace all the strings
-						t;     
+						t;
 		});
 		var prefix = '';
 		function call(name){
-			// creates a function call and puts the expression so far in a parameter for a call 
+			// creates a function call and puts the expression so far in a parameter for a call
 			prefix = name + "(" + prefix;
 		}
 		function makeRegex(t,a,b,c,d,e,f,g){
-			// creates a regular expression matcher for when wildcards and ignore case is used 
+			// creates a regular expression matcher for when wildcards and ignore case is used
 			return str[g].match(/[\*\?]/) || f == '~' ?
 					"/^" + str[g].substring(1,str[g].length-1).replace(/\\([btnfr\\"'])|([^\w\*\?])/g,"\\$1$2").replace(/([\*\?])/g,"[\\w\\W]$1") + (f == '~' ? '$/i' : '$/') + ".test(" + a + ")" :
 					t;
@@ -200,8 +200,8 @@ dojo.provide("dojox.json.query");
 		
 		query = query.replace(/([^=]=)([^=])/g,"$1=$2"). // change the equals to comparisons
 			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 
+				return t.charAt(0) == '.' ? t : // leave .prop alone
+					t == '@' ? "$obj" :// the reference to the current object
 					(t.match(/:|^(\$|Math|true|false|null)$/) ? "" : "$obj.") + t; // plain names should be properties of root... unless they are a label in object initializer
 			}).
 			replace(/\.?\.?\[(`\]|[^\]])*\]|\?.*|\.\.([\w\$_]+)|\.\*/g,function(t,a,b){
@@ -214,7 +214,7 @@ dojo.provide("dojox.json.query");
 						prefix = ",true)";
 					}
 					call(oper[1].match(/\=/) ? "dojo.map" : oper[1].match(/\^/) ? "dojox.json._distinctFilter" : "dojo.filter");
-					return prefix + ",function($obj){return " + oper[2] + "})"; 
+					return prefix + ",function($obj){return " + oper[2] + "})";
 				}
 				oper = t.match(/^\[\s*([\/\\].*)\]/); // [/sortexpr,\sortexpr]
 				if(oper){
@@ -228,13 +228,13 @@ dojo.provide("dojox.json.query");
 				oper = t.match(/^\[(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)\]/); // slice [0:3]
 				if(oper){
 					call("dojox.json._slice");
-					return "," + (oper[1] || 0) + "," + (oper[2] || 0) + "," + (oper[3] || 1) + ")"; 
+					return "," + (oper[1] || 0) + "," + (oper[2] || 0) + "," + (oper[3] || 1) + ")";
 				}
 				if(t.match(/^\.\.|\.\*|\[\s*\*\s*\]|,/)){ // ..prop and [*]
 					call("dojox.json._find");
-					return (t.charAt(1) == '.' ? 
-							",'" + b + "'" : // ..prop 
-								t.match(/,/) ? 
+					return (t.charAt(1) == '.' ?
+							",'" + b + "'" : // ..prop
+								t.match(/,/) ?
 									"," + t : // [prop1,prop2]
 									"") + ")"; // [*]
 				}
diff --git a/dojox/json/ref.js b/dojox/json/ref.js
index dfa53ad..0d5a661 100644
--- a/dojox/json/ref.js
+++ b/dojox/json/ref.js
@@ -9,7 +9,7 @@ dojox.json.ref = {
 	// 		adding referencing support, date handling, and other extra format handling.
 	// 		On parsing, references are resolved. When references are made to
 	// 		ids/objects that have been loaded yet, the loader function will be set to
-	// 		_loadObject to denote a lazy loading (not loaded yet) object. 
+	// 		_loadObject to denote a lazy loading (not loaded yet) object.
 
 
 	resolveJson: function(/*Object*/ root,/*Object?*/ args){
@@ -24,13 +24,13 @@ dojox.json.ref = {
 		//		Object with additional arguments:
 		//
 		// The *index* parameter.
-		//		This is the index object (map) to use to store an index of all the objects. 
+		//		This is the index object (map) to use to store an index of all the objects.
 		// 		If you are using inter-message referencing, you must provide the same object for each call.
 		// The *defaultId* parameter.
 		//		This is the default id to use for the root object (if it doesn't define it's own id)
 		//	The *idPrefix* parameter.
-		//		This the prefix to use for the ids as they enter the index. This allows multiple tables 
-		// 		to use ids (that might otherwise collide) that enter the same global index. 
+		//		This the prefix to use for the ids as they enter the index. This allows multiple tables
+		// 		to use ids (that might otherwise collide) that enter the same global index.
 		// 		idPrefix should be in the form "/Service/".  For example,
 		//		if the idPrefix is "/Table/", and object is encountered {id:"4",...}, this would go in the
 		//		index as "/Table/4".
@@ -38,7 +38,7 @@ dojox.json.ref = {
 		//		This indicates what property is the identity property. This defaults to "id"
 		//	The *assignAbsoluteIds* parameter.
 		//		This indicates that the resolveJson should assign absolute ids (__id) as the objects are being parsed.
-		//  
+		//
 		// The *schemas* parameter
 		//		This provides a map of schemas, from which prototypes can be retrieved
 		// The *loader* parameter
@@ -49,7 +49,7 @@ dojox.json.ref = {
 		var idAttribute = args.idAttribute || 'id';
 		var refAttribute = this.refAttribute;
 		var idAsRef = args.idAsRef;
-		var prefix = args.idPrefix || ''; 
+		var prefix = args.idPrefix || '';
 		var assignAbsoluteIds = args.assignAbsoluteIds;
 		var index = args.index || {}; // create an index if one doesn't exist
 		var timeStamps = args.timeStamps;
@@ -68,13 +68,13 @@ dojox.json.ref = {
 				if(assignAbsoluteIds){
 					it.__id = id;
 				}
-				if(args.schemas && (!(it instanceof Array)) && // won't try on arrays to do prototypes, plus it messes with queries 
+				if(args.schemas && (!(it instanceof Array)) && // won't try on arrays to do prototypes, plus it messes with queries
 		 					(val = id.match(/^(.+\/)[^\.\[]*$/))){ // if it has a direct table id (no paths)
 		 			schema = args.schemas[val[1]];
-				} 
-				// if the id already exists in the system, we should use the existing object, and just 
+				}
+				// if the id already exists in the system, we should use the existing object, and just
 				// update it... as long as the object is compatible
-				if(index[id] && ((it instanceof Array) == (index[id] instanceof Array))){ 
+				if(index[id] && ((it instanceof Array) == (index[id] instanceof Array))){
 					target = index[id];
 					delete target.$ref; // remove this artifact
 					delete target._loadObject;
@@ -107,7 +107,7 @@ dojox.json.ref = {
 			var length = it.length;
 			for(i in it){
 				if(i==length){
-					break;		
+					break;
 				}
 				if(it.hasOwnProperty(i)){
 					val=it[i];
@@ -122,7 +122,9 @@ dojox.json.ref = {
 							// make sure it is a safe reference
 							delete it[i];// remove the property so it doesn't resolve to itself in the case of id.propertyName lazy values
 							var path = ref.toString().replace(/(#)([^\.\[])/,'$1.$2').match(/(^([^\[]*\/)?[^#\.\[]*)#?([\.\[].*)?/); // divide along the path
-							if((ref = (path[1]=='$' || path[1]=='this' || path[1]=='') ? root : index[(prefix + path[1]).replace(pathResolveRegex,'$2$3')])){  // a $ indicates to start with the root, otherwise start with an id
+							if(index[(prefix + ref).replace(pathResolveRegex,'$2$3')]){
+								ref = index[(prefix + ref).replace(pathResolveRegex,'$2$3')];
+							}else if((ref = (path[1]=='$' || path[1]=='this' || path[1]=='') ? root : index[(prefix + path[1]).replace(pathResolveRegex,'$2$3')])){  // a $ indicates to start with the root, otherwise start with an id
 								// if there is a path, we will iterate through the path references
 								if(path[3]){
 									path[3].replace(/(\[([^\]]+)\])|(\.?([^\.\[]+))/g,function(t,a,b,c,d){
@@ -155,21 +157,21 @@ dojox.json.ref = {
 									reWalk==it,
 									id === undefined ? undefined : addProp(id, i), // the default id to use
 									false,
-									propertyDefinition, 
-									// if we have an existing object child, we want to 
+									propertyDefinition,
+									// if we have an existing object child, we want to
 									// maintain it's identity, so we pass it as the default object
-									target != it && typeof target[i] == 'object' && target[i] 
+									target != it && typeof target[i] == 'object' && target[i]
 								);
 							}
 						}
 					}
 					it[i] = val;
-					if(target!=it && !target.__isDirty){// do updates if we are updating an existing object and it's not dirty				
+					if(target!=it && !target.__isDirty){// do updates if we are updating an existing object and it's not dirty
 						var old = target[i];
 						target[i] = val; // only update if it changed
-						if(update && val !== old && // see if it is different 
+						if(update && val !== old && // see if it is different
 								!target._loadObject && // no updates if we are just lazy loading
-								!(i.charAt(0) == '_' && i.charAt(1) == '_') && i != "$ref" &&  
+								!(i.charAt(0) == '_' && i.charAt(1) == '_') && i != "$ref" &&
 								!(val instanceof Date && old instanceof Date && val.getTime() == old.getTime()) && // make sure it isn't an identical date
 								!(typeof val == 'function' && typeof old == 'function' && val.toString() == old.toString()) && // make sure it isn't an indentical function
 								index.onUpdate){
@@ -228,7 +230,7 @@ dojox.json.ref = {
 			var root = eval('(' + str + ')'); // do the eval
 		}catch(e){
 			throw new SyntaxError("Invalid JSON string: " + e.message + " parsing: "+ str);
-		}		
+		}
 		if(root){
 			return this.resolveJson(root, args);
 		}
@@ -269,7 +271,7 @@ dojox.json.ref = {
 				var id = it.__id;
 				if(id){ // we found an identifiable object, we will just serialize a reference to it... unless it is the root
 					if(path != '#' && ((useRefs && !id.match(/#/)) || paths[id])){
-						var ref = id;	
+						var ref = id;
 						if(id.charAt(0)!='#'){
 							if(it.__clientId == id){
 								ref = "cid:" + id;
@@ -348,8 +350,8 @@ dojox.json.ref = {
 	},
 	//	refAttribute: String
 	//		This indicates what property is the reference property. This acts like the idAttribute
-	// 		except that this is used to indicate the current object is a reference or only partially 
-	// 		loaded. This defaults to "$ref". 
+	// 		except that this is used to indicate the current object is a reference or only partially
+	// 		loaded. This defaults to "$ref".
 	refAttribute: "$ref",
 	_useRefs: false,
 	serializeFunctions: false
diff --git a/dojox/json/schema.js b/dojox/json/schema.js
index 33dc54b..b2379d8 100644
--- a/dojox/json/schema.js
+++ b/dojox/json/schema.js
@@ -4,18 +4,18 @@ dojo.provide("dojox.json.schema");
 dojox.json.schema.validate = function(/*Any*/instance,/*Object*/schema){
 	// summary:
 	//  	To use the validator call this with an instance object and an optional schema object.
-	// 		If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating), 
-	// 		that schema will be used to validate and the schema parameter is not necessary (if both exist, 
+	// 		If a schema is provided, it will be used to validate. If the instance object refers to a schema (self-validating),
+	// 		that schema will be used to validate and the schema parameter is not necessary (if both exist,
 	// 		both validations will occur).
 	//	instance:
 	//		The instance value/object to validate
 	// schema:
 	//		The schema to use to validate
-	// description: 
+	// description:
 	// 		The validate method will return an object with two properties:
 	// 			valid: A boolean indicating if the instance is valid by the schema
-	// 			errors: An array of validation errors. If there are no errors, then an 
-	// 					empty list will be returned. A validation error will have two properties: 
+	// 			errors: An array of validation errors. If there are no errors, then an
+	// 					empty list will be returned. A validation error will have two properties:
 	// 						property: which indicates which property had the error
 	// 						message: which indicates what the error was
 	//
@@ -25,14 +25,14 @@ dojox.json.schema.checkPropertyChange = function(/*Any*/value,/*Object*/schema,
 	// summary:
 	// 		The checkPropertyChange method will check to see if an value can legally be in property with the given schema
 	// 		This is slightly different than the validate method in that it will fail if the schema is readonly and it will
-	// 		not check for self-validation, it is assumed that the passed in value is already internally valid.  
-	// 		The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for 
+	// 		not check for self-validation, it is assumed that the passed in value is already internally valid.
+	// 		The checkPropertyChange method will return the same object type as validate, see JSONSchema.validate for
 	// 		information.
 	//	value:
 	//		The new instance value/object to check
 	// schema:
 	//		The schema to use to validate
-	// return: 
+	// return:
 	// 		see dojox.validate.jsonSchema.validate
 	//
 	return this._validate(value,schema, property || "property");
@@ -43,7 +43,7 @@ dojox.json.schema.mustBeValid = function(result){
 	// result: the result returned from checkPropertyChange or validate
 	if(!result.valid){
 		throw new TypeError(dojo.map(result.errors,function(error){return "for property " + error.property + ': ' + error.message;}).join(", "));
-	}	
+	}
 }
 dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolean*/ _changing){
 	
@@ -65,7 +65,7 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 				addError("Invalid schema/property definition " + schema);
 			}
 			return null;
-		}			
+		}
 		if(_changing && schema.readonly){
 			addError("is a readonly field, it can not be changed");
 		}
@@ -75,15 +75,15 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 		// validate a value against a type definition
 		function checkType(type,value){
 			if(type){
-				if(typeof type == 'string' && type != 'any' && 
-						(type == 'null' ? value !== null : typeof value != type) && 
+				if(typeof type == 'string' && type != 'any' &&
+						(type == 'null' ? value !== null : typeof value != type) &&
 						!(value instanceof Array && type == 'array') &&
 						!(type == 'integer' && value%1===0)){
 					return [{property:path,message:(typeof value) + " value found, but a " + type + " is required"}];
 				}
 				if(type instanceof Array){
 					var unionErrors=[];
-					for(var j = 0; j < type.length; j++){ // a union type 
+					for(var j = 0; j < type.length; j++){ // a union type
 						if(!(unionErrors=checkType(type[j],value)).length){
 							break;
 						}
@@ -93,17 +93,17 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 					}
 				}else if(typeof type == 'object'){
 					var priorErrors = errors;
-					errors = []; 
+					errors = [];
 					checkProp(value,type,path);
 					var theseErrors = errors;
 					errors = priorErrors;
-					return theseErrors; 
-				} 
+					return theseErrors;
+				}
 			}
 			return [];
 		}
 		if(value === undefined){
-			if(!schema.optional){  
+			if(!schema.optional){
 				addError("is missing and it is not optional");
 			}
 		}else{
@@ -122,7 +122,7 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 							for(i=0,l=value.length; i<l; i++){
 								errors.concat(checkProp(value[i],schema.items,path,i));
 							}
-						}							
+						}
 					}
 					if(schema.minItems && value.length < schema.minItems){
 						addError("There must be a minimum of " + schema.minItems + " in the array");
@@ -142,11 +142,11 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 				if(schema.minLength && typeof value == 'string' && value.length < schema.minLength){
 					addError("must be at least " + schema.minLength + " characters long");
 				}
-				if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum && 
+				if(typeof schema.minimum !== undefined && typeof value == typeof schema.minimum &&
 						schema.minimum > value){
 					addError("must have a minimum value of " + schema.minimum);
 				}
-				if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum && 
+				if(typeof schema.maximum !== undefined && typeof value == typeof schema.maximum &&
 						schema.maximum < value){
 					addError("must have a maximum value of " + schema.maximum);
 				}
@@ -164,7 +164,7 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 						addError("does not have a value in the enumeration " + enumer.join(", "));
 					}
 				}
-				if(typeof schema.maxDecimal == 'number' && 
+				if(typeof schema.maxDecimal == 'number' &&
 					(value.toString().match(new RegExp("\\.[0-9]{" + (schema.maxDecimal + 1) + ",}")))){
 					addError("may only have " + schema.maxDecimal + " digits of decimal places");
 				}
@@ -180,7 +180,7 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 				errors.push({property:path,message:"an object is required"});
 			}
 			
-			for(var i in objTypeDef){ 
+			for(var i in objTypeDef){
 				if(objTypeDef.hasOwnProperty(i) && !(i.charAt(0) == '_' && i.charAt(1) == '_')){
 					var value = instance[i];
 					var propDef = objTypeDef[i];
@@ -199,7 +199,7 @@ dojox.json.schema._validate = function(/*Any*/instance,/*Object*/schema,/*Boolea
 			}
 			value = instance[i];
 			if(objTypeDef && typeof objTypeDef == 'object' && !(i in objTypeDef)){
-				checkProp(value,additionalProp,path,i); 
+				checkProp(value,additionalProp,path,i);
 			}
 			if(!_changing && value && value.$schema){
 				errors = errors.concat(checkProp(value,value.$schema,path,i));
diff --git a/dojox/json/tests/query.js b/dojox/json/tests/query.js
index d5f6def..b6bdb85 100644
--- a/dojox/json/tests/query.js
+++ b/dojox/json/tests/query.js
@@ -5,32 +5,32 @@ dojo.require("dojox.json.query");
 dojox.json.tests.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 };
 
 dojox.json.tests.testData= {
 	store: {
-		"book": [ 
-			{ 
+		"book": [
+			{
 				"category":"reference",
 				"author":"Nigel Rees",
 				"title":"Sayings of the Century",
 				"price":8.95
 			},
-			{ 
+			{
 				"category":"fiction",
 				"author":"Evelyn Waugh",
 				"title":"Sword of Honour",
 				"price":12.99
 			},
-			{ 
+			{
 				"category":"fiction",
 				"author":"Herman Melville",
 				"title":"Moby Dick",
 				"isbn":"0-553-21311-3",
 				"price":8.99
 			},
-			{ 
+			{
 				"category":"fiction",
 				"author":"J. R. R. Tolkien",
 				"title":"The Lord of the\nRings",
@@ -46,7 +46,7 @@ dojox.json.tests.testData= {
 	"symbols":{"@.$;":5}
 };
 
-doh.register("dojox.json.tests.query", 
+doh.register("dojox.json.tests.query",
 	[
 		{
 			name: "$.store.book[=author]",
@@ -315,36 +315,36 @@ doh.register("dojox.json.tests.query",
 		{
 			name: "safeEval: Illegal Eval",
 			runTest: function(t) {
-				try { 
+				try {
 					var result = dojo.toJson(dojox.json.query("$.store.book[?(push(5))]",dojox.json.tests.testData));
 					console.log("Illegal eval permitted");
 					doh.e("Illegal eval was permitted");
 				} catch(e) {
-					console.log("Eval properly blocked", e);	
+					console.log("Eval properly blocked", e);
 				}
 			}
 		},
 		{
 			name: "safeEval: Illegal Eval 2",
 			runTest: function(t) {
-				try { 
+				try {
 					var result = dojo.toJson(dojox.json.query("$.store.book[?(new Danger)]",dojox.json.tests.testData ));
 					console.log("Illegal eval permitted");
 					doh.e("Illegal eval was permitted");
 				} catch(e) {
-					console.log("Eval properly blocked", e);						
+					console.log("Eval properly blocked", e);
 				}
 			}
 		},
 		{
 			name: "safeEval: Illegal Eval 3",
 			runTest: function(t) {
-				try { 
+				try {
 					var result = dojo.toJson(dojox.json.query("$.store.book[?(@+=2)]",dojox.json.tests.testData));
 					console.log("Illegal eval permitted");
 					doh.e("Illegal eval was permitted");
 				} catch(e) {
-					console.log("Eval properly blocked", e);	
+					console.log("Eval properly blocked", e);
 				}
 			}
 		}
diff --git a/dojox/json/tests/schema.js b/dojox/json/tests/schema.js
index 5df5a42..6115d1f 100644
--- a/dojox/json/tests/schema.js
+++ b/dojox/json/tests/schema.js
@@ -188,13 +188,13 @@ var schemaForSchemas ={"description":"This is the JSON Schema for JSON Schemas."
      "hidden":{
      	"type":"boolean",
 	"optional":true,
-     	"description":"This indicates whether the property should be hidden in user interfaces."},     	
+     	"description":"This indicates whether the property should be hidden in user interfaces."},
      "extends":{
      	"type":"object",
      	"properties":{"$ref":"$.properties"},
      	"description":"This indicates the schema extends the given schema. All instances of this schema must be valid to by the extended schema also.",
 	"optional":true,
-	"default":{}},     	
+	"default":{}},
      "id":{
      	"type":["string","number"],
 	"optional":true,
@@ -217,23 +217,23 @@ doh.register("dojox.validate.tests.jsonSchema",
 		}
 	},
 	{
-		name:"isValidPropertyChange", 
+		name:"isValidPropertyChange",
 		runTest: function(t){
-			doh.f(dojox.json.schema.checkPropertyChange(biggerObj,biggerSchema).valid); //this should fail because of the 
+			doh.f(dojox.json.schema.checkPropertyChange(biggerObj,biggerSchema).valid); //this should fail because of the
 			doh.t(dojox.json.schema.checkPropertyChange(schemaForSchemas,schemaForSchemas).valid); //schema should be valid
 		}
 	},
 	function disallow(t){
 		var schema={
 			disallow: [{maxLength:4}]
-		}		
+		}
 		doh.t(dojox.json.schema.validate("hello", schema).valid);
 		doh.f(dojox.json.schema.validate("hi", schema).valid);
 	},
 	function maxDecimal(t){
 		var schema={
 			maxDecimal: 4
-		}		
+		}
 		doh.t(dojox.json.schema.validate(4.44, schema).valid);
 		doh.f(dojox.json.schema.validate(4.444444, schema).valid);
 		
@@ -241,7 +241,7 @@ doh.register("dojox.validate.tests.jsonSchema",
 	function tuple(t){
 		var schema={
 			items: [{type:"string"},{type:"number"}]
-		};		
+		};
 		doh.t(dojox.json.schema.validate(["hi",33], schema).valid);
 		doh.f(dojox.json.schema.validate([22,22], schema).valid);
 		
@@ -249,7 +249,7 @@ doh.register("dojox.validate.tests.jsonSchema",
 	function union(t){
 		var schema={
 			type: ["string", "number"]
-		};		
+		};
 		doh.t(dojox.json.schema.validate(22, schema).valid);
 		doh.t(dojox.json.schema.validate("hi", schema).valid);
 		doh.f(dojox.json.schema.validate(null, schema).valid);
@@ -257,7 +257,7 @@ doh.register("dojox.validate.tests.jsonSchema",
 	},
 	function aLittleComplex(t){
 		var schema = {type:[
-			{type:"object", properties:{name:{type:"string"}, id:{type:"integer"}}, additionalProperties:false}, 
+			{type:"object", properties:{name:{type:"string"}, id:{type:"integer"}}, additionalProperties:false},
 			{type:"object", properties:{brand:{type:"string"}, id:{type:"integer"}}, additionalProperties:false}]
 		};
 		doh.t(dojox.json.schema.validate({name:"Bill", id:3}, schema).valid);
diff --git a/dojox/jsonPath/query.js b/dojox/jsonPath/query.js
index 20a5a3e..d9eadff 100644
--- a/dojox/jsonPath/query.js
+++ b/dojox/jsonPath/query.js
@@ -5,7 +5,7 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 	// 	Perform jsonPath query `expr` on javascript object or json string `obj`
 	//	obj - object || json string to perform query on
 	//	expr - jsonPath expression (string) to be evaluated
-	//	arg - {}special arugments.  
+	//	arg - {}special arugments.
 	//		resultType: "VALUE"||"BOTH"||"PATH"} (defaults to value)
 	//		evalType: "RESULT"||"ITEM"} (defaults to ?)
 
@@ -53,9 +53,9 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 			var paths=[path];
 			function add(v, p,def){
 			  if (v && v.hasOwnProperty(p) && P.resultType != "VALUE") paths.push(path.concat([p]));
-				if (def) 
+				if (def)
 				  result = v[p];
-			  else if (v && v.hasOwnProperty(p))  
+			  else if (v && v.hasOwnProperty(p))
 					result.push(v[p]);
 			}
 			function desc(v){
@@ -92,11 +92,11 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 					function(i){P.walk(val[i],function(j){ add(val[i],j); })} :
 					function(i){ add(val,i); });
 				}
-				else if (loc === "..") 
+				else if (loc === "..")
 					desc(val);
 				else if (/,/.test(loc)){ // [name1,name2,...]
 					for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++)
-						add(val,repStr(s[i])); 
+						add(val,repStr(s[i]));
 				}
 				else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)]
 					P.walk(val, function(i){ if (P.eval(loc.replace(/^\?\((.*?)\)$/,"$1"),val[i])) add(val,i); });
@@ -104,10 +104,10 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 					slice(loc, val);
 				else {
 					loc=repStr(loc);
-					if (rb && val instanceof Array && !/^[0-9*]+$/.test(loc)) 
+					if (rb && val instanceof Array && !/^[0-9*]+$/.test(loc))
 						P.walk(val, function(i){ add(val[i], loc)});
-					else 
-						add(val,loc,rb);		
+					else
+						add(val,loc,rb);
 				}
 
 			}
@@ -117,7 +117,7 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 				result = [];
 				var valPaths = paths;
 				paths = [];
-				if (rb) 
+				if (rb)
 					oper(val)
 				else
 					P.walk(val,function(i){path=valPaths[i]||path;oper(val[i])});
@@ -152,8 +152,8 @@ dojox.jsonPath.query = function(/*Object*/obj, /*String*/expr, /*Object*/arg){
 	var $ = obj;
 	if (expr && obj){
 		return P.exec(P.normalize(expr).slice(1), obj, arg.evalType == "RESULT");
-	}	
+	}
 
 	return false;
 
-}; 
+};
diff --git a/dojox/jsonPath/tests/jsonPath.js b/dojox/jsonPath/tests/jsonPath.js
index 0bd60d6..dfdabdd 100644
--- a/dojox/jsonPath/tests/jsonPath.js
+++ b/dojox/jsonPath/tests/jsonPath.js
@@ -5,32 +5,32 @@ dojo.require("dojox.jsonPath");
 dojox.jsonPath.tests.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(errData);
 }
 
 dojox.jsonPath.tests.testData= {
 	store: {
-		"book": [ 
-			{ 
+		"book": [
+			{
 				"category":"reference",
 				"author":"Nigel Rees",
 				"title":"Sayings of the Century",
 				"price":8.95
 			},
-			{ 
+			{
 				"category":"fiction",
 				"author":"Evelyn Waugh",
 				"title":"Sword of Honour",
 				"price":12.99
 			},
-			{ 
+			{
 				"category":"fiction",
 				"author":"Herman Melville",
 				"title":"Moby Dick",
 				"isbn":"0-553-21311-3",
 				"price":8.99
 			},
-			{ 
+			{
 				"category":"fiction",
 				"author":"J. R. R. Tolkien",
 				"title":"The Lord of the Rings",
@@ -46,7 +46,7 @@ dojox.jsonPath.tests.testData= {
 	"symbols":{"@.$;":5}
 }
 
-doh.register("dojox.jsonPath.tests.jsonPath", 
+doh.register("dojox.jsonPath.tests.jsonPath",
 	[
 		{
 			name: "$.store.book[*].author",
diff --git a/dojox/lang/aspect.js b/dojox/lang/aspect.js
index 09dbfc4..f701daf 100644
--- a/dojox/lang/aspect.js
+++ b/dojox/lang/aspect.js
@@ -154,7 +154,7 @@ dojo.provide("dojox.lang.aspect");
 		//		satisfy the RegExp condition are processed. This function
 		//		returns a handle, which can be used to unadvise, or null,
 		//		if advising has failed.
-		//		
+		//
 		//		This function is a convenience wrapper for
 		//		dojox.lang.aspect.adviseRaw().
 		//
diff --git a/dojox/lang/docs.js b/dojox/lang/docs.js
index fb6a089..8673581 100644
--- a/dojox/lang/docs.js
+++ b/dojox/lang/docs.js
@@ -4,7 +4,7 @@ dojo.provide("dojox.lang.docs");
 // This can be utilized for runtime metadata retrieval and type checking
 (function(){
 	function error(error){
-		console.log("Warning, the API docs must be available at ../util/docscripts/api.json "+ 
+		console.log("Warning, the API docs must be available at ../util/docscripts/api.json "+
 		"or ../util/docscripts/api/*.json "+
 		"in order for dojox.lang.docs to supply schema information, but it could not be loaded: " + error);
 	}
@@ -18,7 +18,7 @@ dojo.provide("dojox.lang.docs");
 		declaredClasses[name] = clazz;
 	};
 	var getType = function(typeDef){
-		var type = typeDef.type || '';		
+		var type = typeDef.type || '';
 		var typeObj, optional = false, array = false, dontModify;
 		type = type.replace(/\?/, function(){
 			optional = true;
@@ -134,9 +134,9 @@ dojo.provide("dojox.lang.docs");
 
 	dojox.lang.docs.init = function(/*Boolean*/async){
 		// summary:
-		//		Loads the documentation and applies it to the previously defined classes 
+		//		Loads the documentation and applies it to the previously defined classes
 		// 		and any future defined classes
-		// 
+		//
 		// async:
 		// 		 If true, the documentation will be loaded asynchronously
 		function loadFullDocs(){
diff --git a/dojox/lang/functional/array.js b/dojox/lang/functional/array.js
index 5f2c71d..36e105e 100755
--- a/dojox/lang/functional/array.js
+++ b/dojox/lang/functional/array.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.lambda");
 //	- array-processing functions similar to standard JS functions
 
 // Notes:
-//	- this module provides JS standard methods similar to high-level functions in dojo/_base/array.js: 
+//	- this module provides JS standard methods similar to high-level functions in dojo/_base/array.js:
 //		forEach, map, filter, every, some
 
 // Defined methods:
@@ -22,7 +22,7 @@ dojo.require("dojox.lang.functional.lambda");
 		// 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 
+			// 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);
@@ -72,7 +72,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return o;	// Object
 		},
 		map: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates a new array with the results of calling 
+			// 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);
@@ -97,7 +97,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return t;	// Array
 		},
 		every: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether all elements in the array pass the test 
+			// 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);
@@ -129,7 +129,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return true;	// Boolean
 		},
 		some: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether some element in the array passes the test 
+			// 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);
diff --git a/dojox/lang/functional/curry.js b/dojox/lang/functional/curry.js
index 115912e..56aff3b 100755
--- a/dojox/lang/functional/curry.js
+++ b/dojox/lang/functional/curry.js
@@ -7,7 +7,7 @@ dojo.require("dojox.lang.functional.lambda");
 //	- argument pre-processing: mixer and flip
 
 // Acknoledgements:
-//	- partial() is based on work by Oliver Steele 
+//	- partial() is based on work by Oliver Steele
 //		(http://osteele.com/sources/javascript/functional/functional.js)
 //		which was published under MIT License
 
@@ -30,7 +30,7 @@ dojo.require("dojox.lang.functional.lambda");
 	dojo.mixin(df, {
 		// currying and partial functions
 		curry: function(/*Function|String|Array*/ f, /*Number?*/ arity){
-			// summary: curries a function until the arity is satisfied, at 
+			// summary: curries a function until the arity is satisfied, at
 			//	which point it returns the calculated value.
 			f = df.lambda(f);
 			arity = typeof arity == "number" ? arity : f.length;
@@ -39,9 +39,9 @@ dojo.require("dojox.lang.functional.lambda");
 		arg: {},	// marker for missing arguments
 		partial: function(/*Function|String|Array*/ f){
 			// summary: creates a function where some arguments are bound, and
-			//	some arguments (marked as dojox.lang.functional.arg) are will be 
+			//	some arguments (marked as dojox.lang.functional.arg) are will be
 			//	accepted by the final function in the order they are encountered.
-			// description: This method is used to produce partially bound 
+			// description: This method is used to produce partially bound
 			//	functions. If you want to change the order of arguments, use
 			//	dojox.lang.functional.mixer() or dojox.lang.functional.flip().
 			var a = arguments, l = a.length, args = new Array(l - 1), p = [], i = 1, t;
diff --git a/dojox/lang/functional/fold.js b/dojox/lang/functional/fold.js
index a1b5377..e49b7c9 100755
--- a/dojox/lang/functional/fold.js
+++ b/dojox/lang/functional/fold.js
@@ -6,9 +6,9 @@ dojo.require("dojox.lang.functional.lambda");
 //	- "fold" family of functions
 
 // Notes:
-//	- missing high-level functions are provided with the compatible API: 
+//	- missing high-level functions are provided with the compatible API:
 //		foldl, foldl1, foldr, foldr1
-//	- missing JS standard functions are provided with the compatible API: 
+//	- missing JS standard functions are provided with the compatible API:
 //		reduce, reduceRight
 //	- the fold's counterpart: unfold
 
@@ -80,7 +80,7 @@ dojo.require("dojox.lang.functional.lambda");
 		},
 		foldr: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
 			// summary: repeatedly applies a binary function to an array from right
-			//	to left using a seed value as a starting point; returns the final 
+			//	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);
diff --git a/dojox/lang/functional/lambda.js b/dojox/lang/functional/lambda.js
index c88afae..95d68d4 100755
--- a/dojox/lang/functional/lambda.js
+++ b/dojox/lang/functional/lambda.js
@@ -4,12 +4,12 @@ dojo.provide("dojox.lang.functional.lambda");
 //	- anonymous functions built from the string
 
 // Acknoledgements:
-//	- lambda() is based on work by Oliver Steele 
+//	- lambda() is based on work by Oliver Steele
 //		(http://osteele.com/sources/javascript/functional/functional.js)
 //		which was published under MIT License
 
 // Notes:
-//	- lambda() produces functions, which after the compilation step are 
+//	- lambda() produces functions, which after the compilation step are
 //		as fast as regular JS functions (at least theoretically).
 
 // Lambda input values:
@@ -52,7 +52,7 @@ dojo.provide("dojox.lang.functional.lambda");
 					s = s + "$2";
 				}
 			}else{
-				// the point of the long regex below is to exclude all well-known 
+				// the point of the long regex below is to exclude all well-known
 				// lower-case words from the list of potential arguments
 				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, "").
@@ -69,13 +69,13 @@ dojo.provide("dojox.lang.functional.lambda");
 	};
 
 	var compose = function(/*Array*/ a){
-		return a.length ? 
+		return a.length ?
 					function(){
 						var i = a.length - 1, x = df.lambda(a[i]).apply(this, arguments);
 						for(--i; i >= 0; --i){ x = df.lambda(a[i]).call(this, x); }
 						return x;
 					}
-				: 
+				:
 					// identity
 					function(x){ return x; };
 	};
diff --git a/dojox/lang/functional/listcomp.js b/dojox/lang/functional/listcomp.js
index 12c804c..908d739 100755
--- a/dojox/lang/functional/listcomp.js
+++ b/dojox/lang/functional/listcomp.js
@@ -4,7 +4,7 @@ dojo.provide("dojox.lang.functional.listcomp");
 //	- list comprehensions similar to JavaScript 1.7
 
 // Notes:
-//	- listcomp() produces functions, which after the compilation step are 
+//	- listcomp() produces functions, which after the compilation step are
 //		as fast as regular JS functions (at least theoretically).
 
 (function(){
@@ -28,17 +28,17 @@ dojo.provide("dojox.lang.functional.listcomp");
 		buildListcomp: function(/*String*/ s){
 			// summary: builds a function from a text snippet, which represents a valid
 			//	JS 1.7 list comprehension, returns a string, which represents the function.
-			// description: This method returns a textual representation of a function 
-			//	built from the list comprehension text snippet (conformant to JS 1.7). 
-			//	It is meant to be evaled in the proper context, so local variable can be 
+			// description: This method returns a textual representation of a function
+			//	built from the list comprehension text snippet (conformant to JS 1.7).
+			//	It is meant to be evaled in the proper context, so local variable can be
 			//	pulled from the environment.
 			return "function(){" + listcomp(s) + "}";	// String
 		},
 		compileListcomp: function(/*String*/ s){
 			// summary: builds a function from a text snippet, which represents a valid
 			//	JS 1.7 list comprehension, returns a function object.
-			// description: This method returns a function built from the list 
-			//	comprehension text snippet (conformant to JS 1.7). It is meant to be 
+			// description: This method returns a function built from the list
+			//	comprehension text snippet (conformant to JS 1.7). It is meant to be
 			//	reused several times.
 			return new Function([], listcomp(s));	// Function
 		},
diff --git a/dojox/lang/functional/object.js b/dojox/lang/functional/object.js
index 63227c7..525ccd8 100755
--- a/dojox/lang/functional/object.js
+++ b/dojox/lang/functional/object.js
@@ -7,7 +7,7 @@ dojo.require("dojox.lang.functional.lambda");
 
 // Defined methods:
 //	- take any valid lambda argument as the functional argument
-//	- skip all attributes that are present in the empty object 
+//	- skip all attributes that are present in the empty object
 //		(IE and/or 3rd-party libraries).
 
 (function(){
@@ -36,7 +36,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return	t; // Array
 		},
 		filterIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates new object with all attributes that pass the test 
+			// summary: creates new object with all attributes that pass the test
 			//	implemented by the provided function.
 			o = o || d.global; f = df.lambda(f);
 			var t = {}, v, i;
@@ -59,7 +59,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return o;	// Object
 		},
 		mapIn: function(/*Object*/ obj, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: creates new object with the results of calling 
+			// 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);
 			var t = {}, i;
diff --git a/dojox/lang/functional/reversed.js b/dojox/lang/functional/reversed.js
index 575a0a5..656f36a 100755
--- a/dojox/lang/functional/reversed.js
+++ b/dojox/lang/functional/reversed.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.lambda");
 //	- reversed versions of array-processing functions similar to standard JS functions
 
 // Notes:
-//	- this module provides reversed versions of standard array-processing functions: 
+//	- this module provides reversed versions of standard array-processing functions:
 //		forEachRev, mapRev, filterRev
 
 // Defined methods:
@@ -21,7 +21,7 @@ dojo.require("dojox.lang.functional.lambda");
 		// 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 
+			// 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);
@@ -39,7 +39,7 @@ dojo.require("dojox.lang.functional.lambda");
 			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 
+			// 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);
@@ -48,7 +48,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return t;	// Array
 		},
 		everyRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether all elements in the array pass the test 
+			// 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);
@@ -60,7 +60,7 @@ dojo.require("dojox.lang.functional.lambda");
 			return true;	// Boolean
 		},
 		someRev: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: tests whether some element in the array passes the test 
+			// 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);
diff --git a/dojox/lang/functional/scan.js b/dojox/lang/functional/scan.js
index 25864a2..35978f6 100755
--- a/dojox/lang/functional/scan.js
+++ b/dojox/lang/functional/scan.js
@@ -6,7 +6,7 @@ dojo.require("dojox.lang.functional.lambda");
 //	- "scan" family of functions
 
 // Notes:
-//	- missing high-level functions are provided with the compatible API: 
+//	- missing high-level functions are provided with the compatible API:
 //		scanl, scanl1, scanr, scanr1
 
 // Defined methods:
@@ -21,7 +21,7 @@ dojo.require("dojox.lang.functional.lambda");
 	d.mixin(df, {
 		// classic reduce-class functions
 		scanl: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object*/ z, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from left 
+			// summary: repeatedly applies a binary function to an array from left
 			//	to right using a seed value as a starting point; returns an array
 			//	of values produced by foldl() at that point.
 			if(typeof a == "string"){ a = a.split(""); }
@@ -48,8 +48,8 @@ dojo.require("dojox.lang.functional.lambda");
 			return t;	// Array
 		},
 		scanl1: function(/*Array|String|Object*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
-			// summary: repeatedly applies a binary function to an array from left 
-			//	to right; returns an array of values produced by foldl1() at that 
+			// summary: repeatedly applies a binary function to an array from left
+			//	to right; returns an array of values produced by foldl1() at that
 			//	point.
 			if(typeof a == "string"){ a = a.split(""); }
 			o = o || d.global; f = df.lambda(f);
@@ -93,7 +93,7 @@ dojo.require("dojox.lang.functional.lambda");
 		},
 		scanr1: function(/*Array|String*/ a, /*Function|String|Array*/ f, /*Object?*/ o){
 			// summary: repeatedly applies a binary function to an array from right
-			//	to left; returns an array of values produced by foldr1() at that 
+			//	to left; returns an array of values produced by foldr1() at that
 			//	point.
 			if(typeof a == "string"){ a = a.split(""); }
 			o = o || d.global; f = df.lambda(f);
diff --git a/dojox/lang/functional/zip.js b/dojox/lang/functional/zip.js
index 627b779..f4cb818 100755
--- a/dojox/lang/functional/zip.js
+++ b/dojox/lang/functional/zip.js
@@ -12,7 +12,7 @@ dojo.provide("dojox.lang.functional.zip");
 	dojo.mixin(df, {
 		// combiners
 		zip: function(){
-			// summary: returns an array of arrays, where the i-th array 
+			// summary: returns an array of arrays, where the i-th array
 			//	contains the i-th element from each of the argument arrays.
 			// description: This is the venerable zip combiner (for example,
 			//	see Python documentation for general details). The returned
@@ -28,11 +28,11 @@ dojo.provide("dojox.lang.functional.zip");
 			return t;	// Array
 		},
 		unzip: function(/*Array*/ a){
-			// summary: similar to dojox.lang.functional.zip(), but takes 
+			// summary: similar to dojox.lang.functional.zip(), but takes
 			//	a single array of arrays as the input.
-			// description: This function is similar to dojox.lang.functional.zip() 
-			//	and can be used to unzip objects packed by 
-			//	dojox.lang.functional.zip(). It is here mostly to provide 
+			// description: This function is similar to dojox.lang.functional.zip()
+			//	and can be used to unzip objects packed by
+			//	dojox.lang.functional.zip(). It is here mostly to provide
 			//	a short-cut for the different method signature.
 			return df.zip.apply(null, a);	// Array
 		}
diff --git a/dojox/lang/observable.js b/dojox/lang/observable.js
index 636edf0..8c4518f 100644
--- a/dojox/lang/observable.js
+++ b/dojox/lang/observable.js
@@ -1,9 +1,9 @@
 dojo.provide("dojox.lang.observable");
 // Used to create a wrapper object with monitored reads and writes
-// 
+//
 dojo.experimental("dojox.lang.observable");
-// IMPORTANT DISCLAIMER: 
-// This is experimental and based on hideous hacks. 
+// IMPORTANT DISCLAIMER:
+// This is experimental and based on hideous hacks.
 // There are severe limitations on the ability of wrapper objects:
 // Only properties that have vbscript-legal names are accessible (similar to JavaScript, but they can't start with an underscore).
 // The wrapper objects are not expando in IE, because they are built
@@ -13,14 +13,14 @@ dojo.experimental("dojox.lang.observable");
 // This has performance implications as well.
 dojox.lang.observable = function(/*Object*/wrapped,/*function*/onRead,/*function*/onWrite,/*function*/onInvoke){
 	// 	summary:
-	// 		Creates a wrapper object, which can be observed. The wrapper object 
+	// 		Creates a wrapper object, which can be observed. The wrapper object
 	// 		is a proxy to the wrapped object. If you will be making multiple wrapper
 	// 		objects with the same set of listeners, it is recommended that you
-	// 		use makeObservable, as it is more memory efficient.	
-	// 
+	// 		use makeObservable, as it is more memory efficient.
+	//
 	// 	wrapped:
 	// 		The object to be wrapped and monitored for property access and modification
-	//	
+	//
 	// onRead:
 	//		See dojox.lang.makeObservable.onRead
 	// onWrite:
@@ -33,36 +33,36 @@ dojox.lang.observable = function(/*Object*/wrapped,/*function*/onRead,/*function
 dojox.lang.makeObservable = function(/*function*/onRead,/*function*/onWrite,/*function*/onInvoke,/*Object*/hiddenFunctions){
 		
 	// 	summary:
-	// 		Creates and returns an observable creator function. All the objects that 
+	// 		Creates and returns an observable creator function. All the objects that
 	// 		are created with the returned constructor will use the provided onRead and
 	// 		onWrite listeners.
 	// 		The created constructor should be called with a single argument,
-	// 		the object that will be wrapped to be observed. The constructor will 
+	// 		the object that will be wrapped to be observed. The constructor will
 	// 		return the wrapper object.
 	//
 	// onRead:
-	// 		This is called whenever one of the wrapper objects created 
+	// 		This is called whenever one of the wrapper objects created
 	// 		from the constructor has a property that is accessed. onRead
 	// 		will be called with two arguments, the first being the wrapped object,
 	// 		and the second is the name of property that is being accessed.
-	// 		The value that onRead returns will be used as the value returned 
+	// 		The value that onRead returns will be used as the value returned
 	// 		by the property access
-	//  
+	//
 	// onWrite:
-	// 		This is called whenever one of the wrapper objects created 
+	// 		This is called whenever one of the wrapper objects created
 	// 		from the constructor has a property that is modified. onWrite
 	// 		will be called with three arguments, the first being the wrapped object,
 	// 		the second is the name of property that is being modified, and the
 	// 		third is the value that is being set on the property.
-	// 
-	// 	onInvoke: 
-	// 		This is called when a method on the object is invoked. The first 
-	// 		argument is the wrapper object, the second is the original wrapped object, 
+	//
+	// 	onInvoke:
+	// 		This is called when a method on the object is invoked. The first
+	// 		argument is the wrapper object, the second is the original wrapped object,
 	// 		the third is the method name, and the fourth is the arguments.
 	//
-	// hiddenFunctions: 
-	// 		allows you to define functions that should be delegated 
-	// 		but may not be enumerable on the wrapped objects, so they must be 
+	// hiddenFunctions:
+	// 		allows you to define functions that should be delegated
+	// 		but may not be enumerable on the wrapped objects, so they must be
 	// 		explicitly included
 	//
 	// example:
@@ -70,7 +70,7 @@ dojox.lang.makeObservable = function(/*function*/onRead,/*function*/onWrite,/*fu
 	// 		prevent functions from being accessed on an object:
 	// 	|	function onRead(obj,prop){
 	//	|		return typeof obj[prop] == 'function' ? null : obj[prop];
-	//	|	} 
+	//	|	}
 	//	|	var observable = dojox.lang.makeObservable(onRead,onWrite);
 	//	|	var obj = {foo:1,bar:function(){}};
 	//	|	obj = observable(obj);
@@ -104,7 +104,7 @@ dojox.lang.makeObservable = function(/*function*/onRead,/*function*/onWrite,/*fu
 			}
 			if(wrapped.data__){
 				throw new Error("Can wrap an object that is already wrapped");
-			}			
+			}
 			// create the class
 			var props = [], i, l;
 			for(i in hiddenFunctions){
@@ -112,14 +112,14 @@ dojox.lang.makeObservable = function(/*function*/onRead,/*function*/onWrite,/*fu
 			}
 			var vbReservedWords = {type:1,event:1};
 			// find the unique signature for the class so we can reuse it if possible
-			for(i in wrapped){ 
+			for(i in wrapped){
 				if(i.match(/^[a-zA-Z][\w\$_]*$/) && !(i in hiddenFunctions) && !(i in vbReservedWords)){ //can only do properties with valid vb names/tokens and primitive values
 					props.push(i);
 				}
 			}
 			var signature = props.join(",");
-			var prop,clazz = cache[signature]; 
-			if(!clazz){ 
+			var prop,clazz = cache[signature];
+			if(!clazz){
 				var tname = "dj_lettable_"+(factory.inc++);
 				var gtname = tname+"_dj_getter";
 				var cParts = [
@@ -227,16 +227,16 @@ if(!{}.__defineGetter__){
 		frame.style.display="none";
 		var doc = frame.contentWindow.document;
 		dojox.lang.lettableWin = frame.contentWindow;
-		doc.write('<html><head><script language="VBScript" type="text/VBScript">' + 
+		doc.write('<html><head><script language="VBScript" type="text/VBScript">' +
 			'Function vb_global_eval(code)' +
 				'ExecuteGlobal(code)' +
 			'End Function' +
 			'</script>' +
-			'<script type="text/javascript">' + 
+			'<script type="text/javascript">' +
 			'function vbEval(code){ \n' + // this has to be here to call it from another frame
 				'return vb_global_eval(code);' +
 			'}' +
-			'function construct(name){ \n' + // and this too 
+			'function construct(name){ \n' + // and this too
 				'return window[name]();' +
 			'}' +
 			'</script>' +
@@ -248,15 +248,15 @@ if(!{}.__defineGetter__){
 }
 
 dojox.lang.ReadOnlyProxy =
-// summary: 
-// 		Provides a read only proxy to another object, this can be 
+// summary:
+// 		Provides a read only proxy to another object, this can be
 // 		very useful in object-capability systems
 // example:
 // 	|	var obj = {foo:"bar"};
 // 	|	var readonlyObj = dojox.lang.ReadOnlyProxy(obj);
 // 	|	readonlyObj.foo = "test" // throws an error
 // 	|	obj.foo = "new bar";
-// 	|	readonlyObj.foo -> returns "new bar", always reflects the current value of the original (it is not just a copy) 
+// 	|	readonlyObj.foo -> returns "new bar", always reflects the current value of the original (it is not just a copy)
 dojox.lang.makeObservable(function(obj,i){
 		return obj[i];
 	},function(obj,i,value){
diff --git a/dojox/lang/tests/declare-old.js b/dojox/lang/tests/declare-old.js
index 5bf168f..3d1572f 100644
--- a/dojox/lang/tests/declare-old.js
+++ b/dojox/lang/tests/declare-old.js
@@ -5,7 +5,7 @@ dojo.provide("dojox.lang.tests.declare-old");
 // this file courtesy of the TurboAjax Group, licensed under a Dojo CLA
 
 dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function[]*/ superclass, /*Object*/ props){
-	//	summary: 
+	//	summary:
 	//		Create a feature-rich constructor from compact notation
 	//
 	//	description:
@@ -15,21 +15,21 @@ dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function
 	//		The name of the constructor (loosely, a "class")
 	//		stored in the "declaredClass" property in the created prototype
 	//	superclass:
-	//		May be null, a Function, or an Array of Functions. If an array, 
+	//		May be null, a Function, or an Array of Functions. If an array,
 	//		the first element is used as the prototypical ancestor and
 	//		any following Functions become mixin ancestors.
 	//	props:
 	//		An object whose properties are copied to the
 	//		created prototype.
-	//		Add an instance-initialization function by making it a property 
+	//		Add an instance-initialization function by making it a property
 	//		named "constructor".
 	//	description:
 	//		Create a constructor using a compact notation for inheritance and
-	//		prototype extension. 
+	//		prototype extension.
 	//
 	//		All superclasses (including mixins) must be Functions (not simple Objects).
 	//
-	//		Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin 
+	//		Mixin ancestors provide a type of multiple inheritance. Prototypes of mixin
 	//		ancestors are copied to the new class: changes to mixin prototypes will
 	//		not affect classes to which they have been mixed in.
 	//
@@ -40,7 +40,7 @@ dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function
 	//	|	dojo.declare("my.ClassyThing", null, {
 	//	|		aProperty:"string",
 	//	|		constructor: function(args){
-	//	|			dojo.mixin(this, args);	
+	//	|			dojo.mixin(this, args);
 	//	|		}
 	//	|	});
 	//
@@ -51,11 +51,11 @@ dojox.lang.tests.declareOld = function(/*String*/ className, /*Function|Function
 	//	|		someValue: 2,
 	//	|		// initialization function
 	//	|		constructor: function(){
-	//	|			this.myComplicatedObject = new ReallyComplicatedObject(); 
+	//	|			this.myComplicatedObject = new ReallyComplicatedObject();
 	//	|		},
 	//	|		// other functions
-	//	|		someMethod: function(){ 
-	//	|			doStuff(); 
+	//	|		someMethod: function(){
+	//	|			doStuff();
 	//	|		}
 	//	|	);
 	//
@@ -119,14 +119,14 @@ dojo.mixin(dojox.lang.tests.declareOld, {
 		// we have to make a function, but don't want to close over anything
 		return function(){ this._construct(arguments); };
 	},
-	_core: { 
+	_core: {
 		_construct: function(args){
-			var c = args.callee, s = c.superclass, ct = s && s.constructor, 
+			var c = args.callee, s = c.superclass, ct = s && s.constructor,
 				m = c.mixin, mct = m && m.constructor, a = args, ii, fn;
 			// side-effect of = used on purpose here, lint may complain, don't try this at home
-			if(a[0]){ 
+			if(a[0]){
 				// FIXME: preambles for each mixin should be allowed
-				// FIXME: 
+				// FIXME:
 				//		should we allow the preamble here NOT to modify the
 				//		default args, but instead to act on each mixin
 				//		independently of the class instance being constructed
@@ -134,13 +134,13 @@ dojo.mixin(dojox.lang.tests.declareOld, {
 
 				// allow any first argument w/ a "preamble" property to act as a
 				// class preamble (not exclusive of the prototype preamble)
-				if(/*dojo.isFunction*/((fn = a[0].preamble))){ 
-					a = fn.apply(this, a) || a; 
+				if(/*dojo.isFunction*/((fn = a[0].preamble))){
+					a = fn.apply(this, a) || a;
 				}
-			} 
+			}
 			// prototype preamble
 			if((fn = c.prototype.preamble)){ a = fn.apply(this, a) || a; }
-			// FIXME: 
+			// FIXME:
 			//		need to provide an optional prototype-settable
 			//		"_explicitSuper" property which disables this
 			// initialize superclass
@@ -179,17 +179,17 @@ dojo.mixin(dojox.lang.tests.declareOld, {
 			return !has && (p = this._findMixin(ptype)) && this._findMethod(name, method, p, has);
 		},
 		inherited: function(name, args, newArgs){
-			// summary: 
+			// summary:
 			//		Call an inherited member function of this declared class.
 			//
 			// description:
 			//		Call an inherited member function of this declared class, allowing advanced
 			//		manipulation of passed arguments to inherited functions.
 			//		Explicitly cannot handle the case of intending to pass no `newArgs`, though
-			//		hoping the use in conjuction with `dojo.hitch`. Calling an inherited 
+			//		hoping the use in conjuction with `dojo.hitch`. Calling an inherited
 			//		function directly via hitch() is not supported.
 			//
-			// name: String? 
+			// name: String?
 			//		The name of the method to call. If omitted, the special `arguments` passed is
 			//		used to determine the inherited function. All subsequent positional arguments
 			//		are shifted left if `name` has been omitted. (eg: args becomes name)
@@ -200,9 +200,9 @@ dojo.mixin(dojox.lang.tests.declareOld, {
 			//		object, and must be passed.
 			//
 			// newArgs: Array?
-			//		An Array of argument values to pass to the inherited function. If omitted, 
+			//		An Array of argument values to pass to the inherited function. If omitted,
 			//		the original arguments are passed (determined from the `args` variable)
-			// 
+			//
 			// example:
 			//		Simply call an inherited function with the same signature.
 			//	|	this.inherited(arguments);
diff --git a/dojox/lang/tests/docs.js b/dojox/lang/tests/docs.js
index c2fae6e..ab2f60c 100644
--- a/dojox/lang/tests/docs.js
+++ b/dojox/lang/tests/docs.js
@@ -12,16 +12,16 @@ tests.register("dojox.lang.tests.docs", [
 		t.is(!!dijit.ColorPalette.description, true);
 		dojox.lang.docs.init(); // make sure it can be called twice without any problems
 		t.is(!!dijit.ColorPalette.properties.defaultTimeout.description, true);
-		t.is(dijit.ColorPalette.properties.defaultTimeout.type, "number");	
-		t.is(dijit.ColorPalette.methods.onChange.parameters[0].type, "string");	
+		t.is(dijit.ColorPalette.properties.defaultTimeout.type, "number");
+		t.is(dijit.ColorPalette.methods.onChange.parameters[0].type, "string");
 		t.is(dijit.ColorPalette.methods.onChange.parameters[0].name, "color");
-		t.is(dijit.ColorPalette["extends"], dijit._Widget);		
+		t.is(dijit.ColorPalette["extends"], dijit._Widget);
 	},
 	function futureClassHasSchema(t){
 		dojo.require("dijit.Dialog");
 		t.is(!!dijit.Dialog.description, true);
 		t.is(!!dijit.Dialog.properties.autofocus.description, true);
-		t.is(dijit.Dialog.properties.autofocus.type, "boolean");	
+		t.is(dijit.Dialog.properties.autofocus.type, "boolean");
 	},
 	function testSchema(t){
 		
diff --git a/dojox/lang/tests/observable.js b/dojox/lang/tests/observable.js
index 3091d43..229f1d0 100644
--- a/dojox/lang/tests/observable.js
+++ b/dojox/lang/tests/observable.js
@@ -5,7 +5,7 @@ dojo.require("dojox.lang.observable");
 	tests.register("dojox.lang.tests.observable", [
 		function propertyAccessMakeObservable(t){
 			console.log("start");
-			var testStrs = []; 
+			var testStrs = [];
 			var observable = new dojox.lang.makeObservable(
 				function(obj,i){
 					testStrs.push("onRead " + i);
@@ -31,7 +31,7 @@ dojo.require("dojox.lang.observable");
 			t.assertEqual("onInvoke test,onRead foo,returned bar,onWrite foo,onRead foo,new",testStrs.join(','));
 		},
 		function propertyAccessObservable(t){
-			var testStrs = []; 
+			var testStrs = [];
 			var obj = {foo:"bar",test:function(){
 				return this.foo;
 			}};
@@ -53,7 +53,7 @@ dojo.require("dojox.lang.observable");
 		},
 		function readonlyProxy(t){
 			console.log("start");
-			var testStrs = []; 
+			var testStrs = [];
 			var obj = {foo:"bar"};
 			var newObj = dojox.lang.ReadOnlyProxy(obj);
 			testStrs.push(newObj.foo);
@@ -93,10 +93,10 @@ dojo.require("dojox.lang.observable");
 					//
 					//	item: /* object */
 					//	property: /* string */
-					//		property to look up value for	
-					// lazyCallback: /* function*/ 
+					//		property to look up value for
+					// lazyCallback: /* function*/
 					// 		not part of the API, but if you are using lazy loading properties, you may provide a callback to resume, in order to have asynchronous loading
-					var value = item[property]; 
+					var value = item[property];
 					if(value instanceof dojo.Deferred){
 						dojox.rpc._sync = !lazyCallback; // tell the service to operate synchronously (I have some concerns about the "thread" safety with FF3, as I think it does event stacking on sync calls)
 						value.addCallback(function(returned){
diff --git a/dojox/lang/tests/typed.js b/dojox/lang/tests/typed.js
index 4db1aa0..cc50436 100644
--- a/dojox/lang/tests/typed.js
+++ b/dojox/lang/tests/typed.js
@@ -20,8 +20,8 @@ dojo.require("dojox.lang.typed");
 	}));
 	var TypedClass = dojox.lang.tests.TypedClass;
 	TypedClass.properties = {
-		aString:String, 
-		self: TypedClass, 
+		aString:String,
+		self: TypedClass,
 		anInt: {type:"integer", maximum: 100, optional: true}
 	};
 	TypedClass.methods = {
@@ -118,7 +118,7 @@ dojo.require("dojox.lang.typed");
 			});
 			var AutoTypedClass = dojox.lang.tests.AutoTypedClass;
 			AutoTypedClass.properties = {
-				foo:{type:"string"} 
+				foo:{type:"string"}
 			};
 			AutoTypedClass.methods = {
 				subtract: {
diff --git a/dojox/lang/utils.js b/dojox/lang/utils.js
index a28b743..519437a 100644
--- a/dojox/lang/utils.js
+++ b/dojox/lang/utils.js
@@ -51,7 +51,7 @@ dojo.provide("dojox.lang.utils");
 			// summary: Updates an existing object in place with properties from an "source" object.
 			// target: Object: the "target" object to be updated
 			// source: Object: the "source" object, whose properties will be used to source the existed object.
-			// pattern: Array: an array of properties to be copied
+			// pattern: Object: object, whose properties will be used to pull values from the "source"
 			// conv: Boolean?: force conversion to the original type
 			if(!source || !pattern){ return target; }
 			for(var x in pattern){
diff --git a/dojox/layout/ContentPane.js b/dojox/layout/ContentPane.js
index 6fd1fcd..12e328b 100755
--- a/dojox/layout/ContentPane.js
+++ b/dojox/layout/ContentPane.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.layout.ContentPane");
 
 dojo.require("dijit.layout.ContentPane");
-dojo.require("dojox.html._base"); 
+dojo.require("dojox.html._base");
 
 dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
 	// summary:
@@ -24,7 +24,7 @@ dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
 	//		cleans content to make it less likely to generate DOM/JS errors.
 	//	description:
 	//		useful if you send ContentPane a complete page, instead of a html fragment
-	//		scans for 
+	//		scans for
 	//
 	//			* title Node, remove
 	//			* DOCTYPE tag, remove
@@ -62,14 +62,14 @@ dojo.declare("dojox.layout.ContentPane", dijit.layout.ContentPane, {
 	onExecError: function(e){
 		// summary:
 		//		event callback, called on script error or on java handler error
-		//		overide and return your own html string if you want a some text 
+		//		overide and return your own html string if you want a some text
 		//		displayed within the ContentPane
 	},
 
 	_setContent: function(cont){
 		// override dijit.layout.ContentPane._setContent, to enable path adjustments
 		
-		var setter = this._contentSetter; 
+		var setter = this._contentSetter;
 		if(! (setter && setter instanceof dojox.html._ContentSetter)) {
 			setter = this._contentSetter = new dojox.html._ContentSetter({
 				node: this.containerNode,
diff --git a/dojox/layout/DragPane.js b/dojox/layout/DragPane.js
index ed4bc20..b4254bb 100644
--- a/dojox/layout/DragPane.js
+++ b/dojox/layout/DragPane.js
@@ -2,9 +2,7 @@ dojo.provide("dojox.layout.DragPane");
 
 dojo.require("dijit._Widget");
 
-dojo.declare("dojox.layout.DragPane",
-	dijit._Widget, {
-	//
+dojo.declare("dojox.layout.DragPane", dijit._Widget, {
 	// summary: Makes a pane's content dragable by/within it's surface
 	//
 	// description:
@@ -16,34 +14,34 @@ dojo.declare("dojox.layout.DragPane",
 	//		Naturally, the behavior is to invert the axis of the drag.
 	//		Setting invert:false will make the pane drag in the same
 	//		direction as the mouse.
-	invert:true,
+	invert: true,
 	
 	postCreate: function(){
-
-		this.inherited(arguments);
-		this.connect(this.domNode,"onmousedown","_down");
-		this.connect(this.domNode,"onmouseup","_up");
+		this.connect(this.domNode, "onmousedown", "_down");
+		this.connect(this.domNode, "onmouseleave", "_up");
+		this.connect(this.domNode, "onmouseup", "_up");
 	},
 	
 	_down: function(e){
 		// summary: mousedown handler, start the dragging
 		var t = this.domNode;
-		dojo.style(t,"cursor","move");
+		e.preventDefault();
+		dojo.style(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);
-			this._mover = this.connect(t,"onmousemove","_move");
+			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");
-		this.disconnect(this._mover);
+		dojo.style(this.domNode, "cursor", "pointer");
+		this._mover && this.disconnect(this._mover);
+		delete this._mover;
 	},
 	
 	_move: function(e){
diff --git a/dojox/layout/ExpandoPane.js b/dojox/layout/ExpandoPane.js
index dfa8029..562e295 100644
--- a/dojox/layout/ExpandoPane.js
+++ b/dojox/layout/ExpandoPane.js
@@ -13,11 +13,14 @@ dojo.declare("dojox.layout.ExpandoPane",
 	// description:
 	//		Works just like a ContentPane inside of a borderContainer. Will expand/collapse on
 	//		command, and supports having Layout Children as direct descendants
-	//	
+	//
 
 	//maxHeight: "",
 	//maxWidth: "",
 	//splitter: false,
+	attributeMap: dojo.delegate(dijit.layout.ContentPane.prototype.attributeMap, {
+	        title: { node: "titleNode", type: "innerHTML" }
+	}),
 	
 	templateString: dojo.cache("dojox.layout","resources/ExpandoPane.html"),
 
@@ -35,7 +38,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 
 	// startExpanded: Boolean
 	//		Does this widget start in an open (true) or closed (false) state
-	startExpanded: true, 
+	startExpanded: true,
 
 	// previewOpacity: Float
 	//		A value from 0 .. 1 indicating the opacity to use on the container
@@ -59,17 +62,17 @@ dojo.declare("dojox.layout.ExpandoPane",
 			this.easeOut = dojo.getObject(this.easeOut);
 		}
 		if(dojo.isString(this.easeIn)){
-			this.easeIn = dojo.getObject(this.easeIn); 
+			this.easeIn = dojo.getObject(this.easeIn);
 		}
 	
 		var thisClass = "", rtl = !this.isLeftToRight();
 		if(this.region){
 			switch(this.region){
-				case "trailing" : 
+				case "trailing" :
 				case "right" :
 					thisClass = rtl ? "Left" : "Right";
 					break;
-				case "leading" : 
+				case "leading" :
 				case "left" :
 					thisClass = rtl ? "Right" : "Left";
 					break;
@@ -77,7 +80,7 @@ dojo.declare("dojox.layout.ExpandoPane",
 					thisClass = "Top";
 					break;
 				case "bottom" :
-					thisClass = "Bottom"; 
+					thisClass = "Bottom";
 					break;
 			}
 			dojo.addClass(this.domNode, "dojoxExpando" + thisClass);
@@ -132,10 +135,10 @@ dojo.declare("dojox.layout.ExpandoPane",
 	_afterResize: function(e){
 		var tmp = this._currentSize;						// the old size
 		this._currentSize = dojo.marginBox(this.domNode);	// the new size
-		var n = this._currentSize[(this._isHorizontal ? "h" : "w")] 
+		var n = this._currentSize[(this._isHorizontal ? "h" : "w")]
 		if(n > this._titleHeight){
-			if(!this._showing){	
-				this._showing = !this._showing; 
+			if(!this._showing){
+				this._showing = !this._showing;
 				this._showEnd();
 			}
 			this._showSize = n;
@@ -163,16 +166,16 @@ dojo.declare("dojox.layout.ExpandoPane",
 			dimension = isHorizontal ? "height" : "width"
 		;
 
-		showProps[dimension] = { 
+		showProps[dimension] = {
 			end: this._showSize
 		};
-		hideProps[dimension] = { 
+		hideProps[dimension] = {
 			end: this._closedSize
 		};
 		
 		this._showAnim = dojo.animateProperty(dojo.mixin(_common,{
 			easing:this.easeIn,
-			properties: showProps 
+			properties: showProps
 		}));
 		this._hideAnim = dojo.animateProperty(dojo.mixin(_common,{
 			easing:this.easeOut,
@@ -220,9 +223,9 @@ dojo.declare("dojox.layout.ExpandoPane",
 	
 	_showEnd: function(){
 		// summary: Common animation onEnd code - "unclose"
-		dojo.style(this.cwrapper, { 
+		dojo.style(this.cwrapper, {
 			opacity: 0,
-			visibility:"visible" 
+			visibility:"visible"
 		});
 		dojo.anim(this.cwrapper, {
 			opacity: this._isonlypreview ? this.previewOpacity : 1
@@ -249,21 +252,20 @@ dojo.declare("dojox.layout.ExpandoPane",
 		
 	},
 	
-	resize: function(/* Object? */newSize, /*Object?*/ currentSize){
+	resize: function(/* Object? */newSize){
 		// summary:
 		//		we aren't a layout widget, but need to act like one:
 		// newSize: Object
 		//		The size object to resize to
-		// currentSize: Object
-		//		The size of my domNode that has already been set (by BorderContainer)
 
 		if(!this._hasSizes){ this._startupSizes(newSize); }
 		
 		// compute size of container (ie, size left over after title bar)
+		var currentSize = dojo.marginBox(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");
 
 		if(newSize){
diff --git a/dojox/layout/FloatingPane.js b/dojox/layout/FloatingPane.js
index c2f87de..0797708 100644
--- a/dojox/layout/FloatingPane.js
+++ b/dojox/layout/FloatingPane.js
@@ -1,16 +1,16 @@
 dojo.provide("dojox.layout.FloatingPane");
-dojo.experimental("dojox.layout.FloatingPane"); 
+dojo.experimental("dojox.layout.FloatingPane");
 
 dojo.require("dojo.window");
 
-dojo.require("dijit._Templated"); 
-dojo.require("dijit._Widget"); 
+dojo.require("dijit._Templated");
+dojo.require("dijit._Widget");
 dojo.require("dojo.dnd.Moveable");
 
 dojo.require("dojox.layout.ContentPane");
-dojo.require("dojox.layout.ResizeHandle"); 
+dojo.require("dojox.layout.ResizeHandle");
 
-dojo.declare("dojox.layout.FloatingPane", 
+dojo.declare("dojox.layout.FloatingPane",
 	[ dojox.layout.ContentPane, dijit._Templated ],
 	{
 	// summary:
@@ -19,7 +19,7 @@ dojo.declare("dojox.layout.FloatingPane",
 	// 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] 
+	// 		provides minimize(dock) / show() and hide() methods, and resize [almost]
 	//
 	// closable: Boolean
 	//		Allow closure of this Node
@@ -47,7 +47,7 @@ dojo.declare("dojox.layout.FloatingPane",
 
 	// dockTo: DomNode?
 	//		if empty, will create private layout.Dock that scrolls with viewport
-	//		on bottom span of viewport.	
+	//		on bottom span of viewport.
 	dockTo: "",
 
 	// duration: Integer
@@ -68,7 +68,7 @@ dojo.declare("dojox.layout.FloatingPane",
 
 	// animation holders for toggle
 	_showAnim: null,
-	_hideAnim: null, 
+	_hideAnim: null,
 	// node in the dock (if docked)
 	_dockNode: null,
 
@@ -86,18 +86,18 @@ dojo.declare("dojox.layout.FloatingPane",
 	postCreate: function(){
 		this.inherited(arguments);
 		new dojo.dnd.Moveable(this.domNode,{ handle: this.focusNode });
-		//this._listener = dojo.subscribe("/dnd/move/start",this,"bringToTop"); 
+		//this._listener = dojo.subscribe("/dnd/move/start",this,"bringToTop");
 
-		if(!this.dockable){ this.dockNode.style.display = "none"; } 
-		if(!this.closable){ this.closeNode.style.display = "none"; } 
+		if(!this.dockable){ this.dockNode.style.display = "none"; }
+		if(!this.closable){ this.closeNode.style.display = "none"; }
 		if(!this.maxable){
 			this.maxNode.style.display = "none";
 			this.restoreNode.style.display = "none";
 		}
 		if(!this.resizable){
-			this.resizeHandle.style.display = "none"; 	
+			this.resizeHandle.style.display = "none";
 		}else{
-			this.domNode.style.width = dojo.marginBox(this.domNode).w + "px"; 
+			this.domNode.style.width = dojo.marginBox(this.domNode).w + "px";
 		}
 		this._allFPs.push(this);
 		this.domNode.style.position = "absolute";
@@ -118,19 +118,19 @@ dojo.declare("dojox.layout.FloatingPane",
 				this.containerNode.style.overflow = "auto";
 			}
 			
-			this._resizeHandle = new dojox.layout.ResizeHandle({ 
-				targetId: this.id, 
-				resizeAxis: this.resizeAxis 
+			this._resizeHandle = new dojox.layout.ResizeHandle({
+				targetId: this.id,
+				resizeAxis: this.resizeAxis
 			},this.resizeHandle);
 
 		}
 
-		if(this.dockable){ 
+		if(this.dockable){
 			// FIXME: argh.
-			var tmpName = this.dockTo; 
+			var tmpName = this.dockTo;
 
 			if(this.dockTo){
-				this.dockTo = dijit.byId(this.dockTo); 
+				this.dockTo = dijit.byId(this.dockTo);
 			}else{
 				this.dockTo = dijit.byId('dojoxGlobalFloatingDock');
 			}
@@ -141,23 +141,23 @@ dojo.declare("dojox.layout.FloatingPane",
 				// .dojoxDockDefault .. this is a lot. either dockto="node"
 				// and fail if node doesn't exist or make the global one
 				// once, and use it on empty OR invalid dockTo="" node?
-				if(tmpName){ 
+				if(tmpName){
 					tmpId = tmpName;
-					tmpNode = dojo.byId(tmpName); 
+					tmpNode = dojo.byId(tmpName);
 				}else{
 					tmpNode = dojo.create('div', null, dojo.body());
 					dojo.addClass(tmpNode,"dojoxFloatingDockDefault");
 					tmpId = 'dojoxGlobalFloatingDock';
 				}
 				this.dockTo = new dojox.layout.Dock({ id: tmpId, autoPosition: "south" }, tmpNode);
-				this.dockTo.startup(); 
+				this.dockTo.startup();
 			}
 			
 			if((this.domNode.style.display == "none")||(this.domNode.style.visibility == "hidden")){
 				// If the FP is created dockable and non-visible, start up docked.
 				this.minimize();
-			} 
-		} 		
+			}
+		}
 		this.connect(this.focusNode,"onmousedown","bringToTop");
 		this.connect(this.domNode,	"onmousedown","bringToTop");
 
@@ -169,9 +169,9 @@ dojo.declare("dojox.layout.FloatingPane",
 
 	setTitle: function(/* String */ title){
 		// summary: Update the Title bar with a new string
-		dojo.deprecated("pane.setTitle", "Use pane.attr('title', someTitle)", "2.0");
+		dojo.deprecated("pane.setTitle", "Use pane.set('title', someTitle)", "2.0");
 		this.set("title", title);
-		// this.setTitle = dojo.hitch(this, "setTitle") ?? 
+		// this.setTitle = dojo.hitch(this, "setTitle") ??
 	},
 		
 	close: function(){
@@ -180,7 +180,7 @@ dojo.declare("dojox.layout.FloatingPane",
 		dojo.unsubscribe(this._listener);
 		this.hide(dojo.hitch(this,function(){
 			this.destroyRecursive();
-		})); 
+		}));
 	},
 
 	hide: function(/* Function? */ callback){
@@ -188,9 +188,9 @@ dojo.declare("dojox.layout.FloatingPane",
 		dojo.fadeOut({
 			node:this.domNode,
 			duration:this.duration,
-			onEnd: dojo.hitch(this,function() { 
+			onEnd: dojo.hitch(this,function() {
 				this.domNode.style.display = "none";
-				this.domNode.style.visibility = "hidden"; 
+				this.domNode.style.visibility = "hidden";
 				if(this.dockTo && this.dockable){
 					this.dockTo._positionDock(null);
 				}
@@ -205,27 +205,28 @@ dojo.declare("dojox.layout.FloatingPane",
 		// summary: Show the FloatingPane
 		var anim = dojo.fadeIn({node:this.domNode, duration:this.duration,
 			beforeBegin: dojo.hitch(this,function(){
-				this.domNode.style.display = ""; 
+				this.domNode.style.display = "";
 				this.domNode.style.visibility = "visible";
 				if (this.dockTo && this.dockable) { this.dockTo._positionDock(null); }
 				if (typeof callback == "function") { callback(); }
 				this._isDocked = false;
-				if (this._dockNode) { 
+				if (this._dockNode) {
 					this._dockNode.destroy();
 					this._dockNode = null;
 				}
 			})
 		}).play();
 		this.resize(dojo.coords(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(dojo.hitch(this,"_dock")); }
 	},
 
 	maximize: function(){
-		// summary: Make this FloatingPane full-screen (viewport)	
+		// summary: Make this FloatingPane full-screen (viewport)
 		if(this._maximized){ return; }
 		this._naturalState = dojo.position(this.domNode);
 		if(this._isDocked){
@@ -242,7 +243,7 @@ dojo.declare("dojox.layout.FloatingPane",
 			this.resize(this._naturalState);
 			dojo.removeClass(this.focusNode,"floatingPaneMaximized");
 			this._maximized = false;
-		}	
+		}
 	},
 
 	_dock: function(){
@@ -261,7 +262,7 @@ dojo.declare("dojox.layout.FloatingPane",
 		var dns = this.domNode.style;
 		if("t" in dim){ dns.top = dim.t + "px"; }
 		if("l" in dim){ dns.left = dim.l + "px"; }
-		dns.width = dim.w + "px"; 
+		dns.width = dim.w + "px";
 		dns.height = dim.h + "px";
 
 		// Now resize canvas
@@ -282,7 +283,7 @@ dojo.declare("dojox.layout.FloatingPane",
 			this._allFPs,
 			function(i){
 				return i !== this;
-			}, 
+			},
 		this);
 		windows.sort(function(a, b){
 			return a.domNode.style.zIndex - b.domNode.style.zIndex;
@@ -327,9 +328,9 @@ dojo.declare("dojox.layout.Dock",
 		// summary: Instert a dockNode refernce into the dock
 		
 		var div = dojo.create('li', null, this.containerNode),
-			node = new dojox.layout._DockNode({ 
+			node = new dojox.layout._DockNode({
 				title: refNode.title,
-				paneRef: refNode 
+				paneRef: refNode
 			}, div)
 		;
 		node.startup();
@@ -352,7 +353,7 @@ dojo.declare("dojox.layout.Dock",
 	},
 	
 	_positionDock: function(/* Event? */e){
-		if(!this._inPositioning){	
+		if(!this._inPositioning){
 			if(this.autoPosition == "south"){
 				// Give some time for scrollbars to appear/disappear
 				setTimeout(dojo.hitch(this, function() {
@@ -379,7 +380,7 @@ dojo.declare("dojox.layout._DockNode",
 	//		which pane is docked.
 	//
 	// title: String
-	// 		Shown in dock icon. should read parent iconSrc?	
+	// 		Shown in dock icon. should read parent iconSrc?
 	title: "",
 
 	// paneRef: Widget
@@ -396,7 +397,6 @@ dojo.declare("dojox.layout._DockNode",
 		// summary: remove this dock item from parent dock, and call show() on reffed floatingpane
 		this.paneRef.show();
 		this.paneRef.bringToTop();
-		if(!this.paneRef.isLoaded){ this.paneRef.refresh(); }
 		this.destroy();
 	}
 
diff --git a/dojox/layout/GridContainer.js b/dojox/layout/GridContainer.js
index 130b3d1..36a5a60 100644
--- a/dojox/layout/GridContainer.js
+++ b/dojox/layout/GridContainer.js
@@ -333,7 +333,7 @@ dojo.declare(
 		var d = e.pageX - this._initX;
 		if(d == 0){ return; }
 
-		if(!(this._currentColumnWidth + d < this._currentMinCol || 
+		if(!(this._currentColumnWidth + d < this._currentMinCol ||
 				this._nextColumnWidth - d < this._nextMinCol)){
 
 			this._currentColumnWidth += d;
@@ -519,7 +519,7 @@ dojo.declare(
 				if(this.isRightFixed){
 					index = length - 1;
 					grid.splice(index, 0, {
-						'node': grid[index].node.parentNode.insertBefore(node, grid[index].node) 
+						'node': grid[index].node.parentNode.insertBefore(node, grid[index].node)
 					});
 				}
 				else{
diff --git a/dojox/layout/GridContainerLite.js b/dojox/layout/GridContainerLite.js
index d783878..5e38d5b 100644
--- a/dojox/layout/GridContainerLite.js
+++ b/dojox/layout/GridContainerLite.js
@@ -54,7 +54,7 @@ dojo.declare(
 	// 	|	});
 	
 	//	autoRefresh: Boolean
-	//		Enable the refresh of registered areas on drag start. 
+	//		Enable the refresh of registered areas on drag start.
 	autoRefresh: true,
 
 
@@ -174,6 +174,10 @@ dojo.declare(
 			if(widget.resize && dojo.isFunction(widget.resize)){
 				widget.resize();
 			}
+
+			// 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;
@@ -321,7 +325,7 @@ dojo.declare(
 		i = 0;
 		while(i < this.nbZones){
 			// Add the parameter accept in each zone used by AreaManager
-			// (see method dojox.mdnd.AreaManager:registerByNode)			
+			// (see method dojox.mdnd.AreaManager:registerByNode)
 			this._grid.push({
 				'node': dojo.create("td", {
 					'class': "gridContainerZone",
@@ -335,6 +339,12 @@ dojo.declare(
 			i++;
 		}
 	},
+	
+	_getZonesAttr: function(){
+		// summary:
+		//   return array of zone (domNode)
+		return dojo.query(".gridContainerZone",  this.containerNode);
+	},
 
 	enableDnd: function(){
 		// summary:
@@ -442,6 +452,7 @@ dojo.declare(
 				dojo.attr(child.domNode, "tabIndex", "0");
 			}
 		}
+		child.set("column", column);
 		return child; // Widget
 	},
 
@@ -490,7 +501,7 @@ dojo.declare(
 	_setColWidthsAttr: function(value){
 		this.colWidths = dojo.isString(value) ? value.split(",") : (dojo.isArray(value) ? value : [value]);
 		
-		if(this._started){ 
+		if(this._started){
 			this._updateColumnsWidth();
 		}
 	},
diff --git a/dojox/layout/RadioGroup.js b/dojox/layout/RadioGroup.js
index 28bb986..14dfefe 100644
--- a/dojox/layout/RadioGroup.js
+++ b/dojox/layout/RadioGroup.js
@@ -6,13 +6,13 @@ dojo.experimental("dojox.layout.RadioGroup");
 //	attached to :hover of the Buttons created.
 //
 //	FIXME: take the Buttons out of the root template, and allow layoutAlign or similar attrib to use a different
-//	template, or build the template dynamically? 
+//	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.require("dojo.fx.easing");
 
 dojo.declare("dojox.layout.RadioGroup",
 	[dijit.layout.StackContainer,dijit._Templated],
@@ -50,16 +50,15 @@ dojo.declare("dojox.layout.RadioGroup",
 		this._buttons = this._children.length;
 		this._size = dojo.coords(this.containerNode);
 		if(this.hasButtons){
-			dojo.style(this.buttonHolder,"display","block");
+			dojo.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");
 		if(this.hasButtons){
 			
-			dojo.style(child.domNode,"position","absolute");
-			
 			var tmp = this.buttonNode.appendChild(dojo.create('td'));
 			var n = dojo.create("div", null, tmp),
 				_Button = dojo.getObject(this.buttonClass),
@@ -155,11 +154,11 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 	dojox.layout.RadioGroup,
 	{
 	// summary: A Sliding Radio Group
-	// description: 
+	// description:
 	//		An extension on a stock RadioGroup widget, sliding the pane
-	//		into view from being hidden. The entry direction is randomized 
+	//		into view from being hidden. The entry direction is randomized
 	//		on each view
-	//		
+	//
 
 	// easing: Function
 	//	A hook to override the default easing of the pane slides.
@@ -180,7 +179,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 		
 		if(!this._size){ return; } // FIXME: is there a real "size" floating around always?
 		
-		// there should be a contest: obfuscate this function as best you can. 
+		// there should be a contest: obfuscate this function as best you can.
 		var rA = true, rB = true;
 		switch(page.slideFrom){
 			case "bottom" : rB = !rB; break;
@@ -193,7 +192,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 				break;
 		}
 		var prop = rA ? "top" : "left",
-			val = (rB ? "-" : "") + (this._size[rA ? "h" : "w" ] + 20) + "px";	
+			val = (rB ? "-" : "") + (this._size[rA ? "h" : "w" ] + 20) + "px";
 			
 		dojo.style(page.domNode, prop, val);
 
@@ -208,7 +207,7 @@ dojo.declare("dojox.layout.RadioGroupSlide",
 		page.selected = true;
 
 		dojo.style(page.domNode,{
-			zIndex: this.zTop, display:"" 
+			zIndex: this.zTop, display:""
 		})
 
 		if(this._anim && this._anim.status()=="playing"){
@@ -250,8 +249,8 @@ dojo.declare("dojox.layout._RadioButton",
 	{
 	// summary: The Buttons for a RadioGroup
 	//
-	// description: A private widget used to manipulate the StackContainer (RadioGroup*). Don't create directly. 
-	//	
+	// description: A private widget used to manipulate the StackContainer (RadioGroup*). Don't create directly.
+	//
 	
 	// label: String
 	//	the Text Label of the button
@@ -293,5 +292,5 @@ dojo.extend(dijit._Widget,{
 	//		the ContentPane to slide in from a set direction. Defaults
 	//		to "random", or specify one of "top", "left", "right", "bottom"
 	//		to slideFrom top, left, right, or bottom.
-	slideFrom: "random"	
+	slideFrom: "random"
 })
diff --git a/dojox/layout/ResizeHandle.js b/dojox/layout/ResizeHandle.js
index 03b76bd..83adc52 100644
--- a/dojox/layout/ResizeHandle.js
+++ b/dojox/layout/ResizeHandle.js
@@ -1,9 +1,9 @@
 dojo.provide("dojox.layout.ResizeHandle");
-dojo.experimental("dojox.layout.ResizeHandle"); 
+dojo.experimental("dojox.layout.ResizeHandle");
 
 dojo.require("dijit._Widget");
-dojo.require("dijit._Templated"); 
-dojo.require("dojo.fx"); 
+dojo.require("dijit._Templated");
+dojo.require("dojo.fx");
 dojo.require("dojo.window");
 
 dojo.declare("dojox.layout.ResizeHandle",
@@ -22,19 +22,19 @@ dojo.declare("dojox.layout.ResizeHandle",
 	
 	// targetContainer: DomNode
 	//	over-ride targetId and attch this handle directly to a reference of a DomNode
-	targetContainer: null, 
+	targetContainer: null,
 	
 	// resizeAxis: String
-	//	one of: x|y|xy limit resizing to a single axis, default to xy ... 
+	//	one of: x|y|xy limit resizing to a single axis, default to xy ...
 	resizeAxis: "xy",
 	
 	// activeResize: Boolean
-	// 	if true, node will size realtime with mouse movement, 
+	// 	if true, node will size realtime with mouse movement,
 	//	if false, node will create virtual node, and only resize target on mouseUp
 	activeResize: false,
 	
 	// activeResizeClass: String
-	//	css class applied to virtual resize node. 
+	//	css class applied to virtual resize node.
 	activeResizeClass: "dojoxResizeHandleClone",
 	
 	// animateSizing: Boolean
@@ -43,12 +43,12 @@ dojo.declare("dojox.layout.ResizeHandle",
 	animateSizing: true,
 	
 	// animateMethod: String
-	// 	one of "chain" or "combine" ... visual effect only. combine will "scale" 
+	// 	one of "chain" or "combine" ... visual effect only. combine will "scale"
 	// 	node to size, "chain" will alter width, then height
 	animateMethod: "chain",
 
 	// animateDuration: Integer
-	//	time in MS to run sizing animation. if animateMethod="chain", total animation 
+	//	time in MS to run sizing animation. if animateMethod="chain", total animation
 	//	playtime is 2*animateDuration
 	animateDuration: 225,
 
@@ -61,27 +61,27 @@ dojo.declare("dojox.layout.ResizeHandle",
 	minWidth: 100,
 
 	// constrainMax: Boolean
-	//	Toggle if this widget cares about the maxHeight and maxWidth 
-	//	parameters. 
+	//	Toggle if this widget cares about the maxHeight and maxWidth
+	//	parameters.
 	constrainMax: false,
 
 	// maxHeight: Integer
-	//	Largest height size in px the resize node can become. 
-	maxHeight:0, 
+	//	Largest height size in px the resize node can become.
+	maxHeight:0,
 	
 	// maxWidth: Integer
 	//	Largest width size in px the reize node can become.
 	maxWidth:0,
 
 	// fixedAspect: Boolean
-	//		Toggle to enable this widget to maintain the aspect 
-	//		ratio of the attached node. 
+	//		Toggle to enable this widget to maintain the aspect
+	//		ratio of the attached node.
 	fixedAspect: false,
 
 	// intermediateChanges: Boolean
 	//		Toggle to enable/disable this widget from firing onResize
 	//		events at every step of a resize. If `activeResize` is true,
-	//		and this is false, onResize only fires _after_ the drop 
+	//		and this is false, onResize only fires _after_ the drop
 	//		operation. Animated resizing is not affected by this setting.
 	intermediateChanges: false,
 
@@ -98,21 +98,21 @@ dojo.declare("dojox.layout.ResizeHandle",
 	postCreate: function(){
 		// summary: setup our one major listener upon creation
 		this.connect(this.resizeHandle, "onmousedown", "_beginSizing");
-		if(!this.activeResize){ 
+		if(!this.activeResize){
 			// there shall be only a single resize rubberbox that at the top
 			// 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');
 			if(!this._resizeHelper){
-				this._resizeHelper = new dojox.layout._ResizeHelper({ 
+				this._resizeHelper = new dojox.layout._ResizeHelper({
 						id: 'dojoxGlobalResizeHelper'
 				}).placeAt(dojo.body());
 				dojo.addClass(this._resizeHelper.domNode, this.activeResizeClass);
 			}
-		}else{ this.animateSizing = false; } 	
+		}else{ this.animateSizing = false; }
 
-		if(!this.minSize){ 
+		if(!this.minSize){
 			this.minSize = { w: this.minWidth, h: this.minHeight };
 		}
 		
@@ -122,20 +122,20 @@ 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 = dojo.partial(dojo.addClass, this.resizeHandle);
 		switch(this.resizeAxis.toLowerCase()){
-			case "xy" : 
-				this._resizeX = this._resizeY = true; 
+			case "xy" :
+				this._resizeX = this._resizeY = true;
 				// FIXME: need logic to determine NW or NE class to see
 				// based on which [todo] corner is clicked
-				addClass("dojoxResizeNW"); 
-				break; 
-			case "x" : 
-				this._resizeX = true; 
+				addClass("dojoxResizeNW");
+				break;
+			case "x" :
+				this._resizeX = true;
 				addClass("dojoxResizeW");
 				break;
-			case "y" : 
-				this._resizeY = true; 
+			case "y" :
+				this._resizeY = true;
 				addClass("dojoxResizeN");
 				break;
 		}
@@ -165,7 +165,7 @@ dojo.declare("dojox.layout.ResizeHandle",
 		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);  
+		var mb = this.targetWidget ? dojo.marginBox(this.targetDomNode) : dojo.contentBox(this.targetDomNode);
 		this.startSize  = { w:mb.w, h:mb.h };
 		
 		if(this.fixedAspect){
@@ -181,15 +181,15 @@ dojo.declare("dojox.layout.ResizeHandle",
 			this._aspect[max] = val;
 		}
 
-		this._pconnects = []; 
-		this._pconnects.push(dojo.connect(dojo.doc,"onmousemove",this,"_updateSizing")); 
+		this._pconnects = [];
+		this._pconnects.push(dojo.connect(dojo.doc,"onmousemove",this,"_updateSizing"));
 		this._pconnects.push(dojo.connect(dojo.doc,"onmouseup", this, "_endSizing"));
 		
-		dojo.stopEvent(e); 
+		dojo.stopEvent(e);
 	},
 
 	_updateSizing: function(/*Event*/ e){
-		// summary: called when moving the ResizeHandle ... determines 
+		// summary: called when moving the ResizeHandle ... determines
 		//	new size based on settings/position and sets styles.
 
 		if(this.activeResize){
@@ -212,7 +212,7 @@ dojo.declare("dojox.layout.ResizeHandle",
 			// sometimes you get an exception accessing above fields...
 			return false;
 		}
-		this._activeResizeLastEvent = e; 
+		this._activeResizeLastEvent = e;
 
 		var dx = (this.isLeftToRight()? this.startPoint.x - e.clientX: e.clientX - this.startPoint.x),
 			dy = this.startPoint.y - e.clientY,
@@ -265,21 +265,21 @@ dojo.declare("dojox.layout.ResizeHandle",
 		var tmp = this._getNewCoords(e);
 		if(tmp === false){ return; }
 
-		if(this.targetWidget && dojo.isFunction(this.targetWidget.resize)){ 
+		if(this.targetWidget && dojo.isFunction(this.targetWidget.resize)){
 			this.targetWidget.resize(tmp);
 		}else{
 			if(this.animateSizing){
 				var anim = dojo.fx[this.animateMethod]([
 					dojo.animateProperty({
 						node: this.targetDomNode,
-						properties: { 
-							width: { start: this.startSize.w, end: tmp.w } 
-						},	
+						properties: {
+							width: { start: this.startSize.w, end: tmp.w }
+						},
 						duration: this.animateDuration
 					}),
 					dojo.animateProperty({
 						node: this.targetDomNode,
-						properties: { 
+						properties: {
 							height: { start: this.startSize.h, end: tmp.h }
 						},
 						duration: this.animateDuration
@@ -295,7 +295,7 @@ dojo.declare("dojox.layout.ResizeHandle",
 		}
 		if(this.intermediateChanges){
 			this.onResize(e);
-		}	
+		}
 	},
 
 	_endSizing: function(/*Event*/ e){
@@ -314,9 +314,9 @@ dojo.declare("dojox.layout.ResizeHandle",
 	},
 	
 	onResize: function(e){
-		// summary: Stub fired when sizing is done. Fired once 
-		//	after resize, or often when `intermediateChanges` is 
-		//	set to true. 
+		// summary: Stub fired when sizing is done. Fired once
+		//	after resize, or often when `intermediateChanges` is
+		//	set to true.
 	}
 	
 });
@@ -324,22 +324,22 @@ dojo.declare("dojox.layout.ResizeHandle",
 dojo.declare("dojox.layout._ResizeHelper",
 	dijit._Widget,
 	{
-	// summary: A global private resize helper shared between any 
+	// summary: A global private resize helper shared between any
 	//		`dojox.layout.ResizeHandle` with activeSizing off.
 	
 	show: function(){
 		// summary: show helper to start resizing
-		dojo.fadeIn({ 
-			node: this.domNode, 
-			duration: 120, 
+		dojo.fadeIn({
+			node: this.domNode,
+			duration: 120,
 			beforeBegin: function(n){ dojo.style(n, "display", "") }
 		}).play();
 	},
 	
 	hide: function(){
 		// summary: hide helper after resizing is complete
-		dojo.fadeOut({ 
-			node: this.domNode, 
+		dojo.fadeOut({
+			node: this.domNode,
 			duration: 250,
 			onEnd: function(n){ dojo.style(n, "display", "none") }
 		}).play();
diff --git a/dojox/layout/RotatorContainer.js b/dojox/layout/RotatorContainer.js
index 8462edc..33718de 100755
--- a/dojox/layout/RotatorContainer.js
+++ b/dojox/layout/RotatorContainer.js
@@ -7,7 +7,7 @@ dojo.require("dijit._Widget");
 dojo.require("dijit._Templated");
 dojo.require("dijit._Contained");
 
-dojo.declare("dojox.layout.RotatorContainer", 
+dojo.declare("dojox.layout.RotatorContainer",
 	[dijit.layout.StackContainer, dijit._Templated], {
 	// summary:
 	//		Extends a StackContainer to automatically transition between children
@@ -40,7 +40,7 @@ dojo.declare("dojox.layout.RotatorContainer",
 
 	// showTabs: Boolean
 	//		Sets the display of the tabs.  The tabs are actually a StackController.
-	//		The child's title is used for the tab's label. 
+	//		The child's title is used for the tab's label.
 	showTabs: true,
 
 	// transitionDelay: int
@@ -432,8 +432,8 @@ dojo.declare("dojox.layout.RotatorPager", [dijit._Widget, dijit._Templated, diji
 	_state: function(/*boolean*/playing){
 		// summary: Updates the display of the play/pause button
 		if(this.playPause && this.playPause.checked != playing){
-			this.playPause.attr("label", playing ? "Pause" : "Play");
-			this.playPause.attr("checked", playing);
+			this.playPause.set("label", playing ? "Pause" : "Play");
+			this.playPause.set("checked", playing);
 		}
 	},
 
diff --git a/dojox/layout/ScrollPane.js b/dojox/layout/ScrollPane.js
index e9c2c80..2fb4f5d 100644
--- a/dojox/layout/ScrollPane.js
+++ b/dojox/layout/ScrollPane.js
@@ -18,7 +18,7 @@ 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 -->
@@ -34,7 +34,7 @@ dojo.declare("dojox.layout.ScrollPane",
 	_offset: 15,
 	
 	// orientation: String
-	//		either "horizontal" or "vertical" for scroll orientation. 
+	//		either "horizontal" or "vertical" for scroll orientation.
 	orientation: "vertical",
 	
 	// alwaysShow: Boolean
@@ -111,19 +111,19 @@ dojo.declare("dojox.layout.ScrollPane",
 		}
 		dojo.style(this.wrapper,"overflow","hidden");
 	
-	},	
+	},
 	
 	_set: function(/* Float */n){
 		if(!this._size){ return; }
-		// summary: set the pane's scroll offset, and position the virtual scroll helper 
+		// 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");    
+		dojo.style(this.helper, this._edge, Math.floor(this._helpLine.getValue(n)) + "px");
 	},
 	
 	_calc: function(/* Event */e){
 		// summary: calculate the relative offset of the cursor over the node, and call _set
 		if(!this._lo){ this.resize(); }
-		this._set(this._vertical ? 
+		this._set(this._vertical ?
 			((e.pageY - this._lo.y) / this._lo.h) :
 			((e.pageX - this._lo.x) / this._lo.w)
 		);
@@ -131,8 +131,8 @@ dojo.declare("dojox.layout.ScrollPane",
 	
 	_enter: function(e){
 		if(this._hideAnim){
-			if(this._hideAnim.status() == "playing"){ 
-				this._hideAnim.stop(); 
+			if(this._hideAnim.status() == "playing"){
+				this._hideAnim.stop();
 			}
 			this._showAnim.play();
 		}
diff --git a/dojox/layout/TableContainer.js b/dojox/layout/TableContainer.js
index e6b9ebd..f9e112f 100644
--- a/dojox/layout/TableContainer.js
+++ b/dojox/layout/TableContainer.js
@@ -5,7 +5,7 @@ dojo.require("dijit.layout._LayoutWidget");
 dojo.declare("dojox.layout.TableContainer",
 	dijit.layout._LayoutWidget,
 	{
-	// summary: 
+	// summary:
 	//		A container that lays out its child widgets in a table layout.
 	//
 	// description:
@@ -29,7 +29,7 @@ dojo.declare("dojox.layout.TableContainer",
 	
 	// labelWidth: Number|String
 	//		Defines the width of a label.  If the value is a number, it is
-	//		treated as a pixel value.  The other valid value is a percentage, 
+	//		treated as a pixel value.  The other valid value is a percentage,
 	//		e.g. "50%"
 	labelWidth: "100",
 
@@ -38,8 +38,8 @@ dojo.declare("dojox.layout.TableContainer",
 	showLabels: true,
 
 	// orientation: String
-	//		Either "horiz" or "vert" for label orientation. 
-	orientation: "horiz", 
+	//		Either "horiz" or "vert" for label orientation.
+	orientation: "horiz",
 	
 	// spacing: Number
 	//		The cell spacing to apply to the table.
@@ -48,7 +48,7 @@ dojo.declare("dojox.layout.TableContainer",
 	// customClass: String
 	//		A CSS class that will be applied to child elements.  For example, if
 	//		the class is "myClass", the table will have "myClass-table" applied to it,
-	//		each label TD will have "myClass-labelCell" applied, and each 
+	//		each label TD will have "myClass-labelCell" applied, and each
 	//		widget TD will have "myClass-valueCell" applied.
 	customClass: "",
 
@@ -56,13 +56,13 @@ dojo.declare("dojox.layout.TableContainer",
 		this.inherited(arguments);
 		this._children = [];
 		
-		// If the orientation, customClass or cols attributes are changed, 
+		// If the orientation, customClass or cols attributes are changed,
 		// layout the widgets again.
-		dojo.connect(this, "attr", dojo.hitch(this, function(name, value){
+		this.connect(this, "set", function(name, value){
 			if(value && (name == "orientation" || name == "customClass" || name == "cols")) {
 				this.layout();
 			}
-		}))
+		})
 	},
 
 	startup: function() {
@@ -92,7 +92,7 @@ dojo.declare("dojox.layout.TableContainer",
 	},
 
 	resize: function(){
-		// summary: 
+		// summary:
 		//		Resizes all children.  This widget itself
 		//		does not resize, as it takes up 100% of the
 		//		available width.
@@ -104,7 +104,7 @@ dojo.declare("dojox.layout.TableContainer",
 	},
 
 	layout: function(){
-		// summary: 
+		// summary:
 		//		Lays out the child widgets.
 		if(!this._initialized){
 			return;
@@ -165,7 +165,7 @@ dojo.declare("dojox.layout.TableContainer",
 			var colspan = child.colspan || 1;
 			
 			if(colspan > 1) {
-				colspan = this.showLabels ? 
+				colspan = this.showLabels ?
 					Math.min(maxCols - 1, colspan * 2 -1): Math.min(maxCols, colspan);
 			}
 
@@ -189,19 +189,19 @@ dojo.declare("dojox.layout.TableContainer",
 				else {
 					// Add the custom label class to the label cell
 					addCustomClass(labelCell, "labelCell");
-					var labelProps = {"for": child.attr("id")};
+					var labelProps = {"for": child.get("id")};
 					var label = dojo.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", 
-							String(this.labelWidth).indexOf("%") < 0 
+						dojo.style(labelCell, "width",
+							String(this.labelWidth).indexOf("%") < 0
 								? this.labelWidth + "px" : this.labelWidth);
 					}
 
-					label.innerHTML = child.attr("label") || child.attr("title");
+					label.innerHTML = child.get("label") || child.get("title");
 				}
 			}
 			var childCell;
@@ -246,7 +246,7 @@ dojo.declare("dojox.layout.TableContainer",
 	},
 	
 	_setSpacingAttr: function(value) {
-		// summary: 
+		// summary:
 		//		Sets the spacing attribute.
 		this.spacing = value;
 		if(this.table) {
diff --git a/dojox/layout/ToggleSplitter.js b/dojox/layout/ToggleSplitter.js
index 0a9337c..0a2ba63 100644
--- a/dojox/layout/ToggleSplitter.js
+++ b/dojox/layout/ToggleSplitter.js
@@ -1,11 +1,12 @@
-dojo.provide("dojox.layout.ToggleSplitter");
-dojo.experimental("dojox.layout.ToggleSplitter"); 
+define("dojox/layout/ToggleSplitter", ["dojo", "dojox"], function(dojo, dojox) {
+
+dojo.experimental("dojox.layout.ToggleSplitter");
 
 dojo.require("dijit.layout.BorderContainer");
 
 dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 {
-	// summary: 
+	// summary:
 	//		A draggable and toggle-to-close/open spacer between two items in a BorderContainer
 	//
 	// description:
@@ -21,7 +22,7 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 
 	// open: Boolean
 	//	the initial and current state of the splitter (and its attached pane)
-	open: true, 
+	open: true,
 
 	// closedThreshold: Integer
 	//	how small the attached pane can be before its considered closed
@@ -35,30 +36,30 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 	//	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" waiRole="separator"><div dojoAttachPoint="toggleNode" class="dijitSplitterThumb dojoxToggleSplitterIcon"></div></div>',
+	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; 
+		this._started = false;
 
 		this.inherited(arguments);
 		
 		// add a region css hook
-		var region = this.region; 
+		var region = this.region;
 		dojo.addClass(this.domNode, "dojoxToggleSplitter"+region.charAt(0).toUpperCase() + region.substring(1));
 
-		// hook up double-clicks to toggle the splitter - 
+		// hook up double-clicks to toggle the splitter -
 		this.connect(this, "onDblClick", "_toggleMe");
 
-	}, 
+	},
 	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 paneNode = this.child.domNode,
 			intPaneSize = dojo.style(paneNode, (this.horizontal ? "height" : "width"));
 		
-		// creation of splitters is an opaque process in BorderContainer, 
+		// 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){
@@ -79,7 +80,7 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 		this._openStyleProps = this._getStyleProps(paneNode, true);
 
 		// update state
-		this._started = true; 
+		this._started = true;
 		this.set("open", this.open);
 
 		return this;
@@ -87,15 +88,15 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 	_onMouseUp: function(evt){
 		dojo.disconnect(this._onMoveHandle);
 		dojo.disconnect(this._onUpHandle);
-		delete this._onMoveHandle; 
+		delete this._onMoveHandle;
 		delete this._onUpHandle;
-		delete this._startPosn; 
+		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 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
@@ -104,12 +105,12 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 		}
 	},
 	_onMouseDown: function(evt){
-		// summary: 
+		// summary:
 		// 	handle mousedown events from the domNode
 		if(!this.open){
-			// ignore mousedown while closed 
+			// ignore mousedown while closed
 			// - this has the effect of preventing dragging while closed, which is the prefered behavior (for now)
-			return; 
+			return;
 		}
 		// Mousedown can fire more than once (!)
 		// ..so check before connecting
@@ -117,25 +118,25 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 			this._onUpHandle = dojo.connect(dojo.body(), "onmouseup", this, "_onMouseUp");
 		}
 		if(!this._onMoveHandle){
-			this._startPosn = this.horizontal ? evt.clientY : evt.clientX; 
+			this._startPosn = this.horizontal ? evt.clientY : evt.clientX;
 			// start listening for mousemove
 			this._onMoveHandle = dojo.connect(dojo.body(), "onmousemove", this, "_onPrelimMouseMove");
 		}
-	}, 
+	},
 	_handleOnChange: function(){
 		// summary
 		// 	effect the state change with the new value of this.open
 
 		// TODO: animate the open/close
 		
-		var paneNode = this.child.domNode, 
+		var paneNode = this.child.domNode,
 			openProps,
-			dim = this.horizontal ? "height" : "width"; 
+			dim = this.horizontal ? "height" : "width";
 
 		if(this.open){
 			// change to open state
 			var styleProps = dojo.mixin({
-				display: "block", 
+				display: "block",
 				overflow: "auto",
 				visibility: "visible"
 			}, this._openStyleProps);
@@ -149,7 +150,7 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 		} else {
 			// change to closed state
 			// FIXME: this wont work in a drag-to-closed scenario
-			var paneStyle  = dojo.getComputedStyle(paneNode); 
+			var paneStyle  = dojo.getComputedStyle(paneNode);
 			
 			openProps = this._getStyleProps(paneNode, true, paneStyle);
 			var closedProps = this._getStyleProps(paneNode, false, paneStyle);
@@ -164,13 +165,13 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 	},
 	
 	_getStyleProps: function(paneNode, open, paneStyle){
-		// summary: 
-		//	create an object with the style property name: values 
+		// summary:
+		//	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 = {}, 
+		var styleProps = {},
 			dim = this.horizontal ? "height" : "width";
 			
 		styleProps["overflow"] = (open) ? paneStyle["overflow"] : "hidden";
@@ -184,12 +185,12 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 		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]; 
+				var fullname = pname+edgeNames[i];
 				if(pname=="border"){
 					pname+="Width";
 				}
 				if(undefined !== paneStyle[fullname]){
-					styleProps[fullname] = (open) ? 
+					styleProps[fullname] = (open) ?
 						paneStyle[fullname] : 0;
 				}
 			}
@@ -198,7 +199,7 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 	},
 	
 	_setStateClass: function(){
-		// sumamry: 
+		// sumamry:
 		//	apply the appropriate classes for the current open state
 		if(this.open){
 			dojo.removeClass(this.domNode, "dojoxToggleSplitterClosed");
@@ -213,10 +214,10 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 		}
 	},
 	_setOpenAttr: function(/*Boolean*/ value){
-		// summary: 
+		// summary:
 		// 	setter for the open property
 		if(!this._started) {
-			return; 
+			return;
 		}
 		this.open = value;
 		this._handleOnChange(value, true);
@@ -231,7 +232,7 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 	},
 
 	_toggleMe: function(evt){
-		// summary: 
+		// summary:
 		// 	event handle, toggle the open state
 		if(evt){
 			dojo.stopEvent(evt);
@@ -240,7 +241,7 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 	},
 
 	_onKeyPress: function(/*Event*/ e){
-		this.inherited(arguments); 
+		this.inherited(arguments);
 		// TODO: add support for space, enter to cause toggle
 	}
 
@@ -250,12 +251,14 @@ dojo.declare("dojox.layout.ToggleSplitter", [ dijit.layout._Splitter ],
 // 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, 
+	toggleSplitterOpen: true,
 	
 	// toggleSplitterClosedThreshold: Integer
-	toggleSplitterClosedThreshold: 5, 
+	toggleSplitterClosedThreshold: 5,
 
 	// toggleSplitterClosedThreshold: String
 	// 		a css size value (e.g. "100px")
 	toggleSplitterOpenSize: ""
+});
+
 });
\ No newline at end of file
diff --git a/dojox/layout/dnd/PlottedDnd.js b/dojox/layout/dnd/PlottedDnd.js
index 3438f7b..97af13b 100644
--- a/dojox/layout/dnd/PlottedDnd.js
+++ b/dojox/layout/dnd/PlottedDnd.js
@@ -28,7 +28,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 		//Initialize the params to calculate offset
   		this.isOffset = (params.isOffset)?true:false;
   		this.offsetDrag = (params.offsetDrag) ? params.offsetDrag : {x:0,y:0};
-		this.hideSource = params.hideSource ? params.hideSource : true;  
+		this.hideSource = params.hideSource ? params.hideSource : true;
 		this._drop = this.dropIndicator.create();
 		
 	},
@@ -54,20 +54,20 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 		if(!this.withHandles){ return true; }
 		for(var node = (e.target); node && node != this.node; node = node.parentNode){
 			if(dojo.hasClass(node, this.defaultHandleClass)){
-				return true;	
+				return true;
 			}
 		}
 		return false;	// Boolean
 	},
 	
 	setDndItemSelectable: function(/*Node*/node, /*Boolean*/isSelectable) {
-		// summary: set an item as selectable	
+		// summary: set an item as selectable
 		for(var _node = node; _node && node != this.node; _node = _node.parentNode) {
 			if (dojo.hasClass(_node,"dojoDndItem")) {
 				dojo.setSelectable(_node, isSelectable);
 				return;
 			}
-		}	
+		}
 	},
 	
 	getDraggedWidget: function(/*Node*/node) {
@@ -80,7 +80,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	isAccepted: function(/*Node*/ node) {
-		// summary: test if this node can be accepted	
+		// summary: test if this node can be accepted
 		var _dndType = (node) ? node.getAttribute("dndtype") : null;
 		return (_dndType && _dndType in this.accept);
 	},
@@ -109,7 +109,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 
 	onDndCancel:function(){
-		// summary: Called to cancel the DnD operation.	
+		// summary: Called to cancel the DnD operation.
 		var m = dojo.dnd.manager();
 		if(m.source == this && this.hideSource){
 			var nodes = this.getSelectedNodes();
@@ -122,12 +122,12 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	onDndDrop: function(source,nodes,copy,target) {
-		// summary: Called to finish the DnD operation	
+		// summary: Called to finish the DnD operation
 		try{
-			if(!this.isAccepted(nodes[0])){ 
+			if(!this.isAccepted(nodes[0])){
 				this.onDndCancel();
 			}else{
-				if(source == this && this._over && this.dropObject){ 
+				if(source == this && this._over && this.dropObject){
 					this.current = this.dropObject.c;
 				}
 				dojox.layout.dnd.PlottedDnd.superclass.onDndDrop.call(this, source, nodes, copy, target);
@@ -139,7 +139,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 			
 	onMouseDown: function(/*Event*/e) {
-		// summary: Event processor for onmousedown.	
+		// summary: Event processor for onmousedown.
 		if(this.current == null){
 			this.selection = {};
 		}else{
@@ -165,7 +165,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 					this.offsetDrag.x = coords.x - e.pageX;
 					this.offsetDrag.y = coords.y - e.clientY;
 				}
-				if(this.offsetDrag.y < 16 && this.current != null){ 
+				if(this.offsetDrag.y < 16 && this.current != null){
 					this.offsetDrag.y = this.GC_OFFSET_Y;
 				}
 
@@ -179,13 +179,13 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 			}
 		}
 		
-		if(dojo.dnd.isFormElement(e)){ 
+		if(dojo.dnd.isFormElement(e)){
 			this.setDndItemSelectable(e.target,true);
 		}else{
 			this.containerSource = true;
 			var _draggedWidget = this.getDraggedWidget(e.target);
 			if(_draggedWidget && _draggedWidget.dragRestriction){
-			// FIXME: not clear what this was supposed to mean ... this code needs more cleanups. 
+			// FIXME: not clear what this was supposed to mean ... this code needs more cleanups.
 			//	dragRestriction = true;
 			}else{
 				dojox.layout.dnd.PlottedDnd.superclass.onMouseDown.call(this,e);
@@ -194,7 +194,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 
 	onMouseUp: function(/*Event*/e) {
-		// summary: Event processor for onmouseup.	
+		// summary: Event processor for onmouseup.
 		dojox.layout.dnd.PlottedDnd.superclass.onMouseUp.call(this,e);
 		this.containerSource = false;
 		if (!dojo.isIE && this.mouseDown){
@@ -206,7 +206,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	onMouseMove: function(e) {
-		// summary: Event processor for onmousemove	
+		// summary: Event processor for onmousemove
 		var m = dojo.dnd.manager();
 		if(this.isDragging) {
 			var before = false;
@@ -231,14 +231,14 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 				}
 			}
 
-			if(this.allowAutoScroll){ 
+			if(this.allowAutoScroll){
 				this._stopAutoScroll();
 			}
-		}		
+		}
 	},
 	
 	_markTargetAnchor: function(/*Boolean*/before){
-		// summary: Assigns a class to the current target anchor based on "before" status	
+		// summary: Assigns a class to the current target anchor based on "before" status
 		if(this.current == this.targetAnchor && this.before == before){ return; }
 		this.targetAnchor = this.current;
 		this.targetBox = null;
@@ -246,7 +246,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	_unmarkTargetAnchor: function(){
-		// summary: Removes a class of the current target anchor based on "before" status.	
+		// summary: Removes a class of the current target anchor based on "before" status.
 		if(!this.targetAnchor){ return; }
 		this.targetAnchor = null;
 		this.targetBox = null;
@@ -264,10 +264,10 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 					h: this.current.offsetHeight / 2
 				};
 			}
-			before = this.horizontal ? 
+			before = this.horizontal ?
 				(e.pageX - this.current.coords.xy.x) < this.current.coords.w :
 				(e.pageY - this.current.coords.xy.y) < this.current.coords.h
-			this.insertDashedZone(before);	
+			this.insertDashedZone(before);
 		}else{
 			if(!this.dropObject /*|| dojo.isIE*/){ this.insertDashedZone(false); }
 		}
@@ -304,10 +304,10 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 	},
 	
 	insertDashedZone: function(/*Boolean*/before) {
-		// summary: Insert the dashed zone at the right place 
+		// summary: Insert the dashed zone at the right place
 		if(this.dropObject){
-			if( before == this.dropObject.b && 
-				((this.current && this.dropObject.c == this.current.id) || 
+			if( before == this.dropObject.b &&
+				((this.current && this.dropObject.c == this.current.id) ||
 				(!this.current && !this.dropObject.c))
 			){
 				return;
@@ -327,14 +327,14 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 			}else{
 				this.firstIndicator = false;
 			}
-		}else{ 
+		}else{
 			this.node.appendChild(this._drop);
 		}
 		this._drop.style.display = "";
 	},
 	
 	insertNodes: function(/*Boolean*/addSelected, /*Array*/data, /*Boolean*/before, /*Node*/anchor){
-		// summary: Inserts new data items (see Dojo Container's insertNodes method for details).	
+		// summary: Inserts new data items (see Dojo Container's insertNodes method for details).
 		if(this.dropObject){
 			dojo.style(this.dropObject.n,"display","none");
 			dojox.layout.dnd.PlottedDnd.superclass.insertNodes.call(this,true,data,true,this.dropObject.n);
@@ -355,7 +355,7 @@ dojo.declare("dojox.layout.dnd.PlottedDnd", [dojo.dnd.Source], {
 			clearTimeout(this._timer);
 		}
 		this._stopAutoScroll();
-		var node = this.dom, 
+		var node = this.dom,
 			y = this._sumAncestorProperties(node,"offsetTop")
 		;
 		//Down
@@ -422,16 +422,16 @@ dojox.layout.dnd._setGcDndHandle = function(service,withHandles,handleClasses, f
 				_hasHandle = true;
 				if(handleClasses[i] != cls){
 					var _gripNode = dojo.query("." + cls, service.domNode);
-					if(_gripNode.length == 0){ 
+					if(_gripNode.length == 0){
 						dojo.removeClass(service.domNode, cls);
-					}else{				
+					}else{
 						_gripNode.removeClass(cls);
 					}
 					dojo.addClass(_node, cls);
 				}
 			}
 		}
-		if(!_hasHandle){ 
+		if(!_hasHandle){
 			dojo.addClass(service.domNode, cls);
 		}
 	}
diff --git a/dojox/layout/resources/FloatingPane.html b/dojox/layout/resources/FloatingPane.html
index d80a4e1..a96ccdd 100644
--- a/dojox/layout/resources/FloatingPane.html
+++ b/dojox/layout/resources/FloatingPane.html
@@ -1,5 +1,5 @@
 <div class="dojoxFloatingPane" id="${id}">
-	<div tabindex="0" waiRole="button" class="dojoxFloatingPaneTitle" dojoAttachPoint="focusNode">
+	<div tabindex="0" role="button" class="dojoxFloatingPaneTitle" dojoAttachPoint="focusNode">
 		<span dojoAttachPoint="closeNode" dojoAttachEvent="onclick: close" class="dojoxFloatingCloseIcon"></span>
 		<span dojoAttachPoint="maxNode" dojoAttachEvent="onclick: maximize" class="dojoxFloatingMaximizeIcon"> </span>
 		<span dojoAttachPoint="restoreNode" dojoAttachEvent="onclick: _restore" class="dojoxFloatingRestoreIcon"> </span>	
@@ -7,7 +7,7 @@
 		<span dojoAttachPoint="titleNode" class="dijitInline dijitTitleNode"></span>
 	</div>
 	<div dojoAttachPoint="canvas" class="dojoxFloatingPaneCanvas">
-		<div dojoAttachPoint="containerNode" waiRole="region" tabindex="-1" class="${contentClass}">
+		<div dojoAttachPoint="containerNode" role="region" tabindex="-1" class="${contentClass}">
 		</div>
 		<span dojoAttachPoint="resizeHandle" class="dojoxFloatingResizeHandle"></span>
 	</div>
diff --git a/dojox/layout/resources/GridContainer.css b/dojox/layout/resources/GridContainer.css
index 8146fbd..6eda93c 100644
--- a/dojox/layout/resources/GridContainer.css
+++ b/dojox/layout/resources/GridContainer.css
@@ -65,8 +65,8 @@
 }
 
 .dj_ie6 .dropIndicator,
-.dj_ie6 .dijitContentPane,
-.dj_ie6 .dojoxPortlet, .dj_ie6 .dijitTitlePane{
+.dj_ie6 .dojoxPortlet .dijitContentPane,
+.dj_ie6 .dojoxPortlet, .dj_ie6 .dojoxPortlet.dijitTitlePane{
 	margin: 10px;
 }
 .gridContainerZone > *{
diff --git a/dojox/layout/tests/ContentPane.html b/dojox/layout/tests/ContentPane.html
index 77e1d38..a4fe8a5 100644
--- a/dojox/layout/tests/ContentPane.html
+++ b/dojox/layout/tests/ContentPane.html
@@ -92,7 +92,7 @@
 							var cont = "<div dojoType='dojox.TestWidget'>Test</div>";
 							pane1.attr('content', cont);
 							t.assertFalse(cont.toLowerCase() == pane1.domNode.innerHTML.toLowerCase());
-							t.assertEqual(1, dijit._Container.prototype.getChildren.call(pane1).length);
+							t.assertEqual(1, pane1.getChildren().length);
 						}
 					},
 					{
@@ -590,6 +590,51 @@
 						}
 					},
 					{
+						name: "scriptsCommentedOutAndEmptyComments",
+						runTest: function(t){
+							var content = ["<html>\n",
+											"<head>\n",
+											"</head>\n",
+											"<body>\n",
+											"\n",
+											"<!--\n", 
+											"   Some random comment\n",
+											"-->\n",
+											"\n",
+											"Random text before blank comment.\n",
+											"\n",
+											"<!-- -->\n",
+											"\n",
+											"<!--\n",
+											"  <" ,"script type=\"text/javascript\">\n",
+											"    shouldNotBeDefined = true;\n",
+											"  <", "/script>\n",
+											"-->\n",
+											"\n",	
+											"<script type=\"text/javascript\">\n",
+											"  // Junk JS.\n",
+											"  shouldBeDefined = true;\n",
+											"  shouldBeDefined = true;\n",
+											"  shouldBeDefined = true;\n",
+											"  shouldBeDefined = true;\n",
+											"  shouldBeDefined = true;\n",
+											"  shouldBeDefined = true;\n",
+											"  shouldBeDefined = true;\n",
+											"<", "/script>\n",
+											"</body>\n",
+											"</html>\n"].join("");
+							pane1.attr("content", content);
+
+							// let IE inhale here
+							var d = new t.Deferred();
+							setTimeout(d.getTestCallback(function(){
+								t.assertEqual("boolean" , typeof shouldBeDefined);
+								t.assertEqual("undefined" , typeof shouldNotBeDefined);
+							}), 40);
+							return d;
+						}
+					},
+					{
 						name: 'replace_container_with_dijit.byId()',
 						runTest: function(t){
 							console.log("scriptTests: " + this.name);
diff --git a/dojox/layout/tests/resources/script_dnd.js b/dojox/layout/tests/resources/script_dnd.js
index 6972ad8..21bcad2 100644
--- a/dojox/layout/tests/resources/script_dnd.js
+++ b/dojox/layout/tests/resources/script_dnd.js
@@ -17,7 +17,7 @@ function init(){
 			case "dijit.layout.TabContainer" :
 				var tabButton = dijit.byNode(target.node);
 				var panes = tabContainer.getChildren();
-				for (var i = 0, l = panes.length; i < l; i++) {	
+				for (var i = 0, l = panes.length; i < l; i++) {
 					var gc = panes[i];
 					if (gc.controlButton == tabButton) {
 						for (var j=0; j < gc.acceptTypes.length; j++){
@@ -50,7 +50,7 @@ function init(){
 		});
 	});
 	
-	dojo.subscribe(tabContainer.domNode.id+"-removeChild", null, "refresh");	
+	dojo.subscribe(tabContainer.domNode.id+"-removeChild", null, "refresh");
 };
 
 /**
@@ -59,7 +59,7 @@ function init(){
  */
 
 /*Function: createNode
- * 	Create a widget with a dojo draggedNode and drop this into a D&D OAF Area. 
+ * 	Create a widget with a dojo draggedNode and drop this into a D&D OAF Area.
  */
 function createNode(source, nodes, copy, target, dropIndex){
 	//console.log("createNode ::: ", source, nodes, copy, target, dropIndex);
diff --git a/dojox/layout/tests/test_DragPane.html b/dojox/layout/tests/test_DragPane.html
index fee1e8b..6b9eb6b 100644
--- a/dojox/layout/tests/test_DragPane.html
+++ b/dojox/layout/tests/test_DragPane.html
@@ -8,7 +8,7 @@
 	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/tundra/tundra.css">
 
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -56,7 +56,7 @@
 	<p>A simple widget to drag contents around within a sized div</p>
 	
 	<h2>Inverted dragging</h2>
-	<div class="hugetext" id="container" dojoType="dojox.layout.DragPane">
+	<div class="hugetext" id="container" data-dojo-type="dojox.layout.DragPane">
 		<p style="color:#666; padding:8px; margin:0;">
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta. Etiam mattis libero nec ante. Nam 
 		porta lacus eu ligula. Cras mauris. Suspendisse vel augue. Vivamus aliquam orci ut eros. Nunc eleifend 
@@ -110,7 +110,7 @@
 	</div>
 
 	<h2>Not inverted</h2>
-	<div class="hugetext" id="container0" invert="false" dojoType="dojox.layout.DragPane">
+	<div class="hugetext" id="container0" data-dojo-props="invert:false" data-dojo-type="dojox.layout.DragPane">
 		<p style="color:#666; padding:8px; margin:0;">
 		Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta. Etiam mattis libero nec ante. Nam 
 		porta lacus eu ligula. Cras mauris. Suspendisse vel augue. Vivamus aliquam orci ut eros. Nunc eleifend 
@@ -163,40 +163,5 @@
 		</p>	
 	</div>
 	
-	<!--h2>An Image:</h2>
-	
-	<div dojoType="dojox.layout.DragPane" id="imagePane" style="width:200px; height:200px; overflow:hidden;">
-		<div id="innerThing">
-		<div class="fbox">
-			<p style="color:#666; padding:8px; margin:0;">
-			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta. Etiam mattis libero nec ante. Nam 
-			porta lacus eu ligula. Cras mauris. Suspendisse vel augue. Vivamus aliquam orci ut eros. Nunc eleifend 
-			sagittis turpis. purus purus in nibh. Phasellus in nunc.
-			</p>					
-		</div>
-		<div class="fbox">
-			<p style="color:#666; padding:8px; margin:0;">
-			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta. Etiam mattis libero nec ante. Nam 
-			porta lacus eu ligula. Cras mauris. Suspendisse vel augue. Vivamus aliquam orci ut eros. Nunc eleifend 
-			sagittis turpis. purus purus in nibh. Phasellus in nunc.
-			</p>					
-		</div>
-		<div class="fbox">
-			<p style="color:#666; padding:8px; margin:0;">
-			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta. Etiam mattis libero nec ante. Nam 
-			porta lacus eu ligula. Cras mauris. Suspendisse vel augue. Vivamus aliquam orci ut eros. Nunc eleifend 
-			sagittis turpis. purus purus in nibh. Phasellus in nunc.
-			</p>					
-		</div>
-		<div class="fbox">
-			<p style="color:#666; padding:8px; margin:0;">
-			Lorem ipsum dolor sit amet, consectetuer adipiscing elit. In porta. Etiam mattis libero nec ante. Nam 
-			porta lacus eu ligula. Cras mauris. Suspendisse vel augue. Vivamus aliquam orci ut eros. Nunc eleifend 
-			sagittis turpis. purus purus in nibh. Phasellus in nunc.
-			</p>					
-		</div>
-		</div>
-	</div-->
-	
 </body>
 </html>
diff --git a/dojox/layout/tests/test_ExpandoPane.html b/dojox/layout/tests/test_ExpandoPane.html
index e4be70f..d0dfe7a 100644
--- a/dojox/layout/tests/test_ExpandoPane.html
+++ b/dojox/layout/tests/test_ExpandoPane.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.layout.ExpandoPane</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">
 	<!-- test file style rollup, you need resources/ExpandoPane.css exclusively -->
 	<link rel="stylesheet" href="_expando.css">	
 
@@ -183,7 +182,7 @@
 
 	</script>
 </head>
-<body class="tundra">
+<body class="claro">
 		<div id="bc" style="width:100%; height:100%; padding: 5px;" dojoType="dijit.layout.BorderContainer">
 			<div id="header" dojoType="dijit.layout.ContentPane" region="top" splitter="true">Dojo Expando Pane Test</div>
 			<div dojoType="dojox.layout.ExpandoPane" 
@@ -309,7 +308,12 @@
 				style="height: 100px;">
 				<div dojoType="dijit.layout.TabContainer" attachParent="true" tabPosition="bottom" tabStrip="true">
 					<div dojoType="dijit.layout.ContentPane" title="Search">
-												
+						<button dojoType="dijit.form.Button">
+							Change Title
+							<script type="dojo/method" event="onClick">
+								dijit.byId("bottomPane").set("title", new Date())
+							</script>
+						</button>
 					</div>
 					<div dojoType="dijit.layout.AccordionContainer" title="Panes" style="width:275px;" attachParent="true">
 						
diff --git a/dojox/layout/tests/test_RadioGroup.html b/dojox/layout/tests/test_RadioGroup.html
index 8d0632d..df0d2e0 100644
--- a/dojox/layout/tests/test_RadioGroup.html
+++ b/dojox/layout/tests/test_RadioGroup.html
@@ -5,7 +5,7 @@
 	<title>RadioGroup (Animated StackContainer) Widget 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">
 	<link rel="stylesheet" href="../resources/RadioGroup.css">	
 
 	<!-- required: dojo.js -->
@@ -21,6 +21,7 @@
 		dojo.require("dojox.layout.RadioGroup");
 		dojo.require("dojo.parser"); 
 		dojo.require("dijit.layout.ContentPane"); 
+		dojo.require("dijit.form.ComboBox");
 		dojo.require("dijit.form.Button");
 	</script>
 
@@ -50,7 +51,7 @@
 	</style>
 
 </head>
-<body class="tundra">
+<body class="claro">
 
 	<h1 class="testTitle">dojox.layout.RadioGroup test</h1>
 
@@ -73,9 +74,9 @@
 			<div dojoType="dijit.layout.ContentPane" title="Dojox" class="dojoxPane" style="width:300px; height:300px; "></div>
 		</div>
 	</div>
+	
+	<br style="margin-top:30px; clear:both">
 
-	<br style="clear:both">
-	<br style="clear:both">
 	<div>
 		<button dojoType="dijit.form.Button">add children
 			<script type="dojo/method" event="onClick">
@@ -141,10 +142,47 @@
 			// testing addchild after startup
 			new dijit.layout.ContentPane({ title:"after", content:lorem() }).placeAt(g);
 			
-		})
+		});
 	</script>
-	
 
+	<br style="margin-top:30px; clear:both">
+	
+	<h2>Has no buttons (auto rotating via code)</h2>
 
+	<div id="hasnobuttons" style="width:915px; margin:0 auto; height:300px;">
+		<div id="bfirstGroup" dojoType="dojox.layout.RadioGroup" style="width:300px; height:300px; float:left;">
+			<div dojoType="dijit.layout.ContentPane" href="doc0.html" title="Dojo" class="dojoPane" style="width:300px; height:300px;"></div>
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dijit" class="dijitPane" style="width:300px; height:300px;"></div>
+			<div dojoType="dijit.layout.ContentPane" href="doc0.html" title="Dojox" class="dojoxPane" style="width:300px; height:300px;"></div>
+		</div>
+	
+		<div id="bfirstFade" dojoType="dojox.layout.RadioGroupFade" style="width:300px; height:300px; float:left">
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dojo" class="dojoPane" style="width:300px; height:300px;"></div>
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dijit" class="dijitPane" style="width:300px; height:300px;"></div>
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dojox" class="dojoxPane" style="width:300px; height:300px;"></div>
+		</div>
+	
+		<div id="bfirstSlide" dojoType="dojox.layout.RadioGroupSlide" style="width:300px; height:300px;">
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dojo" class="dojoPane" style="width:300px; height:300px;"></div>
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dijit" class="dijitPane" style="width:300px; height:300px;"></div>
+			<div dojoType="dijit.layout.ContentPane" href="_lorem.html" title="Dojox" class="dojoxPane" style="width:300px; height:300px;"></div>
+		</div>
+	</div>
+	<script>
+		// make all the 3 RadioGroups above loop through their children.
+		dojo.ready(function(){
+			var rnd = 500; 
+			dojo.query("#hasnobuttons > div").forEach(function(n){
+				var widget = dijit.byNode(n);
+				setTimeout(function(){
+					setInterval(function(){
+						widget.forward();
+					}, 3000);
+				}, rnd);
+				rnd += 500;
+			});
+		});
+	</script>
+	
 </body>
 </html>
diff --git a/dojox/layout/tests/test_TableContainer.html b/dojox/layout/tests/test_TableContainer.html
index 4ea02a1..ca52b1c 100644
--- a/dojox/layout/tests/test_TableContainer.html
+++ b/dojox/layout/tests/test_TableContainer.html
@@ -26,10 +26,11 @@
 		dojo.require("dijit.form.NumberTextBox");
 		dojo.require("dijit.form.NumberSpinner");
 		dojo.require("dijit.form.CheckBox");
+		dojo.require("dijit.layout.BorderContainer");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dojox.form.DateTextBox");
 		
-		dojo.addOnLoad(function(){
+		dojo.ready(function(){
 			dojo.parser.parse();
 			
 			var programmatic = new dojox.layout.TableContainer(
@@ -302,7 +303,8 @@
 			
 			<div dojoType="dijit.layout.ContentPane" label="Label 1">colspan = 1</div>
 			<div dojoType="dijit.layout.ContentPane" label="Label 1">colspan = 1</div>
-			<div dojoType="dijit.layout.ContentPane" label="Label 1">colspan = 1</div>			<div dojoType="dijit.layout.ContentPane" label="Label 2" colspan="2">colspan = 2</div>
+			<div dojoType="dijit.layout.ContentPane" label="Label 1">colspan = 1</div>
+			<div dojoType="dijit.layout.ContentPane" label="Label 2" colspan="2">colspan = 2</div>
 			<div dojoType="dijit.layout.ContentPane" label="Label 3" colspan="2">colspan = 2</div>
 			<div dojoType="dijit.layout.ContentPane" label="Label 4">colspan = 1</div>
 			<div dojoType="dijit.layout.ContentPane" label="Label 5">colspan = 1</div>
@@ -317,5 +319,38 @@
 	<div id="programmatic" style="width: 800px;">
 		
 	</div>
+
+	<h2>Test resize of the TableContainer</h2>
+	<p>Drag the splitter to resize the TableContainer in the right/center region and confirm the column widths resize correctly to their new width</p>
+	<div dojoType="dijit.layout.BorderContainer" style="height:100px; border: solid #ccc 1px;">
+		<div dojoType="dijit.layout.ContentPane" region="left" style="width:20%" splitter="true">(left)</div>
+		<div dojoType="dijit.layout.ContentPane" region="center">
+			<div dojoType="dojox.layout.TableContainer" region="center" jsId="tblContainerResize" cols="3" customClass="greyBlueLNF" labelWidth="-1">
+				<div dojoType="dijit.layout.ContentPane" label="Col 1 Label">
+					<script type="dojo/connect" event="resize">
+						this.domNode.innerHTML = "<strong>Width: " + dojo.contentBox(this.domNode).w + "</strong>";
+					</script>
+				</div>
+				<div dojoType="dijit.layout.ContentPane" label="Col 2 Label">
+					<script type="dojo/connect" event="resize">
+						this.domNode.innerHTML = "<strong>Width: " + dojo.contentBox(this.domNode).w + "</strong>";
+					</script>
+				</div>
+				<div dojoType="dijit.layout.BorderContainer" label="Col 1 Label" colspan="2" style="height: 50px">
+					<div dojoType="dijit.layout.ContentPane" region="left" style="width: 50%">
+						<script type="dojo/connect" event="resize">
+							this.domNode.innerHTML = "<strong>Nested BC region width: " + dojo.contentBox(this.domNode).w + "</strong>";
+						</script>
+					</div>
+					<div dojoType="dijit.layout.ContentPane" region="center" style="width: 50%">
+						<script type="dojo/connect" event="resize">
+							this.domNode.innerHTML = "<strong>Nested BC region width: " + dojo.contentBox(this.domNode).w + "</strong>";
+							console.log(this.id + " resize");
+						</script>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
 </body>
 </html>
diff --git a/dojox/math.js b/dojox/math.js
index 9d64cc2..1672c8b 100644
--- a/dojox/math.js
+++ b/dojox/math.js
@@ -1,2 +1,6 @@
-dojo.provide("dojox.math");
-dojo.require("dojox.math._base");
+// AMD-ID "dojox/math"
+define(["dojo", "dojox", "dojox/math/_base"], function(dojo, dojox, math) {
+dojo.getObject("math", true, dojox);
+
+return dojox.math;
+});
diff --git a/dojox/math/BigInteger-ext.js b/dojox/math/BigInteger-ext.js
index 449352d..4b6697d 100644
--- a/dojox/math/BigInteger-ext.js
+++ b/dojox/math/BigInteger-ext.js
@@ -1,8 +1,7 @@
-dojo.provide("dojox.math.BigInteger-ext");
+// AMD-ID "dojox/math/BigInteger-ext"
+define(["dojo", "dojox", "dojox/math/BigInteger"], function(dojo, dojox) {
 dojo.experimental("dojox.math.BigInteger-ext");
 
-dojo.require("dojox.math.BigInteger");
-
 // Contributed under CLA by Tom Wu
 
 // Extended JavaScript BN functions, required for RSA private ops.
@@ -12,7 +11,7 @@ dojo.require("dojox.math.BigInteger");
 		nbi = BigInteger._nbi, nbv = BigInteger._nbv,
 		nbits = BigInteger._nbits,
 		Montgomery = BigInteger._Montgomery;
-	
+
 	// (public)
 	function bnClone() { var r = nbi(); this._copyTo(r); return r; }
 
@@ -656,3 +655,6 @@ dojo.require("dojox.math.BigInteger");
 	// static BigInteger valueOf(long val)
 
 })();
+
+return dojox.math.BigInteger;
+});
diff --git a/dojox/math/BigInteger.js b/dojox/math/BigInteger.js
index 5067c65..55a24b0 100644
--- a/dojox/math/BigInteger.js
+++ b/dojox/math/BigInteger.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math.BigInteger");
+// AMD-ID "dojox/math/BigInteger"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("math.BigInteger", true, dojox);
 dojo.experimental("dojox.math.BigInteger");
 
 // Contributed under CLA by Tom Wu <tjw at cs.Stanford.EDU>
@@ -571,12 +573,12 @@ dojo.experimental("dojox.math.BigInteger");
 		// "constants"
 		ZERO:	nbv(0),
 		ONE:	nbv(1),
-		
+
 		// internal functions
 		_nbi: nbi,
 		_nbv: nbv,
 		_nbits: nbits,
-		
+
 		// internal classes
 		_Montgomery: Montgomery
 	});
@@ -584,3 +586,6 @@ dojo.experimental("dojox.math.BigInteger");
 	// export to DojoX
 	dojox.math.BigInteger = BigInteger;
 })();
+
+return dojox.math.BigInteger;
+});
diff --git a/dojox/math/_base.js b/dojox/math/_base.js
index 51c873f..a05788d 100644
--- a/dojox/math/_base.js
+++ b/dojox/math/_base.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math._base");
+// AMD-ID "dojox/math/_base"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("math", true, dojox);
 
 (function(){
 	var m = dojox.math;
@@ -80,7 +82,7 @@ dojo.provide("dojox.math._base");
 		permutations: function(/* Number */n, /* Number */k){
 			//	summary:
 			//	TODO
-			if(n==0 || k==0){ 
+			if(n==0 || k==0){
 				return 1; 	// Number
 			}
 			return this.factorial(n) / this.factorial(n-k);
@@ -89,7 +91,7 @@ dojo.provide("dojox.math._base");
 		combinations: function(/* Number */n, /* Number */r){
 			//	summary:
 			//	TODO
-			if(n==0 || r==0){ 
+			if(n==0 || r==0){
 				return 1; 	//	Number
 			}
 			return this.factorial(n) / (this.factorial(n-r) * this.factorial(r));	// Number
@@ -157,3 +159,6 @@ dojo.provide("dojox.math._base");
 		}
 	});
 })();
+
+return dojox.math;
+});
diff --git a/dojox/math/curves.js b/dojox/math/curves.js
index f57abad..636eacb 100644
--- a/dojox/math/curves.js
+++ b/dojox/math/curves.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math.curves");
+// AMD-ID "dojox/math/curves"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("math.curves", true, dojox);
 
 dojo.mixin(dojox.math.curves, {
 	Line:function (start, end) {
@@ -19,7 +21,7 @@ dojo.mixin(dojox.math.curves, {
 			return retVal;
 		};
 		return this;
-	}, 
+	},
 	Bezier:function(pnts) {
 		this.getValue = function (step) {
 			if (step >= 1) {
@@ -47,7 +49,7 @@ dojo.mixin(dojox.math.curves, {
 		};
 		this.p = pnts;
 		return this;
-	}, 
+	},
 	CatmullRom:function (pnts, c) {
 		this.getValue = function (step) {
 			var percent = step * (this.p.length - 1);
@@ -86,7 +88,7 @@ dojo.mixin(dojox.math.curves, {
 		}
 		this.p = pnts;
 		return this;
-	}, 
+	},
 	Arc:function (start, end, ccw){
 		function translate(a,b){
 			var c=new Array(a.length);
@@ -108,7 +110,7 @@ dojo.mixin(dojox.math.curves, {
 			theta += 90;
 		}
 		dojox.math.curves.CenteredArc.call(this, center, rad, theta, theta + (ccw ? -180 : 180));
-	}, 
+	},
 	CenteredArc:function (center, radius, start, end) {
 		this.center = center;
 		this.radius = radius;
@@ -122,11 +124,11 @@ dojo.mixin(dojox.math.curves, {
 			return retVal;
 		};
 		return this;
-	}, 
+	},
 	Circle:function(center, radius){
 		dojox.math.curves.CenteredArc.call(this, center, radius, 0, 360);
 		return this;
-	}, 
+	},
 	Path:function () {
 		var curves = [];
 		var weights = [];
@@ -187,3 +189,6 @@ dojo.mixin(dojox.math.curves, {
 		return this;
 	}
 });
+
+return dojox.math.curves;
+});
diff --git a/dojox/math/matrix.js b/dojox/math/matrix.js
index 77f5f4b..f4beed1 100644
--- a/dojox/math/matrix.js
+++ b/dojox/math/matrix.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math.matrix");
+// AMD-ID "dojox/math/matrix"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("math.matrix", true, dojox);
 
 dojo.mixin(dojox.math.matrix, {
 	iDF:0,
@@ -288,3 +290,6 @@ dojo.mixin(dojox.math.matrix, {
 		return a;
 	}
 });
+
+return dojox.math.matrix;
+});
diff --git a/dojox/math/random/Secure.js b/dojox/math/random/Secure.js
index c4ac2e4..39b5fce 100644
--- a/dojox/math/random/Secure.js
+++ b/dojox/math/random/Secure.js
@@ -1,4 +1,5 @@
-dojo.provide("dojox.math.random.Secure");
+// AMD-ID "dojox/math/random/Secure"
+define(["dojo"], function(dojo) {
 
 // Copyright (c) 2005  Tom Wu
 // All Rights Reserved.
@@ -40,7 +41,7 @@ dojo.declare("dojox.math.random.Secure", null, {
 			];
 		}
 	},
-	
+
 	destroy: function(){
 		// summary:
 		//	Disconnects events, if any, preparing the object for GC.
@@ -92,3 +93,6 @@ dojo.declare("dojox.math.random.Secure", null, {
 		this.pptr = i;
 	}
 });
+
+return dojox.math.random.Secure;
+});
diff --git a/dojox/math/random/Simple.js b/dojox/math/random/Simple.js
index e33c2e4..467aa18 100644
--- a/dojox/math/random/Simple.js
+++ b/dojox/math/random/Simple.js
@@ -1,4 +1,5 @@
-dojo.provide("dojox.math.random.Simple");
+// AMD-ID "dojox/math/random/Simple"
+define(["dojo"], function(dojo) {
 
 dojo.declare("dojox.math.random.Simple", null, {
 	// summary:
@@ -21,3 +22,6 @@ dojo.declare("dojox.math.random.Simple", null, {
 		}
 	}
 });
+
+return dojox.math.random.Simple;
+});
diff --git a/dojox/math/random/prng4.js b/dojox/math/random/prng4.js
index 9defedc..f7b00cd 100644
--- a/dojox/math/random/prng4.js
+++ b/dojox/math/random/prng4.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math.random.prng4");
+// AMD-ID "dojox/math/random/prng4"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("math.random.prng4", true, dojox);
 
 // Copyright (c) 2005  Tom Wu
 // All Rights Reserved.
@@ -53,3 +55,6 @@ dojo.provide("dojox.math.random.prng4");
 	// 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;
+});
diff --git a/dojox/math/round.js b/dojox/math/round.js
index 94bd4b3..c94f92e 100644
--- a/dojox/math/round.js
+++ b/dojox/math/round.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math.round");
+// 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){
@@ -59,3 +61,6 @@ if((0.9).toFixed() == 0){
 		}
 	})();
 }
+
+return dojox.math.round;
+});
diff --git a/dojox/math/stats.js b/dojox/math/stats.js
index 75a609c..8d275bf 100644
--- a/dojox/math/stats.js
+++ b/dojox/math/stats.js
@@ -1,4 +1,6 @@
-dojo.provide("dojox.math.stats");
+// AMD-ID "dojox/math/stats"
+define(["dojo", "dojox"], function(dojo, dojox) {
+dojo.getObject("math.stats", true, dojox);
 
 (function(){
 	var st = dojox.math.stats;
@@ -188,3 +190,6 @@ dojo.provide("dojox.math.stats");
 		}
 	});
 })();
+
+return dojox.math.stats;
+});
diff --git a/dojox/math/tests/round.js b/dojox/math/tests/round.js
index 0c1c44b..44b2115 100644
--- a/dojox/math/tests/round.js
+++ b/dojox/math/tests/round.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.math.tests.round");
 dojo.require("dojox.math.round");
 
-tests.register("dojox.math.tests.round", 
+tests.register("dojox.math.tests.round",
 	[
 		{
 			name: "round",
diff --git a/dojox/math/tests/stats.js b/dojox/math/tests/stats.js
index 06cf500..6e51132 100644
--- a/dojox/math/tests/stats.js
+++ b/dojox/math/tests/stats.js
@@ -98,5 +98,5 @@ dojo.require("dojox.math.stats");
 			eq(t, s.p90, 18);
 			eq(t, s.max, 20);
 		}
-	]); 
+	]);
 })();
diff --git a/dojox/mdnd/AutoScroll.js b/dojox/mdnd/AutoScroll.js
index 241ac74..3647ac8 100644
--- a/dojox/mdnd/AutoScroll.js
+++ b/dojox/mdnd/AutoScroll.js
@@ -1,8 +1,8 @@
 dojo.provide("dojox.mdnd.AutoScroll");
 
 dojo.declare(
-	"dojox.mdnd.AutoScroll", 
-	null, 
+	"dojox.mdnd.AutoScroll",
+	null,
 {
 	// summary:
 	//		Activate scrolling while dragging a widget.
@@ -29,7 +29,7 @@ dojo.declare(
 	init: function(){
 		//console.log("dojox.mdnd.AutoScroll ::: init ");
 		this._html = (dojo.isWebKit) ? dojo.body() : dojo.body().parentNode;
-		this.getViewport();	
+		this.getViewport();
 	},
 
 	getViewport:function(){
diff --git a/dojox/mdnd/DropIndicator.js b/dojox/mdnd/DropIndicator.js
index cc38b3d..c212e6b 100644
--- a/dojox/mdnd/DropIndicator.js
+++ b/dojox/mdnd/DropIndicator.js
@@ -3,14 +3,14 @@ dojo.provide("dojox.mdnd.DropIndicator");
 dojo.require("dojox.mdnd.AreaManager");
 
 dojo.declare(
-	"dojox.mdnd.DropIndicator", 
-	null, 
+	"dojox.mdnd.DropIndicator",
+	null,
 {
 	// summary:
 	//		DropIndicator managment for DnD.
 
 	// node: DOMNode
-	//		the drop indicator node	
+	//		the drop indicator node
 	node : null,
 		
 	constructor: function(){
@@ -63,7 +63,7 @@ dojo.declare(
 			if(this.node.parentNode){
 				this.node.parentNode.removeChild(this.node);
 			}
-		}	
+		}
 	},
 	 
 	destroy: function(){
diff --git a/dojox/mdnd/Moveable.js b/dojox/mdnd/Moveable.js
index c90cf5b..dee5ce6 100644
--- a/dojox/mdnd/Moveable.js
+++ b/dojox/mdnd/Moveable.js
@@ -1,8 +1,8 @@
 dojo.provide("dojox.mdnd.Moveable");
 
 dojo.declare(
-	"dojox.mdnd.Moveable", 
-	null, 
+	"dojox.mdnd.Moveable",
+	null,
 {
 	// summary:
 	//		Allow end-users to track a DOM node into the web page
@@ -23,14 +23,14 @@ dojo.declare(
 	
 	constructor: function(/*Object*/params, /*DOMNode*/node){
 		// summary:
-		// 		Configure parameters and listen to mousedown events from handle 
+		// 		Configure parameters and listen to mousedown events from handle
 		//		node.
 		// params:
 		//		Hash of parameters
 		// node:
 		//		The draggable node
 
-		//console.log("dojox.mdnd.Moveable ::: constructor"); 
+		//console.log("dojox.mdnd.Moveable ::: constructor");
 		this.node = dojo.byId(node);
 		
 		this.d = this.node.ownerDocument;
@@ -89,24 +89,24 @@ dojo.declare(
 		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;	
+		this._firstY = e.clientY;
 		dojo.stopEvent(e);
 	},
 	
 	onFirstMove: function(/*DOMEvent*/e){
 		// summary:
-		//		Occurs when the user moves the mouse after clicking on the 
+		//		Occurs when the user moves the mouse after clicking on the
 		//		handle.
-		//		Determinate when the drag action will have to begin (see 
+		//		Determinate when the drag action will have to begin (see
 		//		dragDistance).
 		// e:
 		//		A DOM event
 		// tags:
 		//		callback
 
-		//console.log("dojox.mdnd.Moveable ::: onFirstMove"); 
+		//console.log("dojox.mdnd.Moveable ::: onFirstMove");
 		dojo.stopEvent(e);
-		var d = (this._firstX - e.clientX) * (this._firstX - e.clientX) 
+		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;
@@ -158,7 +158,7 @@ dojo.declare(
 		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;		
+			return;
 		}
 		if(this.autoScroll){
 			this.autoScroll.checkAutoScroll(e);
@@ -182,19 +182,21 @@ dojo.declare(
 		// summary:
 		//		Occurs when the user releases the mouse
 		//		Calls the onDragEnd method.
-		// e: 
+		// e:
 		//		a DOM event
 
-		dojo.stopEvent(e);
-		this._isDragging = false;
-		if(this.autoScroll){
-			this.autoScroll.stopAutoScroll();
-		}
+		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());
-		delete this.onMove;
-		this.onDragEnd(this.node);
-		this.node.focus();
 	},
 	
 	onDragStart: function(/*DOMNode*/node, /*Object*/coords, /*Object*/size){
diff --git a/dojox/mdnd/PureSource.js b/dojox/mdnd/PureSource.js
index 2cabe11..01ce7ce 100644
--- a/dojox/mdnd/PureSource.js
+++ b/dojox/mdnd/PureSource.js
@@ -4,7 +4,7 @@ dojo.require("dojo.dnd.Selector");
 dojo.require("dojo.dnd.Manager");
 
 dojo.declare(
-	"dojox.mdnd.PureSource", 
+	"dojox.mdnd.PureSource",
 	dojo.dnd.Selector,
 {
 	// summary:
@@ -16,7 +16,7 @@ dojo.declare(
 	copyOnly: true,
 	skipForm: false,
 	withHandles: false,
-	isSource: true,	
+	isSource: true,
 	targetState: "Disabled",
 	generateText: true,
 	
@@ -105,17 +105,17 @@ dojo.declare(
 		// summary:
 		//		Event processor for onmousemove.
 		// e:
-		//		Mouse event.	
+		//		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();		
+		var m = dojo.dnd.manager();
 		if(this.mouseDown && !this.isDragging && this.isSource){
-			var nodes = this.getSelectedNodes();			
-			if(nodes.length){				
+			var nodes = this.getSelectedNodes();
+			if(nodes.length){
 				m.startDrag(this, nodes, this.copyState(dojo.isCopyKey(e)));
 				this.isDragging = true;
 			}
diff --git a/dojox/mdnd/dropMode/DefaultDropMode.js b/dojox/mdnd/dropMode/DefaultDropMode.js
index 7c89481..0539167 100644
--- a/dojox/mdnd/dropMode/DefaultDropMode.js
+++ b/dojox/mdnd/dropMode/DefaultDropMode.js
@@ -7,7 +7,7 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 	//		Default class to find the nearest target.
 
 	// _oldXPoint: Integer
-	//		used to save a X position 
+	//		used to save a X position
 	_oldXPoint: null,
 
 	// _oldYPoint: Integer
@@ -38,13 +38,13 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 			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--) 
+					for (var j = length-1; j >= i; j--)
 						areas[j + 1] = areas[j];
 					areas[i] = object;
 					break;
 				}
 			}
-			if (i == length) 
+			if (i == length)
 				areas.push(object);
 		}
 		return areas;	// Array
@@ -75,7 +75,7 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 					this._updateArea(area);
 					this._updateArea(nextArea);
 					currentRight = area.coords.x + area.node.offsetWidth;
-					nextLeft =  nextArea.coords.x;	
+					nextLeft =  nextArea.coords.x;
 					area.coords.x2 = currentRight + (nextLeft-currentRight)/2;
 				}
 				else if (i == length-1) {
@@ -159,8 +159,8 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 		// summary:
 		//		return coordinates of the draggable item
 		// description:
-		//		return for: 
-		// 			- X point : the middle 
+		//		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
@@ -181,14 +181,14 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 				this._oldBehaviour = "down";
 				y += size.h;
 			}
-			else 
+			else
 				if (y <= this._oldYPoint) {
 					this._oldBehaviour = "up";
 				}
 		}
 		this._oldYPoint = y;
-		return { 
-			'x': coords.x + (size.w / 2), 
+		return {
+			'x': coords.x + (size.w / 2),
 			'y': y
 			};	// Object
 	},
@@ -258,7 +258,7 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 		//		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 	
+		//		a list of DnD areas objects
 		// index:
 		//		index of a DnD area (to get the interval)
 		// x:
@@ -274,7 +274,7 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 				return true;
 			}
 		}
-		else 
+		else
 			if (coords.x2 == -1) {
 				if (x > coords.x1) {
 					return true;
@@ -326,7 +326,7 @@ dojo.declare("dojox.mdnd.dropMode.DefaultDropMode", null, {
 });
 
 //------------
-//Singleton	
+//Singleton
 //------------
 (function(){
 	dojox.mdnd.areaManager()._dropMode = new dojox.mdnd.dropMode.DefaultDropMode();
diff --git a/dojox/mdnd/tests/robot/module.js b/dojox/mdnd/tests/robot/module.js
index 28a6bed..fe8f911 100644
--- a/dojox/mdnd/tests/robot/module.js
+++ b/dojox/mdnd/tests/robot/module.js
@@ -9,7 +9,7 @@ try{
 			dojo.moduleUrl("dojox.mdnd","tests/robot/test_dnd_overDropMode.html"),60000);
 	doh.registerUrl("dojox.mdnd.tests.robot.DndToDojo",
 			dojo.moduleUrl("dojox.mdnd","tests/robot/test_dnd_dndToDojo.html"),60000);
-	doh.registerUrl("dojox.mdnd.tests.robot.DndFromDojo", 
+	doh.registerUrl("dojox.mdnd.tests.robot.DndFromDojo",
 			dojo.moduleUrl("dojox.mdnd","tests/robot/test_dnd_dndFromDojo.html"),60000);
 }catch(e){
 	doh.debug(e);
diff --git a/dojox/mdnd/tests/unitTests/dropMode/FixtureLib.js b/dojox/mdnd/tests/unitTests/dropMode/FixtureLib.js
index 49086e2..52fb594 100644
--- a/dojox/mdnd/tests/unitTests/dropMode/FixtureLib.js
+++ b/dojox/mdnd/tests/unitTests/dropMode/FixtureLib.js
@@ -77,7 +77,7 @@ dojo.declare("ItemFixture", null, {
 		delete this.array;
 		delete this.moveableA;
 		delete this.moveableB;
-		delete this.moveableC; 
+		delete this.moveableC;
 		delete this.moveableD;
 		delete this.itemA;
 		delete this.itemB;
diff --git a/dojox/mobile/FixedSplitter.js b/dojox/mobile/FixedSplitter.js
new file mode 100644
index 0000000..8cf750a
--- /dev/null
+++ b/dojox/mobile/FixedSplitter.js
@@ -0,0 +1,97 @@
+dojo.provide("dojox.mobile.FixedSplitter");
+
+dojo.require("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>
+
+dojo.declare(
+	"dojox.mobile.FixedSplitter",
+	dijit._WidgetBase,
+{
+	orientation: "H", // "H" or "V"
+
+	isContainer: true,
+
+	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);
+
+		dojo.forEach(this.getChildren(), function(child){if(child.startup){child.startup();}});
+		this._started = true;
+
+		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");
+			}
+		}
+	},
+
+	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 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");
+	}
+});
diff --git a/dojox/mobile/FlippableView.js b/dojox/mobile/FlippableView.js
new file mode 100644
index 0000000..2ff79f4
--- /dev/null
+++ b/dojox/mobile/FlippableView.js
@@ -0,0 +1,132 @@
+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);
+	}
+});
diff --git a/dojox/mobile/IconContainer.js b/dojox/mobile/IconContainer.js
new file mode 100644
index 0000000..120b78d
--- /dev/null
+++ b/dojox/mobile/IconContainer.js
@@ -0,0 +1,307 @@
+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);
+	},
+
+	_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";
+			}
+			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);
+		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];
+			}
+		}
+		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));
+			}
+			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;
+	},
+
+	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);
+			}
+		}
+
+		if(len > 0){
+			(dojox.mobile.parser || dojo.parser).parse(this.containerNode);
+		}
+		this.lazy = false;
+	},
+
+	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);
+			}
+			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);
+				});
+			}
+			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;
+				}
+			}
+			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/README b/dojox/mobile/README
index 3bbbf27..35ac66a 100755
--- a/dojox/mobile/README
+++ b/dojox/mobile/README
@@ -1,11 +1,12 @@
 -------------------------------------------------------------------------------
 Project Name:  dojox.mobile
 -------------------------------------------------------------------------------
-Version 0.01
+Version 1.0
 Release date: 03/23/2010
 -------------------------------------------------------------------------------
 Project state:
-        experimental
+dojox.mobile: stable
+dojox.mobile.app: experimental
 -------------------------------------------------------------------------------
 [ NO ]	l18n support?
 [ NO ]	a11y support?
@@ -13,6 +14,7 @@ Project state:
 Credits:
        Jared Jurkiewicz (jared.jurkiewicz at gmail.com)
        Yoshiroh Kamiyama (Contributor to Jared of base code).
+       Shane O'Sullivan (dojox.mobile.app)
 
 -------------------------------------------------------------------------------
 Project description
@@ -24,7 +26,7 @@ such as the Android and iPhone Smart Phones.
 
 The code is deliberately kept as lightweight as possible, using CSS3 animations
 and the like to perform the effects.  There is a compat.js, which will simulate
-most of the effects using dojo.animateProperty and dojox.gfx where possible on
+most of the effects using dojo.animateProperty and dojox.fx where possible on
 browsers such as FireFox and IE.  It will not load by default, it has to be
 required in separately.
 -------------------------------------------------------------------------------
diff --git a/dojox/mobile/ScrollableView.js b/dojox/mobile/ScrollableView.js
new file mode 100644
index 0000000..8408418
--- /dev/null
+++ b/dojox/mobile/ScrollableView.js
@@ -0,0 +1,118 @@
+dojo.provide("dojox.mobile.ScrollableView");
+
+dojo.require("dijit._WidgetBase");
+dojo.require("dojox.mobile");
+dojo.require("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.
+
+dojo.declare(
+	"dojox.mobile.ScrollableView",
+	[dojox.mobile.View, dojox.mobile._ScrollableMixin],
+{
+	flippable: false,
+
+	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();
+	},
+
+	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";
+			}
+			this.resizeView();
+		}else{
+			this.containerNode.appendChild(c);
+		}
+	},
+
+	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;
+			}
+			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);
+			}
+		}
+		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
+				});
+			}
+			if(fixed === "top"){
+				node.style.top = "0px";
+				this.fixedHeader = node;
+				return fixed;
+			}else if(fixed === "bottom"){
+				this.fixedFooter = node;
+				return fixed;
+			}
+		}
+		return null;
+	},
+
+	onAfterTransitionIn: function(moveTo, dir, transition, context, method){
+		this.flashScrollBar();
+	}
+});
diff --git a/dojox/mobile/TabBar.js b/dojox/mobile/TabBar.js
new file mode 100644
index 0000000..7b603f7
--- /dev/null
+++ b/dojox/mobile/TabBar.js
@@ -0,0 +1,205 @@
+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;
+			}
+			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"
+				});
+			}
+		}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)
+				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";
+				}
+				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(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);
+				}
+			}
+		}
+		this.img1.style.visibility = this.selected ? "hidden" : "";
+		this.img2.style.visibility = this.selected ? "" : "hidden";
+	},
+
+	onClick: function(e){
+		this.defaultClickAction();
+	}
+});
diff --git a/dojox/mobile/TabContainer.js b/dojox/mobile/TabContainer.js
new file mode 100644
index 0000000..bbd3d20
--- /dev/null
+++ b/dojox/mobile/TabContainer.js
@@ -0,0 +1,151 @@
+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/_ScrollableMixin.js b/dojox/mobile/_ScrollableMixin.js
new file mode 100644
index 0000000..be9b992
--- /dev/null
+++ b/dojox/mobile/_ScrollableMixin.js
@@ -0,0 +1,51 @@
+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";
+			}
+			params.fixedFooterHeight = node.offsetHeight;
+		}
+		this.init(params);
+		this.inherited(arguments);
+	}
+});
+(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 79e32e3..5cd4a6b 100644
--- a/dojox/mobile/_base.js
+++ b/dojox/mobile/_base.js
@@ -1,6 +1,7 @@
 dojo.provide("dojox.mobile._base");
 
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
+dojo.isBB = (navigator.userAgent.indexOf("BlackBerry") != -1) && !dojo.isWebKit;
 
 // summary:
 //		Mobile Widgets
@@ -24,7 +25,7 @@ dojo.require("dijit._Widget");
 
 dojo.declare(
 	"dojox.mobile.View",
-	dijit._Widget,
+	dijit._WidgetBase,
 {
 	// summary:
 	//		A widget that represents a view that occupies the full screen
@@ -52,7 +53,6 @@ dojo.declare(
 	buildRendering: function(){
 		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV");
 		this.domNode.className = "mblView";
-//		dojox.mobile.View._pillar = dojo.create("DIV", {className:"mblPillar"});
 		this.connect(this.domNode, "webkitAnimationEnd", "onAnimationEnd");
 		this.connect(this.domNode, "webkitAnimationStart", "onAnimationStart");
 		var id = location.href.match(/#(\w+)([^\w=]|$)/) ? RegExp.$1 : null;
@@ -71,7 +71,7 @@ dojo.declare(
 			if(!_this._visible){
 				_this.domNode.style.display = "none";
 			}else{
-				dojox.mobile._currentView = _this;
+				dojox.mobile.currentView = _this;
 				_this.onStartView();
 			}
 			_this.domNode.style.visibility = "visible";
@@ -159,7 +159,9 @@ dojo.declare(
 		var toNode;
 		if(moveTo){
 			if(typeof(moveTo) == "string"){
-				moveTo.match(/(\w+)/);
+				// removes a leading hash mark (#) and params if exists
+				// ex. "#bar&myParam=0003" -> "bar"
+				moveTo.match(/^#?([^&]+)/);
 				toNode = RegExp.$1;
 			}else{
 				toNode = moveTo;
@@ -178,17 +180,17 @@ dojo.declare(
 		toNode.style.display = "";
 		this.onBeforeTransitionOut.apply(this, arguments);
 		var toWidget = dijit.byNode(toNode);
-		if(toWidget && toWidget.onBeforeTransitionIn){
+		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 || window.pageYOffset || 0;
+				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
-								window.scrollTo(0, 1);
+								dojo.global.scrollTo(0, 1);
 							}, 0);
 						}
 					}
@@ -199,7 +201,7 @@ dojo.declare(
 						fromNode.style.top = toTop - scrollTop + "px";
 						if(dojo.config["mblHideAddressBar"] !== false && toTop > 0){
 							setTimeout(function(){ // iPhone needs setTimeout
-								window.scrollTo(0, toTop + 1);
+								dojo.global.scrollTo(0, toTop + 1);
 							}, 0);
 						}
 					}
@@ -207,7 +209,7 @@ dojo.declare(
 			}else{
 				toNode.style.top = "0px";
 			}
-			toWidget.onBeforeTransitionIn.apply(this, arguments);
+			toWidget.onBeforeTransitionIn.apply(toWidget, arguments);
 		}
 		toNode.style.display = "none";
 		toNode.style.visibility = "visible";
@@ -217,15 +219,12 @@ dojo.declare(
 	_doTransition: function(fromNode, toNode, transition, dir){
 		var rev = (dir == -1) ? " reverse" : "";
 		toNode.style.display = "";
-		if(transition){
-//			var pillar = dojox.mobile.View._pillar;
-//			pillar.style.height = fromNode.offsetHeight+"px";
-//			fromNode.parentNode.appendChild(pillar);
-			dojo.addClass(fromNode, transition + " out" + rev);
-			dojo.addClass(toNode, transition + " in" + rev);
-		}else{
+		if(!transition || transition == "none"){
 			this.domNode.style.display = "none";
 			this.invokeCallback();
+		}else{
+			dojo.addClass(fromNode, transition + " out" + rev);
+			dojo.addClass(toNode, transition + " in" + rev);
 		}
 	},
 
@@ -247,7 +246,6 @@ dojo.declare(
 			dojo.removeClass(li, "mblCloseContent");
 		}
 		if(isOut){
-//			dojox.mobile.View._pillar.parentNode.removeChild(dojox.mobile.View._pillar);
 			this.invokeCallback();
 		}
 		// this.domNode may be destroyed as a result of invoking the callback,
@@ -258,13 +256,11 @@ dojo.declare(
 	invokeCallback: function(){
 		this.onAfterTransitionOut.apply(this, this._arguments);
 		var toWidget = dijit.byNode(this.toNode);
-		if(toWidget && toWidget.onAfterTransitionIn){
-			toWidget.onAfterTransitionIn.apply(this, this._arguments);
+		if(toWidget){
+			toWidget.onAfterTransitionIn.apply(toWidget, this._arguments);
 		}
 
-		if(dojo.hash){
-			dojox.mobile._currentView = toWidget;
-		}
+		dojox.mobile.currentView = toWidget;
 
 		var c = this._context, m = this._method;
 		if(!c && !m){ return; }
@@ -280,6 +276,30 @@ dojo.declare(
 		}
 	},
 
+	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);
 	}
@@ -287,41 +307,50 @@ dojo.declare(
 
 dojo.declare(
 	"dojox.mobile.Heading",
-	dijit._Widget,
+	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 = this.domNode.parentNode && dijit.byNode(this.domNode.parentNode); // parentNode is null if created programmatically
+		this._view = dijit.getEnclosingWidget(this.domNode.parentNode); // parentNode is null if created programmatically
 		if(this.label){
-			this.domNode.innerHTML = this.label;
+			this.domNode.appendChild(document.createTextNode(this.label));
 		}else{
-			this.label = this.domNode.innerHTML;
+			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 head = dojo.doc.createElement("DIV");
-			head.className = "mblArrowButtonHead";
-			var body = this._body = dojo.doc.createElement("DIV");
-			body.className = "mblArrowButtonBody mblArrowButtonText";
+			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.doc.createElement("DIV");
-			neck.className = "mblArrowButtonNeck";
-
-			this.domNode.appendChild(head);
-			this.domNode.appendChild(body);
-			this.domNode.appendChild(neck);
-
+			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");
@@ -336,32 +365,17 @@ dojo.declare(
 			this.label = label;
 			this.domNode.firstChild.nodeValue = label;
 		}
-		var s = this.domNode.style;
-		if(this.label.length > 12){
-			// create a clone to calculate the arrow button width correctly
-			// even when the heading is in the invisible state.
-			var h = this.domNode.cloneNode(true);
-			h.style.visibility = "hidden";
-			dojo.body().appendChild(h);
-			var b = h.childNodes[2];
-			s.paddingLeft = b.offsetWidth + 30 + "px";
-			s.textAlign = "left";
-			dojo.body().removeChild(h);
-			h = null;
-		}else{
-			s.paddingLeft = "";
-			s.textAlign = "";
-		}
 	},
 
 	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){
+			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");
 			}
@@ -375,7 +389,7 @@ dojo.declare(
 
 dojo.declare(
 	"dojox.mobile.RoundRect",
-	dijit._Widget,
+	dijit._WidgetBase,
 {
 	shadow: false,
 
@@ -387,7 +401,7 @@ dojo.declare(
 
 dojo.declare(
 	"dojox.mobile.RoundRectCategory",
-	dijit._Widget,
+	dijit._WidgetBase,
 {
 	label: "",
 
@@ -414,7 +428,7 @@ dojo.declare(
 
 dojo.declare(
 	"dojox.mobile.RoundRectList",
-	dijit._Widget,
+	dijit._WidgetBase,
 {
 	transition: "slide",
 	iconBase: "",
@@ -436,6 +450,7 @@ 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";
@@ -444,18 +459,24 @@ dojo.declare(
 
 dojo.declare(
 	"dojox.mobile.AbstractItem",
-	dijit._Widget,
+	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();
@@ -466,17 +487,34 @@ dojo.declare(
 		}
 	},
 
-	transitionTo: function(moveTo, href, url){
+	findCurrentView: function(moveTo){
+		var w;
+		if(moveTo){
+			w = dijit.byId(moveTo);
+			if(w){ return w.getShowingView(); }
+		}
 		var n = this.domNode.parentNode;
-		var w; // the current view widget
 		while(true){
 			w = dijit.getEnclosingWidget(n);
-			if(!w){ return; }
+			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){
-			w.performTransition(null, 1, this.transition, this, function(){location.href = 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){
@@ -491,6 +529,7 @@ dojo.declare(
 					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();
@@ -502,7 +541,7 @@ dojo.declare(
 							prog.stop();
 							if(response){
 								this._text = response;
-								this.transitionTo(moveTo, href, url);
+								this.transitionTo(moveTo, href, url, scene);
 							}
 						}));
 						xhr.addErrback(function(error){
@@ -520,13 +559,19 @@ dojo.declare(
 				dojox.mobile._viewMap[url] = id;
 			}
 			moveTo = id;
+			w = this.findCurrentView(moveTo) || w; // the current view widget
 		}
-		w.performTransition(moveTo, 1, this.transition, this.callback && this, this.callback);
+		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">
@@ -536,10 +581,11 @@ dojo.declare(
 			}
 			view.setAttribute("_started", "true"); // to avoid startup() is called
 			view.style.visibility = "hidden";
-			dojo.body().appendChild(container);
+			target.appendChild(container);
 			(dojox.mobile.parser || dojo.parser).parse(container);
+			target.appendChild(target.removeChild(container).firstChild); // reparent
 		}else if(text.charAt(0) == "{"){ // json
-			dojo.body().appendChild(container);
+			target.appendChild(container);
 			this._ws = [];
 			view = this._instantiate(eval('('+text+')'), container);
 			for(var i = 0; i < this._ws.length; i++){
@@ -592,6 +638,37 @@ dojo.declare(
 		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;
@@ -605,6 +682,8 @@ dojo.declare(
 	rightText: "",
 	btnClass: "",
 	anchorLabel: false,
+	noArrow: false,
+	selected: false,
 
 	buildRendering: function(){
 		this.inheritParams();
@@ -626,16 +705,16 @@ dojo.declare(
 		}
 		a.appendChild(box);
 		if(this.rightText){
-			var txt = dojo.create("DIV");
-			txt.className = "mblRightText";
-			txt.innerHTML = this.rightText;
-			a.appendChild(txt);
+			this._setRightTextAttr(this.rightText);
 		}
 
 		if(this.moveTo || this.href || this.url || this.clickable){
-			var arrow = dojo.create("DIV");
-			arrow.className = "mblArrow";
-			a.appendChild(arrow);
+			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");
@@ -655,13 +734,13 @@ dojo.declare(
 					// 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";
+		li.className = "mblListItem" + (this.selected ? " mblItemSelected" : "");
 		li.appendChild(a);
 		this.setIcon();
 	},
@@ -682,6 +761,9 @@ dojo.declare(
 	},
 
 	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"){
@@ -694,22 +776,34 @@ dojo.declare(
 				}
 			}
 		}
-		var a = e.currentTarget;
-		var li = a.parentNode;
+		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");
-		setTimeout(function(){
-			dojo.removeClass(li, "mblItemSelected");
-		}, 1000);
-		this.transitionTo(this.moveTo, this.href, this.url);
+		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._Widget,
+	dijit._WidgetBase,
 {
 	value: "on",
 	leftLabel: "ON",
@@ -774,7 +868,7 @@ dojo.declare(
 		}
 		this.left.style.display = "block";
 		this.right.style.display = "block";
-		return false;
+		dojo.stopEvent(e);
 	},
 
 	onTouchMove: function(e){
@@ -792,13 +886,19 @@ dojo.declare(
 		if(pos >= -d){ pos = 0; }
 		this.inner.style.left = pos + "px";
 		this._moved = true;
-		return true;
 	},
 
 	onTouchEnd: function(e){
 		dojo.disconnect(this._conn1);
 		dojo.disconnect(this._conn2);
-		if(this.innerStartX == this.inner.offsetLeft){ return; }
+		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){
@@ -812,311 +912,8 @@ dojo.declare(
 });
 
 dojo.declare(
-	"dojox.mobile.IconContainer",
-	dijit._Widget,
-{
-	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);
-	},
-
-	_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";
-			}
-			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);
-		}
-	},
-
-	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);
-		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];
-			}
-		}
-		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));
-			}
-			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;
-	},
-
-	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);
-			}
-		}
-
-		if(len > 0){
-			(dojox.mobile.parser || dojo.parser).parse(this.containerNode);
-		}
-		this.lazy = false;
-	},
-
-	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);
-			}
-			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);
-				});
-			}
-			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;
-				}
-			}
-			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;
-	}
-});
-
-dojo.declare(
 	"dojox.mobile.Button",
-	dijit._Widget,
+	dijit._WidgetBase,
 {
 	btnClass: "mblBlueButton",
 	duration: 1000, // duration of selection, milliseconds
@@ -1145,115 +942,61 @@ dojo.declare(
 });
 
 dojo.declare(
-	"dojox.mobile.TabContainer",
-	dijit._Widget,
+	"dojox.mobile.ToolBarButton",
+	dojox.mobile.AbstractItem,
 {
-	iconBase: "",
-	iconPos: "",
+	selected: false,
+	_defaultColor: "mblColorDefault",
+	_selColor: "mblColorDefaultSel",
 
 	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));
+		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);
 
-		headerNode.className = "mblTabPanelHeader";
-		headerNode.align = "center";
-		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);
+		if(this.label){
+			this.domNode.innerHTML = this.label;
+		}else{
+			this.label = this.domNode.innerHTML;
 		}
-		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");
-	},
-
-	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._Widget,
-{
-	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; }
+		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");
 	},
 
-	buildRendering: function(){
-		this.inheritParams();
-		this.domNode = this.containerNode = this.srcNodeRef || dojo.doc.createElement("DIV");
-		this.domNode.className = "mblTabPane";
+	select: function(/*Boolean?*/deselect){
+		dojo.toggleClass(this.domNode, this._selColor, !deselect);
+		this.selected = !deselect;
 	},
 
-	getParentWidget: function(){
-		var ref = this.srcNodeRef || this.domNode;
-		return ref && ref.parentNode ? dijit.getEnclosingWidget(ref.parentNode) : null;
+	onClick: function(e){
+		this.defaultClickAction();
 	}
 });
 
@@ -1338,11 +1081,26 @@ dojox.mobile.setupIcon = function(/*DomNode*/iconNode, /*String*/iconPos){
 		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 = -t + "px";
-		iconNode.style.left = -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
 	/*
@@ -1376,11 +1134,14 @@ dojo.addOnLoad(function(){
 	//	You can disable hiding the address bar with the following djConfig.
 	//	var djConfig = { mblHideAddressBar: false };
 	if(dojo.config["mblHideAddressBar"] !== false){
-		var hideAddressBar = function(){
-			setTimeout(function(){ scrollTo(0, 1); }, 100);
-		};
-		hideAddressBar();
-		//dojo.connect(dojo.body(), "onorientationchange", hideAddressBar);
+		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
@@ -1414,7 +1175,7 @@ dojo.addOnLoad(function(){
 			return arr;
 		};
 		dojo.subscribe("/dojo/hashchange", null, function(value){
-			var view = dojox.mobile._currentView;
+			var view = dojox.mobile.currentView;
 			if(!view){ return; }
 			var params = dojox.mobile._params;
 			if(!params){ // browser back/forward button was pressed
diff --git a/dojox/mobile/app/AlertDialog.js b/dojox/mobile/app/AlertDialog.js
index 8c7537d..1fe5a0f 100644
--- a/dojox/mobile/app/AlertDialog.js
+++ b/dojox/mobile/app/AlertDialog.js
@@ -1,8 +1,8 @@
 dojo.provide("dojox.mobile.app.AlertDialog");
 dojo.experimental("dojox.mobile.app.AlertDialog");
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
 
-dojo.declare("dojox.mobile.app.AlertDialog", dijit._Widget, {
+dojo.declare("dojox.mobile.app.AlertDialog", dijit._WidgetBase, {
 
 	// title: String
 	//		The title of the AlertDialog
diff --git a/dojox/mobile/app/ImageThumbView.js b/dojox/mobile/app/ImageThumbView.js
index 56175d0..3de3ee7 100644
--- a/dojox/mobile/app/ImageThumbView.js
+++ b/dojox/mobile/app/ImageThumbView.js
@@ -1,10 +1,10 @@
 dojo.provide("dojox.mobile.app.ImageThumbView");
 dojo.experimental("dojox.mobile.app.ImageThumbView");
 
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
 dojo.require("dojo.string");
 
-dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
+dojo.declare("dojox.mobile.app.ImageThumbView", dijit._WidgetBase, {
 	// summary:
 	//		An image thumbnail gallery
 
@@ -13,12 +13,14 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 	//		If an item is a string, it is expected to be a URL. Otherwise
 	//		by default it is expected to have a 'url' member.  This can
 	//		be configured using the 'urlParam' attribute on this widget.
-	items: null,
+	items: [],
 
 	// urlParam: String
 	//		The paramter name used to retrieve an image url from a JSON object
 	urlParam: "url",
 
+	labelParam: null,
+
 	itemTemplate: '<div class="mblThumbInner">' +
 				'<div class="mblThumbOverlay"></div>' +
 				'<div class="mblThumbMask">' +
@@ -26,17 +28,35 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 				'</div>' +
 			'</div>',
 
-	minPadding: 5,
+	minPadding: 4,
 
 	maxPerRow: 3,
 
+	maxRows: -1,
+
 	baseClass: "mblImageThumbView",
 
+	thumbSize: "medium",
+
+	animationEnabled: true,
+
 	selectedIndex: -1,
 
 	cache: null,
 
+	cacheMustMatch: false,
+
+	clickEvent: "onclick",
+
+	cacheBust: false,
+
+	disableHide: false,
+
+	constructor: function(params, node){
+	},
+
 	postCreate: function(){
+
 		this.inherited(arguments);
 		var _this = this;
 
@@ -44,22 +64,27 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 
 		this.addThumb = dojo.hitch(this, this.addThumb);
 		this.handleImgLoad = dojo.hitch(this, this.handleImgLoad);
+		this.hideCached = dojo.hitch(this, this.hideCached);
 
 		this._onLoadImages = {};
 
 		this.cache = [];
 		this.visibleImages = [];
 
-		this.connect(this.domNode, "onclick", function(event){
+		this._cacheCounter = 0;
+
+		this.connect(this.domNode, this.clickEvent, function(event){
 			var itemNode = _this._getItemNodeFromEvent(event);
 
-			if(itemNode){
+			if(itemNode && !itemNode._cached){
 				_this.onSelect(itemNode._item, itemNode._index, _this.items);
 				dojo.query(".selected", this.domNode).removeClass("selected");
 				dojo.addClass(itemNode, "selected");
 			}
 		});
 
+		dojo.addClass(this.domNode, this.thumbSize);
+
 		this.resize();
 		this.render();
 	},
@@ -69,9 +94,33 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 		//		Dummy function that is triggered when an image is selected.
 	},
 
+	_setAnimationEnabledAttr: function(value){
+		this.animationEnabled = value;
+		dojo[value ? "addClass" : "removeClass"](this.domNode, "animated");
+	},
+
 	_setItemsAttr: function(items){
 		this.items = items || [];
 
+		var urls = {};
+		var i;
+		for(i = 0; i < this.items.length; i++){
+			urls[this.items[i][this.urlParam]] = 1;
+		}
+
+		var clearedUrls = [];
+		for(var url in this._onLoadImages){
+			if(!urls[url] && this._onLoadImages[url]._conn){
+				dojo.disconnect(this._onLoadImages[url]._conn);
+				this._onLoadImages[url].src = null;
+				clearedUrls.push(url);
+			}
+		}
+
+		for(i = 0; i < clearedUrls.length; i++){
+			delete this._onLoadImages[url];
+		}
+
 		this.render();
 	},
 
@@ -93,9 +142,22 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 	resize: function(){
 		this._thumbSize = null;
 
-		this._size = dojo.marginBox(this.domNode);
+		this._size = dojo.contentBox(this.domNode);
 
+		this.disableHide = true;
 		this.render();
+		this.disableHide = false;
+	},
+
+	hideCached: function(){
+		// summary:
+		//		Hides all cached nodes, so that they're no invisible and overlaying
+		//		other screen elements.
+		for(var i = 0; i < this.cache.length; i++){
+			if (this.cache[i]) {
+				dojo.style(this.cache[i], "display", "none");
+			}
+		}
 	},
 
 	render: function(){
@@ -104,24 +166,33 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 		var item;
 
 		var thumb;
-		while(this.visibleImages.length > 0){
+		while(this.visibleImages && this.visibleImages.length > 0){
 			thumb = this.visibleImages.pop();
 			this.cache.push(thumb);
 
-			dojo.addClass(thumb, "hidden");
+			if (!this.disableHide) {
+				dojo.addClass(thumb, "hidden");
+			}
 			thumb._cached = true;
 		}
+
+		if(this.cache && this.cache.length > 0){
+			setTimeout(this.hideCached, 1000);
+		}
+
 		if(!this.items || this.items.length == 0){
-			//dojo.empty(this.domNode);
 			return;
 		}
 
-
 		for(i = 0; i < this.items.length; i++){
 			item = this.items[i];
 			url = (dojo.isString(item) ? item : item[this.urlParam]);
 
 			this.addThumb(item, url, i);
+
+			if(this.maxRows > 0 && (i + 1) / this.maxPerRow >= this.maxRows){
+				break;
+			}
 		}
 
 		if(!this._thumbSize){
@@ -138,6 +209,7 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 			dojo.query(".mblThumb", this.domNode);
 
 		var pos = 0;
+		nodes = this.visibleImages;
 		for(i = 0; i < nodes.length; i++){
 			if(nodes[i]._cached){
 				continue;
@@ -166,22 +238,43 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 		}
 
 		var numRows = Math.ceil(pos / this.maxPerRow);
-		
-		if(this._numRows != numRows){
-			this._numRows = numRows;
-			dojo.style(this.domNode, "height",
-					(numRows * (this._thumbSize.h + this.padding * 2)) + "px");
-		}
 
+		this._numRows = numRows;
+
+		this.setContainerHeight((numRows * (this._thumbSize.h + this.padding * 2)));
+	},
+
+	setContainerHeight: function(amount){
+		dojo.style(this.domNode, "height", amount + "px");
 	},
 
 	addThumb: function(item, url, index){
 
 		var thumbDiv;
+		var cacheHit = false;
 		if(this.cache.length > 0){
 			// Reuse a previously created node if possible
-			thumbDiv = this.cache.pop();
-		}else{
+			var found = false;
+			// Search for an image with the same url first
+			for(var i = 0; i < this.cache.length; i++){
+				if(this.cache[i]._url == url){
+					thumbDiv = this.cache.splice(i, 1)[0];
+					found = true;
+					break
+				}
+			}
+
+			// if no image with the same url is found, just take the last one
+			if(!thumbDiv && !this.cacheMustMatch){
+            	thumbDiv = this.cache.pop();
+				dojo.removeClass(thumbDiv, "selected");
+			} else {
+				cacheHit = true;
+			}
+		}
+
+		if(!thumbDiv){
+
 			// Create a new thumb
 			thumbDiv = dojo.create("div", {
 				"class": "mblThumb hidden",
@@ -190,16 +283,34 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 				}, null, this)
 			}, this.domNode);
 		}
-		dojo.addClass(thumbDiv, "hidden");
-		var loader = dojo.create("img",{});
-		loader._thumbDiv = thumbDiv;
-		loader._conn = dojo.connect(loader, "onload", this.handleImgLoad);
-		loader._url = url;
-		thumbDiv._loading = true;
 
-		this._onLoadImages[url] = loader;
-		loader.src = url;
+		if(this.labelParam) {
+			var labelNode = dojo.query(".mblThumbLabel", thumbDiv)[0];
+			if(!labelNode) {
+				labelNode = dojo.create("div", {
+					"class": "mblThumbLabel"
+				}, thumbDiv);
+			}
+			labelNode.innerHTML = item[this.labelParam] || "";
+		}
+
+	    dojo.style(thumbDiv, "display", "");
+		if (!this.disableHide) {
+			dojo.addClass(thumbDiv, "hidden");
+		}
+
+		if (!cacheHit) {
+			var loader = dojo.create("img", {});
+			loader._thumbDiv = thumbDiv;
+			loader._conn = dojo.connect(loader, "onload", this.handleImgLoad);
+			loader._url = url;
+			thumbDiv._loading = true;
 
+			this._onLoadImages[url] = loader;
+			if (loader) {
+				loader.src = url;
+			}
+		}
 		this.visibleImages.push(thumbDiv);
 
 		thumbDiv._index = index;
@@ -209,6 +320,16 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 
 		if(!this._thumbSize){
 			this._thumbSize = dojo.marginBox(thumbDiv);
+
+			if(this._thumbSize.h == 0){
+				this._thumbSize.h = 100;
+				this._thumbSize.w = 100;
+			}
+
+			if(this.labelParam){
+				this._thumbSize.h += 8;
+			}
+
 			this.calcPadding();
 		}
 	},
@@ -218,9 +339,16 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 		dojo.disconnect(img._conn);
 		dojo.removeClass(img._thumbDiv, "hidden");
 		img._thumbDiv._loading = false;
+		img._conn = null;
+
+		var url = img._url;
+		if(this.cacheBust){
+			url += (url.indexOf("?") > -1 ? "&" : "?")
+				+ "cacheBust=" + (new Date()).getTime() + "_" + (this._cacheCounter++);
+		}
 
 		dojo.query(".mblThumbSrc", img._thumbDiv)
-				.style("backgroundImage", "url(" + img._url + ")");
+				.style("backgroundImage", "url(" + url + ")");
 
 		delete this._onLoadImages[img._url];
 	},
@@ -234,21 +362,28 @@ dojo.declare("dojox.mobile.app.ImageThumbView", dijit._Widget, {
 
 		this.maxPerRow = Math.floor(width / imgBounds);
 
-		this.padding = (width - (thumbWidth * this.maxPerRow)) / (this.maxPerRow * 2);
+		this.padding = Math.floor((width - (thumbWidth * this.maxPerRow)) / (this.maxPerRow * 2));
 	},
 
 	place: function(node, x, y){
-		// TODO: replace this with webkit transforms
-		
-		
 		dojo.style(node, {
 			"-webkit-transform" :"translate(" + x + "px," + y + "px)"
 		});
-//		dojo.style(node, {
-//			top: y + "px",
-//			left: x + "px",
-//			visibility: "visible"
-//		});
-	}
+	},
+
+	destroy: function(){
+		// Stop the loading of any more images
+
+		var img;
+		var counter = 0;
+		for (var url in this._onLoadImages){
+			img = this._onLoadImages[url];
+			if (img) {
+				img.src = null;
+				counter++;
+			}
+		}
 
+		this.inherited(arguments);
+	}
 });
\ No newline at end of file
diff --git a/dojox/mobile/app/List.js b/dojox/mobile/app/List.js
index 0ee45de..26b9008 100644
--- a/dojox/mobile/app/List.js
+++ b/dojox/mobile/app/List.js
@@ -2,13 +2,13 @@ dojo.provide("dojox.mobile.app.List");
 dojo.experimental("dojox.mobile.app.List");
 
 dojo.require("dojo.string");
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
 
 (function(){
 
 	var templateCache = {};
 
-	dojo.declare("dojox.mobile.app.List", dijit._Widget, {
+	dojo.declare("dojox.mobile.app.List", dijit._WidgetBase, {
 		// summary:
 		//		A templated list widget. Given a simple array of data objects
 		//		and a HTML template, it renders a list of elements, with
@@ -18,7 +18,7 @@ dojo.require("dijit._Widget");
 		// items: Array
 		//    The array of data items that will be rendered.
 		items: null,
-	
+
 		// itemTemplate: String
 		//		The URL to the HTML file containing the markup for each individual
 		//		data item.
@@ -29,6 +29,16 @@ dojo.require("dijit._Widget");
 		//		are no data items. This is optional.
 		emptyTemplate: "",
 
+		//  dividerTemplate: String
+		//    The URL to the HTML file containing the markup for the dividers
+		//    between groups of list items
+		dividerTemplate: "",
+
+		// dividerFunction: Function
+		//    Function to create divider elements. This should return a divider
+		//    value for each item in the list
+		dividerFunction: null,
+
 		// labelDelete: String
 		//		The label to display for the Delete button
 		labelDelete: "Delete",
@@ -36,45 +46,54 @@ dojo.require("dijit._Widget");
 		// labelCancel: String
 		//		The label to display for the Cancel button
 		labelCancel: "Cancel",
-	
+
 		// controller: Object
-		//		
+		//
 		controller: null,
-	
+
 		// autoDelete: Boolean
 		autoDelete: true,
 
 		// enableDelete: Boolean
 		enableDelete: true,
 
+		// enableHold: Boolean
+		enableHold: true,
+
+		// formatters: Object
+		//		A name/value map of functions used to format data for display
+		formatters: null,
+
 		// _templateLoadCount: Number
 		//		The number of templates remaining to load before the list renders.
 		_templateLoadCount: 0,
-	
+
 		// _mouseDownPos: Object
 		//    The coordinates of where a mouseDown event was detected
 		_mouseDownPos: null,
-	
+
+		baseClass: "list",
+
 		constructor: function(){
 			this._checkLoadComplete = dojo.hitch(this, this._checkLoadComplete);
 			this._replaceToken = dojo.hitch(this, this._replaceToken);
 			this._postDeleteAnim = dojo.hitch(this, this._postDeleteAnim);
 		},
-	
+
 		postCreate: function(){
-	
+
 			var _this = this;
-	
+
 			if(this.emptyTemplate){
 				this._templateLoadCount++;
 			}
 			if(this.itemTemplate){
 				this._templateLoadCount++;
 			}
-	
-			dojo.addClass(this.domNode, "list");
-			var msg;
-	
+			if(this.dividerTemplate){
+				this._templateLoadCount++;
+			}
+
 			this.connect(this.domNode, "onmousedown", function(event){
 				var touch = event;
 				if(event.targetTouches && event.targetTouches.length > 0){
@@ -83,46 +102,44 @@ dojo.require("dijit._Widget");
 
 				// Find the node that was tapped/clicked
 				var rowNode = _this._getRowNode(event.target);
-		
+
 				if(rowNode){
 					// Add the rows data to the event so it can be picked up
 					// by any listeners
 					_this._setDataInfo(rowNode, event);
-					
+
 					// Select and highlight the row
 					_this._selectRow(rowNode);
-					
+
 					// Record the position that was tapped
 					_this._mouseDownPos = {
 						x: touch.pageX,
 						y: touch.pageY
 					};
 					_this._dragThreshold = null;
-				}else{
-					console.log("didnt get a node");
 				}
 			});
-	
+
 			this.connect(this.domNode, "onmouseup", function(event){
-				// When the mouse/finger comes off the list, 
+				// When the mouse/finger comes off the list,
 				// call the onSelect function and deselect the row.
 				if(event.targetTouches && event.targetTouches.length > 0){
 					event = event.targetTouches[0];
 				}
 				var rowNode = _this._getRowNode(event.target);
-		
+
 				if(rowNode){
-		
+
 					_this._setDataInfo(rowNode, event);
-		
+
 					if(_this._selectedRow){
 						_this.onSelect(rowNode._data, rowNode._idx, rowNode);
 					}
-		
+
 					this._deselectRow();
 				}
 			});
-	
+
 			// If swipe-to-delete is enabled, listen for the mouse moving
 			if(this.enableDelete){
 				this.connect(this.domNode, "mousemove", function(event){
@@ -131,7 +148,7 @@ dojo.require("dijit._Widget");
 						return;
 					}
 					var rowNode = _this._getRowNode(event.target);
-					
+
 					// Still check for enableDelete in case it's changed after
 					// this listener is added.
 					if(_this.enableDelete && rowNode && !_this._deleting){
@@ -146,7 +163,7 @@ dojo.require("dijit._Widget");
 					event = event.touches[0];
 				}
 				var rowNode = _this._getRowNode(event.target, true);
-		
+
 				if(rowNode){
 					_this._setDataInfo(rowNode, event);
 				}
@@ -162,21 +179,25 @@ dojo.require("dijit._Widget");
 					_this._deselectRow();
 				}
 			});
-	
+
 			// If no item template has been provided, it is an error.
 			if(!this.itemTemplate){
 				throw Error("An item template must be provided to " + this.declaredClass);
 			}
-			
+
 			// Load the item template
 			this._loadTemplate(this.itemTemplate, "itemTemplate", this._checkLoadComplete);
-	
+
 			if(this.emptyTemplate){
 				// If the optional empty template has been provided, load it.
 				this._loadTemplate(this.emptyTemplate, "emptyTemplate", this._checkLoadComplete);
 			}
+
+			if(this.dividerTemplate){
+				this._loadTemplate(this.dividerTemplate, "dividerTemplate", this._checkLoadComplete);
+			}
 		},
-	
+
 		handleDrag: function(event){
 			// summary:
 			//		Handles rows being swiped for deletion.
@@ -184,11 +205,11 @@ dojo.require("dijit._Widget");
 			if(event.targetTouches && event.targetTouches.length > 0){
 				touch = event.targetTouches[0];
 			}
-			
+
 			// Get the distance that the mouse or finger has moved since
 			// beginning the swipe action.
 			var diff = touch.pageX - this._mouseDownPos.x;
-	
+
 			var absDiff = Math.abs(diff);
 			if(absDiff > 10 && !this._dragThreshold){
 				// Make the user drag the row 60% of the width to remove it
@@ -197,16 +218,16 @@ dojo.require("dijit._Widget");
 					this.createDeleteButtons(this._selectedRow);
 				}
 			}
-	
+
 			this._selectedRow.style.left = (absDiff > 10 ? diff : 0) + "px";
-	
+
 			// If the user has dragged the row more than the threshold, slide
 			// it off the screen in preparation for deletion.
 			if(this._dragThreshold && this._dragThreshold < absDiff){
 				this.preDelete(diff);
 			}
 		},
-	
+
 		handleDragCancel: function(){
 			// summary:
 			//		Handle a drag action being cancelled, for whatever reason.
@@ -214,24 +235,23 @@ dojo.require("dijit._Widget");
 			if(this._deleting){
 				return;
 			}
-	
 			dojo.removeClass(this._selectedRow, "hold");
 			this._selectedRow.style.left = 0;
 			this._mouseDownPos = null;
 			this._dragThreshold = null;
-	
+
 			this._deleteBtns && dojo.style(this._deleteBtns, "display", "none");
 		},
-	
+
 		preDelete: function(currentLeftPos){
 			// summary:
 			//    Slides the row offscreen before it is deleted
-	
+
 			// TODO: do this with CSS3!
 			var self = this;
-	
+
 			this._deleting = true;
-	
+
 			dojo.animateProperty({
 				node: this._selectedRow,
 				duration: 400,
@@ -248,9 +268,9 @@ dojo.require("dijit._Widget");
 				})
 			}).play();
 		},
-	
+
 		deleteRow: function(row){
-	
+
 			// First make the row invisible
 			// Put it back where it came from
 			dojo.style(row, {
@@ -258,29 +278,38 @@ dojo.require("dijit._Widget");
 				minHeight: "0px"
 			});
 			dojo.removeClass(row, "hold");
-	
+
 			this._deleteAnimConn =
 				this.connect(row, "webkitAnimationEnd", this._postDeleteAnim);
-	
+
 			dojo.addClass(row, "collapsed");
-	
 		},
-	
+
 		_postDeleteAnim: function(event){
 			// summary:
 			//		Completes the deletion of a row.
-	
+
 			if(this._deleteAnimConn){
 				this.disconnect(this._deleteAnimConn);
 				this._deleteAnimConn = null;
 			}
-	
+
 			var row = this._selectedRow;
 			var sibling = row.nextSibling;
-	
+			var prevSibling = row.previousSibling;
+
+			// If the previous node is a divider and either this is
+			// the last element in the list, or the next node is
+			// also a divider, remove the divider for the deleted section.
+			if(prevSibling && prevSibling._isDivider){
+				if(!sibling || sibling._isDivider){
+					prevSibling.parentNode.removeChild(prevSibling);
+				}
+			}
+
 			row.parentNode.removeChild(row);
 			this.onDelete(row._data, row._idx, this.items);
-	
+
 			// Decrement the index of each following row
 			while(sibling){
 				if(sibling._idx){
@@ -288,16 +317,16 @@ dojo.require("dijit._Widget");
 				}
 				sibling = sibling.nextSibling;
 			}
-	
+
 			dojo.destroy(row);
 
 			// Fix up the 'first' and 'last' CSS classes on the rows
 			dojo.query("> *:not(.buttons)", this.domNode).forEach(this.applyClass);
-	
+
 			this._deleting = false;
 			this._deselectRow();
 		},
-	
+
 		createDeleteButtons: function(aroundNode){
 			// summary:
 			//		Creates the two buttons displayed when confirmation is
@@ -306,15 +335,15 @@ dojo.require("dijit._Widget");
 			//		The DOM node of the row about to be deleted.
 			var mb = dojo.marginBox(aroundNode);
 			var pos = dojo._abs(aroundNode, true);
-	
+
 			if(!this._deleteBtns){
 			// Create the delete buttons.
 				this._deleteBtns = dojo.create("div",{
 					"class": "buttons"
 				}, this.domNode);
-		
+
 				this.buttons = [];
-		
+
 				this.buttons.push(new dojox.mobile.Button({
 					btnClass: "mblRedButton",
 					label: this.labelDelete
@@ -323,16 +352,15 @@ dojo.require("dijit._Widget");
 					btnClass: "mblBlueButton",
 					label: this.labelCancel
 				}));
-		
+
 				dojo.place(this.buttons[0].domNode, this._deleteBtns);
 				dojo.place(this.buttons[1].domNode, this._deleteBtns);
-		
+
 				dojo.addClass(this.buttons[0].domNode, "deleteBtn");
 				dojo.addClass(this.buttons[1].domNode, "cancelBtn");
-		
+
 				this._handleButtonClick = dojo.hitch(this._handleButtonClick);
-					this.connect(this._deleteBtns, "onclick", 
-									this._handleButtonClick);
+				this.connect(this._deleteBtns, "onclick", this._handleButtonClick);
 			}
 			dojo.removeClass(this._deleteBtns, "fade out fast");
 			dojo.style(this._deleteBtns, {
@@ -343,7 +371,7 @@ dojo.require("dijit._Widget");
 				left: "0px"
 			});
 		},
-	
+
 		onDelete: function(data, index, array){
 			// summary:
 			//    Called when a row is deleted
@@ -353,7 +381,7 @@ dojo.require("dijit._Widget");
 			//		The index of the data in the total array
 			// array:
 			//		The array of data used.
-	
+
 			array.splice(index, 1);
 
 			// If the data is empty, rerender in case an emptyTemplate has
@@ -362,20 +390,20 @@ dojo.require("dijit._Widget");
 				this.render();
 			}
 		},
-	
+
 		cancelDelete: function(){
 			// summary:
 			//		Cancels the deletion of a row.
 			this._deleting = false;
 			this.handleDragCancel();
 		},
-	
+
 		_handleButtonClick: function(event){
 			// summary:
 			//		Handles the click of one of the deletion buttons, either to
 			//		delete the row or to cancel the deletion.
 			if(event.touches && event.touches.length > 0){
-			event = event.touches[0];
+				event = event.touches[0];
 			}
 			var node = event.target;
 			if(dojo.hasClass(node, "deleteBtn")){
@@ -387,12 +415,12 @@ dojo.require("dijit._Widget");
 			}
 			dojo.addClass(this._deleteBtns, "fade out");
 		},
-	
+
 		applyClass: function(node, idx, array){
 			// summary:
 			//		Applies the 'first' and 'last' CSS classes to the relevant
 			//		rows.
-	
+
 			dojo.removeClass(node, "first last");
 			if(idx == 0){
 				dojo.addClass(node, "first");
@@ -409,27 +437,28 @@ dojo.require("dijit._Widget");
 			event.item = rowNode._data;
 			event.index = rowNode._idx;
 		},
-	
+
 		onSelect: function(data, index, rowNode){
 			// summary:
 			//		Dummy function that is called when a row is tapped
 		},
-	
+
 		_selectRow: function(row){
 			// summary:
 			//		Selects a row, applies the relevant CSS classes.
 			if(this._deleting && this._selectedRow && row != this._selectedRow){
 				this.cancelDelete();
 			}
-	
+
 			if(!dojo.hasClass(row, "row")){
 				return;
 			}
-	
-			dojo.addClass(row, "hold");
+			if(this.enableHold || this.enableDelete){
+				dojo.addClass(row, "hold");
+			}
 			this._selectedRow = row;
 		},
-	
+
 		_deselectRow: function(){
 			// summary:
 			//		Deselects a row, and cancels any drag actions that were
@@ -441,7 +470,7 @@ dojo.require("dijit._Widget");
 			dojo.removeClass(this._selectedRow, "hold");
 			this._selectedRow = null;
 		},
-	
+
 		_getRowNode: function(fromNode, ignoreNoClick){
 			// summary:
 			//		Gets the DOM node of the row that is equal to or the parent
@@ -452,76 +481,109 @@ dojo.require("dijit._Widget");
 				}
 				fromNode = fromNode.parentNode;
 			}
-			return fromNode;
+			return fromNode == this.domNode ? null : fromNode;
 		},
-	
+
+		applyTemplate: function(template, data){
+			return dojo._toDom(dojo.string.substitute(
+					template, data, this._replaceToken, this.formatters || this));
+		},
+
 		render: function(){
 			// summary:
 			//		Renders the list.
 
 			// Delete all existing nodes, except the deletion buttons.
 			dojo.query("> *:not(.buttons)", this.domNode).forEach(dojo.destroy);
-	
-			var rows = [];
-			var row, i;
-	
-			dojo.addClass(this.domNode, "list");
-			
-			for(i = 0; i < this.items.length; i++){
-				// Create a document fragment containing the templated row
-				row = dojo._toDom(dojo.string.substitute(
-					this.itemTemplate, this.items[i], this._replaceToken, this));
-	
-				rows.push(row);
-			}
-			for(i = 0; i < this.items.length; i++){
-				rows[i]._data = this.items[i];
-				rows[i]._idx = i;
-				this.domNode.appendChild(rows[i]);
-			}
-	
+
 			// If there is no data, and an empty template has been provided,
 			// render it.
 			if(this.items.length < 1 && this.emptyTemplate){
 				dojo.place(dojo._toDom(this.emptyTemplate), this.domNode, "first");
+			}else{
+				this.domNode.appendChild(this._renderRange(0, this.items.length));
 			}
-	
 			if(dojo.hasClass(this.domNode.parentNode, "mblRoundRect")){
 				dojo.addClass(this.domNode.parentNode, "mblRoundRectList")
 			}
-	
-			var divs = dojo.query("> div:not(.buttons)", this.domNode);
-			divs.addClass("row");
+
+			var divs = dojo.query("> .row", this.domNode);
 			if(divs.length > 0){
 				dojo.addClass(divs[0], "first");
 				dojo.addClass(divs[divs.length - 1], "last");
 			}
 		},
-	
+
+		_renderRange: function(startIdx, endIdx){
+
+			var rows = [];
+			var row, i;
+			var frag = document.createDocumentFragment();
+			startIdx = Math.max(0, startIdx);
+			endIdx = Math.min(endIdx, this.items.length);
+
+			for(i = startIdx; i < endIdx; i++){
+				// Create a document fragment containing the templated row
+				row = this.applyTemplate(this.itemTemplate, this.items[i]);
+				dojo.addClass(row, 'row');
+				row._data = this.items[i];
+				row._idx = i;
+				rows.push(row);
+			}
+			if(!this.dividerFunction || !this.dividerTemplate){
+				for(i = startIdx; i < endIdx; i++){
+					rows[i]._data = this.items[i];
+					rows[i]._idx = i;
+					frag.appendChild(rows[i]);
+				}
+			}else{
+				var prevDividerValue = null;
+				var dividerValue;
+				var divider;
+				for(i = startIdx; i < endIdx; i++){
+					rows[i]._data = this.items[i];
+					rows[i]._idx = i;
+
+					dividerValue = this.dividerFunction(this.items[i]);
+					if(dividerValue && dividerValue != prevDividerValue){
+						divider = this.applyTemplate(this.dividerTemplate, {
+							label: dividerValue,
+							item: this.items[i]
+						});
+						divider._isDivider = true;
+						frag.appendChild(divider);
+						prevDividerValue = dividerValue;
+					}
+					frag.appendChild(rows[i]);
+				}
+			}
+			return frag;
+		},
+
 		_replaceToken: function(value, key){
-				if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
-				if(typeof value == "undefined"){ return ""; } // 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?
-	
+			if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); }
+			if(typeof value == "undefined"){ return ""; } // 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?
+
 		},
-	
+
 		_checkLoadComplete: function(){
 			// summary:
 			//		Checks if all templates have loaded
 			this._templateLoadCount--;
-	
+
 			if(this._templateLoadCount < 1 && this.get("items")){
 				this.render();
 			}
 		},
-	
+
 		_loadTemplate: function(url, thisAttr, callback){
 			// summary:
 			//		Loads a template
@@ -529,13 +591,13 @@ dojo.require("dijit._Widget");
 				callback();
 				return;
 			}
-	
+
 			if(templateCache[url]){
 				this.set(thisAttr, templateCache[url]);
 				callback();
 			}else{
 				var _this = this;
-		
+
 				dojo.xhrGet({
 					url: url,
 					sync: false,
@@ -548,19 +610,25 @@ dojo.require("dijit._Widget");
 				});
 			}
 		},
-	
-	
+
+
+		_setFormattersAttr: function(formatters){
+			// summary:
+			//    Sets the data items, and causes a rerender of the list
+			this.formatters = formatters;
+		},
+
 		_setItemsAttr: function(items){
 			// summary:
 			//    Sets the data items, and causes a rerender of the list
-	
+
 			this.items = items || [];
-	
+
 			if(this._templateLoadCount < 1 && items){
 				this.render();
 			}
 		},
-	
+
 		destroy: function(){
 			if(this.buttons){
 				dojo.forEach(this.buttons, function(button){
@@ -568,7 +636,7 @@ dojo.require("dijit._Widget");
 				});
 				this.buttons = null;
 			}
-	
+
 			this.inherited(arguments);
 		}
 
diff --git a/dojox/mobile/app/SceneController.js b/dojox/mobile/app/SceneController.js
index 35a6477..e7fb829 100644
--- a/dojox/mobile/app/SceneController.js
+++ b/dojox/mobile/app/SceneController.js
@@ -11,144 +11,157 @@ dojo.require("dojox.mobile._base");
 	dojo.declare("dojox.mobile.app.SceneController", dojox.mobile.View, {
 
 		stageController: null,
-	
+
+		keepScrollPos: false,
+
 		init: function(sceneName, params){
 			// summary:
 			//    Initializes the scene by loading the HTML template and code, if it has
 			//    not already been loaded
-	
+
 			this.sceneName = sceneName;
 			this.params = params;
 			var templateUrl = app.resolveTemplate(sceneName);
-	
+
 			this._deferredInit = new dojo.Deferred();
-	
-			dojo.xhrGet({
-				url: templateUrl,
-				handleAs: "text"
-			}).addCallback(dojo.hitch(this, this._setContents));
-	
+
+			if(templates[sceneName]){
+				// If the template has been cached, do not load it again.
+				this._setContents(templates[sceneName]);
+			}else{
+				// Otherwise load the template
+				dojo.xhrGet({
+					url: templateUrl,
+					handleAs: "text"
+				}).addCallback(dojo.hitch(this, this._setContents));
+			}
+
 			return this._deferredInit;
 		},
-	
+
 		_setContents: function(templateHtml){
 			// summary:
 			//    Sets the content of the View, and invokes either the loading or
 			//    initialization of the scene assistant.
 			templates[this.sceneName] = templateHtml;
-	
+
 			this.domNode.innerHTML = "<div>" + templateHtml + "</div>";
-	
+
 			var sceneAssistantName = "";
-										
+
 			var nameParts = this.sceneName.split("-");
-			
+
 			for(var i = 0; i < nameParts.length; i++){
 				sceneAssistantName += nameParts[i].substring(0, 1).toUpperCase()
 							+ nameParts[i].substring(1);
 			}
 			sceneAssistantName += "Assistant";
 			this.sceneAssistantName = sceneAssistantName;
-			
+
 			var _this = this;
-			
+
 			dojox.mobile.app.loadResourcesForScene(this.sceneName, function(){
-				
+
 				console.log("All resources for ",_this.sceneName," loaded");
-				
+
 				var assistant;
-				if(typeof(window[sceneAssistantName]) != "undefined"){
+				if(typeof(dojo.global[sceneAssistantName]) != "undefined"){
 					_this._initAssistant();
 				}else{
 					var assistantUrl = app.resolveAssistant(_this.sceneName);
-			
+
 					dojo.xhrGet({
 						url: assistantUrl,
 						handleAs: "text"
 					}).addCallback(function(text){
-						dojo.eval(text);
-			
+						try{
+							dojo.eval(text);
+						}catch(e){
+							console.log("Error initializing code for scene " + _this.sceneName
+							+ '. Please check for syntax errors');
+							throw e;
+						}
 						_this._initAssistant();
 					});
 				}
 			});
-			
+
 		},
-	
+
 		_initAssistant: function(){
 			// summary:
 			//    Initializes the scene assistant. At this point, the View is
 			//    populated with the HTML template, and the scene assistant type
 			//    is declared.
-	
+
 			console.log("Instantiating the scene assistant " + this.sceneAssistantName);
-	
+
 			var cls = dojo.getObject(this.sceneAssistantName);
-			
+
 			if(!cls){
 				throw Error("Unable to resolve scene assistant "
 							+ this.sceneAssistantName);
 			}
-			
+
 			this.assistant = new cls(this.params);
-	
+
 			this.assistant.controller = this;
 			this.assistant.domNode = this.domNode.firstChild;
-	
+
 			this.assistant.setup();
-	
+
 			this._deferredInit.callback();
 		},
-	
+
 		query: function(selector, node){
 			// summary:
 			//    Queries for DOM nodes within either the node passed in as an argument
 			//    or within this view.
-	
+
 			return dojo.query(selector, node || this.domNode)
 		},
-	
+
 		parse: function(node){
 			var widgets = this._widgets =
 				dojox.mobile.parser.parse(node || this.domNode, {
 					controller: this
 				});
-	
+
 			// Tell all widgets what their controller is.
 			for(var i = 0; i < widgets.length; i++){
-				widgets[i].attr("controller", this);
+				widgets[i].set("controller", this);
 			}
 		},
-	
+
 		getWindowSize: function(){
 			// TODO, this needs cross browser testing
-	
+
 			return {
-				w: window.innerWidth,
-				h: window.innerHeight
+				w: dojo.global.innerWidth,
+				h: dojo.global.innerHeight
 			}
 		},
-	
+
 		showAlertDialog: function(props){
-	
+
 			var size = dojo.marginBox(this.assistant.domNode);
 			var dialog = new dojox.mobile.app.AlertDialog(
 					dojo.mixin(props, {controller: this}));
 			this.assistant.domNode.appendChild(dialog.domNode);
-	
+
 			console.log("Appended " , dialog.domNode, " to ", this.assistant.domNode);
 			dialog.show();
 		},
-	
+
 		popupSubMenu: function(info){
 			var widget = new dojox.mobile.app.ListSelector({
 				controller: this,
 				destroyOnHide: true,
 				onChoose: info.onChoose
 			});
-	
+
 			this.assistant.domNode.appendChild(widget.domNode);
-	
+
 			widget.set("data", info.choices);
 			widget.show(info.fromNode);
 		}
diff --git a/dojox/mobile/app/StageController.js b/dojox/mobile/app/StageController.js
index 749a701..554090d 100644
--- a/dojox/mobile/app/StageController.js
+++ b/dojox/mobile/app/StageController.js
@@ -14,7 +14,7 @@ dojo.declare("dojox.mobile.app.StageController", null,{
 	constructor: function(node){
 		this.domNode = node;
 		this.scenes = [];
-	
+
 		if(dojo.config.mobileAnim){
 			this.effect = dojo.config.mobileAnim;
 		}
@@ -25,12 +25,11 @@ dojo.declare("dojox.mobile.app.StageController", null,{
 	},
 
 	pushScene: function(sceneName, params){
-		console.log("pushScene", sceneName);
 		if(this._opInProgress){
 			return;
 		}
 		this._opInProgress = true;
-	
+
 		// Push new scenes as the first element on the page.
 		var node = dojo.create("div", {
 			"class": "scene-wrapper",
@@ -38,25 +37,23 @@ dojo.declare("dojox.mobile.app.StageController", null,{
 				visibility: "hidden"
 			}
 		}, this.domNode);
-	
+
 		var controller = new dojox.mobile.app.SceneController({}, node);
-	
+
 		if(this.scenes.length > 0){
-			this.scenes[0].assistant.deactivate();
+			this.scenes[this.scenes.length -1].assistant.deactivate();
 		}
 
 		this.scenes.push(controller);
-	
+
 		var _this = this;
-	
+
 		dojo.forEach(this.scenes, this.setZIndex);
-	
+
 		controller.stageController = this;
-	
+
 		controller.init(sceneName, params).addCallback(function(){
-	
-			console.log("In callback after controller.init");
-	
+
 			if(_this.scenes.length == 1){
 				controller.domNode.style.visibility = "visible";
 				_this.scenes[_this.scenes.length - 1].assistant.activate(params);
@@ -64,18 +61,16 @@ dojo.declare("dojox.mobile.app.StageController", null,{
 			}else{
 				_this.scenes[_this.scenes.length - 2]
 					.performTransition(
-						_this.scenes[_this.scenes.length - 1].domNode, 
-						1, 
-						_this.effect, 
-						null, 
+						_this.scenes[_this.scenes.length - 1].domNode,
+						1,
+						_this.effect,
+						null,
 						function(){
 							// When the scene is ready, activate it.
 							_this.scenes[_this.scenes.length - 1].assistant.activate(params);
 							_this._opInProgress = false;
 						});
 			}
-			console.log("at end of callback after controller.init");
-			
 		});
 	},
 
@@ -89,17 +84,17 @@ dojo.declare("dojox.mobile.app.StageController", null,{
 		if(this._opInProgress){
 			return;
 		}
-	
+
 		var _this = this;
 		if(this.scenes.length > 1){
-	
+
 			this._opInProgress = true;
 			this.scenes[_this.scenes.length - 2].assistant.activate(data);
 			this.scenes[_this.scenes.length - 1]
 				.performTransition(
-					_this.scenes[this.scenes.length - 2].domNode, 
-					-1, 
-					this.effect, 
+					_this.scenes[this.scenes.length - 2].domNode,
+					-1,
+					this.effect,
 					null,
 					function(){
 						// When the scene is no longer visible, destroy it
@@ -116,16 +111,16 @@ dojo.declare("dojox.mobile.app.StageController", null,{
 		if(this._opInProgress){
 			return;
 		}
-	
+
 		while(this.scenes.length > 2 &&
 				this.scenes[this.scenes.length - 2].sceneName != sceneName){
 			this._destroyScene(this.scenes[this.scenes.length - 2]);
 			this.scenes.splice(this.scenes.length - 2, 1);
 		}
-	
+
 		this.popScene(data);
 	},
-	
+
 	_destroyScene: function(scene){
 		scene.assistant.deactivate();
 		scene.assistant.destroy();
diff --git a/dojox/mobile/app/TextBox.js b/dojox/mobile/app/TextBox.js
index 9c208cd..3485bbf 100644
--- a/dojox/mobile/app/TextBox.js
+++ b/dojox/mobile/app/TextBox.js
@@ -5,9 +5,9 @@ dojo.require("dojox.mobile.app._Widget");
 dojo.require("dojox.mobile.app._FormWidget");
 
 dojo.declare(
-	"dojox.mobile.app.TextBox", 
+	"dojox.mobile.app.TextBox",
 	dojox.mobile.app._FormValueWidget, {
-	
+
 		// summary:
 		//		A base class for textbox form inputs
 
@@ -39,27 +39,27 @@ dojo.declare(
 		//		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(this.srcNodeRef, "value") || "",
+				value: dojo.attr(node, "value") || "",
 				placeholder: this.placeHolder || null
 			});
-			
+
 			this.domNode = this.textbox = this.focusNode = node;
 		},
 
@@ -69,7 +69,7 @@ dojo.declare(
 				dojo.attr(this.textbox, "placeholder", v);
 			}
 		},
-		
+
 
 		_getValueAttr: function(){
 			// summary:
@@ -110,14 +110,14 @@ dojo.declare(
 				// 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 
+					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)) 
+			if(formattedValue != null && formattedValue != undefined
+					&& ((typeof formattedValue) != "number" || !isNaN(formattedValue))
 					&& this.textbox.value != formattedValue){
 				this.textbox.value = formattedValue;
 			}
@@ -215,8 +215,6 @@ dojo.declare(
 			// 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
 
-			console.log("postCreate of textinput");
-
 			this.textbox.setAttribute("value", this.textbox.value); // DOM and JS values shuld be the same
 			this.inherited(arguments);
 			if(dojo.isMoz || dojo.isOpera){
@@ -282,7 +280,7 @@ dojo.declare(
 			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){
@@ -306,7 +304,7 @@ dojo.declare(
 					}
 				});
 			}
-			
+
 			this._refreshState();
 			this.inherited(arguments);
 		},
diff --git a/dojox/mobile/app/_FormWidget.js b/dojox/mobile/app/_FormWidget.js
index 777112c..0dab50f 100644
--- a/dojox/mobile/app/_FormWidget.js
+++ b/dojox/mobile/app/_FormWidget.js
@@ -3,9 +3,9 @@ dojo.experimental("dojox.mobile.app._FormWidget");
 
 dojo.require("dojo.window");
 
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
 
-dojo.declare("dojox.mobile.app._FormWidget", dijit._Widget, {
+dojo.declare("dojox.mobile.app._FormWidget", dijit._WidgetBase, {
 	// summary:
 	//		Base class for widgets corresponding to native HTML elements such as <checkbox> or <button>,
 	//		which can be children of a <form> node or a `dojox.mobile.app.Form` widget.
@@ -13,7 +13,7 @@ dojo.declare("dojox.mobile.app._FormWidget", dijit._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`.
+	//		You can set them during widget construction or afterwards, via `dijit._WidgetBase.attr`.
 	//
 	//		They also share some common methods.
 
@@ -47,7 +47,7 @@ dojo.declare("dojox.mobile.app._FormWidget", dijit._Widget, {
 	scrollOnFocus: false,
 
 	// These mixins assume that the focus node is an INPUT, as many but not all _FormWidgets are.
-	attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
+	attributeMap: dojo.delegate(dijit._WidgetBase.prototype.attributeMap, {
 		value: "focusNode",
 		id: "focusNode",
 		alt: "focusNode",
@@ -74,13 +74,6 @@ dojo.declare("dojox.mobile.app._FormWidget", dijit._Widget, {
 		if(this.valueNode){
 			dojo.attr(this.valueNode, 'disabled', value);
 		}
-
-		if(value){
-			// reset these, because after the domNode is disabled, we can no longer receive
-			// mouse related events, see #4200
-			this._hovering = false;
-			this._active = false;
-		}
 	},
 
 	_onFocus: function(e){
diff --git a/dojox/mobile/app/_Widget.js b/dojox/mobile/app/_Widget.js
index c7ebf41..71fd2d5 100644
--- a/dojox/mobile/app/_Widget.js
+++ b/dojox/mobile/app/_Widget.js
@@ -1,9 +1,9 @@
 dojo.provide("dojox.mobile.app._Widget");
 dojo.experimental("dojox.mobile.app._Widget");
 
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
 
-dojo.declare("dojox.mobile.app._Widget", dijit._Widget, {
+dojo.declare("dojox.mobile.app._Widget", dijit._WidgetBase, {
 	// summary:
 	//		The base mobile app widget.
 
@@ -11,8 +11,8 @@ dojo.declare("dojox.mobile.app._Widget", dijit._Widget, {
 		// summary:
 		//		Returns the scroll position.
 		return {
-			x: window.scrollX,
-			y: window.scrollY
+			x: dojo.global.scrollX,
+			y: dojo.global.scrollY
 		};
 	},
 
@@ -20,7 +20,7 @@ dojo.declare("dojox.mobile.app._Widget", dijit._Widget, {
 		if(event.toLowerCase() == "dblclick"
 			|| event.toLowerCase() == "ondblclick"){
 
-			if(window["Mojo"]){
+			if(dojo.global["Mojo"]){
 				// Handle webOS tap event
 				return this.connect(target, Mojo.Event.tap, fn);
 			}
diff --git a/dojox/mobile/app/_base.js b/dojox/mobile/app/_base.js
index 6844b60..f8b82c9 100755
--- a/dojox/mobile/app/_base.js
+++ b/dojox/mobile/app/_base.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.mobile.app._base");
 dojo.experimental("dojox.mobile.app._base");
 
 dojo.require("dijit._base");
-dojo.require("dijit._Widget");
+dojo.require("dijit._WidgetBase");
 dojo.require("dojox.mobile");
 dojo.require("dojox.mobile.parser");
 
@@ -27,12 +27,12 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 		"dojox.mobile",
 		"dojox.mobile.parser"
 	];
-	
+
 	var loadedResources = {};
 	var loadingDependencies;
 
 	var rootNode;
-	
+
 	var sceneResources = [];
 
 	// Load the required resources asynchronously, since not all mobile OSes
@@ -43,10 +43,10 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 		//		the first scene is pushed onto the stack.
 		// resources:
 		//		An array of module names, e.g. 'dojox.mobile.AlertDialog'
-		
+
 		var resource;
 		var url;
-		
+
 		do {
 			resource = resources.pop();
 			if (resource.source) {
@@ -58,22 +58,19 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 				return;
 			}
 		}while (resources.length > 0 && loadedResources[url]);
-		
+
 		if(resources.length < 1 && loadedResources[url]){
-			console.log("All resources already loaded");
 			// All resources have already been loaded
 			callback();
 			return;
 		}
-		
-		console.log("loading url " + url);
-	
+
 		dojo.xhrGet({
 			url: url,
 			sync: false
 		}).addCallbacks(function(text){
 			dojo["eval"](text);
-	
+			loadedResources[url] = true;
 			if(resources.length > 0){
 				loadResources(resources, callback);
 			}else{
@@ -84,7 +81,7 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 			alert("Failed to load resource " + url);
 		});
 	}
-	
+
 	var pushFirstScene = function(){
 		// summary:
 		//		Pushes the first scene onto the stack.
@@ -98,8 +95,8 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 
 		// If the application info has been defined, as it should be,
 		// use it.
-		if(window["appInfo"]){
-			dojo.mixin(defaultInfo, window["appInfo"]);
+		if(dojo.global["appInfo"]){
+			dojo.mixin(defaultInfo, dojo.global["appInfo"]);
 		}
 		appInfo = dojox.mobile.app.info = defaultInfo;
 
@@ -111,38 +108,55 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 		}
 
 		stageController.pushScene(appInfo.initialScene);
-	}
+	};
+
+	var initBackButton = function(){
+		var hasNativeBack = false;
+		if(dojo.global.BackButton){
+			// Android phonegap support
+			BackButton.override();
+			dojo.connect(document, 'backKeyDown', function(e) {
+				dojo.publish("/dojox/mobile/app/goback");
+			});
+			hasNativeBack = true;
+		}else if(dojo.global.Mojo){
+			// TODO: add webOS support
+		}
+		if(hasNativeBack){
+			dojo.addClass(dojo.body(), "mblNativeBack");
+		}
+	};
 
 	dojo.mixin(dojox.mobile.app, {
 		init: function(node){
 			// summary:
 			//    Initializes the mobile app. Creates the
-	
+
 			rootNode = node || dojo.body();
-	
-//			loadingDependencies = dojo.clone(jsDependencies);
-//			loadResources(loadingDependencies, function(){dojox.mobile.app._pushFirstScene()});
-	
+			dojox.mobile.app.STAGE_CONTROLLER_ACTIVE = true;
+
 			dojo.subscribe("/dojox/mobile/app/goback", function(){
 				stageController.popScene();
 			});
-	
+
 			dojo.subscribe("/dojox/mobile/app/alert", function(params){
 				dojox.mobile.app.getActiveSceneController().showAlertDialog(params);
 			});
-			
+
+			dojo.subscribe("/dojox/mobile/app/pushScene", function(sceneName, params){
+				stageController.pushScene(sceneName, params || {});
+			});
+
 			// Get the list of files to load per scene/view
 			dojo.xhrGet({
 				url: "view-resources.json",
 				load: function(data){
 					var resources = [];
-					
+
 					if(data){
 						// Should be an array
 						sceneResources = data = dojo.fromJson(data);
-						
-						console.log("Got scene resources", sceneResources);
-						
+
 						// Get the list of files to load that have no scene
 						// specified, and therefore should be loaded on
 						// startup
@@ -153,38 +167,37 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 						}
 					}
 					if(resources.length > 0){
-						console.log("Loading initial resources");
 						loadResources(resources, pushFirstScene);
 					}else{
-						console.log("No initial resources");
 						pushFirstScene();
 					}
 				},
 				error: pushFirstScene
 			});
-//			pushFirstScene();
+
+			initBackButton();
 		},
-		
+
 		getActiveSceneController: function(){
 			// summary:
 			//		Gets the controller for the active scene.
 
 			return stageController.getActiveSceneController();
 		},
-	
+
 		getStageController: function(){
 			// summary:
 			//		Gets the stage controller.
 			return stageController;
 		},
-		
+
 		loadResources: function(resources, callback){
 			loadResources(resources, callback);
 		},
-		
+
 		loadResourcesForScene: function(sceneName, callback){
 			var resources = [];
-			
+
 			// Get the list of files to load that have no scene
 			// specified, and therefore should be loaded on
 			// startup
@@ -193,16 +206,14 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 					resources.push(sceneResources[i]);
 				}
 			}
-			
+
 			if(resources.length > 0){
-				console.log("Loading " + resources.length + " resources for" +
-								sceneName);
 				loadResources(resources, callback);
 			}else{
 				callback();
 			}
 		},
-	
+
 		resolveTemplate: function(sceneName){
 			// summary:
 			//		Given the name of a scene, returns the path to it's template
@@ -212,7 +223,7 @@ dojo.require("dojox.mobile.app.ImageThumbView");
 			//		a different name to file mapping.
 			return "app/views/" + sceneName + "/" + sceneName + "-scene.html";
 		},
-	
+
 		resolveAssistant: function(sceneName){
 			// summary:
 			//		Given the name of a scene, returns the path to it's assistant
diff --git a/dojox/mobile/app/_event.js b/dojox/mobile/app/_event.js
index 5eedb2c..c4f3074 100644
--- a/dojox/mobile/app/_event.js
+++ b/dojox/mobile/app/_event.js
@@ -89,8 +89,9 @@ dojox.mobile.app.isIPhone = (dojo.isSafari
 		navigator.userAgent.indexOf("iPod") > -1
 	));
 dojox.mobile.app.isWebOS = (navigator.userAgent.indexOf("webOS") > -1);
+dojox.mobile.app.isAndroid = (navigator.userAgent.toLowerCase().indexOf("android") > -1);
 
-if(dojox.mobile.app.isIPhone){
+if(dojox.mobile.app.isIPhone || dojox.mobile.app.isAndroid){
 	// We are touchable.
 	// Override the dojo._connect function to replace mouse events with touch events
 
@@ -108,7 +109,7 @@ dojo._oldConnect = dojo._connect;
 dojo._connect = function(obj, event, context, method, dontFix){
 	event = dojox.mobile.app.eventMap[event] || event;
 	if(event == "flick" || event == "onflick"){
-		if(window["Mojo"]){
+		if(dojo.global["Mojo"]){
 			event = Mojo.Event.flick;
 		}else{
 			return dojox.mobile.app.connectFlick(obj, context, method);
diff --git a/dojox/mobile/app/compat.js b/dojox/mobile/app/compat.js
index b7dbcc7..4cb5732 100644
--- a/dojox/mobile/app/compat.js
+++ b/dojox/mobile/app/compat.js
@@ -85,7 +85,7 @@ dojo.extend(dojox.mobile.app.List, {
 if(dojox.mobile.app.ImageView && !dojo.create("canvas").getContext){
 	dojo.extend(dojox.mobile.app.ImageView, {
 		buildRendering: function(){
-			this.domNode.innerHTML = 
+			this.domNode.innerHTML =
 				"ImageView widget is not supported on this browser."
 				+ "Please try again with a modern browser, e.g. "
 				+ "Safari, Chrome or Firefox";
diff --git a/dojox/mobile/build/build.bat b/dojox/mobile/build/build.bat
index 1e5d094..bb52fe2 100755
--- a/dojox/mobile/build/build.bat
+++ b/dojox/mobile/build/build.bat
@@ -31,16 +31,16 @@ goto end
 :ok
 
 set optimize=shrinksafe
-set profile=mobile.profile.js
+set profile=mobile
 set dir=release-mobile-separate
 set webkit=
-if "%1"=="single" set profile=mobile-all.profile.js
+if "%1"=="single" set profile=mobile-all
 if "%1"=="single" set dir=release-mobile-single
 if "%2"=="webkit" set webkit=webkitMobile=true
 
 cd ..\..\..\util\buildscripts
 
-call build profileFile=../../dojox/mobile/build/profiles/%profile% action=release customDijitBase=true optimize=%optimize% layerOptimize=%optimize% cssOptimize=comments releaseDir=../../%dir%/ %webkit%
+call build profile=%profile% action=release customDijitBase=true optimize=%optimize% layerOptimize=%optimize% cssOptimize=comments releaseDir=../../%dir%/ %webkit%
 
 cd ..\..\dojox\mobile\build
 
diff --git a/dojox/mobile/build/build.sh b/dojox/mobile/build/build.sh
index ab1f456..5f9d958 100755
--- a/dojox/mobile/build/build.sh
+++ b/dojox/mobile/build/build.sh
@@ -30,11 +30,11 @@ if [ $# -eq 0 ]; then
 fi
 
 optimize=shrinksafe
-profile=mobile.profile.js
+profile=mobile
 dir=release-mobile-separate
 webkit=
 if [ "$1" == "single" ]; then
-  profile=mobile-all.profile.js
+  profile=mobile-all
 fi
 if [ "$1" == "single" ]; then
   dir=release-mobile-single
@@ -45,6 +45,6 @@ fi
 
 cd ../../../util/buildscripts
 
-./build.sh profileFile=../../dojox/mobile/build/profiles/$profile action=release customDijitBase=true optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit
+./build.sh profile=$profile action=release customDijitBase=true optimize=$optimize layerOptimize=$optimize cssOptimize=comments releaseDir=../../$dir/ $webkit
 
 cd ../../dojox/mobile/build
diff --git a/dojox/mobile/build/profiles/mobile-all.profile.js b/dojox/mobile/build/profiles/mobile-all.profile.js
deleted file mode 100755
index 6a177de..0000000
--- a/dojox/mobile/build/profiles/mobile-all.profile.js
+++ /dev/null
@@ -1,36 +0,0 @@
-dependencies = {
-	stripConsole: "normal",
-
-	layers: [
-		{
-			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._Widget",
-				"dijit._base.manager",
-				"dijit._base.sniff",
-				"dojox.mobile.parser",
-				"dojox.mobile"
-			]
-		},
-		{
-			name: "../dojox/mobile/compat.js",
-			dependencies: [
-				"dojo._base.fx",
-				"dojox.mobile.compat"
-			]
-		}
-	],
-
-	prefixes: [
-		[ "dijit", "../dijit" ],
-		[ "dojox", "../dojox" ]
-	]
-}
diff --git a/dojox/mobile/build/profiles/mobile.profile.js b/dojox/mobile/build/profiles/mobile.profile.js
deleted file mode 100755
index a0c7437..0000000
--- a/dojox/mobile/build/profiles/mobile.profile.js
+++ /dev/null
@@ -1,40 +0,0 @@
-dependencies = {
-	stripConsole: "normal",
-	layers: [
-		{
-			name: "dojo.js",
-			dependencies: [
-				"dijit._Widget",
-			]
-		},
-		{
-			name: "../dojox/mobile.js",
-			dependencies: [
-				"dojox.mobile"
-			]
-		},
-		{
-			name: "../dojox/mobile/app.js",
-			dependencies: [
-				"dojox.mobile.app"
-			]
-		},
-		{
-			name: "../dojox/mobile/compat.js",
-			dependencies: [
-				"dojox.mobile.compat"
-			]
-		},
-		{
-			name: "../dojox/mobile/app/compat.js",
-			dependencies: [
-				"dojox.mobile.app.compat"
-			]
-		}
-	],
-
-	prefixes: [
-		[ "dijit", "../dijit" ],
-		[ "dojox", "../dojox" ]
-	]
-}
diff --git a/dojox/mobile/compat.js b/dojox/mobile/compat.js
index 40ba11c..f7ef5bf 100644
--- a/dojox/mobile/compat.js
+++ b/dojox/mobile/compat.js
@@ -1,4 +1,5 @@
 dojo.provide("dojox.mobile.compat");
+dojo.require("dijit._base.sniff");
 dojo.require("dojo._base.fx");
 dojo.require("dojo.fx");
 dojo.require("dojox.fx.flip");
@@ -18,12 +19,14 @@ dojo.require("dojox.fx.flip");
 //		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 //
 //		This module also loads compatibility CSS files, which has -compat.css
-//		suffix. You should use the <link> tag instead of @import to load theme
-//		CSS files. Then, this module searches for the <link> tags and loads
-//		compatibility CSS files. For example, if you load iphone.css with a
-//		link tag, this module automatically loads iphone-compat.css.
-//		Of course, you can explicitly load iphone.css and iphone-compat.css
-//		with the @import rule if you would like.
+//		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){
@@ -203,7 +206,7 @@ dojo.extend(dojox.mobile.Switch, {
 	}
 });
 
-if(dojo.isIE){
+if(dojo.isIE || dojo.isBB){
 
 dojo.extend(dojox.mobile.RoundRect, {
 	buildRendering: function(){
@@ -269,6 +272,8 @@ dojo.extend(dojox.mobile.EdgeToEdgeList, {
 	}
 });
 
+if(dojox.mobile.IconContainer){
+
 dojox.mobile.IconContainer._addChild = dojox.mobile.IconContainer.prototype.addChild;
 dojo.extend(dojox.mobile.IconContainer, {
 	addChild: function(widget){
@@ -279,6 +284,8 @@ dojo.extend(dojox.mobile.IconContainer, {
 	}
 });
 
+} // if(dojox.mobile.IconContainer)
+
 dojo.mixin(dojox.mobile, {
 	createRoundRect: function(_this, isList){
 		// summary:
@@ -314,6 +321,24 @@ dojo.mixin(dojox.mobile, {
 	}
 });
 
+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){
@@ -325,7 +350,17 @@ if(dojo.isIE <= 6){
 			var img = nodes[i];
 			var w = img.offsetWidth;
 			var h = img.offsetHeight;
-			if(w === 0 || h === 0){ return; }
+			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;
@@ -345,8 +380,8 @@ dojox.mobile.loadCss = function(/*String|Array*/files){
 	//		private
 	if(!dojo.global._loadedCss){
 		var obj = {};
-		dojo.forEach(dojo.doc.getElementsByTagName("link"), function(item){
-			obj[item.href] = true;
+		dojo.forEach(dojox.mobile.getCssPaths(), function(path){
+			obj[path] = true;
 		});
 		dojo.global._loadedCss = obj;
 	}
@@ -375,25 +410,60 @@ dojox.mobile.loadCss = function(/*String|Array*/files){
 	}
 };
 
+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 elems = dojo.doc.getElementsByTagName("link");
-	for(var i = 0, len = elems.length; i < len; i++){
-		var href = elems[i].href;
-		if((href.indexOf("/mobile/themes/") != -1 || location.href.indexOf("/mobile/tests/") != -1)
-			 && href.substring(href.length - 4) == ".css"){
+	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(){
-	dojox.mobile.loadCompatCssFiles();
+	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/parser.js b/dojox/mobile/parser.js
index cd697d7..a9da7bd 100644
--- a/dojox/mobile/parser.js
+++ b/dojox/mobile/parser.js
@@ -10,7 +10,7 @@ dojox.mobile.parser = new function(){
 		var ws = [];
 		if(list){
 			var i, len;
-			len = list.length
+			len = list.length;
 			for(i = 0; i < len; i++){
 				var node = list[i];
 				var cls = dojo.getObject(dojo.attr(node, "dojoType"));
@@ -37,11 +37,16 @@ dojox.mobile.parser = new function(){
 				}
 				params["class"] = node.className;
 				params["style"] = node.style && node.style.cssText;
-				ws.push(new cls(params, node));
+				var instance = new cls(params, node);
+				ws.push(instance);
+				var jsId = node.getAttribute("jsId");
+				if(jsId){
+					dojo.setObject(jsId, instance);
+				}
 			}
-			len = ws.length
+			len = ws.length;
 			for(i = 0; i < len; i++){
-				var w = ws[i]
+				var w = ws[i];
 				w.startup && !w._started && (!w.getParent || !w.getParent()) && w.startup();
 			}
 		}
@@ -71,7 +76,7 @@ dojox.mobile.parser = new function(){
 		}
 		return this.instantiate(list, defaultParams);
 	};
-};
+}();
 dojo._loaders.unshift(function(){
 	if(dojo.config.parseOnLoad){
 		dojox.mobile.parser.parse();
diff --git a/dojox/mobile/scrollable.js b/dojox/mobile/scrollable.js
new file mode 100644
index 0000000..36f7b45
--- /dev/null
+++ b/dojox/mobile/scrollable.js
@@ -0,0 +1,864 @@
+/*=====
+// summary:
+//		Utility for enabling touch scrolling capability.
+// description:
+//		Mobile WebKit browsers do not allow scrolling inner DIVs. (You need
+//		the two-finger operation to scroll them.)
+//		That means you cannot have fixed-positioned header/footer bars.
+//		To solve this issue, this module disables the browsers default scrolling
+//		behavior, and re-builds its own scrolling machinery by handling touch
+//		events. In this module, this.domNode has height "100%" and is fixed to
+//		the window, and this.containerNode scrolls. If you place a bar outside
+//		of this.containerNode, then it will be fixed-positioned while
+//		this.containerNode is scrollable.
+//
+//		This module has the following features:
+//		- Scrolls inner DIVs vertically, horizontally, or both.
+//		- Vertical and horizontal scroll bars.
+//		- Flashes the scroll bars when a view is shown.
+//		- Simulates the flick operation using animation.
+//		- Respects header/footer bars if any.
+//
+//		dojox.mobile.scrollable is a simple function object, which holds
+//		several properties and functions in it. But if you transform it to a
+//		dojo class, it can be used as a mix-in class for any custom dojo
+//		widgets. dojox.mobile._ScrollableMixin is such a class.
+//
+//		Also, it can be used even for non-dojo applications. In such cases,
+//		several dojo APIs used in this module, such as dojo.connect,
+//		dojo.create, etc., are re-defined so that the code works without dojo.
+//		When in dojo, of course those re-defined functions are not necessary.
+//		So, they are surrounded by the excludeStart and excludeEnd directives
+//		so that they will 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.
+//
+// example:
+//		Use this module from a non-dojo applicatoin:
+//		| function onLoad(){
+//		| 	var scrollable = new dojox.mobile.scrollable();
+//		| 	scrollable.init({
+//		| 		domNode: "outer", // id or node
+//		| 		containerNode: "inner", // id or node
+//		| 		fixedHeaderHeight: document.getElementById("hd1").offsetHeight
+//		| 	});
+//		| }
+//		| <body onload="onLoad()">
+//		| 	<h1 id="hd1" style="position:absolute;width:100%;z-index:1;">
+//		| 		Fixed Header
+//		| 	</h1>
+//		| 	<div id="outer" style="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(){
+	this.fixedHeaderHeight = 0; // height of a fixed header
+	this.fixedFooterHeight = 0; // height of a fixed footer
+	this.isLocalFooter = false; // footer is view-local (as opposed to application-wide)
+	this.scrollBar = true; // show scroll bar or not
+	this.scrollDir = "v"; // v: vertical, h: horizontal, vh: both, f: flip
+	this.weight = 0.6; // frictional drag
+	this.fadeScrollBar = true;
+	this.disableFlashScrollBar = false;
+	this.threshold = 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, "");
+		};
+	}
+//>>excludeEnd("dojo");
+
+	this.init = function(/*Object?*/params){
+		if (params){
+			for(var p in params){
+				if (params.hasOwnProperty(p)) {
+					this[p] = ((p == "domNode" || p == "containerNode") && typeof params[p] == "string") ?
+						dojo.doc.getElementById(params[p]) : params[p]; // mix-in params
+				}
+			}
+		}
+		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"));
+		}
+
+		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.resizeView();
+		var _this = this;
+		setTimeout(function(){
+			_this.flashScrollBar();
+		}, 600);
+	};
+
+	this.cleanup = function(){
+		for(var i = 0; i < this._ch.length; i++){
+			dojo.disconnect(this._ch[i]);
+		}
+		this._ch = null;
+	};
+
+	this.resizeView = function(e){
+		// 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";
+
+		// 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);
+	};
+
+	this.onFlickAnimationStart = function(e){
+		dojo.stopEvent(e);
+	};
+
+	this.onFlickAnimationEnd = function(e){
+		if(e && e.srcElement){
+			dojo.stopEvent(e);
+		}
+		this.stopAnimation();
+		if(this._bounce){
+			var _this = this;
+			var bounce = _this._bounce;
+			setTimeout(function(){
+				_this.slideTo(bounce, 0.3, "ease-out");
+			}, 0);
+			_this._bounce = undefined;
+		}else{
+			this.hideScrollBar();
+			this.removeCover();
+		}
+	};
+
+	this.onTouchStart = function(e){
+		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._aborted = false;
+		if(dojo.hasClass(this.containerNode, "mblScrollableScrollTo2")){
+			this.abort();
+		}
+		this.touchStartX = e.touches ? e.touches[0].pageX : e.clientX;
+		this.touchStartY = e.touches ? e.touches[0].pageY : e.clientY;
+		this.startTime = (new Date()).getTime();
+		this.startPos = this.getPos();
+		this._dim = this.getDim();
+		this._time = [0];
+		this._posX = [this.touchStartX];
+		this._posY = [this.touchStartY];
+
+		if(e.target.nodeType != 1 || (e.target.tagName != "SELECT" && e.target.tagName != "INPUT" && e.target.tagName != "TEXTAREA")){
+			dojo.stopEvent(e);
+		}
+	};
+
+	this.onTouchMove = function(e){
+		var x = e.touches ? e.touches[0].pageX : e.clientX;
+		var y = e.touches ? e.touches[0].pageY : e.clientY;
+		var dx = x - this.touchStartX;
+		var dy = y - this.touchStartY;
+		var to = {x:this.startPos.x + dx, y:this.startPos.y + dy};
+		var dim = this._dim;
+
+		if(this._time.length == 1){ // the first TouchMove after TouchStart
+			if(dx < this.threshold && dy < this.threshold){ return; }
+			this.addCover();
+			this.showScrollBar();
+		}
+
+		var weight = this.weight;
+		if(this._v){
+			if(to.y > 0){ // content is below the screen area
+				to.y = Math.round(to.y * weight);
+			}else if(to.y < -dim.o.h){ // content is above the screen area
+				if(dim.c.h < dim.d.h){ // content is shorter than display
+					to.y = Math.round(to.y * weight);
+				}else{
+					to.y = -dim.o.h - Math.round((-dim.o.h - to.y) * weight);
+				}
+			}
+		}
+		if(this._h || this._f){
+			if(to.x > 0){
+				to.x = Math.round(to.x * weight);
+			}else if(to.x < -dim.o.w){
+				if(dim.c.w < dim.d.w){
+					to.x = Math.round(to.x * weight);
+				}else{
+					to.x = -dim.o.w - Math.round((-dim.o.w - to.x) * weight);
+				}
+			}
+		}
+		this.scrollTo(to);
+
+		var max = 10;
+		var n = this._time.length; // # of samples
+		if(n >= 2){
+			// Check the direction of the finger move.
+			// If the direction has been changed, discard the old data.
+			var d0, d1;
+			if(this._v && !this._h){
+				d0 = this._posY[n - 1] - this._posY[n - 2];
+				d1 = y - this._posY[n - 1];
+			}else if(!this._v && this._h){
+				d0 = this._posX[n - 1] - this._posX[n - 2];
+				d1 = x - this._posX[n - 1];
+			}
+			if(d0 * d1 < 0){ // direction changed
+				// leave only the latest data
+				this._time = [this._time[n - 1]];
+				this._posX = [this._posX[n - 1]];
+				this._posY = [this._posY[n - 1]];
+				n = 1;
+			}
+		}
+		if(n == max){
+			this._time.shift();
+			this._posX.shift();
+			this._posY.shift();
+		}
+		this._time.push((new Date()).getTime() - this.startTime);
+		this._posX.push(x);
+		this._posY.push(y);
+	};
+
+	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(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;
+				}
+				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 pos = this.getPos();
+		var to = {}; // destination
+		var dim = this._dim;
+
+		if(this._v){
+			to.y = pos.y + speed.y;
+		}
+		if(this._h || this._f){
+			to.x = pos.x + speed.x;
+		}
+
+		if(this.scrollDir == "v" && dim.c.h <= dim.d.h){ // content is shorter than display
+			this.slideTo({y:0}, 0.3, "ease-out"); // go back to the top
+			return;
+		}else if(this.scrollDir == "h" && dim.c.w <= dim.d.w){ // content is narrower than display
+			this.slideTo({x:0}, 0.3, "ease-out"); // go back to the left
+			return;
+		}else if(this._v && this._h && dim.c.h <= dim.d.h && dim.c.w <= dim.d.w){
+			this.slideTo({x:0, y:0}, 0.3, "ease-out"); // go back to the top-left
+			return;
+		}
+
+		var duration, easing = "ease-out";
+		var bounce = {};
+		if(this._v){
+			if(to.y > 0){ // going down. bounce back to the top.
+				if(pos.y > 0){ // started from below the screen area. return quickly.
+					duration = 0.3;
+					to.y = 0;
+				}else{
+					to.y = Math.min(to.y, 20);
+					easing = "linear";
+					bounce.y = 0;
+				}
+			}else if(-speed.y > dim.o.h - (-pos.y)){ // going up. bounce back to the bottom.
+				if(pos.y < -dim.o.h){ // started from above the screen top. return quickly.
+					duration = 0.3;
+					to.y = dim.c.h <= dim.d.h ? 0 : -dim.o.h; // if shorter, move to 0
+				}else{
+					to.y = Math.max(to.y, -dim.o.h - 20);
+					easing = "linear";
+					bounce.y = -dim.o.h;
+				}
+			}
+		}
+		if(this._h || this._f){
+			if(to.x > 0){ // going right. bounce back to the left.
+				if(pos.x > 0){ // started from right of the screen area. return quickly.
+					duration = 0.3;
+					to.x = 0;
+				}else{
+					to.x = Math.min(to.x, 20);
+					easing = "linear";
+					bounce.x = 0;
+				}
+			}else if(-speed.x > dim.o.w - (-pos.x)){ // going left. bounce back to the right.
+				if(pos.x < -dim.o.w){ // started from left of the screen top. return quickly.
+					duration = 0.3;
+					to.x = dim.c.w <= dim.d.w ? 0 : -dim.o.w; // if narrower, move to 0
+				}else{
+					to.x = Math.max(to.x, -dim.o.w - 20);
+					easing = "linear";
+					bounce.x = -dim.o.w;
+				}
+			}
+		}
+		this._bounce = (bounce.x !== undefined || bounce.y !== undefined) ? bounce : undefined;
+
+		if(duration === undefined){
+			var distance, velocity;
+			if(this._v && this._h){
+				velocity = Math.sqrt(speed.x+speed.x + speed.y*speed.y);
+				distance = Math.sqrt(Math.pow(to.y - pos.y, 2) + Math.pow(to.x - pos.x, 2));
+			}else if(this._v){
+				velocity = speed.y;
+				distance = to.y - pos.y;
+			}else if(this._h){
+				velocity = speed.x;
+				distance = to.x - pos.x;
+			}
+			duration = velocity !== 0 ? Math.abs(distance / velocity) : 0.01; // time = distance / velocity
+		}
+		this.slideTo(to, duration, easing);
+	};
+
+	this.abort = function(){
+		this.scrollTo(this.getPos());
+		this.stopAnimation();
+		this._aborted = true;
+	};
+
+	this.stopAnimation = function(){
+		// stop the currently running animation
+		dojo.removeClass(this.containerNode, "mblScrollableScrollTo2");
+		if(this._scrollBarV){
+			this._scrollBarV.className = "";
+		}
+		if(this._scrollBarH){
+			this._scrollBarH.className = "";
+		}
+	};
+
+	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){
+			s.webkitTransform = this.makeTranslateStr(to);
+		}else{
+			if(this._v){
+				s.top = to.y + "px";
+			}
+			if(this._h || this._f){
+				s.left = to.x + "px";
+			}
+		}
+		if(!doNotMoveScrollBar){
+			this.scrollScrollBarTo(this.calcScrollBarPos(to));
+		}
+	};
+
+	this.slideTo = function(/*Object*/to, /*Number*/duration, /*String*/easing){
+		this._runSlideAnimation(this.getPos(), to, duration, easing, this.containerNode, 2);
+		this.slideScrollBarTo(to, duration, easing);
+	};
+
+	this.makeTranslateStr = function(to){
+		var y = this._v && typeof to.y == "number" ? to.y+"px" : "0px";
+		var x = (this._h||this._f) && typeof to.x == "number" ? to.x+"px" : "0px";
+		return dojox.mobile.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(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.getDim = function(){
+		var d = {};
+		// content width/height
+		d.c = {h:this.containerNode.offsetHeight - this.fixedHeaderHeight, w:this.containerNode.offsetWidth};
+
+		// view width/height
+		d.v = {h:this.domNode.offsetHeight + this._appFooterHeight, w:this.domNode.offsetWidth};
+
+		// display width/height
+		d.d = {h:d.v.h - this.fixedHeaderHeight - this.fixedFooterHeight, w:d.v.w};
+
+		// overflowed width/height
+		d.o = {h:d.c.h - d.v.h + this.fixedHeaderHeight + this.fixedFooterHeight, w:d.c.w - d.v.w};
+		return d;
+	};
+
+	this.showScrollBar = function(){
+		if(!this.scrollBar){ return; }
+
+		var dim = this._dim;
+		if(this.scrollDir == "v" && dim.c.h <= dim.d.h){ return; }
+		if(this.scrollDir == "h" && dim.c.w <= dim.d.w){ return; }
+		if(this._v && this._h && dim.c.h <= dim.d.h && dim.c.w <= dim.d.w){ return; }
+
+		var createBar = function(self, dir){
+			var bar = self["_scrollBarNode" + dir];
+			if(!bar){
+				var wrapper = dojo.create("div", null, self.domNode);
+				var props = { position: "absolute", overflow: "hidden" };
+				if(dir == "V"){
+					props.right = "2px";
+					props.width = "5px";
+				}else{
+					props.bottom = (self.isLocalFooter ? self.fixedFooterHeight : 0) + 2 + "px";
+					props.height = "5px";
+				}
+				dojo.style(wrapper, props);
+				wrapper.className = "mblScrollBarWrapper";
+				self["_scrollBarWrapper"+dir] = wrapper;
+
+				bar = dojo.create("div", null, wrapper);
+				dojo.style(bar, {
+					opacity: 0.6,
+					position: "absolute",
+					backgroundColor: "#606060",
+					fontSize: "1px",
+					webkitBorderRadius: "2px",
+					MozBorderRadius: "2px",
+					webkitTransformOrigin: "0 0",
+					zIndex: 2147483647 // max of signed 32-bit integer
+				});
+				dojo.style(bar, dir == "V" ? {width: "5px"} : {height: "5px"});
+				self["_scrollBarNode" + dir] = bar;
+			}
+			return bar;
+		};
+		if(this._v && !this._scrollBarV){
+			this._scrollBarV = createBar(this, "V");
+		}
+		if(this._h && !this._scrollBarH){
+			this._scrollBarH = createBar(this, "H");
+		}
+		this.resetScrollBar();
+	};
+
+	this.hideScrollBar = function(){
+		var fadeRule;
+		if(this.fadeScrollBar && dojo.isWebKit){
+			if(!dojox.mobile._fadeRule){
+				var node = dojo.create("style", null, dojo.doc.getElementsByTagName("head")[0]);
+				node.textContent =
+					".mblScrollableFadeOutScrollBar{"+
+					"  -webkit-animation-duration: 1s;"+
+					"  -webkit-animation-name: scrollableViewFadeOutScrollBar;}"+
+					"@-webkit-keyframes scrollableViewFadeOutScrollBar{"+
+					"  from { opacity: 0.6; }"+
+					"  50% { opacity: 0.6; }"+
+					"  to { opacity: 0; }}";
+				dojox.mobile._fadeRule = node.sheet.cssRules[1];
+			}
+			fadeRule = dojox.mobile._fadeRule;
+		}
+		if(!this.scrollBar){ return; }
+		var f = function(bar){
+			dojo.style(bar, {
+				opacity: 0,
+				webkitAnimationDuration: ""
+			});
+			bar.className = "mblScrollableFadeOutScrollBar";
+		};
+		if(this._scrollBarV){
+			f(this._scrollBarV);
+			this._scrollBarV = null;
+		}
+		if(this._scrollBarH){
+			f(this._scrollBarH);
+			this._scrollBarH = null;
+		}
+	};
+
+	this.calcScrollBarPos = function(/*Object*/to){ // to: {x, y}
+		var pos = {};
+		var dim = this._dim;
+		var f = function(wrapperH, barH, t, d, c){
+			var y = Math.round((d - barH - 8) / (d - c) * t);
+			if(y < -barH + 5){
+				y = -barH + 5;
+			}
+			if(y > wrapperH - 5){
+				y = wrapperH - 5;
+			}
+			return y;
+		};
+		if(typeof to.y == "number" && this._scrollBarV){
+			pos.y = f(this._scrollBarWrapperV.offsetHeight, this._scrollBarV.offsetHeight, to.y, dim.d.h, dim.c.h);
+		}
+		if(typeof to.x == "number" && this._scrollBarH){
+			pos.x = f(this._scrollBarWrapperH.offsetWidth, this._scrollBarH.offsetWidth, to.x, dim.d.w, dim.c.w);
+		}
+		return pos;
+	};
+
+	this.scrollScrollBarTo = function(/*Object*/to){ // to: {x, y}
+		if(!this.scrollBar){ return; }
+		if(this._v && this._scrollBarV && typeof to.y == "number"){
+			if(dojo.isWebKit){
+				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){
+				this._scrollBarH.style.webkitTransform = this.makeTranslateStr({x:to.x});
+			}else{
+				this._scrollBarH.style.left = to.x + "px";
+			}
+		}
+	};
+
+	this.slideScrollBarTo = function(/*Object*/to, /*Number*/duration, /*String*/easing){
+		if(!this.scrollBar){ return; }
+		var fromPos = this.calcScrollBarPos(this.getPos());
+		var toPos = this.calcScrollBarPos(to);
+		if(this._v && this._scrollBarV){
+			this._runSlideAnimation({y:fromPos.y}, {y:toPos.y}, duration, easing, this._scrollBarV, 0);
+		}
+		if(this._h && this._scrollBarH){
+			this._runSlideAnimation({x:fromPos.x}, {x:toPos.x}, duration, easing, this._scrollBarH, 1);
+		}
+	};
+
+	this._runSlideAnimation = function(/*Object*/from, /*Object*/to, /*Number*/duration, /*String*/easing, node, idx){
+		// idx: 0:scrollbarV, 1:scrollbarH, 2:content
+		if(dojo.isWebKit){
+			this.setKeyframes(from, to, idx);
+			dojo.style(node, {
+				webkitAnimationDuration: duration + "s",
+				webkitAnimationTimingFunction: easing
+			});
+			dojo.addClass(node, "mblScrollableScrollTo"+idx);
+			if(idx == 2){
+				this.scrollTo(to, true);
+			}else{
+				this.scrollScrollBarTo(to);
+			}
+//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
+		}else if(dojo.fx && dojo.fx.easing){
+			// If you want to support non-webkit browsers,
+			// your application needs to load necessary modules as follows:
+			//
+			// | dojo.require("dojo.fx");
+			// | dojo.require("dojo.fx.easing");
+			//
+			// This module itself does not make dependency on them.
+			var s = dojo.fx.slideTo({
+				node: node,
+				duration: duration*1000,
+				left: to.x,
+				top: to.y,
+				easing: (easing == "ease-out") ? dojo.fx.easing.quadOut : dojo.fx.easing.linear
+			}).play();
+			if(idx == 2){
+				dojo.connect(s, "onEnd", this, "onFlickAnimationEnd");
+			}
+		}else{
+			// directly jump to the destination without animation
+			if(idx == 2){
+				this.scrollTo(to);
+				this.onFlickAnimationEnd();
+			}else{
+				this.scrollScrollBarTo(to);
+			}
+//>>excludeEnd("webkitMobile");
+		}
+	};
+
+	this.resetScrollBar = function(){
+		//	summary:
+		//		Resets the scroll bar length, position, etc.
+		var f = function(wrapper, bar, d, c, hd, v){
+			if(!bar){ return; }
+			var props = {};
+			props[v ? "top" : "left"] = hd + 4 + "px"; // +4 is for top or left margin
+			props[v ? "height" : "width"] = d - 8 + "px";
+			dojo.style(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
+			bar.style[v ? "height" : "width"] = l + "px";
+			dojo.style(bar, {"opacity": 0.6});
+		};
+		var dim = this.getDim();
+		f(this._scrollBarWrapperV, this._scrollBarV, dim.d.h, dim.c.h, this.fixedHeaderHeight, true);
+		f(this._scrollBarWrapperH, this._scrollBarH, dim.d.w, dim.c.w, 0);
+		this.createMask();
+	};
+
+	this.createMask = function(){
+		//	summary:
+		//		Creates a mask for a scroll bar edge.
+		// description:
+		//		This function creates a mask that hides corners of one scroll
+		//		bar edge to make it round edge. The other side of the edge is
+		//		always visible and round shaped with the border-radius style.
+		if(!dojo.isWebKit){ return; }
+		var ctx;
+		if(this._scrollBarWrapperV){
+			var h = this._scrollBarWrapperV.offsetHeight;
+			ctx = dojo.doc.getCSSCanvasContext("2d", "scrollBarMaskV", 5, h);
+			ctx.fillStyle = "rgba(0,0,0,0.5)";
+			ctx.fillRect(1, 0, 3, 2);
+			ctx.fillRect(0, 1, 5, 1);
+			ctx.fillRect(0, h - 2, 5, 1);
+			ctx.fillRect(1, h - 1, 3, 2);
+			ctx.fillStyle = "rgb(0,0,0)";
+			ctx.fillRect(0, 2, 5, h - 4);
+			this._scrollBarWrapperV.style.webkitMaskImage = "-webkit-canvas(scrollBarMaskV)";
+		}
+		if(this._scrollBarWrapperH){
+			var w = this._scrollBarWrapperH.offsetWidth;
+			ctx = dojo.doc.getCSSCanvasContext("2d", "scrollBarMaskH", w, 5);
+			ctx.fillStyle = "rgba(0,0,0,0.5)";
+			ctx.fillRect(0, 1, 2, 3);
+			ctx.fillRect(1, 0, 1, 5);
+			ctx.fillRect(w - 2, 0, 1, 5);
+			ctx.fillRect(w - 1, 1, 2, 3);
+			ctx.fillStyle = "rgb(0,0,0)";
+			ctx.fillRect(2, 0, w - 4, 5);
+			this._scrollBarWrapperH.style.webkitMaskImage = "-webkit-canvas(scrollBarMaskH)";
+		}
+	};
+
+	this.flashScrollBar = function(){
+		if(this.disableFlashScrollBar){ return; }
+		this._dim = this.getDim();
+		if(this._dim.d.h <= 0){ return; } // dom is not ready
+		this.showScrollBar();
+		var _this = this;
+		setTimeout(function(){
+			_this.hideScrollBar();
+		}, 300);
+	};
+
+	this.addCover = function(){
+//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
+		if(!dojox.mobile.hasTouch && !this.noCover){
+			if(!this._cover){
+				this._cover = dojo.create("div", null, dojo.doc.body);
+				dojo.style(this._cover, {
+					backgroundColor: "#ffff00",
+					opacity: 0,
+					position: "absolute",
+					top: "0px",
+					left: "0px",
+					width: "100%",
+					height: "100%",
+					zIndex: 2147483647 // max of signed 32-bit integer
+				});
+				this._ch.push(dojo.connect(this._cover,
+					dojox.mobile.hasTouch ? "touchstart" : "onmousedown", this, "onTouchEnd"));
+			}else{
+				this._cover.style.display = "";
+			}
+		}
+//>>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){
+			this._cover.style.display = "none";
+		}
+//>>excludeEnd("webkitMobile");
+		this.setSelectable(this.domNode, true);
+	};
+
+	this.setKeyframes = function(/*Object*/from, /*Object*/to, /*Number*/idx){
+		if(!dojox.mobile._rule){
+			dojox.mobile._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 =
+				".mblScrollableScrollTo"+idx+"{-webkit-animation-name: scrollableViewScroll"+idx+";}"+
+				"@-webkit-keyframes scrollableViewScroll"+idx+"{}";
+			dojox.mobile._rule[idx] = node.sheet.cssRules[1];
+		}
+		var rule = dojox.mobile._rule[idx];
+		if(rule){
+			if(from){
+				rule.deleteRule("from");
+				rule.insertRule("from { -webkit-transform: "+this.makeTranslateStr(from)+"; }");
+			}
+			if(to){
+				if(to.x === undefined){ to.x = from.x; }
+				if(to.y === undefined){ to.y = from.y; }
+				rule.deleteRule("to");
+				rule.insertRule("to { -webkit-transform: "+this.makeTranslateStr(to)+"; }");
+			}
+		}
+	};
+
+	this.setSelectable = function(node, selectable){
+		// dojo.setSelectable has dependency on dojo.query. Re-define our own.
+		node.style.KhtmlUserSelect = selectable ? "auto" : "none";
+		node.style.MozUserSelect = selectable ? "" : "none";
+		node.onselectstart = selectable ? null : function(){return false;};
+		node.unselectable = selectable ? "" : "on";
+	};
+
+};
+
+(function(){
+	// feature detection
+	if(dojo.isWebKit){
+		var elem = dojo.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);
+	}
+})();
diff --git a/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js b/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
index eb906b5..fc73483 100644
--- a/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/complexListApp/app/assistants/main-assistant.js
@@ -2,122 +2,127 @@ dojo.provide("MainAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
-  
-  setup: function(){
-    console.log("In main assistant setup");
-    
-    this.controller.parse();
-    console.log("In main assistant setup 2");
-    
-    var data1 = [
-      {
-        label: "Row 1",
-        button1Cls: "listButton1",
-        button2Cls: "listButton2",
-        buttonLabel1: "Add"
-      },
-      {
-        label: "Row 2",
-        button1Cls: "listButton2",
-        button2Cls: "listButton1"
-      }
-    ];
-    var data2 = [
-      {
-        label: "Row 3",
-        button1Cls: "listButton1",
-        button2Cls: "listButtonHidden"
-      },
-      {
-        label: "Row 4",
-        button1Cls: "listButton2",
-        button2Cls: "listButton3"
-      },
-      {
-        label: "Row 5",
-        button1Cls: "listButton3",
-        button2Cls: "listButton2",
-        buttonLabel2: "Del"
-      },
-      {
-        label: "Row 6",
-        button1Cls: "listButtonHidden",
-        button2Cls: "listButton2"
-      }
-    ];
-    var data3 = [];
-    
-    dijit.byId("listWidget").set("items", data1);
-    
-    var buttonOutput = this.controller.query("#buttonOutput")[0];
-    
-    this.connect(dijit.byId("btn1"), "onClick", function(){
-      dijit.byId("listWidget").set("items", data1);
-    });
-    this.connect(dijit.byId("btn2"), "onClick", function(){
-      dijit.byId("listWidget").set("items", data2);
-    });
-    this.connect(dijit.byId("btn3"), "onClick", function(){
-      dijit.byId("listWidget").set("items", data3);
-    });
-    
-    var _this = this;
-    
-    this.connect(dijit.byId("listWidget").domNode, "onclick", function(event){
-      // If the user clicked one of the buttons in a row,
-      // then show a popup menu for further actions.
-      if(!event.item){
-        return;
-      }
-      
-      if(dojo.hasClass(event.target, "listBtn")){
-        buttonOutput.innerHTML = "You clicked Item " + event.index
-                + " with the label '" + event.item.label + "'"
-                + " using a button with the CSS class '"
-                + event.target.className.split(" ")[2]
-                + "'";
-                
-        _this.showMenu(event.target);
-      } else {
-        buttonOutput.innerHTML = "You clicked Item " + event.index
-                + " with the label '" + event.item.label + "'"
-      }
-    });
-//    
+
+	setup: function(){
+		console.log("In main assistant setup");
+
+		this.controller.parse();
+		console.log("In main assistant setup 2");
+
+		var data1 = [
+			{
+				label: "Row 1",
+				button1Cls: "listButton1",
+				button2Cls: "listButton2",
+				buttonLabel1: "Add"
+			},
+			{
+				label: "Row 2",
+				button1Cls: "listButton2",
+				button2Cls: "listButton1"
+			}
+		];
+		var data2 = [
+			{
+				label: "Row 3",
+				button1Cls: "listButton1",
+				button2Cls: "listButtonHidden"
+			},
+			{
+				label: "Row 4",
+				button1Cls: "listButton2",
+				button2Cls: "listButton3"
+			},
+			{
+				label: "Row 5",
+				button1Cls: "listButton3",
+				button2Cls: "listButton2",
+				buttonLabel2: "Del"
+			},
+			{
+				label: "Row 6",
+				button1Cls: "listButtonHidden",
+				button2Cls: "listButton2"
+			}
+		];
+		var data3 = [];
+
+		var listWidget = dijit.byId("listWidget");
+
+		listWidget.dividerFunction = function(item){
+			return item.label < "Row 5" ? "First Section" : "Second Section";
+		};
+		listWidget.set("items", data1);
+
+		var buttonOutput = this.controller.query("#buttonOutput")[0];
+
+		this.connect(dijit.byId("btn1"), "onClick", function(){
+			dijit.byId("listWidget").set("items", data1);
+		});
+		this.connect(dijit.byId("btn2"), "onClick", function(){
+			dijit.byId("listWidget").set("items", data2);
+		});
+		this.connect(dijit.byId("btn3"), "onClick", function(){
+			dijit.byId("listWidget").set("items", data3);
+		});
+
+		var _this = this;
+
+		this.connect(dijit.byId("listWidget").domNode, "onclick", function(event){
+			// If the user clicked one of the buttons in a row,
+			// then show a popup menu for further actions.
+			if(!event.item){
+				return;
+			}
+
+			if(dojo.hasClass(event.target, "listBtn")){
+				buttonOutput.innerHTML = "You clicked Item " + event.index
+								+ " with the label '" + event.item.label + "'"
+								+ " using a button with the CSS class '"
+								+ event.target.className.split(" ")[2]
+								+ "'";
+
+				_this.showMenu(event.target);
+			} else {
+				buttonOutput.innerHTML = "You clicked Item " + event.index
+								+ " with the label '" + event.item.label + "'"
+			}
+		});
+//
 //    this.connect(dijit.byId("listWidget").domNode, "onmousedown", function(event){
 //      _this.controller.showAlertDialog({
 //        title: "MDown",
 //        text: "type: " + dojox.mobile.app.isIPhone//event.target.className
 //      })
 //    });
-    
-  },
-  
-  showMenu: function(fromNode){
-    
-    var buttonOutput = this.controller.query("#buttonOutput")[0];
-    
-    this.controller.popupSubMenu({
-      choices: [
-        {label: "Option 1", value: 1},
-        {label: "Option 2", value: 2},
-        {label: "Option 3 - A Bit Longer", value: 3},
-        {label: "Option 4", value: 4}
-      ],
-      
-      fromNode: fromNode,
-      
-      onChoose: function(value){
-        buttonOutput.innerHTML = "You chose the menu item with value " + value;
-      }
-      
-    })
-  },
-  
-  activate: function(){
-    console.log("In main assistant activate");
-    
-    
-  }
-  
+
+	},
+
+	showMenu: function(fromNode){
+
+		var buttonOutput = this.controller.query("#buttonOutput")[0];
+
+		this.controller.popupSubMenu({
+			choices: [
+				{label: "Option 1", value: 1},
+				{label: "Option 2", value: 2},
+				{label: "Option 3 - A Bit Longer", value: 3},
+				{label: "Option 4", value: 4}
+			],
+
+			fromNode: fromNode,
+
+			onChoose: function(value){
+				buttonOutput.innerHTML = "You chose the menu item with value " + value;
+			}
+
+		})
+	},
+
+	activate: function(){
+		console.log("In main assistant activate");
+
+
+	}
+
 });
\ No newline at end of file
diff --git a/dojox/mobile/tests/complexListApp/app/views/main/dividerTemplate.html b/dojox/mobile/tests/complexListApp/app/views/main/dividerTemplate.html
new file mode 100644
index 0000000..b9ff42a
--- /dev/null
+++ b/dojox/mobile/tests/complexListApp/app/views/main/dividerTemplate.html
@@ -0,0 +1,3 @@
+<div class="divider">
+	${label}
+</div>
diff --git a/dojox/mobile/tests/complexListApp/app/views/main/main-scene.html b/dojox/mobile/tests/complexListApp/app/views/main/main-scene.html
index 320ad25..e2a0f4d 100644
--- a/dojox/mobile/tests/complexListApp/app/views/main/main-scene.html
+++ b/dojox/mobile/tests/complexListApp/app/views/main/main-scene.html
@@ -1,23 +1,24 @@
 <div>
-  This scene shows how to render a list containing buttons. 
-  Swipe to delete rows.
+	This scene shows how to render a list containing buttons.
+	Swipe to delete rows.
 </div>
 
-<div dojoType="dojox.mobile.RoundRect" 
-    shadow="true" id="buttonOutput" style="min-height: 70px;">
-  Click a button in the list to see the output here
+<div dojoType="dojox.mobile.RoundRect"
+		shadow="true" id="buttonOutput" style="min-height: 70px;">
+	Click a button in the list to see the output here
 </div>
 
 <button id="btn1" dojoType="dojox.mobile.Button">Data 1</button>
 <button id="btn2" dojoType="dojox.mobile.Button">Data 2</button>
-<button id="btn3" 
-        dojoType="dojox.mobile.Button" 
-        btnClass="mblRedButton">Empty Data</button>
+<button id="btn3"
+				dojoType="dojox.mobile.Button"
+				btnClass="mblRedButton">Empty Data</button>
 
 <div dojoType="dojox.mobile.RoundRect" shadow="true">
-  <div id="listWidget" dojoType="dojox.mobile.app.List" 
-      class="iconList"
-      autoDelete="false"
-      itemTemplate="app/views/main/rowTemplate.html"
-      emptyTemplate="app/views/main/emptyTemplate.html"></div>
+	<div id="listWidget" dojoType="dojox.mobile.app.List"
+			class="iconList"
+			autoDelete="false"
+			itemTemplate="app/views/main/rowTemplate.html"
+			dividerTemplate="app/views/main/dividerTemplate.html"
+			emptyTemplate="app/views/main/emptyTemplate.html"></div>
 </div>
\ No newline at end of file
diff --git a/dojox/mobile/tests/complexListApp/styles/style.css b/dojox/mobile/tests/complexListApp/styles/style.css
index 0989af2..3bf9a02 100644
--- a/dojox/mobile/tests/complexListApp/styles/style.css
+++ b/dojox/mobile/tests/complexListApp/styles/style.css
@@ -1,38 +1,42 @@
 .row .listBtn {
-  float: right;
-  min-width: 32px;
-  min-height: 32px;
-  -webkit-border-radius: 4px;
-	-moz-border-radius: 4px; 
-  margin-right: 8px;
-  color: #333;
-  padding-top: 5px;
-  padding-left: 2px;
-  padding-right: 5px;
-  font-size: smaller;
+	float: right;
+	min-width: 32px;
+	min-height: 32px;
+	-webkit-border-radius: 4px;
+	-moz-border-radius: 4px;
+	margin-right: 8px;
+	color: #333;
+	padding-top: 5px;
+	padding-left: 2px;
+	padding-right: 5px;
+	font-size: smaller;
 }
 
 
 .iconList .row {
-  min-height: 36px;
+	min-height: 36px;
 }
 
 .row .listButton1 {
-  background: url(../images/i-icon-1.png) no-repeat;
+	background: url(../images/i-icon-1.png) no-repeat;
 }
 .row .listButton2 {
-  background: url(../images/i-icon-2.png) no-repeat;
+	background: url(../images/i-icon-2.png) no-repeat;
 }
 .row .listButton3 {
-  background: url(../images/i-icon-3.png) no-repeat;
+	background: url(../images/i-icon-3.png) no-repeat;
 }
 .row .listButton4 {
-  background: url(../images/i-icon-4.png) no-repeat;
+	background: url(../images/i-icon-4.png) no-repeat;
 }
 .row .listButtonText {
-  
+
 }
 
 .row .listButtonHidden {
-  display: none;
+	display: none;
 }
+.divider {
+	padding: 2px;
+	background-color: lightblue;
+}
\ No newline at end of file
diff --git a/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js b/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js
index 58df3d6..392276a 100644
--- a/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/dialogApp/app/assistants/main-assistant.js
@@ -11,8 +11,8 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
     
     var appInfoNode = this.controller.query(".appInfoArea")[0];
     
-    appInfoNode.innerHTML = 
-      "This app has the following info: \n" 
+    appInfoNode.innerHTML =
+      "This app has the following info: \n"
         + dojo.toJson(dojox.mobile.app.info, true);
         
     function handleChoose(value){
@@ -21,7 +21,7 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
     }
     
     
-    var controller = this.controller; 
+    var controller = this.controller;
     
     console.log("btn1 = ", dijit.byId("btn1"));
     
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 f0b9c4e..e558124 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
@@ -2,28 +2,30 @@ dojo.provide("FlickrImageThumbViewAssistant");
 dojo.require("dojox.mobile.app.SceneAssistant");
 
 dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
-  
+
 	apiKey: "8c6803164dbc395fb7131c9d54843627",
-	
+
 	setup: function(){
-	
+
 		// Instantiate widgets in the template HTML.
 		this.controller.parse();
-		
+
 		this.handlePhotoLoad = dojo.hitch(this, this.handlePhotoLoad);
 		this.search = dojo.hitch(this, this.search);
-		
+		this.resizeViewer = dojo.hitch(this, this.resizeViewer);
+
 		this.textWidget = dijit.byId("searchTextThumbInput");
-		
+
 		var viewer = this.viewer = dijit.byId("flickrImageThumbView");
-		
-		console.log("widget flickrImageThumbView = ", viewer);
-		
+
+		// Set the parameter from which to retrieve the owner name
+		viewer.labelParam = "ownername";
+
 		var _this = this;
-		
+
 		this.connect(viewer, "onSelect", function(item, index){
 			console.log("selected ", item, index);
-			
+
 			_this.controller.stageController.pushScene("flickr-image-view",{
 				type: "data",
 				images: _this.urls,
@@ -33,22 +35,44 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 
 		this.connect(this.textWidget, "onChange", function(value){
 			if(!value || value.length == 0){
-				_this.viewer.attr("items", []);
+				_this.viewer.set("items", []);
 				return;
 			}
-			
+
 			if(!_this.timer){
 				_this.timer = setTimeout(_this.search, 1000);
 			}
 		});
+
+		this.connect(dijit.byId("btnSmall"), "onClick", function(event){
+			_this.setThumbSize("small");
+		});
+		this.connect(dijit.byId("btnMedium"), "onClick", function(event){
+			_this.setThumbSize("medium");
+		});
+		this.connect(dijit.byId("btnLarge"), "onClick", function(event){
+			_this.setThumbSize("large");
+		});
+
+		var resizeTimer;
+		// Listen to the resize event on the window to make
+		// 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){
+			if(resizeTimer){
+				clearTimeout(resizeTimer);
+			}
+			resizeTimer = setTimeout(_this.resizeViewer, 300);
+		});
 	},
-  
+
 	activate: function(options){
-		
+
 		// If this is the first time this view is activated, then do the initial
 		// load of images
 		if (!this.dataType) {
-		
+
 			this.dataType = (options ? options.type : "interesting");
 
 			switch (this.dataType) {
@@ -59,35 +83,45 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 					break;
 				case "text":
 					dojo.style(this.textWidget.domNode, "visibility", "visible");
-					this.loadText(this.textWidget.attr("value"));
+					this.loadText(this.textWidget.set("value"));
 					break;
 				case "tag":
 					// Another scene has passed in a list of images
 					// and an initial index
 					dojo.style(this.textWidget.domNode, "visibility", "visible");
-					this.loadTags(this.textWidget.attr("value"));
+					this.loadTags(this.textWidget.set("value"));
 					break;
 				default:
 					console.log("unknown type " + this.dataType, options);
 			}
 		}
 	},
-	
+
+	setThumbSize: function(cls){
+		dojo.removeClass(this.viewer.domNode, ["small", "medium", "large"]);
+		dojo.addClass(this.viewer.domNode, cls);
+		this.resizeViewer();
+	},
+
+	resizeViewer: function(){
+		this.viewer.resize();
+	},
+
 	search: function(){
 		if(this.timer){
 			clearTimeout(this.timer);
 			this.timer = null;
 		}
-		
-		var searchText = this.textWidget.attr("value");
-		
+
+		var searchText = this.textWidget.set("value");
+
 		if(!searchText || dojo.trim(searchText).length < 1){
-			this.viewer.attr("items", []);
-			
+			this.viewer.set("items", []);
+
 			console.log("NOT SEARCHING");
 			return;
 		}
-		
+
 		console.log("search", searchText);
 		switch(this.dataType){
 			case "text":
@@ -100,17 +134,17 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 				break;
 		}
 	},
-  
+
 	loadInteresting: function(){
 		console.log("loading interesting");
 		var _this = this;
-		
+
 		var url = "http://api.flickr.com/services/rest/?method=" +
 					"flickr.interestingness.getList";
 
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json",
 				per_page: 20
@@ -123,16 +157,17 @@ 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";
 
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json",
 				text: text,
+				extras: "owner_name",
 				per_page: 20
 			},
 			jsonp: "jsoncallback"
@@ -143,13 +178,13 @@ 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";
 
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json",
 				tags: text,
@@ -164,14 +199,14 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 		console.log("got photos", res);
 		if(res && res.photos && res.photos.photo){
 			var images = this.images = res.photos.photo;
-			
+
 			var urls = [];
-			
+
 			var baseUrl;
-			
+
 			for(var i = 0; i < images.length; i++){
-				baseUrl = "http://farm" 
-							+ images[i].farm 
+				baseUrl = "http://farm"
+							+ images[i].farm
 							+ ".static.flickr.com/"
 							+ images[i].server
 							+ "/"
@@ -182,17 +217,19 @@ dojo.declare("FlickrImageThumbViewAssistant", dojox.mobile.app.SceneAssistant, {
 					large: baseUrl + ".jpg",
 					small: baseUrl + "_t.jpg",
 					thumb: baseUrl + "_s.jpg",
+					ownername: images[i].ownername,
 					title: images[i].title
 				});
 			}
 			this.urls = urls;
 			this.index = 0;
-			
-			this.viewer.attr("items", urls);
+			this.viewer.set("selectedIndex", this.index);
+
+			this.viewer.set("items", urls);
 		}else{
-			this.viewer.attr("items", []);
+			this.viewer.set("items", []);
 			console.log("didn't get photos");
 		}
 	}
-  
+
 });
\ No newline at end of file
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 d867fb0..8287f03 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
@@ -36,15 +36,15 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 			
 			// If we are not at the first image, set the leftUrl attribute
 			if(_this.index > 0){
-				viewer.attr("leftUrl", _this.urls[_this.index - 1]);
+				viewer.set("leftUrl", _this.urls[_this.index - 1]);
 			}
 		
 			// If we are not at the last image, set the rightUrl attribute
 			if(_this.index < _this.urls.length - 1){
-				viewer.attr("rightUrl", _this.urls[_this.index + 1]);
+				viewer.set("rightUrl", _this.urls[_this.index + 1]);
 			}
 			
-			reportDiv.innerHTML = 
+			reportDiv.innerHTML =
 				(_this.index + 1) + " of " + _this.urls.length
 				+ " " + _this.urls[_this.index].title;
 		});
@@ -76,12 +76,12 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 		this.index = Math.min(images.length - 1, Math.max(0, startIndex));
 	
 		if (this.index > 0) {
-			this.viewer.attr("leftUrl", images[this.index - 1]);
+			this.viewer.set("leftUrl", images[this.index - 1]);
 		}
-		this.viewer.attr("centerUrl", images[this.index]);
+		this.viewer.set("centerUrl", images[this.index]);
 		
 		if (this.index < images.length) {
-			this.viewer.attr("rightUrl", images[this.index + 1]);
+			this.viewer.set("rightUrl", images[this.index + 1]);
 		}
 	},
   
@@ -95,7 +95,7 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json"
 			},
@@ -113,14 +113,14 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 					
 //		"http://api.flickr.com/services/rest/?method=flickr.groups.pools.getPhotos"
 //      + "&api_key=" + lib.API_KEY
-//      + "&group_id=" + group.id 
-//      + "&extras=owner_name" 
+//      + "&group_id=" + group.id
+//      + "&extras=owner_name"
 //      + "&per_page=" + (perPage || 10)
 //      + "&format=json&nojsoncallback=1"
 
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json",
 				group_id: groupData.nsid,
@@ -143,8 +143,8 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 			var baseUrl;
 			
 			for(var i = 0; i < images.length; i++){
-				baseUrl = "http://farm" 
-							+ images[i].farm 
+				baseUrl = "http://farm"
+							+ images[i].farm
 							+ ".static.flickr.com/"
 							+ images[i].server
 							+ "/"
@@ -160,8 +160,8 @@ dojo.declare("FlickrImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 			this.urls = urls;
 			this.index = 0;
 		
-			this.viewer.attr("centerUrl", urls[0]);
-			this.viewer.attr("rightUrl", urls[1]);
+			this.viewer.set("centerUrl", urls[0]);
+			this.viewer.set("rightUrl", urls[1]);
 		}else{
 			console.log("didn't get photos");
 		}
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 38ff4cb..7db0c67 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
@@ -15,7 +15,7 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 		this.listWidget = dijit.byId("searchList");
 		this.textWidget = dijit.byId("searchTextInput");
 		
-		this.listWidget.attr("items", []);
+		this.listWidget.set("items", []);
 		
 		var _this = this;
 		
@@ -29,7 +29,7 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 		//		console.log("search value = ", value);
 			
 			if(!value || value.length == 0){
-				_this.listWidget.attr("items", []);
+				_this.listWidget.set("items", []);
 				return;
 			}
 			
@@ -42,7 +42,7 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 			console.log("select", arguments);
 			
 			_this.controller.stageController.pushScene("flickr-image-view",
-				dojo.mixin({type: "group"}, item));	
+				dojo.mixin({type: "group"}, item));
 		});
 	},
   
@@ -68,7 +68,7 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 		// Focus in the search text input
 		this.textWidget.focus();
 		
-		if(this.textWidget.attr("value")){
+		if(this.textWidget.set("value")){
 			this.search();
 		}
 	},
@@ -82,10 +82,10 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 			this.timer = null;
 		}
 		
-		var searchText = this.textWidget.attr("value");
+		var searchText = this.textWidget.set("value");
 		
 		if(!searchText || dojo.trim(searchText).length < 1){
-			this.listWidget.attr("items", []);
+			this.listWidget.set("items", []);
 			
 			console.log("NOT SEARCHING");
 			return;
@@ -95,7 +95,7 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 		
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json",
 				text: searchText,
@@ -117,7 +117,7 @@ dojo.declare("FlickrSearchGroupAssistant", dojox.mobile.app.SceneAssistant, {
 		}else{
 			groups = [];
 		}
-		this.listWidget.attr("items", groups);
+		this.listWidget.set("items", groups);
 	}
   
 });
\ No newline at end of file
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 b94e3d7..69c1d0d 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
@@ -15,7 +15,7 @@ dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
 		this.listWidget = dijit.byId("searchList");
 		this.textWidget = dijit.byId("searchTextInput");
 		
-		this.listWidget.attr("items", []);
+		this.listWidget.set("items", []);
 		
 		var _this = this;
 		
@@ -29,7 +29,7 @@ dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
 		//		console.log("search value = ", value);
 			
 			if(!value || value.length == 0){
-				_this.listWidget.attr("items", []);
+				_this.listWidget.set("items", []);
 				return;
 			}
 			
@@ -42,7 +42,7 @@ dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
 			console.log("select", arguments);
 			
 			_this.controller.stageController.pushScene("flickr-image-view",
-				dojo.mixin({type: "group"}, item));	
+				dojo.mixin({type: "group"}, item));
 		});
 	},
   
@@ -78,10 +78,10 @@ dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
 			this.timer = null;
 		}
 		
-		var searchText = this.textWidget.attr("value");
+		var searchText = this.textWidget.set("value");
 		
 		if(!searchText || dojo.trim(searchText).length < 1){
-			this.listWidget.attr("items", []);
+			this.listWidget.set("items", []);
 			
 			console.log("NOT SEARCHING");
 			return;
@@ -91,7 +91,7 @@ dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
 		
 		var deferred = dojo.io.script.get({
 			url: url,
-			content: { 
+			content: {
 				api_key: this.apiKey,
 				format: "json",
 				text: searchText,
@@ -113,7 +113,7 @@ dojo.declare("FlickrSearchTextAssistant", dojox.mobile.app.SceneAssistant, {
 		}else{
 			groups = [];
 		}
-		this.listWidget.attr("items", groups);
+		this.listWidget.set("items", groups);
 	}
   
 });
\ No newline at end of file
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 e769d89..cd6bf9b 100644
--- a/dojox/mobile/tests/imageControlsApp/app/assistants/image-view-assistant.js
+++ b/dojox/mobile/tests/imageControlsApp/app/assistants/image-view-assistant.js
@@ -19,9 +19,9 @@ dojo.declare("ImageViewAssistant", dojox.mobile.app.SceneAssistant, {
     
 	var viewer = this.viewer = dijit.byId("imageView");
 	
-	this.viewer.attr("leftUrl", images[0]);
-	this.viewer.attr("centerUrl", images[1]);
-	this.viewer.attr("rightUrl", images[2]);
+	this.viewer.set("leftUrl", images[0]);
+	this.viewer.set("centerUrl", images[1]);
+	this.viewer.set("rightUrl", images[2]);
 	
 	dojo.connect(dijit.byId("decZoom"), "onClick", function(){
 		viewer.set("zoom", viewer.get("zoom") - 0.1);
@@ -74,10 +74,10 @@ dojo.declare("ImageViewAssistant", dojox.mobile.app.SceneAssistant, {
 		console.log("Index = " + index);
 		
 		if(index > 0){
-			viewer.attr("leftUrl", images[index - 1]);
+			viewer.set("leftUrl", images[index - 1]);
 		}
 		if(index < images.length - 1){
-			viewer.attr("rightUrl", images[index + 1]);
+			viewer.set("rightUrl", images[index + 1]);
 		}
 	});
 	
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 55f37b4..8854eeb 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
@@ -1,17 +1,19 @@
 <h1 dojoType="dojox.mobile.Heading" back="Back">
 	Flickr ImageThumbView
 </h1>
-<input 
+<input
 	dojoType="dojox.mobile.app.TextBox"
 	value="mountain"
-	class="fullWidthInput"
+	class="halfWidthInput"
 	style="visibility: hidden;"
 	placeholder="Enter Search Text"
 	intermediateChanges="true"
 	id="searchTextThumbInput">
-<div 
-	dojoType="dojox.mobile.app.ImageThumbView" 
-	id="flickrImageThumbView" 
-	urlParam="thumb"
-	style="width:320px; height: 400px;">
+<button id="btnSmall" dojoType="dojox.mobile.Button">S</button>
+<button id="btnMedium" dojoType="dojox.mobile.Button">M</button>
+<button id="btnLarge" dojoType="dojox.mobile.Button">L</button>
+<div
+	dojoType="dojox.mobile.app.ImageThumbView"
+	id="flickrImageThumbView"
+	urlParam="thumb">
 </div>
\ No newline at end of file
diff --git a/dojox/mobile/tests/images/tab-icon-10.png b/dojox/mobile/tests/images/tab-icon-10.png
new file mode 100644
index 0000000..5266c1e
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-10.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-10h.png b/dojox/mobile/tests/images/tab-icon-10h.png
new file mode 100644
index 0000000..9b12683
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-10h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-11.png b/dojox/mobile/tests/images/tab-icon-11.png
new file mode 100644
index 0000000..57740eb
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-11.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-11h.png b/dojox/mobile/tests/images/tab-icon-11h.png
new file mode 100644
index 0000000..0f3592d
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-11h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-12.png b/dojox/mobile/tests/images/tab-icon-12.png
new file mode 100644
index 0000000..8b6dc5f
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-12.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-12h.png b/dojox/mobile/tests/images/tab-icon-12h.png
new file mode 100644
index 0000000..e230a38
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-12h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-13.png b/dojox/mobile/tests/images/tab-icon-13.png
new file mode 100644
index 0000000..57f21cc
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-13.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-13h.png b/dojox/mobile/tests/images/tab-icon-13h.png
new file mode 100644
index 0000000..ec87db0
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-13h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-14.png b/dojox/mobile/tests/images/tab-icon-14.png
new file mode 100644
index 0000000..cea484a
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-14.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-14h.png b/dojox/mobile/tests/images/tab-icon-14h.png
new file mode 100644
index 0000000..0e602c4
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-14h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-15.png b/dojox/mobile/tests/images/tab-icon-15.png
new file mode 100644
index 0000000..09368cf
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-15.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-15h.png b/dojox/mobile/tests/images/tab-icon-15h.png
new file mode 100644
index 0000000..bd0daee
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-15h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-16.png b/dojox/mobile/tests/images/tab-icon-16.png
new file mode 100644
index 0000000..ee58ce6
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-16.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-16h.png b/dojox/mobile/tests/images/tab-icon-16h.png
new file mode 100644
index 0000000..1ca2c06
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-16h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-17.png b/dojox/mobile/tests/images/tab-icon-17.png
new file mode 100644
index 0000000..0387855
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-17.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-17h.png b/dojox/mobile/tests/images/tab-icon-17h.png
new file mode 100644
index 0000000..06c894e
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-17h.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-18.png b/dojox/mobile/tests/images/tab-icon-18.png
new file mode 100644
index 0000000..ac8fa6d
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-18.png differ
diff --git a/dojox/mobile/tests/images/tab-icon-18h.png b/dojox/mobile/tests/images/tab-icon-18h.png
new file mode 100644
index 0000000..6fa5a1f
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icon-18h.png differ
diff --git a/dojox/mobile/tests/images/tab-icons.png b/dojox/mobile/tests/images/tab-icons.png
new file mode 100644
index 0000000..93f50d0
Binary files /dev/null and b/dojox/mobile/tests/images/tab-icons.png differ
diff --git a/dojox/mobile/tests/index.html b/dojox/mobile/tests/index.html
index 3222928..c419aa3 100644
--- a/dojox/mobile/tests/index.html
+++ b/dojox/mobile/tests/index.html
@@ -1,8 +1,8 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
-		<title>djMobile</title>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<title>dojox.mobile</title>
 	</head>
 	<body>
 		<a href="test_iPhone-Animation.html">test_iPhone-Animation.html</a><br>
@@ -26,6 +26,7 @@
 		<a href="test_Android-ButtonList.html">test_Android-ButtonList.html</a><br>
 		<a href="test_Android-EdgeToEdge.html">test_Android-EdgeToEdge.html</a><br>
 		<a href="test_Android-EdgeToEdgeCategory.html">test_Android-EdgeToEdgeCategory.html</a><br>
+		<a href="test_Android-Heading.html">test_Android-Heading.html</a><br>
 		<a href="test_Android-Icon.html">test_Android-Icon.html</a><br>
 		<a href="test_Android-RoundRectList.html">test_Android-RoundRectList.html</a><br>
 		<a href="test_Android-Settings.html">test_Android-Settings.html</a><br>
@@ -33,6 +34,32 @@
 		<a href="test_Android-TabContainer.html">test_Android-TabContainer.html</a><br>
 		<a href="test_Android-VariableHeightList.html">test_Android-VariableHeightList.html</a><br>
 		<hr>
+		<a href="test_iPhone-ScrollableView-demo.html">test_iPhone-ScrollableView-demo.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-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>
+		<hr>
+		<a href="test_ScrollableMixin-custom.html">test_ScrollableMixin-custom.html</a><br>
+		<a href="test_scrollable-no-dojo.html">test_scrollable-no-dojo.html</a><br>
+		<a href="test_scrollable-no-dojo-ah.html">test_scrollable-no-dojo-ah.html</a><br>
+		<a href="test_scrollable-no-dojo-af.html">test_scrollable-no-dojo-af.html</a><br>
+		<a href="test_scrollable-no-dojo-ah-af.html">test_scrollable-no-dojo-ah-af.html</a><br>
+		<hr>
+		<a href="test_iPad-Settings.html">test_iPad-Settings.html</a><br>
+		<hr>
 		<a href="test_buttons.html">test_buttons.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>
@@ -40,9 +67,21 @@
 		<a href="test_dynamic-items.html">test_dynamic-items.html</a><br>
 		<a href="test_dynamic-icons.html">test_dynamic-icons.html</a><br>
 		<a href="test_dynamic-view.html">test_dynamic-view.html</a><br>
+		<a href="test_dynamic-ScrollableView-ah-af.html">test_dynamic-ScrollableView-ah-af.html</a><br>
+		<a href="test_dynamic-ScrollableView-vh-vf.html">test_dynamic-ScrollableView-vh-vf.html</a><br>
 		<a href="test_ajax-html.html">test_ajax-html.html</a><br>
 		<a href="test_ajax-json.html">test_ajax-json.html</a><br>
 		<a href="test_anchor-label.html">test_anchor-label.html</a><br>
+		<a href="test_css-sprite.html">test_css-sprite.html</a><br>
+		<a href="test_transition-to-dynamic-view.html">test_transition-to-dynamic-view.html</a><br>
+		<a href="test_grouped-views.html">test_grouped-views.html</a><br>
+		<a href="test_grouped-scrollable-views.html">test_grouped-scrollable-views.html</a><br>
+		<a href="test_orientation-transition.html">test_orientation-transition.html</a><br>
+		<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="simpleApp">Simple Full App</a><br>
 		<a href="simpleListApp">Simple Full App Using a List</a><br>
diff --git a/dojox/mobile/tests/items.json b/dojox/mobile/tests/items.json
new file mode 100644
index 0000000..b724415
--- /dev/null
+++ b/dojox/mobile/tests/items.json
@@ -0,0 +1,7 @@
+{
+  items: [
+	{ title:'Top 10 news stories', href:'http://dojotoolkit.org/' },
+	{ title:'Web applications with GFX', href:'http://dojotoolkit.org/' },
+	{ title:'Explores advanced topics', href:'http://dojotoolkit.org/' }
+  ]
+}
diff --git a/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js b/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js
index 5f4d132..a8e110d 100644
--- a/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/multiSceneApp/app/assistants/main-assistant.js
@@ -8,8 +8,8 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
     
     var appInfoNode = this.controller.query(".appInfoArea")[0];
     
-    appInfoNode.innerHTML = 
-      "This app has the following info: \n" 
+    appInfoNode.innerHTML =
+      "This app has the following info: \n"
         + dojo.toJson(dojox.mobile.app.info, true).split("\t").join("  ");
         
     // Instantiate widgets in the template HTML.
diff --git a/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js b/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js
index 2838cd1..15c26af 100644
--- a/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/simpleApp/app/assistants/main-assistant.js
@@ -8,8 +8,8 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
     
     var appInfoNode = this.controller.query(".appInfoArea")[0];
     
-    appInfoNode.innerHTML = 
-      "This app has the following info: \n" 
+    appInfoNode.innerHTML =
+      "This app has the following info: \n"
         + dojo.toJson(dojox.mobile.app.info, true)
     
   },
diff --git a/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js b/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js
index b7d946d..584a9ba 100644
--- a/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js
+++ b/dojox/mobile/tests/simpleListApp/app/assistants/main-assistant.js
@@ -40,7 +40,7 @@ dojo.declare("MainAssistant", dojox.mobile.app.SceneAssistant, {
     dojo.connect(listWidget, "onSelect", function(data, index, rowNode){
       try {
         console.log("selected data item  ", data);
-        _this.controller.query(".listInfo")[0].innerHTML 
+        _this.controller.query(".listInfo")[0].innerHTML
                 = "Selected (" + index + ") '" + data.label + "'";
       } catch(e){
         console.log("caught ", e);
diff --git a/dojox/mobile/tests/test_Android-ButtonList.html b/dojox/mobile/tests/test_Android-ButtonList.html
index 9c3c69b..5a70c0c 100644
--- a/dojox/mobile/tests/test_Android-ButtonList.html
+++ b/dojox/mobile/tests/test_Android-ButtonList.html
@@ -2,7 +2,7 @@
 
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -36,6 +36,9 @@
 					dojo.removeClass(btnDiv, "mblCheckOnButton");
 					dojo.addClass(btnDiv, "mblCheckOffButton");
 				}
+				if(dojo.isBB){
+					btnDiv.parentNode.appendChild(btnDiv.parentNode.removeChild(btnDiv));
+				}
 			}
 		</script>
 	</head>
diff --git a/dojox/mobile/tests/test_Android-EdgeToEdge.html b/dojox/mobile/tests/test_Android-EdgeToEdge.html
index d24b4bd..69456b7 100644
--- a/dojox/mobile/tests/test_Android-EdgeToEdge.html
+++ b/dojox/mobile/tests/test_Android-EdgeToEdge.html
@@ -2,7 +2,7 @@
 
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html b/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
index 9f69394..477e2ee 100644
--- a/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
+++ b/dojox/mobile/tests/test_Android-EdgeToEdgeCategory.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_Android-Heading.html b/dojox/mobile/tests/test_Android-Heading.html
new file mode 100644
index 0000000..1d056ac
--- /dev/null
+++ b/dojox/mobile/tests/test_Android-Heading.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>Heading</title>
+		<link href="../themes/android/android.css" rel="stylesheet"></link>
+		<link href="../themes/domButtons.css" rel="stylesheet"></link>
+
+		<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(){
+				var btn1 = dijit.byId("btn1");
+				btn1.connect(btn1.domNode, "onclick", function(){
+					alert(this.label + " button was clicked");
+				});
+			});
+		</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>
+
+		<h3 style="color:white;">Heading with buttons</div>
+
+		<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>
+
+		</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>
+			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">
+			<!-- 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>
+
+
+		<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="mblDomButton mblDomButtonPlus_2" moveTo="view3" style="float:right;"></div>
+		</div><br>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_Android-Icon.html b/dojox/mobile/tests/test_Android-Icon.html
index 851a874..c71dfc8 100755
--- a/dojox/mobile/tests/test_Android-Icon.html
+++ b/dojox/mobile/tests/test_Android-Icon.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -23,6 +23,7 @@
 			//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>
 	</head>
diff --git a/dojox/mobile/tests/test_Android-RoundRectList.html b/dojox/mobile/tests/test_Android-RoundRectList.html
index 150c0e3..3dac089 100755
--- a/dojox/mobile/tests/test_Android-RoundRectList.html
+++ b/dojox/mobile/tests/test_Android-RoundRectList.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -19,26 +19,20 @@
 		<div id="foo" dojoType="dojox.mobile.View" selected="true">
 			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
 			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/a-icon-2.png">
-				<li id="item1" dojoType="dojox.mobile.ListItem" icon="images/a-icon-10.png" rightText="Off" moveTo="bar" href="test_Android-Icon.html">
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItem" icon="images/a-icon-10.png" rightText="Off" moveTo="bar">
 					u1space
 				</li>
-				<li id="item12" dojoType="dojox.mobile.ListItem" icon="images/a-icon-11.png" rightText="Off" moveTo="bar" href="test_Android-Icon.html">
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="images/a-icon-11.png" rightText="Off" moveTo="bar">
 					u2space
 				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItem" icon="images/a-icon-12.png" rightText="Off" moveTo="bar" href="test_Android-Icon.html">
+				<li id="item3" dojoType="dojox.mobile.ListItem" icon="images/a-icon-12.png" rightText="Off" moveTo="bar">
 					Wi-Fi
 				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" icon="images/a-icon-13.png" rightText="VPN" moveTo="bar" href="test_Android-Icon.html">
+				<li id="item4" dojoType="dojox.mobile.ListItem" icon="images/a-icon-13.png" rightText="VPN" moveTo="bar">
 					VPN
 				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItem" icon="none" rightText="Off">
-					World
-				</li>
 			</ul>
-			<div dojoType="dojox.mobile.RoundRect">
-				Tapping on an item label text opens a different page (test_Android-Icon.html), tapping on right-hand side of the label text shows another view in the same page.
-			</div>
 		</div>
 
 		<div id="bar" dojoType="dojox.mobile.View">
diff --git a/dojox/mobile/tests/test_Android-Settings.html b/dojox/mobile/tests/test_Android-Settings.html
index 7885694..e45ba39 100644
--- a/dojox/mobile/tests/test_Android-Settings.html
+++ b/dojox/mobile/tests/test_Android-Settings.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -32,6 +32,9 @@
 					dojo.removeClass(btnDiv, "mblCheckOnButton");
 					dojo.addClass(btnDiv, "mblCheckOffButton");
 				}
+				if(dojo.isBB){
+					btnDiv.parentNode.appendChild(btnDiv.parentNode.removeChild(btnDiv));
+				}
 			}
 		</script>
 	</head>
diff --git a/dojox/mobile/tests/test_Android-Switch.html b/dojox/mobile/tests/test_Android-Switch.html
index 9ce7a1f..8603cfb 100644
--- a/dojox/mobile/tests/test_Android-Switch.html
+++ b/dojox/mobile/tests/test_Android-Switch.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<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.
diff --git a/dojox/mobile/tests/test_Android-TabBar.html b/dojox/mobile/tests/test_Android-TabBar.html
new file mode 100644
index 0000000..39447a3
--- /dev/null
+++ b/dojox/mobile/tests/test_Android-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/android/android.css" rel="stylesheet"></link>
+		<style>
+		.label {
+			color: white;
+			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>
+	</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<br>(style is not optimized for Android yet)</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>
+		<ul dojoType="dojox.mobile.TabBar" iconBase="images/tab-icons.png">
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,0,29,29" iconPos2="29,0,29,29" selected="true">Featured</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,29,29,29" iconPos2="29,29,29,29">Categories</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,58,29,29" iconPos2="29,58,29,29">Top 25</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,87,29,29" iconPos2="29,87,29,29">Search</li>
+			<li dojoType="dojox.mobile.TabBarButton" iconPos1="0,116,29,29" iconPos2="29,116,29,29">Updates</li>
+		</ul>
+
+		<div id="view1" dojoType="dojox.mobile.View" selected="true">
+			<div class="view">View 1</div>
+		</div>
+		<div id="view2" dojoType="dojox.mobile.View">
+			<div class="view">View 2</div>
+		</div>
+		<div id="view3" dojoType="dojox.mobile.View">
+			<div class="view">View 3</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_Android-TabContainer.html b/dojox/mobile/tests/test_Android-TabContainer.html
index 2701fd1..4cb94fb 100644
--- a/dojox/mobile/tests/test_Android-TabContainer.html
+++ b/dojox/mobile/tests/test_Android-TabContainer.html
@@ -1,9 +1,13 @@
 <!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, user-scalable=no"/>
+		<meta name="viewport" content="width=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</title>
+		<title>Tab Container (deprecated)</title>
 		<link href="../themes/android/android.css" rel="stylesheet"></link>
 		<style>
 		.lnk {
@@ -18,6 +22,7 @@
 			//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>
diff --git a/dojox/mobile/tests/test_Android-VariableHeightList.html b/dojox/mobile/tests/test_Android-VariableHeightList.html
index 0c2bdff..aa6fed4 100755
--- a/dojox/mobile/tests/test_Android-VariableHeightList.html
+++ b/dojox/mobile/tests/test_Android-VariableHeightList.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_FixedSplitter-H2-prog.html b/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
new file mode 100644
index 0000000..91b8ae3
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-H2-prog.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>FixedSplitter Test</title>
+		<style type="text/css">
+			@import "../themes/FixedSplitter.css";
+			html, body{
+				width: 100%;
+				height: 100%;
+				padding: 0px;
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("dojox.mobile.FixedSplitter");
+			dojo.addOnLoad(function(){
+					var w = new dojox.mobile.FixedSplitter({orientation:"H"}, dojo.byId("container"));
+					dojo.create("div", {
+						style: "background-color:yellow;width:200px;",
+						innerHTML: "pane #1 (width=200px)"
+					}, w.containerNode);
+					dojo.create("div", {
+						style:"background-color:pink;",
+						innerHTML: "pane #2"
+					}, w.containerNode);
+					w.startup();
+			});
+		</script>
+	</head>
+	<body>
+		<div id="container"></div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-H2.html b/dojox/mobile/tests/test_FixedSplitter-H2.html
new file mode 100644
index 0000000..4938ae7
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-H2.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>FixedSplitter Test</title>
+		<style type="text/css">
+			@import "../themes/FixedSplitter.css";
+			html, body{
+				width: 100%;
+				height: 100%;
+				padding: 0px;
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("dojox.mobile.FixedSplitter");
+		</script>
+	</head>
+	<body>
+		<div dojoType="dojox.mobile.FixedSplitter" orientation="H">
+			<div style="background-color:yellow;width:200px;">
+				pane #1 (width=200px)
+			</div>
+			<div style="background-color:pink;">
+				pane #2
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V2H2.html b/dojox/mobile/tests/test_FixedSplitter-V2H2.html
new file mode 100644
index 0000000..fd8ca10
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V2H2.html
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>FixedSplitter Test</title>
+		<style type="text/css">
+			@import "../themes/FixedSplitter.css";
+			html, body{
+				width: 100%;
+				height: 100%;
+				padding: 0px;
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("dojox.mobile.FixedSplitter");
+		</script>
+	</head>
+	<body>
+		<div dojoType="dojox.mobile.FixedSplitter" style="width:100%;height:100%;" orientation="V">
+			<div 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%;">
+					pane #2
+				</div>
+				<div style="background-color:cyan;">
+					pane #3
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_FixedSplitter-V3.html b/dojox/mobile/tests/test_FixedSplitter-V3.html
new file mode 100644
index 0000000..2d79f3b
--- /dev/null
+++ b/dojox/mobile/tests/test_FixedSplitter-V3.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<title>FixedSplitter Test</title>
+		<style type="text/css">
+			@import "../themes/FixedSplitter.css";
+			html, body{
+				width: 100%;
+				height: 100%;
+				padding: 0px;
+				margin: 0px;
+				overflow: hidden;
+			}
+		</style>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			dojo.require("dojo.parser");
+			dojo.require("dojox.mobile.FixedSplitter");
+		</script>
+	</head>
+	<body>
+		<div dojoType="dojox.mobile.FixedSplitter" orientation="V">
+			<div style="background-color:cyan;height:200px;">
+				pane #1 (height=200px)
+			</div>
+			<div style="background-color:yellow;height:100px;border-bottom:1px solid black">
+				pane #2 (height=100px)
+			</div>
+			<div style="background-color:pink;">
+				pane #3
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_ScrollableMixin-custom.html b/dojox/mobile/tests/test_ScrollableMixin-custom.html
new file mode 100644
index 0000000..710f387
--- /dev/null
+++ b/dojox/mobile/tests/test_ScrollableMixin-custom.html
@@ -0,0 +1,110 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>ScrollableMixin-custom</title>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			width: 100%;
+			margin: 0px;
+			padding: 0px;
+		}
+		#foo {
+			height: 100%;
+			overflow: hidden;
+		}
+		#header1 {
+			position: absolute;
+			margin: 0px;
+			width: 100%;
+			top: 0px;
+			background-color: cyan;
+			z-index: 1;
+		}
+			
+		</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._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);
+	}
+});
+			
+		</script>
+	</head>
+	<body>
+		<h1 id="header1">Fixed Header</h1>
+		<div id="foo" dojoType="dojox.mobile.ScrollablePane" fixedHeader="header1">
+			<ol>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+				<li>Item</li>
+			<ol>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_ajax-html.html b/dojox/mobile/tests/test_ajax-html.html
index ed4c7a3..b707681 100644
--- a/dojox/mobile/tests/test_ajax-html.html
+++ b/dojox/mobile/tests/test_ajax-html.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_ajax-json.html b/dojox/mobile/tests/test_ajax-json.html
index 1f82d90..5995b2c 100644
--- a/dojox/mobile/tests/test_ajax-json.html
+++ b/dojox/mobile/tests/test_ajax-json.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_anchor-label.html b/dojox/mobile/tests/test_anchor-label.html
index c340df5..f415f0b 100644
--- a/dojox/mobile/tests/test_anchor-label.html
+++ b/dojox/mobile/tests/test_anchor-label.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -36,17 +36,17 @@
 		<div id="foo" dojoType="dojox.mobile.View" selected="true">
 			<h1 dojoType="dojox.mobile.Heading">Anchor Label</h1>
 			<h2 dojoType="dojox.mobile.RoundRectCategory">Items</h2>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li id="item1" dojoType="dojox.mobile.ListItemEx" iconPos="0,0,29,29" moveTo="bar" anchorLabel="true">
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li id="item1" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-1.png" moveTo="bar" anchorLabel="true">
 					Different page
 				</li>
-				<li id="item2" dojoType="dojox.mobile.ListItemEx" iconPos="0,29,29,29" moveTo="bar" anchorLabel="true">
+				<li id="item2" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-2.png" moveTo="bar" anchorLabel="true">
 					Different page
 				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItemEx" iconPos="0,58,29,29" moveTo="bar" anchorLabel="true">
+				<li id="item3" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-3.png" moveTo="bar" anchorLabel="true">
 					External view
 				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItemEx" iconPos="0,87,29,29" moveTo="bar" anchorLabel="true">
+				<li id="item4" dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-4.png" moveTo="bar" anchorLabel="true">
 					External view
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_bookmarkable.html b/dojox/mobile/tests/test_bookmarkable.html
index 45a20fd..9257bdc 100755
--- a/dojox/mobile/tests/test_bookmarkable.html
+++ b/dojox/mobile/tests/test_bookmarkable.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_buttons.html b/dojox/mobile/tests/test_buttons.html
index 318819b..8f81b6c 100644
--- a/dojox/mobile/tests/test_buttons.html
+++ b/dojox/mobile/tests/test_buttons.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<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>
diff --git a/dojox/mobile/tests/test_css-sprite.html b/dojox/mobile/tests/test_css-sprite.html
new file mode 100644
index 0000000..6410872
--- /dev/null
+++ b/dojox/mobile/tests/test_css-sprite.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>Settings</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+
+		<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");
+			if(dojo.isBB){
+				alert("CSS Sprite is not supported for the BlackBerry browser");
+			}
+		</script>
+	</head>
+	<body>
+		<div id="settings" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29">
+					Airplane Mode
+					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" rightText="mac" href="test_iPhone-Icon.html">
+					Wi-Fi
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" rightText="AcmePhone" moveTo="general">
+					Carrier
+				</li>
+			</ul>
+
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
+					Sounds
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="general">
+					Brightness
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">
+					Wallpaper
+				</li>
+			</ul>
+
+			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,29,29,29" moveTo="general">
+					General
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,58,29,29" moveTo="general">
+					Mail, Contacts, Calendars
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,87,29,29" moveTo="general">
+					Phone
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="29,116,29,29" moveTo="general">
+					Safari
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" moveTo="general">
+					SMS/MMS
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" moveTo="general">
+					iPod
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" moveTo="general">
+					Photos
+				</li>
+				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
+					Store
+				</li>
+			</ul>
+		</div>
+
+		<div id="general" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="Settings" moveTo="settings">General</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					About
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="2h 40m" moveTo="about">
+					Usage
+				</li>
+			</ul>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Network
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
+					Bluetooth
+				</li>
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Location Services
+				</li>
+			</ul>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="1 Minute" moveTo="about">
+					Auto-Lock
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
+					Passcode Lock
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="Off" moveTo="about">
+					Restrictions
+				</li>
+			</ul>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Home
+				</li>
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Date & Time					   
+				</li>							   
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Keyboard					   
+				</li>							   
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					International				   
+				</li>							   
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Accessibility
+				</li>
+			</ul>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" moveTo="about">
+					Reset
+				</li>
+			</ul>
+		</div>
+
+		<div id="about" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading" back="General" moveTo="general">About</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="10">
+					Videos
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="96">
+					Photos
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="2">
+					Applications
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
+					Capacity
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
+					Available
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
+					Version
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html b/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.html
new file mode 100644
index 0000000..a4d31e2
--- /dev/null
+++ b/dojox/mobile/tests/test_dynamic-ScrollableView-ah-af.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>Dynamic ScrollableView (app header / app footer)</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<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.ScrollableView");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			dojo.addOnLoad(function(){
+				// ==== view1 ====
+				var view1 = new dojox.mobile.ScrollableView({
+					id: "foo",
+					selected: true
+				});
+				dojo.body().appendChild(view1.domNode);
+				view1.startup();
+
+				var categ1 = new dojox.mobile.RoundRectCategory({
+					label: "Documents"
+				});
+				view1.addChild(categ1);
+
+				var list1 = new dojox.mobile.RoundRectList();
+				view1.addChild(list1);
+
+				var counter = 4;
+				for(var i = 1; i <= 3; i++){
+					var item1 = new dojox.mobile.ListItem({
+						icon: "images/i-icon-"+i+".png",
+						label: "Document 000"+counter,
+						moveTo: "bar"
+					});
+					list1.addChild(item1);
+					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"
+				});
+				dojo.body().appendChild(view2.domNode);
+				view2.startup();
+
+				var rect1 = new dojox.mobile.RoundRect();
+				rect1.containerNode.innerHTML = "Go Back";
+				view2.addChild(rect1);
+				rect1.connect(rect1.domNode, "onclick", function(){
+					view2.performTransition("foo", -1, "slide");
+				});
+
+
+				// ==== App Footer has to be at the last position ====
+				var heading2 = new dojox.mobile.Heading({
+					label: "Fixed App Footer",
+					fixed: "bottom"
+				});
+				dojo.body().appendChild(heading2.domNode);
+
+
+				// ==== Initialize each view when the dom is ready ====
+				view1.findAppBars();
+				view1.resizeView();
+				view2.findAppBars();
+				view2.resizeView();
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html b/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.html
new file mode 100644
index 0000000..28b9522
--- /dev/null
+++ b/dojox/mobile/tests/test_dynamic-ScrollableView-vh-vf.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>Dynamic ScrollableView (view header / view footer)</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<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.ScrollableView");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+
+			dojo.addOnLoad(function(){
+				// ==== view1 ====
+				var view1 = new dojox.mobile.ScrollableView({
+					id: "foo",
+					selected: true
+				});
+				dojo.body().appendChild(view1.domNode);
+				view1.startup();
+
+				var heading2 = new dojox.mobile.Heading({
+					label: "Fixed View Footer",
+					fixed: "bottom"
+				});
+				view1.addChild(heading2);
+
+				var categ1 = new dojox.mobile.RoundRectCategory({
+					label: "Documents"
+				});
+				view1.addChild(categ1);
+
+				var list1 = new dojox.mobile.RoundRectList();
+				view1.addChild(list1);
+
+				var counter = 4;
+				for(var i = 1; i <= 3; i++){
+					var item1 = new dojox.mobile.ListItem({
+						icon: "images/i-icon-"+i+".png",
+						label: "Document 000"+counter,
+						moveTo: "bar"
+					});
+					list1.addChild(item1);
+					counter++;
+				}
+
+				var heading1 = new dojox.mobile.Heading({
+					label: "Fixed View Header",
+					fixed: "top"
+				});
+				view1.addChild(heading1);
+
+
+				// ==== view2 ====
+				var view2 = new dojox.mobile.View({
+					id: "bar"
+				});
+				dojo.body().appendChild(view2.domNode);
+				view2.startup();
+
+				var rect1 = new dojox.mobile.RoundRect();
+				rect1.containerNode.innerHTML = "Go Back";
+				view2.addChild(rect1);
+				rect1.connect(rect1.domNode, "onclick", function(){
+					view2.performTransition("foo", -1, "slide");
+				});
+			});
+		</script>
+	</head>
+	<body>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_dynamic-icons.html b/dojox/mobile/tests/test_dynamic-icons.html
index 970a2e9..6c07303 100644
--- a/dojox/mobile/tests/test_dynamic-icons.html
+++ b/dojox/mobile/tests/test_dynamic-icons.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -24,6 +24,7 @@
 			//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.addOnLoad(function(){
@@ -44,7 +45,7 @@
 	</head>
 	<body class="tundra">
 		<div id="myhome" dojoType="dojox.mobile.View" selected="true">
-			<ul id="ic1" dojoType="dojox.mobile.IconContainer" type="slide" iconBase="images/i-icon-all.png">
+			<ul id="ic1" dojoType="dojox.mobile.IconContainer" type="slide">
 				<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>
diff --git a/dojox/mobile/tests/test_dynamic-items.html b/dojox/mobile/tests/test_dynamic-items.html
index f3c663d..a58d794 100755
--- a/dojox/mobile/tests/test_dynamic-items.html
+++ b/dojox/mobile/tests/test_dynamic-items.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_dynamic-view.html b/dojox/mobile/tests/test_dynamic-view.html
index 6b0992c..36b30b7 100644
--- a/dojox/mobile/tests/test_dynamic-view.html
+++ b/dojox/mobile/tests/test_dynamic-view.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_grouped-scrollable-views.html b/dojox/mobile/tests/test_grouped-scrollable-views.html
new file mode 100644
index 0000000..1f4da26
--- /dev/null
+++ b/dojox/mobile/tests/test_grouped-scrollable-views.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>Grouped ScrollableViews</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<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.ScrollableView");
+
+			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="view1" dojoType="dojox.mobile.View" selected="true">
+			<div id="view11" dojoType="dojox.mobile.ScrollableView" selected="true">
+				<h1 dojoType="dojox.mobile.Heading" fixed="top">View 1-1</h1>
+				<h2 dojoType="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
+				<div dojoType="dojox.mobile.RoundRect" shadow="true">
+					<pre style="font-size:12px">
+ - View 1 (container)
+     |
+     *-- View 1-1
+         View 1-2
+ - View 2</pre>
+				</div>
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view12" transition="slide">
+						View 1-2
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
+						View 2
+					</li>
+				</ul>
+			</div>
+
+			<div id="view12" dojoType="dojox.mobile.ScrollableView">
+				<h1 dojoType="dojox.mobile.Heading" fixed="top">View 1-2</h1>
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view11" transition="slide" transitionDir="-1">
+						View 1-1
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
+						View 2
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div id="view2" dojoType="dojox.mobile.ScrollableView">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top">View 2</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
+					View 1
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_grouped-views.html b/dojox/mobile/tests/test_grouped-views.html
new file mode 100644
index 0000000..279328c
--- /dev/null
+++ b/dojox/mobile/tests/test_grouped-views.html
@@ -0,0 +1,63 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>Grouped Views</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<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="view1" dojoType="dojox.mobile.View" selected="true">
+			<div id="view11" dojoType="dojox.mobile.View" selected="true">
+				<h1 dojoType="dojox.mobile.Heading">View 1-1</h1>
+				<h2 dojoType="dojox.mobile.RoundRectCategory">Grouped View Example</h2>
+				<div dojoType="dojox.mobile.RoundRect" shadow="true">
+					<pre style="font-size:12px">
+ - View 1 (container)
+     |
+     *-- View 1-1
+         View 1-2
+ - View 2</pre>
+				</div>
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view12" transition="slide">
+						View 1-2
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
+						View 2
+					</li>
+				</ul>
+			</div>
+
+			<div id="view12" dojoType="dojox.mobile.View">
+				<h1 dojoType="dojox.mobile.Heading">View 1-2</h1>
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view11" transition="slide" transitionDir="-1">
+						View 1-1
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="view2" transition="slide">
+						View 2
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div id="view2" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading">View 2</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="view1" transition="slide" transitionDir="-1">
+					View 1
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_hash-parameter.html b/dojox/mobile/tests/test_hash-parameter.html
index d1e7899..78ed3bd 100755
--- a/dojox/mobile/tests/test_hash-parameter.html
+++ b/dojox/mobile/tests/test_hash-parameter.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_iPad-Settings.html b/dojox/mobile/tests/test_iPad-Settings.html
new file mode 100644
index 0000000..1999cf5
--- /dev/null
+++ b/dojox/mobile/tests/test_iPad-Settings.html
@@ -0,0 +1,238 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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/iphone.css";
+		@import "../themes/iphone/ipad.css";
+		@import "../themes/FixedSplitter.css";
+		html, body{
+			height: 100%;
+			overflow: hidden;
+		}
+		.mblEdgeToEdgeList {
+			background-color: #DBDDE2;
+		}
+		</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.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");
+		</script>
+	</head>
+	<body>
+		<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">
+						<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">
+						<li dojoType="dojox.mobile.ListItem">
+							Dissolve
+						</li>
+						<li dojoType="dojox.mobile.ListItem">
+							Origami
+						</li>
+					</ul>
+				</div>
+
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-Animation.html b/dojox/mobile/tests/test_iPhone-Animation.html
index 6088129..f3455ab 100644
--- a/dojox/mobile/tests/test_iPhone-Animation.html
+++ b/dojox/mobile/tests/test_iPhone-Animation.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -16,8 +16,8 @@
 
 		<script language="JavaScript" type="text/javascript">
 			//dojo.require("dojo.parser"); // Use the lightweight parser.
-			dojo.require("dojox.mobile");
 			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
 
 			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
 		</script>
diff --git a/dojox/mobile/tests/test_iPhone-Button.html b/dojox/mobile/tests/test_iPhone-Button.html
index 6e22dab..fc7a32b 100755
--- a/dojox/mobile/tests/test_iPhone-Button.html
+++ b/dojox/mobile/tests/test_iPhone-Button.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_iPhone-ButtonList.html b/dojox/mobile/tests/test_iPhone-ButtonList.html
index e666f01..7e2cf32 100644
--- a/dojox/mobile/tests/test_iPhone-ButtonList.html
+++ b/dojox/mobile/tests/test_iPhone-ButtonList.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -31,6 +31,9 @@
 					dojo.removeClass(btnDiv, "mblRedMinusButton");
 					dojo.addClass(btnDiv, "mblBluePlusButton");
 				}
+				if(dojo.isBB){
+					btnDiv.parentNode.appendChild(btnDiv.parentNode.removeChild(btnDiv));
+				}
 			}
 		</script>
 	</head>
diff --git a/dojox/mobile/tests/test_iPhone-EdgeToEdge.html b/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
index dada3e8..e2c3ce6 100644
--- a/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
+++ b/dojox/mobile/tests/test_iPhone-EdgeToEdge.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -17,15 +17,15 @@
 	<body>
 		<div id="settings" dojoType="dojox.mobile.View" selected="true">
 			<h1 dojoType="dojox.mobile.Heading">Settings</h1>
-			<ul dojoType="dojox.mobile.EdgeToEdgeList" iconBase="images/i-icon-all.png">
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29">
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
 					Airplane Mode
 					<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" rightText="mac" moveTo="hello">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" moveTo="hello">
 					Wi-Fi
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" rightText="AcmePhone" moveTo="hello">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="hello">
 					Carrier
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html b/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
index 20ea91f..e148b90 100644
--- a/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
+++ b/dojox/mobile/tests/test_iPhone-EdgeToEdgeCategory.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_iPhone-FlippableView.html b/dojox/mobile/tests/test_iPhone-FlippableView.html
new file mode 100644
index 0000000..85b8138
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-FlippableView.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>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 efed861..146b401 100644
--- a/dojox/mobile/tests/test_iPhone-Heading.html
+++ b/dojox/mobile/tests/test_iPhone-Heading.html
@@ -1,10 +1,11 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
 
 		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
 
@@ -12,13 +13,113 @@
 			//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 btn1 = dijit.byId("btn1");
+				btn1.connect(btn1.domNode, "onclick", function(){
+					alert(this.label + " button was clicked");
+				});
+			});
 		</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" xstyle="padding-left:100px">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</h1>
 		</div>
+
+		<h3>Heading with buttons</div>
+
+		<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>
+
+		</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>
+			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">
+			<!-- 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>
+
+
+		<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="mblDomButton mblDomButtonPlus_2" 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" class="mblDomButton mblDomButtonSearch_2" 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 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" class="mblDomButton mblDomButtonUpArrow_2" selectOne="false"></li>
+				<li dojoType="dojox.mobile.TabBarButton" class="mblDomButton mblDomButtonDownArrow_2" 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>
+		</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>
+			</ul>
+		</h1><br>
 	</body>
 </html>
diff --git a/dojox/mobile/tests/test_iPhone-Icon.html b/dojox/mobile/tests/test_iPhone-Icon.html
index c6e2742..b8355be 100644
--- a/dojox/mobile/tests/test_iPhone-Icon.html
+++ b/dojox/mobile/tests/test_iPhone-Icon.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -23,6 +23,7 @@
 			//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>
 	</head>
diff --git a/dojox/mobile/tests/test_iPhone-IconMulti.html b/dojox/mobile/tests/test_iPhone-IconMulti.html
index 5b651c5..c1320c6 100644
--- a/dojox/mobile/tests/test_iPhone-IconMulti.html
+++ b/dojox/mobile/tests/test_iPhone-IconMulti.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -14,6 +14,7 @@
 			//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>
 	</head>
@@ -21,13 +22,13 @@
 		<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">
+				<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>
-				<li dojoType="dojox.mobile.IconItem" label="Color Palette" icon="images/icon-1.png" lazy="true">
+				<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">
 					<div dojoType='dijit.ColorPalette'></div>
 				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
+				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true" requires="dijit._base.wai">
 					<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 f1cd249..b1f1314 100644
--- a/dojox/mobile/tests/test_iPhone-IconSingle.html
+++ b/dojox/mobile/tests/test_iPhone-IconSingle.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -13,6 +13,7 @@
 			//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>
 	</head>
@@ -20,13 +21,13 @@
 		<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">
+				<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>
-				<li dojoType="dojox.mobile.IconItem" label="Color Palette" icon="images/icon-1.png" lazy="true">
+				<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">
 					<div dojoType='dijit.ColorPalette'></div>
 				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
+				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true" requires="dijit._base.wai">
 					<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 39c0e47..8961cc2 100644
--- a/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
+++ b/dojox/mobile/tests/test_iPhone-IconSingleBelow.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -13,6 +13,7 @@
 			//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>
 	</head>
@@ -20,13 +21,13 @@
 		<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">
+				<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>
-				<li dojoType="dojox.mobile.IconItem" label="Color Palette" icon="images/icon-1.png" lazy="true">
+				<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">
 					<div dojoType='dijit.ColorPalette'></div>
 				</li>
-				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true">
+				<li dojoType="dojox.mobile.IconItem" label="Progress Bar" icon="images/icon-1.png" lazy="true" requires="dijit._base.wai">
 					<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 78162fa..fa44d89 100644
--- a/dojox/mobile/tests/test_iPhone-ResultList.html
+++ b/dojox/mobile/tests/test_iPhone-ResultList.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_iPhone-RoundRect.html b/dojox/mobile/tests/test_iPhone-RoundRect.html
index b9fb47f..f8f0ae9 100644
--- a/dojox/mobile/tests/test_iPhone-RoundRect.html
+++ b/dojox/mobile/tests/test_iPhone-RoundRect.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_iPhone-RoundRectList.html b/dojox/mobile/tests/test_iPhone-RoundRectList.html
index 2e7b882..b59b454 100644
--- a/dojox/mobile/tests/test_iPhone-RoundRectList.html
+++ b/dojox/mobile/tests/test_iPhone-RoundRectList.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -19,17 +19,17 @@
 		<div id="foo" dojoType="dojox.mobile.View" selected="true">
 			<h1 dojoType="dojox.mobile.Heading">Mobile Mashup</h1>
 			<h2 dojoType="dojox.mobile.RoundRectCategory">Spaces</h2>
-			<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-				<li id="item1" dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" rightText="Off" moveTo="bar">
+			<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" iconPos="0,29,29,29" rightText="Off" moveTo="bar">
+				<li id="item2" dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="Off" moveTo="bar">
 					u2space
 				</li>
-				<li id="item3" dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" rightText="Off" moveTo="bar">
+				<li id="item3" dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="Off" moveTo="bar">
 					Wi-Fi
 				</li>
-				<li id="item4" dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" rightText="VPN" moveTo="bar">
+				<li id="item4" dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" rightText="VPN" moveTo="bar">
 					VPN
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html b/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html
new file mode 100644
index 0000000..8cfb756
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-demo.html
@@ -0,0 +1,394 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	<meta name="viewport" content="width=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">
+	<style>
+	html,body{
+		height: 100%;
+		overflow: hidden;
+	}
+	.list1 li{
+		border-style: solid;
+		border-width: 1px 0px 1px 0px;
+		border-top-color: #BABABC;
+		border-bottom-color: #89898C;
+		background-color: #ACACAF;
+		line-height: 0px;
+	}
+	.list1 li table{
+		line-height: normal;
+	}
+	.list1 li:nth-child(even){
+		background-color: #97979B;
+	}
+	#list2 li:nth-child(even){
+		background-color: #eeeeee;
+	}
+	#categ1 {
+		font-size: 18px;
+	}
+	#categ1 li{
+		line-height: 70px;
+	}
+	.lnk {
+		font-size: 14px;
+		color: #0B5199;
+		text-decoration: none;
+	}
+	.content {
+		padding:0px 10px;
+		background-color: white;
+	}
+	p {
+		font-family: Helvetica;
+		font-size: 12px;
+	}
+	.title {
+		color: blue;
+		margin-bottom: 4px;
+	}
+	.subtitle {
+		font-style: italic;
+		color: gray;
+		margin: 0px;
+		margin-bottom: 4px;
+	}
+	.subsubtitle {
+		margin: 16px 0px 0px 0px;
+	}
+	.lst {
+		margin: 0px;
+		padding: 0px 14px;
+	}
+	.lst li {
+		font-family: Helvetica;
+		font-size: 12px;
+		margin: 0px;
+		list-style-type: square;
+	}
+	</style>
+	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+	<script language="JavaScript" type="text/javascript">
+		//dojo.require("dojo.parser"); // Use the lightweight parser.
+		dojo.require("dojox.mobile.parser");
+		dojo.require("dojox.mobile");
+		dojo.require("dojox.mobile.ScrollableView");
+		dojo.require("dojox.mobile.TabBar");
+		dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+		dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+	</script>
+</head>
+<body>
+	<div id="group1" dojoType="dojox.mobile.View" selected="true">
+		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
+			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
+		</ul>
+
+		<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
+			<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1">
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" dojoType="dojox.mobile.ScrollableView">
+			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list2">
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/a-icon-2-41x41.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" dojoType="dojox.mobile.ScrollableView">
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Generic Mobile Device</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Network											   
+				</li>												   
+				<li dojoType="dojox.mobile.ListItem" rightText="AcmePhone">
+					Line
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="1024">
+					Songs
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="10">
+					Videos
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="96">
+					Photos
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="2">
+					Applications
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="29.3 BG">
+					Capacity
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="28.0 BG">
+					Available
+				</li>
+				<li dojoType="dojox.mobile.ListItem" rightText="3.0 (7A341)">
+					Version
+				</li>
+			</ul>
+		</div>
+	</div>
+
+	<div id="categ" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Categories</h1>
+		<ul dojoType="dojox.mobile.EdgeToEdgeList" class="list1" id="categ1">
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 1</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 2</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 3</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 4</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 5</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 6</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 7</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 8</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 9</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 10</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 11</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 12</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 13</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 14</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">Category 15</li>
+		</ul>
+	</div>
+
+	<div id="top25" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">News</h1>
+		<h2 dojoType="dojox.mobile.RoundRectCategory">Top Stories</h2>
+		<ul dojoType="dojox.mobile.RoundRectList">
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
+				Top 10 news stories of the decade
+			</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
+				Create client-side diagrammatic interaction in Web applications with GFX
+			</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem">
+				Explores advanced topics in the new Java framework for implementing and consuming REST-based Web services, Part 3
+			</li>
+		</ul>
+	</div>
+
+	<div id="search" dojoType="dojox.mobile.ScrollableView">
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Search Result</h1>
+		<ul dojoType="dojox.mobile.RoundRectList">
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+				1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+				Sarah Connor Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$14.50 (50%)</font> In Stock<br>
+				# (531)
+			</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+				2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+				Martin Parker Hardcover<br>
+				<font color="red">$14.00 (60%)</font> In Stock<br>
+				# (173)
+			</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+				3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+				Steven Young Hardcover<br>
+				Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$9.50 (62%)</font> In Stock<br>
+				# (1199)
+			</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+				4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+				Marco Rodriguez Hardcover<br>
+				<font color="blue">Not Available</font>
+			</li>
+			<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+				5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+				Melissa Morgan Hardcover<br>
+				Eligible for FREE Super Saver Shipping<br>
+				<font color="red">$12.00 (60%)</font> In Stock<br>
+				# (1847)
+			</li>
+		</ul>
+	</div>
+
+	<div id="article" dojoType="dojox.mobile.ScrollableView" style="background-color:white;height:100%">
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Article</h1>
+		<div class="content">
+			<h3 class="title">Did you know?</h3>
+			<h4 class="subtitle">Features of dojox.mobile</h4>
+			<h5 class="subsubtitle">No images are used</h5>
+			<ul class="lst">
+			  	<li>UI parts consist of DOM and CSS3.</li>
+				<li>Only application icons are images.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Removed dependencies on the dojo modules as much as possible</h5>
+			<ul class="lst">
+			  	<li>No dependencies even on some of the essential core modules like Templated, Container, Contained, dojo.query, or dojo.parser.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Support for CSS sprite</h5>
+			<ul class="lst">
+				<li>Application icon images can be aggregated into a single file to reduce the number of http requests.</li>
+			</ul>
+
+			<h5 class="subsubtitle">Possible to use the webkitMobile build option (when PC browser support is unnecessary)</h5>
+			<ul class="lst">
+				<li>Drops IE and Firefox-specific code at build time, and thus reduces the dojo core size</li>
+			</ul>
+		</div>
+	</div>
+
+	<ul dojoType="dojox.mobile.TabBar" fixed="bottom" style="border-bottom:none;">
+		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" selected="true" moveTo="group1">Featured</li>
+		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="categ">Categories</li>
+		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="top25">Top 25</li>
+		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-11.png" icon2="images/tab-icon-11h.png" moveTo="search">Search</li>
+		<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-13.png" icon2="images/tab-icon-13h.png" moveTo="article">Updates</li>
+	</ul>
+</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-h.html b/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
new file mode 100644
index 0000000..952b350
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-h.html
@@ -0,0 +1,53 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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">
+		<style>
+		.lnk {
+			font-size: 14px;
+			color: #0B5199;
+			text-decoration: none;
+		}
+		html,body{
+			height: 100%;
+			overflow: hidden;
+		}
+		td {
+			white-space: nowrap;
+		}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			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>
+		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="h">
+			<!-- h1 dojoType="dojox.mobile.Heading" fixed="top">Animations</h1 -->
+			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+			</table>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.html
new file mode 100644
index 0000000..c6ae0a0
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-ah-af.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>ScrollableView-hv-ah-af</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;
+		}
+		td {
+			white-space: nowrap;
+		}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			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>
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Application Header Bar</h1>
+		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="hv">
+			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+			</table>
+		</div>
+		<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Application Footer Bar</h1>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.html
new file mode 100644
index 0000000..e057b2f
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-hv-vh-vf.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>ScrollableView-hv-vh-vf</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;
+		}
+		td {
+			white-space: nowrap;
+		}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			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>
+		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="hv">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
+			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+			</table>
+			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html b/dojox/mobile/tests/test_iPhone-ScrollableView-hv.html
new file mode 100644
index 0000000..a468256
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-hv.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>ScrollableView-hv</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;
+		}
+		td {
+			white-space: nowrap;
+		}
+		</style>
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			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>
+		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true" scrollDir="hv">
+			<!-- h1 dojoType="dojox.mobile.Heading" fixed="top">Animations</h1 -->
+			<table border="1" cellpadding="2" cellspacing="0" style="margin:4px;background-color:white;">
+<tr><td>a-icon-1-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>3,886</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>550</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-10.png</td><td>2010/05/06</td><td>08:57</td><td>332</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-11.png</td><td>2010/05/06</td><td>08:57</td><td>343</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-12.png</td><td>2010/05/06</td><td>08:57</td><td>613</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-13.png</td><td>2010/05/06</td><td>08:57</td><td>278</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-14.png</td><td>2010/05/06</td><td>08:57</td><td>612</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-15.png</td><td>2010/05/06</td><td>08:57</td><td>765</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-16.png</td><td>2010/05/06</td><td>08:57</td><td>597</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-17.png</td><td>2010/05/06</td><td>08:57</td><td>942</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-18.png</td><td>2010/05/06</td><td>08:57</td><td>832</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2-41x41.png</td><td>2010/03/23</td><td>13:03</td><td>923</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>644</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-3.png</td><td>2010/04/13</td><td>06:37</td><td>1,346</td><td>mobile/tests/images</td></tr>
+<tr><td>a-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-1.png</td><td>2010/03/23</td><td>13:03</td><td>677</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-10.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-2.png</td><td>2010/03/23</td><td>13:03</td><td>680</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-3.png</td><td>2010/03/23</td><td>13:03</td><td>682</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-4.png</td><td>2010/03/23</td><td>13:03</td><td>697</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-5.png</td><td>2010/03/23</td><td>13:03</td><td>693</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-6.png</td><td>2010/03/23</td><td>13:03</td><td>694</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-7.png</td><td>2010/03/23</td><td>13:03</td><td>691</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-8.png</td><td>2010/03/23</td><td>13:03</td><td>695</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-9.png</td><td>2010/03/23</td><td>13:03</td><td>689</td><td>mobile/tests/images</td></tr>
+<tr><td>i-icon-all.png</td><td>2010/03/23</td><td>13:03</td><td>4,450</td><td>mobile/tests/images</td></tr>
+<tr><td>icon-1.png</td><td>2010/05/06</td><td>08:57</td><td>2,626</td><td>mobile/tests/images</td></tr>
+<tr><td>not-images.png</td><td>2010/04/13</td><td>06:37</td><td>18,459</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-bg.png</td><td>2010/04/13</td><td>06:37</td><td>178</td><td>mobile/tests/images</td></tr>
+<tr><td>red-button-sel-bg.png</td><td>2010/04/13</td><td>06:37</td><td>185</td><td>mobile/tests/images</td></tr>
+<tr><td>test_Android-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,750</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,835</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,615</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,634</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,142</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Settings.html</td><td>2010/10/05</td><td>21:08</td><td>4,375</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>1,000</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,031</td><td>mobile/tests</td></tr>
+<tr><td>test_Android-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,570</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2-prog.html</td><td>2010/10/03</td><td>22:28</td><td>1,089</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-H2.html</td><td>2010/10/03</td><td>22:28</td><td>872</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V2H2.html</td><td>2010/10/03</td><td>22:28</td><td>1,088</td><td>mobile/tests</td></tr>
+<tr><td>test_FixedSplitter-V3.html</td><td>2010/10/03</td><td>22:28</td><td>996</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-html.html</td><td>2010/10/05</td><td>21:09</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_ajax-json.html</td><td>2010/10/05</td><td>21:08</td><td>1,505</td><td>mobile/tests</td></tr>
+<tr><td>test_anchor-label.html</td><td>2010/10/05</td><td>21:08</td><td>2,959</td><td>mobile/tests</td></tr>
+<tr><td>test_bookmarkable.html</td><td>2010/10/05</td><td>21:09</td><td>4,443</td><td>mobile/tests</td></tr>
+<tr><td>test_buttons.html</td><td>2010/10/05</td><td>21:08</td><td>972</td><td>mobile/tests</td></tr>
+<tr><td>test_css-sprite.html</td><td>2010/10/05</td><td>21:09</td><td>5,779</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-icons.html</td><td>2010/10/05</td><td>21:08</td><td>2,080</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-items.html</td><td>2010/10/05</td><td>21:08</td><td>3,375</td><td>mobile/tests</td></tr>
+<tr><td>test_dynamic-view.html</td><td>2010/10/05</td><td>21:09</td><td>1,657</td><td>mobile/tests</td></tr>
+<tr><td>test_hash-parameter.html</td><td>2010/10/05</td><td>21:09</td><td>2,679</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings-fixed.html</td><td>2010/10/03</td><td>22:28</td><td>8,866</td><td>mobile/tests</td></tr>
+<tr><td>test_iPad-Settings.html</td><td>2010/10/03</td><td>22:28</td><td>6,904</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Animation.html</td><td>2010/10/05</td><td>21:08</td><td>3,343</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Button.html</td><td>2010/10/05</td><td>21:09</td><td>1,766</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ButtonList.html</td><td>2010/10/05</td><td>21:09</td><td>2,135</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdge.html</td><td>2010/10/05</td><td>21:08</td><td>1,809</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-EdgeToEdgeCategory.html</td><td>2010/10/05</td><td>21:08</td><td>1,613</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Heading.html</td><td>2010/10/05</td><td>21:08</td><td>1,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Icon.html</td><td>2010/10/05</td><td>21:09</td><td>2,588</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconMulti.html</td><td>2010/10/05</td><td>21:08</td><td>1,863</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingle.html</td><td>2010/10/05</td><td>21:09</td><td>1,814</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-IconSingleBelow.html</td><td>2010/10/05</td><td>21:08</td><td>1,815</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-ResultList.html</td><td>2010/10/05</td><td>21:08</td><td>2,708</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRect.html</td><td>2010/10/05</td><td>21:08</td><td>1,155</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-RoundRectList.html</td><td>2010/10/05</td><td>21:08</td><td>2,136</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Settings.html</td><td>2010/10/05</td><td>21:09</td><td>5,666</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-Switch.html</td><td>2010/10/05</td><td>21:09</td><td>998</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-TabContainer.html</td><td>2010/10/05</td><td>21:09</td><td>5,262</td><td>mobile/tests</td></tr>
+<tr><td>test_iPhone-VariableHeightList.html</td><td>2010/10/05</td><td>21:09</td><td>3,550</td><td>mobile/tests</td></tr>
+<tr><td>test_progress-indicator.html</td><td>2010/10/05</td><td>21:08</td><td>3,124</td><td>mobile/tests</td></tr>
+<tr><td>test_transition-to-dynamic-view.html</td><td>2010/10/05</td><td>21:08</td><td>2,525</td><td>mobile/tests</td></tr>
+<tr><td>view-sample.html</td><td>2010/05/06</td><td>20:30</td><td>1,724</td><td>mobile/tests</td></tr>
+<tr><td>view1.html</td><td>2010/05/06</td><td>20:28</td><td>378</td><td>mobile/tests</td></tr>
+<tr><td>view1.json</td><td>2010/05/28</td><td>00:30</td><td>371</td><td>mobile/tests</td></tr>
+<tr><td>view2.html</td><td>2010/05/06</td><td>21:20</td><td>619</td><td>mobile/tests</td></tr>
+<tr><td>view2.json</td><td>2010/05/28</td><td>00:30</td><td>737</td><td>mobile/tests</td></tr>
+<tr><td>view3.html</td><td>2010/10/05</td><td>21:09</td><td>963</td><td>mobile/tests</td></tr>
+<tr><td>view3.json</td><td>2010/10/05</td><td>21:09</td><td>1,054</td><td>mobile/tests</td></tr>
+<tr><td>widget-bg.png</td><td>2010/03/23</td><td>13:03</td><td>26,234</td><td>mobile/tests/images</td></tr>
+			</table>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.html
new file mode 100644
index 0000000..82097c2
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-ah-af.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>ScrollableView-v-ah-af</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.ScrollableView");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+		</script>
+	</head>
+	<body>
+		<h1 dojoType="dojox.mobile.Heading" fixed="top">Application Header Bar</h1>
+		<div id="foo" dojoType="dojox.mobile.ScrollableView" selected="true">
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+			<div dojoType="dojox.mobile.RoundRect">
+				scrollDir: vertical<br>
+				header: application-header<br>
+				footer: application-footer<br>
+			</div>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 1
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 2
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 3
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 4
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 5
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 6
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 7
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 8
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 9
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 10
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 11
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 12
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 13
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 14
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 15
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 16
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 17
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 18
+				</li>
+			</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-vh-af.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html
new file mode 100644
index 0000000..6e3d9e9
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-af.html
@@ -0,0 +1,140 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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">
+		<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.ScrollableView");
+			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.ScrollableView" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+			<div dojoType="dojox.mobile.RoundRect">
+				scrollDir: vertical<br>
+				header: view-header<br>
+				footer: application-footer<br>
+			</div>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 1
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 2
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 3
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 4
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 5
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 6
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 7
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 8
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 9
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 10
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 11
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 12
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 13
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 14
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 15
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 16
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 17
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 18
+				</li>
+			</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-vf.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html
new file mode 100644
index 0000000..efadd99
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh-vf.html
@@ -0,0 +1,141 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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">
+		<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.ScrollableView");
+			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.ScrollableView" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+			<div dojoType="dojox.mobile.RoundRect">
+				scrollDir: vertical<br>
+				header: view-header<br>
+				footer: view-footer<br>
+			</div>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 1
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 2
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 3
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 4
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 5
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 6
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 7
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 8
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 9
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 10
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 11
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 12
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 13
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 14
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 15
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 16
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 17
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 18
+				</li>
+			</ul>
+			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">View Footer Bar</h1>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.ScrollableView">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+					Sarah Connor Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<font color="red">$14.50 (50%)</font> In Stock<br>
+					# (531)
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+					Martin Parker Hardcover<br>
+					<font color="red">$14.00 (60%)</font> In Stock<br>
+					# (173)
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+					Steven Young Hardcover<br>
+					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
+					Eligible for FREE Super Saver Shipping<br>
+					<font color="red">$9.50 (62%)</font> In Stock<br>
+					# (1199)
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+					Marco Rodriguez Hardcover<br>
+					<font color="blue">Not Available</font>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+					Melissa Morgan Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<font color="red">$12.00 (60%)</font> In Stock<br>
+					# (1847)
+				</li>
+			</ul>
+			<h1 dojoType="dojox.mobile.Heading" fixed="bottom" style="border-bottom:none;">Another View Footer Bar</h1>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.html
new file mode 100644
index 0000000..86984cc
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v-vh.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>ScrollableView-v-vh</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.ScrollableView");
+			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.ScrollableView" selected="true">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top">View Header Bar</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+			<div dojoType="dojox.mobile.RoundRect">
+				scrollDir: vertical<br>
+				header: view-header<br>
+				footer: none<br>
+			</div>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 1
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 2
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 3
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 4
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 5
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 6
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 7
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 8
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 9
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 10
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 11
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 12
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 13
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 14
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 15
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 16
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 17
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 18
+				</li>
+			</ul>
+		</div>
+
+		<div id="bar" dojoType="dojox.mobile.ScrollableView">
+			<h1 dojoType="dojox.mobile.Heading" fixed="top" back="Home" moveTo="foo">Search Result</h1>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					1. <a href="#" class="lnk">Dojo: Traditional Karate-do Spirit</a><br>
+					Sarah Connor Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<font color="red">$14.50 (50%)</font> In Stock<br>
+					# (531)
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					2. <a href="#" class="lnk">Japanese Martial Arts Dojo</a><br>
+					Martin Parker Hardcover<br>
+					<font color="red">$14.00 (60%)</font> In Stock<br>
+					# (173)
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					3. <a href="#" class="lnk">Total Solar Eclipse</a><br>
+					Steven Young Hardcover<br>
+					Get it by Mar. 2 if you order in the next <font color="green"><b>16 hours</b></font><br>
+					Eligible for FREE Super Saver Shipping<br>
+					<font color="red">$9.50 (62%)</font> In Stock<br>
+					# (1199)
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					4. <a href="#" class="lnk">The History of Java Coffee</a><br>
+					Marco Rodriguez Hardcover<br>
+					<font color="blue">Not Available</font>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size:10px">
+					5. <a href="#" class="lnk">The Principles of Spider's Web</a><br>
+					Melissa Morgan Hardcover<br>
+					Eligible for FREE Super Saver Shipping<br>
+					<font color="red">$12.00 (60%)</font> In Stock<br>
+					# (1847)
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-ScrollableView-v.html b/dojox/mobile/tests/test_iPhone-ScrollableView-v.html
new file mode 100644
index 0000000..32cb93a
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-ScrollableView-v.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 name="viewport" content="width=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">
+		<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.ScrollableView");
+			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.ScrollableView" selected="true">
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+
+			<div dojoType="dojox.mobile.RoundRect">
+				scrollDir: vertical<br>
+				header: none<br>
+				footer: none<br>
+			</div>
+
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 1
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 2
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 3
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 4
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 5
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 6
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 7
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 8
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 9
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="bar" transition="slide">
+					Slide 10
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="bar" transition="flip">
+					Flip 11
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="bar" transition="fade">
+					Fade 12
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="bar" transition="slide">
+					Slide 13
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="bar" transition="flip">
+					Flip 14
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="bar" transition="fade">
+					Fade 15
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-7.png" moveTo="bar" transition="slide">
+					Slide 16
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="bar" transition="flip">
+					Flip 17
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="bar" transition="fade">
+					Fade 18
+				</li>
+			</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>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-Settings.html b/dojox/mobile/tests/test_iPhone-Settings.html
index 2c53df6..0f7545f 100644
--- a/dojox/mobile/tests/test_iPhone-Settings.html
+++ b/dojox/mobile/tests/test_iPhone-Settings.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
@@ -18,54 +18,54 @@
 	<body>
 		<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">
+			<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" iconPos="0,29,29,29" rightText="mac" href="test_iPhone-Icon.html">
+				<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" iconPos="0,58,29,29" rightText="AcmePhone" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" 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">
+			<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" iconPos="0,116,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="general">
 					Brightness
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" 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">
+			<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" iconPos="29,58,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-8.png" moveTo="general">
 					Mail, Contacts, Calendars
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,87,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-9.png" moveTo="general">
 					Phone
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="29,116,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-10.png" moveTo="general">
 					Safari
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="general">
 					SMS/MMS
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="general">
 					iPod
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="general">
 					Photos
 				</li>
-				<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="general">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="general">
 					Store
 				</li>
 			</ul>
diff --git a/dojox/mobile/tests/test_iPhone-Switch.html b/dojox/mobile/tests/test_iPhone-Switch.html
index df4a2ef..0e41a0d 100644
--- a/dojox/mobile/tests/test_iPhone-Switch.html
+++ b/dojox/mobile/tests/test_iPhone-Switch.html
@@ -1,12 +1,12 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
 
-		<script type="text/javascript" src="../../../dojo/dojo.js"></script>
+		<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.
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html
new file mode 100644
index 0000000..26d8f52
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped-scroll.html
@@ -0,0 +1,185 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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 -->
+
+		<style>
+			html,body{
+				height: 100%;
+				overflow: hidden;
+			}
+			#list1 li{
+				border-style: solid;
+				border-width: 1px 0px 1px 0px;
+				border-top-color: #BABABC;
+				border-bottom-color: #89898C;
+				background-color: #ACACAF;
+				line-height: 0px;
+			}
+			#list1 li table{
+				line-height: normal;
+			}
+			#list1 li:nth-child(even){
+				background-color: #97979B;
+			}
+			.lnk {
+				font-size: 17px;
+				color: #0B5199;
+				text-decoration: none;
+			}
+		</style>
+
+		<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true, mblAlwaysHideAddressBar: true"></script>
+
+		<script language="JavaScript" type="text/javascript">
+			//dojo.require("dojo.parser"); // Use the lightweight parser.
+			dojo.require("dojox.mobile.parser");
+			dojo.require("dojox.mobile");
+			dojo.require("dojox.mobile.ScrollableView");
+			dojo.require("dojox.mobile.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+			dojo.requireIf(!dojo.isWebKit, "dojo.fx");
+			dojo.requireIf(!dojo.isWebKit, "dojo.fx.easing");
+		</script>
+	</head>
+	<body>
+		<div id="group1" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl" fixed="top">
+				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
+			</ul>
+
+			<div id="view1" dojoType="dojox.mobile.ScrollableView" selected="true">
+				<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list1">
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+										Sarah Connor Hardcover<br>
+										Eligible for FREE Super Saver Shipping
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+										Martin Parker Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">Total Solar Eclipse</a><br>
+										Steven Young Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">The History of Java Coffee</a><br>
+										Marco Rodriguez Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+										Melissa Morgan Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+				</ul>
+			</div>
+
+			<div id="view2" dojoType="dojox.mobile.ScrollableView">
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="hello">
+						Sounds
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="hello">
+						Brightness
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="hello">
+						Wallpaper
+					</li>
+				</ul>
+			</div>
+
+			<div id="view3" dojoType="dojox.mobile.ScrollableView">
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="hello">
+						General
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="hello">
+						Mail, Contacts, Calendars
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="hello">
+						Phone
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div dojoType="dojox.mobile.ScrollableView" id="hello">
+			<h1 dojoType="dojox.mobile.Heading">
+				Hello
+			</h1>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
+					Hello
+				</li>
+				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
+					Carrier
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
new file mode 100644
index 0000000..bcded14
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-TabBar-seg-grouped.html
@@ -0,0 +1,178 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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 -->
+
+		<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.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+	</head>
+	<body>
+		<div id="group1" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
+				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+				<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
+			</ul>
+
+			<div id="view1" dojoType="dojox.mobile.View" selected="true">
+				<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list1">
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+										Sarah Connor Hardcover<br>
+										Eligible for FREE Super Saver Shipping
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+										Martin Parker Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">Total Solar Eclipse</a><br>
+										Steven Young Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">The History of Java Coffee</a><br>
+										Marco Rodriguez Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+					<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+						<table>
+							<tbody>
+								<tr>
+									<td>
+										<img src="images/icon-1.png">
+									</td>
+									<td>
+										<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+										Melissa Morgan Hardcover<br>
+										Eligible for FREE Super Saver Shipping<br>
+									</td>
+								</tr>
+							</tbody>
+						</table>
+					</li>
+				</ul>
+			</div>
+
+			<div id="view2" dojoType="dojox.mobile.View">
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" moveTo="hello">
+						Sounds
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="hello">
+						Brightness
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" moveTo="hello">
+						Wallpaper
+					</li>
+				</ul>
+			</div>
+
+			<div id="view3" dojoType="dojox.mobile.View">
+				<ul dojoType="dojox.mobile.RoundRectList">
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="hello">
+						General
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="hello">
+						Mail, Contacts, Calendars
+					</li>
+					<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="hello">
+						Phone
+					</li>
+				</ul>
+			</div>
+		</div>
+
+		<div dojoType="dojox.mobile.View" id="hello">
+			<h1 dojoType="dojox.mobile.Heading">
+				Hello
+			</h1>
+			<ul dojoType="dojox.mobile.EdgeToEdgeList">
+				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
+					Hello
+				</li>
+				<li dojoType="dojox.mobile.ListItem" moveTo="group1">
+					Carrier
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar-seg.html b/dojox/mobile/tests/test_iPhone-TabBar-seg.html
new file mode 100644
index 0000000..09821b1
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-TabBar-seg.html
@@ -0,0 +1,162 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=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 -->
+
+		<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.TabBar");
+			dojo.requireIf(!dojo.isWebKit, "dojox.mobile.compat");
+		</script>
+	</head>
+	<body>
+		<ul dojoType="dojox.mobile.TabBar" barType="segmentedControl">
+			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-16.png" icon2="images/tab-icon-16h.png" moveTo="view1" selected="true">New</li>
+			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-15.png" icon2="images/tab-icon-15h.png" moveTo="view2">What's Hot</li>
+			<li dojoType="dojox.mobile.TabBarButton" icon1="images/tab-icon-10.png" icon2="images/tab-icon-10h.png" moveTo="view3">Genius</li>
+		</ul>
+
+		<div id="view1" dojoType="dojox.mobile.View" selected="true">
+			<ul dojoType="dojox.mobile.EdgeToEdgeList" id="list1">
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Dojo: Traditional Karate-do Spirit</a><br>
+									Sarah Connor Hardcover<br>
+									Eligible for FREE Super Saver Shipping
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Japanese Martial Arts Dojo</a><br>
+									Martin Parker Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">Total Solar Eclipse</a><br>
+									Steven Young Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The History of Java Coffee</a><br>
+									Marco Rodriguez Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+				<li class="mblVariableHeight" dojoType="dojox.mobile.ListItem" style="font-size: 10px;">
+					<table>
+						<tbody>
+							<tr>
+								<td>
+									<img src="images/icon-1.png">
+								</td>
+								<td>
+									<a class="lnk" href="#">The Principles of Spider's Web</a><br>
+									Melissa Morgan Hardcover<br>
+									Eligible for FREE Super Saver Shipping<br>
+								</td>
+							</tr>
+						</tbody>
+					</table>
+				</li>
+			</ul>
+		</div>
+
+		<div id="view2" dojoType="dojox.mobile.View">
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png">
+					Sounds
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png">
+					Brightness
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png">
+					Wallpaper
+				</li>
+			</ul>
+		</div>
+
+		<div id="view3" dojoType="dojox.mobile.View">
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png">
+					General
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png">
+					Mail, Contacts, Calendars
+				</li>
+				<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png">
+					Phone
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_iPhone-TabBar.html b/dojox/mobile/tests/test_iPhone-TabBar.html
new file mode 100644
index 0000000..ad9e212
--- /dev/null
+++ b/dojox/mobile/tests/test_iPhone-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/iphone/iphone.css" rel="stylesheet"></link>
+		<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>
+	</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/test_iPhone-TabContainer.html b/dojox/mobile/tests/test_iPhone-TabContainer.html
index 130db9d..e453c2f 100644
--- a/dojox/mobile/tests/test_iPhone-TabContainer.html
+++ b/dojox/mobile/tests/test_iPhone-TabContainer.html
@@ -1,9 +1,13 @@
 <!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, user-scalable=no"/>
+		<meta name="viewport" content="width=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</title>
+		<title>Tab Container (deprecated)</title>
 		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
 
 		<style>
@@ -34,6 +38,7 @@
 			//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>
@@ -125,27 +130,27 @@
 					</ul>
 				</div>
 				<div dojoType="dojox.mobile.TabPane" label="What's Hot">
-					<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-						<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" moveTo="hello">
+					<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" iconPos="0,29,29,29" moveTo="hello">
+						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" moveTo="hello">
 							Brightness
 						</li>
-						<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" moveTo="hello">
+						<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" iconBase="images/i-icon-all.png">
-						<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="hello">
+					<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" iconPos="0,116,29,29" moveTo="hello">
+						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="hello">
 							Mail, Contacts, Calendars
 						</li>
-						<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="hello">
+						<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="hello">
 							Phone
 						</li>
 					</ul>
diff --git a/dojox/mobile/tests/test_iPhone-VariableHeightList.html b/dojox/mobile/tests/test_iPhone-VariableHeightList.html
index 46b194c..dbcbe81 100755
--- a/dojox/mobile/tests/test_iPhone-VariableHeightList.html
+++ b/dojox/mobile/tests/test_iPhone-VariableHeightList.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_orientation-transition.html b/dojox/mobile/tests/test_orientation-transition.html
new file mode 100644
index 0000000..62f099f
--- /dev/null
+++ b/dojox/mobile/tests/test_orientation-transition.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>Transition on Orientation Change</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<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(){
+				var portrait = dijit.byId("portrait");
+				var landscape = dijit.byId("landscape");
+				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");
+					}
+				};
+				if(window.orientation != 0){
+					setTimeout(function(){
+						landscape.show();
+					}, 0);
+				}
+				if(window.onorientationchange !== undefined){
+					dojo.connect(dojo.global, "onorientationchange", onChange);
+				}else{
+					dojo.connect(dojo.global, "onresize", onChange);
+				}
+			});
+		</script>
+	</head>
+	<body>
+		<div id="portrait" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Portrait</h1>
+			<div style="text-align:center;padding-top:20px;">
+				<img src="images/a-icon-2-41x41.png">
+				<h2>View<br>for<br>portrait</h2>
+			</div>
+		</div>
+
+		<div id="landscape" dojoType="dojox.mobile.View">
+			<h1 dojoType="dojox.mobile.Heading">Landscape</h1>
+			<div dojoType="dojox.mobile.RoundRect" shadow="true" style="text-align:center;">
+				<h2>View for landscape</h2>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_progress-indicator.html b/dojox/mobile/tests/test_progress-indicator.html
index b001080..4ee1857 100755
--- a/dojox/mobile/tests/test_progress-indicator.html
+++ b/dojox/mobile/tests/test_progress-indicator.html
@@ -1,7 +1,7 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html>
 	<head>
-		<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
+		<meta name="viewport" content="width=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>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-af.html b/dojox/mobile/tests/test_scrollable-no-dojo-af.html
new file mode 100644
index 0000000..94c5783
--- /dev/null
+++ b/dojox/mobile/tests/test_scrollable-no-dojo-af.html
@@ -0,0 +1,115 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html class="mobile">
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>scrollable no-dojo with app footer</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			visibility: visible;
+		}
+		.domNode {
+			height: 100%;
+			overflow: hidden;
+		}
+		.containerNode {
+			position: absolute;
+			width: 100%;
+		}
+		#footer1 {
+			position: absolute;
+			width: 100%;
+			bottom: 0px;
+		}
+		</style>
+		<script type="text/javascript" src="../scrollable.js"></script>
+
+		<script language="JavaScript" type="text/javascript">
+		function onLoad(){
+			var scrollable = new dojox.mobile.scrollable();
+			scrollable.init({
+				domNode: document.getElementById("outer"),
+				containerNode: document.getElementById("inner"),
+				fixedFooterHeight: document.getElementById("footer1").offsetHeight
+			});
+		}
+		</script>
+	</head>
+	<body onload="onLoad()">
+		<div id="outer" class="domNode">
+			<div id="inner" class="containerNode">
+				<h2 class="mblRoundRectCategory">Transition Effects</h2>
+				<ul class="mblRoundRectList">
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-1.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Slide</div>
+						</a>
+					</li>
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-2.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Flip</div>
+						</a>
+					</li>
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-3.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Fade</div>
+						</a>
+					</li>
+				</ul>
+
+				<div class="mblRoundRect">
+					<ol>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+					<ol>
+				</div>
+			</div>
+		</div>
+
+		<div id="footer1" class="mblTabBar">Fixed Footer</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html b/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
new file mode 100644
index 0000000..239c89b
--- /dev/null
+++ b/dojox/mobile/tests/test_scrollable-no-dojo-ah-af.html
@@ -0,0 +1,122 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html class="mobile">
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>scrollable no-dojo with app header/footer</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			visibility: visible;
+		}
+		.domNode {
+			height: 100%;
+			overflow: hidden;
+		}
+		.containerNode {
+			position: absolute;
+			width: 100%;
+		}
+		#header1 {
+			position: absolute;
+			width: 100%;
+		}
+		#footer1 {
+			position: absolute;
+			width: 100%;
+			bottom: 0px;
+		}
+		</style>
+		<script type="text/javascript" src="../scrollable.js"></script>
+
+		<script language="JavaScript" type="text/javascript">
+		function onLoad(){
+			var scrollable = new dojox.mobile.scrollable();
+			scrollable.init({
+				domNode: document.getElementById("outer"),
+				containerNode: document.getElementById("inner"),
+				fixedHeaderHeight: document.getElementById("header1").offsetHeight,
+				fixedFooterHeight: document.getElementById("footer1").offsetHeight
+			});
+		}
+		</script>
+	</head>
+	<body onload="onLoad()">
+		<h1 id="header1" class="mblHeading">Fixed Header (No-Dojo)</h1>
+
+		<div id="outer" class="domNode">
+			<div id="inner" class="containerNode">
+				<h2 class="mblRoundRectCategory">Transition Effects</h2>
+				<ul class="mblRoundRectList">
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-1.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Slide</div>
+						</a>
+					</li>
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-2.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Flip</div>
+						</a>
+					</li>
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-3.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Fade</div>
+						</a>
+					</li>
+				</ul>
+
+				<div class="mblRoundRect">
+					<ol>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+					<ol>
+				</div>
+			</div>
+		</div>
+
+		<div id="footer1" class="mblTabBar">Fixed Footer</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo-ah.html b/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
new file mode 100644
index 0000000..4d43d8e
--- /dev/null
+++ b/dojox/mobile/tests/test_scrollable-no-dojo-ah.html
@@ -0,0 +1,114 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html class="mobile">
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>scrollable no-dojo with app header</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			visibility: visible;
+		}
+		.domNode {
+			height: 100%;
+			overflow: hidden;
+		}
+		.containerNode {
+			position: absolute;
+			width: 100%;
+		}
+		#header1 {
+			position: absolute;
+			width: 100%;
+		}
+		</style>
+		<script type="text/javascript" src="../scrollable.js"></script>
+
+		<script language="JavaScript" type="text/javascript">
+		function onLoad(){
+			var scrollable = new dojox.mobile.scrollable();
+			scrollable.init({
+				domNode: document.getElementById("outer"),
+				containerNode: document.getElementById("inner"),
+				fixedHeaderHeight: document.getElementById("header1").offsetHeight
+			});
+		}
+		</script>
+	</head>
+	<body onload="onLoad()">
+		<h1 id="header1" class="mblHeading">Fixed Header (No-Dojo)</h1>
+
+		<div id="outer" class="domNode">
+			<div id="inner" class="containerNode">
+				<h2 class="mblRoundRectCategory">Transition Effects</h2>
+				<ul class="mblRoundRectList">
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-1.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Slide</div>
+						</a>
+					</li>
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-2.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Flip</div>
+						</a>
+					</li>
+					<li class="mblListItem">
+						<img class="mblListItemIcon" src="images/i-icon-3.png">
+						<a class="mblListItemAnchor">
+							<div class="mblListItemTextBox">Fade</div>
+						</a>
+					</li>
+				</ul>
+
+				<div class="mblRoundRect">
+					<ol>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+						<li>Item</li>
+					<ol>
+				</div>
+			</div>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/test_scrollable-no-dojo.html b/dojox/mobile/tests/test_scrollable-no-dojo.html
new file mode 100644
index 0000000..203cbbb
--- /dev/null
+++ b/dojox/mobile/tests/test_scrollable-no-dojo.html
@@ -0,0 +1,91 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+	<head>
+		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"/>
+		<meta name="apple-mobile-web-app-capable" content="yes" />
+		<title>scrollable no-dojo</title>
+		<style>
+		html, body{
+			height: 100%;
+			overflow: hidden;
+			width: 100%;
+			margin: 0px;
+			padding: 0px;
+		}
+		.domNode {
+			height: 100%;
+			overflow: hidden;
+		}
+		#header1 {
+			position: absolute;
+			margin: 0px;
+			width: 100%;
+			background-color: cyan;
+			z-index: 1;
+			font-size: 20px;
+		}
+			
+		</style>
+		<script type="text/javascript" src="../scrollable.js"></script>
+
+		<script language="JavaScript" type="text/javascript">
+		function onLoad(){
+			var scrollable = new dojox.mobile.scrollable();
+			scrollable.init({
+				domNode: document.getElementById("outer"),
+				containerNode: document.getElementById("inner"),
+				fixedHeaderHeight: document.getElementById("header1").offsetHeight
+			});
+		}
+		</script>
+	</head>
+	<body onload="onLoad()">
+		<h1 id="header1">Fixed Header (No-Dojo)</h1>
+		<div id="outer" class="domNode">
+			<div id="inner" class="containerNode" style="position:absolute;width:100%">
+				<ol>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+					<li>Item</li>
+				<ol>
+			</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
new file mode 100644
index 0000000..5cbb792
--- /dev/null
+++ b/dojox/mobile/tests/test_transition-to-dynamic-view.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>Transition To A Dynamic View</title>
+		<link href="../themes/iphone/iphone.css" rel="stylesheet"></link>
+		<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();
+
+					var categ1 = new dojox.mobile.RoundRectCategory({
+						label: "Documents"
+					});
+					view1.addChild(categ1);
+
+					var list1 = new dojox.mobile.RoundRectList();
+					view1.addChild(list1);
+
+					for(var i = 0; i < items.length; i++){
+						var item1 = new dojox.mobile.ListItem({
+							icon: "images/i-icon-"+(i+1)+".png",
+							label: items[i].title,
+							href: items[i].href
+						});
+						list1.addChild(item1);
+					}
+					var id = view1.id;
+					return dojo.hash ? "#" + id : id;
+				}
+			});
+		</script>
+	</head>
+	<body>
+		<div id="home" dojoType="dojox.mobile.View" selected="true">
+			<h1 dojoType="dojox.mobile.Heading">Animations</h1>
+			<h2 dojoType="dojox.mobile.RoundRectCategory">Transition Effects</h2>
+			<ul dojoType="dojox.mobile.RoundRectList">
+				<li dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-1.png" url="items.json" transition="slide">
+					Slide
+				</li>
+				<li dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-2.png" url="items.json" transition="flip">
+					Flip
+				</li>
+				<li dojoType="dojox.mobile.ListItemEx" icon="images/i-icon-3.png" url="items.json" transition="fade">
+					Fade
+				</li>
+			</ul>
+		</div>
+	</body>
+</html>
diff --git a/dojox/mobile/tests/view3.html b/dojox/mobile/tests/view3.html
index f83c4bc..6a0207a 100644
--- a/dojox/mobile/tests/view3.html
+++ b/dojox/mobile/tests/view3.html
@@ -1,16 +1,16 @@
 <div id="settings" dojoType="dojox.mobile.View">
 	<h1 dojoType="dojox.mobile.Heading" label="view3.html"></h1>
-	<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,0,29,29" label="Airplane Mode">
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-1.png" label="Airplane Mode">
 			<div class="mblItemSwitch" dojoType="dojox.mobile.Switch"></div>
 		</li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,29,29,29" rightText="mac" href="test_iPhone-Icon.html" label="Wi-Fi"></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,58,29,29" rightText="AcmePhone" moveTo="foo" label="Carrier"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-2.png" rightText="mac" href="test_iPhone-Icon.html" label="Wi-Fi"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-3.png" rightText="AcmePhone" moveTo="foo" label="Carrier"></li>
 	</ul>
 
-	<ul dojoType="dojox.mobile.RoundRectList" iconBase="images/i-icon-all.png">
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,87,29,29" moveTo="foo" label="Sounds"></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="0,116,29,29" moveTo="foo" label="Brightness"></li>
-		<li dojoType="dojox.mobile.ListItem" iconPos="29,0,29,29" moveTo="foo" label="Wallpaper"></li>
+	<ul dojoType="dojox.mobile.RoundRectList">
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-4.png" moveTo="foo" label="Sounds"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-5.png" moveTo="foo" label="Brightness"></li>
+		<li dojoType="dojox.mobile.ListItem" icon="images/i-icon-6.png" moveTo="foo" label="Wallpaper"></li>
 	</ul>
 </div>
diff --git a/dojox/mobile/tests/view3.json b/dojox/mobile/tests/view3.json
index b37f15e..b734e31 100644
--- a/dojox/mobile/tests/view3.json
+++ b/dojox/mobile/tests/view3.json
@@ -5,36 +5,34 @@
       "@label": "view3.json"
     },
     "dojox.mobile.RoundRectList": [{
-      "@iconBase": "images/i-icon-all.png",
       "dojox.mobile.ListItem": [{
-        "@iconPos": "0,0,29,29",
+        "@icon": "images/i-icon-1.png",
         "@label": "Airplane Mode",
         "dojox.mobile.Switch": {
           "@class": "mblItemSwitch"
         }
       }, {
         "@href": "test_iPhone-Icon.html",
-        "@iconPos": "0,29,29,29",
+        "@icon": "images/i-icon-2.png",
         "@label": "Wi-Fi",
         "@rightText": "mac"
       }, {
-        "@iconPos": "0,58,29,29",
+        "@icon": "images/i-icon-3.png",
         "@label": "Carrier",
         "@moveTo": "foo",
         "@rightText": "AcmePhone"
       }]
     }, {
-      "@iconBase": "images/i-icon-all.png",
       "dojox.mobile.ListItem": [{
-        "@iconPos": "0,87,29,29",
+        "@icon": "images/i-icon-4.png",
         "@label": "Sounds",
         "@moveTo": "foo"
       }, {
-        "@iconPos": "0,116,29,29",
+        "@icon": "images/i-icon-5.png",
         "@label": "Brightness",
         "@moveTo": "foo"
       }, {
-        "@iconPos": "29,0,29,29",
+        "@icon": "images/i-icon-6.png",
         "@label": "Wallpaper",
         "@moveTo": "foo"
       }]
diff --git a/dojox/mobile/themes/FixedSplitter.css b/dojox/mobile/themes/FixedSplitter.css
new file mode 100644
index 0000000..6788969
--- /dev/null
+++ b/dojox/mobile/themes/FixedSplitter.css
@@ -0,0 +1,22 @@
+.mblFixedSpliter {
+	width: 100%;
+	height: 100%;
+}
+
+.mblFixedSplitterPane {
+	position: absolute;
+	overflow-x: hidden;
+	overflow-y: auto;
+}
+
+.mblFixedSplitterPaneH {
+	position: absolute;
+	height: 100%;
+	top: 0px;
+}
+
+.mblFixedSplitterPaneV {
+	position: absolute;
+	width: 100%;
+	left: 0px;
+}
diff --git a/dojox/mobile/themes/android/android-app-compat.css b/dojox/mobile/themes/android/android-app-compat.css
new file mode 100755
index 0000000..dc0a814
--- /dev/null
+++ b/dojox/mobile/themes/android/android-app-compat.css
@@ -0,0 +1,24 @@
+/* mbl.widget.Heading */
+ at import url("iphone-compat.css");
+
+.alertTitle {
+	background-image: url(compat/heading-bg.png);
+}
+
+.mblImageThumbView .mblThumb {
+	-moz-transition: all 0.5s ease-in-out;
+	-o-transition: all 0.5s ease-in-out;
+}
+
+.mblImageThumbView .mblThumb:hover {
+	-moz-transform: scale(1.2);
+	-moz-transition: all 0.3s ease-in-out;
+	-o-transform: scale(1.2);
+	-o-transition: all 0.3s ease-in-out;
+}
+.mblImageThumbView .mblThumbInner .mblThumbMask .mblThumbSrc {
+  -moz-background-size: 100% 100%;
+  -moz-border-radius: 5px;
+  -o-background-size: 100% 100%;
+  -o-border-radius: 5px;
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/android/android-app.css b/dojox/mobile/themes/android/android-app.css
new file mode 100644
index 0000000..77fc6cd
--- /dev/null
+++ b/dojox/mobile/themes/android/android-app.css
@@ -0,0 +1,349 @@
+ at import url("android.css");
+
+.alertDialog {
+	width: 100%;
+	padding-left: 2px;
+	padding-right: 2px;
+	z-index: 1000;
+}
+
+.alertDialogBody {
+	border: 1px solid #ADAAAD;
+	-webkit-border-radius: 10px;
+	-moz-border-radius: 10px;
+	background-color: white;
+	margin-left: 2px;
+	margin-right: 4px;
+}
+
+.alertTitle {
+	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;
+	text-align: center;
+}
+
+.alertText {
+	text-align: center;
+}
+
+.alertBtns {
+	padding: 5px;
+	text-align: center;
+}
+
+.alertBtns .mblButton {
+	width: 100%;
+	margin-top: 5px;
+}
+
+.alertDialog.out {
+	position: absolute;
+}
+
+.alertDialog.in {
+	position: absolute;
+}
+
+.slidev.out {
+	-webkit-animation-duration: .4s;
+	-webkit-animation-name: slideOut;
+	-webkit-animation-timing-function: linear;
+	-webkit-transform: translateY(-100%);
+}
+.slidev.in {
+	-webkit-animation-duration: .4s;
+	-webkit-animation-name: slideIn;
+	-webkit-animation-timing-function: linear;
+	-webkit-transform: translateY(0px);
+}
+.slidev.out.reverse {
+	-webkit-animation-name: slideOutReverse;
+}
+.slidev.in.reverse {
+	-webkit-animation-name: slideInReverse;
+}
+
+.dialogUnderlayWrapper {
+	position: absolute;
+	left: 0;
+	top: 0;
+	z-index: 998;
+	background: transparent !important;
+	visibility: visible;
+	height: 100%;
+	width: 100%;
+}
+
+.dialogUnderlay {
+	background-color: #eee;
+	opacity: 0.5;
+	width: 100%;
+	height: 100%;
+}
+
+.list .row {
+	padding: 10px;
+	border-bottom: 1px solid #444;
+	position: relative;
+	background-color: black;
+	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: #444;
+}
+
+.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;
+}
+
+ at -webkit-keyframes collapse-vert {
+	from {
+		height: 100%;
+		padding: 10px;
+	}
+	to {
+		height: 0px;
+		padding: 0px;
+	}
+}
+
+.listSelector {
+	position: absolute;
+	-webkit-border-radius: 10px;
+	-moz-border-radius: 10px;
+	border: 1px solid #666;
+	background-color: #ccc;
+	color: #333;
+	z-index: 1000;
+}
+.listSelectorRow {
+	padding: 10px;
+	border-bottom: 1px solid #666;
+	white-space: nowrap;
+}
+.listSelectorRow-selected {
+	background-color: #666;
+	color: #ccc;
+}
+
+.listSelectorRow.last {
+ 	border-bottom: none;
+}
+
+.mblImageView, .mblImageView canvas {
+	width: 100%;
+	height: 100%;
+}
+
+.mblPillar {
+	display: none;
+}
+
+/* Form Input Styles */
+
+input {
+	-webkit-text-size-adjust: 140%;
+}
+
+
+/* ImageThumbView styles */
+.mblImageThumbView {
+	position: relative;
+	-webkit-transition-property: height;
+	-webkit-transition-duration: 0.8s;
+	-webkit-transition-delay: 0;
+}
+
+.mblImageThumbView .mblThumb {
+	width: 100px;
+	min-height: 100px;
+	display: inline-block;
+	z-index: 2;
+	position: absolute;
+}
+
+.mblImageThumbView.animated .mblThumb {
+	-webkit-transition-property: -webkit-transform, opacity;
+	-webkit-transition-duration: 1.3s, 1s;
+	-webkit-transition-delay: 0, 0;
+}
+
+.mblImageThumbView .mblThumb.hidden {
+	z-index: 1;
+	opacity: 0;
+}
+.mblImageThumbView .mblThumbInner {
+	width: 102px;
+	height: 102px;
+	position: relative;
+}
+
+.mblImageThumbView .mblThumbOverlay {
+	width: 102px;
+	height: 102px;
+	background: url(images/thumb-overlay.png) center top no-repeat;
+	position: absolute;
+	z-index: 20;
+	overflow: hidden;
+}
+.mblImageThumbView .mblThumb.selected .mblThumbOverlay {
+	background-position: center bottom;
+}
+.mblImageThumbView .mblThumbInner .mblThumbMask {
+	width: 90px;
+	height: 90px;
+	overflow: hidden;
+	padding-left: 6px;
+	padding-top: 5px;
+	z-index: 10;
+}
+.mblImageThumbView .mblThumbInner .mblThumbMask img {
+	left: 0px;
+	top: 0px;
+	width: 90px;
+	height: 90px;
+}
+
+.mblImageThumbView .mblThumbInner .mblThumbMask .mblThumbSrc {
+	left: 6px;
+	top: 5px;
+	background-position: center center;
+	background-repeat: no-repeat;
+	overflow: hidden;
+	position: absolute;
+	-webkit-background-size: 100% 100%;
+	-webkit-border-radius: 5px;
+	width: 90px;
+	height: 90px;
+	z-index: 5;
+}
+
+.mblImageThumbView .mblThumbMask div {
+	left: 0px;
+	top: 0px;
+	width: 90px;
+	height: 90px;
+	background-repeat: no-repeat;
+}
+.mblImageThumbView .mblThumb:hover,
+.mblImageThumbView .mblThumb.selected {
+	-webkit-transform: scale(1.2);
+	transform: scale(1.2);
+}
+
+/* Large Images */
+.mblImageThumbView.large .mblThumb {
+	width: 150px;
+	min-height: 150px;
+}
+
+.mblImageThumbView.large .mblThumbInner{
+	width: 152px;
+	height: 152px;
+}
+
+.mblImageThumbView.large .mblThumbOverlay {
+	background: url(images/thumb-overlay-large.png) center top no-repeat;
+	width: 152px;
+	height: 152px;
+}
+.mblImageThumbView.large .mblThumbInner .mblThumbMask,
+.mblImageThumbView.large .mblThumbInner .mblThumbMask img,
+.mblImageThumbView.large .mblThumbInner .mblThumbMask .mblThumbSrc,
+.mblImageThumbView.large .mblThumbMask div {
+	width: 133px;
+	height: 133px;
+}
+
+.mblImageThumbView.large .mblThumbInner .mblThumbMask .mblThumbSrc {
+	left: 9px;
+	top: 7px;
+}
+/* Small Images */
+.mblImageThumbView.small .mblThumb {
+	width: 75px;
+	min-height: 75px;
+}
+
+.mblImageThumbView.small .mblThumbInner{
+	width: 77px;
+	height: 77px;
+}
+
+.mblImageThumbView.small .mblThumbOverlay {
+	background: url(images/thumb-overlay-small.png) center top no-repeat;
+	width: 77px;
+	height: 77px;
+}
+.mblImageThumbView.small .mblThumbInner .mblThumbMask,
+.mblImageThumbView.small .mblThumbInner .mblThumbMask img,
+.mblImageThumbView.small .mblThumbInner .mblThumbMask .mblThumbSrc,
+.mblImageThumbView.small .mblThumbMask div {
+	width: 70px;
+	height: 70px;
+}
+
+.mblImageThumbView.small .mblThumbInner .mblThumbMask .mblThumbSrc {
+	left: 4px;
+	top: 3px;
+}
+
+.mblImageThumbView .mblThumbLabel {
+	font-size: smaller;
+	overflow: hidden;
+	white-space: nowrap;
+	text-align: center;
+}
+
+/* Back Button */
+.mblNativeBack .mblArrowButtonHead,
+.mblNativeBack .mblArrowButtonBody,
+.mblNativeBack .mblArrowButtonNeck {
+	display: none;
+}
+
diff --git a/dojox/mobile/themes/android/android-compat.css b/dojox/mobile/themes/android/android-compat.css
index a5a056c..a5552b2 100755
--- a/dojox/mobile/themes/android/android-compat.css
+++ b/dojox/mobile/themes/android/android-compat.css
@@ -10,9 +10,11 @@
 	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);
 }
 
@@ -86,16 +88,21 @@
 	height: 0;
 }
 
-li.mblListItem .mblArrow {
+.mblListItem .mblArrow {
 	border-style: none;
 	width: 9px;
 	height: 13px;
 	background-image: url(compat/gray-arrow.png);
 }
-li.mblItemSelected .mblArrow {
+.mblItemSelected .mblArrow {
 	background-image: url(compat/white-arrow.png);
 }
 
+/* dojox.mobile.TabBarButton */
+.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
+	left: auto;
+}
+
 /* Switch */
 .mblSwitchInner {
 	width: 100px;
@@ -218,7 +225,6 @@ li.mblItemSelected .mblArrow {
 
 /* Tab Container */
 .mblTabPanelHeader {
-	background-image: url(compat/heading-bg.png);
 }
 .mblTabButton {
 	background-image: url(compat/tab-button-bg.png);
diff --git a/dojox/mobile/themes/android/android.css b/dojox/mobile/themes/android/android.css
index 631129e..59620b0 100755
--- a/dojox/mobile/themes/android/android.css
+++ b/dojox/mobile/themes/android/android.css
@@ -13,7 +13,6 @@ html.mobile, .mobile body {
 	background-color: black;
 	font-family: Helvetica;
 	font-size: 17px;
-	min-height: 440px;
 }
 
 /* dojox.mobile.View */
@@ -26,7 +25,6 @@ html.mobile, .mobile body {
 }
 
 .mblView.out {
-	position: absolute;
 }
 
 .mblView.in {
@@ -133,7 +131,13 @@ html.mobile, .mobile body {
 }
 
 /* Heading Arrow Button */
-.dj_webkit .mblArrowButtonHead {
+.mblArrowButton {
+	position: relative;
+	float: left;
+	height: 25px;
+	margin-right: 6px;
+}
+.mblArrowButtonHead {
 	position: absolute;
 	top: 5px;
 	left: 9px;
@@ -164,10 +168,7 @@ html.mobile, .mobile body {
 	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;
 }
-.dj_ie .mblArrowButtonBody, .dj_ff3 .mblArrowButtonBody {
-	padding: 0px 10px 0px 10px;
-}
-.dj_webkit .mblArrowButtonNeck {
+.mblArrowButtonNeck {
 	position: absolute;
 	top: 0px;
 	left: 19px;
@@ -186,6 +187,88 @@ html.mobile, .mobile body {
 	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;
@@ -258,10 +341,11 @@ html.mobile, .mobile body {
 	position: relative;
 	color: white;
 	background-color: black;
+	padding-left: 7px;
 }
 .mblListItemIcon {
 	position: absolute;
-	margin: 18px 0px 0px 7px;
+	top: 18px;
 }
 .mblListItem.mblVariableHeight {
 	line-height: normal;
@@ -272,10 +356,10 @@ html.mobile, .mobile body {
 	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));
 }
-li .mblListItemTextBox {
+.mblListItemTextBox {
 	padding-right: 28px;
 }
-li .mblListItemTextBoxSelected {
+.mblListItemTextBoxSelected {
 	background-color: #048BF4;
 }
 .mblRoundRectList .mblListItem:first-child {
@@ -622,6 +706,7 @@ table.mblClose {
 .mblTabButton {
 	position: relative;
 	float: left;
+	list-style-type: none;
 	width: 78px;
 	text-align: center;
 	height: 61px;
@@ -736,3 +821,20 @@ table.mblClose {
 .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));
+}
diff --git a/dojox/mobile/themes/android/compat/heading-bg.png b/dojox/mobile/themes/android/compat/heading-bg.png
new file mode 100644
index 0000000..8c3999b
Binary files /dev/null and b/dojox/mobile/themes/android/compat/heading-bg.png differ
diff --git a/dojox/mobile/themes/android/images/thumb-overlay-large.png b/dojox/mobile/themes/android/images/thumb-overlay-large.png
new file mode 100644
index 0000000..dfac370
Binary files /dev/null and b/dojox/mobile/themes/android/images/thumb-overlay-large.png differ
diff --git a/dojox/mobile/themes/android/images/thumb-overlay-small.png b/dojox/mobile/themes/android/images/thumb-overlay-small.png
new file mode 100644
index 0000000..b6836d9
Binary files /dev/null and b/dojox/mobile/themes/android/images/thumb-overlay-small.png differ
diff --git a/dojox/mobile/themes/android/images/thumb-overlay.png b/dojox/mobile/themes/android/images/thumb-overlay.png
new file mode 100755
index 0000000..b16efec
Binary files /dev/null and b/dojox/mobile/themes/android/images/thumb-overlay.png differ
diff --git a/dojox/mobile/themes/domButtons-compat.css b/dojox/mobile/themes/domButtons-compat.css
new file mode 100644
index 0000000..7eb7954
--- /dev/null
+++ b/dojox/mobile/themes/domButtons-compat.css
@@ -0,0 +1,6 @@
+/* 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
new file mode 100644
index 0000000..54469e6
--- /dev/null
+++ b/dojox/mobile/themes/domButtons.css
@@ -0,0 +1,6 @@
+/* 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
new file mode 100644
index 0000000..28d561c
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/Common-compat.css
@@ -0,0 +1,3 @@
+.mblTabPanelHeader .mblDomButton {
+	background-position: 8px;
+}
diff --git a/dojox/mobile/themes/domButtons/Common.css b/dojox/mobile/themes/domButtons/Common.css
new file mode 100644
index 0000000..623b7ff
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/Common.css
@@ -0,0 +1,6 @@
+.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
new file mode 100644
index 0000000..dfa3bb6
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonDownArrow-compat.css
@@ -0,0 +1,8 @@
+/* === 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
new file mode 100644
index 0000000..0dd359d
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonDownArrow.css
@@ -0,0 +1,21 @@
+/* === 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
new file mode 100644
index 0000000..dc9c61c
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonPlus-compat.css
@@ -0,0 +1,8 @@
+/* === 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
new file mode 100644
index 0000000..34e79a6
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonPlus.css
@@ -0,0 +1,18 @@
+/* === 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
new file mode 100644
index 0000000..f0f51dc
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonSearch-compat.css
@@ -0,0 +1,12 @@
+/* === 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
new file mode 100644
index 0000000..477f569
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonSearch.css
@@ -0,0 +1,33 @@
+/* === 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
new file mode 100644
index 0000000..6cc860a
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonUpArrow-compat.css
@@ -0,0 +1,8 @@
+/* === 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
new file mode 100644
index 0000000..b6298e4
--- /dev/null
+++ b/dojox/mobile/themes/domButtons/DomButtonUpArrow.css
@@ -0,0 +1,21 @@
+/* === 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/downarrow-button.png b/dojox/mobile/themes/domButtons/compat/downarrow-button.png
new file mode 100755
index 0000000..add30b8
Binary files /dev/null and b/dojox/mobile/themes/domButtons/compat/downarrow-button.png differ
diff --git a/dojox/mobile/themes/domButtons/compat/plus-button.png b/dojox/mobile/themes/domButtons/compat/plus-button.png
new file mode 100755
index 0000000..4b2a010
Binary files /dev/null and b/dojox/mobile/themes/domButtons/compat/plus-button.png differ
diff --git a/dojox/mobile/themes/domButtons/compat/search-button.gif b/dojox/mobile/themes/domButtons/compat/search-button.gif
new file mode 100755
index 0000000..7087ef6
Binary files /dev/null and b/dojox/mobile/themes/domButtons/compat/search-button.gif differ
diff --git a/dojox/mobile/themes/domButtons/compat/search-button.png b/dojox/mobile/themes/domButtons/compat/search-button.png
new file mode 100755
index 0000000..ca09ddb
Binary files /dev/null and b/dojox/mobile/themes/domButtons/compat/search-button.png differ
diff --git a/dojox/mobile/themes/domButtons/compat/uparrow-button.png b/dojox/mobile/themes/domButtons/compat/uparrow-button.png
new file mode 100755
index 0000000..78c1331
Binary files /dev/null and b/dojox/mobile/themes/domButtons/compat/uparrow-button.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png
new file mode 100644
index 0000000..b2afca9
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-bg.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png
new file mode 100644
index 0000000..503c685
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-arrow-button-head.png differ
diff --git a/dojox/mobile/themes/iphone/compat/ipad-heading-bg.png b/dojox/mobile/themes/iphone/compat/ipad-heading-bg.png
new file mode 100644
index 0000000..614bbbd
Binary files /dev/null and b/dojox/mobile/themes/iphone/compat/ipad-heading-bg.png differ
diff --git a/dojox/mobile/themes/iphone/images/thumb-overlay-large.png b/dojox/mobile/themes/iphone/images/thumb-overlay-large.png
new file mode 100644
index 0000000..dfac370
Binary files /dev/null and b/dojox/mobile/themes/iphone/images/thumb-overlay-large.png differ
diff --git a/dojox/mobile/themes/iphone/images/thumb-overlay-small.png b/dojox/mobile/themes/iphone/images/thumb-overlay-small.png
new file mode 100644
index 0000000..b6836d9
Binary files /dev/null and b/dojox/mobile/themes/iphone/images/thumb-overlay-small.png differ
diff --git a/dojox/mobile/themes/iphone/ipad-compat.css b/dojox/mobile/themes/iphone/ipad-compat.css
new file mode 100644
index 0000000..5775d6c
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ipad-compat.css
@@ -0,0 +1,12 @@
+/* mbl.widget.Heading */
+.mblHeading {
+	background-image: url(compat/ipad-heading-bg.png);
+}
+
+/* Heading Arrow Button */
+.mblArrowButtonHead {
+	background-image: url(compat/ipad-arrow-button-head.png);
+}
+.mblArrowButtonBody {
+	background-image: url(compat/ipad-arrow-button-bg.png);
+}
diff --git a/dojox/mobile/themes/iphone/ipad.css b/dojox/mobile/themes/iphone/ipad.css
new file mode 100644
index 0000000..6e6ad62
--- /dev/null
+++ b/dojox/mobile/themes/iphone/ipad.css
@@ -0,0 +1,66 @@
+/* dojox.mobile.View */
+
+/* dojox.mobile.Heading */
+.mblHeading {
+	background-color: #889BB3;
+	background: -webkit-gradient(linear, left top, left bottom, from(#F3F4F6), to(#A7ABB8));
+	border-top: 1px solid #FEFEFE;
+	border-bottom: 1px solid #787E8F;
+	color: #70777F;
+	text-shadow: rgba(256,256,256,0.6) 0px 1px 0px;
+}
+
+/* Heading Arrow Button */
+.mblArrowButtonHead {
+	border-color: #4D4E50;
+	background: -webkit-gradient(linear, left top, right bottom, from(#B1B5BB), to(#6A727D));
+}
+.mblArrowButtonBody {
+	border-color: #C0C0C0;
+	background-color: #5877A2;
+	background: -webkit-gradient(linear, left top, left bottom, from(#B1B5BB), to(#6A727D));
+	-webkit-tap-highlight-color: transparent;
+	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 {
+	background: -webkit-gradient(linear, left top, right bottom, from(#9DA0A3), to(#43484F));
+}
+.mblArrowButtonSelected .mblArrowButtonBody, .mblArrowButtonSelected .mblArrowButtonNeck {
+	background: -webkit-gradient(linear, left top, left bottom, from(#9DA0A3), to(#43484F));
+}
+
+/* dojox.mobile.RoundRect */
+.mblRoundRect {
+	margin: 7px 30px 30px 30px;
+}
+.mblHeading + .mblRoundRect {
+	margin-top: 30px;
+}
+
+/* dojox.mobile.EdgeToEdgeCategory */
+/* dojox.mobile.RoundRectCategory */
+.mblRoundRectCategory {
+	margin: 18px 0px 0px 41px;
+}
+
+/* dojox.mobile.RoundRectList */
+.mblRoundRectList {
+	margin: 7px 30px 30px 30px;
+}
+.mblHeading + .mblRoundRectList {
+	margin-top: 30px;
+}
+
+/* dojox.mobile.EdgeToEdgeList */
+/* dojox.mobile.ListItem */
+/* Switch */
+/* Icon Container */
+/* Icon Content Heading */
+/* dojox.mobile.Button */
+/* Tab Container */
+/* Progress Indicator */
+
diff --git a/dojox/mobile/themes/iphone/iphone-app.css b/dojox/mobile/themes/iphone/iphone-app.css
index 4f19ecb..3cf25ce 100644
--- a/dojox/mobile/themes/iphone/iphone-app.css
+++ b/dojox/mobile/themes/iphone/iphone-app.css
@@ -36,7 +36,7 @@
 	text-align: center;
 }
 
-.alertText {	
+.alertText {
 	text-align: center;
 }
 
@@ -128,14 +128,14 @@
 
 .list .buttons .deleteBtn {
 	background-color: red;
-	
+
 }
 .list .buttons .cancelBtn {
 	margin-left: 10px;
 	background-color: blue;
 }
 
-.row.collapsed { 
+.row.collapsed {
 	-webkit-animation-name: collapse-vert;
 	-webkit-animation-duration: 0.5s;
 	-webkit-animation-timing-function: linear;
@@ -149,7 +149,7 @@
 	to {
 		height: 0px;
 		padding: 0px;
-	} 
+	}
 }
 
 .listSelector {
@@ -189,22 +189,27 @@
 input {
 	-webkit-text-size-adjust: 140%;
 }
- 
- 
+
+
 /* ImageThumbView styles */
 .mblImageThumbView {
 	position: relative;
+	-webkit-transition-property: height;
+	-webkit-transition-duration: 0.8s;
+	-webkit-transition-delay: 0;
 }
 
 .mblImageThumbView .mblThumb {
-	width: 93px;
+	width: 100px;
 	min-height: 100px;
 	display: inline-block;
-	padding: 4px 3px 0px 4px;
 	z-index: 2;
 	position: absolute;
+}
+
+.mblImageThumbView.animated .mblThumb {
 	-webkit-transition-property: -webkit-transform, opacity;
-	-webkit-transition-duration: 0.5s, 0.5s;
+	-webkit-transition-duration: 1.3s, 1s;
 	-webkit-transition-delay: 0, 0;
 }
 
@@ -212,7 +217,6 @@ input {
 	z-index: 1;
 	opacity: 0;
 }
-
 .mblImageThumbView .mblThumbInner {
 	width: 102px;
 	height: 102px;
@@ -227,55 +231,111 @@ input {
 	z-index: 20;
 	overflow: hidden;
 }
-
 .mblImageThumbView .mblThumb.selected .mblThumbOverlay {
-	background: url(images/thumb-overlay.png) center bottom no-repeat;
+	background-position: center bottom;
 }
-
-
 .mblImageThumbView .mblThumbInner .mblThumbMask {
-  width: 90px;
-  height: 90px;
-  overflow: hidden;
-  padding-left: 6px;
-  padding-top: 5px;
-  z-index: 10;
-  
+	width: 90px;
+	height: 90px;
+	overflow: hidden;
+	padding-left: 6px;
+	padding-top: 5px;
+	z-index: 10;
 }
-
 .mblImageThumbView .mblThumbInner .mblThumbMask img {
-  left: 0px;
-  top: 0px;
-  width: 90px;
-  height: 90px;
+	left: 0px;
+	top: 0px;
+	width: 90px;
+	height: 90px;
 }
 
 .mblImageThumbView .mblThumbInner .mblThumbMask .mblThumbSrc {
-  left: 6px;
-  top: 5px;
-  background-position: center center;
-  background-repeat: no-repeat;
-  overflow: hidden;
-  position: absolute;
-  -webkit-background-size: 100% 100%;
-  -webkit-border-radius: 5px;
-  width: 90px;
-  height: 90px;
-  z-index: 5;
+	left: 6px;
+	top: 5px;
+	background-position: center center;
+	background-repeat: no-repeat;
+	overflow: hidden;
+	position: absolute;
+	-webkit-background-size: 100% 100%;
+	-webkit-border-radius: 5px;
+	width: 90px;
+	height: 90px;
+	z-index: 5;
 }
 
 .mblImageThumbView .mblThumbMask div {
-  left: 0px;
-  top: 0px;
-  width: 90px;
-  height: 90px;
-  background-repeat: no-repeat;
+	left: 0px;
+	top: 0px;
+	width: 90px;
+	height: 90px;
+	background-repeat: no-repeat;
 }
-
 .mblImageThumbView .mblThumb:hover,
-.mblImageThumbView .mblThumb.selected  {
+.mblImageThumbView .mblThumb.selected {
 	-webkit-transform: scale(1.2);
+	transform: scale(1.2);
+}
+
+/* Large Images */
+.mblImageThumbView.large .mblThumb {
+	width: 150px;
+	min-height: 150px;
+}
+
+.mblImageThumbView.large .mblThumbInner{
+	width: 152px;
+	height: 152px;
 }
 
+.mblImageThumbView.large .mblThumbOverlay {
+	background: url(images/thumb-overlay-large.png) center top no-repeat;
+	width: 152px;
+	height: 152px;
+}
+.mblImageThumbView.large .mblThumbInner .mblThumbMask,
+.mblImageThumbView.large .mblThumbInner .mblThumbMask img,
+.mblImageThumbView.large .mblThumbInner .mblThumbMask .mblThumbSrc,
+.mblImageThumbView.large .mblThumbMask div {
+	width: 133px;
+	height: 133px;
+}
 
+.mblImageThumbView.large .mblThumbInner .mblThumbMask .mblThumbSrc {
+	left: 9px;
+	top: 7px;
+}
+/* Small Images */
+.mblImageThumbView.small .mblThumb {
+	width: 75px;
+	min-height: 75px;
+}
+
+.mblImageThumbView.small .mblThumbInner{
+	width: 77px;
+	height: 77px;
+}
 
+.mblImageThumbView.small .mblThumbOverlay {
+	background: url(images/thumb-overlay-small.png) center top no-repeat;
+	width: 77px;
+	height: 77px;
+}
+.mblImageThumbView.small .mblThumbInner .mblThumbMask,
+.mblImageThumbView.small .mblThumbInner .mblThumbMask img,
+.mblImageThumbView.small .mblThumbInner .mblThumbMask .mblThumbSrc,
+.mblImageThumbView.small .mblThumbMask div {
+	width: 70px;
+	height: 70px;
+}
+
+.mblImageThumbView.small .mblThumbInner .mblThumbMask .mblThumbSrc {
+	left: 4px;
+	top: 3px;
+}
+
+.mblImageThumbView .mblThumbLabel {
+	font-size: smaller;
+	overflow: hidden;
+	white-space: nowrap;
+	text-align: center;
+}
\ No newline at end of file
diff --git a/dojox/mobile/themes/iphone/iphone-compat.css b/dojox/mobile/themes/iphone/iphone-compat.css
index 6080512..874b489 100755
--- a/dojox/mobile/themes/iphone/iphone-compat.css
+++ b/dojox/mobile/themes/iphone/iphone-compat.css
@@ -6,13 +6,15 @@
 /* Heading Arrow Button */
 .mblArrowButtonHead {
 	position: absolute;
-	top: 5px;
-	left: 6px;
+	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);
 }
 
@@ -91,17 +93,22 @@
 	height: 0;
 }
 
-li.mblListItem .mblArrow, div.mblListItem .mblArrow {
+.mblListItem .mblArrow {
 	border-style: none;
 	top: 16px;
 	width: 9px;
 	height: 13px;
 	background-image: url(compat/gray-arrow.png);
 }
-li.mblItemSelected .mblArrow, div.mblItemSelected .mblArrow {
+.mblItemSelected .mblArrow {
 	background-image: url(compat/white-arrow.png);
 }
 
+/* dojox.mobile.TabBarButton */
+.dj_ie6 .mblTabBarButtonDiv, .dj_ie7 .mblTabBarButtonDiv {
+	left: auto;
+}
+
 /* Switch */
 .mblSwitchInner {
 	width: 100px;
@@ -226,10 +233,10 @@ li.mblItemSelected .mblArrow, div.mblItemSelected .mblArrow {
 .mblTabPanelHeader {
 	background-image: url(compat/heading-bg.png);
 }
-.mblTabButton {
+.mblTabContainer .mblTabButton {
 	background-image: url(compat/tab-button-bg.png);
 }
-.mblTabButtonSelected {
+.mblTabContainer .mblTabButtonSelected {
 	background-image: url(compat/tab-sel-button-bg.png);
 }
 *html .mblTabButton { /* IE6 hack */
diff --git a/dojox/mobile/themes/iphone/iphone.css b/dojox/mobile/themes/iphone/iphone.css
index 88939d1..c6b07c5 100755
--- a/dojox/mobile/themes/iphone/iphone.css
+++ b/dojox/mobile/themes/iphone/iphone.css
@@ -13,7 +13,6 @@ html.mobile, .mobile body {
 	background-color: rgb(197,204,211);
 	font-family: Helvetica;
 	font-size: 17px;
-	min-height: 416px;
 }
 
 /* dojox.mobile.View */
@@ -25,7 +24,6 @@ html.mobile, .mobile body {
 }
 
 .mblView.out {
-	position: absolute;
 }
 
 .mblView.in {
@@ -132,12 +130,19 @@ html.mobile, .mobile body {
 	overflow: hidden;
 	white-space: nowrap;
 	text-overflow: ellipsis;
+	z-index: 1;
 }
 
 /* Heading Arrow Button */
-.dj_webkit .mblArrowButtonHead {
+.mblArrowButton {
+	position: relative;
+	float: left;
+	height: 42px;
+	margin-right: 6px;
+}
+.mblArrowButtonHead {
 	position: absolute;
-	top: 10px;
+	top: 11px;
 	left: 8px;
 	width: 19px;
 	height: 19px;
@@ -149,7 +154,7 @@ html.mobile, .mobile body {
 }
 .mblArrowButtonBody {
 	position: absolute;
-	top: 5px;
+	top: 6px;
 	left: 19px;
 	padding: 0px 10px 0px 3px;
 	height: 29px;
@@ -167,12 +172,9 @@ html.mobile, .mobile body {
 	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;
 }
-.dj_ie .mblArrowButtonBody, .dj_ff3 .mblArrowButtonBody {
-	padding: 0px 10px 0px 10px;
-}
 .mblArrowButtonNeck {
 	position: absolute;
-	top: 5px;
+	top: 6px;
 	left: 19px;
 	width: 4px;
 	height: 29px;
@@ -188,9 +190,93 @@ html.mobile, .mobile body {
 	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;
+	margin: 7px 9px 16px 9px;
 	padding: 8px;
 	border: 1px solid #ADAAAD;
 	-webkit-border-radius: 8px;
@@ -211,6 +297,7 @@ html.mobile, .mobile body {
 	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;
@@ -223,7 +310,8 @@ html.mobile, .mobile body {
 /* dojox.mobile.RoundRectCategory */
 .mblRoundRectCategory {
 	color: #4C566C;
-	margin: 18px 0px 0px 20px;
+	padding: 18px 0px 0px 20px;
+	margin: 0px;
 	text-shadow: rgba(255, 255, 255, 1) 0px 1px 0px;
 	font-family: Helvetica;
 	font-size: 16px;
@@ -234,7 +322,7 @@ html.mobile, .mobile body {
 
 /* dojox.mobile.RoundRectList */
 .mblRoundRectList {
-	margin: 7px 9px 16px;
+	margin: 7px 9px 16px 9px;
 	padding: 0px;
 	border: 1px solid #ADAAAD;
 	-webkit-border-radius: 8px;
@@ -261,10 +349,11 @@ html.mobile, .mobile body {
 	position: relative;
 	color: black;
 	vertical-align: bottom; /* To avoid IE6 LI bug */
+	padding-left: 8px;
 }
 .mblListItemIcon {
 	position: absolute;
-	margin: 7px 0px 0px 8px;
+	top: 7px;
 }
 .mblListItem.mblVariableHeight {
 	line-height: normal;
@@ -275,10 +364,10 @@ html.mobile, .mobile body {
 	background-color: #048BF4;
 	background: -webkit-gradient(linear, left top, left bottom, from(#048BF4), to(#005CE5));
 }
-li .mblListItemTextBox {
+.mblListItemTextBox {
 	padding-right: 28px;
 }
-li .mblListItemTextBoxSelected {
+.mblListItemTextBoxSelected {
 	background-color: #048BF4;
 }
 .mblRoundRectList .mblListItem:first-child {
@@ -300,7 +389,7 @@ li .mblListItemTextBoxSelected {
 .mblListItem a.mblListItemAnchor {
 	background-position: 9px 7px;
 	display: block;
-	padding-left: 48px;
+	padding-left: 40px;
 	text-decoration: none;
 	-webkit-tap-highlight-color: transparent;
 }
@@ -627,6 +716,8 @@ table.mblClose {
 
 .mblTabButton {
 	float: left;
+	position: relative;
+	list-style-type: none;
 	width: 100px;
 	text-align: center;
 	height: 28px;
@@ -639,7 +730,6 @@ table.mblClose {
 	color: white;
 	cursor: pointer;
 	line-height: 29px;
-	background-color: #8297AF;
 	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;
 }
@@ -657,7 +747,7 @@ table.mblClose {
 	-moz-border-radius-bottomright: 5px;
 	border-right-color: #9CACC0;
 }
-.mblTabButtonSelected.mblTabButton {
+.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));
 }
@@ -749,3 +839,20 @@ table.mblClose {
 .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));
+}
diff --git a/dojox/rails/tests/plugd/trigger.js b/dojox/rails/tests/plugd/trigger.js
index a57992a..122196f 100644
--- a/dojox/rails/tests/plugd/trigger.js
+++ b/dojox/rails/tests/plugd/trigger.js
@@ -1,17 +1,17 @@
 dojo.provide("dojox.rails.tests.plugd.trigger");
 (function(d){
 	
-	var isfn = d.isFunction, 
-		leaveRe = /mouse(enter|leave)/, 
+	var isfn = d.isFunction,
+		leaveRe = /mouse(enter|leave)/,
 		_fix = function(_, p){
-			return "mouse" + (p == "enter" ? "over" : "out"); 
+			return "mouse" + (p == "enter" ? "over" : "out");
 		},
 		mix = d._mixin,
 		
 		// the guts of the node triggering logic:
 		// the function accepts node (not string|node), "on"-less event name,
-		// and an object of args to mix into the event. 
-		realTrigger = d.doc.createEvent ? 
+		// and an object of args to mix into the event.
+		realTrigger = d.doc.createEvent ?
 			function(n, e, a){
 				// the sane branch
 				var ev = d.doc.createEvent("HTMLEvents");
@@ -19,13 +19,13 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 				ev.initEvent(e, true, true);
 				a && mix(ev, a);
 				n.dispatchEvent(ev);
-			} : 
+			} :
 			function(n, e, a){
 				// the janktastic branch
-				var ev = "on" + e, stop = false, lc = e.toLowerCase(), node = n; 
+				var ev = "on" + e, stop = false, lc = e.toLowerCase(), node = n;
 				try{
 // FIXME: is this worth it? for mixed-case native event support:? Opera ends up in the
-//	createEvent path above, and also fails on _some_ native-named events. 
+//	createEvent path above, and also fails on _some_ native-named events.
 //					if(lc !== e && d.indexOf(d.NodeList.events, lc) >= 0){
 //						// if the event is one of those listed in our NodeList list
 //						// in lowercase form but is mixed case, throw to avoid
@@ -36,7 +36,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 				}catch(er){
                     console.warn("in catch", er);
 					// a lame duck to work with. we're probably a 'custom event'
-					var evdata = mix({ 
+					var evdata = mix({
 						type: e, target: n, faux: true,
 						// HACK: [needs] added support for customStopper to _base/event.js
 						// some tests will fail until del._stopPropagation has support.
@@ -55,7 +55,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 	;
 	
 	d._trigger = function(/* DomNode|String */node, /* String */event, extraArgs){
-		// summary: 
+		// summary:
 		//		Helper for `dojo.trigger`, which handles the DOM cases. We should never
 		//		be here without a domNode reference and a string eventname.
 		var n = d.byId(node), ev = event && event.slice(0, 2) == "on" ? event.slice(2) : event;
@@ -64,12 +64,12 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 	};
 		
 	d.trigger = function(obj, event, extraArgs){
-		// summary: 
-		//		Trigger some event. It can be either a Dom Event, Custom Event, 
-		//		or direct function call. 
+		// summary:
+		//		Trigger some event. It can be either a Dom Event, Custom Event,
+		//		or direct function call.
 		//
 		// description:
-		//		Trigger some event. It can be either a Dom Event, Custom Event, 
+		//		Trigger some event. It can be either a Dom Event, Custom Event,
 		//		or direct function call. NOTE: This function does not trigger
 		//		default behavior, only triggers bound event listeneres. eg:
 		//		one cannot trigger("anchorNode", "onclick") and expect the browser
@@ -80,7 +80,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		//		If an Object, fire the `event` in the scope of this object,
 		//		similar to calling dojo.hitch(obj, event)(). The return value
 		//		in this case is returned from `dojo.trigger`
-		//	 
+		//
 		// event: String|Function
 		//		The name of the event to trigger. Can be any DOM level 2 event
 		//		and can be in either form: "onclick" or "click" for instance.
@@ -88,7 +88,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		//		a string version of a member function, just like `dojo.hitch`.
 		//
 		// extraArgs: Object?
-		//		An object to mix into the `event` object passed to any bound 
+		//		An object to mix into the `event` object passed to any bound
 		//		listeners. Be careful not to override important members, like
 		//		`type`, or `preventDefault`. It will likely error.
 		//
@@ -96,7 +96,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		//		as all arguments beyond the `event` are curried onto the triggered
 		//		function.
 		//
-		// example: 
+		// example:
 		//	|	dojo.connect(node, "onclick", function(e){ /* stuff */ });
 		//	|	// later:
 		//	|	dojo.trigger(node, "onclick");
@@ -113,7 +113,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		//	|	// fire an anonymous function:
 		//	|	dojo.trigger(d.global, function(){ /* stuff */ });
 		//
-		// example: 
+		// example:
 		//	|	// fire and anonymous function in the scope of obj
 		//	|	dojo.trigger(obj, function(){ this == obj; });
 		//
@@ -129,8 +129,8 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		//
 		// returns: Anything
 		//		Will not return anything in the Dom event case, but will return whatever
-		//		return value is received from the triggered event. 
-		return (isfn(obj) || isfn(event) || isfn(obj[event])) ? 
+		//		return value is received from the triggered event.
+		return (isfn(obj) || isfn(event) || isfn(obj[event])) ?
 			d.hitch.apply(d, arguments)() : d._trigger.apply(d, arguments);
 	};
 	
@@ -140,7 +140,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		trigger: function(event, data){
 			// summary:
 			//		Trigger some Event originating from each of the nodes in this
-			//		`dojo.NodeList`. 
+			//		`dojo.NodeList`.
 			//
 			// event: String
 			//		Any strig identifier for the event.type to be triggered.
@@ -156,7 +156,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 		}
 	});
 	=====*/
-	d.NodeList.prototype.trigger = d.NodeList._adaptAsForEach(d._trigger); 
+	d.NodeList.prototype.trigger = d.NodeList._adaptAsForEach(d._trigger);
 
 	// if the node.js module is available, extend trigger into that.
 	if(d._Node && !d._Node.prototype.trigger){
@@ -164,7 +164,7 @@ dojo.provide("dojox.rails.tests.plugd.trigger");
 			trigger: function(ev, data){
 				// summary:
 				//		Fire some some event originating from this node.
-				//		Only available if both the `dojo.trigger` and `dojo.node` plugin 
+				//		Only available if both the `dojo.trigger` and `dojo.node` plugin
 				//		are enabled. Allows chaining as all `dojo._Node` methods do.
 				//
 				// ev: String
diff --git a/dojox/resources/_modules.js b/dojox/resources/_modules.js
index 2d1b233..9b8bfa6 100644
--- a/dojox/resources/_modules.js
+++ b/dojox/resources/_modules.js
@@ -23,67 +23,67 @@ dojox = {
 	//	DojoX can also be an incubator for entirely new projects.
 }
 
-dojox.analytics = { 
-	// summary: Website analytics and client monitoring system 
+dojox.analytics = {
+	// summary: Website analytics and client monitoring system
 };
 
-dojox.atom = { 
-	// summary: Implements the Atom Syndication Format and Atom Publishing Protocol 
+dojox.atom = {
+	// summary: Implements the Atom Syndication Format and Atom Publishing Protocol
 };
 
-dojox.av = { 
-	// summary: Provides Audio/Video capabilities 
+dojox.av = {
+	// summary: Provides Audio/Video capabilities
 };
 
-dojox.charting = { 
-	// summary: Vector graphic, data-driven graphs and charts 
+dojox.charting = {
+	// summary: Vector graphic, data-driven graphs and charts
 };
 
-dojox.collections = { 
+dojox.collections = {
 	// summary: A set of lists and hashes for easy use within your applications.
 };
 
-dojox.color = { 
+dojox.color = {
 	// summary: Advanced color methods, including HSV, HSL, and CMYK conversion, a color generator and advanced colorspace calculations.
 };
 
-dojox.cometd = { 
+dojox.cometd = {
 	// summary: A cometd client written in Dojo
 };
 
-dojox.data = { 
+dojox.data = {
 	// summary: Additional dojo.data data stores and demos
 };
 
-dojox.date = { 	
+dojox.date = {
 	// summary: Additional date manipulation functions
 };
 
-dojox.drawing = { 	
+dojox.drawing = {
 	// summary: A vector drawing program
 };
 
-dojox.dtl = { 
-	// summary: Django Templating Language implementation	
+dojox.dtl = {
+	// summary: Django Templating Language implementation
 };
 
-dojox.editor = { 
+dojox.editor = {
 	// summary: Extensions for dijit.Editor
 };
 
-dojox.embed = { 
+dojox.embed = {
 	// summary: Base code for embedding for external objects like Flash, Quicktime
 };
 
-dojox.encoding = { 
+dojox.encoding = {
 	// summary: Various encoding algorithms, including crypto and digests.
 };
 
-dojox.flash = { 
+dojox.flash = {
 	// summary: Utilities to embed and communicate with Flash-based objects
 };
 
-dojox.form = { 
+dojox.form = {
 	// summary: Form-related widgets
 };
 
@@ -98,7 +98,7 @@ dojox.fx = {
 	style: { // summary: Module to provide CSS animations
 	},
 
-	scroll: { // summary: Module to provide scroll-related FX 
+	scroll: { // summary: Module to provide scroll-related FX
 	}
 };
 dojox.fx["ext-dojo"] = {
@@ -108,50 +108,50 @@ dojox.fx["ext-dojo"] = {
 	}
 };
 
-dojox.gfx = { 
+dojox.gfx = {
 	// summary: Cross-browser vector graphics API
-	// description: 
+	// description:
 	//
 	//	dojox.gfx is an advanced API providing normalized vector drawing
 	//	in a variety of browsers. It has individual renderers for SVG, VML,
 	//	Canvas, and Silverlight.
 };
 
-dojox.gfx3d = { 
+dojox.gfx3d = {
 	// summary: A 3d API for dojox.gfx
 };
 
-dojox.grid = { 
-	// summary: An advanced Grid widget with virtual scrolling, cell editing, and much more 
-};	
+dojox.grid = {
+	// summary: An advanced Grid widget with virtual scrolling, cell editing, and much more
+};
 
 dojox.help = {
 	// summary: TODOC
 };
 
-dojox.highlight = { 
+dojox.highlight = {
 	// summary: A client-side syntax highlighting engine.
 	// description:
 	//	This project parses pre > code nodes, and applies syntax highlighting for
-	//	a wide variety of languages. Simply dojo.require() in all the 
+	//	a wide variety of languages. Simply dojo.require() in all the
 	//	dojox.highlight.languages you wish to include in your highlighingting,
 	//	and customize colors in the highlight.css.
 	//
-	//	It is provided as a dojo package, contributed under CLA 
+	//	It is provided as a dojo package, contributed under CLA
 	//	by Ivan Sagalaev and is available originally from:
-	// 	http://softwaremaniacs.org/soft/highlight/en/	
-	//	
+	// 	http://softwaremaniacs.org/soft/highlight/en/
+	//
 };
 
 dojox.html = {
 	// summary: TODOC
 };
 
-dojox.image = { 
+dojox.image = {
 	// summary: A collection of image related widgets
 };
 
-dojox.io = { 
+dojox.io = {
 	// summary: Extensions to the Core dojo.io transports
 };
 
@@ -159,22 +159,22 @@ dojox.jq = {
 	// summary: A JQuery compatibility layer
 };
 
-dojox.jsonPath = { 
+dojox.jsonPath = {
 	// summary: A query system for JavaScript objects
 };
 
-dojox.lang = { 
+dojox.lang = {
 	// summary: Language specific extensions
 	functional: {
 		// summary: Functional language constructs, including currying and lambda.
 	}
 };
 
-dojox.layout = { 
+dojox.layout = {
 	// summary: A collection of layout related Widgets
 };
 
-dojox.math = { 
+dojox.math = {
 	// summary: A collection of various advanced math functions.
 };
 
@@ -182,23 +182,23 @@ dojox.robot = {
 	// summary: TODOC
 };
 
-dojox.rpc = { 
+dojox.rpc = {
 	// summary: TODOC
 };
 
-dojox.secure = { 
+dojox.secure = {
 	// summary: TODOC
 };
 
-dojox.sketch = { 
+dojox.sketch = {
 	// summary: TODOC
 };
 
-dojox.sql = { 
+dojox.sql = {
 	// summary: objects to support Dojo Offline (dojox.off)  DEPRECATED
 };
 
-dojox.storage = { 
+dojox.storage = {
 	// summary: Objects for mass storage within the browser.  For when cookies just aren't enough.
 };
 
@@ -214,25 +214,25 @@ dojox.timing = {
 	// summary: A set of objects to perform advanced time-based tasks, including a basic Timer.
 };
 
-dojox.uuid = { 
+dojox.uuid = {
 	// summary: Universally Unique Identifier (UUID) implementations, including an implementation of UUID 2
 };
 
-dojox.validate = { 
+dojox.validate = {
 	// summary: Additional input validation methods
 	ca : {
 		// summary: Methods specific to the Canadian provinces
 	},
 	creditCard : {
-		// summary: Validate various credit card types  
+		// summary: Validate various credit card types
 	}
 };
 
-dojox.widget = { 
+dojox.widget = {
 	// summary: A collection of un-categorized widgets, or code not requiring its own package.
-	// 
-	// description: 
-	// 	These are standalone widgets with varying levels of stability. Some are useful, 
+	//
+	// description:
+	// 	These are standalone widgets with varying levels of stability. Some are useful,
 	//	some were created for demonstration purposes, and learning tools. The each maintain
 	//	their own .css file (typically dojox/widget/WidgetName/WidgetName.css)
 };
diff --git a/dojox/robot/recorder.js b/dojox/robot/recorder.js
index 9d7b4b9..3fb97fb 100644
--- a/dojox/robot/recorder.js
+++ b/dojox/robot/recorder.js
@@ -57,10 +57,10 @@ var addCommand = function(name, args){
 	//
 
 	// omit start/stop record
-	if(startTime == null 
-		|| name=="doh.robot.keyPress" 
-		&& args[0]==dojo.keys.ENTER 
-		&& eval("("+args[2]+")").ctrl 
+	if(startTime == null
+		|| name=="doh.robot.keyPress"
+		&& args[0]==dojo.keys.ENTER
+		&& eval("("+args[2]+")").ctrl
 		&& eval("("+args[2]+")").alt){ return; }
 	var dt = Math.max(Math.min(Math.round((new Date()).getTime() - prevTime.getTime()),MAXIMUM_DELAY),1);
 	// add in dt
@@ -80,13 +80,13 @@ var _optimize = function(){
 
 	// INITIAL OPTIMIZATIONS
 	// remove starting ENTER press
-	if(c[0].name == "doh.robot.keyPress" 
+	if(c[0].name == "doh.robot.keyPress"
 		&& (c[0].args[0] == dojo.keys.ENTER || c[0].args[0] == 77)){
 		c.splice(0,1);
 	}
 	// remove ending CTRL + ALT keypresses in IE
 	for(var i = c.length-1; (i >= c.length-2) && (i>=0); i-- ){
-		if(c[i].name == "doh.robot.keyPress" 
+		if(c[i].name == "doh.robot.keyPress"
 			&& c[i].args[0]==dojo.keys.ALT || c[i].args[0]==dojo.keys.CTRL){
 			c.splice(i,1);
 		}
@@ -94,9 +94,9 @@ var _optimize = function(){
 	// ITERATIVE OPTIMIZATIONS
 	for(i = 0; i<c.length; i++){
 		var next, nextdt;
-		if(c[i+1] 
-			&& c[i].name=="doh.robot.mouseMove" 
-			&& c[i+1].name==c[i].name 
+		if(c[i+1]
+			&& c[i].name=="doh.robot.mouseMove"
+			&& c[i+1].name==c[i].name
 			&& c[i+1].args[2]<MOUSEMOVE_MAXIMUM_DELAY){
 			// mouse movement optimization
 			// if the movement is temporally close, collapse it
@@ -107,19 +107,19 @@ var _optimize = function(){
 			// 	...
 			// 	c[i+n-1]: last mouseMove
 			// 	c[i+n]: something else
-			// result: 
+			// result:
 			// 	c[i]: last mouseMove
 			// 	c[i+1]: something else
 			// the c[i] mouse location changes to move to c[i+n-1]'s location, c[i+n] gains c[i+1]+c[i+2]+...c[i+n-1] delay so the timing is the same
 
 			next = c[i+1];
 			nextdt = 0;
-			while(next 
-				&& next.name==c[i].name 
+			while(next
+				&& next.name==c[i].name
 				&& next.args[2]<MOUSEMOVE_MAXIMUM_DELAY){
 				// cut out next
 				c.splice(i + 1,1);
-				// add next's delay to the total 
+				// add next's delay to the total
 				nextdt += next.args[2];
 				// move to next mouse position
 				c[i].args[0]=next.args[0];
@@ -128,9 +128,9 @@ var _optimize = function(){
 			}
 			// make the total delay the duration
 			c[i].args[3]=nextdt;
-		}else if(c[i+1] 
-			&& c[i].name=="doh.robot.mouseWheel" 
-			&& c[i+1].name==c[i].name 
+		}else if(c[i+1]
+			&& c[i].name=="doh.robot.mouseWheel"
+			&& c[i+1].name==c[i].name
 			&& c[i+1].args[1]<MOUSEMOVE_MAXIMUM_DELAY){
 			// mouse wheel optimization
 			// if the movement is temporally close, collapse it
@@ -142,18 +142,18 @@ var _optimize = function(){
 			// 	...
 			// 	c[i+n-1]: last mouseWheel
 			// 	c[i+n]: something else
-			// result: 
+			// result:
 			// 	c[i]: mouseWheel
 			// 	c[i+1]: something else
 
 			next = c[i+1];
 			nextdt = 0;
-			while(next 
-				&& next.name==c[i].name 
+			while(next
+				&& next.name==c[i].name
 				&& next.args[1]<MOUSEMOVE_MAXIMUM_DELAY){
 				// cut out next
 				c.splice(i + 1, 1);
-				// add next's delay to the total 
+				// add next's delay to the total
 				nextdt += next.args[1];
 				// add in wheel amount
 				c[i].args[0]+=next.args[0];
@@ -161,8 +161,8 @@ var _optimize = function(){
 			}
 			// make the total delay the duration
 			c[i].args[2]=nextdt;
-		}else if(c[i + 2] 
-			&& c[i].name=="doh.robot.mouseMoveAt" 
+		}else if(c[i + 2]
+			&& c[i].name=="doh.robot.mouseMoveAt"
 			&& c[i+2].name=="doh.robot.scrollIntoView"){
 			// swap scrollIntoView of widget and mouseMoveAt
 			// the recorder traps scrollIntoView after the mouse click registers, but in playback, it is better to go the other way
@@ -176,9 +176,9 @@ var _optimize = function(){
 			//	c[i+2]: mousePress
 			var temp = c.splice(i+2,1)[0];
 			c.splice(i,0,temp);
-		}else if(c[i + 1] 
-			&& c[i].name=="doh.robot.mousePress" 
-			&& c[i+1].name=="doh.robot.mouseRelease" 
+		}else if(c[i + 1]
+			&& c[i].name=="doh.robot.mousePress"
+			&& c[i+1].name=="doh.robot.mouseRelease"
 			&& c[i].args[0]==c[i+1].args[0]){
 			// convert mousePress+mouseRelease to mouseClick
 			// expected pattern:
@@ -192,10 +192,10 @@ var _optimize = function(){
 			if(c[i+1] && c[i+1].name == "doh.robot.mouseClick" && c[i].args[0] == c[i+1].args[0]){
 				c.splice(i + 1, 1);
 			}
-		}else if(c[i + 1] 
+		}else if(c[i + 1]
 			&& c[i - 1]
 			&& c[i - 1].name=="doh.robot.mouseMoveAt"
-			&& c[i].name=="doh.robot.mousePress" 
+			&& c[i].name=="doh.robot.mousePress"
 			&& c[i+1].name=="doh.robot.mouseMove"){
 			// convert mouseMoveAt+mousePress+mouseMove to mouseMoveAt+mousePress+mouseMoveAt+mouseMove
 			// this is to kick off dojo.dnd by moving the mouse 1 px
@@ -209,14 +209,14 @@ var _optimize = function(){
 			c.splice(i+1,0,cmd);
 		}else if(c[i + 1]
 			&& ((c[i].name=="doh.robot.keyPress"
-				&& typeof c[i].args[0] =="string") 
-				|| c[i].name=="doh.robot.typeKeys") 
-			&& c[i+1].name=="doh.robot.keyPress" 
+				&& typeof c[i].args[0] =="string")
+				|| c[i].name=="doh.robot.typeKeys")
+			&& c[i+1].name=="doh.robot.keyPress"
 			&& typeof c[i+1].args[0] =="string"
-			&& c[i+1].args[1]<=KEYPRESS_MAXIMUM_DELAY 
-			&& !eval("("+c[i].args[2]+")").ctrl 
-			&& !eval("("+c[i].args[2]+")").alt 
-			&& !eval("("+c[i+1].args[2]+")").ctrl 
+			&& c[i+1].args[1]<=KEYPRESS_MAXIMUM_DELAY
+			&& !eval("("+c[i].args[2]+")").ctrl
+			&& !eval("("+c[i].args[2]+")").alt
+			&& !eval("("+c[i+1].args[2]+")").ctrl
 			&& !eval("("+c[i+1].args[2]+")").alt){
 			// convert keyPress+keyPress+... to typeKeys
 			// expected pattern:
@@ -233,11 +233,11 @@ var _optimize = function(){
 			c[i].args.splice(3,1);
 			next = c[i+1];
 			var typeTime = 0;
-			while(next 
-				&& next.name == "doh.robot.keyPress" 
+			while(next
+				&& next.name == "doh.robot.keyPress"
 				&& typeof next.args[0] =="string"
-				&& next.args[1]<=KEYPRESS_MAXIMUM_DELAY 
-				&& !eval("("+next.args[2]+")").ctrl 
+				&& next.args[1]<=KEYPRESS_MAXIMUM_DELAY
+				&& !eval("("+next.args[2]+")").ctrl
 				&& !eval("("+next.args[2]+")").alt){
 				c.splice(i + 1,1);
 				c[i].args[0] += next.args[0];
@@ -474,7 +474,7 @@ dojo.addOnLoad(function(){
 });
 
 // Get Dojo widget events too!
-dojo.connect(dojo, "connect", 
+dojo.connect(dojo, "connect",
 	function(/*dijit._Widget*/ widget, /*String*/ event, /*Function*/ f){
 		// kill recursion
 		// check for private variable _mine to make sure this isn't a recursive loop
diff --git a/dojox/rpc/Client.js b/dojox/rpc/Client.js
index 20c95d3..f8702e4 100644
--- a/dojox/rpc/Client.js
+++ b/dojox/rpc/Client.js
@@ -1,4 +1,4 @@
-dojo.provide("dojox.rpc.Client");
+define("dojox/rpc/Client", ["dojo"], function(dojo) {
 // Provide extra headers for robust client and server communication
 (function() {
 	dojo._defaultXhr = dojo.xhr;
@@ -19,3 +19,7 @@ dojo.provide("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/JsonRPC.js b/dojox/rpc/JsonRPC.js
index ce17815..c45a527 100644
--- a/dojox/rpc/JsonRPC.js
+++ b/dojox/rpc/JsonRPC.js
@@ -1,7 +1,5 @@
-dojo.provide("dojox.rpc.JsonRPC");
-dojo.require("dojox.rpc.Service");
+define("dojox/rpc/JsonRPC", ["dojo", "dojox", "dojox/rpc/Service"], function(dojo, dojox) {
 
-(function(){
 	function jsonRpcEnvelope(version){
 		return {
 			serialize: function(smd, method, data, options){
@@ -52,4 +50,5 @@ dojo.require("dojox.rpc.Service");
 		},
 		jsonRpcEnvelope("2.0")
 	);
-})();
+
+});
diff --git a/dojox/rpc/JsonRest.js b/dojox/rpc/JsonRest.js
index 34c03b8..f6f9e70 100644
--- a/dojox/rpc/JsonRest.js
+++ b/dojox/rpc/JsonRest.js
@@ -1,10 +1,4 @@
-dojo.provide("dojox.rpc.JsonRest");
-
-dojo.require("dojox.json.ref"); // this provides json indexing
-dojo.require("dojox.rpc.Rest");
-// summary:
-// 		Provides JSON/REST utility functions
-(function(){
+define("dojox/rpc/JsonRest", ["dojo", "dojox", "dojox/json/ref", "dojox/rpc/Rest"], function(dojo, dojox) {
 	var dirtyObjects = [];
 	var Rest = dojox.rpc.Rest;
 	var jr;
@@ -18,7 +12,7 @@ dojo.require("dojox.rpc.Rest");
 			dojox.json.ref.refAttribute = hrefProperty;
 		}
 		value = value && dojox.json.ref.resolveJson(value, {
-			defaultId: defaultId, 
+			defaultId: defaultId,
 			index: Rest._index,
 			timeStamps: timeStamp && Rest._timeStamps,
 			time: timeStamp,
@@ -26,7 +20,7 @@ dojo.require("dojox.rpc.Rest");
 			idAttribute: jr.getIdAttribute(service),
 			schemas: jr.schemas,
 			loader:	jr._loader,
-			idAsRef: service.idAsRef, 
+			idAsRef: service.idAsRef,
 			assignAbsoluteIds: true
 		});
 		dojox.json.ref.refAttribute  = "$ref";
@@ -48,7 +42,7 @@ dojo.require("dojox.rpc.Rest");
 				var object = dirty.object;
 				var old = dirty.old;
 				var append = false;
-				if(!(kwArgs.service && (object || old) && 
+				if(!(kwArgs.service && (object || old) &&
 						(object || old).__id.indexOf(kwArgs.service.servicePath)) && dirty.save){
 					delete object.__isDirty;
 					if(object){
@@ -62,7 +56,7 @@ dojo.require("dojox.rpc.Rest");
 							if(!(object.__id in alreadyRecorded)){// if it has already been saved, we don't want to repeat it
 								// record that we are saving
 								alreadyRecorded[object.__id] = object;
-								if(kwArgs.incrementalUpdates 
+								if(kwArgs.incrementalUpdates
 									&& !pathParts){ // I haven't figured out how we would do incremental updates on sub-objects yet
 									// make an incremental update using a POST
 									var incremental = (typeof kwArgs.incrementalUpdates == 'function' ?
@@ -118,7 +112,7 @@ dojo.require("dojox.rpc.Rest");
 					dirtyObjects = postCommitDirtyObjects;
 				}
 				else{
-					dirtyObjects = dirtyObject.concat(savingObjects); 
+					dirtyObjects = dirtyObject.concat(savingObjects);
 				}
 			});
 			jr.sendToServer(actions, kwArgs);
@@ -138,13 +132,13 @@ dojo.require("dojox.rpc.Rest");
 				// the last one should commit the transaction
 				args.headers['Transaction'] = actions.length - 1 == i ? "commit" : "open";
 				if(conflictDateHeader && timeStamp){
-					args.headers[conflictDateHeader] = timeStamp; 
+					args.headers[conflictDateHeader] = timeStamp;
 				}
 				if(contentLocation){
 					args.headers['Content-ID'] = '<' + contentLocation + '>';
 				}
 				return plainXhr.apply(dojo,arguments);
-			};			
+			};
 			for(i =0; i < actions.length;i++){ // iterate through the actions to execute
 				var action = actions[i];
 				dojox.rpc.JsonRest._contentId = action.content && action.content.__id; // this is used by OfflineRest
@@ -157,7 +151,7 @@ dojo.require("dojox.rpc.Rest");
 				// send the content location to the server
 				contentLocation = isPost && dojox.rpc.JsonRest._contentId;
 				var serviceAndId = jr.getServiceAndId(action.target.__id);
-				var service = serviceAndId.service; 
+				var service = serviceAndId.service;
 				var dfd = action.deferred = service[action.method](
 									serviceAndId.id.replace(/#/,''), // if we are using references, we need eliminate #
 									dojox.json.ref.toJson(action.content, false, service.servicePath, true)
@@ -169,10 +163,10 @@ dojo.require("dojox.rpc.Rest");
 							var newId = dfd.ioArgs.xhr && dfd.ioArgs.xhr.getResponseHeader("Location");
 							//TODO: match URLs if the servicePath is relative...
 							if(newId){
-								// if the path starts in the middle of an absolute URL for Location, we will use the just the path part 
+								// if the path starts in the middle of an absolute URL for Location, we will use the just the path part
 								var startIndex = newId.match(/(^\w+:\/\/)/) && newId.indexOf(service.servicePath);
 								newId = startIndex > 0 ? newId.substring(startIndex) : (service.servicePath + newId).
-										// now do simple relative URL resolution in case of a relative URL. 
+										// now do simple relative URL resolution in case of a relative URL.
 										replace(/^(.*\/)?(\w+:\/\/)|[^\/\.]+\/\.\.\/|^.*\/(\/)/,'$2$3');
 								object.__id = newId;
 								Rest._index[newId] = object;
@@ -212,7 +206,7 @@ dojo.require("dojox.rpc.Rest");
 				var old = dirty.old;
 				var store = dojox.data._getStoreForItem(object || old);
 				
-				if(!(service && (object || old) && 
+				if(!(service && (object || old) &&
 					(object || old).__id.indexOf(service.servicePath))){
 					// if we are in the specified store or if this is a global revert
 					if(object && old){
@@ -284,7 +278,7 @@ dojo.require("dojox.rpc.Rest");
 		},
 		deleteObject: function(object){
 			// summary:
-			//		deletes an object 
+			//		deletes an object
 			//	object:
 			//  	object to delete
 			this.changing(object,true);
@@ -315,7 +309,7 @@ dojo.require("dojox.rpc.Rest");
 						addDefaults(schema['extends']);
 						properties = schema.properties;
 						for(var i in properties){
-							var propDef = properties[i]; 
+							var propDef = properties[i];
 							if(propDef && (typeof propDef == 'object') && ("default" in propDef)){
 								self[i] = propDef["default"];
 							}
@@ -331,12 +325,12 @@ dojo.require("dojox.rpc.Rest");
 					dojo.mixin(self,data);
 				}
 				var idAttribute = jr.getIdAttribute(service);
-				Rest._index[this.__id = this.__clientId = 
-						service.servicePath + (this[idAttribute] || 
+				Rest._index[this.__id = this.__clientId =
+						service.servicePath + (this[idAttribute] ||
 							Math.random().toString(16).substring(2,14) + '@' + ((dojox.rpc.Client && dojox.rpc.Client.clientId) || "client"))] = this;
 				if(dojox.json.schema && properties){
 					dojox.json.schema.mustBeValid(dojox.json.schema.validate(this, service._schema));
-				} 
+				}
 				dirtyObjects.push({object:this, save: true});
 			};
 			return dojo.mixin(service._constructor, service._schema, {load:service});
@@ -366,7 +360,7 @@ dojo.require("dojox.rpc.Rest");
 		},
 		getServiceAndId: function(/*String*/absoluteId){
 			// summary:
-			//		Returns the REST service and the local id for the given absolute id. The result 
+			//		Returns the REST service and the local id for the given absolute id. The result
 			// 		is returned as an object with a service property and an id property
 			//	absoluteId:
 			//		This is the absolute id of the object
@@ -379,7 +373,7 @@ dojo.require("dojox.rpc.Rest");
 			}
 			if (serviceName){
 				return {service: jr.services[serviceName], id:absoluteId.substring(serviceName.length)};
-			}			
+			}
 			var parts = absoluteId.match(/^(.*\/)([^\/]*)$/);
 			return {service: new jr.serviceClass(parts[1], true), id:parts[2]};
 		},
@@ -415,17 +409,17 @@ dojo.require("dojox.rpc.Rest");
 				if(result.nodeType && result.cloneNode){
 					// return immediately if it is an XML document
 					return result;
-				}				
+				}
 				return resolveJson(service, deferred, result, typeof id != 'string' || (args && (args.start || args.count)) ? undefined: id);
 			});
-			return deferred;			
+			return deferred;
 		},
 		_loader: function(callback){
 			// load a lazy object
 			var serviceAndId = jr.getServiceAndId(this.__id);
 			var self = this;
 			jr.query(serviceAndId.service, serviceAndId.id).addBoth(function(result){
-				// if they are the same this means an object was loaded, otherwise it 
+				// if they are the same this means an object was loaded, otherwise it
 				// might be a primitive that was loaded or maybe an error
 				if(result == self){
 					// we can clear the flag, so it is a loaded object
@@ -452,6 +446,7 @@ dojo.require("dojox.rpc.Rest");
 		}
 		
 	};
-})();
 
+	return dojox.rpc.JsonRest;
+});
 
diff --git a/dojox/rpc/OfflineRest.js b/dojox/rpc/OfflineRest.js
index 29e4c23..c7ebd0f 100644
--- a/dojox/rpc/OfflineRest.js
+++ b/dojox/rpc/OfflineRest.js
@@ -1,13 +1,7 @@
-dojo.provide("dojox.rpc.OfflineRest");
-
-dojo.require("dojox.data.ClientFilter");
-dojo.require("dojox.rpc.Rest");
-dojo.require("dojox.storage");
-
+define("dojox/rpc/OfflineRest", ["dojo", "dojox", "dojox/data/ClientFilter", "dojox/rpc/Rest", "dojox/storage"], function(dojo, dojox) {
 // summary:
 // 		Makes the REST service be able to store changes in local
 // 		storage so it can be used offline automatically.
-(function(){
 	var Rest = dojox.rpc.Rest;
 	var namespace = "dojox_rpc_OfflineRest";
 	var loaded;
@@ -55,7 +49,7 @@ dojo.require("dojox.storage");
 	function sync(){
 		OfflineRest.sendChanges();
 		OfflineRest.downloadChanges();
-	} 
+	}
 	var syncId = setInterval(sync,15000);
 	dojo.connect(document, "ononline", sync);
 	OfflineRest = dojox.rpc.OfflineRest = {
@@ -104,11 +98,11 @@ dojo.require("dojox.storage");
 		}catch(e){
 			dfd = new dojo.Deferred();
 			dfd.errback(e);
-		} 
+		}
 		var sync = dojox.rpc._sync;
 		dfd.addCallback(function(result){
 			saveObject(result, service._getRequest(id).url);
-			return result;			
+			return result;
 		});
 		dfd.addErrback(function(error){
 			if(loaded){
@@ -176,7 +170,7 @@ dojo.require("dojox.storage");
 	function changeOccurred(method, absoluteId, contentId, serializedContent, service){
 		if(method=='delete'){
 			dojox.storage.remove(getStorageKey(absoluteId),namespace);
-		}		
+		}
 		else{
 			// both put and post should store the actual object
 			dojox.storage.put(getStorageKey(contentId), serializedContent, function(){
@@ -198,7 +192,7 @@ dojo.require("dojox.storage");
 			var method = message.event.toLowerCase();
 			var service = dojox.rpc.JsonRest && dojox.rpc.JsonRest.getServiceAndId(channel).service;
 			changeOccurred(
-				method, 
+				method,
 				channel,
 				method == "post" ? channel + message.result.id : channel,
 				dojo.toJson(message.result),
@@ -208,7 +202,7 @@ dojo.require("dojox.storage");
 		});
 	});
 	//FIXME: Should we make changes after a commit to see if the server rejected the change
-	// or should we come up with a revert mechanism? 
+	// or should we come up with a revert mechanism?
 	var defaultChange = Rest._change;
 	Rest._change = function(method,service,id,serializedContent){
 		if(!loaded){
@@ -237,16 +231,16 @@ dojo.require("dojox.storage");
 		var dirtyItem = dirty[dirtyId];
 		var serviceAndId = dojox.rpc.JsonRest.getServiceAndId(dirtyItem.id);
 		var deferred = defaultChange(dirtyItem.method,serviceAndId.service,serviceAndId.id,dirtyItem.content);
-		// add it to our list of dirty objects		
+		// add it to our list of dirty objects
 		dirty[dirtyId] = dirtyItem;
 		dojox.storage.put("dirty",dirty,function(){},namespace);
 		deferred.addBoth(function(result){
 			if (isNetworkError(result)){
-				// if a network error (offlineness) was the problem, we leave it 
+				// if a network error (offlineness) was the problem, we leave it
 				// dirty, and return to indicate successfulness
 				return null;
 			}
-			// it was successful or the server rejected it, we remove it from the dirty list 
+			// it was successful or the server rejected it, we remove it from the dirty list
 			var dirty = dojox.storage.get("dirty",namespace) || {};
 			delete dirty[dirtyId];
 			dojox.storage.put("dirty",dirty,function(){},namespace);
@@ -257,5 +251,6 @@ dojo.require("dojox.storage");
 		
 	dojo.connect(index,"onLoad",saveObject);
 	dojo.connect(index,"onUpdate",saveObject);
-	
-})();
+
+	return dojox.rpc.OfflineRest;
+});
diff --git a/dojox/rpc/ProxiedPath.js b/dojox/rpc/ProxiedPath.js
index 9450442..2738cf2 100644
--- a/dojox/rpc/ProxiedPath.js
+++ b/dojox/rpc/ProxiedPath.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.rpc.ProxiedPath");
-dojo.require("dojox.rpc.Service");
+define("dojox/rpc/ProxiedPath", ["dojo", "dojox", "dojox/rpc/Service"], function(dojo, dojox) {
 
 dojox.rpc.envelopeRegistry.register(
 	"PROXIED-PATH",function(str){return str == "PROXIED-PATH"},{
@@ -25,3 +24,5 @@ dojox.rpc.envelopeRegistry.register(
 		}
 	}
 );
+
+});
diff --git a/dojox/rpc/Rest.js b/dojox/rpc/Rest.js
index 24d68c1..8f56fb3 100644
--- a/dojox/rpc/Rest.js
+++ b/dojox/rpc/Rest.js
@@ -1,5 +1,5 @@
-dojo.provide("dojox.rpc.Rest"); 
-// Note: This doesn't require dojox.rpc.Service, and if you want it you must require it 
+define("dojox/rpc/Rest", ["dojo", "dojox"], function(dojo, dojox) {
+// Note: This doesn't require dojox.rpc.Service, and if you want it you must require it
 // yourself, and you must load it prior to dojox.rpc.Rest.
 
 // summary:
@@ -19,7 +19,6 @@ dojo.provide("dojox.rpc.Rest");
 //  	| services.myRestService.put("parameters","data to put in resource");
 //  	| services.myRestService.post("parameters","data to post to the resource");
 //  	| services.myRestService['delete']("parameters");
-(function(){
 	if(dojox.rpc && dojox.rpc.transportRegistry){
 		// register it as an RPC service if the registry is available
 		dojox.rpc.transportRegistry.register(
@@ -34,6 +33,12 @@ dojo.provide("dojox.rpc.Rest");
 						function(id, args){
 							var request = svc._getRequest(method,[id]);
 							request.url= request.target + (request.data ? '?'+  request.data : '');
+							if(args && (args.start >= 0 || args.count >= 0)){
+								request.headers = request.headers || {};
+								request.headers.Range = "items=" + (args.start || '0') + '-' +
+									(("count" in args && args.count != Infinity) ?
+										(args.count + (args.start || 0) - 1) : '');
+							}
 							return request;
 						}
 					);
@@ -83,13 +88,13 @@ dojo.provide("dojox.rpc.Rest");
 				id += (id ? "&" : "?") + "sort("
 				for(var i = 0; i<args.sort.length; i++){
 					var sort = args.sort[i];
-					id += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute); 
+					id += (i > 0 ? "," : "") + (sort.descending ? '-' : '+') + encodeURIComponent(sort.attribute);
 				}
 				id += ")";
 			}
 			var request = {
 				url: path + (id == null ? "" : id),
-				handleAs: isJson ? 'json' : 'text', 
+				handleAs: isJson ? 'json' : 'text',
 				contentType: isJson ? 'application/json' : 'text/plain',
 				sync: dojox.rpc._sync,
 				headers: {
@@ -97,7 +102,9 @@ dojo.provide("dojox.rpc.Rest");
 				}
 			};
 			if(args && (args.start >= 0 || args.count >= 0)){
-				request.headers.Range = "items=" + (args.start || '0') + '-' + ((args.count && args.count != Infinity && (args.count + (args.start || 0) - 1)) || '');
+				request.headers.Range = "items=" + (args.start || '0') + '-' +
+					(("count" in args && args.count != Infinity) ?
+						(args.count + (args.start || 0) - 1) : '');
 			}
 			dojox.rpc._sync = false;
 			return request;
@@ -131,4 +138,6 @@ dojo.provide("dojox.rpc.Rest");
 		// this is called to actually do the get
 		return index(dojo.xhrGet(service._getRequest(id, args)), service, (args.start >= 0 || args.count >= 0), id);
 	};
-})();
+
+	return dojox.rpc.Rest;
+});
diff --git a/dojox/rpc/SMDLibrary/twitter.smd b/dojox/rpc/SMDLibrary/twitter.smd
new file mode 100644
index 0000000..6c19b3a
--- /dev/null
+++ b/dojox/rpc/SMDLibrary/twitter.smd
@@ -0,0 +1,35 @@
+{
+	
+	"SMDVersion": "2.0",
+	"id": "http://apiwiki.twitter.com/w/page/22554756/Twitter-Search-API-Method:-search", 
+	"description": "Twitter Search API",
+		
+	"transport": "JSONP",
+	"envelope": "URL",
+	"additionalParameters": true,
+	
+	"parameters": [
+		// the most important param, the search query:
+		{ "name": "q", optional: false, "default":"" },
+		
+
+		// result size: large | small (8 or 4 per page)
+		{ "name": "rpp", optional:true, "default": 10 },
+
+		// language selection:
+		{ "name": "lang", optional:true, "default": "en" },
+
+		// starting page
+		{ "name": "page", optional:true, "default": 0 }
+
+	],
+
+	"services": {
+
+		"search": {
+			"target": "http://search.twitter.com/search.json",
+			"parameters": [
+			]
+		}		
+	}
+}
diff --git a/dojox/rpc/Service.js b/dojox/rpc/Service.js
index 911dbe9..f7c3ae5 100644
--- a/dojox/rpc/Service.js
+++ b/dojox/rpc/Service.js
@@ -1,6 +1,4 @@
-dojo.provide("dojox.rpc.Service");
-
-dojo.require("dojo.AdapterRegistry");
+define("dojox/rpc/Service", ["dojo", "dojox", "dojo.AdapterRegistry"], function(dojo, dojox) {
 
 dojo.declare("dojox.rpc.Service", null, {
 	constructor: function(smd, options){
@@ -22,7 +20,7 @@ dojo.declare("dojox.rpc.Service", null, {
 		//	description:
 		//		dojox.rpc.Service must be loaded prior to any plugin services like dojox.rpc.Rest
 		// 		dojox.rpc.JsonRpc in order for them to register themselves, otherwise you get
-		// 		a "No match found" error.  
+		// 		a "No match found" error.
 		var url;
 		var self = this;
 		function processSmd(smd){
@@ -150,12 +148,13 @@ dojo.declare("dojox.rpc.Service", null, {
 		return dojo.mixin(request, {
 			sync: dojox.rpc._sync,
 			contentType: contentType,
-			headers: {},
+			headers: method.headers || smd.headers || request.headers || {},
 			target: request.target || dojox.rpc.getTarget(smd, method),
 			transport: method.transport || smd.transport || request.transport,
 			envelope: method.envelope || smd.envelope || request.envelope,
 			timeout: method.timeout || smd.timeout,
 			callbackParamName: method.callbackParamName || smd.callbackParamName,
+			rpcObjectParamName: method.rpcObjectParamName || smd.rpcObjectParamName,
 			schema: schema,
 			handleAs: request.handleAs || "auto",
 			preventCache: method.preventCache || smd.preventCache,
@@ -286,7 +285,7 @@ dojox.rpc.transportRegistry.register(
 	function(str){ return str == "GET"; },
 	{
 		fire: function(r){
-			r.url=  r.target + (r.data ? '?'+  r.data : '');
+			r.url=  r.target + (r.data ? '?' + ((r.rpcObjectParamName) ? r.rpcObjectParamName + '=' : '') + r.data : '');
 			return dojo.xhrGet(r);
 		}
 	}
@@ -299,7 +298,7 @@ dojox.rpc.transportRegistry.register(
 	function(str){ return str == "JSONP"; },
 	{
 		fire: function(r){
-			r.url = r.target + ((r.target.indexOf("?") == -1) ? '?' : '&') + r.data;
+			r.url = r.target + ((r.target.indexOf("?") == -1) ? '?' : '&') + ((r.rpcObjectParamName) ? r.rpcObjectParamName + '=' : '') + r.data;
 			r.callbackParamName = r.callbackParamName || "callback";
 			return dojo.io.script.get(r);
 		}
@@ -317,3 +316,7 @@ dojo._contentHandlers.auto = function(xhr){
 		retContentType.match(/\/xml/) ? handlers.xml(xhr) : handlers.text(xhr);
 	return results;
 };
+
+return dojox.rpc.Service;
+
+});
diff --git a/dojox/rpc/test.txt b/dojox/rpc/test.txt
deleted file mode 100644
index 0478a6a..0000000
--- a/dojox/rpc/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-this is a test file i'm updating. Again, 11.
diff --git a/dojox/rpc/tests/Geonames.js b/dojox/rpc/tests/Geonames.js
index 0468f46..ca5a970 100644
--- a/dojox/rpc/tests/Geonames.js
+++ b/dojox/rpc/tests/Geonames.js
@@ -16,11 +16,11 @@ dojox.rpc.tests._testMethod = function(method){
                         var def = dojox.rpc.tests.service[method.name](method.parameters);
                         def.addCallback(this, function(result){
 				if (method.debugTest) {
-					console.log("Results: ", dojo.toJson(result));	
+					console.log("Results: ", dojo.toJson(result));
 				}
 				var testType = method.testType || "compare";
 				switch(testType){
-					case "compare":	
+					case "compare":
 						console.log("Comparison Test");
 		                                if (dojo.toJson(result)==method.expectedResult){
                                         		d.callback(true);
@@ -31,11 +31,11 @@ dojox.rpc.tests._testMethod = function(method){
 					case "result":
 						console.log("Result Test");
 						if (result && dojo.toJson(result)){
-							d.callback(true);	
+							d.callback(true);
 						}else{
 							d.errback(new Error("Unexpected Return Value, no result or not valid json: ", result));
 
-						}	
+						}
 						break;
 					default:
 						d.errback(new Error("Unknown test type"));
@@ -48,7 +48,7 @@ dojox.rpc.tests._testMethod = function(method){
         }
 };
 
-doh.register("dojox.rpc.tests.geonames", 
+doh.register("dojox.rpc.tests.geonames",
 	[
 		{
 			name: "#1, getCities()",
@@ -153,7 +153,7 @@ doh.register("dojox.rpc.tests.geonames",
                         runTest: dojox.rpc.tests._testMethod({
                                 name: "getCountryCode",
                                 parameters:{lat:40.78343, lng:-73.96625},
-				expectedResult: dojo.toJson({"distance":0,"countryName":"United States","countryCode":"US"}) 
+				expectedResult: dojo.toJson({"distance":0,"countryName":"United States","countryCode":"US"})
                         })
                 },
                 {
diff --git a/dojox/rpc/tests/Service.js b/dojox/rpc/tests/Service.js
index a235b1c..c513f6a 100644
--- a/dojox/rpc/tests/Service.js
+++ b/dojox/rpc/tests/Service.js
@@ -9,7 +9,7 @@ dojo.require("dojox.rpc.Client");
 
 dojox.rpc.tests.service = new dojox.rpc.Service(dojo.moduleUrl("dojox.rpc.tests.resources", "test.smd"));
 
-doh.register("dojox.rpc.tests.echo", 
+doh.register("dojox.rpc.tests.echo",
 	[
 		{
 			name: "#1 POST,URL,Named Parameters",
@@ -116,7 +116,7 @@ doh.register("dojox.rpc.tests.echo",
 				}
 
 				res = this.name + Math.random();
-				//test when given named params				
+				//test when given named params
 				var td = this.svc.restStore.put({location: "res"},res);
 				td.addCallback(this, function(result){
 					var td = this.svc.restStore({location: "res"});
diff --git a/dojox/rpc/tests/Wikipedia.js b/dojox/rpc/tests/Wikipedia.js
index 136bce8..5fc803f 100644
--- a/dojox/rpc/tests/Wikipedia.js
+++ b/dojox/rpc/tests/Wikipedia.js
@@ -26,7 +26,7 @@ dojox.rpc.tests.wikipediaService._query = function(q){
 	}
 };
 
-doh.register("dojox.rpc.tests.wikipedia", 
+doh.register("dojox.rpc.tests.wikipedia",
 	[
 		{
 			name: "#1, Wikipedia::parse",
diff --git a/dojox/rpc/tests/Yahoo.js b/dojox/rpc/tests/Yahoo.js
index e32bc93..1020e5d 100644
--- a/dojox/rpc/tests/Yahoo.js
+++ b/dojox/rpc/tests/Yahoo.js
@@ -26,7 +26,7 @@ dojox.rpc.tests.yahooService._testMethod = function(method){
 	}
 };
 
-doh.register("dojox.rpc.tests.yahoo", 
+doh.register("dojox.rpc.tests.yahoo",
 	[
 		{
 			name: "#1, Yahoo Answers::questionSearch",
diff --git a/dojox/rpc/tests/stores/JsonRestStore.js b/dojox/rpc/tests/stores/JsonRestStore.js
index d89cf25..444e268 100644
--- a/dojox/rpc/tests/stores/JsonRestStore.js
+++ b/dojox/rpc/tests/stores/JsonRestStore.js
@@ -6,21 +6,21 @@ dojo.require("dojox.rpc.Service");
 dojox.data.tests.stores.JsonRestStore.error = function(t, d, errData){
 	//  summary:
 	//		The error callback function to be used for all of the tests.
-	d.errback(errData);	
+	d.errback(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.data.tests.stores.JsonRestStore",
 	[
 		{
 			name: "Fetch some items",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonRestStore of a simple query.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						t.is(4, items.length);
 						d.callback(true);
@@ -33,10 +33,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "fetch by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Simple test of a basic fetch on JsonRestStore of a single item.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"obj1", 
+				jsonStore.fetch({query:"obj1",
 					onComplete: function(item, request){
 						t.is("Object 1", item.name);
 						t.t(jsonStore.hasAttribute(item,"name"));
@@ -52,10 +52,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Modify,save, check by id",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		Fetch an item from a query, modify and save it, and check to see if it was modified correctly
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						var now = new Date().getTime();
 						jsonStore.setValue(items[0],"updated",now);
@@ -81,10 +81,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Post, delete, and put",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"obj1", 
+				jsonStore.fetch({query:"obj1",
 					onComplete: function(item, request){
 						var now = new Date().getTime();
 						var testArray = item.testArray;
@@ -107,10 +107,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Revert",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		append/post an item, delete it, sort the lists, resort the list, saving each time.
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"obj1", 
+				jsonStore.fetch({query:"obj1",
 					onComplete: function(item, request){
 						jsonStore.setValue(item,"name","new name");
 						jsonStore.setValue(item,"newProp","new value");
@@ -132,10 +132,10 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Lazy loading",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		test lazy loading
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"query", 
+				jsonStore.fetch({query:"query",
 					onComplete: function(items, request){
 						/*var item = jsonStore.getValue(items,2); // sync lazy loading
 						t.is(item.name == 'Object 3');*/
@@ -152,16 +152,16 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "Array manipulation",
 			timeout:	10000, //10 seconds.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		test array manipulation
 				var d = new doh.Deferred();
-				jsonStore.fetch({query:"obj1", 
+				jsonStore.fetch({query:"obj1",
 					onComplete: function(item, request){
 						var testArray = item.testArray;
 						testArray.reverse();
 						testArray.unshift(testArray.pop());
 						jsonStore.onSave = function(data) {
-							t.is(data.length,1);						
+							t.is(data.length,1);
 							d.callback(true);
 							jsonStore.onSave = function(){};
 						};
@@ -176,7 +176,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			name: "ReadAPI:  Fetch_20_Streaming",
 			timeout:	10000, //10 seconds.  Json can sometimes be slow.
 			runTest: function(t) {
-				//	summary: 
+				//	summary:
 				//		fetching with paging
 
 				var d = new doh.Deferred();
@@ -193,7 +193,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 					d.callback(true);
 				}
 				//Get everything...
-				jsonStore.fetch({	
+				jsonStore.fetch({
 					query: "bigQuery",
 					onBegin: null,
 					count: 5,
@@ -205,7 +205,7 @@ doh.register("dojox.data.tests.stores.JsonRestStore",
 			}
 		},
 		function testReadAPI_functionConformance(t){
-			//	summary: 
+			//	summary:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
 			//	description:
 			//		Simple test read API conformance.  Checks to see all declared functions are actual functions on the instances.
diff --git a/dojox/secure/DOM.js b/dojox/secure/DOM.js
index 7423509..b1a4a93 100644
--- a/dojox/secure/DOM.js
+++ b/dojox/secure/DOM.js
@@ -32,7 +32,7 @@ dojox.secure.DOM = function(element){
 				return wrapped;
 			}
 			if(result && typeof result == 'object'){
-				if(result.__observable){ 
+				if(result.__observable){
 					// we have already wrapped it, this helps prevent circular/infinite loops
 					return result.__observable;
 				}
@@ -51,8 +51,8 @@ dojox.secure.DOM = function(element){
 			if(typeof result == 'function'){
 				var unwrap = function(result){
 					if(typeof result == 'function'){
-						// if untrusted code passes a function to trusted code, we want the trusted code to be 
-						// able to execute it and have the arguments automatically wrapped 
+						// if untrusted code passes a function to trusted code, we want the trusted code to be
+						// able to execute it and have the arguments automatically wrapped
 						return function(){
 							for (var i = 0; i < arguments.length; i++){
 								arguments[i] = wrap(arguments[i]);
@@ -60,10 +60,10 @@ dojox.secure.DOM = function(element){
 							return unwrap(result.apply(wrap(this),arguments));
 						}
 					}
-					return dojox.secure.unwrap(result);	
+					return dojox.secure.unwrap(result);
 				};
-				// when we wrap a function we make it so that we can untrusted code can execute 
-				// the function and the arguments will be unwrapped for the trusted code 
+				// when we wrap a function we make it so that we can untrusted code can execute
+				// the function and the arguments will be unwrapped for the trusted code
 				return function(){
 					if(result.safetyCheck){
 						result.safetyCheck.apply(unwrap(this),arguments);
@@ -91,7 +91,7 @@ dojox.secure.DOM = function(element){
 	}
 	function safeURL(url){
 		// test a url to see if it is safe
-		if(url.match(/:/) && !url.match(/^(http|ftp|mailto)/)){ 
+		if(url.match(/:/) && !url.match(/^(http|ftp|mailto)/)){
 			throw new Error("Unsafe URL " + url);
 		}
 	}
@@ -102,7 +102,7 @@ dojox.secure.DOM = function(element){
 				var src = el.src;
 				if (src && src != ""){
 					// load the src and evaluate it safely
-					el.parentNode.removeChild(el);					
+					el.parentNode.removeChild(el);
 					dojo.xhrGet({url:src,secure:true}).addCallback(function(result){
 						safeDoc.evaluate(result);
 					});
@@ -123,9 +123,9 @@ dojox.secure.DOM = function(element){
 						el.styleSheet.cssText = cssStr;
 					} else {// w3c
 						var cssText = doc.createTextNode(cssStr);
-						if (el.childNodes[0]) 
+						if (el.childNodes[0])
 							el.replaceChild(cssText,el.childNodes[0])
-						else 
+						else
 							el.appendChild(cssText);
 					 }
 					
@@ -144,9 +144,9 @@ dojox.secure.DOM = function(element){
 			if(el.style){
 				safeCSS(el.style.cssText);
 			}
-			if(el.href){		
+			if(el.href){
 				safeURL(el.href);
-			}		
+			}
 			if(el.src){
 				safeURL(el.src);
 			}
@@ -155,7 +155,7 @@ dojox.secure.DOM = function(element){
 				if(attr.name.substring(0,2)== "on" && attr.value != "null" && attr.value != ""){ // must remove all the event handlers
 					throw new Error("event handlers not allowed in the HTML, they must be set with element.addEventListener");
 				}
-			}		
+			}
 			var children = el.childNodes;
 			for (var i =0, l = children.length; i < l; i++){
 				safeElement(children[i]);
@@ -204,7 +204,7 @@ dojox.secure.DOM = function(element){
 			safeElement(args[newNodeArg]);  // check to make sure the new node is safe
 			return node[name](args[0]);// execute the method
 		};
-	} 
+	}
 	var invokers = {
 		appendChild : domChanger("appendChild",0),
 		insertBefore : domChanger("insertBefore",0),
@@ -219,7 +219,7 @@ dojox.secure.DOM = function(element){
 			});
 		}
 	};
-	invokers.childNodes = invokers.style = invokers.ownerDocument = function(){}; // this is a trick to get these property slots available, they will be overridden  
+	invokers.childNodes = invokers.style = invokers.ownerDocument = function(){}; // this is a trick to get these property slots available, they will be overridden
 	function makeObserver(setter){ // we make two of these, but the setter for style nodes is different
 		return dojox.lang.makeObservable(
 			function(node, prop){
@@ -240,18 +240,18 @@ dojox.secure.DOM = function(element){
 			if(setters[prop]){
 				setters[prop](node,value);
 			}
-			node[prop] = value; 
+			node[prop] = value;
 		});
-	var blockedStyles = {behavior:1,MozBinding:1}; 
+	var blockedStyles = {behavior:1,MozBinding:1};
 	var styleObserver = makeObserver(function(node, prop, value){
 			if(!blockedStyles[prop]){
 				node[prop] = safeCSS(value);
-			} 
-		}); 
+			}
+		});
 	wrap.safeHTML = safeHTML;
 	wrap.safeCSS = safeCSS;
 	return wrap;
 };
 dojox.secure.unwrap = function unwrap(result){
-	return (result && result.data__) || result; 
+	return (result && result.data__) || result;
 };
diff --git a/dojox/secure/capability.js b/dojox/secure/capability.js
index 01c4f7e..afb4ded 100644
--- a/dojox/secure/capability.js
+++ b/dojox/secure/capability.js
@@ -3,23 +3,23 @@ dojo.provide("dojox.secure.capability");
 dojox.secure.badProps = /^__|^(apply|call|callee|caller|constructor|eval|prototype|this|unwatch|valueOf|watch)$|__$/;
 dojox.secure.capability = {
 	keywords: ["break", "case", "catch", "const", "continue","debugger", "default", "delete", "do",
-		 "else", "enum","false", "finally", "for", "function","if", "in", "instanceof", "new", 
-		 "null","yield","return", "switch",  
+		 "else", "enum","false", "finally", "for", "function","if", "in", "instanceof", "new",
+		 "null","yield","return", "switch",
 		 "throw", "true", "try", "typeof", "var", "void", "while"],
 	validate : function(/*string*/script,/*Array*/safeLibraries,/*Object*/safeGlobals) {
 		// summary:
-		// 		pass in the text of a script. If it passes and it can be eval'ed, it should be safe. 
+		// 		pass in the text of a script. If it passes and it can be eval'ed, it should be safe.
 		// 		Note that this does not do full syntax checking, it relies on eval to reject invalid scripts.
 		// 		There are also known false rejections:
 		// 			Nesting vars inside blocks will not declare the variable for the outer block
-		// 	 		Named functions are not treated as declaration so they are generally not allowed unless the name is declared with a var.	
+		// 	 		Named functions are not treated as declaration so they are generally not allowed unless the name is declared with a var.
 		//			Var declaration that involve multiple comma delimited variable assignments are not accepted
 		//
 		// script:
 		// 		 the script to execute
 		//
 		// safeLibraries:
-		// 		The safe libraries that can be called (the functions can not be access/modified by the untrusted code, only called) 
+		// 		The safe libraries that can be called (the functions can not be access/modified by the untrusted code, only called)
 		//
 		// safeGlobals:
 		// 		These globals can be freely interacted with by the untrusted code
@@ -44,9 +44,9 @@ dojox.secure.capability = {
 			replace(/\/\/.*|\/\*[\w\W]*?\*\/|\/(\\[\/\\]|[^*\/])(\\.|[^\/\n\\])*\/[gim]*|("[^"]*")|('[^']*')/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) { 
+			replace(/\.\s*([a-z\$_A-Z][\w\$_]*)|([;,{])\s*([a-z\$_A-Z][\w\$_]*\s*):/g,function(t,prop,prefix,key) {
 				// find all the dot property references, all the object literal keys, and labels
-				prop = prop || key; 
+				prop = prop || key;
 				if(/^__|^(apply|call|callee|caller|constructor|eval|prototype|this|unwatch|valueOf|watch)$|__$/.test(prop)){
 					throw new Error("Illegal property name " + prop);
 				}
@@ -58,7 +58,7 @@ dojox.secure.capability = {
 			}
 		});
 		script = script.replace(new RegExp("(" + safeLibraries.join("|") + ")[\\s~]*\\(","g"),function(call) { // find library calls and make them look safe
-			return "new("; // turn into a known safe call 
+			return "new("; // turn into a known safe call
 		});
 		function findOuterRefs(block,func) {
 			var outerRefs = {};
@@ -84,12 +84,12 @@ dojox.secure.capability = {
 				outerRefs[identifier] = 1;
 			});
 			return outerRefs;
-		}	
+		}
 		var newScript,outerRefs;
 		function parseBlock(t,func,a,b,params,block) {
 			block.replace(/(^|,)0:\s*function#(\d+)/g,function(t,a,b) { // find functions in object literals
 			// note that if named functions are allowed, it could be possible to have label: function name() {} which is a security breach
-					var refs = blocks[b]; 
+					var refs = blocks[b];
 					refs[':method'] = 1;//mark it as a method
 			});
 			block = block.replace(/(^|[^_\w\$])Class\s*\(\s*([_\w\$]+\s*,\s*)*#(\d+)/g,function(t,p,a,b) { // find Class calls
@@ -112,11 +112,11 @@ dojox.secure.capability = {
 			}
 			block.replace(/(\W|^)(var) ([ \t,_\w\$]+)/g,parseVars); // and vars declare variables
 			// FIXME: Give named functions #name syntax so they can be detected as vars in outer scopes (but be careful of nesting)
-			return (a || '') + (b || '') + "#" + (blocks.push(outerRefs)-1); // return a block reference so the outer block can fetch it 
-		}	
+			return (a || '') + (b || '') + "#" + (blocks.push(outerRefs)-1); // return a block reference so the outer block can fetch it
+		}
 		do {
 			// get all the blocks, starting with inside and moving out, capturing the parameters of functions and catchs as variables along the way
-			newScript = script.replace(/((function|catch)(\s+[_\w\$]+)?\s*\(([^\)]*)\)\s*)?{([^{}]*)}/g, parseBlock); 
+			newScript = script.replace(/((function|catch)(\s+[_\w\$]+)?\s*\(([^\)]*)\)\s*)?{([^{}]*)}/g, parseBlock);
 		}
 		while(newScript != script && (script = newScript)); // keep going until we can't find anymore blocks
 		parseBlock(0,0,0,0,0,script); //findOuterRefs(script); // find the references in the outside scope
diff --git a/dojox/secure/fromJson.js b/dojox/secure/fromJson.js
new file mode 100644
index 0000000..e5ab8d7
--- /dev/null
+++ b/dojox/secure/fromJson.js
@@ -0,0 +1,241 @@
+dojo.provide("dojox.secure.fromJson");
+
+// Used with permission from Mike Samuel of Google (has CCLA), from the json-sans-eval project:
+// http://code.google.com/p/json-sans-eval/
+//	Mike Samuel <mikesamuel at gmail.com>
+
+
+
+dojox.secure.fromJson = typeof JSON != "undefined" ? JSON.parse :
+//	summary:
+//		Parses a string of well-formed JSON text.
+//	description:
+//		Parses a string of well-formed JSON text. If the input is not well-formed,
+//		then behavior is undefined, but it is
+//		deterministic and is guaranteed not to modify any object other than its
+//		return value.
+//
+//		This does not use `eval` so is less likely to have obscure security bugs than
+//		json2.js.
+//		It is optimized for speed, so is much faster than json_parse.js.
+//
+//		This library should be used whenever security is a concern (when JSON may
+//		come from an untrusted source), speed is a concern, and erroring on malformed
+//		JSON is *not* a concern.
+//
+//		json2.js is very fast, but potentially insecure since it calls `eval` to
+//		parse JSON data, so an attacker might be able to supply strange JS that
+//		looks like JSON, but that executes arbitrary javascript.
+//
+//		To configure dojox.secure.fromJson as the JSON parser for all Dojo
+// 		JSON parsing, simply do:
+//		|	dojo.require("dojox.secure.fromJson");
+//		|	dojo.fromJson = dojox.secure.fromJson;
+//		or alternately you could configure dojox.secure.fromJson to only handle
+// 		XHR responses:
+//		|	dojo._contentHandlers.json = function(xhr){
+//		|		return dojox.secure.fromJson.fromJson(xhr.responseText);
+//		|	};
+//
+//	json: String
+// 		per RFC 4627
+//	optReviver: Function (this:Object, string, *)
+// 		optional function
+//				that reworks JSON objects post-parse per Chapter 15.12 of EcmaScript3.1.
+//				If supplied, the function is called with a string key, and a value.
+//				The value is the property of 'this'.	The reviver should return
+//				the value to use in its place.	So if dates were serialized as
+//				{@code { "type": "Date", "time": 1234 }}, then a reviver might look like
+//				{@code
+//				function (key, value) {
+//					if (value && typeof value === 'object' && 'Date' === value.type) {
+//						return new Date(value.time);
+//					} else {
+//						return value;
+//					}
+//				}}.
+//				If the reviver returns {@code undefined} then the property named by key
+//				will be deleted from its container.
+//				{@code this} is bound to the object containing the specified property.
+//	returns: {Object|Array}
+(function () {
+	var number
+			= '(?:-?\\b(?:0|[1-9][0-9]*)(?:\\.[0-9]+)?(?:[eE][+-]?[0-9]+)?\\b)';
+	var oneChar = '(?:[^\\0-\\x08\\x0a-\\x1f\"\\\\]'
+			+ '|\\\\(?:[\"/\\\\bfnrt]|u[0-9A-Fa-f]{4}))';
+	var string = '(?:\"' + oneChar + '*\")';
+
+	// Will match a value in a well-formed JSON file.
+	// If the input is not well-formed, may match strangely, but not in an unsafe
+	// way.
+	// Since this only matches value tokens, it does not match whitespace, colons,
+	// or commas.
+	var jsonToken = new RegExp(
+			'(?:false|true|null|[\\{\\}\\[\\]]'
+			+ '|' + number
+			+ '|' + string
+			+ ')', 'g');
+
+	// Matches escape sequences in a string literal
+	var escapeSequence = new RegExp('\\\\(?:([^u])|u(.{4}))', 'g');
+
+	// Decodes escape sequences in object literals
+	var escapes = {
+		'"': '"',
+		'/': '/',
+		'\\': '\\',
+		'b': '\b',
+		'f': '\f',
+		'n': '\n',
+		'r': '\r',
+		't': '\t'
+	};
+	function unescapeOne(_, ch, hex) {
+		return ch ? escapes[ch] : String.fromCharCode(parseInt(hex, 16));
+	}
+
+	// A non-falsy value that coerces to the empty string when used as a key.
+	var EMPTY_STRING = new String('');
+	var SLASH = '\\';
+
+	// Constructor to use based on an open token.
+	var firstTokenCtors = { '{': Object, '[': Array };
+
+	var hop = Object.hasOwnProperty;
+
+	return function (json, opt_reviver) {
+		// Split into tokens
+		var toks = json.match(jsonToken);
+		// Construct the object to return
+		var result;
+		var tok = toks[0];
+		var topLevelPrimitive = false;
+		if ('{' === tok) {
+			result = {};
+		} else if ('[' === tok) {
+			result = [];
+		} else {
+			// The RFC only allows arrays or objects at the top level, but the JSON.parse
+			// defined by the EcmaScript 5 draft does allow strings, booleans, numbers, and null
+			// at the top level.
+			result = [];
+			topLevelPrimitive = true;
+		}
+
+		// If undefined, the key in an object key/value record to use for the next
+		// value parsed.
+		var key;
+		// Loop over remaining tokens maintaining a stack of uncompleted objects and
+		// arrays.
+		var stack = [result];
+		for (var i = 1 - topLevelPrimitive, n = toks.length; i < n; ++i) {
+			tok = toks[i];
+
+			var cont;
+			switch (tok.charCodeAt(0)) {
+				default:	// sign or digit
+					cont = stack[0];
+					cont[key || cont.length] = +(tok);
+					key = void 0;
+					break;
+				case 0x22:	// '"'
+					tok = tok.substring(1, tok.length - 1);
+					if (tok.indexOf(SLASH) !== -1) {
+						tok = tok.replace(escapeSequence, unescapeOne);
+					}
+					cont = stack[0];
+					if (!key) {
+						if (cont instanceof Array) {
+							key = cont.length;
+						} else {
+							key = tok || EMPTY_STRING;	// Use as key for next value seen.
+							break;
+						}
+					}
+					cont[key] = tok;
+					key = void 0;
+					break;
+				case 0x5b:	// '['
+					cont = stack[0];
+					stack.unshift(cont[key || cont.length] = []);
+					key = void 0;
+					break;
+				case 0x5d:	// ']'
+					stack.shift();
+					break;
+				case 0x66:	// 'f'
+					cont = stack[0];
+					cont[key || cont.length] = false;
+					key = void 0;
+					break;
+				case 0x6e:	// 'n'
+					cont = stack[0];
+					cont[key || cont.length] = null;
+					key = void 0;
+					break;
+				case 0x74:	// 't'
+					cont = stack[0];
+					cont[key || cont.length] = true;
+					key = void 0;
+					break;
+				case 0x7b:	// '{'
+					cont = stack[0];
+					stack.unshift(cont[key || cont.length] = {});
+					key = void 0;
+					break;
+				case 0x7d:	// '}'
+					stack.shift();
+					break;
+			}
+		}
+		// Fail if we've got an uncompleted object.
+		if (topLevelPrimitive) {
+			if (stack.length !== 1) { throw new Error(); }
+			result = result[0];
+		} else {
+			if (stack.length) { throw new Error(); }
+		}
+
+		if (opt_reviver) {
+			// Based on walk as implemented in http://www.json.org/json2.js
+			var walk = function (holder, key) {
+				var value = holder[key];
+				if (value && typeof value === 'object') {
+					var toDelete = null;
+					for (var k in value) {
+						if (hop.call(value, k) && value !== holder) {
+							// Recurse to properties first.	This has the effect of causing
+							// the reviver to be called on the object graph depth-first.
+
+							// Since 'this' is bound to the holder of the property, the
+							// reviver can access sibling properties of k including ones
+							// that have not yet been revived.
+
+							// The value returned by the reviver is used in place of the
+							// current value of property k.
+							// If it returns undefined then the property is deleted.
+							var v = walk(value, k);
+							if (v !== void 0) {
+								value[k] = v;
+							} else {
+								// Deleting properties inside the loop has vaguely defined
+								// semantics in ES3 and ES3.1.
+								if (!toDelete) { toDelete = []; }
+								toDelete.push(k);
+							}
+						}
+					}
+					if (toDelete) {
+						for (var i = toDelete.length; --i >= 0;) {
+							delete value[toDelete[i]];
+						}
+					}
+				}
+				return opt_reviver.call(holder, key, value);
+			};
+			result = walk({ '': result }, '');
+		}
+
+		return result;
+	};
+})();
\ No newline at end of file
diff --git a/dojox/secure/sandbox.js b/dojox/secure/sandbox.js
index 024185e..4d2196d 100644
--- a/dojox/secure/sandbox.js
+++ b/dojox/secure/sandbox.js
@@ -7,7 +7,7 @@ dojo.require("dojo.NodeList-fx");
 	var oldTimeout = setTimeout;
 	var oldInterval = setInterval;
 	if({}.__proto__){
-		// mozilla has unsafe methods on array	
+		// mozilla has unsafe methods on array
 		var fixMozArrayFunction = function (name) {
 			var method = Array.prototype[name];
 			if(method && !method.fixed){
@@ -46,7 +46,7 @@ dojo.require("dojo.NodeList-fx");
 		//		The DOM element to use as the container for the sandbox
 		//
 		//	description:
-		//		This function will create and return a sandbox object (see dojox.secure.__Sandbox) 
+		//		This function will create and return a sandbox object (see dojox.secure.__Sandbox)
 		// 		for the provided element.
 		var wrap = dojox.secure.DOM(element);
 		element = wrap(element);
@@ -58,7 +58,7 @@ dojo.require("dojo.NodeList-fx");
 										"alert","confirm","prompt", // some people may not want to allow these to be called, but they don't break capability-limiting
 										"Error","EvalError","RangeError","ReferenceError","SyntaxError","TypeError",
 										"Date","RegExp","Number","Object","Array","String","Math",
-										//"ADSAFE", // not using ADSAFE runtime for the time being 
+										//"ADSAFE", // not using ADSAFE runtime for the time being
 										"setTimeout","setInterval","clearTimeout","clearInterval", // we make these safe below
 										"dojo","get","set","forEach","load","evaluate"];
 	   	for(var i in dojo){
@@ -66,7 +66,7 @@ dojo.require("dojo.NodeList-fx");
 	    	imports.push("var " + i + "=dojo." + i); // add to the list of imports
 	    }
 		// open the dojo namespace (namespaces are pretty silly in an environment where you can't set globals)
-	   	eval(imports.join(";")); 
+	   	eval(imports.join(";"));
 		function get(obj,prop) {
 			// basic access by index function
 			prop = '' + prop;
@@ -76,7 +76,7 @@ dojo.require("dojo.NodeList-fx");
 			if(obj.__get__) {
 				return obj.__get__(prop);
 			}
-			return obj[prop];		
+			return obj[prop];
 		}
 		function set(obj,prop,value) {
 			// basic set by index function
@@ -89,7 +89,7 @@ dojo.require("dojo.NodeList-fx");
 			return value;
 		}
 		function forEach(obj,fun) {
-			//	short syntax iterator function 
+			//	short syntax iterator function
 			if(typeof fun != "function"){
 				throw new TypeError();
 			}
@@ -122,40 +122,40 @@ dojo.require("dojo.NodeList-fx");
 			}
 		}
 		function Class(/*Function*/superclass, /*Object*/properties, /*Object*/classProperties) {
-			// summary: 
+			// summary:
 			// 		A safe class constructor
-			// 
-			// superclass: 
-			// 		There may be zero or more superclass arguments. The constructed class 
-			// 		will inherit from any provided superclasses, protypically from the first, 
+			//
+			// superclass:
+			// 		There may be zero or more superclass arguments. The constructed class
+			// 		will inherit from any provided superclasses, protypically from the first,
 			// 		via mixin for the subsequent. Later arguments
-			// 		will override properties/methods from earlier arguments 
-			// 
-			// properties: 
+			// 		will override properties/methods from earlier arguments
+			//
+			// properties:
 			// 		The constructed
-			// 		"class" will also have the methods/properties defined in this argument. 
+			// 		"class" will also have the methods/properties defined in this argument.
 			//		These methods may utilize the <em>this</em> operator, and they
-			// 		are only the code that has access to <em>this</em>. Inner functions 
-			// 		are also prohibited from using <em>this</em>. 
+			// 		are only the code that has access to <em>this</em>. Inner functions
+			// 		are also prohibited from using <em>this</em>.
 			//
-			// 		If no superclasses are provided, this object will be the prototype of the 
+			// 		If no superclasses are provided, this object will be the prototype of the
 			// 		constructed class (no copying
 			// 		will be done). Consequently you can "beget" by calling new (Class(obj)).
 			// 		All methods are "bound", each call results in |this| safety checking call.
 			//
-			// classProperties: 
+			// classProperties:
 			// 		This properties will be copied to the new class function.
 			//
 			// 		Note that neither dojo.declare nor dojo.extend are acceptable class constructors as
 			// 		they are completely unsecure. This class constructor is conceptually based on declare
-			// 		but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc. 
+			// 		but also somewhat influenced by base2, prototype, YUI, resig's patterns, etc.
 			//
 			// example:
 			// |	var Car = Class({drive:function(speed) { ... } ); // create a Car class with a "drive" method
 			// |	var FastCar = Class(Car,{driveFast: function(speed) { return this.drive(2 * speed); } }); // create a FastCar that extends Car
 			// |	var fastCar = new FastCar; // instantiate
 			// |	fastCar.driveFast(50); // call a method
-			// |	var driveFast = fastCar.driveFast; 
+			// |	var driveFast = fastCar.driveFast;
 			// |	var driveFast(50); // this will throw an error, the method can be used with an object that is not an instance of FastCar
 			var proto,superConstructor,ourConstructor;
 			var arg;
@@ -163,7 +163,7 @@ dojo.require("dojo.NodeList-fx");
 				// go through each superclass argument
 				if(proto) { // we have a prototype now, we must mixin now
 					mixin(proto,arg.prototype);
-				}  
+				}
 				else {
 					// this is the first argument, so we can define the prototype ourselves
 					// link up the prototype chain to the superclass's prototype, so we are a subtype
@@ -184,7 +184,7 @@ dojo.require("dojo.NodeList-fx");
 							if(this instanceof Class){
 								return arguments.callee.__rawMethod__.apply(this,arguments);
 							}
-							throw new Error("Method called on wrong object");	
+							throw new Error("Method called on wrong object");
 						};
 						arg[j].__rawMethod__ = value; // may want to use this for reconstruction and toString,valueOf
 					}
@@ -195,16 +195,16 @@ dojo.require("dojo.NodeList-fx");
 			}
 			proto = proto ? mixin(proto,arg) : arg; // if there is no proto yet, we can use the provided object
 			function Class() {
-				// the super class may not have been constructed using the same technique, we will just call the constructor 
+				// the super class may not have been constructed using the same technique, we will just call the constructor
 				if(superConstructor){
 					superConstructor.apply(this,arguments);
-				} 
+				}
 				if(ourConstructor){
 					ourConstructor.apply(this,arguments);
 				}
 			}
 			mixin(Class,arguments[i]); // the optional second object adds properties to the class
-			proto.constructor = Class; 
+			proto.constructor = Class;
 			Class.prototype = proto;
 			return Class;
 		}
@@ -215,12 +215,12 @@ dojo.require("dojo.NodeList-fx");
 		}
 		function setTimeout(func,time) {
 			// sandboxed setTimeout
-			checkString(func); 
+			checkString(func);
 			return oldTimeout(func,time);
 		}
 		function setInterval(func,time) {
 			// sandboxed setInterval
-			checkString(func); 
+			checkString(func);
 			return oldInterval(func,time);
 		}
 		function evaluate(script){
@@ -232,8 +232,8 @@ dojo.require("dojo.NodeList-fx");
 			if (url.match(/^[\w\s]*:/)){
 				throw new Error("Access denied to cross-site requests");
 			}
-			return xhrGet({url:(new dojo._Url(wrap.rootUrl,url))+'',secure:true}); 
-		}  
+			return xhrGet({url:(new dojo._Url(wrap.rootUrl,url))+'',secure:true});
+		}
 		wrap.evaluate = function(script){
 			//if(!alreadyValidated) {
 			dojox.secure.capability.validate(script,safeCalls, // the safe dojo library and standard operators
@@ -252,9 +252,9 @@ dojo.require("dojo.NodeList-fx");
 		return /*===== dojo.declare("dojox.secure.__Sandbox", null, =====*/ { // dojox.secure.__Sandbox
 			loadJS : function(url){
 				//	summary:
-				// 		Loads the script from the given URL using XHR (assuming 
+				// 		Loads the script from the given URL using XHR (assuming
 				// 		a plugin system is in place for cross-site requests) within the sandbox
-				//	
+				//
 				//	url:
 				//		The url of the script to load
 				wrap.rootUrl = url;
@@ -279,7 +279,7 @@ dojo.require("dojo.NodeList-fx");
 			evaluate : function(script){
 				//	summary:
 				//		Evaluates the given script within the sandbox
-				//	
+				//
 				//	script:
 				//		The JavaScript text to evaluate
 				return wrap.evaluate(script);
@@ -287,9 +287,9 @@ dojo.require("dojo.NodeList-fx");
 			// TODO: could add something for pre-validated scripts
 		}/*===== ) =====*/;
 	};
-})(); 
+})();
 dojox.secure._safeDojoFunctions = function(element,wrap) {
-	//	Creates a safe subset of Dojo core library 
+	//	Creates a safe subset of Dojo core library
 	var safeFunctions = ["mixin","require","isString","isArray","isFunction","isObject","isArrayLike","isAlien",
 	"hitch","delegate","partial","trim","disconnect","subscribe","unsubscribe","Deferred","toJson","style","attr"];
 	//var domFunctions = ["clone","byId"];
@@ -316,9 +316,9 @@ dojox.secure._safeDojoFunctions = function(element,wrap) {
 		connect: function(el,event) {
 			var obj = el;
 			arguments[0] = unwrap(el);
-			if(obj!=arguments[0] && event.substring(0,2) != 'on'){ 
+			if(obj!=arguments[0] && event.substring(0,2) != 'on'){
 				// it is probably an element, and it doesn't look like an event handler, probably not safe
-				throw new Error("Invalid event name for element");				
+				throw new Error("Invalid event name for element");
 			}
 			return dojo.connect.apply(dojo,arguments);
 		},
@@ -330,13 +330,13 @@ dojox.secure._safeDojoFunctions = function(element,wrap) {
 		},
 		fromJson : function(str) {
 			// make sure it is safe before passing it to the unsafe dojo.fromJson
-			dojox.secure.capability.validate(str,[],{}); 
+			dojox.secure.capability.validate(str,[],{});
 			return dojo.fromJson(str);
 		}
 	};
 	for (var i = 0; i < safeFunctions.length; i++) {
 		safe[safeFunctions[i]] = dojo[safeFunctions[i]];
-	} 
+	}
 	return safe;
 };
 
diff --git a/dojox/secure/tests/DOM.js b/dojox/secure/tests/DOM.js
index 38360ef..e0c571c 100644
--- a/dojox/secure/tests/DOM.js
+++ b/dojox/secure/tests/DOM.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.secure.tests.DOM");
 dojo.require("dojox.secure.DOM");
 
-doh.register("dojox.secure.tests.DOM.good", 
+doh.register("dojox.secure.tests.DOM.good",
 	[
 		function setup(){
 			var div = document.createElement("div");
@@ -49,7 +49,7 @@ doh.register("dojox.secure.tests.DOM.good",
 		},*/
 		function addOnclickHandler(t){
 			securedElement.addEventListener("click",function(event) {
-				alert('proper click handler');	
+				alert('proper click handler');
 			});
 			
 		}
@@ -68,7 +68,7 @@ function violater(func) {
 		t.f(insecure);
 	}};
 }
-doh.register("dojox.secure.tests.DOM.bad", 
+doh.register("dojox.secure.tests.DOM.bad",
 	[
 		function parentNode(t){
 			t.f(securedElement.parentNode);
@@ -139,16 +139,16 @@ doh.register("dojox.secure.tests.DOM.bad",
 			}
 		},
 		/*violater(function addStyleTag(t) {
-			securedElement.innerHTML = "<style>div {color:expression(alert(\"hello\")}</style><div>test</div>";		
+			securedElement.innerHTML = "<style>div {color:expression(alert(\"hello\")}</style><div>test</div>";
 		}),
 		violater(function addStyleTag2(t) {
-			securedElement.innerHTML = "<style>@import 'unsafe.css'</style><div>unsafe css</div>";		
+			securedElement.innerHTML = "<style>@import 'unsafe.css'</style><div>unsafe css</div>";
 		}),*/
 		function addJavaScriptHref(t) {
-			securedElement.innerHTML = "<a href='javascript:alert(3)'>illegal link</a>";		
+			securedElement.innerHTML = "<a href='javascript:alert(3)'>illegal link</a>";
 		},
 		/*violater(function addNullCharSrc(t) {
-			securedElement.innerHTML = "<a href='java�script:alert(3)'>illegal link</a>";		
+			securedElement.innerHTML = "<a href='java�script:alert(3)'>illegal link</a>";
 		}),*/
 		function addOnclickHandler(t) {
 			try{
diff --git a/dojox/secure/tests/fromJson.js b/dojox/secure/tests/fromJson.js
new file mode 100644
index 0000000..4bd08e9
--- /dev/null
+++ b/dojox/secure/tests/fromJson.js
@@ -0,0 +1,150 @@
+dojo.provide("dojox.secure.tests.fromJson");
+dojo.require("dojox.secure.fromJson");
+dojo.require("dojox.secure.tests.otherParsers");
+
+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 = dojo.toJson(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 = dojo.toJson(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 = dojo.toJson(largeDataSet);
+
+
+doh.register("dojox.secure.tests.fromJson",
+	[
+		function small(){
+			for(var i = 0;i < 1000;i++){
+				dojox.secure.fromJson(smallJson);
+			}
+		},
+		function medium(){
+			for(var i = 0;i < 100;i++){
+				dojox.secure.fromJson(mediumJson);
+			}
+		},
+		function large(){
+			for(var i = 0;i < 100;i++){
+				dojox.secure.fromJson(largeJson);
+			}
+		},
+		function smallUnsecure(){
+			for(var i = 0;i < 1000;i++){
+				dojo.fromJson(smallJson);
+			}
+		},
+		function mediumUnsecure(){
+			for(var i = 0;i < 100;i++){
+				dojo.fromJson(mediumJson);
+			}
+		},
+		function largeUnsecure(){
+			for(var i = 0;i < 100;i++){
+				dojo.fromJson(largeJson);
+			}
+		},
+		function smallNative(){
+			for(var i = 0;i < 1000;i++){
+				JSON.parse(smallJson);
+			}
+		},
+		function mediumNative(){
+			for(var i = 0;i < 100;i++){
+				JSON.parse(mediumJson);
+			}
+		},
+		function largeNative(){
+			for(var i = 0;i < 100;i++){
+				JSON.parse(largeJson);
+			}
+		},
+		function smallJson2(){
+			for(var i = 0;i < 1000;i++){
+				json2.parse(smallJson);
+			}
+		},
+		function mediumJson2(){
+			for(var i = 0;i < 100;i++){
+				json2.parse(mediumJson);
+			}
+		},
+		function largeJson2(){
+			for(var i = 0;i < 100;i++){
+				json2.parse(largeJson);
+			}
+		},
+		function smallJsonParse(){
+			for(var i = 0;i < 100;i++){
+				json_parse(smallJson);
+			}
+		},
+		function mediumJsonParse(){
+			for(var i = 0;i < 10;i++){
+				json_parse(mediumJson);
+			}
+		},
+		function largeJsonParse(){
+			for(var i = 0;i < 10;i++){
+				json_parse(largeJson);
+			}
+		}
+	]
+);
+
diff --git a/dojox/secure/tests/sandbox.js b/dojox/secure/tests/sandbox.js
index 5e58293..7d09d17 100644
--- a/dojox/secure/tests/sandbox.js
+++ b/dojox/secure/tests/sandbox.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.secure.tests.secure");
 dojo.require("dojox.secure.secure");
 
-doh.register("dojox.secure.tests.secure.good", 
+doh.register("dojox.secure.tests.secure.good",
 	[
 		function setup(){
 			var div = document.createElement("div");
@@ -15,7 +15,7 @@ doh.register("dojox.secure.tests.secure.good",
 			container = document.createElement("div");
 			container.style.backgroundColor = "cyan";
 			container.style.color = "black";
-			div.appendChild(container);			
+			div.appendChild(container);
 		},
 		function innerHTML(t){
 			dojox.secure.evaluate("element.innerHTML = 'Hi there';",container);
@@ -40,7 +40,7 @@ function violater(func) {
 		t.f(insecure);
 	}};
 }
-doh.register("dojox.secure.tests.secure.bad", 
+doh.register("dojox.secure.tests.secure.bad",
 	[
 		function parentNode(t){
 			t.f(dojox.secure.evaluate("document.body",container));
@@ -111,10 +111,10 @@ doh.register("dojox.secure.tests.secure.bad",
 			}
 		},
 		violater(function addStyleTag(t) {
-			securedElement.innerHTML = "<style>div {color:expression(alert(\"hello\")}</style><div>test</div>";		
+			securedElement.innerHTML = "<style>div {color:expression(alert(\"hello\")}</style><div>test</div>";
 		}),
 		violater(function addStyleTag2(t) {
-			securedElement.innerHTML = "<style>@import 'unsafe.css'</style><div>unsafe css</div>";		
+			securedElement.innerHTML = "<style>@import 'unsafe.css'</style><div>unsafe css</div>";
 		})*/
 	]);
 	
\ No newline at end of file
diff --git a/dojox/sketch/Annotation.js b/dojox/sketch/Annotation.js
index c99c8fb..0616c3b 100644
--- a/dojox/sketch/Annotation.js
+++ b/dojox/sketch/Annotation.js
@@ -12,7 +12,7 @@ dojo.require("dojox.sketch._Plugin");
 			if(!this._omd){
 				return;
 			}
-			if(this._cshape){ 
+			if(this._cshape){
 				this._cshape.setShape(rect);
 			} else {
 				this._cshape=this.figure.surface.createRect(rect)
@@ -27,7 +27,7 @@ dojo.require("dojox.sketch._Plugin");
 			}
 			this._omd=false;
 			var f=this.figure;
-			if(this._cshape){ 
+			if(this._cshape){
 				f.surface.remove(this._cshape);
 				delete this._cshape;
 			}
@@ -36,8 +36,8 @@ dojo.require("dojox.sketch._Plugin");
 				//		gets drawn.
 				var limit=10;
 				if(Math.max(
-					limit, 
-					Math.abs(f._absEnd.x-f._start.x), 
+					limit,
+					Math.abs(f._absEnd.x-f._start.x),
 					Math.abs(f._absEnd.y-f._start.y)
 				)>limit){
 					this._create(f._start, f._end);
@@ -51,17 +51,17 @@ dojo.require("dojox.sketch._Plugin");
 			var _=f.nextKey();
 			var a=new (this.annotation)(f, _);
 			a.transform={
-				dx:f._calCol(start.x/f.zoomFactor), 
+				dx:f._calCol(start.x/f.zoomFactor),
 				dy:f._calCol(start.y/f.zoomFactor)
 			};
-			a.end={ 
-				x:f._calCol(end.x/f.zoomFactor), 
-				y:f._calCol(end.y/f.zoomFactor) 
+			a.end={
+				x:f._calCol(end.x/f.zoomFactor),
+				y:f._calCol(end.y/f.zoomFactor)
 			};
 			if(a.control){
-				a.control={ 
+				a.control={
 					x:f._calCol((end.x/2)/f.zoomFactor),
-					y:f._calCol((end.y/2)/f.zoomFactor) 
+					y:f._calCol((end.y/2)/f.zoomFactor)
 				};
 			}
 			f.onBeforeCreateShape(a);
@@ -88,8 +88,8 @@ dojo.require("dojox.sketch._Plugin");
 			'label': ""
 		};
 
-		if(this.figure){ 
-			this.figure.add(this); 
+		if(this.figure){
+			this.figure.add(this);
 		}
 	};
 
@@ -154,10 +154,10 @@ dojo.require("dojox.sketch._Plugin");
 		dx:function(p1, p2, dy){
 			var s=this.slope(p1,p2);
 			if(s==0){ return s; }
-			return dy/s; 
+			return dy/s;
 		},
-		dy:function(p1, p2, dx){ 
-			return this.slope(p1,p2)*dx; 
+		dy:function(p1, p2, dx){
+			return this.slope(p1,p2)*dx;
 		}
 	};
 	p.drawBBox=function(){
@@ -170,8 +170,8 @@ dojo.require("dojox.sketch._Plugin");
 			this.boundingBox.getEventSource().setAttribute("id",this.id+"-boundingBox");
 			this.boundingBox.getEventSource().setAttribute("shape-rendering","crispEdges");
 			this.figure._add(this);
-		} else { 
-			this.boundingBox.setShape(r); 
+		} else {
+			this.boundingBox.setShape(r);
 		}
 	};
 	p.setBinding=function(pt){
@@ -204,8 +204,8 @@ dojo.require("dojox.sketch._Plugin");
 				this.boundingBox=null;
 			}
 		}
-		for(var p in this.anchors){ 
-			this.anchors[p][method](); 
+		for(var p in this.anchors){
+			this.anchors[p][method]();
 		}
 	};
 	p.zoom=function(pct){
diff --git a/dojox/sketch/DoubleArrowAnnotation.js b/dojox/sketch/DoubleArrowAnnotation.js
index e6084b8..4048e3d 100644
--- a/dojox/sketch/DoubleArrowAnnotation.js
+++ b/dojox/sketch/DoubleArrowAnnotation.js
@@ -55,15 +55,15 @@ dojo.require("dojox.sketch.Anchor");
 		if(this.control.y<this.end.y){ offset*=-1; }
 		else { offset+=this.textYOffset; }
 		var ab={
-			x:((this.control.x-this.start.x)*.5)+this.start.x, 
+			x:((this.control.x-this.start.x)*.5)+this.start.x,
 			y:((this.control.y-this.start.y)*.5)+this.start.y
 		};
 		var bc={
-			x:((this.end.x-this.control.x)*.5)+this.control.x, 
+			x:((this.end.x-this.control.x)*.5)+this.control.x,
 			y:((this.end.y-this.control.y)*.5)+this.control.y
 		};
 		this.textPosition={
-			x:((bc.x-ab.x)*.5)+ab.x, 
+			x:((bc.x-ab.x)*.5)+ab.x,
 			y:(((bc.y-ab.y)*.5)+ab.y)+offset
 		};
 	};
@@ -135,9 +135,9 @@ dojo.require("dojox.sketch.Anchor");
 		this.endArrow=this.endArrowGroup.createPath();//("M" + this.end.x + "," + this.end.y + " l-20,-5 3,5 -3,5 Z").setFill(this.property('fill'));
 
 		this.labelShape=this.shape.createText({
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label'), 
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label'),
 				align:this.textAlign
 			})
 			//.setFont(font)
@@ -176,8 +176,8 @@ dojo.require("dojox.sketch.Anchor");
 		this.endArrowGroup.setTransform(endRot);
 		this.endArrow.setFill(this.property('fill'));
 		this.labelShape.setShape({
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
+				x:this.textPosition.x,
+				y:this.textPosition.y,
 				text:this.property('label')
 			})
 			.setFill(this.property('fill'));
diff --git a/dojox/sketch/Figure.js b/dojox/sketch/Figure.js
index 2fd6d13..437ed3c 100644
--- a/dojox/sketch/Figure.js
+++ b/dojox/sketch/Figure.js
@@ -64,10 +64,10 @@ dojo.require("dojox.sketch.UndoStack");
 			return obj;
 		};
 		this.clearSelections=function(){
-			for(var i=0; i<self.selected.length; i++){ 
+			for(var i=0; i<self.selected.length; i++){
 				self.selected[i].setMode(ta.Annotation.Modes.View);
 			}
-			self.selected=[]; 
+			self.selected=[];
 		};
 		this.replaceSelection=function(n, o){
 			if(!self.isSelected(o)){
@@ -77,7 +77,7 @@ dojo.require("dojox.sketch.UndoStack");
 			var idx=-1;
 			for(var i=0; i<self.selected.length; i++){
 				if(self.selected[i]==o){
-					idx=i; 
+					idx=i;
 					break;
 				}
 			}
@@ -134,7 +134,7 @@ dojo.require("dojox.sketch.UndoStack");
 		//	drag handlers.
 		this._md=function(e){
 			//in IE, when clicking into the drawing canvas, the node does not get focused,
-			//do it manually here to force it, otherwise the keydown event listener is 
+			//do it manually here to force it, otherwise the keydown event listener is
 			//never triggered in IE.
 			if(dojox.gfx.renderer=='vml'){
 				self.node.focus();
@@ -337,7 +337,7 @@ dojo.require("dojox.sketch.UndoStack");
 		}
 	};
 	p._get=function(key){
-		if(key&&key.indexOf("bounding")>-1){ 
+		if(key&&key.indexOf("bounding")>-1){
 			key=key.replace("-boundingBox","");
 		}else if(key&&key.indexOf("-labelShape")>-1){
 			key=key.replace("-labelShape","");
@@ -455,15 +455,15 @@ dojo.require("dojox.sketch.UndoStack");
 		//	create from pseudo-DOM
 		if(this.surface){ this.destroy(true); }
 		var node=obj.documentElement;	//	should be either the document or the docElement
-		this.size={ 
-			w:parseFloat(node.getAttribute('width'),10), 
-			h:parseFloat(node.getAttribute('height'),10) 
+		this.size={
+			w:parseFloat(node.getAttribute('width'),10),
+			h:parseFloat(node.getAttribute('height'),10)
 		};
 		var g=node.childrenByName("g")[0];
 		var img=g.childrenByName("image")[0];
 		this.imageSize={
-			w:parseFloat(img.getAttribute('width'),10), 
-			h:parseFloat(img.getAttribute('height'),10) 
+			w:parseFloat(img.getAttribute('width'),10),
+			h:parseFloat(img.getAttribute('height'),10)
 		};
 		this.imageSrc=img.getAttribute("xlink:href");
 		this.initialize(n);
@@ -516,7 +516,7 @@ dojo.require("dojox.sketch.UndoStack");
 			+ 'xmlns:dojoxsketch="http://dojotoolkit.org/dojox/sketch" '
 			+ 'width="' + this.size.w + '" height="' + this.size.h + '">'
 			+ '<g>'
-			+ '<image xlink:href="' + this.imageSrc + '" x="0" y="0" width="' 
+			+ '<image xlink:href="' + this.imageSrc + '" x="0" y="0" width="'
 			+ this.size.w + '" height="' + this.size.h + '" />';
 		for(var i=0; i<this.shapes.length; i++){ s+= this.shapes[i].serialize(); }
 		s += '</g></svg>';
diff --git a/dojox/sketch/LeadAnnotation.js b/dojox/sketch/LeadAnnotation.js
index 7d7fc65..f9a88ef 100644
--- a/dojox/sketch/LeadAnnotation.js
+++ b/dojox/sketch/LeadAnnotation.js
@@ -36,10 +36,10 @@ dojo.require("dojox.sketch.Anchor");
 		this.textAlign="middle";
 		if(Math.abs(slope)>=1){
 			x=this.end.x+this.calculate.dx(this.control, this.end, offset);
-			if(this.control.y>this.end.y){ 
-				y=this.end.y-offset; 
-			} else { 
-				y=this.end.y+offset+this.textYOffset; 
+			if(this.control.y>this.end.y){
+				y=this.end.y-offset;
+			} else {
+				y=this.end.y+offset+this.textYOffset;
 			}
 		} else if(slope==0){
 			x=this.end.x+offset;
@@ -54,7 +54,7 @@ dojo.require("dojox.sketch.Anchor");
 			}
 			if(this.start.y<this.end.y){
 				y=this.end.y+this.calculate.dy(this.control, this.end, offset)+this.textYOffset;
-			} else { 
+			} else {
 				y=this.end.y+this.calculate.dy(this.control, this.end, -offset);
 			}
 		}
@@ -67,7 +67,7 @@ dojo.require("dojox.sketch.Anchor");
 		
 		for(var i=0; i<obj.childNodes.length; i++){
 			var c=obj.childNodes[i];
-			if(c.localName=="text"){ 
+			if(c.localName=="text"){
 				this.property('label',c.childNodes.length?c.childNodes[0].nodeValue:'');
 			}
 			else if(c.localName=="path"){
@@ -107,9 +107,9 @@ dojo.require("dojox.sketch.Anchor");
 		this.shape.getEventSource().setAttribute("id", this.id);
 		this.pathShape=this.shape.createPath("M"+this.start.x+","+this.start.y+" Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+" l0,0");
 		this.labelShape=this.shape.createText({
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label'), 
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label'),
 				align:this.textAlign
 			});
 		this.labelShape.getEventSource().setAttribute('id',this.id+"-labelShape");
@@ -134,10 +134,10 @@ dojo.require("dojox.sketch.Anchor");
 		this._pos();
 		this.shape.setTransform(this.transform);
 		this.pathShape.setShape("M"+this.start.x+","+this.start.y+" Q"+this.control.x+","+this.control.y+" "+this.end.x+","+this.end.y+" l0,0");
-		this.labelShape.setShape({ 
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label') 
+		this.labelShape.setShape({
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label')
 			})
 			.setFill(this.property('fill'));
 		this.zoom();
diff --git a/dojox/sketch/PreexistingAnnotation.js b/dojox/sketch/PreexistingAnnotation.js
index 5b526d8..330f5f5 100644
--- a/dojox/sketch/PreexistingAnnotation.js
+++ b/dojox/sketch/PreexistingAnnotation.js
@@ -45,7 +45,7 @@ dojo.require("dojox.sketch.Anchor");
 		
 		for(var i=0; i<obj.childNodes.length; i++){
 			var c=obj.childNodes[i];
-			if(c.localName=="text"){ 
+			if(c.localName=="text"){
 				this.property('label',c.childNodes.length?c.childNodes[0].nodeValue:'');
 			}
 			else if(c.localName=="rect"){
@@ -78,19 +78,19 @@ dojo.require("dojox.sketch.Anchor");
 		this.shape.getEventSource().setAttribute("id", this.id);
 		//if(this.transform.dx || this.transform.dy){ this.shape.setTransform(this.transform); }
 		this.rectShape=this.shape.createRect({
-				x:this.start.x, 
-				y: this.start.y, 
-				width: this.end.x-this.start.x, 
-				height:this.end.y-this.start.y, 
+				x:this.start.x,
+				y: this.start.y,
+				width: this.end.x-this.start.x,
+				height:this.end.y-this.start.y,
 				r:this.radius
 			})
 			//.setStroke({color:this.property('fill'), width:1})
 			.setFill([255,255,255,0.1]);
 		this.rectShape.getEventSource().setAttribute("shape-rendering","crispEdges");
 		this.labelShape=this.shape.createText({
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label'), 
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label'),
 				align:this.textAlign
 			})
 			//.setFont(font)
@@ -117,19 +117,19 @@ dojo.require("dojox.sketch.Anchor");
 		this._pos();
 		this.shape.setTransform(this.transform);
 		this.rectShape.setShape({
-				x:this.start.x, 
-				y: this.start.y, 
-				width: this.end.x-this.start.x, 
-				height:this.end.y-this.start.y, 
+				x:this.start.x,
+				y: this.start.y,
+				width: this.end.x-this.start.x,
+				height:this.end.y-this.start.y,
 				r:this.radius
 			})
 			//.setStroke({ color:this.property('fill'), width:1 })
 			.setFill([255,255,255,0.1]);
 
-		this.labelShape.setShape({ 
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label') 
+		this.labelShape.setShape({
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label')
 			})
 			.setFill(this.property('fill'));
 		this.zoom();
diff --git a/dojox/sketch/SingleArrowAnnotation.js b/dojox/sketch/SingleArrowAnnotation.js
index 5cfb382..0a883a2 100644
--- a/dojox/sketch/SingleArrowAnnotation.js
+++ b/dojox/sketch/SingleArrowAnnotation.js
@@ -64,7 +64,7 @@ dojo.require("dojox.sketch.Anchor");
 			}
 			if(this.start.y<this.end.y){
 				y=this.end.y+this.calculate.dy(this.control, this.end, offset)+this.textYOffset;
-			} else { 
+			} else {
 				y=this.end.y+this.calculate.dy(this.control, this.end, -offset);
 			}
 		}
@@ -78,7 +78,7 @@ dojo.require("dojox.sketch.Anchor");
 		
 		for(var i=0; i<obj.childNodes.length; i++){
 			var c=obj.childNodes[i];
-			if(c.localName=="text"){ 
+			if(c.localName=="text"){
 				this.property('label',c.childNodes.length?c.childNodes[0].nodeValue:'');
 			}
 			else if(c.localName=="path"){
@@ -133,9 +133,9 @@ dojo.require("dojox.sketch.Anchor");
 		this.arrowhead=this.arrowheadGroup.createPath();//"M0,0 l50,-10 -6,10 6,10 Z").setFill(this.property('fill'));
 
 		this.labelShape=this.shape.createText({
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label'), 
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label'),
 				align:this.textAlign
 			})
 			//.setFont(font)
@@ -171,9 +171,9 @@ dojo.require("dojox.sketch.Anchor");
 		this.arrowhead.setFill(this.property('fill'));
 
 		this.labelShape.setShape({
-				x:this.textPosition.x, 
-				y:this.textPosition.y, 
-				text:this.property('label'), 
+				x:this.textPosition.x,
+				y:this.textPosition.y,
+				text:this.property('label'),
 				align:this.textAlign
 			})
 			.setFill(this.property('fill'));
diff --git a/dojox/sketch/Slider.js b/dojox/sketch/Slider.js
index 66d7cdf..fa8b8ef 100644
--- a/dojox/sketch/Slider.js
+++ b/dojox/sketch/Slider.js
@@ -4,7 +4,7 @@ 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;float:right"});
+		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');
diff --git a/dojox/sketch/Toolbar.js b/dojox/sketch/Toolbar.js
index 1d6d1b4..c5cc851 100644
--- a/dojox/sketch/Toolbar.js
+++ b/dojox/sketch/Toolbar.js
@@ -36,7 +36,7 @@ dojo.declare("dojox.sketch.Toolbar", dijit.Toolbar, {
 		this.shapeGroup=new dojox.sketch.ButtonGroup;
 
 		if(!this.plugins){
-			this.plugins=['Slider','Lead','SingleArrow','DoubleArrow','Underline','Preexisting'];
+			this.plugins=['Lead','SingleArrow','DoubleArrow','Underline','Preexisting','Slider'];
 		}
 		this._plugins=[];
 
diff --git a/dojox/sketch/UnderlineAnnotation.js b/dojox/sketch/UnderlineAnnotation.js
index adf5166..95b4725 100644
--- a/dojox/sketch/UnderlineAnnotation.js
+++ b/dojox/sketch/UnderlineAnnotation.js
@@ -64,9 +64,9 @@ dojo.require("dojox.sketch.Anchor");
 		//if(this.transform.dx || this.transform.dy){ this.shape.setTransform(this.transform); }
 
 		this.labelShape=this.shape.createText({
-				x:0, 
-				y:0, 
-				text:this.property('label'), 
+				x:0,
+				y:0,
+				text:this.property('label'),
 				decoration:"underline",
 				align:"start"
 			})
@@ -74,11 +74,11 @@ dojo.require("dojox.sketch.Anchor");
 			//.setFill(this.property('fill'));
 		this.labelShape.getEventSource().setAttribute('id',this.id+"-labelShape");
 
-		this.lineShape=this.shape.createLine({ 
-				x1:1, 
-				x2:this.labelShape.getTextWidth(), 
-				y1:2, 
-				y2:2 
+		this.lineShape=this.shape.createLine({
+				x1:1,
+				x2:this.labelShape.getTextWidth(),
+				y1:2,
+				y2:2
 			})
 			//.setStroke({ color:this.property('fill'), width:1 });
 		this.lineShape.getEventSource().setAttribute("shape-rendering","crispEdges");
diff --git a/dojox/socket.js b/dojox/socket.js
new file mode 100644
index 0000000..9a5b17e
--- /dev/null
+++ b/dojox/socket.js
@@ -0,0 +1,224 @@
+define("dojox/socket", ["dojo", "dojo/cookie"], function(dojo) {
+
+var WebSocket = window.WebSocket;
+
+function Socket(/*dojo.__XhrArgs*/ argsOrUrl){
+	// summary:
+	//		Provides a simple socket connection using WebSocket, or alternate
+	// 		communication mechanisms in legacy browsers for comet-style communication. This is based
+	//		on the WebSocket API and returns an object that implements the WebSocket interface:
+	//		http://dev.w3.org/html5/websockets/#websocket
+	//	description:
+	//		Provides socket connections. This can be used with virtually any Comet protocol.
+	//	argsOrUrl:
+	//		This uses the same arguments as the other I/O functions in Dojo, or a
+	// 		URL to connect to. The URL should be a relative URL in order to properly
+	//		work with WebSockets (it can still be host relative, like //other-site.org/endpoint)
+	// returns:
+	// 		An object that implements the WebSocket API
+	// example:
+	//		| dojo.require("dojox.socket");
+	//		| var socket = dojox.socket({"//comet-server/comet");
+	//		| // we could also add auto-reconnect support
+	//		| // now we can connect to standard HTML5 WebSocket-style events
+	//		| dojo.connect(socket, "onmessage", function(event){
+	//		|    var message = event.data;
+	//		|    // do something with the message
+	//		| });
+	//		| // send something
+	//		| socket.send("hi there");
+	//		| whenDone(function(){
+	//		|   socket.close();
+	//		| });
+	//		You can also use the Reconnect module:
+	//		| dojo.require("dojox.socket");
+	//		| dojo.require("dojox.socket.Reconnect");
+	//		| var socket = dojox.socket({url:"/comet"});
+	//		| // add auto-reconnect support
+	//		| socket = dojox.socket.Reconnect(socket);
+	if(typeof argsOrUrl == "string"){
+		argsOrUrl = {url: argsOrUrl};
+	}
+	return WebSocket ? dojox.socket.WebSocket(argsOrUrl, true) : dojox.socket.LongPoll(argsOrUrl);
+};
+dojox.socket = Socket;
+
+Socket.WebSocket = function(args, fallback){
+	// summary:
+	//		A wrapper for WebSocket, than handles standard args and relative URLs
+	var ws = new WebSocket(new dojo._Url(document.baseURI.replace(/^http/i,'ws'), args.url));
+	ws.on = function(type, listener){
+		ws.addEventListener(type, listener, true);
+	};
+	var opened;
+	dojo.connect(ws, "onopen", function(event){
+		opened = true;
+	});
+	dojo.connect(ws, "onclose", function(event){
+		if(opened){
+			return;
+		}
+		if(fallback){
+			Socket.replace(ws, dojox.socket.LongPoll(args), true);
+		}
+	});
+	return ws;
+};
+Socket.replace = function(socket, newSocket, listenForOpen){
+	// make the original socket a proxy for the new socket
+	socket.send = dojo.hitch(newSocket, "send");
+	socket.close = dojo.hitch(newSocket, "close");
+	if(listenForOpen){
+		proxyEvent("open");
+	}
+	// redirect the events as well
+	dojo.forEach(["message", "close", "error"], proxyEvent);
+	function proxyEvent(type){
+		(newSocket.addEventListener || newSocket.on).call(newSocket, type, function(event){
+			var newEvent = document.createEvent("MessageEvent");
+			newEvent.initMessageEvent(event.type, false, false, event.data, event.origin, event.lastEventId, event.source);
+			socket.dispatchEvent(newEvent);
+		}, true);
+	}
+};
+Socket.LongPoll = function(/*dojo.__XhrArgs*/ args){
+	// summary:
+	//		Provides a simple long-poll based comet-style socket/connection to a server and returns an
+	// 		object implementing the WebSocket interface:
+	//		http://dev.w3.org/html5/websockets/#websocket
+	//	args:
+	//		This uses the same arguments as the other I/O functions in Dojo, with this addition:
+	//	args.interval:
+	//		Indicates the amount of time (in milliseconds) after a response was received
+	//		before another request is made. By default, a request is made immediately
+	//		after getting a response. The interval can be increased to reduce load on the
+	//		server or to do simple time-based polling where the server always responds
+	// 		immediately.
+	//	args.transport:
+	//		Provide an alternate transport like dojo.io.script.get
+	// returns:
+	// 		An object that implements the WebSocket API
+	// example:
+	//		| dojo.require("dojox.socket.LongPoll");
+	//		| var socket = dojox.socket.LongPoll({url:"/comet"});
+	//		or:
+	//		| dojo.require("dojox.socket.LongPoll");
+	//		| dojox.socket.LongPoll.add();
+	//		| var socket = dojox.socket({url:"/comet"});
+
+var cancelled = false,
+		first = true,
+		timeoutId,
+		connections = [];
+	
+	// create the socket object
+	var socket = {
+		send: function(data){
+			// summary:
+			// 		Send some data using XHR or provided transport
+			var sendArgs = dojo.delegate(args);
+			sendArgs.rawBody = data;
+			clearTimeout(timeoutId);
+			var deferred = first ? (first = false) || socket.firstRequest(sendArgs) :
+				socket.transport(sendArgs);
+			connections.push(deferred);
+			deferred.then(function(response){
+				// got a response
+				socket.readyState = 1;
+				// remove the current connection
+				connections.splice(dojo.indexOf(connections, deferred), 1);
+				// reconnect to listen for the next message if there are no active connections,
+				// we queue it up in case one of the onmessage handlers has a message to send
+				if(!connections.length){
+					timeoutId = setTimeout(connect, args.interval);
+				}
+				if(response){
+					// now send the message along to listeners
+					fire("message", {data: response}, deferred);
+				}
+			}, function(error){
+				connections.splice(dojo.indexOf(connections, deferred), 1);
+				// an error occurred, fire the appropriate event listeners
+				if(!cancelled){
+					fire("error", {error:error}, deferred);
+					if(!connections.length){
+						socket.readyState = 3;
+						fire("close", {wasClean:false}, deferred);
+					}
+				}
+			});
+			return deferred;
+		},
+		close: function(){
+			// summary:
+			// 		Close the connection
+			socket.readyState = 2;
+			cancelled = true;
+			for(var i = 0; i < connections.length; i++){
+				connections[i].cancel();
+			}
+			socket.readyState = 3;
+			fire("close", {wasClean:true});
+		},
+		transport: args.transport || dojo.xhrPost,
+		args: args,
+		url: args.url,
+		readyState: 0,
+		CONNECTING: 0,
+		OPEN: 1,
+		CLOSING: 2,
+		CLOSED: 3,
+		dispatchEvent: function(event){
+			fire(event.type, event);
+		},
+		on: function(type, callback){
+			return dojo.connect(this, "on" + type, callback);
+		},
+		firstRequest: function(args){
+			// summary:
+			// 		This allows for special handling for the first request. This is useful for
+			//		providing information to disambiguate between the first request and
+			//		subsequent long-poll requests so the server can properly setup a
+			// 		connection on the first connection or reject a request for an expired
+			// 		connection if the request is not expecting to be the first for a connection.
+			//		This method can be overriden. The default behavior is to include a Pragma
+			//		header with a value of "start-long-poll"
+			var headers = (args.headers || (args.headers = {}));
+			headers.Pragma = "start-long-poll";
+			try{
+				return this.transport(args);
+			}finally{
+				// cleanup the header so it is not used on subsequent requests
+				delete headers.Pragma;
+			}
+		}
+	};
+	function connect(){
+		if(socket.readyState == 0){
+			// we fire the open event now because we really don't know when the "socket"
+			// is truly open, and this gives us a to do a send() and get it included in the
+			// HTTP request
+			fire("open",{});
+		}
+		// make the long-poll connection, to wait for response from the server
+		if(!connections.length){
+			socket.send();
+		}
+	}
+	function fire(type, object, deferred){
+		if(socket["on" + type]){
+			var event = document.createEvent("HTMLEvents");
+			event.initEvent(type, false, false);
+			dojo.mixin(event, object);
+			event.ioArgs = deferred && deferred.ioArgs;
+			socket["on" + type](event);
+		}
+	}
+	// provide an alias for Dojo's connect method
+	socket.connect = socket.on;
+	// do the initial connection
+	setTimeout(connect);
+	return socket;
+};
+return Socket;
+});
\ No newline at end of file
diff --git a/dojox/socket/README b/dojox/socket/README
new file mode 100644
index 0000000..4828aff
--- /dev/null
+++ b/dojox/socket/README
@@ -0,0 +1,15 @@
+-------------------------------------------------------------------------------
+dojox.socket
+-------------------------------------------------------------------------------
+Version 0.1
+Release date: 10/10/2010
+-------------------------------------------------------------------------------
+Project state:
+beta
+-------------------------------------------------------------------------------
+Credits
+	Kris Zyp
+-------------------------------------------------------------------------------
+Project description
+
+Provides a WebSocket with fallback to HTTP long-polling  
diff --git a/dojox/socket/Reconnect.js b/dojox/socket/Reconnect.js
new file mode 100644
index 0000000..fa932a6
--- /dev/null
+++ b/dojox/socket/Reconnect.js
@@ -0,0 +1,54 @@
+dojo.provide("dojox.socket.Reconnect");
+
+dojox.socket.Reconnect = function(socket, options){
+	// summary:
+	//		Provides auto-reconnection to a websocket after it has been closed
+	//	socket:
+	//		Socket to add reconnection support to.
+	// returns:
+	// 		An object that implements the WebSocket API
+	// example:
+	//		You can use the Reconnect module:
+	//		| dojo.require("dojox.socket");
+	//		| dojo.require("dojox.socket.Reconnect");
+	//		| var socket = dojox.socket({url:"/comet"});
+	//		| // add auto-reconnect support
+	//		| socket = dojox.socket.Reconnect(socket);
+	options = options || {};
+	var reconnectTime = options.reconnectTime || 10000;
+	
+	var connectHandle = dojo.connect(socket, "onclose", function(event){
+		clearTimeout(checkForOpen);
+		if(!event.wasClean){
+			socket.disconnected(function(){
+				dojox.socket.replace(socket, newSocket = socket.reconnect());
+			});
+		}
+	});
+	var checkForOpen, newSocket;
+	if(!socket.disconnected){
+		// add a default impl if it doesn't exist
+		socket.disconnected = function(reconnect){
+			setTimeout(function(){
+				reconnect();
+				checkForOpen = setTimeout(function(){
+					//reset the backoff
+					if(newSocket.readyState < 2){
+						reconnectTime = options.reconnectTime || 10000;
+					}
+				}, 10000);
+			}, reconnectTime);
+			// backoff each time
+			reconnectTime *= options.backoffRate || 2;
+		};
+	}
+	if(!socket.reconnect){
+		// add a default impl if it doesn't exist
+		socket.reconnect = function(){
+			return socket.args ?
+				dojox.socket.LongPoll(socket.args) :
+				dojox.socket.WebSocket({url: socket.URL || socket.url}); // different cases for different impls
+		};
+	}
+	return socket;
+};
diff --git a/dojox/sql.js b/dojox/sql.js
index 0addc86..87da461 100644
--- a/dojox/sql.js
+++ b/dojox/sql.js
@@ -1,2 +1,2 @@
-dojo.provide("dojox.sql"); 
+dojo.provide("dojox.sql");
 dojo.require("dojox.sql._base");
diff --git a/dojox/sql/_base.js b/dojox/sql/_base.js
index 392d308..744bf0d 100644
--- a/dojox/sql/_base.js
+++ b/dojox/sql/_base.js
@@ -8,7 +8,7 @@ dojo.mixin(dojox.sql, {
 	// 	There are four ways to call this:
 	// 	1) Straight SQL: dojox.sql("SELECT * FROM FOOBAR");
 	// 	2) SQL with parameters: dojox.sql("INSERT INTO FOOBAR VALUES (?)", someParam)
-	// 	3) Encrypting particular values: 
+	// 	3) Encrypting particular values:
 	//			dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?))", someParam, "somePassword", callback)
 	// 	4) Decrypting particular values:
 	//			dojox.sql("SELECT DECRYPT(SOMECOL1), DECRYPT(SOMECOL2) FROM
@@ -25,8 +25,8 @@ dojo.mixin(dojox.sql, {
 	// 	Note: If you have multiple columns to encrypt and decrypt, you can use the following
 	// 	convenience form to not have to type ENCRYPT(?)/DECRYPT(*) many times:
 	//
-	// 	dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?, ?, ?))", 
-	//					someParam1, someParam2, someParam3, 
+	// 	dojox.sql("INSERT INTO FOOBAR VALUES (ENCRYPT(?, ?, ?))",
+	//					someParam1, someParam2, someParam3,
 	//					"somePassword", callback)
 	//
 	// 	dojox.sql("SELECT DECRYPT(SOMECOL1, SOMECOL2) FROM
@@ -46,7 +46,7 @@ dojo.mixin(dojox.sql, {
 		}
 		
 		if(!this.dbName){
-			this.dbName = "dot_store_" 
+			this.dbName = "dot_store_"
 				+ window.location.href.replace(/[^0-9A-Za-z_]/g, "_");
 			// database names in Gears are limited to 64 characters long
 			if(this.dbName.length > 63){
@@ -92,7 +92,7 @@ dojo.mixin(dojox.sql, {
 	},
 	
 	_exec: function(params){
-		try{	
+		try{
 			// get the Gears Database object
 			this._initDb();
 		
@@ -133,13 +133,13 @@ dojo.mixin(dojox.sql, {
 			// do we have an ENCRYPT SQL statement? if so, handle that first
 			var crypto;
 			if(this._needsEncrypt(sql)){
-				crypto = new dojox.sql._SQLCrypto("encrypt", sql, 
-													password, args, 
+				crypto = new dojox.sql._SQLCrypto("encrypt", sql,
+													password, args,
 													callback);
 				return null; // encrypted results will arrive asynchronously
 			}else if(this._needsDecrypt(sql)){ // otherwise we have a DECRYPT statement
-				crypto = new dojox.sql._SQLCrypto("decrypt", sql, 
-													password, args, 
+				crypto = new dojox.sql._SQLCrypto("decrypt", sql,
+													password, args,
 													callback);
 				return null; // decrypted results will arrive asynchronously
 			}
@@ -149,7 +149,7 @@ dojo.mixin(dojox.sql, {
 			
 			// Gears ResultSet object's are ugly -- normalize
 			// these into something JavaScript programmers know
-			// how to work with, basically an array of 
+			// how to work with, basically an array of
 			// JavaScript objects where each property name is
 			// simply the field name for a column of data
 			rs = this._normalizeResults(rs);
@@ -165,10 +165,10 @@ dojo.mixin(dojox.sql, {
 			console.debug("SQL Exception: " + exp);
 			
 			if(this._autoClose){
-				try{ 
-					this.close(); 
+				try{
+					this.close();
 				}catch(e){
-					console.debug("Error closing database: " 
+					console.debug("Error closing database: "
 									+ e.message||e);
 				}
 			}
@@ -244,14 +244,14 @@ dojo.declare("dojox.sql._SQLCrypto", null, {
 	//	A private class encapsulating any cryptography that must be done
 	// 	on a SQL statement. We instantiate this class and have it hold
 	//	it's state so that we can potentially have several encryption
-	//	operations happening at the same time by different SQL statements.	
+	//	operations happening at the same time by different SQL statements.
 	constructor: function(action, sql, password, args, callback){
 		if(action == "encrypt"){
 			this._execEncryptSQL(sql, password, args, callback);
 		}else{
 			this._execDecryptSQL(sql, password, args, callback);
-		}		
-	}, 
+		}
+	},
 	
 	_execEncryptSQL: function(sql, password, args, callback){
 		// strip the ENCRYPT/DECRYPT keywords from the SQL
@@ -284,7 +284,7 @@ dojo.declare("dojox.sql._SQLCrypto", null, {
 				return;
 			}
 		
-			// normalize SQL results into a JavaScript object 
+			// normalize SQL results into a JavaScript object
 			// we can work with
 			resultSet = dojox.sql._normalizeResults(resultSet);
 		
@@ -317,7 +317,7 @@ dojo.declare("dojox.sql._SQLCrypto", null, {
 		// be decrypted, or it will return the column names that need
 		// decryption set on a hashtable so we can quickly test a given
 		// column name; the key is the column name that needs
-		// decryption and the value is 'true' (i.e. needsDecrypt["someColumn"] 
+		// decryption and the value is 'true' (i.e. needsDecrypt["someColumn"]
 		// would return 'true' if it needs decryption, and would be 'undefined'
 		// or false otherwise)
 		var needsDecrypt = this._determineDecryptedColumns(sql);
@@ -343,7 +343,7 @@ dojo.declare("dojox.sql._SQLCrypto", null, {
 			return;
 		}
 	
-		// normalize SQL results into a JavaScript object 
+		// normalize SQL results into a JavaScript object
 		// we can work with
 		resultSet = dojox.sql._normalizeResults(resultSet);
 	
@@ -377,7 +377,7 @@ dojo.declare("dojox.sql._SQLCrypto", null, {
 			
 				// FIXME: This currently uses DES as a proof-of-concept since the
 				// DES code used is quite fast and was easy to work with. Modify dojox.sql
-				// to be able to specify a different encryption provider through a 
+				// to be able to specify a different encryption provider through a
 				// a SQL-like syntax, such as dojox.sql("SET ENCRYPTION BLOWFISH"),
 				// and modify the dojox.crypto.Blowfish code to be able to work using
 				// a Google Gears Worker Pool
@@ -419,7 +419,7 @@ dojo.declare("dojox.sql._SQLCrypto", null, {
 				
 					// forming a closure here can cause issues, with values not cleanly
 					// saved on Firefox/Mac OS X for some of the values above that
-					// are needed in the callback below; call a subroutine that will form 
+					// are needed in the callback below; call a subroutine that will form
 					// a closure inside of itself instead
 					this._decryptSingleColumn(columnName, columnValue, password, i,
 												function(finalResultSet){
diff --git a/dojox/sql/_crypto.js b/dojox/sql/_crypto.js
index 119cf92..bf29f82 100644
--- a/dojox/sql/_crypto.js
+++ b/dojox/sql/_crypto.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.sql._crypto");
 dojo.mixin(dojox.sql._crypto, {
 	// summary: dojox.sql cryptography code
-	// description: 
+	// description:
 	//	Taken from http://www.movable-type.co.uk/scripts/aes.html by
 	// 	Chris Veness (CLA signed); adapted for Dojo and Google Gears Worker Pool
 	// 	by Brad Neuberg, bkn3 at columbia.edu
@@ -14,7 +14,7 @@ dojo.mixin(dojox.sql._crypto, {
 		// summary:
 		//	Use Corrected Block TEA to encrypt plaintext using password
 		//	(note plaintext & password must be strings not string objects).
-		//	Results will be returned to the 'callback' asychronously.	
+		//	Results will be returned to the 'callback' asychronously.
 		this._initWorkerPool();
 
 		var msg ={plaintext: plaintext, password: password};
@@ -51,10 +51,10 @@ dojo.mixin(dojox.sql._crypto, {
 		// and put them to work, storing them in an 'employed' hashtable,
 		// keyed by their Worker ID with the value being the callback function
 		// that wants the result. when an employed worker is done, we get
-		// a message in our 'manager' which adds this worker back to the 
+		// a message in our 'manager' which adds this worker back to the
 		// unemployed stack and routes the result to the callback that
 		// wanted it. if all the workers were employed in the past but
-		// more work needed to be done (i.e. it's a tight labor pool ;) 
+		// more work needed to be done (i.e. it's a tight labor pool ;)
 		// then the work messages are pushed onto
 		// a 'handleMessage' queue as an object tuple{msg: msg, callback: callback}
 
@@ -155,7 +155,7 @@ dojo.mixin(dojox.sql._crypto, {
 					 [0x40, 0x00, 0x00, 0x00],
 					 [0x80, 0x00, 0x00, 0x00],
 					 [0x1b, 0x00, 0x00, 0x00],
-					 [0x36, 0x00, 0x00, 0x00] ]; 
+					 [0x36, 0x00, 0x00, 0x00] ];
 
 		/*
 		 * AES Cipher function: encrypt 'input' with Rijndael algorithm
@@ -207,7 +207,7 @@ dojo.mixin(dojox.sql._crypto, {
 			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 
+		  return s;	 // see fp.gladman.plus.com/cryptography_technology/rijndael/aes.spec.311.pdf
 		}
 
 
@@ -278,7 +278,7 @@ dojo.mixin(dojox.sql._crypto, {
 
 		/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  */
 
-		/* 
+		/*
 		 * 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
@@ -288,7 +288,7 @@ dojo.mixin(dojox.sql._crypto, {
 		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 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);
@@ -306,7 +306,7 @@ dojo.mixin(dojox.sql._crypto, {
 
 		  // 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; 
+		  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);
@@ -346,7 +346,7 @@ dojo.mixin(dojox.sql._crypto, {
 		}
 
 
-		/* 
+		/*
 		 * Use AES to decrypt 'ciphertext' with 'password' using 'nBits' key, in Counter mode of operation
 		 *
 		 *	 for each block
@@ -365,7 +365,7 @@ dojo.mixin(dojox.sql._crypto, {
 
 		  var keySchedule = KeyExpansion(key);
 
-		  ciphertext = ciphertext.split('-');  // split ciphertext into array of block-length strings 
+		  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
@@ -415,7 +415,7 @@ dojo.mixin(dojox.sql._crypto, {
 			return AESEncryptCtr(plaintext, password, 256);
 		}
 
-		function decrypt(ciphertext, password){	
+		function decrypt(ciphertext, password){
 			return AESDecryptCtr(ciphertext, password, 256);
 		}
 	
diff --git a/dojox/string/BidiComplex.js b/dojox/string/BidiComplex.js
index ef3f52c..e04fa78 100644
--- a/dojox/string/BidiComplex.js
+++ b/dojox/string/BidiComplex.js
@@ -3,17 +3,17 @@ 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. 
+//		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. 
+//		in both static text and dynamic text during user input.
 
-(function(){  
+(function(){
 
 	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){
 		// summary:
-		//		Attach key listeners to the INPUT field to accomodate dynamic complex BiDi expressions 
+		//		Attach key listeners to the INPUT field to accomodate dynamic complex BiDi expressions
 		// field: INPUT DOM node
 		// pattern: Complex Expression Pattern type. One of "FILE_PATH", "URL", "EMAIL", "XPATH"
 
@@ -25,19 +25,19 @@ dojo.experimental("dojox.string.BidiComplex");
 		dojo.connect(field, "oncut", this, "_ceCutText");
 		dojo.connect(field, "oncopy", this, "_ceCopyText");
 
-		field.value = dojox.string.BidiComplex.createDisplayString(field.value, field.alt);    
+		field.value = dojox.string.BidiComplex.createDisplayString(field.value, field.alt);
 	};
 		
 	dojox.string.BidiComplex.createDisplayString = function(/*String*/str, /*String*/pattern){
 		// summary:
-		//		Create the display string by adding the Unicode direction Markers 
+		//		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); 
+		var segmentsPointers = dojox.string.BidiComplex._parse(str, pattern);
 		
 		var buf = '\u202A'/*LRE*/ + str;
-		var shift = 1;                                           
+		var shift = 1;
 		dojo.forEach(segmentsPointers, function(n){
 			if(n != null){
 				var preStr = buf.substring(0, n + shift);
@@ -46,7 +46,7 @@ dojo.experimental("dojox.string.BidiComplex");
 				shift++;
 			}
 		});
-		return buf;        
+		return buf;
 	};
 
 	dojox.string.BidiComplex.stripSpecialCharacters = function(str){
@@ -57,7 +57,7 @@ dojo.experimental("dojox.string.BidiComplex");
 	};
 
 	dojox.string.BidiComplex._ceKeyDown = function(event){
-		var elem = dojo.isIE ? event.srcElement : event.target;        
+		var elem = dojo.isIE ? event.srcElement : event.target;
 		_str0 = elem.value;
 	};
 				
@@ -93,7 +93,7 @@ dojo.experimental("dojox.string.BidiComplex");
 				return;
 			}
 
-			if(ieKey == dojo.keys.RIGHT_ARROW){             
+			if(ieKey == dojo.keys.RIGHT_ARROW){
 				if(str1.charAt(cursorEnd-1) == LRM){
 					cursorEnd1 = cursorEnd + 1;
 					if(cursorStart == cursorEnd){
@@ -101,9 +101,9 @@ dojo.experimental("dojox.string.BidiComplex");
 					}
 				}
 
-				dojox.string.BidiComplex._setSelectedRange(elem, cursorStart1, cursorEnd1);                        
+				dojox.string.BidiComplex._setSelectedRange(elem, cursorStart1, cursorEnd1);
 				return;
-			}                   
+			}
 		}else{ //Firefox
 			if(ieKey == dojo.keys.LEFT_ARROW){
 				if(str1.charAt(cursorEnd-1) == LRM){
@@ -131,7 +131,7 @@ dojo.experimental("dojox.string.BidiComplex");
 			}
 
 			if(ieKey == dojo.keys.DELETE){
-				dojox.string.BidiComplex._setSelectedRange(elem,cursorStart,cursorEnd); 
+				dojox.string.BidiComplex._setSelectedRange(elem,cursorStart,cursorEnd);
 			}else if(ieKey == dojo.keys.BACKSPACE){
 				if((_str0.length >= cursorEnd) && (_str0.charAt(cursorEnd-1)==LRM)){
 					dojox.string.BidiComplex._setSelectedRange(elem, cursorStart - 1, cursorEnd - 1);
@@ -175,13 +175,13 @@ dojo.experimental("dojox.string.BidiComplex");
 	dojox.string.BidiComplex._ceCutText = function(elem){
 
 		var ret = dojox.string.BidiComplex._processCopy(elem, null, false);
-		if(!ret){ 
+		if(!ret){
 			return false;
 		}
 
 		if(dojo.isIE){
-	//		curPos = elem.selectionStart; 
-			document.selection.clear(); 
+	//		curPos = elem.selectionStart;
+			document.selection.clear();
 		}else{
 			var curPos = elem.selectionStart;
 			elem.value = elem.value.substring(0, curPos) + elem.value.substring(elem.selectionEnd);
@@ -226,18 +226,18 @@ dojo.experimental("dojox.string.BidiComplex");
 					range.expand('textedit');
 				}
 
-				range.collapse();            
+				range.collapse();
 				range.moveEnd('character', selectionEnd);
 				range.moveStart('character', selectionStart);
 				range.select();
 			}
-		}else{        
+		}else{
 			elem.selectionStart = selectionStart;
 			elem.selectionEnd = selectionEnd;
 		}
 	};
 
-	var _isBidiChar = function(c){    
+	var _isBidiChar = function(c){
 		return (c >= '\u0030' && c <= '\u0039') || (c > '\u00ff');
 	};
 
@@ -246,11 +246,11 @@ dojo.experimental("dojox.string.BidiComplex");
 	};
 
 	var _isCharBeforeBiDiChar = function(buffer, i, previous){
-		while(i > 0){    
+		while(i > 0){
 			if(i == previous){
 				return false;
 			}
-			i--;                        
+			i--;
 			if(_isBidiChar(buffer.charAt(i))){
 				return true;
 			}
@@ -258,11 +258,11 @@ dojo.experimental("dojox.string.BidiComplex");
 				return false;
 			}
 		}
-		return false;       
+		return false;
 	};
 
 
-	dojox.string.BidiComplex._parse = function(/*String*/str, /*String*/pattern){    
+	dojox.string.BidiComplex._parse = function(/*String*/str, /*String*/pattern){
 		var previous = -1, segmentsPointers = [];
 		var delimiters = {
 			FILE_PATH: "/\\:.",
@@ -278,36 +278,36 @@ dojo.experimental("dojox.string.BidiComplex");
 				dojo.forEach(str, function(ch, i){
 					if(delimiters.indexOf(ch) >= 0 && _isCharBeforeBiDiChar(str, i, previous)){
 						previous = i;
-						segmentsPointers.push(i);  
+						segmentsPointers.push(i);
 					}
 				});
 				break;
 			case "EMAIL":
 				var inQuotes = false; // FIXME: unused?
 	
-				dojo.forEach(str, function(ch, i){     
+				dojo.forEach(str, function(ch, i){
 					if(ch== '\"'){
 						if(_isCharBeforeBiDiChar(str, i, previous)){
-							previous = i;    
-							segmentsPointers.push(i);  
-						}                    
+							previous = i;
+							segmentsPointers.push(i);
+						}
 						i++;
 						var i1 = str.indexOf('\"', i);
 						if(i1 >= i){
 							i = i1;
 						}
 						if(_isCharBeforeBiDiChar(str, i, previous)){
-							previous = i;    
-							segmentsPointers.push(i);  
-						}                                   
+							previous = i;
+							segmentsPointers.push(i);
+						}
 					}
 	
 					if(delimiters.indexOf(ch) >= 0 && _isCharBeforeBiDiChar(str, i, previous)){
-								previous = i;    
-								segmentsPointers.push(i); 
-					}                                            
+								previous = i;
+								segmentsPointers.push(i);
+					}
 				});
 		}
 		return segmentsPointers;
-	};  
+	};
 })();
diff --git a/dojox/string/Builder.js b/dojox/string/Builder.js
index e18bbc0..d5df55f 100644
--- a/dojox/string/Builder.js
+++ b/dojox/string/Builder.js
@@ -12,10 +12,10 @@ dojox.string.Builder = function(/*String?*/str){
 	var b = "";
 	this.length = 0;
 	
-	this.append = function(/* String... */s){ 
-		// summary: Append all arguments to the end of the buffer 
+	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.
@@ -30,10 +30,10 @@ dojox.string.Builder = function(/*String?*/str){
 				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 
+				significantly with Internet Explorer, particularly when
 				as many arguments are provided as possible.
 
-				Loop unroll per suggestion from Kris Zyp, implemented by 
+				Loop unroll per suggestion from Kris Zyp, implemented by
 				Tom Trenka.
 
 				Note: added empty string to force a string cast if needed.
@@ -81,7 +81,7 @@ dojox.string.Builder = function(/*String?*/str){
 	};
 	
 	this.clear = function(){
-		//	summary: 
+		//	summary:
 		//		Remove all characters from the buffer.
 		b = "";
 		this.length = 0;
@@ -89,7 +89,7 @@ dojox.string.Builder = function(/*String?*/str){
 	};
 	
 	this.replace = function(/* String */oldStr, /* String */ newStr){
-		// 	summary: 
+		// 	summary:
 		//		Replace instances of one string with another in the buffer.
 		b = b.replace(oldStr,newStr);
 		this.length = b.length;
@@ -108,7 +108,7 @@ dojox.string.Builder = function(/*String?*/str){
 	};
 	
 	this.insert = function(/* Number */index, /* String */str){
-		//	summary: 
+		//	summary:
 		//		Insert string str starting at index.
 		if(index == 0){
 			b = str + b;
diff --git a/dojox/string/sprintf.js b/dojox/string/sprintf.js
index 4060061..57601cf 100644
--- a/dojox/string/sprintf.js
+++ b/dojox/string/sprintf.js
@@ -234,7 +234,7 @@ dojo.extend(dojox.string.sprintf.Formatter, {
 					if(token.period != '.'){
 						token.precision = 6;
 					}
-					this.formatDouble(token); 
+					this.formatDouble(token);
 				}
 				this.fitField(token);
 
@@ -261,7 +261,7 @@ dojo.extend(dojox.string.sprintf.Formatter, {
 		// 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);
@@ -308,11 +308,11 @@ dojo.extend(dojox.string.sprintf.Formatter, {
 
 		switch(token.doubleNotation) {
 			case 'e': {
-				token.arg = f.toExponential(token.precision); 
+				token.arg = f.toExponential(token.precision);
 				break;
 			}
 			case 'f': {
-				token.arg = f.toFixed(token.precision); 
+				token.arg = f.toFixed(token.precision);
 				break;
 			}
 			case 'g': {
@@ -323,12 +323,12 @@ dojo.extend(dojox.string.sprintf.Formatter, {
 					//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); 
+					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){ 
+				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
diff --git a/dojox/string/tests/BidiComplex.js b/dojox/string/tests/BidiComplex.js
index 2b0a759..17cd72a 100644
--- a/dojox/string/tests/BidiComplex.js
+++ b/dojox/string/tests/BidiComplex.js
@@ -1,18 +1,18 @@
 dojo.provide("dojox.string.tests.BidiComplex");
 dojo.require("dojox.string.BidiComplex");
 
-tests.register("dojox.string.tests.BidiComplex", 
+tests.register("dojox.string.tests.BidiComplex",
 	[
 		{
 			name: "createDisplayString: FILE_PATH",
 			runTest: function(t){
-				var originalString = "c:\\قائمة\\ملف.txt";	
-				var fixedString="‪c:\\قائمة‎\\ملف‎.txt";				
+				var originalString = "c:\\قائمة\\ملف.txt";
+				var fixedString="‪c:\\قائمة‎\\ملف‎.txt";
 				var displayString = dojox.string.BidiComplex.createDisplayString(originalString, "FILE_PATH");
 				t.is(displayString, fixedString);
 
-//				originalString = "c:\\אבג\\דהו\\123\\אa";	
-//				fixedString="‪‪c:\\אבג‎\\דהו‎\\123‎\\אa";				
+//				originalString = "c:\\אבג\\דהו\\123\\אa";
+//				fixedString="‪‪c:\\אבג‎\\דהו‎\\123‎\\אa";
 //				var displayString = dojox.string.BidiComplex.createDisplayString(originalString, "FILE_PATH");
 //				t.is(displayString, fixedString);
 			}
@@ -20,8 +20,8 @@ tests.register("dojox.string.tests.BidiComplex",
 		{
 			name: "stripSpecialCharacters: FILE_PATH",
 			runTest: function(t){
-				var originalString = "c:\\قائمة\\ملف.txt";	
-				var fixedString="‪c:\\قائمة‎\\ملف‎.txt";				
+				var originalString = "c:\\قائمة\\ملف.txt";
+				var fixedString="‪c:\\قائمة‎\\ملف‎.txt";
 				var stripedString = dojox.string.BidiComplex.stripSpecialCharacters(fixedString);
 				t.is(stripedString, originalString);
 			}
@@ -30,7 +30,7 @@ tests.register("dojox.string.tests.BidiComplex",
 			name: "createDisplayString: EMAIL",
 			runTest: function(t){
 				var originalString = "موظف@شركة.com";
-				var fixedString="‪موظف‎@شركة‎.com";				
+				var fixedString="‪موظف‎@شركة‎.com";
 				var displayString = dojox.string.BidiComplex.createDisplayString(originalString, "EMAIL");
 				t.is(displayString, fixedString);
 			}
@@ -38,8 +38,8 @@ tests.register("dojox.string.tests.BidiComplex",
 		{
 			name: "stripSpecialCharacters: EMAIL",
 			runTest: function(t){
-				var originalString = "موظف@شركة.com";	
-				var fixedString="‪موظف‎@شركة‎.com";				
+				var originalString = "موظف@شركة.com";
+				var fixedString="‪موظف‎@شركة‎.com";
 				var stripedString = dojox.string.BidiComplex.stripSpecialCharacters(fixedString);
 				t.is(stripedString, originalString);
 			}
@@ -47,8 +47,8 @@ tests.register("dojox.string.tests.BidiComplex",
 		{
 			name: "createDisplayString: URL",
 			runTest: function(t){
-				var originalString ="http://قطاع.شركة.com/الموقع/صفحة?دليل=اختبار&&تعيين=نعم"; 
-				var fixedString="‪http://قطاع‎.شركة‎.com/الموقع‎/صفحة‎?دليل‎=اختبار‎&&تعيين‎=نعم";					
+				var originalString ="http://قطاع.شركة.com/الموقع/صفحة?دليل=اختبار&&تعيين=نعم";
+				var fixedString="‪http://قطاع‎.شركة‎.com/الموقع‎/صفحة‎?دليل‎=اختبار‎&&تعيين‎=نعم";
 				var displayString = dojox.string.BidiComplex.createDisplayString(originalString, "URL");
 				t.is(displayString, fixedString);
 			}
@@ -56,8 +56,8 @@ tests.register("dojox.string.tests.BidiComplex",
 		{
 			name: "stripSpecialCharacters: URL",
 			runTest: function(t){
-				var originalString ="http://قطاع.شركة.com/الموقع/صفحة?دليل=اختبار&&تعيين=نعم"; 
-				var fixedString="‪http://قطاع‎.شركة‎.com/الموقع‎/صفحة‎?دليل‎=اختبار‎&&تعيين‎=نعم";				
+				var originalString ="http://قطاع.شركة.com/الموقع/صفحة?دليل=اختبار&&تعيين=نعم";
+				var fixedString="‪http://قطاع‎.شركة‎.com/الموقع‎/صفحة‎?دليل‎=اختبار‎&&تعيين‎=نعم";
 				var stripedString = dojox.string.BidiComplex.stripSpecialCharacters(fixedString);
 				t.is(stripedString, originalString);
 			}
diff --git a/dojox/string/tests/Builder.js b/dojox/string/tests/Builder.js
index 34defe5..5327f99 100644
--- a/dojox/string/tests/Builder.js
+++ b/dojox/string/tests/Builder.js
@@ -37,7 +37,7 @@ tests.register("dojox.string.tests.Builder", [
 			var b = new dojox.string.Builder();
 			t.is("", b.toString());
 			b = new dojox.string.Builder("foo");
-			t.is("foo", b.toString()); 
+			t.is("foo", b.toString());
 		}
 	},
 	{
diff --git a/dojox/testing/DocTest.js b/dojox/testing/DocTest.js
index 56f6e1b..27de034 100644
--- a/dojox/testing/DocTest.js
+++ b/dojox/testing/DocTest.js
@@ -1,5 +1,4 @@
-dojo.provide("dojox.testing.DocTest");
-dojo.require("dojo.string");
+define("dojox/testing/DocTest", ["dojo/string"], function() {
 
 dojo.declare(
 	"dojox.testing.DocTest",
@@ -139,8 +138,8 @@ dojo.declare(
 							line:test.line
 						});
 					}
-					test = { 
-						commands: [], 
+					test = {
+						commands: [],
 						expectedResult: [],
 						line:0
 					};
@@ -188,7 +187,7 @@ dojo.declare(
 		
 		_run: function(/*Array*/tests){
 			//	summary:
-			//		Each element in the array contains the test in the first element, 
+			//		Each element in the array contains the test in the first element,
 			//		and the expected result in the second element.
 			//	tests:
 			//		Make sure that the types are compared properly. There used to be
@@ -222,8 +221,8 @@ dojo.declare(
 				var msg = "Test "+(i+1)+": ";
 				var viewCommands = t.commands.join(" ");
 				// Show the first part of the test command.
-				viewCommands = (viewCommands.length > 50 ? 
-								viewCommands.substr(0,50) + "..." : 
+				viewCommands = (viewCommands.length > 50 ?
+								viewCommands.substr(0,50) + "..." :
 								viewCommands
 				);
 				if(res.success){
@@ -249,7 +248,7 @@ dojo.declare(
 		},
 		
 		runTest: function(commands, expected){
-			var ret = { 
+			var ret = {
 				success: false,
 				actualResult: null
 			};
@@ -259,7 +258,7 @@ dojo.declare(
 			var cmds = commands.join("\n");
 			ret.actualResult = eval(cmds);
 			if( (String(ret.actualResult)==expected) ||
-				(dojo.toJson(ret.actualResult)==expected) || 
+				(dojo.toJson(ret.actualResult)==expected) ||
 				(
 					(expected.charAt(0)=='"')&&
 					(expected.charAt(expected.length-1)=='"')&&
@@ -274,4 +273,7 @@ dojo.declare(
 			return ret;
 		}
 	}
-);
\ No newline at end of file
+);
+
+return dojox.testing.DocTest;
+});
\ No newline at end of file
diff --git a/dojox/timing.js b/dojox/timing.js
index ebc43f7..9cc843f 100644
--- a/dojox/timing.js
+++ b/dojox/timing.js
@@ -1,2 +1,2 @@
 dojo.provide("dojox.timing");
-dojo.require("dojox.timing._base"); 
+dojo.require("dojox.timing._base");
diff --git a/dojox/timing/Sequence.js b/dojox/timing/Sequence.js
index 5e6a241..9de4d41 100644
--- a/dojox/timing/Sequence.js
+++ b/dojox/timing/Sequence.js
@@ -1,17 +1,17 @@
 dojo.provide("dojox.timing.Sequence");
-dojo.experimental("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 
+	// 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: 
+	// description:
 	//	This array will contain the sequence defines resolved, so that
-	// 	ie. repeat:10 will result in 10 elements in the sequence, so 
+	// 	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.
@@ -22,7 +22,7 @@ dojo.declare("dojox.timing.Sequence", null, {
 	_defsResolved: [],
 =====*/
 
-	// This is the time to wait before goOn() calls _go(), which 
+	// 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
@@ -133,15 +133,15 @@ dojo.declare("dojox.timing.Sequence", null, {
 	stop: function(){
 		// summary:  Stop the currently running sequence.
 		//
-		// description: 
+		// 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 
+		//		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;
 	}
 
-}); 
+});
diff --git a/dojox/timing/Streamer.js b/dojox/timing/Streamer.js
index cc2ecf7..91a4540 100644
--- a/dojox/timing/Streamer.js
+++ b/dojox/timing/Streamer.js
@@ -3,9 +3,9 @@ dojo.provide("dojox.timing.Streamer");
 dojo.require("dojox.timing._base");
 
 dojox.timing.Streamer = function(
-	/* function */input, 
-	/* function */output, 
-	/* int */interval, 
+	/* function */input,
+	/* function */output,
+	/* int */interval,
 	/* int */minimum,
 	/* array */initialData
 ){
diff --git a/dojox/timing/ThreadPool.js b/dojox/timing/ThreadPool.js
index 7bd0637..4641608 100644
--- a/dojox/timing/ThreadPool.js
+++ b/dojox/timing/ThreadPool.js
@@ -5,31 +5,31 @@ dojo.experimental("dojox.timing.ThreadPool");
 
 //	dojox.timing.Timer is included as part of _base
 /********************************************************************
-	This is a port of the original System.Threading.ThreadPool from 
+	This is a port of the original System.Threading.ThreadPool from
 	the f(m) class library.
 	
 	Donated to the Dojo toolkit by the author :)
 *********************************************************************/
 (function(){
 	var t=dojox.timing;
-	t.threadStates={ 
-		UNSTARTED:"unstarted", 
-		STOPPED:"stopped", 
-		PENDING:"pending", 
-		RUNNING:"running", 
-		SUSPENDED:"suspended", 
-		WAITING:"waiting", 
+	t.threadStates={
+		UNSTARTED:"unstarted",
+		STOPPED:"stopped",
+		PENDING:"pending",
+		RUNNING:"running",
+		SUSPENDED:"suspended",
+		WAITING:"waiting",
 		COMPLETE:"complete",
 		ERROR:"error"
 	};
 
 	//	Before rar says a word, we actually *use* these numbers for a purpose :)
-	t.threadPriorities={ 
-		LOWEST:1, 
-		BELOWNORMAL:2, 
-		NORMAL:3, 
-		ABOVENORMAL:4, 
-		HIGHEST:5 
+	t.threadPriorities={
+		LOWEST:1,
+		BELOWNORMAL:2,
+		NORMAL:3,
+		ABOVENORMAL:4,
+		HIGHEST:5
 	};
 	
 	t.Thread=function(/* Function */fn, /* dojox.timing.threadPriorities? */priority){
diff --git a/dojox/timing/_base.js b/dojox/timing/_base.js
index 90168ce..9b57312 100644
--- a/dojox/timing/_base.js
+++ b/dojox/timing/_base.js
@@ -1,8 +1,8 @@
 dojo.provide("dojox.timing._base");
-dojo.experimental("dojox.timing"); 
+dojo.experimental("dojox.timing");
 
 dojox.timing.Timer = function(/*int*/ interval){
-	// summary: Timer object executes an "onTick()" method repeatedly at a specified 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;
@@ -33,7 +33,7 @@ dojo.extend(dojox.timing.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, 
+		// 				Note that the onTick() function is not called right away,
 		//				only after first interval passes.
 		if (typeof this.onStart == "function"){
 			this.onStart();
diff --git a/dojox/timing/doLater.js b/dojox/timing/doLater.js
index c908078..ad1e37a 100644
--- a/dojox/timing/doLater.js
+++ b/dojox/timing/doLater.js
@@ -1,5 +1,5 @@
 dojo.provide("dojox.timing.doLater");
-dojo.experimental("dojox.timing.doLater"); 
+dojo.experimental("dojox.timing.doLater");
 
 dojox.timing.doLater = function(/*anything*/conditional,/*Object ?*/context, /* Number ? */interval){
 	// summary:
@@ -7,12 +7,12 @@ dojox.timing.doLater = function(/*anything*/conditional,/*Object ?*/context, /*
 	//		"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 
+	//		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. 
+	//		true if the param is false.
 	//	arguments:
 	//		conditional: anything
 	//			Can be a property that eventually gets set, or
@@ -22,7 +22,7 @@ dojox.timing.doLater = function(/*anything*/conditional,/*Object ?*/context, /*
 	//			The namespace where the call originated.
 	//			Defaults to global and anonymous functions
 	//		interval:	Number
-	//			Poll time to check conditional in Milliseconds 
+	//			Poll time to check conditional in Milliseconds
 	// example:
 	//		| setTimeout(function(){
 	//		| 		if(dojox.timing.doLater(app.ready)){return;}
diff --git a/dojox/uuid/Uuid.js b/dojox/uuid/Uuid.js
index d676bd2..bc8ab4a 100644
--- a/dojox/uuid/Uuid.js
+++ b/dojox/uuid/Uuid.js
@@ -2,8 +2,8 @@ dojo.provide("dojox.uuid.Uuid");
 dojo.require("dojox.uuid");
 
 dojox.uuid.Uuid = function(/*String?*/ input){
-	// summary: 
-	//		This is the constructor for the Uuid class.  The Uuid class offers 
+	// summary:
+	//		This is the constructor for the Uuid class.  The Uuid class offers
 	//		methods for inspecting existing UUIDs.
 	// input: A 36-character string that conforms to the UUID spec.
 	// examples:
@@ -30,11 +30,11 @@ dojox.uuid.Uuid = function(/*String?*/ input){
 };
 
 dojox.uuid.Uuid.compare = function(/*dojox.uuid.Uuid*/ uuidOne, /*dojox.uuid.Uuid*/ uuidTwo){
-	// summary: 
+	// summary:
 	//		Given two UUIDs to compare, this method returns 0, 1, or -1.
 	// description:
 	//		This method is designed to be used by sorting routines, like the
-	//		JavaScript built-in Array sort() method. This implementation is 
+	//		JavaScript built-in Array sort() method. This implementation is
 	//		intended to match the sample implementation in IETF RFC 4122:
 	//		http://www.ietf.org/rfc/rfc4122.txt
 	// uuidOne: Any object that has toString() method that returns a 36-character string that conforms to the UUID spec.
@@ -56,8 +56,8 @@ dojox.uuid.Uuid.compare = function(/*dojox.uuid.Uuid*/ uuidOne, /*dojox.uuid.Uui
 };
 
 dojox.uuid.Uuid.setGenerator = function(/*Function?*/ generator){
-	// summary: 
-	//		Sets the default generator, which will be used by the 
+	// summary:
+	//		Sets the default generator, which will be used by the
 	//		"new dojox.uuid.Uuid()" constructor if no parameters
 	//		are passed in.
 	// generator: A UUID generator function, such as dojox.uuid.generateTimeBasedUuid.
@@ -66,20 +66,20 @@ dojox.uuid.Uuid.setGenerator = function(/*Function?*/ generator){
 };
 
 dojox.uuid.Uuid.getGenerator = function(){
-	// summary: 
+	// summary:
 	//		Returns the default generator.  See setGenerator().
 	return dojox.uuid.Uuid._ourGenerator; // generator (A UUID generator, such as dojox.uuid.TimeBasedGenerator).
 };
 
 dojox.uuid.Uuid.prototype.toString = function(){
-	// summary: 
-	//		This method returns a standard 36-character string representing 
+	// summary:
+	//		This method returns a standard 36-character string representing
 	//		the UUID, such as "3b12f1df-5232-4804-897e-917bf397618a".
 	return this._uuidString; // string
 };
 
 dojox.uuid.Uuid.prototype.compare = function(/*dojox.uuid.Uuid*/ otherUuid){
-	// summary: 
+	// summary:
 	//		Compares this UUID to another UUID, and returns 0, 1, or -1.
 	// description:
 	//		This implementation is intended to match the sample implementation
@@ -89,28 +89,28 @@ dojox.uuid.Uuid.prototype.compare = function(/*dojox.uuid.Uuid*/ otherUuid){
 };
 
 dojox.uuid.Uuid.prototype.isEqual = function(/*dojox.uuid.Uuid*/ otherUuid){
-	// summary: 
+	// summary:
 	//		Returns true if this UUID is equal to the otherUuid, or false otherwise.
 	// otherUuid: Any object that has toString() method that returns a 36-character string that conforms to the UUID spec.
 	return (this.compare(otherUuid) == 0); // boolean
 };
 
 dojox.uuid.Uuid.prototype.isValid = function(){
-	// summary: 
+	// summary:
 	//		Returns true if the UUID was initialized with a valid value.
 	return dojox.uuid.isValid(this);
 };
 
 dojox.uuid.Uuid.prototype.getVariant = function(){
-	// summary: 
+	// summary:
 	//		Returns a variant code that indicates what type of UUID this is.
 	//		Returns one of the enumerated dojox.uuid.variant values.
 
-	// example: 
+	// example:
 	//		var uuid = new dojox.uuid.Uuid("3b12f1df-5232-4804-897e-917bf397618a");
 	//		var variant = uuid.getVariant();
 	//		dojox.uuid.assert(variant == dojox.uuid.variant.DCE);
-	// example: 
+	// example:
 	// "3b12f1df-5232-4804-897e-917bf397618a"
 	//                     ^
 	//                     |
@@ -119,14 +119,14 @@ dojox.uuid.Uuid.prototype.getVariant = function(){
 };
 
 dojox.uuid.Uuid.prototype.getVersion = function(){
-	// summary: 
+	// summary:
 	//		Returns a version number that indicates what type of UUID this is.
 	//		Returns one of the enumerated dojox.uuid.version values.
-	// example: 
+	// example:
 	//		var uuid = new dojox.uuid.Uuid("b4308fb0-86cd-11da-a72b-0800200c9a66");
 	//		var version = uuid.getVersion();
 	//		dojox.uuid.assert(version == dojox.uuid.version.TIME_BASED);
-	// exceptions: 
+	// exceptions:
 	//		Throws an Error if this is not a DCE Variant UUID.
 	if(!this._versionNumber){
 		this._versionNumber = dojox.uuid.getVersion(this);
@@ -135,11 +135,11 @@ dojox.uuid.Uuid.prototype.getVersion = function(){
 };
 
 dojox.uuid.Uuid.prototype.getNode = function(){
-	// summary: 
-	//		If this is a version 1 UUID (a time-based UUID), getNode() returns a 
-	//		12-character string with the "node" or "pseudonode" portion of the UUID, 
-	//		which is the rightmost 12 characters.  
-	// exceptions: 
+	// summary:
+	//		If this is a version 1 UUID (a time-based UUID), getNode() returns a
+	//		12-character string with the "node" or "pseudonode" portion of the UUID,
+	//		which is the rightmost 12 characters.
+	// exceptions:
 	//		Throws an Error if this is not a version 1 UUID.
 	if (!this._nodeString) {
 		this._nodeString = dojox.uuid.getNode(this);
@@ -148,22 +148,22 @@ dojox.uuid.Uuid.prototype.getNode = function(){
 };
 
 dojox.uuid.Uuid.prototype.getTimestamp = function(/*String?*/ returnType){
-	// summary: 
+	// summary:
 	//		If this is a version 1 UUID (a time-based UUID), this method returns
 	//		the timestamp value encoded in the UUID.  The caller can ask for the
-	//		timestamp to be returned either as a JavaScript Date object or as a 
+	//		timestamp to be returned either as a JavaScript Date object or as a
 	//		15-character string of hex digits.
 	// returnType: Any of these five values: "string", String, "hex", "date", Date
-	// returns: 
+	// returns:
 	//		Returns the timestamp value as a JavaScript Date object or a 15-character string of hex digits.
-	// examples: 
+	// examples:
 	//		var uuid = new dojox.uuid.Uuid("b4308fb0-86cd-11da-a72b-0800200c9a66");
 	//		var date, string, hexString;
 	//		date   = uuid.getTimestamp();         // returns a JavaScript Date
-	//		date   = uuid.getTimestamp(Date);     // 
+	//		date   = uuid.getTimestamp(Date);     //
 	//		string = uuid.getTimestamp(String);   // "Mon, 16 Jan 2006 20:21:41 GMT"
 	//		hexString = uuid.getTimestamp("hex"); // "1da86cdb4308fb0"
-	// exceptions: 
+	// exceptions:
 	//		Throws an Error if this is not a version 1 UUID.
 	if(!returnType){returnType = null};
 	switch(returnType){
@@ -172,7 +172,7 @@ dojox.uuid.Uuid.prototype.getTimestamp = function(/*String?*/ returnType){
 			return this.getTimestamp(Date).toUTCString(); // String (e.g. "Mon, 16 Jan 2006 20:21:41 GMT")
 			break;
 		case "hex":
-			// Return a 15-character string of hex digits containing the 
+			// Return a 15-character string of hex digits containing the
 			// timestamp for this UUID, with the high-order bits first.
 			if (!this._timestampAsHexString) {
 				this._timestampAsHexString = dojox.uuid.getTimestamp(this, "hex");
@@ -182,7 +182,7 @@ dojox.uuid.Uuid.prototype.getTimestamp = function(/*String?*/ returnType){
 		case null: // no returnType was specified, so default to Date
 		case "date":
 		case Date:
-			// Return a JavaScript Date object. 
+			// Return a JavaScript Date object.
 			if (!this._timestampAsDate) {
 				this._timestampAsDate = dojox.uuid.getTimestamp(this, Date);
 			}
diff --git a/dojox/uuid/_base.js b/dojox/uuid/_base.js
index 466e0e3..8a58bde 100644
--- a/dojox/uuid/_base.js
+++ b/dojox/uuid/_base.js
@@ -18,11 +18,11 @@ dojox.uuid.variant = {
 	UNKNOWN: "111" };
 
 dojox.uuid.assert = function(/*Boolean*/ booleanValue, /*String?*/ message){
-	// summary: 
+	// summary:
 	//		Throws an exception if the assertion fails.
-	// description: 
+	// description:
 	//		If the asserted condition is true, this method does nothing. If the
-	//		condition is false, we throw an error with a error message. 
+	//		condition is false, we throw an error with a error message.
 	// booleanValue: Must be true for the assertion to succeed.
 	// message: A string describing the assertion.
 	// throws: Throws an Error if 'booleanValue' is false.
@@ -36,18 +36,18 @@ dojox.uuid.assert = function(/*Boolean*/ booleanValue, /*String?*/ message){
 };
 
 dojox.uuid.generateNilUuid = function(){
-	// summary: 
+	// summary:
 	//		This function returns the Nil UUID: "00000000-0000-0000-0000-000000000000".
-	// description: 
+	// description:
 	//		The Nil UUID is described in section 4.1.7 of
 	//		RFC 4122: http://tools.ietf.org/html/rfc4122#section-4.1.7
-	// examples: 
+	// examples:
 	//		var string = dojox.uuid.generateNilUuid();
 	return dojox.uuid.NIL_UUID; // String
 };
 
 dojox.uuid.isValid = function(/*String*/ uuidString){
-	// summary: 
+	// summary:
 	//		Returns true if the UUID was initialized with a valid value.
 	uuidString = uuidString.toString();
 	var valid = (dojo.isString(uuidString) &&
@@ -72,13 +72,13 @@ dojox.uuid.isValid = function(/*String*/ uuidString){
 };
 
 dojox.uuid.getVariant = function(/*String*/ uuidString){
-	// summary: 
+	// summary:
 	//		Returns a variant code that indicates what type of UUID this is.
 	//		Returns one of the enumerated dojox.uuid.variant values.
-	// example: 
+	// example:
 	//		var variant = dojox.uuid.getVariant("3b12f1df-5232-4804-897e-917bf397618a");
 	//		dojox.uuid.assert(variant == dojox.uuid.variant.DCE);
-	// example: 
+	// example:
 	// "3b12f1df-5232-4804-897e-917bf397618a"
 	//                     ^
 	//                     |
@@ -119,13 +119,13 @@ dojox.uuid.getVariant = function(/*String*/ uuidString){
 };
 
 dojox.uuid.getVersion = function(/*String*/ uuidString){
-	// summary: 
+	// summary:
 	//		Returns a version number that indicates what type of UUID this is.
 	//		Returns one of the enumerated dojox.uuid.version values.
-	// example: 
+	// example:
 	//		var version = dojox.uuid.getVersion("b4308fb0-86cd-11da-a72b-0800200c9a66");
 	//		dojox.uuid.assert(version == dojox.uuid.version.TIME_BASED);
-	// exceptions: 
+	// exceptions:
 	//		Throws an Error if this is not a DCE Variant UUID.
 	var errorMessage = "dojox.uuid.getVersion() was not passed a DCE Variant UUID.";
 	dojox.uuid.assert(dojox.uuid.getVariant(uuidString) == dojox.uuid.variant.DCE, errorMessage);
@@ -142,11 +142,11 @@ dojox.uuid.getVersion = function(/*String*/ uuidString){
 };
 
 dojox.uuid.getNode = function(/*String*/ uuidString){
-	// summary: 
-	//		If this is a version 1 UUID (a time-based UUID), getNode() returns a 
-	//		12-character string with the "node" or "pseudonode" portion of the UUID, 
-	//		which is the rightmost 12 characters. 
-	// exceptions: 
+	// summary:
+	//		If this is a version 1 UUID (a time-based UUID), getNode() returns a
+	//		12-character string with the "node" or "pseudonode" portion of the UUID,
+	//		which is the rightmost 12 characters.
+	// exceptions:
 	//		Throws an Error if this is not a version 1 UUID.
 	var errorMessage = "dojox.uuid.getNode() was not passed a TIME_BASED UUID.";
 	dojox.uuid.assert(dojox.uuid.getVersion(uuidString) == dojox.uuid.version.TIME_BASED, errorMessage);
@@ -158,22 +158,22 @@ dojox.uuid.getNode = function(/*String*/ uuidString){
 };
 
 dojox.uuid.getTimestamp = function(/*String*/ uuidString, /*String?*/ returnType){
-	// summary: 
+	// summary:
 	//		If this is a version 1 UUID (a time-based UUID), this method returns
 	//		the timestamp value encoded in the UUID.  The caller can ask for the
-	//		timestamp to be returned either as a JavaScript Date object or as a 
+	//		timestamp to be returned either as a JavaScript Date object or as a
 	//		15-character string of hex digits.
 	// returnType: Any of these five values: "string", String, "hex", "date", Date
-	// returns: 
+	// returns:
 	//		Returns the timestamp value as a JavaScript Date object or a 15-character string of hex digits.
-	// examples: 
+	// examples:
 	//		var uuidString = "b4308fb0-86cd-11da-a72b-0800200c9a66";
 	//		var date, string, hexString;
 	//		date   = dojox.uuid.getTimestamp(uuidString);         // returns a JavaScript Date
-	//		date   = dojox.uuid.getTimestamp(uuidString, Date);     // 
+	//		date   = dojox.uuid.getTimestamp(uuidString, Date);     //
 	//		string = dojox.uuid.getTimestamp(uuidString, String);   // "Mon, 16 Jan 2006 20:21:41 GMT"
 	//		hexString = dojox.uuid.getTimestamp(uuidString, "hex"); // "1da86cdb4308fb0"
-	// exceptions: 
+	// exceptions:
 	//		Throws an Error if this is not a version 1 UUID.
 	var errorMessage = "dojox.uuid.getTimestamp() was not passed a TIME_BASED UUID.";
 	dojox.uuid.assert(dojox.uuid.getVersion(uuidString) == dojox.uuid.version.TIME_BASED, errorMessage);
@@ -186,14 +186,14 @@ dojox.uuid.getTimestamp = function(/*String*/ uuidString, /*String?*/ returnType
 			return dojox.uuid.getTimestamp(uuidString, Date).toUTCString(); // String (e.g. "Mon, 16 Jan 2006 20:21:41 GMT")
 			break;
 		case "hex":
-			// Return a 15-character string of hex digits containing the 
+			// Return a 15-character string of hex digits containing the
 			// timestamp for this UUID, with the high-order bits first.
 			var arrayOfStrings = uuidString.split('-');
 			var hexTimeLow = arrayOfStrings[0];
 			var hexTimeMid = arrayOfStrings[1];
 			var hexTimeHigh = arrayOfStrings[2];
 		
-			// Chop off the leading "1" character, which is the UUID 
+			// Chop off the leading "1" character, which is the UUID
 			// version number for time-based UUIDs.
 			hexTimeHigh = hexTimeHigh.slice(1);
 		
@@ -204,7 +204,7 @@ dojox.uuid.getTimestamp = function(/*String*/ uuidString, /*String?*/ returnType
 		case null: // no returnType was specified, so default to Date
 		case "date":
 		case Date:
-			// Return a JavaScript Date object. 
+			// Return a JavaScript Date object.
 			var GREGORIAN_CHANGE_OFFSET_IN_HOURS = 3394248;
 			var HEX_RADIX = 16;
 		
@@ -215,7 +215,7 @@ dojox.uuid.getTimestamp = function(/*String*/ uuidString, /*String?*/ returnType
 			var hundredNanosecondIntervalsSince1582 = timeHigh & 0x0FFF;
 			hundredNanosecondIntervalsSince1582 <<= 16;
 			hundredNanosecondIntervalsSince1582 += timeMid;
-			// What we really want to do next is shift left 32 bits, but the 
+			// What we really want to do next is shift left 32 bits, but the
 			// result will be too big to fit in an int, so we'll multiply by 2^32,
 			// and the result will be a floating point approximation.
 			hundredNanosecondIntervalsSince1582 *= 0x100000000;
diff --git a/dojox/uuid/generateRandomUuid.js b/dojox/uuid/generateRandomUuid.js
index 5f23c7d..869c272 100644
--- a/dojox/uuid/generateRandomUuid.js
+++ b/dojox/uuid/generateRandomUuid.js
@@ -6,23 +6,23 @@ dojox.uuid.generateRandomUuid = function(){
 	// description:
 	//		A typical generated value would be something like this:
 	//		"3b12f1df-5232-4804-897e-917bf397618a"
-	//		
-	//		For more information about random UUIDs, see sections 4.4 and 
+	//
+	//		For more information about random UUIDs, see sections 4.4 and
 	//		4.5 of RFC 4122: http://tools.ietf.org/html/rfc4122#section-4.4
-	//		
+	//
 	//		This generator function is designed to be small and fast,
 	//		but not necessarily good.
-	//		
+	//
 	//		Small: This generator has a small footprint. Once comments are
-	//		stripped, it's only about 25 lines of code, and it doesn't 
+	//		stripped, it's only about 25 lines of code, and it doesn't
 	//		dojo.require() any other modules.
-	//		
-	//		Fast: This generator can generate lots of new UUIDs fairly quickly 
+	//
+	//		Fast: This generator can generate lots of new UUIDs fairly quickly
 	//		(at least, more quickly than the other dojo UUID generators).
-	//		
+	//
 	//		Not necessarily good: We use Math.random() as our source
-	//		of randomness, which may or may not provide much randomness. 
-	// examples: 
+	//		of randomness, which may or may not provide much randomness.
+	// examples:
 	//		var string = dojox.uuid.generateRandomUuid();
 	var HEX_RADIX = 16;
 
diff --git a/dojox/uuid/generateTimeBasedUuid.js b/dojox/uuid/generateTimeBasedUuid.js
index 97bfc29..cd40fe1 100644
--- a/dojox/uuid/generateTimeBasedUuid.js
+++ b/dojox/uuid/generateTimeBasedUuid.js
@@ -1,9 +1,9 @@
 dojo.provide("dojox.uuid.generateTimeBasedUuid");
 
 dojox.uuid.generateTimeBasedUuid = function(/*String?*/ node){
-	// summary: 
-	//		This function generates time-based UUIDs, meaning "version 1" UUIDs. 
-	// description: 
+	// summary:
+	//		This function generates time-based UUIDs, meaning "version 1" UUIDs.
+	// description:
 	// For more info, see
 	//		http://www.webdav.org/specs/draft-leach-uuids-guids-01.txt
 	//		http://www.infonuovo.com/dma/csdocs/sketch/instidid.htm
@@ -11,16 +11,16 @@ dojox.uuid.generateTimeBasedUuid = function(/*String?*/ node){
 	//		http://www.opengroup.org/onlinepubs/009629399/apdxa.htm#tagcjh_20
 	//		http://jakarta.apache.org/commons/sandbox/id/apidocs/org/apache/commons/id/uuid/clock/Clock.html
 	// node:
-	//		A 12-character hex string representing either a pseudo-node or 
-	//		hardware-node (an IEEE 802.3 network node).  A hardware-node 
-	//		will be something like "017bf397618a", always with the first bit 
-	//		being 0.  A pseudo-node will be something like "f17bf397618a", 
+	//		A 12-character hex string representing either a pseudo-node or
+	//		hardware-node (an IEEE 802.3 network node).  A hardware-node
+	//		will be something like "017bf397618a", always with the first bit
+	//		being 0.  A pseudo-node will be something like "f17bf397618a",
 	//		always with the first bit being 1.
-	// examples: 
+	// examples:
 	//		string = dojox.uuid.generateTimeBasedUuid();
 	//		string = dojox.uuid.generateTimeBasedUuid("017bf397618a");
 	//		dojox.uuid.generateTimeBasedUuid.setNode("017bf397618a");
-	//		string = dojox.uuid.generateTimeBasedUuid(); // the generated UUID has node == "017bf397618a"	
+	//		string = dojox.uuid.generateTimeBasedUuid(); // the generated UUID has node == "017bf397618a"
 	var uuidString = dojox.uuid.generateTimeBasedUuid._generator.generateUuidString(node);
 	return uuidString; // String
 };
@@ -33,7 +33,7 @@ dojox.uuid.generateTimeBasedUuid.isValidNode = function(/*String?*/ node){
 };
 
 dojox.uuid.generateTimeBasedUuid.setNode = function(/*String?*/ node){
-	// summary: 
+	// summary:
 	//		Sets the 'node' value that will be included in generated UUIDs.
 	// node: A 12-character hex string representing a pseudoNode or hardwareNode.
 	dojox.uuid.assert((node === null) || this.isValidNode(node));
@@ -41,7 +41,7 @@ dojox.uuid.generateTimeBasedUuid.setNode = function(/*String?*/ node){
 };
 
 dojox.uuid.generateTimeBasedUuid.getNode = function(){
-	// summary: 
+	// summary:
 	//		Returns the 'node' value that will be included in generated UUIDs.
 	return this._uniformNode; // String (a 12-character hex string representing a pseudoNode or hardwareNode)
 };
@@ -52,7 +52,7 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	this.GREGORIAN_CHANGE_OFFSET_IN_HOURS = 3394248;
 	
 	// Number of seconds between October 15, 1582 and January 1, 1970:
-	//   dojox.uuid.generateTimeBasedUuid.GREGORIAN_CHANGE_OFFSET_IN_SECONDS = 12219292800;	
+	//   dojox.uuid.generateTimeBasedUuid.GREGORIAN_CHANGE_OFFSET_IN_SECONDS = 12219292800;
 	
 	// --------------------------------------------------
 	// Private variables:
@@ -68,9 +68,9 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	var HEX_RADIX = 16;
 
 	function _carry(/* array */ arrayA){
-		// summary: 
-		//		Given an array which holds a 64-bit number broken into 4 16-bit 
-		//		elements, this method carries any excess bits (greater than 16-bits) 
+		// summary:
+		//		Given an array which holds a 64-bit number broken into 4 16-bit
+		//		elements, this method carries any excess bits (greater than 16-bits)
 		//		from each array element into the next.
 		// arrayA: An array with 4 elements, each of which is a 16-bit number.
 		arrayA[2] += arrayA[3] >>> 16;
@@ -83,8 +83,8 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 
 	function _get64bitArrayFromFloat(/* float */ x){
-		// summary: 
-		//		Given a floating point number, this method returns an array which 
+		// summary:
+		//		Given a floating point number, this method returns an array which
 		//		holds a 64-bit number broken into 4 16-bit elements.
 		var result = new Array(0, 0, 0, 0);
 		result[3] = x % 0x10000;
@@ -101,7 +101,7 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 
 	function _addTwo64bitArrays(/* array */ arrayA, /* array */ arrayB){
-		// summary: 
+		// summary:
 		//		Takes two arrays, each of which holds a 64-bit number broken into 4
 		//		16-bit elements, and returns a new array that holds a 64-bit number
 		//		that is the sum of the two original numbers.
@@ -122,7 +122,7 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 
 	function _multiplyTwo64bitArrays(/* array */ arrayA, /* array */ arrayB){
-		// summary: 
+		// summary:
 		//		Takes two arrays, each of which holds a 64-bit number broken into 4
 		//		16-bit elements, and returns a new array that holds a 64-bit number
 		//		that is the product of the two original numbers.
@@ -167,12 +167,12 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 
 	function _padWithLeadingZeros(/* string */ string, /* int */ desiredLength){
-		// summary: 
+		// summary:
 		//		Pads a string with leading zeros and returns the result.
 		// string: A string to add padding to.
 		// desiredLength: The number of characters the return string should have.
 
-		// examples: 
+		// examples:
 		//		result = _padWithLeadingZeros("abc", 6);
 		//		dojox.uuid.assert(result == "000abc");
 		while(string.length < desiredLength){
@@ -182,7 +182,7 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 
 	function _generateRandomEightCharacterHexString() {
-		// summary: 
+		// summary:
 		//		Returns a randomly generated 8-character string of hex digits.
 
 		// FIXME: This probably isn't a very high quality random number.
@@ -199,11 +199,11 @@ dojox.uuid.generateTimeBasedUuid._generator = new function(){
 	}
 	
 	this.generateUuidString = function(/*String?*/ node){
-		// summary: 
-		//		Generates a time-based UUID, meaning a version 1 UUID.  
-		// description: 
-		//		JavaScript code running in a browser doesn't have access to the 
-		//		IEEE 802.3 address of the computer, so if a node value isn't 
+		// summary:
+		//		Generates a time-based UUID, meaning a version 1 UUID.
+		// description:
+		//		JavaScript code running in a browser doesn't have access to the
+		//		IEEE 802.3 address of the computer, so if a node value isn't
 		//		supplied, we generate a random pseudonode value instead.
 		// node: An optional 12-character string to use as the node in the new UUID.
 		if(node){
diff --git a/dojox/uuid/tests/uuid.js b/dojox/uuid/tests/uuid.js
index b5bdc5d..090c822 100644
--- a/dojox/uuid/tests/uuid.js
+++ b/dojox/uuid/tests/uuid.js
@@ -9,7 +9,7 @@ dojox.uuid.tests.uuid.checkValidityOfUuidString = function(/*String*/uuidString)
 	//		A helper function that's used by the registered test functions
 	var NIL_UUID = "00000000-0000-0000-0000-000000000000";
 	if (uuidString == NIL_UUID) {
-		// We'll consider the Nil UUID to be valid, so now 
+		// We'll consider the Nil UUID to be valid, so now
 		// we can just return, with not further checks.
 		return;
 	}
@@ -71,7 +71,7 @@ dojox.uuid.tests.uuid.checkForPseudoNodeBitInTimeBasedUuidString = function(/*St
 	doh.assertTrue(firstBit == '1'); // first bit of section 4 is 1
 }
 
-doh.register("dojox.uuid.tests.uuid", 
+doh.register("dojox.uuid.tests.uuid",
 	[
 		/*
 		function test_uuid_performance(){
@@ -131,7 +131,7 @@ doh.register("dojox.uuid.tests.uuid",
 			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.isEqual(uuidToo));	
+			doh.assertTrue(uuid.isEqual(uuidToo));
 		
 			var timeBasedUuidString = "b4308fb0-86cd-11da-a72b-0800200c9a66";
 			uuid = new dojox.uuid.Uuid(timeBasedUuidString);
diff --git a/dojox/validate.js b/dojox/validate.js
index be0fb1d..b81ed0c 100644
--- a/dojox/validate.js
+++ b/dojox/validate.js
@@ -1,2 +1,2 @@
 dojo.provide("dojox.validate");
-dojo.require("dojox.validate._base"); 
+dojo.require("dojox.validate._base");
diff --git a/dojox/validate/_base.js b/dojox/validate/_base.js
index 11abd53..b8d2091 100644
--- a/dojox/validate/_base.js
+++ b/dojox/validate/_base.js
@@ -7,7 +7,7 @@ dojo.require("dojox.validate.regexp"); 	// additional expressions
 
 dojox.validate.isText = function(/*String*/value, /*Object?*/flags){
 	// summary:
-	//	Checks if a string has non whitespace characters. 
+	//	Checks if a string has non whitespace characters.
 	//	Parameters allow you to constrain the length.
 	//
 	// value: A string
@@ -34,7 +34,7 @@ dojox.validate._isInRangeCache = {};
 dojox.validate.isInRange = function(/*String*/value, /*Object?*/flags){
 	// summary:
 	//	Validates whether a string denoting a number
-	//	is between a max and min. 
+	//	is between a max and min.
 	//
 	// value: A string
 	// flags: {max:Number, min:Number, decimal:String}
@@ -70,7 +70,7 @@ dojox.validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 	//
 	// description:
 	//		Validates any sort of number based format. Use it for phone numbers,
-	//		social security numbers, zip-codes, etc. The value can be validated 
+	//		social security numbers, zip-codes, etc. The value can be validated
 	//		against one format or one of multiple formats.
 	//
 	// Format Definition
@@ -78,7 +78,7 @@ dojox.validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 	// |   ?        Stands for an optional digit, 0-9 or nothing.
 	//    All other characters must appear literally in the expression.
 	//
-	// example:   
+	// example:
 	// |  "(###) ###-####"       ->   (510) 542-9742
 	// |  "(###) ###-#### x#???" ->   (510) 542-9742 x153
 	// |  "###-##-####"          ->   506-82-1089       i.e. social security number
@@ -86,10 +86,10 @@ dojox.validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 	//
 	// value: A string
 	//
-	// flags: Object? 
+	// flags: Object?
 	//		FIXME: make pseudo-object for this
 	//		format: String
-	//			
+	//
 	//    flags.format  A string or an Array of strings for multiple formats.
 	//
 	// example:
@@ -98,7 +98,7 @@ dojox.validate.isNumberFormat = function(/* String */value, /* Object? */flags){
 	//
 	// example:
 	// 		Check Multiple formats:
-	// |	dojox.validate.isNumberFormat("123-45", {	
+	// |	dojox.validate.isNumberFormat("123-45", {
 	// |		format:["### ##","###-##","## ###"]
 	// |	});
 	//
@@ -111,7 +111,7 @@ dojox.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. 
+	//		its integrity.
 	
 	var sum = 0, parity, curDigit;
 	if(!dojo.isString(value)){
diff --git a/dojox/validate/br.js b/dojox/validate/br.js
index 9042ac2..0d08711 100755
--- a/dojox/validate/br.js
+++ b/dojox/validate/br.js
@@ -2,7 +2,7 @@ dojo.provide("dojox.validate.br");
 dojo.require("dojox.validate._base");
 
 dojox.validate.br.isValidCnpj = function(/*String*/value){
-	// summary: 
+	// summary:
 	//		Validates a CNPJ/CGC number
 	//
 	// value: String
@@ -26,7 +26,7 @@ dojox.validate.br.isValidCnpj = function(/*String*/value){
 		]
 	};
 	if(dojox.validate.isNumberFormat(value, flags)){
-		// Matched the initial test, so break this down into the 
+		// Matched the initial test, so break this down into the
 		// parts to be validated.
 		value = value.replace("/", "").replace(/\./g, "").replace("-", "");
 		var cgc = [];
@@ -38,7 +38,7 @@ dojox.validate.br.isValidCnpj = function(/*String*/value){
 		for(i = 0; i < 10; i++){
 			tmp = "";
 			for(j = 0; j < value.length; j++){
-				tmp += "" + i; 
+				tmp += "" + i;
 			}
 			if(value === tmp){
 				return false;
@@ -98,7 +98,7 @@ dojox.validate.br.computeCnpjDv = function(/*String*/value){
 		]
 	};
 	if(dojox.validate.isNumberFormat(value, flags)){
-		// Matched the initial test, so break this down into the 
+		// Matched the initial test, so break this down into the
 		// parts to compute the DV.
 		value = value.replace("/", "").replace(/\./g, "");
 		var cgc = [];
@@ -109,7 +109,7 @@ dojox.validate.br.computeCnpjDv = function(/*String*/value){
 		for(i = 0; i < 10; i++){
 			tmp = "";
 			for(j = 0; j < value.length; j++){
-				tmp += "" + i; 
+				tmp += "" + i;
 			}
 			if(value === tmp){
 				return "";
@@ -139,7 +139,7 @@ dojox.validate.br.computeCnpjDv = function(/*String*/value){
 
 
 dojox.validate.br.isValidCpf = function(/*String*/value){
-	// summary: 
+	// summary:
 	//		Validates a CPF number
 	//
 	// value: String
@@ -162,7 +162,7 @@ dojox.validate.br.isValidCpf = function(/*String*/value){
 		]
 	};
 	if(dojox.validate.isNumberFormat(value, flags)){
-		// Matched the initial test, so break this down into the 
+		// Matched the initial test, so break this down into the
 		// parts to be validated.
 		value = value.replace("-", "").replace(/\./g, "");
 		var cpf = [];
@@ -174,7 +174,7 @@ dojox.validate.br.isValidCpf = function(/*String*/value){
 		for(i = 0; i < 10; i++){
 			tmp = "";
 			for(j = 0; j < value.length; j++){
-				tmp += "" + i; 
+				tmp += "" + i;
 			}
 			if(value === tmp){
 				return false;
@@ -214,7 +214,7 @@ dojox.validate.br.isValidCpf = function(/*String*/value){
 };
 
 dojox.validate.br.computeCpfDv = function(/*String*/value){
-	// summary: 
+	// summary:
 	//		Generate the DV code (checksum part) for a CPF number
 	//
 	// value: String
@@ -235,7 +235,7 @@ dojox.validate.br.computeCpfDv = function(/*String*/value){
 		]
 	};
 	if(dojox.validate.isNumberFormat(value, flags)){
-		// Matched the initial test, so break this down into the 
+		// Matched the initial test, so break this down into the
 		// parts to compute the DV.
 		value = value.replace(/\./g, "");
 		var cpf = [];
@@ -245,7 +245,7 @@ dojox.validate.br.computeCpfDv = function(/*String*/value){
 		for(i = 0; i < 10; i++){
 			tmp = "";
 			for(j = 0; j < value.length; j++){
-				tmp += "" + i; 
+				tmp += "" + i;
 			}
 			if(value === tmp){
 				return "";
diff --git a/dojox/validate/ca.js b/dojox/validate/ca.js
index d3c16a9..61eb1c2 100644
--- a/dojox/validate/ca.js
+++ b/dojox/validate/ca.js
@@ -19,15 +19,15 @@ dojo.mixin(dojox.validate.ca,{
 		// summary: Validates Canadian province abbreviations (2 characters)
 		var re = new RegExp("^" + dojox.validate.regexp.ca.province() + "$", "i");
 		return re.test(value); // Boolean
-	}, 
+	},
  
 	isSocialInsuranceNumber: function(/* String */value) {
-		// summary: Validates Canadian 9 digit social insurance number for several 
+		// summary: Validates Canadian 9 digit social insurance number for several
 		//		common formats
 		//
 		// description:
-		//		Validates Canadian 9 digit social insurance number for several 
-		//		common formats. This routine only pattern matches and does not 
+		//		Validates Canadian 9 digit social insurance number for several
+		//		common formats. This routine only pattern matches and does not
 		//		use the Luhn Algorithm to validate number.
 		//
 		var flags = { format: [ "###-###-###", "### ### ###", "#########" ]};
@@ -36,7 +36,7 @@ dojo.mixin(dojox.validate.ca,{
 
 	isPostalCode: function(value) {
 		// summary: Validates Canadian 6 digit postal code
-		// 
+		//
 		// description:
 		//		Validates Canadian 6 digit postal code.
 		//		Canadian postal codes are in the format ANA NAN,
diff --git a/dojox/validate/check.js b/dojox/validate/check.js
index 8ebe6a4..200b8da 100644
--- a/dojox/validate/check.js
+++ b/dojox/validate/check.js
@@ -34,11 +34,11 @@ dojo.require("dojox.validate._base");
 			// dependant/conditional fields are required if the target field is present and not blank.
 			// At present only textbox, password, and textarea fields are supported.
 			dependencies:	{
-				cc_exp: "cc_no",	
-				cc_type: "cc_no"	
+				cc_exp: "cc_no",
+				cc_type: "cc_no"
 			},
 
-			// Fields can be validated using any boolean valued function.  
+			// Fields can be validated using any boolean valued function.
 			// Use arrays to specify parameters in addition to the field value.
 			constraints: {
 				field_name1: myValidationFunction,
@@ -52,7 +52,7 @@ dojo.require("dojox.validate._base");
 			// It associates each field in its property list with another field whose value should be equal.
 			// If the values are not equal, the field in the property list is reported as Invalid. Unless the target field is blank.
 			confirm: {
-				email_confirm: "email",	
+				email_confirm: "email",
 				pw2: "pw1"
 			}
 		};
@@ -153,18 +153,18 @@ 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++){ 
+		for(var i = 0; i < profile.required.length; i++){
 			if(!dojo.isString(profile.required[i])){ continue; }
 			var elem = form[profile.required[i]];
 			// Are textbox, textarea, or password fields blank.
-			if(!_undef("type", elem) 
-				&& (elem.type == "text" || elem.type == "textarea" || elem.type == "password" || elem.type == "file") 
-				&& /^\s*$/.test(elem.value)){	
+			if(!_undef("type", elem)
+				&& (elem.type == "text" || elem.type == "textarea" || elem.type == "password" || elem.type == "file")
+				&& /^\s*$/.test(elem.value)){
 				missing[missing.length] = elem.name;
 			}
 			// Does drop-down box have option selected.
-			else if(!_undef("type", elem) && (elem.type == "select-one" || elem.type == "select-multiple") 
-						&& (elem.selectedIndex == -1 
+			else if(!_undef("type", elem) && (elem.type == "select-one" || elem.type == "select-multiple")
+						&& (elem.selectedIndex == -1
 						|| /^\s*$/.test(elem.options[elem.selectedIndex].value))){
 				missing[missing.length] = elem.name;
 			}
@@ -174,7 +174,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 				for(var j = 0; j < elem.length; j++){
 					if (elem[j].checked) { checked = true; }
 				}
-				if(!checked){	
+				if(!checked){
 					missing[missing.length] = elem[0].name;
 				}
 			}
@@ -183,11 +183,11 @@ 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++){ 
+		for (var i = 0; i < profile.required.length; i++){
 			if(!dojo.isObject(profile.required[i])){ continue; }
 			var elem, numRequired;
-			for(var name in profile.required[i]){ 
-				elem = form[name]; 
+			for(var name in profile.required[i]){
+				elem = form[name];
 				numRequired = profile.required[i][name];
 			}
 			// case 1: elem is a check box group
@@ -196,7 +196,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 				for(var j = 0; j < elem.length; j++){
 					if(elem[j].checked){ checked++; }
 				}
-				if(checked < numRequired){	
+				if(checked < numRequired){
 					missing[missing.length] = elem[0].name;
 				}
 			}
@@ -206,7 +206,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 				for(var j = 0; j < elem.options.length; j++){
 					if (elem.options[j].selected && !/^\s*$/.test(elem.options[j].value)) { selected++; }
 				}
-				if(selected < numRequired){	
+				if(selected < numRequired){
 					missing[missing.length] = elem.name;
 				}
 			}
@@ -241,11 +241,11 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 			
 			// skip if blank - its optional unless required, in which case it
 			// is already listed as missing.
-			if(!_undef("tagName",elem) 
+			if(!_undef("tagName",elem)
 				&& (elem.tagName.toLowerCase().indexOf("input") >= 0
-					|| elem.tagName.toLowerCase().indexOf("textarea") >= 0) 
-				&& /^\s*$/.test(elem.value)){ 
-				continue; 
+					|| elem.tagName.toLowerCase().indexOf("textarea") >= 0)
+				&& /^\s*$/.test(elem.value)){
+				continue;
 			}
 			
 			var isValid = true;
@@ -267,7 +267,7 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 				}
 			}
 			
-			if(!isValid){	
+			if(!isValid){
 				invalid[invalid.length] = elem.name;
 			}
 		}
@@ -278,13 +278,13 @@ dojox.validate.check = function(/*HTMLFormElement*/form, /*Object*/profile){
 		for(name in profile.confirm){
 			var elem = form[name];	// the confirm element
 			var target = form[profile.confirm[name]];
-			if (_undef("type", elem) || _undef("type", target) || (elem.type != "text" && elem.type != "textarea" && elem.type != "password") 
+			if (_undef("type", elem) || _undef("type", target) || (elem.type != "text" && elem.type != "textarea" && elem.type != "password")
 				||(target.type != elem.type)
 				||(target.value == elem.value)	// it's valid
 				||(results.isInvalid(elem.name))// already listed as invalid
 				||(/^\s*$/.test(target.value)))	// skip if blank - only confirm if target has a value
 			{
-				continue; 
+				continue;
 			}
 			invalid[invalid.length] = elem.name;
 		}
@@ -303,10 +303,10 @@ dojox.validate.evaluateConstraint=function(profile, /*Array*/constraint, fieldNa
 	//              fieldName: [functionToCall, param1, param2, etc.],
 	//              fieldName: [[functionToCallFirst, param1],[functionToCallSecond,param2]]
 	//      }
-	// 
+	//
 	//  This function evaluates a single array function in the format of:
 	//      [functionName, argument1, argument2, etc]
-	// 
+	//
 	//  The function will be parsed out and evaluated against the incoming parameters.
 	//
 	// profile: The dojo.validate.check() profile that this evaluation is against.
diff --git a/dojox/validate/creditCard.js b/dojox/validate/creditCard.js
index f2e2674..1709ada 100644
--- a/dojox/validate/creditCard.js
+++ b/dojox/validate/creditCard.js
@@ -2,8 +2,8 @@ dojo.provide("dojox.validate.creditCard");
 /*=====
 
 	dojox.validate.creditCard = {
-		// summary: 
-		//		Module provides validation functions for Credit Cards, using account number 
+		// summary:
+		//		Module provides validation functions for Credit Cards, using account number
 		//		rules in conjunction with the Luhn algorigthm, with a plugable card info database.
 	};
 	
@@ -11,12 +11,12 @@ dojo.provide("dojox.validate.creditCard");
 dojo.require("dojox.validate._base");
 
 dojox.validate._cardInfo = {
-	// summary: A dictionary list of credit card abbreviations 
+	// summary: A dictionary list of credit card abbreviations
+	//
+	// description:
+	//
+	//		A hash of valid CC abbreviations and regular expressions
 	//
-	// description: 
-	//	
-	//		A hash of valid CC abbreviations and regular expressions 
-	//	
 	//		mc: Mastercard
 	//		ec: Eurocard
 	//		vi: Visa
@@ -32,12 +32,12 @@ dojox.validate._cardInfo = {
 	//		is 15 total length.
 	//	| dojo.mixin(dojox.validate._cardInfo, {
 	//	| 	"my":"7[0-9]{14}"
-	//	| });	
+	//	| });
 	
 	'mc':'5[1-5][0-9]{14}',
 	'ec':'5[1-5][0-9]{14}',
 	'vi':'4(?:[0-9]{12}|[0-9]{15})',
-	'ax':'3[47][0-9]{13}', 
+	'ax':'3[47][0-9]{13}',
 	'dc':'3(?:0[0-5][0-9]{11}|[68][0-9]{12})',
 	'bl':'3(?:0[0-5][0-9]{11}|[68][0-9]{12})',
 	'di':'6011[0-9]{12}',
@@ -49,19 +49,19 @@ dojox.validate.isValidCreditCard = function(value, ccType){
 	// summary: Validate a credit card number by type with Luhn checking.
 	//
 	// description:
-	//		Checks if a credit card type matches the # scheme in a passed value, and if 
-	//		the Luhn checksum is accurate (unless its an Enroute card, in which case 
-	//		the checkSum is skipped), returning a Boolean to check against. 
+	//		Checks if a credit card type matches the # scheme in a passed value, and if
+	//		the Luhn checksum is accurate (unless its an Enroute card, in which case
+	//		the checkSum is skipped), returning a Boolean to check against.
 	//
 	// value: String|Int
 	//		A Value (credit card number) to validate
 	//
 	// ccType: String
-	//		A credit-card abbreviation. 
+	//		A credit-card abbreviation.
 	//
 	// example:
-	// |	if(dojox.validate.isValidCreditCard("12345", "mc")){ 
-	// |		console.log('inconceivable'); 
+	// |	if(dojox.validate.isValidCreditCard("12345", "mc")){
+	// |		console.log('inconceivable');
 	// |	}
 	
 	return ((ccType.toLowerCase() == 'er' || dojox.validate.isValidLuhn(value)) &&
@@ -69,15 +69,15 @@ dojox.validate.isValidCreditCard = function(value, ccType){
 }
 
 dojox.validate.isValidCreditCardNumber = function(value, ccType){
-	// summary: 
+	// summary:
 	//		Checks if value matches the pattern for that card or any card types if none is specified
 	//
 	// value: String|Int
 	//		CC #, white spaces and dashes are ignored
 	//
 	// ccType: String?
-	//		One of the abbreviation values in `dojox.validate._cardInfo` -- 
-	//		if Omitted, function returns a `|` delimited string of matching card types, 
+	//		One of the abbreviation values in `dojox.validate._cardInfo` --
+	//		if Omitted, function returns a `|` delimited string of matching card types,
 	//		or false if no matches found.
 
 	value = String(value).replace(/[- ]/g,''); //ignore dashes and whitespaces
@@ -101,8 +101,8 @@ dojox.validate.isValidCvv = function(/* String|Int */value, /* String */ccType)
 	//  	Validate the security code (CCV) for a passed credit-card type.
 	//
 	// description:
-	// 
-	// value: 
+	//
+	// value:
 	
 	if(!dojo.isString(value)){
 		value = String(value);
diff --git a/dojox/validate/isbn.js b/dojox/validate/isbn.js
index 66949c2..46e62ae 100644
--- a/dojox/validate/isbn.js
+++ b/dojox/validate/isbn.js
@@ -14,7 +14,7 @@ dojox.validate.isValidIsbn = function(/* String */value) {
 	len = value.length;
 
 	switch(len){
-		case 10: 
+		case 10:
 			weight = len;
 			// ISBN-10 validation algorithm
 			for(var i = 0; i < 9; i++){
@@ -23,7 +23,7 @@ dojox.validate.isValidIsbn = function(/* String */value) {
 			}
 			var t = value.charAt(9).toUpperCase();
 			sum += t == 'X' ? 10 : parseInt(t);
-			return sum % 11 == 0; // Boolean			
+			return sum % 11 == 0; // Boolean
 			break;
 		case 13:
 			weight = -1;
@@ -31,8 +31,8 @@ dojox.validate.isValidIsbn = function(/* String */value) {
 				sum += parseInt(value.charAt(i)) * (2 + weight);
 				weight *= -1;
 			}
-			return sum % 10 == 0; // Boolean		
-			break;			
+			return sum % 10 == 0; // Boolean
+			break;
 	}
 	return false;
 }
diff --git a/dojox/validate/regexp.js b/dojox/validate/regexp.js
index 73eac32..ebb1f09 100644
--- a/dojox/validate/regexp.js
+++ b/dojox/validate/regexp.js
@@ -1,6 +1,6 @@
 dojo.provide("dojox.validate.regexp");
 
-dojo.require("dojo.regexp"); 
+dojo.require("dojo.regexp");
 
 dojo.mixin(dojox.validate.regexp, {
 	
@@ -34,34 +34,34 @@ dojo.mixin(dojox.validate.regexp, {
 		if(typeof flags.allowHybrid != "boolean"){ flags.allowHybrid = true; }
 
 		// decimal-dotted IP address RE.
-		var dottedDecimalRE = 
+		var dottedDecimalRE =
 			// Each number is between 0-255.  Zero padding is not allowed.
 			"((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
 
 		// dotted hex IP address RE.  Each number is between 0x0-0xff.  Zero padding is allowed, e.g. 0x00.
 		var dottedHexRE = "(0[xX]0*[\\da-fA-F]?[\\da-fA-F]\\.){3}0[xX]0*[\\da-fA-F]?[\\da-fA-F]";
 
-		// dotted octal IP address RE.  Each number is between 0000-0377.  
+		// dotted octal IP address RE.  Each number is between 0000-0377.
 		// Zero padding is allowed, but each number must have at least 4 characters.
 		var dottedOctalRE = "(0+[0-3][0-7][0-7]\\.){3}0+[0-3][0-7][0-7]";
 
-		// decimal IP address RE.  A decimal number between 0-4294967295.  
+		// decimal IP address RE.  A decimal number between 0-4294967295.
 		var decimalRE =  "(0|[1-9]\\d{0,8}|[1-3]\\d{9}|4[01]\\d{8}|42[0-8]\\d{7}|429[0-3]\\d{6}|" +
 			"4294[0-8]\\d{5}|42949[0-5]\\d{4}|429496[0-6]\\d{3}|4294967[01]\\d{2}|42949672[0-8]\\d|429496729[0-5])";
 
-		// hexadecimal IP address RE. 
+		// hexadecimal IP address RE.
 		// A hexadecimal number between 0x0-0xFFFFFFFF. Case insensitive.  Zero padding is allowed.
 		var hexRE = "0[xX]0*[\\da-fA-F]{1,8}";
 
-		// IPv6 address RE. 
+		// IPv6 address RE.
 		// The format is written as eight groups of four hexadecimal digits, x:x:x:x:x:x:x:x,
-		// where x is between 0000-ffff. Zero padding is optional. Case insensitive. 
+		// where x is between 0000-ffff. Zero padding is optional. Case insensitive.
 		var ipv6RE = "([\\da-fA-F]{1,4}\\:){7}[\\da-fA-F]{1,4}";
 
-		// IPv6/IPv4 Hybrid address RE. 
-		// The format is written as six groups of four hexadecimal digits, 
+		// IPv6/IPv4 Hybrid address RE.
+		// The format is written as six groups of four hexadecimal digits,
 		// followed by the 4 dotted decimal IPv4 format. x:x:x:x:x:x:d.d.d.d
-		var hybridRE = "([\\da-fA-F]{1,4}\\:){6}" + 
+		var hybridRE = "([\\da-fA-F]{1,4}\\:){6}" +
 			"((\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])";
 
 		// Build IP Address RE
@@ -120,7 +120,7 @@ dojo.mixin(dojox.validate.regexp, {
 		// summary: Builds a regular expression that matches a URL
 		//
 		// flags: An object
-		//    flags.scheme  Can be true, false, or [true, false]. 
+		//    flags.scheme  Can be true, false, or [true, false].
 		//      This means: required, not allowed, or match either one.
 		//    flags in regexp.host can be applied.
 		//    flags in regexp.ipAddress can be applied.
@@ -183,7 +183,7 @@ dojo.mixin(dojox.validate.regexp, {
 
 		// build a RE for an Email Address List
 		var emailAddressRE = dojox.validate.regexp.emailAddress(flags);
-		var emailAddressListRE = "(" + emailAddressRE + "\\s*[" + flags.listSeparator + "]\\s*)*" + 
+		var emailAddressListRE = "(" + emailAddressRE + "\\s*[" + flags.listSeparator + "]\\s*)*" +
 			emailAddressRE + "\\s*[" + flags.listSeparator + "]?\\s*";
 
 		return emailAddressListRE; // String
@@ -200,7 +200,7 @@ dojo.mixin(dojox.validate.regexp, {
 		//    ?        Stands for an optional digit, 0-9 or nothing.
 		//    All other characters must appear literally in the expression.
 		//
-		//  Example   
+		//  Example
 		//    "(###) ###-####"       ->   (510) 542-9742
 		//    "(###) ###-#### x#???" ->   (510) 542-9742 x153
 		//    "###-##-####"          ->   506-82-1089       i.e. social security number
@@ -259,8 +259,8 @@ dojox.validate.regexp.us = {
 		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|" + 
+		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
diff --git a/dojox/validate/tests/br.js b/dojox/validate/tests/br.js
index 041b9cc..4c6815f 100755
--- a/dojox/validate/tests/br.js
+++ b/dojox/validate/tests/br.js
@@ -6,7 +6,7 @@ tests.register("dojox.validate.tests.br",[
 	//Randomy generated valid CNJP/CGC numbers.
 	{
 		name:"isValidCnpj",
-		runTest: function(doh) { 
+		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");
@@ -38,7 +38,7 @@ tests.register("dojox.validate.tests.br",[
 	},
 	{
 		name:"computeCnpjDv",
-		runTest: function(doh) { 
+		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");
@@ -58,7 +58,7 @@ tests.register("dojox.validate.tests.br",[
 	//All CPF numbers randomly generated from: http://www.gerardocumentos.com.br
 	{
 		name:"isValidCpf",
-		runTest: function(doh) { 
+		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");
@@ -82,7 +82,7 @@ tests.register("dojox.validate.tests.br",[
 	},
 	{
 		name:"computeCpfDv",
-		runTest: function(doh) { 
+		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");
diff --git a/dojox/validate/tests/creditcard.js b/dojox/validate/tests/creditcard.js
index f6c7c42..d957928 100644
--- a/dojox/validate/tests/creditcard.js
+++ b/dojox/validate/tests/creditcard.js
@@ -4,7 +4,7 @@ dojo.require("dojox.validate.creditCard");
 tests.register("dojox.validate.tests.creditcard",
 	[{
 		name:"isValidLuhn",
-		runTest: function(tests) { 
+		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
@@ -14,7 +14,7 @@ tests.register("dojox.validate.tests.creditcard",
 		}
 	},
 	{
-		name:"isValidCvv", 
+		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
@@ -23,7 +23,7 @@ tests.register("dojox.validate.tests.creditcard",
 			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('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
@@ -67,7 +67,7 @@ tests.register("dojox.validate.tests.creditcard",
 			tests.f(dojox.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(dojox.validate.isValidCreditCard('214900000000000','er'));
 		}
 	},
 	{
diff --git a/dojox/validate/tests/module.js b/dojox/validate/tests/module.js
index 7805e7b..c58145c 100644
--- a/dojox/validate/tests/module.js
+++ b/dojox/validate/tests/module.js
@@ -2,10 +2,10 @@ 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"); 
+	dojo.require("dojox.validate.tests.validate");
+	dojo.require("dojox.validate.tests.br");
 
 }catch(e){
 	doh.debug(e);
-	console.debug(e); 
+	console.debug(e);
 }
diff --git a/dojox/validate/tests/validate.js b/dojox/validate/tests/validate.js
index 6b95495..44148e2 100644
--- a/dojox/validate/tests/validate.js
+++ b/dojox/validate/tests/validate.js
@@ -1,9 +1,9 @@
-dojo.provide("dojox.validate.tests.validate"); 
+dojo.provide("dojox.validate.tests.validate");
 
 dojo.require("dojox.validate._base");
 dojo.require("dojox.validate.check");
 dojo.require("dojox.validate.us");
-dojo.require("dojox.validate.ca"); 
+dojo.require("dojox.validate.ca");
 dojo.require("dojox.validate.web");
 dojo.require("dojox.validate.isbn");
 
@@ -23,12 +23,12 @@ tests.register("dojox.validate.tests.validate",
 			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("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.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
@@ -60,46 +60,46 @@ tests.register("dojox.validate.tests.validate",
 		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.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'));
 
-			// 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'));       
+			// 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'));
 
-			// test dotted octal       
-			tests.t(dojox.validate.isIpAddress('0030.0021.0233.0050'));       
+			// 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(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'));
 		
-			// 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}));       
+			// 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}));
 		
-			// test hex       
-			tests.t(dojox.validate.isIpAddress('0xCF8E83EB'));       
-			tests.t(dojox.validate.isIpAddress('0x0'));       
-			tests.t(dojox.validate.isIpAddress('0x00ffffffff'));       
+			// 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.f(dojox.validate.isIpAddress('0xCF8E83EB', {allowHex: false}));
 			
-			// IPv6       
-			tests.t(dojox.validate.isIpAddress('fedc:BA98:7654:3210:FEDC:BA98:7654:3210'));       
+			// 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}));
 		
@@ -112,7 +112,7 @@ tests.register("dojox.validate.tests.validate",
 	},
 	{
 		name: "isUrlTest",
-		runTest: function(tests){ 
+		runTest: function(tests){
 			
 			tests.t(dojox.validate.isUrl('www.yahoo.com'));
 			tests.t(dojox.validate.isUrl('http://www.yahoo.com'));
@@ -194,22 +194,22 @@ tests.register("dojox.validate.tests.validate",
 				"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(
-				"x at yahoo.com \n x.y.z.w at localhost \n o'mally at yahoo.com \n fred&barney at localhost", 
+				"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(
 				"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(
-					"mailto:x at yahoo.com; <x.y.z.w at yahoo.com>; <mailto:o'mally at yahoo.com>; fred&barney at stonehenge.com", 
+					"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(
-					"mailto:x at yahoo.com; <x.y.z.w at yahoo.com>; <mailto:o'mally at yahoo.com>; fred&barney at stonehenge.com", 
+					"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(
-					"mailto:x at yahoo.com; <x.y.z.w at localhost>; <mailto:o'mally at localhost>; fred&barney at localhost", 
+					"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: ";"} )
 			);
 		}
@@ -257,7 +257,7 @@ tests.register("dojox.validate.tests.validate",
 			tests.f(dojox.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'));
@@ -303,7 +303,7 @@ tests.register("dojox.validate.tests.validate",
 			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.f(dojox.validate.ca.isPostalCode('A1Z3F3'));
 			
 		}
 	},
diff --git a/dojox/validate/web.js b/dojox/validate/web.js
index 75dc275..bd58f22 100644
--- a/dojox/validate/web.js
+++ b/dojox/validate/web.js
@@ -29,7 +29,7 @@ dojox.validate.isUrl = function(/*String*/value, /*Object?*/flags) {
 	// summary: Checks if a string could be a valid URL
 	// value: A string
 	// flags: An object
-	//    flags.scheme  Can be true, false, or [true, false]. 
+	//    flags.scheme  Can be true, false, or [true, false].
 	//      This means: required, not allowed, or either.
 	//    flags in regexp.host can be applied.
 	//    flags in regexp.ipAddress can be applied.
diff --git a/dojox/widget/AnalogGauge.js b/dojox/widget/AnalogGauge.js
index 015ec2b..a3c9c32 100644
--- a/dojox/widget/AnalogGauge.js
+++ b/dojox/widget/AnalogGauge.js
@@ -8,16 +8,14 @@ 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 
+		//		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 shapes = [];
-		shapes[0] = this._gauge.surface.createLine({x1: 0, y1: -this.offset, 
+		return [this._gauge.surface.createLine({x1: 0, y1: -this.offset,
 													x2: 0, y2: -this.length-this.offset})
-					.setStroke({color: this.color, width: this.width});
-		return shapes;
+					.setStroke({color: this.color, width: this.width})];
 	},
 	draw: function(/*Boolean?*/ dontAnimate){
-		// summary: 
+		// 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)
@@ -28,11 +26,7 @@ dojo.declare("dojox.widget.gauge.AnalogLineIndicator",[dojox.widget.gauge._Indic
 				this._gauge.surface.rawNode.removeChild(this.text);
 				this.text = null;
 			}
-
-			var v = this.value;
-			if(v < this._gauge.min){v = this._gauge.min;}
-			if(v > this._gauge.max){v = this._gauge.max;}
-			var a = this._gauge._getAngle(v);
+			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;
@@ -57,28 +51,30 @@ dojo.declare("dojox.widget.gauge.AnalogLineIndicator",[dojox.widget.gauge._Indic
 			}
 	
 			if(this.label){
-				var len=this.length+this.offset;
-				var x=this._gauge.cx+(len+5)*Math.sin(this._gauge._getRadians(a));
-				var y=this._gauge.cy-(len+5)*Math.cos(this._gauge._getRadians(a));
-				var align = 'start';
+				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(a > -10 && a < 10){align='middle';}
+				if(aa < 10){align='middle';}
 				var vAlign = 'bottom';
-				if((a < -90) || (a > 90)){vAlign = 'top';}
+				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: 
+		// 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.currentValue;
+		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){
@@ -110,7 +106,7 @@ dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{
 	//
 	// 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 
+	//		builds a gauge component, used to display numerical data in a familiar format
 	//
 	// usage:
 	//		<script type="text/javascript">
@@ -240,7 +236,7 @@ dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{
 		// summary:
 		//		This function is used to draw (or redraw) a range
 		// description:
-		//		Draws a range (colored area on the background of the gauge) 
+		//		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
@@ -250,18 +246,18 @@ dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{
 			this.surface.remove(range.shape);
 			range.shape = null;
 		}
-		var a1;
-		var a2;
+		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);
-			var y1=this.cy-this.radius*Math.cos(a1);
-			var x2=this.cx+this.radius*Math.sin(a2);
-			var y2=this.cy-this.radius*Math.cos(a2);
-			var big=0;
+			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();
@@ -313,15 +309,17 @@ dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{
 		//		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 y = event.clientY - pos.y;
-		var r = Math.sqrt((y - this.cy)*(y - this.cy) + (x - this.cx)*(x - this.cx));
+		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);
+			var angle = this._getDegrees(Math.atan2(y - this.cy, x - this.cx) + Math.PI/2),
 			//if(angle > this.endAngle){angle = angle - 360;}
-			var value = this._getValueForAngle(angle);
+				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)){
@@ -337,18 +335,17 @@ dojo.declare("dojox.widget.AnalogGauge",dojox.widget.gauge._Gauge,{
 		// summary:
 		//		Handles the dragging of an indicator, including moving/re-drawing
 		// get angle for mouse position
-		var pos = dojo.coords(widget.gaugeContent);
-		var x = event.clientX - pos.x;
-		var y = event.clientY - pos.y;
-		var angle = widget._getDegrees(Math.atan2(y - widget.cy, x - widget.cx) + Math.PI/2);
+		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
-		var value = widget._getValueForAngle(angle);
-		if(value < widget.min){value = widget.min;}
-		if(value > widget.max){value = widget.max;}
+			value = widget._getValueForAngle(angle)
+		;
+		value = Math.min(Math.max(value, widget.min), widget.max);
 		// update the indicator
-		widget._drag.value = value;
-		widget._drag.currentValue = value;
+		widget._drag.value = widget._drag.currentValue = value;
 		// callback
 		widget._drag.onDragMove(widget._drag);
 		// rotate indicator
diff --git a/dojox/widget/BarGauge.js b/dojox/widget/BarGauge.js
index f5d6697..290a702 100644
--- a/dojox/widget/BarGauge.js
+++ b/dojox/widget/BarGauge.js
@@ -9,7 +9,7 @@ dojo.declare("dojox.widget.gauge.BarLineIndicator",[dojox.widget.gauge._Indicato
 	width: 1,
 	_getShapes: function(){
 		// summary:
-		//		Private function for generating the shapes for this indicator. An indicator that behaves the 
+		//		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;
@@ -21,18 +21,18 @@ dojo.declare("dojox.widget.gauge.BarLineIndicator",[dojox.widget.gauge._Indicato
 		var shapes = [];
 		if(this.width > 1){
 			shapes[0] = this._gauge.surface.createRect({
-				x:pos, 
+				x:pos,
 				y:this._gauge.dataY + this.offset,
-				width:this.width, 
+				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, 
+				x1:pos,
 				y1:this._gauge.dataY + this.offset,
-				x2:pos, 
+				x2:pos,
 				y2:this._gauge.dataY + this.offset + this.length
 			});
 			shapes[0].setStroke({color: this.color});
@@ -40,7 +40,7 @@ dojo.declare("dojox.widget.gauge.BarLineIndicator",[dojox.widget.gauge._Indicato
 		return shapes;
 	},
 	draw: function(/*Boolean?*/ dontAnimate){
-		// summary: 
+		// 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)
@@ -88,7 +88,7 @@ dojo.declare("dojox.widget.gauge.BarLineIndicator",[dojox.widget.gauge._Indicato
 		}
 	},
 	_move: function(/*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		//		Moves this indicator (since it's already been drawn once)
 		// dontAnimate: Boolean
 		//		Indicates if the drawing should not be animated (vs. the default of doing an animation)
@@ -152,7 +152,7 @@ dojo.declare("dojox.widget.BarGauge",dojox.widget.gauge._Gauge,{
 
 	startup: function(){
 		// handle settings from HTML by making sure all the options are
-		// converted correctly to numbers 
+		// converted correctly to numbers
 		//
 		// also connects mouse handling events
 
@@ -213,7 +213,7 @@ dojo.declare("dojox.widget.BarGauge",dojox.widget.gauge._Gauge,{
 		// summary:
 		//		This function is used to draw (or redraw) a range
 		// description:
-		//		Draws a range (colored area on the background of the gauge) 
+		//		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
@@ -225,9 +225,9 @@ dojo.declare("dojox.widget.BarGauge",dojox.widget.gauge._Gauge,{
 
 		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, 
+		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});
diff --git a/dojox/widget/Calendar.js b/dojox/widget/Calendar.js
index 09f3b6b..5595c03 100644
--- a/dojox/widget/Calendar.js
+++ b/dojox/widget/Calendar.js
@@ -5,7 +5,7 @@ dojo.require("dijit.Calendar");
 dojo.require("dijit._Container");
 
 dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dijit._Container], {
-	// summary: 
+	// summary:
 	//		The Root class for all _Calendar extensions
 
 	// templateString: String
@@ -39,6 +39,7 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 
 	constructor: function(){
 		this._views = [];
+		this.value = new Date();
 	},
 
 	postMixInProperties: function(){
@@ -52,13 +53,37 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 				c.max = fromISO(c.max);
 			}
 		}
+		this.value = this.parseInitialValue(this.value);
+	},
+
+	parseInitialValue: function(value){
+		if (!value || value === -1){
+			return new Date();
+		}else if(value.getFullYear){
+			return value;
+		}else if (!isNaN(value)) {
+			if (typeof this.value == "string") {
+				value = parseInt(value);
+			}
+			value = this._makeDate(value);
+		}
+		return value;
+	},
+
+	_makeDate: function(value){
+		return value;//new Date(value);
 	},
 
 	postCreate: function(){
 		// summary:
 		//		Instantiates the mixin views
+
 		this.displayMonth = new Date(this.get('value'));
 
+		if(this._isInvalidDate(this.displayMonth)){
+			this.displayMonth = new Date();
+		}
+
 		var mixin = {
 			parent: this,
 			_getValueAttr: dojo.hitch(this, function(){return new Date(this._internalValue || this.value);}),
@@ -88,7 +113,7 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 
 			//Listen for the values in a view to be selected
 			dojo.connect(widget, "onValueSelected", this, "_onDateSelected");
-			widget.attr("value", this.get('value'));
+			widget.set("value", this.get('value'));
 		}, this);
 
 		if(this._views.length < 2){
@@ -105,10 +130,10 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 		//Populate the footer with today's date.
 		var today = new Date();
 
-		this.footer.innerHTML = "Today: " 
+		this.footer.innerHTML = "Today: "
 			+ dojo.date.locale.format(today, {
 				formatLength:this.footerFormat,
-				selector:'date', 
+				selector:'date',
 				locale:this.lang});
 
 		dojo.connect(this.footer, "onclick", this, "goToToday");
@@ -143,13 +168,27 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 		// Stub function than can be overridden to add effects.
 	},
 
+	_isInvalidDate: function(/*Date*/ value){
+		// summary:
+		//		Runs various tests on the value, checking for invalid conditions
+		// tags:
+		//		private
+		return !value || isNaN(value) || typeof value != "object" || value.toString() == this._invalidDate;
+	},
+
 	_setValueAttr: function(/*Date*/ value){
 		// summary:
 		//		Set the current date and update the UI.	If the date is disabled, the selection will
 		//		not change, but the display will change to the corresponding month.
+		if(!value){
+			value = new Date();
+		}
 		if(!value["getFullYear"]){
 			value = dojo.date.stamp.fromISOString(value + "");
 		}
+		if(this._isInvalidDate(value)){
+			return false;
+		}
 		if(!this.value || dojo.date.compare(value, this.value)){
 			value = new Date(value);
 			this.displayMonth = new Date(value);
@@ -158,7 +197,9 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 				this.value = value;
 				this.onChange(value);
 			}
-			this._children[this._currentChild].attr("value", this.value);
+			if (this._children && this._children.length > 0) {
+				this._children[this._currentChild].set("value", this.value);
+			}
 			return true;
 		}
 		return false;
@@ -174,7 +215,7 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 	},
 
 	onValueSelected: function(/*Date*/date){
-		// summary: 
+		// summary:
 		//		A date cell was selected. It may be the same as the previous value.
 	},
 
@@ -210,7 +251,7 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 	},
 
 	_transitionVert: function(/*Number*/direction){
-		// summary: 
+		// summary:
 		//		Animates the views to show one and hide another, in a
 		//		vertical direction.
 		//		If 'direction' is 1, then the views slide upwards.
@@ -222,7 +263,7 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 		dojo.style(nextWidget.domNode, "visibility", "visible");
 
 		var height = dojo.style(this.containerNode, "height");
-		nextWidget.attr("value", this.displayMonth);
+		nextWidget.set("value", this.displayMonth);
 
 		if(curWidget.header){
 			dojo.style(curWidget.header, "display", "none");
@@ -323,7 +364,7 @@ dojo.declare("dojox.widget._CalendarBase", [dijit._Widget, dijit._Templated, dij
 		var month = this.displayMonth = child.adjustDate(this.displayMonth, amount);
 
 		this._slideTable(child, amount, function(){
-			child.attr("value", month);
+			child.set("value", month);
 		});
 	}
 });
@@ -354,7 +395,7 @@ dojo.declare("dojox.widget._CalendarView", dijit._Widget, {
 	},
 
 	_setText: function(node, text){
-		// summary: 
+		// summary:
 		//		Sets the text inside a node
 		if(node.innerHTML != text){
 			dojo.empty(node);
@@ -363,7 +404,7 @@ dojo.declare("dojox.widget._CalendarView", dijit._Widget, {
 	},
 
 	getHeader: function(){
-		// summary: 
+		// summary:
 		//		Returns the header node of a view. If none exists,
 		//		an empty DIV is created and returned.
 		return this.header || (this.header = this.header = dojo.create("span", { "class":this.headerClass }));
@@ -374,7 +415,7 @@ dojo.declare("dojox.widget._CalendarView", dijit._Widget, {
 	},
 
 	adjustDate: function(date, amount){
-		// summary: 
+		// summary:
 		//		Adds or subtracts values from a date.
 		//		The unit, e.g. "day", "month" or "year", is
 		//		specified in the "datePart" property of the
@@ -383,17 +424,17 @@ dojo.declare("dojox.widget._CalendarView", dijit._Widget, {
 	},
 
 	onDisplay: function(){
-		// summary: 
+		// summary:
 		//		Stub function that can be used to tell a view when it is shown.
 	},
 
 	onBeforeDisplay: function(){
-		// summary: 
+		// summary:
 		//		Stub function that can be used to tell a view it is about to be shown.
 	},
 
 	onBeforeUnDisplay: function(){
-		// summary: 
+		// summary:
 		//		Stub function that can be used to tell
 		//		a view when it is no longer shown.
 	}
@@ -430,7 +471,7 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 	dayWidth: "narrow",
 
 	postCreate: function(){
-		// summary: 
+		// summary:
 		//		Constructs the calendar view.
 		this.cloneClass(".dijitCalendarDayLabelTemplate", 6);
 		this.cloneClass(".dijitCalendarDateTemplate", 6);
@@ -457,13 +498,13 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 	},
 
 	_onDayClick: function(e){
-		// summary: 
+		// summary:
 		//		Executed when a day value is clicked.
-		
-		// If the user somehow clicked the TR, rather than a 
+
+		// If the user somehow clicked the TR, rather than a
 		// cell, ignore it.
 		if(typeof(e.target._date) == "undefined"){return;}
-		
+
 		var date = new Date(this.get("displayMonth"));
 
 		var p = e.target.parentNode;
@@ -487,8 +528,9 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 	},
 
 	_populateDays: function(){
-		// summary: 
+		// summary:
 		//		Fills the days of the current month.
+
 		var currentDate = new Date(this.get("displayMonth"));
 		currentDate.setDate(1);
 		var firstDay = currentDate.getDay();
@@ -499,17 +541,17 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 
 		var dayOffset = dojo.cldr.supplemental.getFirstDayOfWeek(this.getLang());
 		if(dayOffset > firstDay){ dayOffset -= 7; }
-		
+
 		var compareDate = dojo.date.compare;
 		var templateCls = ".dijitCalendarDateTemplate";
 		var selectedCls = "dijitCalendarSelectedDate";
-		
+
 		var oldDate = this._lastDate;
-		var redrawRequired = oldDate == null 
+		var redrawRequired = oldDate == null
 				|| oldDate.getMonth() != currentDate.getMonth()
 				|| oldDate.getFullYear() != currentDate.getFullYear();
 		this._lastDate = currentDate;
-		
+
 		// If still showing the same month, it's much faster to not redraw,
 		// and just change the selected date.
 		if(!redrawRequired){
@@ -551,8 +593,8 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 				clazz = "dijitCalendarCurrentDate " + clazz;
 			}
 
-			if(!compareDate(date, selected, "date") 
-					&& !compareDate(date, selected, "month") 
+			if(!compareDate(date, selected, "date")
+					&& !compareDate(date, selected, "month")
 					&& !compareDate(date, selected, "year") ){
 				clazz = selectedCls + " " + clazz;
 			}
@@ -563,15 +605,15 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 
 			var clazz2 = this.getClassForDate(date, this.getLang());
 			if(clazz2){
-				clazz += clazz2 + " " + clazz;
+				clazz = clazz2 + " " + clazz;
 			}
 
-			template.className =	clazz + "Month dijitCalendarDateTemplate";
+			template.className = clazz + "Month dijitCalendarDateTemplate";
 			template.dijitDateValue = date.valueOf();
 			var label = dojo.query(".dijitCalendarDateLabel", template)[0];
-			
+
 			this._setText(label, date.getDate());
-			
+
 			label._date = label.parentNode._date = date.getDate();
 		}, this);
 
@@ -585,7 +627,7 @@ dojo.declare("dojox.widget._CalendarDayView", [dojox.widget._CalendarView, dijit
 
 dojo.declare("dojox.widget._CalendarMonthYear", null, {
 	// summary:
-	//		Mixin class for adding a view listing all 12 
+	//		Mixin class for adding a view listing all 12
 	//		months of the year to the dojox.widget._CalendarBase
 
 	constructor: function(){
@@ -668,7 +710,9 @@ dojo.declare("dojox.widget._CalendarMonthYearView", [dojox.widget._CalendarView,
 	},
 
 	_setValueAttr: function(value){
-		this._populateYears(value.getFullYear());
+		if (value && value.getFullYear()) {
+			this._populateYears(value.getFullYear());
+		}
 	},
 
 	getHeader: function(){
@@ -676,7 +720,7 @@ dojo.declare("dojox.widget._CalendarMonthYearView", [dojox.widget._CalendarView,
 	},
 
 	_getMonthNames: function(format){
-		// summary: 
+		// summary:
 		//		Returns localized month names
 		this._monthNames	= this._monthNames || dojo.date.locale.getNames('months', format, 'standAlone', this.getLang());
 		return this._monthNames;
@@ -711,7 +755,7 @@ dojo.declare("dojox.widget._CalendarMonthYearView", [dojox.widget._CalendarView,
 					max = constraints.max.getMonth();
 				}
 			}
-			
+
 			dojo.query(".dojoxCalendarMonthLabel", this.monthContainer)
 				.forEach(dojo.hitch(this, function(node, cnt){
 					dojo[(cnt < min || cnt > max) ? "addClass" : "removeClass"]
@@ -726,14 +770,13 @@ dojo.declare("dojox.widget._CalendarMonthYearView", [dojox.widget._CalendarView,
 	},
 
 	_populateYears: function(year){
-		// summary: 
+		// summary:
 		//		Fills the list of years with a range of 12 numbers, with the current year
 		//		being the 6th number.
 		var constraints = this.get('constraints');
 		var dispYear = year || this.get("value").getFullYear();
 		var firstYear = dispYear - Math.floor(this.displayedYears/2);
 		var min = constraints && constraints.min ? constraints.min.getFullYear() : firstYear -10000;
-
 		firstYear = Math.max(min, firstYear);
 
 		// summary: Writes the years to display to the view
@@ -793,12 +836,12 @@ dojo.declare("dojox.widget._CalendarMonthYearView", [dojox.widget._CalendarView,
 		})[0];
 		if(!selMonth){return;}
 		var disabled = dojo.hasClass(selMonth, 'dijitCalendarDisabledDate');
-		
+
 		dojo[disabled ? 'addClass' : 'removeClass'](this.okBtn, "dijitDisabled");
 	},
-	
+
 	onClick: function(evt){
-		// summary: 
+		// summary:
 		//		Handles clicks on month names
 		var clazz;
 		var _this = this;
@@ -874,7 +917,13 @@ dojo.declare("dojox.widget.DailyCalendar",
 	[dojox.widget._CalendarBase,
 	 dojox.widget._CalendarDay], {
 	 	// summary: A calendar withonly a daily view.
+		_makeDate: function(value){
+			var now = new Date();
+			now.setDate(value);
+			return now;
+		}
 	 }
+
 );
 
 dojo.declare("dojox.widget.MonthAndYearlyCalendar",
diff --git a/dojox/widget/CalendarViews.js b/dojox/widget/CalendarViews.js
index deefa87..501f0bb 100644
--- a/dojox/widget/CalendarViews.js
+++ b/dojox/widget/CalendarViews.js
@@ -52,8 +52,13 @@ dojo.declare("dojox.widget._CalendarMonthView", [dojox.widget._CalendarView, dij
 	onClick: function(evt){
 		// summary: Handles clicks on month names
 		if(!dojo.hasClass(evt.target, "dojoxCalendarMonthLabel")){dojo.stopEvent(evt); return;}
-		var month = evt.target.parentNode.cellIndex + (evt.target.parentNode.parentNode.rowIndex * 4);
+		var parentNode = evt.target.parentNode;
+		var month = parentNode.cellIndex + (parentNode.parentNode.rowIndex * 4);
 		var date = this.get("value");
+
+		// Seeing a really strange bug in FF3.6 where this has to be called twice
+		// in order to take affect
+		date.setMonth(month);
 		date.setMonth(month);
 		this.onValueSelected(date, month);
 	}
@@ -124,11 +129,21 @@ dojo.declare("dojox.widget.MonthlyCalendar",
 	[dojox.widget._CalendarBase,
 	 dojox.widget._CalendarMonth], {
 	 	// summary: A calendar with only a month view.
+		_makeDate: function(value){
+			var now = new Date();
+			now.setMonth(value);
+			return now;
+		}
 	 }
 );
 dojo.declare("dojox.widget.YearlyCalendar",
 	[dojox.widget._CalendarBase,
 	 dojox.widget._CalendarYear], {
 	 	// summary: A calendar with only a year view.
+		_makeDate: function(value){
+			var now = new Date();
+			now.setFullYear(value);
+			return now;
+		}
 	 }
 );
diff --git a/dojox/widget/ColorPicker.js b/dojox/widget/ColorPicker.js
index 076c860..7686dde 100644
--- a/dojox/widget/ColorPicker.js
+++ b/dojox/widget/ColorPicker.js
@@ -5,8 +5,8 @@ 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("dojo.dnd.move");
+dojo.require("dojo.fx");
 dojo.require("dojox.color");
 dojo.require("dojo.i18n");
 
@@ -22,9 +22,9 @@ dojo.require("dojo.i18n");
 		{
 		// summary: a HSV color picker - similar to Photoshop picker
 		//
-		// description: 
+		// description:
 		//		Provides an interactive HSV ColorPicker similar to
-		//		PhotoShop's color selction tool. This is an enhanced 
+		//		PhotoShop's color selction tool. This is an enhanced
 		//		version of the default dijit.ColorPalette, though provides
 		//		no accessibility.
 		//
@@ -36,8 +36,8 @@ dojo.require("dojo.i18n");
 		// |		webSafe: false,
 		// |		showRgb: false
 		// |	});
-		//	
-		// example: 
+		//
+		// example:
 		// |	<!-- markup: -->
 		// |	<div dojoType="dojox.widget.ColorPicker"></div>
 		//
@@ -63,22 +63,22 @@ dojo.require("dojo.i18n");
 
 		// slideDuration: Integer
 		//	time in ms picker node will slide to next location (non-dragging) when animatePoint=true
-		slideDuration: 250, 
+		slideDuration: 250,
 
 		// liveUpdate: Boolean
 		//		Set to true to fire onChange in an indeterminate way
-		liveUpdate: false, 
+		liveUpdate: false,
 
 		// PICKER_HUE_H: int
-		//     Height of the hue picker, used to calculate positions    
+		//     Height of the hue picker, used to calculate positions
 		PICKER_HUE_H: 150,
 		
 		// PICKER_SAT_VAL_H: int
-		//     Height of the 2d picker, used to calculate positions    
+		//     Height of the 2d picker, used to calculate positions
 		PICKER_SAT_VAL_H: 150,
 		
 		// PICKER_SAT_VAL_W: int
-		//     Width of the 2d picker, used to calculate positions    
+		//     Width of the 2d picker, used to calculate positions
 		PICKER_SAT_VAL_W: 150,
 
 		// PICKER_HUE_SELECTOR_H: int
@@ -99,7 +99,7 @@ dojo.require("dojo.i18n");
 		// value: String
 		//	Default color for this component. Only hex values are accepted as incoming/returned
 		//	values. Adjust this value with `.attr`, eg: dijit.byId("myPicker").attr("value", "#ededed");
-		//	to cause the points to adjust and the values to reflect the current color. 
+		//	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"),
@@ -127,20 +127,20 @@ dojo.require("dojo.i18n");
 		},
 
 		postCreate: function(){
-			// summary: 
+			// summary:
 			//		As quickly as we can, set up ie6 alpha-filter support for our
-			//		underlay.  we don't do image handles (done in css), just the 'core' 
-			//		of this widget: the underlay. 
+			//		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(d.isIE < 7){
 				this.colorUnderlay.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this._underlay+"', sizingMethod='scale')";
 				this.colorUnderlay.src = this._blankGif.toString();
 			}
 			// hide toggle-able nodes:
 			if(!this.showRgb){ this.rgbNode.style.visibility = "hidden"; }
 			if(!this.showHsv){ this.hsvNode.style.visibility = "hidden"; }
-			if(!this.showHex){ this.hexNode.style.visibility = "hidden"; } 
-			if(!this.webSafe){ this.safePreviewNode.style.visibility = "hidden"; } 
+			if(!this.showHex){ this.hexNode.style.visibility = "hidden"; }
+			if(!this.webSafe){ this.safePreviewNode.style.visibility = "hidden"; }
 		},
 		
 		startup: function(){
@@ -226,7 +226,7 @@ dojo.require("dojo.i18n");
 		setColor: function(/* String */color, force){
 			// summary: Set a color on a picker. Usually used to set
 			//          initial color as an alternative to passing defaultColor option
-			//          to the constructor. 
+			//          to the constructor.
 			var col = dojox.color.fromString(color);
 			this._updatePickerLocations(col);
 			this._updateColorInputs(col);
@@ -237,7 +237,7 @@ dojo.require("dojo.i18n");
 			// 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);	
+			this._timer = setInterval(d.hitch(this, "_updateColor"), 45);
 		},
 		
 		_clearTimer: function(/* d.dnd.Mover */mover){
@@ -248,10 +248,10 @@ dojo.require("dojo.i18n");
 		},
 		
 		_setHue: function(/* Decimal */h){
-			// summary: 
-			//		Sets a natural color background for the 
-			//		underlay image against closest hue value (full saturation) 
-			//		h: 0..360 
+			// summary:
+			//		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());
 			
 		},
@@ -286,7 +286,7 @@ dojo.require("dojo.i18n");
 				}
 				y -= selCenter;
 				if(update){
-					dojo.style(this.hueCursorNode, "top", y + "px");	
+					dojo.style(this.hueCursorNode, "top", y + "px");
 				}
 			}else{
 				this._updateColor(true);
@@ -340,8 +340,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");	
+					dojo.style(this.cursorNode, "top", y + "px");
+					dojo.style(this.cursorNode, "left", x + "px");
 				}
 			}else{
 				this._updateColor(true);
@@ -355,7 +355,7 @@ 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, 
+			var _huetop = d.style(this.hueCursorNode,"top") + hueSelCenter,
 				_pickertop = d.style(this.cursorNode,"top") + satSelCenterH,
 				_pickerleft = d.style(this.cursorNode,"left") + satSelCenterW,
 				h = Math.round(360 - (_huetop / this.PICKER_HUE_H * 360)),
@@ -372,7 +372,7 @@ dojo.require("dojo.i18n");
 		},
 		
 		_colorInputChange: function(e){
-			//summary: updates picker position and inputs 
+			//summary: updates picker position and inputs
 			//         according to rgb, hex or hsv input changes
 			var col, hasit = false;
 			switch (e.target) {
@@ -492,13 +492,13 @@ dojo.require("dojo.i18n");
 			}
 		},
 		
-		_setHuePoint: function(/* Event */evt){ 
+		_setHuePoint: function(/* Event */evt){
 			// summary: set the hue picker handle on relative y coordinates
 			var selCenter = (this.PICKER_HUE_SELECTOR_H/2);
 			var ypos = evt.layerY - selCenter;
 			if(this.animatePoint){
-				d.fx.slideTo({ 
-					node: this.hueCursorNode, 
+				d.fx.slideTo({
+					node: this.hueCursorNode,
 					duration:this.slideDuration,
 					top: ypos,
 					left: 0,
@@ -506,7 +506,7 @@ dojo.require("dojo.i18n");
 				}).play();
 			}else{
 				d.style(this.hueCursorNode, "top", ypos + "px");
-				this._updateColor(false); 
+				this._updateColor(false);
 			}
 		},
 		
@@ -521,8 +521,8 @@ dojo.require("dojo.i18n");
 			if(evt){ dijit.focus(evt.target); }
 
 			if(this.animatePoint){
-				d.fx.slideTo({ 
-					node: this.cursorNode, 
+				d.fx.slideTo({
+					node: this.cursorNode,
 					duration: this.slideDuration,
 					top: newTop,
 					left: newLeft,
@@ -531,9 +531,9 @@ dojo.require("dojo.i18n");
 			}else{
 				d.style(this.cursorNode, {
 					left: newLeft + "px",
-					top: newTop + "px"	
+					top: newTop + "px"
 				});
-				this._updateColor(false); 
+				this._updateColor(false);
 			}
 		},
 		
diff --git a/dojox/widget/DataPresentation.js b/dojox/widget/DataPresentation.js
index 9c46d1d..44e5800 100644
--- a/dojox/widget/DataPresentation.js
+++ b/dojox/widget/DataPresentation.js
@@ -6,7 +6,7 @@ dojo.require("dojox.charting.Chart2D");
 dojo.require("dojox.charting.widget.Legend");
 dojo.require("dojox.charting.action2d.Tooltip");
 dojo.require("dojox.charting.action2d.Highlight");
-dojo.require("dojo.colors");		
+dojo.require("dojo.colors");
 dojo.require("dojo.data.ItemFileWriteStore");
 
 (function(){
@@ -56,7 +56,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 
 		var args = { vertical: false, labels: labels, min: 0, max: labels.length-1, majorTickStep: 1, minorTickStep: 1 };
 		
-		// clustered or stacked bars have a vertical independent axis 
+		// clustered or stacked bars have a vertical independent axis
 		if((charttype === "ClusteredBars") || (charttype === "StackedBars")){
 			args.vertical = true;
 		}
@@ -80,7 +80,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 			args.leftBottom = false;
 		}
 
-		// clustered or stacked bars have horizontal dependent axes 
+		// clustered or stacked bars have horizontal dependent axes
 		if((charttype === "ClusteredBars") || (charttype === "StackedBars")){
 			args.vertical = false;
 		}
@@ -99,28 +99,28 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		
 		var args = { type: charttype, hAxis: "independent", vAxis: "dependent-" + axistype, gap: 4, lines: false, areas: false, markers: false };
 		
-		// clustered or stacked bars have horizontal dependent axes 
+		// clustered or stacked bars have horizontal dependent axes
 		if((charttype === "ClusteredBars") || (charttype === "StackedBars")){
 			args.hAxis = args.vAxis;
 			args.vAxis = "independent";
 		}
 
-		// turn on lines for Lines, Areas and StackedAreas 
+		// turn on lines for Lines, Areas and StackedAreas
 		if((charttype === "Lines") || (charttype === "Hybrid-Lines") || (charttype === "Areas") || (charttype === "StackedAreas")){
 			args.lines = true;
 		}
 		
-		// turn on areas for Areas and StackedAreas 
+		// turn on areas for Areas and StackedAreas
 		if((charttype === "Areas") || (charttype === "StackedAreas")){
 			args.areas = true;
 		}
 		
-		// turn on markers and shadow for Lines 
+		// turn on markers and shadow for Lines
 		if(charttype === "Lines"){
 			args.markers = true;
 		}
 		
-		// turn on shadow for Hybrid-Lines 
+		// turn on shadow for Hybrid-Lines
 		// also, Hybrid-Lines is not a true chart type: use Lines for the actual plot
 		if(charttype === "Hybrid-Lines"){
 			args.shadows = {dx: 2, dy: 2, dw: 2};
@@ -187,7 +187,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 			
 		var labels = getLabels(range, labelMod, type, domNode);
 
-		// collect details of whether primary and/or secondary axes are required 
+		// collect details of whether primary and/or secondary axes are required
 		// and what plots we have instantiated using each type of axis
 		var plots = {};
 		
@@ -290,7 +290,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		_chart.addAxis("dependent-secondary", getDependentAxisArgs(type, "secondary", minval, maxval));
 		
 		return _chart;
-	};		
+	};
 
 	// set up a legend presentation
 	var setupLegend = function(/*DomNode*/domNode, /*Legend*/legend, /*Chart2D*/chart, /*Boolean*/horizontal){
@@ -308,8 +308,8 @@ dojo.require("dojo.data.ItemFileWriteStore");
 	
 	// set up a grid presentation
 	var setupGrid = function(/*DomNode*/domNode, /*Object?*/grid, /*Object?*/store, /*String?*/query, /*String?*/queryOptions){
-		var _grid = grid || new dojox.grid.DataGrid({}, domNode);		
-		_grid.startup();		
+		var _grid = grid || new dojox.grid.DataGrid({}, domNode);
+		_grid.startup();
 		_grid.setStore(store, query, queryOptions);
 		
 		var structure = [];
@@ -344,9 +344,9 @@ dojo.require("dojo.data.ItemFileWriteStore");
 	var getSubfield = function(/*Object*/object, /*String*/field){
 		var result = object;
 		
-		if(field){			
+		if(field){
 			var fragments = field.split(/[.\[\]]+/);
-			for(var frag in fragments){
+			for(var frag = 0, l = fragments.length; frag < l; frag++){
 				if(result){
 					result = result[fragments[frag]];
 				}
@@ -409,7 +409,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		//      a warning message in the console unless djConfig.useCommentedJson
 		//      has been set to true.
 		//
-		//  urlContent: Object   
+		//  urlContent: Object
 		//      Content to be passed to the URL when fetching data. If a URL has
 		//      not been supplied, this value is ignored.
 		//
@@ -432,7 +432,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 		//
 		//  series: Array
 		//      an array of objects describing the data series to be included
-		//      in the data presentation. Each object may contain the 
+		//      in the data presentation. Each object may contain the
 		//      following fields:
 		//			datapoints: the name of the field from the source data which
 		//				contains an array of the data points for this data series.
@@ -712,7 +712,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 						
 						if(series_chart[ser]){
 							// convert the data value to a float if possible
-							fdatavalue = parseFloat(datavalue);						
+							fdatavalue = parseFloat(datavalue);
 							if(!isNaN(fdatavalue)){
 								datavalue = fdatavalue;
 							}
@@ -739,15 +739,15 @@ dojo.require("dojo.data.ItemFileWriteStore");
 			}
 			
 			store.series_data = series_data;
-			store.series_name = series_name; 
-			store.series_chart = series_chart; 
-			store.series_charttype = series_charttype; 
-			store.series_linestyle = series_linestyle; 
-			store.series_axis = series_axis; 
-			store.series_grid = series_grid; 
+			store.series_name = series_name;
+			store.series_chart = series_chart;
+			store.series_charttype = series_charttype;
+			store.series_linestyle = series_linestyle;
+			store.series_axis = series_axis;
+			store.series_grid = series_grid;
 			store.series_gridformatter = series_gridformatter;
 			
-			this.setPreparedStore(store);			
+			this.setPreparedStore(store);
 			
 			if(refreshInterval && (this.refreshInterval > 0)){
 				var me = this;
@@ -863,7 +863,7 @@ dojo.require("dojo.data.ItemFileWriteStore");
 			
 			if(this.legendWidget){
 				// no legend.destroy()
-				delete this.legendWidget;				
+				delete this.legendWidget;
 			}
 
 			if(this.gridWidget){
diff --git a/dojox/widget/Dialog.js b/dojox/widget/Dialog.js
index 5ed3fdf..49730eb 100644
--- a/dojox/widget/Dialog.js
+++ b/dojox/widget/Dialog.js
@@ -2,59 +2,55 @@ dojo.provide('dojox.widget.Dialog');
 dojo.experimental('dojox.widget.Dialog');
 
 dojo.require("dojo.window");
-dojo.require('dijit.Dialog');
-dojo.require("dojox.layout.ContentPane");
-
 dojo.require('dojox.fx');
+dojo.require("dojox.widget.DialogSimple");
 
-dojo.declare('dojox.widget.Dialog', 
-	[dojox.layout.ContentPane, dijit._DialogBase], 
+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 
+	//		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 
+	//
+	//		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 
+	//		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
-	//		 
+	//		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, 
+	//		Defaults to [300,300]
+	dimensions: null,
 	
 	// easing: Function?|String?
-	//		An easing function to apply to the sizing animation. 
+	//		An easing function to apply to the sizing animation.
 	easing: null,
 	
 	// sizeDuration: Integer
-	//		Time (in ms) to use in the Animation for sizing. 
+	//		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
+	//		To be passed to dojox.fx.sizeTo, one of "chain" or "combine" to effect
 	//		the animation sequence.
 	sizeMethod: "chain",
 	
@@ -64,30 +60,30 @@ dojo.declare('dojox.widget.Dialog',
 	
 	// 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 
+	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
+	//		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.
+	//		behaviors.
 	modal: false,
 	
 	constructor: function(props, node){
-		this.easing = props.easing || dojo._defaultEasing; 
+		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 
-		//		
+		// summary: Piggyback on dijit.Dialog's _setup for load-time options, deferred to
+
 		this.inherited(arguments);
-		if(!this._alreadyInitialized){			
+		if(!this._alreadyInitialized){
 			this._navIn = dojo.fadeIn({ node: this.closeButtonNode });
-			this._navOut = dojo.fadeOut({ node: this.closeButtonNode }); 
+			this._navOut = dojo.fadeOut({ node: this.closeButtonNode });
 			if(!this.showTitle){
 				dojo.addClass(this.domNode,"dojoxDialogNoTitle");
 			}
-		}	
+		}
 	},
 	
 	layout: function(e){
@@ -96,7 +92,7 @@ dojo.declare('dojox.widget.Dialog',
 	},
 	
 	_setSize: function(){
-		// summary: cache and set our desired end position 
+		// summary: cache and set our desired end position
 		this._vp = dojo.window.getBox();
 		var tc = this.containerNode,
 			vpSized = this.sizeToViewport
@@ -121,7 +117,7 @@ dojo.declare('dojox.widget.Dialog',
 		dojo.style(this.containerNode, {
 			opacity: 0,
 			overflow: "hidden"
-		});	
+		});
 		
 		this.inherited(arguments);
 
@@ -146,7 +142,7 @@ dojo.declare('dojox.widget.Dialog',
 	_handleNav: function(e){
 		// summary: Handle's showing or hiding the close icon
 
-		var navou = "_navOut", 
+		var navou = "_navOut",
 			navin = "_navIn",
 			animou = (e.type == "mouseout" ? navin : navou),
 			animin = (e.type == "mouseout" ? navou : navin)
@@ -162,7 +158,7 @@ dojo.declare('dojox.widget.Dialog',
 	hide: function(){
 		// summary: Hide the dialog
 
-		// if we haven't been initialized yet then we aren't showing and we can just return		
+		// if we haven't been initialized yet then we aren't showing and we can just return
 		if(!this._alreadyInitialized){
 			return;
 		}
@@ -178,10 +174,10 @@ dojo.declare('dojox.widget.Dialog',
 			this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
 		}
 		if(this._relativePosition){
-			delete this._relativePosition;	
+			delete this._relativePosition;
 		}
 		
-		dojox.fx.sizeTo({ 
+		dojox.fx.sizeTo({
 			node: this.domNode,
 			duration:this.sizeDuration || this.duration,
 			width: this._vp.w - 1,
@@ -199,15 +195,15 @@ dojo.declare('dojox.widget.Dialog',
 		if(!this._started){ return; } // prevent content: from firing this anim #8914
 		
 		if(this._sizing){
-			this._sizing.stop();	
+			this._sizing.stop();
 			this.disconnect(this._sizingConnect);
-			delete this._sizing; 
+			delete this._sizing;
 		}
 		
 		this.inherited(arguments);
 		
 		if(!this.open){ dojo.style(this.containerNode, "opacity", 0); }
-		var pad = this.viewportPadding * 2; 
+		var pad = this.viewportPadding * 2;
 		
 		var props = {
 			node: this.domNode,
@@ -217,10 +213,10 @@ dojo.declare('dojox.widget.Dialog',
 		};
 
 		var ds = this._displaysize || this._setSize();
-		props['width'] = ds.w = (ds.w + pad >= this._vp.w || this.sizeToViewport) 
+		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) 
+		props['height'] = ds.h = (ds.h + pad >= this._vp.h || this.sizeToViewport)
 			? this._vp.h - pad : ds.h;
 		
 		this._sizing = dojox.fx.sizeTo(props);
diff --git a/dojox/widget/Dialog/Dialog.css b/dojox/widget/Dialog/Dialog.css
index c7fccf1..fd41fce 100644
--- a/dojox/widget/Dialog/Dialog.css
+++ b/dojox/widget/Dialog/Dialog.css
@@ -79,7 +79,7 @@ div.dojoxDialogNoTitle {
 	padding-top:9px;
 }
 
-.dojoxDialogCloseIcon {
+.dojoxDialogCloseIcon, .dojoxDialogCloseIconHover {
 	background : url("images/dialogCloseButton.png") no-repeat top right;
 	position: absolute;
 	vertical-align: middle;
@@ -94,6 +94,11 @@ div.dojoxDialogNoTitle {
 	background-image: url("images/dialogCloseButton.gif");
 }
 
+.dojoxDialog div.dijitDialogCloseIconHover,
+.dojoxDialog div.dijitDialogCloseIconActive {
+    background-position:0 0;
+}
+
 .dojoxDialog .dijitDialogCloseIconHover {
     background-image: url("images/dialogCloseButton.png");
 }
diff --git a/dojox/widget/Dialog/Dialog.html b/dojox/widget/Dialog/Dialog.html
index 91542c1..dad17de 100644
--- a/dojox/widget/Dialog/Dialog.html
+++ b/dojox/widget/Dialog/Dialog.html
@@ -1,4 +1,4 @@
-<div class="dojoxDialog" tabindex="-1" waiRole="dialog" waiState="labelledby-${id}_title">
+<div class="dojoxDialog" tabindex="-1" role="dialog" aria-labelledby="${id}_title">
 	<div dojoAttachPoint="titleBar" class="dojoxDialogTitleBar">
 		<span dojoAttachPoint="titleNode" class="dojoxDialogTitle" id="${id}_title">${title}</span>
 	</div>
diff --git a/dojox/widget/DialogSimple.js b/dojox/widget/DialogSimple.js
new file mode 100644
index 0000000..b6a8c9f
--- /dev/null
+++ b/dojox/widget/DialogSimple.js
@@ -0,0 +1,10 @@
+dojo.provide("dojox.widget.DialogSimple");
+
+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.
+});
diff --git a/dojox/widget/DocTester.js b/dojox/widget/DocTester.js
index fb905f8..a48291a 100644
--- a/dojox/widget/DocTester.js
+++ b/dojox/widget/DocTester.js
@@ -6,11 +6,11 @@ dojo.require("dijit._Templated");
 dojo.require("dojox.form.BusyButton");
 dojo.require("dojox.testing.DocTest");
 
-dojo.declare('dojox.widget.DocTester', 
+dojo.declare('dojox.widget.DocTester',
 	[dijit._Widget, dijit._Templated],
 	{
 		// summary: A widget to run DocTests inside an HTML page.
-		// 
+		//
 		templateString: dojo.cache('dojox.widget','DocTester/DocTester.html'),
 		widgetsInTemplate: true,
 	
diff --git a/dojox/widget/DynamicTooltip.js b/dojox/widget/DynamicTooltip.js
index 70dffca..3dbbdbf 100644
--- a/dojox/widget/DynamicTooltip.js
+++ b/dojox/widget/DynamicTooltip.js
@@ -8,7 +8,7 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 	{
 		// summary:
 		//		Extention of dijit.Tooltip providing content set via XHR
-		//		request via href param	
+		//		request via href param
 
 		// hasLoaded: Boolean
 		//		false if the contents are yet to be loaded from the HTTP request
@@ -33,7 +33,7 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 		
 		_setLoadingLabel: function(){
 			// summary:
-			//		Changes the tooltip label / contents to loading message, only if 
+			//		Changes the tooltip label / contents to loading message, only if
 			//		there's an href param, otherwise acts as normal tooltip
 
 			if(this.href){
@@ -61,7 +61,7 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 			this.hasLoaded = false;
 		},
 		
-		loadContent: function(){
+		loadContent: function(node){
 			// summary:
 			//		Download contents of href via XHR and display
 			// description:
@@ -78,7 +78,7 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
 					load: function(response, ioArgs){
 						this.tooltipWidget.label = response;
 						this.tooltipWidget.close();
-						this.tooltipWidget.open();
+						this.tooltipWidget.open(node);
 					},
 					preventCache: this.preventCache
 				});
@@ -97,10 +97,10 @@ dojo.declare("dojox.widget.DynamicTooltip", dijit.Tooltip,
  			// summary:
 			//		Display the tooltip; usually not called directly.
 			
-			target = target || this._connectNodes[0];
+			target = target || (this._connectNodes && this._connectNodes[0]);
 			if(!target){ return; }
 
-			this.loadContent();
+			this.loadContent(target);
 			this.inherited(arguments);
 		}
 	}
diff --git a/dojox/widget/FeedPortlet.js b/dojox/widget/FeedPortlet.js
index b4187e3..0e0f9df 100644
--- a/dojox/widget/FeedPortlet.js
+++ b/dojox/widget/FeedPortlet.js
@@ -6,27 +6,27 @@ dojo.require("dijit.form.Button");
 dojo.require("dojox.data.GoogleFeedStore");
 
 dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
-	// summary: 
+	// summary:
 	//		A Portlet that loads a XML feed.
 	// description: The feed is displayed as
 	//		an unordered list of links.	When a link is hovered over
 	//		by the mouse, it displays a summary in a tooltip.
-	
+
 	// local: Boolean
 	//		Specifies whether the feed is to be loaded from the same domain as the
 	//		page, or a remote domain.	If local is true, then the feed must be an
 	//		Atom feed.	If it is false, it can be an Atom or RSS feed.
-	local: false, 
-	
+	local: false,
+
 	// maxResults: Number
 	//		The number of results to display from the feed.
 	maxResults: 5,
-	
+
 	// url: String
 	//		The URL of the feed to load.	If this is different to the domain
 	//		of the HTML page, local should be set to false.
 	url: "",
-	
+
 	// openNew: Boolean
 	//		If true, when a link is clicked it will open in a new window.
 	//		If false, it will not.
@@ -36,20 +36,20 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 	//		If true, the title of the loaded feed is displayed in the title bar of the portlet.
 	//		If false, the title remains unchanged.
 	showFeedTitle: true,
-	
+
 	postCreate: function(){
 		this.inherited(arguments);
 		if(this.local && !dojox.data.AtomReadStore){
 			throw Error(this.declaredClass + ": To use local feeds, you must include dojox.data.AtomReadStore on the page.");
 		}
 	},
-	
+
 	onFeedError: function(){
-		// summary: 
+		// summary:
 		//		Called when a feed fails to load successfully.
 		this.containerNode.innerHTML = "Error accessing the feed."
 	},
-	
+
 	addChild: function(child){
 		this.inherited(arguments);
 		var url = child.attr("feedPortletUrl");
@@ -57,23 +57,23 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 			this.set("url", url);
 		}
 	},
-	
+
 	_getTitle: function(item){
-		// summary: 
+		// summary:
 		//		Gets the title of a feed item.
 		var t = this.store.getValue(item, "title");
 		return this.local ? t.text : t;
 	},
-	
+
 	_getLink: function(item){
-		// summary: 
+		// summary:
 		//		Gets the href link of a feed item.
 		var l = this.store.getValue(item, "link");
 		return this.local ? l.href : l;
 	},
-	
+
 	_getContent: function(item){
-		// summary: 
+		// summary:
 		//		Gets the summary of a feed item.
 		var c = this.store.getValue(item, "summary");
 		if(!c){
@@ -86,9 +86,9 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 		c = c.split("<script").join("<!--").split("</script>").join("-->");
 		c = c.split("<iframe").join("<!--").split("</iframe>").join("-->");
 		return c;
-		
+
 	},
-	
+
 	_setUrlAttr: function(url){
 		// summary:
 		//		Sets the URL to load.
@@ -97,14 +97,14 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 			this.load();
 		}
 	},
-	
+
 	startup: function(){
-		// summary: 
+		// summary:
 		//		Loads the widget.
 		if(this.started || this._started){return;}
-		
+
 		this.inherited(arguments);
-		
+
 		if(!this.url || this.url == ""){
 			throw new Error(this.id + ": A URL must be specified for the feed portlet");
 		}
@@ -112,7 +112,7 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 			this.load();
 		}
 	},
-	
+
 	load: function(){
 		// summary:
 		//		Loads the feed.
@@ -120,8 +120,8 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 			dojo.destroy(this._resultList);
 		}
 		var store, query;
-		
-		// If the feed is on the same domain, use the AtomReadStore, 
+
+		// If the feed is on the same domain, use the AtomReadStore,
 		// as we cannot be guaranteed that it will be available to
 		// Google services.
 		if(this.local){
@@ -129,7 +129,7 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 				url: this.url
 			});
 			query = {};
-			
+
 		}else{
 			store = new dojox.data.GoogleFeedStore();
 			query = {url: this.url};
@@ -148,57 +148,57 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 			}),
 			onError: dojo.hitch(this, "onFeedError")
 		};
-		
+
 		this.store = store;
 		store.fetch(request);
 	},
-	
+
 	generateResults: function (items){
-		// summary: 
+		// summary:
 		//		Generates a list of hyperlinks and displays a tooltip
 		//		containing a summary when the mouse hovers over them.
 		var store = this.store;
 		var timer;
-		var ul = (this._resultList = 
+		var ul = (this._resultList =
 			dojo.create("ul", {"class" : "dojoxFeedPortletList"}, this.containerNode));
 
 		dojo.forEach(items, dojo.hitch(this, function(item){
 			var li = dojo.create("li", {
-				innerHTML: '<a href="' 
-					+ this._getLink(item) 
-					+ '"' 
+				innerHTML: '<a href="'
+					+ this._getLink(item)
+					+ '"'
 					+ (this.openNew ? ' target="_blank"' : '')
-					+'>' 
+					+'>'
 					+ this._getTitle(item) + '</a>'
 			},ul);
-			
+
 			dojo.connect(li, "onmouseover", dojo.hitch(this, function(evt){
 				if(timer){
 					clearTimeout(timer);
 				}
-				
+
 				// Show the tooltip after the mouse has been hovering
 				// for a short time.
 				timer = setTimeout(dojo.hitch(this, function(){
 					timer = null;
 					var summary = this._getContent(item);
 					if(!summary){return;}
-					var content = '<div class="dojoxFeedPortletPreview">' 
+					var content = '<div class="dojoxFeedPortletPreview">'
 						+ summary + '</div>'
-					
+
 					dojo.query("li", ul).forEach(function(item){
 						if(item != evt.target){
 							dijit.hideTooltip(item);
 						}
 					});
-					
+
 					// Hover the tooltip over the anchor tag
 					dijit.showTooltip(content, li.firstChild, !this.isLeftToRight());
 				}), 500);
-				
-				
+
+
 			}));
-			
+
 			// Hide the tooltip when the mouse leaves a list item.
 			dojo.connect(li, "onmouseout", function(){
 				if(timer){
@@ -208,38 +208,38 @@ dojo.declare("dojox.widget.FeedPortlet", dojox.widget.Portlet, {
 				dijit.hideTooltip(li.firstChild);
 			});
 		}));
-		
+
 		this.resize();
 	}
 });
 
 dojo.declare("dojox.widget.ExpandableFeedPortlet", dojox.widget.FeedPortlet, {
-	// summary: 
-	//		A FeedPortlet that uses an list of expandable links to display 
+	// summary:
+	//		A FeedPortlet that uses an list of expandable links to display
 	//		a feed.	An icon is placed to the left of each item
 	//		which, when clicked, toggles the visible state
 	//		of the item summary.
-	
+
 	// onlyOpenOne: Boolean
 	//		If true, only a single item can be expanded at any given time.
 	onlyOpenOne: false,
-	
+
 	generateResults: function(items){
 		// summary:
 		//		Generates a list of items, and places an icon beside them that
 		//		can be used to show or hide a summary of that item.
-		
+
 		var store = this.store;
 		var iconCls = "dojoxPortletToggleIcon";
 		var collapsedCls = "dojoxPortletItemCollapsed";
 		var expandedCls = "dojoxPortletItemOpen";
-		
+
 		var timer;
 		var ul = (this._resultList = dojo.create("ul", {
 			"class": "dojoxFeedPortletExpandableList"
 		}, this.containerNode));
-		
-		// Create the LI elements.	Each LI has two DIV elements, the 
+
+		// Create the LI elements.	Each LI has two DIV elements, the
 		// top DIV contains the toggle icon and title, and the bottom
 		// div contains the extended summary.
 		dojo.forEach(items, dojo.hitch(this, dojo.hitch(this, function(item){
@@ -247,15 +247,15 @@ dojo.declare("dojox.widget.ExpandableFeedPortlet", dojox.widget.FeedPortlet, {
 			var upper = dojo.create("div", {style: "width: 100%;"}, li);
 			var lower = dojo.create("div", {"class": "dojoxPortletItemSummary", innerHTML: this._getContent(item)}, li);
 			dojo.create("span", {
-				"class": iconCls, 
+				"class": iconCls,
 				innerHTML: "<img src='" + dojo.config.baseUrl + "/resources/blank.gif'>"}, upper);
 			var a = dojo.create("a", {href: this._getLink(item), innerHTML: this._getTitle(item) }, upper);
-			
+
 			if(this.openNew){
 				dojo.attr(a, "target", "_blank");
 			}
 		})));
-		
+
 		// Catch all clicks on the list. If a toggle icon is clicked,
 		// toggle the visible state of the summary DIV.
 		dojo.connect(ul, "onclick", dojo.hitch(this, function(evt){
@@ -279,9 +279,9 @@ dojo.declare("dojox.widget.ExpandableFeedPortlet", dojox.widget.FeedPortlet, {
 });
 
 
-dojo.declare("dojox.widget.PortletFeedSettings", 
+dojo.declare("dojox.widget.PortletFeedSettings",
 	dojox.widget.PortletSettings, {
-		
+
 	// summary:
 	//		A Settings widget designed to be used with a dojox.widget.FeedPortlet
 	// description:
@@ -293,7 +293,7 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 	//		If a <select> DOM node is used as the source node for this widget,
 	//		it displays a list of predefined URLs that the user can select from
 	//		to load into the enclosing FeedPortlet.
-	//					
+	//
 	// example:
 	//		<div dojoType="dojox.widget.PortletFeedSettings"></div>
 	//
@@ -302,27 +302,27 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 	//			<option>http://www.dojotoolkit.org/aggregator/rss</option>
 	//			<option>http://dojocampus.org/content/category/podcast/feed/</option>
 	//		</select>
-	
+
 	"class" : "dojoxPortletFeedSettings",
-	
+
 	// urls: Array
 	//		An array of JSON object specifying URLs to display in the
 	//		PortletFeedSettings object. Each object contains a 'url' and 'label'
 	//		attribute, e.g.
 	//		[{url:'http:google.com', label:'Google'}, {url:'http://dojotoolkit.org', label: 'Dojo'}]
 	urls: null,
-	
+
 	// selectedIndex: Number
 	//		The selected URL. Defaults to zero.
 	selectedIndex: 0,
-	
-	buildRendering: function(){
 
+	buildRendering: function(){
 		// If JSON URLs have been specified, create a SELECT DOM node,
 		// and insert the required OPTION elements.
+		var s;
 		if(this.urls && this.urls.length > 0){
-			
-			var s = dojo.create("select");
+			console.log(this.id + " -> creating select with urls ", this.urls)
+			s = dojo.create("select");
 			if(this.srcNodeRef){
 				dojo.place(s, this.srcNodeRef, "before");
 				dojo.destroy(this.srcNodeRef);
@@ -342,15 +342,23 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 			this.srcNodeRef = div;
 			dojo.query("option", this.text).filter("return !item.value;").forEach("item.value = item.innerHTML");
 			if(!this.text.value){
+				if(this.content && this.text.options.length == 0){
+					this.text.appendChild(this.content);
+				}
 				dojo.attr(s || this.text, "value", this.text.options[this.selectedIndex].value);
 			}
 		}
 		this.inherited(arguments);
 	},
-	
+
+	_setContentAttr: function(){
+
+	},
+
 	postCreate: function(){
+		console.log(this.id + " -> postCreate");
 		if(!this.text){
-			// If a select node is not being used, create a new TextBox to 
+			// If a select node is not being used, create a new TextBox to
 			// edit the URL.
 			var text = this.text = new dijit.form.TextBox({});
 			dojo.create("span", {
@@ -364,7 +372,7 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 			label: "Load",
 			onClick: dojo.hitch(this, function(){
 				// Set the URL of the containing Portlet with the selected URL.
-				this.portlet.attr("url", 
+				this.portlet.attr("url",
 					(this.text.tagName == "SELECT") ? this.text.value : this.text.attr('value'));
 				if(this.text.tagName == "SELECT"){
 					// Set the selected index on the Select node.
@@ -380,7 +388,7 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 				this.toggle();
 			})
 		}));
-		
+
 		// Add a CANCEL button, which hides this widget
 		this.addChild(new dijit.form.Button({
 			label: "Cancel",
@@ -388,13 +396,14 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 		}));
 		this.inherited(arguments);
 	},
-		
+
 	startup: function(){
 		// summary:
 		//		Sets the portlet associated with this PortletSettings object.
 		if(this._started){return;}
+		console.log(this.id + " -> startup");
 		this.inherited(arguments);
-		
+
 		if(!this.portlet){
 			throw Error(this.declaredClass + ": A PortletFeedSettings widget cannot exist without a Portlet.");
 		}
@@ -423,7 +432,7 @@ dojo.declare("dojox.widget.PortletFeedSettings",
 			this.portlet.attr("url", this.get("feedPortletUrl"));
 		}
 	},
-	
+
 	_getFeedPortletUrlAttr: function(){
 		return this.text.value;
 	}
diff --git a/dojox/widget/FilePicker.js b/dojox/widget/FilePicker.js
index 5e76952..f8dc179 100644
--- a/dojox/widget/FilePicker.js
+++ b/dojox/widget/FilePicker.js
@@ -2,10 +2,10 @@ dojo.provide("dojox.widget.FilePicker");
 
 dojo.require("dojox.widget.RollingList");
 
-dojo.require("dojo.i18n"); 
-dojo.requireLocalization("dojox.widget", "FilePicker"); 
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dojox.widget", "FilePicker");
 
-dojo.declare("dojox.widget._FileInfoPane", 
+dojo.declare("dojox.widget._FileInfoPane",
 	[dojox.widget._RollingListPane], {
 	// summary: a pane to display the information for the currently-selected
 	//	file
@@ -63,7 +63,7 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 	pathAttr: "path",
 	
 	// preloadItems: boolean or int
-	//  Set this to a sane number - since we expect to mostly be using the 
+	//  Set this to a sane number - since we expect to mostly be using the
 	//	dojox.data.FileStore - which doesn't like loading lots of items
 	//	all at once.
 	preloadItems: 50,
@@ -81,7 +81,7 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 	_itemsMatch: function(/*item*/ item1, /*item*/ item2){
 		// Summary: returns whether or not the two items match - checks ID if
 		//  they aren't the exact same object - ignoring trailing slashes
-		if(!item1 && !item2){ 
+		if(!item1 && !item2){
 			return true;
 		}else if(!item1 || !item2){
 			return false;
@@ -91,7 +91,7 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 			var iArr = [ this.store.getIdentity(item1), this.store.getIdentity(item2) ];
 			dojo.forEach(iArr, function(i, idx){
 				if(i.lastIndexOf(this.pathSeparator) == (i.length - 1)){
-					iArr[idx] = i.substring(0, i.length - 1); 
+					iArr[idx] = i.substring(0, i.length - 1);
 				}else{
 				}
 			}, this);
@@ -182,7 +182,7 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 		}
 		this.store.fetchItemByIdentity({identity: path,
 										onItem: function(v){
-											if(resetLastExec){ 
+											if(resetLastExec){
 												this._lastExecutedValue = v;
 											}
 											this.set("value", v);
@@ -219,5 +219,5 @@ dojo.declare("dojox.widget.FilePicker", dojox.widget.RollingList, {
 			this.value = value;
 			this._onChange(value);
 		}
-	}	
+	}
 });
\ No newline at end of file
diff --git a/dojox/widget/FisheyeList.js b/dojox/widget/FisheyeList.js
index 505da18..73f0156 100644
--- a/dojox/widget/FisheyeList.js
+++ b/dojox/widget/FisheyeList.js
@@ -178,7 +178,7 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 		if(!this.conservativeTrigger){
 			this._onMouseMoveHandle = dojo.connect(document.documentElement, "onmousemove", this, "_onMouseMove");
 		}
-		if (this.isFixed){
+		if(this.isFixed){
 			this._onScrollHandle = dojo.connect(document,"onscroll",this,"_onScroll");
 		}
 			
@@ -237,7 +237,7 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 		//
 		// position the items
 		//
-		for(var i=0; i<this.children.length; i++){
+		for(i=0; i<this.children.length; i++){
 			var itm = this.children[i];
 			var elm = itm.domNode;
 			elm.style.left   = itm.posX + 'px';
@@ -336,7 +336,7 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 	},
 
 	_onScroll: function(){
-		this._calcHitGrid();	
+		this._calcHitGrid();
 	},
 
 	onResized: function(){
@@ -361,7 +361,7 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 		var pos = this.isHorizontal ? x : y;
 		var prx = this.isHorizontal ? this.proximityLeft : this.proximityTop;
 		var siz = this.isHorizontal ? this.itemWidth : this.itemHeight;
-		var sim = this.isHorizontal ? 
+		var sim = this.isHorizontal ?
 			(1.0-this.timerScale)*this.itemWidth + this.timerScale*this.itemMaxWidth :
 			(1.0-this.timerScale)*this.itemHeight + this.timerScale*this.itemMaxHeight ;
 
@@ -373,22 +373,22 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 		//
 		// figure out our off-axis weighting
 		//
-		var off_weight = 0;
+		var off_weight = 0, cen2;
 
 		if(this.anchorEdge == this.EDGE.BOTTOM){
-			var cen2 = (y - this.proximityTop) / this.itemHeight;
+			cen2 = (y - this.proximityTop) / this.itemHeight;
 			off_weight = (cen2 > 0.5) ? 1 : y / (this.proximityTop + (this.itemHeight / 2));
 		}
 		if(this.anchorEdge == this.EDGE.TOP){
-			var cen2 = (y - this.proximityTop) / this.itemHeight;
+			cen2 = (y - this.proximityTop) / this.itemHeight;
 			off_weight = (cen2 < 0.5) ? 1 : (this.totalHeight - y) / (this.proximityBottom + (this.itemHeight / 2));
 		}
 		if(this.anchorEdge == this.EDGE.RIGHT){
-			var cen2 = (x - this.proximityLeft) / this.itemWidth;
+			cen2 = (x - this.proximityLeft) / this.itemWidth;
 			off_weight = (cen2 > 0.5) ? 1 : x / (this.proximityLeft + (this.itemWidth / 2));
 		}
 		if(this.anchorEdge == this.EDGE.LEFT){
-			var cen2 = (x - this.proximityLeft) / this.itemWidth;
+			cen2 = (x - this.proximityLeft) / this.itemWidth;
 			off_weight = (cen2 < 0.5) ? 1 : (this.totalWidth - x) / (this.proximityRight + (this.itemWidth / 2));
 		}
 		if(this.anchorEdge == this.EDGE.CENTER){
@@ -444,6 +444,9 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 	},
 
 	_setItemSize: function(p, scale){
+		if(this.children[p].scale == scale){ return; }
+		this.children[p].scale = scale;
+
 		scale *= this.timerScale;
 		var w = Math.round(this.itemWidth  + ((this.itemMaxWidth  - this.itemWidth ) * scale));
 		var h = Math.round(this.itemHeight + ((this.itemMaxHeight - this.itemHeight) * scale));
@@ -480,7 +483,7 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 			var x = 0;
 			if(this.anchorEdge == this.EDGE.LEFT){
 				x = this.children[p].cenX - (this.itemWidth / 2);
-			}else if (this.anchorEdge == this.EDGE.RIGHT){
+			}else if(this.anchorEdge == this.EDGE.RIGHT){
 				x = this.children[p].cenX - (w - (this.itemWidth / 2));
 			}else{
 				x = this.children[p].cenX - (w / 2);
@@ -503,38 +506,39 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 	_positionElementsFrom: function(p, offset){
 		var pos = 0;
 
+		var usual, start;
 		if(this.isHorizontal){
-			pos = Math.round(this.children[p].usualX + offset);
-			this.children[p].domNode.style.left = pos + 'px';
+			usual = "usualX";
+			start = "left";
 		}else{
-			pos = Math.round(this.children[p].usualY + offset);
-			this.children[p].domNode.style.top = pos + 'px';
+			usual = "usualY";
+			start = "top";
+		}
+		pos = Math.round(this.children[p][usual] + offset);
+		if(this.children[p].domNode.style[start] != (pos + 'px')){
+			this.children[p].domNode.style[start] = pos + 'px';
+			this._positionLabel(this.children[p]);
 		}
-		this._positionLabel(this.children[p]);
 
 		// position before
 		var bpos = pos;
 		for(var i=p-1; i>=0; i--){
 			bpos -= this.children[i].sizeMain;
 
-			if (this.isHorizontal){
-				this.children[i].domNode.style.left = bpos + 'px';
-			}else{
-				this.children[i].domNode.style.top = bpos + 'px';
+			if(this.children[p].domNode.style[start] != (bpos + 'px')){
+				this.children[i].domNode.style[start] = bpos + 'px';
+				this._positionLabel(this.children[i]);
 			}
-			this._positionLabel(this.children[i]);
 		}
 
 		// position after
 		var apos = pos;
-		for(var i=p+1; i<this.itemCount; i++){
+		for(i=p+1; i<this.itemCount; i++){
 			apos += this.children[i-1].sizeMain;
-			if(this.isHorizontal){
-				this.children[i].domNode.style.left = apos + 'px';
-			}else{
-				this.children[i].domNode.style.top = apos + 'px';
+			if(this.children[p].domNode.style[start] != (apos + 'px')){
+				this.children[i].domNode.style[start] = apos + 'px';
+				this._positionLabel(this.children[i]);
 			}
-			this._positionLabel(this.children[i]);
 		}
 
 	},
@@ -599,8 +603,8 @@ dojo.declare("dojox.widget.FisheyeList", [dijit._Widget, dijit._Templated, dijit
 		dojo.disconnect(this._onMouseOutHandle);
 		dojo.disconnect(this._onMouseMoveHandle);
 		dojo.disconnect(this._addChildHandle);
-		if (this.isFixed) { dojo.disconnect(this._onScrollHandle); }
-		dojo.disconnect(this._onResizeHandle); 
+		if(this.isFixed){ dojo.disconnect(this._onScrollHandle); }
+		dojo.disconnect(this._onResizeHandle);
 		this.inherited("destroyRecursive",arguments);
 	}
 });
@@ -633,7 +637,7 @@ dojo.declare("dojox.widget.FisheyeListItem", [dijit._Widget, dijit._Templated, d
 	_isNode: function(/* object */wh){
 		//	summary:
 		//		checks to see if wh is actually a node.
-		if(typeof Element == "function") {
+		if(typeof Element == "function"){
 			try{
 				return wh instanceof Element;	//	boolean
 			}catch(e){}
@@ -641,6 +645,7 @@ dojo.declare("dojox.widget.FisheyeListItem", [dijit._Widget, dijit._Templated, d
 			// best-guess
 			return wh && !isNaN(wh.nodeType);	//	boolean
 		}
+		return false;
 	},
 
 	_hasParent: function(/*Node*/node){
@@ -649,20 +654,21 @@ dojo.declare("dojox.widget.FisheyeListItem", [dijit._Widget, dijit._Templated, d
 		return Boolean(node && node.parentNode && this._isNode(node.parentNode));	//	boolean
 	},
 
-	postCreate: function() {
+	postCreate: function(){
 
 		// set image
+		var parent;
 		if((this.iconSrc.toLowerCase().substring(this.iconSrc.length-4)==".png") && dojo.isIE < 7){
 			/* we set the id of the new fisheyeListItem to the id of the div defined in the HTML */
 			if(this._hasParent(this.imgNode) && this.id != ""){
-				var parent = this.imgNode.parentNode;
+				parent = this.imgNode.parentNode;
 				parent.setAttribute("id", this.id);
 			}
 			this.imgNode.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.iconSrc+"', sizingMethod='scale')";
 			this.imgNode.src = this._blankGif.toString();
 		}else{
 			if(this._hasParent(this.imgNode) && this.id != ""){
-				var parent = this.imgNode.parentNode;
+				parent = this.imgNode.parentNode;
 				parent.setAttribute("id", this.id);
 			}
 			this.imgNode.src = this.iconSrc;
diff --git a/dojox/widget/FisheyeLite.js b/dojox/widget/FisheyeLite.js
index b3c53f4..997b2ca 100644
--- a/dojox/widget/FisheyeLite.js
+++ b/dojox/widget/FisheyeLite.js
@@ -8,7 +8,7 @@ dojo.declare("dojox.widget.FisheyeLite",
 	dijit._Widget,
 	{
 	// summary:  A Light-weight Fisheye Component, or an exhanced version
-	//		of dojo.fx.Toggler ... 
+	//		of dojo.fx.Toggler ...
 	//
 	// description:
 	//		A Simple FisheyeList-like widget which (in the interest of
@@ -33,7 +33,7 @@ dojo.declare("dojox.widget.FisheyeLite",
 	//
 	//
 	// example:
-	//	|	new dojox.widget.FisheyeLite({ 
+	//	|	new dojox.widget.FisheyeLite({
 	//	|		properties:{
 	//	|			// height is literal, width is multiplied
 	//	|			height:{ end: 200 }, width:2.3
@@ -52,7 +52,7 @@ dojo.declare("dojox.widget.FisheyeLite",
 	//		The Time (in ms) to run the hide animation
 	durationOut: 1420,
 	
-	// easeOut: Function	
+	// easeOut: Function
 	// 		An easing function to use for the hide animation
 	easeOut: dojo.fx.easing.elasticOut,
 
@@ -89,7 +89,7 @@ dojo.declare("dojox.widget.FisheyeLite",
 	
 	show: function(){
 		// summary:
-		//		Show this Fisheye item. 
+		//		Show this Fisheye item.
 		this._runningOut.stop();
 		this._runningIn.play();
 	},
diff --git a/dojox/widget/Iterator.js b/dojox/widget/Iterator.js
index b2e82a2..86d6fdb 100644
--- a/dojox/widget/Iterator.js
+++ b/dojox/widget/Iterator.js
@@ -6,9 +6,9 @@ dojo.experimental("dojox.widget.Iterator"); // level: prototype, designed for di
 /*
 	example:
 		from markup:
-	|	<span dojoType="dojo.data.ItemFileReadStore" 
+	|	<span dojoType="dojo.data.ItemFileReadStore"
 	|		jsId="cstore" url="countries.json"></span>
-	|	
+	|
 	|	<div>
 	|		<div dojoType="dojox.widget.Iterator" store="cstore"
 	|			query="{ name: 'A*'}">
@@ -19,12 +19,12 @@ dojo.experimental("dojox.widget.Iterator"); // level: prototype, designed for di
 	example:
 		programmatic:
 	|	var store = new dojo.data.ItemFileReadStore({ url: "countries.json" });
-	|	
-	|	var iter = new dojox.widget.Iterator({ 
+	|
+	|	var iter = new dojox.widget.Iterator({
 	|		store: store,
 	|		template: ""
 	|	});
-	|		
+	|
 
 	example:
 		programmatic from an array of objects:
@@ -32,8 +32,8 @@ dojo.experimental("dojox.widget.Iterator"); // level: prototype, designed for di
 	|		{ name: "foo", valueAttr: "bar" },
 	|		{ name: "thinger", valueAttr: "blah" }
 	|	];
-	|	
-	|	var iter = new dojox.widget.Iterator({ 
+	|
+	|	var iter = new dojox.widget.Iterator({
 	|		data: dataArr,
 	|		template: ""
 	|	});
@@ -44,8 +44,8 @@ dojo.experimental("dojox.widget.Iterator"); // level: prototype, designed for di
 	|		{ name: "foo", valueAttr: "bar" },
 	|		{ name: "thinger", valueAttr: "blah" }
 	|	];
-	|	
-	|	var iter = new dojox.widget.Iterator({ 
+	|
+	|	var iter = new dojox.widget.Iterator({
 	|		data: dataArr,
 	|		template: ""
 	|	});
@@ -76,7 +76,7 @@ dojo.declare("dojox.widget.Iterator",
 	data: null, // should be a reference to an Array
 	store: null,
 	_srcIndex: 0,
-	_srcParent: null, 
+	_srcParent: null,
 
 	_setSrcIndex: function(s){
 		this._srcIndex = 0;
diff --git a/dojox/widget/Loader.js b/dojox/widget/Loader.js
index 9033823..04a5ca6 100644
--- a/dojox/widget/Loader.js
+++ b/dojox/widget/Loader.js
@@ -1,16 +1,16 @@
 dojo.provide("dojox.widget.Loader");
-dojo.deprecated("dojox.widget.Loader", "", "2.0"); 
+dojo.deprecated("dojox.widget.Loader", "", "2.0");
 
 dojo.require("dijit._Widget");
-dojo.require("dijit._Templated"); 
+dojo.require("dijit._Templated");
 
 dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 	// summary: a configurable global xhr-listener to display
-	// a loading message during running xhr's or to simply provide 
-	// base-level topic to subscribe to for custom loading messages 
+	// a loading message during running xhr's or to simply provide
+	// base-level topic to subscribe to for custom loading messages
 	//
 	// loadIcon: String
-	// 	location to the icon used. 
+	// 	location to the icon used.
 	loadIcon: dojo.moduleUrl("dojox.widget.Loader","icons/loading.gif"),
 
 	// loadMessage: String
@@ -19,7 +19,7 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 
 	// hasVisuals: Boolean
 	// 	true to display a fixed loading message in TR cornder, false to unly provide
-	//	"Loader" topic to subscribe to for your own custom loading message.	
+	//	"Loader" topic to subscribe to for your own custom loading message.
 	hasVisuals: true,
 
 	// attachToPointer
@@ -32,10 +32,10 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 
 	// _offset: Integer
 	//	distance in px from the mouse pointer to show attachToPointer avatar
-	_offset: 16, 
+	_offset: 16,
 
 	// holder for mousemove connection
-	_pointerConnect: null, 
+	_pointerConnect: null,
 	_xhrStart: null,
 	_xhrEnd: null,
 
@@ -46,21 +46,21 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 	postCreate: function(){
 		// summary: setup the loader
 
-		if(!this.hasVisuals){ 
+		if(!this.hasVisuals){
 			this.loadNode.style.display = "none"; // _destroy()?
 		}else{
 			if(this.attachToPointer){
-				dojo.removeClass(this.loadNode,"dojoxLoader"); 
-				dojo.addClass(this.loadNode,"dojoxLoaderPointer"); 
+				dojo.removeClass(this.loadNode,"dojoxLoader");
+				dojo.addClass(this.loadNode,"dojoxLoaderPointer");
 			}
 			this._hide();
 		}
-		this._setMessage(this.loadMessage); 
+		this._setMessage(this.loadMessage);
 
 		// FIXME: create our connections.  would be easier, and this might be redundant
-		// if Deferred published something
-		this._xhrStart = this.connect(dojo,"_ioSetArgs","_show"); 
-		this._xhrEnd = this.connect(dojo.Deferred.prototype,"_fire","_hide"); 
+		// if Deferred published something. XHR published stuff. FIXME to use that.
+		this._xhrStart = this.connect(dojo,"_ioSetArgs","_show");
+		this._xhrEnd = this.connect(dojo.Deferred.prototype,"_fire","_hide");
 
 	},
 
@@ -71,32 +71,32 @@ dojo.declare("dojox.widget.Loader", [dijit._Widget,dijit._Templated], {
 
 	_putLoader: function(/* Event */ e){
 		// summary: place the floating loading element based on mousemove connection position
-		dijit.placeOnScreen(this.loadNode,{ x: e.clientX+this._offset, y:e.clientY+this._offset }, ["TL","BR"]); 
+		dijit.placeOnScreen(this.loadNode,{ x: e.clientX+this._offset, y:e.clientY+this._offset }, ["TL","BR"]);
 	},
 
 	_show: function(){
 		// summary: publish and show progress indicator
 		dojo.publish("Loader",[{ message: 'started' }]);
-		if(this.hasVisuals){ 
+		if(this.hasVisuals){
 			if(this.attachToPointer){
 				this._pointerConnect = this.connect(document,"onmousemove","_putLoader");
 			}
 			dojo.style(this.loadNode, {
 				opacity:0, display:""
 			});
-			dojo.fadeIn({ node: this.loadNode, duration:this.duration }).play(); 
+			dojo.fadeIn({ node: this.loadNode, duration:this.duration }).play();
 		}
 	},
 
 	_hide: function(){
 		// summary: publish "xhr ended" and hide progress indicator
 		dojo.publish("Loader",[{ message: 'ended' }]);
-		if(this.hasVisuals){ 
+		if(this.hasVisuals){
 			if(this.attachToPointer){
-				this.disconnect(this._pointerConnect); 
+				this.disconnect(this._pointerConnect);
 			}
-			dojo.fadeOut({ 
-				node: this.loadNode, 
+			dojo.fadeOut({
+				node: this.loadNode,
 				duration:this.duration,
 				onEnd: dojo.partial(dojo.style, this.loadNode, "display", "none")
 			}).play();
diff --git a/dojox/widget/Pager.js b/dojox/widget/Pager.js
index e78e776..3ea4b4d 100644
--- a/dojox/widget/Pager.js
+++ b/dojox/widget/Pager.js
@@ -5,15 +5,15 @@ dojo.require("dijit._Widget");
 dojo.require("dijit._Templated");
 dojo.require("dojo.fx");
 
-dojo.declare("dojox.widget.Pager", 
-	[dijit._Widget, dijit._Templated], 
+dojo.declare("dojox.widget.Pager",
+	[dijit._Widget, dijit._Templated],
 	{
 	// summary: A Pager, displaying a list of sized nodes
 	
 	
 	templateString: dojo.cache("dojox.widget", "Pager/Pager.html"),
 
-/*=====	
+/*=====
 	// iconPrevious: String?
 	//		The url of the previous page icon
 	iconPrevious: "",
@@ -38,11 +38,11 @@ dojo.declare("dojox.widget.Pager",
 	//		A string describing where to put the Pager "current page" indicator. Options are
 	//		"leading" or "trailing". In the case of horiztonal orientation, "leading" indicates
 	//		positioned above the PageItems. In the case of vertical, "leading" indicates "before".
-	statusPos: "leading", 
+	statusPos: "leading",
 	
 	// pagerPos: String
 	//		TODOC
-	pagerPos: "center", 
+	pagerPos: "center",
 
 	// duration: Integer
 	// 		Time in milliseconds to transition the pages
@@ -62,7 +62,7 @@ dojo.declare("dojox.widget.Pager",
 	
 	// itemsPage: Integer
 	//		The numbers of items to display in each "Page"
-	itemsPage: 3, 
+	itemsPage: 3,
 	
 	postMixInProperties: function(){
 		var h = (this.orientation == "horizontal");
@@ -107,7 +107,7 @@ dojo.declare("dojox.widget.Pager",
 
 			case dk.DOWN_ARROW:
 			case dk.LEFT_ARROW:
-			case 112: 
+			case 112:
 			case 80: // key "p"
 				e.preventDefault();
 				this._pagerPrevious();
@@ -337,7 +337,7 @@ dojo.declare("dojox.widget.Pager",
 						var position = (dojo.style(this.pagerContainer, 'height')/2)-(this.iconHeight/2);
 						dojo.style(this.pagerContainerStatus, 'paddingTop', position+'px');
 					}
-				}	
+				}
 				dojo.disconnect(this._iconConnects[pointer]);
 			}, pointer));
 			
@@ -377,8 +377,8 @@ dojo.declare("dojox.widget.Pager",
 			var cmd = (b ? "_pagerPrevious" : "_pagerNext");
 			var connect = this.connect(this, "onScrollEnd", function(){
 				this._toScroll--;
-				if(this._toScroll < 1){ 
-					this.disconnect(connect); 
+				if(this._toScroll < 1){
+					this.disconnect(connect);
 				}else{
 					this[cmd]();
 				}
@@ -442,8 +442,8 @@ dojo.declare("dojox.widget.Pager",
 		}
 		
 		this._anim = dojo.fx.combine(_anims);
-		var animConnect = this.connect(this._anim, "onEnd", function(){ 
-			delete this._anim; 
+		var animConnect = this.connect(this._anim, "onEnd", function(){
+			delete this._anim;
 			this.onScrollEnd();
 			this.disconnect(animConnect);
 		});
@@ -531,7 +531,7 @@ dojo.declare("dojox.widget.Pager",
 });
 
 dojo.declare("dojox.widget._PagerItem",
-	[dijit._Widget, dijit._Templated], 
+	[dijit._Widget, dijit._Templated],
 	{
 	
 	templateString: '<li class="pagerItem" dojoAttachPoint="containerNode"></li>',
diff --git a/dojox/widget/PlaceholderMenuItem.js b/dojox/widget/PlaceholderMenuItem.js
index 3aee250..6f939db 100644
--- a/dojox/widget/PlaceholderMenuItem.js
+++ b/dojox/widget/PlaceholderMenuItem.js
@@ -1,5 +1,7 @@
 dojo.provide("dojox.widget.PlaceholderMenuItem");
 
+dojo.experimental("dojox.widget.PlaceholderMenuItem");
+
 dojo.require("dijit.Menu");
 
 dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
@@ -8,43 +10,43 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 	//		of this item to a unique key and you can then use it to add new
 	//		items at that location.  This item is not displayed.
 	
-	_replaced: false, 
-	_replacedWith: null, 
-	_isPlaceholder: true, 
+	_replaced: false,
+	_replacedWith: null,
+	_isPlaceholder: true,
 
-	postCreate: function(){ 
-		this.domNode.style.display = "none"; 
-		this._replacedWith = []; 
+	postCreate: function(){
+		this.domNode.style.display = "none";
+		this._replacedWith = [];
 		if(!this.label){
 			this.label = this.containerNode.innerHTML;
 		}
-		this.inherited(arguments); 
-	}, 
+		this.inherited(arguments);
+	},
 	
-	replace: function(/*dijit.MenuItem[]*/ menuItems){ 
+	replace: function(/*dijit.MenuItem[]*/ menuItems){
 		// summary:
 		//		replaces this menu item with the given menuItems.  The original
 		//		menu item is not actually removed from the menu - so if you want
 		//		it removed, you must do that explicitly.
 		// returns:
 		//		true if the replace happened, false if not
-		if(this._replaced){ return false; } 
+		if(this._replaced){ return false; }
 
-		var index = this.getIndexInParent(); 
-		if(index < 0){ return false; } 
+		var index = this.getIndexInParent();
+		if(index < 0){ return false; }
 
-		var p = this.getParent(); 
+		var p = this.getParent();
 
-		dojo.forEach(menuItems, function(item){ 
-			p.addChild(item, index++); 
-		}); 
-		this._replacedWith = menuItems; 
+		dojo.forEach(menuItems, function(item){
+			p.addChild(item, index++);
+		});
+		this._replacedWith = menuItems;
 
-		this._replaced = true; 
+		this._replaced = true;
 		return true;
-	}, 
+	},
 	
-	unReplace: function(/*Boolean?*/ destroy){ 
+	unReplace: function(/*Boolean?*/ destroy){
 		// summary:
 		//		Removes menu items added by calling replace().  It returns the
 		//		array of items that were actually removed (in case you want to
@@ -54,42 +56,42 @@ dojo.declare("dojox.widget.PlaceholderMenuItem", dijit.MenuItem, {
 		// returns:
 		//		The array of items that were actually removed
 		
-		if(!this._replaced){ return []; } 
+		if(!this._replaced){ return []; }
 
-		var p = this.getParent(); 
-		if(!p){ return []; } 
+		var p = this.getParent();
+		if(!p){ return []; }
 
-		var r = this._replacedWith; 
-		dojo.forEach(this._replacedWith, function(item){ 
-			p.removeChild(item); 
-			if(destroy){ 
-				item.destroy(); 
-			} 
-		}); 
-		this._replacedWith = []; 
-		this._replaced = false; 
+		var r = this._replacedWith;
+		dojo.forEach(this._replacedWith, function(item){
+			p.removeChild(item);
+			if(destroy){
+				item.destroyRecursive();
+			}
+		});
+		this._replacedWith = [];
+		this._replaced = false;
 
-		return r; // dijit.MenuItem[] 
-	} 
-}); 
+		return r; // dijit.MenuItem[]
+	}
+});
 
 // Se need to extend dijit.Menu so that we have a getPlaceholders function.
-dojo.extend(dijit.Menu, { 
-	getPlaceholders: function(/*String?*/ label){ 
+dojo.extend(dijit.Menu, {
+	getPlaceholders: function(/*String?*/ label){
 		// summary:
-		//		returns an array of placeholders with the given label.  There
+		//		Returns an array of placeholders with the given label.  There
 		//		can be multiples.
 		// label:
 		//		Label to search for - if not specified, then all placeholders
 		//		are returned
 		// returns:
 		//		An array of placeholders that match the given label
-		var r = []; 
+		var r = [];
 
-		var children = this.getChildren(); 
-		children.forEach(function(child){ 
+		var children = this.getChildren();
+		dojo.forEach(children, function(child){
 			if(child._isPlaceholder && (!label || child.label == label)){
-				r.push(child); 
+				r.push(child);
 			}else if(child._started && child.popup && child.popup.getPlaceholders){
 				r = r.concat(child.popup.getPlaceholders(label));
 			}else if(!child._started && child.dropDownContainer){
@@ -99,7 +101,7 @@ dojo.extend(dijit.Menu, {
 					r = r.concat(menu.getPlaceholders(label));
 				}
 			}
-		}, this); 
+		}, this);
 		return r; // dojox.widget.PlaceholderMenuItem[]
 	}
 }); 
\ No newline at end of file
diff --git a/dojox/widget/Portlet.js b/dojox/widget/Portlet.js
index 67a5d14..3f17784 100644
--- a/dojox/widget/Portlet.js
+++ b/dojox/widget/Portlet.js
@@ -8,9 +8,9 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 	//		in a dojox.layout.GridContainer. Child widgets can insert
 	//		an icon into the title bar of the Portlet, which when
 	//		clicked, executes the "toggle" method of the child widget.
-	//		A child widget must specify the attribute 
+	//		A child widget must specify the attribute
 	//		"portletIconClass", and the optional class
-	//		"portletIconHoverClass", as well as the 
+	//		"portletIconHoverClass", as well as the
 	//		"toggle" function.
 
 	// resizeChildren: Boolean
@@ -81,7 +81,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 
 						while(n){
 							if(n == child.domNode){
-								
+
 								// Only fire this once, as the widget is now visible
 								// at least once, so child measurements should be accurate.
 								_this.unsubscribe(s);
@@ -114,7 +114,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 				}
 			}
 		}
-		
+
 		// Prevent clicks on icons from causing a drag to start.
 		this.connect(this.titleBarNode, "onmousedown", function(evt){
 			if (dojo.hasClass(evt.target, "dojoxPortletIcon")) {
@@ -147,7 +147,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 				if(!child.started && !child._started){
 					child.startup()
 				}
-			} 
+			}
 			catch(e){
 				console.log(this.id + ":" + this.declaredClass, e);
 			}
@@ -161,7 +161,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 
 	_placeSettingsWidgets: function(){
 		// summary: Checks all the children to see if they are instances
-		//		of dojox.widget.PortletSettings.	If they are, 
+		//		of dojox.widget.PortletSettings. If they are,
 		//		create an icon for them in the title bar which when clicked,
 		//		calls their toggle() method.
 
@@ -176,7 +176,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 	},
 
 	_createIcon: function(clazz, hoverClazz, fn){
-		// summary: 
+		// summary:
 		//		creates an icon in the title bar.
 
 		var icon = dojo.create("div",{
@@ -199,7 +199,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 	},
 
 	onClose: function(evt){
-		// summary: 
+		// summary:
 		//		Hides the portlet. Note that it does not
 		//		persist this, so it is up to the client to
 		//		listen to this method and persist the closed state
@@ -218,23 +218,23 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 	},
 
 	_updateSize: function(){
-		// summary: 
+		// summary:
 		//		Updates the size of all child widgets.
 		if(!this.open || !this._started || !this.resizeChildren){
 			return;
 		}
-		
+
 		if(this._timer){
 			clearTimeout(this._timer);
 		}
-		// Delay applying the size change in case the size 
+		// Delay applying the size change in case the size
 		// changes very frequently, for performance reasons.
 		this._timer = setTimeout(dojo.hitch(this, function(){
 			var size ={
 				w: dojo.style(this.domNode, "width"),
 				h: dojo.style(this.domNode, "height")
 			};
-	
+
 			// If the Portlet is in a StackWidget, and it is not
 			// visible, do not update the size, as it could
 			// make child widgets miscalculate.
@@ -245,7 +245,7 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 					return;
 				}
 			}
-	
+
 			if(this._size){
 				// If the size of the portlet hasn't changed, don't
 				// resize the children, as this can be expensive
@@ -254,8 +254,6 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 				}
 			}
 			this._size = size;
-	
-			
 
 			var fns = ["resize", "layout"];
 			this._timer = null;
@@ -270,9 +268,9 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 							console.log(e);
 						}
 						break;
-					} 
+					}
 				}
-			});	
+			});
 			this.onUpdateSize();
 		}), 100);
 	},
@@ -296,11 +294,11 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 	},
 
 	addChild: function(child){
-		// summary: 
+ 		// summary:
 		//		Adds a child widget to the portlet.
 		this._size = null;
 		this.inherited(arguments);
-		
+
 		if(this._started){
 			this._placeSettingsWidgets();
 			this._updateSize();
@@ -309,14 +307,21 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 			child.startup();
 		}
 	},
-	
+
 	destroyDescendants: function(/*Boolean*/ preserveDom){
 		this.inherited(arguments);
 		if(this._settingsWidget){
 			this._settingsWidget.destroyRecursive(preserveDom);
 		}
 	},
-	
+
+	destroy: function(){
+		if(this._timer){
+			clearTimeout(this._timer);
+		}
+		this.inherited(arguments);
+	},
+
 	_setCss: function(){
 		this.inherited(arguments);
 		dojo.style(this.arrowNode, "display", this.toggleable ? "":"none");
@@ -324,9 +329,9 @@ dojo.declare("dojox.widget.Portlet", [dijit.TitlePane, dijit._Container],{
 });
 
 dojo.declare("dojox.widget.PortletSettings", [dijit._Container, dijit.layout.ContentPane],{
-	// summary: 
+	// summary:
 	//		A settings widget to be used with a dojox.widget.Portlet.
-	// description: 
+	// description:
 	//		This widget should be placed inside a dojox.widget.Portlet widget.
 	//		It is used to set some preferences for that Portlet.	It is essentially
 	//		a ContentPane, and should contain other widgets and DOM nodes that
@@ -355,13 +360,13 @@ dojo.declare("dojox.widget.PortletSettings", [dijit._Container, dijit.layout.Con
 	},
 
 	_setPortletAttr: function(portlet){
-		// summary: 
+		// summary:
 		//		Sets the portlet that encloses this widget.
 		this.portlet = portlet;
 	},
 
 	toggle: function(){
-		// summary: 
+		// summary:
 		//		Toggles the visibility of this widget.
 		var n = this.domNode;
 		if(dojo.style(n, "display") == "none"){
@@ -384,9 +389,9 @@ dojo.declare("dojox.widget.PortletSettings", [dijit._Container, dijit.layout.Con
 	}
 });
 
-dojo.declare("dojox.widget.PortletDialogSettings", 
+dojo.declare("dojox.widget.PortletDialogSettings",
 	dojox.widget.PortletSettings,{
-	// summary: 
+	// summary:
 	//		A settings widget to be used with a dojox.widget.Portlet, which displays
 	//		the contents of this widget in a dijit.Dialog box.
 
@@ -399,12 +404,12 @@ dojo.declare("dojox.widget.PortletDialogSettings",
 	},
 
 	toggle: function(){
-		// summary: 
+		// summary:
 		//		Shows and hides the Dialog box.
 		if(!this.dialog){
 			dojo["require"]("dijit.Dialog");
 			this.dialog = new dijit.Dialog({title: this.title});
-			
+
 			dojo.body().appendChild(this.dialog.domNode);
 
 			// Move this widget inside the dialog
diff --git a/dojox/widget/Portlet/Portlet.css b/dojox/widget/Portlet/Portlet.css
index ba0f746..d249355 100644
--- a/dojox/widget/Portlet/Portlet.css
+++ b/dojox/widget/Portlet/Portlet.css
@@ -39,7 +39,9 @@
 .nihilo .dojoxPortlet .dojoxPortletIcon {
 	background-image: url("../../../dijit/themes/nihilo/images/spriteRoundedIconsSmall.gif");
 }
-.dojoxPortlet .dojoxCloseNode, 
+.claro .dojoxPortlet .dojoxPortletIcon {
+	background-image: url("../../../dijit/themes/tundra/images/spriteRoundedIconsSmall.gif");
+}
 .dojoxPortlet .dojoxCloseNode {
 	background-position: right 0px;
 }
@@ -49,29 +51,40 @@
 
 .tundra .dojoxPortlet .dijitOpen .dojoxArrowDown,
 .soria .dojoxPortlet .dijitOpen .dojoxArrowDown,
-.nihilo .dojoxPortlet .dijitOpen .dojoxArrowDown {
+.nihilo .dojoxPortlet .dijitOpen .dojoxArrowDown,
+.claro .dojoxPortlet .dijitOpen .dojoxArrowDown{
 	background-position: -15px top;
 }
 .tundra .dojoxPortlet .dijitClosed .dojoxArrowDown,
 .soria .dojoxPortlet .dijitClosed .dojoxArrowDown,
-.nihilo .dojoxPortlet .dijitClosed .dojoxArrowDown {
+.nihilo .dojoxPortlet .dijitClosed .dojoxArrowDown,
+.claro .dojoxPortlet .dijitClosed .dojoxArrowDown {
 	background-position: 0 top;
 }
 
 .tundra .dojoxPortlet .dojoxPortletSettingsIcon,
 .soria .dojoxPortlet .dojoxPortletSettingsIcon,
-.nihilo .dojoxPortlet .dojoxPortletSettingsIcon {
+.nihilo .dojoxPortlet .dojoxPortletSettingsIcon,
+.claro .dojoxPortlet .dojoxPortletSettingsIcon {
 	background-image: url(images/icons.png);
 	background-position: 0 1px;
 }
 .tundra .dojoxPortletSettingsContainer,
 .soria .dojoxPortletSettingsContainer,
-.nihilo .dojoxPortletSettingsContainer {
+.nihilo .dojoxPortletSettingsContainer,
+.claro .dojoxPortletSettingsContainer {
 	border-bottom: 1px solid #BFBFBF;
 	padding: 4px;
 }
 .tundra .dijitDialogPaneContent .dojoxPortletSettingsContainer,
 .soria .dijitDialogPaneContent .dojoxPortletSettingsContainer,
+.nihilo .dijitDialogPaneContent .dojoxPortletSettingsContainer,
+.claro .dijitDialogPaneContent .dojoxPortletSettingsContainer {
+	border-bottom: none;
+}
+
+.tundra .dijitDialogPaneContent .dojoxPortletSettingsContainer,
+.soria .dijitDialogPaneContent .dojoxPortletSettingsContainer,
 .nihilo .dijitDialogPaneContent .dojoxPortletSettingsContainer {
 	border-bottom: none;
 }
diff --git a/dojox/widget/README b/dojox/widget/README
index ea318a5..d211a8e 100644
--- a/dojox/widget/README
+++ b/dojox/widget/README
@@ -6,52 +6,57 @@ Release date: 10/31/2007
 -------------------------------------------------------------------------------
 Project state:
 
-[Calendar]	experimental
+[Calendar]		experimental
 [CalendarFx]	experimental
 [ColorPicker]	beta
-[Dialog]	experimental
+[Dialog]		experimental
+[DialogSimple]	beta
 [FeedPortlet]	experimental
 [FilePicker]	experimental
 [FisheyeList]	experimental
 [FisheyeLite]	beta
-[Iterator]	experimental
-[Loader]	experimental
-[Pager]		experimental
-[Portlet]	experimental
+[Iterator]		experimental
+[Loader]		experimental
+[Pager]			experimental
+[Portlet]		experimental
 [PlaceholderMenuItem]	experimental
-[Roller]	experimental
+[Roller]		experimental
 [RollingList]	experimental
-[SortList]	experimental
-[Toaster]	experimental
-[Wizard]	experimental
+[SortList]		experimental
+[TitleGroup]	beta
+[Toaster]		experimental
+[Wizard]		experimental
 [AnalogGauge]   experimental
 [BarGauge]      experimental
-[Standby]	experimental
+[Standby]		experimental
+
 -------------------------------------------------------------------------------
 Credits:
 
-[Calendar] Shane O'Sullivan
-[CalendarFx] Shane O'Sullivan
-[ColorPicker] Peter Higgins (dante)
-[Dialog] Peter Higgins (dante)
-[FeedPortlet] Shane O'Sullivan
-[FilePicker] Nathan Toone (toonetown)
-[FisheyeList] Karl Tiedt (kteidt)
-[FisheyeLite] Peter Higgins (dante)
-[Iterator] Alex Russell (slightlyoff)
-[Loader] Peter Higgins (dante)
-[Pager] Nikolai Onken (nonken), Peter Higgins (dante);
-[PlaceholderMenuItem] Nathan Toone (toonetown)
-[Portlet] Shane O'Sullivan
-[Roller] Peter Higgins (dante)
-[RollingList] Nathan Toone (toonetown)
-[SortList] Peter Higgins (dante)
-[Toaster] Adam Peller (peller)
-[Wizard] Peter Higgins (dante)
-[AnalogGauge] Benjamin Schell (bmschell) CCLA
-[BarGauge] Benjamin Schell (bmschell) CCLA 
-[Standby] Jared Jurkiewicz (jaredj) CCLA 
-[UpgradeBar] Mike Wilcox (mwilcox), Revin Guillen
+[Calendar]		Shane O'Sullivan
+[CalendarFx]	Shane O'Sullivan
+[ColorPicker]	Peter Higgins (dante)
+[Dialog]		Peter Higgins (dante)
+[DialogSimple]	Peter Higgins (dante)
+[FeedPortlet]	Shane O'Sullivan
+[FilePicker]	Nathan Toone (toonetown)
+[FisheyeList] 	Karl Tiedt (kteidt)
+[FisheyeLite] 	Peter Higgins (dante)
+[Iterator]		Alex Russell (slightlyoff)
+[Loader]		Peter Higgins (dante)
+[Pager]			Nikolai Onken (nonken), Peter Higgins (dante);
+[PlaceholderMenuItem]	Nathan Toone (toonetown)
+[Portlet]		Shane O'Sullivan
+[Roller]		Peter Higgins (dante)
+[RollingList] 	Nathan Toone (toonetown)
+[SortList]		Peter Higgins (dante)
+[TitleGroup]	Peter Higgins (dante)
+[Toaster]		Adam Peller (peller)
+[Wizard]		Peter Higgins (dante)
+[AnalogGauge]	Benjamin Schell (bmschell) CCLA
+[BarGauge]		Benjamin Schell (bmschell) CCLA 
+[Standby]		Jared Jurkiewicz (jaredj) CCLA 
+[UpgradeBar]	Mike Wilcox (mwilcox), Revin Guillen
 
 -------------------------------------------------------------------------------
 Project description
@@ -121,6 +126,8 @@ Other Notes (Brief widget list):
 	* CalendarFx - additional mixable FX for transitions in dojox.widget.Calendar
 
 	* Dialog - An extended version of dijit.Dialog with man options and transition.
+	
+	* DialogSimple - A simple Dijit Dialog providing `dojox.layout.ContentPane` integration
 
 	* FilePicker - a widget for browsing server-side file systems (can use
 		dojox.data.FileStore as backend store)
@@ -150,6 +157,9 @@ Other Notes (Brief widget list):
 		and sorting. Can be the direct descendant of a
 		LayoutContainer and will size to fit.
 
+	* TitleGroup - A container offering variable height TitlePane access, though
+		behaves like an AccordionContainer 
+
 	* Toaster - a messaging system to display unobtrusive 
 		alerts on screen.
 
@@ -167,8 +177,8 @@ Other Notes (Brief widget list):
 		etc.  Very flexible.
 		Requires dojo >= 1.3
 
-	* Standby - a 'blocker' style widget to overlay a translucent div + image over a DOM node/widget to indicate busy.
-		Overlay color, image, and alt text can all be customized.
+	* Standby - a 'blocker' style widget to overlay a translucent div + image over a DOM node/widget 
+		to indicate busy. Overlay color, image, and alt text can all be customized.
 		Requires dojo >= 1.3
 
 	* UpgradeBar - Displays the "yellow bar" at the top of a page to indicate the user
diff --git a/dojox/widget/Roller.js b/dojox/widget/Roller.js
index ff9cb42..1359c4c 100644
--- a/dojox/widget/Roller.js
+++ b/dojox/widget/Roller.js
@@ -3,21 +3,21 @@ 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: 
+	//
+	// 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. 
-	//		
+	//		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. 
+	//		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: 
+	//	example:
 	//	|	// create a scroller from a unordered list with id="lister"
 	//  |	var thinger = new dojox.widget.Roller.Roller({},"lister");
 	//
@@ -29,7 +29,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 	//	|	// add an item:
 	//	|	dijit.byId("roller").items.push("I am a new Label");
 	//
-	//  example: 
+	//  example:
 	//	|	// stop a roller from rolling:
 	//	|	dijit.byId("roller").stop();
 	//
@@ -59,7 +59,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 	// 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[]
@@ -68,19 +68,19 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 	postCreate: function(){
 
 		// add some instance vars:
-		if(!this["items"]){ 
+		if(!this["items"]){
 			this.items = [];
 		}
 		
 		dojo.addClass(this.domNode,"dojoxRoller");
 		
-		// find all the items in this list, and popuplate 
+		// 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; 
+			if(i == 0){
+				this._roller = item;
+				this._idx = 0;
 			}else{ dojo.destroy(item); }
 		}, this);
 		
@@ -99,7 +99,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 	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. 
+		//		will reuse.
 		var n = this.domNode;
 		dojo.mixin(this, {
 			_anim: {
@@ -117,7 +117,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 
 		this.connect(anim["out"], "onEnd", function(){
 			// onEnd of the `out` animation, select the next items and play `in` animation
-			this._set(this._idx + 1);
+			this._setIndex(this._idx + 1);
 			anim["in"].play(15);
 		});
 		
@@ -143,7 +143,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 		// summary: Stops the Roller from looping anymore.
 		this.rolling = false;
 
-		var m = this._anim, 
+		var m = this._anim,
 			t = this._timeout;
 
 		if(t){ clearTimeout(t); }
@@ -151,7 +151,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 		m["out"].stop();
 	},
 	
-	_set: function(i){
+	_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; }
@@ -163,7 +163,7 @@ dojo.declare("dojox.widget.Roller", dijit._Widget, {
 });
 
 dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
-	// summary: An add-on to the Roller to modify animations. This produces 
+	// 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.
 	
@@ -174,7 +174,7 @@ dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
 		// 		Animation stored in _anim Object, which the rest of the widget
 		//		will reuse.
 
-		var n = this.domNode, pos = "position", 
+		var n = this.domNode, pos = "position",
 			props = {
 				top: { end: 0, start: 25 },
 				opacity: 1
@@ -187,8 +187,8 @@ dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
 		dojo.mixin(this, {
 			_anim: {
 				
-				"in": dojo.animateProperty({ 
-					node: n, 
+				"in": dojo.animateProperty({
+					node: n,
 					duration: this.durationIn,
 					properties: props
 				}),
@@ -205,11 +205,11 @@ dojo.declare("dojox.widget.RollerSlide", dojox.widget.Roller, {
 dojo.declare("dojox.widget._RollerHover", null, {
 	// summary: A mixin class to provide a way to automate the "stop on hover" functionality.
 	//
-	// description: 
+	// 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. 
+	//		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
diff --git a/dojox/widget/RollingList.js b/dojox/widget/RollingList.js
index 031d141..674dbb1 100644
--- a/dojox/widget/RollingList.js
+++ b/dojox/widget/RollingList.js
@@ -12,7 +12,7 @@ dojo.require("dijit.form.Button");
 
 dojo.require("dojox.html.metrics");
 
-dojo.require("dojo.i18n"); 
+dojo.require("dojo.i18n");
 dojo.requireLocalization("dijit", "common");
 
 dojo.declare("dojox.widget._RollingListPane",
@@ -92,7 +92,7 @@ dojo.declare("dojox.widget._RollingListPane",
 		if(this.store && this.store.getFeatures()["dojo.data.api.Notification"]){
 			window.setTimeout(dojo.hitch(this, function(){
 				// Set connections after a slight timeout to avoid getting in the
-				// condition where we are setting them while events are still 
+				// condition where we are setting them while events are still
 				// being fired
 				this.connect(this.store, "onSet", "_onSetItem");
 				this.connect(this.store, "onNew", "_onNewItem");
@@ -151,7 +151,7 @@ dojo.declare("dojox.widget._RollingListPane",
 		// summary: loads the given items, and then calls the callback when they
 		//		are finished.
 		var _waitCount = 0, store = this.store;
-		dojo.forEach(items, function(item){ 
+		dojo.forEach(items, function(item){
 			if(!store.isItemLoaded(item)){ _waitCount++; }
 		});
 		if(_waitCount === 0){
@@ -168,7 +168,7 @@ dojo.declare("dojox.widget._RollingListPane",
 					store.loadItem({item: item, onItem: onItem});
 				}
 			});
-		}	
+		}
 	},
 	
 	_doQuery: function(){
@@ -182,11 +182,11 @@ dojo.declare("dojox.widget._RollingListPane",
 			this.onItems();
 		}else{
 			this._setContentAndScroll(this.onFetchStart(), true);
-			this.store.fetch({query: this.query, 
+			this.store.fetch({query: this.query,
 				onComplete: function(items){
 					this.items = items;
 					this.onItems();
-				}, 
+				},
 				onError: function(e){
 					this._onError("Fetch", e);
 				},
@@ -195,7 +195,7 @@ dojo.declare("dojox.widget._RollingListPane",
 	},
 
 	_hasItem: function(/* item */ item){
-		// summary: returns whether or not the given item is handled by this 
+		// summary: returns whether or not the given item is handled by this
 		//  pane
 		var items = this.items || [];
 		for(var i = 0, myItem; (myItem = items[i]); i++){
@@ -206,10 +206,10 @@ dojo.declare("dojox.widget._RollingListPane",
 		return false;
 	},
 	
-	_onSetItem: function(/* item */ item, 
-					/* attribute-name-string */ attribute, 
+	_onSetItem: function(/* item */ item,
+					/* attribute-name-string */ attribute,
 					/* object | array */ oldValue,
-					/* object | array */ newValue){	
+					/* object | array */ newValue){
 		// Summary: called when an item in the store has changed
 		if(this._hasItem(item)){
 			this.refresh();
@@ -271,7 +271,7 @@ dojo.declare("dojox.widget._RollingListPane",
 			this.cancel();
 			this.onLoadDeferred = new dojo.Deferred(dojo.hitch(this, "cancel"));
 		}
-		this._onLoadHandler();		
+		this._onLoadHandler();
 	}
 			
 });
@@ -356,7 +356,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 	},
 	
 	_checkScrollConnection: function(doLoad){
-		// summary: checks whether or not we need to connect to our onscroll 
+		// summary: checks whether or not we need to connect to our onscroll
 		//		function
 		var store = this.store
 		if(this._scrollConn){
@@ -368,7 +368,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 				this._loadVisibleItems();
 			}
 			this._scrollConn = this.connect(this.domNode, "onscroll", "_onScrollPane");
-		}	
+		}
 	},
 	
 	startup: function(){
@@ -424,7 +424,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 		var self = this;
 		var menu = new dijit.Menu({
 			parentMenu: this.parentPane ? this.parentPane._menu : null,
-			onCancel: function(/*Boolean*/ closeAll){ 
+			onCancel: function(/*Boolean*/ closeAll){
 				if(self.parentPane){
 					self.parentPane.focus(true);
 				}
@@ -438,7 +438,7 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 		this.connect(menu, "onItemClick", function(/*dijit.MenuItem*/ item, /*Event*/ evt){
 			if(item.disabled){ return; }
 			evt.alreadySelected = dojo.hasClass(item.domNode, "dojoxRollingListItemSelected");
-			if(evt.alreadySelected && 
+			if(evt.alreadySelected &&
 				((evt.type == "keypress" && evt.charOrCode != dojo.keys.ENTER) ||
 				(evt.type == "internal"))){
 				var p = this.parentWidget.getChildren()[this.getIndexInParent() + 1];
@@ -484,8 +484,8 @@ dojo.declare("dojox.widget._RollingListGroupPane",
 			if(pb){ r += dojo._getPadBorderExtents(n, s).t; }
 			return r;
 		};
-		var topOffset = gpbme(this.domNode, false, true) + 
-						gpbme(this.containerNode, true, true) + 
+		var topOffset = gpbme(this.domNode, false, true) +
+						gpbme(this.containerNode, true, true) +
 						gpbme(menu.domNode, true, true) +
 						gpbme(children[0].domNode, true, false);
 		var h = dojo.contentBox(this.domNode).h;
@@ -596,7 +596,7 @@ dojo.declare("dojox.widget.RollingList",
 	
 	// preloadItems: boolean or int
 	//		if set to true, then onItems will be called only *after* all items have
-	//		been loaded (ie store.isLoaded will return true for all of them).  If 
+	//		been loaded (ie store.isLoaded will return true for all of them).  If
 	//		false, then no preloading will occur.  If set to an integer, preloading
 	//		will occur if the number of items is less than or equal to the value
 	//		of the integer.  The onItems function will need to be aware of handling
@@ -613,7 +613,7 @@ dojo.declare("dojox.widget.RollingList",
 	okButtonLabel: "",
 	
 	// cancelButtonLabel: string
-	//		The string to use for the Cancel button - will use dijit's common 
+	//		The string to use for the Cancel button - will use dijit's common
 	//		"Cancel" string if not set
 	cancelButtonLabel: "",
 
@@ -651,12 +651,12 @@ dojo.declare("dojox.widget.RollingList",
 	_itemsMatch: function(/*item*/ item1, /*item*/ item2){
 		// Summary: returns whether or not the two items match - checks ID if
 		//  they aren't the exact same object
-		if(!item1 && !item2){ 
+		if(!item1 && !item2){
 			return true;
 		}else if(!item1 || !item2){
 			return false;
 		}
-		return (item1 == item2 || 
+		return (item1 == item2 ||
 			(this._isIdentity && this.store.getIdentity(item1) == this.store.getIdentity(item2)));
 	},
 	
@@ -717,9 +717,9 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_updateClass: function(/* Node */ node, /* String */ type, /* Object? */ options){
-		// summary: 
+		// summary:
 		//		sets the state of the given node with the given type and options
-		// options: 
+		// options:
 		//		an object with key-value-pairs.  The values are boolean, if true,
 		//		the key is added as a class, if false, it is removed.
 		if(!this._declaredClasses){
@@ -731,9 +731,9 @@ dojo.declare("dojox.widget.RollingList",
 				for(var k in options||{}){
 					dojo.toggleClass(node, c + type + k, options[k]);
 				}
-				dojo.toggleClass(node, c + type + "FocusSelected", 
+				dojo.toggleClass(node, c + type + "FocusSelected",
 					(dojo.hasClass(node, c + type + "Focus") && dojo.hasClass(node, c + type + "Selected")));
-				dojo.toggleClass(node, c + type + "HoverSelected", 
+				dojo.toggleClass(node, c + type + "HoverSelected",
 					(dojo.hasClass(node, c + type + "Hover") && dojo.hasClass(node, c + type + "Selected")));
 			}
 		});
@@ -741,7 +741,7 @@ dojo.declare("dojox.widget.RollingList",
 	
 	scrollIntoView: function(/*dijit._Widget*/ childWidget){
 		// summary: scrolls the given widget into view
-		if(this._scrollingTimeout){ 
+		if(this._scrollingTimeout){
 			window.clearTimeout(this._scrollingTimeout);
 		}
 		delete this._scrollingTimeout;
@@ -833,7 +833,7 @@ dojo.declare("dojox.widget.RollingList",
 				dojo.forEach(this.childrenAttrs, function(attr){
 					var q = {};
 					q[attr] = item;
-					store.fetch({query: q, scope: this, 
+					store.fetch({query: q, scope: this,
 						onComplete: function(items){
 							if(this._setInProgress !== value){
 								return;
@@ -850,7 +850,7 @@ dojo.declare("dojox.widget.RollingList",
 		});
 		
 		var setFromChain = dojo.hitch(this, function(/*item[]*/itemChain, /*integer*/idx){
-			// Summary: Sets the value of the widget at the given index in the chain - onchanges are not 
+			// Summary: Sets the value of the widget at the given index in the chain - onchanges are not
 			// fired here
 			var set = itemChain[idx];
 			var child = this.getChildren()[idx];
@@ -905,7 +905,7 @@ dojo.declare("dojox.widget.RollingList",
 			}
 		});
 		
-		// Only set the value in display if we are shown - if we are in a dropdown, 
+		// Only set the value in display if we are shown - if we are in a dropdown,
 		// and are hidden, don't actually do the scrolling in the display (it can
 		// mess up layouts)
 		var ns = this.domNode.style;
@@ -981,7 +981,7 @@ dojo.declare("dojox.widget.RollingList",
 				focus: function(){
 					// Do nothing on focus of this guy...
 				}
-			});	
+			});
 			this._updateClass(i.domNode, "Item");
 			return i;
 		}else{
@@ -1003,9 +1003,9 @@ dojo.declare("dojox.widget.RollingList",
 			}else{
 				widgetItem = this.getMenuItemForItem(item, parentPane, null);
 				if(itemLoaded){
-					this._updateClass(widgetItem.domNode, "Item", {"Single": true});				
+					this._updateClass(widgetItem.domNode, "Item", {"Single": true});
 				}else{
-					this._updateClass(widgetItem.domNode, "Item", {"Unloaded": true});				
+					this._updateClass(widgetItem.domNode, "Item", {"Unloaded": true});
 					widgetItem.attr("disabled", true);
 				}
 			}
@@ -1065,7 +1065,7 @@ dojo.declare("dojox.widget.RollingList",
 			try{dijit.focus(this._savedFocus);}catch(e){}
 			dojo.stopEvent(e);
 			return;
-		}else if(e.charOrCode == dojo.keys.LEFT_ARROW || 
+		}else if(e.charOrCode == dojo.keys.LEFT_ARROW ||
 			e.charOrCode == dojo.keys.RIGHT_ARROW){
 			dojo.stopEvent(e);
 			return;
@@ -1078,7 +1078,7 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_onCancel: function(){
-		// Summary: function called when the cancel button is clicked.  It 
+		// Summary: function called when the cancel button is clicked.  It
 		//		resets its value to whatever was last executed and then cancels
 		this._resetValue();
 		this.onCancel();
@@ -1128,7 +1128,7 @@ dojo.declare("dojox.widget.RollingList",
 	},
 	
 	_updateChildClasses: function(){
-		// summary: Called when a child is added or removed - so that we can 
+		// summary: Called when a child is added or removed - so that we can
 		//	update the classes for styling the "current" one differently than
 		//	the others
 		var children = this.getChildren();
@@ -1148,7 +1148,7 @@ dojo.declare("dojox.widget.RollingList",
 		this.connect(this, "addChild", "_updateChildClasses");
 		this.connect(this, "removeChild", "_updateChildClasses");
 		this._setStore(this.store);
-		this.set("showButtons", this.showButtons);	
+		this.set("showButtons", this.showButtons);
 		this.inherited(arguments);
 		this._lastExecutedValue = this.get("value");
 	},
@@ -1176,7 +1176,7 @@ dojo.declare("dojox.widget.RollingList",
 		//  to the given item in the store.  It can return null to not add a new pane
 		//  (ie, you are planning on doing something else with it in onItemClick)
 		//
-		//  Item is undefined for the root pane, children is undefined for non-group panes 
+		//  Item is undefined for the root pane, children is undefined for non-group panes
 		if(!item || children){
 			return new dojox.widget._RollingListGroupPane({});
 		}else{
diff --git a/dojox/widget/SortList.js b/dojox/widget/SortList.js
index 25b5475..6d53bde 100644
--- a/dojox/widget/SortList.js
+++ b/dojox/widget/SortList.js
@@ -9,20 +9,20 @@ dojo.declare("dojox.widget.SortList",
 	{
 	// summary: A sortable unordered-list with a fixed header for use in dijit.demos.chat
 	//		for demonstration purposes only for now. feel free to make API suggestions
-	//		or fixes. 
+	//		or fixes.
 	//
-	// title: String 
+	// title: String
 	//		The title in the header
 	title: "",
 	
 	// heading: String
-	//		In the event a parent container is expecting a title="" attribute, set it for the parent 
-	//		via title, and the title of this widget via heading="" ... assuming you want different 
-	//		titles for each. eg: TabContainer, AccordionContainer, etc. 
+	//		In the event a parent container is expecting a title="" attribute, set it for the parent
+	//		via title, and the title of this widget via heading="" ... assuming you want different
+	//		titles for each. eg: TabContainer, AccordionContainer, etc.
 	heading: "",
 
 	// descending: Boolean
-	//		Toggle sort order based on this value. 
+	//		Toggle sort order based on this value.
 	descending: true,
 
 	// selected: Array
@@ -54,16 +54,16 @@ dojo.declare("dojox.widget.SortList",
 				onItem: dojo.hitch(this, "_addItem"),
 				onComplete: dojo.hitch(this, "onSort")
 			};
-			this.store.fetch(props);	
+			this.store.fetch(props);
 		}else{ this.onSort(); }
 		this.inherited(arguments);
 	},
 
 	startup: function(){
 		this.inherited(arguments);
-		if(this.heading){ 
-			this.setTitle(this.heading); 
-			this.title = this.heading; 
+		if(this.heading){
+			this.setTitle(this.heading);
+			this.title = this.heading;
 		}
 		// we cheat, and give the browser just enough time so we know our height
 		setTimeout(dojo.hitch(this,"resize"), 5);
@@ -73,13 +73,13 @@ dojo.declare("dojox.widget.SortList",
 	resize: function(){
 		// summary: do our additional calculations when resize() is called by or in a parent
 		this.inherited(arguments);
-		// FIXME: 
+		// FIXME:
 		// the 10 comes from the difference between the contentBox and calculated height
-		// because of badding and border extents. this shouldn't be done this way, a theme change will 
-		// break it: but we also don't want to run getComputedStyle or dojo.coords() every time resize() 
+		// because of badding and border extents. this shouldn't be done this way, a theme change will
+		// break it: but we also don't want to run getComputedStyle or dojo.coords() every time resize()
 		// is fired.
 		var offset = ((this._contentBox.h) - (dojo.style(this.titleNode,"height")))-10;
-		this.bodyWrapper.style.height = Math.abs(offset) + "px"; 
+		this.bodyWrapper.style.height = Math.abs(offset) + "px";
 	},
 	
 	onSort: function(/* Event */e){
@@ -96,20 +96,20 @@ dojo.declare("dojox.widget.SortList",
 		var i=0;
 		dojo.forEach(arr,function(item){
 			dojo[(i++) % 2 === 0 ? "addClass" : "removeClass"](item,"sortListItemOdd");
-			this.containerNode.appendChild(item); 
+			this.containerNode.appendChild(item);
 		},this);
 	},
 	
 	_set: function(/* Event */e){
-		// summary: set hover state 
+		// summary: set hover state
 		if(e.target !== this.bodyWrapper){
 			dojo.addClass(e.target,"sortListItemHover");
 		}
 	},
 
 	_unset: function(/* Event */e){
-		// summary: remove hover state (FIXME: combine with _set?) 
-		dojo.removeClass(e.target,"sortListItemHover"); 
+		// summary: remove hover state (FIXME: combine with _set?)
+		dojo.removeClass(e.target,"sortListItemHover");
 	},
 
 	_handleClick: function(/* Event */e){
@@ -144,7 +144,7 @@ dojo.declare("dojox.widget.SortList",
 	},
 
 	onChanged: function(){
-		// summary: stub function, passes the last changed item, and is fired after current state 
+		// summary: stub function, passes the last changed item, and is fired after current state
 	}
 	
 });
diff --git a/dojox/widget/Standby.js b/dojox/widget/Standby.js
index 4432115..957d9d4 100755
--- a/dojox/widget/Standby.js
+++ b/dojox/widget/Standby.js
@@ -1,25 +1,19 @@
-dojo.provide("dojox.widget.Standby");
-
-dojo.require("dojo.window");
-dojo.require("dojo.fx");
-
-dojo.require("dijit._Widget");
-dojo.require("dijit._Templated");
+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],{
 	// summary:
-	//		A widget designed to act as a Standby/Busy/Disable/Blocking widget to indicate a 
+	//		A widget designed to act as a Standby/Busy/Disable/Blocking widget to indicate a
 	//		particular DOM node is processing and cannot be clicked on at this time.
 	//		This widget uses absolute positioning to apply the overlay and image.
-	// 
-	// image:	
-	//		A URL to an image to center within the blocking overlay.  
+	//
+	// image:
+	//		A URL to an image to center within the blocking overlay.
 	//		The default is a basic spinner.
 	//
 	// imageText:
-	//		Text to set on the ALT tag of the image.  
+	//		Text to set on the ALT tag of the image.
 	//		The default is 'Please wait...'
 	//
 	// text:
@@ -31,7 +25,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 	//		Defaults to image.
 	//
 	// color:
-	//		The color to use for the translucent overlay.  
+	//		The color to use for the translucent overlay.
 	//		Text string such as: darkblue, #FE02FD, etc.
 	//
 	// duration:
@@ -41,14 +35,14 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 	// zIndex:
 	//		Control that lets you specify if the zIndex for the overlay
 	//		should be auto-computed based off parent zIndex, or should be set
-	//		to a particular value.  This is useful when you want to overlay 
+	//		to a particular value.  This is useful when you want to overlay
 	//		things in digit.Dialogs, you can specify a base zIndex to append from.
 	//		Default is 'auto'.
 
 	// templateString: [protected] String
 	//		The template string defining out the basics of the widget.  No need for an external
 	//		file.
-	templateString: 
+	templateString:
 		"<div>" +
 			"<div style=\"display: none; opacity: 0; z-index: 9999; " +
 				"position: absolute; cursor:wait;\" dojoAttachPoint=\"_underlayNode\"></div>" +
@@ -60,9 +54,9 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		"</div>",
 
 	// _underlayNode: [private] DOMNode
-	//		The node that is the translucent underlay for the 
+	//		The node that is the translucent underlay for the
 	//		image that blocks access to the target.
-	_underlayNode: null,	
+	_underlayNode: null,
 
 	// _imageNode: [private] DOMNode
 	//		The image node where we attach and define the image to display.
@@ -78,11 +72,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: dojo.moduleUrl("dojox", "widget/Standby/images/loading.gif").toString(),
 
 	// imageText: String
 	//		Text for the ALT tag.
-	imageText: "Please Wait...", 
+	imageText: "Please Wait...",
 
 	// text: String
 	//		Text/HTML to display in the center of the overlay
@@ -98,16 +92,16 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	// _displayed: [private] Boolean
 	//		Flag to indicate if the overlay is displayed or not.
-	_displayed: false, 
+	_displayed: false,
 
 	// _resizeCheck: [private] Object
 	//		Handle to interval function that checks the target for changes.
-	_resizeCheck: null, 
+	_resizeCheck: null,
 	
 	// target: DOMNode||DOMID(String)||WidgetID(String)
-	//		The target to overlay when active.  Can be a widget id, a 
+	//		The target to overlay when active.  Can be a widget id, a
 	//		dom id, or a direct node reference.
-	target: "", 
+	target: "",
 
 	// color:	String
 	//		The color to set the overlay.  Should be in #XXXXXX form.
@@ -118,7 +112,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 	//		Integer defining how long the show and hide effects should take.
 	duration: 500,
 
-	// _started: [private] Boolean 
+	// _started: [private] Boolean
 	//		Trap flag to ensure startup only processes once.
 	_started: false,
 
@@ -130,13 +124,13 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 	// zIndex: String
 	//		Control that lets you specify if the zIndex for the overlay
 	//		should be auto-computed based off parent zIndex, or should be set
-	//		to a particular value.  This is useful when you want to overlay 
+	//		to a particular value.  This is useful when you want to overlay
 	//		things in digit.Dialogs, you can specify a base zIndex to append from.
 	zIndex: "auto",
 
 	startup: function(args){
 		// summary:
-		//		Over-ride of the basic widget startup function.  
+		//		Over-ride of the basic widget startup function.
 		//		Configures the target node and sets the image to use.
 		if(!this._started){
 			if(typeof this.target === "string"){
@@ -165,9 +159,9 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			dojo.style(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.  
+			//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);
 			}
@@ -191,6 +185,10 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		// summary:
 		//		Function to display the blocking overlay and busy/status icon or text.
 		if(!this._displayed){
+			if(this._anim){
+				this._anim.stop();
+				delete this._anim;
+			}
 			this._displayed = true;
 			this._size();
 			this._disableOverflow();
@@ -202,6 +200,10 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		// summary:
 		//		Function to hide the blocking overlay and status icon or text.
 		if(this._displayed){
+			if(this._anim){
+				this._anim.stop();
+				delete this._anim;
+			}
 			this._size();
 			this._fadeOut();
 			this._displayed = false;
@@ -231,7 +233,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 	},
 
 	uninitialize: function(){
-		// summary:	
+		// summary:
 		//		Over-ride to hide the widget, which clears intervals, before cleanup.
 		this._displayed = false;
 		if(this._resizeCheck){
@@ -243,6 +245,10 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			dojo.body().removeChild(this._ieFixNode);
 			delete this._ieFixNode;
 		}
+		if(this._anim){
+			this._anim.stop();
+			delete this._anim;
+		}
 		this.target = null;
 		this._imageNode = null;
 		this._textNode = null;
@@ -252,7 +258,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	_size: function(){
 		// summary:
-		//		Internal function that handles resizing the overlay and 
+		//		Internal function that handles resizing the overlay and
 		//		centering of the image on window resizing.
 		// tags:
 		//		private
@@ -265,7 +271,7 @@ 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"); 
+			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){
@@ -278,7 +284,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			var cntrIndicator = dojo.marginBox(this._centerNode);
 			dojo.style(this._centerNode, "display", curStyle);
 
-			//IE has a horrible zoom bug.  So, we have to try and account for 
+			//IE has a horrible zoom bug.  So, we have to try and account for
 			//it and fix up the scaling.
 			if(this._ieFixNode){
 				_ie7zoom = -this._ieFixNode.offsetTop / 1000;
@@ -328,15 +334,15 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 
 			var pn = target.parentNode;
-			if(pn && pn !== dojo.body() && 
-				target !== dojo.body() && 
+			if(pn && pn !== dojo.body() &&
+				target !== dojo.body() &&
 				target !== dojo.doc){
 				
 				// If the parent is the body tag itself,
-				// we can avoid all this, the body takes 
+				// we can avoid all this, the body takes
 				// care of overflow for me.  Besides, browser
-				// weirdness with height and width on body causes 
-				// problems with this sort of intersect testing 
+				// weirdness with height and width on body causes
+				// problems with this sort of intersect testing
 				// anyway.
 				var obh = box.h;
 				var obw = box.w;
@@ -352,29 +358,29 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				}
 				
 				//Shift the parent width/height a bit if scollers are present.
-				pnBox.w -= pn.scrollHeight > pn.clientHeight && 
+				pnBox.w -= pn.scrollHeight > pn.clientHeight &&
 					pn.clientHeight > 0 ? scrollers.v: 0;
-				pnBox.h -= pn.scrollWidth > pn.clientWidth && 
+				pnBox.h -= pn.scrollWidth > pn.clientWidth &&
 					pn.clientWidth > 0 ? scrollers.h: 0;
 
-				//RTL requires a bit of massaging in some cases 
+				//RTL requires a bit of massaging in some cases
 				//(and differently depending on browser, ugh!)
 				//WebKit and others still need work.
 				if(dir === "rtl"){
 					if(dojo.isOpera){
-						box.x += pn.scrollHeight > pn.clientHeight && 
+						box.x += pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0 ? scrollers.v: 0;
-						pnBox.x += pn.scrollHeight > pn.clientHeight && 
+						pnBox.x += pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0 ? scrollers.v: 0;
 					}else if(dojo.isIE){
-						pnBox.x += pn.scrollHeight > pn.clientHeight && 
+						pnBox.x += pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0 ? scrollers.v: 0;
 					}else if(dojo.isWebKit){
 						//TODO:  FIX THIS!
 					}
 				}
 
-				//Figure out if we need to adjust the overlay to fit a viewable 
+				//Figure out if we need to adjust the overlay to fit a viewable
 				//area, then resize it, we saved the original height/width above.
 				//This is causing issues on IE.  Argh!
 				if(pnBox.w < box.w){
@@ -398,23 +404,23 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 				var bRight = box.x + obw;
 				var delta;
 				//Adjust the height now
-				if(bBottom > vpTop && 
+				if(bBottom > vpTop &&
 					bTop < vpTop){
 					box.y = pnBox.y;
 					//intersecting top, need to do some shifting.
 					delta = vpTop - bTop;
 					var visHeight = obh - delta;
-					//If the visible height < viewport height, 
+					//If the visible height < viewport height,
 					//We need to shift it.
 					if(visHeight < pnBox.h){
 						box.h = visHeight;
 					}else{
 						//Deal with horizontal scrollbars if necessary.
-						box.h -= 2*(pn.scrollWidth > pn.clientWidth && 
+						box.h -= 2*(pn.scrollWidth > pn.clientWidth &&
 							pn.clientWidth > 0? scrollers.h: 0);
 					}
 				}else if(bTop < vpBottom && bBottom > vpBottom){
-					//Intersecting bottom, just figure out how much 
+					//Intersecting bottom, just figure out how much
 					//overlay to show.
 					box.h = vpBottom - bTop;
 				}else if(bBottom <= vpTop || bTop >= vpBottom){
@@ -428,17 +434,17 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 					//intersecting left, need to do some shifting.
 					delta = vpLeft - bLeft;
 					var visWidth = obw - delta;
-					//If the visible width < viewport width, 
+					//If the visible width < viewport width,
 					//We need to shift it.
 					if(visWidth < pnBox.w){
 						box.w = visWidth;
 					}else{
 						//Deal with horizontal scrollbars if necessary.
-						box.w -= 2*(pn.scrollHeight > pn.clientHeight && 
+						box.w -= 2*(pn.scrollHeight > pn.clientHeight &&
 							pn.clientHeight > 0? scrollers.w:0);
 					}
 				}else if(bLeft < vpRight && bRight > vpRight){
-					//Intersecting right, just figure out how much 
+					//Intersecting right, just figure out how much
 					//overlay to show.
 					box.w = vpRight - bLeft;
 				}else if(bRight <= vpLeft || bLeft >= vpRight){
@@ -457,16 +463,16 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 					left: box.x + "px"
 				});
 
-				var styles = ["borderRadius", "borderTopLeftRadius", 
-					"borderTopRightRadius","borderBottomLeftRadius", 
+				var styles = ["borderRadius", "borderTopLeftRadius",
+					"borderTopRightRadius","borderBottomLeftRadius",
 					"borderBottomRightRadius"];
 				this._cloneStyles(styles);
 				if(!dojo.isIE){
 					//Browser specific styles to try and clone if non-IE.
-					styles = ["MozBorderRadius", "MozBorderRadiusTopleft", 
-						"MozBorderRadiusTopright","MozBorderRadiusBottomleft", 
-						"MozBorderRadiusBottomright","WebkitBorderRadius", 
-						"WebkitBorderTopLeftRadius", "WebkitBorderTopRightRadius", 
+					styles = ["MozBorderRadius", "MozBorderRadiusTopleft",
+						"MozBorderRadiusTopright","MozBorderRadiusBottomleft",
+						"MozBorderRadiusBottomright","WebkitBorderRadius",
+						"WebkitBorderTopLeftRadius", "WebkitBorderTopRightRadius",
 						"WebkitBorderBottomLeftRadius","WebkitBorderBottomRightRadius"
 					];
 					this._cloneStyles(styles, this);
@@ -499,7 +505,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	_cloneStyles: function(list){
 		// summary:
-		//		Internal function to clone a set of styles from the target to 
+		//		Internal function to clone a set of styles from the target to
 		//		the underlay.
 		// list: Array
 		//		An array of style names to clone.
@@ -519,19 +525,20 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		var self = this;
 		var underlayNodeAnim = dojo.animateProperty({
 			duration: self.duration,
-			node: self._underlayNode, 
+			node: self._underlayNode,
 			properties: {opacity: {start: 0, end: 0.75}}
 		});
 		var imageAnim = dojo.animateProperty({
 			duration: self.duration,
-			node: self._centerNode, 
+			node: self._centerNode,
 			properties: {opacity: {start: 0, end: 1}},
 			onEnd: function(){
 				self.onShow();
+				delete self._anim;
 			}
 		});
-		var anim = dojo.fx.combine([underlayNodeAnim,imageAnim]);
-		anim.play();
+		this._anim = dojo.fx.combine([underlayNodeAnim,imageAnim]);
+		this._anim.play();
 	},
 
 	_fadeOut: function(){
@@ -542,7 +549,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		var self = this;
 		var underlayNodeAnim = dojo.animateProperty({
 			duration: self.duration,
-			node: self._underlayNode, 
+			node: self._underlayNode,
 			properties: {opacity: {start: 0.75, end: 0}},
 			onEnd: function(){
 				dojo.style(this.node,{"display":"none", "zIndex": "-1000"});
@@ -550,16 +557,17 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		});
 		var imageAnim = dojo.animateProperty({
 			duration: self.duration,
-			node: self._centerNode, 
+			node: self._centerNode,
 			properties: {opacity: {start: 1, end: 0}},
 			onEnd: function(){
 				dojo.style(this.node,{"display":"none", "zIndex": "-1000"});
 				self.onHide();
 				self._enableOverflow();
+				delete self._anim;
 			}
 		});
-		var anim = dojo.fx.combine([underlayNodeAnim,imageAnim]);
-		anim.play();
+		this._anim = dojo.fx.combine([underlayNodeAnim,imageAnim]);
+		this._anim.play();
 	},
 
 	_ignore: function(event){
@@ -604,8 +612,8 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 		div.appendChild(iDiv);
 		dojo.body().appendChild(div);
 
-		//Figure out content size before and after 
-		//scrollbars are there, then just subtract to 
+		//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");
@@ -618,7 +626,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	_setTextAttr: function(text){
 		// summary:
-		//		Function to allow widget.attr to set the text displayed in center 
+		//		Function to allow widget.attr to set the text displayed in center
 		//		if using text display.
 		// text: String
 		//		The text to set.
@@ -673,7 +681,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	_disableOverflow: function(){
 		 // summary:
-		 //		Function to disable scrollbars on the body.  Only used if the overlay 
+		 //		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){
 			 // Store the overflow state we have to restore later.
@@ -687,10 +695,10 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			 }
 			 if(dojo.isIE && !dojo.isQuirks){
 				 // IE will put scrollbars in anyway, html (parent of body)
-				 // also controls them in standards mode, so we have to 
+				 // also controls them in standards mode, so we have to
 				 // remove them, argh.
-				 if(body.parentNode && 
-					body.parentNode.style && 
+				 if(body.parentNode &&
+					body.parentNode.style &&
 					body.parentNode.style.overflow){
 					 this._oldBodyParentOverflow = body.parentNode.style.overflow;
 				 }else{
@@ -708,7 +716,7 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 
 	_enableOverflow: function(){
 		 // summary:
-		 //		Function to restore scrollbars on the body.  Only used if the overlay 
+		 //		Function to restore scrollbars on the body.  Only used if the overlay
 		 //		targets the body or the document.
 		 if(this._overflowDisabled){
 			delete this._overflowDisabled;
@@ -733,4 +741,8 @@ dojo.declare("dojox.widget.Standby",[dijit._Widget, dijit._Templated],{
 			delete this._oldOverflow;
 		}
 	}
-});	
+});
+
+return dojox.widget.Standby;
+
+});
diff --git a/dojox/widget/TitleGroup.js b/dojox/widget/TitleGroup.js
new file mode 100644
index 0000000..96461e3
--- /dev/null
+++ b/dojox/widget/TitleGroup.js
@@ -0,0 +1,87 @@
+dojo.provide("dojox.widget.TitleGroup");
+
+dojo.require("dijit._Widget");
+dojo.require("dijit.TitlePane");
+
+(function(d){
+	
+	var tp = dijit.TitlePane.prototype,
+		lookup = function(){
+			// generic handler function for click and keypress
+			var parent = this._dxfindParent && this._dxfindParent();
+			parent && parent.selectChild(this);
+		}
+	;
+	
+	// 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
+		var n = this.domNode.parentNode;
+		if(n){
+			n = dijit.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){
+		// 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)){
+			lookup.apply(this, arguments);
+		}
+	});
+		
+	d.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
+		//
+		// description:
+		//		A container which controls a series of `dijit.TitlePane`s,
+		//		allowing one to be visible and hiding siblings. Behaves similarly
+		//		to a `dijit.layout.AccordionContainer` in that the children
+		//		are all stacked, though merges the TitlePane behavior of
+		//		variable height
+		//
+		// example:
+		//	|	var group = new dojox.widget.TitleGroup().placeAt(dojo.body());
+		//	|	new dijit.TitlePane({ title:"One" }, "fromsource").placeAt(group);
+		//	|	new dijit.TitlePane({ title:"Remote", href:"foo.html" }).placeAt(group);
+		
+		"class":"dojoxTitleGroup",
+
+		addChild: function(widget, position){
+			// summary: Add a passed widget reference to this container at an optional
+			//		position index.
+			//
+			// widget: dijit.TitlePane
+			//		A widget reference to add
+			// position: String?|Int?
+			//		An optional index or position to pass. defaults to "last"
+			return widget.placeAt(this.domNode, position); // dijit.TitlePane
+		},
+		
+		removeChild: function(widget){
+			// summary: Remove the passed widget from this container. Does not destroy
+			//		child.
+			
+			this.domNode.removeChild(widget.domNode);
+			return widget;
+		},
+		
+		selectChild: function(widget){
+			// 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);
+			});
+			return widget; // dijit.TitlePane
+		}
+	
+	});
+
+})(dojo);
diff --git a/dojox/widget/TitleGroup/TitleGroup.css b/dojox/widget/TitleGroup/TitleGroup.css
new file mode 100644
index 0000000..e8c3fb3
--- /dev/null
+++ b/dojox/widget/TitleGroup/TitleGroup.css
@@ -0,0 +1,28 @@
+/* tundra doesn't appear to need any special css rules */
+
+.claro .dojoxTitleGroup .dijitTitlePaneContentOuter {
+    border-bottom:none;
+}
+
+.claro .dojoxTitleGroup .dijitTitlePaneContentOuter .dijitTitlePaneContentOuter,
+.claro .dojoxTitleGroup {
+    border-bottom:1px solid #B5BCC7;
+}
+
+.soria .dojoxTitleGroup .dijitTitlePaneContentOuter {
+    border-bottom:none;
+}
+
+.soria .dojoxTitleGroup .dijitTitlePaneContentOuter .dijitTitlePaneContentOuter,
+.soria .dojoxTitleGroup {
+    border-bottom:1px solid #BFBFBF;
+}
+
+.nihilo .dojoxTitleGroup .dijitTitlePaneContentOuter {
+    border-bottom:none;
+}
+
+.nihilo .dojoxTitleGroup .dijitTitlePaneContentOuter .dijitTitlePaneContentOuter,
+.nihilo .dojoxTitleGroup {
+    border-bottom:1px solid #BFBFBF;
+}
diff --git a/dojox/widget/Toaster.js b/dojox/widget/Toaster.js
index c2fa25f..634b5ae 100644
--- a/dojox/widget/Toaster.js
+++ b/dojox/widget/Toaster.js
@@ -48,7 +48,7 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 		duration: 2000,
 
 		// slideDuration: Integer
-		//		Number of milliseconds for the slide animation, increasing will cause the Toaster 
+		//		Number of milliseconds for the slide animation, increasing will cause the Toaster
 		//    to slide in more slowly.
 		slideDuration: 500,
 
@@ -121,7 +121,7 @@ dojo.declare("dojox.widget.Toaster", [dijit._Widget, dijit._Templated], {
 			this._cancelHideTimer();
 			if(this.isVisible){
 				this._placeClip();
-				//update hide timer if no sticky message in stack 
+				//update hide timer if no sticky message in stack
 				if(!this._stickyMessage) {
 					this._setHideTimer(duration);
 				}
diff --git a/dojox/widget/Wizard.js b/dojox/widget/Wizard.js
index 2e2cb5f..11c3b3e 100644
--- a/dojox/widget/Wizard.js
+++ b/dojox/widget/Wizard.js
@@ -4,14 +4,11 @@ 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],
-	{
+dojo.require("dojo.i18n");
+dojo.requireLocalization("dijit", "common");
+dojo.requireLocalization("dojox.widget", "Wizard");
+
+dojo.declare("dojox.widget.Wizard", [dijit.layout.StackContainer, dijit._Templated], {
 	// summary:
 	//		A set of panels that display sequentially, typically notating a step-by-step
 	//		procedure like an install
@@ -59,9 +56,9 @@ dojo.declare(
 	},
 
 	startup: function(){
-		if(this._started){ 
-			//console.log('started'); 
-			return; 
+		if(this._started){
+			//console.log('started');
+			return;
 		}
 		this.inherited(arguments);
 		
@@ -79,10 +76,14 @@ dojo.declare(
 		this.connect(this.doneButton, "onClick", "done");
 
 		this._subscription = dojo.subscribe(this.id + "-selectChild", dojo.hitch(this,"_checkButtons"));
-		this._checkButtons();
 		this._started = true;
 		
 	},
+	
+	resize: function(){
+		this.inherited(arguments);
+		this._checkButtons();
+	},
 
 	_checkButtons: function(){
 		
@@ -106,7 +107,7 @@ dojo.declare(
 	},
 
 	_setButtonClass: function(button){
-		button.domNode.style.display = (this.hideDisabled && button.disabled) ? "none" : "";	
+		button.domNode.style.display = (this.hideDisabled && button.disabled) ? "none" : "";
 	},
 
 	_forward: function(){
@@ -128,15 +129,13 @@ dojo.declare(
 	
 });
 
-dojo.declare("dojox.widget.WizardPane",
-	dijit.layout.ContentPane,
-	{
+dojo.declare("dojox.widget.WizardPane", dijit.layout.ContentPane, {
 	// summary: A panel in a `dojox.widget.Wizard`
 	//
 	// description:
 	//	An extended ContentPane with additional hooks for passing named
 	//	functions to prevent the pane from going either forward or
-	//	backwards. 
+	//	backwards.
 	//
 	// canGoBack: Boolean
 	//		If true, then can move back to a previous panel (by clicking the "Previous" button)
@@ -145,7 +144,8 @@ dojo.declare("dojox.widget.WizardPane",
 	// passFunction: String
 	//		Name of function that checks if it's OK to advance to the next panel.
 	//		If it's not OK (for example, mandatory field hasn't been entered), then
-	//		returns an error message (String) explaining the reason.
+	//		returns an error message (String) explaining the reason. Can return null (pass)
+	//		or a Boolean (true == pass)
 	passFunction: null,
 	
 	// doneFunction: String
diff --git a/dojox/widget/Wizard/Wizard.css b/dojox/widget/Wizard/Wizard.css
index d760993..cf354a7 100644
--- a/dojox/widget/Wizard/Wizard.css
+++ b/dojox/widget/Wizard/Wizard.css
@@ -5,23 +5,53 @@
 .dojoxWizardButtons {
 	position:absolute;
 	bottom:5px;
-	right:5px;	
+	right:5px;
+}
+
+/* allot room for the buttons. never let a child overlap */
+.dojoxWizardContainer > * {
+	margin-bottom:39px;
 }
 
 .tundra .dojoxWizard {
 	background: #eeeeee;
 	border: #b7b7b7 1px solid;
 	padding: 2px;
+	border-radius:3pt;
 	-moz-border-radius:3pt;
 	-webkit-border-radius:4pt;
+	-o-border-radius:4pt;
+	-ms-border-radius:4pt;
 }
 
 .soria .dojoxWizard {
 	border:1px solid #b7b7b7;
 	padding:2px;
+	border-radius:3pt;
+	-moz-border-radius:3pt;
+	-webkit-border-radius:4pt;
+	-o-border-radius:4pt;
+	-ms-border-radius:4pt;
 }
 
 .claro .dojoxWizard {
-    border:1px solid #b5bcc7;
-    padding:2px;
+	border:1px solid #b5bcc7;
+	padding:2px;
+	border-radius:3pt;
+	-moz-border-radius:3pt;
+	-webkit-border-radius:4pt;
+	-o-border-radius:4pt;
+	-ms-border-radius:4pt;
+}
+
+/* remove the border and padding when we're in a dialog, it wraps us */
+.tundra .dijitDialogSingleChild .dojoxWizard, 
+.soria .dijitDialogSingleChild .dojoxWizard, 
+.claro .dijitDialogSingleChild .dojoxWizard {
+	border:none;
+	padding:0;
+}
+
+.claro .dijitDialogSingleChild .dojoxWizardButtons {
+	bottom:1px;
 }
\ No newline at end of file
diff --git a/dojox/widget/gauge/AnalogArcIndicator.js b/dojox/widget/gauge/AnalogArcIndicator.js
index e124c77..d485a0a 100644
--- a/dojox/widget/gauge/AnalogArcIndicator.js
+++ b/dojox/widget/gauge/AnalogArcIndicator.js
@@ -6,7 +6,7 @@ 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 
+		// 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));
@@ -33,7 +33,7 @@ dojo.declare("dojox.widget.gauge.AnalogArcIndicator",[dojox.widget.gauge.AnalogL
 		}
 	},
 	draw: function(/*Boolean?*/ dontAnimate){
-		// summary: 
+		// summary:
 		//		Override of dojox.widget._Indicator.draw
 		var v = this.value;
 		if(v < this._gauge.min){v = this._gauge.min;}
diff --git a/dojox/widget/gauge/AnalogArrowIndicator.js b/dojox/widget/gauge/AnalogArrowIndicator.js
index 4e6d00d..ea1a02f 100644
--- a/dojox/widget/gauge/AnalogArrowIndicator.js
+++ b/dojox/widget/gauge/AnalogArrowIndicator.js
@@ -5,7 +5,7 @@ dojo.experimental("dojox.widget.gauge.AnalogArrowIndicator");
 
 dojo.declare("dojox.widget.gauge.AnalogArrowIndicator",[dojox.widget.gauge.AnalogLineIndicator],{
 	_getShapes: function(){
-		// summary: 
+		// summary:
 		//		Override of dojox.widget.AnalogLineIndicator._getShapes
 		if(!this._gauge){
 			return null;
diff --git a/dojox/widget/gauge/AnalogNeedleIndicator.js b/dojox/widget/gauge/AnalogNeedleIndicator.js
index 4a139d3..59c9e9e 100644
--- a/dojox/widget/gauge/AnalogNeedleIndicator.js
+++ b/dojox/widget/gauge/AnalogNeedleIndicator.js
@@ -5,7 +5,7 @@ dojo.experimental("dojox.widget.gauge.AnalogNeedleIndicator");
 
 dojo.declare("dojox.widget.gauge.AnalogNeedleIndicator",[dojox.widget.gauge.AnalogLineIndicator],{
 	_getShapes: function(){
-		// summary: 
+		// summary:
 		//		Override of dojox.widget.AnalogLineIndicator._getShapes
 		if(!this._gauge){
 			return null;
diff --git a/dojox/widget/gauge/BarIndicator.js b/dojox/widget/gauge/BarIndicator.js
index 2a5f3e6..fd837de 100644
--- a/dojox/widget/gauge/BarIndicator.js
+++ b/dojox/widget/gauge/BarIndicator.js
@@ -64,7 +64,7 @@ dojo.declare("dojox.widget.gauge.BarIndicator",[dojox.widget.gauge.BarLineIndica
 		}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)); 
+				dojo.connect(anim, "onAnimate", dojo.hitch(this, this._createShapes));
 				anim.play();
 			}
 		}
diff --git a/dojox/widget/gauge/_Gauge.js b/dojox/widget/gauge/_Gauge.js
index 5ecc4f9..75558bc 100644
--- a/dojox/widget/gauge/_Gauge.js
+++ b/dojox/widget/gauge/_Gauge.js
@@ -16,7 +16,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 	//
 	// 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 
+	//		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
@@ -53,7 +53,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 	// 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 
+	// this value should be the number of dojoxGaugeRange classes that are
 	// defined, starting at dojoxGaugeRange1 (0 indicates falling to default
 	// hardcoded colors)
 	useRangeStyles: 0,
@@ -81,7 +81,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 
 	// _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 
+	// This object is used as the indicator when creating tick marks or when an anonmyous object is passed into
 	// addIndicator.
 	_defaultIndicator: null,
 
@@ -110,7 +110,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 	surface: null,
 
 	// hideValues: Boolean
-	// indicates whether the text boxes showing the value of the indicator (as text 
+	// 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,
 
@@ -176,7 +176,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 	},
 
 	_setTicks: function(/*Object*/ oldTicks, /*Object*/ newTicks, /*Boolean*/ label){
-		// summary: 
+		// summary:
 		//		internal method used to clear existing tick marks, then add new ones
 		var i;
 		if(oldTicks && dojo.isArray(oldTicks._ticks)){
@@ -184,7 +184,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 				this.removeIndicator(oldTicks._ticks[i]);
 			}
 		}
-		var t = {length: newTicks.length, 
+		var t = {length: newTicks.length,
 					offset: newTicks.offset,
 					noChange: true};
 		if(newTicks.color){ t.color = newTicks.color; }
@@ -250,7 +250,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 		// 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 
+		//		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:
@@ -280,12 +280,12 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 		// summary:
 		//		This method is used to add ranges to the gauge.
 		// description:
-		//		Creates a range (colored area on the background of the gauge) 
+		//		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 
+		//		A range is either a dojox.widget.gauge.Range object, or a object
 		//		with similar parameters (low, high, hover, etc.).
-		if(!this._rangeData){ 
+		if(!this._rangeData){
 			this._rangeData = [];
 		}
 		var range;
@@ -335,7 +335,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 
 	removeIndicator: function(/*Object*/indicator){
 		// summary:
-		//		Removes the given indicator from the gauge by calling it's remove function 
+		//		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){
@@ -403,7 +403,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 		// txt:		String
 		//			The text to put in the tooltip.
 		if(this._lastHover != txt){
-			if(txt !== ''){ 
+			if(txt !== ''){
 				dijit.hideTooltip(this.mouseNode);
 				dijit.showTooltip(txt,this.mouseNode, !this.isLeftToRight());
 			}else{
@@ -415,7 +415,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 
 	handleMouseOver: function(/*Object*/event){
 		// summary:
-		//		This is an internal handler used by the gauge to support 
+		//		This is an internal handler used by the gauge to support
 		//		hover text
 		// event:	Object
 		//			The event object
@@ -438,7 +438,7 @@ dojo.declare("dojox.widget.gauge._Gauge",[dijit._Widget, dijit._Templated, dijit
 
 	handleMouseOut: function(/*Object*/event){
 		// summary:
-		//		This is an internal handler used by the gauge to support 
+		//		This is an internal handler used by the gauge to support
 		//		hover text
 		// event:	Object
 		//			The event object
@@ -545,7 +545,7 @@ dojo.declare("dojox.widget.gauge.Range",[dijit._Widget, dijit._Contained],{
 	//		</div>
 	
 	// low: Number
-	// the low value of the range 
+	// the low value of the range
 	low: 0,
 	
 	// high: Numbe
@@ -565,7 +565,7 @@ dojo.declare("dojox.widget.gauge.Range",[dijit._Widget, dijit._Contained],{
 	color: null,
 	
 	// size: Number
-	// for a circular gauge (such as an AnalogGauge), this dictates the size of the arc 
+	// for a circular gauge (such as an AnalogGauge), this dictates the size of the arc
 	size: 0,
 
 	startup: function(){
@@ -578,7 +578,7 @@ dojo.declare("dojox.widget.gauge._Indicator",[dijit._Widget, dijit._Contained, d
 	//		a indicator to be used in a gauge
 	//
 	// description:
-	//		an indicator widget, which has given properties.  drawn by a gauge. 
+	//		an indicator widget, which has given properties.  drawn by a gauge.
 	//
 	// usage:
 	//		<script type="text/javascript">
@@ -666,12 +666,12 @@ dojo.declare("dojox.widget.gauge._Indicator",[dijit._Widget, dijit._Contained, d
 	duration: 1000,
 
 	// hideValues: Boolean
-	// indicates whether the text boxes showing the value of the indicator (as text 
+	// 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 
+	// 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,
 
@@ -720,7 +720,7 @@ dojo.declare("dojox.widget.gauge._Indicator",[dijit._Widget, dijit._Contained, d
 
 	update: function(value){
 		// summary:
-		//		Updates the value of the indicator, including moving/re-drawing at it's new location and 
+		//		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;
diff --git a/dojox/widget/nls/ar/ColorPicker.js b/dojox/widget/nls/ar/ColorPicker.js
index 1fe2a1b..1caa8fa 100644
--- a/dojox/widget/nls/ar/ColorPicker.js
+++ b/dojox/widget/nls/ar/ColorPicker.js
@@ -1,3 +1,5 @@
 ({
+huePickerTitle: "محدد تدرج اللون",
+saturationPickerTitle: "محدد درجة التشبع"
 })
 
diff --git a/dojox/widget/nls/ar/FilePicker.js b/dojox/widget/nls/ar/FilePicker.js
index e878525..6329f21 100644
--- a/dojox/widget/nls/ar/FilePicker.js
+++ b/dojox/widget/nls/ar/FilePicker.js
@@ -1,5 +1,6 @@
 ({
 name: "الاسم",
 path: "‏المسار‏",
-size: "الحجم (بالبايت) "
+size: "الحجم (بالبايت)"
 })
+
diff --git a/dojox/widget/nls/ar/Wizard.js b/dojox/widget/nls/ar/Wizard.js
index 3138965..0c950c2 100644
--- a/dojox/widget/nls/ar/Wizard.js
+++ b/dojox/widget/nls/ar/Wizard.js
@@ -3,3 +3,4 @@ next: "تالي",
 previous: "‏سابق‏",
 done: "اتمام"
 })
+
diff --git a/dojox/widget/nls/ca/ColorPicker.js b/dojox/widget/nls/ca/ColorPicker.js
index e1b7023..7e4781e 100644
--- a/dojox/widget/nls/ca/ColorPicker.js
+++ b/dojox/widget/nls/ca/ColorPicker.js
@@ -1,6 +1,7 @@
 ({
 redLabel: "v",
 greenLabel: "e",
-hueLabel: "m"
+hueLabel: "m",
+huePickerTitle: "Selector de matís",
+saturationPickerTitle: "Selector de saturació"
 })
-
diff --git a/dojox/widget/nls/cs/ColorPicker.js b/dojox/widget/nls/cs/ColorPicker.js
index 0add331..b1a8c8f 100644
--- a/dojox/widget/nls/cs/ColorPicker.js
+++ b/dojox/widget/nls/cs/ColorPicker.js
@@ -5,6 +5,7 @@ blueLabel: "m",
 hueLabel: "o",
 saturationLabel: "n",
 valueLabel: "j", /* aka intensity or brightness */
-hexLabel: "hex"
+huePickerTitle: "Selektor odstínu",
+saturationPickerTitle: "Selektor sytosti"
 })
 
diff --git a/dojox/widget/nls/da/ColorPicker.js b/dojox/widget/nls/da/ColorPicker.js
index 1fe2a1b..e8e45b7 100644
--- a/dojox/widget/nls/da/ColorPicker.js
+++ b/dojox/widget/nls/da/ColorPicker.js
@@ -1,3 +1,5 @@
 ({
+huePickerTitle: "Vælg nuance",
+saturationPickerTitle: "Vælg mætning"
 })
 
diff --git a/dojox/widget/nls/de/ColorPicker.js b/dojox/widget/nls/de/ColorPicker.js
index 1fe2a1b..6417219 100644
--- a/dojox/widget/nls/de/ColorPicker.js
+++ b/dojox/widget/nls/de/ColorPicker.js
@@ -1,3 +1,5 @@
 ({
+huePickerTitle: "Farbtonauswahl",
+saturationPickerTitle: "Sättigungsauswahl"
 })
 
diff --git a/dojox/widget/nls/el/ColorPicker.js b/dojox/widget/nls/el/ColorPicker.js
index 1604f9f..bbf09ce 100644
--- a/dojox/widget/nls/el/ColorPicker.js
+++ b/dojox/widget/nls/el/ColorPicker.js
@@ -5,6 +5,8 @@ blueLabel: "μ",
 hueLabel: "α",
 saturationLabel: "κ",
 valueLabel: "τ", /* aka intensity or brightness */
-hexLabel: "16-αδικό"
+hexLabel: "16-αδικό",
+huePickerTitle: "Επιλογή απόχρωσης",
+saturationPickerTitle: "Επιλογή κορεσμού"
 })
 
diff --git a/dojox/widget/nls/es/ColorPicker.js b/dojox/widget/nls/es/ColorPicker.js
index 1fe2a1b..45d64d9 100644
--- a/dojox/widget/nls/es/ColorPicker.js
+++ b/dojox/widget/nls/es/ColorPicker.js
@@ -1,3 +1,8 @@
 ({
+greenLabel: "v",
+blueLabel: "a",
+hueLabel: "m",
+huePickerTitle: "Selector de tono",
+saturationPickerTitle: "Selector de saturación"
 })
 
diff --git a/dojox/widget/nls/fi/ColorPicker.js b/dojox/widget/nls/fi/ColorPicker.js
index 1fe2a1b..b501a12 100644
--- a/dojox/widget/nls/fi/ColorPicker.js
+++ b/dojox/widget/nls/fi/ColorPicker.js
@@ -1,3 +1,5 @@
 ({
+huePickerTitle: "Sävyn valitsin",
+saturationPickerTitle: "Kylläisyyden valitsin"
 })
 
diff --git a/dojox/widget/nls/fr/ColorPicker.js b/dojox/widget/nls/fr/ColorPicker.js
index 4c68c9c..c2c9087 100644
--- a/dojox/widget/nls/fr/ColorPicker.js
+++ b/dojox/widget/nls/fr/ColorPicker.js
@@ -1,10 +1,7 @@
 ({
-redLabel: "r",
 greenLabel: "v",
-blueLabel: "b",
 hueLabel: "t",
-saturationLabel: "s",
-valueLabel: "v", /* aka intensity or brightness */
-hexLabel: "hex"
+huePickerTitle: "Sélecteur de teinte",
+saturationPickerTitle: "Sélecteur de saturation"
 })
 
diff --git a/dojox/widget/nls/he/ColorPicker.js b/dojox/widget/nls/he/ColorPicker.js
index 91685a1..cc469c1 100644
--- a/dojox/widget/nls/he/ColorPicker.js
+++ b/dojox/widget/nls/he/ColorPicker.js
@@ -5,6 +5,9 @@ blueLabel: "כ",
 hueLabel: "ג",
 saturationLabel: "ר",
 valueLabel: "ע", /* aka intensity or brightness */
-hexLabel: "הקס"
+degLabel: "\u00B0",
+hexLabel: "הקס",
+huePickerTitle: "בורר גוון",
+saturationPickerTitle: "בורר רוויה"
 })
 
diff --git a/dojox/widget/nls/hu/ColorPicker.js b/dojox/widget/nls/hu/ColorPicker.js
index 1fe2a1b..1cd6930 100644
--- a/dojox/widget/nls/hu/ColorPicker.js
+++ b/dojox/widget/nls/hu/ColorPicker.js
@@ -1,3 +1,5 @@
 ({
+huePickerTitle: "Árnyalat kiválasztó",
+saturationPickerTitle: "Telítettség kiválasztó"
 })
 
diff --git a/dojox/widget/nls/it/ColorPicker.js b/dojox/widget/nls/it/ColorPicker.js
index 4c68c9c..d43606c 100644
--- a/dojox/widget/nls/it/ColorPicker.js
+++ b/dojox/widget/nls/it/ColorPicker.js
@@ -1,10 +1,5 @@
 ({
-redLabel: "r",
-greenLabel: "v",
-blueLabel: "b",
-hueLabel: "t",
-saturationLabel: "s",
-valueLabel: "v", /* aka intensity or brightness */
-hexLabel: "hex"
+huePickerTitle: "Selettore tonalità",
+saturationPickerTitle: "Selettore saturazione"
 })
 
diff --git a/dojox/widget/nls/ja/ColorPicker.js b/dojox/widget/nls/ja/ColorPicker.js
index e279369..f4fa716 100644
--- a/dojox/widget/nls/ja/ColorPicker.js
+++ b/dojox/widget/nls/ja/ColorPicker.js
@@ -1,4 +1,5 @@
 ({
-hexLabel: "16 進"
+hexLabel: "16 進",
+huePickerTitle: "色調セレクター",
+saturationPickerTitle: "彩度セレクター"
 })
-
diff --git a/dojox/widget/nls/kk/ColorPicker.js b/dojox/widget/nls/kk/ColorPicker.js
new file mode 100644
index 0000000..a2e033c
--- /dev/null
+++ b/dojox/widget/nls/kk/ColorPicker.js
@@ -0,0 +1,12 @@
+({
+redLabel: "r",
+greenLabel: "д",
+blueLabel: "ә",
+hueLabel: "е",
+saturationLabel: "ң",
+valueLabel: "п", /* aka intensity or brightness */
+hexLabel: "алтылық",
+huePickerTitle: "Реңкті іріктеу",
+saturationPickerTitle: "Қанықтықты іріктеу"
+})
+
diff --git a/dojox/widget/nls/kk/FilePicker.js b/dojox/widget/nls/kk/FilePicker.js
new file mode 100644
index 0000000..5957224
--- /dev/null
+++ b/dojox/widget/nls/kk/FilePicker.js
@@ -0,0 +1,6 @@
+({
+name: "Атауы",
+path: "Жол",
+size: "Өлшемі (байт)"
+})
+
diff --git a/dojox/widget/nls/kk/Wizard.js b/dojox/widget/nls/kk/Wizard.js
new file mode 100644
index 0000000..f3ef373
--- /dev/null
+++ b/dojox/widget/nls/kk/Wizard.js
@@ -0,0 +1,6 @@
+({
+next: "Келесі",
+previous: "Алдыңғы",
+done: "Орындалған"
+})
+
diff --git a/dojox/widget/nls/ko/ColorPicker.js b/dojox/widget/nls/ko/ColorPicker.js
index 451a08a..ed3eaeb 100644
--- a/dojox/widget/nls/ko/ColorPicker.js
+++ b/dojox/widget/nls/ko/ColorPicker.js
@@ -5,6 +5,7 @@ blueLabel: "B",
 hueLabel: "H",
 saturationLabel: "S",
 valueLabel: "V", /* aka intensity or brightness */
-hexLabel: "HEX"
+hexLabel: "16진",
+huePickerTitle: "색상 선택자",
+saturationPickerTitle: "채도 선택자"
 })
-
diff --git a/dojox/widget/nls/nb/ColorPicker.js b/dojox/widget/nls/nb/ColorPicker.js
index 1fe2a1b..b2bc168 100644
--- a/dojox/widget/nls/nb/ColorPicker.js
+++ b/dojox/widget/nls/nb/ColorPicker.js
@@ -1,3 +1,4 @@
 ({
+huePickerTitle: "Nyansevelger",
+saturationPickerTitle: "Metningsvelger"
 })
-
diff --git a/dojox/widget/nls/nl/ColorPicker.js b/dojox/widget/nls/nl/ColorPicker.js
index 9789f65..151d0af 100644
--- a/dojox/widget/nls/nl/ColorPicker.js
+++ b/dojox/widget/nls/nl/ColorPicker.js
@@ -1,6 +1,8 @@
 ({
 hueLabel: "t",
 saturationLabel: "i",
-valueLabel: "h" /* aka intensity or brightness */
+valueLabel: "h", /* aka intensity or brightness */
+huePickerTitle: "Tint selecteren",
+saturationPickerTitle: "Intensiteit selecteren"
 })
 
diff --git a/dojox/widget/nls/nl/FilePicker.js b/dojox/widget/nls/nl/FilePicker.js
index e91c5f8..2cf5365 100644
--- a/dojox/widget/nls/nl/FilePicker.js
+++ b/dojox/widget/nls/nl/FilePicker.js
@@ -3,3 +3,4 @@ name: "Naam",
 path: "Pad",
 size: "Grootte (in bytes)"
 })
+
diff --git a/dojox/widget/nls/pl/ColorPicker.js b/dojox/widget/nls/pl/ColorPicker.js
index 967da23..09f18db 100644
--- a/dojox/widget/nls/pl/ColorPicker.js
+++ b/dojox/widget/nls/pl/ColorPicker.js
@@ -5,6 +5,8 @@ blueLabel: "n",
 hueLabel: "barwa",
 saturationLabel: "nas.",
 valueLabel: "jas.", /* aka intensity or brightness */
-hexLabel: "szesnastkowe"
+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 44cdf79..9329bbf 100644
--- a/dojox/widget/nls/pl/Wizard.js
+++ b/dojox/widget/nls/pl/Wizard.js
@@ -1,5 +1,6 @@
 ({
-next: "Następna",
-previous: "Poprzednia",
+next: "Dalej",
+previous: "Wstecz",
 done: "Gotowe"
 })
+
diff --git a/dojox/widget/nls/pt-pt/ColorPicker.js b/dojox/widget/nls/pt-pt/ColorPicker.js
index 5760b12..7f7d003 100644
--- a/dojox/widget/nls/pt-pt/ColorPicker.js
+++ b/dojox/widget/nls/pt-pt/ColorPicker.js
@@ -3,6 +3,8 @@ redLabel: "e",
 greenLabel: "v",
 blueLabel: "a",
 hueLabel: "t",
-valueLabel: "val" /* aka intensity or brightness */
+valueLabel: "val", /* aka intensity or brightness */
+huePickerTitle: "Selector de tonalidade",
+saturationPickerTitle: "Selector de saturação"
 })
 
diff --git a/dojox/widget/nls/pt/ColorPicker.js b/dojox/widget/nls/pt/ColorPicker.js
index 1fe2a1b..1e5b105 100644
--- a/dojox/widget/nls/pt/ColorPicker.js
+++ b/dojox/widget/nls/pt/ColorPicker.js
@@ -1,3 +1,4 @@
 ({
+huePickerTitle: "Seletor de Matiz",
+saturationPickerTitle: "Seletor de Saturação"
 })
-
diff --git a/dojox/widget/nls/ru/ColorPicker.js b/dojox/widget/nls/ru/ColorPicker.js
index 1de7125..764d174 100644
--- a/dojox/widget/nls/ru/ColorPicker.js
+++ b/dojox/widget/nls/ru/ColorPicker.js
@@ -5,6 +5,8 @@ blueLabel: "с",
 hueLabel: "о",
 saturationLabel: "н",
 valueLabel: "з", /* aka intensity or brightness */
-hexLabel: "шест"
+hexLabel: "шест",
+huePickerTitle: "Выбор оттенка",
+saturationPickerTitle: "Выбор насыщенности"
 })
 
diff --git a/dojox/widget/nls/sl/ColorPicker.js b/dojox/widget/nls/sl/ColorPicker.js
index 1fe2a1b..6f693ea 100644
--- a/dojox/widget/nls/sl/ColorPicker.js
+++ b/dojox/widget/nls/sl/ColorPicker.js
@@ -1,3 +1,5 @@
 ({
+huePickerTitle: "Izbirnik odtenka ",
+saturationPickerTitle: "Izbirnik nasičenosti"
 })
 
diff --git a/dojox/widget/nls/sv/ColorPicker.js b/dojox/widget/nls/sv/ColorPicker.js
index e6fd6e6..d50b6fe 100644
--- a/dojox/widget/nls/sv/ColorPicker.js
+++ b/dojox/widget/nls/sv/ColorPicker.js
@@ -1,6 +1,8 @@
 ({
 hueLabel: "n",
 saturationLabel: "m",
-valueLabel: "l" /* aka intensity or brightness */
+valueLabel: "l", /* aka intensity or brightness */
+huePickerTitle: "Välj färgton",
+saturationPickerTitle: "Välj mättnad"
 })
 
diff --git a/dojox/widget/nls/th/ColorPicker.js b/dojox/widget/nls/th/ColorPicker.js
index 37068ae..8ead10c 100644
--- a/dojox/widget/nls/th/ColorPicker.js
+++ b/dojox/widget/nls/th/ColorPicker.js
@@ -4,6 +4,8 @@ greenLabel: "จี",
 blueLabel: "บี",
 hueLabel: "เอช",
 saturationLabel: "เอส",
-valueLabel: "วี",
-hexLabel: "เลขฐานสิบหก"
+valueLabel: "วี", /* aka intensity or brightness */
+huePickerTitle: "ตัวเลือกสี",
+saturationPickerTitle: "ตัวเลือกความอิ่มของสี"
 })
+
diff --git a/dojox/widget/nls/tr/ColorPicker.js b/dojox/widget/nls/tr/ColorPicker.js
index 2d26abf..be8470d 100644
--- a/dojox/widget/nls/tr/ColorPicker.js
+++ b/dojox/widget/nls/tr/ColorPicker.js
@@ -5,6 +5,8 @@ blueLabel: "m",
 hueLabel: "t",
 saturationLabel: "d",
 valueLabel: "d", /* aka intensity or brightness */
-hexLabel: "onaltılı"
+hexLabel: "onaltılı",
+huePickerTitle: "Ton Seçici",
+saturationPickerTitle: "Doygunluk Seçici"
 })
 
diff --git a/dojox/widget/nls/zh-tw/ColorPicker.js b/dojox/widget/nls/zh-tw/ColorPicker.js
index 254e7cd..3ff7f19 100644
--- a/dojox/widget/nls/zh-tw/ColorPicker.js
+++ b/dojox/widget/nls/zh-tw/ColorPicker.js
@@ -1,4 +1,5 @@
 ({
-hexLabel: "十六進位"
+hexLabel: "十六進位",
+huePickerTitle: "色調選取元",
+saturationPickerTitle: "飽和度選取元"
 })
-
diff --git a/dojox/widget/nls/zh/ColorPicker.js b/dojox/widget/nls/zh/ColorPicker.js
index 786296d..f6397a9 100644
--- a/dojox/widget/nls/zh/ColorPicker.js
+++ b/dojox/widget/nls/zh/ColorPicker.js
@@ -1,4 +1,5 @@
 ({
-hexLabel: "十六进制"
+hexLabel: "十六进制",
+huePickerTitle: "色彩选择器",
+saturationPickerTitle: "饱和度选择器"
 })
-
diff --git a/dojox/widget/nls/zh/FilePicker.js b/dojox/widget/nls/zh/FilePicker.js
index 23cab53..9e8aa6c 100644
--- a/dojox/widget/nls/zh/FilePicker.js
+++ b/dojox/widget/nls/zh/FilePicker.js
@@ -1,5 +1,5 @@
 ({
 name: "名称",
 path: "路径",
-size: "大小(字节"
+size: "大小(字节)"
 })
diff --git a/dojox/widget/rotator/PanFade.js b/dojox/widget/rotator/PanFade.js
new file mode 100644
index 0000000..bd241c4
--- /dev/null
+++ b/dojox/widget/rotator/PanFade.js
@@ -0,0 +1,211 @@
+dojo.provide("dojox.widget.rotator.PanFade");
+dojo.require("dojo.fx");
+
+(function(d){
+
+	// Constants used to identify which edge the pane pans in from.
+	var DOWN = 0,
+		RIGHT = 1,
+		UP = 2,
+		LEFT = 3;
+
+	function _pan(/*int*/type, /*Object*/args){
+		//	summary:
+		//		Handles the preparation of the dom node and creates the dojo.Animation object.
+		var j = {
+				node: args.current.node,
+				duration: args.duration,
+				easing: args.easing
+			},
+			k = {
+				node: args.next.node,
+				duration: args.duration,
+				easing: args.easing
+			},
+			r = args.rotatorBox,
+			m = type % 2,
+			a = m ? "left" : "top",
+			s = (m ? r.w : r.h) * (type < 2 ? -1 : 1),
+			p = {},
+			q = {};
+
+		d.style(k.node, {
+			display: "",
+			opacity: 0
+		});
+
+		p[a] = {
+			start: 0,
+			end: -s
+		};
+
+		q[a] = {
+			start: s,
+			end: 0
+		};
+
+		return d.fx.combine([ /*dojo.Animation*/
+			d.animateProperty(d.mixin({ properties: p }, j)),
+			d.fadeOut(j),
+			d.animateProperty(d.mixin({ properties: q }, k)),
+			d.fadeIn(k)
+		]);
+	}
+
+	function _setZindex(/*DomNode*/n, /*int*/z){
+		//	summary:
+		//		Helper function for continuously panning.
+		d.style(n, "zIndex", z);
+	}
+
+	d.mixin(dojox.widget.rotator, {
+		panFade: function(/*Object*/args){
+			//	summary:
+			//		Returns a dojo.Animation that either pans left or right to the next pane.
+			//		The actual direction depends on the order of the panes.
+			//
+			//		If panning forward from index 1 to 3, it will perform a pan left. If panning
+			//		backwards from 5 to 1, then it will perform a pan right.
+			//
+			//		If the parameter "continuous" is set to true, it will return an animation
+			//		chain of several pan animations of each intermediate pane panning. For
+			//		example, if you pan forward from 1 to 3, it will return an animation panning
+			//		left from 1 to 2 and then 2 to 3.
+			//
+			//		If an easing is specified, it will be applied to each pan transition.  For
+			//		example, if you are panning from pane 1 to pane 5 and you set the easing to
+			//		"dojo.fx.easing.elasticInOut", then it will "wobble" 5 times, once for each
+			//		pan transition.
+			//
+			//		If the parameter "wrap" is set to true, it will pan to the next pane using
+			//		the shortest distance in the array of panes. For example, if there are 6
+			//		panes, then panning from 5 to 1 will pan forward (left) from pane 5 to 6 and
+			//		6 to 1.  If the distance is the same either going forward or backwards, then
+			//		it will always pan forward (left).
+			//
+			//		A continuous pan will use the target pane's duration to pan all intermediate
+			//		panes.  To use the target's pane duration for each intermediate pane, then
+			//		set the "quick" parameter to "false".
+
+			var w = args.wrap,
+				p = args.rotator.panes,
+				len = p.length,
+				z = len,
+				j = args.current.idx,
+				k = args.next.idx,
+				nw = Math.abs(k - j),
+				ww = Math.abs((len - Math.max(j, k)) + Math.min(j, k)) % len,
+				_forward = j < k,
+				_dir = LEFT,
+				_pans = [],
+				_nodes = [],
+				_duration = args.duration;
+
+			// default to pan left, but check if we should pan right.
+			// need to take into account wrapping.
+			if((!w && !_forward) || (w && (_forward && nw > ww || !_forward && nw < ww))){
+				_dir = RIGHT;
+			}
+
+			if(args.continuous){
+				// if continuous pans are quick, then divide the duration by the number of panes
+				if(args.quick){
+					_duration = Math.round(_duration / (w ? Math.min(ww, nw) : nw));
+				}
+
+				// set the current pane's z-index
+				_setZindex(p[j].node, z--);
+
+				var f = (_dir == LEFT);
+
+				// loop and set z-indexes and get all pan animations
+				while(1){
+					// set the current pane
+					var i = j;
+
+					// increment/decrement the next pane's index
+					if(f){
+						if(++j >= len){
+							j = 0;
+						}
+					}else{
+						if(--j < 0){
+							j = len - 1;
+						}
+					}
+
+					var x = p[i],
+						y = p[j];
+
+					// set next pane's z-index
+					_setZindex(y.node, z--);
+
+					// build the pan animation
+					_pans.push(_pan(_dir, d.mixin({
+						easing: function(m){ return m; } // continuous gets a linear easing by default
+					}, args, {
+						current: x,
+						next: y,
+						duration: _duration
+					})));
+
+					// if we're done, then break out of the loop
+					if((f && j == k) || (!f && j == k)){
+						break;
+					}
+
+					// this must come after the break... we don't want the last pane to get it's
+					// styles reset.
+					_nodes.push(y.node);
+				}
+
+				// build the chained animation of all pan animations
+				var _anim = d.fx.chain(_pans),
+
+					// clean up styles when the chained animation finishes
+					h = d.connect(_anim, "onEnd", function(){
+						d.disconnect(h);
+						d.forEach(_nodes, function(q){
+							d.style(q, {
+								display: "none",
+								left: 0,
+								opacity: 1,
+								top: 0,
+								zIndex: 0
+							});
+						});
+					});
+
+				return _anim;
+			}
+
+			// we're not continuous, so just return a normal pan animation
+			return _pan(_dir, args); /*dojo.Animation*/
+		},
+
+		panFadeDown: function(/*Object*/args){
+			//	summary:
+			//		Returns a dojo.Animation that pans in the next rotator pane from the top.
+			return _pan(DOWN, args); /*dojo.Animation*/
+		},
+
+		panFadeRight: function(/*Object*/args){
+			//	summary:
+			//		Returns a dojo.Animation that pans in the next rotator pane from the right.
+			return _pan(RIGHT, args); /*dojo.Animation*/
+		},
+
+		panFadeUp: function(/*Object*/args){
+			//	summary:
+			//		Returns a dojo.Animation that pans in the next rotator pane from the bottom.
+			return _pan(UP, args); /*dojo.Animation*/
+		},
+
+		panFadeLeft: function(/*Object*/args){
+			//	summary:
+			//		Returns a dojo.Animation that pans in the next rotator pane from the left.
+			return _pan(LEFT, args); /*dojo.Animation*/
+		}
+	});
+
+})(dojo);
diff --git a/dojox/widget/tests/CalendarStackLayout.js b/dojox/widget/tests/CalendarStackLayout.js
index a927fe7..da5a078 100644
--- a/dojox/widget/tests/CalendarStackLayout.js
+++ b/dojox/widget/tests/CalendarStackLayout.js
@@ -38,8 +38,8 @@ dojo.declare("dojox.widget.tests.CalendarStackLayout", [dijit._Widget, dijit._Co
 
 		function getChildByDate(date){
 			return _this.dateToPane[
-				date.getFullYear() 
-				+  "-" + dojo.string.pad(String(date.getMonth() + 1), 2) 
+				date.getFullYear()
+				+  "-" + dojo.string.pad(String(date.getMonth() + 1), 2)
 				+ "-" + dojo.string.pad(String(date.getDate()))];
 		}
 
diff --git a/dojox/widget/tests/test_DataPresentation.html b/dojox/widget/tests/test_DataPresentation.html
index 41a3764..91ebd5d 100644
--- a/dojox/widget/tests/test_DataPresentation.html
+++ b/dojox/widget/tests/test_DataPresentation.html
@@ -1,29 +1,27 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 <html style="height: 100%;">
 <head>
+
 	<title>DataPresentation widget example</title>
 	
 	<style type="text/css"> 
-     		@import "../../../dijit/themes/tundra/tundra.css";
-			  @import "../../../dojox/grid/resources/tundraGrid.css";
-     		@import "../../../dojo/resources/dojo.css"
-        @import "../../../dijit/tests/css/dijitTests.css";
+		@import "../../../dijit/themes/tundra/tundra.css";
+		@import "../../../dojox/grid/resources/tundraGrid.css";
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css";
 	</style>
 	
-	
-	
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true"></script>
-  
 	<script type="text/javascript">
 
-    dojo.require("dojox.widget.DataPresentation");
-    dojo.require("dojox.charting.themes.Minty");
-    
+		dojo.require("dojox.widget.DataPresentation");
+		dojo.require("dojox.charting.themes.Minty");
+	
 		var jsondata0 = {
-				"title"  : "Softdrink Sales (2007)",
+				"title"	 : "Softdrink Sales (2007)",
 				"footer" : "North America only",
-				"range"  : [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
-				"series" : [                            
+				"range"	 : [ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ],
+				"series" : [							
 					{ "legend" : "Cola", "line" : true, "values" : [ "35", "37", "44", "41", "43", "57", "62", "69", "74", "86", "101", "124" ] },
 					{ "legend" : "Lemonade", "values" : [ "122", "99", "111", "98", "82", "77", "76", "67", "72", "75", "66", "67" ] },
 					{ "legend" : "Dandelion and burdock", "values" : [ "99", "98", "98", "99", "97", "102", "100", "99", "102", "97", "95", "98" ] },
@@ -35,83 +33,85 @@
 				]
 		};
 
-    // shake things up a bit, just for fun
-    setInterval(function() {
-      var series = Math.floor(jsondata0.series.length * Math.random());
-      var value = Math.floor(jsondata0.series[series].values.length * Math.random());
-      var newvalue = parseInt(jsondata0.series[series].values[value]) + Math.floor(11 * Math.random()) - 5;
-      jsondata0.series[series].values[value] = "" + newvalue;  
-    }, 100);		
+		// shake things up a bit, just for fun
+		setInterval(function() {
+			var series = Math.floor(jsondata0.series.length * Math.random());
+			var value = Math.floor(jsondata0.series[series].values.length * Math.random());
+			var newvalue = parseInt(jsondata0.series[series].values[value]) + Math.floor(11 * Math.random()) - 5;
+			jsondata0.series[series].values[value] = "" + newvalue;	 
+		}, 100);
 
-	  var jsondata1 = {
-        "title"  : "Softdrink Sales (2007)",
-        "footer" : "North America only",
-        "sales"  : [
-          { "month": "Jan", "cola": "84", "lemonade": "75", "dandelionandburdock": "64", "gingerale": "54" },
-          { "month": "Feb", "cola": "108", "lemonade": "65", "dandelionandburdock": "47", "gingerale": "43" },
-          { "month": "Mar", "cola": "24", "lemonade": "85", "dandelionandburdock": "68", "gingerale": "76" },
-          { "month": "Apr", "cola": "56", "lemonade": "75", "dandelionandburdock": "73", "gingerale": "92" },
-          { "month": "May", "cola": "78", "lemonade": "82", "dandelionandburdock": "43", "gingerale": "32" },
-          { "month": "Jun", "cola": "124", "lemonade": "43", "dandelionandburdock": "34", "gingerale": "54" },
-          { "month": "Jul", "cola": "84", "lemonade": "59", "dandelionandburdock": "42", "gingerale": "78" },
-          { "month": "Aug", "cola": "108", "lemonade": "34", "dandelionandburdock": "69", "gingerale": "65" },
-          { "month": "Sep", "cola": "24", "lemonade": "76", "dandelionandburdock": "86", "gingerale": "43" },
-          { "month": "Oct", "cola": "56", "lemonade": "65", "dandelionandburdock": "77", "gingerale": "43" },
-          { "month": "Nov", "cola": "78", "lemonade": "34", "dandelionandburdock": "65", "gingerale": "45" },
-          { "month": "Dec", "cola": "124", "lemonade": "67", "dandelionandburdock": "41", "gingerale": "65" }
-        ]
-    };
+		var jsondata1 = {
+			"title"	 : "Softdrink Sales (2007)",
+			"footer" : "North America only",
+			"sales"	 : [
+				{ "month": "Jan", "cola": "84", "lemonade": "75", "dandelionandburdock": "64", "gingerale": "54" },
+				{ "month": "Feb", "cola": "108", "lemonade": "65", "dandelionandburdock": "47", "gingerale": "43" },
+				{ "month": "Mar", "cola": "24", "lemonade": "85", "dandelionandburdock": "68", "gingerale": "76" },
+				{ "month": "Apr", "cola": "56", "lemonade": "75", "dandelionandburdock": "73", "gingerale": "92" },
+				{ "month": "May", "cola": "78", "lemonade": "82", "dandelionandburdock": "43", "gingerale": "32" },
+				{ "month": "Jun", "cola": "124", "lemonade": "43", "dandelionandburdock": "34", "gingerale": "54" },
+				{ "month": "Jul", "cola": "84", "lemonade": "59", "dandelionandburdock": "42", "gingerale": "78" },
+				{ "month": "Aug", "cola": "108", "lemonade": "34", "dandelionandburdock": "69", "gingerale": "65" },
+				{ "month": "Sep", "cola": "24", "lemonade": "76", "dandelionandburdock": "86", "gingerale": "43" },
+				{ "month": "Oct", "cola": "56", "lemonade": "65", "dandelionandburdock": "77", "gingerale": "43" },
+				{ "month": "Nov", "cola": "78", "lemonade": "34", "dandelionandburdock": "65", "gingerale": "45" },
+				{ "month": "Dec", "cola": "124", "lemonade": "67", "dandelionandburdock": "41", "gingerale": "65" }
+			]
+		};
 
-	  var salesnumbers = function(value, index)
-	  {
-		  var ivalue = parseInt(value);
+		var salesnumbers = function(value, index){
+			var ivalue = parseInt(value);
 		  
-		  if (ivalue > 100)
-			  return '<div style="text-align: right; background-color: #ddffcc; width: ' + (((ivalue * 80) / 130) + 20) + '%;">' + value + '</div>';
-			else
-	      return '<div style="text-align: right; background-color: #ffddcc; width: ' + (((ivalue * 80) / 130) + 20) + '%;">' + value + '</div>';
-	  }
+			if (ivalue > 100){
+				return '<div style="text-align: right; background-color: #ddffcc; width: ' + (((ivalue * 80) / 130) + 20) + '%;">' + value + '</div>';
+			}else{
+				return '<div style="text-align: right; background-color: #ffddcc; width: ' + (((ivalue * 80) / 130) + 20) + '%;">' + value + '</div>';
+			}
+		}
 
-    var makeseries = function(data)
-    {
-      if (!data.sales)
-	      return [ { datapoints: "range", name: "Month", type: "range", chart: false },
-	               { datapoints: "series[0].values", namefield: "series[0].legend", gridformatter: salesnumbers },
-	               { datapoints: "series[1].values", name: "Lemonade (fizzy)", charttype: "line", gridformatter: salesnumbers },
-	               { datapoints: "series[2].values", namefield: "series[2].legend", gridformatter: salesnumbers },
-	               { datapoints: "series[3].values", namefield: "series[3].legend", gridformatter: salesnumbers }
-	             ];
-      else
-        return [ { datapoints: "sales", field: "month", name: "Month", type: "range", chart: false },
-                 { datapoints: "sales", field: "lemonade", name: "Lemonade (fizzy)" },
-                 { datapoints: "sales", field: "dandelionandburdock", name: "Dandelion and burdock" },
-                 { datapoints: "sales", field: "cola", name: "Cola" },
-                 { datapoints: "sales", field: "gingerale", name: "Ginger ale" }
-               ];
-    }
+		var makeseries = function(data){
+			if(!data.sales){
+				return [ 
+					{ datapoints: "range", name: "Month", type: "range", chart: false },
+					{ datapoints: "series[0].values", namefield: "series[0].legend", gridformatter: salesnumbers },
+					{ datapoints: "series[1].values", name: "Lemonade (fizzy)", charttype: "line", gridformatter: salesnumbers },
+					{ datapoints: "series[2].values", namefield: "series[2].legend", gridformatter: salesnumbers },
+					{ datapoints: "series[3].values", namefield: "series[3].legend", gridformatter: salesnumbers }
+				];
+			}else{
+				return [ 
+					{ datapoints: "sales", field: "month", name: "Month", type: "range", chart: false },
+					{ datapoints: "sales", field: "lemonade", name: "Lemonade (fizzy)" },
+					{ datapoints: "sales", field: "dandelionandburdock", name: "Dandelion and burdock" },
+					{ datapoints: "sales", field: "cola", name: "Cola" },
+					{ datapoints: "sales", field: "gingerale", name: "Ginger ale" }
+			   ];
+			}
+		}
 	  
-	  var dp;
+		var dp;
 
 		dojo.addOnLoad(function() {
 
-			  var jsondata = jsondata0;   // (or jsondata1)
+			  var jsondata = jsondata0;	  // (or jsondata1)
 
 			  dp = new dojox.widget.DataPresentation("chartdiv", {
 				  type: "chart",
 				  chartType: "Hybrid",
 				  data: jsondata,
-          refreshInterval: 3000,
+				  refreshInterval: 3000,
 				  series: makeseries(jsondata),
-          legendNode: "legenddiv",
-          legendHorizontal: 2,
-          //labelMod: 2,  // display every other x-axis label
-          //labelMod: 0,  // suppress x-axis labels
-          gridNode: "griddiv",
-          titleNode: "title",
-          footerNode: "footer",
-          theme: "dojox.charting.themes.Minty",
-          labelMod: 2,
-          tooltip: "The value for this {0} for '{1}' in {2} is <b>{3}</b>"
+				  legendNode: "legenddiv",
+				  legendHorizontal: 2,
+				  //labelMod: 2,  // display every other x-axis label
+				  //labelMod: 0,  // suppress x-axis labels
+				  gridNode: "griddiv",
+				  titleNode: "title",
+				  footerNode: "footer",
+				  theme: "dojox.charting.themes.Minty",
+				  labelMod: 2,
+				  tooltip: "The value for this {0} for '{1}' in {2} is <b>{3}</b>"
 			  });
 
 		});
@@ -119,40 +119,42 @@
 </head>
 <body style="font-family: arial; font-size: 12px; height: 100%;" class="tundra">
 
-<h1>An example of DataPresentation widget</h1>
+	<h1>An example of DataPresentation widget</h1>
 
-<p>This example shows automatic refresh (every 3 seconds), although this is
-most useful in conjunction with a URL where the data may change each time. 
-To make something visible, some background code is tweaking the values randomly
-so that the automatic refresh always pulls changed data.</p>
+	<p>This example shows automatic refresh (every 3 seconds), although this is
+		most useful in conjunction with a URL where the data may change each time. 
+		To make something visible, some background code is tweaking the values randomly
+		so that the automatic refresh always pulls changed data.
+	</p>
 
-<p>To see how the widget can cope with different data shapes, switch from 
-jsondata0 to jsondata1 as the input data. jsondata0 is structured as complete
-'series' of values, gathered into an array with series titles. jsondata1 is
-structures as 'data points', each containing multiple sales values.
+	<p>To see how the widget can cope with different data shapes, switch from 
+		jsondata0 to jsondata1 as the input data. jsondata0 is structured as complete
+		'series' of values, gathered into an array with series titles. jsondata1 is
+		structures as 'data points', each containing multiple sales values.
+	</p>
 
-<p>Note that the widget is driving its own DOM node (the chart, in this case, 
-although it could be any of the components) and is also driving other nodes
-containing the grid, legend, etc.</p>
+	<p>Note that the widget is driving its own DOM node (the chart, in this case, 
+		although it could be any of the components) and is also driving other nodes
+		containing the grid, legend, etc.
+	</p>
 
-  <div style="width:400px; text-align: center;">
-    <h2 id="title" style="margin-bottom: 0;"></h2>
-    <p id="footer" style="color: gray; font-size: 0.85em; margin-top: 0.2em;"></p>
-  </div>
+	<div style="width:400px; text-align: center;">
+		<h2 id="title" style="margin-bottom: 0;"></h2>
+		<p id="footer" style="color: gray; font-size: 0.85em; margin-top: 0.2em;"></p>
+	</div>
 	
-  <div style="width: 450px; position: relative;">
-	  <div id="chartdiv" style="width: 400px; height: 300px;"></div>
-      
-    <div style="position: absolute; top: 40px; right: 0px; padding: 0.2em 0.5em; border: 1px solid gray; background-color: rgba(255, 255, 221, 0.8);">
-      <div id="legenddiv" style="z-index: 1;"></div>
-    </div>
+	<div style="width: 450px; position: relative;">
+		<div id="chartdiv" style="width: 400px; height: 300px;"></div>
+		<div style="position: absolute; top: 40px; right: 0px; padding: 0.2em 0.5em; border: 1px solid gray; background-color: rgba(255, 255, 221, 0.8);">
+			<div id="legenddiv" style="z-index: 1;"></div>
+		</div>
 	</div>
 	  
 	<p>Now here is the same data displayed in a grid (also driven by the same DataPresentation widget):</p>
 	
-  <div style="width:400px; height:240px;">
-    <div id="griddiv"></div>
-  </div>    
-
+	<div style="width:400px; height:240px;">
+		<div id="griddiv"></div>
+	</div>
+	
 </body>
 </html>
diff --git a/dojox/widget/tests/test_Dialog.html b/dojox/widget/tests/test_Dialog.html
index f95b0d9..be9ef6d 100644
--- a/dojox/widget/tests/test_Dialog.html
+++ b/dojox/widget/tests/test_Dialog.html
@@ -5,7 +5,7 @@
 	<title>DojoX Dialog example</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">
 	<link rel="stylesheet" href="../Dialog/Dialog.css">
 
 	<style type="text/css">
@@ -25,6 +25,7 @@
 	<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");
@@ -46,10 +47,10 @@
 			// dojoType="" for the purists.
 			dojo.query("button")
 				.forEach(function(n){
-					var oc = dojo.attr(n,"onclick");
+					var oc = dojo.attr(n, "onclick");
 					var button = new dijit.form.Button({
 						onClick: oc
-					},n)
+					}, n)
 				});
 
 			// programatic with content: 
@@ -82,13 +83,44 @@
 		});
 	</script>
 </head>
-<body class="tundra">
+<body class="claro">
 
-	<h1 class="testTitle">dojox.widget.Dialog tests</h1>
+	<h1 class="testTitle">dojox.widget.Dialog module tests</h1>
 	
-	<p>This is the DojoX version of the dijit.Dialog. It's very different.</p>
+	<p>This is the DojoX version of the dijit.Dialog. It is both very simple, and very different.</p>
 
 	<div id='testholder' class="tests">
+		
+		<h2>dojox.widget.DialogSimple</h2>
+		
+		<p>A Simple subclass mixing the capabilities of dojox.layout.ContentPane with default
+			dijit.Dialog styles
+		</p>
+		
+		<button onclick="dijit.byId('stest').show()">DialogSimple</button>
+		<div id="stest" dojoType="dojox.widget.DialogSimple" style="width:200px">
+			<h2 style="margin-top:0">Wow!</h2>
+			<p style="margin-top:0">Vestibulum convallis eros ac justo. Proin dolor. Etiam aliquam. Nam
+			ornare elit vel augue. Suspendisse potenti. Etiam sed mauris eu neque
+			nonummy mollis. Vestibulum vel purus ac pede semper accumsan. Vivamus
+			lobortis, sem vitae nonummy lacinia, nisl est gravida magna, non cursus
+			est quam sed urna. Phasellus adipiscing justo in ipsum. Duis sagittis
+			dolor sit amet magna. Suspendisse suscipit, neque eu dictum auctor,
+			nisi augue tincidunt arcu, non lacinia magna purus nec magna. Praesent
+			pretium sollicitudin sapien. Suspendisse imperdiet. Class aptent taciti
+			sociosqu ad litora torquent per conubia nostra, per inceptos
+			hymenaeos.
+			</p>
+		</div>
+
+		<button onclick="dijit.byId('stestjs').show()">DialogSimple:exejs</button>
+		<div id="stestjs" title="Check the Console" 
+			dojoType="dojox.widget.DialogSimple" style="width:200px" executeScripts="true" href="withjs.html"
+		></div>
+		
+		<h2>dojox.widget.Dialog</h2>
+		<p>Fancy. Has more options. Different styles, too.</p>
+		
 		<button onclick="dijit.byId('firstTest').show()">Defaults only</button>
 		
 		<div id="firstTest" dojoType="dojox.widget.Dialog" title="A Dialog Thinger">
@@ -293,7 +325,6 @@
 			hymenaeos.
 			</p>
 		</div>
-
 	
 	</div>
 
@@ -301,7 +332,8 @@
 		<em>some</em> assumption about how you want to size your pane.</p>
 		 
 	<p>That's all folks, all of the supported options have buttons and inline tests.</p>
-
+	<p>The names of these will be reversed in Dojo 2.0, should they survive the migration</p>
+	
 </body>
 </html>
 
diff --git a/dojox/widget/tests/test_DynamicTooltip.html b/dojox/widget/tests/test_DynamicTooltip.html
index 06e5679..ae46854 100644
--- a/dojox/widget/tests/test_DynamicTooltip.html
+++ b/dojox/widget/tests/test_DynamicTooltip.html
@@ -25,6 +25,8 @@
 		dojo.require("dijit.dijit"); // optimize: load dijit layer
 		dojo.require("dojox.widget.DynamicTooltip");
 		dojo.require("dijit.ColorPalette");
+		dojo.require("dojo.parser");
+		
 		dojo.addOnLoad(function(){
 			console.log("on load func");
 			var tt = new dojox.widget.DynamicTooltip({
@@ -84,8 +86,8 @@
 			</b>
 		</span>
 		<span style="color: blue;">
-			<button onclick="dijit.byId('dyn_two_tooltip').attr('href', 'honey.php');">Set URL honey.php, delayed</button>
-			<button onclick="dijit.byId('dyn_two_tooltip').attr('href', 'get_time.php');">Set URL get_time.php</button>
+			<button onclick="dijit.byId('dyn_two_tooltip').set('href', 'honey.php');">Set URL honey.php, delayed</button>
+			<button onclick="dijit.byId('dyn_two_tooltip').set('href', 'get_time.php');">Set URL get_time.php</button>
 		</span>
 	</div>
 	<span id="programmaticTestDynamic">this text has a programmatically created dynamic tooltip</span>
@@ -170,7 +172,7 @@
 	<span dojoType="dojox.widget.DynamicTooltip" connectId="s5" id="s5_tooltip">s5 tooltip</span>
 
 	<h3>One Tooltip for multiple connect nodes</h3>
-	<span dojoType="dojox.widget.DynamicTooltip" connectId="multi1,multi2" id="multi1,multi2_tooltip" style="display:none;">multi tooltip</span>
+	<span dojoType="dojox.widget.DynamicTooltip" connectId="multi1,multi2" id="multiboth" style="display:none;">multi tooltip</span>
 	<a id="multi1" href="#bogus">multi1</a><br><a id="multi2" href="#bogus">multi2</a>
 
 </body>
diff --git a/dojox/widget/tests/test_PlaceholderMenuItem.html b/dojox/widget/tests/test_PlaceholderMenuItem.html
index d9dbbcd..a675d8e 100644
--- a/dojox/widget/tests/test_PlaceholderMenuItem.html
+++ b/dojox/widget/tests/test_PlaceholderMenuItem.html
@@ -79,7 +79,24 @@
 						]);
 						t.t(ph._replaced);
 						t.is(4, m2.getChildren().length);
-					}
+					},
+					function test_destroyRecursive(t){
+						var menu = new dijit.Menu(),
+							ph = new dojox.widget.PlaceholderMenuItem(),
+							subMenu = new dijit.Menu();
+						menu.addChild(ph);
+						t.f(ph._replaced, "ph._replaced 1");
+						ph.replace([
+							new dijit.PopupMenuItem({label: "Popup 1", popup: subMenu})
+						]);
+						t.t(ph._replaced, "ph._replaced 2");
+						ph.unReplace(true);
+						t.f(ph._replaced, "ph._replaced 3");
+						// subMenu is destroyed iff the Placeholder called
+						// destroyRecursive on the PopupMenuItem instead of just
+						// destroy.
+						t.t(subMenu._destroyed, "subMenu._destroyed");
+					} 
 				]
 			);
 			doh.run();
diff --git a/dojox/widget/tests/test_PortletInGridContainer.html b/dojox/widget/tests/test_PortletInGridContainer.html
index 26edcfd..9a37f07 100644
--- a/dojox/widget/tests/test_PortletInGridContainer.html
+++ b/dojox/widget/tests/test_PortletInGridContainer.html
@@ -11,7 +11,7 @@
 	<style type="text/css">
 		@import "../../../dojo/resources/dojo.css";
 		@import "../../../dijit/tests/css/dijitTests.css";
-		
+
 		@import "../Portlet/Portlet.css";
 		@import "../../layout/resources/GridContainer.css";
 		@import "../Calendar/Calendar.css";
@@ -21,14 +21,14 @@
 		@import "../../grid/resources/nihiloGrid.css";
 		@import "../../image/resources/image.css";
 		@import "../../layout/resources/ExpandoPane.css";
-		
+
 		.dijitTabContainer  .gridContainerTable {
 			border: 0px none;
 		}
 		.dijitTabContainer .gridContainer {
 			padding: 2px;
 		}
-		
+
 		#masker {
 			position: absolute;
 			width: 100%;
@@ -38,7 +38,7 @@
 			background: white;
 			z-index: 1000;
 		}
-		
+
 		#clients .dijitTitlePaneContentInner,
 		#quotes  .dijitTitlePaneContentInner {
 			padding: 0;
@@ -55,7 +55,7 @@
 			padding-bottom: 5px;
 		}
 		.gridContainer {overflow-y: auto;}
-		
+
 		.dijitTooltip {
 			max-width: 400px;
 		}
@@ -75,29 +75,30 @@
 		.gridContainerZone > *{
 			margin: 5px !important;
 		}
-	</style>		
+	</style>
 
 	<!-- required: dojo.js -->
 	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:false, parseOnLoad: false"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
-	
+
 	<script type="text/javascript" src="test_PortletInGridContainer.js"></script>
 	<script type="text/javascript" src="../FeedPortlet.js"></script>
 	<script type="text/javascript" src="CalendarStackLayout.js"></script>
 </head>
 <body class="soria">
+
 	<div id="masker"></div>
 
-	<span dojoType="dojox.data.HtmlStore" 
+	<span dojoType="dojox.data.HtmlStore"
 		jsId="htmlStore" dataId="gridDataTable">
 	</span>
-	
-	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php" 
+
+	<div dojoType="dojox.data.FileStore" url="../../data/demos/stores/filestore_dojotree.php"
 					jsId="fileStore" pathAsQueryParam="true"></div>
-	
-	<div dojoType="dijit.tree.ForestStoreModel" jsId="fileModel" 
+
+	<div dojoType="dijit.tree.ForestStoreModel" jsId="fileModel"
 		store="fileStore" query="{}"
 		rootId="DojoFiles" rootLabel="Dojo Files" childrenAttrs="children">
 		<script type="dojo/method" event="getChildren" args="parent, callback">
@@ -111,20 +112,22 @@
 			  callback(items);
 			})]);
 		</script>
-		
+
 	</div>
 
 	<div dojoType="dijit.Menu" id="gridCols" jsId="gridCols" style="display: none">
 		<div dojoType="dojox.widget.PlaceholderMenuItem" label="GridColumns"></div>
 	</div>
 
+
+
 	<div dojoType="dijit.layout.TabContainer" region="center" style="height:100%;">
-		
-		<div dojoType="dijit.layout.BorderContainer" 
+
+		<div dojoType="dijit.layout.BorderContainer"
 				id="mainLayout"
 				title="Home"
 				style="width: 100%; height: 100%; padding: 2px;">
-	
+
 			<div dojoType="dojox.layout.GridContainer"
 					id="gridContainer"
 					region="center"
@@ -132,11 +135,12 @@
 					hasResizableColumns="false"
 					nbZones="2"
 					dragHandleClass="dijitTitlePaneTitle">
+
 				<div dojoType="dojox.widget.Portlet" title="Info" toggleable="false" dragRestriction="true">
-					<p onclick="text_explode_2(this)">This is a Portlet widget, which is similar to a dijit.TitlePane, 
+					<p onclick="text_explode_2(this)">This is a Portlet widget, which is similar to a dijit.TitlePane,
 						but is designed to be used with the dojox.layout.GridContainer widget.  Each widget can be extended
 						 with a number of different plug in widgets, with each plug in specifying
-						 an icon to display in the title bar. (<i>By the way, click this paragraph somewhere</i> :-) 
+						 an icon to display in the title bar. (<i>By the way, click this paragraph somewhere</i> :-)
 					</p>
 					<p>
 						Two settings widgets are currently defined, <b>dojox.widget.PortletSettings</b>
@@ -144,15 +148,15 @@
 					</p>
 					<p>This Portlet is not draggable, but all others are.</p>
 				</div>
-	
-				<div dojoType="dojox.widget.FeedPortlet" title="Todays News" 
+
+				<div dojoType="dojox.widget.FeedPortlet" title="Todays News"
 					id="todaysNews"
 					url="http://news.google.com/news?hl=en&topic=t&output=atom"
 					maxResults="5"
 					dndType="Portlet"
 					>
 					<div dojoType="dojox.widget.PortletFeedSettings"></div>
-					
+
 					<div>
 					This is a FeedPortlet with a single feed.
 					Click the settings icon in the title bar to enter a
@@ -160,33 +164,33 @@
 					of it in a tooltip.
 					</div>
 				</div>
-	
+
 				<div dojoType="dojox.widget.Portlet" title="Clients"  id="clients"
 					class="gridPortlet"
 					dndType="Portlet">
-					
-					<div id="staticGrid" 
-						dojoType="dojox.grid.DataGrid" 
+
+					<div id="staticGrid"
+						dojoType="dojox.grid.DataGrid"
 						rowsPerPage="10"
 						columnReordering="false"
-						store="htmlStore" 
-						structure="layoutHtmlTable", 
+						store="htmlStore"
+						structure="layoutHtmlTable",
 						query="{}"
-						headerMenu="gridCols" 
-						columnToggling="true" 
+						headerMenu="gridCols"
+						columnToggling="true"
 						title="Simple Grid"
 						autoHeight="true"
 						>
 						<script type="dojo/connect">
 							setTimeout(dojo.hitch(this, "resize"), 100);
 						</script>
-						
+
 					</div>
-	
+
 				</div>
-	
+
 				<div dojoType="dojox.widget.Portlet" title="Line Chart" id="lineChartPortlet" dndType="Portlet">
-					<div dojoType="dojox.widget.PortletDialogSettings" 
+					<div dojoType="dojox.widget.PortletDialogSettings"
 							id="lineChartSettings" dimensions="[300, 117]" title="Line Chart Settings">
 						<div dojoType="dojox.layout.TableContainer" cols="1">
 						  <div dojoType="dijit.form.TextBox" title="Option 3"></div>
@@ -205,18 +209,18 @@
 					</div>
 					<div id="zoomer" style="height:200px; width: 400px;"></div>
 					<div style="margin-bottom:5px;">Scale:</div>
-					<div id="scaleXSlider" dojoType="dijit.form.HorizontalSlider" 
+					<div id="scaleXSlider" dojoType="dijit.form.HorizontalSlider"
 							value="1" minimum="1" maximum="10" discreteValues="10" showButtons="false">
 						<div dojoType="dijit.form.HorizontalRule" container="bottomDecoration" count="10" style="height:5px;"></div>
 						<div dojoType="dijit.form.HorizontalRuleLabels" container="bottomDecoration" minimum="1" maximum="10" count="10"
 							constraints="{pattern: '##'}" style="height:1.2em;font-size:75%;color:gray;"></div>
 					</div>
-					
+
 				</div>
-				
+				-->
 			</div>
-				
-			<div dojoType="dojox.layout.ExpandoPane" region="right" 
+
+			<div dojoType="dojox.layout.ExpandoPane" region="right"
 					title="Calendar"
 					style="height: 100%;">
 
@@ -290,8 +294,9 @@
 				</div>
 
 			</div>
+
 		</div>
-			
+
 		<div dojoType="dijit.layout.BorderContainer" title="My Interests">
 			<div dojoType="dojox.layout.GridContainer"
 				id="gridContainer2"
@@ -321,18 +326,18 @@
 						<option value="http://feeds2.feedburner.com/ajaxian">Ajaxian</option>
 					</select>
 					<div>
-					This is an ExpandableFeedPortlet with multiple available feeds. 
+					This is an ExpandableFeedPortlet with multiple available feeds.
 					Click the settings icon in the title bar to choose a feed to load.
 					This Portlet also maintains its state using a cookie, so when you choose
 					a feed to show and refresh the page, that same feed will be selected.
 					this example also shows how to modify the title of the portlet when a new
 					feed is selected.
-					When a feed is loaded, it automatically sets the title of the Portlet to the 
+					When a feed is loaded, it automatically sets the title of the Portlet to the
 					title of the feed.  This portlet has disabled that behavior using
 					showFeedTitle="false"
 					</div>
 				</div>
-				<div dndType="Portlet" dojoType="dojox.widget.ExpandableFeedPortlet"  title="Cool Blogs -> onlyOpenOne == true" 
+				<div dndType="Portlet" dojoType="dojox.widget.ExpandableFeedPortlet"  title="Cool Blogs -> onlyOpenOne == true"
 						onlyOpenOne="true" >
 					<select dojoType="dojox.widget.PortletFeedSettings" id="multiOptions">
 						<option value="http://www.dojotoolkit.org/aggregator/rss/">Planet Dojo</option>
@@ -341,7 +346,7 @@
 					</select>
 					<div>
 					This is an ExpandableFeedPortlet with multiple available feeds, in which you
-					can only expand a single item at a time. 
+					can only expand a single item at a time.
 					Click the settings icon in the title bar to choose a feed to load.
 					</div>
 				</div>
@@ -356,11 +361,11 @@
 						loadFeed("http://feeds2.feedburner.com/quotationspage/qotd", "quotes");
 					</script>
 					<div id="quotes">
-						
+
 					</div>
 				</div>
-				
-				<div dojoType="dojox.widget.FeedPortlet" dndType="Portlet" title="Dojo Campus - Local Feed" 
+
+				<div dojoType="dojox.widget.FeedPortlet" dndType="Portlet" title="Dojo Campus - Local Feed"
 						url="testAtom.xml"
 						maxResults="5"
 						local="true"
@@ -371,7 +376,7 @@
 					intranet.
 					</div>
 				</div>
-				
+
 				<div dojoType="dojox.widget.Portlet" dndType="Portlet" title="My Flickr">
 					<div dojoType="dojox.widget.PortletSettings">
 						<div dojoType="dojox.layout.TableContainer" cols="1">
@@ -379,10 +384,10 @@
 							<div dojoType="dijit.form.TextBox" title="Option 4"></div>
 						</div>
 					</div>
-					
+
 					<div dojoType="dojox.image.SlideShow" imageWidth="300" imageHeight="300">
 						<script type="dojo/connect">
-							
+
 							var flickrRestStore = new dojox.data.FlickrRestStore();
 							var req = {
 								query: {
@@ -409,10 +414,10 @@
 
 		<div dojoType="dijit.layout.BorderContainer" title="My Files">
 			<div dojoType="dojox.layout.ExpandoPane" region="left" title="File Explorer" style="width: 230px;">
-				<div 
-					id="tree" 
-					dojoType="dijit.Tree" 
-					model="fileModel" 
+				<div
+					id="tree"
+					dojoType="dijit.Tree"
+					model="fileModel"
 					persist="false"
 					style="overflow-y: auto;height: 100%;max-width: 230px;">
 					<script type="dojo/method" event="onClick" args="item">
@@ -422,7 +427,7 @@
 					</script>
 				</div>
 			</div>
-				
+
 				<div dojoType="dojox.layout.GridContainer"
 						region="center"
 						acceptTypes="Portlet"
@@ -433,14 +438,14 @@
 						<div dojoType="dojox.widget.Portlet" dndType="Portlet" title="File Info" class="portletNoBorder">
 							<script type="dojo/connect">
 								var mapping = {
-									"fileName" : "name", 
-									"filePath": "path", 
-									"fileSize": "size", 
-									"fileModified": "modified", 
+									"fileName" : "name",
+									"filePath": "path",
+									"fileSize": "size",
+									"fileModified": "modified",
 									"fileParent":"parentDir",
 									"fileIsDir": "directory"
 								};
-								
+
 								dojo.subscribe("/fileinfo", function(store, item) {
 								  for (var dijitId in mapping) {
 										var attrib = mapping[dijitId];
@@ -452,7 +457,7 @@
 										} else if (attrib == "directory") {
 										  val = val ? "Yes" : "No";
 										}
-									
+
 									  dijit.byId(dijitId).attr("content", val);
 									}
 								});
@@ -466,8 +471,8 @@
 								<div dojoType="dijit.layout.ContentPane" label="Is Directory?:" id="fileIsDir"></div>
 							</div>
 						</div>
-					
-						<div dojoType="dojox.widget.Portlet" dndType="Portlet" title="File Contents" 
+
+						<div dojoType="dojox.widget.Portlet" dndType="Portlet" title="File Contents"
 							id="fileContentPortlet"
 								style="max-height: 350px;">
 							<script type="dojo/connect" event="startup">
@@ -480,10 +485,10 @@
 								});
 								dojo.subscribe("/fileinfo", function(store, item) {
 								  var path = dojo.config.baseUrl + "../" + store.getValue(item, "path");
-									
+
 									if (path.indexOf(".png") > -1 || path.indexOf(".jpg") > -1 || path.indexOf(".gif") > -1) {
 									  widget.attr("content", "<img src='" +path + "'>");
-									} else if(store.getValue(item, "size") > 0 
+									} else if(store.getValue(item, "size") > 0
 											&& path.indexOf(".zip") < 0
 											&& path.indexOf(".tgz") < 0){
 									  widget.attr("href", path);
@@ -494,22 +499,22 @@
 							</script>
 							<div dojoType="dijit.layout.ContentPane" id="fileContents" parseOnLoad="false">
 								<script type="dojo/method" event="_setContent" args="data, isFake">
-									if (data.indexOf("<img") != 0 && data.indexOf("<span") != 0) {
-									  data = data.replace(/</gm, "<").replace(/>/gm, ">")
+									var text = typeof data == "string" ? data : data.textContent;
+									if (text.indexOf("<img") != 0 && text.indexOf("<span") != 0) {
+									  text = text.replace(/</gm, "<").replace(/>/gm, ">")
 													.replace(/\t/g, "  ").split("\n").join("<br>");
 									}
-									dijit.layout.ContentPane.prototype._setContent.apply(this, [data, isFake]);
+									dijit.layout.ContentPane.prototype._setContent.apply(this, [text, isFake]);
 								</script>
 								File contents are loaded here.  Click on any file in the tree to see its contents.
 							</div>
 						</div>
-						
+
 						<div dojoType="dojox.widget.Portlet" dndType="Portlet" title="Selected Files">
 							<script type="dojo/connect">
-								console.log("connecting to fileModel", fileModel);
 								var timer;
-								
-							  dojo.subscribe("/fileChange", dojo.hitch(this, function(items){
+
+							  	dojo.subscribe("/fileChange", dojo.hitch(this, function(items){
 								  this._items = items;
 									if (this._started) {
 									  if (timer) {
@@ -518,104 +523,104 @@
 										timer = setTimeout(dojo.hitch(this, "updateChart"), 200);
 									}
 								}));
-									
-								</script>
-								<script type="dojo/connect" event="startup">
-									dojo.require("dojox.charting.themes.Bahamation");
-									var dc = dojox.charting;
-									
-									var container = dojo.create("div", {}, this.containerNode);
-									dojo.style(container, {"height": "300px", "width" : "300px"});
-									
-									console.log("dimensions of container are", dojo.marginBox(container));
-									
-									var chart = this.chart = new dc.Chart2D(container);	
-									chart.setTheme(dc.themes.Bahamation);
-									chart.addPlot("default", {
-										type: "Pie", 
-										font: "normal normal 11pt Tahoma", 
-										fontColor: "black", 
-										labelOffset: -30,
-										radius: 80
-									});									
-									this.updateChart();
-								</script>
-								<script type="dojo/method" event="updateChart">
-									var extensions = {};
-									var items = this._items;
-									var dc = dojox.charting;
-									
-									if (!items || items.length < 1) {
-									  return;
+
+							</script>
+							<script type="dojo/connect" event="startup">
+								dojo.require("dojox.charting.themes.Bahamation");
+								var dc = dojox.charting;
+
+								var container = dojo.create("div", {}, this.containerNode);
+								dojo.style(container, {"height": "300px", "width" : "300px"});
+
+								console.log("dimensions of container are", dojo.marginBox(container));
+
+								var chart = this.chart = new dc.Chart2D(container);
+								chart.setTheme(dc.themes.Bahamation);
+								chart.addPlot("default", {
+									type: "Pie",
+									font: "normal normal 11pt Tahoma",
+									fontColor: "black",
+									labelOffset: -30,
+									radius: 80
+								});
+								this.updateChart();
+							</script>
+							<script type="dojo/method" event="updateChart">
+								var extensions = {};
+								var items = this._items;
+								var dc = dojox.charting;
+
+								if (!items || items.length < 1) {
+								  return;
+								}
+
+								function val(item, attr) {
+								  return fileStore.getValue(item, attr);
+								}
+								function getExtension(item) {
+								  if (val(item, "directory")) {
+									  return "folder";
 									}
-									
-									function val(item, attr) {
-									  return fileStore.getValue(item, attr);
+									var str = val(item, "name");
+									var parts = str.split(".");
+									if (parts.length < 2) {
+									  return "none";
 									}
-									function getExtension(item) {
-									  if (val(item, "directory")) {
-										  return "folder";
-										}
-										var str = val(item, "name");
-										var parts = str.split(".");
-										if (parts.length < 2) {
-										  return "none";
-										}
-										return parts[1];
+									return parts[1];
+								}
+
+								dojo.forEach(items, function(item){
+								  if (val(item, "directory")) {
+									  return;
 									}
-									
-									dojo.forEach(items, function(item){
-									  if (val(item, "directory")) {
-										  return;
-										}
-									
-									  var count = extensions[getExtension(item)] ;
-										if (!count) {
-										  count = 0;
-										}
-										var ext = getExtension(item);
-										extensions[ext] = ++count;
-									});
-									var series = [];
-									for (var ext in extensions) {
-										series.push({
-										  y : extensions[ext],
-											text: ext,
-											stroke: "black",
-											tooltip: extensions[ext] + " " + 
-												(ext == "none" ? 
-												  "files with no extension" :
-													ext + " files")
-													+ " found" 
-										});
+
+								  var count = extensions[getExtension(item)] ;
+									if (!count) {
+									  count = 0;
 									}
-									
-									
-									this.chart.addSeries("Series A", series);
-								  this.chart.resize(300, 300);	
-									
-									dojo.forEach(this._anims || [], function(anim){
-									  anim.destroy();
+									var ext = getExtension(item);
+									extensions[ext] = ++count;
+								});
+								var series = [];
+								for (var ext in extensions) {
+									series.push({
+									  y : extensions[ext],
+										text: ext,
+										stroke: "black",
+										tooltip: extensions[ext] + " " +
+											(ext == "none" ?
+											  "files with no extension" :
+												ext + " files")
+												+ " found"
 									});
-									
-									this._anims = [
-									new dc.action2d.MoveSlice(this.chart, "default"),
-									new dc.action2d.Highlight(this.chart, "default"),
-									new dc.action2d.Tooltip(this.chart, "default")];
-									
-									this.chart.render();
-								</script>
-								<div>
-									This Pie chart shows the proportion of files in the Dojo toolkit.
-									As you open folders in the tree, it updates the chart.
-								</div>
+								}
+
+
+								this.chart.addSeries("Series A", series);
+							  	this.chart.resize(300, 300);
+
+								dojo.forEach(this._anims || [], function(anim){
+								  anim.destroy();
+								});
+
+								this._anims = [
+								new dc.action2d.MoveSlice(this.chart, "default"),
+								new dc.action2d.Highlight(this.chart, "default"),
+								new dc.action2d.Tooltip(this.chart, "default")];
+
+								this.chart.render();
+							</script>
+							<div>
+								This Pie chart shows the proportion of files in the Dojo toolkit.
+								As you open folders in the tree, it updates the chart.
 							</div>
-						
 						</div>
+
+					</div>
 			</div>
-		
-		</div>
-		
+
+	</div>
+
 		<table id="gridDataTable" style="display:none;">
 			<thead>
 				<tr>
@@ -630,7 +635,7 @@
 					<td >Jones</td>
 					<td >10/26/1974</td>
 				</tr>
-				<tr >				
+				<tr >
 					<td >Dee</td>
 					<td >Murphy</td>
 					<td >2/25/1936</td>
diff --git a/dojox/widget/tests/test_PortletInGridContainer.js b/dojox/widget/tests/test_PortletInGridContainer.js
index e3e4167..83852b3 100644
--- a/dojox/widget/tests/test_PortletInGridContainer.js
+++ b/dojox/widget/tests/test_PortletInGridContainer.js
@@ -33,11 +33,12 @@ dojo.require("dojox.charting.action2d.Tooltip");
 //This must be included on the page for FeedPortlets that
 //load local feeds.
 dojo.require("dojox.data.AtomReadStore");
-	
+
 dojo.require("dojo.parser");
 
 dojo.addOnLoad(function(){
 	dojo.parser.parse();
+
 	var chart = window.chart = new dojox.charting.Chart2D("zoomer");
 	chart.setTheme(dojox.charting.themes.PlotKit.orange);
 	chart.addAxis("x", {fixLower: "minor", natural: true, stroke: "grey",
@@ -54,7 +55,7 @@ dojo.addOnLoad(function(){
 	chart.addSeries("Series B", [15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15], {plot: "plot2"});
 	chart.addPlot("grid", {type: "Grid", hMinorLines: true});
 	chart.render();
-	
+
 	var show = setInterval(function(){
 		var w = dijit.byId("gridContainer");
 		if (w && w.domNode) {
@@ -62,7 +63,7 @@ dojo.addOnLoad(function(){
 			clearInterval(show);
 		}
 	}, 500);
-	
+
 
 	var scaleX = 1, scaleY = 1, offsetX = 0, offsetY = 0;
 	dojo.connect(dijit.byId("scaleXSlider"), "onChange", function(value){
@@ -70,24 +71,24 @@ dojo.addOnLoad(function(){
 		console.log("calling update");
 		update();
 	});
-	
+
 	function update() {
 		chart.setWindow(scaleX, scaleY, offsetX, offsetY).render();
 	}
-	
+
 	var _init = null;
 	var onMouseDown = function(e){
 		_init = {x: e.clientX, y: e.clientY, ox: offsetX, oy: offsetY};
 		dojo.stopEvent(e);
 	};
-	
+
 	var onMouseUp = function(e){
 		if(_init){
 			_init = null;
 			dojo.stopEvent(e);
 		}
 	};
-	
+
 	var onMouseMove = function(e){
 		if(_init){
 			var dx = e.clientX - _init.x,
@@ -98,19 +99,19 @@ dojo.addOnLoad(function(){
 			dojo.stopEvent(e);
 		}
 	};
-	
+
 	dojo.connect(chart.node, "onmousedown", onMouseDown);
 	dojo.connect(chart.node, "onmousemove", onMouseMove);
 	dojo.connect(chart.node, "onmouseup",   onMouseUp);
-	
-	
+
+
 	createProgrammaticPortlet();
 });
 
 function createProgrammaticPortlet() {
 	var portlet = new dojox.widget.FeedPortlet({
 		id: "ProgrammaticPortlet",
-		dndType: "Portlet", 
+		dndType: "Portlet",
 		title: "Programmatic FeedPortlet with multiple feeds"
 	}, dojo.create("div", {
 		innerHTML: "This portlet was created programmatically, and has mulitple feeds to select from."
@@ -120,7 +121,7 @@ function createProgrammaticPortlet() {
 		id: "ProgrammaticPortletSettings",
 		urls: [
 			{
-				url: "http://news.google.com/news?hl=en&topic=t&output=atom", 
+				url: "http://news.google.com/news?hl=en&topic=t&output=atom",
 				label: "Google News"
 			},
 			{
@@ -139,7 +140,7 @@ function createProgrammaticPortlet() {
 
 var count = 0;
 function loadFeed(url, nodeId, emptyMsg, type) {
-	
+
 	var query = {
 		url: url
 	};
@@ -159,10 +160,10 @@ function loadFeed(url, nodeId, emptyMsg, type) {
 	      var ul = dojo.create("ul", null, outNode);
 				dojo.forEach(items, function(item){
 					var li = dojo.create("li", {
-						innerHTML: '<a href="' + testStore.getValue(item, 'link') + '">' 
+						innerHTML: '<a href="' + testStore.getValue(item, 'link') + '">'
 												+ testStore.getValue(item, 'title') + '</a>'
 					},ul);
-					
+
 					dojo.connect(li, "onmouseover", function() {
 						dijit.showTooltip(testStore.getValue(item, "content"), li);
 					});
@@ -174,10 +175,10 @@ function loadFeed(url, nodeId, emptyMsg, type) {
 			else {
 				var accordion = new dijit.layout.AccordionContainer({});
 				dojo.byId(nodeId).appendChild(accordion.domNode);
-				
+
 				dojo.forEach(items, function(item){
 					var summary = testStore.getValue(item, "title");
-					
+
 					if (summary.length > 40) {
 						summary = summary.substring(0, 50);
 					}
@@ -189,7 +190,7 @@ function loadFeed(url, nodeId, emptyMsg, type) {
 					accordion.addChild(contentPane);
 					contentPane.startup();
 				});
-				
+
 				var portlet = dijit.getEnclosingWidget(dojo.byId(nodeId));
 				portlet.addChild(accordion);
 			}
@@ -214,9 +215,9 @@ var layoutHtmlTable = [
 		{name: 'DOB', field: 'DOB', width: '25%'}
 		]
 	];
-			
+
 var text_explode_2 = function(node){
-	
+
 	if(node.style.height){
 		return;
 	}
diff --git a/dojox/widget/tests/test_Standby.html b/dojox/widget/tests/test_Standby.html
index 47dba5e..ae929db 100755
--- a/dojox/widget/tests/test_Standby.html
+++ b/dojox/widget/tests/test_Standby.html
@@ -12,8 +12,9 @@
 			background-color: darkblue;
 			width: 250px;
 			height: 250px;
+			border-radius: 15px;
 			-moz-border-radius: 15px 15px 15px 15px; 
-			-webkit-border-radius: 15px;"        
+			-webkit-border-radius: 15px;"
 		}
 	</style>
 	
@@ -148,8 +149,8 @@
 			var overlay18= dijit.byId("standby18");
 			connects.push(dojo.connect(button35, "onClick", function(){
 				showCount++;
-				console.log(overlay18.attr("text"));
-				overlay18.attr("text", "Shown: " + showCount);
+				console.log(overlay18.get("text"));
+				overlay18.set("text", "Shown: " + showCount);
 				overlay18.show()}));
 			connects.push(dojo.connect(button36, "onClick", function(){overlay18.hide()}));
 
@@ -159,8 +160,8 @@
 			var button38 = dijit.byId("overlay19Button2");
 			var overlay19= dijit.byId("standby19");
 			connects.push(dojo.connect(button37, "onClick", function(){
-				console.log(overlay19.attr("color"));
-				overlay19.attr("color", colors[cPos]);
+				console.log(overlay19.get("color"));
+				overlay19.set("color", colors[cPos]);
 				cPos++;
 				if(cPos === colors.length - 1){
 					cPos = 0;
@@ -268,7 +269,7 @@
 	<button id ="overlay6Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay6Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div id ="overlayTarget6" style="width: 200px; height: 100px; background-color: darkblue; -moz-border-radius: 15px; -webkit-border-radius: 15px;"></div>
+	<div id ="overlayTarget6" style="width: 200px; height: 100px; background-color: darkblue; border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px;"></div>
 	<div id ="standby6" target="overlayTarget6" dojoType="dojox.widget.Standby"></div>
 	<hr>
 
@@ -276,7 +277,7 @@
 	<button id ="overlay7Button1" dojoType="dijit.form.Button">Click to show the standby overlay</button>
 	<br>
 	<button id ="overlay7Button2" dojoType="dijit.form.Button">Click to hide the standby overlay</button>
-	<div id ="overlayTarget7" style="width: 200px; height: 100px; background-color: darkblue; -moz-border-radius: 15px; -webkit-border-radius: 15px; margin: auto"></div>
+	<div id ="overlayTarget7" style="width: 200px; height: 100px; background-color: darkblue; border-radius: 15px; -moz-border-radius: 15px; -webkit-border-radius: 15px; margin: auto"></div>
 	<div id ="standby7" target="overlayTarget7" dojoType="dojox.widget.Standby" color="lightblue"></div>
 	<hr>
 
diff --git a/dojox/widget/tests/test_Standby_quirks.html b/dojox/widget/tests/test_Standby_quirks.html
index 1b82fc6..e858b94 100755
--- a/dojox/widget/tests/test_Standby_quirks.html
+++ b/dojox/widget/tests/test_Standby_quirks.html
@@ -147,8 +147,8 @@
 			var overlay18= dijit.byId("standby18");
 			connects.push(dojo.connect(button35, "onClick", function(){
 				showCount++;
-				console.log(overlay18.attr("text"));
-				overlay18.attr("text", "Shown: " + showCount);
+				console.log(overlay18.get("text"));
+				overlay18.set("text", "Shown: " + showCount);
 				overlay18.show()}));
 			connects.push(dojo.connect(button36, "onClick", function(){overlay18.hide()}));
 
@@ -158,8 +158,8 @@
 			var button38 = dijit.byId("overlay19Button2");
 			var overlay19= dijit.byId("standby19");
 			connects.push(dojo.connect(button37, "onClick", function(){
-				console.log(overlay19.attr("color"));
-				overlay19.attr("color", colors[cPos]);
+				console.log(overlay19.get("color"));
+				overlay19.set("color", colors[cPos]);
 				cPos++;
 				if(cPos === colors.length - 1){
 					cPos = 0;
diff --git a/dojox/widget/tests/test_Standby_rtl.html b/dojox/widget/tests/test_Standby_rtl.html
index b7b1f08..f315f5b 100755
--- a/dojox/widget/tests/test_Standby_rtl.html
+++ b/dojox/widget/tests/test_Standby_rtl.html
@@ -148,8 +148,8 @@
 			var overlay18= dijit.byId("standby18");
 			connects.push(dojo.connect(button35, "onClick", function(){
 				showCount++;
-				console.log(overlay18.attr("text"));
-				overlay18.attr("text", "Shown: " + showCount);
+				console.log(overlay18.get("text"));
+				overlay18.set("text", "Shown: " + showCount);
 				overlay18.show()}));
 			connects.push(dojo.connect(button36, "onClick", function(){overlay18.hide()}));
 
@@ -159,8 +159,8 @@
 			var button38 = dijit.byId("overlay19Button2");
 			var overlay19= dijit.byId("standby19");
 			connects.push(dojo.connect(button37, "onClick", function(){
-				console.log(overlay19.attr("color"));
-				overlay19.attr("color", colors[cPos]);
+				console.log(overlay19.get("color"));
+				overlay19.set("color", colors[cPos]);
 				cPos++;
 				if(cPos === colors.length - 1){
 					cPos = 0;
diff --git a/dojox/widget/tests/test_TitleGroup.html b/dojox/widget/tests/test_TitleGroup.html
new file mode 100644
index 0000000..3d126e2
--- /dev/null
+++ b/dojox/widget/tests/test_TitleGroup.html
@@ -0,0 +1,106 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+		"http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+	
+	<title>Dojox TitleGroup Test</title>
+	
+	<!-- required: a default theme file, and ColorPicker css -->
+	<link rel="stylesheet" id="themeStyles" href="../../../dijit/themes/claro/claro.css">
+	<link rel="stylesheet" href="../TitleGroup/TitleGroup.css">
+
+	<style type="text/css">
+		@import "../../../dojo/resources/dojo.css";
+		@import "../../../dijit/tests/css/dijitTests.css"; 
+		
+		#bar, #bar2 { 
+			width:300px;
+			float:left;
+			margin-right:15px;
+		}
+		
+		.clear {
+			clear:both;
+		}
+	</style>
+
+	<!-- 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 -->
+	<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">
+
+	<h1 class="testTitle">Dojox TitleGroup test</h1>
+
+	<div id="bar" dojoType="dojox.widget.TitleGroup">
+		<div dojoType="dijit.TitlePane" open="true" title="Title 1">Yellow.</div>
+		<div dojoType="dijit.TitlePane" open="false" title="Title b">Heeeeee<br><br>hawwwww</div>
+		<div dojoType="dijit.TitlePane" open="false" title="Title 3"><p style="font-size:27pt">WOW</p></div>
+		<div dojoType="dijit.TitlePane" open="false" title="Title d"><p>a button.</p>
+			<button dojoType="dijit.form.Button">Label</button>
+		</div>
+		<div dojoType="dijit.TitlePane" open="false" title="Title 4 (href)" href="get_time.php"></div>
+	</div>
+
+	<div id="bar2" dojoType="dojox.widget.TitleGroup">
+		<div dojoType="dijit.TitlePane" open="false" title="Title 1" open="open">Yellow.</div>
+		<div dojoType="dijit.TitlePane" open="true" title="Title b">Heeeeee<br><br>hawwwww</div>
+		<div dojoType="dijit.TitlePane" open="false" title="Title 3"><p style="font-size:27pt">WOW</p></div>
+		<div dojoType="dijit.TitlePane" open="false" title="Title d (embedded TitlePanes)">
+			<h3>See:</h3>
+			<div dojoType="dijit.TitlePane" title="I should open fine">
+				<h3>See:</h3>
+				<div dojoType="dijit.TitlePane" title="I should open fine too">
+					<p>Did i?</p>
+				</div>
+			</div>
+		</div>
+	</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 202ea79..1d390b3 100644
--- a/dojox/widget/tests/test_Wizard.html
+++ b/dojox/widget/tests/test_Wizard.html
@@ -1,16 +1,15 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-        "http://www.w3.org/TR/html4/strict.dtd">
+<!DOCTYPE html>
 <html>
 <head>
 
-	<title>Wizard Demo</title>
+	<title>Wizard Test</title>
 
 	<!-- required: a default theme file, and Wizard styles -->
-	<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="../Wizard/Wizard.css">
 	
 	<!-- required: dojo.js -->
-	<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="isDebug:true, parseOnLoad: true"></script>
+	<script type="text/javascript" src="../../../dojo/dojo.js" data-dojo-config="isDebug:true, parseOnLoad: true"></script>
 
 	<!-- do not use! only for testing dynamic themes -->
 	<script type="text/javascript" src="../../../dijit/tests/_testCommon.js"></script>
@@ -20,6 +19,7 @@
 	<script type="text/javascript">
 		dojo.require("dojox.widget.Wizard");
 	
+		dojo.require("dijit.Dialog");
 		dojo.require("dijit.layout.AccordionContainer");
 		dojo.require("dijit.layout.ContentPane");
 		dojo.require("dijit.layout.TabContainer");
@@ -28,7 +28,7 @@
 		function cancel() {
 			alert("Wizard Cancelled!");
 		}
-	    
+		
 		function done() {
 			alert("Wizard Done!");
 		}
@@ -37,18 +37,16 @@
 			
 			var wizard = new dojox.widget.Wizard({
 				style:"width:300px; height:300px"
-			}).placeAt(dojo.body(),"last");
+			}).placeAt("programaticContainer");
 			
 			var contents = [
 				"Pane 1 content", "Pane 2 content", "<h3>Done!</h3>"
 			];
 			
 			dojo.forEach(contents, function(term){
-			
-				new dojox.widget.WizardPane({})
-					.placeAt(wizard)
-					.attr("content", term)
-				;
+				new dojox.widget.WizardPane({
+					content: term
+				}).placeAt(wizard);
 			});
 			wizard.startup();
 			
@@ -62,43 +60,106 @@
 		body {
 			font-family : sans-serif;
 		}
+		.floater {
+			float:left;
+			margin-right:15px;
+			margin-bottom:8px;
+		}
 	</style>
 </head>
 
-<body class="tundra">
+<body class="claro">
 
-	<div style="width:800px; margin:0 auto">
+	<h1 class="testTitle">dojox.widget.Wizard tests</h1>
 
-		<h1 class="testTitle">dojox.widget.Wizard tests</h1>
+	<div class="floater">
+		<p>Test a wizard in a Dialog:</p>
+		<button data-dojo-type="dijit.form.Button" id="showDialog">
+			Show Dialog
+			<script type="dojo/connect" data-dojo-event="onClick">
+				dijit.byId("wizardDialog").show();
+			</script>
+		</button>
+		
+		<div id="wizardDialog" data-dojo-type="dijit.Dialog" data-dojo-props="title:'Wizard Dialog'">
+			<div data-dojo-type="dojox.widget.Wizard" data-dojo-props="style:'height:300px; width:400px'">
+				<div dojoType="dojox.widget.WizardPane">
+					<p>The next two (hidden) children container AccordionContainers. You'll have to be
+						more careful about the styling / sizing, as the child wants to take 100% of
+						it's height. You can size explicitly if you like, or add margin-bottom to
+						leave room for the buttons
+					</p>
+				</div>
+				<div dojoType="dojox.widget.WizardPane" style="padding:8px">
+					<div dojoType="dijit.layout.AccordionContainer">
+						<div title="foo" dojoType="dijit.layout.ContentPane">
+							foo.
+						</div>
+						<div title="bar" dojoType="dijit.layout.ContentPane">
+							foo.
+						</div>
+					</div>
+				</div>
+				<div dojoType="dojox.widget.WizardPane" style="padding:8px">
+					<div dojoType="dijit.layout.BorderContainer">
+						<div region="left" style="width:75px" dojoType="dijit.layout.ContentPane">
+							left pane
+						</div>
+						<div region="center" dojoType="dijit.layout.ContentPane">
+							main pane
+						</div>
+						<div dojoType="dijit.layout.ContentPane" region="right" style="width:75px">
+							right pane
+						</div>
+					</div>
+				</div>
+				<div dojoType="dojox.widget.WizardPane" style="padding:8px">
+					<div dojoType="dijit.layout.TabContainer">
+						<div title="tab1" dojoType="dijit.layout.ContentPane">
+							foo
+						</div>
+						<div title="tab2" dojoType="dijit.layout.ContentPane">
+							foo
+						</div>
+						<div title="tab3" dojoType="dijit.layout.ContentPane">
+							foo
+						</div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
 
+	<div class="floater">
+		
 		<p>This example shows a wizard with customized button labels.</p>
-
-		<div id="wizard1" dojoType="dojox.widget.Wizard"
-			 style="width: 640px; height: 200px;"
-			 nextButtonLabel="Go on"
-			 >
-			<div dojoType="dojox.widget.WizardPane" title="Tab 1">
+		
+		<div id="wizard1" data-dojo-type="dojox.widget.Wizard" data-dojo-props="
+			style:'width:400px; height:200px',
+			nextButtonLabel:'Go on'
+		">
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props='title:"Tab 1"'>
 				<h1>Tab 1</h1>
 				<p>Sized content, box one</p>
 			</div>
-			<div dojoType="dojox.widget.WizardPane">
+			<div data-dojo-type="dojox.widget.WizardPane">
 				<h1>Tab 2</h1>
 			</div>
-			<div dojoType="dojox.widget.WizardPane">
+			<div data-dojo-type="dojox.widget.WizardPane">
 				<h1>Tab 3</h1>
 	
 				You won't be able to come back, but you can finish now...
-				<script type='dojo/method' event="doneFunction">
+				<script type='dojo/method' data-dojo-event="doneFunction">
 					done();
 					console.log('inline done function called');
 				</script>
 			</div>
-			<div dojoType="dojox.widget.WizardPane" canGoBack="false">
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props="canGoBack:false">
 				<h1>Tab 4</h1>
 	
 				... and now you can't go back.
 			</div>
-			<div dojoType="dojox.widget.WizardPane" doneFunction="done">
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props='doneFunction:done'>
 				<h1>Tab 5</h1>
 				... and now you can finish up.
 			</div>
@@ -107,10 +168,13 @@
 				this.destroy();
 			</script>
 		</div>
+	</div>
 	
+	<div class="floater">
+		
 		<p>The next shows the option to hide the inactive buttons, with a smaller width...</p>
 	
-		<div id="wizard2" dojoType="dojox.widget.Wizard" hideDisabled="true" style="width: 50%; height: 200px;">
+		<div id="wizard2" dojoType="dojox.widget.Wizard" hideDisabled="true" style="width: 300px; height: 200px;">
 			<div dojoType="dojox.widget.WizardPane">
 				<h1>Step 1 of 3</h1>
 				<p>Lorem ipsum dolor sit amet</p>
@@ -125,8 +189,12 @@
 			</div>
 		</div>
 
+	</div>
+	<div class="floater">
+		
 		<p>Layout Children</p>
-		<div id="wizard2lay" dojoType="dojox.widget.Wizard" hideDisabled="true" style="width: 50%; height: 240px;">
+		
+		<div id="wizard2lay" dojoType="dojox.widget.Wizard" hideDisabled="true" style="width: 300px; height: 240px;">
 			<div dojoType="dojox.widget.WizardPane">
 				<p>The next two (hidden) children container AccordionContainers. You'll have to be
 					more careful about the styling / sizing, as the child wants to take 100% of
@@ -170,23 +238,24 @@
 					</div>
 				</div>
 			</div>
-			
-			
 		</div>
-
+	</div>
+	
+	<div class="floater">
 	
 		<p>The next shows blocking moving to the next step with a JS function...</p>
 	
 		<script>
-			function checkAgreement() {
-				var frm = document.forms['acceptAgreement'];
+			function checkAgreement(name) {
+				var frm = document.forms[name || 'acceptAgreement'];
 				var accept = frm.accept;
 				if (!accept.checked) {
 					return "You must agree to the terms before continuing.";
 				}
 			}
 		</script>
-		<div id="wizard3" dojoType="dojox.widget.Wizard" style="width: 600px; height: 400px; margin:0 auto;">
+		
+		<div id="wizard3" data-dojo-type="dojox.widget.Wizard" style="width: 420px; height: 400px; margin:0 auto;">
 			<div dojoType="dojox.widget.WizardPane" id="Agreement1" passFunction="checkAgreement">
 				<h1>Agreement Terms</h1>
 	
@@ -205,31 +274,59 @@
 			</div>
 		</div>
 
-			<h2>Another like above, but with dojo/method passFunction</h2>
-			<div id="wizard4" dojoType="dojox.widget.Wizard" style="width: 600px; height: 400px; margin:0 auto;">
-				<div dojoType="dojox.widget.WizardPane" id="Agreement12">
-					<script type="dojo/method" event="passFunction">
-						return "cant do that yet";
-					</script>
-					<h1>Agreement Terms</h1>
-
-					<div dojoType="dijit.layout.ContentPane" style="width:400px; border:1px solid #b7b7b7; background:#fff; padding:8px; margin:0 auto; height:200px; overflow:auto; "
-						href="../../../dojo/LICENSE"></div>
-
-					<form action="#" name="acceptAgreement">
-						<p>
-						<input type="checkbox" name="accept" value="true"/> I accept the terms of this agreement.
-						</p>
-					</form>
-				</div>
-				<div dojoType="dojox.widget.WizardPane" canGoBack="false">
-					<h1>Complete</h1>
-					<p>The license has been accepted.</p>
-				</div>
+	</div>
+
+	<div class="floater">
+		
+		<p>Another like above, but with dojo/method passFunction</p>
+		<div id="wizard4" dojoType="dojox.widget.Wizard" style="width: 500px; height: 400px;">
+			<div data-dojo-type="dojox.widget.WizardPane" id="Agreement12">
+				<script type="dojo/method" data-dojo-event="passFunction">
+					return checkAgreement("acceptAgreementDos");
+				</script>
+				<h1>Agreement Terms</h1>
+
+				<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props='
+					href:"../../../dojo/LICENSE",
+					style:"width:400px; border:1px solid #b7b7b7; background:#fff; padding:8px; margin:0 auto; height:200px; overflow:auto; "
+				'></div>
+
+				<form action="#" name="acceptAgreementDos">
+					<p>
+					<input type="checkbox" name="accept" value="true"/> I accept the terms of this agreement.
+					</p>
+				</form>
 			</div>
-			
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props="canGoBack:false">
+				<h1>Complete</h1>
+				<p>The license has been accepted.</p>
+			</div>
+		</div>	
+	</div>
+	
+	<div class="floater" id="programaticContainer">
+		<p>A Programatic Wizard should appear here</p>
 	</div>
 
+	<div class="floater">
+		<p>This should overflow, <em>badly</em>:</p>
+		<div id="weezard" data-dojo-type="dojox.widget.Wizard" data-dojo-props="
+			style:'height:300px; width:300px'
+		">
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props="
+				href:'../../../dojo/LICENSE'
+			"></div>
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props="
+				href:'../../../dojo/LICENSE'
+			"></div>
+			<div data-dojo-type="dojox.widget.WizardPane" data-dojo-props="
+				href:'../../../dojo/LICENSE'
+			"></div>
+		</div>
+	</div>
+	
+	<div style="clear:both">That's all, folks.</div>
+	
 </body>
 </html>
 
diff --git a/dojox/widget/tests/withjs.html b/dojox/widget/tests/withjs.html
new file mode 100644
index 0000000..2b12d72
--- /dev/null
+++ b/dojox/widget/tests/withjs.html
@@ -0,0 +1,4 @@
+<p>I am HTML</p>
+<script>
+	console.warn("I am JS");
+</script>
\ No newline at end of file
diff --git a/dojox/wire/DataWire.js b/dojox/wire/DataWire.js
index e18c8ed..01f2327 100644
--- a/dojox/wire/DataWire.js
+++ b/dojox/wire/DataWire.js
@@ -132,7 +132,7 @@ dojo.declare("dojox.wire.DataWire", dojox.wire.Wire, {
 		}else{
 			value = this.dataStore.getValue(item, attribute);
 		}
-		return value; //anything 
+		return value; //anything
 	},
 
 	_setAttributeValue: function(/*Object*/item, /*String*/attribute, /*anything*/value){
diff --git a/dojox/wire/Wire.js b/dojox/wire/Wire.js
index 7ba703d..ffd2459 100644
--- a/dojox/wire/Wire.js
+++ b/dojox/wire/Wire.js
@@ -57,7 +57,7 @@ dojo.declare("dojox.wire.Wire", null, {
 							this.converter = testObj;
 						}
 					}catch(e){
-						//Do if this fails.	
+						//Do if this fails.
 					}
 				}else if(dojo.isObject(convertObject)){
 					//It's an object, like a jsId ... see if it has a convert function
@@ -66,7 +66,7 @@ dojo.declare("dojox.wire.Wire", null, {
 					}
 				}
 
-				//No object with that name (Converter is still a string), 
+				//No object with that name (Converter is still a string),
 				//then look for a class that needs to be dynamically loaded...
 				if(dojo.isString(this.converter)){
 					var converterClass = dojox.wire._getClass(this.converter);
diff --git a/dojox/wire/XmlWire.js b/dojox/wire/XmlWire.js
index ca5e0af..90dd60e 100644
--- a/dojox/wire/XmlWire.js
+++ b/dojox/wire/XmlWire.js
@@ -202,7 +202,7 @@ dojo.declare("dojox.wire.XmlWire", dojox.wire.Wire, {
 		//	node:
 		//		A parent node
 		//	name:
-		//		A tag name	
+		//		A tag name
 		//	returns:
 		//		A child node
 		var index = 1;
diff --git a/dojox/wire/_base.js b/dojox/wire/_base.js
index d508a53..6f1aeca 100644
--- a/dojox/wire/_base.js
+++ b/dojox/wire/_base.js
@@ -32,7 +32,7 @@ dojox.wire.register = function(/*Function||String*/wireClass, /*String*/key){
 
 dojox.wire._getClass = function(/*String*/name){
 	//	summary:
-	//		Returns a class 
+	//		Returns a class
 	//	description:
 	//		The class is loaded by dojo.require() and returned
 	//		by dojo.getObject().
diff --git a/dojox/wire/demos/WidgetRepeater.js b/dojox/wire/demos/WidgetRepeater.js
index 9cdea16..6585520 100644
--- a/dojox/wire/demos/WidgetRepeater.js
+++ b/dojox/wire/demos/WidgetRepeater.js
@@ -7,7 +7,7 @@ dojo.require("dijit._Container");
 
 dojo.declare("dojox.wire.demos.WidgetRepeater", [ dijit._Widget, dijit._Templated, dijit._Container ], {
 	//	summary:
-	//		Simple widget that does generation of widgets repetatively, based on calls to 
+	//		Simple widget that does generation of widgets repetatively, based on calls to
 	//		the createNew function and contains them as child widgets.
 	templateString: "<div class='WidgetRepeater' dojoAttachPoint='repeaterNode'></div>",
 	widget: null,
@@ -15,7 +15,7 @@ dojo.declare("dojox.wire.demos.WidgetRepeater", [ dijit._Widget, dijit._Template
 	createNew: function(obj){
 		//	summary:
 		//		Function to handle the creation of a new widget and appending it into the widget tree.
-		//	obj:	
+		//	obj:
 		//		The parameters to pass to the widget.
 		try{
 			if(dojo.isString(this.widget)){
diff --git a/dojox/wire/ml/Action.js b/dojox/wire/ml/Action.js
index 542db29..a36d7a5 100644
--- a/dojox/wire/ml/Action.js
+++ b/dojox/wire/ml/Action.js
@@ -161,7 +161,7 @@ dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, {
 
 	filter: function(){
 		//	summary:
-		//		Check if a required property is specified.  Also, if provided, check to see 
+		//		Check if a required property is specified.  Also, if provided, check to see
 		//		if the required property contains a specific value.
 		//	description:
 		//		If a value is undefined for a property, specified with
@@ -177,7 +177,7 @@ dojo.declare("dojox.wire.ml.ActionFilter", dijit._Widget, {
 		//		If 'required' starts with "arguments", a property of
 		//		the method arguments are checked.
 		//	returns:
-		//		True if a required property is specified (and if requiredValue is specified, 
+		//		True if a required property is specified (and if requiredValue is specified,
 		//		that they match), otherwise false
 		if(this.required === ""){
 			return true; //Boolean
diff --git a/dojox/xml/DomParser.js b/dojox/xml/DomParser.js
index 804c2ce..43c0c3b 100644
--- a/dojox/xml/DomParser.js
+++ b/dojox/xml/DomParser.js
@@ -12,8 +12,8 @@ dojox.xml.DomParser=new (function(){
 	 *	was to keep the resulting object model entirely JS-like.
 	 *
 	 *	All node types but document fragments are supported;
-	 *	all nodes support getElementsByTagName and 
-	 *	getElementsByTagNameNS (with short names byName and 
+	 *	all nodes support getElementsByTagName and
+	 *	getElementsByTagNameNS (with short names byName and
 	 *	byNameNS).  The document node supports getElementById
 	 *	(byId), and all nodes support a supplimental
 	 *	childrenByName/childrenByNameNS method as well.
@@ -21,7 +21,7 @@ dojox.xml.DomParser=new (function(){
 	 *	The object model is intended to be a READONLY format;
 	 *	mutation events are NOT supported, and though you
 	 *	can change properties on a node-by-node basis, certain
-	 *	operations are not supported (such as changing the ID 
+	 *	operations are not supported (such as changing the ID
 	 *	of an element).
 	 **********************************************************/
 
@@ -126,7 +126,7 @@ dojox.xml.DomParser=new (function(){
 	}
 
 	function _createTextNode(v){
-		return { 
+		return {
 			nodeType:nodeTypes.TEXT,
 			nodeName:"#text",
 			nodeValue:v.replace(normalize," ").replace(egt,">").replace(elt,"<").replace(eapos,"'").replace(equot,'"').replace(eamp,"&")
@@ -215,9 +215,9 @@ dojox.xml.DomParser=new (function(){
 				reEntity.lastIndex=0;
 				//	match entities
 				while((entity=reEntity.exec(str))!=null){
-					eRe.push({ 
-						entity:"&"+entity[1].replace(trim,"")+";", 
-						expression:entity[2] 
+					eRe.push({
+						entity:"&"+entity[1].replace(trim,"")+";",
+						expression:entity[2]
 					});
 				}
 				//	replace instances in the document.
@@ -258,44 +258,44 @@ dojox.xml.DomParser=new (function(){
 					//	processing instruction
 					var name=res[1].substr(1);
 					var target=res[2].substr(0,res[2].length-2);
-					obj.childNodes.push({ 
-						nodeType:nodeTypes.PROCESSING_INSTRUCTION, 
-						nodeName:name, 
-						nodeValue:target 
+					obj.childNodes.push({
+						nodeType:nodeTypes.PROCESSING_INSTRUCTION,
+						nodeName:name,
+						nodeValue:target
 					});
 				}
 				else if(res[1].charAt(0)=="!"){
 					//	CDATA; skip over any declaration elements.
 					if(res[1].indexOf("![CDATA[")==0){
 						var val=parseInt(res[1].replace("![CDATA[","").replace("]]",""));
-						obj.childNodes.push({ 
-							nodeType:nodeTypes.CDATA_SECTION, 
-							nodeName:"#cdata-section", 
-							nodeValue:cdSections[val] 
+						obj.childNodes.push({
+							nodeType:nodeTypes.CDATA_SECTION,
+							nodeName:"#cdata-section",
+							nodeValue:cdSections[val]
 						});
 					}
 					//	Comments.
 					else if(res[1].substr(0,3)=="!--"){
 						var val=parseInt(res[1].replace("!--","").replace("--",""));
-						obj.childNodes.push({ 
-							nodeType:nodeTypes.COMMENT, 
-							nodeName:"#comment", 
-							nodeValue:comments[val] 
+						obj.childNodes.push({
+							nodeType:nodeTypes.COMMENT,
+							nodeName:"#comment",
+							nodeValue:comments[val]
 						});
 					}
 				}
 				else {
 					//	Elements (with attribute and text)
 					var name=res[1].replace(trim,"");
-					var o={ 
-						nodeType:nodeTypes.ELEMENT, 
-						nodeName:name, 
-						localName:name, 
-						namespace:dNs, 
-						ownerDocument:root, 
-						attributes:[], 
-						parentNode:null, 
-						childNodes:[] 
+					var o={
+						nodeType:nodeTypes.ELEMENT,
+						nodeName:name,
+						localName:name,
+						namespace:dNs,
+						ownerDocument:root,
+						attributes:[],
+						parentNode:null,
+						childNodes:[]
 					};
 
 					//	check to see if it's namespaced.
@@ -346,11 +346,11 @@ dojox.xml.DomParser=new (function(){
 									ns=t[0];
 								}
 								o.attributes.push({
-									nodeType:nodeTypes.ATTRIBUTE, 
-									nodeName:name, 
-									localName:ln, 
-									namespace:ns, 
-									nodeValue:val 
+									nodeType:nodeTypes.ATTRIBUTE,
+									nodeName:name,
+									localName:ln,
+									namespace:ns,
+									nodeValue:val
 								});
 
 								//	only add id as a property.
diff --git a/dojox/xml/parser.js b/dojox/xml/parser.js
index 7486cfc..1d8ae4c 100644
--- a/dojox/xml/parser.js
+++ b/dojox/xml/parser.js
@@ -20,7 +20,7 @@ dojox.xml.parser.parse = function(/*String?*/ str, /*String?*/ mimetype){
 	//		cross-browser implementation of creating an XML document object from null, empty string, and XML text..
 	//
 	//	str:
-	//		Optional text to create the document from.  If not provided, an empty XML document will be created.  
+	//		Optional text to create the document from.  If not provided, an empty XML document will be created.
 	//		If str is empty string "", then a new empty document will be created.
 	//	mimetype:
 	//		Optional mimetype of the text.  Typically, this is text/xml.  Will be defaulted to text/xml if not provided.
@@ -60,7 +60,7 @@ dojox.xml.parser.parse = function(/*String?*/ str, /*String?*/ mimetype){
 			if(pe.errorCode !== 0){
 				throw new Error("Line: " + pe.line + "\n" +
 					"Col: " + pe.linepos + "\n" +
-					"Reason: " + pe.reason + "\n" + 
+					"Reason: " + pe.reason + "\n" +
 					"Error Code: " + pe.errorCode + "\n" +
 					"Source: " + pe.srcText);
 			}
@@ -91,7 +91,7 @@ dojox.xml.parser.textContent = function(/*Node*/node, /*String?*/text){
 	//		Implementation of the DOM Level 3 attribute; scan node for text
 	//	description:
 	//		Implementation of the DOM Level 3 attribute; scan node for text
-	//		This function can also update the text of a node by replacing all child 
+	//		This function can also update the text of a node by replacing all child
 	//		content of the node.
 	//	node:
 	//		The node to get the text off of or set the text on.
diff --git a/dojox/xml/tests/parser.js b/dojox/xml/tests/parser.js
index 5017adb..68f6916 100755
--- a/dojox/xml/tests/parser.js
+++ b/dojox/xml/tests/parser.js
@@ -1,7 +1,7 @@
 dojo.provide("dojox.xml.tests.parser");
 dojo.require("dojox.xml.parser");
 
-tests.register("dojox.xml.tests.parser", 
+tests.register("dojox.xml.tests.parser",
 	[
 		function testParse(t){
 			var document = dojox.xml.parser.parse();
diff --git a/dojox/xml/widgetParser.js b/dojox/xml/widgetParser.js
index 55055e1..fdc0649 100644
--- a/dojox/xml/widgetParser.js
+++ b/dojox/xml/widgetParser.js
@@ -18,7 +18,7 @@ dojo.require("dojo.parser");
 	 * 		<div>...</div>
 	 * 	</dijit.layout.SplitContainer>
 	 * </body>
-	 * 
+	 *
 	 * This is very tricky because if we parse this as XML then the <div> tag
 	 * is actually an XML tag, not an XML tag, which is problematic in at least
 	 * IE.
@@ -27,19 +27,19 @@ dojo.require("dojo.parser");
 	 * nodes, including the dijit.layout.SplitContainer by converting it to a
 	 * div with the dojoType. Then run it through the standard parser.
 	 * The more HTML you have relative to XML the less extra overhead this is.
-	 * 
+	 *
 	 * For something that is all XML we could have a different approach,
 	 * perhaps signified by a different type of script tag. In that case we
 	 * could just instantiate all the elements without a sourceNodeRef and then
 	 * add the top level components to the app.
-	 * 
+	 *
 	 * That is very straightforward but I haven't done it.
-	 * 
+	 *
 	 * Right now there is no mechanism to have an intermediary bridge between
 	 * the XML and the widget, because we are relying on dojo.parser
 	 * to do the instantiation. It isn't clear to me why we would want
 	 * those bridges in this approach and not in that approach.
-	 * 
+	 *
 	 */
 
 dojox.xml.widgetParser = new function(){
@@ -106,16 +106,16 @@ dojox.xml.widgetParser = new function(){
 			/**
 			 * This is a horrible hack we need because creating a <div>
 			 * with <option> children doesn't work well. Specifically with
-			 * dojo.Declaration at some point the <option> tags get lost 
+			 * dojo.Declaration at some point the <option> tags get lost
 			 * entirely so we need the parent of <option> tags to be <select>
 			 * tags. (Not a problem outside of dojo.Delcaration)
 			 * There are a couple other ways we could do this:
-			 * 1. Look at the first element child to see if it is an option and 
+			 * 1. Look at the first element child to see if it is an option and
 			 * if so create a <select> here.
-			 * 2. When we add a child to parent fix up the parent then if the 
+			 * 2. When we add a child to parent fix up the parent then if the
 			 * child is an <option> and the parent isn't a <select>.
 			 * Both of those are a bit messy and slower than this.
-			 * 
+			 *
 			 * This is potentially a problem for other tag combinations as well,
 			 * such as <tr> under a <table> or <li> under a <ul>/<ol>.
 			 * (dojox.widget.SortList for example). Probably need a robust strategy for
diff --git a/dojox/xmpp/ChatService.js b/dojox/xmpp/ChatService.js
index e40c264..365d219 100644
--- a/dojox/xmpp/ChatService.js
+++ b/dojox/xmpp/ChatService.js
@@ -35,7 +35,7 @@ dojo.declare("dojox.xmpp.ChatService", null, {
 	},
 	
 	invite: function(contact){
-		if (this.uid){return;}	
+		if (this.uid){return;}
 
 
 		if(!contact || contact==''){
@@ -51,7 +51,7 @@ dojo.declare("dojox.xmpp.ChatService", null, {
 			type: "chat"
 		}
 		var request = new dojox.string.Builder(dojox.xmpp.util.createElement("message", req, false));
-		request.append(dojox.xmpp.util.createElement("thread",{},false));	
+		request.append(dojox.xmpp.util.createElement("thread",{},false));
 		request.append(this.chatid);
 		request.append("</thread>");
 		request.append(dojox.xmpp.util.createElement("active",{xmlns: dojox.xmpp.chat.CHAT_STATE_NS},true));
@@ -125,17 +125,17 @@ dojo.declare("dojox.xmpp.ChatService", null, {
 			type: "chat"
 		}
 
-		var request = new dojox.string.Builder(dojox.xmpp.util.createElement("message",req,false));	
+		var request = new dojox.string.Builder(dojox.xmpp.util.createElement("message",req,false));
 		request.append(dojox.xmpp.util.createElement(state, {xmlns: dojox.xmpp.chat.CHAT_STATE_NS},true));
 		this._currentState = state;
 		request.append("<thread>");
 		request.append(this.chatid);
-		request.append("</thread></message>");	
+		request.append("</thread></message>");
 		
 		this.session.dispatchPacket(request.toString());
 	},
 
-	//EVENTS 
+	//EVENTS
 	onNewMessage: function(msg){},
 	onInvite: function(contact){}
 });
diff --git a/dojox/xmpp/RosterService.js b/dojox/xmpp/RosterService.js
index 8d0da99..8d78eb5 100644
--- a/dojox/xmpp/RosterService.js
+++ b/dojox/xmpp/RosterService.js
@@ -79,7 +79,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 		}
 		request.append(dojox.xmpp.util.createElement("item",item,false));
 		
-		var newGroups = groups ? groups : this.session.roster[i].groups; 
+		var newGroups = groups ? groups : this.session.roster[i].groups;
 		
 		if (newGroups){
 			for (var x=0;x<newGroups.length;x++){
@@ -98,7 +98,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 
 	verifyRoster: function(res){
 		if (res.getAttribute('type')=='result'){
-			//this.onAddRosterItem(res.getAttribute('id'));	
+			//this.onAddRosterItem(res.getAttribute('id'));
 		}else{
 			var err=this.session.processXmppError(res);
 			this.onAddRosterItemFailed(err);
@@ -116,16 +116,16 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 		var item = this.session.roster[index];
 		var tgroups = [];
 
-		var found = false; 
+		var found = false;
 
 		for (var i=0; ((item<item.groups.length) && (!found)); i++){
-			if (item.groups[i]!=group){continue;}	
+			if (item.groups[i]!=group){continue;}
 			found=true;
-		} 	
+		}
 	
 		if(!found){
 			return this.updateRosterItem(jid, item.name, item.groups.concat(group),index);
-		}	
+		}
 	
 		return dojox.xmpp.xmpp.INVALID_ID;
 	},
@@ -141,7 +141,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 						item.groups.splice(j,1);
 						this.updateRosterItem(item.jid, item.name, item.groups);
 						//found=true;
-					}				
+					}
 				}
 			}
 		}
@@ -158,7 +158,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 						item.groups[j] = newGroup;
 						this.updateRosterItem(item.jid, item.name, item.groups);
 				//		found=true;
-					}				
+					}
 				}
 			}
 		}
@@ -172,18 +172,18 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 		if (index==-1){return;}
 
 		var item = this.session.roster[index];
-		var found = false; 
+		var found = false;
 
 		for (var i=0; ((i<item.groups.length) && (!found)); i++){
-			if (item.groups[i]!=group){continue;}	
+			if (item.groups[i]!=group){continue;}
 			found=true;
 			index = i;
-		} 	
+		}
 
 		if(found==true){
 			item.groups.splice(index,1);
 			return this.updateRosterItem(jid, item.name, item.groups);
-		}		
+		}
 		
 		return dojox.xmpp.xmpp.INVALID_ID;
 	},
@@ -196,18 +196,18 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 		if (index==-1){return;}
 
 		var item = this.session.roster[index];
-		var found = false; 
+		var found = false;
 
 		for (var i=0; ((i<item.groups.length) && (!found)); i++){
 			if (item.groups[i]==oldGroup){
 				item.groups[i] = newGroup;
 				found=true;
 			}
-		} 	
+		}
 
 		if(found==true){
 			return this.updateRosterItem(jid, item.name, item.groups);
-		}		
+		}
 		
 		return dojox.xmpp.xmpp.INVALID_ID;
 	},
@@ -236,7 +236,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 
 		if (jid.indexOf('@')== -1){
 			jid += jid + '@' + this.session.domain;
-		}	
+		}
 
 		request.append(dojox.xmpp.util.createElement('item',{jid:jid,subscription:"remove"},true));
 
@@ -248,7 +248,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 	},
 
 	//Avatar functions...I removed this stuff for now..can we even do anything useful
-	//with this data even if we have it? 	
+	//with this data even if we have it?
 	getAvatar: function(jid){
 	},
 
@@ -259,7 +259,7 @@ dojo.declare("dojox.xmpp.RosterService", null, {
 	//EVENTS
 
 	onVerifyRoster: function(id){
-		//console.log("Roster::onVerifyRoster() - ", id);	
+		//console.log("Roster::onVerifyRoster() - ", id);
 	},
 
 	onVerifyRosterFailed: function(err){
diff --git a/dojox/xmpp/TransportSession.js b/dojox/xmpp/TransportSession.js
index e06ba77..216b445 100644
--- a/dojox/xmpp/TransportSession.js
+++ b/dojox/xmpp/TransportSession.js
@@ -158,15 +158,15 @@ dojo.extend(dojox.xmpp.TransportSession, {
 
 		dispatchPacket: function(msg, protocolMatchType, matchId, matchProperty){
 			// summary
-			// Main Packet dispatcher, most calls should be made with this other 
-			// than a few setup calls which use add items to the queue directly 
+			// Main Packet dispatcher, most calls should be made with this other
+			// than a few setup calls which use add items to the queue directly
 			//protocolMatchType, matchId, and matchProperty are optional params
 			//that allow a deferred to be tied to a protocol response instad of the whole
 			//rid
 	
 		//	//console.log("In dispatchPacket ", msg, protocolMatchType, matchId, matchProperty);
 			if (msg){
-				this.protocolPacketQueue.push(msg);	
+				this.protocolPacketQueue.push(msg);
 			}
 			
 			var def = new dojo.Deferred();
@@ -174,8 +174,8 @@ dojo.extend(dojox.xmpp.TransportSession, {
 
 			if (protocolMatchType && matchId){
 				def.protocolMatchType = protocolMatchType;
-				def.matchId = matchId;	
-				def.matchProperty = matchProperty || "id";	
+				def.matchId = matchId;
+				def.matchProperty = matchProperty || "id";
 				if(def.matchProperty != "id") {
 					this.matchTypeIdAttribute[protocolMatchType] = def.matchProperty;
 				}
@@ -185,7 +185,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 			if(!this.dispatchTimer) {
 				this.dispatchTimer = setTimeout(dojo.hitch(this, "_dispatchPacket"), 600);
 			}
-			return def;	
+			return def;
 		},
 	
 		_dispatchPacket: function(){
@@ -238,7 +238,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 						return;
 					}
 				
-				} 
+				}
 				req.rid= this.rid++;
 				this.lastPollTime = new Date().getTime();
 				envelope = new dojox.string.Builder(dojox.xmpp.util.createElement("body", req, true));
@@ -287,7 +287,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 			//console.log("TransportSession::sendXml()"+ new Date().getTime() + " RID: ", rid, " MSG: ", message);
 			this.transmitState = "transmitting";
 			var def = null;
-			if(this.useScriptSrcTransport) { 
+			if(this.useScriptSrcTransport) {
 				//console.log("using script src to transmit");
 				def = dojox.xmpp.bosh.get({
 					rid: rid,
@@ -311,7 +311,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 					timeout: this.sendTimeout
 				});
 			}
-			//process the result document 
+			//process the result document
 			def.addCallback(this, function(res){
 				return this.processDocument(res, rid);
 			});
@@ -335,20 +335,20 @@ dojo.extend(dojox.xmpp.TransportSession, {
 			var expectedId = this.outboundQueue[0]["rid"];
 			//console.log("expectedId", expectedId);
 			if (rid==expectedId){
-				this.removeFromOutboundQueue(rid);	
+				this.removeFromOutboundQueue(rid);
 				this.processResponse(body, rid);
-				this.processInboundQueue();	
+				this.processInboundQueue();
 			}else{
 				//console.log("TransportSession::processDocument() rid: ", rid, " expected: ", expectedId);
 				var gap = rid-expectedId;
 			
 				if (gap < this.hold + 2){
-					this.addToInboundQueue(doc,rid);	
+					this.addToInboundQueue(doc,rid);
 				}else{
 					//console.log("TransportSession::processDocument() RID is outside of the expected response window");
 				}
 			}
-			return doc;	
+			return doc;
 		},
 
 		processInboundQueue: function(){
@@ -361,7 +361,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 		addToInboundQueue: function(doc,rid){
 			for (var i=0; i<this.inboundQueue.length;i++){
 				if (rid < this.inboundQueue[i]["rid"]){continue;}
-				this.inboundQueue.splice(i,0,{doc: doc, rid: rid});	
+				this.inboundQueue.splice(i,0,{doc: doc, rid: rid});
 			}
 		},
 
@@ -387,20 +387,20 @@ dojo.extend(dojox.xmpp.TransportSession, {
 					throw new Error("No sid returned during xmpp session startup");
 				}
 
-				this.authId = body.getAttribute("authid");	
+				this.authId = body.getAttribute("authid");
 				if (this.authId == "") {
 					if (this.authRetries-- < 1) {
 						console.error("Unable to obtain Authorization ID");
-						this.terminateSession();	
+						this.terminateSession();
 					}
 				}
-				this.wait= body.getAttribute("wait");	
+				this.wait= body.getAttribute("wait");
 				if( body.getAttribute("polling")){
 					this.polling= parseInt(body.getAttribute("polling"))*1000;
 				}
 			
 				//console.log("Polling value ", this.polling);
-				this.inactivity = body.getAttribute("inactivity");	
+				this.inactivity = body.getAttribute("inactivity");
 				this.setState("Ready");
 			}
 
@@ -468,8 +468,8 @@ dojo.extend(dojox.xmpp.TransportSession, {
 					this.setState("Terminate", errorMessage);
 					return false;
 				}else{
-					this.removeFromOutboundQueue(rid);	
-					setTimeout(dojo.hitch(this, function(){ this.dispatchPacket(); }), 200);	
+					this.removeFromOutboundQueue(rid);
+					setTimeout(dojo.hitch(this, function(){ this.dispatchPacket(); }), 200);
 					return true;
 				}
 				return false;
@@ -479,7 +479,7 @@ dojo.extend(dojox.xmpp.TransportSession, {
 				//console.log("Wait timeout");
 			}
 			
-			this.removeFromOutboundQueue(rid);	
+			this.removeFromOutboundQueue(rid);
 			//FIXME conditional processing if request will be needed based on type of error.
 			if(err && err.firstChild) {
 			//console.log("Error ", err.firstChild.getAttribute("type") + " status code " + httpStatusCode);
@@ -492,10 +492,10 @@ dojo.extend(dojox.xmpp.TransportSession, {
 					}
 					this.setState("Terminate", errorMessage);
 					return false;
-				}			
+				}
 			}
 			this.transmitState = "error";
-			setTimeout(dojo.hitch(this, function(){ this.dispatchPacket(); }), 200);	
+			setTimeout(dojo.hitch(this, function(){ this.dispatchPacket(); }), 200);
 			//console.log("Error: ", arguments);
 			return true;
 		},
diff --git a/dojox/xmpp/UserService.js b/dojox/xmpp/UserService.js
index 9e27972..06a6480 100644
--- a/dojox/xmpp/UserService.js
+++ b/dojox/xmpp/UserService.js
@@ -23,7 +23,7 @@ dojo.declare("dojox.xmpp.UserService", null, {
 		var req={
 			id: this.session.getNextIqId(),
 			type: 'set'
-		}			
+		}
 		
 		var request = new dojox.string.Builder(dojox.xmpp.util.createElement("iq",req,false));
 		request.append(dojox.xmpp.util.createElement("query",{xmlns:"jabber:iq:private"},false));
diff --git a/dojox/xmpp/bosh.js b/dojox/xmpp/bosh.js
index b7e3176..7d527f4 100644
--- a/dojox/xmpp/bosh.js
+++ b/dojox/xmpp/bosh.js
@@ -126,7 +126,7 @@ dojox.xmpp.bosh = {
 	},
 
 	_makeScriptDeferred: function(/*Object*/args){
-		//summary: 
+		//summary:
 		//		sets up a Deferred object for an IO request.
 		var dfd = dojo._ioSetArgs(args, this._deferredCancel, this._deferredOk, this._deferredError);
 
@@ -158,7 +158,7 @@ dojox.xmpp.bosh = {
 		//DO NOT use "this" and expect it to be dojo.xmpp.bosh.
 		var ioArgs = dfd.ioArgs;
 
-		//Add script to list of things that can be removed.		
+		//Add script to list of things that can be removed.
 		if(ioArgs.canDelete){
 			dojox.xmpp.bosh._addDeadScript(ioArgs);
 		}
diff --git a/dojox/xmpp/util.js b/dojox/xmpp/util.js
index 6f43ad3..2962dbb 100644
--- a/dojox/xmpp/util.js
+++ b/dojox/xmpp/util.js
@@ -15,33 +15,33 @@ dojox.xmpp.util.encodeJid = function(jid) {
 			var ch = jid.charAt(i);
 			var rep = ch;
 			switch(ch){
-				case ' ' : 
+				case ' ' :
 					rep = "\\20";
 				break;
 				case '"' :
-					rep = "\\22"; 
+					rep = "\\22";
 				break;
 				case '#' :
-					rep = "\\23"; 
+					rep = "\\23";
 				break;
 				case '&' :
-					rep = "\\26"; 
+					rep = "\\26";
 				break;
 				case "'" :
-					rep = "\\27"; 
+					rep = "\\27";
 				break;
 				case '/' :
-					rep = "\\2f"; 
+					rep = "\\2f";
 				break;
 				case ':' :
-					rep = "\\3a"; 
+					rep = "\\3a";
 				break;
 				case '<' :
-					rep = "\\3c"; 
+					rep = "\\3c";
 				break;
 				case '>' :
-					rep = "\\3e"; 
-				break;			
+					rep = "\\3e";
+				break;
 			}
 			buffer.append(rep);
 		}
@@ -52,24 +52,24 @@ dojox.xmpp.util.decodeJid = function(jid) {
 	
 	jid = jid.replace(/\\([23][02367acef])/g, function(match) {
 			switch(match){
-				case "\\20" : 
+				case "\\20" :
 					return  ' ';
 				case "\\22"  :
-					return '"'; 
+					return '"';
 				case "\\23" :
-					return '#' ; 
+					return '#' ;
 				case "\\26" :
-					return  '&'; 
+					return  '&';
 				case "\\27" :
-					return   "'"; 
+					return   "'";
 				case "\\2f" :
-					return  '/'; 
+					return  '/';
 				case "\\3a" :
-					return ':' ; 
+					return ':' ;
 				case "\\3c" :
-					return  '<'; 
+					return  '<';
 				case "\\3e" :
-					return  '>'; 
+					return  '>';
 			}
 			return "ARG";
 	});
@@ -86,10 +86,10 @@ dojox.xmpp.util.createElement = function(tag, attributes, terminal){
 		elem.append(attr + '="');
 		elem.append(attributes[attr]);
 		elem.append('" ');
-	}	
+	}
 	
 	if (terminal){
-		elem.append("/>");		
+		elem.append("/>");
 	}else{
 		elem.append(">");
 	}
@@ -108,7 +108,7 @@ dojox.xmpp.util.stripHtml = function(str){
 }
 
 dojox.xmpp.util.decodeHtmlEntities = function(str){
-	// Summary: decodes HTML entities to js characters so the string can be 
+	// Summary: decodes HTML entities to js characters so the string can be
 	// fed to a textarea.value
 	var ta = dojo.doc.createElement("textarea");
 	ta.innerHTML = str.replace(/</g,"<").replace(/>/g,">");
diff --git a/dojox/xmpp/widget/ChatSession.js b/dojox/xmpp/widget/ChatSession.js
index 9209f43..cbfc0d3 100644
--- a/dojox/xmpp/widget/ChatSession.js
+++ b/dojox/xmpp/widget/ChatSession.js
@@ -3,7 +3,7 @@ dojo.declare("dojox.xmpp.widget.ChatSession",
 	[dijit.layout.LayoutContainer, dijit._Templated],
 	{
 			templateString: dojo.cache("dojox.xmpp.widget", "templates/ChatSession.html"),
-			enableSubWidgets: true, 
+			enableSubWidgets: true,
 			widgetsInTemplate: true,
 			
 			widgetType: "ChatSession",
diff --git a/dojox/xmpp/xmppSession.js b/dojox/xmpp/xmppSession.js
index 120222c..6329b3d 100644
--- a/dojox/xmpp/xmppSession.js
+++ b/dojox/xmpp/xmppSession.js
@@ -56,7 +56,7 @@ dojox.xmpp.xmppSession = function(props){
 		dojo.mixin(this, props);
 	}
 
-	this.session = new dojox.xmpp.TransportSession(props); 
+	this.session = new dojox.xmpp.TransportSession(props);
 	dojo.connect(this.session, "onReady", this, "onTransportReady");
 	dojo.connect(this.session, "onTerminate", this, "onTransportTerminate");
 	dojo.connect(this.session, "onProcessProtocolResponse", this, "processProtocolResponse");
@@ -96,7 +96,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 
 		close: function(){
 			this.state = dojox.xmpp.xmpp.TERMINATE;
-			this.session.close(dojox.xmpp.util.createElement("presence",{type:"unavailable",xmlns:dojox.xmpp.xmpp.CLIENT_NS},true));	
+			this.session.close(dojox.xmpp.util.createElement("presence",{type:"unavailable",xmlns:dojox.xmpp.xmpp.CLIENT_NS},true));
 		},
 
 		processProtocolResponse: function(msg){
@@ -117,11 +117,11 @@ dojo.extend(dojox.xmpp.xmppSession, {
 					//console.log("default action?", msg.getAttribute('xmlns'));
 					if(msg.getAttribute('xmlns')==dojox.xmpp.xmpp.SASL_NS){
 						this.saslHandler(msg);
-					}	
+					}
 			}
 		},
 
-		//HANDLERS 
+		//HANDLERS
 
 		messageHandler: function(msg){
 			//console.log("xmppSession::messageHandler() ",msg);
@@ -131,7 +131,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 					break;
 				case "normal":
 				default:
-					this.simpleMessageHandler(msg);	
+					this.simpleMessageHandler(msg);
 			}
 			
 		},
@@ -157,7 +157,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				case 'subscribed':
 				case 'unsubscribed':
 					break;
-				case 'error':		
+				case 'error':
 					this.processXmppError(msg);
 					//console.log("xmppService::presenceHandler() Error");
 					break;
@@ -191,7 +191,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 							break;
 						case 'session':
 							hasSessionFeature = true;
-					}	
+					}
 				}
 			}
 			//console.log("Has connected/bind?", this.state, hasBindFeature, authMechanisms);
@@ -285,7 +285,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 					////console.log("ci.chatid: ", ci.chatid, message.chatid);
 					if (ci && ci.chatid == message.chatid) {
 						found = i;
-						break;	
+						break;
 					}
 				}
 			} else {
@@ -297,7 +297,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 						}
 					}
 				}
-			}	
+			}
 
 			if (found>-1 && chatState){
 				var chat = this.chatRegister[found];
@@ -306,10 +306,10 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				if (chat.firstMessage){
 					if (chatState == dojox.xmpp.chat.ACTIVE_STATE) {
 						chat.useChatState = (chatState != null) ? true : false;
-						chat.firstMessage = false;	
+						chat.firstMessage = false;
 					}
 				}
-			} 
+			}
 
 			if ((!message.body || message.body=="") && !message.xhtml) {return;}
 
@@ -346,7 +346,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 					case 'query':
 						if(fn.getAttribute('xmlns') == "jabber:iq:roster"){
 							this.rosterSetHandler(fn);
-							this.sendIqResult(msg.getAttribute('id'), msg.getAttribute('from'));	
+							this.sendIqResult(msg.getAttribute('id'), msg.getAttribute('from'));
 						}
 						break;
 					default:
@@ -400,7 +400,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 								var itemName = n.getAttribute('name');
 								if (itemName){
 									this.roster[x].name = itemName;
-								}	
+								}
 
 								r.groups = [];
 
@@ -442,8 +442,8 @@ dojo.extend(dojox.xmpp.xmppSession, {
 						case dojox.xmpp.roster.CHANGED:
 							this.onRosterChanged(rosterItem, previousCopy);
 							break;
-					}	
-				}	
+					}
+				}
 			}
 		},
 
@@ -464,7 +464,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				show: dojox.xmpp.presence.STATUS_ONLINE,
 				priority: 5,
 				hasAvatar: false
-			}	
+			}
 
 			if(msg.getAttribute('type')=='unavailable'){
 				p.show=dojox.xmpp.presence.STATUS_OFFLINE
@@ -482,14 +482,14 @@ dojo.extend(dojox.xmpp.xmppSession, {
 							p.priority=parseInt(n.firstChild.nodeValue);
 							break;
 						case 'x':
-							if(n.firstChild && n.firstChild.firstChild &&  n.firstChild.firstChild.nodeValue != "") { 
+							if(n.firstChild && n.firstChild.firstChild &&  n.firstChild.firstChild.nodeValue != "") {
 								p.avatarHash= n.firstChild.firstChild.nodeValue;
 								p.hasAvatar = true;
 							}
 							break;
 					}
 				}
-			}	
+			}
 
 			this.onPresenceUpdate(p);
 		},
@@ -529,7 +529,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				status: dojox.xmpp.presence.SUBSCRIPTION_NONE,
 				substatus: dojox.xmpp.presence.SUBSCRIPTION_SUBSTATUS_NONE
 			//	displayToUser: false
-			}	
+			}
 
 			if (!re.name){
 				re.name = re.id;
@@ -542,18 +542,18 @@ dojo.extend(dojox.xmpp.xmppSession, {
 				if (n.nodeName=='group' && n.hasChildNodes()){
 					re.groups.push(n.firstChild.nodeValue);
 				}
-			} 
+			}
 
 			if (elem.getAttribute('subscription')){
 				re.status = elem.getAttribute('subscription');
-			}	
+			}
 
 			if (elem.getAttribute('ask')=='subscribe'){
 				re.substatus = dojox.xmpp.presence.SUBSCRIPTION_REQUEST_PENDING;
-			}	
+			}
 			//Display contact rules from http://www.xmpp.org/extensions/xep-0162.html#contacts
-		/*	if(re.status == dojox.xmpp.presence.SUBSCRIPTION_REQUEST_PENDING || 
-				re.status == dojox.xmpp.presence.SUBSCRIPTION_TO || 
+		/*	if(re.status == dojox.xmpp.presence.SUBSCRIPTION_REQUEST_PENDING ||
+				re.status == dojox.xmpp.presence.SUBSCRIPTION_TO ||
 				re.status == dojox.xmpp.presence.SUBSCRIPTION_BOTH ||
 				re.groups.length > 0 ||
 				re.name
@@ -616,7 +616,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 			if (this.state != state){
 				if (this["on"+state]){
 					this["on"+state](state, this.state, message);
-				}	
+				}
 				this.state=state;
 			}
 		},
@@ -651,8 +651,8 @@ dojo.extend(dojox.xmpp.xmppSession, {
 
 		// EVENTS
 
-		onLogin: function(){ 
-			////console.log("xmppSession::onLogin()"); 
+		onLogin: function(){
+			////console.log("xmppSession::onLogin()");
 			this.retrieveRoster();
 		},
 
@@ -725,16 +725,16 @@ dojo.extend(dojox.xmpp.xmppSession, {
 							this.roster[i] = this.createRosterEntry(query.childNodes[i]);
 						}
 					}
-				}	
+				}
 			}else if(msg.getAttribute('type')=="error"){
-				//console.log("xmppService::storeRoster()  Error recieved on roster get");	
+				//console.log("xmppService::storeRoster()  Error recieved on roster get");
 			}
 
 			////console.log("Roster: ", this.roster);
 			this.setState(dojox.xmpp.xmpp.ACTIVE);
 			this.onRosterUpdated();
 
-			return msg;	
+			return msg;
 		},
 		
 		onRosterUpdated: function() {},
@@ -793,7 +793,7 @@ dojo.extend(dojox.xmpp.xmppSession, {
 						err.errorType = n.getAttribute('type');
 						for (var x=0; x< n.childNodes.length; x++){
 							var cn = n.childNodes[x];
-							if ((cn.nodeName=="text") && (cn.getAttribute('xmlns') == dojox.xmpp.xmpp.STANZA_NS) && cn.hasChildNodes()) {	
+							if ((cn.nodeName=="text") && (cn.getAttribute('xmlns') == dojox.xmpp.xmpp.STANZA_NS) && cn.hasChildNodes()) {
 								err.message = cn.firstChild.nodeValue;
 							} else if ((cn.getAttribute('xmlns') == dojox.xmpp.xmpp.STANZA_NS) &&(!cn.hasChildNodes())){
 								err.condition = cn.nodeName;
@@ -803,15 +803,15 @@ dojo.extend(dojox.xmpp.xmppSession, {
 					default:
 						break;
 				}
-			}	
+			}
 			return err;
 		},
 
 		sendStanzaError: function(stanzaType,to,id,errorType,condition,text){
 			////console.log("xmppSession: sendStanzaError() ", arguments);
 			var req = {type:'error'};
-			if (to) { req.to=to; }	
-			if (id) { req.id=id; }	
+			if (to) { req.to=to; }
+			if (id) { req.id=id; }
 		
 			var request = new dojox.string.Builder(dojox.xmpp.util.createElement(stanzaType,req,false));
 			request.append(dojox.xmpp.util.createElement('error',{type:errorType},false));
diff --git a/util/LICENSE b/util/LICENSE
index 4c93ded..aa6b39f 100644
--- a/util/LICENSE
+++ b/util/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2010, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/buildscripts/LICENSE b/util/buildscripts/LICENSE
index ad1676a..aa6b39f 100644
--- a/util/buildscripts/LICENSE
+++ b/util/buildscripts/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2009, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/buildscripts/build.js b/util/buildscripts/build.js
index 91324b9..3f70a0c 100644
--- a/util/buildscripts/build.js
+++ b/util/buildscripts/build.js
@@ -50,7 +50,7 @@ function help(){
 		+ "> java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar "
 		+ "org.mozilla.javascript.tools.shell.Main build.js [name=value...]\n\n"
 		+ "Here is an example of a typical release build:\n\n"
-		+ "> java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar " 
+		+ "> java -classpath ../shrinksafe/js.jar:../shrinksafe/shrinksafe.jar "
 		+ "org.mozilla.javascript.tools.shell.Main  build.js profile=base action=release\n\n"
 		+ "If you get a 'java.lang.OutOfMemoryError: Java heap space' error, try increasing the "
 		+ "memory Java can use for the command:\n\n"
@@ -284,14 +284,14 @@ function _copyToRelease(/*String*/prefixName, /*String*/prefixPath, /*Object*/kw
 		fileUtil.copyFile(releasePath + "/_base/query-sizzle.js", releasePath + "/_base/query.js");
 	}
 	
-	if(!copiedFiles){ 
-		logger.info(" ********** Not Copied: " + prefixPath ); 
+	if(!copiedFiles){
+		logger.info(" ********** Not Copied: " + prefixPath );
 	}
 	
 	//Make sure to copy over any "source" files for the layers be targeted by
 	//buildLayers. Otherwise dependencies will not be calculated correctly.
 	if(buildLayers){
-		for(i = 0; i < buildLayers.length; i++){		
+		for(i = 0; i < buildLayers.length; i++){
 			var relativeLayerPath = buildLayers[i].replace(/\.\.\//g, "");
 			
 			//See if relativeLayerPath has teh prefix slash name in it.
@@ -316,7 +316,7 @@ function _copyToRelease(/*String*/prefixName, /*String*/prefixPath, /*Object*/kw
 	}
 
 	//Put in code guards for each resource, to protect against redefinition of
-	//code in the layered build cases. Also inject base require calls if there is 
+	//code in the layered build cases. Also inject base require calls if there is
 	//a layer with the customBase attribute. Do this here before the layers are built.
 	if(copiedFiles){
 		var needBaseRequires = false;
@@ -338,12 +338,12 @@ function _copyToRelease(/*String*/prefixName, /*String*/prefixPath, /*Object*/kw
 
 //********* Start _optimizeReleaseDirs *********
 function _optimizeReleaseDirs(
-	/*String*/prefixName, 
+	/*String*/prefixName,
 	/*String*/prefixPath,
 	/*String*/copyrightText,
 	/*Object*/kwArgs,
 	/*RegExp*/layerIgnoreRegExp,
-	/*RegExp*/nlsIgnoreRegExp){	
+	/*RegExp*/nlsIgnoreRegExp){
 	//summary: runs intern strings, i18n bundle flattening and xdomain file generation
 	//on the files in a release directory, if those options are enabled.
 	var releasePath = kwArgs.releaseDir + "/"  + prefixName.replace(/\./g, "/");
@@ -359,7 +359,7 @@ function _optimizeReleaseDirs(
 	buildUtil.processConditionalsForDir(releasePath, layerIgnoreRegExp, kwArgs);
 
 	//Flatten bundles inside the directory
-	i18nUtil.flattenDirBundles(prefixName, prefixPath, kwArgs, nlsIgnoreRegExp);	
+	i18nUtil.flattenDirBundles(prefixName, prefixPath, kwArgs, nlsIgnoreRegExp);
 	
 	if(kwArgs.loader == "xdomain"){
 		buildUtilXd.xdgen(prefixName, prefixPath, prefixes, layerIgnoreRegExp, kwArgs);
diff --git a/util/buildscripts/build_release.sh b/util/buildscripts/build_release.sh
index 7f0a407..5d7d2bf 100755
--- a/util/buildscripts/build_release.sh
+++ b/util/buildscripts/build_release.sh
@@ -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/dojo/trunk  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/dijit/trunk 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/dojox/trunk 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/util/trunk  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/demos/trunk 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.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."
 
 #Check out the tag
 mkdir ../../build
@@ -122,10 +122,16 @@ mv build release-$1
 rm -rf release-$1/$srcName/
 cd release-$1
 
-# md5sum the release files
-for i in *.zip; do md5sum $i > $i.md5; done
-for i in *.gz; do md5sum $i > $i.md5; done
-for i in *.js; do md5sum $i > $i.md5; done
+# 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 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
 
 # pack up the whole thing for easy copying
 cd ..
diff --git a/util/buildscripts/cldr/alias.js b/util/buildscripts/cldr/alias.js
index 0d7fa33..2f2a6b4 100644
--- a/util/buildscripts/cldr/alias.js
+++ b/util/buildscripts/cldr/alias.js
@@ -1,11 +1,11 @@
 /**
  * There are basically two kinds of alias in CLDR:
- * 1. locale alias e.g. 
- *    in xml, <alias source="locale" path="......"/>, 
+ * 1. locale alias e.g.
+ *    in xml, <alias source="locale" path="......"/>,
  *    in gernated JSON bunle, xxxx at localeAlias:{'target':'xxx', 'bundle':'xxxx'}
  * 2. other locale alias e.g.
  *    in xml, currently only like <alias source="fr" path="//ldml"/>
- * #1 is supported by this 'alias.js', 
+ * #1 is supported by this 'alias.js',
  * #2 is covered by 'specialLocale.js' and may need enhancement for future CLDR versions.
  */
 
@@ -22,7 +22,7 @@ var dir/*String*/ = arguments[0];// ${dojo}/dojo/cldr/nls
 var logDir = arguments[1];
 var logStr = "";
 
-//Add new bundles to the list so that they will be aliased according to the ldml spec. 
+//Add new bundles to the list so that they will be aliased according to the ldml spec.
 var BUNDLES = ['gregorian','hebrew','islamic','islamic-civil','buddhist'];
 
 var LOCALE_ALIAS_MARK = '@localeAlias';
@@ -45,7 +45,7 @@ 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*/}
@@ -80,7 +80,7 @@ function _calculateAliasPath(bundle){
 			if(records[localeAliasSource]/*calculated*/){
 				//logStr += p + " has been calculated, ignored\n"
 				continue;
-			} 
+			}
 			
 			var path = [];
 			var aliasIndex = new Number(p.substring(index + LOCALE_ALIAS_MARK.length));
@@ -125,18 +125,18 @@ function _processLocaleAlias(localeAliasPaths/*Array*/, bundle/*JSON Obj*/, nati
 					//logStr += "!" + mapping[LOCALE_ALIAS_SOURCE_PROPERTY] +" has been processed for alias, escaped\n";
 					continue;
 				}
-				_updateLocaleAlias(bundle, mapping[LOCALE_ALIAS_SOURCE_PROPERTY], bundle, 
-								   mapping[LOCALE_ALIAS_TARGET_PROPERTY], nativeSrcBundle);	
+				_updateLocaleAlias(bundle, mapping[LOCALE_ALIAS_SOURCE_PROPERTY], bundle,
+								   mapping[LOCALE_ALIAS_TARGET_PROPERTY], nativeSrcBundle);
 				processed[mapping[LOCALE_ALIAS_SOURCE_PROPERTY]] =  true;
 			}else{
 				//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); 
+				var targetBundle = dojo.i18n.getLocalization('dojo.cldr', mapping[LOCALE_ALIAS_TARGET_BUNDLE], locale);
 				if(processed[mapping[LOCALE_ALIAS_SOURCE_PROPERTY]]){//If being processed, continue;
 					continue;
 				}
-				_updateNoneGregAlias(bundle, mapping[LOCALE_ALIAS_SOURCE_PROPERTY], targetBundle, 
-								   mapping[LOCALE_ALIAS_TARGET_PROPERTY], nativeSrcBundle);	
+				_updateNoneGregAlias(bundle, mapping[LOCALE_ALIAS_SOURCE_PROPERTY], targetBundle,
+								   mapping[LOCALE_ALIAS_TARGET_PROPERTY], nativeSrcBundle);
 				processed[mapping[LOCALE_ALIAS_SOURCE_PROPERTY]] =  true;
 			}
 		}
@@ -157,27 +157,31 @@ function _processLocaleAlias(localeAliasPaths/*Array*/, bundle/*JSON Obj*/, nati
 */
 function _updateNoneGregAlias(sourceBundle/*JSON Obj*/, aliasSource/*String*/, targetBundle/*JSON Obj*/, aliasTarget/*String*/, nativeSrcBundle/*JSON Obj*/){
     for (var sKey in sourceBundle) {
-        if (sKey.indexOf(aliasSource) == 0 && !nativeSrcBundle[sKey] && targetBundle[sKey]&&!compare(sourceBundle[sKey],targetBundle[sKey])) {
-            nativeSrcBundle[sKey] = targetBundle[sKey];
-            sourceBundle[sKey] = targetBundle[sKey];
+        var target = targetBundle[sKey],
+	    source = sourceBundle[sKey],
+	    nativeSrc = nativeSrcBundle[sKey];
+
+	if (sKey.indexOf(aliasSource) == 0 && !nativeSrc && target && !compare(source, target)) {
+            nativeSrcBundle[sKey] = target;
+            sourceBundle[sKey] = target;
             updated = true;
-        }
-        else 
-            if (sKey.indexOf(aliasSource) == 0 && nativeSrcBundle[sKey] && dojo.isArray(sourceBundle[sKey]) && dojo.isArray(targetBundle[sKey])) {
-                for (var i = 0; i < sourceBundle[sKey].length; i++) {
-                    if (sourceBundle[sKey][i] == undefined) {
-                        sourceBundle[sKey][i] = targetBundle[sKey][i];
+        } else {
+            if (sKey.indexOf(aliasSource) == 0 && nativeSrc && dojo.isArray(source) && dojo.isArray(target)) {
+                for (var i = 0; i < source.length; i++) {
+                    if (source[i] === undefined) {
+                        source[i] = target[i];
                         updated = true;
                     }
                 }
-                if (sourceBundle[sKey].length < targetBundle[sKey].length) {
-                    sourceBundle[sKey] = sourceBundle[sKey].concat(targetBundle[sKey].slice(sourceBundle[sKey].length));
+                if (source.length < target.length) {
+                    source = sourceBundle[sKey] = source.concat(target.slice(source.length));
                     updated = true;
                 }
                 if (updated) {
-                    nativeSrcBundle[sKey] = sourceBundle[sKey];
+                    nativeSrcBundle[sKey] = source;
                 }
             }
+        }
     }
 }
 function _updateLocaleAlias(sourceBundle/*JSON Obj*/,aliasSource/*String*/, targetBundle/*JSON Obj*/,
@@ -190,8 +194,8 @@ function _updateLocaleAlias(sourceBundle/*JSON Obj*/,aliasSource/*String*/, targ
 			//sourceBundle[aliasSource] =  targetBundle[aliasTarget];
 			nativeSrcBundle[aliasSource] =  targetBundle[aliasTarget];
 			sourceBundle[aliasSource] = nativeSrcBundle[aliasSource];
-			updated = true;	
-		}else if(nativeSrcBundle[aliasSource] && dojo.isArray(sourceBundle[aliasSource]) 
+			updated = true;
+		}else if(nativeSrcBundle[aliasSource] && dojo.isArray(sourceBundle[aliasSource])
 		         && dojo.isArray(targetBundle[aliasTarget])){
 			if(sourceBundle[aliasSource].length > targetBundle[aliasTarget].length){
 				//logStr +="Error:" + aliasSource + ".length > " +  aliasTarget + ".length \n";
@@ -201,16 +205,16 @@ function _updateLocaleAlias(sourceBundle/*JSON Obj*/,aliasSource/*String*/, targ
 				if(sourceBundle[aliasSource][i] == undefined){//need inherit
 					//logStr += '2 ' + aliasSource + "["+i+"]=" +sourceBundle[aliasSource][i]+" is replaced with " + aliasTarget+"["+i+"]="+targetBundle[aliasTarget][i]+'\n';
 					sourceBundle[aliasSource][i] =  targetBundle[aliasTarget][i];
-					updated = true;	
+					updated = true;
 				}// otherwise no change and use current value
 			}
 			if(sourceBundle[aliasSource].length < targetBundle[aliasTarget].length){
-				//logStr +='3 ' + aliasSource +' from ' + sourceBundle[aliasSource].length +' to ' 
-				//		  + (targetBundle[aliasTarget].length-1) + ' are copied from ' 
+				//logStr +='3 ' + aliasSource +' from ' + sourceBundle[aliasSource].length +' to '
+				//		  + (targetBundle[aliasTarget].length-1) + ' are copied from '
 				//		  +aliasTarget + '='+ targetBundle[aliasTarget] +'\n';
 				sourceBundle[aliasSource] = sourceBundle[aliasSource].concat(
 											targetBundle[aliasTarget].slice(sourceBundle[aliasSource].length));
-				updated = true;	
+				updated = true;
 			}
 			if(updated){
 				nativeSrcBundle[aliasSource] = sourceBundle[aliasSource];
@@ -237,6 +241,6 @@ function cleanLocaleAlias(fileList/*Array*/){
 		if(needUpdate){
 			fileUtil.saveUtf8File(fileName, "(" + dojo.toJson(newBundle, true) + ")");
 			//logStr += "cleaned @localAlias for " + fileName + "\n";
-		} 
+		}
 	}
 }
diff --git a/util/buildscripts/cldr/arrayInherit.js b/util/buildscripts/cldr/arrayInherit.js
index e5232b3..1b17aa6 100644
--- a/util/buildscripts/cldr/arrayInherit.js
+++ b/util/buildscripts/cldr/arrayInherit.js
@@ -2,14 +2,14 @@
  *  The CLDR represents some lists, like month names, as separate entries, and our JSON uses arrays to express them.
  *  For some variants, the best our XSLT can do is translate this to a sparse array with 'undefined' entries.
  *  These entries need to be picked up from the parent locale(s) and copied into the array as necessary(only when the item
- *  is not the source of a locale alias mapping, like 'months-format-abbr' should be ignored if it is the source of 
+ *  is not the source of a locale alias mapping, like 'months-format-abbr' should be ignored if it is the source of
  *  locale alias mapping like 'months-format-abbr at localeAlias' :{'target':"months-format-wide",'bundle':"gregorian"}).
  *  So, this script is responsible for taking all the generated JSON files, and for values which are of type
- *  array and not the source of locale alias mapping, mixing in the parent values with the undefined ones, recursing 
- *  all the way to the 'root' locale,and replacing the contents of the file.  
+ *  array and not the source of locale alias mapping, mixing in the parent values with the undefined ones, recursing
+ *  all the way to the 'root' locale,and replacing the contents of the file.
  *
  *  this script traverses all locales dir in the given root dir
- *  
+ *
  *   E.g.(Just for example, the contents are not applicable)
  *   parent locale - "en":
  *    // generated from ldml/main/ *.xml, xpath: ldml/calendars/calendar-ethiopic
@@ -65,7 +65,7 @@ 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*/}
 	
@@ -93,11 +93,11 @@ for(var i= 0; i < fileList.length; i++){
 			//logStr += locale + "===============================================\n";
 			for(prop in data){
 				if(dojo.isArray(data[prop])){
-					//ignore if the property is an alias source, for alias.js and specialLocale.js 
+					//ignore if the property is an alias source, for alias.js and specialLocale.js
 					if(isLocaleAliasSrc(prop, bundle)){
 						//logStr += prop + " is alias, ignored\n";
 						continue;
-					}			
+					}
 
 					var variantArray = variantData[prop];
 					dojo.forEach(data[prop], function(element, index, list){
diff --git a/util/buildscripts/cldr/build.xml b/util/buildscripts/cldr/build.xml
index 7240fd4..ce856bc 100644
--- a/util/buildscripts/cldr/build.xml
+++ b/util/buildscripts/cldr/build.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="iso-8859-1"?>
 
 <!--
-	Copyright (c) 2004-2010 The Dojo Foundation, Licensed under the Academic
+	Copyright (c) 2004-2011 The Dojo Foundation, Licensed under the Academic
 	Free License version 2.1 or BSD licenses
 -->
 <project name="dojo" default="cldr" basedir=".">
@@ -15,7 +15,7 @@
 	<property name="json" location="${root}/dojo/cldr/nls"/>
 
 	<!-- Arbitrary defaults. locales and currencies properties can be altered or eliminated to build the entire set -->
-	<!--property name="locales" value="ar,hi,he,hu,ru,en-au,en-ca,en-gb,en-us,de-de,es-es,fr-fr,it-it,pt-br,ko-kr,zh-hant,zh-tw,zh-hans,zh-cn,ja-jp"/-->
+	<property name="locales" value="ar,ca,cs,da,de-de,el,en-au,en-ca,en-gb,en-us,es-es,fi,fr-ch,fr-fr,he-il,hu,it-it,ja-jp,ko-kr,nb,nl,pl,pt-br,pt-pt,ro,ru,sk,sl,sv,th,tr,zh,zh-cn,zh-hant,zh-hans,zh-hk,zh-tw" />
 	<property name="currencies" value="GBP,USD,CAD,AUD,EUR,CHF,HKD,JPY,CNY" />
 
 	<target name="-check-config"
@@ -262,5 +262,11 @@
 			<arg value="${logDir}"/>
 			<sysproperty key="DOJO_LOADER" value="${dojoLoader}" />
 		</java>
+		<java jar="../../shrinksafe/js.jar" failonerror="true" fork="true" logError="true" >
+			<arg value="wrap.js" />
+			<arg value="${json}" />
+			<arg value="${logDir}"/>
+			<sysproperty key="DOJO_LOADER" value="${dojoLoader}" />
+		</java>
 	</target>
 </project>
diff --git a/util/buildscripts/cldr/cldrUtil.js b/util/buildscripts/cldr/cldrUtil.js
index b29b40f..4bb2f35 100644
--- a/util/buildscripts/cldr/cldrUtil.js
+++ b/util/buildscripts/cldr/cldrUtil.js
@@ -21,13 +21,13 @@ function isLocaleAliasSrc(prop, bundle){
 				isAlias = true;
 			}
 		}
-	}	
+	}
 	return isAlias;
 }
 
 function getNativeBundle(filePath){
 	//summary: get native bundle content with utf-8 encoding
-	//	native means the content of this bundle is not flattened with parent 
+	//	native means the content of this bundle is not flattened with parent
 	//	returns empty object if file not found
 	try{
 		var content = readFile(filePath, "utf-8");
diff --git a/util/buildscripts/cldr/ldml/core.zip b/util/buildscripts/cldr/ldml/core.zip
index b90e79b..6a4988f 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 577896c..8157a2c 100644
--- a/util/buildscripts/cldr/specialLocale.js
+++ b/util/buildscripts/cldr/specialLocale.js
@@ -1,17 +1,17 @@
 /**
  * In CLDR, there are some special locales with abnormal hierarchy.
- * 
+ *
  * E.g.zh-hk.xml is aliased to zh-hant-hk.xml for all the calendar/number/currency data.
  * So after CLDR transformation, JSON bundles under zh-hk is totally the same as those under zh-hant-hk.
  * Problems will occur when dojo loads zh-hk bundle, as dojo will flatten it with the following sequence:
  * Root -> zh -> zh-hk, but the right sequence should be Root -> zh -> zh-hant -> zh-hk(zh-hant-hk)
  * so the bundles under zh-hant locale is missing.
- * 
+ *
  * This script is used to process all the special locales so that after CLDR transformation,
  * zh-hk bundle will be flatted both with zh-hant and zh-hant-hk, nothing will be lost then.
  * Please see the following SPECIAL_LOCALES_MAP for detail mapping info.
- * 
- * Note: Here for simplification, we name zh-hk as source locale,and name zh-hant-hk as alias locale.  
+ *
+ * Note: Here for simplification, we name zh-hk as source locale,and name zh-hant-hk as alias locale.
  */
 djConfig={baseUrl: "../../../dojo/"};
 
@@ -43,10 +43,10 @@ var SPECIAL_LOCALES_MAP = {
 	//Currently for CLDR 1.6, will be updated with latest CLDR release.
 
 	'zh-hk':'zh-hant-hk',
-	'zh-mo':'zh-hant-mo',		
-	'sh':'sr-latn',	
+	'zh-mo':'zh-hant-mo',
+	'sh':'sr-latn',
 	'mo':'ro-md',
-	'pa-pk':'pa-arab-pk',//pa-pk and pa-arab-pk don't exist, but pa-arab exists		
+	'pa-pk':'pa-arab-pk',//pa-pk and pa-arab-pk don't exist, but pa-arab exists
 	'zh-tw':'zh-hant-tw',//zh-tw and zh-hant-tw don't exist, but zh-hant exists
 	'uz-af':'uz-arab-af',//uz-af and uz-arab-af don't exist, but uz-arab exists
 	'ha-sd':'ha-arab-sd',//ha-sd and ha-arab-sd don't exist, but ha-arab exists
@@ -54,7 +54,7 @@ var SPECIAL_LOCALES_MAP = {
 	
 	/* The following locales don't have any bundles currently (CLDR 1.6),
 	 * listed here for CLDR future release.
-	 *  
+	 *
 	'az-az':'az-latn-az',
 	'ha-gh':'ha-latn-gh',
 	'ha-ne':'ha-latn-ne',
@@ -63,11 +63,11 @@ var SPECIAL_LOCALES_MAP = {
 	'ku-iq':'ku-latn-iq',
 	'ku-ir':'ku-latn-ir',
 	'ku-sy':'ku-latn-sy',
-	'pa-in':'pa-guru-in',	
+	'pa-in':'pa-guru-in',
 	'sr-cs':'sr-cyrl-cs',
 	'sr-me':'sr-cyrl-me',
 	'sr-rs':'sr-cyrl-rs',
-	'sr-yu':'sr-cyrl-rs',	
+	'sr-yu':'sr-cyrl-rs',
 	'uz-uz':'uz-cyrl-uz',
 	'zh-sg':'zh-hans-sg',
 	'zh-cn':'zh-hans-cn',
@@ -137,8 +137,8 @@ for(var i= 0; i < srcLocaleList.length; i++){
 			var aliasBundle = dojo.i18n.getLocalization('dojo.cldr', BUNDLE_MAP[len], aliasLocale);
 		}catch(e){print(e);/*it's ok if no bundle found*/}
 		
-		if(!aliasBundle && !srcBundle){ 
-			break;			
+		if(!aliasBundle && !srcBundle){
+			break;
 		}else if(!aliasBundle && srcBundle){
 			//should be an error case
 			//logStr += 'specialLocale.js error: source locale has more bundles than alias locale\n';
@@ -159,9 +159,9 @@ for(var i= 0; i < srcLocaleList.length; i++){
 			}
 
 			for(p in aliasBundle){
-				if(!isLocaleAliasSrc(p, aliasBundle) // p is not the source of a 'locale' alias mapping 
+				if(!isLocaleAliasSrc(p, aliasBundle) // p is not the source of a 'locale' alias mapping
 				   && (!srcBundle[p] || !compare(srcBundle[p], aliasBundle[p]))){
-				   //inherit 
+				   //inherit
 				   nativeSrcBundle[p] = aliasBundle[p];
 				   //logStr += "copied " + p + "=" + aliasBundle[p] + "\n";
 				   isUpdated = true;
@@ -171,7 +171,7 @@ for(var i= 0; i < srcLocaleList.length; i++){
 			if(isUpdated){
 				validateDir(srcLocalePath);
 				fileUtil.saveUtf8File(srcLocalePath + '/' + BUNDLE_MAP[len] + '.js', NLS_JSON_HEAD[len] + '(' + dojo.toJson(nativeSrcBundle, true) + ')');
-				//logStr += 'specialLocale.js : updated ' + BUNDLE_MAP[len] + '.js in ' + srcLocalePath + '\n';				
+				//logStr += 'specialLocale.js : updated ' + BUNDLE_MAP[len] + '.js in ' + srcLocalePath + '\n';
 			}
 		}
 	}
@@ -184,5 +184,5 @@ function validateDir(/*String*/dirPath){
 	var dir = new java.io.File(dirPath);
 	if(!dir.exists()){
 		dir.mkdir();
-	}	
+	}
 }
\ No newline at end of file
diff --git a/util/buildscripts/cldr/wrap.js b/util/buildscripts/cldr/wrap.js
new file mode 100644
index 0000000..91e8b98
--- /dev/null
+++ b/util/buildscripts/cldr/wrap.js
@@ -0,0 +1,74 @@
+/**
+ * Takes plain JSON structures and wraps them as to requireJS i18n bundles
+ */
+
+djConfig={baseUrl: "../../../dojo/"};
+
+load("../../../dojo/dojo.js");
+load("../jslib/logger.js");
+load("../jslib/fileUtil.js");
+load("cldrUtil.js");
+
+dojo.require("dojo.i18n");
+
+var dir/*String*/ = arguments[0];// ${dojo}/dojo/cldr/nls
+var logDir = arguments[1];
+var logStr = "";
+
+print('wrap.js...');
+
+var wrap = function(contents){
+    return "\n//begin v1.x content\n" + contents + "\n//end v1.x content\n";
+};
+
+// for each .js file in the top-level directory, make a filtered list
+// of all files matching that name in the directory tree
+var fileLists = fileUtil.getFilteredFileList(dir, /\.js$/, true, false, true)
+	.map(function(file){
+		var name = file.substring(file.lastIndexOf("/"));
+		return fileUtil.getFilteredFileList(dir, new RegExp(name+"$"), true);
+	});
+	
+fileLists.forEach(function(fileList){
+	var map = {},
+	    list = [],
+	    rootFile;
+	fileList.forEach(function(file /*Java String*/){
+logStr += "WRAP processing file: "+file.toString()+"\n";
+		var path = file.split("/"),
+		    locale = path[path.length-2],
+		    obj = dojo.fromJson(fileUtil.readFile(file));
+
+		if(locale=="nls"){
+		    rootFile = file;
+		    map.root = obj;
+logStr += "rootFile="+file.toString()+"\n";
+
+		}else{
+logStr += "locale added: "+locale+"\n";
+			list.push(locale);
+			map[locale] = true;
+			fileUtil.saveUtf8File(file, "define(" + wrap(dojo.toJson(obj, true)) + ");");
+		}
+	});
+
+logStr += "writing rootFile="+rootFile+"\n";
+//	var contents = wrap(dojo.toJson(map, true));
+
+//	Assemble file contents to include 1.x markers around map.root
+	var contents = "{ root:\n";
+	contents += wrap(dojo.toJson(map.root, true));
+	if(list.length){
+		list.sort();
+		list.forEach(function(l){
+			contents += ',\n\t"' + l + '": true';
+		});
+		contents += "\n";
+	}
+	contents += "}";
+
+	fileUtil.saveUtf8File(rootFile, "define(" + contents + ");");
+});
+
+fileUtil.saveUtf8File(logDir + '/wrap.log',logStr+'\n');
+//print('wrap finished, please refer to logs at ' + logDir + ' for more details.');
diff --git a/util/buildscripts/copyright.txt b/util/buildscripts/copyright.txt
index c9d4628..28781c0 100644
--- a/util/buildscripts/copyright.txt
+++ b/util/buildscripts/copyright.txt
@@ -1,5 +1,5 @@
 /*
-	Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved.
+	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/buildscripts/jslib/buildUtil.js b/util/buildscripts/jslib/buildUtil.js
index 0b457d2..264e75c 100644
--- a/util/buildscripts/jslib/buildUtil.js
+++ b/util/buildscripts/jslib/buildUtil.js
@@ -13,6 +13,17 @@ buildUtil.DojoBuildOptions = {
 		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. "
@@ -38,7 +49,7 @@ buildUtil.DojoBuildOptions = {
 	},
 	"loader": {
 		defaultValue: "default",
-		helpText: "The type of dojo loader to use. \"default\" or \"xdomain\" are acceptable values."		
+		helpText: "The type of dojo loader to use. \"default\" or \"xdomain\" are acceptable values."
 	},
 	"internStrings": {
 		defaultValue: true,
@@ -61,7 +72,7 @@ buildUtil.DojoBuildOptions = {
 			+ "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." 
+			+ "path to the path where you keep Closure's compiler.jar."
 	},
 	"layerOptimize": {
 		defaultValue: "shrinksafe",
@@ -80,20 +91,20 @@ buildUtil.DojoBuildOptions = {
 			+ "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." 
+			+ "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\" "	
+			+ "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 "	
+			+ "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."
 	},
@@ -203,18 +214,96 @@ 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;
+	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["profileFile"]){
-		var profileProperties = buildUtil.evalProfile(kwArgs.profileFile);
+	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;
@@ -372,7 +461,7 @@ buildUtil.getDependencyList = function(/*Object*/dependencies, /*String or Array
 	var layers = dependencies["layers"];
 	var layerCount = layers.length;
 	
-	//Process dojo layer files 
+	//Process dojo layer files
 	if(layerCount){
 		//Set up a lookup table for the layer URIs based on layer file name.
 		var namedLayerUris = {};
@@ -544,9 +633,9 @@ buildUtil.getDependencyList = function(/*Object*/dependencies, /*String or Array
 			}
 
 			//Get the final list of dependencies in this layer
-			var depList = buildUtil.determineUriList(layer.dependencies, layerUris, dependencies["filters"]); 
+			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 
+			//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.
@@ -600,7 +689,7 @@ buildUtil.getDependencyList = function(/*Object*/dependencies, /*String or Array
 			}
 
 			//Reset for another run through the loop.
-			currentProvideList = []; 
+			currentProvideList = [];
 
 			load = old_load; // restore the original load function
 			dojo["eval"] = dojo._oldEval; // restore the original dojo.eval function
@@ -609,6 +698,7 @@ buildUtil.getDependencyList = function(/*Object*/dependencies, /*String or Array
 			djGlobal['djConfig'] = undefined;
 	
 			delete dojo;
+			delete define;
 		}
 	}
 
@@ -633,8 +723,8 @@ buildUtil.determineUriList = function(/*Array*/dependencies, /*Array*/layerUris,
 		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 
+			//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);
@@ -662,33 +752,36 @@ buildUtil.determineUriList = function(/*Array*/dependencies, /*Array*/layerUris,
 			//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; 
-					} 
-				} 
-			} 
+				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; 
+	//Clear out the loadedUris for the next run.
+	dojo._loadedUrls = [];
+	return depList;
 }
 
 
 buildUtil.evalProfile = function(/*String*/profileFile, /*Boolean*/fileIsProfileText){
 	var dependencies = {};
-	var hostenvType = null;
 	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"]){
@@ -755,7 +848,7 @@ buildUtil.getDojoPrefixPath = function(/*Array*/prefixes){
 
 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. 
+	//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]){
@@ -817,7 +910,7 @@ buildUtil.createLayerContents = function(
 	//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(); 
+	provideList = provideList.sort();
 	var depRegExpString = "";
 	for(i = 0; i < provideList.length; i++){
 		//Skip keepRequire matches.
@@ -899,11 +992,11 @@ buildUtil.changeVersion = function(/*String*/version, /*String*/fileContents){
 	
 	//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] || ""; 
+	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(
@@ -931,7 +1024,7 @@ buildUtil.makeDojoJs = function(/*Object*/dependencyResult, /*String*/version, /
 	//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 dependencyResult;
 
 	//Return the dependency list, since it is used for other things in the ant file.
 	return {
@@ -1020,7 +1113,7 @@ buildUtil.mapPathToResourceName = function(pathName, prefixes){
 	//Remove file extensions and any front slash.
 	newPathName = newPathName.replace(/^\//, "").replace(/\..*?$/, "");
 	
-	return bestPrefix + "." + newPathName.replace(/\//g, "."); 
+	return bestPrefix + "." + newPathName.replace(/\//g, ".");
 }
 
 buildUtil.mapResourceToPath = function(resourceName, prefixes){
@@ -1124,7 +1217,7 @@ buildUtil.internTemplateStringsInFile = function(resourceFile, srcRoot, prefixes
 	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.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);
 
@@ -1144,7 +1237,7 @@ buildUtil.interningRegexpMagic = function(resourceFile, resourceContent, srcRoot
 
 		//logger.trace("Module match: " + parts[6] + " and " + parts[9]);
 		filePath = buildUtil.makeResourceUri(parts[6], parts[9], srcRoot, prefixes);
-		resourceNsName = parts[6] + ':' + parts[9];		
+		resourceNsName = parts[6] + ':' + parts[9];
 
 		if(!filePath || buildUtil.isValueInArray(resourceNsName, skiplist)){
 			logger.trace("    skipping " + filePath);
@@ -1295,10 +1388,11 @@ buildUtil.optimizeJs = function(/*String fileName*/fileName, /*String*/fileConte
 			//Set up options
 			var options = new jscomp.CompilerOptions();
 			options.prettyPrint = optimizeType.indexOf(".keepLines") !== -1;
-			var FLAG_compilation_level = flags.Flag.value(jscomp.CompilationLevel.SIMPLE_OPTIMIZATIONS);
-			FLAG_compilation_level.get().setOptionsForCompilationLevel(options);
-			var FLAG_warning_level = flags.Flag.value(jscomp.WarningLevel.DEFAULT);
-			FLAG_warning_level.get().setOptionsForWarningLevel(options);
+
+			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);
@@ -1697,39 +1791,39 @@ buildUtil.baseMappings = {
 	"_destroyElement": "html",
 	"isDescendant": "html",
 	"setSelectable": "html",
-	"place": "html", 
-	"getComputedStyle": "html", 
-	"_toPixelValue": "html", 
+	"place": "html",
+	"getComputedStyle": "html",
+	"_toPixelValue": "html",
 	"_getOpacity": "html",
-	"_setOpacity": "html", 
-	"style": "html", 
-	"_getPadExtents": "html", 
+	"_setOpacity": "html",
+	"style": "html",
+	"_getPadExtents": "html",
 	"_getBorderExtents": "html",
-	"_getPadBorderExtents": "html", 
-	"_getMarginExtents": "html", 
+	"_getPadBorderExtents": "html",
+	"_getMarginExtents": "html",
 	"_getMarginBox": "html",
-	"_getContentBox": "html", 
-	"_getBorderBox": "html", 
-	"_setBox": "html", 
+	"_getContentBox": "html",
+	"_getBorderBox": "html",
+	"_setBox": "html",
 	"_usesBorderBox": "html",
-	"_setContentSize": "html", 
-	"_setMarginBox": "html", 
-	"marginBox": "html", 
+	"_setContentSize": "html",
+	"_setMarginBox": "html",
+	"marginBox": "html",
 	"contentBox": "html",
-	"_docScroll": "html", 
-	"_isBodyLtr": "html", 
+	"_docScroll": "html",
+	"_isBodyLtr": "html",
 	"_getIeDocumentElementOffset": "html",
 	"_fixIeBiDiScrollLeft": "html",
-	"_abs": "html", 
-	"coords": "html", 
-	"hasAttr": "html", 
+	"_abs": "html",
+	"coords": "html",
+	"hasAttr": "html",
 	"attr": "html",
 	"removeAttr": "html",
 	"create": "html",
 	"empty": "html",
 	"_toDom": "html",
-	"hasClass": "html", 
-	"addClass": "html", 
+	"hasClass": "html",
+	"addClass": "html",
 	"removeClass": "html",
 	"toggleClass": "html",
 	
@@ -1738,11 +1832,11 @@ buildUtil.baseMappings = {
 	"_filterQueryResult": "query",
 	"query": "query",
 	
-	"formToObject": "xhr", 
+	"formToObject": "xhr",
 	"objectToQuery": "xhr",
 	"formToQuery": "xhr",
 	"formToJson": "xhr",
-	"queryToObject": "xhr", 
+	"queryToObject": "xhr",
 	"_ioSetArgs": "xhr",
 	"_ioCancelAll": "xhr",
 	"_ioAddQueryToUrl": "xhr",
@@ -2006,7 +2100,7 @@ buildUtil.extractMatchedParens = function(/*RegExp*/ regexp, /*String*/fileConte
 		// 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 
+		// add file's fragment from previous console.* match to current match
 		cleanedContent.push(fileContents.substring(previousLastIndex, startIndex));
 		
 		// Account for ending semicolon if desired.
diff --git a/util/buildscripts/jslib/buildUtilXd.js b/util/buildscripts/jslib/buildUtilXd.js
index a5e8a2f..2f1b2df 100644
--- a/util/buildscripts/jslib/buildUtilXd.js
+++ b/util/buildscripts/jslib/buildUtilXd.js
@@ -67,7 +67,7 @@ buildUtilXd.xdgen = function(
 			//bundles flattened (therefore have a dojo.provide call),
 			//need to have special xd contents.
 			if(jsFileName.match(/\/nls\//) && fileContents.indexOf("dojo.provide(") == -1){
-				var xdContents = buildUtilXd.makeXdBundleContents(prefixName, prefixPath, jsFileName, fileContents, prefixes, kwArgs);			
+				var xdContents = buildUtilXd.makeXdBundleContents(prefixName, prefixPath, jsFileName, fileContents, prefixes, kwArgs);
 			}else{
 				xdContents = buildUtilXd.makeXdContents(fileContents, prefixes, kwArgs);
 			}
diff --git a/util/buildscripts/jslib/convertTestsToXDomain.js b/util/buildscripts/jslib/convertTestsToXDomain.js
index 74c56a6..dffd7ba 100644
--- a/util/buildscripts/jslib/convertTestsToXDomain.js
+++ b/util/buildscripts/jslib/convertTestsToXDomain.js
@@ -10,7 +10,7 @@ load("jslib/buildUtil.js");
 var fileList = fileUtil.getFilteredFileList(startDir, /\.(html|htm)$/, true);
 
 for(var i = 0; i < fileList.length; i++){
-	var fileName = fileList[i];	
+	var fileName = fileList[i];
 	var fileContents = fileUtil.readFile(fileName);
 	fileContents = fileContents.replace(/src\=\".*dojo.js"/, 'src="' + xdDojoUrl + '"');
 	fileUtil.saveUtf8File(fileName, fileContents);
diff --git a/util/buildscripts/jslib/fileUtil.js b/util/buildscripts/jslib/fileUtil.js
index 1800e86..3ef7916 100644
--- a/util/buildscripts/jslib/fileUtil.js
+++ b/util/buildscripts/jslib/fileUtil.js
@@ -8,7 +8,7 @@ fileUtil.getLineSeparator = function(){
 	return java.lang.System.getProperty("line.separator"); //Java String
 }
 
-fileUtil.getFilteredFileList = function(/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsJavaObject){
+fileUtil.getFilteredFileList = function(/*String*/startDir, /*RegExp*/regExpFilters, /*boolean?*/makeUnixPaths, /*boolean?*/startDirIsJavaObject, /*boolean?*/dontRecurse){
 	//summary: Recurses startDir and finds matches to the files that match regExpFilters.include
 	//and do not match regExpFilters.exclude. Or just one regexp can be passed in for regExpFilters,
 	//and it will be treated as the "include" case.
@@ -48,7 +48,7 @@ fileUtil.getFilteredFileList = function(/*String*/startDir, /*RegExp*/regExpFilt
 				if(ok && !file.getName().match(/^\./)){
 					files.push(filePath);
 				}
-			}else if(file.isDirectory() && !file.getName().match(/^\./)){
+			}else if(file.isDirectory() && !file.getName().match(/^\./) && !dontRecurse){
 				var dirFiles = this.getFilteredFileList(file, regExpFilters, makeUnixPaths, true);
 				files.push.apply(files, dirFiles);
 			}
@@ -77,6 +77,76 @@ fileUtil.copyDir = function(/*String*/srcDir, /*String*/destDir, /*RegExp*/regEx
 	return copiedFiles.length ? copiedFiles : null; //Array or null
 }
 
+fileUtil.asyncFixEOLRe= new RegExp(fileUtil.getLineSeparator(), "g");
+
+fileUtil.transformAsyncModule= function(filename, contents) {
+	var match,
+		bundleMatch,
+		moduleId,
+		requireArgs = [],
+		lineSeparator = fileUtil.getLineSeparator(),
+		dojo = { isBrowser:true },
+		getAsyncArgs = function(moduleId_, deps){
+			if(!deps){
+				//no moduleId given
+				deps= moduleId_;
+			} else {
+				moduleId= moduleId_;
+			}
+			for (var i = 0; i < deps.length; i++) {
+				if (deps[i]!="require") {
+					requireArgs.push(deps[i].replace(/\//g, "."));
+				}
+			}
+		}
+	;
+
+	// the v1.x content in the i18n bundles is bracketed by "//begin v1.x content" and "//end v1.x content"
+	match = contents.match(/(\/\/begin\sv1\.x\scontent)([\s\S]+)(\/\/end\sv1\.x\scontent)/);
+	if(match){
+		return match[2];
+	}
+	// must not be an i18n bundle
+
+	match = contents.match(/\/\/\s*AMD\-ID\s*"([^\n"]+)"/i);
+	moduleId = (match && match[1]) || "";
+	if(moduleId || contents.substring(0, 8) == "define(\""){
+		if((match = contents.match(/^define\(([^\]]+)\]\s*\,[\s\n]*function.+$/m))){
+			eval("getAsyncArgs(" + match[1] + "])");
+			if(!moduleId){
+				logger.info("warning: the module " + filename + " looked like an AMD module, but didn't provide a module id");
+				return contents;
+			}
+			var prefix = "dojo.provide(\"" + moduleId.replace(/\//g, ".") + "\");" + lineSeparator;
+			for(var req, reqs = requireArgs, i = 0; i<reqs.length; i++){
+				req = reqs[i];
+				if(req.substring(0, 5) == "text!"){
+					// do nothing
+				}else if(req.substring(0, 5) == "i18n!"){
+					bundleMatch = req.match(/i18n\!(.+)\.nls\.(\w+)/);
+					prefix += "dojo.requireLocalization(\"" + bundleMatch[1].replace(/\//g, ".") + "\", \"" +	 bundleMatch[2] +	 "\");" + lineSeparator;
+				}else if(req != "dojo" && req != "dijit" && req != "dojox" && !/^dojo\.lib/.test(req)){
+					prefix += "dojo.require(\"" + req +	"\");" + lineSeparator;
+				}
+			}
+
+			// strip all module return values that end with the comment "// AMD-result"
+			contents = contents.replace( /^\s*return\s+.+\/\/\s*AMD-return((\s.+)|(\s*))$/img , "");
+			var matchLength = match.index + match[0].length + 1;
+			var contentsLength = contents.search(/\s*return\s+[_a-zA-Z\.0-9]+\s*;\s*(\/\/.+)?\s*\}\);\s*$/);
+			if(contentsLength == -1){
+				//logger.info("warning: no return for: " + fileUtil.asyncProvideArg);
+				contentsLength= contents.search(/\}\);\s*$/);
+			}
+			return prefix + lineSeparator + contents.substring(matchLength, contentsLength);
+		} else {
+			return contents;
+		}
+	} else {
+		return contents;
+	}
+};
+
 fileUtil.copyFile = function(/*String*/srcFileName, /*String*/destFileName, /*boolean?*/onlyCopyNew){
 	//summary: copies srcFileName to destFileName. If onlyCopyNew is set, it only copies the file if
 	//srcFileName is newer than destFileName. Returns a boolean indicating if the copy occurred.
@@ -102,12 +172,16 @@ fileUtil.copyFile = function(/*String*/srcFileName, /*String*/destFileName, /*bo
 		}
 	}
 
-	//Java's version of copy file.
-	var srcChannel = new java.io.FileInputStream(srcFileName).getChannel();
-	var destChannel = new java.io.FileOutputStream(destFileName).getChannel();
-	destChannel.transferFrom(srcChannel, 0, srcChannel.size());
-	srcChannel.close();
-	destChannel.close();
+	if (/.+\.js$/.test(srcFileName)) {
+		fileUtil.saveUtf8File(destFileName, fileUtil.transformAsyncModule(srcFileName, fileUtil.readFile(srcFileName)).replace(fileUtil.asyncFixEOLRe, "\n"));
+	} else {
+		//Java's version of copy file.
+		var srcChannel = new java.io.FileInputStream(srcFileName).getChannel();
+		var destChannel = new java.io.FileOutputStream(destFileName).getChannel();
+		destChannel.transferFrom(srcChannel, 0, srcChannel.size());
+		srcChannel.close();
+		destChannel.close();
+	}
 	
 	return true; //Boolean
 }
diff --git a/util/buildscripts/jslib/i18nUtil.js b/util/buildscripts/jslib/i18nUtil.js
index 73fa6fa..a426c7b 100644
--- a/util/buildscripts/jslib/i18nUtil.js
+++ b/util/buildscripts/jslib/i18nUtil.js
@@ -64,7 +64,7 @@ i18nUtil.flattenLayerFileBundles = function(/*String*/fileName, /*String*/fileCo
 	};
 	
 	var requireStatements = fileContents.match(/dojo\.requireLocalization\(.*\)\;/g);
-	if(requireStatements){	
+	if(requireStatements){
 		eval(requireStatements.join(";"));
 
 		//print("loaded bundles: "+djLoadedBundles.length);
@@ -170,7 +170,7 @@ i18nUtil.flattenDirBundles = function(/*String*/prefixName, /*String*/prefixDir,
 		
 		//Files in nls directories, except for layer bundles that already have been processed.
 		if(jsFileName.match(/\/nls\//) && !jsFileName.match(nlsIgnoreRegExp)){
-			fileContents = "(" + i18nUtil.makeFlatBundleContents(prefixName, prefixDir, jsFileName) + ")";			
+			fileContents = "(" + i18nUtil.makeFlatBundleContents(prefixName, prefixDir, jsFileName) + ")";
 		}else{
 			fileContents = i18nUtil.modifyRequireLocalization(readText(jsFileName), prefixes);
 		}
@@ -217,9 +217,9 @@ i18nUtil.modifyRequireLocalization = function(/*String*/fileContents, /*Array*/p
 					replacement = "dojo." + depCall + "(" + depArgs + ")";
 				}
 			}
-			return replacement;		
+			return replacement;
 		});
-	}	
+	}
 	return modifiedContents;
 }
 
@@ -320,7 +320,7 @@ i18nUtil.getBundlePartsFromFileName = function(prefix, prefixPath, srcFileName){
 		var bundleName = parts[i+1];
 	}else{
 		var localeName = parts[i+1];
-		var bundleName = parts[i+2];	
+		var bundleName = parts[i+2];
 	}
 
 	if(!bundleName || bundleName.indexOf(".js") == -1){
diff --git a/util/buildscripts/makeDojoJsWeb.js b/util/buildscripts/makeDojoJsWeb.js
index c24619b..57c6c45 100644
--- a/util/buildscripts/makeDojoJsWeb.js
+++ b/util/buildscripts/makeDojoJsWeb.js
@@ -96,7 +96,7 @@ if(isInputOk){
 		
 		result = "OK";
 	}catch(e){
-		result = "ERROR: " + e;	
+		result = "ERROR: " + e;
 	}
 
 	print(result);
diff --git a/util/buildscripts/profiles/baseplus.profile.js b/util/buildscripts/profiles/baseplus.profile.js
index 19e517d..c5257a5 100644
--- a/util/buildscripts/profiles/baseplus.profile.js
+++ b/util/buildscripts/profiles/baseplus.profile.js
@@ -3,10 +3,10 @@ dependencies = {
 		{
 			// This is a specially named layer, literally 'dojo.js'
 			// adding dependencies to this layer will include the modules
-			// in addition to the standard dojo.js base APIs. 
+			// in addition to the standard dojo.js base APIs.
 			name: "dojo.js",
 			dependencies: [
-				"dijit._Widget", 
+				"dijit._Widget",
 				"dijit._Templated",
 				"dojo.fx",
 				"dojo.NodeList-fx"
diff --git a/util/buildscripts/profiles/demos-all.profile.js b/util/buildscripts/profiles/demos-all.profile.js
index c0dc3d3..b38d01a 100644
--- a/util/buildscripts/profiles/demos-all.profile.js
+++ b/util/buildscripts/profiles/demos-all.profile.js
@@ -1,7 +1,14 @@
 // This is the demos-all profile, which mimics the nightly checkout/build profile, but adds in the demos/
 // 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 
+// 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:
 		{
diff --git a/util/buildscripts/profiles/mobile-all.profile.js b/util/buildscripts/profiles/mobile-all.profile.js
new file mode 100755
index 0000000..1e63d91
--- /dev/null
+++ b/util/buildscripts/profiles/mobile-all.profile.js
@@ -0,0 +1,36 @@
+dependencies = {
+	stripConsole: "normal",
+
+	layers: [
+		{
+			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"
+			]
+		},
+		{
+			name: "../dojox/mobile/compat.js",
+			dependencies: [
+				"dijit._base.sniff",
+				"dojo._base.fx",
+				"dojox.mobile.compat"
+			]
+		}
+	],
+
+	prefixes: [
+		[ "dijit", "../dijit" ],
+		[ "dojox", "../dojox" ]
+	]
+}
diff --git a/util/buildscripts/profiles/mobile.profile.js b/util/buildscripts/profiles/mobile.profile.js
new file mode 100755
index 0000000..35421cb
--- /dev/null
+++ b/util/buildscripts/profiles/mobile.profile.js
@@ -0,0 +1,41 @@
+dependencies = {
+	stripConsole: "normal",
+	layers: [
+		{
+			name: "dojo.js",
+			dependencies: [
+				"dijit._WidgetBase",
+				"dijit._base.manager"
+			]
+		},
+		{
+			name: "../dojox/mobile.js",
+			dependencies: [
+				"dojox.mobile"
+			]
+		},
+		{
+			name: "../dojox/mobile/app.js",
+			dependencies: [
+				"dojox.mobile.app"
+			]
+		},
+		{
+			name: "../dojox/mobile/compat.js",
+			dependencies: [
+				"dojox.mobile.compat"
+			]
+		},
+		{
+			name: "../dojox/mobile/app/compat.js",
+			dependencies: [
+				"dojox.mobile.app.compat"
+			]
+		}
+	],
+
+	prefixes: [
+		[ "dijit", "../dijit" ],
+		[ "dojox", "../dojox" ]
+	]
+}
diff --git a/util/buildscripts/profiles/rhino.profile.js b/util/buildscripts/profiles/rhino.profile.js
index 9e02fb1..87bb5ff 100644
--- a/util/buildscripts/profiles/rhino.profile.js
+++ b/util/buildscripts/profiles/rhino.profile.js
@@ -1,5 +1,5 @@
 /*This profile demonstrates how to do a custom build for the Rhino environment.
-  You only need to include the "shrinksafe" prefix entry below if you want to 
+  You only need to include the "shrinksafe" prefix entry below if you want to
   be able to run the DOH unit tests directly from the release directory.
 */
 
diff --git a/util/buildscripts/profiles/standard.profile.js b/util/buildscripts/profiles/standard.profile.js
index 8ee6935..585b9e9 100644
--- a/util/buildscripts/profiles/standard.profile.js
+++ b/util/buildscripts/profiles/standard.profile.js
@@ -33,7 +33,7 @@ dependencies = {
 				"dojox.gfx"
 			]
 		},
-		// FIXME: 
+		// FIXME:
 		//		we probably need a better structure for this layer and need to
 		//		add some of the most common themes
 		{
@@ -56,6 +56,30 @@ dependencies = {
 				"dojox.dtl.tag.misc",
 				"dojox.dtl.ext-dojo.NodeList"
 			]
+		},
+		{
+			name: "../dojox/mobile.js",
+			dependencies: [
+				"dojox.mobile"
+			]
+		},
+		{
+			name: "../dojox/mobile/app.js",
+			dependencies: [
+				"dojox.mobile.app"
+			]
+		},
+		{
+			name: "../dojox/mobile/compat.js",
+			dependencies: [
+				"dojox.mobile.compat"
+			]
+		},
+		{
+			name: "../dojox/mobile/app/compat.js",
+			dependencies: [
+				"dojox.mobile.app.compat"
+			]
 		}
 	],
 
diff --git a/util/buildscripts/tests/conditionalTest.js b/util/buildscripts/tests/conditionalTest.js
index c235180..c65d50a 100644
--- a/util/buildscripts/tests/conditionalTest.js
+++ b/util/buildscripts/tests/conditionalTest.js
@@ -9,7 +9,7 @@ load("../jslib/buildUtil.js");
 
 
 var result = buildUtil.processConditionals(
-	"conditionalTest.txt", 
+	"conditionalTest.txt",
 	fileUtil.readFile("conditionalTest.txt"),
 	{
 		loader: "xdomain",
diff --git a/util/buildscripts/webbuild/server/js/build.js b/util/buildscripts/webbuild/server/js/build.js
index e05a0dc..9e20d8b 100644
--- a/util/buildscripts/webbuild/server/js/build.js
+++ b/util/buildscripts/webbuild/server/js/build.js
@@ -84,7 +84,7 @@ build = {
 		//"1.1.1" or "1.3.2": used to choose directory of dojo to use.
 		/*String*/version,
 		
-		//"google" or "aol" 
+		//"google" or "aol"
 		/*String*/cdnType,
 		
 		//comma-separated list of resource names. No double-quotes or quotes around values.
@@ -117,7 +117,7 @@ build = {
 		xdDojoPath += version;
 
 		//Directory that holds dojo source distro. Direct child under the helma dir
-		var dojoDir = builderPath + version + "/"; 
+		var dojoDir = builderPath + version + "/";
 		
 		//Normalize the dependencies so that have double-quotes
 		//around each dependency.
diff --git a/util/checkstyle/checkstyleUtil.js b/util/checkstyle/checkstyleUtil.js
index 046f060..e0b5d16 100644
--- a/util/checkstyle/checkstyleUtil.js
+++ b/util/checkstyle/checkstyleUtil.js
@@ -81,7 +81,7 @@ checkstyleUtil.getComments = function(contents){
 		}
 		
 		// Now look for all the lines that declare a regex variable, e.g.
-		// var begRegExp = /^,|^NOT |^AND |^OR |^\(|^\)|^!|^&&|^\|\|/i; 
+		// var begRegExp = /^,|^NOT |^AND |^OR |^\(|^\)|^!|^&&|^\|\|/i;
 		
 		idx = contents.indexOf(" = /");
 		
@@ -167,7 +167,7 @@ checkstyleUtil.getComments = function(contents){
 				break;
 		
 		}
-		if (marker != null) {	
+		if (marker != null) {
 			comments[i] = 1;
 		}
 		if (marker == UNMARK){
@@ -215,8 +215,8 @@ checkstyleUtil.getNextChar = function(contents, start, comments, ignoreNewLine){
 		if(comments && comments[i]){
 			continue;
 		}
-		if(contents.charAt(i) != " " 
-			&& contents.charAt(i) != "\t" 
+		if(contents.charAt(i) != " "
+			&& contents.charAt(i) != "\t"
 			&& (!ignoreNewLine || contents.charCodeAt(i) != 13)){
 			return {
 				value: contents[i],
@@ -227,7 +227,7 @@ checkstyleUtil.getNextChar = function(contents, start, comments, ignoreNewLine){
 	return null;
 };
 
-// Find the next occurrence of the character in the 
+// Find the next occurrence of the character in the
 // 'contents' array after the index 'start'
 checkstyleUtil.findNextCharPos = function(contents, start, character){
 	for(var i = start; i < contents.length; i++){
@@ -238,7 +238,7 @@ checkstyleUtil.findNextCharPos = function(contents, start, character){
 	return -1;
 };
 
-// Creates a simple function that searches for the token, and 
+// Creates a simple function that searches for the token, and
 // adds an error if it is found
 checkstyleUtil.createSimpleSearch = function(token, message){
 	return function(fileName, contents, comments){
@@ -266,22 +266,22 @@ checkstyleUtil.createSpaceWrappedSearch = function(token, message){
 		while(idx > -1){
 			before = contents.charAt(idx - 1);
 			after = contents.charAt(idx + tokenLength);
-			if(!comments[idx] && 
-				((before != " " && before != "\t" 
+			if(!comments[idx] &&
+				((before != " " && before != "\t"
 					&& (token != "==" || before != "!")
-					&& (token != "=" || 
-						(before != "<" && 
-						 before != ">" && 
-						 before != "=" && 
-						 before != "!" && 
-						 before != "+" && 
-						 before != "-" && 
-						 before != "*" && 
-						 before != "/" && 
-						 before != "&" && 
-						 before != "|" ))) || 
+					&& (token != "=" ||
+						(before != "<" &&
+						 before != ">" &&
+						 before != "=" &&
+						 before != "!" &&
+						 before != "+" &&
+						 before != "-" &&
+						 before != "*" &&
+						 before != "/" &&
+						 before != "&" &&
+						 before != "|" ))) ||
 				(
-					(after != " " && contents.charCodeAt(idx + tokenLength) != 13 
+					(after != " " && contents.charCodeAt(idx + tokenLength) != 13
 						&& contents.charCodeAt(idx + tokenLength) != 10)
 					&& (token != "==" || after != "=")
 					&& (token != "!=" || after != "=")
@@ -358,13 +358,13 @@ checkstyleUtil.rules = {
 					
 					for(var i = eolIdx; i > idx + 4; i--){
 						var c = contents.charAt(i);
-						if(!comments[i] 
+						if(!comments[i]
 							&& c != ' '
 							&& c != '\t'
 							&& c != ':'
 							&& !checkstyleUtil.isEOL(contents, i)){
 							checkstyleUtil.addError(
-								"A CASE statement should be followed by a new line", 
+								"A CASE statement should be followed by a new line",
 								fileName, contents, idx);
 							break;
 						}
@@ -460,7 +460,7 @@ checkstyleUtil.rules = {
 					// Make sure that there is nothing after the comment name on the same line.
 					while(!checkstyleUtil.isEOL(contents, search)){
 						if(contents[search] != " " && contents[search] != "\t"){
-							checkstyleUtil.addError("The comment \"" + comment + "\" must be followed by a new line" , 
+							checkstyleUtil.addError("The comment \"" + comment + "\" must be followed by a new line" ,
 										fileName, contents, idx);
 							break;
 						}
@@ -485,9 +485,9 @@ var noSpaceAfter = ["catch","do","finally","for","if","switch","try","while","wi
 
 // Add checks for all the elements that are not allowed to have a space after them.
 checkstyleUtil.createNoSpaceAfterFunction = function(name){
-	checkstyleUtil.rules["noSpaceAfter" + noSpaceAfter[i] + "1"] = 
+	checkstyleUtil.rules["noSpaceAfter" + noSpaceAfter[i] + "1"] =
 		checkstyleUtil.createSimpleSearch(" " + name +" ", "\" " + name + " \" cannot be followed by a space");
-	checkstyleUtil.rules["noSpaceAfter" + noSpaceAfter[i] + "2"] = 
+	checkstyleUtil.rules["noSpaceAfter" + noSpaceAfter[i] + "2"] =
 		checkstyleUtil.createSimpleSearch("\t" + name +" ", "\" " + name + " \" cannot be followed by a space");
 }
 
@@ -632,7 +632,7 @@ checkstyleUtil.replaceAllExceptComments = function(contents, old, newStr, commen
 	
 	while(idx > -1){
 		if(!comments[idx]){
-			toRemove.push(idx);		
+			toRemove.push(idx);
 		}
 
 		idx = contents.indexOf(old, idx + old.length);
@@ -708,18 +708,18 @@ checkstyleUtil.fixSpaceBeforeAndAfter = function(contents, token, comments){
 			// - char before is not a space or a tab
 			// - token is "==" and the char before is neither "!" or "="
 		
-			if(before != " " && before != "\t" 
+			if(before != " " && before != "\t"
 				&& (token != "==" || (before != "!" && before != "="))
-				&& (token != "=" || 
-						(before != "<" && 
-						 before != ">" && 
-						 before != "=" && 
-						 before != "!" && 
-						 before != "+" && 
-						 before != "-" && 
-						 before != "*" && 
-						 before != "/" && 
-						 before != "&" && 
+				&& (token != "=" ||
+						(before != "<" &&
+						 before != ">" &&
+						 before != "=" &&
+						 before != "!" &&
+						 before != "+" &&
+						 before != "-" &&
+						 before != "*" &&
+						 before != "/" &&
+						 before != "&" &&
 						 before != "|" ))
 				){
 				
@@ -731,7 +731,7 @@ checkstyleUtil.fixSpaceBeforeAndAfter = function(contents, token, comments){
 			// - char after is not a space
 			// - char after is not a new line
 			// - char after is not "="
-			if((after != " " && contents.charCodeAt(idx + len) != 13 
+			if((after != " " && contents.charCodeAt(idx + len) != 13
 					&& contents.charCodeAt(idx + len) != 10)
 					&& (token != "==" || after != "=")
 					&& (token != "!=" || after != "=")
@@ -790,8 +790,8 @@ checkstyleUtil.generateReport = function(skipPrint){
 			messageId = "m" + messageCounter++;
 			messageIds[message] = messageId;
 			
-			json.push("{id:'" + messageId + 
-					"',msg:'" + message + 
+			json.push("{id:'" + messageId +
+					"',msg:'" + message +
 					"'}");
 		}
 	}
@@ -804,10 +804,10 @@ checkstyleUtil.generateReport = function(skipPrint){
 		var folderName = getFolderName(err.file);
 		pushFolder(folderName);
 		
-		json.push("{id:'" +(ids++) + 
-					"', file:'" + err.file + 
-					"',line:" + err.line + 
-					",msg:{'_reference':'" + messageIds[err.message] + 
+		json.push("{id:'" +(ids++) +
+					"', file:'" + err.file +
+					"',line:" + err.line +
+					",msg:{'_reference':'" + messageIds[err.message] +
 					//"'},folder:'" + folderName +
 					"'},folder: 0" +
 					"}");
diff --git a/util/checkstyle/runCheckstyle.js b/util/checkstyle/runCheckstyle.js
index dcdb365..4427fcd 100644
--- a/util/checkstyle/runCheckstyle.js
+++ b/util/checkstyle/runCheckstyle.js
@@ -77,7 +77,7 @@ function checkstyle(){
 		var fileList = fileUtil.getFilteredFileList("../../" + dirs[i], /\.js$/, true);
 		for(var j = 0; j < fileList.length; j++){
 			if(fileList[j].indexOf("/test") < 0
-				&& fileList[j].indexOf("/nls") < 0 
+				&& fileList[j].indexOf("/nls") < 0
 				&& fileList[j].indexOf("/demos") < 0){
 				
 				var ignore = false;
@@ -112,7 +112,7 @@ function runCommit(){
 		
 		for(var j = 0; j < fileList.length; j++){
 			if(fileList[j].indexOf("/test") < 0
-				&& fileList[j].indexOf("/nls") < 0 
+				&& fileList[j].indexOf("/nls") < 0
 				&& fileList[j].indexOf("/demos") < 0){
 				var fileName = fileList[j].substring(0, fileList[j].length - ".checkstyle.js".length);
 				fileUtil.saveUtf8File(fileName, fileUtil.readFile(fileList[j]));
diff --git a/util/docscripts/LICENSE b/util/docscripts/LICENSE
index 4c93ded..aa6b39f 100644
--- a/util/docscripts/LICENSE
+++ b/util/docscripts/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2010, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/docscripts/_browse.php b/util/docscripts/_browse.php
index b688320..79ca364 100755
--- a/util/docscripts/_browse.php
+++ b/util/docscripts/_browse.php
@@ -25,7 +25,7 @@ $ajaxy = !empty($_REQUEST['ajaxy']);
 	<html>
 		<head>
 		
-		  <title>API Preview tool | The Dojo Toolkit <title>
+		  <title>API Preview tool | The Dojo Toolkit </title>
 		
 		  <script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
 		
diff --git a/util/docscripts/_browse2.php b/util/docscripts/_browse2.php
index 7fc2404..4fe6da0 100644
--- a/util/docscripts/_browse2.php
+++ b/util/docscripts/_browse2.php
@@ -21,52 +21,75 @@ $ajaxy = !empty($_REQUEST['ajaxy']);
 $showall = isset($_REQUEST['showall']);
 
 ?>
-
 <?php if(!$ajaxy){ ?>
+	<!DOCTYPE html>
 	<html>
 		<head>
 		
-		  <title>API Preview tool | The Dojo Toolkit <title>
-		
-		  <script type="text/javascript" src="../../dojo/dojo.js" djConfig="parseOnLoad:true"></script>
+			<title>API Preview tool | The Dojo Toolkit</title>
 		
-		  <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");
-			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').setHref(e.target.href + "&ajaxy=true");
+			<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>
-		  <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>
+			</script>
+
 		</head>
-	<body class="soria">
+		<body class="claro">
 <?php
 
 } // $ajaxy
@@ -78,162 +101,170 @@ $tree = '';
 $u = 0; 
 $files = dojo_get_files(); 
 foreach ($files as $set){ 
-  list($namespace, $file) = $set;
-  $data[$namespace][] = $file;
+	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."&showall=".$showall."\">".$ns."/".$file."</a></li>"; }
-    }else{ $testfiles[] = $ns."/".$file; } 
-  }
-  $tree .= "</ul>";
-  $trees[$ns] = $tree;
+	$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'];
+
+	$ns = $_REQUEST['ns'];
+	$ifile = $_REQUEST['file'];
   
 
-  if($ifile){
-    $apiData = dojo_get_contents($ns,$ifile);
+	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){
+		$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;
+						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;
+							// 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 "tags":
+								$print .= "<li><em>$key2</em>: " . implode(' ', $val2) . '</li>';
+								break;
 
-                case "optional":
-                  if ($val2) {
-                    $print .= "<li><em>$key2</em></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;
+							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;
+							// 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;
 
-                // 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>";
-  }
-}
+							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="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" tabPosition="bottom">
+		<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."\">";
@@ -243,11 +274,11 @@ if(!$ajaxy){ ?>
 			?>
 		</div>
 	</div>
-    <div dojoType="dijit.layout.TabContainer" closeable="false" region="center">
+	<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>
 </div>
 </body>
 </html>
diff --git a/util/docscripts/cheat.php b/util/docscripts/cheat.php
index e52e285..d5e535a 100644
--- a/util/docscripts/cheat.php
+++ b/util/docscripts/cheat.php
@@ -17,8 +17,7 @@
 	if(!empty($_POST['body'])){
 		
 		$head .= "<style type='text/css'>" . file_get_contents("cheat/cheat.css") ."</style></head><body>";
-		$page = $head . $_POST['body'] . "<div class='note'><p>Dojo " . $_POST['version'] . 
-			" Docs generated " . date("Y-m-d") . "</p></div>" . $foot;
+		$page = $head . $_POST['body'] . $foot;
 			
 		if(is_writable("./cheat.html")){
 			file_put_contents("./cheat.html", stripslashes($page));
@@ -39,7 +38,7 @@
 
 		<script type="text/javascript">		
 			dojo.require("util.docscripts.cheat.lib");
-			dojo.addOnLoad(function(){
+			dojo.ready(function(){
 				
  				// a list of things to ignore in the dojo namespace (either useless, or handled specially)
 				var ap = util.docscripts.cheat.lib;
@@ -122,6 +121,8 @@
 					}
 				});
 				
+				dojo.byId("version").innerHTML = dojo.version;
+				
 			});
 		</script>
 	
@@ -140,9 +141,10 @@
 							<li>dk = d.keys</li>
 						</ul>
 					</fieldset>
-				</div>				
+				</div>
 			</div>
 		</fieldset>
 		<div id="container"></div>
+		<span id="version"></span>
 	</body>
 </html>
diff --git a/util/docscripts/cheat/cheat.css b/util/docscripts/cheat/cheat.css
index e2e5b87..e9f2b89 100644
--- a/util/docscripts/cheat/cheat.css
+++ b/util/docscripts/cheat/cheat.css
@@ -120,4 +120,4 @@ li {
 	#vertical-align: auto;	/* makes TextBox,Button line up w/native counterparts on IE6 */
 }
 
-.note { color:#a7a7a7; text-align:center; font-size:9pt; }
\ No newline at end of file
+#version { position:absolute; right:18px; top:10px; color:#a7a7a7; font-size:9pt; }
\ No newline at end of file
diff --git a/util/docscripts/cheat/floatup.js b/util/docscripts/cheat/floatup.js
new file mode 100644
index 0000000..266ec93
--- /dev/null
+++ b/util/docscripts/cheat/floatup.js
@@ -0,0 +1,112 @@
+dojo.provide("util.docscripts.cheat.floatup");
+(function(d){
+	
+	function getMax(list){
+		return Math.max.apply(Math, list)
+	}
+
+	function getMin(list){
+		return Math.min.apply(Math, list);
+	}
+
+	function sum(ar){
+		var t = 0;
+		dojo.forEach(ar, function(v){ t += v });
+		return t;
+	}
+
+	d.NodeList.prototype.floatup = function(selector){
+		
+		selector = selector || "> *";
+		
+		return this.forEach(function(n){
+		   
+			var targets = d.query(selector, n),
+				colWidth = 254,
+				cols = 4,
+				useHighest = true,
+				numTargets = targets.length,
+				targetData = d.map(targets, function(n){ return [n, Math.floor(d.position(n).h)] });
+				heights = d.map(targetData, function(o){ return o[1]; }),
+				totalHeight = sum(heights),
+				// optimum is either the largest height or an average of the total height over the cols
+				avgHeight = totalHeight / cols,
+				maxHeight = getMax(heights),
+				optimumHeight = Math.max(avgHeight, maxHeight),
+				threshold = 75 // pixels to allow over/under optimum
+			;
+
+			function inBounds(val){
+				// returns bool if passed height is within bounds of optimum
+				var upper = optimumHeight + threshold, lower = optimumHeight - threshold;
+				if(val == optimumHeight || (val <= upper && val >= lower)){
+					return true;
+				}else{
+					return false;
+				}
+			}
+
+			function getOptimumPositions(data, sizes, cols){
+				// return an Array of Arrays. Each item in the top level array will be an Array
+				//	of reference to the nodes that needs to be in the corresponding col
+
+				var col = 0;
+				var ret = new Array(cols + 1);
+				d.forEach(ret, function(i, idx){ ret[idx] = []; });
+
+				function colFromHeap(ar){
+					//console.warn("making col", col, ar, sum(ar), sizes.length, data.length, ret[col]);
+					d.forEach(ar, function(size){
+						var idx = d.indexOf(sizes, size);
+						if(~idx){
+							ret[col].push(data[idx][0]);
+							data.splice(idx, 1);
+							sizes.splice(idx, 1);
+						}else{
+							// console.warn("ugh?", size, sizes, idx);
+						}
+
+					});
+					// console.log(ret[col]);
+					col++;
+				}
+				var pass = 0;
+
+				while(sizes.length){
+
+					var heap = [];
+
+					// first size
+					heap.push(useHighest ? getMax(sizes) : sizes[0]);
+					if(!inBounds(sum(heap))){
+						d.forEach(sizes, function(size){
+							var now = sum(heap);
+							if(inBounds(now + size) || size < optimumHeight - now){
+								heap.push(size);
+							}
+						});
+					}
+
+					colFromHeap(heap);
+				}
+
+				return ret;
+			}
+				
+			var stuff = getOptimumPositions(targetData, heights, cols);
+			d.forEach(stuff, function(col, idx){
+
+				var colNode = d.create("div", {
+					style:{ width: colWidth + "px", "float":"left" }
+				}, n);
+
+				d.forEach(col, function(node){
+					d.place(node, colNode);
+				});
+			});
+			
+		});
+		
+	};
+
+})(dojo);
\ No newline at end of file
diff --git a/util/docscripts/cheat/lib.js b/util/docscripts/cheat/lib.js
index 810ca1c..594b244 100644
--- a/util/docscripts/cheat/lib.js
+++ b/util/docscripts/cheat/lib.js
@@ -1,4 +1,5 @@
 dojo.provide("util.docscripts.cheat.lib");
+dojo.require("util.docscripts.cheat.floatup");
 (function(){
 	
 	var api = util.docscripts.cheat.lib;
@@ -21,16 +22,16 @@ dojo.provide("util.docscripts.cheat.lib");
 
 		ignore:[
 			// stuff to ignore:
-			"keys", "NodeList", "fx", "prototype", 
+			"keys", "NodeList", "fx", "prototype", "lib", /* AMD package module */
 			
 			// lifecycle stuff to hide
-			"loaded", "unloaded", "loadInit", "windowUnloaded",
+			"loaded", "unloaded", "loadInit", "windowUnloaded", "simulatedLoading", "floatup",
 			"preamble", "WidgetSet", "registry", "inherited", "postscript",
 
 			// dijit.WidgetSet
-			"add", "remove", 
+			"add", "remove",
 
-			// 
+			//
 			"dijit", "form", "layout", "lang", "dir", "class",
 			"declaredClass", "wai", "typematic", "popup",
 
@@ -45,7 +46,7 @@ dojo.provide("util.docscripts.cheat.lib");
 		tags: {
 			dojo:{
 				"Effects":[
-					"anim", "animateProperty", "fadeIn", "fadeOut", "animate", "fx.chain", "fx.combine", 
+					"anim", "animateProperty", "fadeIn", "fadeOut", "animate", "fx.chain", "fx.combine",
 					"_Animation", "_Line", "Animation" /* _Animation deprecated in 1.4 */
 				],
 
@@ -54,7 +55,7 @@ dojo.provide("util.docscripts.cheat.lib");
 				],
 
 				"Language-Helpers":[
-					"isArray", "isFunction", "isString", "isObject", "isArrayLike", "unique", 
+					"isArray", "isFunction", "isString", "isObject", "isArrayLike", "unique",
 					"eval", "isAlien", "trim", "Deferred", "_toArray", "replace", "when"
 				],
 
@@ -64,13 +65,13 @@ dojo.provide("util.docscripts.cheat.lib");
 				],
 
 				"Event-System":[
-					"connect", "publish", "subscribe", "pub", "sub", "unsubscribe", "disconnect", 
+					"connect", "publish", "subscribe", "pub", "sub", "unsubscribe", "disconnect",
 					"fixEvent", "stopEvent", "connectPublisher", "isCopyKey", "mouseButtons"
 				],
 
 				"NodeList-Events":[
 					"onmousedown", "onmouseenter", "onmouseleave", "onmousemove", "onmouseover",
-					 "onmouseout", "onblur", 
+					 "onmouseout", "onblur",
 					"onfocus", "onclick", "onchange", "onload", "onmousedown", "onmouseup", "onsubmit",
 					"onerror", "onkeydown", "onkeypress", "onkeyup", "hover"
 				],
@@ -90,7 +91,7 @@ dojo.provide("util.docscripts.cheat.lib");
 				],
 
 				"Document-Lifecycle":[
-					"addOnLoad", "addOnUnload", "addOnWindowUnload","loaded", 
+					"addOnLoad", "addOnUnload", "addOnWindowUnload","loaded",
 					"unloaded", "loadInit",  "windowUnloaded", "ready"
 				],
 
@@ -110,12 +111,12 @@ dojo.provide("util.docscripts.cheat.lib");
 				],
 
 				"Styles-CSS":[
-					"style", "addClass", "removeClass", "toggleClass", "hasClass", "getComputedStyle", "boxModel", 
+					"style", "addClass", "removeClass", "toggleClass", "replaceClass", "hasClass", "getComputedStyle", "boxModel",
 					"show", "hide", "toggle", "hoverClass"
 				],
 
 				"JSON":[
-					"fromJson", "toJson", "toJsonIndentStr", "formToObject", "queryToObject", "formToQuery", 
+					"fromJson", "toJson", "toJsonIndentStr", "formToObject", "queryToObject", "formToQuery",
 					"formToJson", "objectToQuery", "fieldToObject"
 				],
 
@@ -125,10 +126,10 @@ dojo.provide("util.docscripts.cheat.lib");
 
 				"Advanced-Scope":[
 					"conflict", "withDoc", "withGlobal", "setContext", "doc", "global"
-				], 
+				],
 
 				"Sniffing":[
-					"isBrowser", "isFF", "isKhtml", "isMoz", "isMozilla", "isIE", "isOpera", "isBrowser", 
+					"isBrowser", "isFF", "isKhtml", "isMoz", "isMozilla", "isIE", "isOpera", "isBrowser",
 					"isQuirks", "isWebKit", "isChrome", /* new 1.4 */ "isMac"
 				]
 			},
@@ -173,14 +174,14 @@ dojo.provide("util.docscripts.cheat.lib");
 				"Dijit-Utils":[
 					"getUniqueId", "getDocumentWindow", "getViewport", "scrollIntoView", "BackgroundIframe",
 					"registerIframe", "moveToBookmark", "getBookmark", "isCollapsed", "placementRegistry",
-					"registerWin" 
+					"registerWin"
 				]
-			}	
+			}
 		},
 
 		getTag: function(key, part){
 			part = part || "dojo";
-			if(api.tags[part]){ 
+			if(api.tags[part]){
 				// summary: find the first matching function name in the tagMap
 				for(var i in api.tags[part]){
 					if(dojo.indexOf(api.tags[part][i], key) >= 0){
@@ -192,7 +193,7 @@ dojo.provide("util.docscripts.cheat.lib");
 		},
 
 		getUl: function(tag){
-			// find the UL within a <div> with this tag's id, or make it. 
+			// find the UL within a <div> with this tag's id, or make it.
 			// return the UL node
 			var n = dojo.byId(tag);
 			if(!n){
@@ -205,7 +206,7 @@ dojo.provide("util.docscripts.cheat.lib");
 
 		getSig: function(key, member, fn){
 			// makup up a function signature for this object
-			if(!dojo.isFunction(fn)){ 
+			if(!dojo.isFunction(fn)){
 //				var t = (typeof fn).toLowerCase()
 //				switch(t){
 //					case "boolean" :
@@ -219,28 +220,29 @@ dojo.provide("util.docscripts.cheat.lib");
 //							console.log(i);
 //						}
 //						break;
-//					default: 
+//					default:
 //						console.log(t);
 //						break;
 //				}
-				return key + member; 
+				return key + member;
 			}
 			if(/^_?[A-Z]/.test(member)){
 				key = "<span class='sig'>new</span> " + key;
 
 // FIXME: determine the actual signature for the a declaredclass?
 //				if(fn.prototype._constructor){
-//					console.log(fn.prototype._constructor)	
+//					console.log(fn.prototype._constructor)
 //				}
 				
 			}
+			// FIXME: unwrap key (refactor all this) so we can link around it to API docs
 			return key + member + "<span class='sig'>" + fn.toString().replace(/function\s+/, "").split(")")[0] + ")" + "</span>";
 		},
 
 		save: function(){
-			dojo.xhrPost({ 
+			dojo.xhrPost({
 				url:"cheat.php",
-				content: { body: dojo.body().innerHTML, version: dojo.version.toString() },
+				content: { body: dojo.body().innerHTML },
 				load: function(response){
 					window.location.href = "./cheat.html";
 				},
@@ -252,7 +254,7 @@ dojo.provide("util.docscripts.cheat.lib");
 
 		buildNav: function(){
 
-			dojo.query("#container > fieldset").forEach(function(n){
+			dojo.query("#container fieldset").forEach(function(n){
 
 				var id = n.id;
 				var mySize = dojo.query(n).query("li").length;
@@ -273,7 +275,7 @@ dojo.provide("util.docscripts.cheat.lib");
 			}else if(dojo.exists(strsomething)){
 				something = dojo.getObject(strsomething);
 			}
-			if(!something){ return; } 
+			if(!something){ return; }
 			
 			var k = api.varmap[strsomething] || (strsomething + ".");
 			for(var i in something){
@@ -291,23 +293,13 @@ dojo.provide("util.docscripts.cheat.lib");
 		},
 		
 		sortFields: function(id){
-			// stolen from demos/faces/src.js
-			var d = dojo;
-			// don't ever let me see you doing this outside of a demo situation. there has
-			// got to be a better way.
-			id = d.byId(id);
-			d.query("> fieldset", id).sort(function(a,b){
-				var q = "ul > li", al = d.query(q, a).length, bl = d.query(q, b).length;
-				return al > bl ? 0 : al < bl ? 1 : -1;
-			}).forEach(function(n){
-				id.appendChild(n);
-			});
+			dojo.query("#" + id).floatup();
 		},
 		
 		hasTag: function(tag){
 			return window.location.href.indexOf(tag) >= 0;
 		}
 
-	});	
+	});
 
 })();
diff --git a/util/docscripts/generate.php b/util/docscripts/generate.php
index 58865e3..c949d20 100755
--- a/util/docscripts/generate.php
+++ b/util/docscripts/generate.php
@@ -14,11 +14,11 @@
 # php generate.php --outfile=custom-api custom
 # -- Runs the custom module, serializes to custom-api.xml
 
-if ($_SERVER['HTTP_HOST']) {
+if (isset($_SERVER['HTTP_HOST'])) {
   die('Run from command line');
 }
 
-ini_set('memory_limit', '128M');
+ini_set('memory_limit', '256M');
 ini_set('display_errors', 1);
 error_reporting(E_ALL ^ E_NOTICE);
 $debug = true;
@@ -437,4 +437,4 @@ foreach ($roots as $id => $root) {
 
 // * Assemble parent/child relationships
 
-?>
\ No newline at end of file
+?>
diff --git a/util/docscripts/lib/parser2/dojo2.inc b/util/docscripts/lib/parser2/dojo2.inc
index 114e334..9453bc3 100644
--- a/util/docscripts/lib/parser2/dojo2.inc
+++ b/util/docscripts/lib/parser2/dojo2.inc
@@ -143,6 +143,62 @@ function dojo_get_files($limit=null) {
     return $files;
 }
 
+function _slashtoname($thing){
+    return str_replace("/", ".", $thing);
+}
+
+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 dojo_get_contents($namespace, $file_name) {
   if (function_exists($namespace . '_code_location')) {
     $location = _dojo_ensure_directory(call_user_func($namespace . '_code_location'));
@@ -152,7 +208,10 @@ function dojo_get_contents($namespace, $file_name) {
     $location = $_dojo_properties_modules[$namespace]['location'];
   }
 
-  $lines = preg_replace('%/\*={3,}|={3,}\*/%', '', file_get_contents($location . '/' . $file_name));
+  $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();
diff --git a/util/docscripts/makeCix.php b/util/docscripts/makeCix.php
index a4e0a08..4e2632d 100755
--- a/util/docscripts/makeCix.php
+++ b/util/docscripts/makeCix.php
@@ -13,7 +13,7 @@
 //
 
 // $Rev: $ 
-$current_version = "1.5.0";
+$current_version = "1.6.0";
 
 header("Content-type: text/xml");
 
@@ -112,7 +112,7 @@ foreach ($out as $ns => $data){
 			}
 			// helpful data:
 			if(!empty($info['summary'])){
-				$objElm->setAttribute("doc", fix_utf(htmlentities($v)));
+				$objElm->setAttribute("doc", fix_utf(htmlentities($info['summary'])));
 			}
 			
 			// avoid appending this node if we skipped popoulating it (in the case of nsdata->appendCHild())
@@ -180,8 +180,13 @@ function dojo_inspect($data,$ns,$doc,$t="scope"){
 							$elm->setAttribute("ilk","function");
 							break;
 						default:
-							$elm->setAttribute("citdl",$info);
-							break;
+							if (is_array($info)) {
+							    if ($info["instance"]) {
+								$elm->setAttribute("citdl",$info["instance"]);
+							    }
+							} else {
+							    $elm->setAttribute("citdl",$info);
+							}
 					}
 				}
 				break;
diff --git a/util/docscripts/parsefile.php b/util/docscripts/parsefile.php
new file mode 100644
index 0000000..721c116
--- /dev/null
+++ b/util/docscripts/parsefile.php
@@ -0,0 +1,95 @@
+<?php
+
+//	Simple single-file doc validation utility, using our php-based `jsdoc` parser. 
+//	To be used as a post-commit hook?
+// 
+//	to use:
+//		php -q parsefile.php dojox/data/AndOrReadStore.js
+//
+//	exits normally (status 0) if OK, with status 255 if failed, other values are from PHP untrapped.
+//
+//	add --debug to last argument to see output data, eg:
+//
+//		php -q parsefile.php dijit/_Widget.js --debug
+//
+//	scan all files prior to running generate/makeCix (considerably faster to detect fatal parser-breaking errors)
+//
+//		php -q parsefile.php --all
+
+include_once('lib/parser2/dojo2.inc');
+$allfiles = dojo_get_files();
+
+function doc_passes($ns, $file, $debug){
+	try{
+		$ret = doc_test($ns, $file, $debug);
+		return $ret;
+	}catch (Exception $e){
+		return false;
+	}
+}
+
+function doc_test($ns, $file, $debug){
+	// the testing of a single file. this is where the actual testing goes.
+	
+	try{
+		$ret = true;
+		$data = dojo_get_contents($ns, $file);
+		// test other things. like we're expecting at the _very_ least a $data['#provides'] key?
+		if(empty($data['#provides'])){
+			if($debug){ 
+				print "Warning: no provide() determined. [" . $ns . "/" . $file . "]\n"; 
+			}
+			$ret = false;	 
+		}else{
+			if(count($data['#provides']) > 1){
+				if($debug){
+					print "Warning: Multiple provides() found?\n";
+					$ret = false;
+				}
+			}
+		}
+		
+		if(count($data) == 0){
+			if($debug){ print "Error: No data found. [" . $ns . "/" . $file . "]"; }
+			$ret = false;
+		}
+		
+		return $ret;
+	}catch (Exception $e){
+		print "Error: Exception trapped processing [" . $ns . "/" . $file . "]\nException:\n";
+		print $e;
+		return false;
+	}
+}
+
+if($argc){
+	
+	$argfile = $argv[1];
+	$debug = in_array("--debug", $argv);
+	if($argfile == "--all"){
+
+		$debug = true;
+		$haserror = false;
+		foreach($allfiles as $set){
+			list($ns, $file) = $set;
+			if(!doc_passes($ns, $file, $debug)){
+				$haserror = true;
+			}
+		}
+
+		if($haserror){
+			die(255);
+		}
+
+	}else{
+
+		$parts = explode("/", $argfile);
+		$ns = array_shift($parts);
+		$file = implode("/", $parts);
+		if(!doc_passes($ns, $file, $debug)){
+			die(255);
+		}
+
+	}
+
+}
diff --git a/util/doh/LICENSE b/util/doh/LICENSE
index ad1676a..aa6b39f 100644
--- a/util/doh/LICENSE
+++ b/util/doh/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2009, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/doh/_browserRunner.js b/util/doh/_browserRunner.js
index 86cbe5f..59948b4 100644
--- a/util/doh/_browserRunner.js
+++ b/util/doh/_browserRunner.js
@@ -1,10 +1,10 @@
-if(window["dojo"]){
-	dojo.provide("doh._browserRunner");
-}
-
 // FIXME: need to add prompting for monkey-do testing
 
 (function(){
+
+//here's the definition of doh/_browserRunner
+
+var d= function(doh) {
 	try{
 		var topdog = (window.parent == window) || !Boolean(window.parent.doh);
 	}catch(e){
@@ -224,7 +224,7 @@ if(window["dojo"]){
 				var standby;
 				if(doh.perfTestResults){
 					if(window.dojo){
-						//If we have dojo and here are perf tests results, 
+						//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");
@@ -345,7 +345,7 @@ if(window["dojo"]){
 					sendToLogPane.call(window, arguments);
 					console.error.apply(console, arguments);
 				};
-			} 
+			}
 			if(console.debug){
 				doh.debug = function(){
 					sendToLogPane.call(window, arguments);
@@ -602,8 +602,8 @@ if(window["dojo"]){
 		}
 
 		// FIXME: move implementation to _browserRunner?
-		doh.registerUrl = function(	/*String*/ group, 
-										/*String*/ url, 
+		doh.registerUrl = function(	/*String*/ group,
+										/*String*/ url,
 										/*Integer*/ timeout){
 			var tg = new String(group);
 			this.register(group, {
@@ -635,7 +635,7 @@ if(window["dojo"]){
 			});
 		}
 
-		// 
+		//
 		// Utility code for runner.html
 		//
 		// var isSafari = navigator.appVersion.indexOf("Safari") >= 0;
@@ -704,7 +704,7 @@ if(window["dojo"]){
 			if(loaded){ return; }
 			loaded = true;
 			groupTemplate = byId("groupTemplate");
-			if(!groupTemplate){ 
+			if(!groupTemplate){
 				// make sure we've got an ammenable DOM structure
 				return;
 			}
@@ -716,7 +716,7 @@ if(window["dojo"]){
 			doh._updateTestList();
 		});
 
-		_addOnEvt("load", 
+		_addOnEvt("load",
 			function(){
 				// let robot code run if it gets to this first
 				var __onEnd = doh._onEnd;
@@ -732,7 +732,7 @@ if(window["dojo"]){
 						toggleRunning();
 					}
 				}
-				if(!byId("play")){ 
+				if(!byId("play")){
 					// make sure we've got an amenable DOM structure
 					return;
 				}
@@ -840,6 +840,7 @@ if(window["dojo"]){
 				return tObj;
 			}
 			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);
@@ -879,5 +880,21 @@ if(window["dojo"]){
 			};
 		}
 	}
+};
 
-})();
+// 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);
diff --git a/util/doh/_rhinoRunner.js b/util/doh/_rhinoRunner.js
index 53f20fb..ebd4319 100644
--- a/util/doh/_rhinoRunner.js
+++ b/util/doh/_rhinoRunner.js
@@ -5,7 +5,7 @@ if(this["dojo"]){
 doh.debug = print;
 doh.error = print;
 
-// Override the doh._report method to make it quit with an 
+// Override the doh._report method to make it quit with an
 // appropriate exit code in case of test failures.
 (function(){
 	var oldReport = doh._report;
diff --git a/util/doh/robot.js b/util/doh/robot.js
index 6260ce0..716829e 100644
--- a/util/doh/robot.js
+++ b/util/doh/robot.js
@@ -84,7 +84,7 @@ if(!doh.robot["_robotLoaded"]){
 			}catch(e){
 				return null;
 			}
-		}	
+		}
 	},
 	
 	startRobot: function(){
@@ -184,20 +184,13 @@ if(!doh.robot["_robotLoaded"]){
 		//		Delay to wait after firing.
 		//
 
-		delay = delay || 1;
-		doh.robot._time += delay;
-		setTimeout(function(){
-			doh.robot._time -= delay;
-			f();
-			if(duration){
-				setTimeout(function(){
-					doh.robot._time -= duration;
-				}, duration);
-			}
-		}, doh.robot._time);
-		if(duration){
-			doh.robot._time += duration;
+		var currentTime = (new Date()).getTime();
+		if(currentTime > (doh.robot._time || 0)){
+			doh.robot._time = currentTime;
 		}
+		doh.robot._time += delay || 1;
+		setTimeout(f, doh.robot._time - currentTime);
+		doh.robot._time += duration || 0;
 	},
 
 	typeKeys: function(/*String||Number*/ chars, /*Integer, optional*/ delay, /*Integer, optional*/ duration){
@@ -232,7 +225,7 @@ if(!doh.robot["_robotLoaded"]){
 			}else if(chars.length){
 				_keyPress(chars.charCodeAt(0), 0, false, false, false, false, 0);
 				for(var i = 1; i<chars.length; i++){
-					_keyPress(chars.charCodeAt(i), 0, false, false, false, false, Math.max(Math.floor(duration/chars.length)-20, 0)); // 20ms is fudge for processing time until robot handles wall clock
+					_keyPress(chars.charCodeAt(i), 0, false, false, false, false, Math.max(Math.floor(duration/chars.length), 0));
 				}
 			}
 		}, delay, duration);
diff --git a/util/doh/robot/DOHRobot.jar b/util/doh/robot/DOHRobot.jar
index ed1dbc3..22517cd 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 3e28f82..ecc70a8 100644
--- a/util/doh/robot/DOHRobot.java
+++ b/util/doh/robot/DOHRobot.java
@@ -55,6 +55,7 @@ public final class DOHRobot extends Applet{
 	private boolean alt = false;
 	private boolean meta = false;
 	private boolean numlockDisabled = false;
+	private long timingError = 0; // how much time the last robot call was off by
 	// shake hands with JavaScript the first keypess to wake up FF2/Mac
 	private boolean jsready = false;
 	private String keystring = "";
@@ -76,6 +77,7 @@ public final class DOHRobot extends Applet{
 	private int docScreenY = -100;
 	private int docScreenXMax;
 	private int docScreenYMax;
+	private Point margin = null;
 	private boolean mouseSecurity = false;
 
 	// The last reported mouse x,y.
@@ -180,6 +182,9 @@ public final class DOHRobot extends Applet{
 	public void init(){
 		// ensure isShowing = true
 		addComponentListener(new onvisible());
+		ProfilingThread jitProfile=new ProfilingThread ();
+		jitProfile.startProfiling();
+		jitProfile.endProfiling();
 	}
 
 	// loading functions
@@ -326,6 +331,10 @@ public final class DOHRobot extends Applet{
 			this.lastMouseY = this.docScreenY = y;
 			this.docScreenXMax = x + w;
 			this.docScreenYMax = y + h;
+			// compute difference between position and browser edge for future reference
+			this.margin = getLocationOnScreen();
+			this.margin.x -= x;
+			this.margin.y -= y;
 			mouseSecurity=true;
 		}
 		log("< setDocumentBounds");
@@ -733,7 +742,7 @@ public final class DOHRobot extends Applet{
 			public Object run(){
 				int x = x1 + docScreenX;
 				int y = y1 + docScreenY;
-				if(x > docScreenXMax || y > docScreenYMax){
+				if(x > docScreenXMax || y > docScreenYMax || x < docScreenX || y < docScreenY){
 					// TODO: try to scroll view
 					log("Request to mouseMove denied");
 					return null;
@@ -863,6 +872,10 @@ public final class DOHRobot extends Applet{
 				case 46:
 					keyboardCode = KeyEvent.VK_DELETE;
 					break;
+				case 224:
+				case 91:
+					keyboardCode = KeyEvent.VK_META;
+					break;
 				case 63289:
 				case 144:
 					keyboardCode = KeyEvent.VK_NUM_LOCK;
@@ -1136,10 +1149,31 @@ public final class DOHRobot extends Applet{
 	}
 
 	public boolean hasFocus(){
+		// sanity check to make sure the robot isn't clicking outside the window when the browser is minimized for instance
 		try{
-			return ((Boolean) window
+			boolean result= ((Boolean) window
 					.eval("var result=false;if(window.parent.document.hasFocus){result=window.parent.document.hasFocus();}else{result=true;}result;"))
 					.booleanValue();
+			if(!result){
+				// can happen for instance if the browser minimized itself, or if there is another applet on the page.
+				// recompute window,mouse positions to see if it is still safe to continue.
+				log("Document focus lost. Recomputing window position");
+				Point p = getLocationOnScreen();
+				log("Old root: "+docScreenX+" "+docScreenY);
+				docScreenX=p.x-margin.x;
+				docScreenY=p.y-margin.y;
+				log("New root: "+docScreenX+" "+docScreenY);
+				docScreenXMax=docScreenX+((Integer)window.eval("window.parent.document.getElementById('dohrobotview').offsetLeft")).intValue();
+				docScreenYMax=docScreenY+((Integer)window.eval("window.parent.document.getElementById('dohrobotview').offsetTop")).intValue();
+				// bring browser to the front again.
+				// if the window just blurred and moved, key events will again be directed to the window.
+				// if an applet stole focus, focus will still be directed to the applet; the test script will ultimately have to click something to get back to a normal state.
+				window.eval("window.parent.focus();");
+				// recompute mouse position
+				return isSecure(this.key);
+			}else{
+				return result;
+			}
 		}catch(Exception e){
 			// runs even after you close the window!
 			return false;
@@ -1150,14 +1184,43 @@ 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!
-	final private class KeyPressThread extends Thread{
+	private class ProfilingThread extends Thread{
+		protected long delay=0;
+		protected long duration=0;
+		private long start;
+		private long oldDelay;
+		protected void startProfiling(){
+			// error correct
+			if(delay>0){
+				oldDelay=delay;
+				delay-=timingError+(duration>0?timingError:0);
+				log("Timing error: "+timingError);
+				if(delay<1){
+					if(duration>0){ duration=Math.max(duration+delay,1); }
+					delay=1;
+				}
+				start=System.currentTimeMillis();
+			}else{
+				// assumption is that only doh.robot.typeKeys actually uses delay/needs this level of error correcting
+				timingError=0;
+			}
+		}
+		protected void endProfiling(){
+			// adaptively correct timingError
+			if(delay>0){
+				long end=System.currentTimeMillis();
+				timingError+=(end-start)-oldDelay;
+			}
+		}
+	}
+	
+	final private class KeyPressThread extends ProfilingThread{
 		private int charCode;
 		private int keyCode;
 		private boolean alt;
 		private boolean ctrl;
 		private boolean shift;
 		private boolean meta;
-		private int delay;
 		private Thread myPreviousThread = null;
 
 		public KeyPressThread(int charCode, int keyCode, boolean alt,
@@ -1177,6 +1240,7 @@ public final class DOHRobot extends Applet{
 			try{
 				if(myPreviousThread != null)
 					myPreviousThread.join();
+				startProfiling();
 				// in different order so async works
 				while(!hasFocus()){
 					Thread.sleep(1000);
@@ -1185,6 +1249,8 @@ public final class DOHRobot extends Applet{
 				log("> run KeyPressThread");
 
 				_typeKey(charCode, keyCode, alt, ctrl, shift, meta);
+
+				endProfiling();
 			}catch(Exception e){
 				log("Bad parameters passed to _typeKey");
 				e.printStackTrace();
@@ -1194,10 +1260,9 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	final private class KeyDownThread extends Thread{
+	final private class KeyDownThread extends ProfilingThread{
 		private int charCode;
 		private int keyCode;
-		private int delay;
 		private Thread myPreviousThread = null;
 
 		public KeyDownThread(int charCode, int keyCode, int delay, Thread myPreviousThread){
@@ -1260,10 +1325,9 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	final private class KeyUpThread extends Thread{
+	final private class KeyUpThread extends ProfilingThread{
 		private int charCode;
 		private int keyCode;
-		private int delay;
 		private Thread myPreviousThread = null;
 
 		public KeyUpThread(int charCode, int keyCode, int delay, Thread myPreviousThread){
@@ -1325,9 +1389,8 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	final private class MousePressThread extends Thread{
+	final private class MousePressThread extends ProfilingThread{
 		private int mask;
-		private int delay;
 		private Thread myPreviousThread = null;
 
 		public MousePressThread(int mask, int delay, Thread myPreviousThread){
@@ -1356,9 +1419,8 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	final private class MouseReleaseThread extends Thread{
+	final private class MouseReleaseThread extends ProfilingThread{
 		private int mask;
-		private int delay;
 		private Thread myPreviousThread = null;
 
 		public MouseReleaseThread(int mask, int delay, Thread myPreviousThread){
@@ -1388,11 +1450,9 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	final private class MouseMoveThread extends Thread{
+	final private class MouseMoveThread extends ProfilingThread{
 		private int x;
 		private int y;
-		private int delay;
-		private int duration;
 		private Thread myPreviousThread = null;
 
 		public MouseMoveThread(int x, int y, int delay, int duration, Thread myPreviousThread){
@@ -1452,18 +1512,20 @@ public final class DOHRobot extends Applet{
 				int intermediateSteps = duration==1?0: // duration==1 -> user wants to jump the mouse
 					((((int)Math.ceil(Math.log(duration+1)))|1)); // |1 to ensure an odd # of intermediate steps for sensible interpolation
 				// assumption: intermediateSteps will always be >=0
-				int delay = duration/(intermediateSteps+1); // +1 to include last move
+				int delay = (int)duration/(intermediateSteps+1); // +1 to include last move
 				// First mouse movement fires at t=0 to official last know position of the mouse.
 				robot.mouseMove(lastMouseX, lastMouseY);
-				long date,date2;
-				date=new Date().getTime();
+				long start,end;
+				
 				// Shift lastMouseX/Y in the direction of the movement for interpolating over the smaller interval.
 				lastMouseX=x1;
 				lastMouseY=y1;
 				// Now interpolate mouse movement from (lastMouseX=x1,lastMouseY=y1) to (x2,y2)
 				// precondition: the amount of time that has passed since the first mousemove is 0*delay.
 				// invariant: each time you end an iteration, after you increment t, the amount of time that has passed is t*delay
+				int timingError=0;
 				for (int t = 0; t < intermediateSteps; t++){
+					start=new Date().getTime();
 					Thread.sleep(delay);
 					x1 = (int) easeInOutQuad((double) t, (double) lastMouseX,
 							(double) x2 - lastMouseX, (double) intermediateSteps-1);
@@ -1471,6 +1533,11 @@ public final class DOHRobot extends Applet{
 							(double) y2 - lastMouseY, (double) intermediateSteps-1);
 					//log("("+x1+","+y1+")");
 					robot.mouseMove(x1, y1);
+					end=new Date().getTime();
+					// distribute error among remaining steps
+					timingError=(((int)(end-start))-delay)/(intermediateSteps-t);
+					log("mouseMove timing error: "+timingError);
+					delay=Math.max(delay-(int)timingError,1);
 				}
 				// postconditions:
 				//	t=intermediateSteps
@@ -1481,7 +1548,7 @@ public final class DOHRobot extends Applet{
 				Thread.sleep(delay);
 				robot.mouseMove(x, y);
 				robot.setAutoWaitForIdle(true);
-				date2=new Date().getTime();
+				
 				//log("mouseMove statistics: duration= "+duration+" steps="+intermediateSteps+" delay="+delay);
 				//log("mouseMove discrepency: "+(date2-date-duration)+"ms");
 				lastMouseX = x;
@@ -1496,10 +1563,8 @@ public final class DOHRobot extends Applet{
 		}
 	}
 
-	final private class MouseWheelThread extends Thread{
+	final private class MouseWheelThread extends ProfilingThread{
 		private int amount;
-		private int delay;
-		private int duration;
 		private Thread myPreviousThread = null;
 
 		public MouseWheelThread(int amount, int delay, int duration, Thread myPreviousThread){
@@ -1518,7 +1583,7 @@ public final class DOHRobot extends Applet{
 				while(!hasFocus()){
 					Thread.sleep(1000);
 				}
-				robot.setAutoDelay(Math.max(duration/Math.abs(amount),1));
+				robot.setAutoDelay(Math.max((int)duration/Math.abs(amount),1));
 				for(int i=0; i<Math.abs(amount); i++){
 					robot.mouseWheel(amount>0?dir:-dir);
 				}
diff --git a/util/doh/runner.html b/util/doh/runner.html
index 930d755..a97b559 100644
--- a/util/doh/runner.html
+++ b/util/doh/runner.html
@@ -1,21 +1,18 @@
-<html>
-	<!--
-		NOTE: we are INTENTIONALLY in quirks mode. It makes it much easier to
-		get a "full screen" UI w/ straightforward CSS.
-	-->
+<!DOCTYPE html>
+<html style="height:100%;">
 	<!--
 		// TODO: provide a UI for prompted tests
 	-->
 	<head>
-		<title>The Dojo Unit Test Harness, $Rev: 22331 $</title>
+		<title>The Dojo Unit Test Harness, $Rev: 24358 $</title>
 
 		<script type="text/javascript">
 			// workaround for bug in Safari 3.  See #7189
 			if (/3[\.0-9]+ Safari/.test(navigator.appVersion))
 			{
 				window.console = {
-				    origConsole: window.console,
-				    log: function(s){
+					origConsole: window.console,
+						log: function(s){
 						this.origConsole.log(s);
 					},
 					info: function(s){
@@ -62,17 +59,75 @@
 					}
 				}
 			}
-
 			document.write("<scr"+"ipt type='text/javascript' djConfig='isDebug: true' src='"+dojoUrl+"'></scr"+"ipt>");
 		</script>
 		<script type="text/javascript">
-			try{
+			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");
-			}catch(e){
+				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>");
+				if(testUrl.length){
+					document.write("<scr"+"ipt type='text/javascript' src='"+testUrl+".js'></scr"+"ipt>");
+				}
 			}
 		</script>
 		<style type="text/css">
@@ -179,7 +234,7 @@
 				border: 1px solid black;
 				*/
 				position: relative;
-				height: 99%;
+				height: 100%;
 				width: 100%;
 				overflow: auto;
 			}
@@ -231,7 +286,7 @@
 			}
 		</style>
 	</head>
-	<body>
+	<body style="height: 100%;">
 		<table id="testLayout" cellpadding="0" cellspacing="0" style="margin: 0;">
 			<tr valign="top" height="40">
 				<td colspan="2" id="logoBar">
@@ -264,7 +319,7 @@
 				</td>
 			</tr>
 			<tr valign="top" style="border: 0; padding: 0; margin: 0;">
-				<td height="100%" style="border: 0; padding: 0; margin: 0;">
+				<td style="border: 0; padding: 0; margin: 0; height:100%;">
 					<div id="testListContainer">
 						<table cellpadding="0" cellspacing="0" border="0"
 							width="100%" id="testList" style="margin: 0;" onclick="doh._jumpToLog(arguments[0]);">
@@ -298,8 +353,8 @@
 						</table>
 					</div>
 				</td>
-				<td>
-					<div style="position: relative; width: 99%; height: 100%; top: 0px; left: 0px;">
+				<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>
diff --git a/util/doh/runner.js b/util/doh/runner.js
index 729299c..ef6e8f5 100644
--- a/util/doh/runner.js
+++ b/util/doh/runner.js
@@ -1,11 +1,8 @@
-// package system gunk.
-try{
-	dojo.provide("doh.runner");
-}catch(e){
-	if(!this["doh"]){
-		doh = {};
-	}
-}
+//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
@@ -46,7 +43,7 @@ doh._mixin = function(/*Object*/ obj, /*Object*/ props){
 		}
 	}
 	// IE doesn't recognize custom toStrings in for..in
-	if(	this["document"] 
+	if(	this["document"]
 		&& document.all
 		&& (typeof props["toString"] == "function")
 		&& (props["toString"] != obj["toString"])
@@ -58,7 +55,7 @@ doh._mixin = function(/*Object*/ obj, /*Object*/ props){
 }
 
 doh.mixin = function(/*Object*/obj, /*Object...*/props){
-	// summary:	Adds all properties and methods of props to obj. 
+	// 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]);
 	}
@@ -110,7 +107,7 @@ doh.error = function(){
 }
 
 doh._AssertFailure = function(msg, hint){
-	// idea for this as way of dis-ambiguating error types is from JUM. 
+	// idea for this as way of dis-ambiguating error types is from JUM.
 	// The JUM is dead! Long live the JUM!
 
 	if(!(this instanceof doh._AssertFailure)){
@@ -197,8 +194,7 @@ doh.extend(doh.Deferred, {
 			if(this.fired == -1){
 				this.errback(new Error("Deferred(unfired)"));
 			}
-		}else if(this.fired == 0 &&
-					(this.results[0] instanceof doh.Deferred)){
+		}else if(this.fired == 0 && this.results[0] && this.results[0].cancel){
 			this.results[0].cancel();
 		}
 	},
@@ -297,7 +293,7 @@ doh.extend(doh.Deferred, {
 			try {
 				res = f(res);
 				fired = ((res instanceof Error) ? 1 : 0);
-				if(res instanceof doh.Deferred){
+				if(res && res.addCallback){
 					cb = function(res){
 						self._continue(res);
 					};
@@ -378,9 +374,9 @@ doh._testFinished = function(group, fixture, success){
 	// slot to be filled in
 }
 
-doh.registerGroup = function(	/*String*/ group, 
-								/*Array||Function||Object*/ tests, 
-								/*Function*/ setUp, 
+doh.registerGroup = function(	/*String*/ group,
+								/*Array||Function||Object*/ tests,
+								/*Function*/ setUp,
 								/*Function*/ tearDown,
 								/*String*/ type){
 	// summary:
@@ -401,7 +397,7 @@ doh.registerGroup = function(	/*String*/ group,
 	// 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 
+	//		null/undefied are standard DOH tests, the valye 'perf' enables
 	//		registering them as performance tests.
 	if(tests){
 		this.register(group, tests, type);
@@ -444,7 +440,7 @@ doh._getTestObj = function(group, test, type){
 		// FIXME: try harder to get the test name here
 	}
 
-	//Augment the test with some specific options to make it identifiable as a 
+	//Augment the test with some specific options to make it identifiable as a
 	//particular type of test so it can be executed properly.
 	if(type === "perf" || tObj.testType === "perf"){
 		tObj.testType = "perf";
@@ -463,7 +459,7 @@ doh._getTestObj = function(group, test, type){
 		}
 		tObj.results = doh.perfTestResults[group][tObj.name];
 		
-		//If it's not set, then set the trial duration 
+		//If it's not set, then set the trial duration
 		//default to 100ms.
 		if(!("trialDuration" in tObj)){
 			tObj.trialDuration = 100;
@@ -479,7 +475,7 @@ doh._getTestObj = function(group, test, type){
 		if(!("trialIterations" in tObj)){
 			tObj.trialIterations = 10;
 		}
-	} 
+	}
 	return tObj;
 }
 
@@ -522,8 +518,8 @@ doh.registerTests = function(/*String*/ group, /*Array*/ testArr, /*String*/ typ
 }
 
 // FIXME: move implementation to _browserRunner?
-doh.registerUrl = function(	/*String*/ group, 
-								/*String*/ url, 
+doh.registerUrl = function(	/*String*/ group,
+								/*String*/ url,
 								/*Integer*/ timeout,
 								/*String*/ type){
 	this.debug("ERROR:");
@@ -603,7 +599,7 @@ doh.registerDocTests = function(module){
 					comment = ", "+parts[parts.length-1]; // Get all after the last //, so we dont get trapped by http:// or alikes :-).
 				}
 				tests.push({
-					runTest: (function(test){ 
+					runTest: (function(test){
 						return function(t){
 							var r = docTest.runTest(test.commands, test.expectedResult);
 							t.assertTrue(r.success);
@@ -625,9 +621,9 @@ doh.registerDocTests = function(module){
 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(arguments.length < 1){
+		throw new doh._AssertFailure("assertTrue failed because it was not passed at least 1 argument");
+	}
 	if(!eval(condition)){
 		throw new doh._AssertFailure("assertTrue('" + condition + "') failed", hint);
 	}
@@ -636,9 +632,9 @@ doh.t = doh.assertTrue = function(/*Object*/ condition, /*String?*/ hint){
 doh.f = doh.assertFalse = function(/*Object*/ condition, /*String?*/ hint){
 	// summary:
 	//		is the passed item "falsey"?
-	if(arguments.length < 1){ 
-		throw new doh._AssertFailure("assertFalse failed because it was not passed at least 1 argument"); 
-	} 
+	if(arguments.length < 1){
+		throw new doh._AssertFailure("assertFalse failed because it was not passed at least 1 argument");
+	}
 	if(eval(condition)){
 		throw new doh._AssertFailure("assertFalse('" + condition + "') failed", hint);
 	}
@@ -669,15 +665,15 @@ doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual, /*St
 	//		equivalent?
 
 	// Compare undefined always with three equal signs, because undefined==null
-	// is true, but undefined===null is false. 
-	if((expected === undefined)&&(actual === undefined)){ 
+	// is true, but undefined===null is false.
+	if((expected === undefined)&&(actual === undefined)){
 		return true;
 	}
-	if(arguments.length < 2){ 
-		throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments"); 
-	} 
+	if(arguments.length < 2){
+		throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments");
+	}
 	if((expected === actual)||(expected == actual)||
-				( typeof expected == "number" && typeof actual == "number" && isNaN(expected) && isNaN(actual) )){ 
+				( typeof expected == "number" && typeof actual == "number" && isNaN(expected) && isNaN(actual) )){
 		return true;
 	}
 	if(	(this._isArray(expected) && this._isArray(actual))&&
@@ -697,24 +693,33 @@ doh.isNot = doh.assertNotEqual = function(/*Object*/ notExpected, /*Object*/ act
 	//		not equivalent?
 
 	// Compare undefined always with three equal signs, because undefined==null
-	// is true, but undefined===null is false. 
-	if((notExpected === undefined)&&(actual === undefined)){ 
+	// 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);
 	}
-	if(arguments.length < 2){ 
-		throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments"); 
-	} 
-	if((notExpected === actual)||(notExpected == actual)){ 
+	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);
 	}
 	if(	(this._isArray(notExpected) && this._isArray(actual))&&
 		(this._arrayEq(notExpected, actual)) ){
 		throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
-	if( ((typeof notExpected == "object")&&((typeof actual == "object")))&&
-		(this._objPropEq(notExpected, actual)) ){
+	if( ((typeof notExpected == "object")&&((typeof actual == "object"))) ){
+		var isequal = false;
+		try{
+			isequal = this._objPropEq(notExpected, actual);
+		}catch(e){
+			if(!(e instanceof doh._AssertFailure)){
+				throw e; //other exceptions, just throw it
+			}
+		}
+		if(isequal){
         throw new doh._AssertFailure("assertNotEqual() failed: not expected |"+notExpected+"| but got |"+actual+"|", hint);
 	}
+	}
     return true;
 }
 
@@ -756,10 +761,10 @@ doh._objPropEq = function(expected, actual){
 }
 
 doh._isArray = function(it){
-	return (it && it instanceof Array || typeof it == "array" || 
+	return (it && it instanceof Array || typeof it == "array" ||
 		(
 			!!doh.global["dojo"] &&
-			doh.global["dojo"]["NodeList"] !== undefined && 
+			doh.global["dojo"]["NodeList"] !== undefined &&
 			it instanceof doh.global["dojo"]["NodeList"]
 		)
 	);
@@ -801,7 +806,7 @@ doh._handleFailure = function(groupName, fixture, e){
 		e.rhinoException.printStackTrace();
 	}else if(e.javaException){
 		e.javaException.printStackTrace();
-	} 
+	}
 }
 
 try{
@@ -817,9 +822,9 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 	//		This function handles how to execute a 'performance' test
 	//		which is different from a straight UT style test.  These
 	//		will often do numerous iterations of the same operation and
-	//		gather execution statistics about it, like max, min, average, 
-	//		etc.  It makes use of the already in place DOH deferred test 
-	//		handling since it is a good idea to put a pause inbetween each 
+	//		gather execution statistics about it, like max, min, average,
+	//		etc.  It makes use of the already in place DOH deferred test
+	//		handling since it is a good idea to put a pause inbetween each
 	//		iteration to allow for GC cleanup and the like.
 	//
 	//	groupName:
@@ -829,7 +834,7 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 	var tg = this._groups[groupName];
 	fixture.startTime = new Date();
 
-	//Perf tests always need to act in an async manner as there is a 
+	//Perf tests always need to act in an async manner as there is a
 	//number of iterations to flow through.
 	var def = new doh.Deferred();
 	tg.inFlight++;
@@ -856,7 +861,7 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 	//Since these can take who knows how long, we don't want to timeout
 	//unless explicitly set
 	var timer;
-	var to = fixture.timeout; 
+	var to = fixture.timeout;
 	if(to > 0) {
 		timer = setTimeout(function(){
 			// ret.cancel();
@@ -892,8 +897,8 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 	itrDef.addCallback(function(iterations){
 		if(iterations){
 			var countdown = fixture.trialIterations;
-			doh.debug("TIMING TEST: [" + fixture.name + 
-					  "]\n\t\tITERATIONS PER TRIAL: " + 
+			doh.debug("TIMING TEST: [" + fixture.name +
+					  "]\n\t\tITERATIONS PER TRIAL: " +
 					  iterations + "\n\tTRIALS: " +
 					  countdown);
 
@@ -915,9 +920,9 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 							state.countdown--;
 							if(state.countdown){
 								var ret = fixture.runTest(doh);
-								if(ret instanceof doh.Deferred){
-									//Deferreds have to be handled async,
-									//otherwise we just keep looping.
+								if(ret && ret.addCallback){
+									// Deferreds have to be handled async,
+									// otherwise we just keep looping.
 									var atState = {
 										countdown: state.countdown
 									};
@@ -951,7 +956,7 @@ doh._runPerfFixture = function(/*String*/groupName, /*Object*/fixture){
 					};
 					res.trials.push(tResults);
 					doh.debug("\n\t\tTRIAL #: " +
-							  tResults.trial + "\n\tTIME: " + 
+							  tResults.trial + "\n\tTIME: " +
 							  tResults.executionTime + "ms.\n\tAVG TEST TIME: " +
 							  (tResults.executionTime/tResults.testIterations) + "ms.");
 
@@ -993,14 +998,14 @@ doh._calcTrialIterations =  function(/*String*/ groupName, /*Object*/ fixture){
 	//		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 
+	//		The callback is passed the # of iterations to hit the requested
 	//		threshold.
 	//
 	//	fixture:
 	//		The test fixture we want to calculate iterations for.
 	var def = new doh.Deferred();
 	var calibrate = function () {
-		var testFunc = fixture.runTest;
+		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
@@ -1015,7 +1020,7 @@ doh._calcTrialIterations =  function(/*String*/ groupName, /*Object*/ fixture){
 				if(state.curIter < state.iterations){
 					try{
 						var ret = testFunc(doh);
-						if(ret instanceof doh.Deferred){
+						if(ret && ret.addCallback){
 							var aState = {
 								start: state.start,
 								curIter: state.curIter + 1,
@@ -1075,12 +1080,12 @@ doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){
 	//		The test fixture to execute.
 	var tg = this._groups[groupName];
 	fixture.startTime = new Date();
-	var ret = fixture.runTest(this); 
+	var ret = fixture.runTest(this);
 	fixture.endTime = new Date();
 	// if we get a deferred back from the test runner, we know we're
 	// gonna wait for an async result. It's up to the test code to trap
 	// errors and give us an errback or callback.
-	if(ret instanceof doh.Deferred){
+	if(ret && ret.addCallback){
 		tg.inFlight++;
 		ret.groupName = groupName;
 		ret.fixture = fixture;
@@ -1101,12 +1106,15 @@ doh._runRegFixture = function(/*String*/groupName, /*Object*/fixture){
 			}
 		}
 
-		var timer = setTimeout(function(){
+		var timeoutFunction = function(){
 			fixture.endTime = new Date();
 			ret.errback(new Error("test timeout in "+fixture.name.toString()));
-		}, fixture["timeout"]||1000);
+		};
+
+		var timer = setTimeout(function(){ timeoutFunction(); }, fixture["timeout"]||1000);
 
 		ret.addBoth(function(arg){
+			timeoutFunction = function(){}; // in IE8, the clearTimeout does not always stop the timer, so clear the function as well
 			clearTimeout(timer);
 			fixture.endTime = new Date();
 			retEnd();
@@ -1127,7 +1135,7 @@ doh._runFixture = function(groupName, fixture){
 	try{
 		// let doh reference "this.group.thinger..." which can be set by
 		// another test or group-level setUp function
-		fixture.group = tg; 
+		fixture.group = tg;
 		// only execute the parts of the fixture we've got
 
 		if(fixture["setUp"]){ fixture.setUp(this); }
@@ -1381,73 +1389,53 @@ tests = doh;
 	var x;
 	try{
 		if(typeof dojo != "undefined"){
-			dojo.platformRequire({
-				browser: ["doh._browserRunner"],
-				rhino: ["doh._rhinoRunner"],
-				spidermonkey: ["doh._rhinoRunner"]
-			});
+			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){
-				if(dojo.isBrowser){
-					dojo.addOnLoad(function(){
-						if (dojo.global.registerModulePath){
-							dojo.forEach(dojo.global.registerModulePath, function(m){
-								dojo.registerModulePath(m[0], m[1]);
-							});
-						}
-						if(dojo.byId("testList")){
-							var _tm = ( (dojo.global.testModule && dojo.global.testModule.length) ? dojo.global.testModule : "dojo.tests.module");
-							dojo.forEach(_tm.split(","), dojo.require, dojo);
-							setTimeout(function(){
-								doh.run();
-							}, 500);
-						}
-					});
-				}else{
-					// dojo.require("doh._base");
-				}
-			}
-		}else{
-			if(typeof load == "function" &&
-				(typeof Packages == "function" || typeof Packages == "object")){
-				throw new Error();
-			}else if(typeof load == "function"){
-				throw new Error();
+			if(_shouldRequire && dojo.isBrowser){
+				dojo.addOnLoad(function(){
+					if (dojo.global.registerModulePath){
+						dojo.forEach(dojo.global.registerModulePath, function(m){
+							dojo.registerModulePath(m[0], m[1]);
+						});
+					}
+				});
 			}
-
-			if(this["document"]){
-				// if we survived all of that, we're probably in a browser but
-				// don't have Dojo handy. 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;
-						}
+		}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>");
-				}
+			}
+			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: 22059 $");
-		print("Copyright (c) 2010, The Dojo Foundation, All Rights Reserved");
+		print("The Dojo Unit Test Harness, $Rev: 24146 $");
+		print("Copyright (c) 2011, The Dojo Foundation, All Rights Reserved");
 		print(doh._line, "\n");
 
 		try{
@@ -1455,13 +1443,13 @@ tests = doh;
 			var testUrl = "";
 			var testModule = "dojo.tests.module";
 			var dohBase = "";
-			for(x=0; x<arguments.length; x++){
-				if(arguments[x].indexOf("=") > 0){
-					var tp = arguments[x].split("=");
+
+			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.
+						//Convert slashes to unix style and make sure properly ended.
 						dohBase = dohBase.replace(/\\/g, "/");
 						if(dohBase.charAt(dohBase.length - 1) != "/"){
 							dohBase += "/";
@@ -1500,4 +1488,26 @@ tests = doh;
 
 		doh.run();
 	}
-}).apply(this, typeof arguments != "undefined" ? arguments : [null]);
+}).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 = {};
+}
+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/jsdoc/LICENSE b/util/jsdoc/LICENSE
index 4c93ded..aa6b39f 100644
--- a/util/jsdoc/LICENSE
+++ b/util/jsdoc/LICENSE
@@ -13,7 +13,7 @@ The text of the AFL and BSD licenses is reproduced below.
 The "New" BSD License:
 **********************
 
-Copyright (c) 2005-2010, The Dojo Foundation
+Copyright (c) 2005-2011, The Dojo Foundation
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/util/shrinksafe/tests/module.js b/util/shrinksafe/tests/module.js
index 86f6b85..e3945df 100644
--- a/util/shrinksafe/tests/module.js
+++ b/util/shrinksafe/tests/module.js
@@ -14,16 +14,16 @@ shrinksafe.tests.module.compress = function(source, stripConsole, escapeUnicode)
 
 shrinksafe.tests.module.loader = function(path, stripConsole, escapeUnicode){
 	// summary: Simple function to load and compress some file. Returns and object
-	//	 with 'original' and 'compressed' members, respectively. 
+	//	 with 'original' and 'compressed' members, respectively.
 	var s = shrinksafe.tests.module.getContents(path);
 	return {
-		original: s, 
+		original: s,
 		compressed: shrinksafe.tests.module.compress(s, stripConsole, escapeUnicode || false)
 	};
 }
 
 try{
-	tests.register("shrinksafe", 
+	tests.register("shrinksafe",
 	[
 		function forwardReference(t){
 			
@@ -53,7 +53,7 @@ try{
 		},
 		
 		function varConflict(t){
-			// ensuring a shrunken variable won't overwrite an existing variable 
+			// ensuring a shrunken variable won't overwrite an existing variable
 			// name, regardless of scope.
 			var src = shrinksafe.tests.module.loader("8974.js", null);
 
@@ -134,7 +134,7 @@ try{
 		},
 
 		function debuggerCall(t){
-			// make sure we don't die when we find a debugger; statement 
+			// make sure we don't die when we find a debugger; statement
 			var src = shrinksafe.tests.module.loader("9444.js", null);
 			t.t(src.compressed.indexOf("debugger") > -1);
 		},
@@ -158,12 +158,12 @@ try{
 
 		function mungeStrings(t){
 			
-			// this test is skipped intentionally. You must manually enabled the 
+			// this test is skipped intentionally. You must manually enabled the
 			// code in Compressor.java which enables this functionality. The functionality
 			// is not considered completely "safe" and thus has been disabled.
-			// simply uncomment the block in Compressor.java to reinstate functionality. 
+			// simply uncomment the block in Compressor.java to reinstate functionality.
 			// original patch came under [ccla]. See bugs.dojotoolkit.org/ticket/8828
-			return; 
+			return;
 			
 			var src = shrinksafe.tests.module.loader("8828.js");
 			

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



More information about the Pkg-javascript-commits mailing list